From patchwork Thu Jul 15 18:40:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Gray X-Patchwork-Id: 1505859 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: 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=gbWQiXwB; dkim-atps=neutral Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GQjqx4J88z9sRR for ; Fri, 16 Jul 2021 04:40:45 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 1541640E85; Thu, 15 Jul 2021 18:40:41 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id MsSuBGZTRMAQ; Thu, 15 Jul 2021 18:40:39 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id 9B1D3400CA; Thu, 15 Jul 2021 18:40:38 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6D85CC0010; Thu, 15 Jul 2021 18:40:38 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id E7F14C000E for ; Thu, 15 Jul 2021 18:40:37 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id C513E42367 for ; Thu, 15 Jul 2021 18:40:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp4.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AlFelJDN_QxX for ; Thu, 15 Jul 2021 18:40:36 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 13449422AA for ; Thu, 15 Jul 2021 18:40:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626374435; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OWGDev/wbBeSrpSDJsOdog5w/EExwBI2ltfMgwCC8dQ=; b=gbWQiXwB5l7/a/RKdFI+5nD8rD0/RBRUG61sVezZeCf2W3VB0KLCqlf1FDt/FRr7/nZwr4 UdTcG9FJSaSEF9+n9B3epsaHlXiw3qx6wFTCh+fLQf6RxRNW7nSO/NBtlrXi7jFQc17coS 1pemVk/RvksEJOy/o2VsssjJuk0+zLw= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-308-wQFDqljLPnWw3gUMU4WI1A-1; Thu, 15 Jul 2021 14:40:27 -0400 X-MC-Unique: wQFDqljLPnWw3gUMU4WI1A-1 Received: by mail-wm1-f71.google.com with SMTP id n5-20020a05600c3b85b02902152e9caa1dso1938061wms.3 for ; Thu, 15 Jul 2021 11:40:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=OWGDev/wbBeSrpSDJsOdog5w/EExwBI2ltfMgwCC8dQ=; b=dmlfUyV/B0phbnpPxJi0wtiwOWmyH9IGzGCyk4kHLm+1OQiEb6N8VCpeByHIAr72Vu UrW3xWIWZdnKW0x78kUr5euy6TCgmRTnoGNF/bVOPt+ZA0L7z1c2RNvaleRIdgJw1ooj woACw1NLZLFqvkxizW0ZfgSojk7N6ttJdSwCbB3Kgxw3JKnClVFgvRjR8jSTPgihg8l/ O1HYPgNKFfU/38zTdt4u1kny9Y+HvOYDrfHfJ7g8qU3ILhJNk9onh0/VhlJp+VI7tvkH DGgfvuzP/ih0Z33PciZldbl2/4K2E5HE7SdDmdX9x2upsxyj8USaudjGnYri+mws0lMF /fKg== X-Gm-Message-State: AOAM532Is8vLSvyhq96Gjyiix8kgACBeIE7r9ZzKdEgAvMM8dJGEOzqN CK4l59/dJnR119PV3Tj4DWa6y0QbxBRAudo2Me14jId1HZ5K1sUU8kx/eq6lKsJOOfZekoHpLZH j4tC9FlHfgUzH0tXQqV5uWSjRy8NEkV1HKXrK4vvvf5AQR+vEsV3U6u5a7P59OqyaAVHj X-Received: by 2002:adf:f9c9:: with SMTP id w9mr7218397wrr.107.1626374426203; Thu, 15 Jul 2021 11:40:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwS88xfJJar0nHaGOFRfG75TJ9k6wn+C7drlJrpYL8f54cfNQSaxB2EiZmDLf90lZoFqQEEFg== X-Received: by 2002:adf:f9c9:: with SMTP id w9mr7218357wrr.107.1626374425720; Thu, 15 Jul 2021 11:40:25 -0700 (PDT) Received: from wsfd-netdev91.ntdv.lab.eng.bos.redhat.com (nat-pool-bos-t.redhat.com. [66.187.233.206]) by smtp.gmail.com with ESMTPSA id k24sm7700027wrh.30.2021.07.15.11.40.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Jul 2021 11:40:25 -0700 (PDT) From: Mark Gray To: dev@openvswitch.org Date: Thu, 15 Jul 2021 14:40:23 -0400 Message-Id: <20210715184023.3452781-1-mark.d.gray@redhat.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mark.d.gray@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: dceara@redhat.com Subject: [ovs-dev] [PATCH ovn v2] northd: Fix defrag flows for duplicate vips 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 adding two SB flows with the same vip but different protocols, only the most recent flow will be added due to the `if` statement: if (!sset_contains(&all_ips, lb_vip->vip_str)) { sset_add(&all_ips, lb_vip->vip_str); This can cause unexpected behaviour when two load balancers with the same VIP (and different protocols) are added to a logical router. This is due to the addition of "protocol" to the match in defrag table flows in a previous commit. Add flow to defrag table for every load-balancer in order to resolve this. Flows for Load Balancers without a port specified are added with priority 100. Flows for Load Balancers with a port specified are added with priority 110. Add a test to check behaviour of Logical Flows when two load balancers of the same VIP are added. This bug was discovered through the OVN CI (ovn-kubernetes.yml). Fixes: 384a7c6237da ("northd: Refactor Logical Flows for routers with DNAT/Load Balancers") Signed-off-by: Mark Gray Acked-by: Dumitru Ceara --- Notes: v2 - Address Mark M.'s comments * Add flows to defrag table for every LB VIP and every LB VIP + proto rather than just every unique LB VIP * Change priority of flows in LB VIP + proto case in order to not clash with flows in LB VIP case. * Add additional tests. northd/ovn-northd.8.xml | 35 +++++++++++----- northd/ovn-northd.c | 64 ++++++++++++++-------------- northd/ovn_northd.dl | 8 ++-- tests/ovn-northd.at | 93 +++++++++++++++++++++++++++++++---------- 4 files changed, 130 insertions(+), 70 deletions(-) diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index a20c5b90dc66..6599ba194fe5 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -2773,17 +2773,32 @@ icmp6 {

- If load balancing rules with virtual IP addresses (and ports) are - configured in OVN_Northbound database for a Gateway router, + If load balancing rules with only virtual IP addresses are configured in + OVN_Northbound database for a Gateway router, a priority-100 flow is added for each configured virtual IP address - VIP. For IPv4 VIPs the flow matches ip - && ip4.dst == VIP. For IPv6 VIPs, - the flow matches ip && ip6.dst == VIP. - The flow applies the action reg0 = VIP - && ct_dnat; to send IP packets to the - connection tracker for packet de-fragmentation and to dnat the - destination IP for the committed connection before sending it to the - next table. + VIP. For IPv4 VIPs the flow matches + ip && ip4.dst == VIP. For IPv6 + VIPs, the flow matches ip && ip6.dst == + VIP. The flow applies the action reg0 = + VIP; ct_dnat; (or xxreg0 for IPv6) to + send IP packets to the connection tracker for packet de-fragmentation and + to dnat the destination IP for the committed connection before sending it + to the next table. +

+ +

+ If load balancing rules with virtual IP addresses and ports are + configured in OVN_Northbound database for a Gateway router, + a priority-110 flow is added for each configured virtual IP address + VIP and protocol PROTO. For IPv4 VIPs + the flow matches ip && ip4.dst == VIP && + PROTO. For IPv6 VIPs, the flow matches + ip && ip6.dst == VIP && + PROTO. The flow applies the action reg0 = + VIP; ct_dnat; (or xxreg0 for IPv6) to send + IP packets to the connection tracker for packet de-fragmentation and to + dnat the destination IP for the committed connection before sending it to + the next table.

diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 999c3f482c29..2a11172d94b6 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -9207,8 +9207,6 @@ static void build_lrouter_lb_flows(struct hmap *lflows, struct ovn_datapath *od, struct hmap *lbs, struct ds *match) { - /* A set to hold all ips that need defragmentation and tracking. */ - struct sset all_ips = SSET_INITIALIZER(&all_ips); for (int i = 0; i < od->nbr->n_load_balancer; i++) { struct nbrec_load_balancer *nb_lb = od->nbr->load_balancer[i]; @@ -9217,6 +9215,7 @@ build_lrouter_lb_flows(struct hmap *lflows, struct ovn_datapath *od, ovs_assert(lb); for (size_t j = 0; j < lb->n_vips; j++) { + int prio = 100; struct ovn_lb_vip *lb_vip = &lb->vips[j]; bool is_udp = nullable_string_is_equal(nb_lb->protocol, "udp"); @@ -9225,42 +9224,41 @@ build_lrouter_lb_flows(struct hmap *lflows, struct ovn_datapath *od, const char *proto = is_udp ? "udp" : is_sctp ? "sctp" : "tcp"; struct ds defrag_actions = DS_EMPTY_INITIALIZER; - if (!sset_contains(&all_ips, lb_vip->vip_str)) { - sset_add(&all_ips, lb_vip->vip_str); - /* If there are any load balancing rules, we should send - * the packet to conntrack for defragmentation and - * tracking. This helps with two things. - * - * 1. With tracking, we can send only new connections to - * pick a DNAT ip address from a group. - * 2. If there are L4 ports in load balancing rules, we - * need the defragmentation to match on L4 ports. */ - ds_clear(match); - ds_clear(&defrag_actions); - if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) { - ds_put_format(match, "ip && ip4.dst == %s", - lb_vip->vip_str); - ds_put_format(&defrag_actions, "reg0 = %s; ct_dnat;", - lb_vip->vip_str); - } else { - ds_put_format(match, "ip && ip6.dst == %s", - lb_vip->vip_str); - ds_put_format(&defrag_actions, "xxreg0 = %s; ct_dnat;", - lb_vip->vip_str); - } - if (lb_vip->vip_port) { - ds_put_format(match, " && %s", proto); - } - ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG, - 100, ds_cstr(match), - ds_cstr(&defrag_actions), - &nb_lb->header_); + /* If there are any load balancing rules, we should send + * the packet to conntrack for defragmentation and + * tracking. This helps with two things. + * + * 1. With tracking, we can send only new connections to + * pick a DNAT ip address from a group. + * 2. If there are L4 ports in load balancing rules, we + * need the defragmentation to match on L4 ports. */ + ds_clear(match); + ds_clear(&defrag_actions); + if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) { + ds_put_format(match, "ip && ip4.dst == %s", + lb_vip->vip_str); + ds_put_format(&defrag_actions, "reg0 = %s; ct_dnat;", + lb_vip->vip_str); + } else { + ds_put_format(match, "ip && ip6.dst == %s", + lb_vip->vip_str); + ds_put_format(&defrag_actions, "xxreg0 = %s; ct_dnat;", + lb_vip->vip_str); } + + if (lb_vip->vip_port) { + ds_put_format(match, " && %s", proto); + prio = 110; + } + ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG, + prio, ds_cstr(match), + ds_cstr(&defrag_actions), + &nb_lb->header_); + ds_destroy(&defrag_actions); } } - sset_destroy(&all_ips); } #define ND_RA_MAX_INTERVAL_MAX 1800 diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl index ceeabe6f384e..dbf0e6ef1cdd 100644 --- a/northd/ovn_northd.dl +++ b/northd/ovn_northd.dl @@ -6168,11 +6168,11 @@ for (RouterLBVIP( * 2. If there are L4 ports in load balancing rules, we * need the defragmentation to match on L4 ports. */ var match1 = "ip && ${ipX}.dst == ${ip_address}" in - var match2 = + (var prio, var match2) = if (port != 0) { - " && ${proto}" + (110, " && ${proto}") } else { - "" + (100, "") } in var __match = match1 ++ match2 in var xx = ip_address.xxreg() in @@ -6183,7 +6183,7 @@ for (RouterLBVIP( * get merged by DDlog. */ Flow(.logical_datapath = lr_uuid, .stage = s_ROUTER_IN_DEFRAG(), - .priority = 100, + .priority = prio, .__match = __match, .actions = __actions, .external_ids = stage_hint(lb._uuid)); diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 11461d3f4c2a..4193b1a933b4 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -3167,7 +3167,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -3200,7 +3200,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -3243,7 +3243,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -3300,7 +3300,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -3344,7 +3344,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.20 && tcp), action=(reg0 = 10.0.0.20; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.20 && tcp), action=(reg0 = 10.0.0.20; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | grep skip_snat_for_lb | sort], [0], [dnl @@ -4361,10 +4361,10 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -4421,10 +4421,10 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -4476,10 +4476,10 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -4534,11 +4534,11 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && tcp), action=(reg0 = 172.168.0.10; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.10 && tcp), action=(reg0 = 172.168.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -4605,12 +4605,12 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && tcp), action=(reg0 = 172.168.0.10; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) - table=5 (lr_in_defrag ), priority=100 , match=(ip && ip6.dst == def0::2 && tcp), action=(xxreg0 = def0::2; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.10 && tcp), action=(reg0 = 172.168.0.10; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip6.dst == def0::2 && tcp), action=(xxreg0 = def0::2; ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl @@ -4652,5 +4652,52 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) ]) +check ovn-nbctl lrp-del lr0-sw0 +check ovn-nbctl lrp-del lr0-public +check ovn-nbctl lr-lb-del lr0 +check ovn-nbctl lr-nat-del lr0 + +check ovn-nbctl lb-add lb3 172.168.0.210:60 "10.0.0.50:6062,10.0.0.60:6062" udp +check ovn-nbctl lb-add lb4 172.168.0.210:60 "10.0.0.50:6062,10.0.0.60:6062" tcp +check ovn-nbctl lr-lb-add lr0 lb3 +check ovn-nbctl lr-lb-add lr0 lb4 +check ovn-nbctl --wait=sb sync + +ovn-sbctl dump-flows lr0 > lr0flows +AT_CAPTURE_FILE([lr0flows]) + +AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl + table=4 (lr_in_unsnat ), priority=0 , match=(1), action=(next;) +]) + +AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl + table=5 (lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.210 && tcp), action=(reg0 = 172.168.0.210; ct_dnat;) + table=5 (lr_in_defrag ), priority=110 , match=(ip && ip4.dst == 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; ct_dnat;) +]) + +AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl + table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && ct_label.natted == 1 && tcp), action=(flags.force_snat_for_lb = 1; next;) + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && ct_label.natted == 1 && udp), action=(flags.force_snat_for_lb = 1; next;) + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && tcp && tcp.dst == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && udp.dst == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) +]) + +AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl + table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +]) + +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl + table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +]) + +AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl + table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +]) + AT_CLEANUP ])