diff options
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r-- | net/ipv6/ndisc.c | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2edce30ef73..4c02e6ab96e 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -370,12 +370,12 @@ static void pndisc_destructor(struct pneigh_entry *n) ipv6_dev_mc_dec(dev, &maddr); } -struct sk_buff *ndisc_build_skb(struct net_device *dev, - const struct in6_addr *daddr, - const struct in6_addr *saddr, - struct icmp6hdr *icmp6h, - const struct in6_addr *target, - int llinfo) +static struct sk_buff *ndisc_build_skb(struct net_device *dev, + const struct in6_addr *daddr, + const struct in6_addr *saddr, + struct icmp6hdr *icmp6h, + const struct in6_addr *target, + int llinfo) { struct net *net = dev_net(dev); struct sock *sk = net->ipv6.ndisc_sk; @@ -431,14 +431,11 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, return skb; } -EXPORT_SYMBOL(ndisc_build_skb); - -void ndisc_send_skb(struct sk_buff *skb, - struct net_device *dev, - struct neighbour *neigh, - const struct in6_addr *daddr, - const struct in6_addr *saddr, - struct icmp6hdr *icmp6h) +static void ndisc_send_skb(struct sk_buff *skb, struct net_device *dev, + struct neighbour *neigh, + const struct in6_addr *daddr, + const struct in6_addr *saddr, + struct icmp6hdr *icmp6h) { struct flowi6 fl6; struct dst_entry *dst; @@ -473,8 +470,6 @@ void ndisc_send_skb(struct sk_buff *skb, rcu_read_unlock(); } -EXPORT_SYMBOL(ndisc_send_skb); - /* * Send a Neighbour Discover packet */ @@ -535,7 +530,6 @@ static void ndisc_send_unsol_na(struct net_device *dev) { struct inet6_dev *idev; struct inet6_ifaddr *ifa; - struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; idev = in6_dev_get(dev); if (!idev) @@ -543,7 +537,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) read_lock_bh(&idev->lock); list_for_each_entry(ifa, &idev->addr_list, if_list) { - ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, + ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &ifa->addr, /*router=*/ !!idev->cnf.forwarding, /*solicited=*/ false, /*override=*/ true, /*inc_opt=*/ true); @@ -905,7 +899,7 @@ static void ndisc_recv_na(struct sk_buff *skb) if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp && pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) { - /* XXX: idev->cnf.prixy_ndp */ + /* XXX: idev->cnf.proxy_ndp */ goto out; } @@ -1033,18 +1027,6 @@ errout: rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err); } -static inline int accept_ra(struct inet6_dev *in6_dev) -{ - /* - * If forwarding is enabled, RA are not accepted unless the special - * hybrid mode (accept_ra=2) is enabled. - */ - if (in6_dev->cnf.forwarding && in6_dev->cnf.accept_ra < 2) - return 0; - - return in6_dev->cnf.accept_ra; -} - static void ndisc_router_discovery(struct sk_buff *skb) { struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb); @@ -1092,7 +1074,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) return; } - if (!accept_ra(in6_dev)) + if (!ipv6_accept_ra(in6_dev)) goto skip_linkparms; #ifdef CONFIG_IPV6_NDISC_NODETYPE @@ -1144,7 +1126,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ND_PRINTK(0, err, "RA: %s got default router without neighbour\n", __func__); - dst_release(&rt->dst); + ip6_rt_put(rt); return; } } @@ -1169,7 +1151,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ND_PRINTK(0, err, "RA: %s got default router without neighbour\n", __func__); - dst_release(&rt->dst); + ip6_rt_put(rt); return; } neigh->flags |= NTF_ROUTER; @@ -1248,7 +1230,7 @@ skip_linkparms: NEIGH_UPDATE_F_ISROUTER); } - if (!accept_ra(in6_dev)) + if (!ipv6_accept_ra(in6_dev)) goto out; #ifdef CONFIG_IPV6_ROUTE_INFO @@ -1325,8 +1307,7 @@ skip_routeinfo: ND_PRINTK(2, warn, "RA: invalid RA options\n"); } out: - if (rt) - dst_release(&rt->dst); + ip6_rt_put(rt); if (neigh) neigh_release(neigh); } @@ -1574,11 +1555,18 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, { struct net_device *dev = ptr; struct net *net = dev_net(dev); + struct inet6_dev *idev; switch (event) { case NETDEV_CHANGEADDR: neigh_changeaddr(&nd_tbl, dev); fib6_run_gc(~0UL, net); + idev = in6_dev_get(dev); + if (!idev) + break; + if (idev->cnf.ndisc_notify) + ndisc_send_unsol_na(dev); + in6_dev_put(idev); break; case NETDEV_DOWN: neigh_ifdown(&nd_tbl, dev); |