Deleted Added
full compact
ip6_output.c (171259) ip6_output.c (171260)
1/* $FreeBSD: head/sys/netinet6/ip6_output.c 171259 2007-07-05 16:23:49Z delphij $ */
1/* $FreeBSD: head/sys/netinet6/ip6_output.c 171260 2007-07-05 16:29:40Z delphij $ */
2/* $KAME: ip6_output.c,v 1.279 2002/01/26 06:12:30 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

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

142 error = ip6_copyexthdr((mp), (caddr_t)(hp), \
143 ((eh)->ip6e_len + 1) << 3); \
144 if (error) \
145 goto freehdrs; \
146 } \
147 } while (/*CONSTCOND*/ 0)
148
149/*
2/* $KAME: ip6_output.c,v 1.279 2002/01/26 06:12:30 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

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

142 error = ip6_copyexthdr((mp), (caddr_t)(hp), \
143 ((eh)->ip6e_len + 1) << 3); \
144 if (error) \
145 goto freehdrs; \
146 } \
147 } while (/*CONSTCOND*/ 0)
148
149/*
150 * Form a chain of extension headers.
150 * Form a chain of extension headers.
151 * m is the extension header mbuf
152 * mp is the previous mbuf in the chain
153 * p is the next header
154 * i is the type of option.
155 */
156#define MAKE_CHAIN(m, mp, p, i)\
157 do {\
158 if (m) {\

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

213 struct secpolicy *sp = NULL;
214#endif /* IPSEC */
215
216 ip6 = mtod(m, struct ip6_hdr *);
217 if (ip6 == NULL) {
218 printf ("ip6 is NULL");
219 goto bad;
220 }
151 * m is the extension header mbuf
152 * mp is the previous mbuf in the chain
153 * p is the next header
154 * i is the type of option.
155 */
156#define MAKE_CHAIN(m, mp, p, i)\
157 do {\
158 if (m) {\

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

213 struct secpolicy *sp = NULL;
214#endif /* IPSEC */
215
216 ip6 = mtod(m, struct ip6_hdr *);
217 if (ip6 == NULL) {
218 printf ("ip6 is NULL");
219 goto bad;
220 }
221
221
222 finaldst = ip6->ip6_dst;
223
224 bzero(&exthdrs, sizeof(exthdrs));
225
226 if (opt) {
227 /* Hop-by-Hop options header */
228 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
229 /* Destination options header(1st part) */

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

241 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
242 }
243 /* Routing header */
244 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
245 /* Destination options header(2nd part) */
246 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
247 }
248
222 finaldst = ip6->ip6_dst;
223
224 bzero(&exthdrs, sizeof(exthdrs));
225
226 if (opt) {
227 /* Hop-by-Hop options header */
228 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
229 /* Destination options header(1st part) */

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

241 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
242 }
243 /* Routing header */
244 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
245 /* Destination options header(2nd part) */
246 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
247 }
248
249 /*
249 /*
250 * IPSec checking which handles several cases.
251 * FAST IPSEC: We re-injected the packet.
252 */
253#ifdef IPSEC
254 switch(ip6_ipsec_output(&m, inp, &flags, &error, &ifp, &sp))
255 {
256 case 1: /* Bad packet */
257 goto freehdrs;
258 case -1: /* Do IPSec */
250 * IPSec checking which handles several cases.
251 * FAST IPSEC: We re-injected the packet.
252 */
253#ifdef IPSEC
254 switch(ip6_ipsec_output(&m, inp, &flags, &error, &ifp, &sp))
255 {
256 case 1: /* Bad packet */
257 goto freehdrs;
258 case -1: /* Do IPSec */
259 needipsec = 1;
259 needipsec = 1;
260 case 0: /* No IPSec */
261 default:
262 break;
263 }
264#endif /* IPSEC */
265
266 /*
267 * Calculate the total length of the extension header chain.
268 * Keep the length of the unfragmentable part for fragmentation.
269 */
270 optlen = 0;
260 case 0: /* No IPSec */
261 default:
262 break;
263 }
264#endif /* IPSEC */
265
266 /*
267 * Calculate the total length of the extension header chain.
268 * Keep the length of the unfragmentable part for fragmentation.
269 */
270 optlen = 0;
271 if (exthdrs.ip6e_hbh)
271 if (exthdrs.ip6e_hbh)
272 optlen += exthdrs.ip6e_hbh->m_len;
272 optlen += exthdrs.ip6e_hbh->m_len;
273 if (exthdrs.ip6e_dest1)
273 if (exthdrs.ip6e_dest1)
274 optlen += exthdrs.ip6e_dest1->m_len;
274 optlen += exthdrs.ip6e_dest1->m_len;
275 if (exthdrs.ip6e_rthdr)
275 if (exthdrs.ip6e_rthdr)
276 optlen += exthdrs.ip6e_rthdr->m_len;
277 unfragpartlen = optlen + sizeof(struct ip6_hdr);
278
279 /* NOTE: we don't add AH/ESP length here. do that later. */
276 optlen += exthdrs.ip6e_rthdr->m_len;
277 unfragpartlen = optlen + sizeof(struct ip6_hdr);
278
279 /* NOTE: we don't add AH/ESP length here. do that later. */
280 if (exthdrs.ip6e_dest2)
280 if (exthdrs.ip6e_dest2)
281 optlen += exthdrs.ip6e_dest2->m_len;
282
283 /*
284 * If we need IPsec, or there is at least one extension header,
285 * separate IP6 header from the payload.
286 */
287 if ((needipsec || optlen) && !hdrsplit) {
288 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {

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

325 * and we insert headers accordingly. Finally, we should be getting:
326 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
327 *
328 * during the header composing process, "m" points to IPv6 header.
329 * "mprev" points to an extension header prior to esp.
330 */
331 u_char *nexthdrp = &ip6->ip6_nxt;
332 mprev = m;
281 optlen += exthdrs.ip6e_dest2->m_len;
282
283 /*
284 * If we need IPsec, or there is at least one extension header,
285 * separate IP6 header from the payload.
286 */
287 if ((needipsec || optlen) && !hdrsplit) {
288 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {

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

325 * and we insert headers accordingly. Finally, we should be getting:
326 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
327 *
328 * during the header composing process, "m" points to IPv6 header.
329 * "mprev" points to an extension header prior to esp.
330 */
331 u_char *nexthdrp = &ip6->ip6_nxt;
332 mprev = m;
333
333
334 /*
335 * we treat dest2 specially. this makes IPsec processing
336 * much easier. the goal here is to make mprev point the
337 * mbuf prior to dest2.
338 *
339 * result: IPv6 dest2 payload
340 * m and mprev will point to IPv6 header.
341 */
342 if (exthdrs.ip6e_dest2) {
343 if (!hdrsplit)
344 panic("assumption failed: hdr not split");
345 exthdrs.ip6e_dest2->m_next = m->m_next;
346 m->m_next = exthdrs.ip6e_dest2;
347 *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
348 ip6->ip6_nxt = IPPROTO_DSTOPTS;
349 }
334 /*
335 * we treat dest2 specially. this makes IPsec processing
336 * much easier. the goal here is to make mprev point the
337 * mbuf prior to dest2.
338 *
339 * result: IPv6 dest2 payload
340 * m and mprev will point to IPv6 header.
341 */
342 if (exthdrs.ip6e_dest2) {
343 if (!hdrsplit)
344 panic("assumption failed: hdr not split");
345 exthdrs.ip6e_dest2->m_next = m->m_next;
346 m->m_next = exthdrs.ip6e_dest2;
347 *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
348 ip6->ip6_nxt = IPPROTO_DSTOPTS;
349 }
350
350
351 /*
352 * result: IPv6 hbh dest1 rthdr dest2 payload
353 * m will point to IPv6 header. mprev will point to the
354 * extension header prior to dest2 (rthdr in the above case).
355 */
356 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
357 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
358 IPPROTO_DSTOPTS);
359 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
360 IPPROTO_ROUTING);
351 /*
352 * result: IPv6 hbh dest1 rthdr dest2 payload
353 * m will point to IPv6 header. mprev will point to the
354 * extension header prior to dest2 (rthdr in the above case).
355 */
356 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
357 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
358 IPPROTO_DSTOPTS);
359 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
360 IPPROTO_ROUTING);
361
361
362#ifdef IPSEC
363 if (!needipsec)
364 goto skip_ipsec2;
362#ifdef IPSEC
363 if (!needipsec)
364 goto skip_ipsec2;
365
365
366 /*
367 * pointers after IPsec headers are not valid any more.
368 * other pointers need a great care too.
369 * (IPsec routines should not mangle mbufs prior to AH/ESP)
370 */
371 exthdrs.ip6e_dest2 = NULL;
366 /*
367 * pointers after IPsec headers are not valid any more.
368 * other pointers need a great care too.
369 * (IPsec routines should not mangle mbufs prior to AH/ESP)
370 */
371 exthdrs.ip6e_dest2 = NULL;
372
372
373 if (exthdrs.ip6e_rthdr) {
374 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
375 segleft_org = rh->ip6r_segleft;
376 rh->ip6r_segleft = 0;
377 }
373 if (exthdrs.ip6e_rthdr) {
374 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
375 segleft_org = rh->ip6r_segleft;
376 rh->ip6r_segleft = 0;
377 }
378
378
379 bzero(&state, sizeof(state));
380 state.m = m;
381 error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
382 &needipsectun);
383 m = state.m;
384 if (error) {
385 /* mbuf is already reclaimed in ipsec6_output_trans. */
386 m = NULL;

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

396 /* FALLTHROUGH */
397 case ENOENT:
398 /* don't show these error codes to the user */
399 error = 0;
400 break;
401 }
402 goto bad;
403 } else if (!needipsectun) {
379 bzero(&state, sizeof(state));
380 state.m = m;
381 error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
382 &needipsectun);
383 m = state.m;
384 if (error) {
385 /* mbuf is already reclaimed in ipsec6_output_trans. */
386 m = NULL;

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

396 /* FALLTHROUGH */
397 case ENOENT:
398 /* don't show these error codes to the user */
399 error = 0;
400 break;
401 }
402 goto bad;
403 } else if (!needipsectun) {
404 /*
405 * In the FAST IPSec case we have already
404 /*
405 * In the FAST IPSec case we have already
406 * re-injected the packet and it has been freed
406 * re-injected the packet and it has been freed
407 * by the ipsec_done() function. So, just clean
407 * by the ipsec_done() function. So, just clean
408 * up after ourselves.
408 * up after ourselves.
409 */
409 */
410 m = NULL;
411 goto done;
410 m = NULL;
411 goto done;
412 }
412 }
413 if (exthdrs.ip6e_rthdr) {
414 /* ah6_output doesn't modify mbuf chain */
415 rh->ip6r_segleft = segleft_org;
416 }
417skip_ipsec2:;
418#endif /* IPSEC */
419
420 /*

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

488 bzero((caddr_t)ro, sizeof(*ro));
489 }
490 ro_pmtu = ro;
491 if (opt && opt->ip6po_rthdr)
492 ro = &opt->ip6po_route;
493 dst = (struct sockaddr_in6 *)&ro->ro_dst;
494
495again:
413 if (exthdrs.ip6e_rthdr) {
414 /* ah6_output doesn't modify mbuf chain */
415 rh->ip6r_segleft = segleft_org;
416 }
417skip_ipsec2:;
418#endif /* IPSEC */
419
420 /*

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

488 bzero((caddr_t)ro, sizeof(*ro));
489 }
490 ro_pmtu = ro;
491 if (opt && opt->ip6po_rthdr)
492 ro = &opt->ip6po_route;
493 dst = (struct sockaddr_in6 *)&ro->ro_dst;
494
495again:
496 /*
496 /*
497 * if specified, try to fill in the traffic class field.
498 * do not override if a non-zero value is already set.
499 * we check the diffserv field and the ecn field separately.
500 */
501 if (opt && opt->ip6po_tclass >= 0) {
502 int mask = 0;
503
504 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0)

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

