Signed-off-by: Gavin McKee <gavmcke...@googlemail.com> --- controller/ovn-controller.8.xml | 5 +++ controller/ovn-controller.c | 1 - controller/patch.c | 44 +++++++++++++++++--- tests/ovn-controller.at | 72 +++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 7 deletions(-)
diff --git a/controller/ovn-controller.8.xml b/controller/ovn-controller.8.xml index 5007f5f80..422eb2cf7 100644 --- a/controller/ovn-controller.8.xml +++ b/controller/ovn-controller.8.xml @@ -554,6 +554,11 @@ bridge, with the same <code>external_ids:ovn-localnet-port</code> value. </p> + <p> + When a <code>localnet</code> port has additional values in its + <code>external_ids</code> column, these key-value pairs are copied to + the corresponding patch ports. + </p> </dd> <dt> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 7940091da..8c8d47fe3 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -5857,7 +5857,6 @@ main(int argc, char *argv[]) ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_sb_global_col_external_ids); ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_external_ids); - ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_port_binding_col_external_ids); ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_ssl_col_external_ids); ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_gateway_chassis_col_external_ids); diff --git a/controller/patch.c b/controller/patch.c index 4fed6e375..5ba1466e0 100644 --- a/controller/patch.c +++ b/controller/patch.c @@ -73,18 +73,38 @@ match_patch_port(const struct ovsrec_port *port, const char *peer) * 'dst_name' in bridge 'dst'. Initializes the patch port's external-ids:'key' * to 'key'. * - * If such a patch port already exists, removes it from 'existing_ports'. */ + * If such a patch port already exists, removes it from 'existing_ports'. Any + * key-value pairs in 'extra_ids' are merged into the port's external IDs. If + * the port already exists, its external IDs are updated accordingly. + */ static void create_patch_port(struct ovsdb_idl_txn *ovs_idl_txn, const char *key, const char *value, const struct ovsrec_bridge *src, const char *src_name, const struct ovsrec_bridge *dst, const char *dst_name, - struct shash *existing_ports) + struct shash *existing_ports, + const struct smap *extra_ids) { for (size_t i = 0; i < src->n_ports; i++) { if (match_patch_port(src->ports[i], dst_name)) { /* Patch port already exists on 'src'. */ - shash_find_and_delete(existing_ports, src->ports[i]->name); + const struct ovsrec_port *port = src->ports[i]; + shash_find_and_delete(existing_ports, port->name); + if (extra_ids) { + const struct smap *ids = &port->external_ids; + struct smap merged = SMAP_INITIALIZER(&merged); + smap_clone(&merged, ids); + struct smap_node *node; + SMAP_FOR_EACH (node, extra_ids) { + const char *cur = smap_get(&merged, node->key); + if (!cur || strcmp(cur, node->value)) { + ovsrec_port_update_external_ids_setkey(port, + node->key, + node->value); + } + } + smap_destroy(&merged); + } return; } } @@ -94,9 +114,16 @@ create_patch_port(struct ovsdb_idl_txn *ovs_idl_txn, src_name, src->name, dst->name); const struct smap if_options = SMAP_CONST1(&if_options, "peer", dst_name); - const struct smap port_ids = SMAP_CONST1(&port_ids, key, value); + + struct smap port_ids = SMAP_INITIALIZER(&port_ids); + if (extra_ids) { + smap_clone(&port_ids, extra_ids); + } + smap_replace(&port_ids, key, value); + ovsport_create(ovs_idl_txn, src, src_name, "patch", &port_ids, NULL, &if_options, 0); + smap_destroy(&port_ids); } static void @@ -223,12 +250,17 @@ add_bridge_mappings_by_type(struct ovsdb_idl_txn *ovs_idl_txn, sset_find_and_delete(&missed_bridges, msg_key); free(msg_key); + const struct smap *extra_ids = + !strcmp(pb_type, "localnet") ? &binding->external_ids : NULL; + char *name1 = patch_port_name(br_int->name, binding->logical_port); char *name2 = patch_port_name(binding->logical_port, br_int->name); create_patch_port(ovs_idl_txn, patch_port_id, binding->logical_port, - br_int, name1, br_ln, name2, existing_ports); + br_int, name1, br_ln, name2, existing_ports, + extra_ids); create_patch_port(ovs_idl_txn, patch_port_id, binding->logical_port, - br_ln, name2, br_int, name1, existing_ports); + br_ln, name2, br_int, name1, existing_ports, + extra_ids); free(name1); free(name2); } diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at index ae7eb6f31..6ae97e87d 100644 --- a/tests/ovn-controller.at +++ b/tests/ovn-controller.at @@ -139,6 +139,7 @@ check_patches \ 'br-int patch-br-int-to-localnet2 patch-localnet2-to-br-int' \ 'br-eth0 patch-localnet2-to-br-int patch-br-int-to-localnet2' + # Add logical patch ports to connect new logical datapath. # # OVN no longer uses OVS patch ports to implement logical patch ports, so @@ -174,6 +175,77 @@ OVS_APP_EXIT_AND_WAIT([ovsdb-server]) AT_CLEANUP ]) +OVN_FOR_EACH_NORTHD([ +AT_SETUP([Localnet port external ids]) +AT_KEYWORDS([lb]) +ovn_start + +check ovn-nbctl ls-add sw0 +check ovn-nbctl lsp-add sw0 sw0-port1 +check ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:01 10.0.0.3 1000::3" +check ovn-nbctl lsp-add sw0 sw0-port2 +check ovn-nbctl lsp-set-addresses sw0-port2 "50:54:00:00:00:02 10.0.0.4 1000::4" + +check ovn-nbctl lr-add lr0 +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 1000::1/64 +check ovn-nbctl lsp-add sw0 sw0-lr0 +check ovn-nbctl lsp-set-type sw0-lr0 router +check ovn-nbctl lsp-set-addresses sw0-lr0 router +check ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0 + +check ovn-nbctl ls-add public +check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24 2000::1/64 +check ovn-nbctl lsp-add public public-lr0 +check ovn-nbctl lsp-set-type public-lr0 router +check ovn-nbctl lsp-set-addresses public-lr0 router +check ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public + +# localnet port +check ovn-nbctl lsp-add public ln-public +check ovn-nbctl lsp-set-type ln-public localnet +check ovn-nbctl lsp-set-addresses ln-public unknown +check ovn-nbctl lsp-set-options ln-public network_name=phys + +check ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20 + +net_add n1 + +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=sw0-port1 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 + +check ovn-nbctl --wait=hv set logical_switch_port ln-public external_ids:foo=bar +wait_column "foo=bar" Port_Binding external_ids logical_port=ln-public + +AT_CHECK([as hv1 ovs-vsctl get port patch-br-int-to-ln-public external_ids:foo], [0], [dnl +bar +]) + +AT_CHECK([as hv1 ovs-vsctl get port patch-ln-public-to-br-int external_ids:foo], [0], [dnl +bar +]) + +check ovn-nbctl --wait=hv set logical_switch_port ln-public external_ids:foo=foobar +wait_column "foo=foobar" Port_Binding external_ids logical_port=ln-public + +AT_CHECK([as hv1 ovs-vsctl get port patch-br-int-to-ln-public external_ids:foo], [0], [dnl +foobar +]) + +AT_CHECK([as hv1 ovs-vsctl get port patch-ln-public-to-br-int external_ids:foo], [0], [dnl +foobar +]) + +AT_CLEANUP +]) + # Checks that ovn-controller populates datapath-type and iface-types # correctly in the Chassis other_config column. OVN_FOR_EACH_NORTHD([ -- 2.34.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev