On 4/14/25 3:45 PM, Ales Musil wrote: > On Mon, Apr 14, 2025 at 10:52 AM Dumitru Ceara <dce...@redhat.com> wrote: > >> Since commit f2e8130d0a42 ("northd: Explicitly handle SNAT for ICMP >> need frag."), if LRP.gw_mtu is set, ovn-northd adds a priority 160 >> logical flow in the lr_in_larger_pkts router pipeline that matches >> on "ct.trk && ct.rpl && ct.dnat" for egress traffic that's larger >> than the configured MTU (if REGBIT_PKT_LARGER] == 1): >> >> table=23(lr_in_larger_pkts ), priority=160, >> match=(inport == "lrp1" && outport == "lrp0" && ip4 && >> reg9[1] && reg9[0] == 0 && ct.trk && ct.rpl && ct.dnat), >> action=(icmp4_error {...};) >> >> The lr_in_larger_pkts logical pipeline stage (23) is translated by >> ovn-controller to OpenFlow table 31. >> >> table=31, priority=160, >> ct_state=+rpl+trk+dnat,ip,reg9=0x2/0x3,reg14=0x2,reg15=0x1,metadata=0x3 >> actions=controller(...) >> >> Due to the way ovs-vswitchd translates OF rules to datapath flows, >> all OpenFlow rules in table 31 that have a priority lower than 160 >> automatically get an implicit match on the inverse ct_state match >> that's generated for the priority 160 OF rule, that is: >> >> ct_state=-trk-rpl-dnat >> >> On specific NICs, such matches (on dnat/snat ct_state) are not >> offloadable to hardware. >> >> However, in OVN, logical switches and logical routers pipelines both >> get translated to the same set of OpenFlow tables. In theory that's >> fine because the logical datapath distinction happens thanks to >> additional metadata field matches (the metadata OF field is actually >> logical datapath id). But in this specific case it means that all >> logical switch traffic that hits OpenFlow table 31 will also generate >> a datapath flow that matches on ct_state=-trk-rpl-dnat, making it >> non-offloadable. >> >> E.g., in an OVN cluster with a logical switch that has no stateful >> config (no stateful ACLs or LBs) traffic hitting the following >> logical switch pipeline stage will also fail to be offloaded to >> hardware if there's a logical router with gw_mtu configured: >> >> table=23(ls_in_dhcp_options ), priority=0, match=(1), action=(next;) >> >> That is essentially all traffic forwarded on that logical switch. >> >> Change the way we match on large packets that have been DNATed and >> instead of directly matching on ct_state first save that into a >> register (using the new ct_state_save() logical action). >> >> That means that with the configuration mentioned above: >> - all routed traffic that is less than MTU will now be forwarded by >> a datapath flow matching on ct_state=-trk >> - all switched traffic will be forwarded by a datapath flow matching on >> ct_state=-trk >> >> In order to not disrupt upgrades on stable branches generate the new >> logical flows only if the ct_state_save() action is supported by all >> ovn-controllers. >> >> Reported-at: https://issues.redhat.com/browse/FDP-1271 >> Fixes: f2e8130d0a42 ("northd: Explicitly handle SNAT for ICMP need frag.") >> Signed-off-by: Dumitru Ceara <dce...@redhat.com> >> --- >> V2: >> - Addressed Ales' comment: >> - simplified code that generates the ct_state match and removed not so >> obvious micro-optimization >> --- >> northd/northd.c | 52 ++++++++++++---- >> northd/ovn-northd.8.xml | 8 ++- >> tests/ovn-northd.at | 128 ++++++++++++++++++++++----------------- >> tests/system-ovn-kmod.at | 49 ++++++++++++--- >> 4 files changed, 160 insertions(+), 77 deletions(-) >> >> diff --git a/northd/northd.c b/northd/northd.c >> index 762e4e057d..1f9340e555 100644 >> --- a/northd/northd.c >> +++ b/northd/northd.c >> @@ -213,6 +213,19 @@ BUILD_ASSERT_DECL(ACL_OBS_STAGE_MAX < (1 << 2)); >> /* Register used for storing persistent ACL IDs */ >> #define REG_ACL_ID "reg2[16..31]" >> >> +/* Register used for storing the ct_state in the router pipeline and >> + * ct_saved_state helpers, matching the ct_state bits definitions from >> + * ovs-fields(7). */ >> +#define REG_CT_STATE "reg4[0..7]" >> + >> +static const char *reg_ct_state[] = { >> +#define CS_STATE(ENUM, INDEX, NAME) \ >> + [CS_##ENUM] = "reg4[" #INDEX "]", >> + >> + CS_STATES >> +#undef CS_STATE >> +}; >> + >> /* Register used for temporarily store ECMP eth.src to avoid masked >> ct_label >> * access. It doesn't really occupy registers because the content of the >> * register is saved to stack and then restored in the same flow. >> @@ -282,10 +295,13 @@ BUILD_ASSERT_DECL(ACL_OBS_STAGE_MAX < (1 << 2)); >> * | R3 | UNUSED | 1 | | | >> | >> * | | | | | | >> | >> * >> +-----+---------------------------+---+-----------------+---+------------------------------------+ >> - * | R4 | REG_LB_IPV4 | X | | | >> | >> - * | | (>= IN_LB_AFF_CHECK && | R | | | >> | >> - * | | <= IN_LB_AFF_LEARN) | R | | | >> | >> - * +-----+---------------------------+ E | UNUSED | X | >> | >> + * | | REG_LB_IPV4 | | | | >> | >> + * | R4 | (>= IN_LB_AFF_CHECK && | | | | >> | >> + * | | <= IN_LB_AFF_LEARN) | | | | >> | >> + * | | REG_CT_STATE | X | | | >> | >> + * | | (>= IN_CHK_PKT_LEN && | R | UNUSED | | >> | >> + * | | <= IN_LARGER_PKTS) | R | | | >> | >> + * +-----+---------------------------+ E | | X | >> | >> * | R5 | SRC_IPV4 for ARP-REQ | G | | X | >> REG_LB_IPV6 | >> * | | (>= IP_INPUT) | 2 | | R | >> (>= IN_LB_AFF_CHECK && | >> * +-----+---------------------------+---+-----------------+ E | >> <= IN_LB_AFF_LEARN) | >> @@ -14690,6 +14706,7 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, >> int mtu, >> const struct shash *meter_groups, struct ds >> *match, >> struct ds *actions, enum ovn_stage stage, >> struct ovn_port *outport, >> + const char *ct_state_match, >> struct lflow_ref *lflow_ref) >> { >> const char *ipv4_meter = copp_meter_get(COPP_ICMP4_ERR, >> op->od->nbr->copp, >> @@ -14701,15 +14718,17 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, >> int mtu, >> ds_put_format(match, "inport == %s", op->json_key); >> >> if (outport) { >> + ovs_assert(ct_state_match); >> + >> ds_put_format(match, " && outport == %s", outport->json_key); >> >> create_icmp_need_frag_lflow(op, mtu, actions, match, ipv4_meter, >> lflows, lflow_ref, stage, 160, false, >> - "ct.trk && ct.rpl && ct.dnat", >> + ct_state_match, >> "flags.icmp_snat = 1; "); >> create_icmp_need_frag_lflow(op, mtu, actions, match, ipv6_meter, >> lflows, lflow_ref, stage, 160, true, >> - "ct.trk && ct.rpl && ct.dnat", >> + ct_state_match, >> "flags.icmp_snat = 1; "); >> } >> >> @@ -14735,15 +14754,25 @@ build_check_pkt_len_flows_for_lrp(struct >> ovn_port *op, >> >> ds_clear(match); >> ds_put_format(match, "outport == %s", op->json_key); >> + const char *mtu_flow_action = features->ct_state_save >> + ? REG_CT_STATE " = ct_state_save(); >> next;" >> + : "next;"; >> build_gateway_mtu_flow(lflows, op, S_ROUTER_IN_CHK_PKT_LEN, 50, 55, >> - match, actions, &op->nbrp->header_, >> - lflow_ref, "next;"); >> + match, actions, &op->nbrp->header_, lflow_ref, >> + "%s", mtu_flow_action); >> >> /* ingress traffic */ >> build_icmperr_pkt_big_flows(op, gw_mtu, lflows, meter_groups, >> match, actions, S_ROUTER_IN_IP_INPUT, >> - NULL, lflow_ref); >> - >> + NULL, NULL, lflow_ref); >> + >> + /* Additional match at egress on tracked and reply and dnat-ed >> traffic. */ >> + char *ct_match = features->ct_state_save >> + ? xasprintf("%s && %s && %s", >> + reg_ct_state[CS_TRACKED], >> + reg_ct_state[CS_REPLY_DIR], >> + reg_ct_state[CS_DST_NAT]) >> + : xstrdup("ct.trk && ct.rpl && ct.dnat"); >> for (size_t i = 0; i < op->od->nbr->n_ports; i++) { >> struct ovn_port *rp = ovn_port_find(lr_ports, >> op->od->nbr->ports[i]->name); >> @@ -14754,8 +14783,9 @@ build_check_pkt_len_flows_for_lrp(struct ovn_port >> *op, >> /* egress traffic */ >> build_icmperr_pkt_big_flows(rp, gw_mtu, lflows, meter_groups, >> match, actions, >> S_ROUTER_IN_LARGER_PKTS, >> - op, lflow_ref); >> + op, ct_match, lflow_ref); >> } >> + free(ct_match); >> >> if (features->ct_commit_nat_v2) { >> ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_OUT_POST_SNAT, >> 100, >> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml >> index 1a70ba579d..e087b6f59f 100644 >> --- a/northd/ovn-northd.8.xml >> +++ b/northd/ovn-northd.8.xml >> @@ -4899,12 +4899,14 @@ output; >> integer value, this table adds a priority-50 logical flow with >> the match <code>outport == <var>GW_PORT</var></code> where >> <var>GW_PORT</var> is the gateway router port and applies the >> - action <code>check_pkt_larger</code> and advances the packet to >> - the next table. >> + actions <code>check_pkt_larger</code> and <code>ct_state_save</code> >> + and then advances the packet to the next table. >> </p> >> >> <pre> >> -REGBIT_PKT_LARGER = check_pkt_larger(<var>L</var>); next; >> +REGBIT_PKT_LARGER = check_pkt_larger(<var>L</var>); >> +REG_CT_STATE = ct_state_save(); >> +next; >> </pre> >> >> <p> >> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at >> index 8ee3c977f2..12d6611b69 100644 >> --- a/tests/ovn-northd.at >> +++ b/tests/ovn-northd.at >> @@ -6654,12 +6654,17 @@ AT_CHECK([ovn-sbctl --columns=tags list >> logical_flow | grep lsp0 -c], [0], [dnl >> AT_CLEANUP >> ]) >> >> -OVN_FOR_EACH_NORTHD_NO_HV([ >> -AT_SETUP([ovn -- gateway mtu check pkt larger flows]) >> +m4_define([GATEWAY_MTU_FLOWS_TEST], >> +[OVN_FOR_EACH_NORTHD_NO_HV([ >> +AT_SETUP([ovn -- gateway mtu check pkt larger flows - ct-state-save=$2]) >> ovn_start >> >> -check ovn-sbctl chassis-add ch1 geneve 127.0.0.1 --\ >> - set chassis ch1 other_config:ct-commit-nat-v2=true >> +AS_BOX([$1]) >> +use_ct_save=$2 >> + >> +check ovn-sbctl chassis-add ch1 geneve 127.0.0.1 -- \ >> + set chassis ch1 other_config:ct-commit-nat-v2=true -- \ >> + set chassis ch1 other_config:ct-state-save=$use_ct_save >> >> check ovn-nbctl ls-add sw0 >> check ovn-nbctl ls-add sw1 >> @@ -6700,18 +6705,26 @@ check ovn-nbctl --wait=sb set logical_router_port >> lr0-public options:gateway_mtu >> ovn-sbctl dump-flows lr0 > lr0flows >> AT_CAPTURE_FILE([lr0flows]) >> >> -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | >> ovn_strip_lflows], [0], [dnl >> +if [[ "$use_ct_save" == "true" ]]; then >> + ct_save_action='reg4[[0..7]] = ct_state_save(); next' >> + larger_pkts_ct_match='reg4[[5]] && reg4[[3]] && reg4[[7]]' >> +else >> + ct_save_action='next' >> + larger_pkts_ct_match='ct.trk && ct.rpl && ct.dnat' >> +fi >> + >> +AT_CHECK_UNQUOTED([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows >> | ovn_strip_lflows], [0], [dnl >> table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); $ct_save_action;) >> table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> ]) >> >> AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | >> ovn_strip_lflows], [0], [dnl >> @@ -6739,18 +6752,18 @@ check ovn-nbctl --wait=sb set logical_router lr0 >> options:chassis=ch1 >> ovn-sbctl dump-flows lr0 > lr0flows >> AT_CAPTURE_FILE([lr0flows]) >> >> -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | >> ovn_strip_lflows], [0], [dnl >> +AT_CHECK_UNQUOTED([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows >> | ovn_strip_lflows], [0], [dnl >> table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); $ct_save_action;) >> table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> ]) >> >> AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | >> ovn_strip_lflows], [0], [dnl >> @@ -6775,19 +6788,19 @@ check ovn-nbctl --wait=sb set logical_router_port >> lr0-public options:gateway_mtu >> ovn-sbctl dump-flows lr0 > lr0flows >> AT_CAPTURE_FILE([lr0flows]) >> >> -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | >> ovn_strip_lflows], [0], [dnl >> +AT_CHECK_UNQUOTED([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows >> | ovn_strip_lflows], [0], [dnl >> table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) >> - table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-public" && (tcp)), action=(next;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); $ct_save_action;) >> + table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-public" && (tcp)), action=($ct_save_action;) >> table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> ]) >> >> AT_CHECK([grep "lr_in_admission" lr0flows | grep -e "check_pkt_larger" -e >> "tcp" | ovn_strip_lflows], [0], [dnl >> @@ -6803,11 +6816,11 @@ check ovn-nbctl --wait=sb set logical_router_port >> lr0-sw0 options:gateway_mtu=14 >> ovn-sbctl dump-flows lr0 > lr0flows >> AT_CAPTURE_FILE([lr0flows]) >> >> -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | >> ovn_strip_lflows], [0], [dnl >> +AT_CHECK_UNQUOTED([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows >> | ovn_strip_lflows], [0], [dnl >> table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); next;) >> - table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-public" && (tcp)), action=(next;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); $ct_save_action;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); $ct_save_action;) >> + table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-public" && (tcp)), action=($ct_save_action;) >> table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = >> 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:20:20:12:13; ip6.dst = ip6.src; ip6.src = fe80::200:20ff:fe20:1213; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> @@ -6817,14 +6830,14 @@ AT_CHECK([grep -e "chk_pkt_len" -e >> "lr_in_larger_pkts" lr0flows | ovn_strip_lflo >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), >> action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), >> action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = >> ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* >> Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. >> */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = >> ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; >> /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 && >> ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 && >> ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = >> ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* >> Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. >> */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = >> ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; >> /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 && >> $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; reg9[[0]] >> = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src >> = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ >> icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 && >> $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; reg9[[0]] >> = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src >> = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. >> */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); >> };) >> ]) >> >> AT_CHECK([grep "lr_in_admission.*check_pkt_larger" lr0flows | >> ovn_strip_lflows], [0], [dnl >> @@ -6853,12 +6866,12 @@ check ovn-nbctl --wait=sb set logical_router_port >> lr0-sw0 options:gateway_mtu_by >> ovn-sbctl dump-flows lr0 > lr0flows >> AT_CAPTURE_FILE([lr0flows]) >> >> -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | >> ovn_strip_lflows], [0], [dnl >> +AT_CHECK_UNQUOTED([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows >> | ovn_strip_lflows], [0], [dnl >> table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); next;) >> - table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-public" && (tcp)), action=(next;) >> - table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-sw0" && (tcp)), action=(next;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); $ct_save_action;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); $ct_save_action;) >> + table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-public" && (tcp)), action=($ct_save_action;) >> + table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-sw0" && (tcp)), action=($ct_save_action;) >> table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = >> 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:20:20:12:13; ip6.dst = ip6.src; ip6.src = fe80::200:20ff:fe20:1213; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> @@ -6868,14 +6881,14 @@ AT_CHECK([grep -e "chk_pkt_len" -e >> "lr_in_larger_pkts" lr0flows | ovn_strip_lflo >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), >> action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), >> action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = >> ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* >> Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. >> */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = >> ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; >> /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 && >> ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 && >> ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = >> ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* >> Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. >> */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = >> ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; >> /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = >> ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1500; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 && >> $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; reg9[[0]] >> = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src >> = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ >> icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 && >> $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; reg9[[0]] >> = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src >> = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. >> */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); >> };) >> ]) >> >> AT_CHECK([grep "lr_in_admission" lr0flows | grep -e "check_pkt_larger" -e >> "tcp" | ovn_strip_lflows], [0], [dnl >> @@ -6894,19 +6907,19 @@ check ovn-nbctl --wait=sb clear >> logical_router_port lr0-public options >> ovn-sbctl dump-flows lr0 > lr0flows >> AT_CAPTURE_FILE([lr0flows]) >> >> -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | >> ovn_strip_lflows], [0], [dnl >> +AT_CHECK_UNQUOTED([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows >> | ovn_strip_lflows], [0], [dnl >> table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) >> - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); next;) >> - table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-sw0" && (tcp)), action=(next;) >> + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == >> "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); $ct_save_action;) >> + table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == >> "lr0-sw0" && (tcp)), action=($ct_save_action;) >> table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = >> 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == >> 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:20:20:12:13; ip6.dst = ip6.src; ip6.src = fe80::200:20ff:fe20:1213; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), >> action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; >> icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag >> Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, >> table=??); };) >> table=??(lr_in_larger_pkts ), priority=150 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), >> action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = >> 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; >> ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; >> icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = >> ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* >> Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. >> */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = >> ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; >> /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 && >> ct.trk && ct.rpl && ct.dnat), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = >> ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination >> Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ >> icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> - table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 && >> ct.trk && ct.rpl && ct.dnat), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = >> ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* >> Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = >> ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* >> Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. >> */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 >> && $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; >> reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = >> ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; >> /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0 && >> $larger_pkts_ct_match), action=(icmp4_error {flags.icmp_snat = 1; reg9[[0]] >> = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src >> = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ >> icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; >> next(pipeline=ingress, table=??); };) >> + table=??(lr_in_larger_pkts ), priority=160 , match=(inport == >> "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0 && >> $larger_pkts_ct_match), action=(icmp6_error {flags.icmp_snat = 1; reg9[[0]] >> = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src >> = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. >> */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=??); >> };) >> ]) >> >> check ovn-nbctl --wait=sb clear logical_router_port lr0-sw0 options >> @@ -6946,7 +6959,10 @@ ovn-sbctl dump-flows lr0 > lr0flows >> AT_CHECK([grep -E "lr_out_post_snat.*ct_commit_nat" lr0flows], [1]) >> >> AT_CLEANUP >> -]) >> +])]) >> + >> +GATEWAY_MTU_FLOWS_TEST([Simulate hv that does not support >> 'ct-state-save'], [false]) >> +GATEWAY_MTU_FLOWS_TEST([Simulate hv that supports 'ct-state-save'], >> [true]) >> >> OVN_FOR_EACH_NORTHD_NO_HV([ >> AT_SETUP([ovn -- static routes flows]) >> diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at >> index df00f99f7d..f0d4de1f8e 100644 >> --- a/tests/system-ovn-kmod.at >> +++ b/tests/system-ovn-kmod.at >> @@ -922,9 +922,11 @@ dnl Logical network: >> dnl 2 logical switches "public" (192.168.10.0/24 and fd10::/64) >> dnl and "internal" (192.168.20.0/24 and fd20::/64) connected to a router >> lr. >> dnl internal has a client. >> -dnl server is connected through localnet. >> +dnl Server1 is connected through localnet. >> +dnl Server2 is connected to the same switch as the client. >> dnl >> -dnl Server IP 192.168.10.2 fd10:2 >> +dnl Server1 IP 192.168.10.2 fd10:2 >> +dnl Server1 IP 192.168.20.3 fd20:3 >> dnl Client IP 192.168.20.2 fd20:2 >> dnl >> dnl SNAT for internal 192.168.20.0/24 with router ip 192.168.10.1. >> @@ -960,17 +962,25 @@ check ovn-nbctl lsp-add public ln_port \ >> -- lsp-set-type ln_port localnet \ >> -- lsp-set-options ln_port network_name=phynet >> >> -ADD_NAMESPACES(server) >> -ADD_VETH(server, server, br-ext, "fd10::2/64", "f0:00:00:01:02:03", >> "fd10::1", >> +ADD_NAMESPACES(server1) >> +ADD_VETH(server1, server1, br-ext, "fd10::2/64", "f0:00:00:01:02:03", >> "fd10::1", >> "nodad", "192.168.10.2/24", "192.168.10.1") >> -NS_EXEC([server], [ip a show dev server]) >> +NS_EXEC([server1], [ip a show dev server1]) >> >> ADD_NAMESPACES(client) >> ADD_VETH(client, client, br-int, "fd20::2/64", "f0:00:0f:01:02:03", >> "fd20::1", >> "nodad", "192.168.20.2/24", "192.168.20.1") >> NS_EXEC([client], [ip a show dev client]) >> + >> +ADD_NAMESPACES(server2) >> +ADD_VETH(server2, server2, br-int, "fd20::3/64", "f0:00:0f:01:02:04", >> "fd20::1", >> + "nodad", "192.168.20.3/24", "192.168.20.1") >> +NS_EXEC([server2], [ip a show dev server2]) >> + >> check ovn-nbctl lsp-add internal client \ >> -- lsp-set-addresses client "f0:00:0f:01:02:03 192.168.20.2 fd20::2" >> +check ovn-nbctl lsp-add internal server2 \ >> + -- lsp-set-addresses server2 "f0:00:0f:01:02:04 192.168.20.3 fd20::3" >> >> check ovn-nbctl set logical_router lr options:chassis=hv1 >> check ovn-nbctl set logical_router_port lr-internal >> options:gateway_mtu=1300 >> @@ -979,6 +989,7 @@ check ovn-nbctl lr-nat-add lr snat 192.168.10.1 >> 192.168.20.0/24 >> check ovn-nbctl lr-nat-add lr snat fd10::1 fd20::/64 >> >> OVN_POPULATE_ARP >> +wait_for_ports_up >> check ovn-nbctl --wait=hv sync >> >> ovn-nbctl show >> @@ -994,7 +1005,7 @@ NS_CHECK_EXEC([client], [ping -c 1 -W 2 -s 1400 >> 192.168.10.2 | FORMAT_PING], >> ]) >> >> NS_CHECK_EXEC([client], [ip r get 192.168.10.2 | grep -q "mtu 1300"]) >> -NS_CHECK_EXEC([server], [ip r get 192.168.10.1 | grep -q "mtu 1300"]) >> +NS_CHECK_EXEC([server1], [ip r get 192.168.10.1 | grep -q "mtu 1300"]) >> >> AS_BOX([IPv6]) >> NS_CHECK_EXEC([client], [ping -c 1 -W 2 -s 1400 fd10::2 | grep -q "Packet >> too big: mtu=1300"]) >> @@ -1005,7 +1016,31 @@ NS_CHECK_EXEC([client], [ping -c 1 -W 2 -s 1400 >> fd10::2 | FORMAT_PING], >> ]) >> >> NS_CHECK_EXEC([client], [ip r get fd10::2 | grep -q "mtu 1300"]) >> -NS_CHECK_EXEC([server], [ip r get fd10::1 | grep -q "mtu 1300"]) >> +NS_CHECK_EXEC([server1], [ip r get fd10::1 | grep -q "mtu 1300"]) >> + >> +AS_BOX([Switched traffic - smaller than MTU - connect to server2]) >> +check ovs-appctl revalidator/purge >> +NS_CHECK_EXEC([client], [ping -c 1 -W 2 192.168.20.3 | FORMAT_PING], >> +[0], [dnl >> +1 packets transmitted, 1 received, 0% packet loss, time 0ms >> +]) >> +NS_CHECK_EXEC([client], [ping -c 1 -W 2 fd20::3 | FORMAT_PING], >> +[0], [dnl >> +1 packets transmitted, 1 received, 0% packet loss, time 0ms >> +]) >> + >> +dnl While the traffic is only switched, OpenFlow tables are shared between >> +dnl router and switch datapaths, making it such that stateful >> configurations >> +dnl in the router pipeline can cause ct_state matches to "leak" to switch >> +dnl specific datapath flows. >> +dnl >> +dnl Ensure datapath flows don't match on any dnat and/or snat conntrack >> states. >> +dnl Those are known to not be offloadable to hardware. >> +ovs-appctl dpctl/dump-flows > dp-flows >> +AT_CAPTURE_FILE([dp-flows]) >> +AT_CHECK([grep 'ct_state(.*nat.*)' -c dp-flows], [1], [dnl >> +0 >> +]) >> >> ovn-appctl -t ovn-controller vlog/set info >> >> -- >> 2.49.0 >> >> > Looks good to me, thanks. > > Acked-by: Ales Musil <amu...@redhat.com> >
Hi Ales, Thanks for the reviews! I applied this series to main, 25.03, 24.09 and 24.03. Regards, Dumitru _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev