The enum version of ovn_stage was too tightly coupled with the particular stages used by ovn-northd for logical switches and logical routers. Using a struct allows for more flexibility for other logical datapaths.
Signed-off-by: Mark Michelson <mmich...@redhat.com> --- northd/lflow-mgr.c | 33 ++++++++-------- northd/lflow-mgr.h | 4 +- northd/northd.c | 96 ++++++++++++++++++++++++++++------------------ northd/northd.h | 65 ++++++++++++++----------------- 4 files changed, 105 insertions(+), 93 deletions(-) diff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c index a4f061b1f..0f7b989cf 100644 --- a/northd/lflow-mgr.c +++ b/northd/lflow-mgr.c @@ -35,13 +35,13 @@ struct ovn_lflow; static void ovn_lflow_init(struct ovn_lflow *, const struct sbrec_datapath_binding *sb_dp, - size_t dp_bitmap_len, enum ovn_stage stage, + size_t dp_bitmap_len, const struct ovn_stage *stage, uint16_t priority, char *match, char *actions, char *io_port, char *ctrl_meter, char *stage_hint, const char *where, const char *flow_desc); static struct ovn_lflow *ovn_lflow_find(const struct hmap *lflows, - enum ovn_stage stage, + const struct ovn_stage *stage, uint16_t priority, const char *match, const char *actions, const char *ctrl_meter, uint32_t hash); @@ -51,7 +51,7 @@ static char *ovn_lflow_hint(const struct ovsdb_idl_row *row); static struct ovn_lflow *do_ovn_lflow_add( struct lflow_table *, size_t dp_bitmap_len, uint32_t hash, - enum ovn_stage stage, uint16_t priority, const char *match, + const struct ovn_stage *stage, uint16_t priority, const char *match, const char *actions, const char *io_port, const char *ctrl_meter, const struct ovsdb_idl_row *stage_hint, @@ -164,7 +164,7 @@ struct ovn_lflow { const struct sbrec_datapath_binding *sb_dp; unsigned long *dpg_bitmap; /* Bitmap of all datapaths by their 'index'.*/ - enum ovn_stage stage; + const struct ovn_stage *stage; uint16_t priority; char *match; char *actions; @@ -300,10 +300,11 @@ lflow_table_sync_to_sb(struct lflow_table *lflow_table, * datapaths, we should only get valid datapath types here. */ ovs_assert(dp_type < DP_MAX); + struct ovn_stage stage = ovn_stage_build(dp_type, pipeline, + sbflow->table_id); lflow = ovn_lflow_find( - lflows, - ovn_stage_build(dp_type, pipeline, sbflow->table_id), + lflows, &stage, sbflow->priority, sbflow->match, sbflow->actions, sbflow->controller_meter, sbflow->hash); if (lflow) { @@ -685,7 +686,7 @@ void lflow_table_add_lflow(struct lflow_table *lflow_table, const struct ovn_datapath *od, const unsigned long *dp_bitmap, size_t dp_bitmap_len, - enum ovn_stage stage, uint16_t priority, + const struct ovn_stage *stage, uint16_t priority, const char *match, const char *actions, const char *io_port, const char *ctrl_meter, const struct ovsdb_idl_row *stage_hint, @@ -757,7 +758,7 @@ lflow_table_add_lflow(struct lflow_table *lflow_table, void lflow_table_add_lflow_default_drop(struct lflow_table *lflow_table, const struct ovn_datapath *od, - enum ovn_stage stage, + const struct ovn_stage *stage, const char *where, struct lflow_ref *lflow_ref) { @@ -880,9 +881,9 @@ lflow_hash_lock_destroy(void) static void ovn_lflow_init(struct ovn_lflow *lflow, const struct sbrec_datapath_binding *sb_dp, - size_t dp_bitmap_len, enum ovn_stage stage, uint16_t priority, - char *match, char *actions, char *io_port, char *ctrl_meter, - char *stage_hint, const char *where, + size_t dp_bitmap_len, const struct ovn_stage *stage, + uint16_t priority, char *match, char *actions, char *io_port, + char *ctrl_meter, char *stage_hint, const char *where, const char *flow_desc) { lflow->dpg_bitmap = bitmap_allocate(dp_bitmap_len); @@ -928,11 +929,11 @@ lflow_hash_unlock(struct ovs_mutex *hash_lock) } static bool -ovn_lflow_equal(const struct ovn_lflow *a, enum ovn_stage stage, +ovn_lflow_equal(const struct ovn_lflow *a, const struct ovn_stage *stage, uint16_t priority, const char *match, const char *actions, const char *ctrl_meter) { - return (a->stage == stage + return (ovn_stage_equal(a->stage, stage) && a->priority == priority && !strcmp(a->match, match) && !strcmp(a->actions, actions) @@ -941,7 +942,7 @@ ovn_lflow_equal(const struct ovn_lflow *a, enum ovn_stage stage, static struct ovn_lflow * ovn_lflow_find(const struct hmap *lflows, - enum ovn_stage stage, uint16_t priority, + const struct ovn_stage *stage, uint16_t priority, const char *match, const char *actions, const char *ctrl_meter, uint32_t hash) { @@ -984,8 +985,8 @@ ovn_lflow_destroy(struct lflow_table *lflow_table, struct ovn_lflow *lflow) static struct ovn_lflow * do_ovn_lflow_add(struct lflow_table *lflow_table, size_t dp_bitmap_len, - uint32_t hash, enum ovn_stage stage, uint16_t priority, - const char *match, const char *actions, + uint32_t hash, const struct ovn_stage *stage, + uint16_t priority, const char *match, const char *actions, const char *io_port, const char *ctrl_meter, const struct ovsdb_idl_row *stage_hint, const char *where, const char *flow_desc) diff --git a/northd/lflow-mgr.h b/northd/lflow-mgr.h index 2e454ce63..4e8aace07 100644 --- a/northd/lflow-mgr.h +++ b/northd/lflow-mgr.h @@ -83,7 +83,7 @@ bool lflow_ref_sync_lflows(struct lflow_ref *, void lflow_table_add_lflow(struct lflow_table *, const struct ovn_datapath *, const unsigned long *dp_bitmap, - size_t dp_bitmap_len, enum ovn_stage stage, + size_t dp_bitmap_len, const struct ovn_stage *stage, uint16_t priority, const char *match, const char *actions, const char *io_port, const char *ctrl_meter, @@ -92,7 +92,7 @@ void lflow_table_add_lflow(struct lflow_table *, const struct ovn_datapath *, struct lflow_ref *); void lflow_table_add_lflow_default_drop(struct lflow_table *, const struct ovn_datapath *, - enum ovn_stage stage, + const struct ovn_stage *stage, const char *where, struct lflow_ref *); diff --git a/northd/northd.c b/northd/northd.c index 0d450738d..3016be949 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -349,18 +349,33 @@ static const char *reg_ct_state[] = { #define ROUTE_PRIO_OFFSET_STATIC 4 #define ROUTE_PRIO_OFFSET_CONNECTED 6 +/* ovn_stages used by northd for logical switches and logical routers. + * The first three components are combined to form the constant stage's + * struct name, e.g. S_SWITCH_IN_PORT_SEC_L2, S_ROUTER_OUT_DELIVERY. + */ +#define PIPELINE_STAGE(DP_TYPE, PIPELINE, STAGE, TABLE, NAME) \ + static const struct ovn_stage T_##DP_TYPE##_##PIPELINE##_##STAGE = { \ + DP_##DP_TYPE, P_##PIPELINE, TABLE, NAME \ + }; \ + static const struct ovn_stage *S_##DP_TYPE##_##PIPELINE##_##STAGE = \ + &T_##DP_TYPE##_##PIPELINE##_##STAGE; + PIPELINE_STAGES +#undef PIPELINE_STAGE + /* Returns the type of the datapath to which a flow with the given 'stage' may * be added. */ enum ovn_datapath_type -ovn_stage_to_datapath_type(enum ovn_stage stage) +ovn_stage_to_datapath_type(const struct ovn_stage *stage) { - switch (stage) { -#define PIPELINE_STAGE(DP_TYPE, PIPELINE, STAGE, TABLE, NAME) \ - case S_##DP_TYPE##_##PIPELINE##_##STAGE: return DP_##DP_TYPE; - PIPELINE_STAGES -#undef PIPELINE_STAGE - default: OVS_NOT_REACHED(); - } + return stage->dp_type; +} + +bool +ovn_stage_equal(const struct ovn_stage *a, const struct ovn_stage *b) +{ + return a->dp_type == b->dp_type && + a->pipeline == b->pipeline && + a->table == b->table; } static uint32_t @@ -5253,7 +5268,7 @@ build_mirror_lflow(struct ovn_port *op, { struct ds match = DS_EMPTY_INITIALIZER; struct ds action = DS_EMPTY_INITIALIZER; - enum ovn_stage stage; + const struct ovn_stage *stage; const char *dir; uint32_t priority = OVN_LPORT_MIRROR_OFFSET + rule->priority; @@ -5285,7 +5300,7 @@ build_mirror_pass_lflow(struct ovn_port *op, { struct ds match = DS_EMPTY_INITIALIZER; struct ds action = DS_EMPTY_INITIALIZER; - enum ovn_stage stage; + const struct ovn_stage *stage; const char *dir; if (egress) { @@ -5554,8 +5569,9 @@ build_lswitch_output_port_sec_od(struct ovn_datapath *od, static void skip_port_from_conntrack(const struct ovn_datapath *od, struct ovn_port *op, - bool has_stateful_acl, enum ovn_stage in_stage, - enum ovn_stage out_stage, uint16_t priority, + bool has_stateful_acl, + const struct ovn_stage *in_stage, + const struct ovn_stage *out_stage, uint16_t priority, struct lflow_table *lflows, struct lflow_ref *lflow_ref) { @@ -6009,13 +6025,13 @@ build_acl_hints(const struct ls_stateful_record *ls_stateful_rec, * corresponding to all potential matches are set. */ - enum ovn_stage stages[] = { + const struct ovn_stage *stages[] = { S_SWITCH_IN_ACL_HINT, S_SWITCH_OUT_ACL_HINT, }; for (size_t i = 0; i < ARRAY_SIZE(stages); i++) { - enum ovn_stage stage = stages[i]; + const struct ovn_stage *stage = stages[i]; /* In any case, advance to the next stage. */ if (!ls_stateful_rec->has_acls && !ls_stateful_rec->has_lb_vip) { @@ -6297,7 +6313,7 @@ build_acl_sample_label_match(struct ds *match, const struct nbrec_acl *acl, static void build_acl_sample_new_flows(const struct ovn_datapath *od, struct lflow_table *lflows, - enum ovn_stage stage, + const struct ovn_stage *stage, struct ds *match, struct ds *actions, const struct nbrec_acl *acl, uint8_t sample_domain_id, bool stateful, @@ -6335,7 +6351,7 @@ build_acl_sample_new_flows(const struct ovn_datapath *od, static void build_acl_sample_est_orig_stateful_flows(const struct ovn_datapath *od, struct lflow_table *lflows, - enum ovn_stage stage, + const struct ovn_stage *stage, struct ds *match, struct ds *actions, const struct nbrec_acl *acl, uint8_t sample_domain_id, @@ -6368,7 +6384,7 @@ build_acl_sample_est_orig_stateful_flows(const struct ovn_datapath *od, static void build_acl_sample_est_rpl_stateful_flows(const struct ovn_datapath *od, struct lflow_table *lflows, - enum ovn_stage rpl_stage, + const struct ovn_stage *rpl_stage, struct ds *match, struct ds *actions, const struct nbrec_acl *acl, uint8_t sample_domain_id, @@ -6396,7 +6412,7 @@ build_acl_sample_est_rpl_stateful_flows(const struct ovn_datapath *od, static void build_acl_sample_est_stateful_flows(const struct ovn_datapath *od, struct lflow_table *lflows, - enum ovn_stage stage, + const struct ovn_stage *stage, struct ds *match, struct ds *actions, const struct nbrec_acl *acl, uint8_t sample_domain_id, @@ -6410,9 +6426,9 @@ build_acl_sample_est_stateful_flows(const struct ovn_datapath *od, /* Install flows in the "opposite" pipeline direction to handle reply * traffic on established connections. */ - enum ovn_stage rpl_stage = (stage == S_SWITCH_OUT_ACL_SAMPLE - ? S_SWITCH_IN_ACL_SAMPLE - : S_SWITCH_OUT_ACL_SAMPLE); + const struct ovn_stage *rpl_stage = (stage == S_SWITCH_OUT_ACL_SAMPLE + ? S_SWITCH_IN_ACL_SAMPLE + : S_SWITCH_OUT_ACL_SAMPLE); build_acl_sample_est_rpl_stateful_flows(od, lflows, rpl_stage, match, actions, acl, sample_domain_id, lflow_ref); @@ -6427,7 +6443,7 @@ static void build_acl_reject_action(struct ds *actions, bool is_ingress); static void build_acl_sample_generic_new_flows(const struct ovn_datapath *od, struct lflow_table *lflows, - enum ovn_stage stage, + const struct ovn_stage *stage, enum acl_observation_stage obs_stage, struct ds *match, struct ds *actions, const struct nbrec_sample_collector *coll, @@ -6474,7 +6490,7 @@ build_acl_sample_generic_new_flows(const struct ovn_datapath *od, static void build_acl_sample_generic_est_flows(const struct ovn_datapath *od, struct lflow_table *lflows, - enum ovn_stage stage, + const struct ovn_stage *stage, enum acl_observation_stage obs_stage, struct ds *match, struct ds *actions, const struct nbrec_sample_collector *coll, @@ -6505,9 +6521,9 @@ build_acl_sample_generic_est_flows(const struct ovn_datapath *od, ovn_lflow_add(lflows, od, stage, 1000, ds_cstr(match), ds_cstr(actions), lflow_ref); - enum ovn_stage rpl_stage = (stage == S_SWITCH_OUT_ACL_SAMPLE - ? S_SWITCH_IN_ACL_SAMPLE - : S_SWITCH_OUT_ACL_SAMPLE); + const struct ovn_stage *rpl_stage = (stage == S_SWITCH_OUT_ACL_SAMPLE + ? S_SWITCH_IN_ACL_SAMPLE + : S_SWITCH_OUT_ACL_SAMPLE); ds_truncate(match, match_len); ds_put_format(match, "ct.rpl && ct_mark.obs_collector_id == %"PRIu8, @@ -6560,7 +6576,7 @@ build_acl_sample_flows(const struct ls_stateful_record *ls_stateful_rec, } bool ingress = !strcmp(acl->direction, "from-lport") ? true : false; - enum ovn_stage stage; + const struct ovn_stage *stage; enum acl_observation_stage obs_stage; if (ingress && smap_get_bool(&acl->options, "apply-after-lb", false)) { @@ -6633,7 +6649,7 @@ consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od, const struct sbrec_acl_id_table *sbrec_acl_id_table) { bool ingress = !strcmp(acl->direction, "from-lport") ? true :false; - enum ovn_stage stage; + const struct ovn_stage *stage; enum acl_observation_stage obs_stage; if (ingress && smap_get_bool(&acl->options, "apply-after-lb", false)) { @@ -6916,13 +6932,13 @@ build_acl_action_lflows(const struct ls_stateful_record *ls_stateful_rec, struct ds *actions, struct lflow_ref *lflow_ref) { - enum ovn_stage stages [] = { + const struct ovn_stage *stages [] = { S_SWITCH_IN_ACL_ACTION, S_SWITCH_IN_ACL_AFTER_LB_ACTION, S_SWITCH_OUT_ACL_ACTION, }; - enum ovn_stage eval_stages[] = { + const struct ovn_stage *eval_stages[] = { S_SWITCH_IN_ACL_EVAL, S_SWITCH_IN_ACL_AFTER_LB_EVAL, S_SWITCH_OUT_ACL_EVAL, @@ -6941,7 +6957,7 @@ build_acl_action_lflows(const struct ls_stateful_record *ls_stateful_rec, size_t verdict_len = actions->length; for (size_t i = 0; i < ARRAY_SIZE(stages); i++) { - enum ovn_stage stage = stages[i]; + const struct ovn_stage *stage = stages[i]; if (max_acl_tiers[i]) { ds_put_cstr(actions, REG_ACL_TIER " = 0; "); } @@ -7031,7 +7047,7 @@ build_acl_log_related_flows(const struct ovn_datapath *od, /* Related/reply flows need to be set on the opposite pipeline * from where the ACL itself is set. */ - enum ovn_stage log_related_stage = ingress ? + const struct ovn_stage *log_related_stage = ingress ? S_SWITCH_OUT_ACL_EVAL : S_SWITCH_IN_ACL_EVAL; ds_clear(match); @@ -7378,7 +7394,9 @@ build_qos(struct ovn_datapath *od, struct lflow_table *lflows, for (size_t i = 0; i < od->nbs->n_qos_rules; i++) { struct nbrec_qos *qos = od->nbs->qos_rules[i]; bool ingress = !strcmp(qos->direction, "from-lport") ? true :false; - enum ovn_stage stage = ingress ? S_SWITCH_IN_QOS : S_SWITCH_OUT_QOS; + const struct ovn_stage *stage = ingress + ? S_SWITCH_IN_QOS + : S_SWITCH_OUT_QOS; static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); int64_t rate = 0; int64_t burst = 0; @@ -12326,7 +12344,9 @@ lrouter_nat_add_ext_ip_match(const struct ovn_datapath *od, allowed_ext_ips->name); } else if (exempted_ext_ips) { struct ds match_exempt = DS_EMPTY_INITIALIZER; - enum ovn_stage stage = is_src ? S_ROUTER_IN_DNAT : S_ROUTER_OUT_SNAT; + const struct ovn_stage *stage = is_src + ? S_ROUTER_IN_DNAT + : S_ROUTER_OUT_SNAT; /* Priority of logical flows corresponding to exempted_ext_ips is * +2 of the corresponding regular NAT rule. @@ -12584,7 +12604,7 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op, static void build_lrouter_drop_own_dest(struct ovn_port *op, const struct lr_stateful_record *lr_stateful_rec, - enum ovn_stage stage, + const struct ovn_stage *stage, uint16_t priority, bool drop_snat_ip, struct lflow_table *lflows, struct lflow_ref *lflow_ref) @@ -13001,7 +13021,7 @@ build_gateway_get_l2_hdr_size(struct ovn_port *op) */ static void OVS_PRINTF_FORMAT(10, 11) build_gateway_mtu_flow(struct lflow_table *lflows, struct ovn_port *op, - enum ovn_stage stage, uint16_t prio_low, + const struct ovn_stage *stage, uint16_t prio_low, uint16_t prio_high, struct ds *match, struct ds *actions, const struct ovsdb_idl_row *hint, struct lflow_ref *lflow_ref, @@ -14401,7 +14421,7 @@ create_icmp_need_frag_lflow(const struct ovn_port *op, int mtu, struct ds *actions, struct ds *match, const char *meter, struct lflow_table *lflows, struct lflow_ref *lflow_ref, - enum ovn_stage stage, uint16_t priority, + const struct ovn_stage *stage, uint16_t priority, bool is_ipv6, const char *extra_match, const char *extra_action) { @@ -14439,7 +14459,7 @@ static void build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct lflow_table *lflows, const struct shash *meter_groups, struct ds *match, - struct ds *actions, enum ovn_stage stage, + struct ds *actions, const struct ovn_stage *stage, struct ovn_port *outport, const char *ct_state_match, struct lflow_ref *lflow_ref) diff --git a/northd/northd.h b/northd/northd.h index 0239f40fe..3de8fc17a 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -455,21 +455,6 @@ ovn_datapath_is_stale(const struct ovn_datapath *od) }; /* Pipeline stages. */ -/* Returns an "enum ovn_stage" built from the arguments. - * - * (It's better to use ovn_stage_build() for type-safety reasons, but inline - * functions can't be used in enums or switch cases.) */ -#define OVN_STAGE_BUILD(DP_TYPE, PIPELINE, TABLE) \ - (((DP_TYPE) << 9) | ((PIPELINE) << 8) | (TABLE)) - -/* A stage within an OVN logical switch or router. - * - * An "enum ovn_stage" indicates whether the stage is part of a logical switch - * or router, whether the stage is part of the ingress or egress pipeline, and - * the table within that pipeline. The first three components are combined to - * form the stage's full name, e.g. S_SWITCH_IN_PORT_SEC_L2, - * S_ROUTER_OUT_DELIVERY. */ -enum ovn_stage { #define PIPELINE_STAGES \ /* Logical switch ingress stages. */ \ PIPELINE_STAGE(SWITCH, IN, CHECK_PORT_SEC, 0, "ls_in_check_port_sec") \ @@ -564,14 +549,23 @@ enum ovn_stage { PIPELINE_STAGE(ROUTER, OUT, EGR_LOOP, 5, "lr_out_egr_loop") \ PIPELINE_STAGE(ROUTER, OUT, DELIVERY, 6, "lr_out_delivery") -#define PIPELINE_STAGE(DP_TYPE, PIPELINE, STAGE, TABLE, NAME) \ - S_##DP_TYPE##_##PIPELINE##_##STAGE \ - = OVN_STAGE_BUILD(DP_##DP_TYPE, P_##PIPELINE, TABLE), - PIPELINE_STAGES -#undef PIPELINE_STAGE +/* A stage within an OVN logical switch or router. + * + * A "struct ovn_stage" indicates whether the stage is part of a logical switch + * or router, whether the stage is part of the ingress or egress pipeline, and + * the table within that pipeline. + */ +struct ovn_stage { + enum ovn_datapath_type dp_type; + enum ovn_pipeline pipeline; + int table; + const char *name; }; -enum ovn_datapath_type ovn_stage_to_datapath_type(enum ovn_stage stage); +bool ovn_stage_equal(const struct ovn_stage *a, const struct ovn_stage *b); + +enum ovn_datapath_type ovn_stage_to_datapath_type( + const struct ovn_stage *stage); /* Returns 'od''s datapath type. */ @@ -581,46 +575,43 @@ ovn_datapath_get_type(const struct ovn_datapath *od) return od->nbs ? DP_SWITCH : DP_ROUTER; } -/* Returns an "enum ovn_stage" built from the arguments. */ -static inline enum ovn_stage +/* Returns a "struct ovn_stage" built from the arguments. + * The stage will not have a proper name, but so far, the only cases + * where stages are built from components, a name is not necessary. + */ +static inline struct ovn_stage ovn_stage_build(enum ovn_datapath_type dp_type, enum ovn_pipeline pipeline, uint8_t table) { - return OVN_STAGE_BUILD(dp_type, pipeline, table); + return (struct ovn_stage) {dp_type, pipeline, table, "<unknown>"}; } /* Returns the pipeline to which 'stage' belongs. */ static inline enum ovn_pipeline -ovn_stage_get_pipeline(enum ovn_stage stage) +ovn_stage_get_pipeline(const struct ovn_stage *stage) { - return (stage >> 8) & 1; + return stage->pipeline; } /* Returns the pipeline name to which 'stage' belongs. */ static inline const char * -ovn_stage_get_pipeline_name(enum ovn_stage stage) +ovn_stage_get_pipeline_name(const struct ovn_stage *stage) { return ovn_stage_get_pipeline(stage) == P_IN ? "ingress" : "egress"; } /* Returns the table to which 'stage' belongs. */ static inline uint8_t -ovn_stage_get_table(enum ovn_stage stage) +ovn_stage_get_table(const struct ovn_stage *stage) { - return stage & 0xff; + return stage->table; } /* Returns a string name for 'stage'. */ static inline const char * -ovn_stage_to_str(enum ovn_stage stage) +ovn_stage_to_str(const struct ovn_stage *stage) { - switch (stage) { -#define PIPELINE_STAGE(DP_TYPE, PIPELINE, STAGE, TABLE, NAME) \ - case S_##DP_TYPE##_##PIPELINE##_##STAGE: return NAME; - PIPELINE_STAGES -#undef PIPELINE_STAGE - default: return "<unknown>"; - } + return stage->name; } /* A logical switch port or logical router port. -- 2.47.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev