On 24/07/2021 15:01, Lorenzo Bianconi wrote:
> As it is already done for distributed gw router scenario, introduce
> check_pkt_larger logical flows for gw router use case.
> 
> Co-authored-by: Numan Siddique <[email protected]>
> Signed-off-by: Numan Siddique <[email protected]>
> Signed-off-by: Lorenzo Bianconi <[email protected]>

Two small documentation issues,

otherwise:

Acked-by: Mark D. Gray <[email protected]>
> ---
>  northd/ovn-northd.8.xml |  24 ++++----
>  northd/ovn-northd.c     |  30 +++++++---
>  northd/ovn_northd.dl    |  82 +++++++++++++++++++++++++++
>  tests/ovn-northd.at     | 121 ++++++++++++++++++++++++++++++++++++++++
>  tests/ovn.at            |  47 ++++++++++++++++
>  5 files changed, 283 insertions(+), 21 deletions(-)
> 
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index 99a19f853..5f2b43cd1 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -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>ip4 &amp;&amp; outport == <var>GW_PORT</var></code>

You did not introduce this but the documentation states that we match on
ip4. This is not the case any more as we support IPv6 and IPv4. Can you
update the documentation.

> +      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>
> @@ -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>
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index 18f6f90ce..20f8d7b73 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -11038,17 +11038,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);
>          }
>      }
> diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl
> index 7bfaae992..4c7bf386a 100644
> --- a/northd/ovn_northd.dl
> +++ b/northd/ovn_northd.dl
> @@ -7504,6 +7504,7 @@ for (&Router(._uuid = lr_uuid))
>  
>  /* Local router ingress table CHK_PKT_LEN: Check packet length.
>   *
> + * For distributed routers with gateway ports.
>   * Any IPv4 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.
> @@ -7514,6 +7515,18 @@ for (&Router(._uuid = lr_uuid))
>   * router port and the 'REGBIT_PKT_LARGER' register bit is set,
>   * generate ICMPv4 packet with type 3 (Destination Unreachable) and
>   * code 4 (Fragmentation needed).
> + *
> + * For Gateway routers.
> + * Any IPv4 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 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 packet with type 3 (Destination Unreachable) and
> + * code 4 (Fragmentation needed).

This comment also refers to IPv4, however, we also support IPv6.
>   * */
>  Flow(.logical_datapath = lr_uuid,
>       .stage            = s_ROUTER_IN_CHK_PKT_LEN(),
> @@ -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
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 94405349e..56d8be7cc 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -4815,3 +4815,124 @@ AT_CHECK([ovn-sbctl --columns=tags list logical_flow 
> | grep lsp0 -c], [0], [dnl
>  
>  AT_CLEANUP
>  ])
> +
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([ovn -- gateway mtu check pkt larger flows])
> +ovn_start
> +
> +check ovn-sbctl chassis-add ch1 geneve 127.0.0.1
> +
> +check ovn-nbctl ls-add sw0
> +check ovn-nbctl ls-add sw1
> +
> +# Create a logical router and attach both logical switches
> +check ovn-nbctl lr-add lr0
> +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
> +check ovn-nbctl lsp-add sw0 sw0-lr0
> +check ovn-nbctl lsp-set-type sw0-lr0 router
> +check ovn-nbctl lsp-set-addresses sw0-lr0 00:00:00:00:ff:01
> +check ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
> +
> +check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 20.0.0.1/24
> +check ovn-nbctl lsp-add sw1 sw1-lr0
> +check ovn-nbctl lsp-set-type sw1-lr0 router
> +check ovn-nbctl lsp-set-addresses sw1-lr0 00:00:00:00:ff:02
> +check ovn-nbctl lsp-set-options sw1-lr0 router-port=lr0-sw1
> +
> +check ovn-nbctl ls-add public
> +check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
> +check ovn-nbctl lsp-add public public-lr0
> +check ovn-nbctl lsp-set-type public-lr0 router
> +check ovn-nbctl lsp-set-addresses public-lr0 router
> +check ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
> +
> +check ovn-nbctl --wait=sb lrp-set-gateway-chassis lr0-public ch1
> +
> +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;)
> +])
> +
> +check ovn-nbctl --wait=sb set logical_router_port lr0-public 
> options:gateway_mtu=1500
> +
> +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=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); };)
> +])
> +
> +# 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
> +
> +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=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); };)
> +])
> +
> +# Set gateway_mtu option on lr0-sw0
> +check ovn-nbctl --wait=sb set logical_router_port lr0-sw0 
> options:gateway_mtu=1400
> +
> +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=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); };)
> +])
> +
> +# Clear gateway_mtu option on lr0-public
> +check ovn-nbctl --wait=sb clear logical_router_port lr0-public options
> +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=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); };)
> +])
> +
> +AT_CLEANUP
> +])
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 13d860f10..6af62aab0 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -16733,6 +16733,53 @@ for mtu in 100 500 118; do
>      test_ip6_packet_larger $mtu
>  done
>  
> +ovn-nbctl lsp-del sw0-lr0
> +
> +ovn-nbctl lr-del lr0
> +ovn-nbctl create Logical_Router name=lr1 options:chassis="hv1"
> +ovn-nbctl lrp-add lr1 lr1-sw0 00:00:00:00:ff:01 10.0.0.1/24 1000::1/64
> +ovn-nbctl lsp-add sw0 sw0-lr1
> +ovn-nbctl lsp-set-type sw0-lr1 router
> +ovn-nbctl lsp-set-addresses sw0-lr1 router
> +ovn-nbctl lsp-set-options sw0-lr1 router-port=lr1-sw0
> +
> +ovn-nbctl lrp-add lr1 lr1-public 00:00:20:20:12:13 172.168.0.100/24 
> 2000::1/64
> +ovn-nbctl lsp-del public-lr0
> +ovn-nbctl lsp-add public public-lr1
> +ovn-nbctl lsp-set-type public-lr1 router
> +ovn-nbctl lsp-set-addresses public-lr1 router
> +ovn-nbctl lsp-set-options public-lr1 router-port=lr1-public
> +
> +ovn-nbctl lr-nat-add lr1 snat 172.168.0.100 10.0.0.0/24
> +ovn-nbctl lr-nat-add lr1 snat 2000::1 1000::/64
> +
> +dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep _uuid | \
> +awk '{print $3}')
> +ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
> +logical_port=lr1-public mac="00\:00\:00\:12\:af\:11"
> +
> +# Try different gateway mtus and send a 142-byte packet (corresponding
> +# to a 124-byte MTU).  If the MTU is less than 124, ovn-controller
> +# should send icmp host not reachable with pmtu set to $mtu.
> +for mtu in 100 500 118; do
> +    AS_BOX([testing gw mtu $mtu])
> +    check ovn-nbctl --wait=hv set logical_router_port lr1-public 
> options:gateway_mtu=$mtu
> +    ovn-sbctl dump-flows > sbflows-gw-$mtu
> +    AT_CAPTURE_FILE([sbflows-gw-$mtu])
> +
> +    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
> +])
> +
> +    AS_BOX([testing gw mtu $mtu - IPv4])
> +    test_ip_packet_larger $mtu
> +
> +    AS_BOX([testing gw mtu $mtu - IPv6])
> +    test_ip6_packet_larger $mtu
> +done
> +
>  OVN_CLEANUP([hv1])
>  AT_CLEANUP
>  ])
> 

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to