summaryrefslogtreecommitdiffstats
path: root/bfdd
diff options
context:
space:
mode:
authorIgor Ryzhov <iryzhov@nfware.com>2021-05-28 14:25:36 +0200
committerIgor Ryzhov <iryzhov@nfware.com>2021-06-01 17:08:29 +0200
commit874ca769973550d6d9c0ead69b5e2e7472014a36 (patch)
tree9027b42bc1919158830339566b845ddf153b8bd5 /bfdd
parentbfdd: don't store interface pointer for multihop sessions (diff)
downloadfrr-874ca769973550d6d9c0ead69b5e2e7472014a36.tar.xz
frr-874ca769973550d6d9c0ead69b5e2e7472014a36.zip
bfdd: forbid setting interface for multihop sessions
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'bfdd')
-rw-r--r--bfdd/bfdd_cli.c35
-rw-r--r--bfdd/bfdd_nb_config.c41
-rw-r--r--bfdd/bfdd_nb_state.c10
3 files changed, 55 insertions, 31 deletions
diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c
index 6ec724d80..26ff4a758 100644
--- a/bfdd/bfdd_cli.c
+++ b/bfdd/bfdd_cli.c
@@ -125,7 +125,13 @@ DEFPY_YANG_NOSH(
if (multihop) {
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;
}
snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
@@ -140,7 +146,7 @@ DEFPY_YANG_NOSH(
if (ifname)
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='%s']", ifname);
- else
+ else if (!multihop)
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='*']");
if (vrf)
@@ -185,10 +191,20 @@ DEFPY_YANG(
char xpath[XPATH_MAXLEN];
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']",
local_address_str);
- else
+ } else
source_str[0] = 0;
slen = snprintf(xpath, sizeof(xpath),
@@ -198,7 +214,7 @@ DEFPY_YANG(
if (ifname)
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='%s']", ifname);
- else
+ else if (!multihop)
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
"[interface='*']");
if (vrf)
@@ -218,7 +234,6 @@ static void _bfd_cli_show_peer(struct vty *vty, struct lyd_node *dnode,
bool mhop)
{
const char *vrf = yang_dnode_get_string(dnode, "./vrf");
- const char *ifname = yang_dnode_get_string(dnode, "./interface");
vty_out(vty, " peer %s",
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))
vty_out(vty, " vrf %s", vrf);
- if (strcmp(ifname, "*"))
- vty_out(vty, " interface %s", ifname);
+ if (!mhop) {
+ const char *ifname =
+ yang_dnode_get_string(dnode, "./interface");
+ if (strcmp(ifname, "*"))
+ vty_out(vty, " interface %s", ifname);
+ }
vty_out(vty, "\n");
}
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index b221b6d53..859e9475d 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -45,11 +45,13 @@ static void bfd_session_get_key(bool mhop, const struct lyd_node *dnode,
if (yang_dnode_exists(dnode, "./source-addr"))
strtosa(yang_dnode_get_string(dnode, "./source-addr"), &lsa);
- ifname = yang_dnode_get_string(dnode, "./interface");
vrfname = yang_dnode_get_string(dnode, "./vrf");
- if (strcmp(ifname, "*") == 0)
- ifname = NULL;
+ if (!mhop) {
+ ifname = yang_dnode_get_string(dnode, "./interface");
+ if (strcmp(ifname, "*") == 0)
+ ifname = NULL;
+ }
/* Generate the corresponding key. */
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;
struct session_iter iter;
struct bfd_session *bs;
- const char *source;
const char *dest;
const char *ifname;
const char *vrfname;
@@ -89,13 +90,27 @@ static int bfd_session_create(struct nb_cb_create_args *args, bool mhop)
switch (args->event) {
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
* require interface name, otherwise we can't figure
* 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");
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");
vrfname = yang_dnode_get_string(args->dnode, "./vrf");
- if (mhop) {
- source = yang_dnode_get_string(args->dnode, "./source-addr");
-
- 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);
- }
+ yang_dnode_iterate(session_iter_cb, &iter, sess_dnode,
+ "./single-hop[dest-addr='%s'][vrf='%s']",
+ dest, vrfname);
if (iter.wildcard && iter.count > 1) {
snprintf(
diff --git a/bfdd/bfdd_nb_state.c b/bfdd/bfdd_nb_state.c
index 043f850af..de0dcebfe 100644
--- a/bfdd/bfdd_nb_state.c
+++ b/bfdd/bfdd_nb_state.c
@@ -351,9 +351,8 @@ int bfdd_bfd_sessions_multi_hop_get_keys(struct nb_cb_get_keys_args *args)
args->keys->num = 4;
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[2], bs->key.ifname, sizeof(args->keys->key[2]));
- strlcpy(args->keys->key[3], bs->key.vrfname,
- sizeof(args->keys->key[3]));
+ strlcpy(args->keys->key[2], bs->key.vrfname,
+ sizeof(args->keys->key[2]));
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 *dest_addr = args->keys->key[1];
- const char *ifname = args->keys->key[2];
- const char *vrf = args->keys->key[3];
+ const char *vrf = args->keys->key[2];
struct sockaddr_any psa, lsa;
struct bfd_key bk;
strtosa(dest_addr, &psa);
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);
}