]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/prefix.c
Merge pull request #3397 from mjstapp/fix_stream_macros
[mirror_frr.git] / lib / prefix.c
index 05af190e9daa5b59db64d3015142a4933dd3685b..858f860ee8e1f8e99e169bc5fe75eae00a056739 100644 (file)
@@ -27,6 +27,7 @@
 #include "memory.h"
 #include "log.h"
 #include "jhash.h"
+#include "lib_errors.h"
 
 DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix")
 
@@ -429,6 +430,15 @@ static const struct in6_addr maskbytes6[] = {
 
 #define MASKBIT(offset)  ((0xff << (PNBBY - (offset))) & 0xff)
 
+void prefix_hexdump(const struct prefix *p)
+{
+       char buf[PREFIX_STRLEN];
+
+       zlog_debug("prefix: %s",
+                  prefix2str(p, buf, sizeof(buf)));
+       zlog_hexdump(p, sizeof(struct prefix));
+}
+
 int is_zero_mac(struct ethaddr *mac)
 {
        int i = 0;
@@ -575,8 +585,8 @@ int prefix_match(const struct prefix *n, const struct prefix *p)
        }
 
        /* Set both prefix's head pointer. */
-       np = (const uint8_t *)&n->u.prefix;
-       pp = (const uint8_t *)&p->u.prefix;
+       np = n->u.val;
+       pp = p->u.val;
 
        offset = n->prefixlen / PNBBY;
        shift = n->prefixlen % PNBBY;
@@ -600,8 +610,8 @@ int prefix_match_network_statement(const struct prefix *n,
        const uint8_t *np, *pp;
 
        /* Set both prefix's head pointer. */
-       np = (const uint8_t *)&n->u.prefix;
-       pp = (const uint8_t *)&p->u.prefix;
+       np = n->u.val;
+       pp = p->u.val;
 
        offset = n->prefixlen / PNBBY;
        shift = n->prefixlen % PNBBY;
@@ -647,7 +657,8 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
                memcpy((void *)dest->u.prefix_flowspec.ptr,
                       (void *)src->u.prefix_flowspec.ptr, len);
        } else {
-               zlog_err("prefix_copy(): Unknown address family %d",
+               flog_err(EC_LIB_DEVELOPMENT,
+                        "prefix_copy(): Unknown address family %d",
                         src->family);
                assert(0);
        }
@@ -733,8 +744,8 @@ int prefix_cmp(const struct prefix *p1, const struct prefix *p2)
                                return 1;
                return 0;
        }
-       pp1 = (const uint8_t *)&p1->u.prefix;
-       pp2 = (const uint8_t *)&p2->u.prefix;
+       pp1 = p1->u.val;
+       pp2 = p2->u.val;
 
        if (p1->prefixlen != p2->prefixlen)
                return 1;
@@ -765,8 +776,8 @@ int prefix_common_bits(const struct prefix *p1, const struct prefix *p2)
        uint8_t xor ;
 
        /* Set both prefix's head pointer. */
-       const uint8_t *pp1 = (const uint8_t *)&p1->u.prefix;
-       const uint8_t *pp2 = (const uint8_t *)&p2->u.prefix;
+       const uint8_t *pp1 = p1->u.val;
+       const uint8_t *pp2 = p2->u.val;
 
        if (p1->family == AF_INET)
                length = IPV4_MAX_BYTELEN;
@@ -842,7 +853,7 @@ int str2prefix_ipv4(const char *str, struct prefix_ipv4 *p)
        /* String doesn't contail slash. */
        if (pnt == NULL) {
                /* Convert string to prefix. */
-               ret = inet_aton(str, &p->prefix);
+               ret = inet_pton(AF_INET, str, &p->prefix);
                if (ret == 0)
                        return 0;
 
@@ -1188,6 +1199,9 @@ int str2prefix(const char *str, struct prefix *p)
 {
        int ret;
 
+       if (!str || !p)
+               return 0;
+
        /* First we try to convert string to struct prefix_ipv4. */
        ret = str2prefix_ipv4(str, (struct prefix_ipv4 *)p);
        if (ret)
@@ -1262,7 +1276,12 @@ static const char *prefixevpn_imet2str(const struct prefix_evpn *p, char *str,
 static const char *prefixevpn_es2str(const struct prefix_evpn *p, char *str,
                                     int size)
 {
-       snprintf(str, size, "Unsupported EVPN prefix");
+       char buf[ESI_STR_LEN];
+
+       snprintf(str, size, "[%d]:[%s]:[%s]/%d", p->prefix.route_type,
+                esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)),
+                inet_ntoa(p->prefix.es_addr.ip.ipaddr_v4),
+                p->prefixlen);
        return str;
 }
 
@@ -1356,17 +1375,6 @@ void prefix_free(struct prefix *p)
        XFREE(MTYPE_PREFIX, p);
 }
 
-/* Utility function.  Check the string only contains digit
- * character.
- * FIXME str.[c|h] would be better place for this function. */
-int all_digit(const char *str)
-{
-       for (; *str != '\0'; str++)
-               if (!isdigit((int)*str))
-                       return 0;
-       return 1;
-}
-
 /* Utility function to convert ipv4 prefixes to Classful prefixes */
 void apply_classful_mask_ipv4(struct prefix_ipv4 *p)
 {
@@ -1540,3 +1548,56 @@ unsigned prefix_hash_key(void *pp)
                     offsetof(struct prefix, u.prefix) + PSIZE(copy.prefixlen),
                     0x55aa5a5a);
 }
+
+/* converts to internal representation of esi
+ * returns 1 on success, 0 otherwise
+ * format accepted: aa:aa:aa:aa:aa:aa:aa:aa:aa:aa
+ * if esi parameter is null, then check only
+ */
+int str_to_esi(const char *str, esi_t *esi)
+{
+       int i;
+       unsigned int a[ESI_BYTES];
+
+       if (!str)
+               return 0;
+
+       if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x",
+                  a + 0, a + 1, a + 2, a + 3,
+                  a + 4, a + 5, a + 6, a + 7,
+                  a + 8, a + 9)
+           != ESI_BYTES) {
+               /* error in incoming str length */
+               return 0;
+       }
+
+       /* valid ESI */
+       if (!esi)
+               return 1;
+       for (i = 0; i < ESI_BYTES; ++i)
+               esi->val[i] = a[i] & 0xff;
+       return 1;
+}
+
+char *esi_to_str(const esi_t *esi, char *buf, int size)
+{
+       char *ptr;
+
+       if (!esi)
+               return NULL;
+       if (!buf)
+               ptr = (char *)XMALLOC(MTYPE_TMP,
+                                     ESI_STR_LEN * sizeof(char));
+       else {
+               assert(size >= ESI_STR_LEN);
+               ptr = buf;
+       }
+
+       snprintf(ptr, ESI_STR_LEN,
+                "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+                esi->val[0], esi->val[1], esi->val[2],
+                esi->val[3], esi->val[4], esi->val[5],
+                esi->val[6], esi->val[7], esi->val[8],
+                esi->val[9]);
+       return ptr;
+}