2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-01 06:45:17 +00:00

lib/flow: add dp_hash and recirc_id to struct flow

Signed-off-by: Andy Zhou <azhou@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Andy Zhou
2014-03-04 14:20:19 -08:00
parent a0cbddc04b
commit a79f29f20e
10 changed files with 158 additions and 9 deletions

View File

@@ -1803,6 +1803,35 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
#define NXM_NX_TCP_FLAGS NXM_HEADER (0x0001, 34, 2) #define NXM_NX_TCP_FLAGS NXM_HEADER (0x0001, 34, 2)
#define NXM_NX_TCP_FLAGS_W NXM_HEADER_W(0x0001, 34, 2) #define NXM_NX_TCP_FLAGS_W NXM_HEADER_W(0x0001, 34, 2)
/* Metadata dp_hash.
*
* Internal use only, not programable from controller.
*
* The dp_hash is used to carry the flow hash computed in the
* datapath.
*
* Prereqs: None.
*
* Format: 32-bit integer in network byte order.
*
* Masking: Fully maskable. */
#define NXM_NX_DP_HASH NXM_HEADER (0x0001, 35, 4)
#define NXM_NX_DP_HASH_W NXM_HEADER_W(0x0001, 35, 4)
/* Metadata recirc_id.
*
* Internal use only, not programable from controller.
*
* The recirc_id used for recirculation. 0 is reserved
* for initially received packet.
*
* Prereqs: None.
*
* Format: 32-bit integer in network byte order.
*
* Masking: not maskable. */
#define NXM_NX_RECIRC_ID NXM_HEADER (0x0001, 36, 4)
/* ## --------------------- ## */ /* ## --------------------- ## */
/* ## Requests and replies. ## */ /* ## Requests and replies. ## */
/* ## --------------------- ## */ /* ## --------------------- ## */

View File

@@ -530,8 +530,10 @@ flow_unwildcard_tp_ports(const struct flow *flow, struct flow_wildcards *wc)
void void
flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd) flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
{ {
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 24); BUILD_ASSERT_DECL(FLOW_WC_SEQ == 25);
fmd->dp_hash = flow->dp_hash;
fmd->recirc_id = flow->recirc_id;
fmd->tun_id = flow->tunnel.tun_id; fmd->tun_id = flow->tunnel.tun_id;
fmd->tun_src = flow->tunnel.ip_src; fmd->tun_src = flow->tunnel.ip_src;
fmd->tun_dst = flow->tunnel.ip_dst; fmd->tun_dst = flow->tunnel.ip_dst;
@@ -1194,7 +1196,7 @@ flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
flow->mpls_lse[0] = set_mpls_lse_values(ttl, tc, 1, htonl(label)); flow->mpls_lse[0] = set_mpls_lse_values(ttl, tc, 1, htonl(label));
/* Clear all L3 and L4 fields. */ /* Clear all L3 and L4 fields. */
BUILD_ASSERT(FLOW_WC_SEQ == 24); BUILD_ASSERT(FLOW_WC_SEQ == 25);
memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0, memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0,
sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT); sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT);
} }

View File

