aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <khlebnikov@yandex-team.ru>2016-04-18 07:41:10 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-19 20:13:19 -0400
commit607ea7cda6315be0ad8be2f98bc9de6f2d656ae6 (patch)
treef3c5db6ef9c984c8b6a7cf9e883b2ec8370cd5d7
parent35c5845957c7982dac1f525ff3412f8acf0a0385 (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.h3
-rw-r--r--net/ipv6/addrconf.c43
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
69struct ipv6_params { 70struct 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
5623static struct addrconf_sysctl_table 5622static 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
5950static int __addrconf_sysctl_register(struct net *net, char *dev_name, 5942static 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
5976free: 5967free:
5977 kfree(t); 5968 kfree(table);
5978out: 5969out:
5979 return -ENOBUFS; 5970 return -ENOBUFS;
5980} 5971}
5981 5972
5982static void __addrconf_sysctl_unregister(struct ipv6_devconf *p) 5973static 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
5995static int addrconf_sysctl_register(struct inet6_dev *idev) 5986static int addrconf_sysctl_register(struct inet6_dev *idev)