diff options
author | Konstantin Khlebnikov <khlebnikov@yandex-team.ru> | 2016-04-18 07:41:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-19 20:13:19 -0400 |
commit | 607ea7cda6315be0ad8be2f98bc9de6f2d656ae6 (patch) | |
tree | f3c5db6ef9c984c8b6a7cf9e883b2ec8370cd5d7 | |
parent | 35c5845957c7982dac1f525ff3412f8acf0a0385 (diff) |
net/ipv6/addrconf: simplify sysctl registration
Struct ctl_table_header holds pointer to sysctl table which could be used
for freeing it after unregistration. IPv4 sysctls already use that.
Remove redundant NULL assignment: ndev allocated using kzalloc.
This also saves some bytes: sysctl table could be shorter than
DEVCONF_MAX+1 if some options are disable in config.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/ipv6.h | 3 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 43 |
2 files changed, 19 insertions, 27 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 7edc14fb66b6..58d6e158755f 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -63,7 +63,8 @@ struct ipv6_devconf { | |||
63 | } stable_secret; | 63 | } stable_secret; |
64 | __s32 use_oif_addrs_only; | 64 | __s32 use_oif_addrs_only; |
65 | __s32 keep_addr_on_down; | 65 | __s32 keep_addr_on_down; |
66 | void *sysctl; | 66 | |
67 | struct ctl_table_header *sysctl_header; | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | struct ipv6_params { | 70 | struct ipv6_params { |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a6c99275bd8c..5a42c0fe0449 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -359,7 +359,6 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) | |||
359 | ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64; | 359 | ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64; |
360 | 360 | ||
361 | ndev->cnf.mtu6 = dev->mtu; | 361 | ndev->cnf.mtu6 = dev->mtu; |
362 | ndev->cnf.sysctl = NULL; | ||
363 | ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); | 362 | ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); |
364 | if (!ndev->nd_parms) { | 363 | if (!ndev->nd_parms) { |
365 | kfree(ndev); | 364 | kfree(ndev); |
@@ -5620,13 +5619,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl, | |||
5620 | return ret; | 5619 | return ret; |
5621 | } | 5620 | } |
5622 | 5621 | ||
5623 | static struct addrconf_sysctl_table | 5622 | static const struct ctl_table addrconf_sysctl[] = { |
5624 | { | ||
5625 | struct ctl_table_header *sysctl_header; | ||
5626 | struct ctl_table addrconf_vars[DEVCONF_MAX+1]; | ||
5627 | } addrconf_sysctl __read_mostly = { | ||
5628 | .sysctl_header = NULL, | ||
5629 | .addrconf_vars = { | ||
5630 | { | 5623 | { |
5631 | .procname = "forwarding", | 5624 | .procname = "forwarding", |
5632 | .data = &ipv6_devconf.forwarding, | 5625 | .data = &ipv6_devconf.forwarding, |
@@ -5944,52 +5937,50 @@ static struct addrconf_sysctl_table | |||
5944 | { | 5937 | { |
5945 | /* sentinel */ | 5938 | /* sentinel */ |
5946 | } | 5939 | } |
5947 | }, | ||
5948 | }; | 5940 | }; |
5949 | 5941 | ||
5950 | static int __addrconf_sysctl_register(struct net *net, char *dev_name, | 5942 | static int __addrconf_sysctl_register(struct net *net, char *dev_name, |
5951 | struct inet6_dev *idev, struct ipv6_devconf *p) | 5943 | struct inet6_dev *idev, struct ipv6_devconf *p) |
5952 | { | 5944 | { |
5953 | int i; | 5945 | int i; |
5954 | struct addrconf_sysctl_table *t; | 5946 | struct ctl_table *table; |
5955 | char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; | 5947 | char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; |
5956 | 5948 | ||
5957 | t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL); | 5949 | table = kmemdup(addrconf_sysctl, sizeof(addrconf_sysctl), GFP_KERNEL); |
5958 | if (!t) | 5950 | if (!table) |
5959 | goto out; | 5951 | goto out; |
5960 | 5952 | ||
5961 | for (i = 0; t->addrconf_vars[i].data; i++) { | 5953 | for (i = 0; table[i].data; i++) { |
5962 | t->addrconf_vars[i].data += (char *)p - (char *)&ipv6_devconf; | 5954 | table[i].data += (char *)p - (char *)&ipv6_devconf; |
5963 | t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */ | 5955 | table[i].extra1 = idev; /* embedded; no ref */ |
5964 | t->addrconf_vars[i].extra2 = net; | 5956 | table[i].extra2 = net; |
5965 | } | 5957 | } |
5966 | 5958 | ||
5967 | snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name); | 5959 | snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name); |
5968 | 5960 | ||
5969 | t->sysctl_header = register_net_sysctl(net, path, t->addrconf_vars); | 5961 | p->sysctl_header = register_net_sysctl(net, path, table); |
5970 | if (!t->sysctl_header) | 5962 | if (!p->sysctl_header) |
5971 | goto free; | 5963 | goto free; |
5972 | 5964 | ||
5973 | p->sysctl = t; | ||
5974 | return 0; | 5965 | return 0; |
5975 | 5966 | ||
5976 | free: | 5967 | free: |
5977 | kfree(t); | 5968 | kfree(table); |
5978 | out: | 5969 | out: |
5979 | return -ENOBUFS; | 5970 | return -ENOBUFS; |
5980 | } | 5971 | } |
5981 | 5972 | ||
5982 | static void __addrconf_sysctl_unregister(struct ipv6_devconf *p) | 5973 | static void __addrconf_sysctl_unregister(struct ipv6_devconf *p) |
5983 | { | 5974 | { |
5984 | struct addrconf_sysctl_table *t; | 5975 | struct ctl_table *table; |
5985 | 5976 | ||
5986 | if (!p->sysctl) | 5977 | if (!p->sysctl_header) |
5987 | return; | 5978 | return; |
5988 | 5979 | ||
5989 | t = p->sysctl; | 5980 | table = p->sysctl_header->ctl_table_arg; |
5990 | p->sysctl = NULL; | 5981 | unregister_net_sysctl_table(p->sysctl_header); |
5991 | unregister_net_sysctl_table(t->sysctl_header); | 5982 | p->sysctl_header = NULL; |
5992 | kfree(t); | 5983 | kfree(table); |
5993 | } | 5984 | } |
5994 | 5985 | ||
5995 | static int addrconf_sysctl_register(struct inet6_dev *idev) | 5986 | static int addrconf_sysctl_register(struct inet6_dev *idev) |