Message ID | 20241120163721.2611818-1-amusil@redhat.com |
---|---|
State | Deferred |
Headers | show |
Series | [ovs-dev,RFC,v2] northd: Commit all traffic when there is stateful NAT/LB. | expand |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | success | apply and check: success |
ovsrobot/github-robot-_Build_and_Test | fail | github build: failed |
ovsrobot/github-robot-_ovn-kubernetes | fail | github build: failed |
On 11/20/24 5:37 PM, Ales Musil wrote: > Commit all traffic that is not already commit by either NAT or LB. This > ensures that the traffic is tracked, and we don't erroneously commit > reply traffic, or reply traffic is not marked as invalid. > > To achieve the commit we need to perform lookup on every packet > that goes through LR pipeline whenever there is stateful NAT. > > The SNAT lookup requires additional flag as the unSNAT is happening > in ingress pipeline and at that point we need to know if the packet > is reply or not. This is not required for DNAT, because unDNAT stage > happens in egress. > > Signed-off-by: Ales Musil <amusil@redhat.com> > --- Hi Han, I was wondering if you had time to evaluate the performance impact of this patch in your lab. Thanks, Dumitru
On Wed, Dec 18, 2024 at 2:08 PM Dumitru Ceara <dceara@redhat.com> wrote: > On 11/20/24 5:37 PM, Ales Musil wrote: > > Commit all traffic that is not already commit by either NAT or LB. This > > ensures that the traffic is tracked, and we don't erroneously commit > > reply traffic, or reply traffic is not marked as invalid. > > > > To achieve the commit we need to perform lookup on every packet > > that goes through LR pipeline whenever there is stateful NAT. > > > > The SNAT lookup requires additional flag as the unSNAT is happening > > in ingress pipeline and at that point we need to know if the packet > > is reply or not. This is not required for DNAT, because unDNAT stage > > happens in egress. > > > > Signed-off-by: Ales Musil <amusil@redhat.com> > > --- > > Hi Han, > > I was wondering if you had time to evaluate the performance impact of > this patch in your lab. > > Thanks, > Dumitru > > Hi Han, by any chance did you have some time to run the performance tests? ovn-kubernetes is really interested in this as it will fix one of the use cases that they have. Thank you, Ales
I know from other emails in this thread that we don't want to merge this without some performance testing. However, from a code correctness perspective, I had a look through the change, and Acked-by: Mark Michelson <mmichels@redhat.com> I have a couple of nitpicks of comments in updated tests below. On 11/20/24 11:37, Ales Musil wrote: > Commit all traffic that is not already commit by either NAT or LB. This > ensures that the traffic is tracked, and we don't erroneously commit > reply traffic, or reply traffic is not marked as invalid. > > To achieve the commit we need to perform lookup on every packet > that goes through LR pipeline whenever there is stateful NAT. > > The SNAT lookup requires additional flag as the unSNAT is happening > in ingress pipeline and at that point we need to know if the packet > is reply or not. This is not required for DNAT, because unDNAT stage > happens in egress. > > Signed-off-by: Ales Musil <amusil@redhat.com> > --- > There are few failing system tests with userspace datapath, that's due > to the recirculation limit that is being hit due to additional > lookups. > --- > include/ovn/logical-fields.h | 4 + > lib/logical-fields.c | 4 + > northd/northd.c | 84 +++++++++++------- > northd/northd.h | 39 ++++---- > tests/ovn-macros.at | 6 ++ > tests/ovn-northd.at | 102 ++++++++++++++------- > tests/system-common-macros.at | 8 ++ > tests/system-ovn.at | 161 ++++++++++++++++++++++++++-------- > 8 files changed, 288 insertions(+), 120 deletions(-) > > diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h > index d563e044c..05bc18eab 100644 > --- a/include/ovn/logical-fields.h > +++ b/include/ovn/logical-fields.h > @@ -86,6 +86,7 @@ enum mff_log_flags_bits { > MLF_LOCALNET_BIT = 15, > MLF_RX_FROM_TUNNEL_BIT = 16, > MLF_ICMP_SNAT_BIT = 17, > + MLF_UNSNAT_NEW_BIT = 18, > }; > > /* MFF_LOG_FLAGS_REG flag assignments */ > @@ -141,6 +142,9 @@ enum mff_log_flags { > MLF_RX_FROM_TUNNEL = (1 << MLF_RX_FROM_TUNNEL_BIT), > > MLF_ICMP_SNAT = (1 << MLF_ICMP_SNAT_BIT), > + > + /* Indicate that the packet didn't go through unSNAT. */ > + MLF_UNSNAT_NEW = (1 << MLF_UNSNAT_NEW_BIT), > }; > > /* OVN logical fields > diff --git a/lib/logical-fields.c b/lib/logical-fields.c > index 5a8b53f2b..081faad5a 100644 > --- a/lib/logical-fields.c > +++ b/lib/logical-fields.c > @@ -139,6 +139,10 @@ ovn_init_symtab(struct shash *symtab) > flags_str); > snprintf(flags_str, sizeof flags_str, "flags[%d]", MLF_RX_FROM_TUNNEL_BIT); > expr_symtab_add_subfield(symtab, "flags.tunnel_rx", NULL, flags_str); > + snprintf(flags_str, sizeof flags_str, "flags[%d]", > + MLF_UNSNAT_NEW_BIT); > + expr_symtab_add_subfield(symtab, "flags.unsnat_new", NULL, > + flags_str); > > /* Connection tracking state. */ > expr_symtab_add_field_scoped(symtab, "ct_mark", MFF_CT_MARK, NULL, false, > diff --git a/northd/northd.c b/northd/northd.c > index aed1d425f..95d2d5bde 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -16207,8 +16207,7 @@ build_lrouter_out_snat_flow(struct lflow_table *lflows, > struct ds *actions, bool distributed_nat, > struct eth_addr mac, int cidr_bits, bool is_v6, > struct ovn_port *l3dgw_port, > - struct lflow_ref *lflow_ref, > - const struct chassis_features *features) > + struct lflow_ref *lflow_ref) > { > if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) { > return; > @@ -16239,34 +16238,6 @@ build_lrouter_out_snat_flow(struct lflow_table *lflows, > priority, ds_cstr(match), > ds_cstr(actions), &nat->header_, > lflow_ref); > - > - /* For the SNAT networks, we need to make sure that connections are > - * properly tracked so we can decide whether to perform SNAT on traffic > - * exiting the network. */ > - if (features->ct_commit_to_zone && features->ct_next_zone && > - nat_entry->type == SNAT && !od->is_gw_router) { > - /* For traffic that comes from SNAT network, initiate CT state before > - * entering S_ROUTER_OUT_SNAT to allow matching on various CT states. > - */ > - ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 70, > - ds_cstr(match), "ct_next(snat);", > - lflow_ref); > - > - build_lrouter_out_snat_match(lflows, od, nat, match, > - distributed_nat, cidr_bits, is_v6, > - l3dgw_port, lflow_ref, true); > - > - /* New traffic that goes into SNAT network is committed to CT to avoid > - * SNAT-ing replies.*/ > - ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, priority, > - ds_cstr(match), "ct_snat;", > - lflow_ref); > - > - ds_put_cstr(match, " && ct.new"); > - ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_SNAT, priority, > - ds_cstr(match), "ct_commit_to_zone(snat);", > - lflow_ref); > - } > } > > static void > @@ -16548,6 +16519,8 @@ static void build_lr_nat_defrag_and_lb_default_flows( > /* Packets are allowed by default. */ > ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG, 0, "1", "next;", lflow_ref); > ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 0, "1", "next;", lflow_ref); > + ovn_lflow_add(lflows, od, S_ROUTER_IN_POST_UNSNAT, 0, "1", "next;", > + lflow_ref); > ovn_lflow_add(lflows, od, S_ROUTER_OUT_CHECK_DNAT_LOCAL, 0, "1", > REGBIT_DST_NAT_IP_LOCAL" = 0; next;", lflow_ref); > ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 0, "1", "next;", lflow_ref); > @@ -16659,9 +16632,6 @@ build_lrouter_nat_defrag_and_lb( > ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 50, > "ip", "flags.loopback = 1; ct_dnat;", > lflow_ref); > - ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 50, > - "ip && ct.new", "ct_commit { } ; next; ", > - lflow_ref); > } > > /* NAT rules are only valid on Gateway routers and routers with > @@ -16679,6 +16649,9 @@ build_lrouter_nat_defrag_and_lb( > !lport_addresses_is_empty(&lrnat_rec->dnat_force_snat_addrs); > bool lb_force_snat_ip = > !lport_addresses_is_empty(&lrnat_rec->lb_force_snat_addrs); > + bool stateful_dnat = lr_stateful_rec->has_lb_vip; > + bool stateful_snat = (dnat_force_snat_ip || lb_force_snat_ip || > + lrnat_rec->lb_force_snat_router_ip); > > for (size_t i = 0; i < lrnat_rec->n_nat_entries; i++) { > struct ovn_nat *nat_entry = &lrnat_rec->nat_entries[i]; > @@ -16697,6 +16670,21 @@ build_lrouter_nat_defrag_and_lb( > continue; > } > > + if (!stateless) { > + switch (nat_entry->type) { > + case DNAT: > + stateful_dnat = true; > + break; > + case SNAT: > + stateful_snat = true; > + break; > + case DNAT_AND_SNAT: > + stateful_snat = true; > + stateful_dnat = true; > + break; > + } > + } > + > /* S_ROUTER_IN_UNSNAT > * Ingress UNSNAT table: It is for already established connections' > * reverse traffic. i.e., SNAT has already been done in egress > @@ -16819,7 +16807,7 @@ build_lrouter_nat_defrag_and_lb( > } else { > build_lrouter_out_snat_flow(lflows, od, nat_entry, match, actions, > distributed_nat, mac, cidr_bits, is_v6, > - l3dgw_port, lflow_ref, features); > + l3dgw_port, lflow_ref); > } > > /* S_ROUTER_IN_ADMISSION - S_ROUTER_IN_IP_INPUT */ > @@ -16909,6 +16897,34 @@ build_lrouter_nat_defrag_and_lb( > } > } > > + > + bool can_commit = features->ct_commit_to_zone && features->ct_next_zone; > + if (can_commit && stateful_dnat) { > + ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG, 10, > + "ip && (!ct.trk || !ct.rpl)", > + "ct_next(dnat);", lflow_ref); > + ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 10, > + "ip && ct.new", "ct_commit_to_zone(dnat);", lflow_ref); > + } > + > + if (can_commit && stateful_snat) { > + /* We would lose the CT state especially the ct.new flag if we have > + * mixed SNAT and DNAT on single LR. In order to know if we actually > + * can commit into SNAT zone keep the flag in register. The SNAT flows > + * in the egress pipeline can then check the flag and commit > + * based on that. */ > + ovn_lflow_add(lflows, od, S_ROUTER_IN_POST_UNSNAT, 10, > + "ip && (!ct.trk || ct.new)", > + "flags.unsnat_new = 1; next;", lflow_ref); > + ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 10, > + "ip && (!ct.trk || !ct.rpl) && " > + "flags.unsnat_new == 1", "ct_next(snat);", > + lflow_ref); > + ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 10, > + "ip && ct.new && flags.unsnat_new == 1", > + "ct_commit_to_zone(snat);", lflow_ref); > + } > + > if (use_common_zone && od->nbr->n_nat) { > ds_clear(match); > ds_put_cstr(match, "ip && ct_mark.natted == 1"); > diff --git a/northd/northd.h b/northd/northd.h > index c1442ff40..162097018 100644 > --- a/northd/northd.h > +++ b/northd/northd.h > @@ -481,27 +481,28 @@ enum ovn_stage { > PIPELINE_STAGE(ROUTER, IN, IP_INPUT, 3, "lr_in_ip_input") \ > PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_REQ, 4, "lr_in_dhcp_relay_req") \ > PIPELINE_STAGE(ROUTER, IN, UNSNAT, 5, "lr_in_unsnat") \ > - PIPELINE_STAGE(ROUTER, IN, DEFRAG, 6, "lr_in_defrag") \ > - PIPELINE_STAGE(ROUTER, IN, LB_AFF_CHECK, 7, "lr_in_lb_aff_check") \ > - PIPELINE_STAGE(ROUTER, IN, DNAT, 8, "lr_in_dnat") \ > - PIPELINE_STAGE(ROUTER, IN, LB_AFF_LEARN, 9, "lr_in_lb_aff_learn") \ > - PIPELINE_STAGE(ROUTER, IN, ECMP_STATEFUL, 10, "lr_in_ecmp_stateful") \ > - PIPELINE_STAGE(ROUTER, IN, ND_RA_OPTIONS, 11, "lr_in_nd_ra_options") \ > - PIPELINE_STAGE(ROUTER, IN, ND_RA_RESPONSE, 12, "lr_in_nd_ra_response") \ > - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_PRE, 13, "lr_in_ip_routing_pre") \ > - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 14, "lr_in_ip_routing") \ > - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 15, "lr_in_ip_routing_ecmp") \ > - PIPELINE_STAGE(ROUTER, IN, POLICY, 16, "lr_in_policy") \ > - PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 17, "lr_in_policy_ecmp") \ > - PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP_CHK, 18, \ > + PIPELINE_STAGE(ROUTER, IN, POST_UNSNAT, 6, "lr_in_post_unsnat") \ > + PIPELINE_STAGE(ROUTER, IN, DEFRAG, 7, "lr_in_defrag") \ > + PIPELINE_STAGE(ROUTER, IN, LB_AFF_CHECK, 8, "lr_in_lb_aff_check") \ > + PIPELINE_STAGE(ROUTER, IN, DNAT, 9, "lr_in_dnat") \ > + PIPELINE_STAGE(ROUTER, IN, LB_AFF_LEARN, 10, "lr_in_lb_aff_learn") \ > + PIPELINE_STAGE(ROUTER, IN, ECMP_STATEFUL, 11, "lr_in_ecmp_stateful") \ > + PIPELINE_STAGE(ROUTER, IN, ND_RA_OPTIONS, 12, "lr_in_nd_ra_options") \ > + PIPELINE_STAGE(ROUTER, IN, ND_RA_RESPONSE, 13, "lr_in_nd_ra_response") \ > + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_PRE, 14, "lr_in_ip_routing_pre") \ > + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 15, "lr_in_ip_routing") \ > + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 16, "lr_in_ip_routing_ecmp") \ > + PIPELINE_STAGE(ROUTER, IN, POLICY, 17, "lr_in_policy") \ > + PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 18, "lr_in_policy_ecmp") \ > + PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP_CHK, 19, \ > "lr_in_dhcp_relay_resp_chk") \ > - PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP, 19, \ > + PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP, 20, \ > "lr_in_dhcp_relay_resp") \ > - PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 20, "lr_in_arp_resolve") \ > - PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN, 21, "lr_in_chk_pkt_len") \ > - PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 22, "lr_in_larger_pkts") \ > - PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 23, "lr_in_gw_redirect") \ > - PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 24, "lr_in_arp_request") \ > + PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 21, "lr_in_arp_resolve") \ > + PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN, 22, "lr_in_chk_pkt_len") \ > + PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 23, "lr_in_larger_pkts") \ > + PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 24, "lr_in_gw_redirect") \ > + PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 25, "lr_in_arp_request") \ > \ > /* Logical router egress stages. */ \ > PIPELINE_STAGE(ROUTER, OUT, CHECK_DNAT_LOCAL, 0, \ > diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at > index efb333a47..beaeef167 100644 > --- a/tests/ovn-macros.at > +++ b/tests/ovn-macros.at > @@ -1315,6 +1315,12 @@ ovn_strip_collector_set() { > sed 's/collector_set=[[0-9]]*,\?/collector_set=??,/g' > } > > +get_zone_num() { > + output=$1 > + name=$2 > + printf "$output" | grep $name | cut -d ' ' -f 2 > +} > + > OVS_END_SHELL_HELPERS > > m4_define([OVN_POPULATE_ARP], [AT_CHECK(ovn_populate_arp__, [0], [ignore])]) > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index 8477e4250..4b936f1c6 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -1188,18 +1188,18 @@ AT_CAPTURE_FILE([crflows]) > > AT_CHECK([grep -e "lr_out_snat" drflows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.src == $allowed_range), action=(ct_snat;) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) > ]) > > AT_CHECK([grep -e "lr_out_post_snat" drflows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.src == $allowed_range && ct.new), action=(ct_commit_to_zone(snat);) > ]) > > AT_CHECK([grep -e "lr_out_snat" crflows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) > ]) > @@ -1227,19 +1227,19 @@ AT_CAPTURE_FILE([crflows2]) > > AT_CHECK([grep -e "lr_out_snat" drflows2 | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1")), action=(ct_snat;) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) > table=??(lr_out_snat ), priority=163 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $disallowed_range), action=(next;) > ]) > > AT_CHECK([grep -e "lr_out_post_snat" drflows2 | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ct.new), action=(ct_commit_to_zone(snat);) > ]) > > AT_CHECK([grep -e "lr_out_snat" crflows2 | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) > table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) > @@ -1266,6 +1266,7 @@ AT_CAPTURE_FILE([crflows2]) > > AT_CHECK([grep -e "lr_out_snat" drflows3 | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) > ]) > @@ -1276,6 +1277,7 @@ AT_CHECK([grep -e "lr_out_post_snat" drflows3 | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep -e "lr_out_snat" crflows3 | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) > ]) > @@ -1301,6 +1303,7 @@ AT_CAPTURE_FILE([crflows2]) > > AT_CHECK([grep -e "lr_out_snat" drflows4 | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) > table=??(lr_out_snat ), priority=163 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $disallowed_range), action=(next;) > @@ -1308,6 +1311,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows4 | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep -e "lr_out_snat" crflows4 | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) > table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) > @@ -4284,12 +4288,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) > ]) > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.4:8080);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.40:8080);) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > @@ -4315,12 +4321,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) > ]) > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > @@ -4333,6 +4341,7 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip4), action=(ct_snat(20.0.0.4);) > table=??(lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip6), action=(ct_snat(aef0::4);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > @@ -4346,7 +4355,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="router_ip" > @@ -4366,12 +4375,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) > ]) > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > @@ -4384,6 +4395,7 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) > @@ -4398,7 +4410,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > check ovn-nbctl --wait=sb remove logical_router lr0 options chassis > @@ -4431,12 +4443,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) > ]) > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > @@ -4449,6 +4463,7 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) > @@ -4464,7 +4479,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > check ovn-nbctl --wait=sb lb-add lb2 10.0.0.20:80 10.0.0.40:8080 > @@ -4483,6 +4498,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.20), action=(ct_dnat;) > ]) > @@ -4505,7 +4521,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CLEANUP > @@ -5767,10 +5783,12 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > ]) > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);) > ]) > > @@ -5789,10 +5807,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat_in_czone(172.168.0.10);) > table=??(lr_out_snat ), priority=154 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl) && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.10);) > @@ -5819,10 +5839,12 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > ]) > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat(10.0.0.3);) > ]) > > @@ -5837,24 +5859,20 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) > - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > - table=??(lr_out_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) > table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) > - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) > ]) > > AT_CHECK([grep "lr_out_post_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) > - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) > ]) > > # Associate load balancer to lr0 > @@ -5889,6 +5907,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) > @@ -5897,6 +5916,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.4:8080);) > @@ -5929,10 +5949,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat_in_czone(172.168.0.10);) > table=??(lr_out_snat ), priority=154 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl) && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.10);) > @@ -5959,6 +5981,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) > @@ -5967,6 +5990,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat(10.0.0.3);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.4:8080);) > @@ -5995,24 +6019,20 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) > - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > - table=??(lr_out_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) > table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) > - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) > ]) > > AT_CHECK([grep "lr_out_post_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) > - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) > ]) > > # Make the logical router as Gateway router > @@ -6033,6 +6053,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) > @@ -6041,6 +6062,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.4:8080);) > @@ -6066,11 +6088,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > table=??(lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) > table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) > @@ -6096,6 +6119,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) > @@ -6104,6 +6128,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) > @@ -6129,11 +6154,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > @@ -6160,6 +6186,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) > @@ -6169,6 +6196,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) > @@ -6195,11 +6223,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > @@ -6236,6 +6265,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.10), action=(ct_dnat;) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) > @@ -6246,6 +6276,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) > @@ -6273,11 +6304,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) > table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-public"), action=(ct_snat(def0::10);) > @@ -6308,11 +6340,13 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) > table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.210), action=(ct_dnat;) > ]) > > AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.210 && tcp && tcp.dst == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > @@ -6335,11 +6369,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) > + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) > ]) > > AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) > + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) > table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) > ]) > > @@ -6371,6 +6406,7 @@ check ovn-nbctl --wait=sb sync > > AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.10), action=(reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=??);};) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) > @@ -6385,6 +6421,7 @@ check ovn-nbctl --wait=sb set load_balancer lb5 options:skip_snat=true > > AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.10), action=(flags.skip_snat_for_lb = 1; reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=??);};) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) > @@ -6401,6 +6438,7 @@ check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="route > > AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.10), action=(flags.force_snat_for_lb = 1; reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=??);};) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) > @@ -6418,6 +6456,7 @@ check ovn-nbctl --wait=sb lr-lb-add lr0 lb6 > > AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.30), action=(drop;) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) > @@ -6432,6 +6471,7 @@ check ovn-nbctl --wait=sb set load_balancer lb6 options:skip_snat=true > > AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.30), action=(flags.skip_snat_for_lb = 1; drop;) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) > @@ -6448,6 +6488,7 @@ check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="route > > AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.30), action=(flags.force_snat_for_lb = 1; drop;) > table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) > table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) > @@ -7997,9 +8038,6 @@ AT_CHECK([grep lr_in_unsnat lrflows | grep ct_snat | ovn_strip_lflows], [0], [dn > ]) > > AT_CHECK([grep lr_out_snat lrflows | grep ct_snat | ovn_strip_lflows], [0], [dnl > - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1")), action=(ct_snat;) > - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S2" && is_chassis_resident("cr-DR-S2")), action=(ct_snat;) > - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S3" && is_chassis_resident("cr-DR-S3")), action=(ct_snat;) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 20.0.0.10 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.10);) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 20.0.0.10 && outport == "DR-S2" && is_chassis_resident("cr-DR-S2") && (!ct.trk || !ct.rpl)), action=(ct_snat(10.0.0.10);) > table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 20.0.0.10 && outport == "DR-S3" && is_chassis_resident("cr-DR-S3") && (!ct.trk || !ct.rpl)), action=(ct_snat(192.168.0.10);) > @@ -8007,9 +8045,6 @@ AT_CHECK([grep lr_out_snat lrflows | grep ct_snat | ovn_strip_lflows], [0], [dnl > > AT_CHECK([grep lr_out_post_snat lrflows | ovn_strip_lflows], [0], [dnl > table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) > - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ct.new), action=(ct_commit_to_zone(snat);) > - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S2" && is_chassis_resident("cr-DR-S2") && ct.new), action=(ct_commit_to_zone(snat);) > - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S3" && is_chassis_resident("cr-DR-S3") && ct.new), action=(ct_commit_to_zone(snat);) > ]) > > check ovn-nbctl --wait=sb lr-nat-del DR snat 20.0.0.10 > @@ -9435,6 +9470,7 @@ AT_CHECK([grep "lr_in_lb_aff_check" R1flows | ovn_strip_lflows], [0], [dnl > ]) > AT_CHECK([grep "lr_in_dnat " R1flows | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; ct_lb_mark(backends=10.0.0.2:80);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; ct_lb_mark(backends=20.0.0.2:80);) > @@ -9459,6 +9495,7 @@ AT_CAPTURE_FILE([R1flows_skip_snat]) > > AT_CHECK([grep "lr_in_dnat " R1flows_skip_snat | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; skip_snat);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; skip_snat);) > @@ -9480,6 +9517,7 @@ AT_CAPTURE_FILE([R1flows_force_snat]) > > AT_CHECK([grep "lr_in_dnat " R1flows_force_snat | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; force_snat);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; force_snat);) > @@ -9500,6 +9538,7 @@ AT_CAPTURE_FILE([R1flows_force_skip_snat]) > > AT_CHECK([grep "lr_in_dnat " R1flows_force_skip_snat | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; skip_snat);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; skip_snat);) > @@ -9524,6 +9563,7 @@ AT_CAPTURE_FILE([R1flows_2lbs]) > > AT_CHECK([grep "lr_in_dnat " R1flows_2lbs | ovn_strip_lflows], [0], [dnl > table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) > + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);) > table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.20 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);) > table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; skip_snat);) > diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at > index c59556173..ffc69d67c 100644 > --- a/tests/system-common-macros.at > +++ b/tests/system-common-macros.at > @@ -237,6 +237,14 @@ m4_define([STRIP_MONITOR_CSUM], [grep "csum:" | sed 's/csum:.*/csum: <skip>/']) > m4_define([FORMAT_CT], > [[grep -F "dst=$1," | sed -e 's/port=[0-9]*/port=<cleared>/g' -e 's/id=[0-9]*/id=<cleared>/g' -e 's/state=[0-9_A-Z]*/state=<cleared>/g' | sort | uniq]]) > > +# FORMAT_CT_WITH_ZONE([ip-addr], [zone]) > +# > +# Strip content from the piped input which would differ from test to test > +# and limit the output to the rows containing 'ip-addr' and 'zone'. > +# > +m4_define([FORMAT_CT_WITH_ZONE], > + [[grep -F "dst=$1," | grep -F "zone=$2" | sed -e 's/port=[0-9]*/port=<cleared>/g' -e 's/id=[0-9]*/id=<cleared>/g' -e 's/state=[0-9_A-Z]*/state=<cleared>/g' | sort]]) > + > # DAEMONIZE([command], [pidfile]) > # > # Run 'command' as a background process and record its pid to 'pidfile' to > diff --git a/tests/system-ovn.at b/tests/system-ovn.at > index 145399ded..599e5ff50 100644 > --- a/tests/system-ovn.at > +++ b/tests/system-ovn.at > @@ -89,37 +89,62 @@ ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \ > ovn-nbctl lsp-add bar bar1 \ > -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2" > > -# Add a DNAT rule. > -ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \ > - external_ip=30.0.0.2 -- add logical_router R2 nat @nat > +# Add a DNAT and SNAT rule. > +check ovn-nbctl lr-nat-add R2 dnat_and_snat 30.0.0.2 192.168.1.2 > > # Add a SNAT rule > -ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \ > - external_ip=30.0.0.1 -- add logical_router R2 nat @nat > +check ovn-nbctl lr-nat-add R2 snat 30.0.0.1 192.168.2.2 > > # wait for ovn-controller to catch up. > ovn-nbctl --wait=hv sync > OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=30.0.0.1)']) > > -# 'alice1' should be able to ping 'foo1' directly. > -NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \ > -[0], [dnl > +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) > +r2_dnat=$(get_zone_num "$ct_zones" R2_dnat) > +r2_snat=$(get_zone_num "$ct_zones" R2_snat) > + > +test_alice1_to_foo1() { > + check ovn-nbctl --wait=hv sync > + > + check ovs-appctl dpctl/flush-conntrack > + > + # 'alice1' should be able to ping 'foo1' directly. > + NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \ > + [0], [dnl > 3 packets transmitted, 3 received, 0% packet loss, time 0ms > ]) > > -# North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2 > -NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \ > -[0], [dnl > + # North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2 > + NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \ > + [0], [dnl > 3 packets transmitted, 3 received, 0% packet loss, time 0ms > ]) > > -# Check conntrack entries. > -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \ > -sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > + # Check conntrack entries. > + AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \ > + sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared> > icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared> > icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared> > ]) > > + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.2], [$r2_snat])], [0], [dnl > +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_snat > +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_snat > +]) > + > + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.2], [$r2_dnat])], [0], [dnl > +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_dnat > +icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_dnat > +]) > +} > + > +test_alice1_to_foo1 > + > +check ovn-nbctl lr-nat-del R2 dnat_and_snat > +check ovn-nbctl lr-nat-add R2 dnat 30.0.0.2 192.168.1.2 > +test_alice1_to_foo1 > + > # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic > # from 30.0.0.1 > NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \ > @@ -269,37 +294,62 @@ ADD_VETH(bar1, bar1, br-int, "fd12::2/64", "f0:00:00:01:02:05", \ > ovn-nbctl lsp-add bar bar1 \ > -- lsp-set-addresses bar1 "f0:00:00:01:02:05 fd12::2" > > -# Add a DNAT rule. > -ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=\"fd11::2\" \ > - external_ip=\"fd30::2\" -- add logical_router R2 nat @nat > +# Add a DNAT and SNAT rule. > +check ovn-nbctl lr-nat-add R2 dnat_and_snat fd30::2 fd11::2 > > # Add a SNAT rule > -ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=\"fd12::2\" \ > - external_ip=\"fd30::1\" -- add logical_router R2 nat @nat > +check ovn-nbctl lr-nat-add R2 snat fd30::1 fd12::2 > > # wait for ovn-controller to catch up. > ovn-nbctl --wait=hv sync > OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=fd30::1)']) > > -# 'alice1' should be able to ping 'foo1' directly. > -NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd11::2 | FORMAT_PING], \ > -[0], [dnl > +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) > +r2_snat=$(get_zone_num "$ct_zones" R2_snat) > +r2_dnat=$(get_zone_num "$ct_zones" R2_dnat) > + > +test_alice1_to_foo1() { > + check ovn-nbctl --wait=hv sync > + > + check ovs-appctl dpctl/flush-conntrack > + > + # 'alice1' should be able to ping 'foo1' directly. > + NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd11::2 | FORMAT_PING], \ > + [0], [dnl > 3 packets transmitted, 3 received, 0% packet loss, time 0ms > ]) > > -# North-South DNAT: 'alice1' should also be able to ping 'foo1' via fd30::2 > -NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd30::2 | FORMAT_PING], \ > -[0], [dnl > + # North-South DNAT: 'alice1' should also be able to ping 'foo1' via fd30::2 > + NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd30::2 | FORMAT_PING], \ > + [0], [dnl > 3 packets transmitted, 3 received, 0% packet loss, time 0ms > ]) > > -# Check conntrack entries. > -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd21::2) | \ > -sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > + # Check conntrack entries. > + AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd21::2) | \ > + sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=<cleared> > icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=<cleared> > icmpv6,orig=(src=fd21::2,dst=fd30::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=<cleared> > ]) > > + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd21::2], [$r2_snat])], [0], [dnl > +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_snat > +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_snat > +]) > + > + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd21::2], [$r2_dnat])], [0], [dnl > +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_dnat > +icmpv6,orig=(src=fd21::2,dst=fd30::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_dnat > +]) > +} > + > +test_alice1_to_foo1 > + > +check ovn-nbctl lr-nat-del R2 dnat_and_snat > +check ovn-nbctl lr-nat-add R2 dnat_and_snat fd30::2 fd11::2 > +test_alice1_to_foo1 > + > # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic > # from fd30::1 > NS_CHECK_EXEC([bar1], [ping6 -q -c 3 -i 0.3 -w 2 fd21::2 | FORMAT_PING], \ > @@ -3753,6 +3803,7 @@ NS_CHECK_EXEC([foo2], [ping6 -q -c 3 -i 0.3 -w 2 fd20::2 | FORMAT_PING], \ > ovs-appctl dpctl/dump-conntrack | grep icmpv6 > AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd11::3) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmpv6,orig=(src=fd11::3,dst=fd20::2,id=<cleared>,type=128,code=0),reply=(src=fd20::2,dst=fd11::3,id=<cleared>,type=129,code=0),zone=<cleared> > ]) > > # We verify that SNAT indeed happened via 'dump-conntrack' command. > @@ -3924,6 +3975,10 @@ AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.1 0.0.0.0/0]) > ovn-nbctl --wait=hv sync > OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=172.16.1.1)']) > > +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) > +r1_snat=$(get_zone_num "$ct_zones" R1_snat) > +r1_dnat=$(get_zone_num "$ct_zones" R1_dnat) > + > echo "------ hv dump ------" > ovs-ofctl show br-int > ovs-ofctl dump-flows br-int > @@ -3938,6 +3993,8 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \ > # We verify that the connection is not tracked. I think "not" needs to be removed from the comment above. > AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmp,orig=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=0,code=0),zone=<cleared> > +icmp,orig=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=0,code=0),zone=<cleared> > ]) > > AT_CHECK([ovs-appctl dpctl/flush-conntrack]) > @@ -3950,6 +4007,8 @@ NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \ > # We verify that the connection is not tracked. Like my previous finding, I believe "not" needs to be removed here. > AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmp,orig=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=0,code=0),zone=<cleared> > +icmp,orig=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=0,code=0),zone=<cleared> > ]) > > AT_CHECK([ovs-appctl dpctl/flush-conntrack]) > @@ -3959,9 +4018,11 @@ NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.3 | FORMAT_PING], \ > 3 packets transmitted, 3 received, 0% packet loss, time 0ms > ]) > > -# We verify that the connection is not tracked. > +# We verify that the connection is tracked. > AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmp,orig=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=8,code=0),reply=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> > +icmp,orig=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=8,code=0),reply=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> > ]) > > AT_CHECK([ovs-appctl dpctl/flush-conntrack]) > @@ -3978,6 +4039,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(172.16.1.4) | > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > icmp,orig=(src=172.16.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.3,id=<cleared>,type=0,code=0),zone=<cleared> > icmp,orig=(src=192.168.1.2,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.3,id=<cleared>,type=0,code=0),zone=<cleared> > +icmp,orig=(src=192.168.1.2,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=192.168.1.2,id=<cleared>,type=0,code=0),zone=<cleared> > ]) > > AT_CHECK([ovs-appctl dpctl/flush-conntrack]) > @@ -3997,6 +4059,16 @@ icmp,orig=(src=172.16.1.1,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src > icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared> > ]) > > +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.1], [$r1_snat])], [0], [dnl > +icmp,orig=(src=172.16.1.1,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=$r1_snat > +icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=$r1_snat > +]) > + > +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.4], [$r1_dnat])], [0], [dnl > +icmp,orig=(src=172.16.1.1,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=$r1_dnat > +icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=192.168.1.3,id=<cleared>,type=0,code=0),zone=$r1_dnat > +]) > + > OVS_APP_EXIT_AND_WAIT([ovn-controller]) > > as ovn-sb > @@ -4108,6 +4180,10 @@ AT_CHECK([ovn-nbctl lr-nat-add R1 snat fd20::1 ::/0]) > ovn-nbctl --wait=hv sync > OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=fd20::1)']) > > +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) > +r1_snat=$(get_zone_num "$ct_zones" R1_snat) > +r1_dnat=$(get_zone_num "$ct_zones" R1_dnat) > + > echo "------ hv dump ------" > ovs-ofctl show br-int > ovs-ofctl dump-flows br-int > @@ -4144,6 +4220,7 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 fd20::4 | FORMAT_PING], \ > # Then DNAT of 'bar1' address happens (listed first below). > AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd20::4) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmpv6,orig=(src=fd11::2,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd11::2,id=<cleared>,type=129,code=0),zone=<cleared> > icmpv6,orig=(src=fd11::2,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd20::3,id=<cleared>,type=129,code=0),zone=<cleared> > icmpv6,orig=(src=fd20::3,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::3,id=<cleared>,type=129,code=0),zone=<cleared> > ]) > @@ -4165,6 +4242,16 @@ icmpv6,orig=(src=fd20::1,dst=fd12::2,id=<cleared>,type=128,code=0),reply=(src=fd > icmpv6,orig=(src=fd20::1,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::1,id=<cleared>,type=129,code=0),zone=<cleared> > ]) > > +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd20::1], [$r1_snat])], [0], [dnl > +icmpv6,orig=(src=fd11::3,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd20::1,id=<cleared>,type=129,code=0),zone=$r1_snat > +icmpv6,orig=(src=fd20::1,dst=fd12::2,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::1,id=<cleared>,type=129,code=0),zone=$r1_snat > +]) > + > +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd20::4], [$r1_dnat])], [0], [dnl > +icmpv6,orig=(src=fd11::3,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd11::3,id=<cleared>,type=129,code=0),zone=$r1_dnat > +icmpv6,orig=(src=fd20::1,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::1,id=<cleared>,type=129,code=0),zone=$r1_dnat > +]) > + > OVS_APP_EXIT_AND_WAIT([ovn-controller]) > > as ovn-sb > @@ -8682,10 +8769,10 @@ test_ping sw11 192.168.1.2 > OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep -v "n_packets=0" | grep 'nat(src=172.16.1.21)']) > # Ensure conntrack entry is present > OVS_WAIT_FOR_OUTPUT([ > - ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ > + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.1.2) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > -icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> > -tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) > +icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.21,id=<cleared>,type=0,code=0),zone=<cleared> > +tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.21,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) > ]) > > AT_CHECK([ovs-appctl dpctl/flush-conntrack]) > @@ -8697,9 +8784,11 @@ test_ping sw11 192.168.1.2 > > # Ensure conntrack entry is present > OVS_WAIT_FOR_OUTPUT([ > - ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ > + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.1.2) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > +icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.21,id=<cleared>,type=0,code=0),zone=<cleared> > icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> > +tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.21,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) > tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) > ]) > > @@ -8711,10 +8800,10 @@ test_ping sw11 172.16.1.2 > > # Ensure conntrack entry is present > OVS_WAIT_FOR_OUTPUT([ > - ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ > + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.1.2) | \ > sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl > -icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> > -tcp,orig=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) > +icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.21,id=<cleared>,type=0,code=0),zone=<cleared> > +tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.21,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) > ]) > > AT_CHECK([ovs-appctl dpctl/flush-conntrack])
On Tue, Jan 7, 2025 at 7:44 AM Ales Musil <amusil@redhat.com> wrote: > > > > On Wed, Dec 18, 2024 at 2:08 PM Dumitru Ceara <dceara@redhat.com> wrote: >> >> On 11/20/24 5:37 PM, Ales Musil wrote: >> > Commit all traffic that is not already commit by either NAT or LB. This >> > ensures that the traffic is tracked, and we don't erroneously commit >> > reply traffic, or reply traffic is not marked as invalid. >> > >> > To achieve the commit we need to perform lookup on every packet >> > that goes through LR pipeline whenever there is stateful NAT. >> > >> > The SNAT lookup requires additional flag as the unSNAT is happening >> > in ingress pipeline and at that point we need to know if the packet >> > is reply or not. This is not required for DNAT, because unDNAT stage >> > happens in egress. >> > >> > Signed-off-by: Ales Musil <amusil@redhat.com> >> > --- >> >> Hi Han, >> >> I was wondering if you had time to evaluate the performance impact of >> this patch in your lab. >> >> Thanks, >> Dumitru >> > > Hi Han, > > by any chance did you have some time to run the performance tests? > ovn-kubernetes is really interested in this as it will fix one of the use cases > that they have. > > Thank you, > Ales Hi Folks, I am sorry that the test got delayed. Adding Alin here because he is willing to help on this. Hopefully we will get some results soon. Thanks, Han
diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h index d563e044c..05bc18eab 100644 --- a/include/ovn/logical-fields.h +++ b/include/ovn/logical-fields.h @@ -86,6 +86,7 @@ enum mff_log_flags_bits { MLF_LOCALNET_BIT = 15, MLF_RX_FROM_TUNNEL_BIT = 16, MLF_ICMP_SNAT_BIT = 17, + MLF_UNSNAT_NEW_BIT = 18, }; /* MFF_LOG_FLAGS_REG flag assignments */ @@ -141,6 +142,9 @@ enum mff_log_flags { MLF_RX_FROM_TUNNEL = (1 << MLF_RX_FROM_TUNNEL_BIT), MLF_ICMP_SNAT = (1 << MLF_ICMP_SNAT_BIT), + + /* Indicate that the packet didn't go through unSNAT. */ + MLF_UNSNAT_NEW = (1 << MLF_UNSNAT_NEW_BIT), }; /* OVN logical fields diff --git a/lib/logical-fields.c b/lib/logical-fields.c index 5a8b53f2b..081faad5a 100644 --- a/lib/logical-fields.c +++ b/lib/logical-fields.c @@ -139,6 +139,10 @@ ovn_init_symtab(struct shash *symtab) flags_str); snprintf(flags_str, sizeof flags_str, "flags[%d]", MLF_RX_FROM_TUNNEL_BIT); expr_symtab_add_subfield(symtab, "flags.tunnel_rx", NULL, flags_str); + snprintf(flags_str, sizeof flags_str, "flags[%d]", + MLF_UNSNAT_NEW_BIT); + expr_symtab_add_subfield(symtab, "flags.unsnat_new", NULL, + flags_str); /* Connection tracking state. */ expr_symtab_add_field_scoped(symtab, "ct_mark", MFF_CT_MARK, NULL, false, diff --git a/northd/northd.c b/northd/northd.c index aed1d425f..95d2d5bde 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -16207,8 +16207,7 @@ build_lrouter_out_snat_flow(struct lflow_table *lflows, struct ds *actions, bool distributed_nat, struct eth_addr mac, int cidr_bits, bool is_v6, struct ovn_port *l3dgw_port, - struct lflow_ref *lflow_ref, - const struct chassis_features *features) + struct lflow_ref *lflow_ref) { if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) { return; @@ -16239,34 +16238,6 @@ build_lrouter_out_snat_flow(struct lflow_table *lflows, priority, ds_cstr(match), ds_cstr(actions), &nat->header_, lflow_ref); - - /* For the SNAT networks, we need to make sure that connections are - * properly tracked so we can decide whether to perform SNAT on traffic - * exiting the network. */ - if (features->ct_commit_to_zone && features->ct_next_zone && - nat_entry->type == SNAT && !od->is_gw_router) { - /* For traffic that comes from SNAT network, initiate CT state before - * entering S_ROUTER_OUT_SNAT to allow matching on various CT states. - */ - ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 70, - ds_cstr(match), "ct_next(snat);", - lflow_ref); - - build_lrouter_out_snat_match(lflows, od, nat, match, - distributed_nat, cidr_bits, is_v6, - l3dgw_port, lflow_ref, true); - - /* New traffic that goes into SNAT network is committed to CT to avoid - * SNAT-ing replies.*/ - ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, priority, - ds_cstr(match), "ct_snat;", - lflow_ref); - - ds_put_cstr(match, " && ct.new"); - ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_SNAT, priority, - ds_cstr(match), "ct_commit_to_zone(snat);", - lflow_ref); - } } static void @@ -16548,6 +16519,8 @@ static void build_lr_nat_defrag_and_lb_default_flows( /* Packets are allowed by default. */ ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG, 0, "1", "next;", lflow_ref); ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 0, "1", "next;", lflow_ref); + ovn_lflow_add(lflows, od, S_ROUTER_IN_POST_UNSNAT, 0, "1", "next;", + lflow_ref); ovn_lflow_add(lflows, od, S_ROUTER_OUT_CHECK_DNAT_LOCAL, 0, "1", REGBIT_DST_NAT_IP_LOCAL" = 0; next;", lflow_ref); ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 0, "1", "next;", lflow_ref); @@ -16659,9 +16632,6 @@ build_lrouter_nat_defrag_and_lb( ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 50, "ip", "flags.loopback = 1; ct_dnat;", lflow_ref); - ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 50, - "ip && ct.new", "ct_commit { } ; next; ", - lflow_ref); } /* NAT rules are only valid on Gateway routers and routers with @@ -16679,6 +16649,9 @@ build_lrouter_nat_defrag_and_lb( !lport_addresses_is_empty(&lrnat_rec->dnat_force_snat_addrs); bool lb_force_snat_ip = !lport_addresses_is_empty(&lrnat_rec->lb_force_snat_addrs); + bool stateful_dnat = lr_stateful_rec->has_lb_vip; + bool stateful_snat = (dnat_force_snat_ip || lb_force_snat_ip || + lrnat_rec->lb_force_snat_router_ip); for (size_t i = 0; i < lrnat_rec->n_nat_entries; i++) { struct ovn_nat *nat_entry = &lrnat_rec->nat_entries[i]; @@ -16697,6 +16670,21 @@ build_lrouter_nat_defrag_and_lb( continue; } + if (!stateless) { + switch (nat_entry->type) { + case DNAT: + stateful_dnat = true; + break; + case SNAT: + stateful_snat = true; + break; + case DNAT_AND_SNAT: + stateful_snat = true; + stateful_dnat = true; + break; + } + } + /* S_ROUTER_IN_UNSNAT * Ingress UNSNAT table: It is for already established connections' * reverse traffic. i.e., SNAT has already been done in egress @@ -16819,7 +16807,7 @@ build_lrouter_nat_defrag_and_lb( } else { build_lrouter_out_snat_flow(lflows, od, nat_entry, match, actions, distributed_nat, mac, cidr_bits, is_v6, - l3dgw_port, lflow_ref, features); + l3dgw_port, lflow_ref); } /* S_ROUTER_IN_ADMISSION - S_ROUTER_IN_IP_INPUT */ @@ -16909,6 +16897,34 @@ build_lrouter_nat_defrag_and_lb( } } + + bool can_commit = features->ct_commit_to_zone && features->ct_next_zone; + if (can_commit && stateful_dnat) { + ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG, 10, + "ip && (!ct.trk || !ct.rpl)", + "ct_next(dnat);", lflow_ref); + ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 10, + "ip && ct.new", "ct_commit_to_zone(dnat);", lflow_ref); + } + + if (can_commit && stateful_snat) { + /* We would lose the CT state especially the ct.new flag if we have + * mixed SNAT and DNAT on single LR. In order to know if we actually + * can commit into SNAT zone keep the flag in register. The SNAT flows + * in the egress pipeline can then check the flag and commit + * based on that. */ + ovn_lflow_add(lflows, od, S_ROUTER_IN_POST_UNSNAT, 10, + "ip && (!ct.trk || ct.new)", + "flags.unsnat_new = 1; next;", lflow_ref); + ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 10, + "ip && (!ct.trk || !ct.rpl) && " + "flags.unsnat_new == 1", "ct_next(snat);", + lflow_ref); + ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 10, + "ip && ct.new && flags.unsnat_new == 1", + "ct_commit_to_zone(snat);", lflow_ref); + } + if (use_common_zone && od->nbr->n_nat) { ds_clear(match); ds_put_cstr(match, "ip && ct_mark.natted == 1"); diff --git a/northd/northd.h b/northd/northd.h index c1442ff40..162097018 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -481,27 +481,28 @@ enum ovn_stage { PIPELINE_STAGE(ROUTER, IN, IP_INPUT, 3, "lr_in_ip_input") \ PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_REQ, 4, "lr_in_dhcp_relay_req") \ PIPELINE_STAGE(ROUTER, IN, UNSNAT, 5, "lr_in_unsnat") \ - PIPELINE_STAGE(ROUTER, IN, DEFRAG, 6, "lr_in_defrag") \ - PIPELINE_STAGE(ROUTER, IN, LB_AFF_CHECK, 7, "lr_in_lb_aff_check") \ - PIPELINE_STAGE(ROUTER, IN, DNAT, 8, "lr_in_dnat") \ - PIPELINE_STAGE(ROUTER, IN, LB_AFF_LEARN, 9, "lr_in_lb_aff_learn") \ - PIPELINE_STAGE(ROUTER, IN, ECMP_STATEFUL, 10, "lr_in_ecmp_stateful") \ - PIPELINE_STAGE(ROUTER, IN, ND_RA_OPTIONS, 11, "lr_in_nd_ra_options") \ - PIPELINE_STAGE(ROUTER, IN, ND_RA_RESPONSE, 12, "lr_in_nd_ra_response") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_PRE, 13, "lr_in_ip_routing_pre") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 14, "lr_in_ip_routing") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 15, "lr_in_ip_routing_ecmp") \ - PIPELINE_STAGE(ROUTER, IN, POLICY, 16, "lr_in_policy") \ - PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 17, "lr_in_policy_ecmp") \ - PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP_CHK, 18, \ + PIPELINE_STAGE(ROUTER, IN, POST_UNSNAT, 6, "lr_in_post_unsnat") \ + PIPELINE_STAGE(ROUTER, IN, DEFRAG, 7, "lr_in_defrag") \ + PIPELINE_STAGE(ROUTER, IN, LB_AFF_CHECK, 8, "lr_in_lb_aff_check") \ + PIPELINE_STAGE(ROUTER, IN, DNAT, 9, "lr_in_dnat") \ + PIPELINE_STAGE(ROUTER, IN, LB_AFF_LEARN, 10, "lr_in_lb_aff_learn") \ + PIPELINE_STAGE(ROUTER, IN, ECMP_STATEFUL, 11, "lr_in_ecmp_stateful") \ + PIPELINE_STAGE(ROUTER, IN, ND_RA_OPTIONS, 12, "lr_in_nd_ra_options") \ + PIPELINE_STAGE(ROUTER, IN, ND_RA_RESPONSE, 13, "lr_in_nd_ra_response") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_PRE, 14, "lr_in_ip_routing_pre") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 15, "lr_in_ip_routing") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 16, "lr_in_ip_routing_ecmp") \ + PIPELINE_STAGE(ROUTER, IN, POLICY, 17, "lr_in_policy") \ + PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 18, "lr_in_policy_ecmp") \ + PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP_CHK, 19, \ "lr_in_dhcp_relay_resp_chk") \ - PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP, 19, \ + PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP, 20, \ "lr_in_dhcp_relay_resp") \ - PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 20, "lr_in_arp_resolve") \ - PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN, 21, "lr_in_chk_pkt_len") \ - PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 22, "lr_in_larger_pkts") \ - PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 23, "lr_in_gw_redirect") \ - PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 24, "lr_in_arp_request") \ + PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 21, "lr_in_arp_resolve") \ + PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN, 22, "lr_in_chk_pkt_len") \ + PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 23, "lr_in_larger_pkts") \ + PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 24, "lr_in_gw_redirect") \ + PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 25, "lr_in_arp_request") \ \ /* Logical router egress stages. */ \ PIPELINE_STAGE(ROUTER, OUT, CHECK_DNAT_LOCAL, 0, \ diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at index efb333a47..beaeef167 100644 --- a/tests/ovn-macros.at +++ b/tests/ovn-macros.at @@ -1315,6 +1315,12 @@ ovn_strip_collector_set() { sed 's/collector_set=[[0-9]]*,\?/collector_set=??,/g' } +get_zone_num() { + output=$1 + name=$2 + printf "$output" | grep $name | cut -d ' ' -f 2 +} + OVS_END_SHELL_HELPERS m4_define([OVN_POPULATE_ARP], [AT_CHECK(ovn_populate_arp__, [0], [ignore])]) diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 8477e4250..4b936f1c6 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -1188,18 +1188,18 @@ AT_CAPTURE_FILE([crflows]) AT_CHECK([grep -e "lr_out_snat" drflows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.src == $allowed_range), action=(ct_snat;) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) ]) AT_CHECK([grep -e "lr_out_post_snat" drflows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.src == $allowed_range && ct.new), action=(ct_commit_to_zone(snat);) ]) AT_CHECK([grep -e "lr_out_snat" crflows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) ]) @@ -1227,19 +1227,19 @@ AT_CAPTURE_FILE([crflows2]) AT_CHECK([grep -e "lr_out_snat" drflows2 | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1")), action=(ct_snat;) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) table=??(lr_out_snat ), priority=163 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $disallowed_range), action=(next;) ]) AT_CHECK([grep -e "lr_out_post_snat" drflows2 | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 50.0.0.11 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ct.new), action=(ct_commit_to_zone(snat);) ]) AT_CHECK([grep -e "lr_out_snat" crflows2 | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) @@ -1266,6 +1266,7 @@ AT_CAPTURE_FILE([crflows2]) AT_CHECK([grep -e "lr_out_snat" drflows3 | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) ]) @@ -1276,6 +1277,7 @@ AT_CHECK([grep -e "lr_out_post_snat" drflows3 | ovn_strip_lflows], [0], [dnl AT_CHECK([grep -e "lr_out_snat" crflows3 | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) ]) @@ -1301,6 +1303,7 @@ AT_CAPTURE_FILE([crflows2]) AT_CHECK([grep -e "lr_out_snat" drflows4 | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) table=??(lr_out_snat ), priority=163 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $disallowed_range), action=(next;) @@ -1308,6 +1311,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows4 | ovn_strip_lflows], [0], [dnl AT_CHECK([grep -e "lr_out_snat" crflows4 | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) @@ -4284,12 +4288,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.4:8080);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.40:8080);) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) @@ -4315,12 +4321,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) @@ -4333,6 +4341,7 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip4), action=(ct_snat(20.0.0.4);) table=??(lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip6), action=(ct_snat(aef0::4);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) @@ -4346,7 +4355,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="router_ip" @@ -4366,12 +4375,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) @@ -4384,6 +4395,7 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) @@ -4398,7 +4410,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) check ovn-nbctl --wait=sb remove logical_router lr0 options chassis @@ -4431,12 +4443,14 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) @@ -4449,6 +4463,7 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) @@ -4464,7 +4479,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) check ovn-nbctl --wait=sb lb-add lb2 10.0.0.20:80 10.0.0.40:8080 @@ -4483,6 +4498,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.100), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.20), action=(ct_dnat;) ]) @@ -4505,7 +4521,7 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CLEANUP @@ -5767,10 +5783,12 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);) ]) @@ -5789,10 +5807,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat_in_czone(172.168.0.10);) table=??(lr_out_snat ), priority=154 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl) && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.10);) @@ -5819,10 +5839,12 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat(10.0.0.3);) ]) @@ -5837,24 +5859,20 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=??(lr_out_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) ]) AT_CHECK([grep "lr_out_post_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) ]) # Associate load balancer to lr0 @@ -5889,6 +5907,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) @@ -5897,6 +5916,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.4:8080);) @@ -5929,10 +5949,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat_in_czone(172.168.0.10);) table=??(lr_out_snat ), priority=154 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl) && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.10);) @@ -5959,6 +5981,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) @@ -5967,6 +5990,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat(10.0.0.3);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.4:8080);) @@ -5995,24 +6019,20 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) - table=??(lr_out_post_undnat ), priority=70 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_next(snat);) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=??(lr_out_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) table=??(lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) ]) AT_CHECK([grep "lr_out_post_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_snat ), priority=153 , match=(ip && ip4.dst == 10.0.0.0/24 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 10.0.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public") && ct.new), action=(ct_commit_to_zone(snat);) ]) # Make the logical router as Gateway router @@ -6033,6 +6053,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) @@ -6041,6 +6062,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.4:8080);) @@ -6066,11 +6088,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) table=??(lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) @@ -6096,6 +6119,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.200), action=(ct_dnat;) @@ -6104,6 +6128,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) @@ -6129,11 +6154,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) @@ -6160,6 +6186,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) @@ -6169,6 +6196,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) @@ -6195,11 +6223,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) @@ -6236,6 +6265,7 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 10.0.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.10), action=(ct_dnat;) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.100), action=(ct_dnat;) @@ -6246,6 +6276,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) @@ -6273,11 +6304,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) table=??(lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-public"), action=(ct_snat(def0::10);) @@ -6308,11 +6340,13 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_defrag ), priority=0 , match=(1), action=(next;) + table=??(lr_in_defrag ), priority=10 , match=(ip && (!ct.trk || !ct.rpl)), action=(ct_next(dnat);) table=??(lr_in_defrag ), priority=100 , match=(ip && ip4.dst == 172.168.0.210), action=(ct_dnat;) ]) AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.210 && tcp && tcp.dst == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) @@ -6335,11 +6369,12 @@ AT_CHECK([grep "lr_out_undnat" lr0flows | ovn_strip_lflows], [0], [dnl AT_CHECK([grep "lr_out_post_undnat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) + table=??(lr_out_post_undnat ), priority=10 , match=(ip && (!ct.trk || !ct.rpl) && flags.unsnat_new == 1), action=(ct_next(snat);) ]) AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=10 , match=(ip && ct.new && flags.unsnat_new == 1), action=(ct_commit_to_zone(snat);) table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) @@ -6371,6 +6406,7 @@ check ovn-nbctl --wait=sb sync AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.10), action=(reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=??);};) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) @@ -6385,6 +6421,7 @@ check ovn-nbctl --wait=sb set load_balancer lb5 options:skip_snat=true AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.10), action=(flags.skip_snat_for_lb = 1; reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=??);};) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) @@ -6401,6 +6438,7 @@ check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="route AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.10), action=(flags.force_snat_for_lb = 1; reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=??);};) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) @@ -6418,6 +6456,7 @@ check ovn-nbctl --wait=sb lr-lb-add lr0 lb6 AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.30), action=(drop;) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) @@ -6432,6 +6471,7 @@ check ovn-nbctl --wait=sb set load_balancer lb6 options:skip_snat=true AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.30), action=(flags.skip_snat_for_lb = 1; drop;) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) @@ -6448,6 +6488,7 @@ check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="route AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.168.10.30), action=(flags.force_snat_for_lb = 1; drop;) table=??(lr_in_dnat ), priority=50 , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;) table=??(lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) @@ -7997,9 +8038,6 @@ AT_CHECK([grep lr_in_unsnat lrflows | grep ct_snat | ovn_strip_lflows], [0], [dn ]) AT_CHECK([grep lr_out_snat lrflows | grep ct_snat | ovn_strip_lflows], [0], [dnl - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1")), action=(ct_snat;) - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S2" && is_chassis_resident("cr-DR-S2")), action=(ct_snat;) - table=??(lr_out_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S3" && is_chassis_resident("cr-DR-S3")), action=(ct_snat;) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 20.0.0.10 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.10);) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 20.0.0.10 && outport == "DR-S2" && is_chassis_resident("cr-DR-S2") && (!ct.trk || !ct.rpl)), action=(ct_snat(10.0.0.10);) table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 20.0.0.10 && outport == "DR-S3" && is_chassis_resident("cr-DR-S3") && (!ct.trk || !ct.rpl)), action=(ct_snat(192.168.0.10);) @@ -8007,9 +8045,6 @@ AT_CHECK([grep lr_out_snat lrflows | grep ct_snat | ovn_strip_lflows], [0], [dnl AT_CHECK([grep lr_out_post_snat lrflows | ovn_strip_lflows], [0], [dnl table=??(lr_out_post_snat ), priority=0 , match=(1), action=(next;) - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ct.new), action=(ct_commit_to_zone(snat);) - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S2" && is_chassis_resident("cr-DR-S2") && ct.new), action=(ct_commit_to_zone(snat);) - table=??(lr_out_post_snat ), priority=161 , match=(ip && ip4.dst == 20.0.0.10 && inport == "DR-S3" && is_chassis_resident("cr-DR-S3") && ct.new), action=(ct_commit_to_zone(snat);) ]) check ovn-nbctl --wait=sb lr-nat-del DR snat 20.0.0.10 @@ -9435,6 +9470,7 @@ AT_CHECK([grep "lr_in_lb_aff_check" R1flows | ovn_strip_lflows], [0], [dnl ]) AT_CHECK([grep "lr_in_dnat " R1flows | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; ct_lb_mark(backends=10.0.0.2:80);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; ct_lb_mark(backends=20.0.0.2:80);) @@ -9459,6 +9495,7 @@ AT_CAPTURE_FILE([R1flows_skip_snat]) AT_CHECK([grep "lr_in_dnat " R1flows_skip_snat | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; skip_snat);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; skip_snat);) @@ -9480,6 +9517,7 @@ AT_CAPTURE_FILE([R1flows_force_snat]) AT_CHECK([grep "lr_in_dnat " R1flows_force_snat | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; force_snat);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; force_snat);) @@ -9500,6 +9538,7 @@ AT_CAPTURE_FILE([R1flows_force_skip_snat]) AT_CHECK([grep "lr_in_dnat " R1flows_force_skip_snat | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; skip_snat);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; skip_snat);) @@ -9524,6 +9563,7 @@ AT_CAPTURE_FILE([R1flows_2lbs]) AT_CHECK([grep "lr_in_dnat " R1flows_2lbs | ovn_strip_lflows], [0], [dnl table=??(lr_in_dnat ), priority=0 , match=(1), action=(next;) + table=??(lr_in_dnat ), priority=10 , match=(ip && ct.new), action=(ct_commit_to_zone(dnat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);) table=??(lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && ip4.dst == 172.16.0.20 && tcp && tcp.dst == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);) table=??(lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; skip_snat);) diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at index c59556173..ffc69d67c 100644 --- a/tests/system-common-macros.at +++ b/tests/system-common-macros.at @@ -237,6 +237,14 @@ m4_define([STRIP_MONITOR_CSUM], [grep "csum:" | sed 's/csum:.*/csum: <skip>/']) m4_define([FORMAT_CT], [[grep -F "dst=$1," | sed -e 's/port=[0-9]*/port=<cleared>/g' -e 's/id=[0-9]*/id=<cleared>/g' -e 's/state=[0-9_A-Z]*/state=<cleared>/g' | sort | uniq]]) +# FORMAT_CT_WITH_ZONE([ip-addr], [zone]) +# +# Strip content from the piped input which would differ from test to test +# and limit the output to the rows containing 'ip-addr' and 'zone'. +# +m4_define([FORMAT_CT_WITH_ZONE], + [[grep -F "dst=$1," | grep -F "zone=$2" | sed -e 's/port=[0-9]*/port=<cleared>/g' -e 's/id=[0-9]*/id=<cleared>/g' -e 's/state=[0-9_A-Z]*/state=<cleared>/g' | sort]]) + # DAEMONIZE([command], [pidfile]) # # Run 'command' as a background process and record its pid to 'pidfile' to diff --git a/tests/system-ovn.at b/tests/system-ovn.at index 145399ded..599e5ff50 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -89,37 +89,62 @@ ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \ ovn-nbctl lsp-add bar bar1 \ -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2" -# Add a DNAT rule. -ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \ - external_ip=30.0.0.2 -- add logical_router R2 nat @nat +# Add a DNAT and SNAT rule. +check ovn-nbctl lr-nat-add R2 dnat_and_snat 30.0.0.2 192.168.1.2 # Add a SNAT rule -ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \ - external_ip=30.0.0.1 -- add logical_router R2 nat @nat +check ovn-nbctl lr-nat-add R2 snat 30.0.0.1 192.168.2.2 # wait for ovn-controller to catch up. ovn-nbctl --wait=hv sync OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=30.0.0.1)']) -# 'alice1' should be able to ping 'foo1' directly. -NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \ -[0], [dnl +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) +r2_dnat=$(get_zone_num "$ct_zones" R2_dnat) +r2_snat=$(get_zone_num "$ct_zones" R2_snat) + +test_alice1_to_foo1() { + check ovn-nbctl --wait=hv sync + + check ovs-appctl dpctl/flush-conntrack + + # 'alice1' should be able to ping 'foo1' directly. + NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \ + [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2 -NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \ -[0], [dnl + # North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2 + NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \ + [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# Check conntrack entries. -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \ -sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl + # Check conntrack entries. + AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \ + sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared> icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared> icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared> ]) + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.2], [$r2_snat])], [0], [dnl +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_snat +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_snat +]) + + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.2], [$r2_dnat])], [0], [dnl +icmp,orig=(src=172.16.1.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_dnat +icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=$r2_dnat +]) +} + +test_alice1_to_foo1 + +check ovn-nbctl lr-nat-del R2 dnat_and_snat +check ovn-nbctl lr-nat-add R2 dnat 30.0.0.2 192.168.1.2 +test_alice1_to_foo1 + # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic # from 30.0.0.1 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \ @@ -269,37 +294,62 @@ ADD_VETH(bar1, bar1, br-int, "fd12::2/64", "f0:00:00:01:02:05", \ ovn-nbctl lsp-add bar bar1 \ -- lsp-set-addresses bar1 "f0:00:00:01:02:05 fd12::2" -# Add a DNAT rule. -ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=\"fd11::2\" \ - external_ip=\"fd30::2\" -- add logical_router R2 nat @nat +# Add a DNAT and SNAT rule. +check ovn-nbctl lr-nat-add R2 dnat_and_snat fd30::2 fd11::2 # Add a SNAT rule -ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=\"fd12::2\" \ - external_ip=\"fd30::1\" -- add logical_router R2 nat @nat +check ovn-nbctl lr-nat-add R2 snat fd30::1 fd12::2 # wait for ovn-controller to catch up. ovn-nbctl --wait=hv sync OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=fd30::1)']) -# 'alice1' should be able to ping 'foo1' directly. -NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd11::2 | FORMAT_PING], \ -[0], [dnl +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) +r2_snat=$(get_zone_num "$ct_zones" R2_snat) +r2_dnat=$(get_zone_num "$ct_zones" R2_dnat) + +test_alice1_to_foo1() { + check ovn-nbctl --wait=hv sync + + check ovs-appctl dpctl/flush-conntrack + + # 'alice1' should be able to ping 'foo1' directly. + NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd11::2 | FORMAT_PING], \ + [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# North-South DNAT: 'alice1' should also be able to ping 'foo1' via fd30::2 -NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd30::2 | FORMAT_PING], \ -[0], [dnl + # North-South DNAT: 'alice1' should also be able to ping 'foo1' via fd30::2 + NS_CHECK_EXEC([alice1], [ping6 -q -c 3 -i 0.3 -w 2 fd30::2 | FORMAT_PING], \ + [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# Check conntrack entries. -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd21::2) | \ -sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl + # Check conntrack entries. + AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd21::2) | \ + sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=<cleared> icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=<cleared> icmpv6,orig=(src=fd21::2,dst=fd30::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=<cleared> ]) + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd21::2], [$r2_snat])], [0], [dnl +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_snat +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_snat +]) + + AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd21::2], [$r2_dnat])], [0], [dnl +icmpv6,orig=(src=fd21::2,dst=fd11::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_dnat +icmpv6,orig=(src=fd21::2,dst=fd30::2,id=<cleared>,type=128,code=0),reply=(src=fd11::2,dst=fd21::2,id=<cleared>,type=129,code=0),zone=$r2_dnat +]) +} + +test_alice1_to_foo1 + +check ovn-nbctl lr-nat-del R2 dnat_and_snat +check ovn-nbctl lr-nat-add R2 dnat_and_snat fd30::2 fd11::2 +test_alice1_to_foo1 + # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic # from fd30::1 NS_CHECK_EXEC([bar1], [ping6 -q -c 3 -i 0.3 -w 2 fd21::2 | FORMAT_PING], \ @@ -3753,6 +3803,7 @@ NS_CHECK_EXEC([foo2], [ping6 -q -c 3 -i 0.3 -w 2 fd20::2 | FORMAT_PING], \ ovs-appctl dpctl/dump-conntrack | grep icmpv6 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd11::3) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmpv6,orig=(src=fd11::3,dst=fd20::2,id=<cleared>,type=128,code=0),reply=(src=fd20::2,dst=fd11::3,id=<cleared>,type=129,code=0),zone=<cleared> ]) # We verify that SNAT indeed happened via 'dump-conntrack' command. @@ -3924,6 +3975,10 @@ AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.1 0.0.0.0/0]) ovn-nbctl --wait=hv sync OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=172.16.1.1)']) +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) +r1_snat=$(get_zone_num "$ct_zones" R1_snat) +r1_dnat=$(get_zone_num "$ct_zones" R1_dnat) + echo "------ hv dump ------" ovs-ofctl show br-int ovs-ofctl dump-flows br-int @@ -3938,6 +3993,8 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \ # We verify that the connection is not tracked. AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmp,orig=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=0,code=0),zone=<cleared> +icmp,orig=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=0,code=0),zone=<cleared> ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3950,6 +4007,8 @@ NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \ # We verify that the connection is not tracked. AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmp,orig=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=0,code=0),zone=<cleared> +icmp,orig=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=0,code=0),zone=<cleared> ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3959,9 +4018,11 @@ NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.3 | FORMAT_PING], \ 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that the connection is not tracked. +# We verify that the connection is tracked. AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmp,orig=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=8,code=0),reply=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> +icmp,orig=(src=192.168.2.2,dst=192.168.1.3,id=<cleared>,type=8,code=0),reply=(src=192.168.1.3,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3978,6 +4039,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(172.16.1.4) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl icmp,orig=(src=172.16.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.3,id=<cleared>,type=0,code=0),zone=<cleared> icmp,orig=(src=192.168.1.2,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.3,id=<cleared>,type=0,code=0),zone=<cleared> +icmp,orig=(src=192.168.1.2,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=192.168.1.2,id=<cleared>,type=0,code=0),zone=<cleared> ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3997,6 +4059,16 @@ icmp,orig=(src=172.16.1.1,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared> ]) +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.1], [$r1_snat])], [0], [dnl +icmp,orig=(src=172.16.1.1,dst=192.168.2.2,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=$r1_snat +icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=$r1_snat +]) + +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([172.16.1.4], [$r1_dnat])], [0], [dnl +icmp,orig=(src=172.16.1.1,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=$r1_dnat +icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=192.168.1.3,id=<cleared>,type=0,code=0),zone=$r1_dnat +]) + OVS_APP_EXIT_AND_WAIT([ovn-controller]) as ovn-sb @@ -4108,6 +4180,10 @@ AT_CHECK([ovn-nbctl lr-nat-add R1 snat fd20::1 ::/0]) ovn-nbctl --wait=hv sync OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=fd20::1)']) +ct_zones=$(ovn-appctl -t ovn-controller ct-zone-list) +r1_snat=$(get_zone_num "$ct_zones" R1_snat) +r1_dnat=$(get_zone_num "$ct_zones" R1_dnat) + echo "------ hv dump ------" ovs-ofctl show br-int ovs-ofctl dump-flows br-int @@ -4144,6 +4220,7 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 fd20::4 | FORMAT_PING], \ # Then DNAT of 'bar1' address happens (listed first below). AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd20::4) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmpv6,orig=(src=fd11::2,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd11::2,id=<cleared>,type=129,code=0),zone=<cleared> icmpv6,orig=(src=fd11::2,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd20::3,id=<cleared>,type=129,code=0),zone=<cleared> icmpv6,orig=(src=fd20::3,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::3,id=<cleared>,type=129,code=0),zone=<cleared> ]) @@ -4165,6 +4242,16 @@ icmpv6,orig=(src=fd20::1,dst=fd12::2,id=<cleared>,type=128,code=0),reply=(src=fd icmpv6,orig=(src=fd20::1,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::1,id=<cleared>,type=129,code=0),zone=<cleared> ]) +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd20::1], [$r1_snat])], [0], [dnl +icmpv6,orig=(src=fd11::3,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd20::1,id=<cleared>,type=129,code=0),zone=$r1_snat +icmpv6,orig=(src=fd20::1,dst=fd12::2,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::1,id=<cleared>,type=129,code=0),zone=$r1_snat +]) + +AT_CHECK_UNQUOTED([ovs-appctl dpctl/dump-conntrack | FORMAT_CT_WITH_ZONE([fd20::4], [$r1_dnat])], [0], [dnl +icmpv6,orig=(src=fd11::3,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd20::4,dst=fd11::3,id=<cleared>,type=129,code=0),zone=$r1_dnat +icmpv6,orig=(src=fd20::1,dst=fd20::4,id=<cleared>,type=128,code=0),reply=(src=fd12::2,dst=fd20::1,id=<cleared>,type=129,code=0),zone=$r1_dnat +]) + OVS_APP_EXIT_AND_WAIT([ovn-controller]) as ovn-sb @@ -8682,10 +8769,10 @@ test_ping sw11 192.168.1.2 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep -v "n_packets=0" | grep 'nat(src=172.16.1.21)']) # Ensure conntrack entry is present OVS_WAIT_FOR_OUTPUT([ - ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.1.2) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> -tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) +icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.21,id=<cleared>,type=0,code=0),zone=<cleared> +tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.21,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -8697,9 +8784,11 @@ test_ping sw11 192.168.1.2 # Ensure conntrack entry is present OVS_WAIT_FOR_OUTPUT([ - ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.1.2) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.21,id=<cleared>,type=0,code=0),zone=<cleared> icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> +tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.21,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) ]) @@ -8711,10 +8800,10 @@ test_ping sw11 172.16.1.2 # Ensure conntrack entry is present OVS_WAIT_FOR_OUTPUT([ - ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.1.2) | \ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared> -tcp,orig=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) +icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.21,id=<cleared>,type=0,code=0),zone=<cleared> +tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.21,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>) ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack])
Commit all traffic that is not already commit by either NAT or LB. This ensures that the traffic is tracked, and we don't erroneously commit reply traffic, or reply traffic is not marked as invalid. To achieve the commit we need to perform lookup on every packet that goes through LR pipeline whenever there is stateful NAT. The SNAT lookup requires additional flag as the unSNAT is happening in ingress pipeline and at that point we need to know if the packet is reply or not. This is not required for DNAT, because unDNAT stage happens in egress. Signed-off-by: Ales Musil <amusil@redhat.com> --- There are few failing system tests with userspace datapath, that's due to the recirculation limit that is being hit due to additional lookups. --- include/ovn/logical-fields.h | 4 + lib/logical-fields.c | 4 + northd/northd.c | 84 +++++++++++------- northd/northd.h | 39 ++++---- tests/ovn-macros.at | 6 ++ tests/ovn-northd.at | 102 ++++++++++++++------- tests/system-common-macros.at | 8 ++ tests/system-ovn.at | 161 ++++++++++++++++++++++++++-------- 8 files changed, 288 insertions(+), 120 deletions(-)