The localnet is excluded from MAC learning for scale
reason. However there might be a valid workflow
when yo uwant to enable the learning and benefit
for that for HW offload. Add option called
'localnet_learn_fdb' to LSP, which will enable/disable
the learning. Setting it as disabled by default.

Reported-at: https://bugzilla.redhat.com/2070529
Signed-off-by: Ales Musil <[email protected]>
---
v2: Add helper method for getting the option, add
test case in ovn.at, rebase on main
---
 NEWS                |  2 ++
 northd/northd.c     | 14 ++++++++--
 ovn-nb.xml          |  7 +++++
 ovn-sb.xml          |  1 +
 tests/ovn-northd.at | 36 +++++++++++++++++++++++++
 tests/ovn.at        | 65 +++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 123 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 2ee283a56..e015ae8e7 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ Post v22.06.0
 -------------
   - ovn-controller: Add configuration knob, through OVS external-id
     "ovn-encap-df_default" to enable or disable tunnel DF flag.
+  - Add option "localnet_learn_fdb" to LSP that will allow localnet
+    ports to learn MAC addresses and store them in FDB table.
 
 OVN v22.06.0 - XX XXX XXXX
 --------------------------
diff --git a/northd/northd.c b/northd/northd.c
index b78adee11..0207f6ce1 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -1845,6 +1845,12 @@ lsp_is_localnet(const struct nbrec_logical_switch_port 
*nbsp)
     return !strcmp(nbsp->type, "localnet");
 }
 
+static bool
+localnet_can_learn_mac(const struct nbrec_logical_switch_port *nbsp)
+{
+    return smap_get_bool(&nbsp->options, "localnet_learn_fdb", false);
+}
+
 static bool
 lsp_is_type_changed(const struct sbrec_port_binding *sb,
                 const struct nbrec_logical_switch_port *nbsp,
@@ -5448,8 +5454,12 @@ build_lswitch_learn_fdb_op(
         struct ovn_port *op, struct hmap *lflows,
         struct ds *actions, struct ds *match)
 {
-    if (op->nbsp && !op->n_ps_addrs && !strcmp(op->nbsp->type, "") &&
-        op->has_unknown) {
+    if (!op->nbsp) {
+        return;
+    }
+
+    if (!op->n_ps_addrs && op->has_unknown && (!strcmp(op->nbsp->type, "") ||
+        (lsp_is_localnet(op->nbsp) && localnet_can_learn_mac(op->nbsp)))) {
         ds_clear(match);
         ds_clear(actions);
         ds_put_format(match, "inport == %s", op->json_key);
diff --git a/ovn-nb.xml b/ovn-nb.xml
index c197f431f..618a48b97 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -976,6 +976,13 @@
           headers. Supported values: 802.11q (default), 802.11ad.
         </column>
 
+        <column name="options" key="localnet_learn_fdb"
+                type='{"type": "boolean"}'>
+          Optional. Allows localnet port to learn MACs and store them in FDB
+          table if set to <code>true</code>. The default value is
+          <code>false</code>.
+        </column>
+
       </group>
 
       <group title="Options for l2gateway ports">
diff --git a/ovn-sb.xml b/ovn-sb.xml
index 9f47a037e..898f3676a 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -4676,6 +4676,7 @@ tcp.flags = RST;
   <table name="FDB" title="Port to MAC bindings">
     <p>
       This table is primarily used to learn the MACs observed on a VIF
+      (or a localnet port with 'localnet_learn_fdb' enabled)
       which belongs to a <code>Logical_Switch_Port</code> record in
       <code>OVN_Northbound</code> whose port security is disabled
       and 'unknown' address set.  If port security is disabled on a
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index a071b3689..a94a7d441 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -7577,3 +7577,39 @@ AT_CHECK([ovn-sbctl lflow-list | grep 'ls.*acl.*blocked' 
], [0], [dnl
 
 AT_CLEANUP
 ])
+
+AT_SETUP([Localnet MAC learning option])
+ovn_start
+
+AT_CHECK([ovn-nbctl ls-add ls0])
+
+AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
+AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
+AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
+AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=phys])
+AT_CHECK([ovn-nbctl --wait=sb sync])
+
+# Check MAC learning flows with 'localnet_learn_fdb' default (false)
+AT_CHECK([ovn-sbctl dump-flows ls0 | grep -e 'ls_in_\(put\|lookup\)_fdb' | 
sort | sed 's/table=./table=?/'], [0], [dnl
+  table=? (ls_in_lookup_fdb   ), priority=0    , match=(1), action=(next;)
+  table=? (ls_in_put_fdb      ), priority=0    , match=(1), action=(next;)
+])
+
+# Enable 'localnet_learn_fdb' and check the flows
+AT_CHECK([ovn-nbctl --wait=sb lsp-set-options ln_port localnet_learn_fdb=true])
+AT_CHECK([ovn-sbctl dump-flows ls0 | grep -e 'ls_in_\(put\|lookup\)_fdb' | 
sort | sed 's/table=./table=?/'], [0], [dnl
+  table=? (ls_in_lookup_fdb   ), priority=0    , match=(1), action=(next;)
+  table=? (ls_in_lookup_fdb   ), priority=100  , match=(inport == "ln_port"), 
action=(reg0[[11]] = lookup_fdb(inport, eth.src); next;)
+  table=? (ls_in_put_fdb      ), priority=0    , match=(1), action=(next;)
+  table=? (ls_in_put_fdb      ), priority=100  , match=(inport == "ln_port" && 
reg0[[11]] == 0), action=(put_fdb(inport, eth.src); next;)
+])
+
+# Disable 'localnet_learn_fdb' and check the flows
+AT_CHECK([ovn-nbctl --wait=sb lsp-set-options ln_port 
localnet_learn_fdb=false])
+AT_CHECK([ovn-sbctl dump-flows ls0 | grep -e 'ls_in_\(put\|lookup\)_fdb' | 
sort | sed 's/table=./table=?/'], [0], [dnl
+  table=? (ls_in_lookup_fdb   ), priority=0    , match=(1), action=(next;)
+  table=? (ls_in_put_fdb      ), priority=0    , match=(1), action=(next;)
+])
+
+AT_CLEANUP
+])
diff --git a/tests/ovn.at b/tests/ovn.at
index 3c079e0fb..c0ade387d 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -31972,3 +31972,68 @@ check test "$snat_zone" = "$SNAT_ZONE_REG"
 
 OVN_CLEANUP([hv1])
 AT_CLEANUP
