@@ -1923,6 +1923,15 @@ output;
<code>eth.dst == <var>E</var></code> is only programmed on
the gateway port instance on the gateway chassis.
</p>
+
+ <p>
+ For a distributed logical router or for gateway router where
+ the port is configured with <code>options:gateway_mtu</code>
+ the action of the above flow is modified adding
+ <code>check_pkt_larger</code> in order to mark the packet
+ setting <code>REGBIT_PKT_LARGER</code> if the size is greater
+ than the MTU
+ </p>
</li>
<li>
@@ -2147,6 +2156,46 @@ next;
</p>
<ul>
+ <li>
+ <p>
+ For distributed logical routers or gateway routers with gateway port
+ configured with <code>options:gateway_mtu</code> to a valid integer
+ value, a priority-150 flow with the match <code>inport ==
+ <var>LRP</var> && REGBIT_PKT_LARGER &&
+ REGBIT_EGRESS_LOOPBACK == 0</code>, where <var>LRP</var> is the
+ logical router port and applies the following action for ipv4
+ and ipv6 respectively:
+ </p>
+
+ <pre>
+icmp4 {
+ icmp4.type = 3; /* Destination Unreachable. */
+ icmp4.code = 4; /* Frag Needed and DF was Set. */
+ icmp4.frag_mtu = <var>M</var>;
+ eth.dst = <var>E</var>;
+ ip4.dst = ip4.src;
+ ip4.src = <var>I</var>;
+ ip.ttl = 255;
+ REGBIT_EGRESS_LOOPBACK = 1;
+ REGBIT_PKT_LARGER 0;
+ next(pipeline=ingress, table=0);
+};
+
+icmp6 {
+ icmp6.type = 2;
+ icmp6.code = 0;
+ icmp6.frag_mtu = <var>M</var>;
+ eth.dst = <var>E</var>;
+ ip6.dst = ip6.src;
+ ip6.src = <var>I</var>;
+ ip.ttl = 255;
+ REGBIT_EGRESS_LOOPBACK = 1;
+ REGBIT_PKT_LARGER 0;
+ next(pipeline=ingress, table=0);
+};
+ </pre>
+ </li>
+
<li>
<p>
For each NAT entry of a distributed logical router (with
@@ -3631,12 +3680,11 @@ REGBIT_PKT_LARGER = check_pkt_larger(<var>L</var>); next;
<p>
For distributed logical routers or gateway routers with gateway port
configured with <code>options:gateway_mtu</code> to a valid integer
- value, this table adds the following priority-50 logical flow for each
+ value, this table adds the following priority-150 logical flow for each
logical router port with the match <code>inport == <var>LRP</var>
- && outport == <var>GW_PORT</var> &&
- REGBIT_PKT_LARGER</code>, where <var>LRP</var> is the logical
- router port and <var>GW_PORT</var> is the gateway router port and applies
- the following action for ipv4 and ipv6 respectively:
+ && 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:
</p>
<pre>
@@ -3649,6 +3697,7 @@ icmp4 {
ip4.src = <var>I</var>;
ip.ttl = 255;
REGBIT_EGRESS_LOOPBACK = 1;
+ REGBIT_PKT_LARGER = 0;
next(pipeline=ingress, table=0);
};
@@ -3661,6 +3710,7 @@ icmp6 {
ip6.src = <var>I</var>;
ip.ttl = 255;
REGBIT_EGRESS_LOOPBACK = 1;
+ REGBIT_PKT_LARGER = 0;
next(pipeline=ingress, table=0);
};
</pre>
@@ -9509,6 +9509,10 @@ build_adm_ctrl_flows_for_lrouter(
}
}
+static void
+build_check_pkt_len_action_string(struct ovn_port *op, int *pmtu,
+ struct ds *actions);
+
/* Logical router ingress Table 0: L2 Admission Control
* This table drops packets that the router shouldn’t see at all based
* on their Ethernet headers.
@@ -9536,6 +9540,8 @@ build_adm_ctrl_flows_for_lrouter_port(
* the pipeline.
*/
ds_clear(actions);
+
+ build_check_pkt_len_action_string(op, NULL, actions);
ds_put_format(actions, REG_INPORT_ETH_ADDR " = %s; next;",
op->lrp_networks.ea_s);
@@ -10430,32 +10436,110 @@ build_arp_resolve_flows_for_lrouter_port(
}
+static void
+build_icmperr_pkt_big_flows(struct ovn_port *op, int mtu, struct hmap *lflows,
+ struct ds *match, struct ds *actions,
+ enum ovn_stage stage)
+{
+ 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_clear(actions);
+ /* Set icmp4.frag_mtu to gw_mtu */
+ ds_put_format(actions,
+ "icmp4_error {"
+ REGBIT_EGRESS_LOOPBACK" = 1; "
+ REGBIT_PKT_LARGER" = 0; "
+ "eth.dst = %s; "
+ "ip4.dst = ip4.src; "
+ "ip4.src = %s; "
+ "ip.ttl = 255; "
+ "icmp4.type = 3; /* Destination Unreachable. */ "
+ "icmp4.code = 4; /* Frag Needed and DF was Set. */ "
+ "icmp4.frag_mtu = %d; "
+ "next(pipeline=ingress, table=%d); };",
+ op->lrp_networks.ea_s,
+ op->lrp_networks.ipv4_addrs[0].addr_s,
+ mtu, ovn_stage_get_table(S_ROUTER_IN_ADMISSION));
+ ovn_lflow_add_with_hint(lflows, op->od, stage, 150,
+ ds_cstr(match), ds_cstr(actions),
+ &op->nbrp->header_);
+ }
+
+ 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_clear(actions);
+ /* Set icmp6.frag_mtu to gw_mtu */
+ ds_put_format(actions,
+ "icmp6_error {"
+ REGBIT_EGRESS_LOOPBACK" = 1; "
+ REGBIT_PKT_LARGER" = 0; "
+ "eth.dst = %s; "
+ "ip6.dst = ip6.src; "
+ "ip6.src = %s; "
+ "ip.ttl = 255; "
+ "icmp6.type = 2; /* Packet Too Big. */ "
+ "icmp6.code = 0; "
+ "icmp6.frag_mtu = %d; "
+ "next(pipeline=ingress, table=%d); };",
+ op->lrp_networks.ea_s,
+ op->lrp_networks.ipv6_addrs[0].addr_s,
+ mtu, ovn_stage_get_table(S_ROUTER_IN_ADMISSION));
+ ovn_lflow_add_with_hint(lflows, op->od, stage, 150,
+ ds_cstr(match), ds_cstr(actions),
+ &op->nbrp->header_);
+ }
+}
+
+static void
+build_check_pkt_len_action_string(struct ovn_port *op, int *pmtu,
+ struct ds *actions)
+{
+ int gw_mtu = smap_get_int(&op->nbrp->options, "gateway_mtu", 0);
+
+ if (gw_mtu > 0) {
+ /* Add the flows only if gateway_mtu is configured. */
+ ds_put_format(actions,
+ REGBIT_PKT_LARGER" = check_pkt_larger(%d); ",
+ gw_mtu + VLAN_ETH_HEADER_LEN);
+ }
+ if (pmtu) {
+ *pmtu = gw_mtu;
+ }
+}
+
static void
build_check_pkt_len_flows_for_lrp(struct ovn_port *op,
struct hmap *lflows, struct hmap *ports,
struct ds *match, struct ds *actions)
{
- int gw_mtu = 0;
+ int gw_mtu;
- if (op->nbrp) {
- gw_mtu = smap_get_int(&op->nbrp->options, "gateway_mtu", 0);
- }
- /* Add the flows only if gateway_mtu is configured. */
+ ds_clear(actions);
+ build_check_pkt_len_action_string(op, &gw_mtu, actions);
if (gw_mtu <= 0) {
return;
}
+ ds_put_format(actions, "next;");
+
ds_clear(match);
ds_put_format(match, "outport == %s", op->json_key);
- ds_clear(actions);
- ds_put_format(actions,
- REGBIT_PKT_LARGER" = check_pkt_larger(%d);"
- " next;", gw_mtu + VLAN_ETH_HEADER_LEN);
ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_CHK_PKT_LEN, 50,
ds_cstr(match), ds_cstr(actions),
&op->nbrp->header_);
+ /* ingress traffic */
+ build_icmperr_pkt_big_flows(op, gw_mtu, lflows, match, actions,
+ S_ROUTER_IN_IP_INPUT);
+
for (size_t i = 0; i < op->od->nbr->n_ports; i++) {
struct ovn_port *rp = ovn_port_find(ports,
op->od->nbr->ports[i]->name);
@@ -10463,63 +10547,9 @@ build_check_pkt_len_flows_for_lrp(struct ovn_port *op,
continue;
}
- if (rp->lrp_networks.ipv4_addrs) {
- ds_clear(match);
- ds_put_format(match, "inport == %s && outport == %s"
- " && ip4 && "REGBIT_PKT_LARGER,
- rp->json_key, op->json_key);
-
- ds_clear(actions);
- /* Set icmp4.frag_mtu to gw_mtu */
- ds_put_format(actions,
- "icmp4_error {"
- REGBIT_EGRESS_LOOPBACK" = 1; "
- "eth.dst = %s; "
- "ip4.dst = ip4.src; "
- "ip4.src = %s; "
- "ip.ttl = 255; "
- "icmp4.type = 3; /* Destination Unreachable. */ "
- "icmp4.code = 4; /* Frag Needed and DF was Set. */ "
- "icmp4.frag_mtu = %d; "
- "next(pipeline=ingress, table=%d); };",
- rp->lrp_networks.ea_s,
- rp->lrp_networks.ipv4_addrs[0].addr_s,
- gw_mtu,
- ovn_stage_get_table(S_ROUTER_IN_ADMISSION));
- ovn_lflow_add_with_hint(lflows, op->od,
- S_ROUTER_IN_LARGER_PKTS, 50,
- ds_cstr(match), ds_cstr(actions),
- &rp->nbrp->header_);
- }
-
- if (rp->lrp_networks.ipv6_addrs) {
- ds_clear(match);
- ds_put_format(match, "inport == %s && outport == %s"
- " && ip6 && "REGBIT_PKT_LARGER,
- rp->json_key, op->json_key);
-
- ds_clear(actions);
- /* Set icmp6.frag_mtu to gw_mtu */
- ds_put_format(actions,
- "icmp6_error {"
- REGBIT_EGRESS_LOOPBACK" = 1; "
- "eth.dst = %s; "
- "ip6.dst = ip6.src; "
- "ip6.src = %s; "
- "ip.ttl = 255; "
- "icmp6.type = 2; /* Packet Too Big. */ "
- "icmp6.code = 0; "
- "icmp6.frag_mtu = %d; "
- "next(pipeline=ingress, table=%d); };",
- rp->lrp_networks.ea_s,
- rp->lrp_networks.ipv6_addrs[0].addr_s,
- gw_mtu,
- ovn_stage_get_table(S_ROUTER_IN_ADMISSION));
- ovn_lflow_add_with_hint(lflows, op->od,
- S_ROUTER_IN_LARGER_PKTS, 50,
- ds_cstr(match), ds_cstr(actions),
- &rp->nbrp->header_);
- }
+ /* egress traffic */
+ build_icmperr_pkt_big_flows(rp, gw_mtu, lflows, match, actions,
+ S_ROUTER_IN_LARGER_PKTS);
}
}
@@ -11579,8 +11609,10 @@ build_lrouter_ingress_flow(struct hmap *lflows, struct ovn_datapath *od,
* down in the pipeline.
*/
ds_clear(actions);
+
+ build_check_pkt_len_action_string(od->l3dgw_port, NULL, actions);
ds_put_format(actions, REG_INPORT_ETH_ADDR " = %s; next;",
- od->l3dgw_port->lrp_networks.ea_s);
+ od->l3dgw_port->lrp_networks.ea_s);
ds_clear(match);
ds_put_format(match,
@@ -4474,7 +4474,12 @@ for (&RouterPort(.lrp = lrp,
* This will save us from having to match on inport further down in
* the pipeline.
*/
- var actions = "${rEG_INPORT_ETH_ADDR()} = ${lrp_networks.ea}; next;" in {
+ var gw_mtu = lrp.options.get_int_def("gateway_mtu", 0) in
+ var mtu = gw_mtu + vLAN_ETH_HEADER_LEN() in
+ var actions = "${rEG_INPORT_ETH_ADDR()} = ${lrp_networks.ea}; " ++
+ if (gw_mtu > 0) {
+ "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); next;"
+ } else { "next;" } in {
Flow(.logical_datapath = router._uuid,
.stage = s_ROUTER_IN_ADMISSION(),
.priority = 50,
@@ -7166,11 +7171,12 @@ Flow(.logical_datapath = lr_uuid,
var mtu = gw_mtu + vLAN_ETH_HEADER_LEN().
Flow(.logical_datapath = lr_uuid,
.stage = s_ROUTER_IN_LARGER_PKTS(),
- .priority = 50,
- .__match = "inport == ${rp.json_name} && outport == ${l3dgw_port_json_name} && "
- "ip4 && ${rEGBIT_PKT_LARGER()}",
+ .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}; "
@@ -7191,13 +7197,44 @@ Flow(.logical_datapath = lr_uuid,
rp in &RouterPort(.router = r),
rp.lrp != l3dgw_port,
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),
+ 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_ipv4} = rp.networks.ipv4_addrs.nth(0).
+
Flow(.logical_datapath = lr_uuid,
.stage = s_ROUTER_IN_LARGER_PKTS(),
- .priority = 50,
- .__match = "inport == ${rp.json_name} && outport == ${l3dgw_port_json_name} && "
- "ip6 && ${rEGBIT_PKT_LARGER()}",
+ .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}; "
@@ -7219,6 +7256,35 @@ Flow(.logical_datapath = lr_uuid,
rp.lrp != l3dgw_port,
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),
+ 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(),
@@ -7235,11 +7301,12 @@ Flow(.logical_datapath = lr_uuid,
var mtu = gw_mtu + vLAN_ETH_HEADER_LEN().
Flow(.logical_datapath = lr_uuid,
.stage = s_ROUTER_IN_LARGER_PKTS(),
- .priority = 50,
- .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && "
- "ip4 && ${rEGBIT_PKT_LARGER()}",
+ .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}; "
@@ -7260,13 +7327,44 @@ Flow(.logical_datapath = lr_uuid,
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 = 50,
- .__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && "
- "ip6 && ${rEGBIT_PKT_LARGER()}",
+ .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}; "
@@ -7288,6 +7386,35 @@ Flow(.logical_datapath = lr_uuid,
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,
+ 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).
+
/* Logical router ingress table GW_REDIRECT: Gateway redirect.
*
* For traffic with outport equal to the l3dgw_port
@@ -3788,10 +3788,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=50 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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" && 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); };)
])
# Clear the gateway-chassis for lr0-public
@@ -3815,10 +3815,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=50 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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" && 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); };)
])
# Set gateway_mtu option on lr0-sw0
@@ -3832,14 +3832,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=50 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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" && 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); };)
])
# Clear gateway_mtu option on lr0-public
@@ -3851,10 +3851,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=50 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]]), action=(icmp4_error {reg9[[0]] = 1; 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=50 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]]), action=(icmp6_error {reg9[[0]] = 1; 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" && 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); };)
])
AT_CLEANUP
@@ -16319,6 +16319,52 @@ test_ip_packet_larger() {
fi
}
+test_ip_packet_larger_ext() {
+ local mtu=$1
+
+ # Send ip packet from sw0-port1 to outside
+ src_mac="00000012af11" # external mac
+ dst_mac="000020201213" # lr0-public mac
+ src_ip=`ip_to_hex 172 168 0 4`
+ dst_ip=`ip_to_hex 172 168 0 100`
+ # Set the packet length to 118.
+ pkt_len=0076
+ packet=${dst_mac}${src_mac}08004500${pkt_len}00000000400120cf
+ orig_packet_l3=${src_ip}${dst_ip}0900000000000000
+ orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
+ orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
+ orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
+ orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
+ orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
+ packet=${packet}${orig_packet_l3}
+
+ gw_ip_garp=ffffffffffff00002020121308060001080006040001000020201213aca80064000000000000aca80064
+ ext_ip_garp=ffffffffffff00000012af110806000108000604000100000012af11aca80004000000000000aca80004
+
+ src_ip=`ip_to_hex 172 168 0 100`
+ dst_ip=`ip_to_hex 172 168 0 4`
+ # pkt len should be 146 (28 (icmp packet) + 118 (orig ip + payload))
+ reply_pkt_len=0092
+ ip_csum=f397
+ icmp_reply=${src_mac}${dst_mac}08004500${reply_pkt_len}00004000fe0122b2
+ icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000$(printf "%04x" $mtu)
+ icmp_reply=${icmp_reply}4500${pkt_len}00000000400120cf
+ icmp_reply=${icmp_reply}${orig_packet_l3}
+ echo $icmp_reply > br-phys_n1.expected
+
+ echo $gw_ip_garp >> br-phys_n1.expected
+
+ as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
+ as hv1 reset_pcap_file hv1-vif1 hv1/vif1
+
+ check as hv1 ovs-appctl netdev-dummy/receive br-phys_n1 $ext_ip_garp
+ sleep 1
+ # Send packet from sw0-port1 to outside
+ check as hv1 ovs-appctl netdev-dummy/receive br-phys_n1 $packet
+
+ OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br-phys_n1.expected])
+}
+
test_ip6_packet_larger() {
local mtu=$1
@@ -16334,7 +16380,7 @@ test_ip6_packet_larger() {
local payload=${payload}0000000000000000000000000000000000000000
local payload=${payload}0000000000000000000000000000000000000000
- local ip6_hdr=6000000000583aff${ipv6_src}${ipv6_dst}
+ local ip6_hdr=6000000000583afe${ipv6_src}${ipv6_dst}
local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000ec7662f00001${payload}
as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
@@ -16351,11 +16397,11 @@ test_ip6_packet_larger() {
mtu_needed=$(expr ${packet_bytes} - 18)
if test $mtu -lt $mtu_needed; then
# First construct the inner IPv6 packet.
- inner_ip6=6000000000583afe${ipv6_src}${ipv6_dst}
+ inner_ip6=6000000000583afd${ipv6_src}${ipv6_dst}
inner_icmp6=8000000062f00001
inner_icmp6_and_payload=$(icmp6_csum_inplace ${inner_icmp6}${payload} ${inner_ip6})
inner_packet=${inner_ip6}${inner_icmp6_and_payload}
-
+
# Then the outer.
outer_ip6=6000000000883afe${ipv6_rt}${ipv6_src}
outer_icmp6_and_payload=$(icmp6_csum_inplace 020000000000$(printf "%04x" $mtu)${inner_packet} $outer_ip6)
@@ -16373,6 +16419,53 @@ test_ip6_packet_larger() {
fi
}
+test_ip6_packet_larger_ext() {
+ local mtu=$1
+
+ local eth_src=00000012af11
+ local eth_dst=000020201213
+
+ local ipv6_src=20000000000000000000000000000004
+ local ipv6_dst=20000000000000000000000000000001
+
+ local payload=0000000000000000000000000000000000000000
+ local payload=${payload}0000000000000000000000000000000000000000
+ local payload=${payload}0000000000000000000000000000000000000000
+ local payload=${payload}0000000000000000000000000000000000000000
+
+ local ip6_hdr=6000000000583afe${ipv6_src}${ipv6_dst}
+ local packet=${eth_dst}${eth_src}86dd${ip6_hdr}9000cc7662f00001${payload}
+
+ local ns=ffffffffffff00002020121308060001080006040001000020201213aca80064000000000000aca80064
+ echo $ns > br-phys_n1.expected
+
+ as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
+ as hv1 reset_pcap_file hv1-vif1 hv1/vif1
+
+ local na_ip6_hdr=6000000000203aff${ipv6_src}${ipv6_dst}
+ local na=${eth_dst}${eth_src}86dd${na_ip6_hdr}8800d78440000000${ipv6_src}0201${eth_src}
+ check as hv1 ovs-appctl netdev-dummy/receive br-phys_n1 $na
+ sleep 1
+ check as hv1 ovs-appctl netdev-dummy/receive br-phys_n1 $packet
+ AT_CAPTURE_FILE([trace-$mtu])
+
+ # First construct the inner IPv6 packet.
+ inner_ip6=6000000000583afe${ipv6_src}${ipv6_dst}
+ inner_icmp6=9000000062f00001
+ inner_icmp6_and_payload=$(icmp6_csum_inplace ${inner_icmp6}${payload} ${inner_ip6})
+ inner_packet=${inner_ip6}${inner_icmp6_and_payload}
+
+ # Then the outer.
+ outer_ip6=6000000000883afe${ipv6_dst}${ipv6_src}
+ outer_icmp6_and_payload=$(icmp6_csum_inplace 020000000000$(printf "%04x" $mtu)${inner_packet} $outer_ip6)
+ outer_packet=${outer_ip6}${outer_icmp6_and_payload}
+
+ icmp6_reply=${eth_src}${eth_dst}86dd${outer_packet}
+ echo $icmp6_reply >> br-phys_n1.expected
+
+ OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br-phys_n1.expected])
+}
+
wait_for_ports_up
ovn-nbctl --wait=hv sync
@@ -16405,7 +16498,7 @@ for mtu in 100 500 118; do
OVS_WAIT_FOR_OUTPUT([
as hv1 ovs-ofctl dump-flows br-int > br-int-flows-$mtu
AT_CAPTURE_FILE([br-int-flows-$mtu])
- grep "check_pkt_larger($(expr $mtu + 18))" br-int-flows-$mtu | wc -l], [0], [1
+ grep "check_pkt_larger($(expr $mtu + 18))" br-int-flows-$mtu | wc -l], [0], [3
])
AS_BOX([testing mtu $mtu - IPv4])
@@ -16415,6 +16508,23 @@ for mtu in 100 500 118; do
test_ip6_packet_larger $mtu
done
+AS_BOX([testing mtu $mtu])
+check ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=100
+ovn-sbctl dump-flows > ext-sbflows-100
+AT_CAPTURE_FILE([ext-sbflows-$mtu])
+
+OVS_WAIT_FOR_OUTPUT([
+ as hv1 ovs-ofctl dump-flows br-int > ext-br-int-flows-100
+ AT_CAPTURE_FILE([ext-br-int-flows-100])
+ grep "check_pkt_larger(118)" ext-br-int-flows-100 | wc -l], [0], [3
+])
+
+AS_BOX([testing ext mtu 100 - IPv4])
+test_ip_packet_larger_ext 100
+
+AS_BOX([testing mtu 100 - IPv6])
+test_ip6_packet_larger_ext 100
+
ovn-nbctl lsp-del sw0-lr0
ovn-nbctl lr-del lr0
@@ -16452,7 +16562,7 @@ for mtu in 100 500 118; do
OVS_WAIT_FOR_OUTPUT([
as hv1 ovs-ofctl dump-flows br-int > br-int-gw-flows-$mtu
AT_CAPTURE_FILE([br-int-gw-flows-$mtu])
- grep "check_pkt_larger($(expr $mtu + 18))" br-int-gw-flows-$mtu | wc -l], [0], [1
+ grep "check_pkt_larger($(expr $mtu + 18))" br-int-gw-flows-$mtu | wc -l], [0], [3
])
AS_BOX([testing gw mtu $mtu - IPv4])
@@ -16462,6 +16572,23 @@ for mtu in 100 500 118; do
test_ip6_packet_larger $mtu
done
+AS_BOX([testing gw mtu $mtu])
+check ovn-nbctl --wait=hv set logical_router_port lr1-public options:gateway_mtu=100
+ovn-sbctl dump-flows > ext-gw-sbflows-100
+AT_CAPTURE_FILE([ext-gw-sbflows-$mtu])
+
+OVS_WAIT_FOR_OUTPUT([
+ as hv1 ovs-ofctl dump-flows br-int > ext-br-int-gw-flows-100
+ AT_CAPTURE_FILE([ext-br-int-gw-flows-100])
+ grep "check_pkt_larger(118)" ext-br-int-gw-flows-100 | wc -l], [0], [3
+])
+
+AS_BOX([testing gw ext mtu 100 - IPv4])
+test_ip_packet_larger_ext 100
+
+AS_BOX([testing gw mtu 100 - IPv6])
+test_ip6_packet_larger_ext 100
+
OVN_CLEANUP([hv1])
AT_CLEANUP
])
Introduce check_pkt_larger action for ingress traffic entering the cluster from a distributed gw router port or from a gw router. This patch enables pMTU discovery for ingress traffic. Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> --- northd/ovn-northd.8.xml | 60 +++++++++++++-- northd/ovn-northd.c | 166 ++++++++++++++++++++++++---------------- northd/ovn_northd.dl | 153 ++++++++++++++++++++++++++++++++---- tests/ovn-northd.at | 40 +++++----- tests/ovn.at | 137 +++++++++++++++++++++++++++++++-- 5 files changed, 446 insertions(+), 110 deletions(-)