Merge pull request #8758 from idryzhov/bfd-fixes

BFD fixes
This commit is contained in:
Rafael Zalamena 2021-06-07 08:34:06 -03:00 committed by GitHub
commit a36dd4c930
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 75 additions and 45 deletions

View File

@ -656,7 +656,7 @@ int bfd_recv_cb(struct thread *t)
* If no interface was detected, save the interface where the * If no interface was detected, save the interface where the
* packet came in. * packet came in.
*/ */
if (bfd->ifp == NULL) if (!is_mhop && bfd->ifp == NULL)
bfd->ifp = if_lookup_by_index(ifindex, vrfid); bfd->ifp = if_lookup_by_index(ifindex, vrfid);
/* Log remote discriminator changes. */ /* Log remote discriminator changes. */

View File

@ -125,7 +125,13 @@ DEFPY_YANG_NOSH(
if (multihop) { if (multihop) {
if (!local_address_str) { if (!local_address_str) {
vty_out(vty, "%% local-address is required when using multihop\n"); vty_out(vty,
"%% local-address is required when using multihop\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (ifname) {
vty_out(vty,
"%% interface is prohibited when using multihop\n");
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
snprintf(source_str, sizeof(source_str), "[source-addr='%s']", snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
@ -140,7 +146,7 @@ DEFPY_YANG_NOSH(
if (ifname) if (ifname)
slen += snprintf(xpath + slen, sizeof(xpath) - slen, slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='%s']", ifname); "[interface='%s']", ifname);
else else if (!multihop)
slen += snprintf(xpath + slen, sizeof(xpath) - slen, slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='*']"); "[interface='*']");
if (vrf) if (vrf)
@ -185,10 +191,20 @@ DEFPY_YANG(
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
char source_str[INET6_ADDRSTRLEN + 32]; char source_str[INET6_ADDRSTRLEN + 32];
if (multihop) if (multihop) {
if (!local_address_str) {
vty_out(vty,
"%% local-address is required when using multihop\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (ifname) {
vty_out(vty,
"%% interface is prohibited when using multihop\n");
return CMD_WARNING_CONFIG_FAILED;
}
snprintf(source_str, sizeof(source_str), "[source-addr='%s']", snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
local_address_str); local_address_str);
else } else
source_str[0] = 0; source_str[0] = 0;
slen = snprintf(xpath, sizeof(xpath), slen = snprintf(xpath, sizeof(xpath),
@ -198,7 +214,7 @@ DEFPY_YANG(
if (ifname) if (ifname)
slen += snprintf(xpath + slen, sizeof(xpath) - slen, slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='%s']", ifname); "[interface='%s']", ifname);
else else if (!multihop)
slen += snprintf(xpath + slen, sizeof(xpath) - slen, slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='*']"); "[interface='*']");
if (vrf) if (vrf)
@ -218,7 +234,6 @@ static void _bfd_cli_show_peer(struct vty *vty, struct lyd_node *dnode,
bool mhop) bool mhop)
{ {
const char *vrf = yang_dnode_get_string(dnode, "./vrf"); const char *vrf = yang_dnode_get_string(dnode, "./vrf");
const char *ifname = yang_dnode_get_string(dnode, "./interface");
vty_out(vty, " peer %s", vty_out(vty, " peer %s",
yang_dnode_get_string(dnode, "./dest-addr")); yang_dnode_get_string(dnode, "./dest-addr"));
@ -233,8 +248,12 @@ static void _bfd_cli_show_peer(struct vty *vty, struct lyd_node *dnode,
if (strcmp(vrf, VRF_DEFAULT_NAME)) if (strcmp(vrf, VRF_DEFAULT_NAME))
vty_out(vty, " vrf %s", vrf); vty_out(vty, " vrf %s", vrf);
if (strcmp(ifname, "*")) if (!mhop) {
vty_out(vty, " interface %s", ifname); const char *ifname =
yang_dnode_get_string(dnode, "./interface");
if (strcmp(ifname, "*"))
vty_out(vty, " interface %s", ifname);
}
vty_out(vty, "\n"); vty_out(vty, "\n");
} }

View File

@ -45,11 +45,13 @@ static void bfd_session_get_key(bool mhop, const struct lyd_node *dnode,
if (yang_dnode_exists(dnode, "./source-addr")) if (yang_dnode_exists(dnode, "./source-addr"))
strtosa(yang_dnode_get_string(dnode, "./source-addr"), &lsa); strtosa(yang_dnode_get_string(dnode, "./source-addr"), &lsa);
ifname = yang_dnode_get_string(dnode, "./interface");
vrfname = yang_dnode_get_string(dnode, "./vrf"); vrfname = yang_dnode_get_string(dnode, "./vrf");
if (strcmp(ifname, "*") == 0) if (!mhop) {
ifname = NULL; ifname = yang_dnode_get_string(dnode, "./interface");
if (strcmp(ifname, "*") == 0)
ifname = NULL;
}
/* Generate the corresponding key. */ /* Generate the corresponding key. */
gen_bfd_key(bk, &psa, &lsa, mhop, ifname, vrfname); gen_bfd_key(bk, &psa, &lsa, mhop, ifname, vrfname);
@ -80,7 +82,6 @@ static int bfd_session_create(struct nb_cb_create_args *args, bool mhop)
const struct lyd_node *sess_dnode; const struct lyd_node *sess_dnode;
struct session_iter iter; struct session_iter iter;
struct bfd_session *bs; struct bfd_session *bs;
const char *source;
const char *dest; const char *dest;
const char *ifname; const char *ifname;
const char *vrfname; const char *vrfname;
@ -89,13 +90,27 @@ static int bfd_session_create(struct nb_cb_create_args *args, bool mhop)
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
yang_dnode_get_prefix(&p, args->dnode, "./dest-addr");
if (mhop) {
/*
* Do not allow IPv6 link-local address for multihop.
*/
if (p.family == AF_INET6
&& IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
snprintf(
args->errmsg, args->errmsg_len,
"Cannot use link-local address for multihop sessions");
return NB_ERR_VALIDATION;
}
return NB_OK;
}
/* /*
* When `dest-addr` is IPv6 and link-local we must * When `dest-addr` is IPv6 and link-local we must
* require interface name, otherwise we can't figure * require interface name, otherwise we can't figure
* which interface to use to send the packets. * which interface to use to send the packets.
*/ */
yang_dnode_get_prefix(&p, args->dnode, "./dest-addr");
ifname = yang_dnode_get_string(args->dnode, "./interface"); ifname = yang_dnode_get_string(args->dnode, "./interface");
if (p.family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6) if (p.family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)
@ -114,17 +129,9 @@ static int bfd_session_create(struct nb_cb_create_args *args, bool mhop)
dest = yang_dnode_get_string(args->dnode, "./dest-addr"); dest = yang_dnode_get_string(args->dnode, "./dest-addr");
vrfname = yang_dnode_get_string(args->dnode, "./vrf"); vrfname = yang_dnode_get_string(args->dnode, "./vrf");
if (mhop) { yang_dnode_iterate(session_iter_cb, &iter, sess_dnode,
source = yang_dnode_get_string(args->dnode, "./source-addr"); "./single-hop[dest-addr='%s'][vrf='%s']",
dest, vrfname);
yang_dnode_iterate(session_iter_cb, &iter, sess_dnode,
"./multi-hop[source-addr='%s'][dest-addr='%s'][vrf='%s']",
source, dest, vrfname);
} else {
yang_dnode_iterate(session_iter_cb, &iter, sess_dnode,
"./single-hop[dest-addr='%s'][vrf='%s']",
dest, vrfname);
}
if (iter.wildcard && iter.count > 1) { if (iter.wildcard && iter.count > 1) {
snprintf( snprintf(

View File

@ -351,9 +351,8 @@ int bfdd_bfd_sessions_multi_hop_get_keys(struct nb_cb_get_keys_args *args)
args->keys->num = 4; args->keys->num = 4;
strlcpy(args->keys->key[0], srcbuf, sizeof(args->keys->key[0])); strlcpy(args->keys->key[0], srcbuf, sizeof(args->keys->key[0]));
strlcpy(args->keys->key[1], dstbuf, sizeof(args->keys->key[1])); strlcpy(args->keys->key[1], dstbuf, sizeof(args->keys->key[1]));
strlcpy(args->keys->key[2], bs->key.ifname, sizeof(args->keys->key[2])); strlcpy(args->keys->key[2], bs->key.vrfname,
strlcpy(args->keys->key[3], bs->key.vrfname, sizeof(args->keys->key[2]));
sizeof(args->keys->key[3]));
return NB_OK; return NB_OK;
} }
@ -363,14 +362,13 @@ bfdd_bfd_sessions_multi_hop_lookup_entry(struct nb_cb_lookup_entry_args *args)
{ {
const char *source_addr = args->keys->key[0]; const char *source_addr = args->keys->key[0];
const char *dest_addr = args->keys->key[1]; const char *dest_addr = args->keys->key[1];
const char *ifname = args->keys->key[2]; const char *vrf = args->keys->key[2];
const char *vrf = args->keys->key[3];
struct sockaddr_any psa, lsa; struct sockaddr_any psa, lsa;
struct bfd_key bk; struct bfd_key bk;
strtosa(dest_addr, &psa); strtosa(dest_addr, &psa);
strtosa(source_addr, &lsa); strtosa(source_addr, &lsa);
gen_bfd_key(&bk, &psa, &lsa, true, ifname, vrf); gen_bfd_key(&bk, &psa, &lsa, true, NULL, vrf);
return bfd_key_lookup(bk); return bfd_key_lookup(bk);
} }

View File

@ -232,7 +232,7 @@ int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state)
stream_putl(msg, ZEBRA_INTERFACE_BFD_DEST_UPDATE); stream_putl(msg, ZEBRA_INTERFACE_BFD_DEST_UPDATE);
/* NOTE: Interface is a shortcut to avoid comparing source address. */ /* NOTE: Interface is a shortcut to avoid comparing source address. */
if (bs->ifp != NULL) if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) && bs->ifp != NULL)
stream_putl(msg, bs->ifp->ifindex); stream_putl(msg, bs->ifp->ifindex);
else else
stream_putl(msg, IFINDEX_INTERNAL); stream_putl(msg, IFINDEX_INTERNAL);

View File

@ -2112,10 +2112,13 @@ DEFPY(debug_bgp_bfd, debug_bgp_bfd_cmd,
bfd_protocol_integration_set_debug(true); bfd_protocol_integration_set_debug(true);
} }
} else { } else {
if (no) if (no) {
TERM_DEBUG_OFF(bfd, BFD_LIB); TERM_DEBUG_OFF(bfd, BFD_LIB);
else bfd_protocol_integration_set_debug(false);
} else {
TERM_DEBUG_ON(bfd, BFD_LIB); TERM_DEBUG_ON(bfd, BFD_LIB);
bfd_protocol_integration_set_debug(true);
}
} }
return CMD_SUCCESS; return CMD_SUCCESS;

View File

@ -314,9 +314,17 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
stream_putc(s, args->ttl); stream_putc(s, args->ttl);
/* Send interface name if any. */ /* Send interface name if any. */
stream_putc(s, args->ifnamelen); if (args->mhop) {
if (args->ifnamelen) /* Don't send interface. */
stream_put(s, args->ifname, args->ifnamelen); stream_putc(s, 0);
if (bsglobal.debugging && args->ifnamelen)
zlog_debug("%s: multi hop is configured, not sending interface",
__func__);
} else {
stream_putc(s, args->ifnamelen);
if (args->ifnamelen)
stream_put(s, args->ifname, args->ifnamelen);
}
/* Send the C bit indicator. */ /* Send the C bit indicator. */
stream_putc(s, args->cbit); stream_putc(s, args->cbit);
@ -385,7 +393,7 @@ struct bfd_session_params *bfd_sess_new(bsp_status_update updatecb, void *arg)
/* Set defaults. */ /* Set defaults. */
bsp->args.detection_multiplier = BFD_DEF_DETECT_MULT; bsp->args.detection_multiplier = BFD_DEF_DETECT_MULT;
bsp->args.ttl = BFD_SINGLE_HOP_TTL; bsp->args.ttl = 1;
bsp->args.min_rx = BFD_DEF_MIN_RX; bsp->args.min_rx = BFD_DEF_MIN_RX;
bsp->args.min_tx = BFD_DEF_MIN_TX; bsp->args.min_tx = BFD_DEF_MIN_TX;
bsp->args.vrf_id = VRF_DEFAULT; bsp->args.vrf_id = VRF_DEFAULT;

View File

@ -435,7 +435,7 @@ module frr-bfdd {
} }
list multi-hop { list multi-hop {
key "source-addr dest-addr interface vrf"; key "source-addr dest-addr vrf";
description "List of multi hop sessions"; description "List of multi hop sessions";
leaf source-addr { leaf source-addr {
@ -448,11 +448,6 @@ module frr-bfdd {
description "IP address of the peer"; description "IP address of the peer";
} }
leaf interface {
type frr-interface:interface-ref;
description "Interface to use to contact peer";
}
leaf vrf { leaf vrf {
type frr-vrf:vrf-ref; type frr-vrf:vrf-ref;
description "Virtual Routing Domain name"; description "Virtual Routing Domain name";