[ovs-dev] [PATCH v6 ovn 2/3] northd: enable check_pkt_larger for gw router

Lorenzo Bianconi lorenzo.bianconi at redhat.com
Tue Jul 27 13:28:08 UTC 2021


> 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 <numans at ovn.org>
> > Signed-off-by: Numan Siddique <numans at ovn.org>
> > Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
> 
> Two small documentation issues,

thx Mark, I will fix them in v7.

Regards,
Lorenzo

> 
> otherwise:
> 
> Acked-by: Mark D. Gray <mark.d.gray at redhat.com>
> > ---
> >  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 && 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 && 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>
> >        && 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 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
> >  ])
> > 
> 


More information about the dev mailing list