Skip to content

Commit

Permalink
OVN: fix pinctrl ip buffering for gw router port
Browse files Browse the repository at this point in the history
Use sb mac binding table to trigger ip buffer dequeueing instead of
the APR/ND packet reception since the ARP reply can be managed on a
different chassis if a gw router port is scheduled on a different
node

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
LorenzoBianconi authored and ovsrobot committed May 7, 2019
1 parent 21ffe40 commit 2d7aca1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 52 deletions.
113 changes: 66 additions & 47 deletions ovn/controller/pinctrl.c
Expand Up @@ -149,6 +149,11 @@ static struct pinctrl pinctrl;

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,
Expand All @@ -164,8 +169,6 @@ static void run_put_mac_bindings(
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);

Expand Down Expand Up @@ -321,6 +324,7 @@ struct buffered_packets {

/* key */
struct in6_addr ip;
struct eth_addr ea;

long long int timestamp;

Expand All @@ -329,15 +333,17 @@ struct buffered_packets {
};

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;

Expand All @@ -348,7 +354,7 @@ destroy_buffered_packets(struct buffered_packets *bp)

bp->head = (bp->head + 1) % BUFFER_QUEUE_DEPTH;
}
hmap_remove(&buffered_packets_map, &bp->hmap_node);
hmap_remove(map, &bp->hmap_node);
free(bp);
}

Expand All @@ -357,9 +363,14 @@ destroy_buffered_packets_map(void)
{
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
Expand Down Expand Up @@ -426,7 +437,7 @@ buffered_packets_map_gc(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);
}
}
}
Expand Down Expand Up @@ -1851,7 +1862,6 @@ pinctrl_handler(void *arg_)
}
}

buffered_packets_map_gc();
rconn_run_wait(swconn);
rconn_recv_wait(swconn);
send_garp_wait(send_garp_time);
Expand Down Expand Up @@ -1903,6 +1913,9 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
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);
}

Expand Down Expand Up @@ -2249,7 +2262,6 @@ pinctrl_destroy(void)
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);
Expand Down Expand Up @@ -2283,13 +2295,11 @@ struct put_mac_binding {

/* 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
Expand All @@ -2299,17 +2309,6 @@ destroy_put_mac_bindings(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)
Expand Down Expand Up @@ -2372,17 +2371,10 @@ static void
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);
}
}

Expand Down Expand Up @@ -2472,12 +2464,50 @@ run_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn,
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();
}
}
Expand All @@ -2490,17 +2520,6 @@ wait_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn)
}
}

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)
{
Expand Down
11 changes: 6 additions & 5 deletions tests/ovn.at
Expand Up @@ -2883,11 +2883,10 @@ for is in 1 2 3; do
echo $arp >> $id$jd2$kd.expected
done
done
if test $(vif_to_hv ${is}${js}${ks}) = $(vif_to_hv ${id}${jd}1); then
hmac=8000000000$o4
rmac=00000000ff$id$jd
echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
fi

hmac=8000000000$o4
rmac=00000000ff$id$jd
echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected

host_mac=8000000000$o4
lrmac=00000000ff$id$jd
Expand Down Expand Up @@ -3207,6 +3206,8 @@ sha=f00000000012
test_arp 12 $sha $spa $tpa
OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
ovn-nbctl --wait=hv sync
# give to the hv the time to send queued ip packets
sleep 1

# Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.

Expand Down

0 comments on commit 2d7aca1

Please sign in to comment.