LCOV - code coverage report
Current view: top level - vnet/ip - ip_packet.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 28 28 100.0 %
Date: 2023-10-26 01:39:38 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : /*
      16             :  * ip/ip_packet.h: packet format common between ip4 & ip6
      17             :  *
      18             :  * Copyright (c) 2008 Eliot Dresselhaus
      19             :  *
      20             :  * Permission is hereby granted, free of charge, to any person obtaining
      21             :  * a copy of this software and associated documentation files (the
      22             :  * "Software"), to deal in the Software without restriction, including
      23             :  * without limitation the rights to use, copy, modify, merge, publish,
      24             :  * distribute, sublicense, and/or sell copies of the Software, and to
      25             :  * permit persons to whom the Software is furnished to do so, subject to
      26             :  * the following conditions:
      27             :  *
      28             :  * The above copyright notice and this permission notice shall be
      29             :  * included in all copies or substantial portions of the Software.
      30             :  *
      31             :  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      32             :  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      33             :  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      34             :  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      35             :  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      36             :  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
      37             :  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      38             :  */
      39             : 
      40             : #ifndef included_ip_packet_h
      41             : #define included_ip_packet_h
      42             : 
      43             : #include <vppinfra/byte_order.h>
      44             : #include <vppinfra/error.h>
      45             : #include <vppinfra/format.h>
      46             : 
      47             : typedef enum ip_protocol
      48             : {
      49             : #define ip_protocol(n,s) IP_PROTOCOL_##s = n,
      50             : #include "protocols.def"
      51             : #undef ip_protocol
      52             : } __clib_packed ip_protocol_t;
      53             : 
      54             : /* TCP/UDP ports. */
      55             : typedef enum
      56             : {
      57             : #define ip_port(s,n) IP_PORT_##s = n,
      58             : #include "ports.def"
      59             : #undef ip_port
      60             : } ip_port_t;
      61             : 
      62             : /* Classifies protocols into UDP, ICMP or other. */
      63             : typedef enum
      64             : {
      65             :   IP_BUILTIN_PROTOCOL_UDP,
      66             :   IP_BUILTIN_PROTOCOL_ICMP,
      67             :   IP_BUILTIN_PROTOCOL_UNKNOWN,
      68             : } ip_builtin_protocol_t;
      69             : 
      70             : #define foreach_ip_builtin_multicast_group      \
      71             :   _ (1, all_hosts_on_subnet)                    \
      72             :   _ (2, all_routers_on_subnet)                  \
      73             :   _ (4, dvmrp)                                  \
      74             :   _ (5, ospf_all_routers)                       \
      75             :   _ (6, ospf_designated_routers)                \
      76             :   _ (13, pim)                                   \
      77             :   _ (18, vrrp)                                  \
      78             :   _ (102, hsrp)                                 \
      79             :   _ (22, igmp_v3)
      80             : 
      81             : typedef enum
      82             : {
      83             : #define _(n,f) IP_MULTICAST_GROUP_##f = n,
      84             :   foreach_ip_builtin_multicast_group
      85             : #undef _
      86             : } ip_multicast_group_t;
      87             : 
      88             : 
      89             : /**
      90             :  * The set of RFC defined DSCP values.
      91             :  */
      92             : #define foreach_ip_dscp                       \
      93             :   _(0, CS0)                                   \
      94             :   _(8, CS1)                                   \
      95             :   _(10, AF11)                                 \
      96             :   _(12, AF12)                                 \
      97             :   _(14, AF13)                                 \
      98             :   _(16, CS2)                                  \
      99             :   _(18, AF21)                                 \
     100             :   _(20, AF22)                                 \
     101             :   _(22, AF23)                                 \
     102             :   _(24, CS3)                                  \
     103             :   _(26, AF31)                                 \
     104             :   _(28, AF32)                                 \
     105             :   _(30, AF33)                                 \
     106             :   _(32, CS4)                                  \
     107             :   _(34, AF41)                                 \
     108             :   _(36, AF42)                                 \
     109             :   _(38, AF43)                                 \
     110             :   _(40, CS5)                                  \
     111             :   _(46, EF)                                   \
     112             :   _(48, CS6)                                  \
     113             :   _(50, CS7)
     114             : 
     115             : typedef enum ip_dscp_t_
     116             : {
     117             : #define _(n,f) IP_DSCP_##f = n,
     118             :   foreach_ip_dscp
     119             : #undef _
     120             : } __clib_packed ip_dscp_t;
     121             : 
     122             : extern u8 *format_ip_dscp (u8 * s, va_list * va);
     123             : unformat_function_t unformat_ip_dscp;
     124             : 
     125             : /**
     126             :  * IP DSCP bit shift
     127             :  *  The ECN occupies the 2 least significant bits of the TC field
     128             :  */
     129             : #define IP_PACKET_TC_FIELD_DSCP_BIT_SHIFT 2
     130             : #define IP_PACKET_TC_FIELD_ECN_MASK 0x03
     131             : 
     132             : /**
     133             :  * The set of RFC defined DSCP values.
     134             :  */
     135             : #define foreach_ip_ecn                        \
     136             :   _(0, NON_ECN)                               \
     137             :   _(1, ECT_0)                                 \
     138             :   _(2, ECT_1)                                 \
     139             :   _(3, CE)
     140             : 
     141             : typedef enum ip_ecn_t_
     142             : {
     143             : #define _(n,f) IP_ECN_##f = n,
     144             :   foreach_ip_ecn
     145             : #undef _
     146             : } __clib_packed ip_ecn_t;
     147             : 
     148             : STATIC_ASSERT_SIZEOF (ip_ecn_t, 1);
     149             : 
     150             : extern u8 *format_ip_ecn (u8 * s, va_list * va);
     151             : 
     152             : /* Incremental checksum update. */
     153             : typedef uword ip_csum_t;
     154             : 
     155             : always_inline ip_csum_t
     156  8480061730 : ip_csum_with_carry (ip_csum_t sum, ip_csum_t x)
     157             : {
     158  8480061730 :   ip_csum_t t = sum + x;
     159  8480061730 :   return t + (t < x);
     160             : }
     161             : 
     162             : /* Update checksum changing field at even byte offset from x -> 0. */
     163             : always_inline ip_csum_t
     164     1198039 : ip_csum_add_even (ip_csum_t c, ip_csum_t x)
     165             : {
     166             :   ip_csum_t d;
     167             : 
     168     1198039 :   d = c - x;
     169             : 
     170             :   /* Fold in carry from high bit. */
     171     1198039 :   d -= d > c;
     172             : 
     173     1198039 :   ip_csum_t t = ip_csum_with_carry (d, x);
     174     1198040 :   ASSERT ((t - c == 0) || (t - c == ~0));
     175             : 
     176     1198040 :   return d;
     177             : }
     178             : 
     179             : /* Update checksum changing field at even byte offset from 0 -> x. */
     180             : always_inline ip_csum_t
     181     1282082 : ip_csum_sub_even (ip_csum_t c, ip_csum_t x)
     182             : {
     183     1282082 :   return ip_csum_with_carry (c, x);
     184             : }
     185             : 
     186             : always_inline ip_csum_t
     187     1043898 : ip_csum_update_inline (ip_csum_t sum, ip_csum_t old, ip_csum_t new,
     188             :                        u32 field_byte_offset, u32 field_n_bytes)
     189             : {
     190             :   /* For even 1-byte fields on big-endian and odd 1-byte fields on little endian
     191             :      we need to shift byte into place for checksum. */
     192     1043898 :   if ((field_n_bytes % 2)
     193      547477 :       && (field_byte_offset % 2) == CLIB_ARCH_IS_LITTLE_ENDIAN)
     194             :     {
     195      259931 :       old = old << 8;
     196      259931 :       new = new << 8;
     197             :     }
     198     1043898 :   sum = ip_csum_sub_even (sum, old);
     199     1043898 :   sum = ip_csum_add_even (sum, new);
     200     1043898 :   return sum;
     201             : }
     202             : 
     203             : #define ip_csum_update(sum,old,new,type,field)                  \
     204             :   ip_csum_update_inline ((sum), (old), (new),                   \
     205             :                          STRUCT_OFFSET_OF (type, field),        \
     206             :                          STRUCT_SIZE_OF (type, field))
     207             : 
     208             : always_inline u16
     209    26151005 : ip_csum_fold (ip_csum_t c)
     210             : {
     211             :   /* Reduce to 16 bits. */
     212             : #if defined(__x86_64__) && defined(__BMI2__)
     213             :   u64 tmp;
     214      335262 :   asm volatile(
     215             :     /* using ADC is much faster than mov, shift, add sequence
     216             :      * compiler produces */
     217             :     "mov   %k[sum], %k[tmp]                \n\t"
     218             :     "shr   $32, %[sum]                     \n\t"
     219             :     "add   %k[tmp], %k[sum]                \n\t"
     220             :     "mov   $16, %k[tmp]                    \n\t"
     221             :     "shrx  %k[tmp], %k[sum], %k[tmp]       \n\t"
     222             :     "adc   %w[tmp], %w[sum]                \n\t"
     223             :     "adc   $0, %w[sum]                     \n\t"
     224             :     : [ sum ] "+&r"(c), [ tmp ] "=&r"(tmp));
     225             : #else
     226             : #if uword_bits == 64
     227    25815743 :   c = (c & (ip_csum_t) 0xffffffff) + (c >> (ip_csum_t) 32);
     228    25815743 :   c = (c & 0xffff) + (c >> 16);
     229             : #endif
     230             : 
     231    25815743 :   c = (c & 0xffff) + (c >> 16);
     232    25815743 :   c = (c & 0xffff) + (c >> 16);
     233             : #endif
     234    26151005 :   return c;
     235             : }
     236             : 
     237             : extern ip_csum_t (*vnet_incremental_checksum_fp) (ip_csum_t, void *, uword);
     238             : 
     239             : /* Checksum routine. */
     240             : always_inline ip_csum_t
     241    49594135 : ip_incremental_checksum (ip_csum_t sum, void *_data, uword n_bytes)
     242             : {
     243    49594135 :   return (*vnet_incremental_checksum_fp) (sum, _data, n_bytes);
     244             : }
     245             : 
     246             : always_inline u16
     247             : ip_csum_and_memcpy_fold (ip_csum_t sum, void *dst)
     248             : {
     249             :   return ip_csum_fold (sum);
     250             : }
     251             : 
     252             : #endif /* included_ip_packet_h */
     253             : 
     254             : /*
     255             :  * fd.io coding-style-patch-verification: ON
     256             :  *
     257             :  * Local Variables:
     258             :  * eval: (c-set-style "gnu")
     259             :  * End:
     260             :  */

Generated by: LCOV version 1.14