On 11/30/23 15:54, Naveen Yerramneni wrote: > > >> On 30-Nov-2023, at 6:06 PM, Dumitru Ceara <dce...@redhat.com> wrote: >> >> On 11/30/23 09:45, Naveen Yerramneni wrote: >>> >>> >>>> On 29-Nov-2023, at 2:24 PM, Dumitru Ceara <dce...@redhat.com> wrote: >>>> >>>> On 11/29/23 07:45, naveen.yerramneni wrote: >>>>> This functionality can be enabled at the logical switch level: >>>>> - "other_config:fdb_local" can be used to enable/disable this >>>>> functionality, it is disabled by default. >>>>> - "other_config:fdb_local_idle_timeout" sepcifies idle timeout >>>>> for locally learned fdb flows, default timeout is 300 secs. >>>>> >>>>> If enabled, below lflow is added for each port that has unknown addr set. >>>>> - table=2 (ls_in_lookup_fdb), priority=100, match=(inport == <in_port>), >>>>> action=(commit_fdb_local(timeout=<timeout>); next; >>>>> >>>>> New OVN action: "commit_fdb_local". This sets following OVS action. >>>>> - learn(table=71,idle_timeout=<timeout>,delete_learned,OXM_OF_METADATA[], >>>>> >>>>> NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_NX_REG14[]->NXM_NX_REG15[]) >>>>> >>>>> This is useful when OVN is managing VLAN network that has multiple ports >>>>> set with unknown addr and localnet_learn_fdb is enabled. With this config, >>>>> if there is east-west traffic flowing between VMs part of same VLAN >>>>> deployed on different hypervisors then, MAC addrs of the source and >>>>> destination VMs keeps flapping between VM port and localnet port in >>>>> Southbound FDB table. Enabling fdb_local config makes fdb table local to >>>>> the chassis and avoids MAC flapping. >>>>> >>>>> Signed-off-by: Naveen Yerramneni <naveen.yerramn...@nutanix.com> >>>>> --- >>>> >>>> Hi Naveen, >>>> >>>> Thanks a lot for the patch! >>>> >>>> Just a note, we already have a fix for the east-west traffic that causes >>>> FDB flapping when localnet is used: >>>> >>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_ovn-2Dorg_ovn_commit_2acf91e9628e9481c48e4a6cec8ad5159fdd6d2e&d=DwICaQ&c=s883GpUCOChKOHiocYtGcg&r=2PQjSDR7A28z1kXE1ptSm6X36oL_nCq1XxeEt7FkLmA&m=kPuq992rikXYk63APGxlIpfqY3lPpreN9f4ha9pZKpodnVgE9KfjEUNozpPUFzUu&s=LP9_zs2Rj34vMx20ntbu-A3taXqKMJNVH2TLQyOXCh0&e= >>>> >>>> >>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_ovn-2Dorg_ovn_commit_f3a14907fe2b1ecdcfddfbed595cd097b6efbe14&d=DwICaQ&c=s883GpUCOChKOHiocYtGcg&r=2PQjSDR7A28z1kXE1ptSm6X36oL_nCq1XxeEt7FkLmA&m=kPuq992rikXYk63APGxlIpfqY3lPpreN9f4ha9pZKpodnVgE9KfjEUNozpPUFzUu&s=gsUGtjyf9gSOr1LkcCH0O6MB1_tjXi9fuTgwEFgbRx8&e= >>>> >>>> >>>> In general, however, I think it's a very good idea to move the FDB away >>>> from the Southbound and make it local to each hypervisor. That reduces >>>> load on the Southbound among other things. >>>> >>> >>> Hi Dumitru, >>> >>> Thanks for informing about the patches. >>> Yes, local FDB reduces load on southbound. >>> >>> >>>>> include/ovn/actions.h | 7 +++ >>>>> lib/actions.c | 94 ++++++++++++++++++++++++++++++++++++ >>>>> northd/northd.c | 26 ++++++++++ >>>>> ovn-nb.xml | 14 ++++++ >>>>> tests/ovn.at | 108 ++++++++++++++++++++++++++++++++++++++++++ >>>>> utilities/ovn-trace.c | 2 + >>>>> 6 files changed, 251 insertions(+) >>>>> >>>>> diff --git a/include/ovn/actions.h b/include/ovn/actions.h >>>>> index 49cfe0624..85ac92cd3 100644 >>>>> --- a/include/ovn/actions.h >>>>> +++ b/include/ovn/actions.h >>>>> @@ -127,6 +127,7 @@ struct collector_set_ids; >>>>> OVNACT(CHK_LB_AFF, ovnact_result) \ >>>>> OVNACT(SAMPLE, ovnact_sample) \ >>>>> OVNACT(MAC_CACHE_USE, ovnact_null) \ >>>>> + OVNACT(COMMIT_FDB_LOCAL, ovnact_commit_fdb_local) \ >>>>> >>>>> /* enum ovnact_type, with a member OVNACT_<ENUM> for each action. */ >>>>> enum OVS_PACKED_ENUM ovnact_type { >>>>> @@ -514,6 +515,12 @@ struct ovnact_commit_lb_aff { >>>>> uint16_t timeout; >>>>> }; >>>>> >>>>> +/* OVNACT_COMMIT_FBD_LOCAL. */ >>>>> +struct ovnact_commit_fdb_local{ >>>>> + struct ovnact ovnact; >>>>> + uint16_t timeout; /* fdb_local flow timeout */ >>>>> +}; >>>>> + >>>>> /* Internal use by the helpers below. */ >>>>> void ovnact_init(struct ovnact *, enum ovnact_type, size_t len); >>>>> void *ovnact_put(struct ofpbuf *, enum ovnact_type, size_t len); >>>>> diff --git a/lib/actions.c b/lib/actions.c >>>>> index a73fe1a1e..f5aa78db1 100644 >>>>> --- a/lib/actions.c >>>>> +++ b/lib/actions.c >>>>> @@ -5236,6 +5236,98 @@ format_MAC_CACHE_USE(const struct ovnact_null >>>>> *null OVS_UNUSED, struct ds *s) >>>>> ds_put_cstr(s, "mac_cache_use;"); >>>>> } >>>>> >>>>> +static void >>>>> +parse_commit_fdb_local(struct action_context *ctx, >>>>> + struct ovnact_commit_fdb_local *fdb_local) >>>>> +{ >>>>> + uint16_t timeout = 0; >>>>> + lexer_force_match(ctx->lexer, LEX_T_LPAREN); /* Skip '('. */ >>>>> + if (!lexer_match_id(ctx->lexer, "timeout")) { >>>>> + lexer_syntax_error(ctx->lexer, "invalid parameter"); >>>>> + return; >>>>> + } >>>>> + if (!lexer_force_match(ctx->lexer, LEX_T_EQUALS)) { >>>>> + lexer_syntax_error(ctx->lexer, "invalid parameter"); >>>>> + return; >>>>> + } >>>>> + if (!action_parse_uint16(ctx, &timeout, "fdb_local flow timeout")) { >>>>> + return; >>>>> + } >>>>> + fdb_local->timeout = timeout; >>>>> + lexer_force_match(ctx->lexer, LEX_T_RPAREN); /* Skip ')'. */ >>>>> +} >>>>> + >>>>> +static void >>>>> +format_COMMIT_FDB_LOCAL(const struct ovnact_commit_fdb_local *fdb_local, >>>>> + struct ds *s) >>>>> +{ >>>>> + ds_put_format(s, "commit_fdb_local(timeout=%u);", >>>>> fdb_local->timeout); >>>>> +} >>>>> + >>>>> +static void >>>>> +ovnact_commit_fdb_local_free(struct ovnact_commit_fdb_local *fdb_local >>>>> OVS_UNUSED) >>>>> +{ >>>>> +} >>>>> + >>>>> +static void >>>>> +commit_fdb_local_learn_action(struct ovnact_commit_fdb_local *fdb_local, >>>>> + struct ofpbuf *ofpacts, uint32_t cookie) >>>>> +{ >>>>> + struct ofpact_learn *ol = ofpact_put_LEARN(ofpacts); >>>>> + struct match match = MATCH_CATCHALL_INITIALIZER; >>>>> + struct ofpact_learn_spec *ol_spec; >>>>> + unsigned int imm_bytes; >>>>> + uint8_t *src_imm; >>>>> + >>>>> + ol->flags = NX_LEARN_F_DELETE_LEARNED; >>>>> + ol->idle_timeout = fdb_local->timeout; >>>>> + ol->hard_timeout = OFP_FLOW_PERMANENT; >>>>> + ol->priority = OFP_DEFAULT_PRIORITY; >>>>> + ol->table_id = OFTABLE_GET_FDB; >>>>> + ol->cookie = htonll(cookie); >>>>> + >>>>> + /* Match on metadata of the packet that created the new table. */ >>>>> + ol_spec = ofpbuf_put_zeros(ofpacts, sizeof *ol_spec); >>>>> + ol_spec->dst.field = mf_from_id(MFF_METADATA); >>>>> + ol_spec->dst.ofs = 0; >>>>> + ol_spec->dst.n_bits = ol_spec->dst.field->n_bits; >>>>> + ol_spec->n_bits = ol_spec->dst.n_bits; >>>>> + ol_spec->dst_type = NX_LEARN_DST_MATCH; >>>>> + ol_spec->src_type = NX_LEARN_SRC_FIELD; >>>>> + ol_spec->src.field = mf_from_id(MFF_METADATA); >>>>> + >>>>> + /* Match on metadata of the packet. */ >>>>> + ol_spec = ofpbuf_put_zeros(ofpacts, sizeof *ol_spec); >>>>> + ol_spec->dst.field = mf_from_id(MFF_ETH_DST); >>>>> + ol_spec->dst.ofs = 0; >>>>> + ol_spec->dst.n_bits = ol_spec->dst.field->n_bits; >>>>> + ol_spec->n_bits = ol_spec->dst.n_bits; >>>>> + ol_spec->dst_type = NX_LEARN_DST_MATCH; >>>>> + ol_spec->src_type = NX_LEARN_SRC_FIELD; >>>>> + ol_spec->src.field = mf_from_id(MFF_ETH_SRC); >>>>> + >>>>> + >>>>> + /* Load MFF_LOG_OUTPORT from MFF_IN_PORT. */ >>>>> + ol_spec = ofpbuf_put_zeros(ofpacts, sizeof *ol_spec); >>>>> + ol_spec->dst.field = mf_from_id(MFF_LOG_OUTPORT); >>>>> + ol_spec->dst.ofs = 0; >>>>> + ol_spec->dst.n_bits = ol_spec->dst.field->n_bits; >>>>> + ol_spec->n_bits = ol_spec->dst.n_bits; >>>>> + ol_spec->dst_type = NX_LEARN_DST_LOAD; >>>>> + ol_spec->src_type = NX_LEARN_SRC_FIELD; >>>>> + ol_spec->src.field = mf_from_id(MFF_LOG_INPORT); >>>>> + >>>>> + ofpact_finish_LEARN(ofpacts, &ol); >>>>> +} >>>> >>>> A difference from today's SB.FDB centralized approach is that when >>>> ovn-controller restarts these flows will be cleared, I think. >>>> >>>> Are we OK with that? I think so but if not what are the options to >>>> avoid clearing the local fdb cache on restart? >>>> >>> >>> OVS has to relearn the FDB flows whenever tables are cleared. >>> During this time, packets gets flooded. I need to think about possible >>> options if we want to retain FDB table. >>> >>> Can we take this up as an enhancement in a separate patch >>> once we identify a solution for this ? >>> >> >> Sounds good to me. >> >>>> Another difference with today's approach is that this avoids a >>>> controller action, that's great! >>>> >>>>> + >>>>> +static void >>>>> +encode_COMMIT_FDB_LOCAL(const struct ovnact_commit_fdb_local *fdb_local, >>>>> + const struct ovnact_encode_params *ep, >>>>> + struct ofpbuf *ofpacts) >>>>> +{ >>>>> + commit_fdb_local_learn_action(fdb_local, ofpacts, >>>>> ep->lflow_uuid.parts[0]); >>>>> +} >>>>> + >>>>> static void >>>>> encode_MAC_CACHE_USE(const struct ovnact_null *null OVS_UNUSED, >>>>> const struct ovnact_encode_params *ep, >>>>> @@ -5451,6 +5543,8 @@ parse_action(struct action_context *ctx) >>>>> parse_sample(ctx); >>>>> } else if (lexer_match_id(ctx->lexer, "mac_cache_use")) { >>>>> ovnact_put_MAC_CACHE_USE(ctx->ovnacts); >>>>> + } else if (lexer_match_id(ctx->lexer, "commit_fdb_local")) { >>>>> + parse_commit_fdb_local(ctx, >>>>> ovnact_put_COMMIT_FDB_LOCAL(ctx->ovnacts)); >>>>> } else { >>>>> lexer_syntax_error(ctx->lexer, "expecting action"); >>>>> } >>>>> diff --git a/northd/northd.c b/northd/northd.c >>>>> index d1465ddf7..de18694a0 100644 >>>>> --- a/northd/northd.c >>>>> +++ b/northd/northd.c >>>>> @@ -1834,6 +1834,12 @@ localnet_can_learn_mac(const struct >>>>> nbrec_logical_switch_port *nbsp) >>>>> return smap_get_bool( ->options, "localnet_learn_fdb", false); >>>>> } >>>>> >>>>> +static bool >>>>> +ls_is_fdb_local(const struct nbrec_logical_switch *nbs) >>>>> +{ >>>>> + return smap_get_bool(&nbs->other_config, "fdb_local", false); >>>>> +} >>>>> + >>>> >>>> Personally, I'd prefer if we don't add another config knob and we just >>>> make this the only way FDB works. We could also document that the FDB >>>> SB table should be deprecated. >>>> >>> >>> If we want to make local FDB as default then, I think we need to handle >>> overlay >>> use case as well. Probably, we might have to add a new stage in logical >>> switch >>> egress pipeline to learn FDB entries for packets coming over tunnel (or) >>> something similar. >>> >>> Can we take this up in a separate patch ? >>> >>> >> >> Given that we have a fix already for the original problem you were >> trying to address I would prefer that we avoid adding new config knobs >> and handle both the localnet and overlay cases at the same time. >> > > Sure. > >> OTOH, why is there a difference? >> >> The learned flow loads MFF_LOG_INPORT (from the packet that triggers the >> learn() action) into MFF_LOG_INPORT: >> >> With Geneve and STT overlay MFF_LOG_INPORT is still correctly set. With >> VXLAN that's not the case but that's already a documented limitation, >> LOG_INPORT is not available after VXLAN tunneling therefore features >> that need it (like egress ACLs matching against ingress port >> identifiers) are not supported: >> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_ovn-2Dorg_ovn_blob_main_ovn-2Darchitecture.7.xml-23L2842&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=2PQjSDR7A28z1kXE1ptSm6X36oL_nCq1XxeEt7FkLmA&m=LO8-TXDG00EgnhB_oBbKGhuFWEv1FgwWbp-oMgCaMjsrN1ow1XIgiNdpeQ2FpNyQ&s=AyiJd4NaZd3P4HGvFbMO9No0cO8bux35PJNhtr8ZGe4&e= >> >> > > In case of overlay, ingress and egress pipelines are processed on different > nodes > assuming source and dest VMs are on different nodes. I think this makes local > FDB > to learn only local VMs MACs and it never learn remote VMs MACs. > > Example: > 2 VMs with unknown addr set are connected to same logical switch where vm1 is > on hv1 > and vm2 is on hv2. When vm1 is sending ICMP req packet to vm2, ingress > pipeline happens > on hv1 and it learns vm1-mac and this packet gets flooded since vm2-mac is > not yet learned. > Packet reaches hv2 over tunnel and egress pipeline is exercised on hv2. Now, > when vm2 is > responding back, ingress pipeline happens on hv2 and it learns vm2-mac and > this packet also > gets flooded since vm1-mac is not learnt on hv2 when ICMP req packet is > received. > >
Ah, I see your point, you're right. So it does look like we'd need a dedicated fdb learning stage in the egress pipeline. But that is probably not that terrible. >> One more thing we need to take care of in order to be able to make local >> FDB the default is "FDB refresh": >> >> 551527a5e68e ("controller: Update FDB timestamp") >> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_ovn-2Dorg_ovn_commit_551527a5e68e7233ad80d212d549df98f13e37bc&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=2PQjSDR7A28z1kXE1ptSm6X36oL_nCq1XxeEt7FkLmA&m=LO8-TXDG00EgnhB_oBbKGhuFWEv1FgwWbp-oMgCaMjsrN1ow1XIgiNdpeQ2FpNyQ&s=dNv1oya7S00oKbz1E9i5IyhqDOsEajuutcKSV6bIAfs&e= >> >> > > Sure. > >>>>> static bool >>>>> lsp_is_type_changed(const struct sbrec_port_binding *sb, >>>>> const struct nbrec_logical_switch_port *nbsp, >>>>> @@ -7033,6 +7039,8 @@ build_lswitch_port_sec_op(struct ovn_port *op, >>>>> struct hmap *lflows, >>>>> } >>>>> } >>>>> >>>>> +#define FDB_LOCAL_DEF_IDLE_TIMEOUT_S 300 >>>>> + >>>> >>>> This, on the other hand, might be a good candidate for a config option. >>> >>> “fdb_local_idle_timeout” option is added in this patch to configure the >>> timeout. >>> Default value is 300 secs. >>> >> >> True, I missed that you do that below. However, we already have >> "LS.other_config:fdb_age_threshold" in the NB database to control >> exactly the same thing. I'd just use that one. >> > > Yes, we can reuse the same. > >>>> >>>>> static void >>>>> build_lswitch_learn_fdb_op( >>>>> struct ovn_port *op, struct hmap *lflows, >>>>> @@ -7042,6 +7050,24 @@ build_lswitch_learn_fdb_op( >>>>> >>>>> if (!op->n_ps_addrs && op->has_unknown && (!strcmp(op->nbsp->type, "") >>>>> || >>>>> (lsp_is_localnet(op->nbsp) && localnet_can_learn_mac(op->nbsp)))) { >>>>> + >>>>> + if (ls_is_fdb_local(op->od->nbs)) >>>>> + { >>>>> + uint32_t idle_timeout =smap_get_uint( >>>>> + &op->od->nbs->other_config, >>>>> "fdb_local_idle_timeout", >>>>> + FDB_LOCAL_DEF_IDLE_TIMEOUT_S); >>>>> + ds_clear(match); >>>>> + ds_clear(actions); >>>>> + ds_put_format(match, "inport == %s", op->json_key); >>>>> + ds_put_format(actions, "commit_fdb_local(timeout=%u); next;", >>>>> + idle_timeout); >>>>> + ovn_lflow_add_with_lport_and_hint(lflows, op->od, >>>>> + S_SWITCH_IN_LOOKUP_FDB, >>>>> 100, >>>>> + ds_cstr(match), >>>>> ds_cstr(actions), >>>>> + op->key, >>>>> &op->nbsp->header_); >>>>> + return; >>>>> + } >>>>> + >>>>> 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 fcb1c6ecc..3547ec4a6 100644 >>>>> --- a/ovn-nb.xml >>>>> +++ b/ovn-nb.xml >>>>> @@ -803,6 +803,20 @@ >>>>> </column> >>>>> </group> >>>>> >>>>> + <group title="Local FDB options"> >>>>> + <column name="other_config" key="fdb_local" >>>>> + type='{"type": "boolean"}'> >>>>> + If set to <code>true</code>, FDB flows are commited only to the >>>>> + local chassis instead of southbound DB. Default is false. >>>>> + </column> >>>>> + <column name="other_config" key="fdb_local_idle_timeout" >>>>> + type='{"type": "integer", "minInteger": 0, "maxInteger": >>>>> 65535}'> >>>>> + Local FDB flows <code>idle_timeout</code> value in seconds. FDB >>>>> local >>>>> + flows exceeding this timeout will be automatically removed. The >>>>> value >>>>> + defaults to 300, 0 means disabled. >>>>> + </column> >>>>> + </group> >>>>> + >>>>> <column name="copp"> >>>>> <p> >>>>> The control plane protection policy from table <ref table="Copp"/> >>>>> diff --git a/tests/ovn.at b/tests/ovn.at >>>>> index 92cf27581..dff50364a 100644 >>>>> --- a/tests/ovn.at >>>>> +++ b/tests/ovn.at >>>>> @@ -34504,6 +34504,114 @@ OVN_CLEANUP([hv1]) >>>>> AT_CLEANUP >>>>> ]) >>>>> >>>>> +OVN_FOR_EACH_NORTHD([ >>>>> +AT_SETUP([Local FDB MAC learning]) >>>>> +ovn_start >>>>> +net_add n1 >>>>> + >>>>> +AT_CHECK([ovn-nbctl ls-add ls0]) >>>>> + >>>>> +AT_CHECK([ovn-nbctl lsp-add ls0 vif0]) >>>>> +AT_CHECK([ovn-nbctl lsp-set-addresses vif0 "50:54:00:00:00:03 10.0.0.3" >>>>> "unknown"]) >>>>> +AT_CHECK([ovn-nbctl set logical_switch_port vif0 >>>>> options:requested-tnl-key=2]) >>>>> + >>>>> +AT_CHECK([ovn-nbctl lsp-add ls0 vif1]) >>>>> +AT_CHECK([ovn-nbctl lsp-set-addresses vif1 "50:54:00:00:00:04 10.0.0.4"]) >>>>> +AT_CHECK([ovn-nbctl set logical_switch_port vif1 >>>>> options:requested-tnl-key=3]) >>>>> + >>>>> +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 set logical_switch_port ln_port >>>>> options:localnet_learn_fdb=true]) >>>>> +AT_CHECK([ovn-nbctl set logical_switch_port ln_port >>>>> options:requested-tnl-key=1]) >>>>> + >>>>> +AT_CHECK([ovn-nbctl set logical_switch ls0 other_config:fdb_local=true]) >>>>> + >>>>> +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-int vif1 -- \ >>>>> + set interface vif1 external-ids:iface-id=vif1 \ >>>>> + options:tx_pcap=hv1/vif1-tx.pcap \ >>>>> + options:rxq_pcap=hv1/vif1-rx.pcap \ >>>>> + ofport-request=2 >>>>> +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=3 >>>>> +ovs-vsctl set open . external_ids:ovn-bridge-mappings=physnet1:br-phys >>>>> + >>>>> +wait_for_ports_up >>>>> +AT_CHECK([ovn-nbctl --wait=hv sync]) >>>>> + >>>>> +send_packet() { >>>>> + src_mac=$1 >>>>> + src_ip=$2 >>>>> + dst_mac=$3 >>>>> + dst_ip=$4 >>>>> + iface=$5 >>>>> + >>>>> packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000 >>>>> + ovs-appctl netdev-dummy/receive $iface $packet >>>>> +} >>>>> + >>>>> + >>>>> +# Check that there is commit_fdb_local_fdb() flow added by ovn-northd >>>>> for vif0 and localnet >>>>> +ovn-sbctl dump-flows ls0 > sw0flows >>>>> +AT_CAPTURE_FILE([sw0flows]) >>>>> + >>>>> +AT_CHECK([grep "ls_in_lookup_fdb" sw0flows | sort], [0], [dnl >>>>> + table=2 (ls_in_lookup_fdb ), priority=0 , dnl >>>>> +match=(1), action=(next;) >>>>> + table=2 (ls_in_lookup_fdb ), priority=100 , dnl >>>>> +match=(inport == "ln_port"), action=(commit_fdb_local(timeout=300); >>>>> next;) >>>>> + table=2 (ls_in_lookup_fdb ), priority=100 , dnl >>>>> +match=(inport == "vif0"), action=(commit_fdb_local(timeout=300); next;) >>>>> +]) >>>>> + >>>>> +AT_CHECK([grep "ls_in_put_fdb" sw0flows | sort], [0], [dnl >>>>> + table=3 (ls_in_put_fdb ), priority=0 , dnl >>>>> +match=(1), action=(next;) >>>>> +]) >>>>> + >>>>> + >>>>> +src_mac="505400000003" >>>>> +src_ip=`ip_to_hex 10.0.0.3` >>>>> +dst_mac="505400000004" >>>>> +dst_ip=`ip_to_hex 10.0.0.4` >>>>> + >>>>> +# send packet from vif0(which has unknown addr set) to vif1 >>>>> +send_packet $src_mac $src_ip $dst_mac $dst_ip vif0 >>>>> + >>>>> +# send packet from vif1 to vif0(which has unknown addr set) >>>>> +send_packet $dst_mac $dst_ip $src_mac $src_ip vif1 >>>>> + >>>>> +# send packet from underlay to vif1 >>>>> +src_mac="505400000064" >>>>> +src_ip=`ip_to_hex 10.0.0.100` >>>>> +send_packet $src_mac $src_ip $dst_mac $dst_ip ext0 >>>>> +AT_CHECK([ovn-nbctl --wait=hv sync]) >>>>> + >>>>> +# Make sure that OVS table 71 is populated on hv1. >>>>> +AS_BOX([Check that ovn-controller programs the flows for FDB]) >>>>> +as hv1 ovs-ofctl dump-flows br-int table=71 > hv1_offlows_table71.txt >>>>> +AT_CAPTURE_FILE([hv1_offlows_table71.txt]) >>>>> +AT_CHECK([cat hv1_offlows_table71.txt | grep -v NXST | cut -d ' ' -f7- | >>>>> sort], [0], [dnl >>>>> +idle_timeout=300, idle_age=0, metadata=0x1,dl_dst=50:54:00:00:00:03 >>>>> actions=load:0x2->NXM_NX_REG15[[]] >>>>> +idle_timeout=300, idle_age=0, metadata=0x1,dl_dst=50:54:00:00:00:64 >>>>> actions=load:0x1->NXM_NX_REG15[[]] >>>>> +]) >>>>> + >>>>> +OVN_CLEANUP([hv1]) >>>>> +AT_CLEANUP >>>>> +]) >>>>> + >>>>> OVN_FOR_EACH_NORTHD([ >>>>> AT_SETUP([MAC binding aging]) >>>>> AT_SKIP_IF([test $HAVE_SCAPY = no]) >>>>> diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c >>>>> index 0b86eae7b..354f84a4b 100644 >>>>> --- a/utilities/ovn-trace.c >>>>> +++ b/utilities/ovn-trace.c >>>>> @@ -3355,6 +3355,8 @@ trace_actions(const struct ovnact *ovnacts, size_t >>>>> ovnacts_len, >>>>> break; >>>>> case OVNACT_MAC_CACHE_USE: >>>>> break; >>>>> + case OVNACT_COMMIT_FDB_LOCAL: >>>>> + break; >>>>> } >>>>> } >>>>> ofpbuf_uninit(&stack); >>>> >> >> Regards, >> Dumitru > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev