(usagi-users 03557) Possible bug in net/ipv6/ndisc.c
Tushar Gohad <[email protected]>
| Newsgroups | gmane.linux.ipv6.usagi.users |
|---|---|
| Message-ID | <[email protected]> |
Hello USAGI folks,
In the following code of net/ipv6/ndisc.c (2.6.14),
---
void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
struct in6_addr *target)
{
...
ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf,
&skb->nh.ipv6h->saddr);
dst = ip6_route_output(NULL, &fl);
if (dst == NULL)
return;
...
---
The code would use rt6_lookup() in place of ip6_route_output()
earlier in 2.6.11 with a dev->ifindex parameter.
---
... (2.6.11)
...
ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf,
&skb->nh.ipv6h->saddr);
rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
if (rt == NULL)
return;
...
---
In 2.6.14 version, how does the dev->ifindex value get into oif
field of the flow? ip6_route_output() seems to use fl->oif.
A possible solution is to pass dev->ifindex to ndisc_flow_init().
Attached is the corresponding patch.
Thanks,
- Tushar
ipv6-fix-ndisc-flow_init.patch
(text/x-patch, 1.9 KB)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -401,7 +401,9 @@ static void pndisc_destructor(struct pne
*/
static inline void ndisc_flow_init(struct flowi *fl, u8 type,
- struct in6_addr *saddr, struct in6_addr *daddr)
+ struct in6_addr *saddr,
+ struct in6_addr *daddr,
+ int oif)
{
memset(fl, 0, sizeof(*fl));
ipv6_addr_copy(&fl->fl6_src, saddr);
@@ -409,6 +411,7 @@ static inline void ndisc_flow_init(struc
fl->proto = IPPROTO_ICMPV6;
fl->fl_icmp_type = type;
fl->fl_icmp_code = 0;
+ fl->oif = oif;
}
static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
@@ -440,7 +443,8 @@ static void ndisc_send_na(struct net_dev
src_addr = &tmpaddr;
}
- ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
+ ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT,
+ src_addr, daddr, dev->ifindex);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
if (!dst)
@@ -530,7 +534,8 @@ void ndisc_send_ns(struct net_device *de
saddr = &addr_buf;
}
- ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
+ ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION,
+ saddr, daddr, dev->ifindex);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
if (!dst)
@@ -605,7 +610,8 @@ void ndisc_send_rs(struct net_device *de
int len;
int err;
- ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
+ ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION,
+ saddr, daddr, dev->ifindex);
dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
if (!dst)
@@ -1340,7 +1346,8 @@ void ndisc_send_redirect(struct sk_buff
return;
}
- ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
+ ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf,
+ &skb->nh.ipv6h->saddr, dev->ifindex);
dst = ip6_route_output(NULL, &fl);
if (dst == NULL)