On Tue, Jun 9, 2026 at 7:54 AM Eelco Chaudron <[email protected]> wrote:

>
>
> On 9 Jun 2026, at 4:48, Numan Siddique wrote:
>
> > On Sat, Jun 6, 2026 at 1:26 AM Numan Siddique <[email protected]> wrote:
> >
> >>
> >>
> >> On Fri, Jun 5, 2026 at 10:16 AM Eelco Chaudron <[email protected]>
> >> wrote:
> >>
> >>>
> >>>
> >>> On 2 Jun 2026, at 22:50, [email protected] wrote:
> >>>
> >>>> From: Numan Siddique <[email protected]>
> >>>>
> >>>> Hello,
> >>>>
> >>>> Below is a side-by-side trace of the same OVN-driven datapath
> pipeline,
> >>>> In our prod deployment we are seeing intermittent offload issues. All
> >>>> the datapath flows of a chain are getting offloaded except the last
> one.
> >>>> It is installed in the kernel dp because of which it kills the
> >>> performance.
> >>>> If I run the command - ovs-appctl dpctl/del-flows,  the problematic
> >>>> flow gets offloaded.
> >>>>
> >>>> The issue again can be reproduced if we run a script to the delete
> >>>> the dp flows in a loop with a sleep of 5 seconds.  Generally the issue
> >>>> gets surfaced after 5-6 del flows.
> >>>>
> >>>> Below are the datapath flows when the issue is seen
> >>>>
> >>>> The traffic is destined to the public IP(s) (there are 2 public ips in
> >>>> our setup) of the VM and enters the compute node PF and via the br-ex
> >>>> to the OVN pipeline.
> >>>>
> >>>>
> >>>
> -------------------------------------------------------------------------------
> >>>> 1. BEFORE FLUSH
> >>>>
> >>>
> -------------------------------------------------------------------------------
> >>>>
> >>>> Two upstream branches merge into the stranded chain `0x314610`.  Each
> >>>> branch is exactly two TC-offloaded stages followed by the umbrella
> that
> >>>> is stuck in dp:ovs.
> >>>>
> >>>>    +------------------------------+
> >>> +------------------------------+
> >>>>    | recirc_id(0)        BRANCH A |      | recirc_id(0)        BRANCH
> B
> >>> |
> >>>>    | ufid:b81b9ab4                |      | ufid:29ac3fbf
> >>> |
> >>>>    | in_port=enp210s0f0np0  (PF)  |      | in_port=enp210s0f0np0  (PF)
> >>> |
> >>>>    | eth_type=0x8100, VLAN 120    |      | eth_type=0x8100, VLAN 26
> >>>  |
> >>>>    | eth(src=b0:cf:0e:b1:31:ff,   |      | eth(src=b0:cf:0e:b1:31:ff,
> >>>  |
> >>>>    |     dst=ae:ad:c9:2a:9d:0f)   |      |     dst=ae:ad:c9:2a:9d:0f)
> >>>  |
> >>>>    | ipv4(dst=AA.BB.CC.DD,        |      | ipv4(dst=XX.YY.ZZ.AA,
> >>> |
> >>>>    |      src=32.0.0.0/224.0.0.0, |      |      src=8.0.0.0/248.0.0.0
> ,
> >>> |
> >>>>    |      ttl=119)                |      |      ttl=62)
> >>>  |
> >>>>    | ct_state(0/0x2b)             |      | ct_state(0/0x2b)
> >>>  |
> >>>>    | ct_mark(0/0x2)               |      | ct_mark(0/0x2)
> >>>  |
> >>>>    |                              |      |
> >>> |
> >>>>    | actions:                     |      | actions:
> >>>  |
> >>>>    |   pop_vlan,                  |      |   pop_vlan,
> >>> |
> >>>>    |   ct(zone=6,nat),            |      |   ct(zone=5,nat),
> >>> |
> >>>>    |   recirc(0x320213)           |      |   recirc(0x321f17)
> >>>  |
> >>>>    |                              |      |
> >>> |
> >>>>    | pkts=565   bytes=44636       |      | pkts=26,867,289
> >>> |
> >>>>    | used=1.640s                  |      | bytes=241,881,487,034
> >>> |
> >>>>    | offloaded:yes, dp:tc         |      | used=0.620s
> >>> |
> >>>>    +------------------------------+      | offloaded:yes, dp:tc
> >>>  |
> >>>>                   |
> >>> +------------------------------+
> >>>>                   | post-DNAT in zone 6                  |
> >>>>                   v                                     | post-DNAT in
> >>> zone 5
> >>>>    +------------------------------+                     v
> >>>>    | recirc_id(0x320213)          |
> >>> +------------------------------+
> >>>>    | ufid:3413a279                |      | recirc_id(0x321f17)
> >>> |
> >>>>    | in_port=enp210s0f0np0  (PF)  |      | ufid:9f638cd3
> >>> |
> >>>>    | ct_state(0x2a/0x3e)          |      | in_port=enp210s0f0np0  (PF)
> >>> |
> >>>>    | ct_mark(0/0x43)              |      | ct_state(0x2a/0x3e)
> >>> |
> >>>>    | eth(src=b0:cf:0e:b1:31:ff,   |      | ct_mark(0/0x43)
> >>> |
> >>>>    |     dst=ae:ad:c9:2a:9d:0f)   |      | eth(src=b0:cf:0e:b1:31:ff,
> >>>  |
> >>>>    | ipv4(src=0.0.0.0/128.0.0.0,  |      |     dst=ae:ad:c9:2a:9d:0f)
> >>>  |
> >>>>    |      dst=172.27.61.7,        |      | ipv4(src=8.0.0.0/248.0.0.0
> ,
> >>> |
> >>>>    |      proto=6, ttl=119)       |      |      dst=172.27.61.7,
> >>> |
> >>>>    |                              |      |      proto=6, ttl=62)
> >>> |
> >>>>    | actions:                     |      |
> >>> |
> >>>>    |   ct_clear,                  |      | actions:
> >>>  |
> >>>>    |   set(eth src=               |      |   ct_clear,
> >>> |
> >>>>    |        1a:83:58:7b:a8:ed),   |      |   set(eth src=
> >>>  |
> >>>>    |   set(ipv4 ttl=118),         |      |        1a:83:58:7b:a8:ed),
> >>>  |
> >>>>    |   ct(zone=11,nat),           |      |   set(ipv4 ttl=60),
> >>> |
> >>>>    |   recirc(0x314610)           |      |   ct(zone=11,nat),
> >>>  |
> >>>>    |                              |      |   recirc(0x314610)
> >>>  |
> >>>>    | pkts=565   bytes=44636       |      |
> >>> |
> >>>>    | used=1.640s                  |      | pkts=26,867,289
> >>> |
> >>>>    | offloaded:yes, dp:tc         |      | bytes=241,881,487,034
> >>> |
> >>>>    +------------------------------+      | used=0.620s
> >>> |
> >>>>                   |                      | offloaded:yes, dp:tc
> >>>  |
> >>>>                   |
> >>> +------------------------------+
> >>>>                   |                                     |
> >>>>                   +--------------+        +-------------+
> >>>>                                  |        |
> >>>>                                  v        v
> >>>>                   +--------------------------------------+
> >>>>                   | recirc_id(0x314610)        STAGE 2   |
> >>>>                   | ufid:1ee350bf                        |
> >>>>                   | in_port=enp210s0f0np0   (PF)         |
> >>>>                   | ct_state(0x2a/0x3f)  <-- mask 0x3f   |
> >>>>                   | ct_mark(0/0x41)                      |
> >>>>                   | eth(src=*, dst=ae:ad:c9:2a:9d:0f)    |
> >>>>                   | ipv4(src=*, dst=172.27.61.7,         |
> >>>>                   |      proto=0/0, ttl=0/0)             |
> >>>>                   |                                      |
> >>>>                   | actions: enp210s0f0_1   (VF)         |
> >>>>                   |                                      |
> >>>>                   | pkts=41,192,879                      |
> >>>>                   | bytes=2,502,536,363,732              |
> >>>>                   | used=0.020s, flags=SFPR.             |
> >>>>                   |                                      |
> >>>>                   | dp:ovs   <-- STRANDED, NOT OFFLOADED |
> >>>>                   +--------------------------------------+
> >>>>
> >>>>
> >>>>
> >>>
> -------------------------------------------------------------------------------
> >>>> 2. AFTER FLUSH (ovs-appctl dpctl/del-flows)
> >>>>
> >>>
> -------------------------------------------------------------------------------
> >>>>
> >>>> After `ovs-appctl dpctl/del-flows` everything is re-installed in the
> >>>> natural pipeline order, so the chain check passes for every stage.
> >>>> The megaflow masks have not been re-aggregated yet, so we see a
> >>>> "fanned out" pipeline:
> >>>>
> >>>>    +----------------+    +----------------+    +----------------+
> >>>>    | recirc_id(0)   |    | recirc_id(0)   |    | (parent for    |
> >>>>    |    BRANCH A    |    |    BRANCH B    |    |  chain         |
> >>>>    | 5 sub-megaflows|    | 1 megaflow     |    |  0x3229d9 had  |
> >>>>    | vlan 120       |    | vlan 26        |    |  aged out at   |
> >>>>    | zone 6 NAT     |    | zone 5 NAT     |    |  dump time --  |
> >>>>    |                |    |                |    |  the two       |
> >>>>    | dst=           |    | dst=           |    |  stage-1       |
> >>>>    |  AA.BB.CC.DD   |    |  XX.YY.ZZ.AA   |    |  flows below   |
> >>>>    | by src/ttl:    |    | src=8.0.0.0/5  |    |  had pkts=0)   |
> >>>>    |  104/5 ttl=56  |    |  ttl=62        |    |                |
> >>>>    |  32/3  ttl=119 |    |                |    |  ufid:1b6d210e |
> >>>>    |  124/7 ttl=234 |    | pkts=14,326,765|    |  -- not        |
> >>>>    |  32/3  ttl=122 |    | bytes=128.7 GB |    |     captured   |
> >>>>    |  192/3 ttl=243 |    | used=0.660s    |    |     for branch |
> >>>>    |                |    |                |    |     C          |
> >>>>    | actions:       |    | actions:       |    |                |
> >>>>    |  pop_vlan,     |    |  pop_vlan,     |    |                |
> >>>>    |  ct(zone=6,    |    |  ct(zone=5,    |    |                |
> >>>>    |     nat),      |    |     nat),      |    |                |
> >>>>    |  recirc(       |    |  recirc(       |    |                |
> >>>>    |   0x320213)    |    |   0x321f17)    |    |                |
> >>>>    | offloaded:yes  |    | offloaded:yes  |    |                |
> >>>>    | dp:tc          |    | dp:tc          |    |                |
> >>>>    +----------------+    +----------------+    +----------------+
> >>>>             |                    |                       :
> >>>>             v                    v                       v
> >>>>    +----------------+    +----------------+    +----------------+
> >>>>    | recirc_id      |    | recirc_id      |    | recirc_id      |
> >>>>    |  (0x320213)    |    |  (0x321f17)    |    |  (0x3229d9)    |
> >>>>    |                |    |                |    |                |
> >>>>    | 3 sub-megaflows|    | 1 megaflow     |    | 2 megaflows    |
> >>>>    | ct_state(      |    | ct_state(      |    | ct_state(      |
> >>>>    |  0x2a/0x3e)    |    |  0x2a/0x3e)    |    |  0x21/0x3f)    |
> >>>>    | (+est+rpl+trk) |    | (+est+rpl+trk) |    | (+new+trk)     |
> >>>>    |                |    |                |    |                |
> >>>>    | ttl 119 -> 118 |    | ttl 62  -> 60  |    | ttl 234 -> 233 |
> >>>>    | ttl 56  -> 55  |    |                |    | ttl 243 -> 242 |
> >>>>    | ttl 122 -> 121 |    | pkts=14,326,690|    |                |
> >>>>    |                |    | bytes=128.7 GB |    | pkts=0  (new   |
> >>>>    | pkts=68+9+1=78 |    | used=0.660s    |    |   conn attempts|
> >>>>    |                |    |                |    |   in flight)   |
> >>>>    | actions:       |    | actions:       |    |                |
> >>>>    |  ct_clear,     |    |  ct_clear,     |    | actions:       |
> >>>>    |  set(eth src=  |    |  set(eth src=  |    |  (same shape   |
> >>>>    |   1a:83:..),   |    |   1a:83:..),   |    |   as branch    |
> >>>>    |  set(ipv4 ttl  |    |  set(ipv4 ttl  |    |   A/B stage 1) |
> >>>>    |   -1),         |    |   -1),         |    |  recirc(       |
> >>>>    |  ct(zone=11,   |    |  ct(zone=11,   |    |   0x314610)    |
> >>>>    |   nat),        |    |   nat),        |    |                |
> >>>>    |  recirc(       |    |  recirc(       |    | offloaded:yes  |
> >>>>    |   0x314610)    |    |   0x314610)    |    | dp:tc          |
> >>>>    | offloaded:yes  |    | offloaded:yes  |    |                |
> >>>>    | dp:tc          |    | dp:tc          |    |                |
> >>>>    +----------------+    +----------------+    +----------------+
> >>>>             |                    |                       |
> >>>>             +--------+           |          +------------+
> >>>>                      |           |          |
> >>>>                      v           v          v
> >>>>             +-----------------------------------------+
> >>>>             | recirc_id(0x314610)     STAGE 2         |
> >>>>             |                                         |
> >>>>             | Three flows now (all offloaded:yes,     |
> >>>>             | dp:tc):                                 |
> >>>>             |                                         |
> >>>>             | 1. ufid:c51ef89d   <-- the umbrella     |
> >>>>             |    ct_state(0x2a/0x3e)  <-- mask 0x3e   |
> >>>>             |    ct_mark(0/0x41)                      |
> >>>>             |    eth(src=*, dst=ae:ad:c9:2a:9d:0f)    |
> >>>>             |    ipv4(dst=172.27.61.7)                |
> >>>>             |    actions: enp210s0f0_1   (VF)         |
> >>>>             |    pkts=14,326,720                      |
> >>>>             |    bytes=128,674,265,194                |
> >>>>             |    used=0.660s                          |
> >>>>             |                                         |
> >>>>             | 2. ufid:d6f6c8c3   (DROP, new conn ACL) |
> >>>>             |    ct_state(0x21/0x3f)  (+new+trk)      |
> >>>>             |    eth(src=1a:83:58:7b:a8:ed,           |
> >>>>             |        dst=ae:ad:00:00:00:00/           |
> >>>>             |            ff:ff:00:00:00:00)           |
> >>>>             |    dst=172.27.60.0/23,                  |
> >>>>             |    tcp ports w/ submask                 |
> >>>>             |    actions: drop                        |
> >>>>             |    pkts=0                               |
> >>>>             |                                         |
> >>>>             | 3. ufid:0b52d8bd   (DROP, new conn ACL) |
> >>>>             |    same shape, different tcp submask    |
> >>>>             |    actions: drop                        |
> >>>>             |    pkts=0                               |
> >>>>             +-----------------------------------------+
> >>>>
> >>>>
> >>>> (Note:  The above ascii graph is generated by Claude)
> >>>>
> >>>>
> >>>> In the OVS logs we also see the below msg (
> >>>
> https://github.com/openvswitch/ovs/blob/main/lib/dpif-offload-tc-netdev.c#L2363
> >>> )
> >>>>
> >>>> ```
> >>>> 2026-06-01T21:15:33.774Z|10763|netdev_offload_tc(handler18)|DBG|
> >>>>   match for chain 3229200 failed due to non-existing goto chain action
> >>>> ```
> >>>>
> >>>> There seems to be a race condition during the ccmap 'used_chains'.
> >>>>
> >>>> As per Claude, the issue seems to be introduced in the commit :
> >>>> `273a4fce951a`** — `netdev-offload-tc: Only install recirc flows if
> the
> >>> parent is present.`
> >>>> and there is a possibility of a race window in the function
> >>> netdev_tc_flow_put()
> >>>> between
> >>>
> https://github.com/openvswitch/ovs/blob/main/lib/dpif-offload-tc-netdev.c#L2695
> >>>> and
> >>>
> https://github.com/openvswitch/ovs/blob/main/lib/dpif-offload-tc-netdev.c#L2730
> >>>>
> >>>> @Eelco @Ilya - Do you have any idea on what could be going on here ?
> >>>
> >>> Hi Numan,
> >>>
> >>> Sorry for the late response, but this message ended up in my
> >>> spam box which I was cleaning up :( Put Ilya also on the TO
> >>> line, maybe it ended up in his spam also.
> >>>
> >>> I'm on PTO on Monday, so will try to take a look at this later
> >>> in the week.
> >>>
> >>> //Eelco
> >>>
> >>
> >>
> >> Hi Eelco,
> >>
> >> Thanks for the reply.
> >>
> >> Below are some of the details I found during my investigation.
> >>
> >> OVN Logical topology
> >> ----
> >>
> >> VM1 -> VPC Logical switch (with ACLs) ->  Logical Router (NATs
> configured)
> >> ->
> >>    Public logical switch with localnet port ->  br-int <->  patch ports
> ->
> >> br-ex -> Physical NIC
> >>
> >> In this case, there is an iperf session between the VM1 and outside
> iperf
> >> server.
> >>
> >> When the reply traffic from iperf server to the VM 1 enters the host via
> >> the physical NIC,
> >> before the packet is delivered to the VM, there are in total 3
> >> recirculations
> >> (stage 0, 1 and 2) because of NAT in the logical router pipeline and
> ACLs
> >> in the logical switch
> >> pipeline -> recirc 0, recirc 4 and recirc 5 (for example).
> >>
> >> When the datapath flow for recirc 0 is offloaded, recirc 4 is saved in
> the
> >> "used_chains"
> >> (in tc_netdev_flow_put()) and when the dp flow with recirc 4 is
> offloaded,
> >> recirc 5 is saved
> >> in the "used_chains".
> >>
> >>
> >> What I noticed is that for some of the packets from the server to the
> VM,
> >> tcp.flags has push/ack set
> >> and for some only ack set.
> >>
> >> And ovs-vswitchd generates different ufid in both the cases, but after
> the
> >> flow translation
> >> same datapath flow is generated.
> >>
> >> Suppose if I delete the dp flows when iperf is running (ovs-appctl
> >> dpctl/del-flows),
> >> a lot of packets get upcalled.  What I noticed is one set of reply
> packets
> >> from server
> >> has tcp.flags == push/ack and another set with just tcp.flags == ack.
> >>
> >> When the handler thread does the flow translation for packets with
> >> [recirc=5, tcp.flags == push/ack]
> >> it generates ufid 'A' and offloads the flow if '5' is present in
> >> 'used_chains'
> >>
> >> And when the handler thread does the flow translation for packets with
> >> [recirc=5, tcp.flags == ack] it generates ufid 'B' and when it tries to
> >> offload,  tc returns EEXISTS because both ufid 'A' and 'B' generates
> >> the same datapath flow (as the datapath flow doesn't have matches for
> tcp
> >> flags).
> >>
> >>
> >> And I see the error message 'match for chain 5 failed due to
> non-existing
> >> goto chain action'
> >> if the stage 1 flow (with recirc 4) was deleted.
> >>
> >> I was able to fix this issue by hacking ovn-northd and adding the below
> >> logical flow
> >>
> >> table=6 (ls_out_acl_eval    ), priority=65533, match=(ct.est && !ct.rel
> &&
> >> ct.rpl && ct_mark.blocked == 0 && tcp && (tcp.flags == 24 || tcp.flags
> ==
> >> 16)), action=(reg8[21] = ct_label.nf; reg8[16] = 1; next;)
> >> table=6 (ls_out_acl_eval    ), priority=65532, match=(ct.est && !ct.rel
> &&
> >> ct.rpl && ct_mark.blocked == 0), action=(reg8[21] = ct_label.nf;
> reg8[16]
> >> = 1; next;)
> >>
> >> Priority 65532 is the existing logical flow which northd adds to allow
> all
> >> the established reply packets.
> >>
> >> Since priority 65533 flow matches on tcp.flags, now two distinct
> datapath
> >> flows are added and I do not see this race issue even after deleting the
> >> dpctl flows in a loop.  (I added a sleep of 8 seconds between the
> deletes).
> >>
> >> Without the hack in northd,  I'm able to reproduce the issue 100% of the
> >> time within the first 3 dp flow deletes in a fake-multinode environment.
> >>
> >> When the issue is seen, the first 2 dp flows (recirc 0 and 4) are
> >> offloaded to tc and the last one is not.
> >>
> >>
> >> When 2 different ufids result in the same dp flow, perhaps the
> >> tc_netdev_flow_put() should store both ufids in the ufid_to_tc_mappings
> ?
> >>
> >> Let me know if you want me to provide a script to reproduce using
> >> ovn-fake-multinode.
> >>
> >
> > Please ignore my hack theory.  I deployed a simple fake multi node
> > environment and started the iperf between the fake vm "sw01p1" in
> > ovn-chassis-1
> > and the "ovnfake-ext1" namespace on the host.  And I was able to
> reproduce
> > the issue even with the hack and delete the dp flows.
> >
> > You can run the command - watch -n1 'ovs-appctl dpctl/dump-flows -m |
> grep
> > "in_port(eth2"' in ovn-chassis-1 and notice that the dp flow
> > changes from "dp:tc" to "dp:ovs".
> >
> >
> > Below is my theory on why offload fails in our prod deployment
> >
> > T1.  Packet P_A arrives (upcalled), hashed to ufid:A.
> >        xlate produces megaflow M1 with action set ending in
> >        recirc(R1).
> >        R1 = recirc_alloc_id_ctx(frozen-alpha).
> >        tc_netdev_flow_put(M1) fails (any reason -- unsupported
> >        action, EOPNOTSUPP from a probe, mlx5 driver capability
> >        mismatch, etc.).
> >        M1 lands in dp:ovs via dpif_netlink fallback.
> >        ccmap_inc(used_chains, R1) NEVER fires.
> >
> >   T2.  P_A continues through openvswitch.ko, internal recirc to
> >        R1, miss, upcall.
> >        Hashed to ufid:B.
> >        xlate produces megaflow M2 matching on recirc_id=R1, with
> >        some output action (e.g. mirred to a port).
> >        tc_netdev_flow_put(M2):
> >          chain check: ccmap_find(used_chains, R1) == 0  ->  BAIL
> >          return EOPNOTSUPP.
> >        M2 lands in dp:ovs.
> >
> >   T3.  A different packet P_C arrives, hashed to ufid:C.
> >        xlate produces megaflow M3 with a DIFFERENT match key but
> >        arrives at the same OF freeze point as M1's translation did.
> >        Same frozen_state -> same R1.
> >        M3 install SUCCEEDS in TC.
> >        ccmap_inc(used_chains, R1)  ->  count = 1.
> >
> >   T4.  P_C continues, TC recircs to R1.
> >        TC chain R1 is empty (M2 is in dp:ovs, not TC).
> >        Packet falls to openvswitch.ko at recirc_id=R1.
> >        M2 matches; executes in SW.
> >
> > Net result: M3 (upstream sibling) is in dp:tc, M2 (downstream) is
> > permanently in dp:ovs.  P_C traffic does TC-fast-path on the
> > upstream stage but kernel-SW on the downstream stage, every packet.
> >
> > Does this theory make sense ?
>
> Hi Numan,
>
> I think you're running into a known limitation, but first I want to mention
> that you should not use dpctl/del-flows in production, as it will mess up
> OVS's internal state.
>

Thanks Eelco for looking into it.

Yes.  In prod we see the issue without flushing the flows.  I could
reproduce
locally and faster by flushing the dp flows.



>
> Below is a test case that replicates the problem, a known issue. It's a
> quick and dirty attempt to show you the problem.
>
>   sudo make -j 128 check-offloads \
>     TESTSUITEFLAGS="-k 'split recirc rules kernel vs offload' -v"
>
> I do not have a quick fix for this, as it requires some kind of signaling
> across the boundaries from ofproto, to dpif, and to hardware offload (and
> back).
>
> I'll try to come up with something quick and dirty later today or this
> week,
> so you can see if it really is the same problem you are facing.
>

Thanks

Numan


>
> Cheers,
>
> Eelco
>
>
> diff --git a/tests/fuzz-regression-list.at b/tests/fuzz-regression-list.at
> old mode 100644
> new mode 100755
> diff --git a/tests/system-offloads-traffic.at b/tests/
> system-offloads-traffic.at
> index 13a8054a4..6cfb9f07c 100644
> --- a/tests/system-offloads-traffic.at
> +++ b/tests/system-offloads-traffic.at
> @@ -1103,7 +1103,6 @@ table=1,priority=200,ip,actions=group:1
>  table=2,ip,actions=ovs-p2
>  table=3,ip,actions=ovs-p1
>  ])
> -AT_CHECK([ovs-ofctl add-groups br0 groups.txt])
>  AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
>
>  NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.1 -W 2 10.0.0.2 |
> FORMAT_PING], [0], [dnl
> @@ -1200,6 +1199,76 @@ OVS_WAIT_WHILE(
>  OVS_TRAFFIC_VSWITCHD_STOP
>  AT_CLEANUP
>
> +AT_SETUP([offloads - split recirc rules kernel vs offload])
> +OVS_TRAFFIC_VSWITCHD_START([], [], [-- set Open_vSwitch .
> other_config:hw-offload=true])
> +
> +ADD_NAMESPACES(at_ns0, at_ns1)
> +
> +ADD_VETH(p1, at_ns0, br0, "10.0.0.1/24")
> +ADD_VETH(p2, at_ns1, br0, "10.0.0.2/24")
> +
> +dnl Two source IPs on the same veth guarantee the same in_port and
> therefore
> +dnl the same recirc ID R1 for the second datapath flow.
> +NS_CHECK_EXEC([at_ns0], [ip addr add 10.0.0.3/24 dev p1])
> +
> +AT_CHECK([ovs-vsctl -- set interface ovs-p1 ofport_request=1 \
> +                    -- set interface ovs-p2 ofport_request=2])
> +
> +AT_CHECK([ovs-appctl vlog/set dpif_offload_tc_netdev:dbg])
> +
> +dnl controller() is not TC-offloadable, so both datapath flows land in
> dp:ovs.
> +AT_DATA([flows.txt], [dnl
> +table=0,arp,actions=NORMAL
>
> +table=0,priority=100,in_port=ovs-p1,ip,nw_dst=10.0.0.2,actions=controller(),ct(commit,table=1)
> +table=0,priority=100,in_port=ovs-p2,ip,actions=ovs-p1
> +table=1,ip,actions=ovs-p2
> +])
> +AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
> +
> +NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 10.0.0.2 |
> FORMAT_PING], [0], [dnl
> +3 packets transmitted, 3 received, 0% packet loss, time 0ms
> +])
> +AT_CHECK([ovs-appctl revalidator/wait])
> +
> +AT_CHECK([grep -q "match for chain .* failed due to non-existing goto
> chain action" \
> +          ovs-vswitchd.log])
> +AT_CHECK([ovs-appctl dpctl/dump-flows --names type=ovs \
> +          filter='in_port(ovs-p1),ipv4' | grep -c "in_port(ovs-p1)"],
> [0], [2
> +])
> +AT_CHECK([ovs-appctl dpctl/dump-flows --names type=tc \
> +          filter='in_port(ovs-p1),ipv4'], [0], [dnl
> +])
> +
> +dnl Replace the rule with plain ct (TC-offloadable).  Traffic from
> 10.0.0.3
> +dnl offloads its first datapath flow to dp:tc, which registers the recirc
> ID.
> +dnl The second datapath flow for 10.0.0.1 shares the same recirc ID but
> +dnl remains stranded in dp:ovs.
> +AT_CHECK([ovs-ofctl del-flows br0
> "table=0,in_port=ovs-p1,ip,nw_dst=10.0.0.2"])
> +AT_DATA([flows2.txt], [dnl
>
> +table=0,priority=100,in_port=ovs-p1,ip,nw_dst=10.0.0.2,actions=ct(commit,table=1)
> +])
> +AT_CHECK([ovs-ofctl add-flows br0 flows2.txt])
> +
> +NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 -I 10.0.0.3 10.0.0.2 |
> FORMAT_PING], [0], [dnl
> +3 packets transmitted, 3 received, 0% packet loss, time 0ms
> +])
> +AT_CHECK([ovs-appctl revalidator/wait])
> +
> +dnl Dump all datapath flows for debugging to show the split between dp:tc
> and dp:ovs.
> +AT_CHECK([ovs-appctl dpctl/dump-flows --names -m
> filter='in_port(ovs-p1),ipv4'],
> +         [0], [ignore])
> +
> +AT_CHECK([ovs-appctl dpctl/dump-flows --names type=tc \
> +          filter='in_port(ovs-p1),ipv4' | grep -c "in_port(ovs-p1)"],
> [0], [2
> +])
> +AT_CHECK([ovs-appctl dpctl/dump-flows --names type=ovs \
> +          filter='in_port(ovs-p1),ipv4' | grep "actions:ovs-p2"], [0],
> [ignore])
> +AT_CHECK([ovs-appctl dpctl/dump-flows --names type=tc \
> +          filter='in_port(ovs-p1),ipv4' | grep "actions:ovs-p2"], [1])
> +
> +OVS_TRAFFIC_VSWITCHD_STOP
> +AT_CLEANUP
> +
>  AT_SETUP([offloads - ovs-appctl dpif/offload/show - offloads enabled])
>  AT_KEYWORDS([dpif-offload])
>  OVS_TRAFFIC_VSWITCHD_START([], [],
>
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to