ovn supports creating remote logical ports. An user can set requested-chassis option for a logical switch port to the remote chassis and ovn-northd can bind it to that chassis. This is required for OVN IC in ovn-k8s. Right now ovn-k8s ovnkube-controller after creating a remote logical port, sets the chassis column of the corresponding port binding in SB DB to the remote chassis. This process can be implemented in ovn-northd.
Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2217930 Signed-off-by: Lorenzo Bianconi <[email protected]> --- Changes since v2: - address missing logica cases - add more unit tests Changes since v1: - add NEWS entry - do not remove ovn-ic code to bind sb to gw chassis - simplify codebase --- NEWS | 2 ++ ic/ovn-ic.c | 5 ++++ northd/northd.c | 28 +++++++++++++++++++ tests/ovn-ic.at | 2 ++ tests/ovn-northd.at | 67 +++++++++++++++++++++++++++++++++++++++++++++ tests/ovn.at | 27 ++++++++++++++++++ 6 files changed, 131 insertions(+) diff --git a/NEWS b/NEWS index 93d4bedcd..d7580d9bd 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,8 @@ Post v23.06.0 Existing sessions might get re-hashed to a different ECMP path when OVN detects the algorithm support in the datapath during an upgrade or restart of ovn-controller. + - Introduce support for binding remote ports in ovn-northd if the CMS sets + requested-chassis option for a remote logical switch port. OVN v23.06.0 - 01 Jun 2023 -------------------------- diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index db7e86bc1..2a8383523 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -651,6 +651,11 @@ sync_remote_port(struct ic_context *ctx, /* Sync tunnel key from ISB to NB */ sync_lsp_tnl_key(lsp, isb_pb->tunnel_key); + /* Skip port binding if it is already requested by the CMS. */ + if (smap_get(&lsp->options, "requested-chassis")) { + return; + } + /* Sync gateway from ISB to SB */ if (isb_pb->gateway[0]) { if (!sb_pb->chassis || strcmp(sb_pb->chassis->name, isb_pb->gateway)) { diff --git a/northd/northd.c b/northd/northd.c index a01f59efb..e6b37e66a 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -3579,6 +3579,28 @@ ovn_port_update_sbrec(struct ovsdb_idl_txn *ovnsb_txn, } } + if (lsp_is_remote(op->nbsp)) { + /* ovn-northd is supposed to set port_binding for remote ports + * if requested chassis is marked as remote. */ + if (op->sb->requested_chassis && + smap_get_bool(&op->sb->requested_chassis->other_config, + "is-remote", false)) { + sbrec_port_binding_set_chassis(op->sb, + op->sb->requested_chassis); + smap_add(&options, "is-remote-nb-binded", "true"); + } else if (smap_get_bool(&op->sb->options, + "is-remote-nb-binded", false)) { + sbrec_port_binding_set_chassis(op->sb, NULL); + smap_add(&options, "is-remote-nb-binded", "false"); + } + } else if (op->sb->chassis && + smap_get_bool(&op->sb->chassis->other_config, + "is-remote", false)) { + /* Its not a remote port but if the chassis is set and if its a + * remote chassis then clear it. */ + sbrec_port_binding_set_chassis(op->sb, NULL); + } + sbrec_port_binding_set_options(op->sb, &options); smap_destroy(&options); if (ovn_is_known_nb_lsp_type(op->nbsp->type)) { @@ -3616,6 +3638,12 @@ ovn_port_update_sbrec(struct ovsdb_idl_txn *ovnsb_txn, sbrec_port_binding_set_ha_chassis_group(op->sb, NULL); } } else { + if (op->sb->chassis && + smap_get_bool(&op->sb->chassis->other_config, + "is-remote", false)) { + sbrec_port_binding_set_chassis(op->sb, NULL); + } + const char *chassis = NULL; if (op->peer && op->peer->od && op->peer->od->nbr) { chassis = smap_get(&op->peer->od->nbr->options, "chassis"); diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at index 09eac860c..66368e7c9 100644 --- a/tests/ovn-ic.at +++ b/tests/ovn-ic.at @@ -336,6 +336,7 @@ ovn-nbctl lsp-set-addresses lsp-ts1-lr1 router ovn-nbctl lsp-set-type lsp-ts1-lr1 router ovn-nbctl --wait=hv lsp-set-options lsp-ts1-lr1 router-port=lrp-lr1-ts1 +ovn_as az2 ovn-nbctl lsp-set-options lsp-ts1-lr1 requested-chassis=gw1 AT_CHECK([ovn_as az2 ovn-nbctl show | uuidfilt], [0], [dnl switch <0> (ts1) port lsp-ts1-lr1 @@ -350,6 +351,7 @@ lsp-ts1-lr1,remote ovn-nbctl lrp-set-gateway-chassis lrp-lr1-ts1 gw1 OVS_WAIT_UNTIL([ovn_as az2 ovn-sbctl show | grep lsp-ts1-lr1]) +ovn_as az2 ovn-nbctl lsp-set-options lsp-ts1-lr1 requested-chassis="" ovn-nbctl lrp-del-gateway-chassis lrp-lr1-ts1 gw1 OVS_WAIT_WHILE([ovn_as az2 ovn-sbctl show | grep lsp-ts1-lr1]) diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index acb1a4334..7f50e4c7f 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -9728,3 +9728,70 @@ AT_CHECK([grep "lr_in_gw_redirect" R1flows |sed s'/table=../table=??/' |sort], [ AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([Remote port binding]) +AT_KEYWORDS([remote-port-binding]) +ovn_start + +check ovn-sbctl chassis-add remote-ch0 geneve 127.0.0.1 +check ovn-sbctl set chassis remote-ch0 other_config:is-remote=true + +check ovn-sbctl chassis-add local-ch0 geneve 127.0.0.2 +wait_row_count Chassis 2 + +remote_chassis_uuid=$(fetch_column Chassis _uuid name=remote-ch0) +as northd ovn-appctl -t NORTHD_TYPE vlog/set dbg + +check ovn-nbctl ls-add sw0 +check ovn-nbctl lsp-add sw0 sw0-r1 -- lsp-set-type sw0-r1 remote +check ovn-nbctl lsp-set-options sw0-r1 requested-chassis=remote-ch0 +wait_for_ports_up sw0-r1 + +# Make sure it is bound by remote-ch0 +check_column $remote_chassis_uuid Port_Binding chassis logical_port=sw0-r1 + +check ovn-nbctl remove logical_switch_port sw0-r1 options requested-chassis +wait_row_count nb:Logical_Switch_Port 1 up=false name=sw0-r1 + +check_column '' Port_Binding chassis logical_port=sw0-r1 + +# Set the requested-chassis to local-ch0. ovn-northd should not +# bind it. But before that bind again to remote-ch0. This becomes +# easier to test for the local-ch0 scenario. +check ovn-nbctl lsp-set-options sw0-r1 requested-chassis=remote-ch0 +wait_for_ports_up sw0-r1 +check_column $remote_chassis_uuid Port_Binding chassis logical_port=sw0-r1 +check ovn-nbctl lsp-set-options sw0-r1 requested-chassis=local-ch0 +wait_row_count nb:Logical_Switch_Port 1 up=false name=sw0-r1 +check_column '' Port_Binding chassis logical_port=sw0-r1 + +# Set the requested-chassis to unknown chassis. ovn-northd should not +# bind it. But before that bind again to remote-ch0. This becomes +# easier to test for the local-ch0 scenario. +check ovn-nbctl lsp-set-options sw0-r1 requested-chassis=remote-ch0 +wait_for_ports_up sw0-r1 +check_column $remote_chassis_uuid Port_Binding chassis logical_port=sw0-r1 +check ovn-nbctl lsp-set-options sw0-r1 requested-chassis=foo +wait_row_count nb:Logical_Switch_Port 1 up=false name=sw0-r1 +check_column '' Port_Binding chassis logical_port=sw0-r1 + +# Change the port type to normal and ovn-northd should not bind it. +check ovn-nbctl lsp-set-options sw0-r1 requested-chassis=remote-ch0 +wait_for_ports_up sw0-r1 +check_column $remote_chassis_uuid Port_Binding chassis logical_port=sw0-r1 +check ovn-nbctl lsp-set-type sw0-r1 '' +wait_row_count nb:Logical_Switch_Port 1 up=false name=sw0-r1 +check_column '' Port_Binding chassis logical_port=sw0-r1 + +# Change back to type to remote and ovn-northd should bind it. +check ovn-nbctl lsp-set-type sw0-r1 remote +wait_for_ports_up sw0-r1 +check_column $remote_chassis_uuid Port_Binding chassis logical_port=sw0-r1 + +# Set the type to router and ovn-northd should not claim it. +check ovn-nbctl lsp-set-type sw0-r1 router +check_column '' Port_Binding chassis logical_port=sw0-r1 + +AT_CLEANUP +]) diff --git a/tests/ovn.at b/tests/ovn.at index 2e9ae31c0..8f367b499 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -26133,6 +26133,19 @@ done # XXX This should be more systematic. sleep 2 +# Populate requested-chassis options for remote lsps +for az in $(seq 1 $n_az); do + ovn_as az${az} + for ts in $(seq 1 $n_ts); do + for i in $(seq 1 $n_ts); do + if [[ $i -eq ${az} ]]; then + continue + fi + check ovn-nbctl lsp-set-options lsp-ts${ts}-lr${i}-${ts} requested-chassis=gw$i + done + done +done + ovn-ic-nbctl show > ic-nbctl.dump AT_CAPTURE_FILE([ic-nbctl.dump]) @@ -26356,6 +26369,13 @@ check ovn-nbctl lsp-add ts ts-lr3 \ wait_for_ports_up +ovn_as az1 +check ovn-nbctl lsp-set-options ts-lr2 requested-chassis=hv2 +check ovn-nbctl lsp-set-options ts-lr3 requested-chassis=hv2 + +ovn_as az2 +check ovn-nbctl lsp-set-options ts-lr1 requested-chassis=hv1 + dnl Enable unregistered IP multicast flooding and IP multicast relay. ovn_as az1 check ovn-nbctl set logical_switch ls1 other_config:mcast_snoop="true" \ @@ -26561,6 +26581,13 @@ check ovn-nbctl lsp-add ts ts-lr3 \ wait_for_ports_up +ovn_as az1 +check ovn-nbctl lsp-set-options ts-lr2 requested-chassis=hv2 +check ovn-nbctl lsp-set-options ts-lr3 requested-chassis=hv2 + +ovn_as az2 +check ovn-nbctl lsp-set-options ts-lr1 requested-chassis=hv1 + dnl Enable IP multicast snooping and IP multicast relay. Reports are dnl forwarded statically. ovn_as az1 -- 2.41.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
