aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Nuorvala <vnuorval@tcs.hut.fi>2006-09-22 14:43:19 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 15:20:24 -0700
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 bd187daffdb..c8aacbd2e33 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -126,6 +126,7 @@ struct pneigh_entry
{
struct pneigh_entry *next;
struct net_device *dev;
+ u8 flags;
u8 key[0];
};
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index a45bd2124d6..b6c69e1463e 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)
lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
if (ndm->ndm_flags & NTF_PROXY) {
- err = 0;
- if (pneigh_lookup(tbl, dst, dev, 1) == NULL)
- err = -ENOBUFS;
+ struct pneigh_entry *pn;
+
+ err = -ENOBUFS;
+ pn = pneigh_lookup(tbl, dst, dev, 1);
+ if (pn) {
+ pn->flags = ndm->ndm_flags;
+ err = 0;
+ }
goto out_dev_put;
}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0e0d6ce6902..ddf038636f0 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -736,8 +736,10 @@ static void ndisc_recv_ns(struct sk_buff *skb)
struct inet6_ifaddr *ifp;
struct inet6_dev *idev = NULL;
struct neighbour *neigh;
+ struct pneigh_entry *pneigh = NULL;
int dad = ipv6_addr_any(saddr);
int inc;
+ int is_router;
if (ipv6_addr_is_multicast(&msg->target)) {
ND_PRINTK2(KERN_WARNING
@@ -822,7 +824,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
if (ipv6_chk_acast_addr(dev, &msg->target) ||
(idev->cnf.forwarding &&
- pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
+ (pneigh = pneigh_lookup(&nd_tbl,
+ &msg->target, dev, 0)) != NULL)) {
if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
skb->pkt_type != PACKET_HOST &&
inc != 0 &&
@@ -843,12 +846,17 @@ static void ndisc_recv_ns(struct sk_buff *skb)
goto out;
}
+ if (pneigh)
+ is_router = pneigh->flags & NTF_ROUTER;
+ else
+ is_router = idev->cnf.forwarding;
+
if (dad) {
struct in6_addr maddr;
ipv6_addr_all_nodes(&maddr);
ndisc_send_na(dev, NULL, &maddr, &msg->target,
- idev->cnf.forwarding, 0, (ifp != NULL), 1);
+ is_router, 0, (ifp != NULL), 1);
goto out;
}
@@ -869,7 +877,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
NEIGH_UPDATE_F_OVERRIDE);
if (neigh || !dev->hard_header) {
ndisc_send_na(dev, neigh, saddr, &msg->target,
- idev->cnf.forwarding,
+ is_router,
1, (ifp != NULL && inc), inc);
if (neigh)
neigh_release(neigh);