LCOV - code coverage report
Current view: top level - vnet/ip - ip6_pg.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 41 76 53.9 %
Date: 2023-07-05 22:20:52 Functions: 2 3 66.7 %

          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/ip6_pg: IP v4 packet-generator interface
      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             : #include <vnet/ip/ip.h>
      41             : #include <vnet/pg/pg.h>
      42             : 
      43             : static void
      44           0 : ip6_pg_edit_function (pg_main_t * pg,
      45             :                       pg_stream_t * s,
      46             :                       pg_edit_group_t * g, u32 * packets, u32 n_packets)
      47             : {
      48           0 :   vlib_main_t *vm = vlib_get_main ();
      49           0 :   u32 ip_header_offset = g->start_byte_offset;
      50             : 
      51           0 :   while (n_packets >= 2)
      52             :     {
      53             :       u32 pi0, pi1;
      54             :       vlib_buffer_t *p0, *p1;
      55             :       ip6_header_t *ip0, *ip1;
      56             : 
      57           0 :       pi0 = packets[0];
      58           0 :       pi1 = packets[1];
      59           0 :       p0 = vlib_get_buffer (vm, pi0);
      60           0 :       p1 = vlib_get_buffer (vm, pi1);
      61           0 :       n_packets -= 2;
      62           0 :       packets += 2;
      63             : 
      64           0 :       ip0 = (void *) (p0->data + ip_header_offset);
      65           0 :       ip1 = (void *) (p1->data + ip_header_offset);
      66             : 
      67           0 :       ip0->payload_length =
      68           0 :         clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, p0) -
      69           0 :                               ip_header_offset - sizeof (ip0[0]));
      70           0 :       ip1->payload_length =
      71           0 :         clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, p1) -
      72           0 :                               ip_header_offset - sizeof (ip1[0]));
      73             :     }
      74             : 
      75           0 :   while (n_packets >= 1)
      76             :     {
      77             :       u32 pi0;
      78             :       vlib_buffer_t *p0;
      79             :       ip6_header_t *ip0;
      80             : 
      81           0 :       pi0 = packets[0];
      82           0 :       p0 = vlib_get_buffer (vm, pi0);
      83           0 :       n_packets -= 1;
      84           0 :       packets += 1;
      85             : 
      86           0 :       ip0 = (void *) (p0->data + ip_header_offset);
      87             : 
      88           0 :       ip0->payload_length =
      89           0 :         clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, p0) -
      90           0 :                               ip_header_offset - sizeof (ip0[0]));
      91             :     }
      92           0 : }
      93             : 
      94             : typedef struct
      95             : {
      96             :   pg_edit_t ip_version;
      97             :   pg_edit_t traffic_class;
      98             :   pg_edit_t flow_label;
      99             :   pg_edit_t payload_length;
     100             :   pg_edit_t protocol;
     101             :   pg_edit_t hop_limit;
     102             :   pg_edit_t src_address, dst_address;
     103             : } pg_ip6_header_t;
     104             : 
     105             : static inline void
     106           3 : pg_ip6_header_init (pg_ip6_header_t * p)
     107             : {
     108             :   /* Initialize fields that are not bit fields in the IP header. */
     109             : #define _(f) pg_edit_init (&p->f, ip6_header_t, f);
     110           3 :   _(payload_length);
     111           3 :   _(hop_limit);
     112           3 :   _(protocol);
     113           3 :   _(src_address);
     114           3 :   _(dst_address);
     115             : #undef _
     116             : 
     117             :   /* Initialize bit fields. */
     118           3 :   pg_edit_init_bitfield (&p->ip_version, ip6_header_t,
     119             :                          ip_version_traffic_class_and_flow_label, 28, 4);
     120           3 :   pg_edit_init_bitfield (&p->traffic_class, ip6_header_t,
     121             :                          ip_version_traffic_class_and_flow_label, 20, 8);
     122           3 :   pg_edit_init_bitfield (&p->flow_label, ip6_header_t,
     123             :                          ip_version_traffic_class_and_flow_label, 0, 20);
     124           3 : }
     125             : 
     126             : uword
     127           3 : unformat_pg_ip6_header (unformat_input_t * input, va_list * args)
     128             : {
     129           3 :   pg_stream_t *s = va_arg (*args, pg_stream_t *);
     130             :   pg_ip6_header_t *p;
     131             :   u32 group_index;
     132             : 
     133           3 :   p = pg_create_edit_group (s, sizeof (p[0]), sizeof (ip6_header_t),
     134             :                             &group_index);
     135           3 :   pg_ip6_header_init (p);
     136             : 
     137             :   /* Defaults. */
     138           3 :   pg_edit_set_fixed (&p->ip_version, 6);
     139           3 :   pg_edit_set_fixed (&p->traffic_class, 0);
     140           3 :   pg_edit_set_fixed (&p->flow_label, 0);
     141           3 :   pg_edit_set_fixed (&p->hop_limit, 64);
     142             : 
     143           3 :   p->payload_length.type = PG_EDIT_UNSPECIFIED;
     144             : 
     145           3 :   if (!unformat (input, "%U: %U -> %U",
     146             :                  unformat_pg_edit,
     147             :                  unformat_ip_protocol, &p->protocol,
     148             :                  unformat_pg_edit,
     149             :                  unformat_ip6_address, &p->src_address,
     150             :                  unformat_pg_edit, unformat_ip6_address, &p->dst_address))
     151           0 :     goto error;
     152             : 
     153             :   /* Parse options. */
     154             :   while (1)
     155             :     {
     156           3 :       if (unformat (input, "version %U",
     157             :                     unformat_pg_edit, unformat_pg_number, &p->ip_version))
     158             :         ;
     159             : 
     160           3 :       else if (unformat (input, "traffic-class %U",
     161             :                          unformat_pg_edit,
     162             :                          unformat_pg_number, &p->traffic_class))
     163             :         ;
     164             : 
     165           3 :       else if (unformat (input, "length %U",
     166             :                          unformat_pg_edit,
     167             :                          unformat_pg_number, &p->payload_length))
     168             :         ;
     169             : 
     170           3 :       else if (unformat (input, "hop-limit %U",
     171             :                          unformat_pg_edit, unformat_pg_number, &p->hop_limit))
     172             :         ;
     173             : 
     174             :       /* Can't parse input: try next protocol level. */
     175             :       else
     176           3 :         break;
     177             :     }
     178             : 
     179             :   {
     180           3 :     ip_main_t *im = &ip_main;
     181             :     ip_protocol_t protocol;
     182             :     ip_protocol_info_t *pi;
     183             : 
     184           3 :     pi = 0;
     185           3 :     if (p->protocol.type == PG_EDIT_FIXED)
     186             :       {
     187           3 :         protocol = pg_edit_get_value (&p->protocol, PG_EDIT_LO);
     188           3 :         pi = ip_get_protocol_info (im, protocol);
     189             :       }
     190             : 
     191           3 :     if (pi && pi->unformat_pg_edit
     192           3 :         && unformat_user (input, pi->unformat_pg_edit, s))
     193             :       ;
     194             : 
     195           1 :     else if (!unformat_user (input, unformat_pg_payload, s))
     196           0 :       goto error;
     197             : 
     198           3 :     if (p->payload_length.type == PG_EDIT_UNSPECIFIED
     199           3 :         && s->min_packet_bytes == s->max_packet_bytes
     200           3 :         && group_index + 1 < vec_len (s->edit_groups))
     201             :       {
     202           3 :         pg_edit_set_fixed (&p->payload_length,
     203           3 :                            pg_edit_group_n_bytes (s,
     204             :                                                   group_index) -
     205             :                            sizeof (ip6_header_t));
     206             :       }
     207             : 
     208           3 :     p = pg_get_edit_group (s, group_index);
     209           3 :     if (p->payload_length.type == PG_EDIT_UNSPECIFIED)
     210             :       {
     211           0 :         pg_edit_group_t *g = pg_stream_get_group (s, group_index);
     212           0 :         g->edit_function = ip6_pg_edit_function;
     213             :       }
     214             : 
     215           3 :     return 1;
     216             :   }
     217             : 
     218           0 : error:
     219             :   /* Free up any edits we may have added. */
     220           0 :   pg_free_edit_group (s);
     221           0 :   return 0;
     222             : }
     223             : 
     224             : 
     225             : /*
     226             :  * fd.io coding-style-patch-verification: ON
     227             :  *
     228             :  * Local Variables:
     229             :  * eval: (c-set-style "gnu")
     230             :  * End:
     231             :  */

Generated by: LCOV version 1.14