2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 09:58:01 +00:00

Allow general masking of IPv6 addresses rather than just CIDR masks.

OF1.2 and later make these fields fully maskable so we might as well also.

Reviewed-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ben Pfaff 2012-05-22 22:49:31 -07:00
parent c08201d664
commit ff0b06eef1
7 changed files with 42 additions and 25 deletions

4
NEWS
View File

@ -4,8 +4,8 @@ post-v1.7.0
- ovs-ofctl: - ovs-ofctl:
- "mod-port" command can now control all OpenFlow config flags. - "mod-port" command can now control all OpenFlow config flags.
- OpenFlow: - OpenFlow:
- Allow general bitwise masking for IPv4 source and destination - Allow general bitwise masking for IPv4 and IPv6 addresses in
addresses in IPv4 and ARP packets. (Previously, only CIDR masks IPv4, IPv6, and ARP packets. (Previously, only CIDR masks
were allowed.) were allowed.)
- Allow support for arbitrary Ethernet masks. (Previously, only - Allow support for arbitrary Ethernet masks. (Previously, only
the multicast bit in the destination address could be individually the multicast bit in the destination address could be individually

View File

@ -1608,7 +1608,8 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
* *
* Format: 128-bit IPv6 address. * Format: 128-bit IPv6 address.
* *
* Masking: Only CIDR masks are allowed, that is, masks that consist of N * Masking: Fully maskable, in Open vSwitch 1.8 and later. In previous
* versions, only CIDR masks are allowed, that is, masks that consist of N
* high-order bits set to 1 and the other 128-N bits set to 0. */ * high-order bits set to 1 and the other 128-N bits set to 0. */
#define NXM_NX_IPV6_SRC NXM_HEADER (0x0001, 19, 16) #define NXM_NX_IPV6_SRC NXM_HEADER (0x0001, 19, 16)
#define NXM_NX_IPV6_SRC_W NXM_HEADER_W(0x0001, 19, 16) #define NXM_NX_IPV6_SRC_W NXM_HEADER_W(0x0001, 19, 16)
@ -1636,7 +1637,8 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
* *
* Format: 128-bit IPv6 address. * Format: 128-bit IPv6 address.
* *
* Masking: Only CIDR masks are allowed, that is, masks that consist of N * Masking: Fully maskable, in Open vSwitch 1.8 and later. In previous
* versions, only CIDR masks are allowed, that is, masks that consist of N
* high-order bits set to 1 and the other 128-N bits set to 0. */ * high-order bits set to 1 and the other 128-N bits set to 0. */
#define NXM_NX_ND_TARGET NXM_HEADER (0x0001, 23, 16) #define NXM_NX_ND_TARGET NXM_HEADER (0x0001, 23, 16)
#define NXM_NX_ND_TARGET_W NXM_HEADER_W (0x0001, 23, 16) #define NXM_NX_ND_TARGET_W NXM_HEADER_W (0x0001, 23, 16)

View File

@ -195,7 +195,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
{ {
MFF_IPV6_SRC, "ipv6_src", NULL, MFF_IPV6_SRC, "ipv6_src", NULL,
MF_FIELD_SIZES(ipv6), MF_FIELD_SIZES(ipv6),
MFM_CIDR, 0, MFM_FULLY, 0,
MFS_IPV6, MFS_IPV6,
MFP_IPV6, MFP_IPV6,
true, true,
@ -204,7 +204,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
}, { }, {
MFF_IPV6_DST, "ipv6_dst", NULL, MFF_IPV6_DST, "ipv6_dst", NULL,
MF_FIELD_SIZES(ipv6), MF_FIELD_SIZES(ipv6),
MFM_CIDR, 0, MFM_FULLY, 0,
MFS_IPV6, MFS_IPV6,
MFP_IPV6, MFP_IPV6,
true, true,
@ -407,7 +407,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
{ {
MFF_ND_TARGET, "nd_target", NULL, MFF_ND_TARGET, "nd_target", NULL,
MF_FIELD_SIZES(ipv6), MF_FIELD_SIZES(ipv6),
MFM_CIDR, 0, MFM_FULLY, 0,
MFS_IPV6, MFS_IPV6,
MFP_ND, MFP_ND,
false, false,
@ -814,11 +814,6 @@ mf_is_mask_valid(const struct mf_field *mf, const union mf_value *mask)
case MFM_FULLY: case MFM_FULLY:
return true; return true;
case MFM_CIDR:
return (mf->n_bytes == 4
? ip_is_cidr(mask->be32)
: ipv6_is_cidr(&mask->ipv6));
} }
NOT_REACHED(); NOT_REACHED();
@ -2091,12 +2086,14 @@ mf_from_ipv6_string(const struct mf_field *mf, const char *s,
netmask = strtok_r(NULL, "/", &save_ptr); netmask = strtok_r(NULL, "/", &save_ptr);
if (netmask) { if (netmask) {
int prefix = atoi(netmask); if (inet_pton(AF_INET6, netmask, mask) != 1) {
if (prefix <= 0 || prefix > 128) { int prefix = atoi(netmask);
free(str); if (prefix <= 0 || prefix > 128) {
return xasprintf("%s: prefix bits not between 1 and 128", s); free(str);
} else { return xasprintf("%s: prefix bits not between 1 and 128", s);
*mask = ipv6_create_mask(prefix); } else {
*mask = ipv6_create_mask(prefix);
}
} }
} else { } else {
*mask = in6addr_exact; *mask = in6addr_exact;

View File

@ -144,7 +144,6 @@ enum mf_prereqs {
enum mf_maskable { enum mf_maskable {
MFM_NONE, /* No sub-field masking. */ MFM_NONE, /* No sub-field masking. */
MFM_FULLY, /* Every bit is individually maskable. */ MFM_FULLY, /* Every bit is individually maskable. */
MFM_CIDR /* Contiguous low-order bits may be masked. */
}; };
/* How to format or parse a field's value. */ /* How to format or parse a field's value. */

View File

@ -350,7 +350,10 @@ ipv6_create_mask(int mask)
/* Given the IPv6 netmask 'netmask', returns the number of bits of the IPv6 /* 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'. * address that it specifies, that is, the number of 1-bits in 'netmask'.
* 'netmask' must be a CIDR netmask (see ipv6_is_cidr()). */ * 'netmask' must be a CIDR netmask (see ipv6_is_cidr()).
*
* If 'netmask' is not a CIDR netmask (see ipv6_is_cidr()), the return value
* will still be in the valid range but isn't otherwise meaningful. */
int int
ipv6_count_cidr_bits(const struct in6_addr *netmask) ipv6_count_cidr_bits(const struct in6_addr *netmask)
{ {
@ -358,8 +361,6 @@ ipv6_count_cidr_bits(const struct in6_addr *netmask)
int count = 0; int count = 0;
const uint8_t *netmaskp = &netmask->s6_addr[0]; const uint8_t *netmaskp = &netmask->s6_addr[0];
assert(ipv6_is_cidr(netmask));
for (i=0; i<16; i++) { for (i=0; i<16; i++) {
if (netmaskp[i] == 0xff) { if (netmaskp[i] == 0xff) {
count += 8; count += 8;

View File

@ -350,14 +350,21 @@ NXM_NX_ARP_THA(0002e30f80a4)
NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005) NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005) NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_SRC_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000) NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_SRC_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000)
NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_SRC_W(20010db83c4d00010000000000000000/5a5a5a5a5a5a5a5a0000000000000000)
NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_SRC_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000) NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_SRC_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000)
# IPv6 destination # IPv6 destination
NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_DST(20010db83c4d00010002000300040005) NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_DST(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_DST(20010db83c4d00010002000300040005) NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_DST(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_DST_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000) NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_DST_W(20010db83c4d00010000000000000000/77777777777777777777777777777777)
NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_DST_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000) NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_DST_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000)
# ND target address
NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(87) NXM_NX_ND_TARGET(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(88) NXM_NX_ND_TARGET(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(87) NXM_NX_ND_TARGET_W(20010db83c4d00010002000300040005/0123456789abcdeffedcba9876543210)
NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(88) NXM_NX_ND_TARGET_W(20010db83c4d00010002000300040005/fedcba98765432100123456789abcdef)
# ND source hardware address # ND source hardware address
NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(87) NXM_NX_ND_TARGET(20010db83c4d00010002000300040005) NXM_NX_ND_SLL(0002e30f80a4) NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(87) NXM_NX_ND_TARGET(20010db83c4d00010002000300040005) NXM_NX_ND_SLL(0002e30f80a4)
NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(88) NXM_NX_ND_TARGET(20010db83c4d00010002000300040005) NXM_NX_ND_SLL(0002e30f80a4) NXM_OF_ETH_TYPE(86dd) NXM_OF_IP_PROTO(3a) NXM_NX_ICMPV6_TYPE(88) NXM_NX_ND_TARGET(20010db83c4d00010002000300040005) NXM_NX_ND_SLL(0002e30f80a4)
@ -554,14 +561,21 @@ nx_pull_match() returned error OFPBMC_BAD_PREREQ
NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005) NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005)
nx_pull_match() returned error OFPBMC_BAD_PREREQ nx_pull_match() returned error OFPBMC_BAD_PREREQ
NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_SRC_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000) NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_SRC_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000)
NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_SRC_W(00000818184800000000000000000000/5a5a5a5a5a5a5a5a0000000000000000)
nx_pull_match() returned error OFPBMC_BAD_PREREQ nx_pull_match() returned error OFPBMC_BAD_PREREQ
# IPv6 destination # IPv6 destination
NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_DST(20010db83c4d00010002000300040005) NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_DST(20010db83c4d00010002000300040005)
nx_pull_match() returned error OFPBMC_BAD_PREREQ nx_pull_match() returned error OFPBMC_BAD_PREREQ
NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_DST_W(20010db83c4d00010000000000000000/ffffffffffffffff0000000000000000) NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_DST_W(20010530344500010000000000000000/77777777777777777777777777777777)
nx_pull_match() returned error OFPBMC_BAD_PREREQ nx_pull_match() returned error OFPBMC_BAD_PREREQ
# ND target address
NXM_OF_ETH_TYPE(86dd), NXM_OF_IP_PROTO(3a), NXM_NX_ICMPV6_TYPE(87), NXM_NX_ND_TARGET(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(86dd), NXM_OF_IP_PROTO(3a), NXM_NX_ICMPV6_TYPE(88), NXM_NX_ND_TARGET(20010db83c4d00010002000300040005)
NXM_OF_ETH_TYPE(86dd), NXM_OF_IP_PROTO(3a), NXM_NX_ICMPV6_TYPE(87), NXM_NX_ND_TARGET_W(00010520080900010000000000040000/0123456789abcdeffedcba9876543210)
NXM_OF_ETH_TYPE(86dd), NXM_OF_IP_PROTO(3a), NXM_NX_ICMPV6_TYPE(88), NXM_NX_ND_TARGET_W(20000898344400000002000300000005/fedcba98765432100123456789abcdef)
# ND source hardware address # ND source hardware address
NXM_OF_ETH_TYPE(86dd), NXM_OF_IP_PROTO(3a), NXM_NX_ICMPV6_TYPE(87), NXM_NX_ND_TARGET(20010db83c4d00010002000300040005), NXM_NX_ND_SLL(0002e30f80a4) NXM_OF_ETH_TYPE(86dd), NXM_OF_IP_PROTO(3a), NXM_NX_ICMPV6_TYPE(87), NXM_NX_ND_TARGET(20010db83c4d00010002000300040005), NXM_NX_ND_SLL(0002e30f80a4)
nx_pull_match() returned error OFPBMC_BAD_PREREQ nx_pull_match() returned error OFPBMC_BAD_PREREQ

View File

@ -676,7 +676,11 @@ which may be specified as defined in RFC 2373. The preferred format is
address. A single instance of \fB::\fR may be used to indicate multiple address. A single instance of \fB::\fR may be used to indicate multiple
groups of 16-bits of zeros. The optional \fInetmask\fR allows groups of 16-bits of zeros. The optional \fInetmask\fR allows
restricting a match to an IPv6 address prefix. A netmask is specified restricting a match to an IPv6 address prefix. A netmask is specified
as a CIDR block (e.g. \fB2001:db8:3c4d:1::/64\fR). as an IPv6 address (e.g. \fB2001:db8:3c4d:1::/ffff:ffff:ffff:ffff::\fR)
or a CIDR block (e.g. \fB2001:db8:3c4d:1::/64\fR). Open vSwitch 1.8
and later support arbitrary masks; earlier versions support only CIDR
masks, that is, CIDR block and IPv6 addresses that are equivalent to
CIDR blocks.
. .
.IP \fBipv6_label=\fIlabel\fR .IP \fBipv6_label=\fIlabel\fR
When \fBdl_type\fR is 0x86dd (possibly via shorthand, e.g., \fBipv6\fR When \fBdl_type\fR is 0x86dd (possibly via shorthand, e.g., \fBipv6\fR