static void test_ipv4_cidr(void) { assert(ip_is_cidr(htonl(0x00000000))); assert(ip_is_cidr(htonl(0x80000000))); assert(ip_is_cidr(htonl(0xf0000000))); assert(ip_is_cidr(htonl(0xffffffe0))); assert(ip_is_cidr(htonl(0xffffffff))); assert(!ip_is_cidr(htonl(0x00000001))); assert(!ip_is_cidr(htonl(0x40000000))); assert(!ip_is_cidr(htonl(0x0fffffff))); assert(!ip_is_cidr(htonl(0xffffffd0))); }
void ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *s) { ds_put_format(s, IP_FMT, IP_ARGS(&ip)); if (mask != htonl(UINT32_MAX)) { if (ip_is_cidr(mask)) { ds_put_format(s, "/%d", ip_count_cidr_bits(mask)); } else { ds_put_format(s, "/"IP_FMT, IP_ARGS(&mask)); } } }
static void lex_token_format_masked_integer(const struct lex_token *token, struct ds *s) { enum lex_format format = lex_token_get_format(token); lex_token_format_value(&token->value, format, s); ds_put_char(s, '/'); const union mf_subvalue *mask = &token->mask; if (format == LEX_F_IPV4 && ip_is_cidr(mask->ipv4)) { ds_put_format(s, "%d", ip_count_cidr_bits(mask->ipv4)); } else if (token->format == LEX_F_IPV6 && ipv6_is_cidr(&mask->ipv6)) { ds_put_format(s, "%d", ipv6_count_cidr_bits(&mask->ipv6)); } else { lex_token_format_value(&token->mask, format, s); } }
/* Given the IP netmask 'netmask', returns the number of bits of the IP address * that it specifies, that is, the number of 1-bits in 'netmask'. 'netmask' * must be a CIDR netmask (see ip_is_cidr()). */ int ip_count_cidr_bits(ovs_be32 netmask) { assert(ip_is_cidr(netmask)); return 32 - ctz(ntohl(netmask)); }