Skip to content

Commit

Permalink
northd: Make vxlan_mode a global variable.
Browse files Browse the repository at this point in the history
This simplifies code and subsequent commit to explicitely disable VXLAN
mode is based on these changes.

Also "VXLAN mode" term is introduced in ovn-architecture man page.

Signed-off-by: Vladislav Odintsov <odivlad@gmail.com>
  • Loading branch information
odivlad committed May 3, 2024
1 parent d06e497 commit 0332b28
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 57 deletions.
4 changes: 2 additions & 2 deletions northd/en-global-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ en_global_config_run(struct engine_node *node , void *data)
config_data->svc_monitor_mac);
}

char *max_tunid = xasprintf("%d",
get_ovn_max_dp_key_local(sbrec_chassis_table));
init_vxlan_mode(sbrec_chassis_table);
char *max_tunid = xasprintf("%d", get_ovn_max_dp_key_local());
smap_replace(options, "max_tunid", max_tunid);
free(max_tunid);

Expand Down
85 changes: 36 additions & 49 deletions northd/northd.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ static bool use_ct_inv_match = true;
*/
static bool default_acl_drop;

/* If this option is 'true' northd will use limited 24-bit space for datapath
* and ports tunnel key allocation (12 bits for each instead of default 16). */
static bool vxlan_mode;

#define MAX_OVN_TAGS 4096


Expand Down Expand Up @@ -881,40 +885,40 @@ join_datapaths(const struct nbrec_logical_switch_table *nbrec_ls_table,
}
}

static bool
is_vxlan_mode(const struct sbrec_chassis_table *sbrec_chassis_table)
void
init_vxlan_mode(const struct sbrec_chassis_table *sbrec_chassis_table)
{
const struct sbrec_chassis *chassis;
SBREC_CHASSIS_TABLE_FOR_EACH (chassis, sbrec_chassis_table) {
for (int i = 0; i < chassis->n_encaps; i++) {
if (!strcmp(chassis->encaps[i]->type, "vxlan")) {
return true;
vxlan_mode = true;
return;
}
}
}
return false;
vxlan_mode = false;
}

