diff options
Diffstat (limited to 'lib/bfd.c')
-rw-r--r-- | lib/bfd.c | 30 |
1 files changed, 27 insertions, 3 deletions
@@ -146,6 +146,7 @@ BUILD_ASSERT_DECL(BFD_PACKET_LEN == sizeof(struct msg)); #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 +156,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'. */ @@ -370,7 +372,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 +392,13 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg, bfd_status_changed(bfd); } + int old_mult = bfd->mult; + int new_mult = smap_get_int(cfg, "mult", DEFAULT_MULT); + if (new_mult < 1 || new_mult > 255) { + new_mult = DEFAULT_MULT; + } + bfd->mult = new_mult; + bfd->oam = smap_get_bool(cfg, "oam", false); atomic_store_relaxed(&bfd->check_tnl_key, @@ -458,6 +468,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 +818,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 +834,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 +995,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 +1291,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 |