Skip to content

Commit

Permalink
northd: enable check_pkt_larger for gw router
Browse files Browse the repository at this point in the history
As it is already done for distributed gw router scenario, introduce
check_pkt_larger logical flows for gw router use case.

Acked-by: Mark D. Gray <mark.d.gray@redhat.com>
Co-authored-by: Numan Siddique <numans@ovn.org>
Signed-off-by: Numan Siddique <numans@ovn.org>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
  • Loading branch information
LorenzoBianconi and numansiddique committed Jul 29, 2021
1 parent 2c2f180 commit 947e8d4
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 26 deletions.
24 changes: 12 additions & 12 deletions northd/ovn-northd.8.xml
Expand Up @@ -3673,13 +3673,13 @@ outport = <var>P</var>
<h3>Ingress Table 15: Check packet length</h3>

<p>
For distributed logical routers with distributed gateway port configured
with <code>options:gateway_mtu</code> to a valid integer value, this
table adds a priority-50 logical flow with the match
<code>ip4 &amp;&amp; outport == <var>GW_PORT</var></code> where
<var>GW_PORT</var> is the distributed gateway router port and applies the
action <code>check_pkt_larger</code> and advances the packet to the
next table.
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 a priority-50 logical flow with
the match <code>outport == <var>GW_PORT</var></code> where
<var>GW_PORT</var> is the gateway router port and applies the
action <code>check_pkt_larger</code> and advances the packet to
the next table.
</p>

<pre>
Expand All @@ -3703,14 +3703,14 @@ REGBIT_PKT_LARGER = check_pkt_larger(<var>L</var>); next;
<h3>Ingress Table 16: Handle larger packets</h3>

<p>
For distributed logical routers with distributed 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
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
logical router port with the match <code>inport == <var>LRP</var>
&amp;&amp; outport == <var>GW_PORT</var> &amp;&amp;
REGBIT_PKT_LARGER</code>, where <var>LRP</var> is the logical
router port and <var>GW_PORT</var> is the distributed gateway router
port and applies the following action for ipv4 and ipv6 respectively:
router port and <var>GW_PORT</var> is the gateway router port and applies
the following action for ipv4 and ipv6 respectively:
</p>

<pre>
Expand Down
30 changes: 21 additions & 9 deletions northd/ovn-northd.c
Expand Up @@ -11043,17 +11043,29 @@ build_check_pkt_len_flows_for_lrouter(
struct ds *match, struct ds *actions,
struct shash *meter_groups)
{
if (od->nbr) {
if (!od->nbr) {
return;
}

/* Packets are allowed by default. */
ovn_lflow_add(lflows, od, S_ROUTER_IN_CHK_PKT_LEN, 0, "1",
"next;");
ovn_lflow_add(lflows, od, S_ROUTER_IN_LARGER_PKTS, 0, "1",
"next;");
/* Packets are allowed by default. */
ovn_lflow_add(lflows, od, S_ROUTER_IN_CHK_PKT_LEN, 0, "1",
"next;");
ovn_lflow_add(lflows, od, S_ROUTER_IN_LARGER_PKTS, 0, "1",
"next;");

if (od->l3dgw_port && od->l3redirect_port) {
build_check_pkt_len_flows_for_lrp(od->l3dgw_port, lflows,
ports, meter_groups,
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);
}
}
Expand Down
92 changes: 87 additions & 5 deletions northd/ovn_northd.dl
Expand Up @@ -7504,17 +7504,30 @@ for (&Router(._uuid = lr_uuid))

/* Local router ingress table CHK_PKT_LEN: Check packet length.
*
* Any IPv4 packet with outport set to the distributed gateway
* 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.
*
* Local router ingress table LARGER_PKTS: Handle larger packets.
*
* Any IPv4 packet with outport set to the distributed gateway
* Any IPv4 or IPv6 packet with outport set to the distributed gateway
* router port and the 'REGBIT_PKT_LARGER' register bit is set,
* generate ICMPv4 packet with type 3 (Destination Unreachable) and
* code 4 (Fragmentation needed).
* */
* 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(),
.priority = 0,
Expand Down Expand Up @@ -7602,6 +7615,75 @@ MeteredFlow(.logical_datapath = lr_uuid,
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 = 50,
.__match = "inport == ${rp.json_name} && outport == ${gw_mtu_rp.json_name} && "
"ip4 && ${rEGBIT_PKT_LARGER()}",
.actions = "icmp4_error {"
"${rEGBIT_EGRESS_LOOPBACK()} = 1; "
"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()}",
.actions = "icmp6_error {"
"${rEGBIT_EGRESS_LOOPBACK()} = 1; "
"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
Expand Down

0 comments on commit 947e8d4

Please sign in to comment.