@@ -37,7 +37,7 @@ struct pkt_metadata;
/* This sequence number should be incremented whenever anything involving flows /* This sequence number should be incremented whenever anything involving flows
* or the wildcarding of flows changes. This will cause build assertion * or the wildcarding of flows changes. This will cause build assertion
* failures in places which likely need to be updated. */ * failures in places which likely need to be updated. */
#define FLOW_WC_SEQ 24 #define FLOW_WC_SEQ 25
#define FLOW_N_REGS 8 #define FLOW_N_REGS 8
BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS); BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS);
@@ -97,6 +97,11 @@ union flow_in_port {
* be looked at. This enables better wildcarding for datapath flows. * be looked at. This enables better wildcarding for datapath flows.
*/ */
struct flow { struct flow {
/* Recirculation */
uint32_t dp_hash; /* Datapath computed hash value. The exact
computation is opaque to the user space.*/
uint32_t recirc_id; /* Must be exact match. */
/* L1 */ /* L1 */
struct flow_tnl tunnel; /* Encapsulating tunnel parameters. */ struct flow_tnl tunnel; /* Encapsulating tunnel parameters. */
ovs_be64 metadata; /* OpenFlow Metadata. */ ovs_be64 metadata; /* OpenFlow Metadata. */
@@ -139,8 +144,8 @@ BUILD_ASSERT_DECL(sizeof(struct flow) % 4 == 0);
/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */ /* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
BUILD_ASSERT_DECL(offsetof(struct flow, tp_dst) + 2 BUILD_ASSERT_DECL(offsetof(struct flow, tp_dst) + 2
== sizeof(struct flow_tnl) + 164 == sizeof(struct flow_tnl) + 172
&& FLOW_WC_SEQ == 24); && FLOW_WC_SEQ == 25);
/* Incremental points at which flow classification may be performed in /* Incremental points at which flow classification may be performed in
* segments. * segments.
@@ -165,6 +170,8 @@ extern const uint8_t flow_segment_u32s[];
/* Represents the metadata fields of struct flow. */ /* Represents the metadata fields of struct flow. */
struct flow_metadata { struct flow_metadata {
uint32_t dp_hash; /* Datapath computed hash field. */
uint32_t recirc_id; /* Recirculation ID. */
ovs_be64 tun_id; /* Encapsulating tunnel ID. */ ovs_be64 tun_id; /* Encapsulating tunnel ID. */
ovs_be32 tun_src; /* Tunnel outer IPv4 src addr */ ovs_be32 tun_src; /* Tunnel outer IPv4 src addr */
ovs_be32 tun_dst; /* Tunnel outer IPv4 dst addr */ ovs_be32 tun_dst; /* Tunnel outer IPv4 dst addr */

View File

@@ -164,6 +164,26 @@ match_zero_wildcarded_fields(struct match *match)
flow_zero_wildcards(&match->flow, &match->wc); flow_zero_wildcards(&match->flow, &match->wc);
} }
void
match_set_dp_hash(struct match *match, uint32_t value)
{
match_set_dp_hash_masked(match, value, UINT32_MAX);
}
void
match_set_dp_hash_masked(struct match *match, uint32_t value, uint32_t mask)
{
match->wc.masks.dp_hash = mask;
match->flow.dp_hash = value & mask;
}
void
match_set_recirc_id(struct match *match, uint32_t value)
{
match->flow.recirc_id = value;
match->wc.masks.recirc_id = UINT32_MAX;
}
void void
match_set_reg(struct match *match, unsigned int reg_idx, uint32_t value) match_set_reg(struct match *match, unsigned int reg_idx, uint32_t value)
{ {
@@ -895,7 +915,7 @@ match_format(const struct match *match, struct ds *s, unsigned int priority)
int i; int i;
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 24); BUILD_ASSERT_DECL(FLOW_WC_SEQ == 25);
if (priority != OFP_DEFAULT_PRIORITY) { if (priority != OFP_DEFAULT_PRIORITY) {
ds_put_format(s, "priority=%u,", priority); ds_put_format(s, "priority=%u,", priority);
@@ -903,6 +923,16 @@ match_format(const struct match *match, struct ds *s, unsigned int priority)
format_uint32_masked(s, "pkt_mark", f->pkt_mark, wc->masks.pkt_mark); format_uint32_masked(s, "pkt_mark", f->pkt_mark, wc->masks.pkt_mark);
if (wc->masks.recirc_id) {
format_uint32_masked(s, "recirc_id", f->recirc_id,
wc->masks.recirc_id);
}
if (f->dp_hash && wc->masks.dp_hash) {
format_uint32_masked(s, "dp_hash", f->dp_hash,
wc->masks.dp_hash);
}
if (wc->masks.skb_priority) { if (wc->masks.skb_priority) {
ds_put_format(s, "skb_priority=%#"PRIx32",", f->skb_priority); ds_put_format(s, "skb_priority=%#"PRIx32",", f->skb_priority);
} }

View File

@@ -41,6 +41,12 @@ void match_init_catchall(struct match *);
void match_zero_wildcarded_fields(struct match *); void match_zero_wildcarded_fields(struct match *);
void match_set_dp_hash(struct match *, uint32_t value);
void match_set_dp_hash_masked(struct match *, uint32_t value, uint32_t mask);
void match_set_recirc_id(struct match *, uint32_t value);
void match_set_recirc_id_masked(struct match *, uint32_t value, uint32_t mask);
void match_set_reg(struct match *, unsigned int reg_idx, uint32_t value); void match_set_reg(struct match *, unsigned int reg_idx, uint32_t value);
void match_set_reg_masked(struct match *, unsigned int reg_idx, void match_set_reg_masked(struct match *, unsigned int reg_idx,
uint32_t value, uint32_t mask); uint32_t value, uint32_t mask);

View File

@@ -52,6 +52,30 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
/* ## -------- ## */ /* ## -------- ## */
{ {
MFF_DP_HASH, "dp_hash", NULL,
MF_FIELD_SIZES(be32),
MFM_FULLY,
MFS_HEXADECIMAL,
MFP_NONE,
false,
NXM_NX_DP_HASH, "NXM_NX_DP_HASH",
NXM_NX_DP_HASH, "NXM_NX_DP_HASH",
OFPUTIL_P_NXM_OXM_ANY,
OFPUTIL_P_NXM_OXM_ANY,
-1,
}, {
MFF_RECIRC_ID, "recirc_id", NULL,
MF_FIELD_SIZES(be32),
MFM_NONE,
MFS_DECIMAL,
MFP_NONE,
false,
NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID",
NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID",
OFPUTIL_P_NXM_OXM_ANY,
OFPUTIL_P_NXM_OXM_ANY,
-1,
}, {
MFF_TUN_ID, "tun_id", "tunnel_id", MFF_TUN_ID, "tun_id", "tunnel_id",
MF_FIELD_SIZES(be64), MF_FIELD_SIZES(be64),
MFM_FULLY, MFM_FULLY,
@@ -879,6 +903,10 @@ bool
mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
{ {
switch (mf->id) { switch (mf->id) {
case MFF_DP_HASH:
return !wc->masks.dp_hash;
case MFF_RECIRC_ID:
return !wc->masks.recirc_id;
case MFF_TUN_SRC: case MFF_TUN_SRC:
return !wc->masks.tunnel.ip_src; return !wc->masks.tunnel.ip_src;
case MFF_TUN_DST: case MFF_TUN_DST:
@@ -1124,6 +1152,8 @@ bool
mf_is_value_valid(const struct mf_field *mf, const union mf_value *value) mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
{ {
switch (mf->id) { switch (mf->id) {
case MFF_DP_HASH:
case MFF_RECIRC_ID:
case MFF_TUN_ID: case MFF_TUN_ID:
case MFF_TUN_SRC: case MFF_TUN_SRC:
case MFF_TUN_DST: case MFF_TUN_DST:
@@ -1217,6 +1247,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
union mf_value *value) union mf_value *value)
{ {
switch (mf->id) { switch (mf->id) {
case MFF_DP_HASH:
value->be32 = htonl(flow->dp_hash);
break;
case MFF_RECIRC_ID:
value->be32 = htonl(flow->recirc_id);
break;
case MFF_TUN_ID: case MFF_TUN_ID:
value->be64 = flow->tunnel.tun_id; value->be64 = flow->tunnel.tun_id;
break; break;
@@ -1409,6 +1445,12 @@ mf_set_value(const struct mf_field *mf,
const union mf_value *value, struct match *match) const union mf_value *value, struct match *match)
{ {
switch (mf->id) { switch (mf->id) {
case MFF_DP_HASH:
match_set_dp_hash(match, ntohl(value->be32));
break;
case MFF_RECIRC_ID:
match_set_recirc_id(match, ntohl(value->be32));
break;
case MFF_TUN_ID: case MFF_TUN_ID:
match_set_tun_id(match, value->be64); match_set_tun_id(match, value->be64);
break; break;
@@ -1622,6 +1664,12 @@ mf_set_flow_value(const struct mf_field *mf,
const union mf_value *value, struct flow *flow) const union mf_value *value, struct flow *flow)
{ {
switch (mf->id) { switch (mf->id) {
case MFF_DP_HASH:
flow->dp_hash = ntohl(value->be32);
break;
case MFF_RECIRC_ID:
flow->recirc_id = ntohl(value->be32);
break;
case MFF_TUN_ID: case MFF_TUN_ID:
flow->tunnel.tun_id = value->be64; flow->tunnel.tun_id = value->be64;
break; break;
@@ -1834,6 +1882,14 @@ void
mf_set_wild(const struct mf_field *mf, struct match *match) mf_set_wild(const struct mf_field *mf, struct match *match)
{ {
switch (mf->id) { switch (mf->id) {
case MFF_DP_HASH:
match->flow.dp_hash = 0;
match->wc.masks.dp_hash = 0;
break;
case MFF_RECIRC_ID:
match->flow.recirc_id = 0;
match->wc.masks.recirc_id = 0;
break;
case MFF_TUN_ID: case MFF_TUN_ID:
match_set_tun_id_masked(match, htonll(0), htonll(0)); match_set_tun_id_masked(match, htonll(0), htonll(0));
break; break;
@@ -2046,6 +2102,7 @@ mf_set(const struct mf_field *mf,
} }
switch (mf->id) { switch (mf->id) {
case MFF_RECIRC_ID:
case MFF_IN_PORT: case MFF_IN_PORT:
case MFF_IN_PORT_OXM: case MFF_IN_PORT_OXM:
case MFF_SKB_PRIORITY: case MFF_SKB_PRIORITY:
@@ -2068,6 +2125,9 @@ mf_set(const struct mf_field *mf,
case MFF_ICMPV6_CODE: case MFF_ICMPV6_CODE:
return OFPUTIL_P_NONE; return OFPUTIL_P_NONE;
case MFF_DP_HASH:
match_set_dp_hash_masked(match, ntohl(value->be32), ntohl(mask->be32));
break;
case MFF_TUN_ID: case MFF_TUN_ID:
match_set_tun_id_masked(match, value->be64, mask->be64); match_set_tun_id_masked(match, value->be64, mask->be64);
break; break;

View File

@@ -33,6 +33,8 @@ struct match;
* to represent its value. */ * to represent its value. */
enum OVS_PACKED_ENUM mf_field_id { enum OVS_PACKED_ENUM mf_field_id {
/* Metadata. */ /* Metadata. */
MFF_DP_HASH, /* be32 */
MFF_RECIRC_ID, /* be32 */
MFF_TUN_ID, /* be64 */ MFF_TUN_ID, /* be64 */
MFF_TUN_SRC, /* be32 */ MFF_TUN_SRC, /* be32 */
MFF_TUN_DST, /* be32 */ MFF_TUN_DST, /* be32 */

View File

@@ -572,9 +572,22 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match,
int match_len; int match_len;
int i; int i;
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 24); BUILD_ASSERT_DECL(FLOW_WC_SEQ == 25);
/* Metadata. */ /* Metadata. */
if (match->wc.masks.dp_hash) {
if (!oxm) {
nxm_put_32m(b, NXM_NX_DP_HASH, htonl(flow->dp_hash),
htonl(match->wc.masks.dp_hash));
}
}
if (match->wc.masks.recirc_id) {
if (!oxm) {
nxm_put_32(b, NXM_NX_RECIRC_ID, htonl(flow->recirc_id));
}
}
if (match->wc.masks.in_port.ofp_port) { if (match->wc.masks.in_port.ofp_port) {
ofp_port_t in_port = flow->in_port.ofp_port; ofp_port_t in_port = flow->in_port.ofp_port;
if (oxm) { if (oxm) {

View File

@@ -85,7 +85,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
void void
ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc) ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
{ {
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 24); BUILD_ASSERT_DECL(FLOW_WC_SEQ == 25);
/* Initialize most of wc. */ /* Initialize most of wc. */
flow_wildcards_init_catchall(wc); flow_wildcards_init_catchall(wc);

View File

@@ -1693,7 +1693,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
/* If 'struct flow' gets additional metadata, we'll need to zero it out /* If 'struct flow' gets additional metadata, we'll need to zero it out
* before traversing a patch port. */ * before traversing a patch port. */
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 24); BUILD_ASSERT_DECL(FLOW_WC_SEQ == 25);
if (!xport) { if (!xport) {
xlate_report(ctx, "Nonexistent output port"); xlate_report(ctx, "Nonexistent output port");