[...]
> > + mac_cache_update_req_delay(&cache_data->thresholds, req_delay);
> > + *req_delay = *req_delay / 2;
> > + if (*req_delay) {
> > + VLOG_DBG("MAC probe binding statistics dalay: %"PRIu64,
> > *req_delay);
>
> s/dalay/delay/
ack, I will fix it in v2.
>
> > + }
> > +}
> > diff --git a/controller/mac-cache.h b/controller/mac-cache.h
> > index 40d7b9c25..eb2ad7b55 100644
> > --- a/controller/mac-cache.h
> > +++ b/controller/mac-cache.h
> > @@ -70,6 +70,10 @@ struct mac_binding {
> > const struct sbrec_mac_binding *sbrec;
> > /* User specified timestamp (in ms) */
> > long long timestamp;
> > + /* SB MAC binding logical port address. */
> > + struct lport_addresses laddr;
> > + /* SB Port binding tunnel key. */
> > + int64_t tunnel_key;
> > };
> > struct fdb_data {
> > @@ -147,7 +151,9 @@ mac_binding_data_init(struct mac_binding_data *data,
> > }
> > void mac_binding_add(struct hmap *map, struct mac_binding_data mb_data,
> > - const struct sbrec_mac_binding *, long long
> > timestamp);
> > + const struct sbrec_mac_binding *smb,
> > + const struct sbrec_port_binding *pb,
> > + long long timestamp);
> > void mac_binding_remove(struct hmap *map, struct mac_binding *mb);
> > @@ -180,15 +186,17 @@ void
> > mac_binding_stats_process_flow_stats(struct ovs_list *stats_list,
> > struct ofputil_flow_stats
> > *ofp_stats);
> > -void mac_binding_stats_run(struct ovs_list *stats_list, uint64_t
> > *req_delay,
> > - void *data);
> > +void mac_binding_stats_run(struct rconn *swconn OVS_UNUSED,
> > + struct ovs_list *stats_list,
> > + uint64_t *req_delay, void *data);
> > /* FDB stat processing. */
> > void fdb_stats_process_flow_stats(struct ovs_list *stats_list,
> > struct ofputil_flow_stats *ofp_stats);
> > -void fdb_stats_run(struct ovs_list *stats_list, uint64_t *req_delay,
> > - void *data);
> > +void fdb_stats_run(struct rconn *swconn OVS_UNUSED,
> > + struct ovs_list *stats_list,
> > + uint64_t *req_delay, void *data);
> > void mac_cache_stats_destroy(struct ovs_list *stats_list);
> > @@ -221,4 +229,12 @@ bool buffered_packets_ctx_is_ready_to_send(struct
> > buffered_packets_ctx *ctx);
> > bool buffered_packets_ctx_has_packets(struct buffered_packets_ctx *ctx);
> > +void mac_binding_probe_stats_process_flow_stats(
> > + struct ovs_list *stats_list,
> > + struct ofputil_flow_stats *ofp_stats);
> > +
> > +void mac_binding_probe_stats_run(struct rconn *swconn,
> > + struct ovs_list *stats_list,
> > + uint64_t *req_delay, void *data);
> > +
> > #endif /* controller/mac-cache.h */
> > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> > index 081411cba..5749f316b 100644
> > --- a/controller/ovn-controller.c
> > +++ b/controller/ovn-controller.c
> > @@ -3054,14 +3054,17 @@ en_lb_data_cleanup(void *data)
> > static void
> > mac_binding_add_sb(struct mac_cache_data *data,
> > - const struct sbrec_mac_binding *smb)
> > + const struct sbrec_mac_binding *smb,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name)
> > {
> > struct mac_binding_data mb_data;
> > if (!mac_binding_data_from_sbrec(&mb_data, smb)) {
> > return;
> > }
> > - mac_binding_add(&data->mac_bindings, mb_data, smb, 0);
> > + const struct sbrec_port_binding *pb = lport_lookup_by_name(
> > + sbrec_port_binding_by_name, smb->logical_port);
> > + mac_binding_add(&data->mac_bindings, mb_data, smb, pb, 0);
> > }
> > static void
> > @@ -3113,7 +3116,8 @@ fdb_remove_sb(struct mac_cache_data *data, const
> > struct sbrec_fdb *sfdb)
> > static void
> > mac_cache_mb_handle_for_datapath(struct mac_cache_data *data,
> > const struct sbrec_datapath_binding *dp,
> > - struct ovsdb_idl_index *sbrec_mb_by_dp)
> > + struct ovsdb_idl_index *sbrec_mb_by_dp,
> > + struct ovsdb_idl_index *sbrec_pb_by_name)
> > {
> > bool has_threshold = mac_cache_threshold_find(data, dp->tunnel_key);
> > @@ -3124,7 +3128,7 @@ mac_cache_mb_handle_for_datapath(struct
> > mac_cache_data *data,
> > const struct sbrec_mac_binding *mb;
> > SBREC_MAC_BINDING_FOR_EACH_EQUAL (mb, mb_index_row, sbrec_mb_by_dp) {
> > if (has_threshold) {
> > - mac_binding_add_sb(data, mb);
> > + mac_binding_add_sb(data, mb, sbrec_pb_by_name);
> > } else {
> > mac_binding_remove_sb(data, mb);
> > }
> > @@ -3185,6 +3189,10 @@ en_mac_cache_run(struct engine_node *node, void
> > *data)
> > engine_ovsdb_node_get_index(
> > engine_get_input("SB_fdb", node),
> > "dp_key");
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name =
> > + engine_ovsdb_node_get_index(
> > + engine_get_input("SB_port_binding", node),
> > + "name");
> > mac_cache_thresholds_clear(cache_data);
> > mac_bindings_clear(&cache_data->mac_bindings);
> > @@ -3199,7 +3207,8 @@ en_mac_cache_run(struct engine_node *node, void *data)
> > mac_cache_threshold_add(cache_data, sbrec_dp);
> > mac_cache_mb_handle_for_datapath(cache_data, sbrec_dp,
> > - sbrec_mb_by_dp);
> > + sbrec_mb_by_dp,
> > + sbrec_port_binding_by_name);
> > mac_cache_fdb_handle_for_datapath(cache_data, sbrec_dp,
> > sbrec_fdb_by_dp_key);
> > }
> > @@ -3216,6 +3225,10 @@ mac_cache_sb_mac_binding_handler(struct engine_node
> > *node, void *data)
> > const struct sbrec_mac_binding_table *mb_table =
> > EN_OVSDB_GET(engine_get_input("SB_mac_binding", node));
> > size_t previous_size = hmap_count(&cache_data->mac_bindings);
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name =
> > + engine_ovsdb_node_get_index(
> > + engine_get_input("SB_port_binding", node),
> > + "name");
> > const struct sbrec_mac_binding *sbrec_mb;
> > SBREC_MAC_BINDING_TABLE_FOR_EACH_TRACKED (sbrec_mb, mb_table) {
> > @@ -3231,7 +3244,8 @@ mac_cache_sb_mac_binding_handler(struct engine_node
> > *node, void *data)
> > if (mac_cache_threshold_find(cache_data,
> > sbrec_mb->datapath->tunnel_key)) {
> > - mac_binding_add_sb(cache_data, sbrec_mb);
> > + mac_binding_add_sb(cache_data, sbrec_mb,
> > + sbrec_port_binding_by_name);
> > }
> > }
> > @@ -3292,6 +3306,10 @@ mac_cache_runtime_data_handler(struct engine_node
> > *node, void *data OVS_UNUSED)
> > engine_ovsdb_node_get_index(
> > engine_get_input("SB_fdb", node),
> > "dp_key");
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name =
> > + engine_ovsdb_node_get_index(
> > + engine_get_input("SB_port_binding", node),
> > + "name");
> > /* There are no tracked data. Fall back to full recompute. */
> > if (!rt_data->tracked) {
> > @@ -3312,7 +3330,8 @@ mac_cache_runtime_data_handler(struct engine_node
> > *node, void *data OVS_UNUSED)
> > HMAP_FOR_EACH (tdp, node, &rt_data->tracked_dp_bindings) {
> > mac_cache_mb_handle_for_datapath(cache_data, tdp->dp,
> > - sbrec_mb_by_dp);
> > + sbrec_mb_by_dp,
> > + sbrec_port_binding_by_name);
> > mac_cache_fdb_handle_for_datapath(cache_data, tdp->dp,
> > sbrec_fdb_by_dp_key);
> > @@ -3342,6 +3361,10 @@ mac_cache_sb_datapath_binding_handler(struct
> > engine_node *node, void *data)
> > engine_ovsdb_node_get_index(
> > engine_get_input("SB_fdb", node),
> > "dp_key");
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name =
> > + engine_ovsdb_node_get_index(
> > + engine_get_input("SB_port_binding", node),
> > + "name");
> > size_t previous_mb_size = hmap_count(&cache_data->mac_bindings);
> > size_t previous_fdb_size = hmap_count(&cache_data->fdbs);
> > @@ -3365,7 +3388,8 @@ mac_cache_sb_datapath_binding_handler(struct
> > engine_node *node, void *data)
> > SBREC_DATAPATH_BINDING_TABLE_FOR_EACH_TRACKED (sbrec_dp, dp_table) {
> > mac_cache_mb_handle_for_datapath(cache_data, sbrec_dp,
> > - sbrec_mb_by_dp);
> > + sbrec_mb_by_dp,
> > + sbrec_port_binding_by_name);
> > mac_cache_fdb_handle_for_datapath(cache_data, sbrec_dp,
> > sbrec_fdb_by_dp_key);
> > diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> > index 47c4bf78b..1957ff771 100644
> > --- a/controller/pinctrl.c
> > +++ b/controller/pinctrl.c
> > @@ -4718,7 +4718,7 @@ pinctrl_handle_put_mac_binding(const struct flow *md,
> > ? random_range(MAX_MAC_BINDING_DELAY_MSEC) + 1
> > : 0;
> > long long timestamp = time_msec() + delay;
> > - mac_binding_add(&put_mac_bindings, mb_data, NULL, timestamp);
> > + mac_binding_add(&put_mac_bindings, mb_data, NULL, NULL, timestamp);
> > /* We can send the buffered packet once the main ovn-controller
> > * thread calls pinctrl_run() and it writes the mac_bindings stored
> > @@ -4924,7 +4924,7 @@ run_buffered_binding(const struct
> > sbrec_mac_binding_table *mac_binding_table,
> > continue;
> > }
> > - mac_binding_add(&recent_mbs, mb_data, smb, 0);
> > + mac_binding_add(&recent_mbs, mb_data, smb, pb, 0);
> > const char *redirect_port =
> > smap_get(&pb->options, "chassis-redirect-port");
> > @@ -4941,7 +4941,7 @@ run_buffered_binding(const struct
> > sbrec_mac_binding_table *mac_binding_table,
> > /* Add the same entry also for chassisredirect port as the
> > buffered
> > * traffic might be buffered on the cr port. */
> > mb_data.port_key = pb->tunnel_key;
> > - mac_binding_add(&recent_mbs, mb_data, smb, 0);
> > + mac_binding_add(&recent_mbs, mb_data, smb, NULL, 0);
> > }
> > buffered_packets_ctx_run(&buffered_packets_ctx, &recent_mbs,
> > @@ -5303,7 +5303,7 @@ send_garp_rarp_delete(const char *lport)
> > notify_pinctrl_handler();
> > }
> > -static void
> > +void
> > send_self_originated_neigh_packet(struct rconn *swconn,
> > uint32_t dp_key, uint32_t port_key,
> > struct eth_addr eth,
> > diff --git a/controller/pinctrl.h b/controller/pinctrl.h
> > index 8459f4f53..e33d7cbf5 100644
> > --- a/controller/pinctrl.h
> > +++ b/controller/pinctrl.h
> > @@ -31,6 +31,7 @@ struct ovsdb_idl_index;
> > struct ovsdb_idl_txn;
> > struct ovsrec_bridge;
> > struct ovsrec_open_vswitch_table;
> > +struct rconn;
> > struct sbrec_chassis;
> > struct sbrec_dns_table;
> > struct sbrec_controller_event_table;
> > @@ -77,4 +78,10 @@ struct activated_port {
> > void tag_port_as_activated_in_engine(struct activated_port *ap);
> > struct ovs_list *get_ports_to_activate_in_engine(void);
> > bool pinctrl_is_port_activated(int64_t dp_key, int64_t port_key);
> > +void send_self_originated_neigh_packet(struct rconn *swconn,
> > + uint32_t dp_key, uint32_t port_key,
> > + struct eth_addr eth,
> > + struct in6_addr *local,
> > + struct in6_addr *target,
> > + uint8_t table_id);
> > #endif /* controller/pinctrl.h */
> > diff --git a/controller/statctrl.c b/controller/statctrl.c
> > index d3c70ccba..6052d2884 100644
> > --- a/controller/statctrl.c
> > +++ b/controller/statctrl.c
> > @@ -39,6 +39,7 @@ VLOG_DEFINE_THIS_MODULE(statctrl);
> > enum stat_type {
> > STATS_MAC_BINDING = 0,
> > STATS_FDB,
> > + STATS_MAC_BINDING_PROBE,
> > STATS_MAX,
> > };
> > @@ -62,7 +63,8 @@ struct stats_node {
> > struct ofputil_flow_stats *ofp_stats);
> > /* Function to process the parsed stats.
> > * This function runs in main thread locked behind mutex. */
> > - void (*run)(struct ovs_list *stats_list, uint64_t *req_delay, void
> > *data);
> > + void (*run)(struct rconn *swconn, struct ovs_list *stats_list,
> > + uint64_t *req_delay, void *data);
> > };
> > #define STATS_NODE(NAME, REQUEST, DESTROY, PROCESS, RUN)
> > \
> > @@ -145,6 +147,18 @@ statctrl_init(void)
> > STATS_NODE(FDB, fdb_request, mac_cache_stats_destroy,
> > fdb_stats_process_flow_stats, fdb_stats_run);
> > + struct ofputil_flow_stats_request mac_binding_probe_request = {
> > + .cookie = htonll(0),
> > + .cookie_mask = htonll(0),
> > + .out_port = OFPP_ANY,
> > + .out_group = OFPG_ANY,
> > + .table_id = OFTABLE_MAC_BINDING,
> > + };
> > + STATS_NODE(MAC_BINDING_PROBE, mac_binding_probe_request,
> > + mac_cache_stats_destroy,
> > + mac_binding_probe_stats_process_flow_stats,
> > + mac_binding_probe_stats_run);
> > +
> > statctrl_ctx.thread = ovs_thread_create("ovn_statctrl",
> > statctrl_thread_handler,
> > &statctrl_ctx);
> > @@ -158,7 +172,11 @@ statctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
> > return;
> > }
> > - void *node_data[STATS_MAX] = {mac_cache_data, mac_cache_data};
> > + void *node_data[STATS_MAX] = {
> > + mac_cache_data,
> > + mac_cache_data,
> > + mac_cache_data
> > + };
> > bool schedule_updated = false;
> > long long now = time_msec();
> > @@ -168,7 +186,8 @@ statctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
> > struct stats_node *node = &statctrl_ctx.nodes[i];
> > uint64_t prev_delay = node->request_delay;
> > - node->run(&node->stats_list, &node->request_delay, node_data[i]);
> > + node->run(statctrl_ctx.swconn, &node->stats_list,
> > + &node->request_delay, node_data[i]);
> > schedule_updated |=
> > statctrl_update_next_request_timestamp(node, now,
> > prev_delay);
> > diff --git a/tests/ovn.at b/tests/ovn.at
> > index 1889f5202..d81f22f3c 100644
> > --- a/tests/ovn.at
> > +++ b/tests/ovn.at
> > @@ -35862,10 +35862,106 @@ done
> > uuid2=$(fetch_column mac_binding _uuid ip="192.168.10.10"
> > logical_port="lr-ls1")
> > check test "$uuid" = "$uuid2"
> > -# The other entry must have expired by now.
> > -check_row_count mac_binding 0 ip="192.168.20.10" logical_port="lr-ls2"
> > -# Wait for the alive one to expire as well.
> > -wait_row_count mac_binding 0 ip="192.168.10.10" logical_port="lr-ls1"
> > +wait_row_count mac_binding 0
> > +
> > +OVN_CLEANUP([hv1])
> > +AT_CLEANUP
> > +])
> > +
> > +OVN_FOR_EACH_NORTHD([
> > +AT_SETUP([MAC binding aging - probing])
> > +AT_SKIP_IF([test $HAVE_SCAPY = no])
> > +ovn_start
> > +
> > +send_udp() {
> > + local hv=$1 dev=$2 hdst=$3 hsrc=$4 idst=$5 isrc=$6
> > + local packet=$(fmt_pkt "Ether(dst='${hdst}', src='${hsrc}')/ \
> > + IP(dst='${idst}', src='${isrc}')/UDP()")
> > + as $hv ovs-appctl netdev-dummy/receive $dev $packet
> > +}
> > +
> > +net_add n1
> > +sim_add hv1
> > +as hv1
> > +check ovs-vsctl add-br br-phys
> > +ovn_attach n1 br-phys 192.168.0.1
> > +ovn-appctl -t ovn-controller vlog/set mac_cache:file:dbg pinctrl:file:dbg
> > +
> > +check ovn-nbctl \
> > + -- ls-add ls1 \
> > + -- ls-add ls2 \
> > + -- lr-add lr \
> > + -- set logical_router lr options:mac_binding_age_threshold=15 \
> > + -- lrp-add lr lr-ls1 00:00:00:00:10:00 192.168.10.1/24 \
> > + -- lrp-add lr lr-ls2 00:00:00:00:20:00 192.168.20.1/24 \
> > + -- lsp-add ls1 ls1-lr \
> > + -- lsp-set-type ls1-lr router \
> > + -- lsp-set-addresses ls1-lr router \
> > + -- lsp-set-options ls1-lr router-port=lr-ls1 \
> > + -- lsp-add ls1 vif1 \
> > + -- lsp-set-addresses vif1 "unknown" \
> > + -- lsp-add ls2 ls2-lr \
> > + -- lsp-set-type ls2-lr router \
> > + -- lsp-set-addresses ls2-lr router \
> > + -- lsp-set-options ls2-lr router-port=lr-ls2 \
> > + -- lsp-add ls2 vif2 \
> > + -- lsp-set-addresses vif2 "unknown"
> > +
> > +check 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
> > \
> > + -- add-port br-int vif2
> > \
> > + -- set interface vif2 external-ids:iface-id=vif2
> > \
> > + options:tx_pcap=hv1/vif2-tx.pcap options:rxq_pcap=hv1/vif2-rx.pcap
> > +
> > +OVN_POPULATE_ARP
> > +wait_for_ports_up
> > +check ovn-nbctl --wait=hv sync
> > +
> > +dnl Wait for pinctrl thread to be connected.
> > +OVS_WAIT_UNTIL([grep pinctrl hv1/ovn-controller.log | grep -q connected])
> > +
> > +send_garp hv1 vif1 2 00:00:00:00:10:1a ff:ff:ff:ff:ff:ff 192.168.10.100
> > 192.168.10.100
> > +wait_row_count mac_binding 1 ip="192.168.10.100" logical_port="lr-ls1"
> > +
> > +send_garp hv1 vif2 2 00:00:00:00:10:1b ff:ff:ff:ff:ff:ff 192.168.20.100
> > 192.168.20.100
> > +wait_row_count mac_binding 1 ip="192.168.20.100" logical_port="lr-ls2"
> > +
> > +# Send UDP traffic to create entries in OFTABLE_MAC_BINDING
> > +send_udp hv1 vif1 00:00:00:00:10:00 00:00:00:00:10:1a 192.168.20.100
> > 192.168.10.100
> > +echo
> > '00000000101b00000000200008004500001c000100003f11dbb7c0a80a64c0a814640035003500085f5b'
> > > expected2
>
> Can you use fmt_pkt() for these expected packets? It makes it much easier to
> understand the test.
ack, I will fix it in v2.
Regards,
Lorenzo
>
> > +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected2])
> > +
> > +send_udp hv1 vif2 00:00:00:00:20:00 00:00:00:00:10:1b 192.168.10.100
> > 192.168.20.100
> > +echo
> > '00000000101a00000000100008004500001c000100003f11dbb7c0a81464c0a80a640035003500085f5b'
> > > expected1
> > +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected1])
> > +
> > +OVS_WAIT_UNTIL([$(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_BINDING | \
> > + sed
> > 's/reg15=0x.,metadata=0x./reg15=<cleared>,metadata=<cleared>/g' | \
> > + grep -q
> > "reg0=0xc0a80a64,reg15=<cleared>,metadata=<cleared>
> > actions=mod_dl_dst:00:00:00:00:10:1a")])
> > +OVS_WAIT_UNTIL([$(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_BINDING | \
> > + sed
> > 's/reg15=0x.,metadata=0x./reg15=<cleared>,metadata=<cleared>/g' | \
> > + grep -q
> > "reg0=0xc0a81464,reg15=<cleared>,metadata=<cleared>
> > actions=mod_dl_dst:00:00:00:00:10:1b")])
> > +
> > +ts0=$(fetch_column Mac_Binding timestamp ip=192.168.10.100)
> > +# Wait for ARP requests to be generated.
> > +echo
> > "ffffffffffff00000000100008060001080006040001000000001000c0a80a01000000000000c0a80a64"
> > >> expected1
> > +OVN_CHECK_PACKETS_CONTAIN([hv1/vif1-tx.pcap], [expected1])
> > +# Check MAC_Binding timestamp is updated receiving the ARP replay.
> > +send_garp hv1 vif1 2 00:00:00:00:10:1a 00:00:00:00:10:00 192.168.10.100
> > 192.168.10.1
> > +OVS_WAIT_UNTIL([test $(fetch_column Mac_Binding timestamp
> > ip=192.168.10.100) -gt $ts0])
> > +# Refresh OFTABLE_MAC_BINDING entires.
> > +send_udp hv1 vif1 00:00:00:00:10:00 00:00:00:00:10:1a 192.168.20.100
> > 192.168.10.100
> > +send_udp hv1 vif2 00:00:00:00:20:00 00:00:00:00:10:1b 192.168.10.100
> > 192.168.20.100
> > +
> > +echo
> > "ffffffffffff00000000100008060001080006040001000000001000c0a80a01000000000000c0a80a64"
> > >> expected1
> > +wait_row_count mac_binding 0 ip="192.168.10.100" logical_port="lr-ls1"
> > +OVN_CHECK_PACKETS_CONTAIN([hv1/vif1-tx.pcap], [expected1])
> > +
> > +echo
> > "ffffffffffff00000000200008060001080006040001000000002000c0a81401000000000000c0a81464"
> > >> expected2
> > +wait_row_count mac_binding 0 ip="192.168.20.100" logical_port="lr-ls2"
> > +OVN_CHECK_PACKETS_CONTAIN([hv1/vif2-tx.pcap], [expected2])
> > OVN_CLEANUP([hv1])
> > AT_CLEANUP
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev