提交 afb1d4b5 编写于 作者: D David Ahern 提交者: David S. Miller

net/ipv6: Pass net namespace to route functions

Pass network namespace reference into route add, delete and get
functions.
Signed-off-by: NDavid Ahern <dsahern@gmail.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 7aef6859
...@@ -101,8 +101,8 @@ void ip6_route_cleanup(void); ...@@ -101,8 +101,8 @@ void ip6_route_cleanup(void);
int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg); int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg);
int ip6_route_add(struct fib6_config *cfg, struct netlink_ext_ack *extack); int ip6_route_add(struct fib6_config *cfg, struct netlink_ext_ack *extack);
int ip6_ins_rt(struct rt6_info *); int ip6_ins_rt(struct net *net, struct rt6_info *rt);
int ip6_del_rt(struct rt6_info *); int ip6_del_rt(struct net *net, struct rt6_info *rt);
void rt6_flush_exceptions(struct rt6_info *rt); void rt6_flush_exceptions(struct rt6_info *rt);
int rt6_remove_exception_rt(struct rt6_info *rt); int rt6_remove_exception_rt(struct rt6_info *rt);
...@@ -137,7 +137,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6); ...@@ -137,7 +137,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6);
void fib6_force_start_gc(struct net *net); void fib6_force_start_gc(struct net *net);
struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, struct rt6_info *addrconf_dst_alloc(struct net *net, struct inet6_dev *idev,
const struct in6_addr *addr, bool anycast); const struct in6_addr *addr, bool anycast);
struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev, struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev,
...@@ -147,9 +147,11 @@ struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev, ...@@ -147,9 +147,11 @@ struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev,
* support functions for ND * support functions for ND
* *
*/ */
struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct rt6_info *rt6_get_dflt_router(struct net *net,
const struct in6_addr *addr,
struct net_device *dev); struct net_device *dev);
struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, struct rt6_info *rt6_add_dflt_router(struct net *net,
const struct in6_addr *gwaddr,
struct net_device *dev, unsigned int pref); struct net_device *dev, unsigned int pref);
void rt6_purge_dflt_routers(struct net *net); void rt6_purge_dflt_routers(struct net *net);
......
...@@ -1037,7 +1037,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, ...@@ -1037,7 +1037,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
goto out; goto out;
} }
rt = addrconf_dst_alloc(idev, addr, false); rt = addrconf_dst_alloc(net, idev, addr, false);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
err = PTR_ERR(rt); err = PTR_ERR(rt);
rt = NULL; rt = NULL;
...@@ -1187,7 +1187,7 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_r ...@@ -1187,7 +1187,7 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_r
0, RTF_GATEWAY | RTF_DEFAULT); 0, RTF_GATEWAY | RTF_DEFAULT);
if (rt) { if (rt) {
if (del_rt) if (del_rt)
ip6_del_rt(rt); ip6_del_rt(dev_net(ifp->idev->dev), rt);
else { else {
if (!(rt->rt6i_flags & RTF_EXPIRES)) if (!(rt->rt6i_flags & RTF_EXPIRES))
rt6_set_expires(rt, expires); rt6_set_expires(rt, expires);
...@@ -2666,7 +2666,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) ...@@ -2666,7 +2666,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
if (rt) { if (rt) {
/* Autoconf prefix route */ /* Autoconf prefix route */
if (valid_lft == 0) { if (valid_lft == 0) {
ip6_del_rt(rt); ip6_del_rt(net, rt);
rt = NULL; rt = NULL;
} else if (addrconf_finite_timeout(rt_expires)) { } else if (addrconf_finite_timeout(rt_expires)) {
/* not infinity */ /* not infinity */
...@@ -3333,7 +3333,8 @@ static void addrconf_gre_config(struct net_device *dev) ...@@ -3333,7 +3333,8 @@ static void addrconf_gre_config(struct net_device *dev)
} }
#endif #endif
static int fixup_permanent_addr(struct inet6_dev *idev, static int fixup_permanent_addr(struct net *net,
struct inet6_dev *idev,
struct inet6_ifaddr *ifp) struct inet6_ifaddr *ifp)
{ {
/* !rt6i_node means the host route was removed from the /* !rt6i_node means the host route was removed from the
...@@ -3343,7 +3344,7 @@ static int fixup_permanent_addr(struct inet6_dev *idev, ...@@ -3343,7 +3344,7 @@ static int fixup_permanent_addr(struct inet6_dev *idev,
if (!ifp->rt || !ifp->rt->rt6i_node) { if (!ifp->rt || !ifp->rt->rt6i_node) {
struct rt6_info *rt, *prev; struct rt6_info *rt, *prev;
rt = addrconf_dst_alloc(idev, &ifp->addr, false); rt = addrconf_dst_alloc(net, idev, &ifp->addr, false);
if (IS_ERR(rt)) if (IS_ERR(rt))
return PTR_ERR(rt); return PTR_ERR(rt);
...@@ -3367,7 +3368,7 @@ static int fixup_permanent_addr(struct inet6_dev *idev, ...@@ -3367,7 +3368,7 @@ static int fixup_permanent_addr(struct inet6_dev *idev,
return 0; return 0;
} }
static void addrconf_permanent_addr(struct net_device *dev) static void addrconf_permanent_addr(struct net *net, struct net_device *dev)
{ {
struct inet6_ifaddr *ifp, *tmp; struct inet6_ifaddr *ifp, *tmp;
struct inet6_dev *idev; struct inet6_dev *idev;
...@@ -3380,7 +3381,7 @@ static void addrconf_permanent_addr(struct net_device *dev) ...@@ -3380,7 +3381,7 @@ static void addrconf_permanent_addr(struct net_device *dev)
list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) { list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) {
if ((ifp->flags & IFA_F_PERMANENT) && if ((ifp->flags & IFA_F_PERMANENT) &&
fixup_permanent_addr(idev, ifp) < 0) { fixup_permanent_addr(net, idev, ifp) < 0) {
write_unlock_bh(&idev->lock); write_unlock_bh(&idev->lock);
in6_ifa_hold(ifp); in6_ifa_hold(ifp);
ipv6_del_addr(ifp); ipv6_del_addr(ifp);
...@@ -3449,7 +3450,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, ...@@ -3449,7 +3450,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
if (event == NETDEV_UP) { if (event == NETDEV_UP) {
/* restore routes for permanent addresses */ /* restore routes for permanent addresses */
addrconf_permanent_addr(dev); addrconf_permanent_addr(net, dev);
if (!addrconf_link_ready(dev)) { if (!addrconf_link_ready(dev)) {
/* device is not ready yet. */ /* device is not ready yet. */
...@@ -3735,7 +3736,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) ...@@ -3735,7 +3736,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
spin_unlock_bh(&ifa->lock); spin_unlock_bh(&ifa->lock);
if (rt) if (rt)
ip6_del_rt(rt); ip6_del_rt(net, rt);
if (state != INET6_IFADDR_STATE_DEAD) { if (state != INET6_IFADDR_STATE_DEAD) {
__ipv6_ifa_notify(RTM_DELADDR, ifa); __ipv6_ifa_notify(RTM_DELADDR, ifa);
...@@ -3853,6 +3854,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) ...@@ -3853,6 +3854,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
struct inet6_dev *idev = ifp->idev; struct inet6_dev *idev = ifp->idev;
struct net_device *dev = idev->dev; struct net_device *dev = idev->dev;
bool bump_id, notify = false; bool bump_id, notify = false;
struct net *net;
addrconf_join_solict(dev, &ifp->addr); addrconf_join_solict(dev, &ifp->addr);
...@@ -3863,8 +3865,9 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) ...@@ -3863,8 +3865,9 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
if (ifp->state == INET6_IFADDR_STATE_DEAD) if (ifp->state == INET6_IFADDR_STATE_DEAD)
goto out; goto out;
net = dev_net(dev);
if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
(dev_net(dev)->ipv6.devconf_all->accept_dad < 1 && (net->ipv6.devconf_all->accept_dad < 1 &&
idev->cnf.accept_dad < 1) || idev->cnf.accept_dad < 1) ||
!(ifp->flags&IFA_F_TENTATIVE) || !(ifp->flags&IFA_F_TENTATIVE) ||
ifp->flags & IFA_F_NODAD) { ifp->flags & IFA_F_NODAD) {
...@@ -3900,8 +3903,8 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) ...@@ -3900,8 +3903,8 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
* Frames right away * Frames right away
*/ */
if (ifp->flags & IFA_F_OPTIMISTIC) { if (ifp->flags & IFA_F_OPTIMISTIC) {
ip6_ins_rt(ifp->rt); ip6_ins_rt(net, ifp->rt);
if (ipv6_use_optimistic_addr(dev_net(dev), idev)) { if (ipv6_use_optimistic_addr(net, idev)) {
/* Because optimistic nodes can use this address, /* Because optimistic nodes can use this address,
* notify listeners. If DAD fails, RTM_DELADDR is sent. * notify listeners. If DAD fails, RTM_DELADDR is sent.
*/ */
...@@ -5604,7 +5607,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) ...@@ -5604,7 +5607,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
* to do it again * to do it again
*/ */
if (!rcu_access_pointer(ifp->rt->rt6i_node)) if (!rcu_access_pointer(ifp->rt->rt6i_node))
ip6_ins_rt(ifp->rt); ip6_ins_rt(net, ifp->rt);
if (ifp->idev->cnf.forwarding) if (ifp->idev->cnf.forwarding)
addrconf_join_anycast(ifp); addrconf_join_anycast(ifp);
if (!ipv6_addr_any(&ifp->peer_addr)) if (!ipv6_addr_any(&ifp->peer_addr))
...@@ -5621,11 +5624,11 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) ...@@ -5621,11 +5624,11 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
rt = addrconf_get_prefix_route(&ifp->peer_addr, 128, rt = addrconf_get_prefix_route(&ifp->peer_addr, 128,
ifp->idev->dev, 0, 0); ifp->idev->dev, 0, 0);
if (rt) if (rt)
ip6_del_rt(rt); ip6_del_rt(net, rt);
} }
if (ifp->rt) { if (ifp->rt) {
if (dst_hold_safe(&ifp->rt->dst)) if (dst_hold_safe(&ifp->rt->dst))
ip6_del_rt(ifp->rt); ip6_del_rt(net, ifp->rt);
} }
rt_genid_bump_ipv6(net); rt_genid_bump_ipv6(net);
break; break;
......
...@@ -247,6 +247,7 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr) ...@@ -247,6 +247,7 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)
{ {
struct ifacaddr6 *aca; struct ifacaddr6 *aca;
struct rt6_info *rt; struct rt6_info *rt;
struct net *net;
int err; int err;
ASSERT_RTNL(); ASSERT_RTNL();
...@@ -265,7 +266,8 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr) ...@@ -265,7 +266,8 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)
} }
} }
rt = addrconf_dst_alloc(idev, addr, true); net = dev_net(idev->dev);
rt = addrconf_dst_alloc(net, idev, addr, true);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
err = PTR_ERR(rt); err = PTR_ERR(rt);
goto out; goto out;
...@@ -286,7 +288,7 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr) ...@@ -286,7 +288,7 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)
aca_get(aca); aca_get(aca);
write_unlock_bh(&idev->lock); write_unlock_bh(&idev->lock);
ip6_ins_rt(rt); ip6_ins_rt(net, rt);
addrconf_join_solict(idev->dev, &aca->aca_addr); addrconf_join_solict(idev->dev, &aca->aca_addr);
...@@ -329,7 +331,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr) ...@@ -329,7 +331,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
addrconf_leave_solict(idev, &aca->aca_addr); addrconf_leave_solict(idev, &aca->aca_addr);
dst_hold(&aca->aca_rt->dst); dst_hold(&aca->aca_rt->dst);
ip6_del_rt(aca->aca_rt); ip6_del_rt(dev_net(idev->dev), aca->aca_rt);
aca_put(aca); aca_put(aca);
return 0; return 0;
...@@ -357,7 +359,7 @@ void ipv6_ac_destroy_dev(struct inet6_dev *idev) ...@@ -357,7 +359,7 @@ void ipv6_ac_destroy_dev(struct inet6_dev *idev)
addrconf_leave_solict(idev, &aca->aca_addr); addrconf_leave_solict(idev, &aca->aca_addr);
dst_hold(&aca->aca_rt->dst); dst_hold(&aca->aca_rt->dst);
ip6_del_rt(aca->aca_rt); ip6_del_rt(dev_net(idev->dev), aca->aca_rt);
aca_put(aca); aca_put(aca);
......
...@@ -1156,6 +1156,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1156,6 +1156,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
struct neighbour *neigh = NULL; struct neighbour *neigh = NULL;
struct inet6_dev *in6_dev; struct inet6_dev *in6_dev;
struct rt6_info *rt = NULL; struct rt6_info *rt = NULL;
struct net *net;
int lifetime; int lifetime;
struct ndisc_options ndopts; struct ndisc_options ndopts;
int optlen; int optlen;
...@@ -1253,9 +1254,9 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1253,9 +1254,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
/* Do not accept RA with source-addr found on local machine unless /* Do not accept RA with source-addr found on local machine unless
* accept_ra_from_local is set to true. * accept_ra_from_local is set to true.
*/ */
net = dev_net(in6_dev->dev);
if (!in6_dev->cnf.accept_ra_from_local && if (!in6_dev->cnf.accept_ra_from_local &&
ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, ipv6_chk_addr(net, &ipv6_hdr(skb)->saddr, in6_dev->dev, 0)) {
in6_dev->dev, 0)) {
ND_PRINTK(2, info, ND_PRINTK(2, info,
"RA from local address detected on dev: %s: default router ignored\n", "RA from local address detected on dev: %s: default router ignored\n",
skb->dev->name); skb->dev->name);
...@@ -1272,7 +1273,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1272,7 +1273,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
pref = ICMPV6_ROUTER_PREF_MEDIUM; pref = ICMPV6_ROUTER_PREF_MEDIUM;
#endif #endif
rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev); rt = rt6_get_dflt_router(net, &ipv6_hdr(skb)->saddr, skb->dev);
if (rt) { if (rt) {
neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr); neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
...@@ -1285,7 +1286,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1285,7 +1286,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
} }
} }
if (rt && lifetime == 0) { if (rt && lifetime == 0) {
ip6_del_rt(rt); ip6_del_rt(net, rt);
rt = NULL; rt = NULL;
} }
...@@ -1294,7 +1295,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1294,7 +1295,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
if (!rt && lifetime) { if (!rt && lifetime) {
ND_PRINTK(3, info, "RA: adding default router\n"); ND_PRINTK(3, info, "RA: adding default router\n");
rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref); rt = rt6_add_dflt_router(net, &ipv6_hdr(skb)->saddr,
skb->dev, pref);
if (!rt) { if (!rt) {
ND_PRINTK(0, err, ND_PRINTK(0, err,
"RA: %s failed to add default route\n", "RA: %s failed to add default route\n",
......
...@@ -850,13 +850,13 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, ...@@ -850,13 +850,13 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
} }
if (rinfo->prefix_len == 0) if (rinfo->prefix_len == 0)
rt = rt6_get_dflt_router(gwaddr, dev); rt = rt6_get_dflt_router(net, gwaddr, dev);
else else
rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, rt = rt6_get_route_info(net, prefix, rinfo->prefix_len,
gwaddr, dev); gwaddr, dev);
if (rt && !lifetime) { if (rt && !lifetime) {
ip6_del_rt(rt); ip6_del_rt(net, rt);
rt = NULL; rt = NULL;
} }
...@@ -1014,9 +1014,9 @@ static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info, ...@@ -1014,9 +1014,9 @@ static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info,
return err; return err;
} }
int ip6_ins_rt(struct rt6_info *rt) int ip6_ins_rt(struct net *net, struct rt6_info *rt)
{ {
struct nl_info info = { .nl_net = dev_net(rt->dst.dev), }; struct nl_info info = { .nl_net = net, };
struct mx6_config mxc = { .mx = NULL, }; struct mx6_config mxc = { .mx = NULL, };
/* Hold dst to account for the reference from the fib6 tree */ /* Hold dst to account for the reference from the fib6 tree */
...@@ -1121,14 +1121,13 @@ static struct rt6_info *rt6_get_pcpu_route(struct rt6_info *rt) ...@@ -1121,14 +1121,13 @@ static struct rt6_info *rt6_get_pcpu_route(struct rt6_info *rt)
return pcpu_rt; return pcpu_rt;
} }
static struct rt6_info *rt6_make_pcpu_route(struct rt6_info *rt) static struct rt6_info *rt6_make_pcpu_route(struct net *net,
struct rt6_info *rt)
{ {
struct rt6_info *pcpu_rt, *prev, **p; struct rt6_info *pcpu_rt, *prev, **p;
pcpu_rt = ip6_rt_pcpu_alloc(rt); pcpu_rt = ip6_rt_pcpu_alloc(rt);
if (!pcpu_rt) { if (!pcpu_rt) {
struct net *net = dev_net(rt->dst.dev);
dst_hold(&net->ipv6.ip6_null_entry->dst); dst_hold(&net->ipv6.ip6_null_entry->dst);
return net->ipv6.ip6_null_entry; return net->ipv6.ip6_null_entry;
} }
...@@ -1787,7 +1786,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, ...@@ -1787,7 +1786,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
/* No dst_hold() on rt is needed because grabbing /* No dst_hold() on rt is needed because grabbing
* rt->rt6i_ref makes sure rt can't be released. * rt->rt6i_ref makes sure rt can't be released.
*/ */
pcpu_rt = rt6_make_pcpu_route(rt); pcpu_rt = rt6_make_pcpu_route(net, rt);
rt6_release(rt); rt6_release(rt);
} else { } else {
/* rt is already removed from tree */ /* rt is already removed from tree */
...@@ -2088,7 +2087,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) ...@@ -2088,7 +2087,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
if (rt) { if (rt) {
if (rt->rt6i_flags & RTF_CACHE) { if (rt->rt6i_flags & RTF_CACHE) {
if (rt6_check_expired(rt)) { if (rt6_check_expired(rt)) {
ip6_del_rt(rt); ip6_del_rt(dev_net(dst->dev), rt);
dst = NULL; dst = NULL;
} }
} else { } else {
...@@ -2109,7 +2108,7 @@ static void ip6_link_failure(struct sk_buff *skb) ...@@ -2109,7 +2108,7 @@ static void ip6_link_failure(struct sk_buff *skb)
if (rt) { if (rt) {
if (rt->rt6i_flags & RTF_CACHE) { if (rt->rt6i_flags & RTF_CACHE) {
if (dst_hold_safe(&rt->dst)) if (dst_hold_safe(&rt->dst))
ip6_del_rt(rt); ip6_del_rt(dev_net(rt->dst.dev), rt);
} else { } else {
struct fib6_node *fn; struct fib6_node *fn;
...@@ -3018,9 +3017,9 @@ int ip6_route_add(struct fib6_config *cfg, ...@@ -3018,9 +3017,9 @@ int ip6_route_add(struct fib6_config *cfg,
static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
{ {
int err; struct net *net = info->nl_net;
struct fib6_table *table; struct fib6_table *table;
struct net *net = dev_net(rt->dst.dev); int err;
if (rt == net->ipv6.ip6_null_entry) { if (rt == net->ipv6.ip6_null_entry) {
err = -ENOENT; err = -ENOENT;
...@@ -3037,11 +3036,10 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) ...@@ -3037,11 +3036,10 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
return err; return err;
} }
int ip6_del_rt(struct rt6_info *rt) int ip6_del_rt(struct net *net, struct rt6_info *rt)
{ {
struct nl_info info = { struct nl_info info = { .nl_net = net };
.nl_net = dev_net(rt->dst.dev),
};
return __ip6_del_rt(rt, &info); return __ip6_del_rt(rt, &info);
} }
...@@ -3376,13 +3374,15 @@ static struct rt6_info *rt6_add_route_info(struct net *net, ...@@ -3376,13 +3374,15 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
} }
#endif #endif
struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_device *dev) struct rt6_info *rt6_get_dflt_router(struct net *net,
const struct in6_addr *addr,
struct net_device *dev)
{ {
u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT; u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT;
struct rt6_info *rt; struct rt6_info *rt;
struct fib6_table *table; struct fib6_table *table;
table = fib6_get_table(dev_net(dev), tb_id); table = fib6_get_table(net, tb_id);
if (!table) if (!table)
return NULL; return NULL;
...@@ -3399,7 +3399,8 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev ...@@ -3399,7 +3399,8 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev
return rt; return rt;
} }
struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, struct rt6_info *rt6_add_dflt_router(struct net *net,
const struct in6_addr *gwaddr,
struct net_device *dev, struct net_device *dev,
unsigned int pref) unsigned int pref)
{ {
...@@ -3412,7 +3413,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, ...@@ -3412,7 +3413,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
.fc_protocol = RTPROT_RA, .fc_protocol = RTPROT_RA,
.fc_nlinfo.portid = 0, .fc_nlinfo.portid = 0,
.fc_nlinfo.nlh = NULL, .fc_nlinfo.nlh = NULL,
.fc_nlinfo.nl_net = dev_net(dev), .fc_nlinfo.nl_net = net,
}; };
cfg.fc_gateway = *gwaddr; cfg.fc_gateway = *gwaddr;
...@@ -3425,10 +3426,11 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, ...@@ -3425,10 +3426,11 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
table->flags |= RT6_TABLE_HAS_DFLT_ROUTER; table->flags |= RT6_TABLE_HAS_DFLT_ROUTER;
} }
return rt6_get_dflt_router(gwaddr, dev); return rt6_get_dflt_router(net, gwaddr, dev);
} }
static void __rt6_purge_dflt_routers(struct fib6_table *table) static void __rt6_purge_dflt_routers(struct net *net,
struct fib6_table *table)
{ {
struct rt6_info *rt; struct rt6_info *rt;
...@@ -3439,7 +3441,7 @@ static void __rt6_purge_dflt_routers(struct fib6_table *table) ...@@ -3439,7 +3441,7 @@ static void __rt6_purge_dflt_routers(struct fib6_table *table)
(!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) { (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
if (dst_hold_safe(&rt->dst)) { if (dst_hold_safe(&rt->dst)) {
rcu_read_unlock(); rcu_read_unlock();
ip6_del_rt(rt); ip6_del_rt(net, rt);
} else { } else {
rcu_read_unlock(); rcu_read_unlock();
} }
...@@ -3463,7 +3465,7 @@ void rt6_purge_dflt_routers(struct net *net) ...@@ -3463,7 +3465,7 @@ void rt6_purge_dflt_routers(struct net *net)
head = &net->ipv6.fib_table_hash[h]; head = &net->ipv6.fib_table_hash[h];
hlist_for_each_entry_rcu(table, head, tb6_hlist) { hlist_for_each_entry_rcu(table, head, tb6_hlist) {
if (table->flags & RT6_TABLE_HAS_DFLT_ROUTER) if (table->flags & RT6_TABLE_HAS_DFLT_ROUTER)
__rt6_purge_dflt_routers(table); __rt6_purge_dflt_routers(net, table);
} }
} }
...@@ -3583,12 +3585,12 @@ static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff ...@@ -3583,12 +3585,12 @@ static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff
* Allocate a dst for local (unicast / anycast) address. * Allocate a dst for local (unicast / anycast) address.
*/ */
struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, struct rt6_info *addrconf_dst_alloc(struct net *net,
struct inet6_dev *idev,
const struct in6_addr *addr, const struct in6_addr *addr,
bool anycast) bool anycast)
{ {
u32 tb_id; u32 tb_id;
struct net *net = dev_net(idev->dev);
struct net_device *dev = idev->dev; struct net_device *dev = idev->dev;
struct rt6_info *rt; struct rt6_info *rt;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册