> Add LSP/LRP option `requested-encap-ip` so the CMS can request a specific > `Port_Binding.encap` IP (e.g., transit switch ports in ovn-k8s interconnect > mode). > > When the same encap IP exists for both Geneve and VXLAN, prefer Geneve. > > If `requested-chassis` is set, consider only encaps on that chassis; otherwise > (router-LSP cases), use IP-only lookup. > > NB-requested encap overrides the VIF `external_ids:encap-ip`. Track NB > ownership with Port_Binding option `is-encap-nb-bound` to avoid ovn-northd vs > ovn-controller races.
Hi Lei, I think the patch is mostly fine, just some comments inline. Regards, Lorenzo > > CC: Han Zhou <[email protected]> > Signed-off-by: Lei Huang <[email protected]> > --- > NEWS | 3 + > controller/binding.c | 11 ++- > northd/en-northd.c | 4 ++ > northd/inc-proc-northd.c | 7 ++ > northd/northd.c | 116 +++++++++++++++++++++++++++++-- > northd/northd.h | 1 + > ovn-nb.xml | 18 +++++ > tests/ovn-inc-proc-graph-dump.at | 2 + > tests/ovn-northd.at | 92 ++++++++++++++++++++++++ > tests/ovn.at | 55 +++++++++++++++ > 10 files changed, 300 insertions(+), 9 deletions(-) > > diff --git a/NEWS b/NEWS > index ef7b4210b..888946b54 100644 > --- a/NEWS > +++ b/NEWS > @@ -3,6 +3,9 @@ Post v26.03.0 > > OVN v26.03.0 - xxx xx xxxx > -------------------------- > + - Added LSP/LRP option "requested-encap-ip" to let CMS request a specific > + SB Port_Binding encap IP (e.g., for transit switch ports in ovn-k8s > + interconnect mode). > - Added DNS query statistics tracking in ovn-controller using OVS coverage > counters. Statistics can be queried using "ovn-appctl -t ovn-controller > coverage/read-counter <counter_name>" or "coverage/show". Tracked > metrics > diff --git a/controller/binding.c b/controller/binding.c > index eb9524142..8c7da101e 100644 > --- a/controller/binding.c > +++ b/controller/binding.c > @@ -1306,6 +1306,10 @@ update_port_encap_if_needed(const struct > sbrec_port_binding *pb, > const struct ovsrec_interface *iface_rec, > bool sb_readonly) > { > + if (smap_get_bool(&pb->options, "is-encap-nb-bound", false)) { I guess we need document this option. > + return true; > + } > + > const struct sbrec_encap *encap_rec = > sbrec_get_port_encap(chassis_rec, iface_rec); > if ((encap_rec && pb->encap != encap_rec) || > @@ -1508,7 +1512,8 @@ release_lport_main_chassis(const struct > sbrec_port_binding *pb, > bool sb_readonly, > struct if_status_mgr *if_mgr) > { > - if (pb->encap) { > + if (pb->encap && > + !smap_get_bool(&pb->options, "is-encap-nb-bound", false)) { > if (sb_readonly) { > return false; > } > @@ -2406,7 +2411,9 @@ binding_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn, > bool any_changes = false; > SBREC_PORT_BINDING_TABLE_FOR_EACH (binding_rec, port_binding_table) { > if (binding_rec->chassis == chassis_rec) { > - if (binding_rec->encap) { > + if (binding_rec->encap && > + !smap_get_bool(&binding_rec->options, > + "is-encap-nb-bound", false)) { > sbrec_port_binding_set_encap(binding_rec, NULL); > } > sbrec_port_binding_set_chassis(binding_rec, NULL); > diff --git a/northd/en-northd.c b/northd/en-northd.c > index a828f9a5f..c34818dba 100644 > --- a/northd/en-northd.c > +++ b/northd/en-northd.c > @@ -51,6 +51,10 @@ northd_get_input_data(struct engine_node *node, > engine_ovsdb_node_get_index( > engine_get_input("SB_chassis", node), > "sbrec_chassis_by_hostname"); > + input_data->sbrec_encap_by_ip = > + engine_ovsdb_node_get_index( > + engine_get_input("SB_encap", node), > + "sbrec_encap_by_ip"); > input_data->sbrec_ha_chassis_grp_by_name = > engine_ovsdb_node_get_index( > engine_get_input("SB_ha_chassis_group", node), > diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c > index b79272324..cdab8d168 100644 > --- a/northd/inc-proc-northd.c > +++ b/northd/inc-proc-northd.c > @@ -97,6 +97,7 @@ static unixctl_cb_func chassis_features_list; > #define SB_NODES \ > SB_NODE(sb_global) \ > SB_NODE(chassis) \ > + SB_NODE(encap) \ > SB_NODE(address_set) \ > SB_NODE(port_group) \ > SB_NODE(logical_flow) \ > @@ -261,6 +262,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > NULL); > > engine_add_input(&en_northd, &en_sb_chassis, NULL); > + engine_add_input(&en_northd, &en_sb_encap, NULL); Can this dependency have a ovn-northd performance impact? What about adding a IP handler for it? > engine_add_input(&en_northd, &en_sb_mirror, NULL); > engine_add_input(&en_northd, &en_sb_meter, NULL); > engine_add_input(&en_northd, &en_sb_dns, NULL); > @@ -514,6 +516,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > ip_mcast_index_create(sb->idl); > struct ovsdb_idl_index *sbrec_chassis_by_hostname = > chassis_hostname_index_create(sb->idl); > + struct ovsdb_idl_index *sbrec_encap_by_ip = > + ovsdb_idl_index_create1(sb->idl, &sbrec_encap_col_ip); > struct ovsdb_idl_index *sbrec_mac_binding_by_datapath > = mac_binding_by_datapath_index_create(sb->idl); > struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip > @@ -529,6 +533,9 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > engine_ovsdb_node_add_index(&en_sb_chassis, > "sbrec_chassis_by_hostname", > sbrec_chassis_by_hostname); > + engine_ovsdb_node_add_index(&en_sb_encap, > + "sbrec_encap_by_ip", > + sbrec_encap_by_ip); > engine_ovsdb_node_add_index(&en_sb_ha_chassis_group, > "sbrec_ha_chassis_grp_by_name", > sbrec_ha_chassis_grp_by_name); > diff --git a/northd/northd.c b/northd/northd.c > index 983975dac..8caddc62d 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -2546,6 +2546,90 @@ ovn_port_update_sbrec_chassis( > free(requested_chassis_sb); > } > > +static const struct sbrec_encap * > +encap_lookup_by_ip(struct ovsdb_idl_index *sbrec_encap_by_ip, > + const char *ip, const char *requested_chassis) > +{ > + struct sbrec_encap *key = > + sbrec_encap_index_init_row(sbrec_encap_by_ip); > + sbrec_encap_index_set_ip(key, ip); > + > + const struct sbrec_encap *best = NULL; > + const struct sbrec_encap *encap; > + SBREC_ENCAP_FOR_EACH_EQUAL (encap, key, sbrec_encap_by_ip) { > + if (requested_chassis && > + strcmp(encap->chassis_name, requested_chassis)) { > + continue; > + } > + > + enum chassis_tunnel_type tun_type = get_tunnel_type(encap->type); > + if (tun_type == TUNNEL_TYPE_INVALID) { > + continue; > + } > + /* Pick the highest-preference tunnel type (geneve > vxlan) > + * when multiple encap types share the same IP. */ > + if (!best || get_tunnel_type(best->type) < tun_type) { > + best = encap; > + } > + } > + sbrec_encap_index_destroy_row(key); > + > + return best; > +} > + > +static void > +ovn_port_update_requested_encap( > + struct ovsdb_idl_index *sbrec_encap_by_ip, > + const struct ovn_port *op, > + bool was_encap_nb_bound) > +{ > + if (is_cr_port(op)) { > + return; > + } > + > + const struct smap *options = op->nbsp ? &op->nbsp->options > + : &op->nbrp->options; > + const char *requested_ip = smap_get(options, "requested-encap-ip"); > + if (!requested_ip || !requested_ip[0]) { > + if (was_encap_nb_bound) { > + if (op->sb->encap) { > + sbrec_port_binding_set_encap(op->sb, NULL); > + } > + sbrec_port_binding_update_options_delkey(op->sb, > + "is-encap-nb-bound"); > + } > + return; > + } > + > + const char *requested_chassis = op->sb->requested_chassis > + ? op->sb->requested_chassis->name > + : NULL; > + const struct sbrec_encap *encap = encap_lookup_by_ip(sbrec_encap_by_ip, > + requested_ip, > + requested_chassis); > + if (!encap) { > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); > + if (requested_chassis) { > + VLOG_WARN_RL(&rl, > + "No Encap matches options requested-encap-ip=\"%s\" > " > + "and requested-chassis=\"%s\" for logical port %s; " > + "clearing Port_Binding.encap.", > + requested_ip, requested_chassis, op->key); > + } else { > + VLOG_WARN_RL(&rl, > + "No Encap matches option requested-encap-ip=\"%s\" " > + "for logical port %s; clearing Port_Binding.encap.", > + requested_ip, op->key); > + } > + } > + > + if (op->sb->encap != encap) { > + sbrec_port_binding_set_encap(op->sb, encap); > + } > + sbrec_port_binding_update_options_setkey(op->sb, "is-encap-nb-bound", > + "true"); > +} > + > static void > check_and_do_sb_mirror_deletion(const struct ovn_port *op) > { > @@ -2616,11 +2700,14 @@ ovn_port_update_sbrec(struct ovsdb_idl_txn *ovnsb_txn, > struct ovsdb_idl_index *sbrec_chassis_by_hostname, > struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name, > const struct sbrec_mirror_table *sbrec_mirror_table, > + struct ovsdb_idl_index *sbrec_encap_by_ip, > const struct ovn_port *op, > unsigned long *queue_id_bitmap, > struct sset *active_ha_chassis_grps) > { > sbrec_port_binding_set_datapath(op->sb, op->od->sdp->sb_dp); > + bool was_encap_nb_bound = smap_get_bool(&op->sb->options, > + "is-encap-nb-bound", false); > if (op->nbrp) { > /* Note: SB port binding options for router ports are set in > * sync_pbs(). */ > @@ -2952,6 +3039,9 @@ common: > sbrec_port_binding_set_tunnel_key(op->sb, op->tunnel_key); > } > > + ovn_port_update_requested_encap(sbrec_encap_by_ip, op, > + was_encap_nb_bound); > + > /* ovn-controller will update 'Port_Binding.up' only if it was explicitly > * set to 'false'. > */ > @@ -4232,6 +4322,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn, > const struct sbrec_ha_chassis_group_table *sbrec_ha_chassis_group_table, > struct ovsdb_idl_index *sbrec_chassis_by_name, > struct ovsdb_idl_index *sbrec_chassis_by_hostname, > + struct ovsdb_idl_index *sbrec_encap_by_ip, > struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name, > struct hmap *ls_datapaths, struct hmap *lr_datapaths, > struct hmap *ls_ports, struct hmap *lr_ports, > @@ -4307,6 +4398,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn, > sbrec_chassis_by_hostname, > sbrec_ha_chassis_grp_by_name, > sbrec_mirror_table, > + sbrec_encap_by_ip, > op, queue_id_bitmap, > &active_ha_chassis_grps); > op->od->is_transit_router |= is_transit_router_port(op); > @@ -4321,6 +4413,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn, > sbrec_chassis_by_hostname, > sbrec_ha_chassis_grp_by_name, > sbrec_mirror_table, > + sbrec_encap_by_ip, > op, queue_id_bitmap, > &active_ha_chassis_grps); > sbrec_port_binding_set_logical_port(op->sb, op->key); > @@ -4543,7 +4636,8 @@ ls_port_init(struct ovn_port *op, struct ovsdb_idl_txn > *ovnsb_txn, > const struct sbrec_port_binding *sb, > const struct sbrec_mirror_table *sbrec_mirror_table, > struct ovsdb_idl_index *sbrec_chassis_by_name, > - struct ovsdb_idl_index *sbrec_chassis_by_hostname) > + struct ovsdb_idl_index *sbrec_chassis_by_hostname, > + struct ovsdb_idl_index *sbrec_encap_by_ip) > { > op->od = od; > parse_lsp_addrs(op); > @@ -4573,6 +4667,7 @@ ls_port_init(struct ovn_port *op, struct ovsdb_idl_txn > *ovnsb_txn, > } > ovn_port_update_sbrec(ovnsb_txn, sbrec_chassis_by_name, > sbrec_chassis_by_hostname, NULL, > sbrec_mirror_table, > + sbrec_encap_by_ip, > op, NULL, NULL); > return true; > } > @@ -4583,13 +4678,15 @@ ls_port_create(struct ovsdb_idl_txn *ovnsb_txn, > struct hmap *ls_ports, > struct ovn_datapath *od, > const struct sbrec_mirror_table *sbrec_mirror_table, > struct ovsdb_idl_index *sbrec_chassis_by_name, > - struct ovsdb_idl_index *sbrec_chassis_by_hostname) > + struct ovsdb_idl_index *sbrec_chassis_by_hostname, > + struct ovsdb_idl_index *sbrec_encap_by_ip) > { > 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_by_name, sbrec_chassis_by_hostname)) { > + sbrec_chassis_by_name, sbrec_chassis_by_hostname, > + sbrec_encap_by_ip)) { > ovn_port_destroy(ls_ports, op); > return NULL; > } > @@ -4604,14 +4701,16 @@ ls_port_reinit(struct ovn_port *op, struct > ovsdb_idl_txn *ovnsb_txn, > const struct sbrec_port_binding *sb, > const struct sbrec_mirror_table *sbrec_mirror_table, > struct ovsdb_idl_index *sbrec_chassis_by_name, > - struct ovsdb_idl_index *sbrec_chassis_by_hostname) > + struct ovsdb_idl_index *sbrec_chassis_by_hostname, > + struct ovsdb_idl_index *sbrec_encap_by_ip) > { > ovn_port_cleanup(op); > op->sb = sb; > ovn_port_set_nb(op, nbsp, NULL); > op->primary_port = op->cr_port = NULL; > return ls_port_init(op, ovnsb_txn, od, sb, sbrec_mirror_table, > - sbrec_chassis_by_name, sbrec_chassis_by_hostname); > + sbrec_chassis_by_name, sbrec_chassis_by_hostname, > + sbrec_encap_by_ip); > } > > /* Returns true if the logical switch has changes which can be > @@ -4810,7 +4909,8 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn > *ovnsb_idl_txn, > new_nbsp->name, new_nbsp, od, > ni->sbrec_mirror_table, > ni->sbrec_chassis_by_name, > - ni->sbrec_chassis_by_hostname); > + ni->sbrec_chassis_by_hostname, > + ni->sbrec_encap_by_ip); > if (!op) { > goto fail; > } > @@ -4853,7 +4953,8 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn > *ovnsb_idl_txn, > new_nbsp, > od, sb, ni->sbrec_mirror_table, > ni->sbrec_chassis_by_name, > - ni->sbrec_chassis_by_hostname)) { > + ni->sbrec_chassis_by_hostname, > + ni->sbrec_encap_by_ip)) { > if (sb) { > sbrec_port_binding_delete(sb); > } > @@ -20959,6 +21060,7 @@ ovnnb_db_run(struct northd_input *input_data, > input_data->sbrec_ha_chassis_group_table, > input_data->sbrec_chassis_by_name, > input_data->sbrec_chassis_by_hostname, > + input_data->sbrec_encap_by_ip, > input_data->sbrec_ha_chassis_grp_by_name, > &data->ls_datapaths.datapaths, &data->lr_datapaths.datapaths, > &data->ls_ports, &data->lr_ports, > diff --git a/northd/northd.h b/northd/northd.h > index 4dcd128cc..a876e0a56 100644 > --- a/northd/northd.h > +++ b/northd/northd.h > @@ -86,6 +86,7 @@ struct northd_input { > struct ovsdb_idl_index *nbrec_mirror_by_type_and_sink; > struct ovsdb_idl_index *sbrec_chassis_by_name; > struct ovsdb_idl_index *sbrec_chassis_by_hostname; > + struct ovsdb_idl_index *sbrec_encap_by_ip; > struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name; > struct ovsdb_idl_index *sbrec_ip_mcast_by_dp; > struct ovsdb_idl_index *sbrec_fdb_by_dp_and_port; > diff --git a/ovn-nb.xml b/ovn-nb.xml > index 954ed1166..f1cd89509 100644 > --- a/ovn-nb.xml > +++ b/ovn-nb.xml > @@ -1567,6 +1567,15 @@ > </p> > </column> > > + <column name="options" key="requested-encap-ip"> > + Requests the encapsulation IP address for the port binding. If set, > + <code>ovn-northd</code> uses this IP to select the > + <ref table="Encap" db="OVN_Southbound"/> entry written to > + <ref table="Port_Binding" column="encap" db="OVN_Southbound"/>. > + This is intended for ports without a local OVS interface, e.g. > remote > + transit switch ports in ovn-kubernetes interconnect mode. > + </column> > + > <column name="options" key="activation-strategy"> > If used with multiple chassis set in > <ref column="requested-chassis"/>, specifies an activation strategy > @@ -4543,6 +4552,15 @@ or > </p> > </column> > > + <column name="options" key="requested-encap-ip"> > + Requests the encapsulation IP address for the port binding. If set, > + <code>ovn-northd</code> uses this IP to select the > + <ref table="Encap" db="OVN_Southbound"/> entry written to > + <ref table="Port_Binding" column="encap" db="OVN_Southbound"/>. > + This is intended for ports without a local OVS interface, e.g. remote > + transit router ports in ovn-kubernetes interconnect mode. > + </column> > + > <column name="options" key="dynamic-routing-redistribute" > type='{"type": "string"}'> > <p> > diff --git a/tests/ovn-inc-proc-graph-dump.at > b/tests/ovn-inc-proc-graph-dump.at > index a31aad6e7..44fa4dee9 100644 > --- a/tests/ovn-inc-proc-graph-dump.at > +++ b/tests/ovn-inc-proc-graph-dump.at > @@ -20,6 +20,7 @@ digraph "Incremental-Processing-Engine" { > NB_network_function_group [[style=filled, shape=box, fillcolor=white, > label="NB_network_function_group"]]; > NB_logical_switch_port_health_check [[style=filled, shape=box, > fillcolor=white, label="NB_logical_switch_port_health_check"]]; > SB_chassis [[style=filled, shape=box, fillcolor=white, > label="SB_chassis"]]; > + SB_encap [[style=filled, shape=box, fillcolor=white, label="SB_encap"]]; > SB_mirror [[style=filled, shape=box, fillcolor=white, > label="SB_mirror"]]; > SB_meter [[style=filled, shape=box, fillcolor=white, label="SB_meter"]]; > SB_dns [[style=filled, shape=box, fillcolor=white, label="SB_dns"]]; > @@ -78,6 +79,7 @@ digraph "Incremental-Processing-Engine" { > NB_network_function_group -> northd [[label=""]]; > NB_logical_switch_port_health_check -> northd [[label=""]]; > SB_chassis -> northd [[label=""]]; > + SB_encap -> northd [[label=""]]; > SB_mirror -> northd [[label=""]]; > SB_meter -> northd [[label=""]]; > SB_dns -> northd [[label=""]]; > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index e29f6d7b5..90f64f6fe 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -2896,6 +2896,98 @@ OVN_CLEANUP_NORTHD > AT_CLEANUP > ]) > > +OVN_FOR_EACH_NORTHD_NO_HV([ > +AT_SETUP([check options:requested-encap-ip fills port binding encap col]) > +AT_KEYWORDS([requested encap ip]) > +ovn_start > + > +check_uuid ovn-sbctl \ > + -- --id=@e11 create encap chassis_name=ch1 ip="192.168.1.1" type="vxlan" > \ > + -- --id=@e12 create encap chassis_name=ch1 ip="192.168.1.2" > type="geneve" \ > + -- --id=@c1 create chassis name=ch1 encaps=@e11,@e12 > +check_uuid ovn-sbctl \ > + -- --id=@e21 create encap chassis_name=ch2 ip="192.168.2.1" > type="geneve" \ > + -- --id=@e22 create encap chassis_name=ch2 ip="192.168.2.2" > type="geneve" \ > + -- --id=@c2 create chassis name=ch2 encaps=@e21,@e22 > + > +wait_row_count Chassis 2 > +wait_row_count Encap 4 > +en11_uuid=$(fetch_column Encap _uuid ip="192.168.1.1") > +en12_uuid=$(fetch_column Encap _uuid ip="192.168.1.2") > +en21_uuid=$(fetch_column Encap _uuid ip="192.168.2.1") > +en22_uuid=$(fetch_column Encap _uuid ip="192.168.2.2") > +ovn-sbctl show > + > +echo "__file__:__line__: encap uuid: $en11_uuid, ip: 192.168.1.1" > +echo "__file__:__line__: encap uuid: $en12_uuid, ip: 192.168.1.2" > +echo "__file__:__line__: encap uuid: $en21_uuid, ip: 192.168.2.1" > +echo "__file__:__line__: encap uuid: $en22_uuid, ip: 192.168.2.2" > + > +check ovn-nbctl --wait=sb ls-add ls1 > +check ovn-nbctl --wait=sb lsp-add ls1 lsp1 > +check ovn-nbctl --wait=sb lsp-add ls1 lsp2 > +ovn-nbctl show > + > +# set options:requested-encap-ip without requested-chassis > +check ovn-nbctl --wait=sb set logical-switch-port lsp1 \ > + options:requested-encap-ip=192.168.1.1 > +check ovn-nbctl --wait=sb sync > +wait_row_count Port_Binding 1 logical_port=lsp1 encap="$en11_uuid" > + > +# With requested-chassis set to a different chassis, encap should be cleared. > +check ovn-nbctl --wait=sb set logical-switch-port lsp1 \ > + options:requested-chassis=ch2 > +wait_row_count Port_Binding 1 logical_port=lsp1 'encap=[[]]' > + > +# Set both options to a matching chassis+IP. > +check ovn-nbctl --wait=sb set logical-switch-port lsp1 \ > + options:requested-chassis=ch1 \ > + options:requested-encap-ip=192.168.1.1 > +check ovn-nbctl --wait=sb set logical-switch-port lsp2 \ > + options:requested-chassis=ch2 \ > + options:requested-encap-ip=192.168.2.2 > + > +wait_row_count Port_Binding 1 logical_port=lsp1 encap="$en11_uuid" > +wait_row_count Port_Binding 1 logical_port=lsp2 encap="$en22_uuid" > + > +# Add geneve encap with the same IP and ensure it is preferred over vxlan. > +check_uuid ovn-sbctl \ > + -- --id=@e11g create encap chassis_name=ch1 ip="192.168.1.1" > type="geneve" \ > + -- add chassis ch1 encaps @e11g > +wait_row_count Encap 5 > +en11g_uuid=$(fetch_column Encap _uuid chassis_name=ch1 ip="192.168.1.1" > type=geneve) > +wait_row_count Port_Binding 1 logical_port=lsp1 encap="$en11g_uuid" > + > +# Router LSP path has no requested-chassis, but requested-encap-ip should > work. > +check ovn-nbctl --wait=sb lr-add lr1 > +check ovn-nbctl --wait=sb lrp-add lr1 lrp1 00:00:00:01:00:01 100.64.0.1/24 > +check ovn-nbctl --wait=sb lsp-add ls1 lsp-router1 \ > + -- lsp-set-type lsp-router1 router \ > + -- lsp-set-options lsp-router1 router-port=lrp1 \ > + -- lsp-set-addresses lsp-router1 router > +check ovn-nbctl --wait=sb set logical-switch-port lsp-router1 \ > + options:requested-encap-ip=192.168.2.1 > +wait_row_count Port_Binding 1 logical_port=lsp-router1 encap="$en21_uuid" > + > +# remove options:requested-encap-ip from lsp1 > +check ovn-nbctl --wait=sb remove logical_switch_port lsp1 \ > + options requested-encap-ip=192.168.1.1 > +wait_row_count Port_Binding 1 logical_port=lsp1 'encap=[[]]' > + > +# remove options:requested-chassis from lsp2 and keep requested-encap-ip > +check ovn-nbctl --wait=sb remove logical_switch_port lsp2 \ > + options requested-chassis=ch2 > +wait_row_count Port_Binding 1 logical_port=lsp2 encap="$en22_uuid" > + > +# remove options:requested-encap-ip from lsp2 > +check ovn-nbctl --wait=sb remove logical_switch_port lsp2 \ > + options requested-encap-ip=192.168.2.2 > +wait_row_count Port_Binding 1 logical_port=lsp2 'encap=[[]]' > + > +OVN_CLEANUP_NORTHD > +AT_CLEANUP > +]) > + > OVN_FOR_EACH_NORTHD_NO_HV([ > AT_SETUP([port requested-tnl-key]) > AT_KEYWORDS([requested tnl tunnel key keys]) > diff --git a/tests/ovn.at b/tests/ovn.at > index 9082bba82..ae7909899 100644 > --- a/tests/ovn.at > +++ b/tests/ovn.at > @@ -40748,6 +40748,61 @@ ignored_dp=lsw0]) > AT_CLEANUP > ]) > > +OVN_FOR_EACH_NORTHD([ > +AT_SETUP([ovn-controller - requested-encap-ip should override VIF encap-ip]) > +ovn_start > +net_add n1 > + > +sim_add hv1 > +as hv1 > +ovs-vsctl add-br br-phys > +ovn_attach n1 br-phys 192.168.0.1 > +check ovs-vsctl set Open_vSwitch . \ > + external_ids:ovn-encap-ip="192.168.0.1,192.168.0.11" \ > + external_ids:ovn-encap-ip-default=192.168.0.1 \ > + external_ids:ovn-enable-flow-based-tunnels=false > + > +check ovn-nbctl ls-add ls0 > +check ovn-nbctl lsp-add ls0 lsp0 > +check ovn-nbctl lsp-set-addresses lsp0 "50:54:00:00:00:01 10.0.0.1" > + > +as hv1 > +check ovs-vsctl -- add-port br-int vif0 -- \ > + set Interface vif0 external-ids:iface-id=lsp0 \ > + external-ids:encap-ip=192.168.0.11 > + > +wait_row_count Chassis 1 name=hv1 > +wait_row_count Encap 4 chassis_name=hv1 > +check ovn-nbctl --wait=hv sync > +wait_for_ports_up lsp0 > + > +encap_uuid_vif=$(ovn-sbctl --bare --columns _uuid find Encap \ > + chassis_name=hv1 ip="192.168.0.11" type=geneve) > +encap_uuid_nb=$(ovn-sbctl --bare --columns _uuid find Encap \ > + chassis_name=hv1 ip="192.168.0.1" type=geneve) > + > +get_pb_encap_uuid() { > + fetch_column Port_Binding encap logical_port=lsp0 > +} > + > +# Verify local VIF encap-ip is reflected by ovn-controller. > +OVS_WAIT_UNTIL([test "$encap_uuid_vif" = "$(get_pb_encap_uuid)"]) > + > +# Now request NB-driven encap. > +check ovn-nbctl --wait=sb lsp-set-options lsp0 \ > + requested-chassis=hv1 requested-encap-ip=192.168.0.1 > + > +# Touch iface to trigger ovn-controller processing for this VIF. > +as hv1 > +check ovs-vsctl set Interface vif0 external-ids:encap-ip=192.168.0.11 should we add some code to manage this dependency automatically instead of requiring user intervention? > + > +# Expected behavior: NB request should win over local iface encap-ip. > +OVS_WAIT_UNTIL([test "$encap_uuid_nb" = "$(get_pb_encap_uuid)"]) > + > +OVN_CLEANUP([hv1]) > +AT_CLEANUP > +]) > + > OVN_FOR_EACH_NORTHD([ > AT_SETUP([DHCP RELAY]) > ovn_start > -- > 2.43.0 > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
_______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
