aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-03-04 16:47:47 -0500
committerDavid S. Miller <davem@davemloft.net>2008-03-04 16:47:47 -0500
commit5578689a4e3c04f2d43ea39736fd3fa396d80c6e (patch)
tree3fca397549e4b08bf71e07a14527dc2f793f15f9 /net/ipv6/route.c
parent7b4da53229bb61469bdab321384b9a13406e3485 (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>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c98
1 files changed, 49 insertions, 49 deletions
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)
609int ip6_ins_rt(struct rt6_info *rt) 609int 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,
746void ip6_route_input(struct sk_buff *skb) 746void 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
769static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, 770static 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
892static int ipv6_get_mtu(struct net_device *dev); 893static int ipv6_get_mtu(struct net_device *dev);
893 894
894static inline unsigned int ipv6_advmss(unsigned int mtu) 895static 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
961out: 963out:
962 return &rt->u.dst; 964 return &rt->u.dst;
@@ -1049,6 +1051,7 @@ int ipv6_get_hoplimit(struct net_device *dev)
1049int ip6_route_add(struct fib6_config *cfg) 1051int 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)
1271int ip6_del_rt(struct rt6_info *rt) 1274int 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
1723static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg, 1731static 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
1743int ipv6_route_ioctl(unsigned int cmd, void __user *arg) 1752int 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
2025static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2036static 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
2041static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2048static 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);
2256errout: 2256errout:
2257 return err; 2257 return err;
2258} 2258}
@@ -2260,6 +2260,7 @@ errout:
2260void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) 2260void 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());
2283errout: 2284errout:
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
2549static struct pernet_operations ip6_route_net_ops = { 2551static struct pernet_operations ip6_route_net_ops = {
@@ -2592,7 +2594,6 @@ fib6_rules_init:
2592xfrm6_init: 2594xfrm6_init:
2593 xfrm6_fini(); 2595 xfrm6_fini();
2594out_fib6_init: 2596out_fib6_init:
2595 rt6_ifdown(&init_net, NULL);
2596 fib6_gc_cleanup(); 2597 fib6_gc_cleanup();
2597out_kmem_cache: 2598out_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}