diff options
Diffstat (limited to 'lib/prefix.c')
| -rw-r--r-- | lib/prefix.c | 138 |
1 files changed, 109 insertions, 29 deletions
diff --git a/lib/prefix.c b/lib/prefix.c index 1344039498..ed55fac883 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -31,8 +31,8 @@ DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix") /* Maskbit. */ -static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, - 0xf8, 0xfc, 0xfe, 0xff}; +static const uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff}; static const struct in6_addr maskbytes6[] = { /* /0 */ {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -441,7 +441,7 @@ int is_zero_mac(struct ethaddr *mac) return 1; } -unsigned int prefix_bit(const u_char *prefix, const u_char prefixlen) +unsigned int prefix_bit(const uint8_t *prefix, const uint8_t prefixlen) { unsigned int offset = prefixlen / 8; unsigned int shift = 7 - (prefixlen % 8); @@ -449,9 +449,9 @@ unsigned int prefix_bit(const u_char *prefix, const u_char prefixlen) return (prefix[offset] >> shift) & 1; } -unsigned int prefix6_bit(const struct in6_addr *prefix, const u_char prefixlen) +unsigned int prefix6_bit(const struct in6_addr *prefix, const uint8_t prefixlen) { - return prefix_bit((const u_char *)&prefix->s6_addr, prefixlen); + return prefix_bit((const uint8_t *)&prefix->s6_addr, prefixlen); } int str2family(const char *string) @@ -523,6 +523,8 @@ const char *safi2str(safi_t safi) return "evpn"; case SAFI_LABELED_UNICAST: return "labeled-unicast"; + case SAFI_FLOWSPEC: + return "flowspec"; default: return "unknown"; } @@ -533,15 +535,33 @@ int prefix_match(const struct prefix *n, const struct prefix *p) { int offset; int shift; - const u_char *np, *pp; + const uint8_t *np, *pp; /* If n's prefix is longer than p's one return 0. */ if (n->prefixlen > p->prefixlen) return 0; + if (n->family == AF_FLOWSPEC) { + /* prefixlen is unused. look at fs prefix len */ + if (n->u.prefix_flowspec.prefixlen > + p->u.prefix_flowspec.prefixlen) + return 0; + + /* Set both prefix's head pointer. */ + np = (const uint8_t *)&n->u.prefix_flowspec.ptr; + pp = (const uint8_t *)&p->u.prefix_flowspec.ptr; + + offset = n->u.prefix_flowspec.prefixlen; + + while (offset--) + if (np[offset] != pp[offset]) + return 0; + return 1; + } + /* Set both prefix's head pointer. */ - np = (const u_char *)&n->u.prefix; - pp = (const u_char *)&p->u.prefix; + np = (const uint8_t *)&n->u.prefix; + pp = (const uint8_t *)&p->u.prefix; offset = n->prefixlen / PNBBY; shift = n->prefixlen % PNBBY; @@ -562,11 +582,11 @@ int prefix_match_network_statement(const struct prefix *n, { int offset; int shift; - const u_char *np, *pp; + const uint8_t *np, *pp; /* Set both prefix's head pointer. */ - np = (const u_char *)&n->u.prefix; - pp = (const u_char *)&p->u.prefix; + np = (const uint8_t *)&n->u.prefix; + pp = (const uint8_t *)&p->u.prefix; offset = n->prefixlen / PNBBY; shift = n->prefixlen % PNBBY; @@ -581,7 +601,6 @@ int prefix_match_network_statement(const struct prefix *n, return 1; } -/* Copy prefix from src to dest. */ void prefix_copy(struct prefix *dest, const struct prefix *src) { dest->family = src->family; @@ -600,6 +619,18 @@ void prefix_copy(struct prefix *dest, const struct prefix *src) } else if (src->family == AF_UNSPEC) { dest->u.lp.id = src->u.lp.id; dest->u.lp.adv_router = src->u.lp.adv_router; + } else if (src->family == AF_FLOWSPEC) { + void *temp; + int len; + + len = src->u.prefix_flowspec.prefixlen; + dest->u.prefix_flowspec.prefixlen = + src->u.prefix_flowspec.prefixlen; + dest->family = src->family; + temp = XCALLOC(MTYPE_PREFIX_FLOWSPEC, len); + dest->u.prefix_flowspec.ptr = (uintptr_t)temp; + memcpy((void *)dest->u.prefix_flowspec.ptr, + (void *)src->u.prefix_flowspec.ptr, len); } else { zlog_err("prefix_copy(): Unknown address family %d", src->family); @@ -639,6 +670,15 @@ int prefix_same(const struct prefix *p1, const struct prefix *p2) if (!memcmp(&p1->u.prefix_evpn, &p2->u.prefix_evpn, sizeof(struct evpn_addr))) return 1; + if (p1->family == AF_FLOWSPEC) { + if (p1->u.prefix_flowspec.prefixlen != + p2->u.prefix_flowspec.prefixlen) + return 0; + if (!memcmp(&p1->u.prefix_flowspec.ptr, + &p2->u.prefix_flowspec.ptr, + p2->u.prefix_flowspec.prefixlen)) + return 1; + } } return 0; } @@ -659,12 +699,30 @@ int prefix_cmp(const struct prefix *p1, const struct prefix *p2) int shift; /* Set both prefix's head pointer. */ - const u_char *pp1 = (const u_char *)&p1->u.prefix; - const u_char *pp2 = (const u_char *)&p2->u.prefix; + const uint8_t *pp1; + const uint8_t *pp2; - if (p1->family != p2->family || p1->prefixlen != p2->prefixlen) + if (p1->family != p2->family) return 1; + if (p1->family == AF_FLOWSPEC) { + pp1 = (const uint8_t *)p1->u.prefix_flowspec.ptr; + pp2 = (const uint8_t *)p2->u.prefix_flowspec.ptr; + + if (p1->u.prefix_flowspec.prefixlen != + p2->u.prefix_flowspec.prefixlen) + return 1; + offset = p1->u.prefix_flowspec.prefixlen; + while (offset--) + if (pp1[offset] != pp2[offset]) + return 1; + return 0; + } + pp1 = (const uint8_t *)&p1->u.prefix; + pp2 = (const uint8_t *)&p2->u.prefix; + + if (p1->prefixlen != p2->prefixlen) + return 1; offset = p1->prefixlen / PNBBY; shift = p1->prefixlen % PNBBY; @@ -689,11 +747,11 @@ int prefix_common_bits(const struct prefix *p1, const struct prefix *p2) { int pos, bit; int length = 0; - u_char xor ; + uint8_t xor ; /* Set both prefix's head pointer. */ - const u_char *pp1 = (const u_char *)&p1->u.prefix; - const u_char *pp2 = (const u_char *)&p2->u.prefix; + const uint8_t *pp1 = (const uint8_t *)&p1->u.prefix; + const uint8_t *pp2 = (const uint8_t *)&p2->u.prefix; if (p1->family == AF_INET) length = IPV4_MAX_BYTELEN; @@ -787,7 +845,7 @@ int str2prefix_ipv4(const char *str, struct prefix_ipv4 *p) XFREE(MTYPE_TMP, cp); /* Get prefix length. */ - plen = (u_char)atoi(++pnt); + plen = (uint8_t)atoi(++pnt); if (plen > IPV4_MAX_PREFIXLEN) return 0; @@ -821,7 +879,7 @@ int str2prefix_eth(const char *str, struct prefix_eth *p) if (pnt) { /* Get prefix length. */ - plen = (u_char)atoi(++pnt); + plen = (uint8_t)atoi(++pnt); if (plen > 48) { ret = 0; goto done; @@ -883,7 +941,7 @@ void masklen2ip(const int masklen, struct in_addr *netmask) /* Convert IP address's netmask into integer. We assume netmask is sequential one. Argument netmask should be network byte order. */ -u_char ip_masklen(struct in_addr netmask) +uint8_t ip_masklen(struct in_addr netmask) { uint32_t tmp = ~ntohl(netmask.s_addr); if (tmp) @@ -953,7 +1011,7 @@ int str2prefix_ipv6(const char *str, struct prefix_ipv6 *p) XFREE(MTYPE_TMP, cp); if (ret == 0) return 0; - plen = (u_char)atoi(++pnt); + plen = (uint8_t)atoi(++pnt); if (plen > IPV6_MAX_BITLEN) return 0; p->prefixlen = plen; @@ -964,7 +1022,7 @@ int str2prefix_ipv6(const char *str, struct prefix_ipv6 *p) } /* Convert struct in6_addr netmask into integer. - * FIXME return u_char as ip_maskleni() does. */ + * FIXME return uint8_t as ip_maskleni() does. */ int ip6_masklen(struct in6_addr netmask) { int len = 0; @@ -996,14 +1054,14 @@ void masklen2ip6(const int masklen, struct in6_addr *netmask) void apply_mask_ipv6(struct prefix_ipv6 *p) { - u_char *pnt; + uint8_t *pnt; int index; int offset; index = p->prefixlen / 8; if (index < 16) { - pnt = (u_char *)&p->prefix; + pnt = (uint8_t *)&p->prefix; offset = p->prefixlen % 8; pnt[index] &= maskbit[offset]; @@ -1135,7 +1193,7 @@ int str2prefix(const char *str, struct prefix *p) static const char *prefixevpn2str(const struct prefix *p, char *str, int size) { - u_char family; + uint8_t family; char buf[PREFIX2STR_BUFFER]; char buf2[ETHER_ADDR_STRLEN]; @@ -1207,6 +1265,10 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size) prefixevpn2str(p, str, size); break; + case AF_FLOWSPEC: + sprintf(str, "FS prefix"); + break; + default: sprintf(str, "UNK prefix"); break; @@ -1244,7 +1306,7 @@ int all_digit(const char *str) void apply_classful_mask_ipv4(struct prefix_ipv4 *p) { - u_int32_t destination; + uint32_t destination; destination = ntohl(p->prefix.s_addr); @@ -1292,8 +1354,8 @@ int netmask_str2prefix_str(const char *net_str, const char *mask_str, { struct in_addr network; struct in_addr mask; - u_char prefixlen; - u_int32_t destination; + uint8_t prefixlen; + uint32_t destination; int ret; ret = inet_aton(net_str, &network); @@ -1386,6 +1448,24 @@ unsigned prefix_hash_key(void *pp) { struct prefix copy; + if (((struct prefix *)pp)->family == AF_FLOWSPEC) { + uint32_t len; + void *temp; + + /* make sure *all* unused bits are zero, + * particularly including alignment / + * padding and unused prefix bytes. + */ + memset(©, 0, sizeof(copy)); + prefix_copy(©, (struct prefix *)pp); + len = jhash((void *)copy.u.prefix_flowspec.ptr, + copy.u.prefix_flowspec.prefixlen, + 0x55aa5a5a); + temp = (void *)copy.u.prefix_flowspec.ptr; + XFREE(MTYPE_PREFIX_FLOWSPEC, temp); + copy.u.prefix_flowspec.ptr = (uintptr_t)NULL; + return len; + } /* make sure *all* unused bits are zero, particularly including * alignment / * padding and unused prefix bytes. */ |
