summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 f5b7ad52d..b5dd6c3ea 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 2280e738a..9401376a6 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 b97af3096..32707e33f 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 4af7a1ff2..5bd220b6a 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 bbf493440..833074cc5 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 740892cb8..a2ec7f92b 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 085a2c258..4d34bd461 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