Skip to content

Commit 4cd8a06

Browse files
naveen-yerramnenidceara
authored andcommitted
northd: Drop post-NF flood copies causing MAC flaps.
A Network Function (NF) in inline mode redirects matched traffic through a service VM. When the redirected traffic is IP unknown-unicast (destination MAC not yet in the FDB), the packet coming back from the NF is re-flooded by the switch, because the destination MAC is still unknown. That re-flood produces a copy on the same port the packet originally arrived on, causing MAC flaps and potential L2 loops. Following are the example packet flows. Example 1, VLAN switch (MAC flap): Topology VM1, VM2 and the NF are on the same logical switch (LS), which is VLAN-backed (localnet port on every node). VM1 is on N1, VM2 on N2 (its port has "unknown" in addresses and a to-lport ACL that redirects to the inline NF on N3). Flow 1. VM1 sends pkt to dst MAC X (not in FDB). 2. The LS floods the pkt; on N1 the copy exits the localnet port and the TOR floods it to N2. 3. On N2 the pkt ingresses on localnet; the LS floods it and the copy reaches VM2 (unknown-addr). 4. The ACL redirects the pkt to the NF on N3; the NF returns it to N2. 5. X is still not in the FDB, so the LS floods again; on N2 one copy exits the localnet port. Result The TOR now sees VM1's source MAC on N2's port, but it had just learned VM1's MAC on N1's port, so the MAC flaps on the TOR. Example 2, VLAN switch with two protected VMs (loop): Topology As above, plus VM3 (on N3, same LS) also has "unknown" in addresses and is also NF-protected. Flow 1-5 as above; in parallel, the original flood also reaches N3 via the TOR, where it is redirected to N3's NF, returns, and the LS re-floods it out N3's localnet port. 6. N3's re-flood reaches N2 via the TOR; the LS floods it on N2, the copy hits VM2 (unknown-addr), is redirected to the NF, and re-floods out N2's localnet port. 7. That re-flood reaches N3 via the TOR; the LS floods it on N3, the copy hits VM3 (also unknown-addr), is redirected to the NF, re-floods out localnet, ... Result The pkt keeps bouncing between N2 and N3 via the TOR, i.e. an L2 loop, on top of continuous MAC flaps. The loop persists as long as X stays unknown. Example 3, overlay switch (copy reflected to inport): Topology VM1, VM2 and the NF are on the same LS and all on N1. VM1 and VM2 both have "unknown" in addresses; VM2's to-lport ACL redirects to the inline NF. Flow 1. VM1 sends pkt to dst MAC X (not in FDB). 2. The LS floods to MC_UNKNOWN members on N1; one copy goes to VM2. 3. VM2's ACL redirects its copy to the NF; the NF returns it to N1. 4. X is still not in the FDB, so the LS floods to MC_UNKNOWN again; one copy is headed back out VM1's own port. Result VM1 receives a copy of the packet it just sent (reflected to the inport). Fix: Use the nf_learn_orig_inport() / nf_lookup_orig_inport() actions from the previous commit to remember the original ingress port and drop the copy if it is about to be sent back out of that port. - In the NF redirect stage (ls_in_nf for a from-lport ACL, ls_out_nf for a to-lport ACL), existing priority-99 redirect flows are updated to learn the original ingress port (nf_learn_orig_inport()) before redirecting unicast IP packets to the NF. - Priority 50 (overlay switches only, in ls_in_nf): learn on the inport's ingress node when the ACL did not redirect the packet (REGBIT_NF_ENABLED == 0), so the learn stays co-located with the lookup even when the redirecting port and the inport live on different nodes. VLAN-backed switches do not need this: the post-NF packet is always sent back to the inport's node. - On the post-NF return path, run REGBIT_NF_LOOKUP_HIT = nf_lookup_orig_inport() on both NF ports. A priority-115 flow in ls_out_pre_acl runs the lookup on input_port and skips already-traversed egress stages. A priority-2 flow in ls_out_nf runs the lookup on output_port for packets redirected from the ingress pipeline (for example, a from-lport request that is re-flooded after NF processing and re-enters egress). - A new priority-110 flow in ls_out_check_port_sec drops packets with REGBIT_NF_LOOKUP_HIT == 1, i.e. the copies about to be sent back out of the port they originally arrived on. All new flows are gated on the switch having an inline NF group on an ACL. Acked-by: Aditya Mehakare <aditya.mehakare@nutanix.com> Fixes: 8e2d6fa ("northd, tests: Network Function insertion logical flow programming.") CC: Sragdhara Datta Chaudhuri <sragdha.chaudhu@nutanix.com> Assisted-by: Claude Opus 4.7, Cursor Signed-off-by: Naveen Yerramneni <naveen.yerramneni@nutanix.com> Signed-off-by: Dumitru Ceara <dceara@redhat.com>
1 parent a6b38af commit 4cd8a06

