static void init_buffered_packets_map(void);
static void destroy_buffered_packets_map(void);
+static void
+run_buffered_binding(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+ const struct hmap *local_datapaths)
+ OVS_REQUIRES(pinctrl_mutex);
static void pinctrl_handle_put_mac_binding(const struct flow *md,
const struct flow *headers,
OVS_REQUIRES(pinctrl_mutex);
static void wait_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn);
static void flush_put_mac_bindings(void);
-static void buffer_put_mac_bindings(void);
-static void destroy_buffered_mac_bindings(void);
static void send_mac_binding_buffered_pkts(struct rconn *swconn)
OVS_REQUIRES(pinctrl_mutex);
/* key */
struct in6_addr ip;
+ struct eth_addr ea;
long long int timestamp;
};
static struct hmap buffered_packets_map;
+static struct hmap buffered_mac_bindings;
static void
init_buffered_packets_map(void)
{
hmap_init(&buffered_packets_map);
+ hmap_init(&buffered_mac_bindings);
}
static void
-destroy_buffered_packets(struct buffered_packets *bp)
+destroy_buffered_packets(struct buffered_packets *bp, struct hmap *map)
{
struct buffer_info *bi;
bp->head = (bp->head + 1) % BUFFER_QUEUE_DEPTH;
}
- hmap_remove(&buffered_packets_map, &bp->hmap_node);
+ hmap_remove(map, &bp->hmap_node);
free(bp);
}
{
struct buffered_packets *bp, *next;
HMAP_FOR_EACH_SAFE (bp, next, hmap_node, &buffered_packets_map) {
- destroy_buffered_packets(bp);
+ destroy_buffered_packets(bp, &buffered_packets_map);
}
hmap_destroy(&buffered_packets_map);
+
+ HMAP_FOR_EACH_SAFE (bp, next, hmap_node, &buffered_mac_bindings) {
+ destroy_buffered_packets(bp, &buffered_mac_bindings);
+ }
+ hmap_destroy(&buffered_mac_bindings);
}
static void
HMAP_FOR_EACH_SAFE (cur_qp, next_qp, hmap_node, &buffered_packets_map) {
if (now > cur_qp->timestamp + BUFFER_MAP_TIMEOUT) {
- destroy_buffered_packets(cur_qp);
+ destroy_buffered_packets(cur_qp, &buffered_packets_map);
}
}
}
}
}
- buffered_packets_map_gc();
rconn_run_wait(swconn);
rconn_recv_wait(swconn);
send_garp_wait(send_garp_time);
prepare_ipv6_ras(sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name, local_datapaths);
sync_dns_cache(dns_table);
+ run_buffered_binding(sbrec_port_binding_by_datapath,
+ sbrec_mac_binding_by_lport_ip,
+ local_datapaths);
ovs_mutex_unlock(&pinctrl_mutex);
}
destroy_ipv6_ras();
destroy_buffered_packets_map();
destroy_put_mac_bindings();
- destroy_buffered_mac_bindings();
destroy_dns_cache();
seq_destroy(pinctrl_main_seq);
seq_destroy(pinctrl_handler_seq);
/* Contains "struct put_mac_binding"s. */
static struct hmap put_mac_bindings;
-static struct hmap buffered_mac_bindings;
static void
init_put_mac_bindings(void)
{
hmap_init(&put_mac_bindings);
- hmap_init(&buffered_mac_bindings);
}
static void
hmap_destroy(&put_mac_bindings);
}
-static void
-destroy_buffered_mac_bindings(void)
-{
- struct put_mac_binding *pmb;
- HMAP_FOR_EACH_POP (pmb, hmap_node, &buffered_mac_bindings) {
- free(pmb);
- }
-
- hmap_destroy(&buffered_mac_bindings);
-}
-
static struct put_mac_binding *
pinctrl_find_put_mac_binding(uint32_t dp_key, uint32_t port_key,
const struct in6_addr *ip_key, uint32_t hash)
send_mac_binding_buffered_pkts(struct rconn *swconn)
OVS_REQUIRES(pinctrl_mutex)
{
- struct put_mac_binding *pmb;
struct buffered_packets *bp;
- HMAP_FOR_EACH_POP (pmb, hmap_node, &buffered_mac_bindings) {
- uint32_t bhash = hash_bytes(&pmb->ip_key, sizeof pmb->ip_key, 0);
-
- bp = pinctrl_find_buffered_packets(&pmb->ip_key, bhash);
- if (bp) {
- buffered_send_packets(swconn, bp, &pmb->mac);
- }
-
- free(pmb);
+ HMAP_FOR_EACH_POP (bp, hmap_node, &buffered_mac_bindings) {
+ buffered_send_packets(swconn, bp, &bp->ea);
+ free(bp);
}
}
sbrec_mac_binding_by_lport_ip,
pmb);
}
+}
+
+static void
+run_buffered_binding(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+ const struct hmap *local_datapaths)
+ OVS_REQUIRES(pinctrl_mutex)
+{
+ const struct local_datapath *ld;
+ bool notify = false;
+
+ HMAP_FOR_EACH (ld, hmap_node, local_datapaths) {
+ struct sbrec_port_binding *target = sbrec_port_binding_index_init_row(
+ sbrec_port_binding_by_datapath);
+ sbrec_port_binding_index_set_datapath(target, ld->datapath);
+
+ const struct sbrec_port_binding *pb;
+ SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
+ sbrec_port_binding_by_datapath) {
+ struct buffered_packets *cur_qp, *next_qp;
+ HMAP_FOR_EACH_SAFE (cur_qp, next_qp, hmap_node,
+ &buffered_packets_map) {
+ struct ds ip_s = DS_EMPTY_INITIALIZER;
+ ipv6_format_mapped(&cur_qp->ip, &ip_s);
+ const struct sbrec_mac_binding *b = mac_binding_lookup(
+ sbrec_mac_binding_by_lport_ip, pb->logical_port,
+ ds_cstr(&ip_s));
+ if (b && ovs_scan(b->mac, ETH_ADDR_SCAN_FMT,
+ ETH_ADDR_SCAN_ARGS(cur_qp->ea))) {
+ uint32_t hash = hash_bytes(&cur_qp->ip,
+ sizeof cur_qp->ip, 0);
+ hmap_remove(&buffered_packets_map, &cur_qp->hmap_node);
+ hmap_insert(&buffered_mac_bindings, &cur_qp->hmap_node,
+ hash);
+ notify = true;
+ }
+ ds_destroy(&ip_s);
+ }
+ }
+ sbrec_port_binding_index_destroy_row(target);
+ }
+ buffered_packets_map_gc();
- /* Move the mac bindings from 'put_mac_bindings' hmap to
- * 'buffered_mac_bindings' and notify the pinctrl_handler.
- * pinctrl_handler will reinject the buffered packets. */
- if (!hmap_is_empty(&put_mac_bindings)) {
- buffer_put_mac_bindings();
+ if (notify) {
notify_pinctrl_handler();
}
}
}
}
-static void
-buffer_put_mac_bindings(void)
-{
- struct put_mac_binding *pmb;
- HMAP_FOR_EACH_POP (pmb, hmap_node, &put_mac_bindings) {
- uint32_t hash = hash_bytes(&pmb->ip_key, sizeof pmb->ip_key,
- hash_2words(pmb->dp_key, pmb->port_key));
- hmap_insert(&buffered_mac_bindings, &pmb->hmap_node, hash);
- }
-}
-
static void
flush_put_mac_bindings(void)
{