From fa0ac2c5668cb8f387a8e16dcf8d2d7154a09fe2 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Tue, 12 Mar 2019 04:34:53 -0700 Subject: [PATCH] GBP: contracts API fixed length of allowed ethertypes VAPI does not handle two VLAs in one struct. Change-Id: I259c998bef4398ead2bbb9e788350d50c2f05694 Signed-off-by: Neale Ranns --- extras/vom/vom/gbp_contract_cmds.cpp | 34 ++++++++++++-------------- src/plugins/gbp/gbp.api | 4 ++-- src/plugins/gbp/gbp_api.c | 11 +++------ src/plugins/gbp/gbp_contract.c | 46 +++++++++++++++++++++++++++++++----- test/test_gbp.py | 5 +++- 5 files changed, 64 insertions(+), 36 deletions(-) diff --git a/extras/vom/vom/gbp_contract_cmds.cpp b/extras/vom/vom/gbp_contract_cmds.cpp index 9e8a177422b..b5705347791 100644 --- a/extras/vom/vom/gbp_contract_cmds.cpp +++ b/extras/vom/vom/gbp_contract_cmds.cpp @@ -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()); } diff --git a/src/plugins/gbp/gbp.api b/src/plugins/gbp/gbp.api index 303ea1c15cc..ae45159d705 100644 --- a/src/plugins/gbp/gbp.api +++ b/src/plugins/gbp/gbp.api @@ -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 diff --git a/src/plugins/gbp/gbp_api.c b/src/plugins/gbp/gbp_api.c index 3f35555efd1..8878119d766 100644 --- a/src/plugins/gbp/gbp_api.c +++ b/src/plugins/gbp/gbp_api.c @@ -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), diff --git a/src/plugins/gbp/gbp_contract.c b/src/plugins/gbp/gbp_contract.c index 805e9b23d09..e4ac611b16e 100644 --- a/src/plugins/gbp/gbp_contract.c +++ b/src/plugins/gbp/gbp_contract.c @@ -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 ] [dst ]\n", .function = gbp_contract_show, }; /* *INDENT-ON* */ diff --git a/test/test_gbp.py b/test/test_gbp.py index 05a4b4df513..cf9ad251d4b 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -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() -- 2.16.6