6 files changed

Lines changed: 496 additions & 59 deletions

File tree

Documentation/ref/ovn-logical-flows.7.rst

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -946,11 +946,15 @@ refer to either the parent or child ports as applicable to this logical switch.
946946
table.
947947

948948
- In inline: For each active network function with *id* that is referenced in a
949-
network function group, a priority-99 flow matches ``reg8[21] == 1 &&
950-
reg8[22] == 1 && reg0[22..29] == id`` and sets ``outport=P; output;`` where
951-
*P* is the ``inport`` of that network function. This redirects request
952-
packets for flows matching ``from-lport`` ACLs with network_function_group
953-
to the specific network function selected by the Pre Network Function stage.
949+
network function group, priority-99 flows match ``ip4 && reg8[21] == 1 &&
950+
reg8[22] == 1 && reg0[22..29] == id`` and ``ip6 && reg8[21] == 1 &&
951+
reg8[22] == 1 && reg0[22..29] == id`` and set
952+
``nf_learn_orig_inport(ipv6 = false|true); outport=P; output;``
953+
where *P* is the ``inport`` of that network function. This redirects request
954+
packets for flows matching ``from-lport`` ACLs with
955+
network_function_group to the specific network function selected by the Pre
956+
Network Function stage. It also learns the original inport before
957+
redirection.
954958

955959
- In vtap mode: For each active network function with *id*, a priority-99
956960
forward flow matches ``reg8[21] == 1 && reg8[22] == 1 && reg0[22..29] == id``
@@ -965,6 +969,12 @@ refer to either the parent or child ports as applicable to this logical switch.
965969
This redirects response and related packets for ``to-lport`` ACLs to the
966970
same network function that handled the request.
967971

972+
- In inline (overlay logical switches only), two priority-50 flows match
973+
``ip4 && reg8[21] == 0`` and ``ip6 && reg8[21] == 0`` and set
974+
``nf_learn_orig_inport(ipv6 = false|true); next;``. This learns on the
975+
packet's ingress node even when redirection happens on a different node,
976+
so the learn stays co-located with the lookup.
977+
968978
- In vtap mode: A priority-99 reverse flow matches ``reg8[21] == 1 && reg8[22]
969979
== 0 && ct_label.nf_id == id`` and sets ``clone { outport = P; output; };
970980
next;`` to mirror response/related packets to the same NF.
@@ -1645,13 +1655,17 @@ peer of a logical router port. This flow is added to skip the connection
16451655
tracking of packets which will be entering logical router datapath from logical
16461656
switch datapath for routing.
16471657

1648-
This table also has a priority-110 flow for each network_function ``inport`` *P*
1649-
that matches ``inport == P``. The action is to skip all the egress tables up to
1650-
the :ref:`Network Function <ls-out-13>` table and advance the packet directly to
1651-
the table after that. This is for the case where packet redirection happens in
1652-
egress :ref:`Network Function <ls-out-13>` table. The same packet when it comes
1653-
out of the other port of network function, they should not be processed again by
1654-
the same egress stages, specially they should skip the conntrack processing.
1658+
This table also has a priority-115 flow for each network_function ``inport``
1659+
*P*
1660+
that matches ``inport == P`` and applies
1661+
``reg8[24] = nf_lookup_orig_inport(); next(pipeline=egress, table=T);`` where
1662+
*T* is the table immediately following :ref:`Network Function <ls-out-13>`.
1663+
This is for the case where packet redirection happens in egress
1664+
:ref:`Network Function <ls-out-13>` table. When the packet comes back from the
1665+
other NF port, it should not be processed again by the same egress stages,
1666+
specifically conntrack processing should be skipped. This flow also performs
1667+
``nf_lookup_orig_inport()`` before continuing so post-NF loopback copies can
1668+
be detected and dropped.
16551669

16561670
.. _ls-out-3:
16571671

