Deleted Added
full compact
0a1,3
> /* $FreeBSD: head/sys/netinet6/frag6.c 62587 2000-07-04 16:35:15Z itojun $ */
> /* $KAME: frag6.c,v 1.24 2000/03/25 07:23:41 sumikawa Exp $ */
>
28,29d30
< *
< * $FreeBSD: head/sys/netinet6/frag6.c 54350 1999-12-09 08:56:50Z shin $
49c50
< #include <netinet6/ip6.h>
---
> #include <netinet/ip6.h>
51c52
< #include <netinet6/icmp6.h>
---
> #include <netinet/icmp6.h>
60c61
< #define IN6_IFSTAT_STRICT
---
> #define IN6_IFSTAT_STRICT
62,66c63,67
< static void frag6_enq __P((struct ip6asfrag *, struct ip6asfrag *));
< static void frag6_deq __P((struct ip6asfrag *));
< static void frag6_insque __P((struct ip6q *, struct ip6q *));
< static void frag6_remque __P((struct ip6q *));
< static void frag6_freef __P((struct ip6q *));
---
> static void frag6_enq __P((struct ip6asfrag *, struct ip6asfrag *));
> static void frag6_deq __P((struct ip6asfrag *));
> static void frag6_insque __P((struct ip6q *, struct ip6q *));
> static void frag6_remque __P((struct ip6q *));
> static void frag6_freef __P((struct ip6q *));
68,70c69,71
< int frag6_doing_reass;
< u_int frag6_nfragpackets;
< struct ip6q ip6q; /* ip6 reassemble queue */
---
> int frag6_doing_reass;
> u_int frag6_nfragpackets;
> struct ip6q ip6q; /* ip6 reassemble queue */
72c73
< #if !defined(M_FTABLE)
---
> /* FreeBSD tweak */
73a75,77
>
> #ifndef offsetof /* XXX */
> #define offsetof(type, member) ((size_t)(&((type *)0)->member))
89d92
< ip6q.ip6q_next = ip6q.ip6q_prev = &ip6q;
90a94
> ip6q.ip6q_next = ip6q.ip6q_prev = &ip6q;
93a98,126
> * In RFC2460, fragment and reassembly rule do not agree with each other,
> * in terms of next header field handling in fragment header.
> * While the sender will use the same value for all of the fragmented packets,
> * receiver is suggested not to check the consistency.
> *
> * fragment rule (p20):
> * (2) A Fragment header containing:
> * The Next Header value that identifies the first header of
> * the Fragmentable Part of the original packet.
> * -> next header field is same for all fragments
> *
> * reassembly rule (p21):
> * The Next Header field of the last header of the Unfragmentable
> * Part is obtained from the Next Header field of the first
> * fragment's Fragment header.
> * -> should grab it from the first fragment only
> *
> * The following note also contradicts with fragment rule - noone is going to
> * send different fragment with different next header field.
> *
> * additional note (p22):
> * The Next Header values in the Fragment headers of different
> * fragments of the same original packet may differ. Only the value
> * from the Offset zero fragment packet is used for reassembly.
> * -> should grab it from the first fragment only
> *
> * There is no explicit reason given in the RFC. Historical reason maybe?
> */
> /*
105c138
< struct ip6asfrag *af6, *ip6af;
---
> struct ip6asfrag *af6, *ip6af, *af6dwn;
108c141
< u_short fragoff, frgpartlen;
---
> int fragoff, frgpartlen; /* must be larger than u_int16_t */
115,116d147
< IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE);
<
117a149,150
> #ifndef PULLDOWN_TEST
> IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE);
118a152,156
> #else
> IP6_EXTHDR_GET(ip6f, struct ip6_frag *, m, offset, sizeof(*ip6f));
> if (ip6f == NULL)
> return IPPROTO_DONE;
> #endif
162c200
< (caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
---
> offsetof(struct ip6_hdr, ip6_plen));
170,174c208
< /*
< * Presence of header sizes in mbufs
< * would confuse code below.
< */
<
---
> /* offset now points to data portion */
176,177d209
< m->m_data += offset;
< m->m_len -= offset;
206a239
> bzero(q6, sizeof(*q6));
209a243
> /* ip6q_nxt will be filled afterwards, from 1st fragment */
210a245,247
> #ifdef notyet
> q6->ip6q_nxtp = (u_char *)nxtp;
> #endif
235c272
< frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
---
> frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
239,240d275
< m->m_data -= offset;
< m->m_len += offset;
242c277,278
< offset - sizeof(struct ip6_frag) + 2);
---
> offset - sizeof(struct ip6_frag) +
> offsetof(struct ip6_frag, ip6f_offlg));
247,248d282
< m->m_data -= offset;
< m->m_len += offset;
250c284,285
< offset - sizeof(struct ip6_frag) + 2);
---
> offset - sizeof(struct ip6_frag) +
> offsetof(struct ip6_frag, ip6f_offlg));
258,259d292
< struct ip6asfrag *af6dwn;
<
271a305
> free(af6, M_FTABLE);
274,275d307
< merr->m_data -= af6->ip6af_offset;
< merr->m_len += af6->ip6af_offset;
287c319,320
< erroff - sizeof(struct ip6_frag) + 2);
---
> erroff - sizeof(struct ip6_frag) +
> offsetof(struct ip6_frag, ip6f_offlg));
292,293c325,333
< /* Override the IPv6 header */
< ip6af = (struct ip6asfrag *)ip6;
---
> ip6af = (struct ip6asfrag *)malloc(sizeof(struct ip6asfrag), M_FTABLE,
> M_DONTWAIT);
> if (ip6af == NULL)
> goto dropfrag;
> bzero(ip6af, sizeof(*ip6af));
> ip6af->ip6af_head = ip6->ip6_flow;
> ip6af->ip6af_len = ip6->ip6_plen;
> ip6af->ip6af_nxt = ip6->ip6_nxt;
> ip6af->ip6af_hlim = ip6->ip6_hlim;
312a353
> #if 0
313a355,389
> * If there is a preceding segment, it may provide some of
> * our data already. If so, drop the data from the incoming
> * segment. If it provides all of our data, drop us.
> */
> if (af6->ip6af_up != (struct ip6asfrag *)q6) {
> i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen
> - ip6af->ip6af_off;
> if (i > 0) {
> if (i >= ip6af->ip6af_frglen)
> goto dropfrag;
> m_adj(IP6_REASS_MBUF(ip6af), i);
> ip6af->ip6af_off += i;
> ip6af->ip6af_frglen -= i;
> }
> }
>
> /*
> * While we overlap succeeding segments trim them or,
> * if they are completely covered, dequeue them.
> */
> while (af6 != (struct ip6asfrag *)q6 &&
> ip6af->ip6af_off + ip6af->ip6af_frglen > af6->ip6af_off) {
> i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off;
> if (i < af6->ip6af_frglen) {
> af6->ip6af_frglen -= i;
> af6->ip6af_off += i;
> m_adj(IP6_REASS_MBUF(af6), i);
> break;
> }
> af6 = af6->ip6af_down;
> m_freem(IP6_REASS_MBUF(af6->ip6af_up));
> frag6_deq(af6->ip6af_up);
> }
> #else
> /*
336a413
> #endif
346a424,429
> #if 0 /* xxx */
> if (q6 != ip6q.ip6q_next) {
> frag6_remque(q6);
> frag6_insque(q6, &ip6q);
> }
> #endif
364d446
<
367a450
> frag6_deq(ip6af);
368a452,453
> af6dwn = af6->ip6af_down;
> frag6_deq(af6);
372c457,459
< af6 = af6->ip6af_down;
---
> m_adj(t->m_next, af6->ip6af_offset);
> free(af6, M_FTABLE);
> af6 = af6dwn;
377c464,465
< ip6 = (struct ip6_hdr *)ip6af;
---
> free(ip6af, M_FTABLE);
> ip6 = mtod(m, struct ip6_hdr *);
381a470,472
> #ifdef notyet
> *q6->ip6q_nxtp = (u_char)(nxt & 0xff);
> #endif
386,387c477
<
< if (offset < m->m_len)
---
> if (offset < m->m_len) {
390,392c480,491
< else {
< ovbcopy(mtod(m, caddr_t), (caddr_t)ip6 + offset, m->m_len);
< m->m_data -= sizeof(struct ip6_frag);
---
> m->m_data += sizeof(struct ip6_frag);
> m->m_len -= sizeof(struct ip6_frag);
> } else {
> /* this comes with no copy if the boundary is on cluster */
> if ((t = m_split(m, offset, M_DONTWAIT)) == NULL) {
> frag6_remque(q6);
> free(q6, M_FTABLE);
> frag6_nfragpackets--;
> goto dropfrag;
> }
> m_adj(t, sizeof(struct ip6_frag));
> m_cat(m, t);
394,395d492
< m->m_data -= offset;
< m->m_len += offset;
461,462d557
< m->m_data -= af6->ip6af_offset;
< m->m_len += af6->ip6af_offset;
471,472c566
< }
< else
---
> } else
473a568
> free(af6, M_FTABLE);
532a628,630
> #if 0
> extern struct route_in6 ip6_forward_rt;
> #endif
556a655,671
>
> #if 0
> /*
> * Routing changes might produce a better route than we last used;
> * make sure we notice eventually, even if forwarding only for one
> * destination and the cache is never replaced.
> */
> if (ip6_forward_rt.ro_rt) {
> RTFREE(ip6_forward_rt.ro_rt);
> ip6_forward_rt.ro_rt = 0;
> }
> if (ipsrcchk_rt.ro_rt) {
> RTFREE(ipsrcchk_rt.ro_rt);
> ipsrcchk_rt.ro_rt = 0;
> }
> #endif
>