]> git.proxmox.com Git - mirror_frr.git/commitdiff
bfdd: forbid setting interface for multihop sessions
authorIgor Ryzhov <iryzhov@nfware.com>
Fri, 28 May 2021 12:25:36 +0000 (15:25 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Tue, 1 Jun 2021 15:08:29 +0000 (18:08 +0300)
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
bfdd/bfdd_cli.c
bfdd/bfdd_nb_config.c
bfdd/bfdd_nb_state.c
yang/frr-bfdd.yang

index 6ec724d80cdd981caeb47c1f0117d9bc1df50162..26ff4a758a03a3ac10277007eec78a277a2dab58 100644 (file)
@@ -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");
 }
index b221b6d539fc130f49c5d9c51938487c81b9272d..859e9475d0f1707625ecd53efccf98c76cecee0a 100644 (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"))
                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(
index 043f850afa179a343fe18ceb291f5fb48588b478..de0dcebfea11f9156d14c3871e5d7f6c0e0c4472 100644 (file)
@@ -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);
 }
index d21ff5068a718385cf46e9e564cb914faf0e8652..d2746e3503d83e1b84bb0a425b1875b702e2f5ba 100644 (file)
@@ -435,7 +435,7 @@ module frr-bfdd {
         }
 
         list multi-hop {
-          key "source-addr dest-addr interface vrf";
+          key "source-addr dest-addr vrf";
           description "List of multi hop sessions";
 
           leaf source-addr {
@@ -448,11 +448,6 @@ module frr-bfdd {
             description "IP address of the peer";
           }
 
-          leaf interface {
-            type frr-interface:interface-ref;
-            description "Interface to use to contact peer";
-          }
-
           leaf vrf {
             type frr-vrf:vrf-ref;
             description "Virtual Routing Domain name";