563 /* FALLTHROUGH */
564 case ENOENT:
565 /* don't show these error codes to the user */
566 error = 0;
567 break;
568 }
569 goto bad;
570 } else {
497 * if specified, try to fill in the traffic class field.
498 * do not override if a non-zero value is already set.
499 * we check the diffserv field and the ecn field separately.
500 */
501 if (opt && opt->ip6po_tclass >= 0) {
502 int mask = 0;
503
504 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0)

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

563 /* FALLTHROUGH */
564 case ENOENT:
565 /* don't show these error codes to the user */
566 error = 0;
567 break;
568 }
569 goto bad;
570 } else {
571 /*
572 * In the FAST IPSec case we have already
571 /*
572 * In the FAST IPSec case we have already
573 * re-injected the packet and it has been freed
573 * re-injected the packet and it has been freed
574 * by the ipsec_done() function. So, just clean
574 * by the ipsec_done() function. So, just clean
575 * up after ourselves.
576 */
577 m = NULL;
578 goto done;
579 }
580
581 exthdrs.ip6e_ip6 = m;
582 }

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

1053sendorfree:
1054 m = m0->m_nextpkt;
1055 m0->m_nextpkt = 0;
1056 m_freem(m0);
1057 for (m0 = m; m; m = m0) {
1058 m0 = m->m_nextpkt;
1059 m->m_nextpkt = 0;
1060 if (error == 0) {
575 * up after ourselves.
576 */
577 m = NULL;
578 goto done;
579 }
580
581 exthdrs.ip6e_ip6 = m;
582 }

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

1053sendorfree:
1054 m = m0->m_nextpkt;
1055 m0->m_nextpkt = 0;
1056 m_freem(m0);
1057 for (m0 = m; m; m = m0) {
1058 m0 = m->m_nextpkt;
1059 m->m_nextpkt = 0;
1060 if (error == 0) {
1061 /* Record statistics for this interface address. */
1062 if (ia) {
1063 ia->ia_ifa.if_opackets++;
1064 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
1065 }
1061 /* Record statistics for this interface address. */
1062 if (ia) {
1063 ia->ia_ifa.if_opackets++;
1064 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
1065 }
1066 error = nd6_output(ifp, origifp, m, dst, ro->ro_rt);
1067 } else
1068 m_freem(m);
1069 }
1070
1071 if (error == 0)
1072 ip6stat.ip6s_fragmented++;
1073

--- 2240 unchanged lines hidden ---
1066 error = nd6_output(ifp, origifp, m, dst, ro->ro_rt);
1067 } else
1068 m_freem(m);
1069 }
1070
1071 if (error == 0)
1072 ip6stat.ip6s_fragmented++;
1073

--- 2240 unchanged lines hidden ---