> On Thu, Aug 28, 2025 at 4:14 PM Lorenzo Bianconi < > lorenzo.bianc...@redhat.com> wrote: > > > Introduce disable_garp_rarp option in the Logical_Router table in order > > to disable GARP/RARP announcements by all the peer ports of this logical > > router. > > > > Reported-at: https://issues.redhat.com/browse/FDP-1537 > > Signed-off-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com> > > --- > > Changes in v3: > > - Trigger garp_rarp_run if datapath sb table change > > - Improve unit-test > > - cosmetics > > --- > > > > Hi Lorenzo, > > thank you for the v3, I have a few comments down below.
Hi Ales, thx for the review. > > > > NEWS | 2 + > > controller/garp_rarp.c | 26 ++++++++++- > > controller/ovn-controller.c | 1 + > > northd/en-datapath-logical-router.c | 5 ++ > > ovn-nb.xml | 9 ++++ > > tests/ovn.at | 72 +++++++++++++++++++++++++++++ > > 6 files changed, 113 insertions(+), 2 deletions(-) > > > > diff --git a/NEWS b/NEWS > > index 932e173af..f21a7e235 100644 > > --- a/NEWS > > +++ b/NEWS > > @@ -66,6 +66,8 @@ OVN v25.09.0 - xxx xx xxxx > > - ovn-sbctl: > > * Added --filter option that allows filtering the command output. See > > ovn-sbctl(8) for more details. > > + - Added disable_garp_rarp option to logical_router table in order to > > disable > > + GARP/RARP announcements by all the peer ports of this logical router. > > > > OVN v25.03.0 - 07 Mar 2025 > > -------------------------- > > diff --git a/controller/garp_rarp.c b/controller/garp_rarp.c > > index 8eccf10fe..940c38e13 100644 > > --- a/controller/garp_rarp.c > > +++ b/controller/garp_rarp.c > > @@ -446,6 +446,26 @@ garp_rarp_clear(struct garp_rarp_ctx_in *r_ctx_in) > > sset_clear(&r_ctx_in->data->local_lports); > > } > > > > +static bool > > +garp_rarp_is_enabled(struct ovsdb_idl_index *sbrec_port_binding_by_name, > > + const struct sbrec_port_binding *pb) > > +{ > > + if (smap_get_bool(&pb->options, "disable_garp_rarp", false)) { > > + return false; > > + } > > + > > + /* Check if GARP probing is disabled on the peer logical router. */ > > + const struct sbrec_port_binding *peer = lport_get_peer( > > + pb, sbrec_port_binding_by_name); > > + if (peer && peer->datapath && > > + smap_get_bool(&peer->datapath->external_ids, > > + "disable_garp_rarp", false)) { > > + return false; > > + } > > + > > + return true; > > +} > > + > > void > > garp_rarp_run(struct garp_rarp_ctx_in *r_ctx_in) > > { > > @@ -478,7 +498,8 @@ garp_rarp_run(struct garp_rarp_ctx_in *r_ctx_in) > > SSET_FOR_EACH (iface_id, &localnet_vifs) { > > const struct sbrec_port_binding *pb = lport_lookup_by_name( > > r_ctx_in->sbrec_port_binding_by_name, iface_id); > > - if (pb && !smap_get_bool(&pb->options, "disable_garp_rarp", > > false)) { > > + if (pb && > > + garp_rarp_is_enabled(r_ctx_in->sbrec_port_binding_by_name, > > pb)) { > > send_garp_rarp_update(r_ctx_in, pb, &nat_addresses); > > } > > } > > @@ -488,7 +509,8 @@ garp_rarp_run(struct garp_rarp_ctx_in *r_ctx_in) > > SSET_FOR_EACH (gw_port, &local_l3gw_ports) { > > const struct sbrec_port_binding *pb = lport_lookup_by_name( > > r_ctx_in->sbrec_port_binding_by_name, gw_port); > > - if (pb && !smap_get_bool(&pb->options, "disable_garp_rarp", > > false)) { > > + if (pb && > > + garp_rarp_is_enabled(r_ctx_in->sbrec_port_binding_by_name, > > pb)) { > > send_garp_rarp_update(r_ctx_in, pb, &nat_addresses); > > } > > } > > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c > > index 6396fa898..61a79b308 100644 > > --- a/controller/ovn-controller.c > > +++ b/controller/ovn-controller.c > > @@ -6864,6 +6864,7 @@ main(int argc, char *argv[]) > > dns_cache_sb_dns_handler); > > > > engine_add_input(&en_garp_rarp, &en_ovs_open_vswitch, NULL); > > + engine_add_input(&en_garp_rarp, &en_sb_datapath_binding, NULL); > > > > This will unfortunately cause a lot of unrelated recomputes which could > be pretty costly, we had an issue with this node in the past when it > caused a lot of forced recomputes. I think the simplest handler > which will minimize the impact should check: > 1) Datapath is local. > 2) Datapath is a logical router. > 3) And the column external_ids has changed. > > This will prevent a lot of unnecessary > recomputes. ack, fine. Do you think it is ok to just return EN_UNHANDLED if the conditions above are met? Or do you prefer something more precise? > > engine_add_input(&en_garp_rarp, &en_sb_chassis, NULL); > > engine_add_input(&en_garp_rarp, &en_sb_port_binding, > > garp_rarp_sb_port_binding_handler); > > diff --git a/northd/en-datapath-logical-router.c > > b/northd/en-datapath-logical-router.c > > index 22687e849..f6f49422f 100644 > > --- a/northd/en-datapath-logical-router.c > > +++ b/northd/en-datapath-logical-router.c > > @@ -83,6 +83,11 @@ gather_external_ids(const struct nbrec_logical_router > > *nbr, > > "%u", age_threshold); > > } > > > > + bool disable_garp_rarp = smap_get_bool(&nbr->options, > > "disable_garp_rarp", > > + false); > > + smap_add_format(external_ids, "disable_garp_rarp", > > + disable_garp_rarp ? "true" : "false"); > > + > > /* For backwards-compatibility, also store the NB UUID in > > * external-ids:logical-router. This is useful if ovn-controller > > * has not updated and expects this to be where to find the > > diff --git a/ovn-nb.xml b/ovn-nb.xml > > index b7b5b5c40..034500e00 100644 > > --- a/ovn-nb.xml > > +++ b/ovn-nb.xml > > @@ -3333,6 +3333,15 @@ or > > routes in <code>ovn-ic</code> daemon. > > </p> > > </column> > > + > > + <column name="options" key="disable_garp_rarp" > > + type='{"type": "boolean"}'> > > + <p> > > + If set to <code>true</code>, GARP and RARP announcements are not > > + sent by all the VIF peer ports of this logical router. > > + The default value is <code>false</code>. > > + </p> > > + </column> > > </group> > > <group title="Common Columns"> > > <column name="external_ids"> > > diff --git a/tests/ovn.at b/tests/ovn.at > > index 292ca0dae..cd5bdfeef 100644 > > --- a/tests/ovn.at > > +++ b/tests/ovn.at > > @@ -26310,6 +26310,78 @@ OVN_CLEANUP([hv1]) > > AT_CLEANUP > > ]) > > > > +OVN_FOR_EACH_NORTHD([ > > +AT_SETUP([Disabling RARP/GARP announcements from Router options]) > > +ovn_start > > + > > +net_add n1 > > + > > +sim_add hv1 > > +as hv1 > > +ovs-vsctl add-br br-phys > > +ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys > > +ovn_attach n1 br-phys 192.168.0.1 > > + > > +check ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif > > options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap > > +check ovs-vsctl add-port br-int vif1 -- set Interface vif1 > > external-ids:iface-id=lsp1 > > + > > +check ovs-vsctl set Open_vSwitch . external-ids:garp-max-timeout-sec=1 > > + > > +check ovn-nbctl ls-add ls1 > > +check ovn-nbctl lsp-add ls1 ln1 > > +check ovn-nbctl lsp-set-addresses ln1 unknown > > +check ovn-nbctl lsp-set-type ln1 localnet > > +check ovn-nbctl lsp-set-options ln1 network_name=phys > > + > > +check ovn-nbctl lr-add lr1 > > +check ovn-nbctl set Logical_Router lr1 options:disable_garp_rarp="true" > > +check ovn-nbctl lrp-add lr1 lrp 00:00:00:00:00:11 192.168.1.1/24 > > +check ovn-nbctl lsp-add ls1 ls-lrp \ > > + -- set Logical_Switch_Port ls-lrp type=router \ > > + options:router-port=lrp addresses=\"00:00:00:00:00:11\" > > +check ovn-nbctl lrp-set-gateway-chassis lrp hv1 > > + > > +check ovn-nbctl lsp-add ls1 lsp1 > > +check ovn-nbctl lsp-set-addresses lsp1 "00:00:00:00:00:12 192.168.1.2" > > > > Sorry I didn't mention that earlier, but we should also define a NAT > on the lr1 and make sure the NAT isn't advertised as well when the > option is set to true. That's the main use case for the RFE. > > nit: Missing ovn-nbctl --wait=hv sync. ack, I will add it. > > > > +wait_for_ports_up > > + > > +garp_lrp=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', > > src='00:00:00:00:00:11')/ \ > > + ARP(hwsrc='00:00:00:00:00:11', psrc='192.168.1.1', > > pdst='192.168.1.1')") > > +garp_vif=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', > > src='00:00:00:00:00:12')/ \ > > + ARP(hwsrc='00:00:00:00:00:12', psrc='192.168.1.2', > > pdst='192.168.1.2')") > > +# GARP packet for vif > > +echo $garp_vif > expected > > +OVN_CHECK_PACKETS_UNIQ([hv1/snoopvif-tx.pcap], [expected]) > > +$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap > > > hv1/snoopvif-tx.packets > > +AT_CHECK([grep -q "$garp_lrp" hv1/snoopvif-tx.packets], [1]) > > + > > +# GARP packet for lrp > > +echo $garp_lrp >> expected > > +check ovn-nbctl --wait=sb set Logical_Router lr1 > > options:disable_garp_rarp="false" > > > > nit: The wait target should be hv instead of sb. ack, I will fix it. > > > > +OVN_CHECK_PACKETS_UNIQ([hv1/snoopvif-tx.pcap], [expected]) > > + > > +# Check for GW router > > +check ovn-nbctl lrp-del-gateway-chassis lrp hv1 > > +check ovn-nbctl set Logical_Router lr1 options:chassis="hv1" > > +check ovn-nbctl set Logical_Router lr1 options:disable_garp_rarp="true" > > +check ovn-nbctl --wait=sb sync > > > > nit: Same here, s/sb/hv/ ack, I will fix it. > > > > + > > +sleep_controller hv1 > > +reset_pcap_file snoopvif hv1/snoopvif > > +wake_up_controller hv1 > > + > > +echo $garp_vif > expected > > +OVN_CHECK_PACKETS_UNIQ([hv1/snoopvif-tx.pcap], [expected]) > > +$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap > > > hv1/snoopvif-tx.packets > > +AT_CHECK([grep -q "$garp_lrp" hv1/snoopvif-tx.packets], [1]) > > + > > +echo $garp_lrp >> expected > > +check ovn-nbctl set Logical_Router lr1 options:disable_garp_rarp="false" > > > > nit: Missing --wait=hv ack, I will fix it. Regards, Lorenzo > > > > +OVN_CHECK_PACKETS_UNIQ([hv1/snoopvif-tx.pcap], [expected]) > > + > > +AT_CLEANUP > > +]) > > + > > OVN_FOR_EACH_NORTHD([ > > AT_SETUP([Stateless Floating IP]) > > ovn_start > > -- > > 2.50.1 > > > > > Thanks, > Ales
_______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev