diff options
-rw-r--r-- | include/net/neighbour.h | 1 | ||||
-rw-r--r-- | net/core/neighbour.c | 11 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 14 |
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); |