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( ->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
