Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62dd9318 authored by Ville Nuorvala's avatar Ville Nuorvala Committed by David S. Miller
Browse files

[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: default avatarVille Nuorvala <vnuorval@tcs.hut.fi>
Signed-off-by: default avatarMasahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
parent 5f3e6e9e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ struct pneigh_entry
{
	struct pneigh_entry	*next;
	struct net_device		*dev;
	u8			flags;
	u8			key[0];
};

+8 −3
Original line number Diff line number Diff line
@@ -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)
			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;
		}

+11 −3
Original line number Diff line number Diff line
@@ -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);