mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 22:35:15 +00:00
openflow-1.0: Rename ofp_match to ofp10_match, OFPFW_* to OFPFW10_*.
This better fits our general policy of adding a version number suffix to structures and constants whose values differ from one OpenFlow version to the next. Reviewed-by: Simon Horman <horms@verge.net.au> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -1149,11 +1149,11 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
|
||||
|
||||
/* Flexible flow specifications (aka NXM = Nicira Extended Match).
|
||||
*
|
||||
* OpenFlow 1.0 has "struct ofp_match" for specifying flow matches. This
|
||||
* OpenFlow 1.0 has "struct ofp10_match" for specifying flow matches. This
|
||||
* structure is fixed-length and hence difficult to extend. This section
|
||||
* describes a more flexible, variable-length flow match, called "nx_match" for
|
||||
* short, that is also supported by Open vSwitch. This section also defines a
|
||||
* replacement for each OpenFlow message that includes struct ofp_match.
|
||||
* replacement for each OpenFlow message that includes struct ofp10_match.
|
||||
*
|
||||
*
|
||||
* Format
|
||||
@@ -1211,7 +1211,7 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
|
||||
* matches bit J in nxm_value. A 0-bit in nxm_mask causes the
|
||||
* corresponding bits in nxm_value and the field's value to be ignored.
|
||||
* (The sense of the nxm_mask bits is the opposite of that used by the
|
||||
* "wildcards" member of struct ofp_match.)
|
||||
* "wildcards" member of struct ofp10_match.)
|
||||
*
|
||||
* When nxm_hasmask is 1, nxm_length is always even.
|
||||
*
|
||||
|
@@ -372,41 +372,43 @@ enum ofp_flow_mod_command {
|
||||
|
||||
/* Flow wildcards. */
|
||||
enum ofp_flow_wildcards {
|
||||
OFPFW_IN_PORT = 1 << 0, /* Switch input port. */
|
||||
OFPFW_DL_VLAN = 1 << 1, /* VLAN vid. */
|
||||
OFPFW_DL_SRC = 1 << 2, /* Ethernet source address. */
|
||||
OFPFW_DL_DST = 1 << 3, /* Ethernet destination address. */
|
||||
OFPFW_DL_TYPE = 1 << 4, /* Ethernet frame type. */
|
||||
OFPFW_NW_PROTO = 1 << 5, /* IP protocol. */
|
||||
OFPFW_TP_SRC = 1 << 6, /* TCP/UDP source port. */
|
||||
OFPFW_TP_DST = 1 << 7, /* TCP/UDP destination port. */
|
||||
OFPFW10_IN_PORT = 1 << 0, /* Switch input port. */
|
||||
OFPFW10_DL_VLAN = 1 << 1, /* VLAN vid. */
|
||||
OFPFW10_DL_SRC = 1 << 2, /* Ethernet source address. */
|
||||
OFPFW10_DL_DST = 1 << 3, /* Ethernet destination address. */
|
||||
OFPFW10_DL_TYPE = 1 << 4, /* Ethernet frame type. */
|
||||
OFPFW10_NW_PROTO = 1 << 5, /* IP protocol. */
|
||||
OFPFW10_TP_SRC = 1 << 6, /* TCP/UDP source port. */
|
||||
OFPFW10_TP_DST = 1 << 7, /* TCP/UDP destination port. */
|
||||
|
||||
/* IP source address wildcard bit count. 0 is exact match, 1 ignores the
|
||||
* LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
|
||||
* the entire field. This is the *opposite* of the usual convention where
|
||||
* e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded. */
|
||||
OFPFW_NW_SRC_SHIFT = 8,
|
||||
OFPFW_NW_SRC_BITS = 6,
|
||||
OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT,
|
||||
OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT,
|
||||
OFPFW10_NW_SRC_SHIFT = 8,
|
||||
OFPFW10_NW_SRC_BITS = 6,
|
||||
OFPFW10_NW_SRC_MASK = (((1 << OFPFW10_NW_SRC_BITS) - 1)
|
||||
<< OFPFW10_NW_SRC_SHIFT),
|
||||
OFPFW10_NW_SRC_ALL = 32 << OFPFW10_NW_SRC_SHIFT,
|
||||
|
||||
/* IP destination address wildcard bit count. Same format as source. */
|
||||
OFPFW_NW_DST_SHIFT = 14,
|
||||
OFPFW_NW_DST_BITS = 6,
|
||||
OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT,
|
||||
OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT,
|
||||
OFPFW10_NW_DST_SHIFT = 14,
|
||||
OFPFW10_NW_DST_BITS = 6,
|
||||
OFPFW10_NW_DST_MASK = (((1 << OFPFW10_NW_DST_BITS) - 1)
|
||||
<< OFPFW10_NW_DST_SHIFT),
|
||||
OFPFW10_NW_DST_ALL = 32 << OFPFW10_NW_DST_SHIFT,
|
||||
|
||||
OFPFW_DL_VLAN_PCP = 1 << 20, /* VLAN priority. */
|
||||
OFPFW_NW_TOS = 1 << 21, /* IP ToS (DSCP field, 6 bits). */
|
||||
OFPFW10_DL_VLAN_PCP = 1 << 20, /* VLAN priority. */
|
||||
OFPFW10_NW_TOS = 1 << 21, /* IP ToS (DSCP field, 6 bits). */
|
||||
|
||||
/* Wildcard all fields. */
|
||||
OFPFW_ALL = ((1 << 22) - 1)
|
||||
OFPFW10_ALL = ((1 << 22) - 1)
|
||||
};
|
||||
|
||||
/* The wildcards for ICMP type and code fields use the transport source
|
||||
* and destination port fields, respectively. */
|
||||
#define OFPFW_ICMP_TYPE OFPFW_TP_SRC
|
||||
#define OFPFW_ICMP_CODE OFPFW_TP_DST
|
||||
#define OFPFW10_ICMP_TYPE OFPFW10_TP_SRC
|
||||
#define OFPFW10_ICMP_CODE OFPFW10_TP_DST
|
||||
|
||||
/* Values below this cutoff are 802.3 packets and the two bytes
|
||||
* following MAC addresses are used as a frame length. Otherwise, the
|
||||
@@ -425,7 +427,7 @@ enum ofp_flow_wildcards {
|
||||
#define OFP_VLAN_NONE 0xffff
|
||||
|
||||
/* Fields to match against flows */
|
||||
struct ofp_match {
|
||||
struct ofp10_match {
|
||||
ovs_be32 wildcards; /* Wildcard fields. */
|
||||
ovs_be16 in_port; /* Input switch port. */
|
||||
uint8_t dl_src[OFP_ETH_ALEN]; /* Ethernet source address. */
|
||||
@@ -443,7 +445,7 @@ struct ofp_match {
|
||||
ovs_be16 tp_src; /* TCP/UDP source port. */
|
||||
ovs_be16 tp_dst; /* TCP/UDP destination port. */
|
||||
};
|
||||
OFP_ASSERT(sizeof(struct ofp_match) == 40);
|
||||
OFP_ASSERT(sizeof(struct ofp10_match) == 40);
|
||||
|
||||
/* Value used in "idle_timeout" and "hard_timeout" to indicate that the entry
|
||||
* is permanent. */
|
||||
@@ -462,7 +464,7 @@ enum ofp_flow_mod_flags {
|
||||
/* Flow setup and teardown (controller -> datapath). */
|
||||
struct ofp_flow_mod {
|
||||
struct ofp_header header;
|
||||
struct ofp_match match; /* Fields to match */
|
||||
struct ofp10_match match; /* Fields to match */
|
||||
ovs_be64 cookie; /* Opaque controller-issued identifier. */
|
||||
|
||||
/* Flow actions. */
|
||||
@@ -486,7 +488,7 @@ OFP_ASSERT(sizeof(struct ofp_flow_mod) == 72);
|
||||
/* Flow removed (datapath -> controller). */
|
||||
struct ofp_flow_removed {
|
||||
struct ofp_header header;
|
||||
struct ofp_match match; /* Description of fields. */
|
||||
struct ofp10_match match; /* Description of fields. */
|
||||
ovs_be64 cookie; /* Opaque controller-issued identifier. */
|
||||
|
||||
ovs_be16 priority; /* Priority level of flow entry. */
|
||||
@@ -545,7 +547,7 @@ OFP_ASSERT(sizeof(struct ofp_desc_stats) == 1068);
|
||||
/* Stats request of type OFPST_AGGREGATE or OFPST_FLOW. */
|
||||
struct ofp_flow_stats_request {
|
||||
struct ofp_stats_msg osm;
|
||||
struct ofp_match match; /* Fields to match. */
|
||||
struct ofp10_match match; /* Fields to match. */
|
||||
uint8_t table_id; /* ID of table to read (from ofp_table_stats)
|
||||
or 0xff for all tables. */
|
||||
uint8_t pad; /* Align to 32 bits. */
|
||||
@@ -560,7 +562,7 @@ struct ofp_flow_stats {
|
||||
ovs_be16 length; /* Length of this entry. */
|
||||
uint8_t table_id; /* ID of table flow came from. */
|
||||
uint8_t pad;
|
||||
struct ofp_match match; /* Description of fields. */
|
||||
struct ofp10_match match; /* Description of fields. */
|
||||
ovs_be32 duration_sec; /* Time flow has been alive in seconds. */
|
||||
ovs_be32 duration_nsec; /* Time flow has been alive in nanoseconds
|
||||
beyond duration_sec. */
|
||||
@@ -592,7 +594,7 @@ struct ofp_table_stats {
|
||||
are consulted first. */
|
||||
uint8_t pad[3]; /* Align to 32-bits. */
|
||||
char name[OFP_MAX_TABLE_NAME_LEN];
|
||||
ovs_be32 wildcards; /* Bitmap of OFPFW_* wildcards that are
|
||||
ovs_be32 wildcards; /* Bitmap of OFPFW10_* wildcards that are
|
||||
supported by the table. */
|
||||
ovs_be32 max_entries; /* Max number of entries supported. */
|
||||
ovs_be32 active_count; /* Number of active entries. */
|
||||
|
@@ -29,7 +29,6 @@
|
||||
struct dpif_flow_stats;
|
||||
struct ds;
|
||||
struct flow_wildcards;
|
||||
struct ofp_match;
|
||||
struct ofpbuf;
|
||||
|
||||
/* This sequence number should be incremented whenever anything involving flows
|
||||
@@ -145,11 +144,11 @@ flow_hash(const struct flow *flow, uint32_t basis)
|
||||
|
||||
typedef unsigned int OVS_BITWISE flow_wildcards_t;
|
||||
|
||||
/* Same values and meanings as corresponding OFPFW_* bits. */
|
||||
/* Same values and meanings as corresponding OFPFW10_* bits. */
|
||||
#define FWW_IN_PORT ((OVS_FORCE flow_wildcards_t) (1 << 0))
|
||||
#define FWW_DL_TYPE ((OVS_FORCE flow_wildcards_t) (1 << 4))
|
||||
#define FWW_NW_PROTO ((OVS_FORCE flow_wildcards_t) (1 << 5))
|
||||
/* No corresponding OFPFW_* bits. */
|
||||
/* No corresponding OFPFW10_* bits. */
|
||||
#define FWW_NW_DSCP ((OVS_FORCE flow_wildcards_t) (1 << 1))
|
||||
#define FWW_NW_ECN ((OVS_FORCE flow_wildcards_t) (1 << 2))
|
||||
#define FWW_ARP_SHA ((OVS_FORCE flow_wildcards_t) (1 << 3))
|
||||
|
@@ -111,15 +111,15 @@ lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg)
|
||||
/* Try to wildcard as many fields as possible, but we cannot
|
||||
* wildcard all fields. We need in_port to detect moves. We need
|
||||
* Ethernet source and dest and VLAN VID to do L2 learning. */
|
||||
ofpfw = (OFPFW_DL_TYPE | OFPFW_DL_VLAN_PCP
|
||||
| OFPFW_NW_SRC_ALL | OFPFW_NW_DST_ALL
|
||||
| OFPFW_NW_TOS | OFPFW_NW_PROTO
|
||||
| OFPFW_TP_SRC | OFPFW_TP_DST);
|
||||
ofpfw = (OFPFW10_DL_TYPE | OFPFW10_DL_VLAN_PCP
|
||||
| OFPFW10_NW_SRC_ALL | OFPFW10_NW_DST_ALL
|
||||
| OFPFW10_NW_TOS | OFPFW10_NW_PROTO
|
||||
| OFPFW10_TP_SRC | OFPFW10_TP_DST);
|
||||
} else {
|
||||
ofpfw = cfg->wildcards;
|
||||
}
|
||||
|
||||
ofputil_wildcard_from_openflow(ofpfw, &sw->wc);
|
||||
ofputil_wildcard_from_ofpfw10(ofpfw, &sw->wc);
|
||||
}
|
||||
|
||||
sw->default_queue = cfg->default_queue;
|
||||
|
@@ -34,7 +34,7 @@ struct lswitch_config {
|
||||
enum lswitch_mode mode;
|
||||
|
||||
/* 0 to use exact-match flow entries,
|
||||
* a OFPFW_* bitmask to enable specific wildcards,
|
||||
* a OFPFW10_* bitmask to enable specific wildcards,
|
||||
* or UINT32_MAX to use the default wildcards (wildcarding as many fields
|
||||
* as possible.
|
||||
*
|
||||
|
@@ -826,25 +826,25 @@ print_ip_netmask(struct ds *string, const char *leader, ovs_be32 ip,
|
||||
}
|
||||
|
||||
void
|
||||
ofp_print_match(struct ds *f, const struct ofp_match *om, int verbosity)
|
||||
ofp10_match_print(struct ds *f, const struct ofp10_match *om, int verbosity)
|
||||
{
|
||||
char *s = ofp_match_to_string(om, verbosity);
|
||||
char *s = ofp10_match_to_string(om, verbosity);
|
||||
ds_put_cstr(f, s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
char *
|
||||
ofp_match_to_string(const struct ofp_match *om, int verbosity)
|
||||
ofp10_match_to_string(const struct ofp10_match *om, int verbosity)
|
||||
{
|
||||
struct ds f = DS_EMPTY_INITIALIZER;
|
||||
uint32_t w = ntohl(om->wildcards);
|
||||
bool skip_type = false;
|
||||
bool skip_proto = false;
|
||||
|
||||
if (!(w & OFPFW_DL_TYPE)) {
|
||||
if (!(w & OFPFW10_DL_TYPE)) {
|
||||
skip_type = true;
|
||||
if (om->dl_type == htons(ETH_TYPE_IP)) {
|
||||
if (!(w & OFPFW_NW_PROTO)) {
|
||||
if (!(w & OFPFW10_NW_PROTO)) {
|
||||
skip_proto = true;
|
||||
if (om->nw_proto == IPPROTO_ICMP) {
|
||||
ds_put_cstr(&f, "icmp,");
|
||||
@@ -865,44 +865,46 @@ ofp_match_to_string(const struct ofp_match *om, int verbosity)
|
||||
skip_type = false;
|
||||
}
|
||||
}
|
||||
print_wild(&f, "in_port=", w & OFPFW_IN_PORT, verbosity,
|
||||
print_wild(&f, "in_port=", w & OFPFW10_IN_PORT, verbosity,
|
||||
"%d", ntohs(om->in_port));
|
||||
print_wild(&f, "dl_vlan=", w & OFPFW_DL_VLAN, verbosity,
|
||||
print_wild(&f, "dl_vlan=", w & OFPFW10_DL_VLAN, verbosity,
|
||||
"%d", ntohs(om->dl_vlan));
|
||||
print_wild(&f, "dl_vlan_pcp=", w & OFPFW_DL_VLAN_PCP, verbosity,
|
||||
print_wild(&f, "dl_vlan_pcp=", w & OFPFW10_DL_VLAN_PCP, verbosity,
|
||||
"%d", om->dl_vlan_pcp);
|
||||
print_wild(&f, "dl_src=", w & OFPFW_DL_SRC, verbosity,
|
||||
print_wild(&f, "dl_src=", w & OFPFW10_DL_SRC, verbosity,
|
||||
ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_src));
|
||||
print_wild(&f, "dl_dst=", w & OFPFW_DL_DST, verbosity,
|
||||
print_wild(&f, "dl_dst=", w & OFPFW10_DL_DST, verbosity,
|
||||
ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_dst));
|
||||
if (!skip_type) {
|
||||
print_wild(&f, "dl_type=", w & OFPFW_DL_TYPE, verbosity,
|
||||
print_wild(&f, "dl_type=", w & OFPFW10_DL_TYPE, verbosity,
|
||||
"0x%04x", ntohs(om->dl_type));
|
||||
}
|
||||
print_ip_netmask(&f, "nw_src=", om->nw_src,
|
||||
(w & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT, verbosity);
|
||||
(w & OFPFW10_NW_SRC_MASK) >> OFPFW10_NW_SRC_SHIFT,
|
||||
verbosity);
|
||||
print_ip_netmask(&f, "nw_dst=", om->nw_dst,
|
||||
(w & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT, verbosity);
|
||||
(w & OFPFW10_NW_DST_MASK) >> OFPFW10_NW_DST_SHIFT,
|
||||
verbosity);
|
||||
if (!skip_proto) {
|
||||
if (om->dl_type == htons(ETH_TYPE_ARP)) {
|
||||
print_wild(&f, "arp_op=", w & OFPFW_NW_PROTO, verbosity,
|
||||
print_wild(&f, "arp_op=", w & OFPFW10_NW_PROTO, verbosity,
|
||||
"%u", om->nw_proto);
|
||||
} else {
|
||||
print_wild(&f, "nw_proto=", w & OFPFW_NW_PROTO, verbosity,
|
||||
print_wild(&f, "nw_proto=", w & OFPFW10_NW_PROTO, verbosity,
|
||||
"%u", om->nw_proto);
|
||||
}
|
||||
}
|
||||
print_wild(&f, "nw_tos=", w & OFPFW_NW_TOS, verbosity,
|
||||
print_wild(&f, "nw_tos=", w & OFPFW10_NW_TOS, verbosity,
|
||||
"%u", om->nw_tos);
|
||||
if (om->nw_proto == IPPROTO_ICMP) {
|
||||
print_wild(&f, "icmp_type=", w & OFPFW_ICMP_TYPE, verbosity,
|
||||
print_wild(&f, "icmp_type=", w & OFPFW10_ICMP_TYPE, verbosity,
|
||||
"%d", ntohs(om->tp_src));
|
||||
print_wild(&f, "icmp_code=", w & OFPFW_ICMP_CODE, verbosity,
|
||||
print_wild(&f, "icmp_code=", w & OFPFW10_ICMP_CODE, verbosity,
|
||||
"%d", ntohs(om->tp_dst));
|
||||
} else {
|
||||
print_wild(&f, "tp_src=", w & OFPFW_TP_SRC, verbosity,
|
||||
print_wild(&f, "tp_src=", w & OFPFW10_TP_SRC, verbosity,
|
||||
"%d", ntohs(om->tp_src));
|
||||
print_wild(&f, "tp_dst=", w & OFPFW_TP_DST, verbosity,
|
||||
print_wild(&f, "tp_dst=", w & OFPFW10_TP_DST, verbosity,
|
||||
"%d", ntohs(om->tp_dst));
|
||||
}
|
||||
if (ds_last(&f) == ',') {
|
||||
@@ -952,7 +954,7 @@ ofp_print_flow_mod(struct ds *s, const struct ofp_header *oh,
|
||||
ds_put_char(s, ' ');
|
||||
if (verbosity >= 3 && code == OFPUTIL_OFPT_FLOW_MOD) {
|
||||
const struct ofp_flow_mod *ofm = (const struct ofp_flow_mod *) oh;
|
||||
ofp_print_match(s, &ofm->match, verbosity);
|
||||
ofp10_match_print(s, &ofm->match, verbosity);
|
||||
|
||||
/* ofp_print_match() doesn't print priority. */
|
||||
need_priority = true;
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
struct ofp_flow_mod;
|
||||
struct ofp_match;
|
||||
struct ofp10_match;
|
||||
struct ds;
|
||||
union ofp_action;
|
||||
|
||||
@@ -35,10 +35,10 @@ void ofp_print(FILE *, const void *, size_t, int verbosity);
|
||||
void ofp_print_packet(FILE *stream, const void *data, size_t len);
|
||||
|
||||
void ofp_print_actions(struct ds *, const union ofp_action *, size_t);
|
||||
void ofp_print_match(struct ds *, const struct ofp_match *, int verbosity);
|
||||
void ofp10_match_print(struct ds *, const struct ofp10_match *, int verbosity);
|
||||
|
||||
char *ofp_to_string(const void *, size_t, int verbosity);
|
||||
char *ofp_match_to_string(const struct ofp_match *, int verbosity);
|
||||
char *ofp10_match_to_string(const struct ofp10_match *, int verbosity);
|
||||
char *ofp_packet_to_string(const void *data, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
101
lib/ofp-util.c
101
lib/ofp-util.c
@@ -72,7 +72,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
|
||||
return 32 - ip_count_cidr_bits(netmask);
|
||||
}
|
||||
|
||||
/* A list of the FWW_* and OFPFW_ bits that have the same value, meaning, and
|
||||
/* A list of the FWW_* and OFPFW10_ bits that have the same value, meaning, and
|
||||
* name. */
|
||||
#define WC_INVARIANT_LIST \
|
||||
WC_INVARIANT_BIT(IN_PORT) \
|
||||
@@ -81,7 +81,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
|
||||
|
||||
/* Verify that all of the invariant bits (as defined on WC_INVARIANT_LIST)
|
||||
* actually have the same names and values. */
|
||||
#define WC_INVARIANT_BIT(NAME) BUILD_ASSERT_DECL(FWW_##NAME == OFPFW_##NAME);
|
||||
#define WC_INVARIANT_BIT(NAME) BUILD_ASSERT_DECL(FWW_##NAME == OFPFW10_##NAME);
|
||||
WC_INVARIANT_LIST
|
||||
#undef WC_INVARIANT_BIT
|
||||
|
||||
@@ -93,11 +93,12 @@ static const flow_wildcards_t WC_INVARIANTS = 0
|
||||
#undef WC_INVARIANT_BIT
|
||||
;
|
||||
|
||||
/* Converts the wildcard in 'ofpfw' into a flow_wildcards in 'wc' for use in
|
||||
* struct cls_rule. It is the caller's responsibility to handle the special
|
||||
* case where the flow match's dl_vlan is set to OFP_VLAN_NONE. */
|
||||
/* Converts the OpenFlow 1.0 wildcards in 'ofpfw' (OFPFW10_*) into a
|
||||
* flow_wildcards in 'wc' for use in struct cls_rule. It is the caller's
|
||||
* responsibility to handle the special case where the flow match's dl_vlan is
|
||||
* set to OFP_VLAN_NONE. */
|
||||
void
|
||||
ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
|
||||
ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
|
||||
{
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
|
||||
|
||||
@@ -105,53 +106,53 @@ ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
|
||||
flow_wildcards_init_catchall(wc);
|
||||
wc->wildcards = (OVS_FORCE flow_wildcards_t) ofpfw & WC_INVARIANTS;
|
||||
|
||||
/* Wildcard fields that aren't defined by ofp_match or tun_id. */
|
||||
/* Wildcard fields that aren't defined by ofp10_match or tun_id. */
|
||||
wc->wildcards |= (FWW_ARP_SHA | FWW_ARP_THA | FWW_NW_ECN | FWW_NW_TTL
|
||||
| FWW_IPV6_LABEL);
|
||||
|
||||
if (ofpfw & OFPFW_NW_TOS) {
|
||||
if (ofpfw & OFPFW10_NW_TOS) {
|
||||
/* OpenFlow 1.0 defines a TOS wildcard, but it's much later in
|
||||
* the enum than we can use. */
|
||||
wc->wildcards |= FWW_NW_DSCP;
|
||||
}
|
||||
|
||||
wc->nw_src_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_SRC_SHIFT);
|
||||
wc->nw_dst_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_DST_SHIFT);
|
||||
wc->nw_src_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW10_NW_SRC_SHIFT);
|
||||
wc->nw_dst_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW10_NW_DST_SHIFT);
|
||||
|
||||
if (!(ofpfw & OFPFW_TP_SRC)) {
|
||||
if (!(ofpfw & OFPFW10_TP_SRC)) {
|
||||
wc->tp_src_mask = htons(UINT16_MAX);
|
||||
}
|
||||
if (!(ofpfw & OFPFW_TP_DST)) {
|
||||
if (!(ofpfw & OFPFW10_TP_DST)) {
|
||||
wc->tp_dst_mask = htons(UINT16_MAX);
|
||||
}
|
||||
|
||||
if (!(ofpfw & OFPFW_DL_SRC)) {
|
||||
if (!(ofpfw & OFPFW10_DL_SRC)) {
|
||||
memset(wc->dl_src_mask, 0xff, ETH_ADDR_LEN);
|
||||
}
|
||||
if (!(ofpfw & OFPFW_DL_DST)) {
|
||||
if (!(ofpfw & OFPFW10_DL_DST)) {
|
||||
memset(wc->dl_dst_mask, 0xff, ETH_ADDR_LEN);
|
||||
}
|
||||
|
||||
/* VLAN TCI mask. */
|
||||
if (!(ofpfw & OFPFW_DL_VLAN_PCP)) {
|
||||
if (!(ofpfw & OFPFW10_DL_VLAN_PCP)) {
|
||||
wc->vlan_tci_mask |= htons(VLAN_PCP_MASK | VLAN_CFI);
|
||||
}
|
||||
if (!(ofpfw & OFPFW_DL_VLAN)) {
|
||||
if (!(ofpfw & OFPFW10_DL_VLAN)) {
|
||||
wc->vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI);
|
||||
}
|
||||
}
|
||||
|
||||
/* Converts the ofp_match in 'match' into a cls_rule in 'rule', with the given
|
||||
* 'priority'. */
|
||||
/* Converts the ofp10_match in 'match' into a cls_rule in 'rule', with the
|
||||
* given 'priority'. */
|
||||
void
|
||||
ofputil_cls_rule_from_match(const struct ofp_match *match,
|
||||
ofputil_cls_rule_from_ofp10_match(const struct ofp10_match *match,
|
||||
unsigned int priority, struct cls_rule *rule)
|
||||
{
|
||||
uint32_t ofpfw = ntohl(match->wildcards) & OFPFW_ALL;
|
||||
uint32_t ofpfw = ntohl(match->wildcards) & OFPFW10_ALL;
|
||||
|
||||
/* Initialize rule->priority, rule->wc. */
|
||||
rule->priority = !ofpfw ? UINT16_MAX : priority;
|
||||
ofputil_wildcard_from_openflow(ofpfw, &rule->wc);
|
||||
ofputil_wildcard_from_ofpfw10(ofpfw, &rule->wc);
|
||||
|
||||
/* Initialize most of rule->flow. */
|
||||
rule->flow.nw_src = match->nw_src;
|
||||
@@ -166,12 +167,12 @@ ofputil_cls_rule_from_match(const struct ofp_match *match,
|
||||
rule->flow.nw_proto = match->nw_proto;
|
||||
|
||||
/* Translate VLANs. */
|
||||
if (!(ofpfw & OFPFW_DL_VLAN) && match->dl_vlan == htons(OFP_VLAN_NONE)) {
|
||||
if (!(ofpfw & OFPFW10_DL_VLAN) && match->dl_vlan == htons(OFP_VLAN_NONE)) {
|
||||
/* Match only packets without 802.1Q header.
|
||||
*
|
||||
* When OFPFW_DL_VLAN_PCP is wildcarded, this is obviously correct.
|
||||
* When OFPFW10_DL_VLAN_PCP is wildcarded, this is obviously correct.
|
||||
*
|
||||
* If OFPFW_DL_VLAN_PCP is matched, the flow match is contradictory,
|
||||
* If OFPFW10_DL_VLAN_PCP is matched, the flow match is contradictory,
|
||||
* because we can't have a specific PCP without an 802.1Q header.
|
||||
* However, older versions of OVS treated this as matching packets
|
||||
* withut an 802.1Q header, so we do here too. */
|
||||
@@ -190,50 +191,53 @@ ofputil_cls_rule_from_match(const struct ofp_match *match,
|
||||
cls_rule_zero_wildcarded_fields(rule);
|
||||
}
|
||||
|
||||
/* Convert 'rule' into the OpenFlow match structure 'match'. */
|
||||
/* Convert 'rule' into the OpenFlow 1.0 match structure 'match'. */
|
||||
void
|
||||
ofputil_cls_rule_to_match(const struct cls_rule *rule, struct ofp_match *match)
|
||||
ofputil_cls_rule_to_ofp10_match(const struct cls_rule *rule,
|
||||
struct ofp10_match *match)
|
||||
{
|
||||
const struct flow_wildcards *wc = &rule->wc;
|
||||
uint32_t ofpfw;
|
||||
|
||||
/* Figure out most OpenFlow wildcards. */
|
||||
ofpfw = (OVS_FORCE uint32_t) (wc->wildcards & WC_INVARIANTS);
|
||||
ofpfw |= ofputil_netmask_to_wcbits(wc->nw_src_mask) << OFPFW_NW_SRC_SHIFT;
|
||||
ofpfw |= ofputil_netmask_to_wcbits(wc->nw_dst_mask) << OFPFW_NW_DST_SHIFT;
|
||||
ofpfw |= (ofputil_netmask_to_wcbits(wc->nw_src_mask)
|
||||
<< OFPFW10_NW_SRC_SHIFT);
|
||||
ofpfw |= (ofputil_netmask_to_wcbits(wc->nw_dst_mask)
|
||||
<< OFPFW10_NW_DST_SHIFT);
|
||||
if (wc->wildcards & FWW_NW_DSCP) {
|
||||
ofpfw |= OFPFW_NW_TOS;
|
||||
ofpfw |= OFPFW10_NW_TOS;
|
||||
}
|
||||
if (!wc->tp_src_mask) {
|
||||
ofpfw |= OFPFW_TP_SRC;
|
||||
ofpfw |= OFPFW10_TP_SRC;
|
||||
}
|
||||
if (!wc->tp_dst_mask) {
|
||||
ofpfw |= OFPFW_TP_DST;
|
||||
ofpfw |= OFPFW10_TP_DST;
|
||||
}
|
||||
if (eth_addr_is_zero(wc->dl_src_mask)) {
|
||||
ofpfw |= OFPFW_DL_SRC;
|
||||
ofpfw |= OFPFW10_DL_SRC;
|
||||
}
|
||||
if (eth_addr_is_zero(wc->dl_dst_mask)) {
|
||||
ofpfw |= OFPFW_DL_DST;
|
||||
ofpfw |= OFPFW10_DL_DST;
|
||||
}
|
||||
|
||||
/* Translate VLANs. */
|
||||
match->dl_vlan = htons(0);
|
||||
match->dl_vlan_pcp = 0;
|
||||
if (rule->wc.vlan_tci_mask == htons(0)) {
|
||||
ofpfw |= OFPFW_DL_VLAN | OFPFW_DL_VLAN_PCP;
|
||||
ofpfw |= OFPFW10_DL_VLAN | OFPFW10_DL_VLAN_PCP;
|
||||
} else if (rule->wc.vlan_tci_mask & htons(VLAN_CFI)
|
||||
&& !(rule->flow.vlan_tci & htons(VLAN_CFI))) {
|
||||
match->dl_vlan = htons(OFP_VLAN_NONE);
|
||||
} else {
|
||||
if (!(rule->wc.vlan_tci_mask & htons(VLAN_VID_MASK))) {
|
||||
ofpfw |= OFPFW_DL_VLAN;
|
||||
ofpfw |= OFPFW10_DL_VLAN;
|
||||
} else {
|
||||
match->dl_vlan = htons(vlan_tci_to_vid(rule->flow.vlan_tci));
|
||||
}
|
||||
|
||||
if (!(rule->wc.vlan_tci_mask & htons(VLAN_PCP_MASK))) {
|
||||
ofpfw |= OFPFW_DL_VLAN_PCP;
|
||||
ofpfw |= OFPFW10_DL_VLAN_PCP;
|
||||
} else {
|
||||
match->dl_vlan_pcp = vlan_tci_to_pcp(rule->flow.vlan_tci);
|
||||
}
|
||||
@@ -256,7 +260,8 @@ ofputil_cls_rule_to_match(const struct cls_rule *rule, struct ofp_match *match)
|
||||
}
|
||||
|
||||
/* Given a 'dl_type' value in the format used in struct flow, returns the
|
||||
* corresponding 'dl_type' value for use in an OpenFlow ofp_match structure. */
|
||||
* corresponding 'dl_type' value for use in an ofp10_match or ofp11_match
|
||||
* structure. */
|
||||
ovs_be16
|
||||
ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type)
|
||||
{
|
||||
@@ -265,7 +270,7 @@ ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type)
|
||||
: flow_dl_type);
|
||||
}
|
||||
|
||||
/* Given a 'dl_type' value in the format used in an OpenFlow ofp_match
|
||||
/* Given a 'dl_type' value in the format used in an ofp10_match or ofp11_match
|
||||
* structure, returns the corresponding 'dl_type' value for use in struct
|
||||
* flow. */
|
||||
ovs_be16
|
||||
@@ -1402,12 +1407,12 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
|
||||
* ofputil_normalize_rule() can put wildcards where the original flow
|
||||
* didn't have them. */
|
||||
priority = ntohs(ofm->priority);
|
||||
if (!(ofm->match.wildcards & htonl(OFPFW_ALL))) {
|
||||
if (!(ofm->match.wildcards & htonl(OFPFW10_ALL))) {
|
||||
priority = UINT16_MAX;
|
||||
}
|
||||
|
||||
/* Translate the rule. */
|
||||
ofputil_cls_rule_from_match(&ofm->match, priority, &fm->cr);
|
||||
ofputil_cls_rule_from_ofp10_match(&ofm->match, priority, &fm->cr);
|
||||
ofputil_normalize_rule(&fm->cr);
|
||||
|
||||
/* Translate the message. */
|
||||
@@ -1487,7 +1492,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
|
||||
case OFPUTIL_P_OF10_TID:
|
||||
msg = ofpbuf_new(sizeof *ofm + actions_len);
|
||||
ofm = put_openflow(sizeof *ofm, OFPT10_FLOW_MOD, msg);
|
||||
ofputil_cls_rule_to_match(&fm->cr, &ofm->match);
|
||||
ofputil_cls_rule_to_ofp10_match(&fm->cr, &ofm->match);
|
||||
ofm->cookie = fm->new_cookie;
|
||||
ofm->command = htons(command);
|
||||
ofm->idle_timeout = htons(fm->idle_timeout);
|
||||
@@ -1565,7 +1570,7 @@ ofputil_decode_ofpst_flow_request(struct ofputil_flow_stats_request *fsr,
|
||||
(const struct ofp_flow_stats_request *) oh;
|
||||
|
||||
fsr->aggregate = aggregate;
|
||||
ofputil_cls_rule_from_match(&ofsr->match, 0, &fsr->match);
|
||||
ofputil_cls_rule_from_ofp10_match(&ofsr->match, 0, &fsr->match);
|
||||
fsr->out_port = ntohs(ofsr->out_port);
|
||||
fsr->table_id = ofsr->table_id;
|
||||
fsr->cookie = fsr->cookie_mask = htonll(0);
|
||||
@@ -1652,7 +1657,7 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
|
||||
|
||||
type = fsr->aggregate ? OFPST_AGGREGATE : OFPST_FLOW;
|
||||
ofsr = ofputil_make_stats_request(sizeof *ofsr, type, 0, &msg);
|
||||
ofputil_cls_rule_to_match(&fsr->match, &ofsr->match);
|
||||
ofputil_cls_rule_to_ofp10_match(&fsr->match, &ofsr->match);
|
||||
ofsr->table_id = fsr->table_id;
|
||||
ofsr->out_port = htons(fsr->out_port);
|
||||
break;
|
||||
@@ -1763,7 +1768,7 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
|
||||
}
|
||||
|
||||
fs->cookie = get_32aligned_be64(&ofs->cookie);
|
||||
ofputil_cls_rule_from_match(&ofs->match, ntohs(ofs->priority),
|
||||
ofputil_cls_rule_from_ofp10_match(&ofs->match, ntohs(ofs->priority),
|
||||
&fs->rule);
|
||||
fs->table_id = ofs->table_id;
|
||||
fs->duration_sec = ntohl(ofs->duration_sec);
|
||||
@@ -1857,7 +1862,7 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
|
||||
ofs->length = htons(len);
|
||||
ofs->table_id = fs->table_id;
|
||||
ofs->pad = 0;
|
||||
ofputil_cls_rule_to_match(&fs->rule, &ofs->match);
|
||||
ofputil_cls_rule_to_ofp10_match(&fs->rule, &ofs->match);
|
||||
ofs->duration_sec = htonl(fs->duration_sec);
|
||||
ofs->duration_nsec = htonl(fs->duration_nsec);
|
||||
ofs->priority = htons(fs->rule.priority);
|
||||
@@ -1953,7 +1958,7 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
|
||||
const struct ofp_flow_removed *ofr;
|
||||
|
||||
ofr = (const struct ofp_flow_removed *) oh;
|
||||
ofputil_cls_rule_from_match(&ofr->match, ntohs(ofr->priority),
|
||||
ofputil_cls_rule_from_ofp10_match(&ofr->match, ntohs(ofr->priority),
|
||||
&fr->rule);
|
||||
fr->cookie = ofr->cookie;
|
||||
fr->reason = ofr->reason;
|
||||
@@ -2009,7 +2014,7 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
|
||||
|
||||
ofr = make_openflow_xid(sizeof *ofr, OFPT_FLOW_REMOVED, htonl(0),
|
||||
&msg);
|
||||
ofputil_cls_rule_to_match(&fr->rule, &ofr->match);
|
||||
ofputil_cls_rule_to_ofp10_match(&fr->rule, &ofr->match);
|
||||
ofr->cookie = fr->cookie;
|
||||
ofr->priority = htons(fr->rule.priority);
|
||||
ofr->reason = fr->reason;
|
||||
@@ -3127,7 +3132,7 @@ make_flow_mod(uint16_t command, const struct cls_rule *rule,
|
||||
ofm->header.length = htons(size);
|
||||
ofm->cookie = 0;
|
||||
ofm->priority = htons(MIN(rule->priority, UINT16_MAX));
|
||||
ofputil_cls_rule_to_match(rule, &ofm->match);
|
||||
ofputil_cls_rule_to_ofp10_match(rule, &ofm->match);
|
||||
ofm->command = htons(command);
|
||||
return out;
|
||||
}
|
||||
|
@@ -112,8 +112,8 @@ enum ofperr ofputil_check_output_port(uint16_t ofp_port, int max_ports);
|
||||
bool ofputil_port_from_string(const char *, uint16_t *port);
|
||||
void ofputil_format_port(uint16_t port, struct ds *);
|
||||
|
||||
/* Converting OFPFW_NW_SRC_MASK and OFPFW_NW_DST_MASK wildcard bit counts to
|
||||
* and from IP bitmasks. */
|
||||
/* Converting OFPFW10_NW_SRC_MASK and OFPFW10_NW_DST_MASK wildcard bit counts
|
||||
* to and from IP bitmasks. */
|
||||
ovs_be32 ofputil_wcbits_to_netmask(int wcbits);
|
||||
int ofputil_netmask_to_wcbits(ovs_be32 netmask);
|
||||
|
||||
@@ -177,12 +177,14 @@ enum ofputil_protocol ofputil_nx_flow_format_to_protocol(enum nx_flow_format);
|
||||
bool ofputil_nx_flow_format_is_valid(enum nx_flow_format);
|
||||
const char *ofputil_nx_flow_format_to_string(enum nx_flow_format);
|
||||
|
||||
/* Work with OpenFlow 1.0 ofp_match. */
|
||||
void ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *);
|
||||
void ofputil_cls_rule_from_match(const struct ofp_match *,
|
||||
unsigned int priority, struct cls_rule *);
|
||||
/* Work with ofp10_match. */
|
||||
void ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *);
|
||||
void ofputil_cls_rule_from_ofp10_match(const struct ofp10_match *,
|
||||
unsigned int priority,
|
||||
struct cls_rule *);
|
||||
void ofputil_normalize_rule(struct cls_rule *);
|
||||
void ofputil_cls_rule_to_match(const struct cls_rule *, struct ofp_match *);
|
||||
void ofputil_cls_rule_to_ofp10_match(const struct cls_rule *,
|
||||
struct ofp10_match *);
|
||||
|
||||
/* dl_type translation between OpenFlow and 'struct flow' format. */
|
||||
ovs_be16 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type);
|
||||
|
@@ -435,7 +435,7 @@ struct ofproto_class {
|
||||
*
|
||||
* - 'name' to "table#" where # is the table ID.
|
||||
*
|
||||
* - 'wildcards' to OFPFW_ALL.
|
||||
* - 'wildcards' to OFPFW10_ALL.
|
||||
*
|
||||
* - 'max_entries' to 1,000,000.
|
||||
*
|
||||
|
@@ -2138,7 +2138,7 @@ handle_table_stats_request(struct ofconn *ofconn,
|
||||
for (i = 0; i < p->n_tables; i++) {
|
||||
ots[i].table_id = i;
|
||||
sprintf(ots[i].name, "table%zu", i);
|
||||
ots[i].wildcards = htonl(OFPFW_ALL);
|
||||
ots[i].wildcards = htonl(OFPFW10_ALL);
|
||||
ots[i].max_entries = htonl(1000000); /* An arbitrary big number. */
|
||||
ots[i].active_count = htonl(classifier_count(&p->tables[i].cls));
|
||||
}
|
||||
|
@@ -365,7 +365,8 @@ ofp_util|INFO|post: priority=65535,arp,in_port=1,vlan_tci=0x0000,dl_src=50:54:00
|
||||
])
|
||||
AT_CLEANUP
|
||||
|
||||
# The flow is formatted with ofp_match_to_string() for the high-verbosity case.
|
||||
# The flow is formatted with ofp10_match_to_string() for the
|
||||
# high-verbosity case.
|
||||
AT_SETUP([OFPT_FLOW_MOD - high verbosity])
|
||||
AT_KEYWORDS([ofp-print])
|
||||
AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' ofp-print "\
|
||||
@@ -833,7 +834,8 @@ NXT_FLOW_MOD (xid=0x2): ADD reg0=0x7b,tun_id=0x1c8 actions=load:0x5->NXM_NX_REG0
|
||||
])
|
||||
AT_CLEANUP
|
||||
|
||||
# The flow is formatted with ofp_match_to_string() for the low-verbosity case.
|
||||
# The flow is formatted with ofp10_match_to_string() for the
|
||||
# low-verbosity case.
|
||||
AT_SETUP([NXT_FLOW_MOD, high verbosity])
|
||||
AT_KEYWORDS([ofp-print])
|
||||
AT_CHECK([ovs-ofctl ofp-print "\
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
|
||||
* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,7 @@
|
||||
int
|
||||
main(int argc OVS_UNUSED, char *argv[])
|
||||
{
|
||||
struct ofp_match expected_match;
|
||||
struct ofp10_match expected_match;
|
||||
FILE *flows, *pcap;
|
||||
int retval;
|
||||
int n = 0, errors = 0;
|
||||
@@ -55,7 +55,7 @@ main(int argc OVS_UNUSED, char *argv[])
|
||||
|
||||
while (fread(&expected_match, sizeof expected_match, 1, flows)) {
|
||||
struct ofpbuf *packet;
|
||||
struct ofp_match extracted_match;
|
||||
struct ofp10_match extracted_match;
|
||||
struct cls_rule rule;
|
||||
struct flow flow;
|
||||
|
||||
@@ -70,11 +70,11 @@ main(int argc OVS_UNUSED, char *argv[])
|
||||
|
||||
flow_extract(packet, 0, 0, 1, &flow);
|
||||
cls_rule_init_exact(&flow, 0, &rule);
|
||||
ofputil_cls_rule_to_match(&rule, &extracted_match);
|
||||
ofputil_cls_rule_to_ofp10_match(&rule, &extracted_match);
|
||||
|
||||
if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) {
|
||||
char *exp_s = ofp_match_to_string(&expected_match, 2);
|
||||
char *got_s = ofp_match_to_string(&extracted_match, 2);
|
||||
char *exp_s = ofp10_match_to_string(&expected_match, 2);
|
||||
char *got_s = ofp10_match_to_string(&extracted_match, 2);
|
||||
errors++;
|
||||
printf("mismatch on packet #%d (1-based).\n", n);
|
||||
printf("Packet:\n");
|
||||
|
@@ -62,7 +62,7 @@ static bool set_up_flows = true;
|
||||
/* -N, --normal: Use "NORMAL" action instead of explicit port? */
|
||||
static bool action_normal = false;
|
||||
|
||||
/* -w, --wildcard: 0 to disable wildcard flow entries, a OFPFW_* bitmask to
|
||||
/* -w, --wildcard: 0 to disable wildcard flow entries, an OFPFW10_* bitmask to
|
||||
* enable specific wildcards, or UINT32_MAX to use the default wildcards. */
|
||||
static uint32_t wildcards = 0;
|
||||
|
||||
|
Reference in New Issue
Block a user