GBP: contracts API fixed length of allowed ethertypes 09/18209/3
authorNeale Ranns <nranns@cisco.com>
Tue, 12 Mar 2019 11:34:53 +0000 (04:34 -0700)
committerNeale Ranns <nranns@cisco.com>
Tue, 12 Mar 2019 15:45:25 +0000 (15:45 +0000)
VAPI does not handle two VLAs in one struct.

Change-Id: I259c998bef4398ead2bbb9e788350d50c2f05694
Signed-off-by: Neale Ranns <nranns@cisco.com>
extras/vom/vom/gbp_contract_cmds.cpp
src/plugins/gbp/gbp.api
src/plugins/gbp/gbp_api.c
src/plugins/gbp/gbp_contract.c
test/test_gbp.py

index 9e8a177..b570534 100644 (file)
@@ -42,23 +42,32 @@ create_cmd::operator==(const create_cmd& other) const
           (m_allowed_ethertypes == other.m_allowed_ethertypes));
 }
 
+#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))
+
 rc_t
 create_cmd::issue(connection& con)
 {
   size_t n_rules = m_gbp_rules.size();
-  size_t n_et_rules = 0;
+  uint32_t ii = 0;
 
-  msg_t req(con.ctx(), n_rules, n_et_rules, std::ref(*this));
+  msg_t req(con.ctx(), n_rules, std::ref(*this));
 
   auto& payload = req.get_request().get_payload();
   payload.is_add = 1;
   payload.contract.acl_index = m_acl.value();
   payload.contract.sclass = m_sclass;
   payload.contract.dclass = m_dclass;
-
-  uint32_t ii = 0;
   payload.contract.n_rules = n_rules;
+  payload.contract.n_ether_types = m_allowed_ethertypes.size();
+
+  for (auto tt : m_allowed_ethertypes) {
+    payload.contract.allowed_ethertypes[ii] = tt.value();
+    ii++;
+    if (ii == ARRAY_LEN(payload.contract.allowed_ethertypes))
+      break;
+  }
 
+  ii = 0;
   for (auto rule : m_gbp_rules) {
     if (rule.action() == gbp_rule::action_t::REDIRECT)
       payload.contract.rules[ii].action = GBP_API_RULE_REDIRECT;
@@ -88,19 +97,6 @@ create_cmd::issue(connection& con)
     ++ii;
   }
 
-  u8* data;
-  u16* et;
-
-  data = (((u8*)&payload.contract.n_ether_types) +
-          (sizeof(payload.contract.rules[0]) * payload.contract.n_rules));
-  *data = m_allowed_ethertypes.size();
-  et = (u16*)(++data);
-  ii = 0;
-  for (auto tt : m_allowed_ethertypes) {
-    et[ii] = tt.value();
-    ii++;
-  }
-
   VAPI_CALL(req.execute());
 
   return (wait());
@@ -136,7 +132,7 @@ delete_cmd::operator==(const delete_cmd& other) const
 rc_t
 delete_cmd::issue(connection& con)
 {
-  msg_t req(con.ctx(), 0, 0, std::ref(*this));
+  msg_t req(con.ctx(), 0, std::ref(*this));
 
   auto& payload = req.get_request().get_payload();
   payload.is_add = 0;
@@ -154,7 +150,7 @@ delete_cmd::to_string() const
 {
   std::ostringstream s;
   s << "gbp-contract-delete: " << m_hw_item.to_string()
-    << " src-epg-id:" << m_sclass << " dst-epg-id:" << m_dclass;
+    << " sclass:" << m_sclass << " dclass:" << m_dclass;
 
   return (s.str());
 }
index 303ea1c..ae45159 100644 (file)
@@ -299,10 +299,10 @@ typedef gbp_contract
   u16 sclass;
   u16 dclass;
   u32 acl_index;
+  u8 n_ether_types;
+  u16 allowed_ethertypes[16];
   u8  n_rules;
   vl_api_gbp_rule_t rules[n_rules];
-  u8 n_ether_types;
-  u16 allowed_ethertypes[n_ether_types];
 };
 
 autoreply define gbp_contract_add_del
index 3f35555..8878119 100644 (file)
@@ -931,8 +931,7 @@ vl_api_gbp_contract_add_del_t_handler (vl_api_gbp_contract_add_del_t * mp)
   u16 *allowed_ethertypes;
   index_t *rules;
   int ii, rv = 0;
-  u8 *data, n_et;
-  u16 *et;
+  u8 n_et;
 
   if (mp->is_add)
     {
@@ -944,19 +943,15 @@ vl_api_gbp_contract_add_del_t_handler (vl_api_gbp_contract_add_del_t * mp)
       allowed_ethertypes = NULL;
 
       /*
-       * move past the variable legnth array of rules to get to the
        * allowed ether types
        */
-      data = (((u8 *) & mp->contract.n_ether_types) +
-             (sizeof (mp->contract.rules[0]) * mp->contract.n_rules));
-      n_et = *data;
-      et = (u16 *) (++data);
+      n_et = mp->contract.n_ether_types;
       vec_validate (allowed_ethertypes, n_et - 1);
 
       for (ii = 0; ii < n_et; ii++)
        {
          /* leave the ether types in network order */
-         allowed_ethertypes[ii] = et[ii];
+         allowed_ethertypes[ii] = mp->contract.allowed_ethertypes[ii];
        }
 
       rv = gbp_contract_update (ntohs (mp->contract.sclass),
index 805e9b2..e4ac611 100644 (file)
@@ -612,8 +612,8 @@ format_gbp_contract (u8 * s, va_list * args)
 
   gc = gbp_contract_get (gci);
 
-  s = format (s, "%U: acl-index:%d",
-             format_gbp_contract_key, &gc->gc_key, gc->gc_acl_index);
+  s = format (s, "[%d] %U: acl-index:%d",
+             gci, format_gbp_contract_key, &gc->gc_key, gc->gc_acl_index);
 
   vec_foreach (gui, gc->gc_rules)
   {
@@ -624,7 +624,8 @@ format_gbp_contract (u8 * s, va_list * args)
   vec_foreach (et, gc->gc_allowed_ethertypes)
   {
     int host_et = clib_net_to_host_u16 (*et);
-    s = format (s, "0x%x, ", host_et);
+    if (0 != host_et)
+      s = format (s, "0x%x, ", host_et);
   }
   s = format (s, "]");
 
@@ -635,14 +636,47 @@ static clib_error_t *
 gbp_contract_show (vlib_main_t * vm,
                   unformat_input_t * input, vlib_cli_command_t * cmd)
 {
+  gbp_contract_t *gc;
+  u32 src, dst;
   index_t gci;
 
+  src = dst = SCLASS_INVALID;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "src %d", &src))
+       ;
+      else if (unformat (input, "dst %d", &dst))
+       ;
+      else
+       break;
+    }
+
   vlib_cli_output (vm, "Contracts:");
 
   /* *INDENT-OFF* */
-  pool_foreach_index (gci, gbp_contract_pool,
+  pool_foreach (gc, gbp_contract_pool,
   ({
-    vlib_cli_output (vm, "  [%d] %U", gci, format_gbp_contract, gci);
+    gci = gc - gbp_contract_pool;
+
+    if (SCLASS_INVALID != src && SCLASS_INVALID != dst)
+      {
+        if (gc->gc_key.gck_src == src &&
+            gc->gc_key.gck_dst == dst)
+          vlib_cli_output (vm, "  %U", format_gbp_contract, gci);
+      }
+    else if (SCLASS_INVALID != src)
+      {
+        if (gc->gc_key.gck_src == src)
+          vlib_cli_output (vm, "  %U", format_gbp_contract, gci);
+      }
+    else if (SCLASS_INVALID != dst)
+      {
+        if (gc->gc_key.gck_dst == dst)
+          vlib_cli_output (vm, "  %U", format_gbp_contract, gci);
+      }
+    else
+      vlib_cli_output (vm, "  %U", format_gbp_contract, gci);
   }));
   /* *INDENT-ON* */
 
@@ -659,7 +693,7 @@ gbp_contract_show (vlib_main_t * vm,
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (gbp_contract_show_node, static) = {
   .path = "show gbp contract",
-  .short_help = "show gbp contract\n",
+  .short_help = "show gbp contract [src <SRC>] [dst <DST>]\n",
   .function = gbp_contract_show,
 };
 /* *INDENT-ON* */
index 05a4b4d..cf9ad25 100644 (file)
@@ -461,6 +461,8 @@ class VppGbpContract(VppObject):
         self.dst_epg = dst_epg
         self.rules = rules
         self.allowed_ethertypes = allowed_ethertypes
+        while (len(self.allowed_ethertypes) < 16):
+            self.allowed_ethertypes.append(0)
 
     def add_vpp_config(self):
         rules = []
@@ -481,7 +483,8 @@ class VppGbpContract(VppObject):
             self.src_epg.sclass,
             self.dst_epg.sclass,
             self.acl_index,
-            [], [])
+            [],
+            self.allowed_ethertypes)
 
     def __str__(self):
         return self.object_id()