ip_ecn.c revision 62587
162587Sitojun/* $FreeBSD: head/sys/netinet/ip_ecn.c 62587 2000-07-04 16:35:15Z itojun $ */ 262587Sitojun/* $KAME: ip_ecn.c,v 1.7 2000/05/05 11:00:56 sumikawa Exp $ */ 362587Sitojun 455009Sshin/* 555009Sshin * Copyright (C) 1999 WIDE Project. 655009Sshin * All rights reserved. 755009Sshin * 855009Sshin * Redistribution and use in source and binary forms, with or without 955009Sshin * modification, are permitted provided that the following conditions 1055009Sshin * are met: 1155009Sshin * 1. Redistributions of source code must retain the above copyright 1255009Sshin * notice, this list of conditions and the following disclaimer. 1355009Sshin * 2. Redistributions in binary form must reproduce the above copyright 1455009Sshin * notice, this list of conditions and the following disclaimer in the 1555009Sshin * documentation and/or other materials provided with the distribution. 1655009Sshin * 3. Neither the name of the project nor the names of its contributors 1755009Sshin * may be used to endorse or promote products derived from this software 1855009Sshin * without specific prior written permission. 1955009Sshin * 2055009Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2155009Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2255009Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2355009Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2455009Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2555009Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2655009Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2755009Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2855009Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2955009Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3055009Sshin * SUCH DAMAGE. 3155009Sshin * 3255009Sshin */ 3355009Sshin/* 3455009Sshin * ECN consideration on tunnel ingress/egress operation. 3555009Sshin * http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt 3655009Sshin */ 3755009Sshin 3855009Sshin#include "opt_inet.h" 3955009Sshin#include "opt_inet6.h" 4055009Sshin 4155009Sshin#include <sys/param.h> 4255009Sshin#include <sys/systm.h> 4355009Sshin#include <sys/mbuf.h> 4455009Sshin#include <sys/errno.h> 4555009Sshin 4655009Sshin#ifdef INET 4755009Sshin#include <netinet/in.h> 4855009Sshin#include <netinet/in_systm.h> 4955009Sshin#include <netinet/ip.h> 5055009Sshin#endif 5155009Sshin 5255009Sshin#ifdef INET6 5355009Sshin#ifndef INET 5455009Sshin#include <netinet/in.h> 5555009Sshin#endif 5655009Sshin#include <netinet/ip6.h> 5755009Sshin#endif 5855009Sshin 5955009Sshin#include <netinet/ip_ecn.h> 6055009Sshin#ifdef INET6 6155009Sshin#include <netinet6/ip6_ecn.h> 6255009Sshin#endif 6355009Sshin 6455009Sshin/* 6555009Sshin * modify outer ECN (TOS) field on ingress operation (tunnel encapsulation). 6655009Sshin * call it after you've done the default initialization/copy for the outer. 6755009Sshin */ 6855009Sshinvoid 6955009Sshinip_ecn_ingress(mode, outer, inner) 7055009Sshin int mode; 7155009Sshin u_int8_t *outer; 7255009Sshin u_int8_t *inner; 7355009Sshin{ 7455009Sshin if (!outer || !inner) 7555009Sshin panic("NULL pointer passed to ip_ecn_ingress"); 7655009Sshin 7755009Sshin switch (mode) { 7855009Sshin case ECN_ALLOWED: /* ECN allowed */ 7955009Sshin *outer &= ~IPTOS_CE; 8055009Sshin break; 8155009Sshin case ECN_FORBIDDEN: /* ECN forbidden */ 8255009Sshin *outer &= ~(IPTOS_ECT | IPTOS_CE); 8355009Sshin break; 8455009Sshin case ECN_NOCARE: /* no consideration to ECN */ 8555009Sshin break; 8655009Sshin } 8755009Sshin} 8855009Sshin 8955009Sshin/* 9055009Sshin * modify inner ECN (TOS) field on egress operation (tunnel decapsulation). 9155009Sshin * call it after you've done the default initialization/copy for the inner. 9255009Sshin */ 9355009Sshinvoid 9455009Sshinip_ecn_egress(mode, outer, inner) 9555009Sshin int mode; 9655009Sshin u_int8_t *outer; 9755009Sshin u_int8_t *inner; 9855009Sshin{ 9955009Sshin if (!outer || !inner) 10055009Sshin panic("NULL pointer passed to ip_ecn_egress"); 10155009Sshin 10255009Sshin switch (mode) { 10355009Sshin case ECN_ALLOWED: 10455009Sshin if (*outer & IPTOS_CE) 10555009Sshin *inner |= IPTOS_CE; 10655009Sshin break; 10755009Sshin case ECN_FORBIDDEN: /* ECN forbidden */ 10855009Sshin case ECN_NOCARE: /* no consideration to ECN */ 10955009Sshin break; 11055009Sshin } 11155009Sshin} 11255009Sshin 11355009Sshin#ifdef INET6 11455009Sshinvoid 11555009Sshinip6_ecn_ingress(mode, outer, inner) 11655009Sshin int mode; 11755009Sshin u_int32_t *outer; 11855009Sshin u_int32_t *inner; 11955009Sshin{ 12055009Sshin u_int8_t outer8, inner8; 12155009Sshin 12255009Sshin if (!outer || !inner) 12355009Sshin panic("NULL pointer passed to ip6_ecn_ingress"); 12455009Sshin 12555009Sshin outer8 = (ntohl(*outer) >> 20) & 0xff; 12655009Sshin inner8 = (ntohl(*inner) >> 20) & 0xff; 12755009Sshin ip_ecn_ingress(mode, &outer8, &inner8); 12855009Sshin *outer &= ~htonl(0xff << 20); 12955009Sshin *outer |= htonl((u_int32_t)outer8 << 20); 13055009Sshin} 13155009Sshin 13255009Sshinvoid 13355009Sshinip6_ecn_egress(mode, outer, inner) 13455009Sshin int mode; 13555009Sshin u_int32_t *outer; 13655009Sshin u_int32_t *inner; 13755009Sshin{ 13855009Sshin u_int8_t outer8, inner8; 13955009Sshin 14055009Sshin if (!outer || !inner) 14155009Sshin panic("NULL pointer passed to ip6_ecn_egress"); 14255009Sshin 14355009Sshin outer8 = (ntohl(*outer) >> 20) & 0xff; 14455009Sshin inner8 = (ntohl(*inner) >> 20) & 0xff; 14555009Sshin ip_ecn_egress(mode, &outer8, &inner8); 14655009Sshin *inner &= ~htonl(0xff << 20); 14755009Sshin *inner |= htonl((u_int32_t)inner8 << 20); 14855009Sshin} 14955009Sshin#endif 150