diff options
author | Daniel Lezcano <dlezcano@fr.ibm.com> | 2008-03-04 16:47:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-03-04 16:47:47 -0500 |
commit | 5578689a4e3c04f2d43ea39736fd3fa396d80c6e (patch) | |
tree | 3fca397549e4b08bf71e07a14527dc2f793f15f9 | |
parent | 7b4da53229bb61469bdab321384b9a13406e3485 (diff) |
[NETNS][IPV6] route6 - make route6 per namespace
This patch makes the routing engine use the network namespaces to
access routing informations: Add a network namespace parameter to
ipv6_route_ioctl and propagate the network namespace value to all the
routing code that have not yet been changed.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/ip6_route.h | 4 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 3 | ||||
-rw-r--r-- | net/ipv6/route.c | 98 |
3 files changed, 54 insertions, 51 deletions
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 1444d358836d..2bcbfb826530 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h | |||
@@ -49,7 +49,9 @@ extern struct dst_entry * ip6_route_output(struct sock *sk, | |||
49 | extern int ip6_route_init(void); | 49 | extern int ip6_route_init(void); |
50 | extern void ip6_route_cleanup(void); | 50 | extern void ip6_route_cleanup(void); |
51 | 51 | ||
52 | extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg); | 52 | extern int ipv6_route_ioctl(struct net *net, |
53 | unsigned int cmd, | ||
54 | void __user *arg); | ||
53 | 55 | ||
54 | extern int ip6_route_add(struct fib6_config *cfg); | 56 | extern int ip6_route_add(struct fib6_config *cfg); |
55 | extern int ip6_ins_rt(struct rt6_info *); | 57 | extern int ip6_ins_rt(struct rt6_info *); |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 73021d5baece..60b8a2254046 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -440,6 +440,7 @@ EXPORT_SYMBOL(inet6_getname); | |||
440 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 440 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
441 | { | 441 | { |
442 | struct sock *sk = sock->sk; | 442 | struct sock *sk = sock->sk; |
443 | struct net *net = sk->sk_net; | ||
443 | 444 | ||
444 | switch(cmd) | 445 | switch(cmd) |
445 | { | 446 | { |
@@ -452,7 +453,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
452 | case SIOCADDRT: | 453 | case SIOCADDRT: |
453 | case SIOCDELRT: | 454 | case SIOCDELRT: |
454 | 455 | ||
455 | return(ipv6_route_ioctl(cmd,(void __user *)arg)); | 456 | return(ipv6_route_ioctl(net, cmd, (void __user *)arg)); |
456 | 457 | ||
457 | case SIOCSIFADDR: | 458 | case SIOCSIFADDR: |
458 | return addrconf_add_ifaddr((void __user *) arg); | 459 | return addrconf_add_ifaddr((void __user *) arg); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ad3d684e544a..b3ac4901af86 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -609,7 +609,7 @@ static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info) | |||
609 | int ip6_ins_rt(struct rt6_info *rt) | 609 | int ip6_ins_rt(struct rt6_info *rt) |
610 | { | 610 | { |
611 | struct nl_info info = { | 611 | struct nl_info info = { |
612 | .nl_net = &init_net, | 612 | .nl_net = rt->rt6i_dev->nd_net, |
613 | }; | 613 | }; |
614 | return __ip6_ins_rt(rt, &info); | 614 | return __ip6_ins_rt(rt, &info); |
615 | } | 615 | } |
@@ -746,6 +746,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, | |||
746 | void ip6_route_input(struct sk_buff *skb) | 746 | void ip6_route_input(struct sk_buff *skb) |
747 | { | 747 | { |
748 | struct ipv6hdr *iph = ipv6_hdr(skb); | 748 | struct ipv6hdr *iph = ipv6_hdr(skb); |
749 | struct net *net = skb->dev->nd_net; | ||
749 | int flags = RT6_LOOKUP_F_HAS_SADDR; | 750 | int flags = RT6_LOOKUP_F_HAS_SADDR; |
750 | struct flowi fl = { | 751 | struct flowi fl = { |
751 | .iif = skb->dev->ifindex, | 752 | .iif = skb->dev->ifindex, |
@@ -763,7 +764,7 @@ void ip6_route_input(struct sk_buff *skb) | |||
763 | if (rt6_need_strict(&iph->daddr)) | 764 | if (rt6_need_strict(&iph->daddr)) |
764 | flags |= RT6_LOOKUP_F_IFACE; | 765 | flags |= RT6_LOOKUP_F_IFACE; |
765 | 766 | ||
766 | skb->dst = fib6_rule_lookup(&init_net, &fl, flags, ip6_pol_route_input); | 767 | skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input); |
767 | } | 768 | } |
768 | 769 | ||
769 | static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, | 770 | static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, |
@@ -891,12 +892,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
891 | 892 | ||
892 | static int ipv6_get_mtu(struct net_device *dev); | 893 | static int ipv6_get_mtu(struct net_device *dev); |
893 | 894 | ||
894 | static inline unsigned int ipv6_advmss(unsigned int mtu) | 895 | static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu) |
895 | { | 896 | { |
896 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); | 897 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); |
897 | 898 | ||
898 | if (mtu < init_net.ipv6.sysctl.ip6_rt_min_advmss) | 899 | if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) |
899 | mtu = init_net.ipv6.sysctl.ip6_rt_min_advmss; | 900 | mtu = net->ipv6.sysctl.ip6_rt_min_advmss; |
900 | 901 | ||
901 | /* | 902 | /* |
902 | * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and | 903 | * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and |
@@ -918,6 +919,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
918 | { | 919 | { |
919 | struct rt6_info *rt; | 920 | struct rt6_info *rt; |
920 | struct inet6_dev *idev = in6_dev_get(dev); | 921 | struct inet6_dev *idev = in6_dev_get(dev); |
922 | struct net *net = dev->nd_net; | ||
921 | 923 | ||
922 | if (unlikely(idev == NULL)) | 924 | if (unlikely(idev == NULL)) |
923 | return NULL; | 925 | return NULL; |
@@ -940,7 +942,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
940 | atomic_set(&rt->u.dst.__refcnt, 1); | 942 | atomic_set(&rt->u.dst.__refcnt, 1); |
941 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255; | 943 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255; |
942 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); | 944 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); |
943 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); | 945 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); |
944 | rt->u.dst.output = ip6_output; | 946 | rt->u.dst.output = ip6_output; |
945 | 947 | ||
946 | #if 0 /* there's no chance to use these for ndisc */ | 948 | #if 0 /* there's no chance to use these for ndisc */ |
@@ -956,7 +958,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
956 | icmp6_dst_gc_list = &rt->u.dst; | 958 | icmp6_dst_gc_list = &rt->u.dst; |
957 | spin_unlock_bh(&icmp6_dst_lock); | 959 | spin_unlock_bh(&icmp6_dst_lock); |
958 | 960 | ||
959 | fib6_force_start_gc(dev->nd_net); | 961 | fib6_force_start_gc(net); |
960 | 962 | ||
961 | out: | 963 | out: |
962 | return &rt->u.dst; | 964 | return &rt->u.dst; |
@@ -1049,6 +1051,7 @@ int ipv6_get_hoplimit(struct net_device *dev) | |||
1049 | int ip6_route_add(struct fib6_config *cfg) | 1051 | int ip6_route_add(struct fib6_config *cfg) |
1050 | { | 1052 | { |
1051 | int err; | 1053 | int err; |
1054 | struct net *net = cfg->fc_nlinfo.nl_net; | ||
1052 | struct rt6_info *rt = NULL; | 1055 | struct rt6_info *rt = NULL; |
1053 | struct net_device *dev = NULL; | 1056 | struct net_device *dev = NULL; |
1054 | struct inet6_dev *idev = NULL; | 1057 | struct inet6_dev *idev = NULL; |
@@ -1063,7 +1066,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1063 | #endif | 1066 | #endif |
1064 | if (cfg->fc_ifindex) { | 1067 | if (cfg->fc_ifindex) { |
1065 | err = -ENODEV; | 1068 | err = -ENODEV; |
1066 | dev = dev_get_by_index(&init_net, cfg->fc_ifindex); | 1069 | dev = dev_get_by_index(net, cfg->fc_ifindex); |
1067 | if (!dev) | 1070 | if (!dev) |
1068 | goto out; | 1071 | goto out; |
1069 | idev = in6_dev_get(dev); | 1072 | idev = in6_dev_get(dev); |
@@ -1074,7 +1077,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1074 | if (cfg->fc_metric == 0) | 1077 | if (cfg->fc_metric == 0) |
1075 | cfg->fc_metric = IP6_RT_PRIO_USER; | 1078 | cfg->fc_metric = IP6_RT_PRIO_USER; |
1076 | 1079 | ||
1077 | table = fib6_new_table(&init_net, cfg->fc_table); | 1080 | table = fib6_new_table(net, cfg->fc_table); |
1078 | if (table == NULL) { | 1081 | if (table == NULL) { |
1079 | err = -ENOBUFS; | 1082 | err = -ENOBUFS; |
1080 | goto out; | 1083 | goto out; |
@@ -1121,12 +1124,12 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1121 | if ((cfg->fc_flags & RTF_REJECT) || | 1124 | if ((cfg->fc_flags & RTF_REJECT) || |
1122 | (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { | 1125 | (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { |
1123 | /* hold loopback dev/idev if we haven't done so. */ | 1126 | /* hold loopback dev/idev if we haven't done so. */ |
1124 | if (dev != init_net.loopback_dev) { | 1127 | if (dev != net->loopback_dev) { |
1125 | if (dev) { | 1128 | if (dev) { |
1126 | dev_put(dev); | 1129 | dev_put(dev); |
1127 | in6_dev_put(idev); | 1130 | in6_dev_put(idev); |
1128 | } | 1131 | } |
1129 | dev = init_net.loopback_dev; | 1132 | dev = net->loopback_dev; |
1130 | dev_hold(dev); | 1133 | dev_hold(dev); |
1131 | idev = in6_dev_get(dev); | 1134 | idev = in6_dev_get(dev); |
1132 | if (!idev) { | 1135 | if (!idev) { |
@@ -1163,7 +1166,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1163 | if (!(gwa_type&IPV6_ADDR_UNICAST)) | 1166 | if (!(gwa_type&IPV6_ADDR_UNICAST)) |
1164 | goto out; | 1167 | goto out; |
1165 | 1168 | ||
1166 | grt = rt6_lookup(&init_net, gw_addr, NULL, cfg->fc_ifindex, 1); | 1169 | grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); |
1167 | 1170 | ||
1168 | err = -EHOSTUNREACH; | 1171 | err = -EHOSTUNREACH; |
1169 | if (grt == NULL) | 1172 | if (grt == NULL) |
@@ -1230,7 +1233,7 @@ install_route: | |||
1230 | if (!rt->u.dst.metrics[RTAX_MTU-1]) | 1233 | if (!rt->u.dst.metrics[RTAX_MTU-1]) |
1231 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); | 1234 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); |
1232 | if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) | 1235 | if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) |
1233 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); | 1236 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); |
1234 | rt->u.dst.dev = dev; | 1237 | rt->u.dst.dev = dev; |
1235 | rt->rt6i_idev = idev; | 1238 | rt->rt6i_idev = idev; |
1236 | rt->rt6i_table = table; | 1239 | rt->rt6i_table = table; |
@@ -1271,7 +1274,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) | |||
1271 | int ip6_del_rt(struct rt6_info *rt) | 1274 | int ip6_del_rt(struct rt6_info *rt) |
1272 | { | 1275 | { |
1273 | struct nl_info info = { | 1276 | struct nl_info info = { |
1274 | .nl_net = &init_net, | 1277 | .nl_net = rt->rt6i_dev->nd_net, |
1275 | }; | 1278 | }; |
1276 | return __ip6_del_rt(rt, &info); | 1279 | return __ip6_del_rt(rt, &info); |
1277 | } | 1280 | } |
@@ -1283,7 +1286,7 @@ static int ip6_route_del(struct fib6_config *cfg) | |||
1283 | struct rt6_info *rt; | 1286 | struct rt6_info *rt; |
1284 | int err = -ESRCH; | 1287 | int err = -ESRCH; |
1285 | 1288 | ||
1286 | table = fib6_get_table(&init_net, cfg->fc_table); | 1289 | table = fib6_get_table(cfg->fc_nlinfo.nl_net, cfg->fc_table); |
1287 | if (table == NULL) | 1290 | if (table == NULL) |
1288 | return err; | 1291 | return err; |
1289 | 1292 | ||
@@ -1382,6 +1385,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, | |||
1382 | struct net_device *dev) | 1385 | struct net_device *dev) |
1383 | { | 1386 | { |
1384 | int flags = RT6_LOOKUP_F_HAS_SADDR; | 1387 | int flags = RT6_LOOKUP_F_HAS_SADDR; |
1388 | struct net *net = dev->nd_net; | ||
1385 | struct ip6rd_flowi rdfl = { | 1389 | struct ip6rd_flowi rdfl = { |
1386 | .fl = { | 1390 | .fl = { |
1387 | .oif = dev->ifindex, | 1391 | .oif = dev->ifindex, |
@@ -1398,8 +1402,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, | |||
1398 | if (rt6_need_strict(dest)) | 1402 | if (rt6_need_strict(dest)) |
1399 | flags |= RT6_LOOKUP_F_IFACE; | 1403 | flags |= RT6_LOOKUP_F_IFACE; |
1400 | 1404 | ||
1401 | return (struct rt6_info *)fib6_rule_lookup(&init_net, | 1405 | return (struct rt6_info *)fib6_rule_lookup(net, (struct flowi *)&rdfl, |
1402 | (struct flowi *)&rdfl, | ||
1403 | flags, __ip6_route_redirect); | 1406 | flags, __ip6_route_redirect); |
1404 | } | 1407 | } |
1405 | 1408 | ||
@@ -1457,7 +1460,8 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, | |||
1457 | nrt->rt6i_nexthop = neigh_clone(neigh); | 1460 | nrt->rt6i_nexthop = neigh_clone(neigh); |
1458 | /* Reset pmtu, it may be better */ | 1461 | /* Reset pmtu, it may be better */ |
1459 | nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); | 1462 | nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); |
1460 | nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst)); | 1463 | nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(neigh->dev->nd_net, |
1464 | dst_mtu(&nrt->u.dst)); | ||
1461 | 1465 | ||
1462 | if (ip6_ins_rt(nrt)) | 1466 | if (ip6_ins_rt(nrt)) |
1463 | goto out; | 1467 | goto out; |
@@ -1485,9 +1489,10 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, | |||
1485 | struct net_device *dev, u32 pmtu) | 1489 | struct net_device *dev, u32 pmtu) |
1486 | { | 1490 | { |
1487 | struct rt6_info *rt, *nrt; | 1491 | struct rt6_info *rt, *nrt; |
1492 | struct net *net = dev->nd_net; | ||
1488 | int allfrag = 0; | 1493 | int allfrag = 0; |
1489 | 1494 | ||
1490 | rt = rt6_lookup(dev->nd_net, daddr, saddr, dev->ifindex, 0); | 1495 | rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0); |
1491 | if (rt == NULL) | 1496 | if (rt == NULL) |
1492 | return; | 1497 | return; |
1493 | 1498 | ||
@@ -1520,7 +1525,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, | |||
1520 | rt->u.dst.metrics[RTAX_MTU-1] = pmtu; | 1525 | rt->u.dst.metrics[RTAX_MTU-1] = pmtu; |
1521 | if (allfrag) | 1526 | if (allfrag) |
1522 | rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; | 1527 | rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; |
1523 | dst_set_expires(&rt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires); | 1528 | dst_set_expires(&rt->u.dst, net->ipv6.sysctl.ip6_rt_mtu_expires); |
1524 | rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; | 1529 | rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; |
1525 | goto out; | 1530 | goto out; |
1526 | } | 1531 | } |
@@ -1546,7 +1551,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, | |||
1546 | * which is 10 mins. After 10 mins the decreased pmtu is expired | 1551 | * which is 10 mins. After 10 mins the decreased pmtu is expired |
1547 | * and detecting PMTU increase will be automatically happened. | 1552 | * and detecting PMTU increase will be automatically happened. |
1548 | */ | 1553 | */ |
1549 | dst_set_expires(&nrt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires); | 1554 | dst_set_expires(&nrt->u.dst, net->ipv6.sysctl.ip6_rt_mtu_expires); |
1550 | nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; | 1555 | nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; |
1551 | 1556 | ||
1552 | ip6_ins_rt(nrt); | 1557 | ip6_ins_rt(nrt); |
@@ -1659,7 +1664,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d | |||
1659 | struct rt6_info *rt; | 1664 | struct rt6_info *rt; |
1660 | struct fib6_table *table; | 1665 | struct fib6_table *table; |
1661 | 1666 | ||
1662 | table = fib6_get_table(&init_net, RT6_TABLE_DFLT); | 1667 | table = fib6_get_table(dev->nd_net, RT6_TABLE_DFLT); |
1663 | if (table == NULL) | 1668 | if (table == NULL) |
1664 | return NULL; | 1669 | return NULL; |
1665 | 1670 | ||
@@ -1688,6 +1693,9 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr, | |||
1688 | .fc_ifindex = dev->ifindex, | 1693 | .fc_ifindex = dev->ifindex, |
1689 | .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | | 1694 | .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | |
1690 | RTF_UP | RTF_EXPIRES | RTF_PREF(pref), | 1695 | RTF_UP | RTF_EXPIRES | RTF_PREF(pref), |
1696 | .fc_nlinfo.pid = 0, | ||
1697 | .fc_nlinfo.nlh = NULL, | ||
1698 | .fc_nlinfo.nl_net = dev->nd_net, | ||
1691 | }; | 1699 | }; |
1692 | 1700 | ||
1693 | ipv6_addr_copy(&cfg.fc_gateway, gwaddr); | 1701 | ipv6_addr_copy(&cfg.fc_gateway, gwaddr); |
@@ -1720,7 +1728,8 @@ restart: | |||
1720 | read_unlock_bh(&table->tb6_lock); | 1728 | read_unlock_bh(&table->tb6_lock); |
1721 | } | 1729 | } |
1722 | 1730 | ||
1723 | static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg, | 1731 | static void rtmsg_to_fib6_config(struct net *net, |
1732 | struct in6_rtmsg *rtmsg, | ||
1724 | struct fib6_config *cfg) | 1733 | struct fib6_config *cfg) |
1725 | { | 1734 | { |
1726 | memset(cfg, 0, sizeof(*cfg)); | 1735 | memset(cfg, 0, sizeof(*cfg)); |
@@ -1733,14 +1742,14 @@ static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg, | |||
1733 | cfg->fc_src_len = rtmsg->rtmsg_src_len; | 1742 | cfg->fc_src_len = rtmsg->rtmsg_src_len; |
1734 | cfg->fc_flags = rtmsg->rtmsg_flags; | 1743 | cfg->fc_flags = rtmsg->rtmsg_flags; |
1735 | 1744 | ||
1736 | cfg->fc_nlinfo.nl_net = &init_net; | 1745 | cfg->fc_nlinfo.nl_net = net; |
1737 | 1746 | ||
1738 | ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst); | 1747 | ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst); |
1739 | ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src); | 1748 | ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src); |
1740 | ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway); | 1749 | ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway); |
1741 | } | 1750 | } |
1742 | 1751 | ||
1743 | int ipv6_route_ioctl(unsigned int cmd, void __user *arg) | 1752 | int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg) |
1744 | { | 1753 | { |
1745 | struct fib6_config cfg; | 1754 | struct fib6_config cfg; |
1746 | struct in6_rtmsg rtmsg; | 1755 | struct in6_rtmsg rtmsg; |
@@ -1756,7 +1765,7 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) | |||
1756 | if (err) | 1765 | if (err) |
1757 | return -EFAULT; | 1766 | return -EFAULT; |
1758 | 1767 | ||
1759 | rtmsg_to_fib6_config(&rtmsg, &cfg); | 1768 | rtmsg_to_fib6_config(net, &rtmsg, &cfg); |
1760 | 1769 | ||
1761 | rtnl_lock(); | 1770 | rtnl_lock(); |
1762 | switch (cmd) { | 1771 | switch (cmd) { |
@@ -1835,21 +1844,22 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1835 | const struct in6_addr *addr, | 1844 | const struct in6_addr *addr, |
1836 | int anycast) | 1845 | int anycast) |
1837 | { | 1846 | { |
1847 | struct net *net = idev->dev->nd_net; | ||
1838 | struct rt6_info *rt = ip6_dst_alloc(); | 1848 | struct rt6_info *rt = ip6_dst_alloc(); |
1839 | 1849 | ||
1840 | if (rt == NULL) | 1850 | if (rt == NULL) |
1841 | return ERR_PTR(-ENOMEM); | 1851 | return ERR_PTR(-ENOMEM); |
1842 | 1852 | ||
1843 | dev_hold(init_net.loopback_dev); | 1853 | dev_hold(net->loopback_dev); |
1844 | in6_dev_hold(idev); | 1854 | in6_dev_hold(idev); |
1845 | 1855 | ||
1846 | rt->u.dst.flags = DST_HOST; | 1856 | rt->u.dst.flags = DST_HOST; |
1847 | rt->u.dst.input = ip6_input; | 1857 | rt->u.dst.input = ip6_input; |
1848 | rt->u.dst.output = ip6_output; | 1858 | rt->u.dst.output = ip6_output; |
1849 | rt->rt6i_dev = init_net.loopback_dev; | 1859 | rt->rt6i_dev = net->loopback_dev; |
1850 | rt->rt6i_idev = idev; | 1860 | rt->rt6i_idev = idev; |
1851 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); | 1861 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); |
1852 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); | 1862 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); |
1853 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; | 1863 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; |
1854 | rt->u.dst.obsolete = -1; | 1864 | rt->u.dst.obsolete = -1; |
1855 | 1865 | ||
@@ -1866,7 +1876,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1866 | 1876 | ||
1867 | ipv6_addr_copy(&rt->rt6i_dst.addr, addr); | 1877 | ipv6_addr_copy(&rt->rt6i_dst.addr, addr); |
1868 | rt->rt6i_dst.plen = 128; | 1878 | rt->rt6i_dst.plen = 128; |
1869 | rt->rt6i_table = fib6_get_table(&init_net, RT6_TABLE_LOCAL); | 1879 | rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL); |
1870 | 1880 | ||
1871 | atomic_set(&rt->u.dst.__refcnt, 1); | 1881 | atomic_set(&rt->u.dst.__refcnt, 1); |
1872 | 1882 | ||
@@ -1898,6 +1908,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) | |||
1898 | { | 1908 | { |
1899 | struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; | 1909 | struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; |
1900 | struct inet6_dev *idev; | 1910 | struct inet6_dev *idev; |
1911 | struct net *net = arg->dev->nd_net; | ||
1901 | 1912 | ||
1902 | /* In IPv6 pmtu discovery is not optional, | 1913 | /* In IPv6 pmtu discovery is not optional, |
1903 | so that RTAX_MTU lock cannot disable it. | 1914 | so that RTAX_MTU lock cannot disable it. |
@@ -1929,7 +1940,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) | |||
1929 | (dst_mtu(&rt->u.dst) < arg->mtu && | 1940 | (dst_mtu(&rt->u.dst) < arg->mtu && |
1930 | dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) { | 1941 | dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) { |
1931 | rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu; | 1942 | rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu; |
1932 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(arg->mtu); | 1943 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, arg->mtu); |
1933 | } | 1944 | } |
1934 | return 0; | 1945 | return 0; |
1935 | } | 1946 | } |
@@ -2024,13 +2035,9 @@ errout: | |||
2024 | 2035 | ||
2025 | static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2036 | static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
2026 | { | 2037 | { |
2027 | struct net *net = skb->sk->sk_net; | ||
2028 | struct fib6_config cfg; | 2038 | struct fib6_config cfg; |
2029 | int err; | 2039 | int err; |
2030 | 2040 | ||
2031 | if (net != &init_net) | ||
2032 | return -EINVAL; | ||
2033 | |||
2034 | err = rtm_to_fib6_config(skb, nlh, &cfg); | 2041 | err = rtm_to_fib6_config(skb, nlh, &cfg); |
2035 | if (err < 0) | 2042 | if (err < 0) |
2036 | return err; | 2043 | return err; |
@@ -2040,13 +2047,9 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a | |||
2040 | 2047 | ||
2041 | static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2048 | static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
2042 | { | 2049 | { |
2043 | struct net *net = skb->sk->sk_net; | ||
2044 | struct fib6_config cfg; | 2050 | struct fib6_config cfg; |
2045 | int err; | 2051 | int err; |
2046 | 2052 | ||
2047 | if (net != &init_net) | ||
2048 | return -EINVAL; | ||
2049 | |||
2050 | err = rtm_to_fib6_config(skb, nlh, &cfg); | 2053 | err = rtm_to_fib6_config(skb, nlh, &cfg); |
2051 | if (err < 0) | 2054 | if (err < 0) |
2052 | return err; | 2055 | return err; |
@@ -2190,9 +2193,6 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2190 | struct flowi fl; | 2193 | struct flowi fl; |
2191 | int err, iif = 0; | 2194 | int err, iif = 0; |
2192 | 2195 | ||
2193 | if (net != &init_net) | ||
2194 | return -EINVAL; | ||
2195 | |||
2196 | err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); | 2196 | err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); |
2197 | if (err < 0) | 2197 | if (err < 0) |
2198 | goto errout; | 2198 | goto errout; |
@@ -2222,7 +2222,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2222 | 2222 | ||
2223 | if (iif) { | 2223 | if (iif) { |
2224 | struct net_device *dev; | 2224 | struct net_device *dev; |
2225 | dev = __dev_get_by_index(&init_net, iif); | 2225 | dev = __dev_get_by_index(net, iif); |
2226 | if (!dev) { | 2226 | if (!dev) { |
2227 | err = -ENODEV; | 2227 | err = -ENODEV; |
2228 | goto errout; | 2228 | goto errout; |
@@ -2252,7 +2252,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2252 | goto errout; | 2252 | goto errout; |
2253 | } | 2253 | } |
2254 | 2254 | ||
2255 | err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); | 2255 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); |
2256 | errout: | 2256 | errout: |
2257 | return err; | 2257 | return err; |
2258 | } | 2258 | } |
@@ -2260,6 +2260,7 @@ errout: | |||
2260 | void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | 2260 | void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) |
2261 | { | 2261 | { |
2262 | struct sk_buff *skb; | 2262 | struct sk_buff *skb; |
2263 | struct net *net = info->nl_net; | ||
2263 | u32 seq; | 2264 | u32 seq; |
2264 | int err; | 2265 | int err; |
2265 | 2266 | ||
@@ -2278,11 +2279,11 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
2278 | kfree_skb(skb); | 2279 | kfree_skb(skb); |
2279 | goto errout; | 2280 | goto errout; |
2280 | } | 2281 | } |
2281 | err = rtnl_notify(skb, &init_net, info->pid, | 2282 | err = rtnl_notify(skb, net, info->pid, RTNLGRP_IPV6_ROUTE, |
2282 | RTNLGRP_IPV6_ROUTE, info->nlh, gfp_any()); | 2283 | info->nlh, gfp_any()); |
2283 | errout: | 2284 | errout: |
2284 | if (err < 0) | 2285 | if (err < 0) |
2285 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_ROUTE, err); | 2286 | rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err); |
2286 | } | 2287 | } |
2287 | 2288 | ||
2288 | /* | 2289 | /* |
@@ -2544,6 +2545,7 @@ static void ip6_route_net_exit(struct net *net) | |||
2544 | proc_net_remove(net, "ipv6_route"); | 2545 | proc_net_remove(net, "ipv6_route"); |
2545 | proc_net_remove(net, "rt6_stats"); | 2546 | proc_net_remove(net, "rt6_stats"); |
2546 | #endif | 2547 | #endif |
2548 | rt6_ifdown(net, NULL); | ||
2547 | } | 2549 | } |
2548 | 2550 | ||
2549 | static struct pernet_operations ip6_route_net_ops = { | 2551 | static struct pernet_operations ip6_route_net_ops = { |
@@ -2592,7 +2594,6 @@ fib6_rules_init: | |||
2592 | xfrm6_init: | 2594 | xfrm6_init: |
2593 | xfrm6_fini(); | 2595 | xfrm6_fini(); |
2594 | out_fib6_init: | 2596 | out_fib6_init: |
2595 | rt6_ifdown(&init_net, NULL); | ||
2596 | fib6_gc_cleanup(); | 2597 | fib6_gc_cleanup(); |
2597 | out_kmem_cache: | 2598 | out_kmem_cache: |
2598 | kmem_cache_destroy(ip6_dst_ops.kmem_cachep); | 2599 | kmem_cache_destroy(ip6_dst_ops.kmem_cachep); |
@@ -2604,7 +2605,6 @@ void ip6_route_cleanup(void) | |||
2604 | unregister_pernet_subsys(&ip6_route_net_ops); | 2605 | unregister_pernet_subsys(&ip6_route_net_ops); |
2605 | fib6_rules_cleanup(); | 2606 | fib6_rules_cleanup(); |
2606 | xfrm6_fini(); | 2607 | xfrm6_fini(); |
2607 | rt6_ifdown(&init_net, NULL); | ||
2608 | fib6_gc_cleanup(); | 2608 | fib6_gc_cleanup(); |
2609 | kmem_cache_destroy(ip6_dst_ops.kmem_cachep); | 2609 | kmem_cache_destroy(ip6_dst_ops.kmem_cachep); |
2610 | } | 2610 | } |