aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/neighbour.h1
-rw-r--r--net/core/neighbour.c11
-rw-r--r--net/ipv6/ndisc.c14
3 files changed, 20 insertions, 6 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index bd187daffdb9..c8aacbd2e333 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -126,6 +126,7 @@ struct pneigh_entry
126{ 126{
127 struct pneigh_entry *next; 127 struct pneigh_entry *next;
128 struct net_device *dev; 128 struct net_device *dev;
129 u8 flags;
129 u8 key[0]; 130 u8 key[0];
130}; 131};
131 132
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index a45bd2124d6b..b6c69e1463e8 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1544,9 +1544,14 @@ int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1544 lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; 1544 lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
1545 1545
1546 if (ndm->ndm_flags & NTF_PROXY) { 1546 if (ndm->ndm_flags & NTF_PROXY) {
1547 err = 0; 1547 struct pneigh_entry *pn;
1548 if (pneigh_lookup(tbl, dst, dev, 1) == NULL) 1548
1549 err = -ENOBUFS; 1549 err = -ENOBUFS;
1550 pn = pneigh_lookup(tbl, dst, dev, 1);
1551 if (pn) {
1552 pn->flags = ndm->ndm_flags;
1553 err = 0;
1554 }
1550 goto out_dev_put; 1555 goto out_dev_put;
1551 } 1556 }
1552 1557
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0e0d6ce69021..ddf038636f01 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -736,8 +736,10 @@ static void ndisc_recv_ns(struct sk_buff *skb)
736 struct inet6_ifaddr *ifp; 736 struct inet6_ifaddr *ifp;
737 struct inet6_dev *idev = NULL; 737 struct inet6_dev *idev = NULL;
738 struct neighbour *neigh; 738 struct neighbour *neigh;
739 struct pneigh_entry *pneigh = NULL;
739 int dad = ipv6_addr_any(saddr); 740 int dad = ipv6_addr_any(saddr);
740 int inc; 741 int inc;
742 int is_router;
741 743
742 if (ipv6_addr_is_multicast(&msg->target)) { 744 if (ipv6_addr_is_multicast(&msg->target)) {
743 ND_PRINTK2(KERN_WARNING 745 ND_PRINTK2(KERN_WARNING
@@ -822,7 +824,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
822 824
823 if (ipv6_chk_acast_addr(dev, &msg->target) || 825 if (ipv6_chk_acast_addr(dev, &msg->target) ||
824 (idev->cnf.forwarding && 826 (idev->cnf.forwarding &&
825 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) { 827 (pneigh = pneigh_lookup(&nd_tbl,
828 &msg->target, dev, 0)) != NULL)) {
826 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && 829 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
827 skb->pkt_type != PACKET_HOST && 830 skb->pkt_type != PACKET_HOST &&
828 inc != 0 && 831 inc != 0 &&
@@ -843,12 +846,17 @@ static void ndisc_recv_ns(struct sk_buff *skb)
843 goto out; 846 goto out;
844 } 847 }
845 848
849 if (pneigh)
850 is_router = pneigh->flags & NTF_ROUTER;
851 else
852 is_router = idev->cnf.forwarding;
853
846 if (dad) { 854 if (dad) {
847 struct in6_addr maddr; 855 struct in6_addr maddr;
848 856
849 ipv6_addr_all_nodes(&maddr); 857 ipv6_addr_all_nodes(&maddr);
850 ndisc_send_na(dev, NULL, &maddr, &msg->target, 858 ndisc_send_na(dev, NULL, &maddr, &msg->target,
851 idev->cnf.forwarding, 0, (ifp != NULL), 1); 859 is_router, 0, (ifp != NULL), 1);
852 goto out; 860 goto out;
853 } 861 }
854 862
@@ -869,7 +877,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
869 NEIGH_UPDATE_F_OVERRIDE); 877 NEIGH_UPDATE_F_OVERRIDE);
870 if (neigh || !dev->hard_header) { 878 if (neigh || !dev->hard_header) {
871 ndisc_send_na(dev, neigh, saddr, &msg->target, 879 ndisc_send_na(dev, neigh, saddr, &msg->target,
872 idev->cnf.forwarding, 880 is_router,
873 1, (ifp != NULL && inc), inc); 881 1, (ifp != NULL && inc), inc);
874 if (neigh) 882 if (neigh)
875 neigh_release(neigh); 883 neigh_release(neigh);