X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fflow.h;h=a19a9ae5e42b5356ec2a9cee4a5a9a1609059a80;hb=c0a56d9fe1fdb57220b9c1e2f709ea2db5d6489d;hp=df16a77c6d1cbf07f9c9ef3956f943d3f2a57938;hpb=0b3e77bbef23a41d45a3a29ba32eb55759878f03;p=openvswitch diff --git a/lib/flow.h b/lib/flow.h index df16a77c..a19a9ae5 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -28,10 +28,15 @@ #include "util.h" struct ds; +struct flow_wildcards; struct ofp_match; struct ofpbuf; +#define FLOW_N_REGS 3 +BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS); + struct flow { + uint32_t regs[FLOW_N_REGS]; /* Registers. */ ovs_be32 tun_id; /* Encapsulating tunnel ID. */ ovs_be32 nw_src; /* IP source address. */ ovs_be32 nw_dst; /* IP destination address. */ @@ -49,7 +54,7 @@ struct flow { /* Assert that there are FLOW_SIG_SIZE bytes of significant data in "struct * flow", followed by FLOW_PAD_SIZE bytes of padding. */ -#define FLOW_SIG_SIZE 37 +#define FLOW_SIG_SIZE (37 + FLOW_N_REGS * 4) #define FLOW_PAD_SIZE 3 BUILD_ASSERT_DECL(offsetof(struct flow, nw_tos) == FLOW_SIG_SIZE - 1); BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->nw_tos) == 1); @@ -59,10 +64,10 @@ int flow_extract(struct ofpbuf *, ovs_be32 tun_id, uint16_t in_port, struct flow *); void flow_extract_stats(const struct flow *flow, struct ofpbuf *packet, struct odp_flow_stats *stats); -void flow_to_match(const struct flow *, uint32_t wildcards, bool tun_id_cookie, +void flow_to_match(const struct flow *, uint32_t wildcards, int flow_format, struct ofp_match *); -void flow_from_match(const struct ofp_match *, bool tun_id_from_cookie, - ovs_be64 cookie, struct flow *, uint32_t *wildcards); +void flow_from_match(const struct ofp_match *, int flow_format, + ovs_be64 cookie, struct flow *, struct flow_wildcards *); char *flow_to_string(const struct flow *); void flow_format(struct ds *, const struct flow *); void flow_print(FILE *, const struct flow *); @@ -88,35 +93,76 @@ flow_hash(const struct flow *flow, uint32_t basis) return hash_bytes(flow, FLOW_SIG_SIZE, basis); } -/* Information on wildcards for a flow, as a supplement to struct flow. */ +/* Open vSwitch internal-only wildcard bits. + * + * These are used only internally to Open vSwitch, in the 'wildcards' member of + * struct flow_wildcards. They never appear in the wire protocol in this + * form. */ + +/* Set to 1 if any bits in any of the reg_masks are wildcarded. This maintains + * the invariant that 'wildcards' is nonzero if and only if any bits are + * wildcarded. */ +#define FWW_REGS (1u << 31) + +/* Set to 1 if bit 0 (the multicast bit) of the flow's dl_dst is wildcarded. + * + * (We reinterpret OFPFW_DL_DST as excluding bit 0. Both OFPFW_DL_DST and + * FWW_ETH_MCAST have to be set to wildcard the entire Ethernet destination + * address.) */ +#define FWW_ETH_MCAST (1u << 30) + +/* Avoid collisions. */ +#define FWW_ALL (FWW_REGS | FWW_ETH_MCAST) +BUILD_ASSERT_DECL(!(FWW_ALL & OVSFW_ALL)); + +/* Information on wildcards for a flow, as a supplement to "struct flow". + * + * The flow_wildcards_*() functions below both depend on and maintain the + * following important invariants: + * + * 1. 'wildcards' is nonzero if and only if at least one bit or field is + * wildcarded. + * + * 2. Bits in 'wildcards' not included in OVSFW_ALL or FWW_ALL are set to 0. + * (This is a corollary to invariant #1.) + * + * 3. The fields in 'wildcards' masked by OFPFW_NW_SRC_MASK and + * OFPFW_NW_DST_MASK have values between 0 and 32, inclusive. + * + * 4. The fields masked by OFPFW_NW_SRC_MASK and OFPFW_NW_DST_MASK correspond + * correctly to the masks in 'nw_src_mask' and 'nw_dst_mask', respectively. + * + * 5. FWW_REGS is set to 1 in 'wildcards' if and only if at least one bit in + * 'reg_masks[]' is nonzero. (This allows wildcarded 'reg_masks[]' to + * satisfy invariant #1.) + * + * 6. If FWW_REGS is set to 0 in 'wildcards', then the values of all of the + * other members can be correctly predicted based on 'wildcards' alone. + */ struct flow_wildcards { - uint32_t wildcards; /* enum ofp_flow_wildcards. */ + uint32_t wildcards; /* OFPFW_* | OVSFW_* | FWW_*. */ + uint32_t reg_masks[FLOW_N_REGS]; /* 1-bit in each significant regs bit. */ ovs_be32 nw_src_mask; /* 1-bit in each significant nw_src bit. */ ovs_be32 nw_dst_mask; /* 1-bit in each significant nw_dst bit. */ }; -/* Given the wildcard bit count in bits 'shift' through 'shift + 5' (inclusive) - * of 'wildcards', returns a 32-bit bit mask with a 1 in each bit that must - * match and a 0 in each bit that is wildcarded. - * - * The bits in 'wildcards' are in the format used in enum ofp_flow_wildcards: 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. */ -static inline ovs_be32 -flow_nw_bits_to_mask(uint32_t wildcards, int shift) -{ - wildcards = (wildcards >> shift) & 0x3f; - return wildcards < 32 ? htonl(~((1u << wildcards) - 1)) : 0; -} +ovs_be32 flow_nw_bits_to_mask(uint32_t wildcards, int shift); +void flow_wildcards_init(struct flow_wildcards *, uint32_t wildcards); +void flow_wildcards_init_exact(struct flow_wildcards *); -static inline void -flow_wildcards_init(struct flow_wildcards *wc, uint32_t wildcards) -{ - wc->wildcards = wildcards & OVSFW_ALL; - wc->nw_src_mask = flow_nw_bits_to_mask(wc->wildcards, OFPFW_NW_SRC_SHIFT); - wc->nw_dst_mask = flow_nw_bits_to_mask(wc->wildcards, OFPFW_NW_DST_SHIFT); -} +bool flow_wildcards_set_nw_src_mask(struct flow_wildcards *, ovs_be32); +bool flow_wildcards_set_nw_dst_mask(struct flow_wildcards *, ovs_be32); +void flow_wildcards_set_reg_mask(struct flow_wildcards *, + int idx, uint32_t mask); + +void flow_wildcards_combine(struct flow_wildcards *dst, + const struct flow_wildcards *src1, + const struct flow_wildcards *src2); +bool flow_wildcards_has_extra(const struct flow_wildcards *, + const struct flow_wildcards *); + +uint32_t flow_wildcards_hash(const struct flow_wildcards *); +bool flow_wildcards_equal(const struct flow_wildcards *, + const struct flow_wildcards *); #endif /* flow.h */