Similarly to 80187a8031b6 [0], use eth.src for nd_lookup if nd.tll is zero.
As per RFC 4861 nd.tll is allowed to be 0 in reply to unicast ND NS. This
enables the MAC Binding refresh to work when we receive reply to unicast
ND NS, it should also prevent unnecessary pinctrl calls when we already
know given MAC Binding.
[0] 80187a8031b6 ("ovn-northd: Add flow to use eth.src if nd.tll is 0 in
put_nd() action.")
Fixes: 783337b24c3f ("Learn the mac binding only if required")
Signed-off-by: Ales Musil <[email protected]>
---
v2: Rebase on top of latest main.
Add missing Fixes tag.
Add missing documentation.
Enahnce the lflow test.
---
Documentation/ref/ovn-logical-flows.7.rst | 14 ++++++++++++++
northd/northd.c | 20 ++++++++++++++++++++
tests/ovn-northd.at | 23 +++++++++++++++++++++++
3 files changed, 57 insertions(+)
diff --git a/Documentation/ref/ovn-logical-flows.7.rst
b/Documentation/ref/ovn-logical-flows.7.rst
index 2778b3633..556aa0cb8 100644
--- a/Documentation/ref/ovn-logical-flows.7.rst
+++ b/Documentation/ref/ovn-logical-flows.7.rst
@@ -2122,6 +2122,20 @@ Following flows are added:
reg9[3] = 1;
next;
+- A higher priority-105 flow which matches on IPv6 Neighbor Discovery
+ advertisement packet with ``nd.tll == 0`` and applies the actions if
+ the option ``always_learn_from_arp_request`` is ``true``::
+
+ reg9[2] = lookup_nd(inport, nd.target, eth.src);
+ next;
+
+ If the option ``always_learn_from_arp_request`` is ``false``, a priority-115
+ flow is added instead::
+
+ reg9[2] = lookup_nd(inport, nd.target, eth.src);
+ reg9[3] = lookup_nd_ip(inport, nd.target);
+ next;
+
- A priority-100 flow which matches on IPv6 Neighbor Discovery solicitation
packet and applies the actions if the option
``always_learn_from_arp_request``
is ``true``::
diff --git a/northd/northd.c b/northd/northd.c
index 4ca9820d4..cc6e2e999 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -14979,6 +14979,7 @@ build_neigh_learning_flows_for_lrouter(
* REGBIT_LOOKUP_NEIGHBOR_RESULT bit. If
* "always_learn_from_arp_request" is set to false,
* REGBIT_LOOKUP_NEIGHBOR_IP_RESULT bit is set.
+ * The lookup backs up to eth.src in case when nd.tll == 0.
*
* For IPv6 ND NS packets, table LOOKUP_NEIGHBOR does a lookup
* for the (ip6.src, nd.sll) in the mac binding table using the
@@ -15016,6 +15017,14 @@ build_neigh_learning_flows_for_lrouter(
ovn_lflow_add(lflows, od, S_ROUTER_IN_LOOKUP_NEIGHBOR, 100, "nd_na",
ds_cstr(actions), lflow_ref);
+ ds_clear(actions);
+ ds_put_format(actions, REGBIT_LOOKUP_NEIGHBOR_RESULT
+ " = lookup_nd(inport, nd.target, eth.src); %s%snext;",
+ learn_from_arp_request ? "" :
+ REGBIT_LOOKUP_NEIGHBOR_IP_RESULT" = 1; ", flood);
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_LOOKUP_NEIGHBOR, 105,
+ "nd_na && nd.tll == 0", ds_cstr(actions), lflow_ref);
+
if (!learn_from_arp_request) {
/* Add flow to skip GARP LLA if we don't know it already.
* From RFC 2461, section 4.4, Neighbor Advertisement Message
@@ -15033,6 +15042,17 @@ build_neigh_learning_flows_for_lrouter(
ovn_lflow_add(lflows, od, S_ROUTER_IN_LOOKUP_NEIGHBOR, 110,
"nd_na && ip6.src == fe80::/10 && ip6.dst == ff00::/8",
ds_cstr(actions), lflow_ref);
+
+ ds_clear(actions);
+ ds_put_format(actions, REGBIT_LOOKUP_NEIGHBOR_RESULT
+ " = lookup_nd(inport, nd.target, eth.src); "
+ REGBIT_LOOKUP_NEIGHBOR_IP_RESULT
+ " = lookup_nd_ip(inport, nd.target); %snext;",
+ flood);
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_LOOKUP_NEIGHBOR, 115,
+ "nd_na && nd.tll == 0 && "
+ "ip6.src == fe80::/10 && ip6.dst == ff00::/8",
+ ds_cstr(actions), lflow_ref);
}
ds_clear(actions);
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 810e9f2d7..5d5eb696c 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -9317,6 +9317,29 @@ AT_CHECK([cat lrflows | grep -e lr_in_lookup_neighbor -e
lr_in_learn_neighbor |
table=??(lr_in_lookup_neighbor), priority=100 , match=(arp.op == 2),
action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); next;)
table=??(lr_in_lookup_neighbor), priority=100 , match=(nd_na),
action=(reg9[[2]] = lookup_nd(inport, nd.target, nd.tll); next;)
table=??(lr_in_lookup_neighbor), priority=100 , match=(nd_ns),
action=(reg9[[2]] = lookup_nd(inport, ip6.src, nd.sll); next;)
+ table=??(lr_in_lookup_neighbor), priority=105 , match=(nd_na && nd.tll ==
0), action=(reg9[[2]] = lookup_nd(inport, nd.target, eth.src); next;)
+])
+
+check ovn-nbctl --wait=sb set Logical_Router lr0
options:always_learn_from_arp_request=false
+
+ovn-sbctl dump-flows lr0 > lrflows
+AT_CAPTURE_FILE([lrflows])
+
+AT_CHECK([cat lrflows | grep -e lr_in_lookup_neighbor -e lr_in_learn_neighbor
| ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_learn_neighbor), priority=0 , match=(1), action=(drop;)
+ table=??(lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == 1 ||
reg9[[3]] == 0), action=(mac_cache_use; next;)
+ table=??(lr_in_learn_neighbor), priority=90 , match=(arp),
action=(put_arp(inport, arp.spa, arp.sha); next;)
+ table=??(lr_in_learn_neighbor), priority=90 , match=(nd_na),
action=(put_nd(inport, nd.target, nd.tll); next;)
+ table=??(lr_in_learn_neighbor), priority=90 , match=(nd_ns),
action=(put_nd(inport, ip6.src, nd.sll); next;)
+ table=??(lr_in_learn_neighbor), priority=95 , match=(nd_na && nd.tll ==
0), action=(put_nd(inport, nd.target, eth.src); next;)
+ table=??(lr_in_learn_neighbor), priority=95 , match=(nd_ns && (ip6.src ==
0 || nd.sll == 0)), action=(next;)
+ table=??(lr_in_lookup_neighbor), priority=0 , match=(1),
action=(reg9[[2]] = 1; next;)
+ table=??(lr_in_lookup_neighbor), priority=100 , match=(arp.op == 2),
action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); reg9[[3]] = 1; next;)
+ table=??(lr_in_lookup_neighbor), priority=100 , match=(nd_na),
action=(reg9[[2]] = lookup_nd(inport, nd.target, nd.tll); reg9[[3]] = 1; next;)
+ table=??(lr_in_lookup_neighbor), priority=100 , match=(nd_ns),
action=(reg9[[2]] = lookup_nd(inport, ip6.src, nd.sll); reg9[[3]] =
lookup_nd_ip(inport, ip6.src); next;)
+ table=??(lr_in_lookup_neighbor), priority=105 , match=(nd_na && nd.tll ==
0), action=(reg9[[2]] = lookup_nd(inport, nd.target, eth.src); reg9[[3]] = 1;
next;)
+ table=??(lr_in_lookup_neighbor), priority=110 , match=(nd_na && ip6.src ==
fe80::/10 && ip6.dst == ff00::/8), action=(reg9[[2]] = lookup_nd(inport,
nd.target, nd.tll); reg9[[3]] = lookup_nd_ip(inport, nd.target); next;)
+ table=??(lr_in_lookup_neighbor), priority=115 , match=(nd_na && nd.tll == 0
&& ip6.src == fe80::/10 && ip6.dst == ff00::/8), action=(reg9[[2]] =
lookup_nd(inport, nd.target, eth.src); reg9[[3]] = lookup_nd_ip(inport,
nd.target); next;)
])
OVN_CLEANUP_NORTHD
--
2.55.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev