Skip to content

Commit

Permalink
features: Add detection for sample with registers.
Browse files Browse the repository at this point in the history
Add detection for sample action that allows to configure
obs_domain_id and obs_point_id via registers. This feature
is available only from OvS version 3.4.

Signed-off-by: Ales Musil <[email protected]>
---
V5:
- Addressed Ilya's comments:
  - Fixed SB chassis reconciliation.
  - Rename OVS_DP_SAMPLE_REG_SUPPORT to OVS_SAMPLE_REG_SUPPORT
  • Loading branch information
almusil authored and dceara committed Aug 5, 2024
1 parent 71c00f7 commit 216a59f
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 0 deletions.
15 changes: 15 additions & 0 deletions controller/chassis.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ struct ovs_chassis_cfg {
struct ds iface_types;
/* Is this chassis an interconnection gateway. */
bool is_interconn;
/* Does OVS support sampling with ids taken from registers? */
bool sample_with_regs;
};

static void
Expand Down Expand Up @@ -338,6 +340,8 @@ chassis_parse_ovs_config(const struct ovsrec_open_vswitch_table *ovs_table,
&ovs_cfg->iface_types);

ovs_cfg->is_interconn = get_is_interconn(&cfg->external_ids, chassis_id);
ovs_cfg->sample_with_regs =
ovs_feature_is_supported(OVS_SAMPLE_REG_SUPPORT);

return true;
}
Expand Down Expand Up @@ -372,6 +376,8 @@ chassis_build_other_config(const struct ovs_chassis_cfg *ovs_cfg,
smap_replace(config, OVN_FEATURE_LS_DPG_COLUMN, "true");
smap_replace(config, OVN_FEATURE_CT_COMMIT_NAT_V2, "true");
smap_replace(config, OVN_FEATURE_CT_COMMIT_TO_ZONE, "true");
smap_replace(config, OVN_FEATURE_SAMPLE_WITH_REGISTERS,
ovs_cfg->sample_with_regs ? "true" : "false");
}

/*
Expand Down Expand Up @@ -523,6 +529,14 @@ chassis_other_config_changed(const struct ovs_chassis_cfg *ovs_cfg,
return true;
}

bool chassis_sample_with_regs =
smap_get_bool(&chassis_rec->other_config,
OVN_FEATURE_SAMPLE_WITH_REGISTERS,
false);
if (chassis_sample_with_regs != ovs_cfg->sample_with_regs) {
return true;
}

return false;
}

Expand Down Expand Up @@ -656,6 +670,7 @@ update_supported_sset(struct sset *supported)
sset_add(supported, OVN_FEATURE_LS_DPG_COLUMN);
sset_add(supported, OVN_FEATURE_CT_COMMIT_NAT_V2);
sset_add(supported, OVN_FEATURE_CT_COMMIT_TO_ZONE);
sset_add(supported, OVN_FEATURE_SAMPLE_WITH_REGISTERS);
}

static void
Expand Down
3 changes: 3 additions & 0 deletions include/ovn/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define OVN_FEATURE_LS_DPG_COLUMN "ls-dpg-column"
#define OVN_FEATURE_CT_COMMIT_NAT_V2 "ct-commit-nat-v2"
#define OVN_FEATURE_CT_COMMIT_TO_ZONE "ct-commit-to-zone"
#define OVN_FEATURE_SAMPLE_WITH_REGISTERS "ovn-sample-with-registers"

/* OVS datapath supported features. Based on availability OVN might generate
* different types of openflows.
Expand All @@ -39,6 +40,7 @@ enum ovs_feature_support_bits {
OVS_CT_TUPLE_FLUSH_BIT,
OVS_DP_HASH_L4_SYM_BIT,
OVS_OF_GROUP_SUPPORT_BIT,
OVS_SAMPLE_REG_SUPPORT_BIT,
};

enum ovs_feature_value {
Expand All @@ -47,6 +49,7 @@ enum ovs_feature_value {
OVS_CT_TUPLE_FLUSH_SUPPORT = (1 << OVS_CT_TUPLE_FLUSH_BIT),
OVS_DP_HASH_L4_SYM_SUPPORT = (1 << OVS_DP_HASH_L4_SYM_BIT),
OVS_OF_GROUP_SUPPORT = (1 << OVS_OF_GROUP_SUPPORT_BIT),
OVS_SAMPLE_REG_SUPPORT = (1 << OVS_SAMPLE_REG_SUPPORT_BIT),
};

void ovs_feature_support_destroy(void);
Expand Down
91 changes: 91 additions & 0 deletions lib/features.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "openvswitch/vlog.h"
#include "openvswitch/ofpbuf.h"
#include "openvswitch/rconn.h"
#include "openvswitch/ofp-actions.h"
#include "openvswitch/ofp-bundle.h"
#include "openvswitch/ofp-msgs.h"
#include "openvswitch/ofp-meter.h"
#include "openvswitch/ofp-group.h"
Expand Down Expand Up @@ -185,6 +187,87 @@ group_features_handle_response(struct ovs_openflow_feature *feature,
return supported_ovs_features & feature->value;
}

static void
sample_with_reg_send_request(struct ovs_openflow_feature *feature)
{
struct ofputil_bundle_ctrl_msg ctrl = {
.bundle_id = 0,
.flags = OFPBF_ORDERED | OFPBF_ATOMIC,
.type = OFPBCT_OPEN_REQUEST,
};
rconn_send(swconn,
ofputil_encode_bundle_ctrl_request(OFP15_VERSION, &ctrl), NULL);

uint8_t actions_stub[64];
struct ofpbuf actions;
ofpbuf_use_stub(&actions, actions_stub, sizeof(actions_stub));

struct mf_subfield subfield = {
.field = mf_from_id(MFF_REG0),
.n_bits = 32,
.ofs = 0
};

struct ofpact_sample *sample = ofpact_put_SAMPLE(&actions);
sample->probability = UINT16_MAX;
sample->collector_set_id = 0;
sample->obs_domain_src = subfield;
sample->obs_point_src = subfield;
sample->sampling_port = OFPP_NONE;

struct ofputil_flow_mod fm = {
.priority = 0,
.table_id = 0,
.ofpacts = actions.data,
.ofpacts_len = actions.size,
.command = OFPFC_ADD,
.new_cookie = htonll(0),
.buffer_id = UINT32_MAX,
.out_port = OFPP_ANY,
.out_group = OFPG_ANY,
};

struct match match;
match_init_catchall(&match);
minimatch_init(&fm.match, &match);

struct ofpbuf *fm_msg = ofputil_encode_flow_mod(&fm, OFPUTIL_P_OF15_OXM);

struct ofputil_bundle_add_msg bam = {
.bundle_id = ctrl.bundle_id,
.flags = ctrl.flags,
.msg = fm_msg->data,
};
struct ofpbuf *msg = ofputil_encode_bundle_add(OFP15_VERSION, &bam);

feature->xid = ((struct ofp_header *) msg->data)->xid;
rconn_send(swconn, msg, NULL);

ctrl.type = OFPBCT_DISCARD_REQUEST;
rconn_send(swconn,
ofputil_encode_bundle_ctrl_request(OFP15_VERSION, &ctrl), NULL);

minimatch_destroy(&fm.match);
ofpbuf_delete(fm_msg);
}

static bool
sample_with_reg_handle_response(struct ovs_openflow_feature *feature,
enum ofptype type, const struct ofp_header *oh)
{
if (type != OFPTYPE_ERROR) {
log_unexpected_reply(feature, oh);
}

return false;
}

static bool
sample_with_reg_handle_barrier(struct ovs_openflow_feature *feature OVS_UNUSED)
{
return true;
}

static struct ovs_openflow_feature all_openflow_features[] = {
{
.value = OVS_DP_METER_SUPPORT,
Expand All @@ -199,6 +282,13 @@ static struct ovs_openflow_feature all_openflow_features[] = {
.send_request = group_features_send_request,
.handle_response = group_features_handle_response,
.handle_barrier = default_barrier_response_handle,
},
{
.value = OVS_SAMPLE_REG_SUPPORT,
.name = "sample_action_with_registers",
.send_request = sample_with_reg_send_request,
.handle_response = sample_with_reg_handle_response,
.handle_barrier = sample_with_reg_handle_barrier,
}
};

Expand Down Expand Up @@ -271,6 +361,7 @@ ovs_feature_is_valid(enum ovs_feature_value feature)
case OVS_CT_TUPLE_FLUSH_SUPPORT:
case OVS_DP_HASH_L4_SYM_SUPPORT:
case OVS_OF_GROUP_SUPPORT:
case OVS_SAMPLE_REG_SUPPORT:
return true;
default:
return false;
Expand Down
10 changes: 10 additions & 0 deletions northd/en-global-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ northd_enable_all_features(struct ed_type_global_config *data)
.ls_dpg_column = true,
.ct_commit_nat_v2 = true,
.ct_commit_to_zone = true,
.sample_with_reg = true,
};
}

Expand Down Expand Up @@ -442,6 +443,15 @@ build_chassis_features(const struct sbrec_chassis_table *sbrec_chassis_table,
chassis_features->ct_commit_to_zone) {
chassis_features->ct_commit_to_zone = false;
}

bool sample_with_reg =
smap_get_bool(&chassis->other_config,
OVN_FEATURE_SAMPLE_WITH_REGISTERS,
false);
if (!sample_with_reg &&
chassis_features->sample_with_reg) {
chassis_features->sample_with_reg = false;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions northd/en-global-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct chassis_features {
bool ls_dpg_column;
bool ct_commit_nat_v2;
bool ct_commit_to_zone;
bool sample_with_reg;
};

struct global_config_tracked_data {
Expand Down

0 comments on commit 216a59f

Please sign in to comment.