| 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
On 1/31/25 11:56 PM, Alin Serdean wrote: > > Hi, > Hi Alin, > Apologies for the delay. > > I managed to test the patch. For what it is worth it did not apply cleanly : > https://github.com/aserdean/ovn/commit/1d1fe23a2da81e9bda699dddba57b1ef6a062d1d > <https://github.com/aserdean/ovn/commit/1d1fe23a2da81e9bda699dddba57b1ef6a062d1d> > Thanks for trying this patch out! > The performance numbers after applying the patch are the same as the ones from > upstream: > > > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 3.45 > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 3.73 > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 3.34 > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 3.74 > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 3.46 > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 3.43 > > > It is a huge degradation compared to the revert. > > > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 161.28 > root@worker4:/opt# > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 161.75 > root@worker4:/opt# ./iperfCex.sh 8-27 10 10.0.120.10 > Running iperf3 test with size of 256K for 10 sec on cores 8-27 > > TOTAL_THROUGHPUT > 187 > I agree, this is a huge performance drop, but I have some questions. > > Please let me know if I should include any relevant logs / traces. > Could you please share the OVN NB/SB databases and the OVS database from the node(s) where you run your test workloads? Is this test with any sort of hardware offload enabled? If so, should conntrack also be offloaded to hardware in this scenario? If that's the case, one hunch I have is that maybe we end up forwarding traffic without committing to conntrack, that is forwarding all traffic with ct_state=+trk+new. We should be able to tell if that's the case if we run the following command while the test traffic is flowing: ovs-appctl dpctl/dump-flows -m --names Also, to avoid any potential conflict resolution issues it might be easier to just pick up the latest version of the patch from here: https://patchwork.ozlabs.org/project/ovn/patch/20250130125125.2877584-1-amusil@redhat.com/ https://github.com/ovsrobot/ovn/tree/refs/heads/series_442285 This version makes the commit-all opt-in so you'd have to enable it on the ovn logical routers: ovn-nbctl set logical_router <rtr> options:commit-all=true For the test to be equivalent, you'd have to do this on all logical routers configured in your database. Regards, Dumitru > Thank you, > Alin > >> On 23 Jan 2025, at 18:01, Han Zhou <hzhou@ovn.org> wrote: >> >> >> >> >> On Tue, Jan 7, 2025 at 7:44 AM Ales Musil <amusil@redhat.com >> <mailto:amusil@redhat.com>> wrote: >> > >> > >> > >> > On Wed, Dec 18, 2024 at 2:08 PM Dumitru Ceara <dceara@redhat.com >> <mailto: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 <mailto: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(-)