With OpenFlow 1.1 requiring arbitrary ethernet match support, it simplifies other code if we have some extra helper functions. This patch adds eth_mask_is_exact(mask), eth_addr_bitand(src, mask, dst) and eth_format_masked(eth, mask, output).
Signed-off-by: Joe Stringer <j...@wand.net.nz> --- lib/packets.c | 20 ++++++++++++++++++++ lib/packets.h | 11 +++++++++++ 2 files changed, 31 insertions(+), 0 deletions(-) diff --git a/lib/packets.c b/lib/packets.c index 84ca590..bbe35e6 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -148,6 +148,26 @@ eth_from_hex(const char *hex, struct ofpbuf **packetp) return NULL; } +void +eth_format_masked(const uint8_t eth[ETH_ADDR_LEN], + const uint8_t mask[ETH_ADDR_LEN], struct ds *s) +{ + ds_put_format(s, ETH_ADDR_FMT, ETH_ADDR_ARGS(eth)); + if (mask && !eth_addr_is_zero(mask) && !eth_mask_is_exact(mask)) { + ds_put_format(s, "/"ETH_ADDR_FMT, ETH_ADDR_ARGS(mask)); + } +} + +void eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN], + const uint8_t mask[ETH_ADDR_LEN], + uint8_t dst[ETH_ADDR_LEN]) +{ + int i = 0; + for (; i < ETH_ADDR_LEN; ++i) { + dst[i] = src[i] & mask[i]; + } +} + /* 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()). */ diff --git a/lib/packets.h b/lib/packets.h index f9e5bb6..5807200 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -64,6 +64,12 @@ static inline bool eth_addr_is_zero(const uint8_t ea[6]) { return !(ea[0] | ea[1] | ea[2] | ea[3] | ea[4] | ea[5]); } + +static inline int eth_mask_is_exact(const uint8_t ea[ETH_ADDR_LEN]) +{ + return (ea[0] & ea[1] & ea[2] & ea[3] & ea[4] & ea[5]) == 0xff; +} + static inline int eth_addr_compare_3way(const uint8_t a[ETH_ADDR_LEN], const uint8_t b[ETH_ADDR_LEN]) { @@ -136,6 +142,11 @@ void eth_push_vlan(struct ofpbuf *, ovs_be16 tci); void eth_pop_vlan(struct ofpbuf *); const char *eth_from_hex(const char *hex, struct ofpbuf **packetp); +void eth_format_masked(const uint8_t eth[ETH_ADDR_LEN], + const uint8_t mask[ETH_ADDR_LEN], struct ds *s); +void eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN], + const uint8_t mask[ETH_ADDR_LEN], + uint8_t dst[ETH_ADDR_LEN]); /* Example: * -- 1.6.0.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev