Deleted Added
full compact
frag6.c (77969) frag6.c (78064)
1/* $FreeBSD: head/sys/netinet6/frag6.c 77969 2001-06-10 11:04:10Z jesper $ */
2/* $KAME: frag6.c,v 1.24 2000/03/25 07:23:41 sumikawa Exp $ */
1/* $FreeBSD: head/sys/netinet6/frag6.c 78064 2001-06-11 12:39:29Z ume $ */
2/* $KAME: frag6.c,v 1.31 2001/05/17 13:45:34 jinmei Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 50 unchanged lines hidden (view full) ---

61#define IN6_IFSTAT_STRICT
62
63static void frag6_enq __P((struct ip6asfrag *, struct ip6asfrag *));
64static void frag6_deq __P((struct ip6asfrag *));
65static void frag6_insque __P((struct ip6q *, struct ip6q *));
66static void frag6_remque __P((struct ip6q *));
67static void frag6_freef __P((struct ip6q *));
68
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 50 unchanged lines hidden (view full) ---

61#define IN6_IFSTAT_STRICT
62
63static void frag6_enq __P((struct ip6asfrag *, struct ip6asfrag *));
64static void frag6_deq __P((struct ip6asfrag *));
65static void frag6_insque __P((struct ip6q *, struct ip6q *));
66static void frag6_remque __P((struct ip6q *));
67static void frag6_freef __P((struct ip6q *));
68
69/* XXX we eventually need splreass6, or some real semaphore */
69int frag6_doing_reass;
70u_int frag6_nfragpackets;
71struct ip6q ip6q; /* ip6 reassemble queue */
72
73/* FreeBSD tweak */
74static MALLOC_DEFINE(M_FTABLE, "fragment", "fragment reassembly header");
75
76/*

--- 124 unchanged lines hidden (view full) ---

201 }
202
203 ip6stat.ip6s_fragments++;
204 in6_ifstat_inc(dstifp, ifs6_reass_reqd);
205
206 /* offset now points to data portion */
207 offset += sizeof(struct ip6_frag);
208
70int frag6_doing_reass;
71u_int frag6_nfragpackets;
72struct ip6q ip6q; /* ip6 reassemble queue */
73
74/* FreeBSD tweak */
75static MALLOC_DEFINE(M_FTABLE, "fragment", "fragment reassembly header");
76
77/*

--- 124 unchanged lines hidden (view full) ---

202 }
203
204 ip6stat.ip6s_fragments++;
205 in6_ifstat_inc(dstifp, ifs6_reass_reqd);
206
207 /* offset now points to data portion */
208 offset += sizeof(struct ip6_frag);
209
210 frag6_doing_reass = 1;
211
209 for (q6 = ip6q.ip6q_next; q6 != &ip6q; q6 = q6->ip6q_next)
210 if (ip6f->ip6f_ident == q6->ip6q_ident &&
211 IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) &&
212 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &q6->ip6q_dst))
213 break;
214
215 if (q6 == &ip6q) {
216 /*
217 * the first fragment to arrive, create a reassembly queue.
218 */
219 first_frag = 1;
212 for (q6 = ip6q.ip6q_next; q6 != &ip6q; q6 = q6->ip6q_next)
213 if (ip6f->ip6f_ident == q6->ip6q_ident &&
214 IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) &&
215 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &q6->ip6q_dst))
216 break;
217
218 if (q6 == &ip6q) {
219 /*
220 * the first fragment to arrive, create a reassembly queue.
221 */
222 first_frag = 1;
220 frag6_nfragpackets++;
221
222 /*
223 * Enforce upper bound on number of fragmented packets
224 * for which we attempt reassembly;
225 * If maxfrag is 0, never accept fragments.
226 * If maxfrag is -1, accept all fragments without limitation.
227 */
223
224 /*
225 * Enforce upper bound on number of fragmented packets
226 * for which we attempt reassembly;
227 * If maxfrag is 0, never accept fragments.
228 * If maxfrag is -1, accept all fragments without limitation.
229 */
228 if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets) {
229 ip6stat.ip6s_fragoverflow++;
230 in6_ifstat_inc(dstifp, ifs6_reass_fail);
231 frag6_freef(ip6q.ip6q_prev);
232 }
230 if (ip6_maxfragpackets < 0)
231 ;
232 else if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets)
233 goto dropfrag;
234 frag6_nfragpackets++;
233 q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE,
234 M_DONTWAIT);
235 if (q6 == NULL)
236 goto dropfrag;
237 bzero(q6, sizeof(*q6));
238
239 frag6_insque(q6, &ip6q);
240

--- 28 unchanged lines hidden (view full) ---

269 */
270 frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
271 if (q6->ip6q_unfrglen >= 0) {
272 /* The 1st fragment has already arrived. */
273 if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
274 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
275 offset - sizeof(struct ip6_frag) +
276 offsetof(struct ip6_frag, ip6f_offlg));
235 q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE,
236 M_DONTWAIT);
237 if (q6 == NULL)
238 goto dropfrag;
239 bzero(q6, sizeof(*q6));
240
241 frag6_insque(q6, &ip6q);
242

--- 28 unchanged lines hidden (view full) ---

