Home | History | Annotate | Line # | Download | only in netinet
ip_ecn.c revision 1.9
      1 /*	$NetBSD: ip_ecn.c,v 1.9 2000/10/02 03:55:41 itojun Exp $	*/
      2 /*	$KAME: ip_ecn.c,v 1.9 2000/10/01 12:44:48 itojun Exp $	*/
      3 
      4 /*
      5  * Copyright (C) 1999 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:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. Neither the name of the project nor the names of its contributors
     17  *    may be used to endorse or promote products derived from this software
     18  *    without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     30  * SUCH DAMAGE.
     31  *
     32  */
     33 /*
     34  * ECN consideration on tunnel ingress/egress operation.
     35  * http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
     36  */
     37 
     38 #include "opt_inet.h"
     39 
     40 #include <sys/param.h>
     41 #include <sys/systm.h>
     42 #include <sys/malloc.h>
     43 #include <sys/mbuf.h>
     44 #include <sys/errno.h>
     45 
     46 #include <netinet/in.h>
     47 #include <netinet/in_systm.h>
     48 #include <netinet/ip.h>
     49 #ifdef INET6
     50 #include <netinet/ip6.h>
     51 #endif
     52 
     53 #include <netinet/ip_ecn.h>
     54 
     55 /*
     56  * modify outer ECN (TOS) field on ingress operation (tunnel encapsulation).
     57  * call it after you've done the default initialization/copy for the outer.
     58  */
     59 void
     60 ip_ecn_ingress(mode, outer, inner)
     61 	int mode;
     62 	u_int8_t *outer;
     63 	u_int8_t *inner;
     64 {
     65 	if (!outer || !inner)
     66 		panic("NULL pointer passed to ip_ecn_ingress");
     67 
     68 	switch (mode) {
     69 	case ECN_ALLOWED:		/* ECN allowed */
     70 		*outer &= ~IPTOS_CE;
     71 		break;
     72 	case ECN_FORBIDDEN:		/* ECN forbidden */
     73 		*outer &= ~(IPTOS_ECT | IPTOS_CE);
     74 		break;
     75 	case ECN_NOCARE:	/* no consideration to ECN */
     76 		break;
     77 	}
     78 }
     79 
     80 /*
     81  * modify inner ECN (TOS) field on egress operation (tunnel decapsulation).
     82  * call it after you've done the default initialization/copy for the inner.
     83  */
     84 void
     85 ip_ecn_egress(mode, outer, inner)
     86 	int mode;
     87 	u_int8_t *outer;
     88 	u_int8_t *inner;
     89 {
     90 	if (!outer || !inner)
     91 		panic("NULL pointer passed to ip_ecn_egress");
     92 
     93 	switch (mode) {
     94 	case ECN_ALLOWED:
     95 		if (*outer & IPTOS_CE)
     96 			*inner |= IPTOS_CE;
     97 		break;
     98 	case ECN_FORBIDDEN:		/* ECN forbidden */
     99 	case ECN_NOCARE:	/* no consideration to ECN */
    100 		break;
    101 	}
    102 }
    103 
    104 #ifdef INET6
    105 void
    106 ip6_ecn_ingress(mode, outer, inner)
    107 	int mode;
    108 	u_int32_t *outer;
    109 	u_int32_t *inner;
    110 {
    111 	u_int8_t outer8, inner8;
    112 
    113 	if (!outer || !inner)
    114 		panic("NULL pointer passed to ip6_ecn_ingress");
    115 
    116 	outer8 = (ntohl(*outer) >> 20) & 0xff;
    117 	inner8 = (ntohl(*inner) >> 20) & 0xff;
    118 	ip_ecn_ingress(mode, &outer8, &inner8);
    119 	*outer &= ~htonl(0xff << 20);
    120 	*outer |= htonl((u_int32_t)outer8 << 20);
    121 }
    122 
    123 void
    124 ip6_ecn_egress(mode, outer, inner)
    125 	int mode;
    126 	u_int32_t *outer;
    127 	u_int32_t *inner;
    128 {
    129 	u_int8_t outer8, inner8;
    130 
    131 	if (!outer || !inner)
    132 		panic("NULL pointer passed to ip6_ecn_egress");
    133 
    134 	outer8 = (ntohl(*outer) >> 20) & 0xff;
    135 	inner8 = (ntohl(*inner) >> 20) & 0xff;
    136 	ip_ecn_egress(mode, &outer8, &inner8);
    137 	*inner &= ~htonl(0xff << 20);
    138 	*inner |= htonl((u_int32_t)inner8 << 20);
    139 }
    140 #endif
    141