@@ -146,6 +146,8 @@ BUILD_ASSERT_DECL(BFD_PACKET_LEN == sizeof(structmsg));
#define VERS_SHIFT 5
#define STATE_MASK 0xC0
#define FLAGS_MASK 0x3f
+#define DEFAULT_MULT 3
+
struct bfd {
struct hmap_node node; /* In 'all_bfds'. */
@@ -155,6 +157,7 @@ struct bfd {
bool cpath_down; /* Concatenated Path Down. */
uint8_t mult; /* bfd.DetectMult. */
+ uint8_t rmt_mult; /* Remote bfd.DetectMult. */
struct netdev *netdev;
uint64_t rx_packets; /* Packets received by 'netdev'. */
@@ -354,6 +357,8 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg,
bool need_poll = false;
bool cfg_min_rx_changed = false;
bool cpath_down, forwarding_if_rx;
+ int new_mult;
+ int old_mult;
if (!cfg || !smap_get_bool(cfg, "enable", false)) {
bfd_unref(bfd);
@@ -370,7 +375,8 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg,
bfd->diag = DIAG_NONE;
bfd->min_tx = 1000;
- bfd->mult = 3;
+ bfd->rmt_mult = 0;
+ bfd->mult = DEFAULT_MULT;
ovs_refcount_init(&bfd->ref_cnt);
bfd->netdev = netdev_ref(netdev);
bfd->rx_packets = bfd_rx_packets(bfd);
@@ -389,6 +395,21 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg,
bfd_status_changed(bfd);
}
+ old_mult = bfd->mult;
+
+ new_mult = smap_get_int(cfg, "mult", DEFAULT_MULT);
+ if (new_mult < 1 || new_mult > 255) {
+ VLOG_INFO("Interface %s mult value %d out of range 1-255 changedto %d",
+ name, new_mult, DEFAULT_MULT);
+ new_mult = DEFAULT_MULT;
+ }
+
+ bfd->mult = (uint8_t) new_mult;
+ if (new_mult != old_mult) {
+ VLOG_INFO("Interface %s mult value %d changed to %d",
+ name, old_mult, new_mult);
+ }
+
bfd->oam = smap_get_bool(cfg, "oam", false);
atomic_store_relaxed(&bfd->check_tnl_key,
@@ -458,6 +479,9 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg,
} else {
bfd->forwarding_if_rx_detect_time = 0;
}
+ } else if (bfd->state == STATE_UP && bfd->forwarding_if_rx
+ && old_mult != new_mult) {
+ bfd_forwarding_if_rx_update(bfd);
}
if (need_poll) {
@@ -805,6 +829,12 @@ bfd_process_packet(struct bfd *bfd, const struct flow *flow,
bfd->flags |= FLAG_FINAL;
}
+ if (bfd->rmt_mult != msg->mult) {
+ VLOG_INFO("Interface %s remote mult value %d changed to %d",
+ bfd->name, bfd->rmt_mult, msg->mult);
+ bfd->rmt_mult = msg->mult;
+ }
+
rmt_min_rx = MAX(ntohl(msg->min_rx) / 1000, 1);
if (bfd->rmt_min_rx != rmt_min_rx) {
bfd->rmt_min_rx = rmt_min_rx;
@@ -815,7 +845,7 @@ bfd_process_packet(struct bfd *bfd, const struct flow*flow,
}
bfd->rmt_min_tx = MAX(ntohl(msg->min_tx) / 1000, 1);
- bfd->detect_time = bfd_rx_interval(bfd) * bfd->mult + time_msec();
+ bfd->detect_time = bfd_rx_interval(bfd) * bfd->rmt_mult + time_msec();
if (bfd->state == STATE_ADMIN_DOWN) {
VLOG_DBG_RL(&rl, "Administratively down, dropping control message.");
@@ -976,7 +1006,11 @@ static void
bfd_set_next_tx(struct bfd *bfd) OVS_REQUIRES(mutex)
{
long long int interval = bfd_tx_interval(bfd);
- interval -= interval * random_range(26) / 100;
+ if (bfd->mult == 1) {
+ interval -= interval * (10 + random_range(16)) / 100;
+ } else {
+ interval -= interval * random_range(26) / 100;
+ }
bfd->next_tx = bfd->last_tx + interval;
}
@@ -1268,6 +1302,7 @@ bfd_put_details(struct ds *ds, const struct bfd *bfd) OVS_REQUIRES(mutex)
bfd->rmt_min_tx);
ds_put_format(ds, "\tRemote Minimum RX Interval: %lldms\n",
bfd->rmt_min_rx);
+ ds_put_format(ds, "\tRemote Detect Multiplier: %d\n", bfd->rmt_mult);
}
static void
@@ -1,10 +1,9 @@
AT_BANNER([bfd])
m4_define([BFD_CHECK], [
-AT_CHECK([ovs-appctl bfd/show $1 | sed -e '/Time:/d' | sed -e '/Discriminator/d' | sed -e '/Interval:/d'],[0],
+AT_CHECK([ovs-appctl bfd/show $1 | sed -e '/Time:/d' | sed -e '/Discriminator/d' | sed -e '/Interval:/d'| sed -e '/Multiplier/d'],[0],
[dnl
Forwarding: $2
- Detect Multiplier: 3
Concatenated Path Down: $3
Local Flags: $4
@@ -42,6 +41,14 @@ $3
])
])
+m4_define([BFD_CHECK_MULT], [
+AT_CHECK([ovs-appctl bfd/show $1 | sed -n '/Detect Multiplier/p'],[0],
+[dnl
+ Detect Multiplier: $2
+ Remote Detect Multiplier: $3
+])
+])
+
AT_SETUP([bfd - basic config on different bridges])
#Create 2 bridges connected by patch ports and enable BFD
OVS_VSWITCHD_START(
@@ -1043,3 +1050,53 @@ check_liveness 3 LIVE
OVS_VSWITCHD_STOP
AT_CLEANUP
+
+AT_SETUP([bfd - Edit the Detect Mult values])
+#Create 2 bridges connected by patch ports and enable BFD
+OVS_VSWITCHD_START()
+ovs-appctl time/stop
+AT_CHECK([ ovs-vsctl -- add-br br1 -- \
+ set bridge br1 datapath-type=dummy ])
+AT_CHECK([ ovs-vsctl -- add-port br1 p1 -- set Interface p1 type=patch\
+ options:peer=p0 ])
+AT_CHECK([ ovs-vsctl -- add-port br0 p0 -- set Interface p0 type=patch\
+ options:peer=p1 ])
+AT_CHECK([ ovs-vsctl -- set interface p0 bfd:enable=true ])
+AT_CHECK([ ovs-vsctl -- set interface p1 bfd:enable=true ])
+ovs-appctl time/warp 3100 100
+#Verify that BFD has been enabled on both interfaces.
+BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
+BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic])
+#Verify that default mult values are 3.
+BFD_CHECK_MULT([p0], [3], [3])
+BFD_CHECK_MULT([p1], [3], [3])
+#Set the mult values to valid range border mult(p0)=1 mult(p1)=255.
+AT_CHECK([ovs-vsctl set interface p0 bfd:mult=1])
+AT_CHECK([ovs-vsctl set interface p1 bfd:mult=255])
+ovs-appctl time/warp 3100 100
+BFD_CHECK_MULT([p0], [1], [255])
+BFD_CHECK_MULT([p1], [255], [1])
+
+#Set the mult values out valid range border mult(p0)=0 mult(p1)=256.
+AT_CHECK([ovs-vsctl set interface p0 bfd:mult=0])
+AT_CHECK([ovs-vsctl set interface p1 bfd:mult=256])
+ovs-appctl time/warp 3100 100
+BFD_CHECK_MULT([p0], [3], [3])
+BFD_CHECK_MULT([p1], [3], [3])
+
+#Set valid non default mult values mult(p0)=8 mult(p1)=125.
+AT_CHECK([ovs-vsctl set interface p0 bfd:mult=8])
+AT_CHECK([ovs-vsctl set interface p1 bfd:mult=125])
+ovs-appctl time/warp 3100 100
+BFD_CHECK_MULT([p0], [8], [125])
+BFD_CHECK_MULT([p1], [125], [8])
+
+#Clear mult values. Detect mult values shall be default 3 again.
+AT_CHECK([ovs-vsctl remove interface p0 bfd mult])
+AT_CHECK([ovs-vsctl remove interface p1 bfd mult])
+ovs-appctl time/warp 3100 100
+BFD_CHECK_MULT([p0], [3], [3])
+BFD_CHECK_MULT([p1], [3], [3])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
@@ -2917,6 +2917,16 @@
this to true, BFD packets will be marked as OAM if encapsulated in
one of these tunnels.
</column>
+
+ <column name="bfd" key="mult"
+ type='{"type": "integer", "minInteger": 1, "maxInteger": 255}'>
+ From RFC5880 Jun 20 2010 page 28 (bfd.DetectMult)
+ "The desired Detection Time multiplier for BFD Control packetson
+ the local system. The negotiated Control packet transmission
+ interval, multiplied by this variable, will be the Detection Time
+ for this session (as seen by the remote system). This variable
+ MUST be a nonzero integer..." Defaults to <code>3</code>.
+ </column>
</group>
<group title="BFD Status">