aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ndisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r--net/ipv6/ndisc.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index b4d8e331432e..e77b74edfd63 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -661,6 +661,20 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
661 } 661 }
662} 662}
663 663
664static struct pneigh_entry *pndisc_check_router(struct net_device *dev,
665 struct in6_addr *addr, int *is_router)
666{
667 struct pneigh_entry *n;
668
669 read_lock_bh(&nd_tbl.lock);
670 n = __pneigh_lookup(&nd_tbl, dev_net(dev), addr, dev);
671 if (n != NULL)
672 *is_router = (n->flags & NTF_ROUTER);
673 read_unlock_bh(&nd_tbl.lock);
674
675 return n;
676}
677
664static void ndisc_recv_ns(struct sk_buff *skb) 678static void ndisc_recv_ns(struct sk_buff *skb)
665{ 679{
666 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); 680 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
@@ -677,7 +691,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
677 struct pneigh_entry *pneigh = NULL; 691 struct pneigh_entry *pneigh = NULL;
678 int dad = ipv6_addr_any(saddr); 692 int dad = ipv6_addr_any(saddr);
679 int inc; 693 int inc;
680 int is_router; 694 int is_router = 0;
681 695
682 if (ipv6_addr_is_multicast(&msg->target)) { 696 if (ipv6_addr_is_multicast(&msg->target)) {
683 ND_PRINTK2(KERN_WARNING 697 ND_PRINTK2(KERN_WARNING
@@ -776,8 +790,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
776 if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) || 790 if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) ||
777 (idev->cnf.forwarding && 791 (idev->cnf.forwarding &&
778 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && 792 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
779 (pneigh = pneigh_lookup(&nd_tbl, dev_net(dev), 793 (pneigh = pndisc_check_router(dev, &msg->target,
780 &msg->target, dev, 0)) != NULL)) { 794 &is_router)) != NULL)) {
781 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && 795 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
782 skb->pkt_type != PACKET_HOST && 796 skb->pkt_type != PACKET_HOST &&
783 inc != 0 && 797 inc != 0 &&
@@ -798,7 +812,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
798 goto out; 812 goto out;
799 } 813 }
800 814
801 is_router = !!(pneigh ? pneigh->flags & NTF_ROUTER : idev->cnf.forwarding); 815 is_router = !!(pneigh ? is_router : idev->cnf.forwarding);
802 816
803 if (dad) { 817 if (dad) {
804 struct in6_addr maddr; 818 struct in6_addr maddr;