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.c269
1 files changed, 103 insertions, 166 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5df2f6a0b0f0..5cdbc102a418 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -140,11 +140,11 @@ void in_dev_finish_destroy(struct in_device *idev)
140#endif 140#endif
141 dev_put(dev); 141 dev_put(dev);
142 if (!idev->dead) 142 if (!idev->dead)
143 printk("Freeing alive in_device %p\n", idev); 143 pr_err("Freeing alive in_device %p\n", idev);
144 else { 144 else
145 kfree(idev); 145 kfree(idev);
146 }
147} 146}
147EXPORT_SYMBOL(in_dev_finish_destroy);
148 148
149static struct in_device *inetdev_init(struct net_device *dev) 149static struct in_device *inetdev_init(struct net_device *dev)
150{ 150{
@@ -159,7 +159,8 @@ static struct in_device *inetdev_init(struct net_device *dev)
159 sizeof(in_dev->cnf)); 159 sizeof(in_dev->cnf));
160 in_dev->cnf.sysctl = NULL; 160 in_dev->cnf.sysctl = NULL;
161 in_dev->dev = dev; 161 in_dev->dev = dev;
162 if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) 162 in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl);
163 if (!in_dev->arp_parms)
163 goto out_kfree; 164 goto out_kfree;
164 if (IPV4_DEVCONF(in_dev->cnf, FORWARDING)) 165 if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
165 dev_disable_lro(dev); 166 dev_disable_lro(dev);
@@ -405,13 +406,15 @@ struct in_device *inetdev_by_index(struct net *net, int ifindex)
405{ 406{
406 struct net_device *dev; 407 struct net_device *dev;
407 struct in_device *in_dev = NULL; 408 struct in_device *in_dev = NULL;
408 read_lock(&dev_base_lock); 409
409 dev = __dev_get_by_index(net, ifindex); 410 rcu_read_lock();
411 dev = dev_get_by_index_rcu(net, ifindex);
410 if (dev) 412 if (dev)
411 in_dev = in_dev_get(dev); 413 in_dev = in_dev_get(dev);
412 read_unlock(&dev_base_lock); 414 rcu_read_unlock();
413 return in_dev; 415 return in_dev;
414} 416}
417EXPORT_SYMBOL(inetdev_by_index);
415 418
416/* Called only from RTNL semaphored context. No locks. */ 419/* Called only from RTNL semaphored context. No locks. */
417 420
@@ -557,7 +560,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. 560 * Determine a default network mask, based on the IP address.
558 */ 561 */
559 562
560static __inline__ int inet_abc_len(__be32 addr) 563static inline int inet_abc_len(__be32 addr)
561{ 564{
562 int rc = -1; /* Something else, probably a multicast. */ 565 int rc = -1; /* Something else, probably a multicast. */
563 566
@@ -646,13 +649,15 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
646 rtnl_lock(); 649 rtnl_lock();
647 650
648 ret = -ENODEV; 651 ret = -ENODEV;
649 if ((dev = __dev_get_by_name(net, ifr.ifr_name)) == NULL) 652 dev = __dev_get_by_name(net, ifr.ifr_name);
653 if (!dev)
650 goto done; 654 goto done;
651 655
652 if (colon) 656 if (colon)
653 *colon = ':'; 657 *colon = ':';
654 658
655 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { 659 in_dev = __in_dev_get_rtnl(dev);
660 if (in_dev) {
656 if (tryaddrmatch) { 661 if (tryaddrmatch) {
657 /* Matthias Andree */ 662 /* Matthias Andree */
658 /* compare label and address (4.4BSD style) */ 663 /* compare label and address (4.4BSD style) */
@@ -720,7 +725,8 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
720 725
721 if (!ifa) { 726 if (!ifa) {
722 ret = -ENOBUFS; 727 ret = -ENOBUFS;
723 if ((ifa = inet_alloc_ifa()) == NULL) 728 ifa = inet_alloc_ifa();
729 if (!ifa)
724 break; 730 break;
725 if (colon) 731 if (colon)
726 memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ); 732 memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
@@ -822,10 +828,10 @@ static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
822 struct ifreq ifr; 828 struct ifreq ifr;
823 int done = 0; 829 int done = 0;
824 830
825 if (!in_dev || (ifa = in_dev->ifa_list) == NULL) 831 if (!in_dev)
826 goto out; 832 goto out;
827 833
828 for (; ifa; ifa = ifa->ifa_next) { 834 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
829 if (!buf) { 835 if (!buf) {
830 done += sizeof(ifr); 836 done += sizeof(ifr);
831 continue; 837 continue;
@@ -875,36 +881,33 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
875 if (!addr) 881 if (!addr)
876 addr = ifa->ifa_local; 882 addr = ifa->ifa_local;
877 } endfor_ifa(in_dev); 883 } endfor_ifa(in_dev);
878no_in_dev:
879 rcu_read_unlock();
880 884
881 if (addr) 885 if (addr)
882 goto out; 886 goto out_unlock;
887no_in_dev:
883 888
884 /* Not loopback addresses on loopback should be preferred 889 /* Not loopback addresses on loopback should be preferred
885 in this case. It is importnat that lo is the first interface 890 in this case. It is importnat that lo is the first interface
886 in dev_base list. 891 in dev_base list.
887 */ 892 */
888 read_lock(&dev_base_lock); 893 for_each_netdev_rcu(net, dev) {
889 rcu_read_lock(); 894 in_dev = __in_dev_get_rcu(dev);
890 for_each_netdev(net, dev) { 895 if (!in_dev)
891 if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
892 continue; 896 continue;
893 897
894 for_primary_ifa(in_dev) { 898 for_primary_ifa(in_dev) {
895 if (ifa->ifa_scope != RT_SCOPE_LINK && 899 if (ifa->ifa_scope != RT_SCOPE_LINK &&
896 ifa->ifa_scope <= scope) { 900 ifa->ifa_scope <= scope) {
897 addr = ifa->ifa_local; 901 addr = ifa->ifa_local;
898 goto out_unlock_both; 902 goto out_unlock;
899 } 903 }
900 } endfor_ifa(in_dev); 904 } endfor_ifa(in_dev);
901 } 905 }
902out_unlock_both: 906out_unlock:
903 read_unlock(&dev_base_lock);
904 rcu_read_unlock(); 907 rcu_read_unlock();
905out:
906 return addr; 908 return addr;
907} 909}
910EXPORT_SYMBOL(inet_select_addr);
908 911
909static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst, 912static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
910 __be32 local, int scope) 913 __be32 local, int scope)
@@ -940,7 +943,7 @@ static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
940 } 943 }
941 } endfor_ifa(in_dev); 944 } endfor_ifa(in_dev);
942 945
943 return same? addr : 0; 946 return same ? addr : 0;
944} 947}
945 948
946/* 949/*
@@ -961,17 +964,16 @@ __be32 inet_confirm_addr(struct in_device *in_dev,
961 return confirm_addr_indev(in_dev, dst, local, scope); 964 return confirm_addr_indev(in_dev, dst, local, scope);
962 965
963 net = dev_net(in_dev->dev); 966 net = dev_net(in_dev->dev);
964 read_lock(&dev_base_lock);
965 rcu_read_lock(); 967 rcu_read_lock();
966 for_each_netdev(net, dev) { 968 for_each_netdev_rcu(net, dev) {
967 if ((in_dev = __in_dev_get_rcu(dev))) { 969 in_dev = __in_dev_get_rcu(dev);
970 if (in_dev) {
968 addr = confirm_addr_indev(in_dev, dst, local, scope); 971 addr = confirm_addr_indev(in_dev, dst, local, scope);
969 if (addr) 972 if (addr)
970 break; 973 break;
971 } 974 }
972 } 975 }
973 rcu_read_unlock(); 976 rcu_read_unlock();
974 read_unlock(&dev_base_lock);
975 977
976 return addr; 978 return addr;
977} 979}
@@ -984,14 +986,16 @@ int register_inetaddr_notifier(struct notifier_block *nb)
984{ 986{
985 return blocking_notifier_chain_register(&inetaddr_chain, nb); 987 return blocking_notifier_chain_register(&inetaddr_chain, nb);
986} 988}
989EXPORT_SYMBOL(register_inetaddr_notifier);
987 990
988int unregister_inetaddr_notifier(struct notifier_block *nb) 991int unregister_inetaddr_notifier(struct notifier_block *nb)
989{ 992{
990 return blocking_notifier_chain_unregister(&inetaddr_chain, nb); 993 return blocking_notifier_chain_unregister(&inetaddr_chain, nb);
991} 994}
995EXPORT_SYMBOL(unregister_inetaddr_notifier);
992 996
993/* Rename ifa_labels for a device name change. Make some effort to preserve existing 997/* Rename ifa_labels for a device name change. Make some effort to preserve
994 * alias numbering and to create unique labels if possible. 998 * existing alias numbering and to create unique labels if possible.
995*/ 999*/
996static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) 1000static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
997{ 1001{
@@ -1010,11 +1014,10 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
1010 sprintf(old, ":%d", named); 1014 sprintf(old, ":%d", named);
1011 dot = old; 1015 dot = old;
1012 } 1016 }
1013 if (strlen(dot) + strlen(dev->name) < IFNAMSIZ) { 1017 if (strlen(dot) + strlen(dev->name) < IFNAMSIZ)
1014 strcat(ifa->ifa_label, dot); 1018 strcat(ifa->ifa_label, dot);
1015 } else { 1019 else
1016 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); 1020 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot);
1017 }
1018skip: 1021skip:
1019 rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); 1022 rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
1020 } 1023 }
@@ -1061,8 +1064,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1061 if (!inetdev_valid_mtu(dev->mtu)) 1064 if (!inetdev_valid_mtu(dev->mtu))
1062 break; 1065 break;
1063 if (dev->flags & IFF_LOOPBACK) { 1066 if (dev->flags & IFF_LOOPBACK) {
1064 struct in_ifaddr *ifa; 1067 struct in_ifaddr *ifa = inet_alloc_ifa();
1065 if ((ifa = inet_alloc_ifa()) != NULL) { 1068
1069 if (ifa) {
1066 ifa->ifa_local = 1070 ifa->ifa_local =
1067 ifa->ifa_address = htonl(INADDR_LOOPBACK); 1071 ifa->ifa_address = htonl(INADDR_LOOPBACK);
1068 ifa->ifa_prefixlen = 8; 1072 ifa->ifa_prefixlen = 8;
@@ -1170,38 +1174,54 @@ nla_put_failure:
1170static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 1174static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1171{ 1175{
1172 struct net *net = sock_net(skb->sk); 1176 struct net *net = sock_net(skb->sk);
1173 int idx, ip_idx; 1177 int h, s_h;
1178 int idx, s_idx;
1179 int ip_idx, s_ip_idx;
1174 struct net_device *dev; 1180 struct net_device *dev;
1175 struct in_device *in_dev; 1181 struct in_device *in_dev;
1176 struct in_ifaddr *ifa; 1182 struct in_ifaddr *ifa;
1177 int s_ip_idx, s_idx = cb->args[0]; 1183 struct hlist_head *head;
1184 struct hlist_node *node;
1178 1185
1179 s_ip_idx = ip_idx = cb->args[1]; 1186 s_h = cb->args[0];
1180 idx = 0; 1187 s_idx = idx = cb->args[1];
1181 for_each_netdev(net, dev) { 1188 s_ip_idx = ip_idx = cb->args[2];
1182 if (idx < s_idx) 1189
1183 goto cont; 1190 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
1184 if (idx > s_idx) 1191 idx = 0;
1185 s_ip_idx = 0; 1192 head = &net->dev_index_head[h];
1186 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) 1193 rcu_read_lock();
1187 goto cont; 1194 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
1188 1195 if (idx < s_idx)
1189 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; 1196 goto cont;
1190 ifa = ifa->ifa_next, ip_idx++) { 1197 if (idx > s_idx)
1191 if (ip_idx < s_ip_idx) 1198 s_ip_idx = 0;
1192 continue; 1199 in_dev = __in_dev_get_rcu(dev);
1193 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, 1200 if (!in_dev)
1201 goto cont;
1202
1203 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1204 ifa = ifa->ifa_next, ip_idx++) {
1205 if (ip_idx < s_ip_idx)
1206 continue;
1207 if (inet_fill_ifaddr(skb, ifa,
1208 NETLINK_CB(cb->skb).pid,
1194 cb->nlh->nlmsg_seq, 1209 cb->nlh->nlmsg_seq,
1195 RTM_NEWADDR, NLM_F_MULTI) <= 0) 1210 RTM_NEWADDR, NLM_F_MULTI) <= 0) {
1196 goto done; 1211 rcu_read_unlock();
1197 } 1212 goto done;
1213 }
1214 }
1198cont: 1215cont:
1199 idx++; 1216 idx++;
1217 }
1218 rcu_read_unlock();
1200 } 1219 }
1201 1220
1202done: 1221done:
1203 cb->args[0] = idx; 1222 cb->args[0] = h;
1204 cb->args[1] = ip_idx; 1223 cb->args[1] = idx;
1224 cb->args[2] = ip_idx;
1205 1225
1206 return skb->len; 1226 return skb->len;
1207} 1227}
@@ -1239,18 +1259,18 @@ static void devinet_copy_dflt_conf(struct net *net, int i)
1239{ 1259{
1240 struct net_device *dev; 1260 struct net_device *dev;
1241 1261
1242 read_lock(&dev_base_lock); 1262 rcu_read_lock();
1243 for_each_netdev(net, dev) { 1263 for_each_netdev_rcu(net, dev) {
1244 struct in_device *in_dev; 1264 struct in_device *in_dev;
1245 rcu_read_lock(); 1265
1246 in_dev = __in_dev_get_rcu(dev); 1266 in_dev = __in_dev_get_rcu(dev);
1247 if (in_dev && !test_bit(i, in_dev->cnf.state)) 1267 if (in_dev && !test_bit(i, in_dev->cnf.state))
1248 in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i]; 1268 in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i];
1249 rcu_read_unlock();
1250 } 1269 }
1251 read_unlock(&dev_base_lock); 1270 rcu_read_unlock();
1252} 1271}
1253 1272
1273/* called with RTNL locked */
1254static void inet_forward_change(struct net *net) 1274static void inet_forward_change(struct net *net)
1255{ 1275{
1256 struct net_device *dev; 1276 struct net_device *dev;
@@ -1259,7 +1279,6 @@ static void inet_forward_change(struct net *net)
1259 IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on; 1279 IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
1260 IPV4_DEVCONF_DFLT(net, FORWARDING) = on; 1280 IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
1261 1281
1262 read_lock(&dev_base_lock);
1263 for_each_netdev(net, dev) { 1282 for_each_netdev(net, dev) {
1264 struct in_device *in_dev; 1283 struct in_device *in_dev;
1265 if (on) 1284 if (on)
@@ -1270,7 +1289,6 @@ static void inet_forward_change(struct net *net)
1270 IN_DEV_CONF_SET(in_dev, FORWARDING, on); 1289 IN_DEV_CONF_SET(in_dev, FORWARDING, on);
1271 rcu_read_unlock(); 1290 rcu_read_unlock();
1272 } 1291 }
1273 read_unlock(&dev_base_lock);
1274} 1292}
1275 1293
1276static int devinet_conf_proc(ctl_table *ctl, int write, 1294static int devinet_conf_proc(ctl_table *ctl, int write,
@@ -1293,58 +1311,6 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
1293 return ret; 1311 return ret;
1294} 1312}
1295 1313
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, 1314static int devinet_sysctl_forward(ctl_table *ctl, int write,
1349 void __user *buffer, 1315 void __user *buffer,
1350 size_t *lenp, loff_t *ppos) 1316 size_t *lenp, loff_t *ppos)
@@ -1390,47 +1356,28 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
1390 return ret; 1356 return ret;
1391} 1357}
1392 1358
1393int ipv4_doint_and_flush_strategy(ctl_table *table, 1359#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 { \ 1360 { \
1409 .ctl_name = NET_IPV4_CONF_ ## attr, \
1410 .procname = name, \ 1361 .procname = name, \
1411 .data = ipv4_devconf.data + \ 1362 .data = ipv4_devconf.data + \
1412 NET_IPV4_CONF_ ## attr - 1, \ 1363 NET_IPV4_CONF_ ## attr - 1, \
1413 .maxlen = sizeof(int), \ 1364 .maxlen = sizeof(int), \
1414 .mode = mval, \ 1365 .mode = mval, \
1415 .proc_handler = proc, \ 1366 .proc_handler = proc, \
1416 .strategy = sysctl, \
1417 .extra1 = &ipv4_devconf, \ 1367 .extra1 = &ipv4_devconf, \
1418 } 1368 }
1419 1369
1420#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \ 1370#define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
1421 DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \ 1371 DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc)
1422 devinet_conf_sysctl)
1423 1372
1424#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \ 1373#define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
1425 DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \ 1374 DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc)
1426 devinet_conf_sysctl)
1427 1375
1428#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \ 1376#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
1429 DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl) 1377 DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc)
1430 1378
1431#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \ 1379#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
1432 DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \ 1380 DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush)
1433 ipv4_doint_and_flush_strategy)
1434 1381
1435static struct devinet_sysctl_table { 1382static struct devinet_sysctl_table {
1436 struct ctl_table_header *sysctl_header; 1383 struct ctl_table_header *sysctl_header;
@@ -1439,8 +1386,7 @@ static struct devinet_sysctl_table {
1439} devinet_sysctl = { 1386} devinet_sysctl = {
1440 .devinet_vars = { 1387 .devinet_vars = {
1441 DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding", 1388 DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
1442 devinet_sysctl_forward, 1389 devinet_sysctl_forward),
1443 devinet_conf_sysctl),
1444 DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"), 1390 DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
1445 1391
1446 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"), 1392 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
@@ -1450,6 +1396,7 @@ static struct devinet_sysctl_table {
1450 DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"), 1396 DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
1451 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, 1397 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
1452 "accept_source_route"), 1398 "accept_source_route"),
1399 DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
1453 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), 1400 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
1454 DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), 1401 DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
1455 DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), 1402 DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
@@ -1471,7 +1418,7 @@ static struct devinet_sysctl_table {
1471}; 1418};
1472 1419
1473static int __devinet_sysctl_register(struct net *net, char *dev_name, 1420static int __devinet_sysctl_register(struct net *net, char *dev_name,
1474 int ctl_name, struct ipv4_devconf *p) 1421 struct ipv4_devconf *p)
1475{ 1422{
1476 int i; 1423 int i;
1477 struct devinet_sysctl_table *t; 1424 struct devinet_sysctl_table *t;
@@ -1479,9 +1426,9 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
1479#define DEVINET_CTL_PATH_DEV 3 1426#define DEVINET_CTL_PATH_DEV 3
1480 1427
1481 struct ctl_path devinet_ctl_path[] = { 1428 struct ctl_path devinet_ctl_path[] = {
1482 { .procname = "net", .ctl_name = CTL_NET, }, 1429 { .procname = "net", },
1483 { .procname = "ipv4", .ctl_name = NET_IPV4, }, 1430 { .procname = "ipv4", },
1484 { .procname = "conf", .ctl_name = NET_IPV4_CONF, }, 1431 { .procname = "conf", },
1485 { /* to be set */ }, 1432 { /* to be set */ },
1486 { }, 1433 { },
1487 }; 1434 };
@@ -1506,7 +1453,6 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
1506 goto free; 1453 goto free;
1507 1454
1508 devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name; 1455 devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name;
1509 devinet_ctl_path[DEVINET_CTL_PATH_DEV].ctl_name = ctl_name;
1510 1456
1511 t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path, 1457 t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path,
1512 t->devinet_vars); 1458 t->devinet_vars);
@@ -1540,9 +1486,9 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
1540static void devinet_sysctl_register(struct in_device *idev) 1486static void devinet_sysctl_register(struct in_device *idev)
1541{ 1487{
1542 neigh_sysctl_register(idev->dev, idev->arp_parms, NET_IPV4, 1488 neigh_sysctl_register(idev->dev, idev->arp_parms, NET_IPV4,
1543 NET_IPV4_NEIGH, "ipv4", NULL, NULL); 1489 NET_IPV4_NEIGH, "ipv4", NULL);
1544 __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, 1490 __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
1545 idev->dev->ifindex, &idev->cnf); 1491 &idev->cnf);
1546} 1492}
1547 1493
1548static void devinet_sysctl_unregister(struct in_device *idev) 1494static void devinet_sysctl_unregister(struct in_device *idev)
@@ -1553,14 +1499,12 @@ static void devinet_sysctl_unregister(struct in_device *idev)
1553 1499
1554static struct ctl_table ctl_forward_entry[] = { 1500static struct ctl_table ctl_forward_entry[] = {
1555 { 1501 {
1556 .ctl_name = NET_IPV4_FORWARD,
1557 .procname = "ip_forward", 1502 .procname = "ip_forward",
1558 .data = &ipv4_devconf.data[ 1503 .data = &ipv4_devconf.data[
1559 NET_IPV4_CONF_FORWARDING - 1], 1504 NET_IPV4_CONF_FORWARDING - 1],
1560 .maxlen = sizeof(int), 1505 .maxlen = sizeof(int),
1561 .mode = 0644, 1506 .mode = 0644,
1562 .proc_handler = devinet_sysctl_forward, 1507 .proc_handler = devinet_sysctl_forward,
1563 .strategy = devinet_conf_sysctl,
1564 .extra1 = &ipv4_devconf, 1508 .extra1 = &ipv4_devconf,
1565 .extra2 = &init_net, 1509 .extra2 = &init_net,
1566 }, 1510 },
@@ -1568,8 +1512,8 @@ static struct ctl_table ctl_forward_entry[] = {
1568}; 1512};
1569 1513
1570static __net_initdata struct ctl_path net_ipv4_path[] = { 1514static __net_initdata struct ctl_path net_ipv4_path[] = {
1571 { .procname = "net", .ctl_name = CTL_NET, }, 1515 { .procname = "net", },
1572 { .procname = "ipv4", .ctl_name = NET_IPV4, }, 1516 { .procname = "ipv4", },
1573 { }, 1517 { },
1574}; 1518};
1575#endif 1519#endif
@@ -1587,7 +1531,7 @@ static __net_init int devinet_init_net(struct net *net)
1587 all = &ipv4_devconf; 1531 all = &ipv4_devconf;
1588 dflt = &ipv4_devconf_dflt; 1532 dflt = &ipv4_devconf_dflt;
1589 1533
1590 if (net != &init_net) { 1534 if (!net_eq(net, &init_net)) {
1591 all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL); 1535 all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL);
1592 if (all == NULL) 1536 if (all == NULL)
1593 goto err_alloc_all; 1537 goto err_alloc_all;
@@ -1608,13 +1552,11 @@ static __net_init int devinet_init_net(struct net *net)
1608 } 1552 }
1609 1553
1610#ifdef CONFIG_SYSCTL 1554#ifdef CONFIG_SYSCTL
1611 err = __devinet_sysctl_register(net, "all", 1555 err = __devinet_sysctl_register(net, "all", all);
1612 NET_PROTO_CONF_ALL, all);
1613 if (err < 0) 1556 if (err < 0)
1614 goto err_reg_all; 1557 goto err_reg_all;
1615 1558
1616 err = __devinet_sysctl_register(net, "default", 1559 err = __devinet_sysctl_register(net, "default", dflt);
1617 NET_PROTO_CONF_DEFAULT, dflt);
1618 if (err < 0) 1560 if (err < 0)
1619 goto err_reg_dflt; 1561 goto err_reg_dflt;
1620 1562
@@ -1680,8 +1622,3 @@ void __init devinet_init(void)
1680 rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); 1622 rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr);
1681} 1623}
1682 1624
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);