@@ -1886,13 +1900,15 @@ in ``ct_label.nf_id`` during request processing.
18861900
table.
18871901

18881902
- In inline: For each active network function with *id* that is referenced in a
1889-
network function group, a priority-99 flow matches ``reg8[21] == 1 &&
1890-
reg8[22] == 1 && reg0[22..29] == id`` and sets ``outport=P; reg8[23] = 1;
1891-
next(pipeline=ingress, table=T)`` where *P* is the ``outport`` of
1892-
that network function and *T* is the ingress table :ref:`Destination Lookup
1893-
<ls-in-33>`. This redirects request packets matching ``to-lport`` ACLs with
1894-
network_function_group to the specific network function selected by the Pre
1895-
Network Function stage.
1903+
network function group, priority-99 flows match ``ip4 && reg8[21] == 1 &&
1904+
reg8[22] == 1 && reg0[22..29] == id`` and ``ip6 && reg8[21] == 1 &&
1905+
reg8[22] == 1 && reg0[22..29] == id`` and set
1906+
``nf_learn_orig_inport(ipv6 = false|true); outport=P; reg8[23] = 1;
1907+
next(pipeline=ingress, table=T);`` where *P* is the NF outport and *T* is
1908+
the ingress :ref:`Destination Lookup <ls-in-33>` table. This redirects
1909+
request packets matching ``to-lport`` ACLs with network_function_group to the
1910+
specific network function selected by the Pre Network Function stage, and
1911+
learns the original inport before redirection.
18961912

18971913
- In vtap mode: For each active network function with *id*, a priority-99
18981914
forward flow matches ``reg8[21] == 1 && reg8[22] == 1 && reg0[22..29] == id``
@@ -1922,6 +1938,10 @@ in ``ct_label.nf_id`` during request processing.
19221938
port) and advances to the next table so packets to the NF are not mirrored
19231939
again.
19241940

1941+
- In inline: A priority-2 flow matches ``inport == P`` where *P* is the NF
1942+
``outport`` and sets ``reg8[24] = nf_lookup_orig_inport(); next;``. This
1943+
captures post-NF packets that re-enter egress from ingress recirculation.
1944+
19251945
- In vtap mode: In egress Pre ACL table, a priority-110 flow matches ``ip &&
19261946
outport == P`` with action ``ct_clear; next;`` for the vtap NF port so
19271947
packets toward the NF are not committed to conntrack.
@@ -1944,6 +1964,9 @@ This is similar to the port security logic in table :ref:`Ingress Port Security
19441964
check <ls-in-0>` except that action ``check_out_port_sec`` is used to check the
19451965
port security rules. This table adds the below logical flows.
19461966

1967+
- A priority-110 flow matching ``reg8[24] == 1`` with action ``drop;``. This
1968+
drops post-NF loopback copies detected by ``nf_lookup_orig_inport()``.
1969+
19471970
- A priority 100 flow which matches on the multicast traffic and applies the
19481971
action ``REGBIT_PORT_SEC_DROP" = 0; next;"`` to skip the out port security
19491972
checks.

TODO.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,16 @@ OVN To-do List
177177
* Geneve tunnel is used for supporting this feature for VLAN network.
178178
Extend the support over VxLAN tunnel as well.
179179

180+
* Inline-NF loop prevention has limitations in topologies where
181+
a post-NF flood copy may reach the same logical inport from a
182+
different node than the packet's original ingress node. In that
183+
case, the lookup runs on a different node than where the inport
184+
was learned, so loopback copies are not identified.
185+
Known example: OVN-IC L2 stretch with the NF and IC gateway on
186+
different chassis. With ``unknown``-addressed ports, the post-NF
187+
packet can be flooded across AZs and come back to the source AZ via
188+
another node, so the lookup does not hit the original learn entry.
189+
180190
* CI
181191

182192
* ovn-kubernetes: Only a subset of the ovn-kubernetes features is currently

northd/northd.c

