]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: support for route-distinguisher format with 3 fields
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 24 Nov 2022 15:13:08 +0000 (16:13 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 10 Feb 2023 09:27:23 +0000 (10:27 +0100)
The ietf proposes to define a RD with a 3 field separated by
the ':' character. The last 2 fields stands for the usual
fields, namely AS4B:NN, AS2B,NNNN, IP:NN. The first field
stands for the kind of route distinguisher used.

Today, except with the route-map, no other RD configuration
supports this mode. Handle the support for this in FRR.

Link: https://github.com/FRRouting/frr/blob/master/yang/ietf/ietf-routing-types.yang#L258
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_rd.c
bgpd/bgp_rd.h

index f2ecd3de5fba2b461979d13b727138beb832565d..e406d9ca6de509daf0da0f445c42ad177d0afa75 100644 (file)
@@ -99,8 +99,8 @@ void decode_rd_vnc_eth(const uint8_t *pnt, struct rd_vnc_eth *rd_vnc_eth)
 
 int str2prefix_rd(const char *str, struct prefix_rd *prd)
 {
-       int ret = 0;
-       char *p;
+       int ret = 0, type = RD_TYPE_UNDEFINED;
+       char *p, *p2;
        struct stream *s = NULL;
        char *half = NULL;
        struct in_addr addr;
@@ -113,30 +113,53 @@ int str2prefix_rd(const char *str, struct prefix_rd *prd)
        if (!p)
                goto out;
 
+       /* a second ':' is accepted */
+       p2 = strchr(p + 1, ':');
+       if (p2) {
+               /* type is in first part */
+               half = XMALLOC(MTYPE_TMP, (p - str) + 1);
+               memcpy(half, str, (p - str));
+               half[p - str] = '\0';
+               type = atoi(half);
+               if (type != RD_TYPE_AS && type != RD_TYPE_IP &&
+                   type != RD_TYPE_AS4)
+                       goto out;
+               XFREE(MTYPE_TMP, half);
+               half = XMALLOC(MTYPE_TMP, (p2 - p));
+               memcpy(half, p + 1, (p2 - p - 1));
+               half[p2 - p - 1] = '\0';
+               p = p2 + 1;
+       } else {
+               half = XMALLOC(MTYPE_TMP, (p - str) + 1);
+               memcpy(half, str, (p - str));
+               half[p - str] = '\0';
+       }
        if (!all_digit(p + 1))
                goto out;
 
-       /* case AS dot format is used */
        s = stream_new(RD_BYTES);
 
-       half = XMALLOC(MTYPE_TMP, (p - str) + 1);
-       memcpy(half, str, (p - str));
-       half[p - str] = '\0';
        /* if it is an AS format or an IP */
        if (asn_str2asn(half, &as_val)) {
                if (as_val > UINT16_MAX) {
                        stream_putw(s, RD_TYPE_AS4);
                        stream_putl(s, as_val);
                        stream_putw(s, atol(p + 1));
+                       if (type != RD_TYPE_UNDEFINED && type != RD_TYPE_AS4)
+                               goto out;
                } else {
                        stream_putw(s, RD_TYPE_AS);
                        stream_putw(s, as_val);
                        stream_putl(s, atol(p + 1));
+                       if (type != RD_TYPE_UNDEFINED && type != RD_TYPE_AS)
+                               goto out;
                }
        } else if (inet_aton(half, &addr)) {
                stream_putw(s, RD_TYPE_IP);
                stream_put_in_addr(s, &addr);
                stream_putw(s, atol(p + 1));
+               if (type != RD_TYPE_UNDEFINED && type != RD_TYPE_IP)
+                       goto out;
        } else
                goto out;
        memcpy(prd->val, s->data, 8);
index aa9bc0b872bbc32156a2b6345ac03750c51afd26..073eb7e114e1ccfe660e4da4f9033b484225598a 100644 (file)
@@ -27,6 +27,7 @@
 #include "prefix.h"
 
 /* RD types */
+#define RD_TYPE_UNDEFINED (-1)
 #define RD_TYPE_AS      0
 #define RD_TYPE_IP      1
 #define RD_TYPE_AS4     2