aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Nuorvala <vnuorval@tcs.hut.fi>2006-09-22 17:43:19 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:20:24 -0400
commit62dd93181aaa1d5a501a9cebcb254f44b8a48af7 (patch)
treeb19cc7f630d3fecccc338f1c5a75000a4485565a
parent5f3e6e9e19f50a6910aec2dbd479187aabba04b7 (diff)
[IPV6] NDISC: Set per-entry is_router flag in Proxy NA.
We have sent NA with router flag from the node-wide forwarding configuration. This is not appropriate for proxy NA, and it should be set according to each proxy entry's configuration. This is used by Mobile IPv6 home agent to support physical home link in acting as a proxy router for mobile node which is not a router, for example. Based on MIPL2 kernel patch. Signed-off-by: Ville Nuorvala <vnuorval@tcs.hut.fi> Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
-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);