aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c306
1 files changed, 125 insertions, 181 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5df2f6a0b0f0..90e3d6379a42 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -50,6 +50,7 @@
50#include <linux/notifier.h> 50#include <linux/notifier.h>
51#include <linux/inetdevice.h> 51#include <linux/inetdevice.h>
52#include <linux/igmp.h> 52#include <linux/igmp.h>
53#include <linux/slab.h>
53#ifdef CONFIG_SYSCTL 54#ifdef CONFIG_SYSCTL
54#include <linux/sysctl.h> 55#include <linux/sysctl.h>
55#endif 56#endif
@@ -64,20 +65,20 @@
64 65
65static struct ipv4_devconf ipv4_devconf = { 66static struct ipv4_devconf ipv4_devconf = {
66 .data = { 67 .data = {
67 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, 68 [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
68 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, 69 [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
69 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, 70 [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
70 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, 71 [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
71 }, 72 },
72}; 73};
73 74
74static struct ipv4_devconf ipv4_devconf_dflt = { 75static struct ipv4_devconf ipv4_devconf_dflt = {
75 .data = { 76 .data = {
76 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, 77 [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
77 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, 78 [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
78 [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, 79 [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
79 [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, 80 [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
80 [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1, 81 [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
81 }, 82 },
82}; 83};
83 84
@@ -140,11 +141,11 @@ void in_dev_finish_destroy(struct in_device *idev)
140#endif 141#endif
141 dev_put(dev); 142 dev_put(dev);
142 if (!idev->dead) 143 if (!idev->dead)
143 printk("Freeing alive in_device %p\n", idev); 144 pr_err("Freeing alive in_device %p\n", idev);
144 else { 145 else
145 kfree(idev); 146 kfree(idev);
146 }
147} 147}
148EXPORT_SYMBOL(in_dev_finish_destroy);
148 149
149static struct in_device *inetdev_init(struct net_device *dev) 150static struct in_device *inetdev_init(struct net_device *dev)
150{ 151{
@@ -159,7 +160,8 @@ static struct in_device *inetdev_init(struct net_device *dev)
159 sizeof(in_dev->cnf)); 160 sizeof(in_dev->cnf));
160 in_dev->cnf.sysctl = NULL; 161 in_dev->cnf.sysctl = NULL;
161 in_dev->dev = dev; 162 in_dev->dev = dev;
162 if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) 163 in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl);
164 if (!in_dev->arp_parms)
163 goto out_kfree; 165 goto out_kfree;
164 if (IPV4_DEVCONF(in_dev->cnf, FORWARDING)) 166 if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
165 dev_disable_lro(dev); 167 dev_disable_lro(dev);
@@ -405,13 +407,15 @@ struct in_device *inetdev_by_index(struct net *net, int ifindex)
405{ 407{
406 struct net_device *dev; 408 struct net_device *dev;
407 struct in_device *in_dev = NULL; 409 struct in_device *in_dev = NULL;
408 read_lock(&dev_base_lock); 410
409 dev = __dev_get_by_index(net, ifindex); 411 rcu_read_lock();
412 dev = dev_get_by_index_rcu(net, ifindex);
410 if (dev) 413 if (dev)
411 in_dev = in_dev_get(dev); 414 in_dev = in_dev_get(dev);
412 read_unlock(&dev_base_lock); 415 rcu_read_unlock();
413 return in_dev; 416 return in_dev;
414} 417}
418EXPORT_SYMBOL(inetdev_by_index);
415 419
416/* Called only from RTNL semaphored context. No locks. */ 420/* Called only from RTNL semaphored context. No locks. */
417 421
@@ -557,7 +561,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
557 * Determine a default network mask, based on the IP address. 561 * Determine a default network mask, based on the IP address.
558 */ 562 */
559 563
560static __inline__ int inet_abc_len(__be32 addr) 564static inline int inet_abc_len(__be32 addr)
561{ 565{
562 int rc = -1; /* Something else, probably a multicast. */ 566 int rc = -1; /* Something else, probably a multicast. */
563 567
@@ -646,13 +650,15 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
646 rtnl_lock(); 650 rtnl_lock();
647 651
648 ret = -ENODEV; 652 ret = -ENODEV;
649 if ((dev = __dev_get_by_name(net, ifr.ifr_name)) == NULL) 653 dev = __dev_get_by_name(net, ifr.ifr_name);
654 if (!dev)
650 goto done; 655 goto done;
651 656
652 if (colon) 657 if (colon)
653 *colon = ':'; 658 *colon = ':';
654 659
655 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { 660 in_dev = __in_dev_get_rtnl(dev);
661 if (in_dev) {
656 if (tryaddrmatch) { 662 if (tryaddrmatch) {
657 /* Matthias Andree */ 663 /* Matthias Andree */
658 /* compare label and address (4.4BSD style) */ 664 /* compare label and address (4.4BSD style) */
@@ -720,7 +726,8 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
720 726
721 if (!ifa) { 727 if (!ifa) {
722 ret = -ENOBUFS; 728 ret = -ENOBUFS;
723 if ((ifa = inet_alloc_ifa()) == NULL) 729 ifa = inet_alloc_ifa();
730 if (!ifa)
724 break; 731 break;
725 if (colon) 732 if (colon)
726 memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ); 733 memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
@@ -822,10 +829,10 @@ static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
822 struct ifreq ifr; 829 struct ifreq ifr;
823 int done = 0; 830 int done = 0;
824 831
825 if (!in_dev || (ifa = in_dev->ifa_list) == NULL) 832 if (!in_dev)
826 goto out; 833 goto out;
827 834
828 for (; ifa; ifa = ifa->ifa_next) { 835 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
829 if (!buf) { 836 if (!buf) {
830 done += sizeof(ifr); 837 done += sizeof(ifr);
831 continue; 838 continue;
@@ -875,36 +882,33 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
875 if (!addr) 882 if (!addr)
876 addr = ifa->ifa_local; 883 addr = ifa->ifa_local;
877 } endfor_ifa(in_dev); 884 } endfor_ifa(in_dev);
878no_in_dev:
879 rcu_read_unlock();
880 885
881 if (addr) 886 if (addr)
882 goto out; 887 goto out_unlock;
888no_in_dev:
883 889
884 /* Not loopback addresses on loopback should be preferred 890 /* Not loopback addresses on loopback should be preferred
885 in this case. It is importnat that lo is the first interface 891 in this case. It is importnat that lo is the first interface
886 in dev_base list. 892 in dev_base list.
887 */ 893 */
888 read_lock(&dev_base_lock); 894 for_each_netdev_rcu(net, dev) {
889 rcu_read_lock(); 895 in_dev = __in_dev_get_rcu(dev);
890 for_each_netdev(net, dev) { 896 if (!in_dev)
891 if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
892 continue; 897 continue;
893 898
894 for_primary_ifa(in_dev) { 899 for_primary_ifa(in_dev) {
895 if (ifa->ifa_scope != RT_SCOPE_LINK && 900 if (ifa->ifa_scope != RT_SCOPE_LINK &&
896 ifa->ifa_scope <= scope) { 901 ifa->ifa_scope <= scope) {
897 addr = ifa->ifa_local; 902 addr = ifa->ifa_local;
898 goto out_unlock_both; 903 goto out_unlock;
899 } 904 }
900 } endfor_ifa(in_dev); 905 } endfor_ifa(in_dev);
901 } 906 }
902out_unlock_both: 907out_unlock:
903 read_unlock(&dev_base_lock);
904 rcu_read_unlock(); 908 rcu_read_unlock();
905out:
906 return addr; 909 return addr;
907} 910}
911EXPORT_SYMBOL(inet_select_addr);
908 912
909static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst, 913static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
910 __be32 local, int scope) 914 __be32 local, int scope)
@@ -940,7 +944,7 @@ static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
940 } 944 }
941 } endfor_ifa(in_dev); 945 } endfor_ifa(in_dev);
942 946
943 return same? addr : 0; 947 return same ? addr : 0;
944} 948}
945 949
946/* 950/*
@@ -961,17 +965,16 @@ __be32 inet_confirm_addr(struct in_device *in_dev,
961 return confirm_addr_indev(in_dev, dst, local, scope); 965 return confirm_addr_indev(in_dev, dst, local, scope);
962 966
963 net = dev_net(in_dev->dev); 967 net = dev_net(in_dev->dev);
964 read_lock(&dev_base_lock);
965 rcu_read_lock(); 968 rcu_read_lock();
966 for_each_netdev(net, dev) { 969 for_each_netdev_rcu(net, dev) {
967 if ((in_dev = __in_dev_get_rcu(dev))) { 970 in_dev = __in_dev_get_rcu(dev);
971 if (in_dev) {
968 addr = confirm_addr_indev(in_dev, dst, local, scope); 972 addr = confirm_addr_indev(in_dev, dst, local, scope);
969 if (addr) 973 if (addr)
970 break; 974 break;
971 } 975 }
972 } 976 }
973 rcu_read_unlock(); 977 rcu_read_unlock();
974 read_unlock(&dev_base_lock);
975 978
976 return addr; 979 return addr;
977} 980}
@@ -984,14 +987,16 @@ int register_inetaddr_notifier(struct notifier_block *nb)
984{ 987{
985 return blocking_notifier_chain_register(&inetaddr_chain, nb); 988 return blocking_notifier_chain_register(&inetaddr_chain, nb);
986} 989}
990EXPORT_SYMBOL(register_inetaddr_notifier);
987 991
988int unregister_inetaddr_notifier(struct notifier_block *nb) 992int unregister_inetaddr_notifier(struct notifier_block *nb)
989{ 993{
990 return blocking_notifier_chain_unregister(&inetaddr_chain, nb); 994 return blocking_notifier_chain_unregister(&inetaddr_chain, nb);
991} 995}
996EXPORT_SYMBOL(unregister_inetaddr_notifier);
992 997
993/* Rename ifa_labels for a device name change. Make some effort to preserve existing 998/* Rename ifa_labels for a device name change. Make some effort to preserve
994 * alias numbering and to create unique labels if possible. 999 * existing alias numbering and to create unique labels if possible.
995*/ 1000*/
996static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) 1001static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
997{ 1002{
@@ -1010,11 +1015,10 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
1010 sprintf(old, ":%d", named); 1015 sprintf(old, ":%d", named);
1011 dot = old; 1016 dot = old;
1012 } 1017 }
1013 if (strlen(dot) + strlen(dev->name) < IFNAMSIZ) { 1018 if (strlen(dot) + strlen(dev->name) < IFNAMSIZ)
1014 strcat(ifa->ifa_label, dot); 1019 strcat(ifa->ifa_label, dot);
1015 } else { 1020 else
1016 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); 1021 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot);
1017 }
1018skip: 1022skip:
1019 rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); 1023 rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
1020 } 1024 }
@@ -1061,8 +1065,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1061 if (!inetdev_valid_mtu(dev->mtu)) 1065 if (!inetdev_valid_mtu(dev->mtu))
1062 break; 1066 break;
1063 if (dev->flags & IFF_LOOPBACK) { 1067 if (dev->flags & IFF_LOOPBACK) {
1064 struct in_ifaddr *ifa; 1068 struct in_ifaddr *ifa = inet_alloc_ifa();
1065 if ((ifa = inet_alloc_ifa()) != NULL) { 1069
1070 if (ifa) {
1066 ifa->ifa_local = 1071 ifa->ifa_local =
1067 ifa->ifa_address = htonl(INADDR_LOOPBACK); 1072 ifa->ifa_address = htonl(INADDR_LOOPBACK);
1068 ifa->ifa_prefixlen = 8; 1073 ifa->ifa_prefixlen = 8;
@@ -1170,38 +1175,54 @@ nla_put_failure:
1170static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 1175static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1171{ 1176{
1172 struct net *net = sock_net(skb->sk); 1177 struct net *net = sock_net(skb->sk);
1173 int idx, ip_idx; 1178 int h, s_h;
1179 int idx, s_idx;
1180 int ip_idx, s_ip_idx;
1174 struct net_device *dev; 1181 struct net_device *dev;
1175 struct in_device *in_dev; 1182 struct in_device *in_dev;
1176 struct in_ifaddr *ifa; 1183 struct in_ifaddr *ifa;
1177 int s_ip_idx, s_idx = cb->args[0]; 1184 struct hlist_head *head;
1185 struct hlist_node *node;
1178 1186
1179 s_ip_idx = ip_idx = cb->args[1]; 1187 s_h = cb->args[0];
1180 idx = 0; 1188 s_idx = idx = cb->args[1];
1181 for_each_netdev(net, dev) { 1189 s_ip_idx = ip_idx = cb->args[2];
1182 if (idx < s_idx) 1190
1183 goto cont; 1191 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
1184 if (idx > s_idx) 1192 idx = 0;
1185 s_ip_idx = 0; 1193 head = &net->dev_index_head[h];
1186 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) 1194 rcu_read_lock();
1187 goto cont; 1195 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
1188 1196 if (idx < s_idx)
1189 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; 1197 goto cont;
1190 ifa = ifa->ifa_next, ip_idx++) { 1198 if (h > s_h || idx > s_idx)
1191 if (ip_idx < s_ip_idx) 1199 s_ip_idx = 0;
1192 continue; 1200 in_dev = __in_dev_get_rcu(dev);
1193 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, 1201 if (!in_dev)
1202 goto cont;
1203
1204 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1205 ifa = ifa->ifa_next, ip_idx++) {
1206 if (ip_idx < s_ip_idx)
1207 continue;
1208 if (inet_fill_ifaddr(skb, ifa,
1209 NETLINK_CB(cb->skb).pid,
1194 cb->nlh->nlmsg_seq, 1210 cb->nlh->nlmsg_seq,
1195 RTM_NEWADDR, NLM_F_MULTI) <= 0) 1211 RTM_NEWADDR, NLM_F_MULTI) <= 0) {
1196 goto done; 1212 rcu_read_unlock();
1197 } 1213 goto done;
1214 }
1215 }
1198cont: 1216cont:
1199 idx++; 1217 idx++;
1218 }
1219 rcu_read_unlock();
1200 } 1220 }
1201 1221
1202done: 1222done:
1203 cb->args[0] = idx; 1223 cb->args[0] = h;
1204 cb->args[1] = ip_idx; 1224 cb->args[1] = idx;
1225 cb->args[2] = ip_idx;
1205 1226
1206 return skb->len; 1227 return skb->len;
1207} 1228}
@@ -1239,18 +1260,18 @@ static void devinet_copy_dflt_conf(struct net *net, int i)
1239{ 1260{
1240 struct net_device *dev; 1261 struct net_device *dev;
1241 1262
1242 read_lock(&dev_base_lock); 1263 rcu_read_lock();
1243 for_each_netdev(net, dev) { 1264 for_each_netdev_rcu(net, dev) {
1244 struct in_device *in_dev; 1265 struct in_device *in_dev;
1245 rcu_read_lock(); 1266
1246 in_dev = __in_dev_get_rcu(dev); 1267 in_dev = __in_dev_get_rcu(dev);
1247 if (in_dev && !test_bit(i, in_dev->cnf.state)) 1268 if (in_dev && !test_bit(i, in_dev->cnf.state))
1248 in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i]; 1269 in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i];
1249 rcu_read_unlock();
1250 } 1270 }
1251 read_unlock(&dev_base_lock); 1271 rcu_read_unlock();
1252} 1272}
1253 1273
1274/* called with RTNL locked */
1254static void inet_forward_change(struct net *net) 1275static void inet_forward_change(struct net *net)
1255{ 1276{
1256 struct net_device *dev; 1277 struct net_device *dev;
@@ -1259,7 +1280,6 @@ static void inet_forward_change(struct net *net)
1259 IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on; 1280 IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
1260 IPV4_DEVCONF_DFLT(net, FORWARDING) = on; 1281 IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
1261 1282
1262 read_lock(&dev_base_lock);
1263 for_each_netdev(net, dev) { 1283 for_each_netdev(net, dev) {
1264 struct in_device *in_dev; 1284 struct in_device *in_dev;
1265 if (on) 1285 if (on)
@@ -1270,7 +1290,6 @@ static void inet_forward_change(struct net *net)
1270 IN_DEV_CONF_SET(in_dev, FORWARDING, on); 1290 IN_DEV_CONF_SET(in_dev, FORWARDING, on);
1271 rcu_read_unlock(); 1291 rcu_read_unlock();
1272 } 1292 }
1273 read_unlock(&dev_base_lock);
1274} 1293}
1275 1294
1276static int devinet_conf_proc(ctl_table *ctl, int write, 1295static int devinet_conf_proc(ctl_table *ctl, int write,
@@ -1293,72 +1312,25 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
1293 return ret; 1312 return ret;
1294} 1313}
1295 1314
1296static int devinet_conf_sysctl(ctl_table *table,
1297 void __user *oldval, size_t __user *oldlenp,
1298 void __user *newval, size_t newlen)
1299{
1300 struct ipv4_devconf *cnf;
1301 struct net *net;
1302 int *valp = table->data;
1303 int new;
1304 int i;
1305
1306 if (!newval || !newlen)
1307 return 0;
1308
1309 if (newlen != sizeof(int))
1310 return -EINVAL;
1311
1312 if (get_user(new, (int __user *)newval))
1313 return -EFAULT;
1314
1315 if (new == *valp)
1316 return 0;
1317
1318 if (oldval && oldlenp) {
1319 size_t len;
1320
1321 if (get_user(len, oldlenp))
1322 return -EFAULT;
1323
1324 if (len) {
1325 if (len > table->maxlen)
1326 len = table->maxlen;
1327 if (copy_to_user(oldval, valp, len))
1328 return -EFAULT;
1329 if (put_user(len, oldlenp))
1330 return -EFAULT;
1331 }
1332 }
1333
1334 *valp = new;
1335
1336 cnf = table->extra1;
1337 net = table->extra2;
1338 i = (int *)table->data - cnf->data;
1339
1340 set_bit(i, cnf->state);
1341
1342 if (cnf == net->ipv4.devconf_dflt)
1343 devinet_copy_dflt_conf(net, i);
1344
1345 return 1;
1346}
1347
1348static int devinet_sysctl_forward(ctl_table *ctl, int write, 1315static int devinet_sysctl_forward(ctl_table *ctl, int write,
1349 void __user *buffer, 1316 void __user *buffer,
1350 size_t *lenp, loff_t *ppos) 1317 size_t *lenp, loff_t *ppos)
1351{ 1318{
1352 int *valp = ctl->data; 1319 int *valp = ctl->data;
1353 int val = *valp; 1320 int val = *valp;
1321 loff_t pos = *ppos;
1354 int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 1322 int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1355 1323
1356 if (write && *valp != val) { 1324 if (write && *valp != val) {
1357 struct net *net = ctl->extra2; 1325 struct net *net = ctl->extra2;
1358 1326
1359 if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) { 1327 if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
1360 if (!rtnl_trylock()) 1328 if (!rtnl_trylock()) {
1329 /* Restore the original values before restarting */
1330 *valp = val;
1331 *ppos = pos;
1361 return restart_syscall(); 1332 return restart_syscall();
1333 }
1362 if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) { 1334 if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
1363 inet_forward_change(net); 1335 inet_forward_change(net);
1364 } else if (*valp) { 1336 } else if (*valp) {
@@ -1390,57 +1362,37 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
1390 return ret; 1362 return ret;
1391} 1363}
1392 1364
1393int ipv4_doint_and_flush_strategy(ctl_table *table, 1365#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc) \
1394 void __user *oldval, size_t __user *oldlenp,
1395 void __user *newval, size_t newlen)
1396{
1397 int ret = devinet_conf_sysctl(table, oldval, oldlenp, newval, newlen);
1398 struct net *net = table->extra2;
1399
1400 if (ret == 1)
1401 rt_cache_flush(net, 0);
1402
1403 return ret;
1404}
1405
1406
1407#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \
1408 { \ 1366 { \
1409 .ctl_name = NET_IPV4_CONF_ ## attr, \
1410 .procname = name, \ 1367 .procname = name, \
1411 .data = ipv4_devconf.data + \ 1368 .data = ipv4_devconf.data + \
1412 NET_IPV4_CONF_ ## attr - 1, \ 1369 IPV4_DEVCONF_ ## attr - 1, \
1413 .maxlen = sizeof(int), \ 1370 .maxlen = sizeof(int), \
1414 .mode = mval, \ 1371 .mode = mval, \
1415 .proc_handler = proc, \ 1372 .proc_handler = proc, \
1416 .strategy = sysctl, \
1417 .extra1 = &ipv4_devconf, \ 1373 .extra1 = &ipv4_devconf, \
1418 } 1374 }
1419 1375
1420#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \ 1376#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
1421 DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \ 1377 DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc)
1422 devinet_conf_sysctl)
1423 1378
1424#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \ 1379#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
1425 DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \ 1380 DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc)
1426 devinet_conf_sysctl)
1427 1381
1428#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \ 1382#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
1429 DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl) 1383 DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc)
1430 1384
1431#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \ 1385#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
1432 DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \ 1386 DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush)
1433 ipv4_doint_and_flush_strategy)
1434 1387
1435static struct devinet_sysctl_table { 1388static struct devinet_sysctl_table {
1436 struct ctl_table_header *sysctl_header; 1389 struct ctl_table_header *sysctl_header;
1437 struct ctl_table devinet_vars[__NET_IPV4_CONF_MAX]; 1390 struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX];
1438 char *dev_name; 1391 char *dev_name;
1439} devinet_sysctl = { 1392} devinet_sysctl = {
1440 .devinet_vars = { 1393 .devinet_vars = {
1441 DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding", 1394 DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
1442 devinet_sysctl_forward, 1395 devinet_sysctl_forward),
1443 devinet_conf_sysctl),
1444 DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"), 1396 DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
1445 1397
1446 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"), 1398 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
@@ -1450,6 +1402,8 @@ static struct devinet_sysctl_table {
1450 DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"), 1402 DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
1451 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, 1403 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
1452 "accept_source_route"), 1404 "accept_source_route"),
1405 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
1406 DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
1453 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), 1407 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
1454 DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), 1408 DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
1455 DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), 1409 DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
@@ -1460,6 +1414,7 @@ static struct devinet_sysctl_table {
1460 DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"), 1414 DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
1461 DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"), 1415 DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
1462 DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"), 1416 DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
1417 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
1463 1418
1464 DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"), 1419 DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
1465 DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"), 1420 DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
@@ -1471,7 +1426,7 @@ static struct devinet_sysctl_table {
1471}; 1426};
1472 1427
1473static int __devinet_sysctl_register(struct net *net, char *dev_name, 1428static int __devinet_sysctl_register(struct net *net, char *dev_name,
1474 int ctl_name, struct ipv4_devconf *p) 1429 struct ipv4_devconf *p)
1475{ 1430{
1476 int i; 1431 int i;
1477 struct devinet_sysctl_table *t; 1432 struct devinet_sysctl_table *t;
@@ -1479,9 +1434,9 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
1479#define DEVINET_CTL_PATH_DEV 3 1434#define DEVINET_CTL_PATH_DEV 3
1480 1435
1481 struct ctl_path devinet_ctl_path[] = { 1436 struct ctl_path devinet_ctl_path[] = {
1482 { .procname = "net", .ctl_name = CTL_NET, }, 1437 { .procname = "net", },
1483 { .procname = "ipv4", .ctl_name = NET_IPV4, }, 1438 { .procname = "ipv4", },
1484 { .procname = "conf", .ctl_name = NET_IPV4_CONF, }, 1439 { .procname = "conf", },
1485 { /* to be set */ }, 1440 { /* to be set */ },
1486 { }, 1441 { },
1487 }; 1442 };
@@ -1506,7 +1461,6 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
1506 goto free; 1461 goto free;
1507 1462
1508 devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name; 1463 devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name;
1509 devinet_ctl_path[DEVINET_CTL_PATH_DEV].ctl_name = ctl_name;
1510 1464
1511 t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path, 1465 t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path,
1512 t->devinet_vars); 1466 t->devinet_vars);
@@ -1539,10 +1493,9 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
1539 1493
1540static void devinet_sysctl_register(struct in_device *idev) 1494static void devinet_sysctl_register(struct in_device *idev)
1541{ 1495{
1542 neigh_sysctl_register(idev->dev, idev->arp_parms, NET_IPV4, 1496 neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4", NULL);
1543 NET_IPV4_NEIGH, "ipv4", NULL, NULL);
1544 __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, 1497 __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
1545 idev->dev->ifindex, &idev->cnf); 1498 &idev->cnf);
1546} 1499}
1547 1500
1548static void devinet_sysctl_unregister(struct in_device *idev) 1501static void devinet_sysctl_unregister(struct in_device *idev)
@@ -1553,14 +1506,12 @@ static void devinet_sysctl_unregister(struct in_device *idev)
1553 1506
1554static struct ctl_table ctl_forward_entry[] = { 1507static struct ctl_table ctl_forward_entry[] = {
1555 { 1508 {
1556 .ctl_name = NET_IPV4_FORWARD,
1557 .procname = "ip_forward", 1509 .procname = "ip_forward",
1558 .data = &ipv4_devconf.data[ 1510 .data = &ipv4_devconf.data[
1559 NET_IPV4_CONF_FORWARDING - 1], 1511 IPV4_DEVCONF_FORWARDING - 1],
1560 .maxlen = sizeof(int), 1512 .maxlen = sizeof(int),
1561 .mode = 0644, 1513 .mode = 0644,
1562 .proc_handler = devinet_sysctl_forward, 1514 .proc_handler = devinet_sysctl_forward,
1563 .strategy = devinet_conf_sysctl,
1564 .extra1 = &ipv4_devconf, 1515 .extra1 = &ipv4_devconf,
1565 .extra2 = &init_net, 1516 .extra2 = &init_net,
1566 }, 1517 },
@@ -1568,8 +1519,8 @@ static struct ctl_table ctl_forward_entry[] = {
1568}; 1519};
1569 1520
1570static __net_initdata struct ctl_path net_ipv4_path[] = { 1521static __net_initdata struct ctl_path net_ipv4_path[] = {
1571 { .procname = "net", .ctl_name = CTL_NET, }, 1522 { .procname = "net", },
1572 { .procname = "ipv4", .ctl_name = NET_IPV4, }, 1523 { .procname = "ipv4", },
1573 { }, 1524 { },
1574}; 1525};
1575#endif 1526#endif
@@ -1587,7 +1538,7 @@ static __net_init int devinet_init_net(struct net *net)
1587 all = &ipv4_devconf; 1538 all = &ipv4_devconf;
1588 dflt = &ipv4_devconf_dflt; 1539 dflt = &ipv4_devconf_dflt;
1589 1540
1590 if (net != &init_net) { 1541 if (!net_eq(net, &init_net)) {
1591 all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL); 1542 all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL);
1592 if (all == NULL) 1543 if (all == NULL)
1593 goto err_alloc_all; 1544 goto err_alloc_all;
@@ -1601,20 +1552,18 @@ static __net_init int devinet_init_net(struct net *net)
1601 if (tbl == NULL) 1552 if (tbl == NULL)
1602 goto err_alloc_ctl; 1553 goto err_alloc_ctl;
1603 1554
1604 tbl[0].data = &all->data[NET_IPV4_CONF_FORWARDING - 1]; 1555 tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING - 1];
1605 tbl[0].extra1 = all; 1556 tbl[0].extra1 = all;
1606 tbl[0].extra2 = net; 1557 tbl[0].extra2 = net;
1607#endif 1558#endif
1608 } 1559 }
1609 1560
1610#ifdef CONFIG_SYSCTL 1561#ifdef CONFIG_SYSCTL
1611 err = __devinet_sysctl_register(net, "all", 1562 err = __devinet_sysctl_register(net, "all", all);
1612 NET_PROTO_CONF_ALL, all);
1613 if (err < 0) 1563 if (err < 0)
1614 goto err_reg_all; 1564 goto err_reg_all;
1615 1565
1616 err = __devinet_sysctl_register(net, "default", 1566 err = __devinet_sysctl_register(net, "default", dflt);
1617 NET_PROTO_CONF_DEFAULT, dflt);
1618 if (err < 0) 1567 if (err < 0)
1619 goto err_reg_dflt; 1568 goto err_reg_dflt;
1620 1569
@@ -1680,8 +1629,3 @@ void __init devinet_init(void)
1680 rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); 1629 rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr);
1681} 1630}
1682 1631
1683EXPORT_SYMBOL(in_dev_finish_destroy);
1684EXPORT_SYMBOL(inet_select_addr);
1685EXPORT_SYMBOL(inetdev_by_index);
1686EXPORT_SYMBOL(register_inetaddr_notifier);
1687EXPORT_SYMBOL(unregister_inetaddr_notifier);