Message ID | 20210805153934.3865265-2-hzhou@ovn.org |
---|---|
State | Accepted |
Headers | show |
Series | Multiple distributed gateway port support. | expand |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | success | apply and check: success |
ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
ovsrobot/github-robot-_ovn-kubernetes | fail | github build: failed |
> The commit 1c9e46ab5 removed the outport match from the lflows, which > leads to a problem for gateway routers that have multiple ports > configured with different MTUs. For example, R0 has port P1, P2 and P3. > P2 and P3 both have gateway_mtu configured: P2 mtu = 1400, P3 mtu = 1500. > Below lflows are generated: > table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) > table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) > > These two lflows have exact same match, but different actions (with > different MTUs). This will result in a random one gets installed by > ovn-controller and the icmp4_error message may contain incorrect mtu. > This patch fixes it by adding the outport back for these flows, so that > mtu that matches the outport setting is used in the generated icmp error > messages. > > Another problem of the commit is that the ddlog part used Flow instead > of MeterFlow for the gateway router flows that generates icmp errors, > while the flows for Distributed Gateway Ports use MeterFlow. This patch > also fixes that by combining the DGP and gateway router code using > MeterFlow. The check for DGP and Gateway Router is removed to simplify > the code, because checking the gateway_mtu config should be sufficient, > which also makes it consistent with the flows in the ADMISSION and > IP_INPUT stages where we didn't check DGP and gateway router but only > the gateway_mtu settings. > > Fixes: 1c9e46ab5 ("northd: add check_pkt_larger lflows for ingress traffic") > Signed-off-by: Han Zhou <hzhou@ovn.org> Hi Han, I have not run any test yet, but the code seems fine to me. Regards, Lorenzo > --- > northd/ovn-northd.8.xml | 7 +- > northd/ovn-northd.c | 49 +++++----- > northd/ovn_northd.dl | 195 +++++----------------------------------- > tests/ovn-northd.at | 48 +++++----- > 4 files changed, 74 insertions(+), 225 deletions(-) > > diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml > index 08d484760..de4fe90c7 100644 > --- a/northd/ovn-northd.8.xml > +++ b/northd/ovn-northd.8.xml > @@ -3756,9 +3756,10 @@ REGBIT_PKT_LARGER = check_pkt_larger(<var>L</var>); next; > configured with <code>options:gateway_mtu</code> to a valid integer > value, this table adds the following priority-150 logical flow for each > logical router port with the match <code>inport == <var>LRP</var> > - && REGBIT_PKT_LARGER && !REGBIT_EGRESS_LOOPBACK</code>, > - where <var>LRP</var> is the logical router port and applies the following > - action for ipv4 and ipv6 respectively: > + && outport == <var>GW_PORT</var> && REGBIT_PKT_LARGER > + && !REGBIT_EGRESS_LOOPBACK</code>, where <var>LRP</var> is the > + logical router port and <var>GW_PORT</var> is the gateway port and > + applies the following action for ipv4 and ipv6 respectively: > </p> > > <pre> > diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c > index a0eaa1247..605e33486 100644 > --- a/northd/ovn-northd.c > +++ b/northd/ovn-northd.c > @@ -10894,13 +10894,19 @@ build_arp_resolve_flows_for_lrouter_port( > static void > build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, > struct shash *meter_groups, struct ds *match, > - struct ds *actions, enum ovn_stage stage) > + struct ds *actions, enum ovn_stage stage, > + struct ovn_port *outport) > { > + char *outport_match = NULL; > + if (outport) { > + outport_match = xasprintf("outport == %s && ", outport->json_key); > + } > + > if (op->lrp_networks.ipv4_addrs) { > ds_clear(match); > - ds_put_format(match, > - "inport == %s && ip4 && "REGBIT_PKT_LARGER > - " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key); > + ds_put_format(match, "inport == %s && %sip4 && "REGBIT_PKT_LARGER > + " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key, > + outport ? outport_match : ""); > > ds_clear(actions); > /* Set icmp4.frag_mtu to gw_mtu */ > @@ -10931,8 +10937,9 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, > > if (op->lrp_networks.ipv6_addrs) { > ds_clear(match); > - ds_put_format(match, "inport == %s && ip6 && "REGBIT_PKT_LARGER > - " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key); > + ds_put_format(match, "inport == %s && %sip6 && "REGBIT_PKT_LARGER > + " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key, > + outport ? outport_match : ""); > > ds_clear(actions); > /* Set icmp6.frag_mtu to gw_mtu */ > @@ -10960,6 +10967,9 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, > meter_groups), > &op->nbrp->header_); > } > + if (outport) { > + free(outport_match); > + } > } > > static int > @@ -10999,7 +11009,8 @@ build_check_pkt_len_flows_for_lrp(struct ovn_port *op, > > /* ingress traffic */ > build_icmperr_pkt_big_flows(op, gw_mtu, lflows, meter_groups, > - match, actions, S_ROUTER_IN_IP_INPUT); > + match, actions, S_ROUTER_IN_IP_INPUT, > + NULL); > > for (size_t i = 0; i < op->od->nbr->n_ports; i++) { > struct ovn_port *rp = ovn_port_find(ports, > @@ -11010,7 +11021,8 @@ 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); > + match, actions, S_ROUTER_IN_LARGER_PKTS, > + op); > } > } > > @@ -11044,21 +11056,14 @@ build_check_pkt_len_flows_for_lrouter( > ovn_lflow_add(lflows, od, S_ROUTER_IN_LARGER_PKTS, 0, "1", > "next;"); > > - if (od->l3dgw_port && od->l3redirect_port) { > - /* gw router port */ > - build_check_pkt_len_flows_for_lrp(od->l3dgw_port, lflows, > - ports, meter_groups, match, actions); > - } else if (smap_get(&od->nbr->options, "chassis")) { > - for (size_t i = 0; i < od->nbr->n_ports; i++) { > - /* gw router */ > - struct ovn_port *rp = ovn_port_find(ports, > - od->nbr->ports[i]->name); > - if (!rp) { > - continue; > - } > - build_check_pkt_len_flows_for_lrp(rp, lflows, ports, meter_groups, > - match, actions); > + for (size_t i = 0; i < od->nbr->n_ports; i++) { > + struct ovn_port *rp = ovn_port_find(ports, > + od->nbr->ports[i]->name); > + if (!rp || !rp->nbrp) { > + continue; > } > + build_check_pkt_len_flows_for_lrp(rp, lflows, ports, meter_groups, > + match, actions); > } > } > > diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl > index 091fe10b3..d7141294e 100644 > --- a/northd/ovn_northd.dl > +++ b/northd/ovn_northd.dl > @@ -7508,29 +7508,16 @@ for (&Router(._uuid = lr_uuid)) > > /* Local router ingress table CHK_PKT_LEN: Check packet length. > * > - * For distributed routers with gateway ports. > - * Any IPv4 or IPv6 packet with outport set to the distributed gateway > - * router port, check the packet length and store the result in the > - * 'REGBIT_PKT_LARGER' register bit. > + * Any IPv4 or IPv6 packet with outport set to a router port that has > + * gateway_mtu > 0 configured, check the packet length and store the result in > + * the 'REGBIT_PKT_LARGER' register bit. > * > * Local router ingress table LARGER_PKTS: Handle larger packets. > * > - * Any IPv4 or IPv6 packet with outport set to the distributed gateway > - * router port and the 'REGBIT_PKT_LARGER' register bit is set, > + * Any IPv4 or IPv6 packet with outport set to a router port that has > + * gatway_mtu > 0 configured and the 'REGBIT_PKT_LARGER' register bit is set, > * generate an ICMPv4/ICMPv6 packet with type 3/2 (Destination > * Unreachable/Packet Too Big) and code 4/0 (Fragmentation needed). > - * > - * For Gateway routers. > - * Any IPv4 or IPv6 packet with outport set to the router port which has > - * the option 'gateway_mtu' set, check the packet length and store > - * the result in the 'REGBIT_PKT_LARGER' register bit. > - * > - * Local router ingress table LARGER_PKTS: Handle larger packets. > - * > - * Any IPv4 or IPv6 packet with outport set to the router port which has > - * the option 'gateway_mtu' set and the 'REGBIT_PKT_LARGER' register bit > - * is set, generate ICMPv4/ICMPv6 packet with type 3/2 (Destination > - * Unreachable/Packet Too Big) and * code 4/0 (Fragmentation needed). > */ > Flow(.logical_datapath = lr_uuid, > .stage = s_ROUTER_IN_CHK_PKT_LEN(), > @@ -7549,21 +7536,19 @@ Flow(.logical_datapath = lr_uuid, > Flow(.logical_datapath = lr_uuid, > .stage = s_ROUTER_IN_CHK_PKT_LEN(), > .priority = 50, > - .__match = "outport == ${l3dgw_port_json_name}", > + .__match = "outport == ${gw_mtu_rp.json_name}", > .actions = "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); " > "next;", > - .external_ids = stage_hint(l3dgw_port._uuid)) :- > + .external_ids = stage_hint(gw_mtu_rp.lrp._uuid)) :- > r in &Router(._uuid = lr_uuid), > - Some{var l3dgw_port} = r.l3dgw_port, > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > - r.redirect_port_name != "", > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > + gw_mtu_rp in &RouterPort(.router = r), > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > gw_mtu > 0, > var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(). > MeteredFlow(.logical_datapath = lr_uuid, > .stage = s_ROUTER_IN_LARGER_PKTS(), > .priority = 150, > - .__match = "inport == ${rp.json_name} && ip4 && " > + .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && ip4 && " > "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > .actions = "icmp4_error {" > "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > @@ -7582,13 +7567,12 @@ MeteredFlow(.logical_datapath = lr_uuid, > .controller_meter = r.copp.get(cOPP_ICMP4_ERR()), > .external_ids = stage_hint(rp.lrp._uuid)) :- > r in &Router(._uuid = lr_uuid), > - Some{var l3dgw_port} = r.l3dgw_port, > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > - r.redirect_port_name != "", > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > + gw_mtu_rp in &RouterPort(.router = r), > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > gw_mtu > 0, > + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > rp in &RouterPort(.router = r), > - rp.lrp != l3dgw_port, > + rp.lrp != gw_mtu_rp.lrp, > Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > > MeteredFlow(.logical_datapath = lr_uuid, > @@ -7613,19 +7597,18 @@ MeteredFlow(.logical_datapath = lr_uuid, > .controller_meter = r.copp.get(cOPP_ICMP4_ERR()), > .external_ids = stage_hint(rp.lrp._uuid)) :- > r in &Router(._uuid = lr_uuid), > - Some{var l3dgw_port} = r.l3dgw_port, > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > - r.redirect_port_name != "", > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > + gw_mtu_rp in &RouterPort(.router = r), > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > gw_mtu > 0, > + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > rp in &RouterPort(.router = r), > - rp.lrp == l3dgw_port, > + rp.lrp == gw_mtu_rp.lrp, > Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > > MeteredFlow(.logical_datapath = lr_uuid, > .stage = s_ROUTER_IN_LARGER_PKTS(), > .priority = 150, > - .__match = "inport == ${rp.json_name} && ip6 && " > + .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && ip6 && " > "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > .actions = "icmp6_error {" > "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > @@ -7644,13 +7627,12 @@ MeteredFlow(.logical_datapath = lr_uuid, > .controller_meter = r.copp.get(cOPP_ICMP6_ERR()), > .external_ids = stage_hint(rp.lrp._uuid)) :- > r in &Router(._uuid = lr_uuid), > - Some{var l3dgw_port} = r.l3dgw_port, > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > - r.redirect_port_name != "", > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > + gw_mtu_rp in &RouterPort(.router = r), > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > gw_mtu > 0, > + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > rp in &RouterPort(.router = r), > - rp.lrp != l3dgw_port, > + rp.lrp != gw_mtu_rp.lrp, > Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). > > MeteredFlow(.logical_datapath = lr_uuid, > @@ -7675,137 +7657,6 @@ MeteredFlow(.logical_datapath = lr_uuid, > .controller_meter = r.copp.get(cOPP_ICMP6_ERR()), > .external_ids = stage_hint(rp.lrp._uuid)) :- > r in &Router(._uuid = lr_uuid), > - Some{var l3dgw_port} = r.l3dgw_port, > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > - r.redirect_port_name != "", > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > - gw_mtu > 0, > - rp in &RouterPort(.router = r), > - rp.lrp == l3dgw_port, > - Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). > - > -/* Gateway routers. */ > -Flow(.logical_datapath = lr_uuid, > - .stage = s_ROUTER_IN_CHK_PKT_LEN(), > - .priority = 50, > - .__match = "outport == ${gw_mtu_rp.json_name}", > - .actions = "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); " > - "next;", > - .external_ids = stage_hint(gw_mtu_rp.lrp._uuid)) :- > - r in &Router(._uuid = lr_uuid), > - r.is_gateway, > - gw_mtu_rp in &RouterPort(.router = r), > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > - gw_mtu > 0, > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(). > -Flow(.logical_datapath = lr_uuid, > - .stage = s_ROUTER_IN_LARGER_PKTS(), > - .priority = 150, > - .__match = "inport == ${rp.json_name} && ip4 && " > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > - .actions = "icmp4_error {" > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > - "${rEGBIT_PKT_LARGER()} = 0; " > - "eth.dst = ${rp.networks.ea}; " > - "ip4.dst = ip4.src; " > - "ip4.src = ${first_ipv4.addr}; " > - "ip.ttl = 255; " > - "icmp4.type = 3; /* Destination Unreachable. */ " > - "icmp4.code = 4; /* Frag Needed and DF was Set. */ " > - /* Set icmp4.frag_mtu to gw_mtu */ > - "icmp4.frag_mtu = ${gw_mtu}; " > - "next(pipeline=ingress, table=0); " > - "};", > - .external_ids = stage_hint(rp.lrp._uuid)) :- > - r in &Router(._uuid = lr_uuid), > - r.is_gateway, > - gw_mtu_rp in &RouterPort(.router = r), > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > - gw_mtu > 0, > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > - rp in &RouterPort(.router = r), > - rp.lrp != gw_mtu_rp.lrp, > - Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > - > -Flow(.logical_datapath = lr_uuid, > - .stage = s_ROUTER_IN_IP_INPUT(), > - .priority = 150, > - .__match = "inport == ${rp.json_name} && ip4 && " > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > - .actions = "icmp4_error {" > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > - "${rEGBIT_PKT_LARGER()} = 0; " > - "eth.dst = ${rp.networks.ea}; " > - "ip4.dst = ip4.src; " > - "ip4.src = ${first_ipv4.addr}; " > - "ip.ttl = 255; " > - "icmp4.type = 3; /* Destination Unreachable. */ " > - "icmp4.code = 4; /* Frag Needed and DF was Set. */ " > - /* Set icmp4.frag_mtu to gw_mtu */ > - "icmp4.frag_mtu = ${gw_mtu}; " > - "next(pipeline=ingress, table=0); " > - "};", > - .external_ids = stage_hint(rp.lrp._uuid)) :- > - r in &Router(._uuid = lr_uuid), > - r.is_gateway, > - gw_mtu_rp in &RouterPort(.router = r), > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > - gw_mtu > 0, > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > - rp in &RouterPort(.router = r), > - rp.lrp == gw_mtu_rp.lrp, > - Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > - > -Flow(.logical_datapath = lr_uuid, > - .stage = s_ROUTER_IN_LARGER_PKTS(), > - .priority = 150, > - .__match = "inport == ${rp.json_name} && ip6 && " > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > - .actions = "icmp6_error {" > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > - "${rEGBIT_PKT_LARGER()} = 0; " > - "eth.dst = ${rp.networks.ea}; " > - "ip6.dst = ip6.src; " > - "ip6.src = ${first_ipv6.addr}; " > - "ip.ttl = 255; " > - "icmp6.type = 2; /* Packet Too Big. */ " > - "icmp6.code = 0; " > - /* Set icmp6.frag_mtu to gw_mtu */ > - "icmp6.frag_mtu = ${gw_mtu}; " > - "next(pipeline=ingress, table=0); " > - "};", > - .external_ids = stage_hint(rp.lrp._uuid)) :- > - r in &Router(._uuid = lr_uuid), > - r.is_gateway, > - gw_mtu_rp in &RouterPort(.router = r), > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > - gw_mtu > 0, > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > - rp in &RouterPort(.router = r), > - rp.lrp != gw_mtu_rp.lrp, > - Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). > - > -Flow(.logical_datapath = lr_uuid, > - .stage = s_ROUTER_IN_IP_INPUT(), > - .priority = 150, > - .__match = "inport == ${rp.json_name} && ip6 && " > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > - .actions = "icmp6_error {" > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > - "${rEGBIT_PKT_LARGER()} = 0; " > - "eth.dst = ${rp.networks.ea}; " > - "ip6.dst = ip6.src; " > - "ip6.src = ${first_ipv6.addr}; " > - "ip.ttl = 255; " > - "icmp6.type = 2; /* Packet Too Big. */ " > - "icmp6.code = 0; " > - /* Set icmp6.frag_mtu to gw_mtu */ > - "icmp6.frag_mtu = ${gw_mtu}; " > - "next(pipeline=ingress, table=0); " > - "};", > - .external_ids = stage_hint(rp.lrp._uuid)) :- > - r in &Router(._uuid = lr_uuid), > - r.is_gateway, > gw_mtu_rp in &RouterPort(.router = r), > var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > gw_mtu > 0, > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index 474e88021..2098b1c19 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -4865,10 +4865,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > ]) > > AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl > @@ -4886,14 +4886,6 @@ AT_CHECK([grep -E "lr_in_ip_input.*icmp6_error" lr0flows | sort], [0], [dnl > # Clear the gateway-chassis for lr0-public > check ovn-nbctl --wait=sb clear logical_router_port lr0-public gateway_chassis > > -ovn-sbctl dump-flows lr0 > lr0flows > -AT_CAPTURE_FILE([sw0flows]) > - > -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl > - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > -]) > - > # Make lr0 as a gateway router. > check ovn-nbctl --wait=sb set logical_router lr0 options:chassis=ch1 > > @@ -4904,10 +4896,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > ]) > > AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl > @@ -4933,14 +4925,14 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > ]) > > AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl > @@ -4968,10 +4960,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > + table=16(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=0); };) > ]) > > AT_CLEANUP > -- > 2.30.2 > > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
On Thu, Aug 5, 2021 at 1:10 PM Lorenzo Bianconi <lorenzo.bianconi@redhat.com> wrote: > > > The commit 1c9e46ab5 removed the outport match from the lflows, which > > leads to a problem for gateway routers that have multiple ports > > configured with different MTUs. For example, R0 has port P1, P2 and P3. > > P2 and P3 both have gateway_mtu configured: P2 mtu = 1400, P3 mtu = 1500. > > Below lflows are generated: > > table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) > > table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) > > > > These two lflows have exact same match, but different actions (with > > different MTUs). This will result in a random one gets installed by > > ovn-controller and the icmp4_error message may contain incorrect mtu. > > This patch fixes it by adding the outport back for these flows, so that > > mtu that matches the outport setting is used in the generated icmp error > > messages. > > > > Another problem of the commit is that the ddlog part used Flow instead > > of MeterFlow for the gateway router flows that generates icmp errors, > > while the flows for Distributed Gateway Ports use MeterFlow. This patch > > also fixes that by combining the DGP and gateway router code using > > MeterFlow. The check for DGP and Gateway Router is removed to simplify > > the code, because checking the gateway_mtu config should be sufficient, > > which also makes it consistent with the flows in the ADMISSION and > > IP_INPUT stages where we didn't check DGP and gateway router but only > > the gateway_mtu settings. > > > > Fixes: 1c9e46ab5 ("northd: add check_pkt_larger lflows for ingress traffic") > > Signed-off-by: Han Zhou <hzhou@ovn.org> > > Hi Han, > > I have not run any test yet, but the code seems fine to me. > > Regards, > Lorenzo Thanks for fixing this. Please see below one small nit comment. With that addressed: Acked-by: Numan Siddique <numans@ovn.org> Numan > > > --- > > northd/ovn-northd.8.xml | 7 +- > > northd/ovn-northd.c | 49 +++++----- > > northd/ovn_northd.dl | 195 +++++----------------------------------- > > tests/ovn-northd.at | 48 +++++----- > > 4 files changed, 74 insertions(+), 225 deletions(-) > > > > diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml > > index 08d484760..de4fe90c7 100644 > > --- a/northd/ovn-northd.8.xml > > +++ b/northd/ovn-northd.8.xml > > @@ -3756,9 +3756,10 @@ REGBIT_PKT_LARGER = check_pkt_larger(<var>L</var>); next; > > configured with <code>options:gateway_mtu</code> to a valid integer > > value, this table adds the following priority-150 logical flow for each > > logical router port with the match <code>inport == <var>LRP</var> > > - && REGBIT_PKT_LARGER && !REGBIT_EGRESS_LOOPBACK</code>, > > - where <var>LRP</var> is the logical router port and applies the following > > - action for ipv4 and ipv6 respectively: > > + && outport == <var>GW_PORT</var> && REGBIT_PKT_LARGER > > + && !REGBIT_EGRESS_LOOPBACK</code>, where <var>LRP</var> is the > > + logical router port and <var>GW_PORT</var> is the gateway port and > > + applies the following action for ipv4 and ipv6 respectively: > > </p> > > > > <pre> > > diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c > > index a0eaa1247..605e33486 100644 > > --- a/northd/ovn-northd.c > > +++ b/northd/ovn-northd.c > > @@ -10894,13 +10894,19 @@ build_arp_resolve_flows_for_lrouter_port( > > static void > > build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, > > struct shash *meter_groups, struct ds *match, > > - struct ds *actions, enum ovn_stage stage) > > + struct ds *actions, enum ovn_stage stage, > > + struct ovn_port *outport) > > { > > + char *outport_match = NULL; > > + if (outport) { > > + outport_match = xasprintf("outport == %s && ", outport->json_key); > > + } > > + The above can be simplified as: char *outport_match = outport ? xasprintf("outport == %s && ", outport->json_key) : NULL; > > if (op->lrp_networks.ipv4_addrs) { > > ds_clear(match); > > - ds_put_format(match, > > - "inport == %s && ip4 && "REGBIT_PKT_LARGER > > - " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key); > > + ds_put_format(match, "inport == %s && %sip4 && "REGBIT_PKT_LARGER > > + " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key, > > + outport ? outport_match : ""); > > > > ds_clear(actions); > > /* Set icmp4.frag_mtu to gw_mtu */ > > @@ -10931,8 +10937,9 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, > > > > if (op->lrp_networks.ipv6_addrs) { > > ds_clear(match); > > - ds_put_format(match, "inport == %s && ip6 && "REGBIT_PKT_LARGER > > - " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key); > > + ds_put_format(match, "inport == %s && %sip6 && "REGBIT_PKT_LARGER > > + " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key, > > + outport ? outport_match : ""); > > > > ds_clear(actions); > > /* Set icmp6.frag_mtu to gw_mtu */ > > @@ -10960,6 +10967,9 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, > > meter_groups), > > &op->nbrp->header_); > > } > > + if (outport) { > > + free(outport_match); > > + } There is no need to check for outport to not NULL before freeing. Thanks Numan > > } > > > > static int > > @@ -10999,7 +11009,8 @@ build_check_pkt_len_flows_for_lrp(struct ovn_port *op, > > > > /* ingress traffic */ > > build_icmperr_pkt_big_flows(op, gw_mtu, lflows, meter_groups, > > - match, actions, S_ROUTER_IN_IP_INPUT); > > + match, actions, S_ROUTER_IN_IP_INPUT, > > + NULL); > > > > for (size_t i = 0; i < op->od->nbr->n_ports; i++) { > > struct ovn_port *rp = ovn_port_find(ports, > > @@ -11010,7 +11021,8 @@ 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); > > + match, actions, S_ROUTER_IN_LARGER_PKTS, > > + op); > > } > > } > > > > @@ -11044,21 +11056,14 @@ build_check_pkt_len_flows_for_lrouter( > > ovn_lflow_add(lflows, od, S_ROUTER_IN_LARGER_PKTS, 0, "1", > > "next;"); > > > > - if (od->l3dgw_port && od->l3redirect_port) { > > - /* gw router port */ > > - build_check_pkt_len_flows_for_lrp(od->l3dgw_port, lflows, > > - ports, meter_groups, match, actions); > > - } else if (smap_get(&od->nbr->options, "chassis")) { > > - for (size_t i = 0; i < od->nbr->n_ports; i++) { > > - /* gw router */ > > - struct ovn_port *rp = ovn_port_find(ports, > > - od->nbr->ports[i]->name); > > - if (!rp) { > > - continue; > > - } > > - build_check_pkt_len_flows_for_lrp(rp, lflows, ports, meter_groups, > > - match, actions); > > + for (size_t i = 0; i < od->nbr->n_ports; i++) { > > + struct ovn_port *rp = ovn_port_find(ports, > > + od->nbr->ports[i]->name); > > + if (!rp || !rp->nbrp) { > > + continue; > > } > > + build_check_pkt_len_flows_for_lrp(rp, lflows, ports, meter_groups, > > + match, actions); > > } > > } > > > > diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl > > index 091fe10b3..d7141294e 100644 > > --- a/northd/ovn_northd.dl > > +++ b/northd/ovn_northd.dl > > @@ -7508,29 +7508,16 @@ for (&Router(._uuid = lr_uuid)) > > > > /* Local router ingress table CHK_PKT_LEN: Check packet length. > > * > > - * For distributed routers with gateway ports. > > - * Any IPv4 or IPv6 packet with outport set to the distributed gateway > > - * router port, check the packet length and store the result in the > > - * 'REGBIT_PKT_LARGER' register bit. > > + * Any IPv4 or IPv6 packet with outport set to a router port that has > > + * gateway_mtu > 0 configured, check the packet length and store the result in > > + * the 'REGBIT_PKT_LARGER' register bit. > > * > > * Local router ingress table LARGER_PKTS: Handle larger packets. > > * > > - * Any IPv4 or IPv6 packet with outport set to the distributed gateway > > - * router port and the 'REGBIT_PKT_LARGER' register bit is set, > > + * Any IPv4 or IPv6 packet with outport set to a router port that has > > + * gatway_mtu > 0 configured and the 'REGBIT_PKT_LARGER' register bit is set, > > * generate an ICMPv4/ICMPv6 packet with type 3/2 (Destination > > * Unreachable/Packet Too Big) and code 4/0 (Fragmentation needed). > > - * > > - * For Gateway routers. > > - * Any IPv4 or IPv6 packet with outport set to the router port which has > > - * the option 'gateway_mtu' set, check the packet length and store > > - * the result in the 'REGBIT_PKT_LARGER' register bit. > > - * > > - * Local router ingress table LARGER_PKTS: Handle larger packets. > > - * > > - * Any IPv4 or IPv6 packet with outport set to the router port which has > > - * the option 'gateway_mtu' set and the 'REGBIT_PKT_LARGER' register bit > > - * is set, generate ICMPv4/ICMPv6 packet with type 3/2 (Destination > > - * Unreachable/Packet Too Big) and * code 4/0 (Fragmentation needed). > > */ > > Flow(.logical_datapath = lr_uuid, > > .stage = s_ROUTER_IN_CHK_PKT_LEN(), > > @@ -7549,21 +7536,19 @@ Flow(.logical_datapath = lr_uuid, > > Flow(.logical_datapath = lr_uuid, > > .stage = s_ROUTER_IN_CHK_PKT_LEN(), > > .priority = 50, > > - .__match = "outport == ${l3dgw_port_json_name}", > > + .__match = "outport == ${gw_mtu_rp.json_name}", > > .actions = "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); " > > "next;", > > - .external_ids = stage_hint(l3dgw_port._uuid)) :- > > + .external_ids = stage_hint(gw_mtu_rp.lrp._uuid)) :- > > r in &Router(._uuid = lr_uuid), > > - Some{var l3dgw_port} = r.l3dgw_port, > > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > > - r.redirect_port_name != "", > > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > > + gw_mtu_rp in &RouterPort(.router = r), > > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > gw_mtu > 0, > > var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(). > > MeteredFlow(.logical_datapath = lr_uuid, > > .stage = s_ROUTER_IN_LARGER_PKTS(), > > .priority = 150, > > - .__match = "inport == ${rp.json_name} && ip4 && " > > + .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && ip4 && " > > "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > > .actions = "icmp4_error {" > > "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > > @@ -7582,13 +7567,12 @@ MeteredFlow(.logical_datapath = lr_uuid, > > .controller_meter = r.copp.get(cOPP_ICMP4_ERR()), > > .external_ids = stage_hint(rp.lrp._uuid)) :- > > r in &Router(._uuid = lr_uuid), > > - Some{var l3dgw_port} = r.l3dgw_port, > > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > > - r.redirect_port_name != "", > > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > > + gw_mtu_rp in &RouterPort(.router = r), > > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > gw_mtu > 0, > > + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > > rp in &RouterPort(.router = r), > > - rp.lrp != l3dgw_port, > > + rp.lrp != gw_mtu_rp.lrp, > > Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > > > > MeteredFlow(.logical_datapath = lr_uuid, > > @@ -7613,19 +7597,18 @@ MeteredFlow(.logical_datapath = lr_uuid, > > .controller_meter = r.copp.get(cOPP_ICMP4_ERR()), > > .external_ids = stage_hint(rp.lrp._uuid)) :- > > r in &Router(._uuid = lr_uuid), > > - Some{var l3dgw_port} = r.l3dgw_port, > > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > > - r.redirect_port_name != "", > > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > > + gw_mtu_rp in &RouterPort(.router = r), > > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > gw_mtu > 0, > > + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > > rp in &RouterPort(.router = r), > > - rp.lrp == l3dgw_port, > > + rp.lrp == gw_mtu_rp.lrp, > > Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > > > > MeteredFlow(.logical_datapath = lr_uuid, > > .stage = s_ROUTER_IN_LARGER_PKTS(), > > .priority = 150, > > - .__match = "inport == ${rp.json_name} && ip6 && " > > + .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && ip6 && " > > "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > > .actions = "icmp6_error {" > > "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > > @@ -7644,13 +7627,12 @@ MeteredFlow(.logical_datapath = lr_uuid, > > .controller_meter = r.copp.get(cOPP_ICMP6_ERR()), > > .external_ids = stage_hint(rp.lrp._uuid)) :- > > r in &Router(._uuid = lr_uuid), > > - Some{var l3dgw_port} = r.l3dgw_port, > > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > > - r.redirect_port_name != "", > > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > > + gw_mtu_rp in &RouterPort(.router = r), > > + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > gw_mtu > 0, > > + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > > rp in &RouterPort(.router = r), > > - rp.lrp != l3dgw_port, > > + rp.lrp != gw_mtu_rp.lrp, > > Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). > > > > MeteredFlow(.logical_datapath = lr_uuid, > > @@ -7675,137 +7657,6 @@ MeteredFlow(.logical_datapath = lr_uuid, > > .controller_meter = r.copp.get(cOPP_ICMP6_ERR()), > > .external_ids = stage_hint(rp.lrp._uuid)) :- > > r in &Router(._uuid = lr_uuid), > > - Some{var l3dgw_port} = r.l3dgw_port, > > - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), > > - r.redirect_port_name != "", > > - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), > > - gw_mtu > 0, > > - rp in &RouterPort(.router = r), > > - rp.lrp == l3dgw_port, > > - Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). > > - > > -/* Gateway routers. */ > > -Flow(.logical_datapath = lr_uuid, > > - .stage = s_ROUTER_IN_CHK_PKT_LEN(), > > - .priority = 50, > > - .__match = "outport == ${gw_mtu_rp.json_name}", > > - .actions = "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); " > > - "next;", > > - .external_ids = stage_hint(gw_mtu_rp.lrp._uuid)) :- > > - r in &Router(._uuid = lr_uuid), > > - r.is_gateway, > > - gw_mtu_rp in &RouterPort(.router = r), > > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > - gw_mtu > 0, > > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(). > > -Flow(.logical_datapath = lr_uuid, > > - .stage = s_ROUTER_IN_LARGER_PKTS(), > > - .priority = 150, > > - .__match = "inport == ${rp.json_name} && ip4 && " > > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > > - .actions = "icmp4_error {" > > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > > - "${rEGBIT_PKT_LARGER()} = 0; " > > - "eth.dst = ${rp.networks.ea}; " > > - "ip4.dst = ip4.src; " > > - "ip4.src = ${first_ipv4.addr}; " > > - "ip.ttl = 255; " > > - "icmp4.type = 3; /* Destination Unreachable. */ " > > - "icmp4.code = 4; /* Frag Needed and DF was Set. */ " > > - /* Set icmp4.frag_mtu to gw_mtu */ > > - "icmp4.frag_mtu = ${gw_mtu}; " > > - "next(pipeline=ingress, table=0); " > > - "};", > > - .external_ids = stage_hint(rp.lrp._uuid)) :- > > - r in &Router(._uuid = lr_uuid), > > - r.is_gateway, > > - gw_mtu_rp in &RouterPort(.router = r), > > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > - gw_mtu > 0, > > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > > - rp in &RouterPort(.router = r), > > - rp.lrp != gw_mtu_rp.lrp, > > - Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > > - > > -Flow(.logical_datapath = lr_uuid, > > - .stage = s_ROUTER_IN_IP_INPUT(), > > - .priority = 150, > > - .__match = "inport == ${rp.json_name} && ip4 && " > > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > > - .actions = "icmp4_error {" > > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > > - "${rEGBIT_PKT_LARGER()} = 0; " > > - "eth.dst = ${rp.networks.ea}; " > > - "ip4.dst = ip4.src; " > > - "ip4.src = ${first_ipv4.addr}; " > > - "ip.ttl = 255; " > > - "icmp4.type = 3; /* Destination Unreachable. */ " > > - "icmp4.code = 4; /* Frag Needed and DF was Set. */ " > > - /* Set icmp4.frag_mtu to gw_mtu */ > > - "icmp4.frag_mtu = ${gw_mtu}; " > > - "next(pipeline=ingress, table=0); " > > - "};", > > - .external_ids = stage_hint(rp.lrp._uuid)) :- > > - r in &Router(._uuid = lr_uuid), > > - r.is_gateway, > > - gw_mtu_rp in &RouterPort(.router = r), > > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > - gw_mtu > 0, > > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > > - rp in &RouterPort(.router = r), > > - rp.lrp == gw_mtu_rp.lrp, > > - Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). > > - > > -Flow(.logical_datapath = lr_uuid, > > - .stage = s_ROUTER_IN_LARGER_PKTS(), > > - .priority = 150, > > - .__match = "inport == ${rp.json_name} && ip6 && " > > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > > - .actions = "icmp6_error {" > > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > > - "${rEGBIT_PKT_LARGER()} = 0; " > > - "eth.dst = ${rp.networks.ea}; " > > - "ip6.dst = ip6.src; " > > - "ip6.src = ${first_ipv6.addr}; " > > - "ip.ttl = 255; " > > - "icmp6.type = 2; /* Packet Too Big. */ " > > - "icmp6.code = 0; " > > - /* Set icmp6.frag_mtu to gw_mtu */ > > - "icmp6.frag_mtu = ${gw_mtu}; " > > - "next(pipeline=ingress, table=0); " > > - "};", > > - .external_ids = stage_hint(rp.lrp._uuid)) :- > > - r in &Router(._uuid = lr_uuid), > > - r.is_gateway, > > - gw_mtu_rp in &RouterPort(.router = r), > > - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > - gw_mtu > 0, > > - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), > > - rp in &RouterPort(.router = r), > > - rp.lrp != gw_mtu_rp.lrp, > > - Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). > > - > > -Flow(.logical_datapath = lr_uuid, > > - .stage = s_ROUTER_IN_IP_INPUT(), > > - .priority = 150, > > - .__match = "inport == ${rp.json_name} && ip6 && " > > - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", > > - .actions = "icmp6_error {" > > - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " > > - "${rEGBIT_PKT_LARGER()} = 0; " > > - "eth.dst = ${rp.networks.ea}; " > > - "ip6.dst = ip6.src; " > > - "ip6.src = ${first_ipv6.addr}; " > > - "ip.ttl = 255; " > > - "icmp6.type = 2; /* Packet Too Big. */ " > > - "icmp6.code = 0; " > > - /* Set icmp6.frag_mtu to gw_mtu */ > > - "icmp6.frag_mtu = ${gw_mtu}; " > > - "next(pipeline=ingress, table=0); " > > - "};", > > - .external_ids = stage_hint(rp.lrp._uuid)) :- > > - r in &Router(._uuid = lr_uuid), > > - r.is_gateway, > > gw_mtu_rp in &RouterPort(.router = r), > > var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), > > gw_mtu > 0, > > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > > index 474e88021..2098b1c19 100644 > > --- a/tests/ovn-northd.at > > +++ b/tests/ovn-northd.at > > @@ -4865,10 +4865,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > > table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) > > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > ]) > > > > AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl > > @@ -4886,14 +4886,6 @@ AT_CHECK([grep -E "lr_in_ip_input.*icmp6_error" lr0flows | sort], [0], [dnl > > # Clear the gateway-chassis for lr0-public > > check ovn-nbctl --wait=sb clear logical_router_port lr0-public gateway_chassis > > > > -ovn-sbctl dump-flows lr0 > lr0flows > > -AT_CAPTURE_FILE([sw0flows]) > > - > > -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl > > - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > > - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > > -]) > > - > > # Make lr0 as a gateway router. > > check ovn-nbctl --wait=sb set logical_router lr0 options:chassis=ch1 > > > > @@ -4904,10 +4896,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > > table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) > > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > ]) > > > > AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl > > @@ -4933,14 +4925,14 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) > > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) > > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > ]) > > > > AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl > > @@ -4968,10 +4960,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d > > table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) > > table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) > > table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > + table=16(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=0); };) > > ]) > > > > AT_CLEANUP > > -- > > 2.30.2 > > > > > > _______________________________________________ > > dev mailing list > > dev@openvswitch.org > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
On Fri, Aug 6, 2021 at 12:00 PM Numan Siddique <numans@ovn.org> wrote: > > On Thu, Aug 5, 2021 at 1:10 PM Lorenzo Bianconi > <lorenzo.bianconi@redhat.com> wrote: > > > > > The commit 1c9e46ab5 removed the outport match from the lflows, which > > > leads to a problem for gateway routers that have multiple ports > > > configured with different MTUs. For example, R0 has port P1, P2 and P3. > > > P2 and P3 both have gateway_mtu configured: P2 mtu = 1400, P3 mtu = 1500. > > > Below lflows are generated: > > > table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) > > > table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) > > > > > > These two lflows have exact same match, but different actions (with > > > different MTUs). This will result in a random one gets installed by > > > ovn-controller and the icmp4_error message may contain incorrect mtu. > > > This patch fixes it by adding the outport back for these flows, so that > > > mtu that matches the outport setting is used in the generated icmp error > > > messages. > > > > > > Another problem of the commit is that the ddlog part used Flow instead > > > of MeterFlow for the gateway router flows that generates icmp errors, > > > while the flows for Distributed Gateway Ports use MeterFlow. This patch > > > also fixes that by combining the DGP and gateway router code using > > > MeterFlow. The check for DGP and Gateway Router is removed to simplify > > > the code, because checking the gateway_mtu config should be sufficient, > > > which also makes it consistent with the flows in the ADMISSION and > > > IP_INPUT stages where we didn't check DGP and gateway router but only > > > the gateway_mtu settings. > > > > > > Fixes: 1c9e46ab5 ("northd: add check_pkt_larger lflows for ingress traffic") > > > Signed-off-by: Han Zhou <hzhou@ovn.org> > > > > Hi Han, > > > > I have not run any test yet, but the code seems fine to me. > > > > Regards, > > Lorenzo > > Thanks for fixing this. > > Please see below one small nit comment. > > With that addressed: > > Acked-by: Numan Siddique <numans@ovn.org> > > Numan > Thanks Numan. I applied the patch with the nit addressed.
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index 08d484760..de4fe90c7 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -3756,9 +3756,10 @@ REGBIT_PKT_LARGER = check_pkt_larger(<var>L</var>); next; configured with <code>options:gateway_mtu</code> to a valid integer value, this table adds the following priority-150 logical flow for each logical router port with the match <code>inport == <var>LRP</var> - && REGBIT_PKT_LARGER && !REGBIT_EGRESS_LOOPBACK</code>, - where <var>LRP</var> is the logical router port and applies the following - action for ipv4 and ipv6 respectively: + && outport == <var>GW_PORT</var> && REGBIT_PKT_LARGER + && !REGBIT_EGRESS_LOOPBACK</code>, where <var>LRP</var> is the + logical router port and <var>GW_PORT</var> is the gateway port and + applies the following action for ipv4 and ipv6 respectively: </p> <pre> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index a0eaa1247..605e33486 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -10894,13 +10894,19 @@ build_arp_resolve_flows_for_lrouter_port( static void build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, struct shash *meter_groups, struct ds *match, - struct ds *actions, enum ovn_stage stage) + struct ds *actions, enum ovn_stage stage, + struct ovn_port *outport) { + char *outport_match = NULL; + if (outport) { + outport_match = xasprintf("outport == %s && ", outport->json_key); + } + if (op->lrp_networks.ipv4_addrs) { ds_clear(match); - ds_put_format(match, - "inport == %s && ip4 && "REGBIT_PKT_LARGER - " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key); + ds_put_format(match, "inport == %s && %sip4 && "REGBIT_PKT_LARGER + " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key, + outport ? outport_match : ""); ds_clear(actions); /* Set icmp4.frag_mtu to gw_mtu */ @@ -10931,8 +10937,9 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, if (op->lrp_networks.ipv6_addrs) { ds_clear(match); - ds_put_format(match, "inport == %s && ip6 && "REGBIT_PKT_LARGER - " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key); + ds_put_format(match, "inport == %s && %sip6 && "REGBIT_PKT_LARGER + " && "REGBIT_EGRESS_LOOPBACK" == 0", op->json_key, + outport ? outport_match : ""); ds_clear(actions); /* Set icmp6.frag_mtu to gw_mtu */ @@ -10960,6 +10967,9 @@ build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows, meter_groups), &op->nbrp->header_); } + if (outport) { + free(outport_match); + } } static int @@ -10999,7 +11009,8 @@ build_check_pkt_len_flows_for_lrp(struct ovn_port *op, /* ingress traffic */ build_icmperr_pkt_big_flows(op, gw_mtu, lflows, meter_groups, - match, actions, S_ROUTER_IN_IP_INPUT); + match, actions, S_ROUTER_IN_IP_INPUT, + NULL); for (size_t i = 0; i < op->od->nbr->n_ports; i++) { struct ovn_port *rp = ovn_port_find(ports, @@ -11010,7 +11021,8 @@ 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); + match, actions, S_ROUTER_IN_LARGER_PKTS, + op); } } @@ -11044,21 +11056,14 @@ build_check_pkt_len_flows_for_lrouter( ovn_lflow_add(lflows, od, S_ROUTER_IN_LARGER_PKTS, 0, "1", "next;"); - if (od->l3dgw_port && od->l3redirect_port) { - /* gw router port */ - build_check_pkt_len_flows_for_lrp(od->l3dgw_port, lflows, - ports, meter_groups, match, actions); - } else if (smap_get(&od->nbr->options, "chassis")) { - for (size_t i = 0; i < od->nbr->n_ports; i++) { - /* gw router */ - struct ovn_port *rp = ovn_port_find(ports, - od->nbr->ports[i]->name); - if (!rp) { - continue; - } - build_check_pkt_len_flows_for_lrp(rp, lflows, ports, meter_groups, - match, actions); + for (size_t i = 0; i < od->nbr->n_ports; i++) { + struct ovn_port *rp = ovn_port_find(ports, + od->nbr->ports[i]->name); + if (!rp || !rp->nbrp) { + continue; } + build_check_pkt_len_flows_for_lrp(rp, lflows, ports, meter_groups, + match, actions); } } diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl index 091fe10b3..d7141294e 100644 --- a/northd/ovn_northd.dl +++ b/northd/ovn_northd.dl @@ -7508,29 +7508,16 @@ for (&Router(._uuid = lr_uuid)) /* Local router ingress table CHK_PKT_LEN: Check packet length. * - * For distributed routers with gateway ports. - * Any IPv4 or IPv6 packet with outport set to the distributed gateway - * router port, check the packet length and store the result in the - * 'REGBIT_PKT_LARGER' register bit. + * Any IPv4 or IPv6 packet with outport set to a router port that has + * gateway_mtu > 0 configured, check the packet length and store the result in + * the 'REGBIT_PKT_LARGER' register bit. * * Local router ingress table LARGER_PKTS: Handle larger packets. * - * Any IPv4 or IPv6 packet with outport set to the distributed gateway - * router port and the 'REGBIT_PKT_LARGER' register bit is set, + * Any IPv4 or IPv6 packet with outport set to a router port that has + * gatway_mtu > 0 configured and the 'REGBIT_PKT_LARGER' register bit is set, * generate an ICMPv4/ICMPv6 packet with type 3/2 (Destination * Unreachable/Packet Too Big) and code 4/0 (Fragmentation needed). - * - * For Gateway routers. - * Any IPv4 or IPv6 packet with outport set to the router port which has - * the option 'gateway_mtu' set, check the packet length and store - * the result in the 'REGBIT_PKT_LARGER' register bit. - * - * Local router ingress table LARGER_PKTS: Handle larger packets. - * - * Any IPv4 or IPv6 packet with outport set to the router port which has - * the option 'gateway_mtu' set and the 'REGBIT_PKT_LARGER' register bit - * is set, generate ICMPv4/ICMPv6 packet with type 3/2 (Destination - * Unreachable/Packet Too Big) and * code 4/0 (Fragmentation needed). */ Flow(.logical_datapath = lr_uuid, .stage = s_ROUTER_IN_CHK_PKT_LEN(), @@ -7549,21 +7536,19 @@ Flow(.logical_datapath = lr_uuid, Flow(.logical_datapath = lr_uuid, .stage = s_ROUTER_IN_CHK_PKT_LEN(), .priority = 50, - .__match = "outport == ${l3dgw_port_json_name}", + .__match = "outport == ${gw_mtu_rp.json_name}", .actions = "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); " "next;", - .external_ids = stage_hint(l3dgw_port._uuid)) :- + .external_ids = stage_hint(gw_mtu_rp.lrp._uuid)) :- r in &Router(._uuid = lr_uuid), - Some{var l3dgw_port} = r.l3dgw_port, - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), - r.redirect_port_name != "", - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), + gw_mtu_rp in &RouterPort(.router = r), + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), gw_mtu > 0, var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(). MeteredFlow(.logical_datapath = lr_uuid, .stage = s_ROUTER_IN_LARGER_PKTS(), .priority = 150, - .__match = "inport == ${rp.json_name} && ip4 && " + .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && ip4 && " "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", .actions = "icmp4_error {" "${rEGBIT_EGRESS_LOOPBACK()} = 1; " @@ -7582,13 +7567,12 @@ MeteredFlow(.logical_datapath = lr_uuid, .controller_meter = r.copp.get(cOPP_ICMP4_ERR()), .external_ids = stage_hint(rp.lrp._uuid)) :- r in &Router(._uuid = lr_uuid), - Some{var l3dgw_port} = r.l3dgw_port, - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), - r.redirect_port_name != "", - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), + gw_mtu_rp in &RouterPort(.router = r), + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), gw_mtu > 0, + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), rp in &RouterPort(.router = r), - rp.lrp != l3dgw_port, + rp.lrp != gw_mtu_rp.lrp, Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). MeteredFlow(.logical_datapath = lr_uuid, @@ -7613,19 +7597,18 @@ MeteredFlow(.logical_datapath = lr_uuid, .controller_meter = r.copp.get(cOPP_ICMP4_ERR()), .external_ids = stage_hint(rp.lrp._uuid)) :- r in &Router(._uuid = lr_uuid), - Some{var l3dgw_port} = r.l3dgw_port, - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), - r.redirect_port_name != "", - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), + gw_mtu_rp in &RouterPort(.router = r), + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), gw_mtu > 0, + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), rp in &RouterPort(.router = r), - rp.lrp == l3dgw_port, + rp.lrp == gw_mtu_rp.lrp, Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). MeteredFlow(.logical_datapath = lr_uuid, .stage = s_ROUTER_IN_LARGER_PKTS(), .priority = 150, - .__match = "inport == ${rp.json_name} && ip6 && " + .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && ip6 && " "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", .actions = "icmp6_error {" "${rEGBIT_EGRESS_LOOPBACK()} = 1; " @@ -7644,13 +7627,12 @@ MeteredFlow(.logical_datapath = lr_uuid, .controller_meter = r.copp.get(cOPP_ICMP6_ERR()), .external_ids = stage_hint(rp.lrp._uuid)) :- r in &Router(._uuid = lr_uuid), - Some{var l3dgw_port} = r.l3dgw_port, - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), - r.redirect_port_name != "", - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), + gw_mtu_rp in &RouterPort(.router = r), + var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), gw_mtu > 0, + var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), rp in &RouterPort(.router = r), - rp.lrp != l3dgw_port, + rp.lrp != gw_mtu_rp.lrp, Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). MeteredFlow(.logical_datapath = lr_uuid, @@ -7675,137 +7657,6 @@ MeteredFlow(.logical_datapath = lr_uuid, .controller_meter = r.copp.get(cOPP_ICMP6_ERR()), .external_ids = stage_hint(rp.lrp._uuid)) :- r in &Router(._uuid = lr_uuid), - Some{var l3dgw_port} = r.l3dgw_port, - var l3dgw_port_json_name = json_string_escape(l3dgw_port.name), - r.redirect_port_name != "", - var gw_mtu = l3dgw_port.options.get_int_def("gateway_mtu", 0), - gw_mtu > 0, - rp in &RouterPort(.router = r), - rp.lrp == l3dgw_port, - Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). - -/* Gateway routers. */ -Flow(.logical_datapath = lr_uuid, - .stage = s_ROUTER_IN_CHK_PKT_LEN(), - .priority = 50, - .__match = "outport == ${gw_mtu_rp.json_name}", - .actions = "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); " - "next;", - .external_ids = stage_hint(gw_mtu_rp.lrp._uuid)) :- - r in &Router(._uuid = lr_uuid), - r.is_gateway, - gw_mtu_rp in &RouterPort(.router = r), - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), - gw_mtu > 0, - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(). -Flow(.logical_datapath = lr_uuid, - .stage = s_ROUTER_IN_LARGER_PKTS(), - .priority = 150, - .__match = "inport == ${rp.json_name} && ip4 && " - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", - .actions = "icmp4_error {" - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " - "${rEGBIT_PKT_LARGER()} = 0; " - "eth.dst = ${rp.networks.ea}; " - "ip4.dst = ip4.src; " - "ip4.src = ${first_ipv4.addr}; " - "ip.ttl = 255; " - "icmp4.type = 3; /* Destination Unreachable. */ " - "icmp4.code = 4; /* Frag Needed and DF was Set. */ " - /* Set icmp4.frag_mtu to gw_mtu */ - "icmp4.frag_mtu = ${gw_mtu}; " - "next(pipeline=ingress, table=0); " - "};", - .external_ids = stage_hint(rp.lrp._uuid)) :- - r in &Router(._uuid = lr_uuid), - r.is_gateway, - gw_mtu_rp in &RouterPort(.router = r), - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), - gw_mtu > 0, - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), - rp in &RouterPort(.router = r), - rp.lrp != gw_mtu_rp.lrp, - Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). - -Flow(.logical_datapath = lr_uuid, - .stage = s_ROUTER_IN_IP_INPUT(), - .priority = 150, - .__match = "inport == ${rp.json_name} && ip4 && " - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", - .actions = "icmp4_error {" - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " - "${rEGBIT_PKT_LARGER()} = 0; " - "eth.dst = ${rp.networks.ea}; " - "ip4.dst = ip4.src; " - "ip4.src = ${first_ipv4.addr}; " - "ip.ttl = 255; " - "icmp4.type = 3; /* Destination Unreachable. */ " - "icmp4.code = 4; /* Frag Needed and DF was Set. */ " - /* Set icmp4.frag_mtu to gw_mtu */ - "icmp4.frag_mtu = ${gw_mtu}; " - "next(pipeline=ingress, table=0); " - "};", - .external_ids = stage_hint(rp.lrp._uuid)) :- - r in &Router(._uuid = lr_uuid), - r.is_gateway, - gw_mtu_rp in &RouterPort(.router = r), - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), - gw_mtu > 0, - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), - rp in &RouterPort(.router = r), - rp.lrp == gw_mtu_rp.lrp, - Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). - -Flow(.logical_datapath = lr_uuid, - .stage = s_ROUTER_IN_LARGER_PKTS(), - .priority = 150, - .__match = "inport == ${rp.json_name} && ip6 && " - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", - .actions = "icmp6_error {" - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " - "${rEGBIT_PKT_LARGER()} = 0; " - "eth.dst = ${rp.networks.ea}; " - "ip6.dst = ip6.src; " - "ip6.src = ${first_ipv6.addr}; " - "ip.ttl = 255; " - "icmp6.type = 2; /* Packet Too Big. */ " - "icmp6.code = 0; " - /* Set icmp6.frag_mtu to gw_mtu */ - "icmp6.frag_mtu = ${gw_mtu}; " - "next(pipeline=ingress, table=0); " - "};", - .external_ids = stage_hint(rp.lrp._uuid)) :- - r in &Router(._uuid = lr_uuid), - r.is_gateway, - gw_mtu_rp in &RouterPort(.router = r), - var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), - gw_mtu > 0, - var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(), - rp in &RouterPort(.router = r), - rp.lrp != gw_mtu_rp.lrp, - Some{var first_ipv6} = rp.networks.ipv6_addrs.nth(0). - -Flow(.logical_datapath = lr_uuid, - .stage = s_ROUTER_IN_IP_INPUT(), - .priority = 150, - .__match = "inport == ${rp.json_name} && ip6 && " - "${rEGBIT_PKT_LARGER()} && ${rEGBIT_EGRESS_LOOPBACK()} == 0", - .actions = "icmp6_error {" - "${rEGBIT_EGRESS_LOOPBACK()} = 1; " - "${rEGBIT_PKT_LARGER()} = 0; " - "eth.dst = ${rp.networks.ea}; " - "ip6.dst = ip6.src; " - "ip6.src = ${first_ipv6.addr}; " - "ip.ttl = 255; " - "icmp6.type = 2; /* Packet Too Big. */ " - "icmp6.code = 0; " - /* Set icmp6.frag_mtu to gw_mtu */ - "icmp6.frag_mtu = ${gw_mtu}; " - "next(pipeline=ingress, table=0); " - "};", - .external_ids = stage_hint(rp.lrp._uuid)) :- - r in &Router(._uuid = lr_uuid), - r.is_gateway, gw_mtu_rp in &RouterPort(.router = r), var gw_mtu = gw_mtu_rp.lrp.options.get_int_def("gateway_mtu", 0), gw_mtu > 0, diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 474e88021..2098b1c19 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -4865,10 +4865,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) ]) AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl @@ -4886,14 +4886,6 @@ AT_CHECK([grep -E "lr_in_ip_input.*icmp6_error" lr0flows | sort], [0], [dnl # Clear the gateway-chassis for lr0-public check ovn-nbctl --wait=sb clear logical_router_port lr0-public gateway_chassis -ovn-sbctl dump-flows lr0 > lr0flows -AT_CAPTURE_FILE([sw0flows]) - -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) -]) - # Make lr0 as a gateway router. check ovn-nbctl --wait=sb set logical_router lr0 options:chassis=ch1 @@ -4904,10 +4896,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) ]) AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl @@ -4933,14 +4925,14 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) ]) AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl @@ -4968,10 +4960,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [d table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && 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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) + table=16(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=0); };) ]) AT_CLEANUP
The commit 1c9e46ab5 removed the outport match from the lflows, which leads to a problem for gateway routers that have multiple ports configured with different MTUs. For example, R0 has port P1, P2 and P3. P2 and P3 both have gateway_mtu configured: P2 mtu = 1400, P3 mtu = 1500. Below lflows are generated: table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "P1" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {... icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) These two lflows have exact same match, but different actions (with different MTUs). This will result in a random one gets installed by ovn-controller and the icmp4_error message may contain incorrect mtu. This patch fixes it by adding the outport back for these flows, so that mtu that matches the outport setting is used in the generated icmp error messages. Another problem of the commit is that the ddlog part used Flow instead of MeterFlow for the gateway router flows that generates icmp errors, while the flows for Distributed Gateway Ports use MeterFlow. This patch also fixes that by combining the DGP and gateway router code using MeterFlow. The check for DGP and Gateway Router is removed to simplify the code, because checking the gateway_mtu config should be sufficient, which also makes it consistent with the flows in the ADMISSION and IP_INPUT stages where we didn't check DGP and gateway router but only the gateway_mtu settings. Fixes: 1c9e46ab5 ("northd: add check_pkt_larger lflows for ingress traffic") Signed-off-by: Han Zhou <hzhou@ovn.org> --- northd/ovn-northd.8.xml | 7 +- northd/ovn-northd.c | 49 +++++----- northd/ovn_northd.dl | 195 +++++----------------------------------- tests/ovn-northd.at | 48 +++++----- 4 files changed, 74 insertions(+), 225 deletions(-)