LCOV - code coverage report
Current view: top level - netinet - ip_ecn.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 25 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ip_ecn.c,v 1.8 2016/09/24 14:51:37 naddy 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 <sys/param.h>
      39             : #include <sys/systm.h>
      40             : #include <sys/mbuf.h>
      41             : 
      42             : #include <netinet/in.h>
      43             : #include <netinet/ip.h>
      44             : 
      45             : #ifdef INET6
      46             : #include <netinet/ip6.h>
      47             : #endif
      48             : 
      49             : #include <netinet/ip_ecn.h>
      50             : 
      51             : /*
      52             :  * ECN and TOS (or TCLASS) processing rules at tunnel encapsulation and
      53             :  * decapsulation from RFC3168:
      54             :  *
      55             :  *                      Outer Hdr at                 Inner Hdr at
      56             :  *                      Encapsulator                 Decapsulator
      57             :  *   Header fields:     --------------------         ------------
      58             :  *     DS Field         copied from inner hdr        no change
      59             :  *     ECN Field        constructed by (I)           constructed by (E)
      60             :  *
      61             :  * ECN_ALLOWED (full functionality):
      62             :  *    (I) if the ECN field in the inner header is set to CE, then set the
      63             :  *    ECN field in the outer header to ECT(0).
      64             :  *    otherwise, copy the ECN field to the outer header.
      65             :  *
      66             :  *    (E) if the ECN field in the outer header is set to CE and the ECN
      67             :  *    field of the inner header is not-ECT, drop the packet.
      68             :  *    if the ECN field in the inner header is set to ECT(0) or ECT(1)
      69             :  *    and the ECN field in the outer header is set to CE, then copy CE to
      70             :  *    the inner header.  otherwise, make no change to the inner header.
      71             :  *
      72             :  * ECN_FORBIDDEN (limited functionality):
      73             :  *    (I) set the ECN field to not-ECT in the outer header.
      74             :  *
      75             :  *    (E) if the ECN field in the outer header is set to CE, drop the packet.
      76             :  *    otherwise, make no change to the ECN field in the inner header.
      77             :  *
      78             :  * the drop rule is for backward compatibility and protection against
      79             :  * erasure of CE.
      80             :  */
      81             : 
      82             : /*
      83             :  * modify outer ECN (TOS) field on ingress operation (tunnel encapsulation).
      84             :  * call it after you've done the default initialization/copy for the outer.
      85             :  */
      86             : void
      87           0 : ip_ecn_ingress(int mode, u_int8_t *outer, u_int8_t *inner)
      88             : {
      89           0 :         if (!outer || !inner)
      90           0 :                 panic("NULL pointer passed to ip_ecn_ingress");
      91             : 
      92           0 :         *outer = *inner;
      93           0 :         switch (mode) {
      94             :         case ECN_ALLOWED:               /* ECN allowed */
      95             :         case ECN_ALLOWED_IPSEC:
      96             :                 /*
      97             :                  * full-functionality: if the inner is CE, set ECT(0)
      98             :                  * to the outer.  otherwise, copy the ECN field.
      99             :                  */
     100           0 :                 if ((*inner & IPTOS_ECN_MASK) == IPTOS_ECN_CE)
     101           0 :                         *outer &= ~IPTOS_ECN_ECT1;
     102             :                 break;
     103             :         case ECN_FORBIDDEN:             /* ECN forbidden */
     104             :                 /*
     105             :                  * limited-functionality: set not-ECT to the outer
     106             :                  */
     107           0 :                 *outer &= ~IPTOS_ECN_MASK;
     108           0 :                 break;
     109             :         case ECN_NOCARE:        /* no consideration to ECN */
     110             :                 break;
     111             :         }
     112           0 : }
     113             : 
     114             : /*
     115             :  * modify inner ECN (TOS) field on egress operation (tunnel decapsulation).
     116             :  * call it after you've done the default initialization/copy for the inner.
     117             :  * the caller should drop the packet if the return value is 0.
     118             :  */
     119             : int
     120           0 : ip_ecn_egress(int mode, u_int8_t *outer, u_int8_t *inner)
     121             : {
     122           0 :         if (!outer || !inner)
     123           0 :                 panic("NULL pointer passed to ip_ecn_egress");
     124             : 
     125           0 :         switch (mode) {
     126             :         case ECN_ALLOWED:
     127             :         case ECN_ALLOWED_IPSEC:
     128             :                 /*
     129             :                  * full-functionality: if the outer is CE and the inner is
     130             :                  * not-ECT, should drop it.  otherwise, copy CE.
     131             :                  * However, according to RFC4301, we should just leave the
     132             :                  * inner as non-ECT for IPsec.
     133             :                  */
     134           0 :                 if ((*outer & IPTOS_ECN_MASK) == IPTOS_ECN_CE) {
     135           0 :                         if ((*inner & IPTOS_ECN_MASK) == IPTOS_ECN_NOTECT) {
     136           0 :                                 if (mode == ECN_ALLOWED_IPSEC)
     137           0 :                                         return (1);
     138             :                                 else
     139           0 :                                         return (0);
     140             :                         }
     141           0 :                         *inner |= IPTOS_ECN_CE;
     142           0 :                 }
     143             :                 break;
     144             :         case ECN_FORBIDDEN:             /* ECN forbidden */
     145             :                 /*
     146             :                  * limited-functionality: if the outer is CE, should drop it.
     147             :                  * otherwise, leave the inner.
     148             :                  */
     149           0 :                 if ((*outer & IPTOS_ECN_MASK) == IPTOS_ECN_CE)
     150           0 :                         return (0);
     151             :                 break;
     152             :         case ECN_NOCARE:        /* no consideration to ECN */
     153             :                 break;
     154             :         }
     155           0 :         return (1);
     156           0 : }

Generated by: LCOV version 1.13