summaryrefslogtreecommitdiffstats
path: root/bfdd
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2019-04-15 17:20:25 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2019-05-14 16:49:49 +0200
commit9beff0bda93a1ab398647cfda6e5efc06222a46c (patch)
treee536633959fe4d7e5d903aa74fab0ae290e8c97d /bfdd
parentMerge pull request #4312 from lkrishnamoor/json_cli_bug_fix (diff)
downloadfrr-9beff0bda93a1ab398647cfda6e5efc06222a46c.tar.xz
frr-9beff0bda93a1ab398647cfda6e5efc06222a46c.zip
bfdd, lib, bgpd: add bfd cbit usage
bfd cbit is a value carried out in bfd messages, that permit to keep or not, the independence between control plane and dataplane. In other words, while most of the cases plan to flush entries, when bfd goes down, there are some cases where that bfd event should be ignored. this is the case with non stop forwarding mechanisms where entries may be kept. this is the case for BGP, when graceful restart capability is used. If BFD event down happens, and bgp is in graceful restart mode, it is wished to ignore the BFD event while waiting for the remote router to restart. The changes take into account the following: - add a config flag across zebra layer so that daemon can set or not the cbit capability. - ability for daemons to read the remote bfd capability associated to a bfd notification. - in bfdd, according to the value, the cbit value is set - in bfdd, the received value is retrived and stored in the bfd session context. - by default, the local cbit announced to remote is set to 1 while preservation of the local path is not set. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bfdd')
-rw-r--r--bfdd/bfd.c11
-rw-r--r--bfdd/bfd.h8
-rw-r--r--bfdd/bfd_packet.c9
-rw-r--r--bfdd/bfdctl.h2
-rw-r--r--bfdd/ptm_adapter.c13
5 files changed, 41 insertions, 2 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index a2e84e928..d4e283483 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -600,6 +600,17 @@ skip_echo:
bfd_recvtimer_update(bs);
bfd_xmttimer_update(bs, bs->xmt_TO);
}
+ if (bpc->bpc_cbit) {
+ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
+ return;
+
+ BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
+ } else {
+ if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
+ return;
+
+ BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
+ }
}
static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc)
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 3f3d60383..213e905bf 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -129,6 +129,12 @@ struct bfd_echo_pkt {
flags |= (val & 0x3) << 6; \
}
#define BFD_GETSTATE(flags) ((flags >> 6) & 0x3)
+#define BFD_SETCBIT(flags, val) \
+ { \
+ if ((val)) \
+ flags |= val; \
+ }
+#define BFD_GETCBIT(flags) (flags & BFD_FBIT)
#define BFD_ECHO_VERSION 1
#define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt)
@@ -168,6 +174,7 @@ enum bfd_session_flags {
*/
BFD_SESS_FLAG_SHUTDOWN = 1 << 7, /* disable BGP peer function */
BFD_SESS_FLAG_CONFIG = 1 << 8, /* Session configured with bfd NB API */
+ BFD_SESS_FLAG_CBIT = 1 << 9, /* CBIT is set */
};
#define BFD_SET_FLAG(field, flag) (field |= flag)
@@ -210,6 +217,7 @@ struct bfd_session {
uint8_t detect_mult;
uint8_t remote_detect_mult;
uint8_t mh_ttl;
+ uint8_t remote_cbit;
/* Timers */
struct bfd_timers timers;
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 8edba05d1..f3acfa416 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -221,6 +221,10 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit)
BFD_SETVER(cp.diag, BFD_VERSION);
cp.flags = 0;
BFD_SETSTATE(cp.flags, bfd->ses_state);
+
+ if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_CBIT))
+ BFD_SETCBIT(cp.flags, BFD_CBIT);
+
BFD_SETDEMANDBIT(cp.flags, BFD_DEF_DEMAND);
/*
@@ -646,6 +650,11 @@ int bfd_recv_cb(struct thread *t)
ntohl(cp->timers.required_min_echo);
bfd->remote_detect_mult = cp->detect_mult;
+ if (BFD_GETCBIT(cp->flags))
+ bfd->remote_cbit = 1;
+ else
+ bfd->remote_cbit = 0;
+
/* State switch from section 6.2. */
bs_state_handler(bfd, BFD_GETSTATE(cp->flags));
diff --git a/bfdd/bfdctl.h b/bfdd/bfdctl.h
index 0da1ca8df..4ce23a8f2 100644
--- a/bfdd/bfdctl.h
+++ b/bfdd/bfdctl.h
@@ -88,6 +88,8 @@ struct bfd_peer_cfg {
bool bpc_createonly;
bool bpc_shutdown;
+ bool bpc_cbit;
+
/* Status information */
enum bfd_peer_status bpc_bps;
uint32_t bpc_id;
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index a12a3c196..3e2ace6ea 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -89,6 +89,7 @@ static void debug_printbpc(const char *func, unsigned int line,
{
char addr[3][128];
char timers[3][128];
+ char cbit_str[10];
addr[0][0] = addr[1][0] = addr[2][0] = timers[0][0] = timers[1][0] =
timers[2][0] = 0;
@@ -117,9 +118,11 @@ static void debug_printbpc(const char *func, unsigned int line,
snprintf(timers[2], sizeof(timers[2]), " detect-multiplier:%d",
bpc->bpc_detectmultiplier);
- log_debug("%s:%d: %s %s%s%s%s%s%s", func, line,
+ sprintf(cbit_str, "CB %x", bpc->bpc_cbit);
+
+ log_debug("%s:%d: %s %s%s%s%s%s%s %s", func, line,
bpc->bpc_mhop ? "multi-hop" : "single-hop", addr[0], addr[1],
- addr[2], timers[0], timers[1], timers[2]);
+ addr[2], timers[0], timers[1], timers[2], cbit_str);
}
#define DEBUG_PRINTBPC(bpc) debug_printbpc(__FILE__, __LINE__, (bpc))
@@ -173,6 +176,7 @@ int ptm_bfd_notify(struct bfd_session *bs)
* - AF_INET6:
* - 16 bytes: ipv6
* - c: prefix length
+ * - c: cbit
*
* Commands: ZEBRA_BFD_DEST_REPLAY
*
@@ -219,6 +223,8 @@ int ptm_bfd_notify(struct bfd_session *bs)
/* BFD source prefix information. */
_ptm_msg_address(msg, bs->key.family, &bs->key.local);
+ stream_putc(msg, bs->remote_cbit);
+
/* Write packet size. */
stream_putw_at(msg, 0, stream_get_endp(msg));
@@ -293,6 +299,7 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
* - 16 bytes: ipv6 address
* - c: ifname length
* - X bytes: interface name
+ * - c: bfd_cbit
*
* q(64), l(32), w(16), c(8)
*/
@@ -371,6 +378,8 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
}
}
+ STREAM_GETC(msg, bpc->bpc_cbit);
+
/* Sanity check: peer and local address must match IP types. */
if (bpc->bpc_local.sa_sin.sin_family != 0
&& (bpc->bpc_local.sa_sin.sin_family