X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=lib%2Fpackets.c;h=815d4e66be9d0b0b7b007123ba413e56f7f6d916;hb=f137ed099e3feaa4a9d8c5dc5f5234945451795e;hp=094f55366404dde0de4c11442341b75c4dfd5f0d;hpb=d9065a90b6b955aa38586c952e8804ca7a22547e;p=openvswitch diff --git a/lib/packets.c b/lib/packets.c index 094f5536..815d4e66 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -99,6 +99,30 @@ eth_push_vlan(struct ofpbuf *packet, ovs_be16 tci) packet->l2 = packet->data; } +/* 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)); +} + +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)); + } + } +} + + /* Stores the string representation of the IPv6 address 'addr' into the * character array 'addr_str', which must be at least INET6_ADDRSTRLEN * bytes long. */ @@ -111,10 +135,29 @@ format_ipv6_addr(char *addr_str, const struct in6_addr *addr) void print_ipv6_addr(struct ds *string, const struct in6_addr *addr) { - char addr_str[INET6_ADDRSTRLEN]; + char *dst; + + ds_reserve(string, string->length + INET6_ADDRSTRLEN); + + dst = string->string + string->length; + format_ipv6_addr(dst, addr); + string->length += strlen(dst); +} - format_ipv6_addr(addr_str, addr); - ds_put_format(string, "%s", addr_str); +void +print_ipv6_masked(struct ds *s, const struct in6_addr *addr, + const struct in6_addr *mask) +{ + print_ipv6_addr(s, addr); + if (mask && !ipv6_mask_is_exact(mask)) { + if (ipv6_is_cidr(mask)) { + int cidr_bits = ipv6_count_cidr_bits(mask); + ds_put_format(s, "/%d", cidr_bits); + } else { + ds_put_char(s, '/'); + print_ipv6_addr(s, mask); + } + } } struct in6_addr ipv6_addr_bitand(const struct in6_addr *a, @@ -158,9 +201,9 @@ ipv6_create_mask(int mask) return netmask; } -/* Given the IPv6 netmask 'netmask', returns the number of bits of the - * IPv6 address that it wildcards. 'netmask' must be a CIDR netmask (see - * ipv6_is_cidr()). */ +/* Given the IPv6 netmask 'netmask', returns the number of bits of the IPv6 + * address that it specifies, that is, the number of 1-bits in 'netmask'. + * 'netmask' must be a CIDR netmask (see ipv6_is_cidr()). */ int ipv6_count_cidr_bits(const struct in6_addr *netmask) {