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); |