uint32_t
get_ovn_max_dp_key_local(const struct sbrec_chassis_table *sbrec_chassis_table)
get_ovn_max_dp_key_local(void)
{
if (is_vxlan_mode(sbrec_chassis_table)) {
/* OVN_MAX_DP_GLOBAL_NUM doesn't apply for vxlan mode. */
if (vxlan_mode) {
/* OVN_MAX_DP_GLOBAL_NUM doesn't apply for VXLAN mode. */
return OVN_MAX_DP_VXLAN_KEY;
}
return OVN_MAX_DP_KEY - OVN_MAX_DP_GLOBAL_NUM;
}

static void
ovn_datapath_allocate_key(const struct sbrec_chassis_table *sbrec_ch_table,
struct hmap *datapaths, struct hmap *dp_tnlids,
ovn_datapath_allocate_key(struct hmap *datapaths, struct hmap *dp_tnlids,
struct ovn_datapath *od, uint32_t *hint)
{
if (!od->tunnel_key) {
od->tunnel_key = ovn_allocate_tnlid(dp_tnlids, "datapath",
OVN_MIN_DP_KEY_LOCAL,
get_ovn_max_dp_key_local(sbrec_ch_table),
hint);
OVN_MIN_DP_KEY_LOCAL,
get_ovn_max_dp_key_local(),
hint);
if (!od->tunnel_key) {
if (od->sb) {
sbrec_datapath_binding_delete(od->sb);
Expand All @@ -927,7 +931,6 @@ ovn_datapath_allocate_key(const struct sbrec_chassis_table *sbrec_ch_table,

static void
ovn_datapath_assign_requested_tnl_id(
const struct sbrec_chassis_table *sbrec_chassis_table,
struct hmap *dp_tnlids, struct ovn_datapath *od)
{
const struct smap *other_config = (od->nbs
Expand All @@ -936,8 +939,7 @@ ovn_datapath_assign_requested_tnl_id(
uint32_t tunnel_key = smap_get_int(other_config, "requested-tnl-key", 0);
if (tunnel_key) {
const char *interconn_ts = smap_get(other_config, "interconn-ts");
if (!interconn_ts && is_vxlan_mode(sbrec_chassis_table) &&
tunnel_key >= 1 << 12) {
if (!interconn_ts && vxlan_mode && tunnel_key >= 1 << 12) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
VLOG_WARN_RL(&rl, "Tunnel key %"PRIu32" for datapath %s is "
"incompatible with VXLAN", tunnel_key,
Expand Down Expand Up @@ -985,7 +987,6 @@ build_datapaths(struct ovsdb_idl_txn *ovnsb_txn,
const struct nbrec_logical_switch_table *nbrec_ls_table,
const struct nbrec_logical_router_table *nbrec_lr_table,
const struct sbrec_datapath_binding_table *sbrec_dp_table,
const struct sbrec_chassis_table *sbrec_chassis_table,
struct ovn_datapaths *ls_datapaths,
struct ovn_datapaths *lr_datapaths,
struct ovs_list *lr_list)
Expand All @@ -1000,12 +1001,11 @@ build_datapaths(struct ovsdb_idl_txn *ovnsb_txn,
struct hmap dp_tnlids = HMAP_INITIALIZER(&dp_tnlids);
struct ovn_datapath *od;
LIST_FOR_EACH (od, list, &both) {
ovn_datapath_assign_requested_tnl_id(sbrec_chassis_table, &dp_tnlids,
od);
ovn_datapath_assign_requested_tnl_id(&dp_tnlids, od);
}
LIST_FOR_EACH (od, list, &nb_only) {
ovn_datapath_assign_requested_tnl_id(sbrec_chassis_table, &dp_tnlids,
od); }
ovn_datapath_assign_requested_tnl_id(&dp_tnlids, od);
}

/* Keep nonconflicting tunnel IDs that are already assigned. */
LIST_FOR_EACH (od, list, &both) {
Expand All @@ -1017,12 +1017,10 @@ build_datapaths(struct ovsdb_idl_txn *ovnsb_txn,
/* Assign new tunnel ids where needed. */
uint32_t hint = 0;
LIST_FOR_EACH_SAFE (od, list, &both) {
ovn_datapath_allocate_key(sbrec_chassis_table,
datapaths, &dp_tnlids, od, &hint);
ovn_datapath_allocate_key(datapaths, &dp_tnlids, od, &hint);
}
LIST_FOR_EACH_SAFE (od, list, &nb_only) {
ovn_datapath_allocate_key(sbrec_chassis_table,
datapaths, &dp_tnlids, od, &hint);
ovn_datapath_allocate_key(datapaths, &dp_tnlids, od, &hint);
}

/* Sync tunnel ids from nb to sb. */
Expand Down Expand Up @@ -3982,16 +3980,14 @@ ovn_port_add_tnlid(struct ovn_port *op, uint32_t tunnel_key)
* that the I-P engine can fallback to recompute if needed; otherwise return
* true (even if the key is not allocated). */
static bool
ovn_port_assign_requested_tnl_id(
const struct sbrec_chassis_table *sbrec_chassis_table, struct ovn_port *op)
ovn_port_assign_requested_tnl_id(struct ovn_port *op)
{
const struct smap *options = (op->nbsp
? &op->nbsp->options
: &op->nbrp->options);
uint32_t tunnel_key = smap_get_int(options, "requested-tnl-key", 0);
if (tunnel_key) {
if (is_vxlan_mode(sbrec_chassis_table) &&
tunnel_key >= OVN_VXLAN_MIN_MULTICAST) {
if (vxlan_mode && tunnel_key >= OVN_VXLAN_MIN_MULTICAST) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
VLOG_WARN_RL(&rl, "Tunnel key %"PRIu32" for port %s "
"is incompatible with VXLAN",
Expand All @@ -4011,11 +4007,10 @@ ovn_port_assign_requested_tnl_id(
}

static bool
ovn_port_allocate_key(const struct sbrec_chassis_table *sbrec_chassis_table,
struct ovn_port *op)
ovn_port_allocate_key(struct ovn_port *op)
{
if (!op->tunnel_key) {
uint8_t key_bits = is_vxlan_mode(sbrec_chassis_table)? 12 : 16;
uint8_t key_bits = vxlan_mode ? 12 : 16;
op->tunnel_key = ovn_allocate_tnlid(&op->od->port_tnlids, "port",
1, (1u << (key_bits - 1)) - 1,
&op->od->port_key_hint);
Expand All @@ -4035,7 +4030,6 @@ ovn_port_allocate_key(const struct sbrec_chassis_table *sbrec_chassis_table,
static void
build_ports(struct ovsdb_idl_txn *ovnsb_txn,
const struct sbrec_port_binding_table *sbrec_port_binding_table,
const struct sbrec_chassis_table *sbrec_chassis_table,
const struct sbrec_mirror_table *sbrec_mirror_table,
const struct sbrec_mac_binding_table *sbrec_mac_binding_table,
const struct sbrec_ha_chassis_group_table *sbrec_ha_chassis_group_table,
Expand Down Expand Up @@ -4069,10 +4063,10 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
/* Assign explicitly requested tunnel ids first. */
struct ovn_port *op;
LIST_FOR_EACH (op, list, &both) {
ovn_port_assign_requested_tnl_id(sbrec_chassis_table, op);
ovn_port_assign_requested_tnl_id(op);
}
LIST_FOR_EACH (op, list, &nb_only) {
ovn_port_assign_requested_tnl_id(sbrec_chassis_table, op);
ovn_port_assign_requested_tnl_id(op);
}

/* Keep nonconflicting tunnel IDs that are already assigned. */
Expand All @@ -4084,14 +4078,14 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,

/* Assign new tunnel ids where needed. */
LIST_FOR_EACH_SAFE (op, list, &both) {
if (!ovn_port_allocate_key(sbrec_chassis_table, op)) {
if (!ovn_port_allocate_key(op)) {
sbrec_port_binding_delete(op->sb);
ovs_list_remove(&op->list);
ovn_port_destroy(ports, op);
}
}
LIST_FOR_EACH_SAFE (op, list, &nb_only) {
if (!ovn_port_allocate_key(sbrec_chassis_table, op)) {
if (!ovn_port_allocate_key(op)) {
ovs_list_remove(&op->list);
ovn_port_destroy(ports, op);
}
Expand Down Expand Up @@ -4303,14 +4297,13 @@ ls_port_init(struct ovn_port *op, struct ovsdb_idl_txn *ovnsb_txn,
struct ovn_datapath *od,
const struct sbrec_port_binding *sb,
const struct sbrec_mirror_table *sbrec_mirror_table,
const struct sbrec_chassis_table *sbrec_chassis_table,
struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_chassis_by_hostname)
{
op->od = od;
parse_lsp_addrs(op);
/* Assign explicitly requested tunnel ids first. */
if (!ovn_port_assign_requested_tnl_id(sbrec_chassis_table, op)) {
if (!ovn_port_assign_requested_tnl_id(op)) {
return false;
}
/* Keep nonconflicting tunnel IDs that are already assigned. */
Expand All @@ -4320,7 +4313,7 @@ ls_port_init(struct ovn_port *op, struct ovsdb_idl_txn *ovnsb_txn,
}
}
/* Assign new tunnel ids where needed. */
if (!ovn_port_allocate_key(sbrec_chassis_table, op)) {
if (!ovn_port_allocate_key(op)) {
return false;
}
/* Create new binding, if needed. */
Expand All @@ -4344,15 +4337,13 @@ ls_port_create(struct ovsdb_idl_txn *ovnsb_txn, struct hmap *ls_ports,
const char *key, const struct nbrec_logical_switch_port *nbsp,
struct ovn_datapath *od,
const struct sbrec_mirror_table *sbrec_mirror_table,
const struct sbrec_chassis_table *sbrec_chassis_table,
struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_chassis_by_hostname)
{
struct ovn_port *op = ovn_port_create(ls_ports, key, nbsp, NULL,
NULL);
hmap_insert(&od->ports, &op->dp_node, hmap_node_hash(&op->key_node));
if (!ls_port_init(op, ovnsb_txn, od, NULL,
sbrec_mirror_table, sbrec_chassis_table,
if (!ls_port_init(op, ovnsb_txn, od, NULL, sbrec_mirror_table,
sbrec_chassis_by_name, sbrec_chassis_by_hostname)) {
ovn_port_destroy(ls_ports, op);
return NULL;
Expand All @@ -4367,16 +4358,14 @@ ls_port_reinit(struct ovn_port *op, struct ovsdb_idl_txn *ovnsb_txn,
struct ovn_datapath *od,
const struct sbrec_port_binding *sb,
const struct sbrec_mirror_table *sbrec_mirror_table,
const struct sbrec_chassis_table *sbrec_chassis_table,
struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_chassis_by_hostname)
{
ovn_port_cleanup(op);
op->sb = sb;
ovn_port_set_nb(op, nbsp, NULL);
op->l3dgw_port = op->cr_port = NULL;
return ls_port_init(op, ovnsb_txn, od, sb,
sbrec_mirror_table, sbrec_chassis_table,
return ls_port_init(op, ovnsb_txn, od, sb, sbrec_mirror_table,
sbrec_chassis_by_name, sbrec_chassis_by_hostname);
}

Expand Down Expand Up @@ -4521,7 +4510,6 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
op = ls_port_create(ovnsb_idl_txn, &nd->ls_ports,
new_nbsp->name, new_nbsp, od,
ni->sbrec_mirror_table,
ni->sbrec_chassis_table,
ni->sbrec_chassis_by_name,
ni->sbrec_chassis_by_hostname);
if (!op) {
Expand Down Expand Up @@ -4553,7 +4541,6 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
if (!ls_port_reinit(op, ovnsb_idl_txn,
new_nbsp,
od, sb, ni->sbrec_mirror_table,
ni->sbrec_chassis_table,
ni->sbrec_chassis_by_name,
ni->sbrec_chassis_by_hostname)) {
if (sb) {
Expand Down Expand Up @@ -17609,19 +17596,19 @@ ovnnb_db_run(struct northd_input *input_data,
use_common_zone = smap_get_bool(input_data->nb_options, "use_common_zone",
false);

init_vxlan_mode(input_data->sbrec_chassis_table);

build_datapaths(ovnsb_txn,
input_data->nbrec_logical_switch_table,
input_data->nbrec_logical_router_table,
input_data->sbrec_datapath_binding_table,
input_data->sbrec_chassis_table,
&data->ls_datapaths,
&data->lr_datapaths, &data->lr_list);
build_lb_datapaths(input_data->lbs, input_data->lbgrps,
&data->ls_datapaths, &data->lr_datapaths,
&data->lb_datapaths_map, &data->lb_group_datapaths_map);
build_ports(ovnsb_txn,
input_data->sbrec_port_binding_table,
input_data->sbrec_chassis_table,
input_data->sbrec_mirror_table,
input_data->sbrec_mac_binding_table,
input_data->sbrec_ha_chassis_group_table,
Expand Down
5 changes: 4 additions & 1 deletion northd/northd.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@ lr_has_multiple_gw_ports(const struct ovn_datapath *od)
return od->n_l3dgw_ports > 1 && !od->is_gw_router;
}

uint32_t get_ovn_max_dp_key_local(const struct sbrec_chassis_table *);
void
init_vxlan_mode(const struct sbrec_chassis_table *sbrec_chassis_table);

uint32_t get_ovn_max_dp_key_local(void);

#endif /* NORTHD_H */
10 changes: 5 additions & 5 deletions ovn-architecture.7.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2809,11 +2809,11 @@
</ul>

<p>
When VXLAN is enabled on any hypervisor in a cluster, datapath and egress
port identifier ranges are reduced to 12-bits. This is done because only
STT and Geneve provide the large space for metadata (over 32 bits per
packet). To accommodate for VXLAN, 24 bits available are split as
follows:
When VXLAN is enabled on any hypervisor in a cluster, datapath and egress
port identifier ranges are reduced to 12-bits. This is done because only
STT and Geneve provide the large space for metadata (over 32 bits per
packet). The mode with reduced ranges is called <code>VXLAN mode</code>.
To accommodate for VXLAN, 24 bits available are split as follows:
</p>

<ul>
Expand Down

0 comments on commit 0332b28

Please sign in to comment.