Lines changed: 107 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ static bool vxlan_mode;
176176
#define REGBIT_NF_ENABLED "reg8[21]"
177177
#define REGBIT_NF_ORIG_DIR "reg8[22]"
178178
#define REGBIT_NF_EGRESS_LOOPBACK "reg8[23]"
179+
/* Set on a post-NF packet flowing back out its original ingress port;
180+
* such packets are dropped. */
181+
#define REGBIT_NF_LOOKUP_HIT "reg8[24]"
179182
/* Register to store the network function group id */
180183
#define REG_NF_GROUP_ID "reg0[22..29]"
181184
/* REG_NF_ID overrides REG_NF_GROUP_ID in the pre_network_function stage. */
@@ -315,6 +318,8 @@ static const char *reg_ct_state[] = {
315318
* | | REGBIT_NF_{ENABLED/ORIG_DIR/ | G | |
316319
* | | EGRESS_LOOPBACK} | 4 | |
317320
* | | (>= ACL_EVAL* && <= NF*) | | |
321+
* | | REGBIT_NF_LOOKUP_HIT | | |
322+
* | | (>= OUT_PRE_ACL && <= OUT_CHECK_PORT_SEC)| | |
318323
* +----+----------------------------------------------+ +-----------------------------------+
319324
* | R9 | OBS_POINT_ID_EST | | |
320325
* | | (>= ACL_EVAL* && <= ACL_ACTION*) | | |
@@ -19776,35 +19781,64 @@ consider_network_function_inline(struct lflow_table *lflows,
1977619781

1977719782
/* Add forward flows for redirection:
1977819783
* Flows to handle request packets for new or existing connections.
19784+
* These flows learn the original inport before redirection.
1977919785
*
1978019786
* from-lport ACL in_nf priority 99:
1978119787
* in_acl_eval has already categorized it and populated nf_enabled,
1978219788
* direction and nfg_id registers. in_pre_nf sets the active network
19783-
* function id in nf_id register. Here this rule sets the outport to the
19784-
* NF port and does output action to skip the rest of the ingress pipeline.
19789+
* function id in nf_id register. Here this rule learns original inport,
19790+
* sets the outport to the NF port and does output action to skip the
19791+
* rest of the ingress pipeline.
1978519792
*
1978619793
* to-lport ACL out_nf priority 99:
1978719794
* out_acl_eval, and out_pre_nf set the nf related registers. Then the
19788-
* out_nf stage sets the outport to NF port and submits the
19789-
* packet back to ingress pipeline l2_lkup table. The l2_lkup would skip
19790-
* mac based lookup as the NF_EGRESS_LOOPBACK is set.
19795+
* out_nf stage learns original inport, sets the outport to NF port and
19796+
* submits the packet back to ingress pipeline l2_lkup table. The l2_lkup
19797+
* would skip mac based lookup as the NF_EGRESS_LOOPBACK is set.
1979119798
*/
19799+
ds_put_format(&match, REGBIT_NF_ENABLED" == 1 && "
19800+
REGBIT_NF_ORIG_DIR" == 1 && "
19801+
REG_NF_ID " == %"PRIu8,
19802+
(uint8_t) nf->id);
19803+
size_t fwd_match_len = match.length;
19804+
19805+
/* IPv4 redirect flow: learn original inport before redirect. */
19806+
ds_put_format(&match, " && ip4");
19807+
ds_clear(&action);
1979219808
if (ingress) {
19793-
ds_put_format(&action, "outport = %s; output;",
19809+
ds_put_format(&action, "nf_learn_orig_inport(ipv6 = false); "
19810+
"outport = %s; output;",
1979419811
redirect_port->json_key);
1979519812
} else {
19796-
ds_put_format(&action, "outport = %s; "
19813+
ds_put_format(&action, "nf_learn_orig_inport(ipv6 = false); "
19814+
"outport = %s; "
19815+
REGBIT_NF_EGRESS_LOOPBACK" = 1; "
19816+
"next(pipeline=ingress, table=%d);",
19817+
redirect_port->json_key,
19818+
ovn_stage_get_table(S_SWITCH_IN_L2_LKUP));
19819+
}
19820+
ovn_lflow_add(lflows, od, fwd_stage, 99, ds_cstr(&match),
19821+
ds_cstr(&action), lflow_ref);
19822+
ds_truncate(&match, fwd_match_len);
19823+
19824+
/* IPv6 redirect flow: learn original inport before redirect. */
19825+
ds_put_format(&match, " && ip6");
19826+
ds_clear(&action);
19827+
if (ingress) {
19828+
ds_put_format(&action, "nf_learn_orig_inport(ipv6 = true); "
19829+
"outport = %s; output;",
19830+
redirect_port->json_key);
19831+
} else {
19832+
ds_put_format(&action, "nf_learn_orig_inport(ipv6 = true); "
19833+
"outport = %s; "
1979719834
REGBIT_NF_EGRESS_LOOPBACK" = 1; "
1979819835
"next(pipeline=ingress, table=%d);",
1979919836
redirect_port->json_key,
1980019837
ovn_stage_get_table(S_SWITCH_IN_L2_LKUP));
1980119838
}
19802-
ds_put_format(&match, REGBIT_NF_ENABLED" == 1 && "
19803-
REGBIT_NF_ORIG_DIR" == 1 && "
19804-
REG_NF_ID " == %"PRIu8,
19805-
(uint8_t) nf->id);
1980619839
ovn_lflow_add(lflows, od, fwd_stage, 99, ds_cstr(&match),
1980719840
ds_cstr(&action), lflow_ref);
19841+
1980819842
ds_clear(&match);
1980919843
ds_clear(&action);
1981019844

@@ -19876,19 +19910,31 @@ consider_network_function_inline(struct lflow_table *lflows,
1987619910
ds_clear(&match);
1987719911
ds_clear(&action);
1987819912

19879-
/* For packets redirected from egress pipleline to the NF, when they come
19880-
* out from the other NF port, we don't want to process them again through
19881-
* egress stages they already went through, especially not again through
19882-
* conntrack as these packets are already accounted for there. Hence we
19883-
* need to skip the initial pipeline stages for such packets and directly
19884-
* start from the NF table. The packets that fall under this category are
19885-
* the response packets from NF for from-lport ACLs and request packets
19886-
* received from NF for to-lport ACLs. */
19913+
/* Post-NF Processing: Resumes pipeline after ls_out_nf to bypass
19914+
* previously completed egress stages (e.g., conntrack). Uses priority
19915+
* 115 in out_pre_acl to take precedence over priority-110 conntrack
19916+
* skip flows, and calls nf_lookup_orig_inport() to identify loopback
19917+
* packets returning on their original inport. */
1988719918
ds_put_format(&match, "inport == %s", input_port->json_key);
19888-
ds_put_format(&action, "next(pipeline=egress, table=%d);",
19889-
(ovn_stage_get_table(S_SWITCH_OUT_NF) + 1));
19890-
ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 110, ds_cstr(&match),
19919+
ds_put_format(&action,
19920+
REGBIT_NF_LOOKUP_HIT " = nf_lookup_orig_inport(); "
19921+
"next(pipeline=egress, table=%d);",
19922+
ovn_stage_get_table(S_SWITCH_OUT_NF) + 1);
19923+
ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 115, ds_cstr(&match),
19924+
ds_cstr(&action), lflow_ref);
19925+
ds_clear(&match);
19926+
ds_clear(&action);
19927+
19928+
/* Priority 2 in out_nf (output_port): post-NF packet re-entering the
19929+
* egress pipeline; run the lookup here so ls_out_check_port_sec drops
19930+
* a loopback copy. */
19931+
ds_put_format(&match, "inport == %s", output_port->json_key);
19932+
ds_put_format(&action,
19933+
REGBIT_NF_LOOKUP_HIT " = nf_lookup_orig_inport(); next;");
19934+
ovn_lflow_add(lflows, od, S_SWITCH_OUT_NF, 2, ds_cstr(&match),
1989119935
ds_cstr(&action), lflow_ref);
19936+
ds_clear(&match);
19937+
ds_clear(&action);
1989219938

1989319939
/* Priority 120 flows in out_stateful:
1989419940
* If packet was received on a tunnel interface and being forwarded to a
@@ -20107,6 +20153,7 @@ build_network_function(const struct ovn_datapath *od,
2010720153
{
2010820154
unsigned long *nfg_ingress_bitmap = bitmap_allocate(MAX_OVN_NF_GROUP_IDS);
2010920155
unsigned long *nfg_egress_bitmap = bitmap_allocate(MAX_OVN_NF_GROUP_IDS);
20156+
bool has_inline_nfg = false;
2011020157

2011120158
/* This flow matches packets injected from out_nf stage -
2011220159
* after it sets the outport - back to in_l2_lkup stage. This rule must be
@@ -20169,12 +20216,16 @@ build_network_function(const struct ovn_datapath *od,
2016920216
? true : false;
2017020217
unsigned long *nfg_bitmap = ingress ? nfg_ingress_bitmap
2017120218
: nfg_egress_bitmap;
20172-
unsigned int nfg_id = acl->network_function_group->id;
20173-
if (bitmap_is_set(nfg_bitmap, nfg_id)) {
20219+
const struct nbrec_network_function_group *nfg =
20220+
acl->network_function_group;
20221+
if (bitmap_is_set(nfg_bitmap, nfg->id)) {
2017420222
/* Skip if same NF is used again. */
2017520223
continue;
2017620224
}
20177-
nfg_bitmap = bitmap_set1(nfg_bitmap, nfg_id);
20225+
nfg_bitmap = bitmap_set1(nfg_bitmap, nfg->id);
20226+
if (!has_inline_nfg && !network_function_group_is_vtap_mode(nfg)) {
20227+
has_inline_nfg = true;
20228+
}
2017820229
consider_network_function(lflows, od, acl->network_function_group,
2017920230
ingress, lflow_ref);
2018020231
}
@@ -20194,19 +20245,47 @@ build_network_function(const struct ovn_datapath *od,
2019420245
unsigned long *nfg_bitmap = ingress
2019520246
? nfg_ingress_bitmap
2019620247
: nfg_egress_bitmap;
20197-
unsigned int nfg_id = acl->network_function_group->id;
20198-
if (bitmap_is_set(nfg_bitmap, nfg_id)) {
20248+
const struct nbrec_network_function_group *nfg =
20249+
acl->network_function_group;
20250+
if (bitmap_is_set(nfg_bitmap, nfg->id)) {
2019920251
/* Skip if same NF is used again. */
2020020252
continue;
2020120253
}
20202-
nfg_bitmap = bitmap_set1(nfg_bitmap, nfg_id);
20254+
nfg_bitmap = bitmap_set1(nfg_bitmap, nfg->id);
20255+
20256+
if (!has_inline_nfg &&
20257+
!network_function_group_is_vtap_mode(nfg)) {
20258+
has_inline_nfg = true;
20259+
}
2020320260
consider_network_function(lflows, od,
2020420261
acl->network_function_group,
2020520262
ingress, lflow_ref);
2020620263
}
2020720264
}
2020820265
}
2020920266
}
20267+
20268+
if (has_inline_nfg) {
20269+
/* Drop the loopback copy flagged by nf_lookup_orig_inport(). */
20270+
ovn_lflow_add(lflows, od, S_SWITCH_OUT_CHECK_PORT_SEC, 110,
20271+
REGBIT_NF_LOOKUP_HIT " == 1", debug_drop_action(),
20272+
lflow_ref);
20273+
20274+
/* Overlay only: always learn the inport so a post-NF loopback copy
20275+
* can be detected and dropped when redirection happens on a different
20276+
* node than where the packet originally entered the LS. */
20277+
if (!ls_has_localnet_port(od)) {
20278+
ovn_lflow_add(lflows, od, S_SWITCH_IN_NF, 50,
20279+
"ip4 && " REGBIT_NF_ENABLED" == 0",
20280+
"nf_learn_orig_inport(ipv6 = false); next;",
20281+
lflow_ref);
20282+
ovn_lflow_add(lflows, od, S_SWITCH_IN_NF, 50,
20283+
"ip6 && " REGBIT_NF_ENABLED" == 0",
20284+
"nf_learn_orig_inport(ipv6 = true); next;",
20285+
lflow_ref);
20286+
}
20287+
}
20288+
2021020289
bitmap_free(nfg_ingress_bitmap);
2021120290
bitmap_free(nfg_egress_bitmap);
2021220291
}

ovn-nb.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6760,6 +6760,19 @@ or
67606760
as down, the fallback method is applied.
67616761
</p>
67626762

6763+
<p>
6764+
<b>Known limitation (inline mode)</b>: in topologies where a
6765+
post-NF flood copy may reach the same logical inport from a
6766+
different node than the packet's original ingress node,
6767+
the lookup runs on a different node than where the inport
6768+
was learned, so loopback copies are not identified.
6769+
For example: OVN-IC L2 stretch with the NF and IC gateway on
6770+
different chassis. With <code>unknown</code>-addressed ports, the
6771+
post-NF packet can be flooded across AZs and come back to the
6772+
source AZ via another node, so the lookup does not hit the
6773+
original learn entry.
6774+
</p>
6775+
67636776
<column name="name">
67646777
Name of the <ref table="Network_Function_Group"/>. Name should be unique.
67656778
</column>

0 commit comments

Comments
 (0)