+
+AT_SETUP([OVN FDB (MAC learning) - Localnet])
+ovn_start
+
+net_add n1
+
+AT_CHECK([ovn-nbctl ls-add ls0])
+
+AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
+AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
+AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
+AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
+
+AT_CHECK([ovn-nbctl lsp-add ls0 vif0])
+AT_CHECK([ovn-nbctl lsp-set-addresses vif0 "00:00:00:00:10:10 192.168.10.10"])
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int vif0 -- \
+    set interface vif0 external-ids:iface-id=vif0 \
+    options:tx_pcap=hv1/vif0-tx.pcap \
+    options:rxq_pcap=hv1/vif0-rx.pcap \
+    ofport-request=1
+ovs-vsctl -- add-port br-phys ext0 -- \
+    set interface ext0 \
+    options:tx_pcap=hv1/ext0-tx.pcap \
+    options:rxq_pcap=hv1/ext0-rx.pcap \
+    ofport-request=2
+ovs-vsctl set open . external_ids:ovn-bridge-mappings=physnet1:br-phys
+
+send_packet() {
+    dev_byte=$1
+
+    src_mac="0000000010$dev_byte"
+    src_ip=`ip_to_hex 192 168 10 $dev_byte`
+    dst_ip=`ip_to_hex 192 168 10 10`
+    dst_mac="000000001010"
+    
packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
+    ovs-appctl netdev-dummy/receive ext0 $packet
+}
+
+wait_for_ports_up
+AT_CHECK([ovn-nbctl --wait=hv sync])
+
+# Learning is disabled, the table should be empty
+send_packet 20
+AT_CHECK([test $(ovn-sbctl list fdb | grep -c "00:00:00:00:10:20") = 0])
+
+# Enable learning on localnet port
+AT_CHECK([ovn-nbctl set logical_switch_port ln_port 
options:localnet_learn_fdb=true])
+AT_CHECK([ovn-nbctl --wait=hv sync])
+send_packet 20
+AT_CHECK([test $(ovn-sbctl list fdb | grep -c "00:00:00:00:10:20") = 1])
+
+# Disable learning on localnet port
+AT_CHECK([ovn-nbctl set logical_switch_port ln_port 
options:localnet_learn_fdb=false])
+AT_CHECK([ovn-nbctl --wait=hv sync])
+send_packet 30
+AT_CHECK([test $(ovn-sbctl list fdb | grep -c "00:00:00:00:10:30") = 0])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
-- 
2.35.3

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to