aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2012-05-22 22:06:03 -0700
committerBen Pfaff <blp@nicira.com>2012-06-12 21:19:22 -0700
commitc08201d6645520f384bbfee3b490b99af8f2c149 (patch)
tree3987c6448820cd39844d056c9741b3a3150f131f
parent410698cf7d0c9364a2ecb61b692e60da737bec78 (diff)
Allow general masking of IPv4 addresses rather than just CIDR masks.
OF1.1 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>
-rw-r--r--NEWS8
-rw-r--r--include/openflow/nicira-ext.h6
-rw-r--r--lib/meta-flow.c8
-rw-r--r--lib/ofp-util.c17
-rw-r--r--lib/packets.c7
-rw-r--r--tests/ovs-ofctl.at18
-rw-r--r--utilities/ovs-ofctl.8.in4
7 files changed, 46 insertions, 22 deletions
diff --git a/NEWS b/NEWS
index f5b7ad52..b5dd6c3e 100644
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,13 @@ post-v1.7.0
- New FAQ. Please send updates and additions!
- ovs-ofctl:
- "mod-port" command can now control all OpenFlow config flags.
- - Added support for arbitrary ethernet masks
+ - OpenFlow:
+ - Allow general bitwise masking for IPv4 source and destination
+ addresses in IPv4 and ARP packets. (Previously, only CIDR masks
+ were allowed.)
+ - Allow support for arbitrary Ethernet masks. (Previously, only
+ the multicast bit in the destination address could be individually
+ masked.)
- Additional protocols are not mirrored and dropped when forward-bpdu is
false. For a full list, see the ovs-vswitchd.conf.db man page.
- Open vSwitch now sends RARP packets in situations where it previously
diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index 2280e738..9401376a 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -1461,7 +1461,8 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
*
* Format: 32-bit integer in network byte order.
*
- * Masking: Only CIDR masks are allowed, that is, masks that consist of N
+ * Masking: Fully maskable, in Open vSwitch 1.8 and later. In earlier
+ * versions, only CIDR masks are allowed, that is, masks that consist of N
* high-order bits set to 1 and the other 32-N bits set to 0. */
#define NXM_OF_IP_SRC NXM_HEADER (0x0000, 7, 4)
#define NXM_OF_IP_SRC_W NXM_HEADER_W(0x0000, 7, 4)
@@ -1530,7 +1531,8 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
*
* Format: 32-bit integer in network byte order.
*
- * Masking: Only CIDR masks are allowed, that is, masks that consist of N
+ * Masking: Fully maskable, in Open vSwitch 1.8 and later. In earlier
+ * versions, only CIDR masks are allowed, that is, masks that consist of N
* high-order bits set to 1 and the other 32-N bits set to 0. */
#define NXM_OF_ARP_SPA NXM_HEADER (0x0000, 16, 4)
#define NXM_OF_ARP_SPA_W NXM_HEADER_W(0x0000, 16, 4)
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index b97af309..32707e33 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -175,7 +175,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
{
MFF_IPV4_SRC, "ip_src", "nw_src",
MF_FIELD_SIZES(be32),
- MFM_CIDR, 0,
+ MFM_FULLY, 0,
MFS_IPV4,
MFP_IPV4,
true,
@@ -184,7 +184,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
}, {
MFF_IPV4_DST, "ip_dst", "nw_dst",
MF_FIELD_SIZES(be32),
- MFM_CIDR, 0,
+ MFM_FULLY, 0,
MFS_IPV4,
MFP_IPV4,
true,
@@ -281,7 +281,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
}, {
MFF_ARP_SPA, "arp_spa", NULL,
MF_FIELD_SIZES(be32),
- MFM_CIDR, 0,
+ MFM_FULLY, 0,
MFS_IPV4,
MFP_ARP,
false,
@@ -290,7 +290,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
}, {
MFF_ARP_TPA, "arp_tpa", NULL,
MF_FIELD_SIZES(be32),
- MFM_CIDR, 0,
+ MFM_FULLY, 0,
MFS_IPV4,
MFP_ARP,
false,
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 4af7a1ff..5bd220b6 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -64,8 +64,11 @@ ofputil_wcbits_to_netmask(int wcbits)
}
/* Given the IP netmask 'netmask', returns the number of bits of the IP address
- * that it wildcards, that is, the number of 0-bits in 'netmask'. 'netmask'
- * must be a CIDR netmask (see ip_is_cidr()). */
+ * that it wildcards, that is, the number of 0-bits in 'netmask', a number
+ * between 0 and 32 inclusive.
+ *
+ * If 'netmask' is not a CIDR netmask (see ip_is_cidr()), the return value will
+ * still be in the valid range but isn't otherwise meaningful. */
int
ofputil_netmask_to_wcbits(ovs_be32 netmask)
{
@@ -348,11 +351,6 @@ ofputil_cls_rule_from_ofp11_match(const struct ofp11_match *match,
if (!(wc & OFPFW11_NW_PROTO)) {
cls_rule_set_nw_proto(rule, match->nw_proto);
}
-
- if (!ip_is_cidr(~match->nw_src_mask) ||
- !ip_is_cidr(~match->nw_dst_mask)) {
- return OFPERR_OFPBMC_BAD_NW_ADDR_MASK;
- }
cls_rule_set_nw_src_masked(rule, match->nw_src, ~match->nw_src_mask);
cls_rule_set_nw_dst_masked(rule, match->nw_dst, ~match->nw_dst_mask);
}
@@ -1497,6 +1495,11 @@ ofputil_usable_protocols(const struct cls_rule *rule)
return OFPUTIL_P_NXM_ANY;
}
+ /* Only NXM supports non-CIDR IPv4 address masks. */
+ if (!ip_is_cidr(wc->nw_src_mask) || !ip_is_cidr(wc->nw_dst_mask)) {
+ return OFPUTIL_P_NXM_ANY;
+ }
+
/* Only NXM supports bitwise matching on transport port. */
if ((wc->tp_src_mask && wc->tp_src_mask != htons(UINT16_MAX)) ||
(wc->tp_dst_mask && wc->tp_dst_mask != htons(UINT16_MAX))) {
diff --git a/lib/packets.c b/lib/packets.c
index bbf49344..833074cc 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -246,12 +246,13 @@ eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN],
}
/* 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()). */
+ * that it specifies, that is, the number of 1-bits in 'netmask'.
+ *
+ * If 'netmask' is not a CIDR netmask (see ip_is_cidr()), the return value will
+ * still be in the valid range but isn't otherwise meaningful. */
int
ip_count_cidr_bits(ovs_be32 netmask)
{
- assert(ip_is_cidr(netmask));
return 32 - ctz(ntohl(netmask));
}
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index 740892cb..a2ec7f92 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -274,12 +274,14 @@ NXM_NX_IP_TTL(80)
# IP source
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_SRC(ac100014)
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_SRC_W(C0a80000/FFFF0000)
+NXM_OF_ETH_TYPE(0800) NXM_OF_IP_SRC_W(C0a80000/5a5a5a5a)
NXM_OF_ETH_TYPE(0806) NXM_OF_IP_SRC(ac100014)
NXM_OF_IP_SRC_W(C0D80000/FFFF0000)
# IP destination
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_DST(ac100014)
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_DST_W(C0a88012/FFFF0000)
+NXM_OF_ETH_TYPE(0800) NXM_OF_IP_DST_W(C0a80000/5a5a5a5a)
NXM_OF_IP_DST(ac100014)
NXM_OF_ETH_TYPE(0806) NXM_OF_IP_DST_W(C0D80000/FFFF0000)
@@ -323,12 +325,14 @@ NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_OP(0001) NXM_OF_ARP_OP(0001)
# ARP source protocol address
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_SPA(ac100014)
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_SPA_W(C0a81234/FFFFFF00)
+NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_SPA_W(C0a81234/aaaaaa00)
NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_SPA(ac100014)
NXM_OF_ARP_SPA_W(C0D8fedc/FFFF0000)
# ARP destination protocol address
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_TPA(ac100014)
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_TPA_W(C0a812fe/FFFFFF00)
+NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_TPA_W(C0a81234/77777777)
NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_TPA(ac100014)
NXM_OF_ARP_TPA_W(C0D80000/FFFF0000)
@@ -474,12 +478,14 @@ nx_pull_match() returned error OFPBMC_BAD_PREREQ
# IP source
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_SRC(ac100014)
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_SRC_W(c0a80000/ffff0000)
+NXM_OF_ETH_TYPE(0800), NXM_OF_IP_SRC_W(40080000/5a5a5a5a)
nx_pull_match() returned error OFPBMC_BAD_PREREQ
nx_pull_match() returned error OFPBMC_BAD_PREREQ
# IP destination
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_DST(ac100014)
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_DST_W(c0a80000/ffff0000)
+NXM_OF_ETH_TYPE(0800), NXM_OF_IP_DST_W(40080000/5a5a5a5a)
nx_pull_match() returned error OFPBMC_BAD_PREREQ
nx_pull_match() returned error OFPBMC_BAD_PREREQ
@@ -523,12 +529,14 @@ nx_pull_match() returned error OFPBMC_DUP_FIELD
# ARP source protocol address
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA(ac100014)
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA_W(c0a81200/ffffff00)
+NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA_W(80a80200/aaaaaa00)
nx_pull_match() returned error OFPBMC_BAD_PREREQ
nx_pull_match() returned error OFPBMC_BAD_PREREQ
# ARP destination protocol address
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_TPA(ac100014)
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_TPA_W(c0a81200/ffffff00)
+NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_TPA_W(40201234/77777777)
nx_pull_match() returned error OFPBMC_BAD_PREREQ
nx_pull_match() returned error OFPBMC_BAD_PREREQ
@@ -765,8 +773,9 @@ dnl Try invalid TOS:
0000 00 00 0800 00 00 c0a88000000000ff 00000000ffffffff 0000 0000 dnl
00000000 00 000000 0000000000000000ffffffffffffffff
-dnl Try non-CIDR nw_src_mask:
-# bad ofp11_match: OFPBMC_BAD_NW_ADDR_MASK
+# ip,nw_src=128.160.128.0/165.165.165.165
+# 44: c0 -> 80
+# 45: a8 -> a0
0000 0058 00000000 000003f7 dnl
000000000000ffffffffffff 000000000000ffffffffffff dnl
0000 00 00 0800 00 00 c0a880005a5a5a5a 00000000ffffffff 0000 0000 dnl
@@ -778,8 +787,9 @@ dnl Try non-CIDR nw_src_mask:
0000 00 00 0800 00 00 00000000ffffffff c0a88000000000ff 0000 0000 dnl
00000000 00 000000 0000000000000000ffffffffffffffff
-dnl Try non-CIDR nw_dst_mask:
-# bad ofp11_match: OFPBMC_BAD_NW_ADDR_MASK
+# ip,nw_dst=128.160.128.0/165.165.165.165
+# 52: c0 -> 80
+# 53: a8 -> a0
0000 0058 00000000 000003f7 dnl
000000000000ffffffffffff 000000000000ffffffffffff dnl
0000 00 00 0800 00 00 00000000ffffffff c0a880005a5a5a5a 0000 0000 dnl
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 085a2c25..4d34bd46 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -418,7 +418,9 @@ which may be specified as an IP address or host name
\fInetmask\fR allows restricting a match to an IPv4 address prefix.
The netmask may be specified as a dotted quad
(e.g. \fB192.168.1.0/255.255.255.0\fR) or as a CIDR block
-(e.g. \fB192.168.1.0/24\fR).
+(e.g. \fB192.168.1.0/24\fR). Open vSwitch 1.8 and later support
+arbitrary dotted quad masks; earlier versions support only CIDR masks,
+that is, the dotted quads that are equivalent to some CIDR block.
.IP
When \fBdl_type=0x0806\fR or \fBarp\fR is specified, matches the
\fBar_spa\fR or \fBar_tpa\fR field, respectively, in ARP packets for