Merge pull request #7476 from opensourcerouting/bfd-fixes

bfdd,lib: integration fixes
This commit is contained in:
Russ White 2020-11-17 07:34:29 -05:00 committed by GitHub
commit a1a41d5c6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 110 additions and 62 deletions

View File

@ -84,10 +84,11 @@ static void bfdd_client_deregister(struct stream *msg);
static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...)
{
char timers[3][128] = {};
char minttl_str[32] = {};
char addr[3][128] = {};
char profile[128] = {};
char cbit_str[32];
char msgbuf[256];
char msgbuf[512];
va_list vl;
/* Avoid debug calculations if it's disabled. */
@ -120,6 +121,10 @@ static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...)
snprintf(cbit_str, sizeof(cbit_str), " cbit:0x%02x", bpc->bpc_cbit);
if (bpc->bpc_has_minimum_ttl)
snprintf(minttl_str, sizeof(minttl_str), " minimum-ttl:%d",
bpc->bpc_minimum_ttl);
if (bpc->bpc_has_profile)
snprintf(profile, sizeof(profile), " profile:%s",
bpc->bpc_profile);
@ -128,9 +133,10 @@ static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...)
vsnprintf(msgbuf, sizeof(msgbuf), fmt, vl);
va_end(vl);
zlog_debug("%s [mhop:%s %s%s%s%s%s%s%s%s]", msgbuf,
zlog_debug("%s [mhop:%s %s%s%s%s%s%s%s%s%s]", msgbuf,
bpc->bpc_mhop ? "yes" : "no", addr[0], addr[1], addr[2],
timers[0], timers[1], timers[2], cbit_str, profile);
timers[0], timers[1], timers[2], cbit_str, minttl_str,
profile);
}
static void _ptm_bfd_session_del(struct bfd_session *bs, uint8_t diag)
@ -307,6 +313,8 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
/*
* Register/Deregister/Update Message format:
*
* Old format (being used by PTM BFD).
* - header: Command, VRF
* - l: pid
* - w: family
@ -322,16 +330,37 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
* - multihop:
* - w: family
* - AF_INET:
* - l: destination ipv4
* - l: source IPv4 address
* - AF_INET6:
* - 16 bytes: destination IPv6
* - 16 bytes: source IPv6 address
* - c: ttl
* - no multihop
* - AF_INET6:
* - w: family
* - 16 bytes: ipv6 address
* - 16 bytes: source IPv6 address
* - c: ifname length
* - X bytes: interface name
*
* New format:
* - header: Command, VRF
* - l: pid
* - w: family
* - AF_INET:
* - l: destination IPv4 address
* - AF_INET6:
* - 16 bytes: destination IPv6 address
* - l: min_rx
* - l: min_tx
* - c: detect multiplier
* - c: is_multihop?
* - w: family
* - AF_INET:
* - l: source IPv4 address
* - AF_INET6:
* - 16 bytes: source IPv6 address
* - c: ttl
* - c: ifname length
* - X bytes: interface name
* - c: bfd_cbit
* - c: profile name length.
* - X bytes: profile name.
@ -355,58 +384,50 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
bpc->bpc_ipv4 = (bpc->bpc_peer.sa_sin.sin_family == AF_INET);
/* Get peer configuration. */
if (command != ZEBRA_BFD_DEST_DEREGISTER) {
STREAM_GETL(msg, bpc->bpc_recvinterval);
bpc->bpc_has_recvinterval =
(bpc->bpc_recvinterval != BPC_DEF_RECEIVEINTERVAL);
STREAM_GETL(msg, bpc->bpc_recvinterval);
bpc->bpc_has_recvinterval =
(bpc->bpc_recvinterval != BPC_DEF_RECEIVEINTERVAL);
STREAM_GETL(msg, bpc->bpc_txinterval);
bpc->bpc_has_txinterval =
(bpc->bpc_txinterval != BPC_DEF_TRANSMITINTERVAL);
STREAM_GETL(msg, bpc->bpc_txinterval);
bpc->bpc_has_txinterval =
(bpc->bpc_txinterval != BPC_DEF_TRANSMITINTERVAL);
STREAM_GETC(msg, bpc->bpc_detectmultiplier);
bpc->bpc_has_detectmultiplier =
(bpc->bpc_detectmultiplier != BPC_DEF_DETECTMULTIPLIER);
}
STREAM_GETC(msg, bpc->bpc_detectmultiplier);
bpc->bpc_has_detectmultiplier =
(bpc->bpc_detectmultiplier != BPC_DEF_DETECTMULTIPLIER);
/* Read (single|multi)hop and its options. */
STREAM_GETC(msg, bpc->bpc_mhop);
if (bpc->bpc_mhop) {
/* Read multihop source address and TTL. */
_ptm_msg_read_address(msg, &bpc->bpc_local);
STREAM_GETC(msg, bpc->bpc_minimum_ttl);
if (bpc->bpc_minimum_ttl >= BFD_TTL_VAL
|| bpc->bpc_minimum_ttl == 0) {
zlog_warn("%s: received invalid TTL configuration %d",
__func__, bpc->bpc_has_minimum_ttl);
bpc->bpc_minimum_ttl = BFD_DEF_MHOP_TTL;
bpc->bpc_has_minimum_ttl = false;
} else {
bpc->bpc_minimum_ttl =
(BFD_TTL_VAL + 1) - bpc->bpc_minimum_ttl;
bpc->bpc_has_minimum_ttl = true;
}
/* Read multihop source address and TTL. */
_ptm_msg_read_address(msg, &bpc->bpc_local);
/* Read the minimum TTL (0 means unset or invalid). */
STREAM_GETC(msg, bpc->bpc_minimum_ttl);
if (bpc->bpc_minimum_ttl == 0) {
bpc->bpc_minimum_ttl = BFD_DEF_MHOP_TTL;
bpc->bpc_has_minimum_ttl = false;
} else {
/* If target is IPv6, then we must obtain local address. */
if (bpc->bpc_ipv4 == false)
_ptm_msg_read_address(msg, &bpc->bpc_local);
/*
* Read interface name and make sure it fits our data
* structure, otherwise fail.
*/
STREAM_GETC(msg, ifnamelen);
if (ifnamelen >= sizeof(bpc->bpc_localif)) {
zlog_err("ptm-read: interface name is too big");
return -1;
}
bpc->bpc_has_localif = ifnamelen > 0;
if (bpc->bpc_has_localif) {
STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
bpc->bpc_localif[ifnamelen] = 0;
}
bpc->bpc_minimum_ttl = (BFD_TTL_VAL + 1) - bpc->bpc_minimum_ttl;
bpc->bpc_has_minimum_ttl = true;
}
/*
* Read interface name and make sure it fits our data
* structure, otherwise fail.
*/
STREAM_GETC(msg, ifnamelen);
if (ifnamelen >= sizeof(bpc->bpc_localif)) {
zlog_err("ptm-read: interface name is too big");
return -1;
}
bpc->bpc_has_localif = ifnamelen > 0;
if (bpc->bpc_has_localif) {
STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
bpc->bpc_localif[ifnamelen] = 0;
}
if (vrf_id != VRF_DEFAULT) {
struct vrf *vrf;
@ -424,6 +445,7 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
strlcpy(bpc->bpc_vrfname, VRF_DEFAULT_NAME, sizeof(bpc->bpc_vrfname));
}
/* Read control plane independant configuration. */
STREAM_GETC(msg, bpc->bpc_cbit);
/* Handle profile names. */

View File

@ -104,7 +104,10 @@ void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx, uint32_t min_tx,
if (((*bfd_info)->required_min_rx != min_rx)
|| ((*bfd_info)->desired_min_tx != min_tx)
|| ((*bfd_info)->detect_mult != detect_mult)
|| (profile && strcmp((*bfd_info)->profile, profile)))
|| ((*bfd_info)->profile[0] == 0 && profile)
|| ((*bfd_info)->profile[0] && profile == NULL)
|| (profile && (*bfd_info)->profile[0]
&& strcmp((*bfd_info)->profile, profile)))
*command = ZEBRA_BFD_DEST_UPDATE;
}
@ -468,6 +471,39 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
: sizeof(struct in6_addr);
stream_put(s, &args->dst, addrlen);
/*
* For more BFD integration protocol details, see function
* `_ptm_msg_read` in `bfdd/ptm_adapter.c`.
*/
#if HAVE_BFDD > 0
/* Session timers. */
stream_putl(s, args->min_rx);
stream_putl(s, args->min_tx);
stream_putc(s, args->detection_multiplier);
/* Is multi hop? */
stream_putc(s, args->mhop != 0);
/* Source address. */
stream_putw(s, args->family);
stream_put(s, &args->src, addrlen);
/* Send the expected TTL. */
stream_putc(s, args->ttl);
/* Send interface name if any. */
stream_putc(s, args->ifnamelen);
if (args->ifnamelen)
stream_put(s, args->ifname, args->ifnamelen);
/* Send the C bit indicator. */
stream_putc(s, args->cbit);
/* Send profile name if any. */
stream_putc(s, args->profilelen);
if (args->profilelen)
stream_put(s, args->profile, args->profilelen);
#else /* PTM BFD */
/* Encode timers if this is a registration message. */
if (args->command != ZEBRA_BFD_DEST_DEREGISTER) {
stream_putl(s, args->min_rx);
@ -500,16 +536,6 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
if (args->ifnamelen)
stream_put(s, args->ifname, args->ifnamelen);
}
/* Send the C bit indicator. */
stream_putc(s, args->cbit);
/* `ptm-bfd` doesn't support profiles yet. */
#if HAVE_BFDD > 0
/* Send profile name if any. */
stream_putc(s, args->profilelen);
if (args->profilelen)
stream_put(s, args->profile, args->profilelen);
#endif /* HAVE_BFDD */
/* Finish the message by writing the size. */