Skip to content

Commit

Permalink
fixed a loss of fragmented packets when the corresponding NDP state i…
Browse files Browse the repository at this point in the history
…s not resolved.
  • Loading branch information
suz committed Jan 21, 2005
1 parent 4dceb07 commit 657b10f
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 20 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG
@@ -1,7 +1,11 @@
CHANGELOG for KAME kit
$KAME: CHANGELOG,v 1.2717 2005/01/17 09:53:51 suz Exp $
$KAME: CHANGELOG,v 1.2718 2005/01/21 03:14:48 suz Exp $

<200501>
2005-01-21 suz@crl.hitachi.co.jp
* kame/sys/netinet6/{nd6.c, nd6_nbr.c}: fixed a loss of fragmented
packets when the corresponding NDP state is not resolved.

2005-01-17 suz@crl.hitachi.co.jp
* kame/sys/netinet6/icmp6.c: ignores ICMPv6 code field in case of
ICMPv6 Packet-Too-Big.
Expand Down
54 changes: 42 additions & 12 deletions kame/sys/netinet6/nd6.c
@@ -1,4 +1,4 @@
/* $KAME: nd6.c,v 1.369 2005/01/20 09:14:05 t-momose Exp $ */
/* $KAME: nd6.c,v 1.370 2005/01/21 03:14:49 suz Exp $ */

/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
Expand Down Expand Up @@ -608,6 +608,10 @@ nd6_llinfo_timer(arg)
} else {
struct mbuf *m = ln->ln_hold;
if (m) {
/*
* assuming every packet in ln_hold has the
* same IP header
*/
ln->ln_hold = NULL;
icmp6_error2(m, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_ADDR, 0, rt->rt_ifp);
Expand Down Expand Up @@ -2116,12 +2120,28 @@ nd6_cache_lladdr(ifp, from, lladdr, lladdrlen, type, code)
nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);

if (ln->ln_hold) {
/*
* we assume ifp is not a p2p here, so just
* set the 2nd argument as the 1st one.
*/
nd6_output(ifp, ifp, ln->ln_hold,
(struct sockaddr_in6 *)rt_key(rt), rt);
struct mbuf *m_hold, *m_hold_next;
for (m_hold = ln->ln_hold; m_hold;
m_hold = m_hold_next) {
struct mbuf *mpkt = NULL;

m_hold_next = m_hold->m_nextpkt;
mpkt = m_copym(m_hold, 0, M_COPYALL, M_DONTWAIT);
if (mpkt == NULL) {
m_freem(m_hold);
break;
}
mpkt->m_nextpkt = NULL;

/*
* we assume ifp is not a p2p here, so
* just set the 2nd argument as the
* 1st one.
*/
nd6_output(ifp, ifp, mpkt,
(struct sockaddr_in6 *)rt_key(rt),
rt);
}
ln->ln_hold = NULL;
}
} else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
Expand Down Expand Up @@ -2494,14 +2514,24 @@ nd6_output(ifp, origifp, m0, dst, rt0)

/*
* There is a neighbor cache entry, but no ethernet address
* response yet. Replace the held mbuf (if any) with this
* latest one.
* response yet. Append this latest packet to the end of the
* packet queue in the mbuf
*/
if (ln->ln_state == ND6_LLINFO_NOSTATE)
ln->ln_state = ND6_LLINFO_INCOMPLETE;
if (ln->ln_hold)
m_freem(ln->ln_hold);
ln->ln_hold = m;
if (ln->ln_hold) {
struct mbuf *m_hold, *m_hold_last;

m_hold = m_hold_last = ln->ln_hold;
while (m_hold) {
m_hold_last = m_hold;
m_hold = m_hold->m_nextpkt;
}
m_hold_last->m_nextpkt = m;
} else {
ln->ln_hold = m;
}

/*
* If there has been no NS for the neighbor after entering the
* INCOMPLETE state, send the first solicitation.
Expand Down
31 changes: 24 additions & 7 deletions kame/sys/netinet6/nd6_nbr.c
@@ -1,4 +1,4 @@
/* $KAME: nd6_nbr.c,v 1.153 2004/12/27 05:41:19 itojun Exp $ */
/* $KAME: nd6_nbr.c,v 1.154 2005/01/21 03:14:49 suz Exp $ */

/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
Expand Down Expand Up @@ -499,6 +499,10 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, dad)
struct in6_addr *hsrc = NULL;

if (ln && ln->ln_hold) {
/*
* assuming every packet in ln_hold has the same IP
* header
*/
hip6 = mtod(ln->ln_hold, struct ip6_hdr *);
hsrc = &hip6->ip6_src;
}
Expand Down Expand Up @@ -921,12 +925,25 @@ nd6_na_input(m, off, icmp6len)
rt->rt_flags &= ~RTF_REJECT;
ln->ln_asked = 0;
if (ln->ln_hold) {
/*
* we assume ifp is not a loopback here, so just set the 2nd
* argument as the 1st one.
*/
nd6_output(ifp, ifp, ln->ln_hold,
(struct sockaddr_in6 *)rt_key(rt), rt);
struct mbuf *m_hold, *m_hold_next;

for (m_hold = ln->ln_hold; m_hold; m_hold = m_hold_next) {
struct mbuf *mpkt = NULL;

m_hold_next = m_hold->m_nextpkt;
mpkt = m_copym(m_hold, 0, M_COPYALL, M_DONTWAIT);
if (mpkt == NULL) {
m_freem(m_hold);
break;
}
mpkt->m_nextpkt = NULL;
/*
* we assume ifp is not a loopback here, so just set
* the 2nd argument as the 1st one.
*/
nd6_output(ifp, ifp, mpkt,
(struct sockaddr_in6 *)rt_key(rt), rt);
}
ln->ln_hold = NULL;
}

Expand Down

0 comments on commit 657b10f

Please sign in to comment.