LCOV - code coverage report
Current view: top level - plugins/nat/dslite - dslite_in2out.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 196 242 81.0 %
Date: 2023-07-05 22:20:52 Functions: 17 23 73.9 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 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             : #include <nat/dslite/dslite.h>
      16             : #include <nat/lib/nat_syslog.h>
      17             : 
      18             : typedef enum
      19             : {
      20             :   DSLITE_IN2OUT_NEXT_IP4_LOOKUP,
      21             :   DSLITE_IN2OUT_NEXT_IP6_ICMP,
      22             :   DSLITE_IN2OUT_NEXT_DROP,
      23             :   DSLITE_IN2OUT_NEXT_SLOWPATH,
      24             :   DSLITE_IN2OUT_N_NEXT,
      25             : } dslite_in2out_next_t;
      26             : 
      27             : static char *dslite_in2out_error_strings[] = {
      28             : #define _(sym,string) string,
      29             :   foreach_dslite_error
      30             : #undef _
      31             : };
      32             : 
      33             : static u32
      34           3 : slow_path (dslite_main_t * dm, dslite_session_key_t * in2out_key,
      35             :            dslite_session_t ** sp, u32 next, u8 * error, u32 thread_index)
      36             : {
      37             :   dslite_b4_t *b4;
      38             :   clib_bihash_kv_16_8_t b4_kv, b4_value;
      39             :   clib_bihash_kv_24_8_t in2out_kv;
      40             :   clib_bihash_kv_8_8_t out2in_kv;
      41             :   dlist_elt_t *head_elt, *oldest_elt, *elt;
      42             :   u32 oldest_index;
      43             :   dslite_session_t *s;
      44             :   nat_session_key_t out2in_key;
      45             :   nat_ip4_addr_port_t addr_port;
      46             :   u32 b4_index;
      47             : 
      48           3 :   out2in_key.protocol = in2out_key->proto;
      49           3 :   out2in_key.fib_index = 0;
      50             : 
      51           3 :   b4_kv.key[0] = in2out_key->softwire_id.as_u64[0];
      52           3 :   b4_kv.key[1] = in2out_key->softwire_id.as_u64[1];
      53             : 
      54           3 :   if (clib_bihash_search_16_8
      55           3 :       (&dm->per_thread_data[thread_index].b4_hash, &b4_kv, &b4_value))
      56             :     {
      57           2 :       pool_get (dm->per_thread_data[thread_index].b4s, b4);
      58           2 :       clib_memset (b4, 0, sizeof (*b4));
      59           2 :       b4->addr.as_u64[0] = in2out_key->softwire_id.as_u64[0];
      60           2 :       b4->addr.as_u64[1] = in2out_key->softwire_id.as_u64[1];
      61             : 
      62           2 :       pool_get (dm->per_thread_data[thread_index].list_pool, head_elt);
      63           2 :       b4->sessions_per_b4_list_head_index =
      64           2 :         head_elt - dm->per_thread_data[thread_index].list_pool;
      65           2 :       clib_dlist_init (dm->per_thread_data[thread_index].list_pool,
      66           2 :                        b4->sessions_per_b4_list_head_index);
      67             : 
      68           2 :       b4_index = b4_kv.value = b4 - dm->per_thread_data[thread_index].b4s;
      69           2 :       clib_bihash_add_del_16_8 (&dm->per_thread_data[thread_index].b4_hash,
      70             :                                 &b4_kv, 1);
      71             : 
      72           2 :       vlib_set_simple_counter (&dm->total_b4s, thread_index, 0,
      73           2 :                                pool_elts (dm->
      74           2 :                                           per_thread_data[thread_index].b4s));
      75             :     }
      76             :   else
      77             :     {
      78           1 :       b4_index = b4_value.value;
      79           1 :       b4 =
      80           1 :         pool_elt_at_index (dm->per_thread_data[thread_index].b4s,
      81             :                            b4_value.value);
      82             :     }
      83             : 
      84             :   //TODO configurable quota
      85           3 :   if (b4->nsessions >= 1000)
      86             :     {
      87             :       oldest_index =
      88           0 :         clib_dlist_remove_head (dm->per_thread_data[thread_index].list_pool,
      89           0 :                                 b4->sessions_per_b4_list_head_index);
      90           0 :       ASSERT (oldest_index != ~0);
      91           0 :       clib_dlist_addtail (dm->per_thread_data[thread_index].list_pool,
      92           0 :                           b4->sessions_per_b4_list_head_index, oldest_index);
      93           0 :       oldest_elt =
      94           0 :         pool_elt_at_index (dm->per_thread_data[thread_index].list_pool,
      95             :                            oldest_index);
      96           0 :       s =
      97           0 :         pool_elt_at_index (dm->per_thread_data[thread_index].sessions,
      98             :                            oldest_elt->value);
      99             : 
     100           0 :       in2out_kv.key[0] = s->in2out.as_u64[0];
     101           0 :       in2out_kv.key[1] = s->in2out.as_u64[1];
     102           0 :       in2out_kv.key[2] = s->in2out.as_u64[2];
     103           0 :       clib_bihash_add_del_24_8 (&dm->per_thread_data[thread_index].in2out,
     104             :                                 &in2out_kv, 0);
     105           0 :       out2in_kv.key = s->out2in.as_u64;
     106           0 :       clib_bihash_add_del_8_8 (&dm->per_thread_data[thread_index].out2in,
     107             :                                &out2in_kv, 0);
     108             : 
     109           0 :       addr_port.addr.as_u32 = s->out2in.addr.as_u32;
     110           0 :       addr_port.port = s->out2in.port;
     111             : 
     112           0 :       nat_free_ip4_addr_and_port (&dm->pool, thread_index,
     113           0 :                                   s->out2in.protocol, &addr_port);
     114             : 
     115           0 :       nat_syslog_dslite_apmdel (b4_index, &s->in2out.softwire_id,
     116           0 :                                 &s->in2out.addr, s->in2out.port,
     117           0 :                                 &s->out2in.addr, s->out2in.port,
     118           0 :                                 s->in2out.proto);
     119             : 
     120           0 :       if (nat_alloc_ip4_addr_and_port
     121             :           (&dm->pool, 0, thread_index, thread_index,
     122           0 :            dm->port_per_thread, out2in_key.protocol, &addr_port))
     123           0 :         ASSERT (0);
     124             : 
     125           0 :       out2in_key.addr.as_u32 = addr_port.addr.as_u32;
     126           0 :       out2in_key.port = addr_port.port;
     127             :     }
     128             :   else
     129             :     {
     130           3 :       if (nat_alloc_ip4_addr_and_port
     131             :           (&dm->pool, 0, thread_index, thread_index,
     132           3 :            dm->port_per_thread, out2in_key.protocol, &addr_port))
     133             :         {
     134           0 :           *error = DSLITE_ERROR_OUT_OF_PORTS;
     135           0 :           return DSLITE_IN2OUT_NEXT_DROP;
     136             :         }
     137             : 
     138           3 :       out2in_key.addr.as_u32 = addr_port.addr.as_u32;
     139           3 :       out2in_key.port = addr_port.port;
     140             : 
     141           3 :       pool_get (dm->per_thread_data[thread_index].sessions, s);
     142           3 :       clib_memset (s, 0, sizeof (*s));
     143           3 :       b4->nsessions++;
     144             : 
     145           3 :       pool_get (dm->per_thread_data[thread_index].list_pool, elt);
     146           3 :       clib_dlist_init (dm->per_thread_data[thread_index].list_pool,
     147           3 :                        elt - dm->per_thread_data[thread_index].list_pool);
     148           3 :       elt->value = s - dm->per_thread_data[thread_index].sessions;
     149           3 :       s->per_b4_index = elt - dm->per_thread_data[thread_index].list_pool;
     150           3 :       s->per_b4_list_head_index = b4->sessions_per_b4_list_head_index;
     151           3 :       clib_dlist_addtail (dm->per_thread_data[thread_index].list_pool,
     152           3 :                           s->per_b4_list_head_index,
     153           3 :                           elt - dm->per_thread_data[thread_index].list_pool);
     154             : 
     155           3 :       vlib_set_simple_counter (&dm->total_sessions, thread_index, 0,
     156           3 :                                pool_elts (dm->per_thread_data
     157           3 :                                           [thread_index].sessions));
     158             :     }
     159             : 
     160           3 :   s->in2out = *in2out_key;
     161           3 :   s->out2in = out2in_key;
     162           3 :   *sp = s;
     163           3 :   in2out_kv.key[0] = s->in2out.as_u64[0];
     164           3 :   in2out_kv.key[1] = s->in2out.as_u64[1];
     165           3 :   in2out_kv.key[2] = s->in2out.as_u64[2];
     166           3 :   in2out_kv.value = s - dm->per_thread_data[thread_index].sessions;
     167           3 :   clib_bihash_add_del_24_8 (&dm->per_thread_data[thread_index].in2out,
     168             :                             &in2out_kv, 1);
     169           3 :   out2in_kv.key = s->out2in.as_u64;
     170           3 :   out2in_kv.value = s - dm->per_thread_data[thread_index].sessions;
     171           3 :   clib_bihash_add_del_8_8 (&dm->per_thread_data[thread_index].out2in,
     172             :                            &out2in_kv, 1);
     173             : 
     174           3 :   nat_syslog_dslite_apmadd (b4_index, &s->in2out.softwire_id, &s->in2out.addr,
     175           3 :                             s->in2out.port, &s->out2in.addr, s->out2in.port,
     176           3 :                             s->in2out.proto);
     177             : 
     178           3 :   return next;
     179             : }
     180             : 
     181             : static inline u32
     182           1 : dslite_icmp_in2out (dslite_main_t * dm, ip6_header_t * ip6,
     183             :                     ip4_header_t * ip4, dslite_session_t ** sp, u32 next,
     184             :                     u8 * error, u32 thread_index)
     185             : {
     186           1 :   dslite_session_t *s = 0;
     187           1 :   icmp46_header_t *icmp = ip4_next_header (ip4);
     188             :   clib_bihash_kv_24_8_t kv, value;
     189             :   dslite_session_key_t key;
     190           1 :   u32 n = next;
     191             :   echo_header_t *echo;
     192             :   u32 new_addr, old_addr;
     193             :   u16 old_id, new_id;
     194             :   ip_csum_t sum;
     195             : 
     196           1 :   if (icmp_type_is_error_message (icmp->type))
     197             :     {
     198           0 :       n = DSLITE_IN2OUT_NEXT_DROP;
     199           0 :       *error = DSLITE_ERROR_BAD_ICMP_TYPE;
     200           0 :       goto done;
     201             :     }
     202             : 
     203           1 :   echo = (echo_header_t *) (icmp + 1);
     204             : 
     205           1 :   key.addr = ip4->src_address;
     206           1 :   key.port = echo->identifier;
     207           1 :   key.proto = NAT_PROTOCOL_ICMP;
     208           1 :   key.softwire_id.as_u64[0] = ip6->src_address.as_u64[0];
     209           1 :   key.softwire_id.as_u64[1] = ip6->src_address.as_u64[1];
     210           1 :   key.pad = 0;
     211           1 :   kv.key[0] = key.as_u64[0];
     212           1 :   kv.key[1] = key.as_u64[1];
     213           1 :   kv.key[2] = key.as_u64[2];
     214             : 
     215           1 :   if (clib_bihash_search_24_8
     216           1 :       (&dm->per_thread_data[thread_index].in2out, &kv, &value))
     217             :     {
     218           1 :       n = slow_path (dm, &key, &s, next, error, thread_index);
     219           1 :       if (PREDICT_FALSE (next == DSLITE_IN2OUT_NEXT_DROP))
     220           0 :         goto done;
     221             :     }
     222             :   else
     223             :     {
     224           0 :       s =
     225           0 :         pool_elt_at_index (dm->per_thread_data[thread_index].sessions,
     226             :                            value.value);
     227             :     }
     228             : 
     229           1 :   old_addr = ip4->src_address.as_u32;
     230           1 :   ip4->src_address = s->out2in.addr;
     231           1 :   new_addr = ip4->src_address.as_u32;
     232           1 :   sum = ip4->checksum;
     233           1 :   sum = ip_csum_update (sum, old_addr, new_addr, ip4_header_t, src_address);
     234           1 :   ip4->checksum = ip_csum_fold (sum);
     235             : 
     236           1 :   old_id = echo->identifier;
     237           1 :   echo->identifier = new_id = s->out2in.port;
     238           1 :   sum = icmp->checksum;
     239           1 :   sum = ip_csum_update (sum, old_id, new_id, echo_header_t, identifier);
     240           1 :   icmp->checksum = ip_csum_fold (sum);
     241             : 
     242           1 : done:
     243           1 :   *sp = s;
     244           1 :   return n;
     245             : }
     246             : 
     247             : static inline uword
     248           7 : dslite_in2out_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
     249             :                               vlib_frame_t * frame, u8 is_slow_path)
     250             : {
     251             :   u32 n_left_from, *from, *to_next;
     252             :   dslite_in2out_next_t next_index;
     253             :   u32 node_index;
     254             :   vlib_node_runtime_t *error_node;
     255           7 :   u32 thread_index = vm->thread_index;
     256           7 :   f64 now = vlib_time_now (vm);
     257           7 :   dslite_main_t *dm = &dslite_main;
     258             : 
     259           7 :   node_index =
     260           7 :     is_slow_path ? dm->dslite_in2out_slowpath_node_index :
     261             :     dm->dslite_in2out_node_index;
     262             : 
     263           7 :   error_node = vlib_node_get_runtime (vm, node_index);
     264             : 
     265           7 :   from = vlib_frame_vector_args (frame);
     266           7 :   n_left_from = frame->n_vectors;
     267           7 :   next_index = node->cached_next_index;
     268             : 
     269          14 :   while (n_left_from > 0)
     270             :     {
     271             :       u32 n_left_to_next;
     272             : 
     273           7 :       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
     274             : 
     275          14 :       while (n_left_from > 0 && n_left_to_next > 0)
     276             :         {
     277             :           u32 bi0;
     278             :           vlib_buffer_t *b0;
     279           7 :           u32 next0 = DSLITE_IN2OUT_NEXT_IP4_LOOKUP;
     280             :           ip4_header_t *ip40;
     281             :           ip6_header_t *ip60;
     282           7 :           u8 error0 = DSLITE_ERROR_IN2OUT;
     283             :           u32 proto0;
     284           7 :           dslite_session_t *s0 = 0;
     285             :           clib_bihash_kv_24_8_t kv0, value0;
     286             :           dslite_session_key_t key0;
     287             :           udp_header_t *udp0;
     288             :           tcp_header_t *tcp0;
     289             :           ip_csum_t sum0;
     290             :           u32 new_addr0, old_addr0;
     291             :           u16 old_port0, new_port0;
     292             : 
     293             :           /* speculatively enqueue b0 to the current next frame */
     294           7 :           bi0 = from[0];
     295           7 :           to_next[0] = bi0;
     296           7 :           from += 1;
     297           7 :           to_next += 1;
     298           7 :           n_left_from -= 1;
     299           7 :           n_left_to_next -= 1;
     300             : 
     301           7 :           b0 = vlib_get_buffer (vm, bi0);
     302           7 :           ip60 = vlib_buffer_get_current (b0);
     303             : 
     304           7 :           if (PREDICT_FALSE (ip60->protocol != IP_PROTOCOL_IP_IN_IP))
     305             :             {
     306           1 :               if (ip60->protocol == IP_PROTOCOL_ICMP6)
     307             :                 {
     308           1 :                   next0 = DSLITE_IN2OUT_NEXT_IP6_ICMP;
     309           1 :                   goto trace0;
     310             :                 }
     311           0 :               error0 = DSLITE_ERROR_BAD_IP6_PROTOCOL;
     312           0 :               next0 = DSLITE_IN2OUT_NEXT_DROP;
     313           0 :               goto trace0;
     314             :             }
     315             : 
     316           6 :           ip40 = vlib_buffer_get_current (b0) + sizeof (ip6_header_t);
     317           6 :           proto0 = ip_proto_to_nat_proto (ip40->protocol);
     318             : 
     319           6 :           if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
     320             :             {
     321           0 :               error0 = DSLITE_ERROR_UNSUPPORTED_PROTOCOL;
     322           0 :               next0 = DSLITE_IN2OUT_NEXT_DROP;
     323           0 :               goto trace0;
     324             :             }
     325             : 
     326           6 :           udp0 = ip4_next_header (ip40);
     327           6 :           tcp0 = (tcp_header_t *) udp0;
     328             : 
     329           6 :           if (is_slow_path)
     330             :             {
     331           3 :               if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
     332             :                 {
     333             :                   next0 =
     334           1 :                     dslite_icmp_in2out (dm, ip60, ip40, &s0, next0, &error0,
     335             :                                         thread_index);
     336           1 :                   if (PREDICT_FALSE (next0 == DSLITE_IN2OUT_NEXT_DROP))
     337           0 :                     goto trace0;
     338             : 
     339           1 :                   goto accounting0;
     340             :                 }
     341             :             }
     342             :           else
     343             :             {
     344           3 :               if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
     345             :                 {
     346           1 :                   next0 = DSLITE_IN2OUT_NEXT_SLOWPATH;
     347           1 :                   goto trace0;
     348             :                 }
     349             :             }
     350             : 
     351           4 :           key0.addr = ip40->src_address;
     352           4 :           key0.port = udp0->src_port;
     353           4 :           key0.proto = proto0;
     354           4 :           key0.softwire_id.as_u64[0] = ip60->src_address.as_u64[0];
     355           4 :           key0.softwire_id.as_u64[1] = ip60->src_address.as_u64[1];
     356           4 :           key0.pad = 0;
     357           4 :           kv0.key[0] = key0.as_u64[0];
     358           4 :           kv0.key[1] = key0.as_u64[1];
     359           4 :           kv0.key[2] = key0.as_u64[2];
     360             : 
     361           4 :           if (clib_bihash_search_24_8
     362           4 :               (&dm->per_thread_data[thread_index].in2out, &kv0, &value0))
     363             :             {
     364           4 :               if (is_slow_path)
     365             :                 {
     366             :                   next0 =
     367           2 :                     slow_path (dm, &key0, &s0, next0, &error0, thread_index);
     368           2 :                   if (PREDICT_FALSE (next0 == DSLITE_IN2OUT_NEXT_DROP))
     369           0 :                     goto trace0;
     370             :                 }
     371             :               else
     372             :                 {
     373           2 :                   next0 = DSLITE_IN2OUT_NEXT_SLOWPATH;
     374           2 :                   goto trace0;
     375             :                 }
     376             :             }
     377             :           else
     378             :             {
     379           0 :               s0 =
     380           0 :                 pool_elt_at_index (dm->per_thread_data[thread_index].sessions,
     381             :                                    value0.value);
     382             :             }
     383             : 
     384           2 :           old_addr0 = ip40->src_address.as_u32;
     385           2 :           ip40->src_address = s0->out2in.addr;
     386           2 :           new_addr0 = ip40->src_address.as_u32;
     387           2 :           sum0 = ip40->checksum;
     388             :           sum0 =
     389           2 :             ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
     390             :                             src_address);
     391           2 :           ip40->checksum = ip_csum_fold (sum0);
     392           2 :           if (PREDICT_TRUE (proto0 == NAT_PROTOCOL_TCP))
     393             :             {
     394           1 :               old_port0 = tcp0->src_port;
     395           1 :               tcp0->src_port = s0->out2in.port;
     396           1 :               new_port0 = tcp0->src_port;
     397             : 
     398           1 :               sum0 = tcp0->checksum;
     399             :               sum0 =
     400           1 :                 ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
     401             :                                 dst_address);
     402             :               sum0 =
     403           1 :                 ip_csum_update (sum0, old_port0, new_port0, ip4_header_t,
     404             :                                 length);
     405             :               //mss_clamping (&dslite_main, tcp0, &sum0);
     406           1 :               tcp0->checksum = ip_csum_fold (sum0);
     407             :             }
     408             :           else
     409             :             {
     410           1 :               old_port0 = udp0->src_port;
     411           1 :               udp0->src_port = s0->out2in.port;
     412           1 :               udp0->checksum = 0;
     413             :             }
     414             : 
     415           3 :         accounting0:
     416             :           /* Accounting */
     417           3 :           s0->last_heard = now;
     418           3 :           s0->total_pkts++;
     419           3 :           s0->total_bytes += vlib_buffer_length_in_chain (vm, b0);
     420             :           /* Per-B4 LRU list maintenance */
     421           3 :           clib_dlist_remove (dm->per_thread_data[thread_index].list_pool,
     422           3 :                              s0->per_b4_index);
     423           3 :           clib_dlist_addtail (dm->per_thread_data[thread_index].list_pool,
     424           3 :                               s0->per_b4_list_head_index, s0->per_b4_index);
     425             : 
     426           3 :           ip40->tos =
     427           3 :             (clib_net_to_host_u32
     428           3 :              (ip60->ip_version_traffic_class_and_flow_label) & 0x0ff00000) >>
     429             :             20;
     430           3 :           vlib_buffer_advance (b0, sizeof (ip6_header_t));
     431             : 
     432           7 :         trace0:
     433           7 :           if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
     434             :                              && (b0->flags & VLIB_BUFFER_IS_TRACED)))
     435             :             {
     436           7 :               dslite_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
     437           7 :               t->next_index = next0;
     438           7 :               t->session_index = ~0;
     439           7 :               if (s0)
     440           3 :                 t->session_index =
     441           3 :                   s0 - dm->per_thread_data[thread_index].sessions;
     442             :             }
     443             : 
     444           7 :           b0->error = error_node->errors[error0];
     445             : 
     446             :           /* verify speculative enqueue, maybe switch current next frame */
     447           7 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
     448             :                                            n_left_to_next, bi0, next0);
     449             :         }
     450           7 :       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     451             :     }
     452             : 
     453           7 :   return frame->n_vectors;
     454             : }
     455             : 
     456        2240 : VLIB_NODE_FN (dslite_in2out_node) (vlib_main_t * vm,
     457             :                                    vlib_node_runtime_t * node,
     458             :                                    vlib_frame_t * frame)
     459             : {
     460           4 :   return dslite_in2out_node_fn_inline (vm, node, frame, 0);
     461             : }
     462             : 
     463             : /* *INDENT-OFF* */
     464      143960 : VLIB_REGISTER_NODE (dslite_in2out_node) = {
     465             :   .name = "dslite-in2out",
     466             :   .vector_size = sizeof (u32),
     467             :   .format_trace = format_dslite_trace,
     468             :   .type = VLIB_NODE_TYPE_INTERNAL,
     469             :   .n_errors = ARRAY_LEN (dslite_in2out_error_strings),
     470             :   .error_strings = dslite_in2out_error_strings,
     471             :   .n_next_nodes = DSLITE_IN2OUT_N_NEXT,
     472             :   /* edit / add dispositions here */
     473             :   .next_nodes = {
     474             :     [DSLITE_IN2OUT_NEXT_DROP] = "error-drop",
     475             :     [DSLITE_IN2OUT_NEXT_IP4_LOOKUP] = "ip4-lookup",
     476             :     [DSLITE_IN2OUT_NEXT_IP6_ICMP] = "ip6-icmp-input",
     477             :     [DSLITE_IN2OUT_NEXT_SLOWPATH] = "dslite-in2out-slowpath",
     478             :   },
     479             : };
     480             : /* *INDENT-ON* */
     481             : 
     482        2239 : VLIB_NODE_FN (dslite_in2out_slowpath_node) (vlib_main_t * vm,
     483             :                                             vlib_node_runtime_t * node,
     484             :                                             vlib_frame_t * frame)
     485             : {
     486           3 :   return dslite_in2out_node_fn_inline (vm, node, frame, 1);
     487             : }
     488             : 
     489             : /* *INDENT-OFF* */
     490      143960 : VLIB_REGISTER_NODE (dslite_in2out_slowpath_node) = {
     491             :   .name = "dslite-in2out-slowpath",
     492             :   .vector_size = sizeof (u32),
     493             :   .format_trace = format_dslite_trace,
     494             :   .type = VLIB_NODE_TYPE_INTERNAL,
     495             :   .n_errors = ARRAY_LEN (dslite_in2out_error_strings),
     496             :   .error_strings = dslite_in2out_error_strings,
     497             :   .n_next_nodes = DSLITE_IN2OUT_N_NEXT,
     498             :   /* edit / add dispositions here */
     499             :   .next_nodes = {
     500             :     [DSLITE_IN2OUT_NEXT_DROP] = "error-drop",
     501             :     [DSLITE_IN2OUT_NEXT_IP4_LOOKUP] = "ip4-lookup",
     502             :     [DSLITE_IN2OUT_NEXT_IP6_ICMP] = "ip6-lookup",
     503             :     [DSLITE_IN2OUT_NEXT_SLOWPATH] = "dslite-in2out-slowpath",
     504             :   },
     505             : };
     506             : /* *INDENT-ON* */
     507             : 
     508             : /*
     509             :  * fd.io coding-style-patch-verification: ON
     510             :  *
     511             :  * Local Variables:
     512             :  * eval: (c-set-style "gnu")
     513             :  * End:
     514             :  */

Generated by: LCOV version 1.14