Skip to content

Commit 77eb3e4

Browse files
mkp-rhigsilya
authored andcommitted
bond: Always revalidate unbalanced bonds when active member changes.
Currently a bond will not always revalidate when an active member changes. This can result in counter-intuitive behaviors like the fact that using ovs-appctl bond/set-active-member will cause the bond to revalidate but changing other_config:bond-primary will not trigger a revalidate in the bond. When revalidation is not set but the active member changes in an unbalanced bond, OVS may send traffic out of previously active member instead of the new active member. This change will always mark unbalanced bonds for revalidation if the active member changes. Reported-at: https://issues.redhat.com/browse/FDP-845 Acked-by: Eelco Chaudron <[email protected]> Signed-off-by: Mike Pattrick <[email protected]> Signed-off-by: Ilya Maximets <[email protected]>
1 parent 44fc7ea commit 77eb3e4

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

ofproto/bond.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ static void bond_update_post_recirc_rules__(struct bond *, bool force)
193193
static bool bond_is_falling_back_to_ab(const struct bond *);
194194
static void bond_add_lb_output_buckets(const struct bond *);
195195
static void bond_del_lb_output_buckets(const struct bond *);
196+
static bool bond_is_balanced(const struct bond *bond) OVS_REQ_RDLOCK(rwlock);
196197

197198

198199
/* Attempts to parse 's' as the name of a bond balancing mode. If successful,
@@ -549,6 +550,7 @@ bond_find_member_by_mac(const struct bond *bond, const struct eth_addr mac)
549550

550551
static void
551552
bond_active_member_changed(struct bond *bond)
553+
OVS_REQ_WRLOCK(rwlock)
552554
{
553555
if (bond->active_member) {
554556
struct eth_addr mac;
@@ -558,6 +560,9 @@ bond_active_member_changed(struct bond *bond)
558560
bond->active_member_mac = eth_addr_zero;
559561
}
560562
bond->active_member_changed = true;
563+
if (!bond_is_balanced(bond)) {
564+
bond->bond_revalidate = true;
565+
}
561566
seq_change(connectivity_seq_get());
562567
}
563568

@@ -1121,7 +1126,7 @@ bond_get_recirc_id_and_hash_basis(struct bond *bond, uint32_t *recirc_id,
11211126
/* Rebalancing. */
11221127

11231128
static bool
1124-
bond_is_balanced(const struct bond *bond) OVS_REQ_RDLOCK(rwlock)
1129+
bond_is_balanced(const struct bond *bond)
11251130
{
11261131
return bond->rebalance_interval
11271132
&& (bond->balance == BM_SLB || bond->balance == BM_TCP)
@@ -1725,7 +1730,6 @@ bond_unixctl_set_active_member(struct unixctl_conn *conn,
17251730
}
17261731

17271732
if (bond->active_member != member) {
1728-
bond->bond_revalidate = true;
17291733
bond->active_member = member;
17301734
VLOG_INFO("bond %s: active member is now %s",
17311735
bond->name, member->name);

tests/ofproto-dpif.at

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,49 @@ recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=ff:
351351
OVS_VSWITCHD_STOP
352352
AT_CLEANUP
353353

354+
AT_SETUP([ofproto-dpif - active-backup bonding set primary])
355+
356+
OVS_VSWITCHD_START(
357+
[add-bond br0 bond0 p1 p2 bond_mode=active-backup \
358+
other_config:bond-primary=p1 -- \
359+
set bridge br0 other-config:hwaddr=aa:66:aa:66:aa:00 -- \
360+
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
361+
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
362+
add-port br0 p7 -- set interface p7 ofport_request=7 type=dummy -- \
363+
add-br br1 -- \
364+
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
365+
set bridge br1 datapath-type=dummy -- \
366+
add-bond br1 bond1 p3 p4 bond_mode=active-backup \
367+
other_config:bond-primary=p3 -- \
368+
set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 -- \
369+
set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 -- \
370+
add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy])
371+
372+
WAIT_FOR_DUMMY_PORTS([p3], [p4])
373+
374+
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
375+
AT_CHECK([ovs-ofctl add-flow br1 action=normal])
376+
377+
dnl Create datapath flow with bidirectional traffic.
378+
AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),eth(src=50:54:00:00:00:0a,dst=50:54:00:00:00:09),eth_type(0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
379+
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
380+
AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),eth(src=50:54:00:00:00:0a,dst=50:54:00:00:00:09),eth_type(0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
381+
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
382+
383+
dnl Set p2 and p4 as primary.
384+
AT_CHECK([ovs-vsctl set port bond0 other_config:bond-primary=p2 -- \
385+
set port bond1 other_config:bond-primary=p4])
386+
387+
OVS_WAIT_UNTIL([ovs-appctl bond/show | grep -q 'active-backup primary: p4'])
388+
389+
AT_CHECK([ovs-appctl revalidator/wait])
390+
391+
AT_CHECK([ovs-appctl dpctl/dump-flows --names | grep -q "actions:p[[13]]"], [1])
392+
AT_CHECK([ovs-appctl dpctl/dump-flows --names | grep -q "actions:p[[24]]"], [0])
393+
394+
OVS_VSWITCHD_STOP
395+
AT_CLEANUP
396+
354397
AT_SETUP([ofproto-dpif - balance-slb bonding])
355398
# Create br0 with members bond0(p1, p2, p3) and p7,
356399
# and br1 with members p4, p5, p6 and p8.

0 commit comments

Comments
 (0)