271 */
272 frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
273 if (q6->ip6q_unfrglen >= 0) {
274 /* The 1st fragment has already arrived. */
275 if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
276 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
277 offset - sizeof(struct ip6_frag) +
278 offsetof(struct ip6_frag, ip6f_offlg));
279 frag6_doing_reass = 0;
277 return(IPPROTO_DONE);
278 }
279 }
280 else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
281 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
282 offset - sizeof(struct ip6_frag) +
283 offsetof(struct ip6_frag, ip6f_offlg));
280 return(IPPROTO_DONE);
281 }
282 }
283 else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
284 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
285 offset - sizeof(struct ip6_frag) +
286 offsetof(struct ip6_frag, ip6f_offlg));
287 frag6_doing_reass = 0;
284 return(IPPROTO_DONE);
285 }
286 /*
287 * If it's the first fragment, do the above check for each
288 * fragment already stored in the reassembly queue.
289 */
290 if (fragoff == 0) {
291 for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;

--- 234 unchanged lines hidden (view full) ---

526
527 frag6_doing_reass = 0;
528 return nxt;
529
530 dropfrag:
531 in6_ifstat_inc(dstifp, ifs6_reass_fail);
532 ip6stat.ip6s_fragdropped++;
533 m_freem(m);
288 return(IPPROTO_DONE);
289 }
290 /*
291 * If it's the first fragment, do the above check for each
292 * fragment already stored in the reassembly queue.
293 */
294 if (fragoff == 0) {
295 for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;

--- 234 unchanged lines hidden (view full) ---

530
531 frag6_doing_reass = 0;
532 return nxt;
533
534 dropfrag:
535 in6_ifstat_inc(dstifp, ifs6_reass_fail);
536 ip6stat.ip6s_fragdropped++;
537 m_freem(m);
538 frag6_doing_reass = 0;
534 return IPPROTO_DONE;
535}
536
537/*
538 * Free a fragment reassembly header and all
539 * associated datagrams.
540 */
541void

--- 73 unchanged lines hidden (view full) ---

615frag6_remque(p6)
616 struct ip6q *p6;
617{
618 p6->ip6q_prev->ip6q_next = p6->ip6q_next;
619 p6->ip6q_next->ip6q_prev = p6->ip6q_prev;
620}
621
622/*
539 return IPPROTO_DONE;
540}
541
542/*
543 * Free a fragment reassembly header and all
544 * associated datagrams.
545 */
546void

--- 73 unchanged lines hidden (view full) ---

620frag6_remque(p6)
621 struct ip6q *p6;
622{
623 p6->ip6q_prev->ip6q_next = p6->ip6q_next;
624 p6->ip6q_next->ip6q_prev = p6->ip6q_prev;
625}
626
627/*
623 * IP timer processing;
628 * IPv6 reassembling timer processing;
624 * if a timer expires on a reassembly
625 * queue, discard it.
626 */
627void
628frag6_slowtimo()
629{
630 struct ip6q *q6;
631 int s = splnet();
629 * if a timer expires on a reassembly
630 * queue, discard it.
631 */
632void
633frag6_slowtimo()
634{
635 struct ip6q *q6;
636 int s = splnet();
632#if 0
633 extern struct route_in6 ip6_forward_rt;
634#endif
635
636 frag6_doing_reass = 1;
637 q6 = ip6q.ip6q_next;
638 if (q6)
639 while (q6 != &ip6q) {
640 --q6->ip6q_ttl;
641 q6 = q6->ip6q_next;
642 if (q6->ip6q_prev->ip6q_ttl == 0) {
643 ip6stat.ip6s_fragtimeout++;
644 /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
645 frag6_freef(q6->ip6q_prev);
646 }
647 }
648 /*
649 * If we are over the maximum number of fragments
650 * (due to the limit being lowered), drain off
651 * enough to get down to the new limit.
652 */
637
638 frag6_doing_reass = 1;
639 q6 = ip6q.ip6q_next;
640 if (q6)
641 while (q6 != &ip6q) {
642 --q6->ip6q_ttl;
643 q6 = q6->ip6q_next;
644 if (q6->ip6q_prev->ip6q_ttl == 0) {
645 ip6stat.ip6s_fragtimeout++;
646 /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
647 frag6_freef(q6->ip6q_prev);
648 }
649 }
650 /*
651 * If we are over the maximum number of fragments
652 * (due to the limit being lowered), drain off
653 * enough to get down to the new limit.
654 */
653 while (frag6_nfragpackets > (u_int)ip6_maxfragpackets) {
655 while (frag6_nfragpackets > (u_int)ip6_maxfragpackets &&
656 ip6q.ip6q_prev) {
654 ip6stat.ip6s_fragoverflow++;
655 /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
656 frag6_freef(ip6q.ip6q_prev);
657 }
658 frag6_doing_reass = 0;
659
660#if 0
661 /*

--- 31 unchanged lines hidden ---
657 ip6stat.ip6s_fragoverflow++;
658 /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
659 frag6_freef(ip6q.ip6q_prev);
660 }
661 frag6_doing_reass = 0;
662
663#if 0
664 /*

--- 31 unchanged lines hidden ---