LCOV - code coverage report
Current view: top level - vnet/session - session_rules_table.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 162 302 53.6 %
Date: 2023-07-05 22:20:52 Functions: 17 25 68.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017-2019 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             : #include <vnet/session/mma_16.h>
      17             : #include <vnet/session/mma_template.c>
      18             : #include <vnet/session/mma_40.h>
      19             : #include <vnet/session/mma_template.c>
      20             : #include <vnet/session/session_rules_table.h>
      21             : #include <vnet/session/transport.h>
      22             : 
      23             : u32
      24          12 : session_rule_tag_key_index (u32 ri, u8 is_ip4)
      25             : {
      26          12 :   return ((ri << 1) | is_ip4);
      27             : }
      28             : 
      29             : void
      30           0 : session_rule_tag_key_index_parse (u32 rti_key, u32 * ri, u8 * is_ip4)
      31             : {
      32           0 :   *is_ip4 = rti_key & 1;
      33           0 :   *ri = rti_key >> 1;
      34           0 : }
      35             : 
      36             : u8 *
      37           4 : session_rules_table_rule_tag (session_rules_table_t * srt, u32 ri, u8 is_ip4)
      38             : {
      39             :   uword *tip;
      40             :   session_rule_tag_t *rt;
      41             : 
      42             :   tip =
      43           4 :     hash_get (srt->tags_by_rules, session_rule_tag_key_index (ri, is_ip4));
      44           4 :   if (tip)
      45             :     {
      46           2 :       rt = pool_elt_at_index (srt->rule_tags, *tip);
      47           2 :       return rt->tag;
      48             :     }
      49           2 :   return 0;
      50             : }
      51             : 
      52             : void
      53           6 : session_rules_table_del_tag (session_rules_table_t * srt, u8 * tag, u8 is_ip4)
      54             : {
      55             :   uword *rip, *rtip;
      56             :   session_rule_tag_t *rt;
      57             :   u32 rti_key;
      58             : 
      59           6 :   if (tag == 0)
      60           2 :     return;
      61           4 :   rip = hash_get_mem (srt->rules_by_tag, tag);
      62           4 :   if (!rip)
      63             :     {
      64           0 :       clib_warning ("tag has no rule associated");
      65           0 :       return;
      66             :     }
      67           4 :   rti_key = session_rule_tag_key_index (*rip, is_ip4);
      68           4 :   rtip = hash_get (srt->tags_by_rules, rti_key);
      69           4 :   if (!rtip)
      70             :     {
      71           0 :       clib_warning ("rule has no tag associated");
      72           0 :       return;
      73             :     }
      74           4 :   rt = pool_elt_at_index (srt->rule_tags, *rtip);
      75           4 :   ASSERT (rt);
      76           4 :   hash_unset_mem (srt->rules_by_tag, tag);
      77           4 :   hash_unset (srt->tags_by_rules, rti_key);
      78           4 :   pool_put (srt->rule_tags, rt);
      79             : }
      80             : 
      81             : void
      82          25 : session_rules_table_add_tag (session_rules_table_t * srt, u8 * tag,
      83             :                              u32 rule_index, u8 is_ip4)
      84             : {
      85             :   uword *rip;
      86             :   session_rule_tag_t *rt;
      87             :   u32 rti_key;
      88             : 
      89          25 :   if (tag == 0)
      90          21 :     return;
      91           4 :   rip = hash_get_mem (srt->rules_by_tag, tag);
      92           4 :   if (rip)
      93           0 :     session_rules_table_del_tag (srt, tag, is_ip4);
      94           4 :   pool_get (srt->rule_tags, rt);
      95           4 :   rt->tag = vec_dup (tag);
      96           8 :   hash_set_mem (srt->rules_by_tag, rt->tag, rule_index);
      97           4 :   rti_key = session_rule_tag_key_index (rule_index, is_ip4);
      98           4 :   hash_set (srt->tags_by_rules, rti_key, rt - srt->rule_tags);
      99             : }
     100             : 
     101             : u32
     102          44 : session_rules_table_rule_for_tag (session_rules_table_t * srt, u8 * tag)
     103             : {
     104             :   uword *rp;
     105          44 :   if (tag == 0)
     106          38 :     return SESSION_RULES_TABLE_INVALID_INDEX;
     107           6 :   rp = hash_get_mem (srt->rules_by_tag, tag);
     108           6 :   return (rp == 0 ? SESSION_RULES_TABLE_INVALID_INDEX : *rp);
     109             : }
     110             : 
     111             : static void
     112        7384 : fib_pref_normalize (fib_prefix_t * pref)
     113             : {
     114        7384 :   if (pref->fp_proto == FIB_PROTOCOL_IP4)
     115        7384 :     ip4_address_normalize (&pref->fp_addr.ip4, pref->fp_len);
     116             :   else
     117           0 :     ip6_address_normalize (&pref->fp_addr.ip6, pref->fp_len);
     118        7384 : }
     119             : 
     120             : u8 *
     121           0 : format_session_rule4 (u8 * s, va_list * args)
     122             : {
     123           0 :   session_rules_table_t *srt = va_arg (*args, session_rules_table_t *);
     124           0 :   mma_rule_16_t *sr = va_arg (*args, mma_rule_16_t *);
     125             :   session_mask_or_match_4_t *mask, *match;
     126             :   mma_rules_table_16_t *srt4;
     127           0 :   u8 *tag = 0, *null_tag = format (0, "none");
     128             :   u32 ri;
     129             :   int i;
     130             : 
     131           0 :   srt4 = &srt->session_rules_tables_16;
     132           0 :   ri = mma_rules_table_rule_index_16 (srt4, sr);
     133           0 :   tag = session_rules_table_rule_tag (srt, ri, 1);
     134           0 :   match = (session_mask_or_match_4_t *) & sr->match;
     135           0 :   mask = (session_mask_or_match_4_t *) & sr->mask;
     136             : 
     137           0 :   s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri,
     138             :               format_ip4_address, &match->lcl_ip,
     139             :               ip4_mask_to_preflen (&mask->lcl_ip),
     140           0 :               clib_net_to_host_u16 (match->lcl_port), format_ip4_address,
     141             :               &match->rmt_ip, ip4_mask_to_preflen (&mask->rmt_ip),
     142           0 :               clib_net_to_host_u16 (match->rmt_port), sr->action_index,
     143             :               tag ? tag : null_tag);
     144           0 :   if (vec_len (sr->next_indices))
     145             :     {
     146           0 :       s = format (s, "\n    children: ");
     147           0 :       for (i = 0; i < vec_len (sr->next_indices); i++)
     148           0 :         s = format (s, "%d ", sr->next_indices[i]);
     149             :     }
     150           0 :   vec_free (null_tag);
     151           0 :   return s;
     152             : }
     153             : 
     154             : u8 *
     155           0 : format_session_rule6 (u8 * s, va_list * args)
     156             : {
     157           0 :   session_rules_table_t *srt = va_arg (*args, session_rules_table_t *);
     158           0 :   mma_rule_40_t *sr = va_arg (*args, mma_rule_40_t *);
     159             :   session_mask_or_match_6_t *mask, *match;
     160             :   mma_rules_table_40_t *srt6;
     161           0 :   u8 *tag = 0, *null_tag = format (0, "none");
     162             :   u32 ri;
     163             :   int i;
     164             : 
     165           0 :   srt6 = &srt->session_rules_tables_40;
     166           0 :   ri = mma_rules_table_rule_index_40 (srt6, sr);
     167           0 :   tag = session_rules_table_rule_tag (srt, ri, 0);
     168           0 :   match = (session_mask_or_match_6_t *) & sr->match;
     169           0 :   mask = (session_mask_or_match_6_t *) & sr->mask;
     170             : 
     171           0 :   s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri,
     172             :               format_ip6_address, &match->lcl_ip,
     173             :               ip6_mask_to_preflen (&mask->lcl_ip),
     174           0 :               clib_net_to_host_u16 (match->lcl_port), format_ip6_address,
     175             :               &match->rmt_ip, ip6_mask_to_preflen (&mask->rmt_ip),
     176           0 :               clib_net_to_host_u16 (match->rmt_port), sr->action_index,
     177             :               tag ? tag : null_tag);
     178           0 :   if (vec_len (sr->next_indices))
     179             :     {
     180           0 :       s = format (s, "\n    children: ");
     181           0 :       for (i = 0; i < vec_len (sr->next_indices); i++)
     182           0 :         s = format (s, "%d ", sr->next_indices[i]);
     183             :     }
     184           0 :   vec_free (null_tag);
     185           0 :   return s;
     186             : }
     187             : 
     188             : void *
     189           0 : session_rules_table_get (session_rules_table_t * srt, u8 fib_proto)
     190             : {
     191           0 :   if (fib_proto == FIB_PROTOCOL_IP4)
     192           0 :     return &srt->session_rules_tables_16;
     193           0 :   else if (fib_proto == FIB_PROTOCOL_IP6)
     194           0 :     return &srt->session_rules_tables_40;
     195           0 :   return 0;
     196             : }
     197             : 
     198             : int
     199           5 : rule_cmp_16 (mma_rule_16_t * rule1, mma_rule_16_t * rule2)
     200             : {
     201             :   session_mask_or_match_4_t *m1, *m2;
     202             : 
     203           5 :   m1 = (session_mask_or_match_4_t *) & rule1->max_match;
     204           5 :   m2 = (session_mask_or_match_4_t *) & rule2->max_match;
     205           5 :   if (m1->rmt_ip.as_u32 != m2->rmt_ip.as_u32)
     206           5 :     return (m1->rmt_ip.as_u32 < m2->rmt_ip.as_u32 ? -1 : 1);
     207           0 :   if (m1->lcl_ip.as_u32 != m2->lcl_ip.as_u32)
     208           0 :     return (m1->lcl_ip.as_u32 < m2->lcl_ip.as_u32 ? -1 : 1);
     209           0 :   if (m1->rmt_port != m2->rmt_port)
     210           0 :     return (m1->rmt_port < m2->rmt_port ? -1 : 1);
     211           0 :   if (m1->lcl_port != m2->lcl_port)
     212           0 :     return (m1->lcl_port < m2->lcl_port ? -1 : 1);
     213           0 :   return 0;
     214             : }
     215             : 
     216             : int
     217           0 : rule_cmp_40 (mma_rule_40_t * rule1, mma_rule_40_t * rule2)
     218             : {
     219             :   session_mask_or_match_6_t *r1, *r2;
     220           0 :   r1 = (session_mask_or_match_6_t *) & rule1->max_match;
     221           0 :   r2 = (session_mask_or_match_6_t *) & rule2->max_match;
     222           0 :   if (r1->rmt_ip.as_u64[0] != r2->rmt_ip.as_u64[0])
     223           0 :     return (r1->rmt_ip.as_u64[0] < r2->rmt_ip.as_u64[0] ? -1 : 1);
     224           0 :   if (r1->rmt_ip.as_u64[1] != r2->rmt_ip.as_u64[1])
     225           0 :     return (r1->rmt_ip.as_u64[1] < r2->rmt_ip.as_u64[1] ? -1 : 1);
     226           0 :   if (r1->lcl_ip.as_u64[0] != r2->lcl_ip.as_u64[0])
     227           0 :     return (r1->lcl_ip.as_u64[0] < r2->lcl_ip.as_u64[0] ? -1 : 1);
     228           0 :   if (r1->lcl_ip.as_u64[1] != r2->lcl_ip.as_u64[1])
     229           0 :     return (r1->lcl_ip.as_u64[1] < r2->lcl_ip.as_u64[1]) ? -1 : 1;
     230           0 :   if (r1->rmt_port != r2->rmt_port)
     231           0 :     return (r1->rmt_port < r2->rmt_port ? -1 : 1);
     232           0 :   if (r1->lcl_port != r2->lcl_port)
     233           0 :     return (r1->lcl_port < r2->lcl_port ? -1 : 1);
     234           0 :   return 0;
     235             : }
     236             : 
     237             : void
     238        1867 : session_rules_table_init_rule_16 (mma_rule_16_t * rule,
     239             :                                   fib_prefix_t * lcl, u16 lcl_port,
     240             :                                   fib_prefix_t * rmt, u16 rmt_port)
     241             : {
     242             :   session_mask_or_match_4_t *match, *mask, *max_match;
     243        1867 :   fib_pref_normalize (lcl);
     244        1867 :   fib_pref_normalize (rmt);
     245        1867 :   match = (session_mask_or_match_4_t *) & rule->match;
     246        1867 :   match->lcl_ip.as_u32 = lcl->fp_addr.ip4.as_u32;
     247        1867 :   match->rmt_ip.as_u32 = rmt->fp_addr.ip4.as_u32;
     248        1867 :   match->lcl_port = lcl_port;
     249        1867 :   match->rmt_port = rmt_port;
     250        1867 :   mask = (session_mask_or_match_4_t *) & rule->mask;
     251        1867 :   ip4_preflen_to_mask (lcl->fp_len, &mask->lcl_ip);
     252        1867 :   ip4_preflen_to_mask (rmt->fp_len, &mask->rmt_ip);
     253        1867 :   mask->lcl_port = lcl_port == 0 ? 0 : (u16) ~ 0;
     254        1867 :   mask->rmt_port = rmt_port == 0 ? 0 : (u16) ~ 0;
     255        1867 :   max_match = (session_mask_or_match_4_t *) & rule->max_match;
     256        1867 :   ip4_prefix_max_address_host_order (&rmt->fp_addr.ip4, rmt->fp_len,
     257             :                                      &max_match->rmt_ip);
     258        1867 :   ip4_prefix_max_address_host_order (&lcl->fp_addr.ip4, lcl->fp_len,
     259             :                                      &max_match->lcl_ip);
     260        1867 :   max_match->lcl_port = lcl_port == 0 ? (u16) ~ 0 : lcl_port;
     261        1867 :   max_match->rmt_port = rmt_port == 0 ? (u16) ~ 0 : rmt_port;
     262        1867 : }
     263             : 
     264             : void
     265        1825 : session_rules_table_init_rule_40 (mma_rule_40_t * rule,
     266             :                                   fib_prefix_t * lcl, u16 lcl_port,
     267             :                                   fib_prefix_t * rmt, u16 rmt_port)
     268             : {
     269             :   session_mask_or_match_6_t *match, *mask, *max_match;
     270        1825 :   fib_pref_normalize (lcl);
     271        1825 :   fib_pref_normalize (rmt);
     272        1825 :   match = (session_mask_or_match_6_t *) & rule->match;
     273        1825 :   clib_memcpy_fast (&match->lcl_ip, &lcl->fp_addr.ip6,
     274             :                     sizeof (match->lcl_ip));
     275        1825 :   clib_memcpy_fast (&match->rmt_ip, &rmt->fp_addr.ip6,
     276             :                     sizeof (match->rmt_ip));
     277        1825 :   match->lcl_port = lcl_port;
     278        1825 :   match->rmt_port = rmt_port;
     279        1825 :   mask = (session_mask_or_match_6_t *) & rule->mask;
     280        1825 :   ip6_preflen_to_mask (lcl->fp_len, &mask->lcl_ip);
     281        1825 :   ip6_preflen_to_mask (rmt->fp_len, &mask->rmt_ip);
     282        1825 :   mask->lcl_port = lcl_port == 0 ? 0 : (u16) ~ 0;
     283        1825 :   mask->rmt_port = rmt_port == 0 ? 0 : (u16) ~ 0;
     284        1825 :   max_match = (session_mask_or_match_6_t *) & rule->max_match;
     285        1825 :   ip6_prefix_max_address_host_order (&rmt->fp_addr.ip6, rmt->fp_len,
     286             :                                      &max_match->rmt_ip);
     287        1825 :   ip6_prefix_max_address_host_order (&lcl->fp_addr.ip6, lcl->fp_len,
     288             :                                      &max_match->lcl_ip);
     289        1825 :   max_match->lcl_port = lcl_port == 0 ? (u16) ~ 0 : lcl_port;
     290        1825 :   max_match->rmt_port = rmt_port == 0 ? (u16) ~ 0 : rmt_port;
     291        1825 : }
     292             : 
     293             : mma_rule_16_t *
     294        1850 : session_rules_table_alloc_rule_16 (mma_rules_table_16_t * srt,
     295             :                                    fib_prefix_t * lcl, u16 lcl_port,
     296             :                                    fib_prefix_t * rmt, u16 rmt_port)
     297             : {
     298        1850 :   mma_rule_16_t *rule = 0;
     299        1850 :   rule = mma_rules_table_rule_alloc_16 (srt);
     300        1850 :   session_rules_table_init_rule_16 (rule, lcl, lcl_port, rmt, rmt_port);
     301        1850 :   return rule;
     302             : }
     303             : 
     304             : mma_rule_40_t *
     305        1825 : session_rules_table_alloc_rule_40 (mma_rules_table_40_t * srt,
     306             :                                    fib_prefix_t * lcl, u16 lcl_port,
     307             :                                    fib_prefix_t * rmt, u16 rmt_port)
     308             : {
     309             :   mma_rule_40_t *rule;
     310        1825 :   rule = mma_rules_table_rule_alloc_40 (srt);
     311        1825 :   session_rules_table_init_rule_40 (rule, lcl, lcl_port, rmt, rmt_port);
     312        1825 :   return rule;
     313             : }
     314             : 
     315             : u32
     316           4 : session_rules_table_lookup_rule4 (session_rules_table_t * srt,
     317             :                                   ip4_address_t * lcl_ip,
     318             :                                   ip4_address_t * rmt_ip, u16 lcl_port,
     319             :                                   u16 rmt_port)
     320             : {
     321           4 :   mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16;
     322           4 :   session_mask_or_match_4_t key = {
     323           4 :     .lcl_ip.as_u32 = lcl_ip->as_u32,
     324           4 :     .rmt_ip.as_u32 = rmt_ip->as_u32,
     325             :     .lcl_port = lcl_port,
     326             :     .rmt_port = rmt_port,
     327             :   };
     328           4 :   return mma_rules_table_lookup_rule_16 (srt4,
     329             :                                          (mma_mask_or_match_16_t *) & key,
     330             :                                          srt4->root_index);
     331             : }
     332             : 
     333             : u32
     334         463 : session_rules_table_lookup4 (session_rules_table_t * srt,
     335             :                              ip4_address_t * lcl_ip, ip4_address_t * rmt_ip,
     336             :                              u16 lcl_port, u16 rmt_port)
     337             : {
     338         463 :   mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16;
     339         463 :   session_mask_or_match_4_t key = {
     340         463 :     .lcl_ip.as_u32 = lcl_ip->as_u32,
     341         463 :     .rmt_ip.as_u32 = rmt_ip->as_u32,
     342             :     .lcl_port = lcl_port,
     343             :     .rmt_port = rmt_port,
     344             :   };
     345         463 :   return mma_rules_table_lookup_16 (srt4, (mma_mask_or_match_16_t *) & key,
     346             :                                     srt4->root_index);
     347             : }
     348             : 
     349             : u32
     350           0 : session_rules_table_lookup_rule6 (session_rules_table_t * srt,
     351             :                                   ip6_address_t * lcl_ip,
     352             :                                   ip6_address_t * rmt_ip, u16 lcl_port,
     353             :                                   u16 rmt_port)
     354             : {
     355           0 :   mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40;
     356           0 :   session_mask_or_match_6_t key = {
     357             :     .lcl_port = lcl_port,
     358             :     .rmt_port = rmt_port,
     359             :   };
     360           0 :   clib_memcpy_fast (&key.lcl_ip, lcl_ip, sizeof (*lcl_ip));
     361           0 :   clib_memcpy_fast (&key.rmt_ip, rmt_ip, sizeof (*rmt_ip));
     362           0 :   return mma_rules_table_lookup_rule_40 (srt6,
     363             :                                          (mma_mask_or_match_40_t *) & key,
     364             :                                          srt6->root_index);
     365             : }
     366             : 
     367             : u32
     368          19 : session_rules_table_lookup6 (session_rules_table_t * srt,
     369             :                              ip6_address_t * lcl_ip, ip6_address_t * rmt_ip,
     370             :                              u16 lcl_port, u16 rmt_port)
     371             : {
     372          19 :   mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40;
     373          19 :   session_mask_or_match_6_t key = {
     374             :     .lcl_port = lcl_port,
     375             :     .rmt_port = rmt_port,
     376             :   };
     377          19 :   clib_memcpy_fast (&key.lcl_ip, lcl_ip, sizeof (*lcl_ip));
     378          19 :   clib_memcpy_fast (&key.rmt_ip, rmt_ip, sizeof (*rmt_ip));
     379          19 :   return mma_rules_table_lookup_40 (srt6, (mma_mask_or_match_40_t *) & key,
     380             :                                     srt6->root_index);
     381             : }
     382             : 
     383             : /**
     384             :  * Add/delete session rule
     385             :  *
     386             :  * @param srt table where rule should be added
     387             :  * @param args rule arguments
     388             :  *
     389             :  * @return 0 if success, clib_error_t error otherwise
     390             :  */
     391             : int
     392          44 : session_rules_table_add_del (session_rules_table_t * srt,
     393             :                              session_rule_table_add_del_args_t * args)
     394             : {
     395          44 :   u8 fib_proto = args->rmt.fp_proto, *rt;
     396             :   u32 ri_from_tag, ri;
     397             :   int rv;
     398             : 
     399          44 :   ri_from_tag = session_rules_table_rule_for_tag (srt, args->tag);
     400          44 :   if (args->is_add && ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX)
     401           0 :     return VNET_API_ERROR_INVALID_VALUE;
     402             : 
     403          44 :   if (fib_proto == FIB_PROTOCOL_IP4)
     404             :     {
     405             :       mma_rules_table_16_t *srt4;
     406          44 :       srt4 = &srt->session_rules_tables_16;
     407          44 :       if (args->is_add)
     408             :         {
     409             :           mma_rule_16_t *rule4;
     410          25 :           rule4 = session_rules_table_alloc_rule_16 (srt4, &args->lcl,
     411          25 :                                                      args->lcl_port,
     412             :                                                      &args->rmt,
     413          25 :                                                      args->rmt_port);
     414          25 :           rule4->action_index = args->action_index;
     415          25 :           rv = mma_rules_table_add_rule_16 (srt4, rule4);
     416          25 :           if (!rv)
     417             :             {
     418          21 :               ri = mma_rules_table_rule_index_16 (srt4, rule4);
     419          21 :               session_rules_table_add_tag (srt, args->tag, ri, 1);
     420             :             }
     421             :           else
     422             :             {
     423           4 :               ri = session_rules_table_lookup_rule4 (srt,
     424             :                                                      &args->lcl.fp_addr.ip4,
     425             :                                                      &args->rmt.fp_addr.ip4,
     426           4 :                                                      args->lcl_port,
     427           4 :                                                      args->rmt_port);
     428           4 :               if (ri != SESSION_RULES_TABLE_INVALID_INDEX)
     429             :                 {
     430           4 :                   rt = session_rules_table_rule_tag (srt, ri, 1);
     431           4 :                   session_rules_table_del_tag (srt, rt, 1);
     432           4 :                   session_rules_table_add_tag (srt, args->tag, ri, 1);
     433             :                 }
     434             :             }
     435             :         }
     436             :       else
     437             :         {
     438             :           mma_rule_16_t *rule;
     439          19 :           if (ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX)
     440             :             {
     441           2 :               rule = mma_rules_table_get_rule_16 (srt4, ri_from_tag);
     442           2 :               mma_rules_table_del_rule_16 (srt4, rule, srt4->root_index);
     443           2 :               session_rules_table_del_tag (srt, args->tag, 1);
     444             :             }
     445             :           else
     446             :             {
     447             :               mma_rule_16_t _rule;
     448          17 :               rule = &_rule;
     449          17 :               clib_memset (rule, 0, sizeof (*rule));
     450          17 :               session_rules_table_init_rule_16 (rule, &args->lcl,
     451          17 :                                                 args->lcl_port, &args->rmt,
     452          17 :                                                 args->rmt_port);
     453          17 :               mma_rules_table_del_rule_16 (srt4, rule, srt4->root_index);
     454             :             }
     455             :         }
     456             :     }
     457           0 :   else if (fib_proto == FIB_PROTOCOL_IP6)
     458             :     {
     459             :       mma_rules_table_40_t *srt6;
     460             :       mma_rule_40_t *rule6;
     461           0 :       srt6 = &srt->session_rules_tables_40;
     462           0 :       if (args->is_add)
     463             :         {
     464           0 :           rule6 = session_rules_table_alloc_rule_40 (srt6, &args->lcl,
     465           0 :                                                      args->lcl_port,
     466             :                                                      &args->rmt,
     467           0 :                                                      args->rmt_port);
     468           0 :           rule6->action_index = args->action_index;
     469           0 :           rv = mma_rules_table_add_rule_40 (srt6, rule6);
     470           0 :           if (!rv)
     471             :             {
     472           0 :               ri = mma_rules_table_rule_index_40 (srt6, rule6);
     473           0 :               session_rules_table_add_tag (srt, args->tag, ri, 0);
     474             :             }
     475             :           else
     476             :             {
     477           0 :               ri = session_rules_table_lookup_rule6 (srt,
     478             :                                                      &args->lcl.fp_addr.ip6,
     479             :                                                      &args->rmt.fp_addr.ip6,
     480           0 :                                                      args->lcl_port,
     481           0 :                                                      args->rmt_port);
     482           0 :               if (ri != SESSION_RULES_TABLE_INVALID_INDEX)
     483             :                 {
     484           0 :                   rt = session_rules_table_rule_tag (srt, ri, 0);
     485           0 :                   session_rules_table_del_tag (srt, rt, 1);
     486           0 :                   session_rules_table_add_tag (srt, args->tag, ri, 0);
     487             :                 }
     488             :             }
     489             :         }
     490             :       else
     491             :         {
     492             :           mma_rule_40_t *rule;
     493           0 :           if (ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX)
     494             :             {
     495           0 :               rule = mma_rules_table_get_rule_40 (srt6, ri_from_tag);
     496           0 :               mma_rules_table_del_rule_40 (srt6, rule, srt6->root_index);
     497           0 :               session_rules_table_del_tag (srt, args->tag, 0);
     498             :             }
     499             :           else
     500             :             {
     501             :               mma_rule_40_t _rule;
     502           0 :               rule = &_rule;
     503           0 :               clib_memset (rule, 0, sizeof (*rule));
     504           0 :               session_rules_table_init_rule_40 (rule, &args->lcl,
     505           0 :                                                 args->lcl_port, &args->rmt,
     506           0 :                                                 args->rmt_port);
     507           0 :               mma_rules_table_del_rule_40 (srt6, rule, srt6->root_index);
     508             :             }
     509             :         }
     510             :     }
     511             :   else
     512           0 :     return VNET_API_ERROR_INVALID_VALUE_2;
     513          44 :   return 0;
     514             : }
     515             : 
     516             : void
     517          24 : session_rules_table_free (session_rules_table_t *srt)
     518             : {
     519          24 :   mma_rules_table_free_16 (&srt->session_rules_tables_16);
     520          24 :   mma_rules_table_free_40 (&srt->session_rules_tables_40);
     521          24 : }
     522             : 
     523             : void
     524        1825 : session_rules_table_init (session_rules_table_t * srt)
     525             : {
     526             :   mma_rules_table_16_t *srt4;
     527             :   mma_rules_table_40_t *srt6;
     528             :   mma_rule_16_t *rule4;
     529             :   mma_rule_40_t *rule6;
     530             :   fib_prefix_t null_prefix;
     531             : 
     532        1825 :   clib_memset (&null_prefix, 0, sizeof (null_prefix));
     533             : 
     534        1825 :   srt4 = &srt->session_rules_tables_16;
     535        1825 :   rule4 = session_rules_table_alloc_rule_16 (srt4, &null_prefix, 0,
     536             :                                              &null_prefix, 0);
     537        1825 :   rule4->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
     538        1825 :   srt4->root_index = mma_rules_table_rule_index_16 (srt4, rule4);
     539        1825 :   srt4->rule_cmp_fn = rule_cmp_16;
     540             : 
     541        1825 :   srt6 = &srt->session_rules_tables_40;
     542        1825 :   rule6 = session_rules_table_alloc_rule_40 (srt6, &null_prefix, 0,
     543             :                                              &null_prefix, 0);
     544        1825 :   rule6->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
     545        1825 :   srt6->root_index = mma_rules_table_rule_index_40 (srt6, rule6);
     546        1825 :   srt6->rule_cmp_fn = rule_cmp_40;
     547             : 
     548        1825 :   srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
     549        1825 :   srt->tags_by_rules = hash_create (0, sizeof (uword));
     550        1825 : }
     551             : 
     552             : void
     553           0 : session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt,
     554             :                                ip46_address_t * lcl_ip, u16 lcl_port,
     555             :                                ip46_address_t * rmt_ip, u16 rmt_port,
     556             :                                u8 is_ip4)
     557             : {
     558             :   mma_rules_table_16_t *srt4;
     559             :   mma_rules_table_40_t *srt6;
     560             :   mma_rule_16_t *sr4;
     561             :   mma_rule_40_t *sr6;
     562             :   u32 ri;
     563             : 
     564           0 :   if (is_ip4)
     565             :     {
     566           0 :       srt4 = session_rules_table_get (srt, FIB_PROTOCOL_IP4);
     567           0 :       session_mask_or_match_4_t key = {
     568           0 :         .lcl_ip.as_u32 = lcl_ip->ip4.as_u32,
     569           0 :         .rmt_ip.as_u32 = rmt_ip->ip4.as_u32,
     570             :         .lcl_port = lcl_port,
     571             :         .rmt_port = rmt_port,
     572             :       };
     573             :       ri =
     574           0 :         mma_rules_table_lookup_rule_16 (srt4,
     575             :                                         (mma_mask_or_match_16_t *) & key,
     576             :                                         srt4->root_index);
     577           0 :       sr4 = mma_rules_table_get_rule_16 (srt4, ri);
     578           0 :       vlib_cli_output (vm, "%U", format_session_rule4, srt, sr4);
     579             :     }
     580             :   else
     581             :     {
     582           0 :       srt6 = session_rules_table_get (srt, FIB_PROTOCOL_IP6);
     583           0 :       session_mask_or_match_6_t key = {
     584             :         .lcl_port = lcl_port,
     585             :         .rmt_port = rmt_port,
     586             :       };
     587           0 :       clib_memcpy_fast (&key.lcl_ip, &lcl_ip->ip6, sizeof (lcl_ip->ip6));
     588           0 :       clib_memcpy_fast (&key.rmt_ip, &rmt_ip->ip6, sizeof (rmt_ip->ip6));
     589           0 :       ri = mma_rules_table_lookup_rule_40 (srt6,
     590             :                                            (mma_mask_or_match_40_t *) & key,
     591             :                                            srt6->root_index);
     592           0 :       sr6 = mma_rules_table_get_rule_40 (srt6, ri);
     593           0 :       vlib_cli_output (vm, "%U", format_session_rule6, srt, sr6);
     594             :     }
     595           0 : }
     596             : 
     597             : void
     598           0 : session_rules_table_cli_dump (vlib_main_t * vm, session_rules_table_t * srt,
     599             :                               u8 fib_proto)
     600             : {
     601           0 :   if (fib_proto == FIB_PROTOCOL_IP4)
     602             :     {
     603             :       mma_rules_table_16_t *srt4;
     604             :       mma_rule_16_t *sr4;
     605           0 :       srt4 = &srt->session_rules_tables_16;
     606           0 :       vlib_cli_output (vm, "IP4 rules");
     607             : 
     608             :       /* *INDENT-OFF* */
     609           0 :       pool_foreach (sr4, srt4->rules)  {
     610           0 :         vlib_cli_output (vm, "%U", format_session_rule4, srt, sr4);
     611             :       }
     612             :       /* *INDENT-ON* */
     613             : 
     614             :     }
     615           0 :   else if (fib_proto == FIB_PROTOCOL_IP6)
     616             :     {
     617             :       mma_rules_table_40_t *srt6;
     618             :       mma_rule_40_t *sr6;
     619           0 :       srt6 = &srt->session_rules_tables_40;
     620           0 :       vlib_cli_output (vm, "IP6 rules");
     621             : 
     622             :       /* *INDENT-OFF* */
     623           0 :       pool_foreach (sr6, srt6->rules)  {
     624           0 :         vlib_cli_output (vm, "%U", format_session_rule6, srt, sr6);
     625             :       }
     626             :       /* *INDENT-ON* */
     627             : 
     628             :     }
     629           0 : }
     630             : 
     631             : /*
     632             :  * fd.io coding-style-patch-verification: ON
     633             :  *
     634             :  * Local Variables:
     635             :  * eval: (c-set-style "gnu")
     636             :  * End:
     637             :  */

Generated by: LCOV version 1.14