[ovs-dev] [PATCH 2/3] flow: Adds ethernet mask fields to flow_wildcards
Joe Stringer
joe at wand.net.nz
Wed May 16 02:13:26 UTC 2012
Apologies on the whitespace "fixes" -- I realise I didn't go back over the
CodingStyle before mailing the patches. Please ignore those parts for the
purposes of reviewing. I was expecting to need to make other changes and
resubmit newer patches after I get some feedback, so please ignore these
for the moment, and I'll fix those up when I re-submit.
On 16 May 2012 13:16, Joe Stringer <joe at wand.net.nz> wrote:
> Arbitrary ethernet mask support is one step on the way to support for
> OpenFlow
> 1.0+. This patch set seeks to add this capability without breaking current
> protocol support.
>
> This patch also includes some whitespace fixes -- ^L replaced with empty
> lines.
>
> Signed-off-by: Joe Stringer <joe at wand.net.nz>
> ---
> Initial introduction of arbitrary ethernet masks to flow_wildcards. I've
> gone through the build asserts to increment FLOW_WC_SEQ, implementing
> arbitrary
> ethernet support in places I understand the code.
>
> Areas that I did not understand fully have /* ATTN */ markers with a
> relevant
> question. One overarching question I have is how ethernet matching should
> be
> handled, going forward. As I understand currently, FWW_DL_DST and
> FWW_ETH_MCAST
> bits are used in wildcards_t to indicate what kind of matching takes place.
> Will this continue to be the case?
>
> With OpenFlow 1.1, there is no equivalent ofp_flow_wildcards flags for
> ethernet
> masking; this is replaced by the eth_{src,dst}_mask. To support this fully,
> will we set the appropriate FWW_DL_DST/FWW_ETH_MCAST bits in the
> wildcards_t
> when translating from OF11+? Or do we change the OF10 code to set the
> appropriate masks, and migrate other code away from using these flags?
>
> Although nx-match.c code uses the cls_rule struct (which now contains eth
> mask
> fields), I haven't modified the nxm_put_match() code to serialize these
> masks.
> I noted that it uses flow_wildcards_to_dl_dst_mask(wc) for the mask, so
> left
> it alone as I wasn't sure if it is meant to follow OF10 functionality?
>
> All tests are satisfied, with no (known) changes to functionality, given
> that
> currently supported protocols lack support for arbitrary ethernet masks.
>
> As my first patch for submission, (and being new to the code!), I expect
> there may be some things I've missed, so I ask for your patience as I try
> to
> wrap my head around the code and attempt to contribute.
> ---
> lib/classifier.c | 21 +++++++++++++++------
> lib/flow.c | 47 +++++++++++++++++++++++++++++++++++------------
> lib/flow.h | 12 +++++++-----
> lib/learn.c | 2 +-
> lib/nx-match.c | 18 +++++++++---------
> lib/nx-match.h | 4 ++--
> lib/ofp-util.c | 27 ++++++++++++++++++---------
> 7 files changed, 87 insertions(+), 44 deletions(-)
>
> diff --git a/lib/classifier.c b/lib/classifier.c
> index e11a585..6a1b040 100644
> --- a/lib/classifier.c
> +++ b/lib/classifier.c
> @@ -449,6 +449,15 @@ cls_rule_hash(const struct cls_rule *rule, uint32_t
> basis)
> }
>
> static void
> +format_eth_masked(struct ds *s, const char *name, const uint8_t eth[6],
> + const uint8_t mask[6])
> +{
> + ds_put_format(s, "%s=", name);
> + eth_format_masked(eth, mask, s);
> + ds_put_char(s, ',');
> +}
> +
> +static void
> format_ip_netmask(struct ds *s, const char *name, ovs_be32 ip,
> ovs_be32 netmask)
> {
> @@ -500,7 +509,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds
> *s)
>
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> if (rule->priority != OFP_DEFAULT_PRIORITY) {
> ds_put_format(s, "priority=%d,", rule->priority);
> @@ -598,7 +607,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds
> *s)
> }
> }
> if (!(w & FWW_DL_SRC)) {
> - ds_put_format(s, "dl_src="ETH_ADDR_FMT",",
> ETH_ADDR_ARGS(f->dl_src));
> + format_eth_masked(s, "dl_src", f->dl_src, wc->dl_src_mask);
> }
> switch (w & (FWW_DL_DST | FWW_ETH_MCAST)) {
> case 0:
> @@ -715,7 +724,7 @@ cls_rule_print(const struct cls_rule *rule)
> puts(s);
> free(s);
> }
> -
> +
> /* Initializes 'cls' as a classifier that initially contains no
> classification
> * rules. */
> void
> @@ -900,7 +909,7 @@ classifier_rule_overlaps(const struct classifier *cls,
>
> return false;
> }
> -
> +
> /* Iteration. */
>
> static bool
> @@ -1019,7 +1028,7 @@ cls_cursor_next(struct cls_cursor *cursor, struct
> cls_rule *rule)
>
> return NULL;
> }
> -
> +
> static struct cls_table *
> find_table(const struct classifier *cls, const struct flow_wildcards *wc)
> {
> @@ -1179,7 +1188,7 @@ flow_equal_except(const struct flow *a, const struct
> flow *b,
> const flow_wildcards_t wc = wildcards->wildcards;
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> for (i = 0; i < FLOW_N_REGS; i++) {
> if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
> diff --git a/lib/flow.c b/lib/flow.c
> index fc61610..c802467 100644
> --- a/lib/flow.c
> +++ b/lib/flow.c
> @@ -444,7 +444,7 @@ flow_zero_wildcards(struct flow *flow, const struct
> flow_wildcards *wildcards)
> const flow_wildcards_t wc = wildcards->wildcards;
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> for (i = 0; i < FLOW_N_REGS; i++) {
> flow->regs[i] &= wildcards->reg_masks[i];
> @@ -506,7 +506,7 @@ flow_zero_wildcards(struct flow *flow, const struct
> flow_wildcards *wildcards)
> void
> flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
> {
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> fmd->tun_id = flow->tun_id;
> fmd->tun_id_mask = htonll(UINT64_MAX);
> @@ -588,14 +588,14 @@ flow_print(FILE *stream, const struct flow *flow)
> fputs(s, stream);
> free(s);
> }
> -
> +
> /* flow_wildcards functions. */
>
> /* Initializes 'wc' as a set of wildcards that matches every packet. */
> void
> flow_wildcards_init_catchall(struct flow_wildcards *wc)
> {
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> wc->wildcards = FWW_ALL;
> wc->tun_id_mask = htonll(0);
> @@ -609,6 +609,8 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc)
> wc->nw_frag_mask = 0;
> wc->tp_src_mask = htons(0);
> wc->tp_dst_mask = htons(0);
> + memset(wc->dl_src_mask, 0, ETH_ADDR_LEN);
> + memset(wc->dl_dst_mask, 0, ETH_ADDR_LEN);
> memset(wc->zeros, 0, sizeof wc->zeros);
> }
>
> @@ -617,7 +619,7 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc)
> void
> flow_wildcards_init_exact(struct flow_wildcards *wc)
> {
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> wc->wildcards = 0;
> wc->tun_id_mask = htonll(UINT64_MAX);
> @@ -631,6 +633,8 @@ flow_wildcards_init_exact(struct flow_wildcards *wc)
> wc->nw_frag_mask = UINT8_MAX;
> wc->tp_src_mask = htons(UINT16_MAX);
> wc->tp_dst_mask = htons(UINT16_MAX);
> + memset(wc->dl_src_mask, 0xff, ETH_ADDR_LEN);
> + memset(wc->dl_dst_mask, 0xff, ETH_ADDR_LEN);
> memset(wc->zeros, 0, sizeof wc->zeros);
> }
>
> @@ -641,7 +645,7 @@ flow_wildcards_is_exact(const struct flow_wildcards
> *wc)
> {
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> if (wc->wildcards
> || wc->tun_id_mask != htonll(UINT64_MAX)
> @@ -650,6 +654,8 @@ flow_wildcards_is_exact(const struct flow_wildcards
> *wc)
> || wc->tp_src_mask != htons(UINT16_MAX)
> || wc->tp_dst_mask != htons(UINT16_MAX)
> || wc->vlan_tci_mask != htons(UINT16_MAX)
> + || !eth_mask_is_exact(wc->dl_src_mask)
> + || !eth_mask_is_exact(wc->dl_dst_mask)
> || !ipv6_mask_is_exact(&wc->ipv6_src_mask)
> || !ipv6_mask_is_exact(&wc->ipv6_dst_mask)
> || !ipv6_mask_is_exact(&wc->nd_target_mask)
> @@ -673,7 +679,7 @@ flow_wildcards_is_catchall(const struct flow_wildcards
> *wc)
> {
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> if (wc->wildcards != FWW_ALL
> || wc->tun_id_mask != htonll(0)
> @@ -682,6 +688,8 @@ flow_wildcards_is_catchall(const struct flow_wildcards
> *wc)
> || wc->tp_src_mask != htons(0)
> || wc->tp_dst_mask != htons(0)
> || wc->vlan_tci_mask != htons(0)
> + || !eth_addr_is_zero(wc->dl_src_mask)
> + || !eth_addr_is_zero(wc->dl_dst_mask)
> || !ipv6_mask_is_any(&wc->ipv6_src_mask)
> || !ipv6_mask_is_any(&wc->ipv6_dst_mask)
> || !ipv6_mask_is_any(&wc->nd_target_mask)
> @@ -708,7 +716,7 @@ flow_wildcards_combine(struct flow_wildcards *dst,
> {
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> dst->wildcards = src1->wildcards | src2->wildcards;
> dst->tun_id_mask = src1->tun_id_mask & src2->tun_id_mask;
> @@ -726,6 +734,8 @@ flow_wildcards_combine(struct flow_wildcards *dst,
> dst->vlan_tci_mask = src1->vlan_tci_mask & src2->vlan_tci_mask;
> dst->tp_src_mask = src1->tp_src_mask & src2->tp_src_mask;
> dst->tp_dst_mask = src1->tp_dst_mask & src2->tp_dst_mask;
> + eth_addr_bitand(src1->dl_src_mask, src2->dl_src_mask,
> dst->dl_src_mask);
> + eth_addr_bitand(src1->dl_dst_mask, src2->dl_dst_mask,
> dst->dl_dst_mask);
> }
>
> /* Returns a hash of the wildcards in 'wc'. */
> @@ -735,7 +745,7 @@ flow_wildcards_hash(const struct flow_wildcards *wc,
> uint32_t basis)
> /* If you change struct flow_wildcards and thereby trigger this
> * assertion, please check that the new struct flow_wildcards has no
> holes
> * in it before you update the assertion. */
> - BUILD_ASSERT_DECL(sizeof *wc == 80 + FLOW_N_REGS * 4);
> + BUILD_ASSERT_DECL(sizeof *wc == 88 + FLOW_N_REGS * 4);
> return hash_bytes(wc, sizeof *wc, basis);
> }
>
> @@ -747,7 +757,7 @@ flow_wildcards_equal(const struct flow_wildcards *a,
> {
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> if (a->wildcards != b->wildcards
> || a->tun_id_mask != b->tun_id_mask
> @@ -758,7 +768,9 @@ flow_wildcards_equal(const struct flow_wildcards *a,
> || !ipv6_addr_equals(&a->ipv6_dst_mask, &b->ipv6_dst_mask)
> || !ipv6_addr_equals(&a->nd_target_mask, &b->nd_target_mask)
> || a->tp_src_mask != b->tp_src_mask
> - || a->tp_dst_mask != b->tp_dst_mask) {
> + || a->tp_dst_mask != b->tp_dst_mask
> + || !eth_addr_equals(a->dl_src_mask, b->dl_src_mask)
> + || !eth_addr_equals(a->dl_dst_mask, b->dl_dst_mask)) {
> return false;
> }
>
> @@ -778,9 +790,10 @@ flow_wildcards_has_extra(const struct flow_wildcards
> *a,
> const struct flow_wildcards *b)
> {
> int i;
> + uint8_t eth_masked[ETH_ADDR_LEN];
> struct in6_addr ipv6_masked;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> for (i = 0; i < FLOW_N_REGS; i++) {
> if ((a->reg_masks[i] & b->reg_masks[i]) != b->reg_masks[i]) {
> @@ -788,6 +801,16 @@ flow_wildcards_has_extra(const struct flow_wildcards
> *a,
> }
> }
>
> + eth_addr_bitand(a->dl_src_mask, b->dl_src_mask, eth_masked);
> + if (!eth_addr_equals(eth_masked, b->dl_src_mask)) {
> + return true;
> + }
> +
> + eth_addr_bitand(a->dl_dst_mask, b->dl_dst_mask, eth_masked);
> + if (!eth_addr_equals(eth_masked, b->dl_dst_mask)) {
> + return true;
> + }
> +
> ipv6_masked = ipv6_addr_bitand(&a->ipv6_src_mask, &b->ipv6_src_mask);
> if (!ipv6_addr_equals(&ipv6_masked, &b->ipv6_src_mask)) {
> return true;
> diff --git a/lib/flow.h b/lib/flow.h
> index 7ee9a26..5d1f353 100644
> --- a/lib/flow.h
> +++ b/lib/flow.h
> @@ -35,7 +35,7 @@ struct ofpbuf;
> /* This sequence number should be incremented whenever anything involving
> flows
> * or the wildcarding of flows changes. This will cause build assertion
> * failures in places which likely need to be updated. */
> -#define FLOW_WC_SEQ 10
> +#define FLOW_WC_SEQ 11
>
> #define FLOW_N_REGS 8
> BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS);
> @@ -100,7 +100,7 @@ BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->nw_frag)
> == 1);
> BUILD_ASSERT_DECL(sizeof(struct flow) == FLOW_SIG_SIZE + FLOW_PAD_SIZE);
>
> /* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
> -BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 142 && FLOW_WC_SEQ == 10);
> +BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 142 && FLOW_WC_SEQ == 11);
>
> void flow_extract(struct ofpbuf *, uint32_t priority, ovs_be64 tun_id,
> uint16_t in_port, struct flow *);
> @@ -164,7 +164,7 @@ typedef unsigned int OVS_BITWISE flow_wildcards_t;
> #define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 12)) - 1))
>
> /* Remember to update FLOW_WC_SEQ when adding or removing FWW_*. */
> -BUILD_ASSERT_DECL(FWW_ALL == ((1 << 12) - 1) && FLOW_WC_SEQ == 10);
> +BUILD_ASSERT_DECL(FWW_ALL == ((1 << 12) - 1) && FLOW_WC_SEQ == 11);
>
> /* Information on wildcards for a flow, as a supplement to "struct flow".
> *
> @@ -184,11 +184,13 @@ struct flow_wildcards {
> ovs_be16 tp_src_mask; /* 1-bit in each significant tp_src bit. */
> ovs_be16 tp_dst_mask; /* 1-bit in each significant tp_dst bit. */
> uint8_t nw_frag_mask; /* 1-bit in each significant nw_frag bit.
> */
> - uint8_t zeros[5]; /* Padding field set to zero. */
> + uint8_t zeros[1]; /* Padding field set to zero. */
> + uint8_t dl_src_mask[6]; /* 1-bit in each significant dl_src bit.
> */
> + uint8_t dl_dst_mask[6]; /* 1-bit in each significant dl_dst bit.
> */
> };
>
> /* Remember to update FLOW_WC_SEQ when updating struct flow_wildcards. */
> -BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 112 && FLOW_WC_SEQ ==
> 10);
> +BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 120 && FLOW_WC_SEQ ==
> 11);
>
> void flow_wildcards_init_catchall(struct flow_wildcards *);
> void flow_wildcards_init_exact(struct flow_wildcards *);
> diff --git a/lib/learn.c b/lib/learn.c
> index e995c29..a89ed70 100644
> --- a/lib/learn.c
> +++ b/lib/learn.c
> @@ -184,7 +184,7 @@ learn_check(const struct nx_action_learn *learn, const
> struct flow *flow)
> * prerequisites. No prerequisite depends on the
> value of
> * a field that is wider than 64 bits. So just skip
> * setting it entirely. */
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
> }
> }
> }
> diff --git a/lib/nx-match.c b/lib/nx-match.c
> index 34c8354..a5d6f12 100644
> --- a/lib/nx-match.c
> +++ b/lib/nx-match.c
> @@ -54,7 +54,7 @@ nxm_field_bits(uint32_t header)
> {
> return nxm_field_bytes(header) * 8;
> }
> -
> +
> /* nx_pull_match() and helpers. */
>
> static uint32_t
> @@ -209,7 +209,7 @@ nx_pull_match_loose(struct ofpbuf *b, unsigned int
> match_len,
> return nx_pull_match__(b, match_len, false, priority, rule, cookie,
> cookie_mask);
> }
> -
> +
> /* nx_put_match() and helpers.
> *
> * 'put' functions whose names end in 'w' add a wildcarded field.
> @@ -471,7 +471,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule
> *cr,
> int match_len;
> int i;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> /* Metadata. */
> if (!(wc & FWW_IN_PORT)) {
> @@ -556,7 +556,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule
> *cr,
> ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len);
> return match_len;
> }
> -
> +
> /* nx_match_to_string() and helpers. */
>
> static void format_nxm_field_name(struct ds *, uint32_t header);
> @@ -676,7 +676,7 @@ parse_nxm_field_name(const char *name, int name_len)
>
> return 0;
> }
> -
> +
> /* nx_match_from_string(). */
>
> int
> @@ -740,7 +740,7 @@ nx_match_from_string(const char *s, struct ofpbuf *b)
> ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len);
> return match_len;
> }
> -
> +
> void
> nxm_parse_reg_move(struct nx_action_reg_move *move, const char *s)
> {
> @@ -797,7 +797,7 @@ nxm_parse_reg_load(struct nx_action_reg_load *load,
> const char *s)
> load->dst = htonl(dst.field->nxm_header);
> load->value = htonll(value);
> }
> -
> +
> /* nxm_format_reg_move(), nxm_format_reg_load(). */
>
> void
> @@ -824,7 +824,7 @@ nxm_format_reg_load(const struct nx_action_reg_load
> *load, struct ds *s)
> nxm_decode(&dst, load->dst, load->ofs_nbits);
> mf_format_subfield(&dst, s);
> }
> -
> +
> /* nxm_check_reg_move(), nxm_check_reg_load(). */
>
> enum ofperr
> @@ -866,7 +866,7 @@ nxm_check_reg_load(const struct nx_action_reg_load
> *action,
>
> return 0;
> }
> -
> +
> /* nxm_execute_reg_move(), nxm_execute_reg_load(). */
>
> void
> diff --git a/lib/nx-match.h b/lib/nx-match.h
> index a039225..f51bae5 100644
> --- a/lib/nx-match.h
> +++ b/lib/nx-match.h
> @@ -89,8 +89,8 @@ nxm_decode_n_bits(ovs_be16 ofs_nbits)
> void nxm_decode(struct mf_subfield *, ovs_be32 header, ovs_be16
> ofs_nbits);
> void nxm_decode_discrete(struct mf_subfield *, ovs_be32 header,
> ovs_be16 ofs, ovs_be16 n_bits);
> -
> -BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> +
> +BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
> /* Upper bound on the length of an nx_match. The longest nx_match (an
> * IPV6 neighbor discovery message using 5 registers) would be:
> *
> diff --git a/lib/ofp-util.c b/lib/ofp-util.c
> index 501ccab..c9e77b5 100644
> --- a/lib/ofp-util.c
> +++ b/lib/ofp-util.c
> @@ -101,7 +101,7 @@ static const flow_wildcards_t WC_INVARIANTS = 0
> void
> ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
> {
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
>
> /* Initialize most of rule->wc. */
> flow_wildcards_init_catchall(wc);
> @@ -127,11 +127,16 @@ ofputil_wildcard_from_openflow(uint32_t ofpfw,
> struct flow_wildcards *wc)
> wc->tp_dst_mask = htons(UINT16_MAX);
> }
>
> + if (!(ofpfw & OFPFW_DL_SRC)) {
> + memset(wc->dl_src_mask, 0xff, ETH_ADDR_LEN);
> + }
> if (ofpfw & OFPFW_DL_DST) {
> /* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet
> destination, but
> * Open vSwitch breaks the Ethernet destination into bits as
> FWW_DL_DST
> * and FWW_ETH_MCAST. */
> wc->wildcards |= FWW_ETH_MCAST;
> + } else {
> + memset(wc->dl_dst_mask, 0xff, ETH_ADDR_LEN);
> }
>
> /* VLAN TCI mask. */
> @@ -279,7 +284,7 @@ alloc_xid(void)
> static uint32_t next_xid = 1;
> return htonl(next_xid++);
> }
> -
> +
> /* Basic parsing of OpenFlow messages. */
>
> struct ofputil_msg_type {
> @@ -858,7 +863,7 @@ ofputil_msg_type_code(const struct ofputil_msg_type
> *type)
> {
> return type->code;
> }
> -
> +
> /* Protocols. */
>
> struct proto_abbrev {
> @@ -1174,7 +1179,11 @@ ofputil_usable_protocols(const struct cls_rule
> *rule)
> {
> const struct flow_wildcards *wc = &rule->wc;
>
> - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 10);
> + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
> +
> + /* ATTN: How do we express OFP11-supported features? Do we need to add
> + * anything here?
> + */
>
> /* Only NXM supports separately wildcards the Ethernet multicast bit.
> */
> if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST))
> {
> @@ -2257,7 +2266,7 @@ ofputil_decode_packet_out(struct ofputil_packet_out
> *po,
>
> return 0;
> }
> -
> +
> /* ofputil_phy_port */
>
> /* NETDEV_F_* to and from OFPPF_* and OFPPF10_*. */
> @@ -2455,7 +2464,7 @@ ofputil_append_port_desc_stats_reply(uint8_t
> ofp_version,
> ofputil_encode_ofp11_port(pp, op);
> }
> }
> -
> +
> /* ofputil_switch_features */
>
> #define OFPC_COMMON (OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS
> | \
> @@ -2662,7 +2671,7 @@ ofputil_put_switch_features_port(const struct
> ofputil_phy_port *pp,
>
> ofputil_put_phy_port(osf->header.version, pp, b);
> }
> -
> +
> /* ofputil_port_status */
>
> /* Decodes the OpenFlow "port status" message in '*ops' into an abstract
> form
> @@ -2706,7 +2715,7 @@ ofputil_encode_port_status(const struct
> ofputil_port_status *ps,
> update_openflow_length(b);
> return b;
> }
> -
> +
> /* ofputil_port_mod */
>
> /* Decodes the OpenFlow "port mod" message in '*oh' into an abstract form
> in
> @@ -2824,7 +2833,7 @@ ofputil_msg_type_name(const struct ofputil_msg_type
> *type)
> {
> return type->name;
> }
> -
> +
> /* Allocates and stores in '*bufferp' a new ofpbuf with a size of
> * 'openflow_len', starting with an OpenFlow header with the given 'type'
> and
> * an arbitrary transaction id. Allocated bytes beyond the header, if
> any, are
> --
> 1.6.0.1
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20120516/7e35f657/attachment-0003.html>
More information about the dev
mailing list