summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2022-11-24 16:13:08 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2023-02-10 10:27:23 +0100
commit6f167d2363949dbbfac767b2c4bebf7b870febed (patch)
tree46389b9ef8e74d5b02096ff3a5c70e474b7d6cfc
parentad45cb7c040fc7b079751f9fdc77f0ae924d6d7e (diff)
bgpd: support for route-distinguisher format with 3 fields
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>
-rw-r--r--bgpd/bgp_rd.c35
-rw-r--r--bgpd/bgp_rd.h1
2 files changed, 30 insertions, 6 deletions
diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c
index f2ecd3de5f..e406d9ca6d 100644
--- a/bgpd/bgp_rd.c
+++ b/bgpd/bgp_rd.c
@@ -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);
diff --git a/bgpd/bgp_rd.h b/bgpd/bgp_rd.h
index aa9bc0b872..073eb7e114 100644
--- a/bgpd/bgp_rd.h
+++ b/bgpd/bgp_rd.h
@@ -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