LCOV - code coverage report
Current view: top level - vnet/pg - edit.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 60 72 83.3 %
Date: 2023-07-05 22:20:52 Functions: 5 5 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             :  * pg_edit.c: packet generator edits
      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 <vlib/vlib.h>
      41             : #include <vnet/pg/pg.h>
      42             : 
      43             : static void
      44          51 : pg_edit_set_value_helper (pg_edit_t * e, u64 value, u8 * result)
      45             : {
      46             :   int i, j, n_bits_left;
      47             :   u8 *v, tmp[8];
      48             : 
      49          51 :   v = tmp;
      50             : 
      51          51 :   n_bits_left = e->n_bits;
      52          51 :   i = 0;
      53          51 :   j = e->lsb_bit_offset % BITS (v[0]);
      54             : 
      55          51 :   if (n_bits_left > 0 && j != 0)
      56             :     {
      57          18 :       v[i] = (value & 0xff) << j;
      58          18 :       value >>= BITS (v[0]) - j;
      59          18 :       n_bits_left -= BITS (v[0]) - j;
      60          18 :       i += 1;
      61             :     }
      62             : 
      63         109 :   while (n_bits_left > 0)
      64             :     {
      65          58 :       v[i] = value & 0xff;
      66          58 :       value >>= 8;
      67          58 :       n_bits_left -= 8;
      68          58 :       i += 1;
      69             :     }
      70             : 
      71             :   /* Convert to network byte order. */
      72         127 :   for (j = 0; j < i; j++)
      73          76 :     result[j] = v[i - 1 - j];
      74          51 : }
      75             : 
      76             : void
      77          45 : pg_edit_set_value (pg_edit_t * e, int hi_or_lo, u64 value)
      78             : {
      79          45 :   pg_edit_alloc_value (e, hi_or_lo);
      80          45 :   pg_edit_set_value_helper (e, value, e->values[hi_or_lo]);
      81          45 : }
      82             : 
      83             : /* Parse an int either %d or 0x%x into network byte order. */
      84             : uword
      85           6 : unformat_pg_number (unformat_input_t * input, va_list * args)
      86             : {
      87           6 :   u8 *result = va_arg (*args, u8 *);
      88           6 :   pg_edit_t *e = va_arg (*args, pg_edit_t *);
      89             :   u64 value;
      90             : 
      91           6 :   ASSERT (BITS (value) >= e->n_bits);
      92             : 
      93           6 :   if (!unformat (input, "0x%X", sizeof (value), &value)
      94           6 :       && !unformat (input, "%D", sizeof (value), &value))
      95           0 :     return 0;
      96             : 
      97             :   /* Number given does not fit into bit field. */
      98           6 :   if (e->n_bits < 64 && value >= (u64) 1 << (u64) e->n_bits)
      99           0 :     return 0;
     100             : 
     101           6 :   pg_edit_set_value_helper (e, value, result);
     102           6 :   return 1;
     103             : }
     104             : 
     105             : uword
     106          52 : unformat_pg_edit (unformat_input_t * input, va_list * args)
     107             : {
     108          52 :   unformat_function_t *f = va_arg (*args, unformat_function_t *);
     109          52 :   pg_edit_t *e = va_arg (*args, pg_edit_t *);
     110             : 
     111          52 :   pg_edit_alloc_value (e, PG_EDIT_LO);
     112          52 :   if (!unformat_user (input, f, e->values[PG_EDIT_LO], e))
     113           0 :     return 0;
     114             : 
     115          52 :   pg_edit_alloc_value (e, PG_EDIT_HI);
     116          52 :   if (unformat (input, "-%U", f, e->values[PG_EDIT_HI], e))
     117           1 :     e->type = PG_EDIT_INCREMENT;
     118          51 :   else if (unformat (input, "+%U", f, e->values[PG_EDIT_HI], e))
     119           0 :     e->type = PG_EDIT_RANDOM;
     120             :   else
     121          51 :     e->type = PG_EDIT_FIXED;
     122             : 
     123          52 :   return 1;
     124             : }
     125             : 
     126             : uword
     127           6 : unformat_pg_payload (unformat_input_t * input, va_list * args)
     128             : {
     129           6 :   pg_stream_t *s = va_arg (*args, pg_stream_t *);
     130           6 :   vlib_main_t *vm = vlib_get_main ();
     131             :   pg_edit_t *e;
     132             :   u32 i, node_index, len, max_len;
     133             :   u8 *v;
     134             : 
     135           6 :   v = 0;
     136             : 
     137           6 :   if (unformat (input, "incrementing %d", &len))
     138             :     {
     139           6 :       vec_resize (v, len);
     140         538 :       for (i = 0; i < len; i++)
     141         532 :         v[i] = i % len;
     142             :     }
     143           0 :   else if (unformat (input, "hex 0x%U", unformat_hex_string, &v))
     144             :     ;
     145           0 :   else if (unformat (input, "%U", unformat_vlib_node, vm, &node_index))
     146             :     {
     147           0 :       pg_node_t *pn = pg_get_node (node_index);
     148           0 :       if (!pn->unformat_edit)
     149           0 :         return 0;
     150           0 :       return unformat (input, "%U", pn->unformat_edit, s);
     151             :     }
     152             : 
     153             :   else
     154           0 :     return 0;
     155             : 
     156             :   /* Length not including this payload. */
     157           6 :   max_len = pg_edit_group_n_bytes (s, 0);
     158             : 
     159           6 :   if (max_len >= s->max_packet_bytes)
     160             :     {
     161             :       /* no payload */
     162           0 :       len = 0;
     163             :     }
     164             :   else
     165             :     {
     166             :       /* make a bigger v to hold the data */
     167           6 :       len = s->max_packet_bytes - max_len;
     168             :     }
     169             : 
     170           6 :   vec_resize (v, len);
     171             : 
     172           6 :   e = pg_create_edit_group (s, sizeof (e[0]), len, 0);
     173             : 
     174           6 :   e->type = PG_EDIT_FIXED;
     175           6 :   e->n_bits = len * BITS (v[0]);
     176             : 
     177             :   /* Least significant bit is at end of bitstream, since everything is always bigendian. */
     178           6 :   e->lsb_bit_offset = len > 0 ? e->n_bits - BITS (v[0]) : 0;
     179             : 
     180           6 :   e->values[PG_EDIT_LO] = v;
     181             : 
     182           6 :   return 1;
     183             : }
     184             : 
     185             : /*
     186             :  * fd.io coding-style-patch-verification: ON
     187             :  *
     188             :  * Local Variables:
     189             :  * eval: (c-set-style "gnu")
     190             :  * End:
     191             :  */

Generated by: LCOV version 1.14