Skip to content

Commit

Permalink
TODO: squash fix duplicate sampling
Browse files Browse the repository at this point in the history
Signed-off-by: Dumitru Ceara <[email protected]>
  • Loading branch information
dceara committed Jul 30, 2024
1 parent b5a0b02 commit d1a2212
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 103 deletions.
4 changes: 2 additions & 2 deletions include/ovn/logical-fields.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,13 @@ const struct ovn_field *ovn_field_from_name(const char *name);
#define OVN_CT_NATTED_BIT 1
#define OVN_CT_LB_SKIP_SNAT_BIT 2
#define OVN_CT_LB_FORCE_SNAT_BIT 3
#define OVN_CT_OBS_AFTER_LB_BIT 4
#define OVN_CT_OBS_STAGE_1ST_BIT 4
#define OVN_CT_OBS_STAGE_END_BIT 5

#define OVN_CT_BLOCKED 1
#define OVN_CT_NATTED 2
#define OVN_CT_LB_SKIP_SNAT 4
#define OVN_CT_LB_FORCE_SNAT 8
#define OVN_CT_OBS_AFTER_LB 16

#define OVN_CT_ECMP_ETH_1ST_BIT 32
#define OVN_CT_ECMP_ETH_END_BIT 79
Expand Down
5 changes: 3 additions & 2 deletions lib/logical-fields.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,10 @@ ovn_init_symtab(struct shash *symtab)
OVN_CT_STR(OVN_CT_LB_FORCE_SNAT_BIT)
"]",
WR_CT_COMMIT);
expr_symtab_add_subfield_scoped(symtab, "ct_mark.obs_after_lb", NULL,
expr_symtab_add_subfield_scoped(symtab, "ct_mark.obs_stage", NULL,
"ct_mark["
OVN_CT_STR(OVN_CT_OBS_AFTER_LB_BIT)
OVN_CT_STR(OVN_CT_OBS_STAGE_1ST_BIT) ".."
OVN_CT_STR(OVN_CT_OBS_STAGE_END_BIT)
"]",
WR_CT_COMMIT);
expr_symtab_add_subfield_scoped(symtab, "ct_mark.obs_collector_id", NULL,
Expand Down
57 changes: 39 additions & 18 deletions northd/northd.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,20 @@ static bool vxlan_mode;
#define REGBIT_ACL_VERDICT_ALLOW "reg8[16]"
#define REGBIT_ACL_VERDICT_DROP "reg8[17]"
#define REGBIT_ACL_VERDICT_REJECT "reg8[18]"
#define REGBIT_ACL_OBS_STAGE "reg8[19..20]"
#define REG_ACL_TIER "reg8[30..31]"

enum acl_observation_stage {
ACL_OBS_FROM_LPORT,
ACL_OBS_FROM_LPORT_AFTER_LB,
ACL_OBS_TO_LPORT,
ACL_OBS_STAGE_MAX
};

/* enum acl_observation_stage_t values must fit in the 2 bits of
* REGBIT_ACL_OBS_STAGE .*/
BUILD_ASSERT_DECL(ACL_OBS_STAGE_MAX < (1 << 2));

/* Indicate that this packet has been recirculated using egress
* loopback. This allows certain checks to be bypassed, such as a
* logical router dropping packets with source IP address equals
Expand Down Expand Up @@ -191,7 +203,6 @@ static bool vxlan_mode;
#define REG_OBS_POINT_ID_EST "reg9"
#define REG_OBS_COLLECTOR_ID_NEW "reg8[0..7]"
#define REG_OBS_COLLECTOR_ID_EST "reg2[16..23]"
#define REGBIT_OBS_AFTER_LB "reg8[19]"

/* Register used for temporarily store ECMP eth.src to avoid masked ct_label
* access. It doesn't really occupy registers because the content of the
Expand Down Expand Up @@ -6525,7 +6536,7 @@ static void
build_acl_sample_label_action(struct ds *actions, const struct nbrec_acl *acl,
const struct nbrec_sample *sample_new,
const struct nbrec_sample *sample_est,
bool obs_after_lb)
enum acl_observation_stage obs_stage)
{
if (!acl->label && !sample_new && !sample_est) {
return;
Expand Down Expand Up @@ -6559,10 +6570,10 @@ build_acl_sample_label_action(struct ds *actions, const struct nbrec_acl *acl,
REG_OBS_POINT_ID_EST " = %"PRIu32"; "
REG_OBS_COLLECTOR_ID_NEW " = %"PRIu8"; "
REG_OBS_COLLECTOR_ID_EST " = %"PRIu8"; "
REGBIT_OBS_AFTER_LB " = %c; ",
REGBIT_ACL_OBS_STAGE " = %"PRIu8"; ",
point_id_new, point_id_est,
collector_id_new, collector_id_est,
obs_after_lb ? '1' : '0');
(uint8_t) obs_stage);
}

/* This builds an ACL logical flow specific match that selects traffic
Expand Down Expand Up @@ -6737,6 +6748,7 @@ static void
build_acl_sample_generic_new_flows(const struct ovn_datapath *od,
struct lflow_table *lflows,
enum ovn_stage stage,
enum acl_observation_stage obs_stage,
struct ds *match, struct ds *actions,
const struct nbrec_sample_collector *coll,
uint8_t sample_domain_id, bool stateful,
Expand All @@ -6746,10 +6758,10 @@ build_acl_sample_generic_new_flows(const struct ovn_datapath *od,
ds_clear(actions);

ds_put_format(match, "ip %s&& "REG_OBS_COLLECTOR_ID_NEW" == %"PRIu8" && "
REGBIT_OBS_AFTER_LB" == %c",
REGBIT_ACL_OBS_STAGE " == %"PRIu8,
stateful ? "&& ct.new " : "",
(uint8_t) coll->set_id,
stage == S_SWITCH_IN_ACL_AFTER_LB_SAMPLE ? '1' : '0');
(uint8_t) obs_stage);

ds_put_format(actions, "sample(probability=%"PRIu16","
"collector_set=%"PRIu8","
Expand All @@ -6772,6 +6784,7 @@ static void
build_acl_sample_generic_est_flows(const struct ovn_datapath *od,
struct lflow_table *lflows,
enum ovn_stage stage,
enum acl_observation_stage obs_stage,
struct ds *match, struct ds *actions,
const struct nbrec_sample_collector *coll,
uint8_t sample_domain_id,
Expand All @@ -6785,9 +6798,9 @@ build_acl_sample_generic_est_flows(const struct ovn_datapath *od,

size_t match_len = match->length;
ds_put_format(match, "!ct.rpl && ct_mark.obs_collector_id == %"PRIu8" && "
"ct_mark.obs_after_lb == %c",
"ct_mark.obs_stage == %"PRIu8,
(uint8_t) coll->set_id,
stage == S_SWITCH_IN_ACL_AFTER_LB_SAMPLE ? '1' : '0');
(uint8_t) obs_stage);

ds_put_format(actions, "sample(probability=%"PRIu16","
"collector_set=%"PRIu8","
Expand Down Expand Up @@ -6857,13 +6870,17 @@ 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;
enum acl_observation_stage obs_stage;

if (ingress && smap_get_bool(&acl->options, "apply-after-lb", false)) {
stage = S_SWITCH_IN_ACL_AFTER_LB_SAMPLE;
obs_stage = ACL_OBS_FROM_LPORT_AFTER_LB;
} else if (ingress) {
stage = S_SWITCH_IN_ACL_SAMPLE;
obs_stage = ACL_OBS_FROM_LPORT;
} else {
stage = S_SWITCH_OUT_ACL_SAMPLE;
obs_stage = ACL_OBS_TO_LPORT;
}

uint8_t sample_new_domain_id =
Expand All @@ -6872,7 +6889,8 @@ build_acl_sample_flows(const struct ls_stateful_record *ls_stateful_rec,
sampling_app_get_id(sampling_apps, SAMPLING_APP_ACL_EST_TRAFFIC);

if (acl_use_generic_sample_flows(acl->sample_new, features)) {
build_acl_sample_generic_new_flows(od, lflows, stage, match, actions,
build_acl_sample_generic_new_flows(od, lflows, stage, obs_stage,
match, actions,
acl->sample_new->collectors[0],
sample_new_domain_id,
stateful_match, lflow_ref);
Expand All @@ -6887,7 +6905,8 @@ build_acl_sample_flows(const struct ls_stateful_record *ls_stateful_rec,
}

if (acl_use_generic_sample_flows(acl->sample_est, features)) {
build_acl_sample_generic_est_flows(od, lflows, stage, match, actions,
build_acl_sample_generic_est_flows(od, lflows, stage, obs_stage,
match, actions,
acl->sample_est->collectors[0],
sample_est_domain_id, lflow_ref);
} else {
Expand Down Expand Up @@ -6922,15 +6941,17 @@ consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,
{
bool ingress = !strcmp(acl->direction, "from-lport") ? true :false;
enum ovn_stage stage;
enum acl_observation_stage obs_stage;

bool apply_after_lb = false;
if (ingress && smap_get_bool(&acl->options, "apply-after-lb", false)) {
stage = S_SWITCH_IN_ACL_AFTER_LB_EVAL;
apply_after_lb = true;
obs_stage = ACL_OBS_FROM_LPORT_AFTER_LB;
} else if (ingress) {
stage = S_SWITCH_IN_ACL_EVAL;
obs_stage = ACL_OBS_FROM_LPORT;
} else {
stage = S_SWITCH_OUT_ACL_EVAL;
obs_stage = ACL_OBS_TO_LPORT;
}

const char *verdict;
Expand Down Expand Up @@ -6965,7 +6986,7 @@ consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,

/* For stateless ACLs just sample "new" packets. */
build_acl_sample_label_action(actions, acl, acl->sample_new, NULL,
apply_after_lb);
obs_stage);

ds_put_cstr(actions, "next;");
ds_put_format(match, "(%s)", acl->match);
Expand Down Expand Up @@ -7004,7 +7025,7 @@ consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,

/* For stateful ACLs sample "new" and "established" packets. */
build_acl_sample_label_action(actions, acl, acl->sample_new,
acl->sample_est, apply_after_lb);
acl->sample_est, obs_stage);
ds_put_cstr(actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage, priority,
ds_cstr(match), ds_cstr(actions),
Expand All @@ -7028,7 +7049,7 @@ consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,

/* For stateful ACLs sample "new" and "established" packets. */
build_acl_sample_label_action(actions, acl, acl->sample_new,
acl->sample_est, apply_after_lb);
acl->sample_est, obs_stage);
ds_put_cstr(actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage, priority,
ds_cstr(match), ds_cstr(actions),
Expand All @@ -7049,7 +7070,7 @@ consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,

/* For drop ACLs just sample all packets as "new" packets. */
build_acl_sample_label_action(actions, acl, acl->sample_new, NULL,
apply_after_lb);
obs_stage);
ds_put_cstr(actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage, priority,
ds_cstr(match), ds_cstr(actions),
Expand All @@ -7073,7 +7094,7 @@ consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,

/* For drop ACLs just sample all packets as "new" packets. */
build_acl_sample_label_action(actions, acl, acl->sample_new, NULL,
apply_after_lb);
obs_stage);
ds_put_cstr(actions, "ct_commit { ct_mark.blocked = 1; }; next;");
ovn_lflow_add_with_hint(lflows, od, stage, priority,
ds_cstr(match), ds_cstr(actions),
Expand Down Expand Up @@ -8195,7 +8216,7 @@ build_stateful(struct ovn_datapath *od, struct lflow_table *lflows,
ds_put_cstr(&actions,
"ct_commit { "
"ct_mark.blocked = 0; "
"ct_mark.obs_after_lb = " REGBIT_OBS_AFTER_LB "; "
"ct_mark.obs_stage = " REGBIT_ACL_OBS_STAGE "; "
"ct_mark.obs_collector_id = " REG_OBS_COLLECTOR_ID_EST "; "
"ct_label.obs_point_id = " REG_OBS_POINT_ID_EST "; "
"}; next;");
Expand Down
Loading

0 comments on commit d1a2212

Please sign in to comment.