On Fri, Jul 15, 2022 at 4:35 AM Lorenzo Bianconi <
lorenzo.bianc...@redhat.com> wrote:
>
> Rely on the following new actions for ecmp-symmetric routing:
> - chk_ecmp_nh_mac
> - chk_ecmp_nh
> - commit_ecmp_nh
>
> In this way OVN is able to keep up if for any reason the ECMP traffic
> source changes L2 address and keeps old L3 addresses.

Hi Lorenzo, do you have more details of the problem scenario? It seems the
bugzilla access is limited.

>
> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2096233
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com>
> ---
>  northd/northd.c         | 102 +++++++++++++++++++++++++++++++++++-----
>  northd/ovn-northd.8.xml |  25 ++++++----
>  tests/ovn-northd.at     |  18 ++++++-
>  tests/ovn.at            |   4 +-
>  tests/system-ovn.at     |  79 ++++++++++++++++++++++++++-----
>  5 files changed, 191 insertions(+), 37 deletions(-)
>
> diff --git a/northd/northd.c b/northd/northd.c
> index d31cb1688..57ec3675b 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -227,6 +227,7 @@ enum ovn_stage {
>  #define REGBIT_LOOKUP_NEIGHBOR_RESULT "reg9[2]"
>  #define REGBIT_LOOKUP_NEIGHBOR_IP_RESULT "reg9[3]"
>  #define REGBIT_DST_NAT_IP_LOCAL "reg9[4]"
> +#define REGBIT_KNOWN_ECMP_NH    "reg9[5]"
>
>  /* Register to store the eth address associated to a router port for
packets
>   * received in S_ROUTER_IN_ADMISSION.
> @@ -327,7 +328,8 @@ enum ovn_stage {
>   * |     |   EGRESS_LOOPBACK/       | G |     UNUSED      |
>   * | R9  |   PKT_LARGER/            | 4 |                 |
>   * |     |   LOOKUP_NEIGHBOR_RESULT/|   |                 |
> - * |     |   SKIP_LOOKUP_NEIGHBOR}  |   |                 |
> + * |     |   SKIP_LOOKUP_NEIGHBOR/  |   |                 |
> + * |     |   KNOWN_ECMP_NH}         |   |                 |
>   * |     |                          |   |                 |
>   * |     | REG_ORIG_TP_DPORT_ROUTER |   |                 |
>   * |     |                          |   |                 |
> @@ -9437,6 +9439,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
>                                 struct ds *route_match)
>  {
>      const struct nbrec_logical_router_static_route *st_route =
route->route;
> +    struct ds base_match = DS_EMPTY_INITIALIZER;
>      struct ds match = DS_EMPTY_INITIALIZER;
>      struct ds actions = DS_EMPTY_INITIALIZER;
>      struct ds ecmp_reply = DS_EMPTY_INITIALIZER;
> @@ -9448,20 +9451,22 @@ add_ecmp_symmetric_reply_flows(struct hmap
*lflows,
>      /* If symmetric ECMP replies are enabled, then packets that arrive
over
>       * an ECMP route need to go through conntrack.
>       */
> -    ds_put_format(&match, "inport == %s && ip%s.%s == %s",
> +    ds_put_format(&base_match, "inport == %s && ip%s.%s == %s",
>                    out_port->json_key,
>                    IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "4" : "6",
>                    route->is_src_route ? "dst" : "src",
>                    cidr);
>      free(cidr);
>      ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG, 100,
> -                            ds_cstr(&match), "ct_next;",
> -                            &st_route->header_);
> +            ds_cstr(&base_match),
> +            REGBIT_KNOWN_ECMP_NH" = chk_ecmp_nh_mac(); ct_next;",
> +            &st_route->header_);
>
>      /* And packets that go out over an ECMP route need conntrack */
>      ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG, 100,
> -                            ds_cstr(route_match), "ct_next;",
> -                            &st_route->header_);
> +            ds_cstr(route_match),
> +            REGBIT_KNOWN_ECMP_NH" = chk_ecmp_nh(); ct_next;",
> +            &st_route->header_);
>
>      /* Save src eth and inport in ct_label for packets that arrive over
>       * an ECMP route.
> @@ -9469,11 +9474,84 @@ add_ecmp_symmetric_reply_flows(struct hmap
*lflows,
>       * NOTE: we purposely are not clearing match before this
>       * ds_put_cstr() call. The previous contents are needed.
>       */
> -    ds_put_cstr(&match, " && (ct.new && !ct.est)");
> +    ds_put_format(&match, "%s && (ct.new && !ct.est) && tcp",
> +                  ds_cstr(&base_match));
> +    ds_put_format(&actions,
> +            "ct_commit { ct_label.ecmp_reply_eth = eth.src; "
> +            " %s = %" PRId64 ";}; "
> +            "commit_ecmp_nh(ipv6 = %s, proto = tcp); next;",
> +            ct_ecmp_reply_port_match, out_port->sb->tunnel_key,
> +            IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "false" : "true");
> +    ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
> +                            ds_cstr(&match), ds_cstr(&actions),
> +                            &st_route->header_);
> +    ds_clear(&match);
> +    ds_put_format(&match, "%s && (ct.new && !ct.est) && udp",
> +                  ds_cstr(&base_match));
> +    ds_clear(&actions);
> +    ds_put_format(&actions,
> +            "ct_commit { ct_label.ecmp_reply_eth = eth.src; "
> +            " %s = %" PRId64 ";}; "
> +            "commit_ecmp_nh(ipv6 = %s, proto = udp); next;",
> +            ct_ecmp_reply_port_match, out_port->sb->tunnel_key,
> +            IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "false" : "true");
> +    ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
> +                            ds_cstr(&match), ds_cstr(&actions),
> +                            &st_route->header_);
> +    ds_clear(&match);
> +    ds_put_format(&match, "%s && (ct.new && !ct.est) && sctp",
> +                  ds_cstr(&base_match));
> +    ds_clear(&actions);
> +    ds_put_format(&actions,
> +            "ct_commit { ct_label.ecmp_reply_eth = eth.src; "
> +            " %s = %" PRId64 ";}; "
> +            "commit_ecmp_nh(ipv6 = %s, proto = sctp); next;",
> +            ct_ecmp_reply_port_match, out_port->sb->tunnel_key,
> +            IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "false" : "true");
> +    ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
> +                            ds_cstr(&match), ds_cstr(&actions),
> +                            &st_route->header_);
>
> -    ds_put_format(&actions, "ct_commit { ct_label.ecmp_reply_eth =
eth.src;"
> -                  " %s = %" PRId64 ";}; next;",
> -                  ct_ecmp_reply_port_match, out_port->sb->tunnel_key);
> +    ds_clear(&match);
> +    ds_put_format(&match,
> +            "%s && (!ct.rpl && ct.est) && tcp && "REGBIT_KNOWN_ECMP_NH"
== 0",
> +            ds_cstr(&base_match));
> +    ds_clear(&actions);
> +    ds_put_format(&actions,
> +            "ct_commit { ct_label.ecmp_reply_eth = eth.src; "
> +            " %s = %" PRId64 ";}; "
> +            "commit_ecmp_nh(ipv6 = %s, proto = tcp); next;",
> +            ct_ecmp_reply_port_match, out_port->sb->tunnel_key,
> +            IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "false" : "true");
> +    ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
> +                            ds_cstr(&match), ds_cstr(&actions),
> +                            &st_route->header_);
> +
> +    ds_clear(&match);
> +    ds_put_format(&match,
> +            "%s && (!ct.rpl && ct.est) && udp && "REGBIT_KNOWN_ECMP_NH"
== 0",
> +            ds_cstr(&base_match));
> +    ds_clear(&actions);
> +    ds_put_format(&actions,
> +            "ct_commit { ct_label.ecmp_reply_eth = eth.src; "
> +            " %s = %" PRId64 ";}; "

Sorry that I haven't reviewed the details yet, but this flow would break HW
offload again, which was fixed in 22.03 and backported to 21.12. cc @Mark
Michelson <mmich...@redhat.com>

Thanks,
Han

> +            "commit_ecmp_nh(ipv6 = %s, proto = udp); next;",
> +            ct_ecmp_reply_port_match, out_port->sb->tunnel_key,
> +            IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "false" : "true");
> +    ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
> +                            ds_cstr(&match), ds_cstr(&actions),
> +                            &st_route->header_);
> +    ds_clear(&match);
> +    ds_put_format(&match,
> +            "%s && (!ct.rpl && ct.est) && sctp && "REGBIT_KNOWN_ECMP_NH"
== 0",
> +            ds_cstr(&base_match));
> +    ds_clear(&actions);
> +    ds_put_format(&actions,
> +            "ct_commit { ct_label.ecmp_reply_eth = eth.src; "
> +            " %s = %" PRId64 ";}; "
> +            "commit_ecmp_nh(ipv6 = %s, proto = sctp); next;",
> +            ct_ecmp_reply_port_match, out_port->sb->tunnel_key,
> +            IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "false" : "true");
>      ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
>                              ds_cstr(&match), ds_cstr(&actions),
>                              &st_route->header_);
> @@ -9481,7 +9559,8 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
>      /* Bypass ECMP selection if we already have ct_label information
>       * for where to route the packet.
>       */
> -    ds_put_format(&ecmp_reply, "ct.rpl && %s == %"PRId64,
> +    ds_put_format(&ecmp_reply,
> +                  "ct.rpl && "REGBIT_KNOWN_ECMP_NH" == 1 && %s ==
%"PRId64,
>                    ct_ecmp_reply_port_match, out_port->sb->tunnel_key);
>      ds_clear(&match);
>      ds_put_format(&match, "%s && %s", ds_cstr(&ecmp_reply),
> @@ -9517,6 +9596,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
>                              200, ds_cstr(&ecmp_reply),
>                              action, &st_route->header_);
>
> +    ds_destroy(&base_match);
>      ds_destroy(&match);
>      ds_destroy(&actions);
>      ds_destroy(&ecmp_reply);
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index a87df24bd..aa7196a92 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -3166,8 +3166,12 @@ icmp6 {
>        configured. The matching logic for these ports essentially
reverses the
>        configured logic of the ECMP route. So for instance, a route with a
>        destination routing policy will instead match if the source IP
address
> -      matches the static route's prefix. The flow uses the action
> -      <code>ct_next</code> to send IP packets to the connection tracker
for
> +      matches the static route's prefix. The flow uses the actions
> +      <code>chk_ecmp_nh_mac(); ct_next</code> or
> +      <code>chk_ecmp_nh(); ct_next</code> to send IP packets to table
> +      <code>OFTABLE_ECMP_NH_MAC</code> or to table
> +      <code>OFTABLE_ECMP_NH</code> in order to check if source info are
already
> +      stored by OVN and then to the connection tracker for
>        packet de-fragmentation and tracking before sending it to the next
table.
>      </p>
>
> @@ -3426,10 +3430,11 @@ icmp6 {
>          route with a destination routing policy will instead match if the
>          source IP address matches the static route's prefix. The flow
uses
>          the action <code>ct_commit { ct_label.ecmp_reply_eth = eth.src;"
> -        " ct_mark.ecmp_reply_port = <var>K</var>;}; next; </code> to
commit
> -        the connection and storing <code>eth.src</code> and the ECMP
> -        reply port binding tunnel key <var>K</var> in the
> -        <code>ct_label</code>.
> +        " ct_mark.ecmp_reply_port = <var>K</var>;}; commit_ecmp_nh();
next;
> +        </code> to commit the connection and storing
<code>eth.src</code> and
> +        the ECMP reply port binding tunnel key <var>K</var> in the
> +        <code>ct_label</code> and the traffic pattern to table
> +        <code>OFTABLE_ECMP_NH_MAC</code> or <code>OFTABLE_ECMP_NH</code>.
>        </li>
>      </ul>
>
> @@ -3568,10 +3573,10 @@ output;
>        which the packet should be sent. The
<code>ct_mark.ecmp_reply_port</code>
>        tells the logical router port on which the packet should be sent.
These
>        values saved to the conntrack fields when the initial ingress
traffic is
> -      received over the ECMP route and committed to conntrack. The
> -      priority-10300 flows in this stage set the <code>outport</code>,
> -      while the <code>eth.dst</code> is set by flows at the ARP/ND
Resolution
> -      stage.
> +      received over the ECMP route and committed to conntrack.
> +      If <code>REGBIT_KNOWN_ECMP_NH</code> is set, the priority-10300
> +      flows in this stage set the <code>outport</code>, while the
> +      <code>eth.dst</code> is set by flows at the ARP/ND Resolution
stage.
>      </p>
>
>      <p>
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 610a5ce12..0c7b24816 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -5644,10 +5644,24 @@ AT_CHECK([grep -e "lr_in_ip_routing_ecmp"
lr0flows | sed 's/192\.168\.0\..0/192.
>    table=??(lr_in_ip_routing_ecmp), priority=150  , match=(reg8[[0..15]]
== 0), action=(next;)
>  ])
>
> +AT_CHECK([grep -e "lr_in_ecmp_stateful".*commit_ecmp_nh lr0flows | sed
's/table=../table=??/' | sort], [0], [dnl
> +  table=??(lr_in_ecmp_stateful), priority=100  , match=(inport ==
"lr0-public" && ip4.src == 1.0.0.1 && (!ct.rpl && ct.est) && sctp &&
reg9[[5]] == 0), action=(ct_commit { ct_label.ecmp_reply_eth = eth.src;
 ct_label.ecmp_reply_port = 1;}; commit_ecmp_nh(ipv6 = false, proto =
sctp); next;)
> +  table=??(lr_in_ecmp_stateful), priority=100  , match=(inport ==
"lr0-public" && ip4.src == 1.0.0.1 && (!ct.rpl && ct.est) && tcp &&
reg9[[5]] == 0), action=(ct_commit { ct_label.ecmp_reply_eth = eth.src;
 ct_label.ecmp_reply_port = 1;}; commit_ecmp_nh(ipv6 = false, proto = tcp);
next;)
> +  table=??(lr_in_ecmp_stateful), priority=100  , match=(inport ==
"lr0-public" && ip4.src == 1.0.0.1 && (!ct.rpl && ct.est) && udp &&
reg9[[5]] == 0), action=(ct_commit { ct_label.ecmp_reply_eth = eth.src;
 ct_label.ecmp_reply_port = 1;}; commit_ecmp_nh(ipv6 = false, proto = udp);
next;)
> +  table=??(lr_in_ecmp_stateful), priority=100  , match=(inport ==
"lr0-public" && ip4.src == 1.0.0.1 && (ct.new && !ct.est) && sctp),
action=(ct_commit { ct_label.ecmp_reply_eth = eth.src;
 ct_label.ecmp_reply_port = 1;}; commit_ecmp_nh(ipv6 = false, proto =
sctp); next;)
> +  table=??(lr_in_ecmp_stateful), priority=100  , match=(inport ==
"lr0-public" && ip4.src == 1.0.0.1 && (ct.new && !ct.est) && tcp),
action=(ct_commit { ct_label.ecmp_reply_eth = eth.src;
 ct_label.ecmp_reply_port = 1;}; commit_ecmp_nh(ipv6 = false, proto = tcp);
next;)
> +  table=??(lr_in_ecmp_stateful), priority=100  , match=(inport ==
"lr0-public" && ip4.src == 1.0.0.1 && (ct.new && !ct.est) && udp),
action=(ct_commit { ct_label.ecmp_reply_eth = eth.src;
 ct_label.ecmp_reply_port = 1;}; commit_ecmp_nh(ipv6 = false, proto = udp);
next;)
> +])
> +
> +AT_CHECK([grep -e "lr_in_defrag".*chk_ecmp_nh* lr0flows | sed
's/table=../table=??/' | sort], [0], [dnl
> +  table=??(lr_in_defrag       ), priority=100  , match=(inport ==
"lr0-public" && ip4.src == 1.0.0.1), action=(reg9[[5]] = chk_ecmp_nh_mac();
ct_next;)
> +  table=??(lr_in_defrag       ), priority=100  , match=(reg7 == 0 &&
ip4.dst == 1.0.0.1/32), action=(reg9[[5]] = chk_ecmp_nh(); ct_next;)
> +])
> +
>  dnl The chassis was created with other_config:ct-no-masked-label=false,
the flows
>  dnl should be using ct_label.ecmp_reply_port.
>  AT_CHECK([grep -e "lr_in_arp_resolve.*ecmp" lr0flows | sed
's/table=../table=??/'], [0], [dnl
> -  table=??(lr_in_arp_resolve  ), priority=200  , match=(ct.rpl &&
ct_label.ecmp_reply_port == 1), action=(push(xxreg1); xxreg1 = ct_label;
eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;)
> +  table=??(lr_in_arp_resolve  ), priority=200  , match=(ct.rpl &&
reg9[[5]] == 1 && ct_label.ecmp_reply_port == 1), action=(push(xxreg1);
xxreg1 = ct_label; eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;)
>  ])
>
>  dnl Simulate an ovn-controller upgrade to a version that supports
> @@ -5657,7 +5671,7 @@ check ovn-sbctl set chassis ch1
other_config:ct-no-masked-label=true
>  check ovn-nbctl --wait=sb sync
>  ovn-sbctl dump-flows lr0 > lr0flows
>  AT_CHECK([grep -e "lr_in_arp_resolve.*ecmp" lr0flows | sed
's/table=../table=??/'], [0], [dnl
> -  table=??(lr_in_arp_resolve  ), priority=200  , match=(ct.rpl &&
ct_mark.ecmp_reply_port == 1), action=(push(xxreg1); xxreg1 = ct_label;
eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;)
> +  table=??(lr_in_arp_resolve  ), priority=200  , match=(ct.rpl &&
reg9[[5]] == 1 && ct_mark.ecmp_reply_port == 1), action=(push(xxreg1);
xxreg1 = ct_label; eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;)
>  ])
>
>  # add ecmp route with wrong nexthop
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 91dc3b9d6..12ba3f6d0 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -27173,7 +27173,7 @@ AT_CHECK([
>          grep "priority=200" | \
>          grep -c
"move:NXM_NX_CT_LABEL\\[[\\]]->NXM_NX_XXREG1\\[[\\]],move:NXM_NX_XXREG1\\[[32..79\\]]->NXM_OF_ETH_DST"
>      done; :], [0], [dnl
> -1
> +6
>  1
>  0
>  0
> @@ -27298,7 +27298,7 @@ AT_CHECK([
>          grep "priority=200" | \
>          grep -c
"move:NXM_NX_CT_LABEL\\[[\\]]->NXM_NX_XXREG1\\[[\\]],move:NXM_NX_XXREG1\\[[32..79\\]]->NXM_OF_ETH_DST"
>      done; :], [0], [dnl
> -1
> +6
>  1
>  0
>  0
> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> index 4a8fdede8..b3096deb3 100644
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -5956,11 +5956,8 @@ ovn-nbctl --wait=hv sync
>
>  on_exit 'ovs-ofctl dump-flows br-int'
>
> -# 'bob1' should be able to ping 'alice1' directly.
> -NS_CHECK_EXEC([bob1], [ping -q -c 20 -i 0.3 -w 15 10.0.0.2 |
FORMAT_PING], \
> -[0], [dnl
> -20 packets transmitted, 20 received, 0% packet loss, time 0ms
> -])
> +NETNS_DAEMONIZE([alice1], [nc -l -k 80], [alice1.pid])
> +NS_CHECK_EXEC([bob1], [nc -z 10.0.0.2 80], [0])
>
>  # Ensure conntrack entry is present. We should not try to predict
>  # the tunnel key for the output port, so we strip it from the labels
> @@ -5968,7 +5965,7 @@ NS_CHECK_EXEC([bob1], [ping -q -c 20 -i 0.3 -w 15
10.0.0.2 | FORMAT_PING], \
>  AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.0.1) | \
>  sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>  sed -e 's/mark=[[0-9]]*/mark=<cleared>/'], [0], [dnl
>
-icmp,orig=(src=172.16.0.1,dst=10.0.0.2,id=<cleared>,type=8,code=0),reply=(src=10.0.0.2,dst=172.16.0.1,id=<cleared>,type=0,code=0),zone=<cleared>,mark=<cleared>,labels=0x401020400000000
>
+tcp,orig=(src=172.16.0.1,dst=10.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=10.0.0.2,dst=172.16.0.1,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=<cleared>,labels=0x401020400000000,protoinfo=(state=<cleared>)
>  ])
>
>  # Ensure datapaths show conntrack states as expected
> @@ -5981,6 +5978,36 @@ AT_CHECK([ovs-appctl dpctl/dump-flows | grep
'ct_state(-new+est+rpl+trk).*ct_lab
>  1
>  ])
>
> +# Flush conntrack entries for easier output parsing of next test.
> +AT_CHECK([ovs-appctl dpctl/flush-conntrack])
> +
> +# Change bob1 L2 address anche check the reply is properly updated.
> +ovn-nbctl set Logical_Router_Port R2_ext mac='"00:00:10:01:02:04"'
> +ovn-nbctl set Logical_Switch_Port r2-ext \
> +     type=router options:router-port=R2_ext
addresses='"00:00:10:01:02:04"'
> +
> +NS_CHECK_EXEC([bob1], [nc -z 10.0.0.2 80], [0])
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep
'ct_state(+new-est-rpl+trk).*ct(.*label=0x1001020400000000/.*)' -c], [0],
[dnl
> +1
> +])
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep
'ct_state(-new+est+rpl+trk).*ct_label(0x1001020400000000)' -c], [0], [dnl
> +1
> +])
> +
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep 0x1001020400000000 |
FORMAT_CT(172.16.0.1) | \
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> +sed -e 's/mark=[[0-9]]*/mark=<cleared>/'], [0], [dnl
>
+tcp,orig=(src=172.16.0.1,dst=10.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=10.0.0.2,dst=172.16.0.1,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=<cleared>,labels=0x1001020400000000,protoinfo=(state=<cleared>)
> +])
> +
> +# Check entries in table 76 and 77 expires w/o traffic
> +OVS_WAIT_UNTIL([
> +test $(ovs-ofctl dump-flows br-int | grep -c 'table=76, n_packets') -eq 0
> +])
> +OVS_WAIT_UNTIL([
> +test $(ovs-ofctl dump-flows br-int | grep -c 'table=77, n_packets') -eq 0
> +])
> +
>  ovs-ofctl dump-flows br-int
>
>  OVS_APP_EXIT_AND_WAIT([ovn-controller])
> @@ -6122,11 +6149,8 @@ ovn-nbctl --wait=hv sync
>
>  on_exit 'ovs-ofctl dump-flows br-int'
>
> -# 'bob1' should be able to ping 'alice1' directly.
> -NS_CHECK_EXEC([bob1], [ping -q -c 20 -i 0.3 -w 15 fd01::2 |
FORMAT_PING], \
> -[0], [dnl
> -20 packets transmitted, 20 received, 0% packet loss, time 0ms
> -])
> +NETNS_DAEMONIZE([alice1], [nc -6 -l -k 80], [alice1.pid])
> +NS_CHECK_EXEC([bob1], [nc -6 -z fd01::2 80], [0])
>
>  # Ensure datapaths show conntrack states as expected
>  # Like with conntrack entries, we shouldn't try to predict
> @@ -6145,7 +6169,38 @@ AT_CHECK([ovs-appctl dpctl/dump-flows | grep
'ct_state(-new+est+rpl+trk).*ct_lab
>  AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd01::2) | \
>  sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
>  sed -e 's/mark=[[0-9]]*/mark=<cleared>/'], [0], [dnl
>
-icmpv6,orig=(src=fd07::1,dst=fd01::2,id=<cleared>,type=128,code=0),reply=(src=fd01::2,dst=fd07::1,id=<cleared>,type=129,code=0),zone=<cleared>,mark=<cleared>,labels=0x401020400000000
>
+tcp,orig=(src=fd07::1,dst=fd01::2,sport=<cleared>,dport=<cleared>),reply=(src=fd01::2,dst=fd07::1,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=<cleared>,labels=0x401020400000000,protoinfo=(state=<cleared>)
> +])
> +
> +# Flush conntrack entries for easier output parsing of next test.
> +AT_CHECK([ovs-appctl dpctl/flush-conntrack])
> +
> +# Change bob1 L2 address anche check the reply is properly updated.
> +ovn-nbctl set Logical_Router_Port R2_ext mac='"00:00:10:01:02:04"'
> +ovn-nbctl set Logical_Switch_Port r2-ext \
> +     type=router options:router-port=R2_ext
addresses='"00:00:10:01:02:04"'
> +
> +NS_CHECK_EXEC([bob1], [nc -6 -z fd01::2 80], [0])
> +
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep
'ct_state(+new-est-rpl+trk).*ct(.*label=0x1001020400000000/.*)' -c], [0],
[dnl
> +1
> +])
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep
'ct_state(-new+est+rpl+trk).*ct_label(0x1001020400000000)' -c], [0], [dnl
> +1
> +])
> +
> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep 0x1001020400000000 |
FORMAT_CT(fd01::2) | \
> +sed -e 's/zone=[[0-9]]*/zone=<cleared>/' |
> +sed -e 's/mark=[[0-9]]*/mark=<cleared>/'], [0], [dnl
>
+tcp,orig=(src=fd07::1,dst=fd01::2,sport=<cleared>,dport=<cleared>),reply=(src=fd01::2,dst=fd07::1,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=<cleared>,labels=0x1001020400000000,protoinfo=(state=<cleared>)
> +])
> +
> +# Check entries in table 76 and 77 expires w/o traffic
> +OVS_WAIT_UNTIL([
> +test $(ovs-ofctl dump-flows br-int | grep -c 'table=76, n_packets') -eq 0
> +])
> +OVS_WAIT_UNTIL([
> +test $(ovs-ofctl dump-flows br-int | grep -c 'table=77, n_packets') -eq 0
>  ])
>
>  ovs-ofctl dump-flows br-int
> --
> 2.36.1
>
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to