mirror of
https://github.com/openvswitch/ovs
synced 2025-10-25 15:07:05 +00:00
packets: Adds ethernet-matching helper functions
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), eth_addr_equal_except(a, b, mask) and eth_format_masked(eth, mask, output). Signed-off-by: Joe Stringer <joe@wand.net.nz> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -33,6 +33,7 @@ Jean Tourrilhes jt@hpl.hp.com
|
||||
Jeremy Stribling strib@nicira.com
|
||||
Jesse Gross jesse@nicira.com
|
||||
Joe Perches joe@perches.com
|
||||
Joe Stringer joe@wand.net.nz
|
||||
Jun Nakajima jun.nakajima@intel.com
|
||||
Justin Pettit jpettit@nicira.com
|
||||
Keith Amidon keith@nicira.com
|
||||
|
||||
@@ -2273,10 +2273,7 @@ mf_format(const struct mf_field *mf,
|
||||
break;
|
||||
|
||||
case MFS_ETHERNET:
|
||||
ds_put_format(s, ETH_ADDR_FMT, ETH_ADDR_ARGS(value->mac));
|
||||
if (mask) {
|
||||
ds_put_format(s, "/"ETH_ADDR_FMT, ETH_ADDR_ARGS(mask->mac));
|
||||
}
|
||||
eth_format_masked(value->mac, mask->mac, s);
|
||||
break;
|
||||
|
||||
case MFS_IPV4:
|
||||
|
||||
@@ -148,6 +148,28 @@ 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) {
|
||||
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;
|
||||
|
||||
for (i = 0; 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()). */
|
||||
|
||||
@@ -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])
|
||||
{
|
||||
@@ -74,6 +80,17 @@ static inline bool eth_addr_equals(const uint8_t a[ETH_ADDR_LEN],
|
||||
{
|
||||
return !eth_addr_compare_3way(a, b);
|
||||
}
|
||||
static inline bool eth_addr_equal_except(const uint8_t a[ETH_ADDR_LEN],
|
||||
const uint8_t b[ETH_ADDR_LEN],
|
||||
const uint8_t mask[ETH_ADDR_LEN])
|
||||
{
|
||||
return (((a[0] ^ b[0]) & mask[0])
|
||||
|| ((a[1] ^ b[1]) & mask[1])
|
||||
|| ((a[2] ^ b[2]) & mask[2])
|
||||
|| ((a[3] ^ b[3]) & mask[3])
|
||||
|| ((a[4] ^ b[4]) & mask[4])
|
||||
|| ((a[5] ^ b[5]) & mask[5]));
|
||||
}
|
||||
static inline uint64_t eth_addr_to_uint64(const uint8_t ea[ETH_ADDR_LEN])
|
||||
{
|
||||
return (((uint64_t) ea[0] << 40)
|
||||
@@ -136,6 +153,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:
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user