From 22b3b846822df2701bb6cb508fa4e023526e5717 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Tue, 17 Apr 2018 19:35:42 +0200 Subject: gbp: Add support for ACL Change-Id: I7513c41307e62068ab5d9739cac393675c6066f8 Signed-off-by: Mohsin Kazmi --- src/plugins/gbp/gbp.h | 10 +++++++ src/plugins/gbp/gbp_api.c | 23 ++++++-------- src/plugins/gbp/gbp_contract.c | 65 +++++++++++++++++++++++++++++++++------- src/plugins/gbp/gbp_contract.h | 23 ++++++++++++-- src/plugins/gbp/gbp_policy.c | 59 +++++++++++++++++++++++++++--------- src/plugins/gbp/gbp_policy_dpo.c | 56 +++++++++++++++++++++++----------- 6 files changed, 178 insertions(+), 58 deletions(-) (limited to 'src/plugins/gbp') diff --git a/src/plugins/gbp/gbp.h b/src/plugins/gbp/gbp.h index 8672fd3b092..06612cd948f 100644 --- a/src/plugins/gbp/gbp.h +++ b/src/plugins/gbp/gbp.h @@ -31,6 +31,8 @@ #ifndef __GBP_H__ #define __GBP_H__ +#include + #include #include #include @@ -38,6 +40,14 @@ #include #include +typedef struct +{ + u32 gbp_acl_user_id; + acl_plugin_methods_t acl_plugin; +} gbp_main_t; + +extern gbp_main_t gbp_main; + #endif /* diff --git a/src/plugins/gbp/gbp_api.c b/src/plugins/gbp/gbp_api.c index 88b2cd1cea9..1f24eedc3d0 100644 --- a/src/plugins/gbp/gbp_api.c +++ b/src/plugins/gbp/gbp_api.c @@ -46,7 +46,7 @@ /* Get the API version number */ #define vl_api_version(n,v) static u32 api_version=(v); -#include +#include #undef vl_api_version #include @@ -63,17 +63,11 @@ _(GBP_CONTRACT_ADD_DEL, gbp_contract_add_del) \ _(GBP_CONTRACT_DUMP, gbp_contract_dump) -/** - * L2 Emulation Main - */ -typedef struct gbp_main_t_ -{ - u16 msg_id_base; -} gbp_main_t; +gbp_main_t gbp_main; -static gbp_main_t gbp_main; +static u16 msg_id_base; -#define GBP_MSG_BASE gbp_main.msg_id_base +#define GBP_MSG_BASE msg_id_base static void vl_api_gbp_endpoint_add_del_t_handler (vl_api_gbp_endpoint_add_del_t * mp) @@ -418,7 +412,7 @@ gbp_contract_send_details (gbp_contract_t * gbpc, void *args) mp->contract.src_epg = ntohl (gbpc->gc_key.gck_src); mp->contract.dst_epg = ntohl (gbpc->gc_key.gck_dst); - mp->contract.acl_index = ntohl (gbpc->gc_acl_index); + mp->contract.acl_index = ntohl (gbpc->gc_value.gc_acl_index); vl_api_send_msg (ctx->reg, (u8 *) mp); @@ -484,10 +478,11 @@ gbp_init (vlib_main_t * vm) gbp_main_t *gbpm = &gbp_main; u8 *name = format (0, "gbp_%08x%c", api_version, 0); - /* Ask for a correctly-sized block of API message decode slots */ - gbpm->msg_id_base = vl_msg_api_get_msg_ids ((char *) name, - VL_MSG_FIRST_AVAILABLE); + gbpm->gbp_acl_user_id = ~0; + /* Ask for a correctly-sized block of API message decode slots */ + msg_id_base = vl_msg_api_get_msg_ids ((char *) name, + VL_MSG_FIRST_AVAILABLE); gbp_api_hookup (vm); /* Add our API messages to the global name_crc hash table */ diff --git a/src/plugins/gbp/gbp_contract.c b/src/plugins/gbp/gbp_contract.c index 71d8bcf4671..a536f89e5fe 100644 --- a/src/plugins/gbp/gbp_contract.c +++ b/src/plugins/gbp/gbp_contract.c @@ -25,22 +25,64 @@ gbp_contract_db_t gbp_contract_db; void gbp_contract_update (epg_id_t src_epg, epg_id_t dst_epg, u32 acl_index) { + gbp_main_t *gm = &gbp_main; + u32 *acl_vec = 0; + gbp_contract_value_t value = { + .gc_lc_index = ~0, + .gc_acl_index = ~0, + }; + uword *p; + gbp_contract_key_t key = { .gck_src = src_epg, .gck_dst = dst_epg, }; - hash_set (gbp_contract_db.gc_hash, key.as_u64, acl_index); + if (~0 == gm->gbp_acl_user_id) + { + acl_plugin_exports_init (&gm->acl_plugin); + gm->gbp_acl_user_id = + gm->acl_plugin.register_user_module ("GBP ACL", "src-epg", "dst-epg"); + } + + p = hash_get (gbp_contract_db.gc_hash, key.as_u64); + if (p != NULL) + { + value.as_u64 = p[0]; + } + else + { + value.gc_lc_index = + gm->acl_plugin.get_lookup_context_index (gm->gbp_acl_user_id, src_epg, + dst_epg); + value.gc_acl_index = acl_index; + hash_set (gbp_contract_db.gc_hash, key.as_u64, value.as_u64); + } + + if (value.gc_lc_index == ~0) + return; + vec_add1 (acl_vec, acl_index); + gm->acl_plugin.set_acl_vec_for_context (value.gc_lc_index, acl_vec); + vec_free (acl_vec); } void gbp_contract_delete (epg_id_t src_epg, epg_id_t dst_epg) { + gbp_main_t *gm = &gbp_main; + uword *p; + gbp_contract_value_t value; gbp_contract_key_t key = { .gck_src = src_epg, .gck_dst = dst_epg, }; + p = hash_get (gbp_contract_db.gc_hash, key.as_u64); + if (p != NULL) + { + value.as_u64 = p[0]; + gm->acl_plugin.put_lookup_context_index (value.gc_lc_index); + } hash_unset (gbp_contract_db.gc_hash, key.as_u64); } @@ -48,14 +90,14 @@ void gbp_contract_walk (gbp_contract_cb_t cb, void *ctx) { gbp_contract_key_t key; - u32 acl_index; + gbp_contract_value_t value; /* *INDENT-OFF* */ - hash_foreach(key.as_u64, acl_index, gbp_contract_db.gc_hash, + hash_foreach(key.as_u64, value.as_u64, gbp_contract_db.gc_hash, ({ gbp_contract_t gbpc = { .gc_key = key, - .gc_acl_index = acl_index, + .gc_value = value, }; if (!cb(&gbpc, ctx)) @@ -112,11 +154,14 @@ gbp_contract_cli (vlib_main_t * vm, * @cliexstart{set gbp contract [del] src-epg dst-epg acl-index } * @cliexend ?*/ +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (gbp_contract_cli_node, static) = { -.path = "gbp contract",.short_help = - "gbp contract [del] src-epg dst-epg acl-index ",.function - = gbp_contract_cli,}; + .path = "gbp contract", + .short_help = + "gbp contract [del] src-epg dst-epg acl-index ", + .function = gbp_contract_cli, +}; /* *INDENT-ON* */ static clib_error_t * @@ -124,15 +169,15 @@ gbp_contract_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { gbp_contract_key_t key; - epg_id_t epg_id; + gbp_contract_value_t value; vlib_cli_output (vm, "Contracts:"); /* *INDENT-OFF* */ - hash_foreach (key.as_u64, epg_id, gbp_contract_db.gc_hash, + hash_foreach (key.as_u64, value.as_u64, gbp_contract_db.gc_hash, { vlib_cli_output (vm, " {%d,%d} -> %d", key.gck_src, - key.gck_dst, epg_id); + key.gck_dst, value.gc_acl_index); }); /* *INDENT-ON* */ diff --git a/src/plugins/gbp/gbp_contract.h b/src/plugins/gbp/gbp_contract.h index 1964098adc3..75f2edca116 100644 --- a/src/plugins/gbp/gbp_contract.h +++ b/src/plugins/gbp/gbp_contract.h @@ -37,6 +37,25 @@ typedef struct gbp_contract_key_t_ }; } gbp_contract_key_t; +/** + * The value for an Contract + */ +typedef struct gbp_contract_value_t_ +{ + union + { + struct + { + /** + * lookup context and acl index + */ + u32 gc_lc_index; + u32 gc_acl_index; + }; + u64 as_u64; + }; +} gbp_contract_value_t; + /** * A Group Based Policy Contract. * Determines the ACL that applies to traffic pass between two endpoint groups @@ -51,7 +70,7 @@ typedef struct gbp_contract_t_ /** * The ACL to apply for packets from the source to the destination EPG */ - u32 gc_acl_index;; + gbp_contract_value_t gc_value; } gbp_contract_t; /** @@ -78,7 +97,7 @@ extern void gbp_contract_walk (gbp_contract_cb_t bgpe, void *ctx); */ extern gbp_contract_db_t gbp_contract_db; -always_inline u32 +always_inline u64 gbp_acl_lookup (gbp_contract_key_t * key) { uword *p; diff --git a/src/plugins/gbp/gbp_policy.c b/src/plugins/gbp/gbp_policy.c index 8f3fc76a019..38254644631 100644 --- a/src/plugins/gbp/gbp_policy.c +++ b/src/plugins/gbp/gbp_policy.c @@ -68,6 +68,7 @@ static uword gbp_policy (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { + gbp_main_t *gm = &gbp_main; gbp_policy_main_t *gpm = &gbp_policy_main; u32 n_left_from, *from, *to_next; u32 next_index; @@ -86,9 +87,11 @@ gbp_policy (vlib_main_t * vm, { gbp_policy_next_t next0; gbp_contract_key_t key0; + gbp_contract_value_t value0 = { + .as_u64 = ~0, + }; u32 bi0, sw_if_index0; vlib_buffer_t *b0; - u32 acl_index0; next0 = GBP_POLICY_NEXT_DENY; bi0 = from[0]; @@ -106,7 +109,6 @@ gbp_policy (vlib_main_t * vm, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; key0.gck_dst = gbp_port_to_epg (sw_if_index0); key0.gck_src = vnet_buffer2 (b0)->gbp.src_epg; - acl_index0 = ~0; if (~0 != key0.gck_src) { @@ -120,20 +122,48 @@ gbp_policy (vlib_main_t * vm, } else { - acl_index0 = gbp_acl_lookup (&key0); + value0.as_u64 = gbp_acl_lookup (&key0); - if (~0 != acl_index0) + if (~0 != value0.gc_lc_index) { + fa_5tuple_opaque_t pkt_5tuple0; + u8 action0 = 0; + u32 acl_pos_p0, acl_match_p0; + u32 rule_match_p0, trace_bitmap0; + u8 *h0, l2_len0; + u16 ether_type0; + u8 is_ip60 = 0; + + l2_len0 = vnet_buffer (b0)->l2.l2_len; + h0 = vlib_buffer_get_current (b0); + + ether_type0 = + clib_net_to_host_u16 (*(u16 *) (h0 + l2_len0 - 2)); + + is_ip60 = (ether_type0 == ETHERNET_TYPE_IP6) ? 1 : 0; /* - * TODO tests against the ACL - */ - /* - * ACL tables are not available outside of ACL plugin - * until then bypass the ACL to next node + * tests against the ACL */ - next0 = - vnet_l2_feature_next (b0, gpm->l2_output_feat_next, - L2OUTPUT_FEAT_GBP_POLICY); + acl_plugin_fill_5tuple_inline (gm-> + acl_plugin.p_acl_main, + value0.gc_lc_index, b0, + is_ip60, + /* is_input */ 0, + /* is_l2_path */ 1, + &pkt_5tuple0); + acl_plugin_match_5tuple_inline (gm-> + acl_plugin.p_acl_main, + value0.gc_lc_index, + &pkt_5tuple0, is_ip60, + &action0, &acl_pos_p0, + &acl_match_p0, + &rule_match_p0, + &trace_bitmap0); + + if (action0 > 0) + next0 = + vnet_l2_feature_next (b0, gpm->l2_output_feat_next, + L2OUTPUT_FEAT_GBP_POLICY); } } } @@ -153,7 +183,7 @@ gbp_policy (vlib_main_t * vm, vlib_add_trace (vm, node, b0, sizeof (*t)); t->src_epg = key0.gck_src; t->dst_epg = key0.gck_dst; - t->acl_index = acl_index0; + t->acl_index = value0.gc_acl_index; } /* verify speculative enqueue, maybe switch current next frame */ @@ -209,6 +239,7 @@ static clib_error_t * gbp_policy_init (vlib_main_t * vm) { gbp_policy_main_t *gpm = &gbp_policy_main; + clib_error_t *error = 0; /* Initialize the feature next-node indexes */ feat_bitmap_init_next_nodes (vm, @@ -217,7 +248,7 @@ gbp_policy_init (vlib_main_t * vm) l2output_get_feat_names (), gpm->l2_output_feat_next); - return 0; + return error; } VLIB_INIT_FUNCTION (gbp_policy_init); diff --git a/src/plugins/gbp/gbp_policy_dpo.c b/src/plugins/gbp/gbp_policy_dpo.c index 0f62fb3445d..e2af1e6daab 100644 --- a/src/plugins/gbp/gbp_policy_dpo.c +++ b/src/plugins/gbp/gbp_policy_dpo.c @@ -13,15 +13,15 @@ * limitations under the License. */ -#include -#include -#include - #include #include #include #include +#include +#include +#include + /** * DPO pool */ @@ -206,8 +206,9 @@ typedef enum always_inline uword gbp_policy_dpo_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * from_frame, fib_protocol_t fproto) + vlib_frame_t * from_frame, u8 is_ip6) { + gbp_main_t *gm = &gbp_main; u32 n_left_from, next_index, *from, *to_next; from = vlib_frame_vector_args (from_frame); @@ -224,8 +225,11 @@ gbp_policy_dpo_inline (vlib_main_t * vm, while (n_left_from > 0 && n_left_to_next > 0) { const gbp_policy_dpo_t *gpd0; - u32 bi0, next0, acl_index0; + u32 bi0, next0; gbp_contract_key_t key0; + gbp_contract_value_t value0 = { + .as_u64 = ~0, + }; vlib_buffer_t *b0; bi0 = from[0]; @@ -235,7 +239,6 @@ gbp_policy_dpo_inline (vlib_main_t * vm, n_left_from -= 1; n_left_to_next -= 1; next0 = GBP_POLICY_DROP; - acl_index0 = ~0; b0 = vlib_get_buffer (vm, bi0); gpd0 = @@ -256,18 +259,35 @@ gbp_policy_dpo_inline (vlib_main_t * vm, } else { - acl_index0 = gbp_acl_lookup (&key0); + value0.as_u64 = gbp_acl_lookup (&key0); - if (~0 != acl_index0) + if (~0 != value0.gc_lc_index) { + fa_5tuple_opaque_t pkt_5tuple0; + u8 action0 = 0; + u32 acl_pos_p0, acl_match_p0; + u32 rule_match_p0, trace_bitmap0; /* - * TODO tests against the ACL - */ - /* - * ACL tables are not available outside of ACL plugin - * until then bypass the ACL to next node + * tests against the ACL */ - next0 = gpd0->gpd_dpo.dpoi_next_node; + acl_plugin_fill_5tuple_inline (gm-> + acl_plugin.p_acl_main, + value0.gc_lc_index, b0, + is_ip6, + /* is_input */ 1, + /* is_l2_path */ 0, + &pkt_5tuple0); + acl_plugin_match_5tuple_inline (gm-> + acl_plugin.p_acl_main, + value0.gc_lc_index, + &pkt_5tuple0, is_ip6, + &action0, &acl_pos_p0, + &acl_match_p0, + &rule_match_p0, + &trace_bitmap0); + + if (action0 > 0) + next0 = gpd0->gpd_dpo.dpoi_next_node; } } } @@ -287,7 +307,7 @@ gbp_policy_dpo_inline (vlib_main_t * vm, tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->src_epg = key0.gck_src; tr->dst_epg = key0.gck_dst; - tr->acl_index = acl_index0; + tr->acl_index = value0.gc_acl_index; } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, @@ -315,14 +335,14 @@ static uword ip4_gbp_policy_dpo (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { - return (gbp_policy_dpo_inline (vm, node, from_frame, FIB_PROTOCOL_IP4)); + return (gbp_policy_dpo_inline (vm, node, from_frame, 0)); } static uword ip6_gbp_policy_dpo (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { - return (gbp_policy_dpo_inline (vm, node, from_frame, FIB_PROTOCOL_IP6)); + return (gbp_policy_dpo_inline (vm, node, from_frame, 1)); } /* *INDENT-OFF* */ -- cgit 1.2.3-korg