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 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev