From patchwork Wed Dec 6 16:44:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 1872850 X-Patchwork-Delegate: dceara@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=gH5ZVANB; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Sljth5dQJz23nD for ; Thu, 7 Dec 2023 03:45:00 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id E748E6151E; Wed, 6 Dec 2023 16:44:58 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org E748E6151E Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=gH5ZVANB X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wO2hCob6agsw; Wed, 6 Dec 2023 16:44:57 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id B47DC60A74; Wed, 6 Dec 2023 16:44:56 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org B47DC60A74 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8A413C0077; Wed, 6 Dec 2023 16:44:56 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 25069C0037 for ; Wed, 6 Dec 2023 16:44:55 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 007D683495 for ; Wed, 6 Dec 2023 16:44:55 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 007D683495 Authentication-Results: smtp1.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=gH5ZVANB X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id d0IAen2qQAcs for ; Wed, 6 Dec 2023 16:44:53 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id 795B283265 for ; Wed, 6 Dec 2023 16:44:53 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 795B283265 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1701881092; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kNDmHuE3WfxPi4u7h8joqua2dmeEP0tjxjgf+A9xXZU=; b=gH5ZVANBtUVayEW0GH2A3pMyHZAKy264xrCKsQcgulCGTdQBirM4qqeFDwS8urkvTMHKi5 r2MHOlqcYtdQdI0t5F3C0XoEeCVR/xSfJLBivi1tExnQZ33S8/YRQm3jiVUJ1vDHu9LEGB DUpyqKvnUNfSyT2WoI3at6/kOxKOQLI= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-138-c3qAdcpYNRWBc5HvWASPPw-1; Wed, 06 Dec 2023 11:44:51 -0500 X-MC-Unique: c3qAdcpYNRWBc5HvWASPPw-1 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-33335c6d495so761024f8f.2 for ; Wed, 06 Dec 2023 08:44:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701881089; x=1702485889; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kNDmHuE3WfxPi4u7h8joqua2dmeEP0tjxjgf+A9xXZU=; b=hugT8F0SQ0R1CfXzxWZAWBq50ZmlTVP3lHjUPXyS9rQaAm2yUDNTgjzETy78ewaQIZ aLq0JDh5i3kDGIkwHz4fB7TWC5st0I93CxJYn1pI/anGHTb+8PZX6gPSJRb94mqN2zZp L/JEYdAohkQLWj9JwewEPhVUY9kq9i64Ya4NBcjWP+UffOfR3xMCeh95aNFHyFhJxE/1 yoUZnFlY1tSdI7+FAToWQv/OnCB7Op8FPYVrqtcRC3GHeQ3yjkshJMZmd6CAxnpQCu0M V0P0ve/rrdylWCL00DW4X/zLbAgi1mw4q8Ya1g+TTqntnOAIVNYE0+23V7JMpdXbfKdi 7usw== X-Gm-Message-State: AOJu0Yzu7EP+JyExbov97RADksmqA9xfiQScS8cRKsH3eTLSXodFdtrF 7WMXT0wdKHHI6Fo8iFPLMzv6Cv1zmXlpDNlOiPy8HT+VugK7jMeXu4XMe7A6yJbA0JNkwo8br2k AoUTrZ7jvWly24AmhdEudTnALOHiXCiGt3TvbuFQ9ospqQufuSHQ6h3NCSh9gHEPMY6U2YAnQ2c X0K/BJKYwF4194 X-Received: by 2002:a05:600c:3587:b0:40b:5e21:ec1d with SMTP id p7-20020a05600c358700b0040b5e21ec1dmr767602wmq.79.1701881089453; Wed, 06 Dec 2023 08:44:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IHLz4ovoSt5DxPjGdSmHM0vuBPPtKbrrWhZMAhwX7gQvwmUcrM5RUKgtM7FG5s9TemNmDW+ag== X-Received: by 2002:a05:600c:3587:b0:40b:5e21:ec1d with SMTP id p7-20020a05600c358700b0040b5e21ec1dmr767594wmq.79.1701881088878; Wed, 06 Dec 2023 08:44:48 -0800 (PST) Received: from localhost (net-93-71-3-198.cust.vodafonedsl.it. [93.71.3.198]) by smtp.gmail.com with ESMTPSA id o15-20020a05600c510f00b0040c1d2c6331sm130949wms.32.2023.12.06.08.44.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Dec 2023 08:44:48 -0800 (PST) From: Lorenzo Bianconi To: ovs-dev@openvswitch.org Date: Wed, 6 Dec 2023 17:44:44 +0100 Message-ID: X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH ovn 22.03] controller: make garp_max_timeout configurable X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When using VLAN backed networks and OVN routers leveraging the 'ovn-chassis-mac-mappings' option for east-west traffic, the eth.src field is replaced by the chassis mac address in order to not expose the router mac address from different nodes and confuse the TOR switch. However doing so the TOR switch is not able to learn the port/mac bindings for routed E/W traffic and it is force to always flood it. Fix this issue adding the capability to configure a given timeout for garp sent by ovn-controller and not disable it after the exponential backoff in order to keep refreshing the entries in TOR swtich fdb table. More into about the issue can be found here [0]. [0] https://mail.openvswitch.org/pipermail/ovs-discuss/2020-September/050678.html Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2087779 Signed-off-by: Lorenzo Bianconi Acked-by: Ales Musil Signed-off-by: Mark Michelson --- NEWS | 2 + controller/ovn-controller.8.xml | 11 +++++ controller/ovn-controller.c | 4 +- controller/pinctrl.c | 73 +++++++++++++++++++++++++++------ controller/pinctrl.h | 4 +- tests/ovn.at | 16 ++++++++ 6 files changed, 95 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index a924a2310..d2e495af3 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ OVN v22.03.6 - xx xxx xxxx -------------------------- + - Add "garp-max-timeout-sec" config option to vswitchd external-ids to + cap the time between when ovn-controller sends gARP packets. OVN v22.03.5 - 01 Dec 2023 -------------------------- diff --git a/controller/ovn-controller.8.xml b/controller/ovn-controller.8.xml index 3b597f80e..bcb8a8a01 100644 --- a/controller/ovn-controller.8.xml +++ b/controller/ovn-controller.8.xml @@ -343,6 +343,17 @@ heplful to pin source outer IP for the tunnel when multiple interfaces are used on the host for overlay traffic. +
external_ids:garp-max-timeout-sec
+
+ When used, this configuration value specifies the maximum timeout + (in seconds) between two consecutive GARP packets sent by + ovn-controller. + ovn-controller by default sends just 4 GARP packets + with an exponential backoff timeout. + Setting external_ids:garp-max-timeout-sec allows to + cap for the exponential backoff used by ovn-controller + to send GARPs packets. +

diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 75d42a043..2afb94611 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -4040,7 +4040,9 @@ main(int argc, char *argv[]) &runtime_data->local_datapaths, &runtime_data->active_tunnels, &runtime_data->local_active_ports_ipv6_pd, - &runtime_data->local_active_ports_ras); + &runtime_data->local_active_ports_ras, + ovsrec_open_vswitch_table_get( + ovs_idl_loop.idl)); stopwatch_stop(PINCTRL_RUN_STOPWATCH_NAME, time_msec()); /* Updating monitor conditions if runtime data or diff --git a/controller/pinctrl.c b/controller/pinctrl.c index 3502c7fe4..1b5fea1aa 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -164,6 +164,10 @@ static struct ovs_mutex pinctrl_mutex = OVS_MUTEX_INITIALIZER; static struct seq *pinctrl_handler_seq; static struct seq *pinctrl_main_seq; +#define GARP_RARP_DEF_MAX_TIMEOUT 16000 +static long long int garp_rarp_max_timeout = GARP_RARP_DEF_MAX_TIMEOUT; +static bool garp_rarp_continuous; + static void *pinctrl_handler(void *arg); struct pinctrl { @@ -210,7 +214,8 @@ static void send_garp_rarp_prepare( const struct ovsrec_bridge *, const struct sbrec_chassis *, const struct hmap *local_datapaths, - const struct sset *active_tunnels) + const struct sset *active_tunnels, + const struct ovsrec_open_vswitch_table *ovs_table) OVS_REQUIRES(pinctrl_mutex); static void send_garp_rarp_run(struct rconn *swconn, long long int *send_garp_rarp_time) @@ -3511,7 +3516,8 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, const struct hmap *local_datapaths, const struct sset *active_tunnels, const struct shash *local_active_ports_ipv6_pd, - const struct shash *local_active_ports_ras) + const struct shash *local_active_ports_ras, + const struct ovsrec_open_vswitch_table *ovs_table) { ovs_mutex_lock(&pinctrl_mutex); pinctrl_set_br_int_name_(br_int->name); @@ -3523,7 +3529,7 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, send_garp_rarp_prepare(ovnsb_idl_txn, sbrec_port_binding_by_datapath, sbrec_port_binding_by_name, sbrec_mac_binding_by_lport_ip, br_int, chassis, - local_datapaths, active_tunnels); + local_datapaths, active_tunnels, ovs_table); prepare_ipv6_ras(local_active_ports_ras, sbrec_port_binding_by_name); prepare_ipv6_prefixd(ovnsb_idl_txn, sbrec_port_binding_by_name, local_active_ports_ipv6_pd, chassis, @@ -4374,7 +4380,8 @@ struct garp_rarp_data { struct eth_addr ea; /* Ethernet address of port. */ ovs_be32 ipv4; /* Ipv4 address of port. */ long long int announce_time; /* Next announcement in ms. */ - int backoff; /* Backoff for the next announcement. */ + int backoff; /* Backoff timeout for the next + * announcement (in msecs). */ uint32_t dp_key; /* Datapath used to output this GARP. */ uint32_t port_key; /* Port to inject the GARP into. */ }; @@ -4403,7 +4410,7 @@ add_garp_rarp(const char *name, const struct eth_addr ea, ovs_be32 ip, garp_rarp->ea = ea; garp_rarp->ipv4 = ip; garp_rarp->announce_time = time_msec() + 1000; - garp_rarp->backoff = 1; + garp_rarp->backoff = 1000; /* msec. */ garp_rarp->dp_key = dp_key; garp_rarp->port_key = port_key; shash_add(&send_garp_rarp_data, name, garp_rarp); @@ -4419,7 +4426,9 @@ send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn, struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip, const struct hmap *local_datapaths, const struct sbrec_port_binding *binding_rec, - struct shash *nat_addresses) + struct shash *nat_addresses, + long long int garp_max_timeout, + bool garp_continuous) { volatile struct garp_rarp_data *garp_rarp = NULL; @@ -4445,6 +4454,12 @@ send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn, if (garp_rarp) { garp_rarp->dp_key = binding_rec->datapath->tunnel_key; garp_rarp->port_key = binding_rec->tunnel_key; + if (garp_max_timeout != garp_rarp_max_timeout || + garp_continuous != garp_rarp_continuous) { + /* reset backoff */ + garp_rarp->announce_time = time_msec() + 1000; + garp_rarp->backoff = 1000; /* msec. */ + } } else { add_garp_rarp(name, laddrs->ea, laddrs->ipv4_addrs[i].addr, @@ -4469,6 +4484,12 @@ send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn, if (garp_rarp) { garp_rarp->dp_key = binding_rec->datapath->tunnel_key; garp_rarp->port_key = binding_rec->tunnel_key; + if (garp_max_timeout != garp_rarp_max_timeout || + garp_continuous != garp_rarp_continuous) { + /* reset backoff */ + garp_rarp->announce_time = time_msec() + 1000; + garp_rarp->backoff = 1000; /* msec. */ + } } else { add_garp_rarp(name, laddrs->ea, 0, binding_rec->datapath->tunnel_key, @@ -4488,6 +4509,12 @@ send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn, if (garp_rarp) { garp_rarp->dp_key = binding_rec->datapath->tunnel_key; garp_rarp->port_key = binding_rec->tunnel_key; + if (garp_max_timeout != garp_rarp_max_timeout || + garp_continuous != garp_rarp_continuous) { + /* reset backoff */ + garp_rarp->announce_time = time_msec() + 1000; + garp_rarp->backoff = 1000; /* msec. */ + } return; } @@ -4573,13 +4600,15 @@ send_garp_rarp(struct rconn *swconn, struct garp_rarp_data *garp_rarp, ofpbuf_uninit(&ofpacts); /* Set the next announcement. At most 5 announcements are sent for a - * vif. */ - if (garp_rarp->backoff < 16) { - garp_rarp->backoff *= 2; - garp_rarp->announce_time = current_time + garp_rarp->backoff * 1000; + * vif if garp_rarp_max_timeout is not specified otherwise cap the max + * timeout to garp_rarp_max_timeout. */ + if (garp_rarp_continuous || garp_rarp->backoff < garp_rarp_max_timeout) { + garp_rarp->announce_time = current_time + garp_rarp->backoff; } else { garp_rarp->announce_time = LLONG_MAX; } + garp_rarp->backoff = MIN(garp_rarp_max_timeout, garp_rarp->backoff * 2); + return garp_rarp->announce_time; } @@ -5822,13 +5851,26 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, const struct hmap *local_datapaths, - const struct sset *active_tunnels) + const struct sset *active_tunnels, + const struct ovsrec_open_vswitch_table *ovs_table) OVS_REQUIRES(pinctrl_mutex) { struct sset localnet_vifs = SSET_INITIALIZER(&localnet_vifs); struct sset local_l3gw_ports = SSET_INITIALIZER(&local_l3gw_ports); struct sset nat_ip_keys = SSET_INITIALIZER(&nat_ip_keys); struct shash nat_addresses; + unsigned long long garp_max_timeout = GARP_RARP_DEF_MAX_TIMEOUT; + bool garp_continuous = false; + const struct ovsrec_open_vswitch *cfg = + ovsrec_open_vswitch_table_first(ovs_table); + if (cfg) { + garp_max_timeout = smap_get_ullong( + &cfg->external_ids, "garp-max-timeout-sec", 0) * 1000; + garp_continuous = !!garp_max_timeout; + if (!garp_max_timeout) { + garp_max_timeout = GARP_RARP_DEF_MAX_TIMEOUT; + } + } shash_init(&nat_addresses); @@ -5859,7 +5901,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn, if (pb) { send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip, - local_datapaths, pb, &nat_addresses); + local_datapaths, pb, &nat_addresses, + garp_max_timeout, garp_continuous); } } @@ -5870,7 +5913,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn, = lport_lookup_by_name(sbrec_port_binding_by_name, gw_port); if (pb) { send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip, - local_datapaths, pb, &nat_addresses); + local_datapaths, pb, &nat_addresses, + garp_max_timeout, garp_continuous); } } @@ -5888,6 +5932,9 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn, shash_destroy(&nat_addresses); sset_destroy(&nat_ip_keys); + + garp_rarp_max_timeout = garp_max_timeout; + garp_rarp_continuous = garp_continuous; } static bool diff --git a/controller/pinctrl.h b/controller/pinctrl.h index 88f18e983..b76e43626 100644 --- a/controller/pinctrl.h +++ b/controller/pinctrl.h @@ -28,6 +28,7 @@ struct lport_index; struct ovsdb_idl_index; struct ovsdb_idl_txn; struct ovsrec_bridge; +struct ovsrec_open_vswitch_table; struct sbrec_chassis; struct sbrec_dns_table; struct sbrec_controller_event_table; @@ -52,7 +53,8 @@ void pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, const struct hmap *local_datapaths, const struct sset *active_tunnels, const struct shash *local_active_ports_ipv6_pd, - const struct shash *local_active_ports_ras); + const struct shash *local_active_ports_ras, + const struct ovsrec_open_vswitch_table *ovs_table); void pinctrl_wait(struct ovsdb_idl_txn *ovnsb_idl_txn); void pinctrl_destroy(void); void pinctrl_set_br_int_name(char *br_int_name); diff --git a/tests/ovn.at b/tests/ovn.at index 7126bdb5a..29e2de60d 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -8635,6 +8635,7 @@ AT_CLEANUP OVN_FOR_EACH_NORTHD([ AT_SETUP([send gratuitous arp for l3gateway only on selected chassis]) +AT_SKIP_IF([test $HAVE_TCPDUMP = no]) ovn_start # Create logical switch @@ -8736,6 +8737,21 @@ sleep 2 OVN_CHECK_PACKETS_CONTAIN([hv2/snoopvif-tx.pcap], [arp_expected]) OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [empty_expected]) +# Temporarily remove lr0 chassis +AT_CHECK([ovn-nbctl --wait=hv remove logical_router lr0 options chassis]) + +as hv1 reset_pcap_file snoopvif hv1/snoopvif +as hv2 reset_pcap_file snoopvif hv2/snoopvif + +AT_CHECK([ovn-nbctl --wait=hv set logical_router lr0 options:chassis=hv1]) +# set garp max timeout to 2s +AT_CHECK([as hv1 ovs-vsctl set Open_vSwitch . external-ids:garp-max-timeout-sec=2]) + +OVS_WAIT_UNTIL([ +n_arp=$(tcpdump -c 10 -ner hv1/snoopvif-tx.pcap arp | wc -l) +test "$n_arp" = 10 +]) + OVN_CLEANUP([hv1],[hv2]) AT_CLEANUP