Skip to content

Commit

Permalink
odp-util: Share fields between odp and dpif_backer.
Browse files Browse the repository at this point in the history
Datapath support for some flow key fields is used inside ofproto-dpif as
well as odp-util. Share these fields using the same structure.

Signed-off-by: Joe Stringer <[email protected]>
Acked-by: Andy Zhou <[email protected]>
  • Loading branch information
joestringer committed Jul 6, 2015
1 parent 7552cf4 commit 2494ccd
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 48 deletions.
10 changes: 7 additions & 3 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ static struct shash dp_netdevs OVS_GUARDED_BY(dp_netdev_mutex)

static struct vlog_rate_limit upcall_rl = VLOG_RATE_LIMIT_INIT(600, 600);

static struct odp_support dp_netdev_support = {
.max_mpls_depth = SIZE_MAX,
.recirc = true,
};

/* Stores a miniflow with inline values */

struct netdev_flow_key {
Expand Down Expand Up @@ -1824,8 +1829,7 @@ dp_netdev_flow_to_dpif_flow(const struct dp_netdev_flow *netdev_flow,
struct odp_flow_key_parms odp_parms = {
.flow = &netdev_flow->flow,
.mask = &wc.masks,
.recirc = true,
.max_mpls_depth = SIZE_MAX,
.support = dp_netdev_support,
};

miniflow_expand(&netdev_flow->cr.mask->mf, &wc.masks);
Expand Down Expand Up @@ -3030,7 +3034,7 @@ dp_netdev_upcall(struct dp_netdev_pmd_thread *pmd, struct dp_packet *packet_,
.flow = flow,
.mask = &wc->masks,
.odp_in_port = flow->in_port.odp_port,
.recirc = true,
.support = dp_netdev_support,
};

ofpbuf_init(&key, 0);
Expand Down
4 changes: 2 additions & 2 deletions lib/odp-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -3467,7 +3467,7 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms,

nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->pkt_mark);

if (parms->recirc) {
if (parms->support.recirc) {
nl_msg_put_u32(buf, OVS_KEY_ATTR_RECIRC_ID, data->recirc_id);
nl_msg_put_u32(buf, OVS_KEY_ATTR_DP_HASH, data->dp_hash);
}
Expand Down Expand Up @@ -3542,7 +3542,7 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms,

n = flow_count_mpls_labels(flow, NULL);
if (export_mask) {
n = MIN(n, parms->max_mpls_depth);
n = MIN(n, parms->support.max_mpls_depth);
}
mpls_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_MPLS,
n * sizeof *mpls_key);
Expand Down
20 changes: 13 additions & 7 deletions lib/odp-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,16 @@ int odp_flow_from_string(const char *s,
const struct simap *port_names,
struct ofpbuf *, struct ofpbuf *);

/* Indicates support for various fields. This defines how flows will be
* serialised. */
struct odp_support {
/* Maximum number of MPLS label stack entries to serialise in a mask. */
size_t max_mpls_depth;

/* If this is true, then recirculation fields will always be serialised. */
bool recirc;
};

struct odp_flow_key_parms {
/* The flow and mask to be serialized. In the case of masks, 'flow'
* is used as a template to determine how to interpret 'mask'. For
Expand All @@ -173,13 +183,9 @@ struct odp_flow_key_parms {
* port. */
odp_port_t odp_in_port;

/* Indicates support for recirculation fields. If this is true, then
* these fields will always be serialised. */
bool recirc;

/* Only used for mask translation: */

size_t max_mpls_depth;
/* Indicates support for various fields. If the datapath supports a field,
* then it will always be serialised. */
struct odp_support support;

/* The netlink formatted version of the flow. It is used in cases where
* the mask cannot be constructed from the OVS internal representation
Expand Down
4 changes: 2 additions & 2 deletions lib/tnl-ports.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,15 @@ tnl_port_show(struct unixctl_conn *conn, int argc OVS_UNUSED,

/* Key. */
odp_parms.odp_in_port = flow.in_port.odp_port;
odp_parms.recirc = true;
odp_parms.support.recirc = true;
ofpbuf_use_stack(&buf, &keybuf, sizeof keybuf);
odp_flow_key_from_flow(&odp_parms, &buf);
key = buf.data;
key_len = buf.size;

/* mask*/
odp_parms.odp_in_port = wc.masks.in_port.odp_port;
odp_parms.recirc = false;
odp_parms.support.recirc = false;
ofpbuf_use_stack(&buf, &maskbuf, sizeof maskbuf);
odp_flow_key_from_mask(&odp_parms, &buf);
mask = buf.data;
Expand Down
2 changes: 1 addition & 1 deletion ofproto/bond.c
Original file line number Diff line number Diff line change
Expand Up @@ -1137,7 +1137,7 @@ bond_rebalance(struct bond *bond)
}
bond->next_rebalance = time_msec() + bond->rebalance_interval;

use_recirc = ofproto_dpif_get_enable_recirc(bond->ofproto) &&
use_recirc = ofproto_dpif_get_support(bond->ofproto)->odp.recirc &&
bond_may_recirc(bond, NULL, NULL);

if (use_recirc) {
Expand Down
7 changes: 2 additions & 5 deletions ofproto/ofproto-dpif-upcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,30 +1361,27 @@ ukey_create_from_upcall(struct upcall *upcall)
{
struct odputil_keybuf keystub, maskstub;
struct ofpbuf keybuf, maskbuf;
bool recirc, megaflow;
bool megaflow;
struct odp_flow_key_parms odp_parms = {
.flow = upcall->flow,
.mask = &upcall->xout.wc.masks,
};

odp_parms.support = ofproto_dpif_get_support(upcall->ofproto)->odp;
if (upcall->key_len) {
ofpbuf_use_const(&keybuf, upcall->key, upcall->key_len);
} else {
/* dpif-netdev doesn't provide a netlink-formatted flow key in the
* upcall, so convert the upcall's flow here. */
ofpbuf_use_stack(&keybuf, &keystub, sizeof keystub);
odp_parms.odp_in_port = upcall->flow->in_port.odp_port;
odp_parms.recirc = true;
odp_flow_key_from_flow(&odp_parms, &keybuf);
}

atomic_read_relaxed(&enable_megaflows, &megaflow);
recirc = ofproto_dpif_get_enable_recirc(upcall->ofproto);
ofpbuf_use_stack(&maskbuf, &maskstub, sizeof maskstub);
if (megaflow) {
odp_parms.odp_in_port = ODPP_NONE;
odp_parms.max_mpls_depth = ofproto_dpif_get_max_mpls_depth(upcall->ofproto);
odp_parms.recirc = recirc;
odp_parms.key_buf = &keybuf;

odp_flow_key_from_mask(&odp_parms, &maskbuf);
Expand Down
6 changes: 3 additions & 3 deletions ofproto/ofproto-dpif-xlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1735,7 +1735,7 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,
struct flow_wildcards *wc = &ctx->xout->wc;
struct ofport_dpif *ofport;

if (ctx->xbridge->support.recirc) {
if (ctx->xbridge->support.odp.recirc) {
use_recirc = bond_may_recirc(
out_xbundle->bond, &xr.recirc_id, &xr.hash_basis);

Expand Down Expand Up @@ -3625,7 +3625,7 @@ compose_mpls_pop_action(struct xlate_ctx *ctx, ovs_be16 eth_type)
int n = flow_count_mpls_labels(flow, wc);

if (flow_pop_mpls(flow, n, eth_type, wc)) {
if (ctx->xbridge->support.recirc) {
if (ctx->xbridge->support.odp.recirc) {
ctx->was_mpls = true;
}
} else if (n >= FLOW_MAX_MPLS_LABELS) {
Expand Down Expand Up @@ -4808,7 +4808,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
if (is_ip_any(flow)) {
wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
}
if (xbridge->support.recirc) {
if (xbridge->support.odp.recirc) {
/* Always exactly match recirc_id when datapath supports
* recirculation. */
wc->masks.recirc_id = UINT32_MAX;
Expand Down
24 changes: 10 additions & 14 deletions ofproto/ofproto-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,22 +359,16 @@ ofproto_dpif_cast(const struct ofproto *ofproto)
return CONTAINER_OF(ofproto, struct ofproto_dpif, up);
}

size_t
ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *ofproto)
{
return ofproto->backer->support.max_mpls_depth;
}

bool
ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *ofproto)
ofproto_dpif_get_enable_ufid(const struct dpif_backer *backer)
{
return ofproto->backer->support.recirc;
return backer->support.ufid;
}

bool
ofproto_dpif_get_enable_ufid(struct dpif_backer *backer)
struct dpif_backer_support *
ofproto_dpif_get_support(const struct ofproto_dpif *ofproto)
{
return backer->support.ufid;
return &ofproto->backer->support;
}

static void ofproto_trace(struct ofproto_dpif *, struct flow *,
Expand Down Expand Up @@ -1005,7 +999,9 @@ check_recirc(struct dpif_backer *backer)
bool enable_recirc;
struct odp_flow_key_parms odp_parms = {
.flow = &flow,
.recirc = true,
.support = {
.recirc = true,
},
};

memset(&flow, 0, sizeof flow);
Expand Down Expand Up @@ -1226,8 +1222,8 @@ check_support(struct dpif_backer *backer)
/* This feature needs to be tested after udpif threads are set. */
backer->support.variable_length_userdata = false;

backer->support.recirc = check_recirc(backer);
backer->support.max_mpls_depth = check_max_mpls_depth(backer);
backer->support.odp.recirc = check_recirc(backer);
backer->support.odp.max_mpls_depth = check_max_mpls_depth(backer);
backer->support.masked_set_action = check_masked_set_action(backer);
backer->support.ufid = check_ufid(backer);
backer->support.tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif);
Expand Down
15 changes: 5 additions & 10 deletions ofproto/ofproto-dpif.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,27 +80,22 @@ struct dpif_backer_support {
* False if the datapath supports only 8-byte (or shorter) userdata. */
bool variable_length_userdata;

/* Maximum number of MPLS label stack entries that the datapath supports
* in a match */
size_t max_mpls_depth;

/* True if the datapath supports masked data in OVS_ACTION_ATTR_SET
* actions. */
bool masked_set_action;

/* True if the datapath supports recirculation. */
bool recirc;

/* True if the datapath supports tnl_push and pop actions. */
bool tnl_push_pop;

/* True if the datapath supports OVS_FLOW_ATTR_UFID. */
bool ufid;

/* Each member represents support for related OVS_KEY_ATTR_* fields. */
struct odp_support odp;
};

size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *);
bool ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *);
bool ofproto_dpif_get_enable_ufid(struct dpif_backer *backer);
bool ofproto_dpif_get_enable_ufid(const struct dpif_backer *backer);
struct dpif_backer_support *ofproto_dpif_get_support(const struct ofproto_dpif *);

cls_version_t ofproto_dpif_get_tables_version(struct ofproto_dpif *);

Expand Down
4 changes: 3 additions & 1 deletion tests/test-odp.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ parse_keys(bool wc_keys)
if (!wc_keys) {
struct odp_flow_key_parms odp_parms = {
.flow = &flow,
.recirc = true,
.support = {
.recirc = true,
},
};

/* Convert odp_key to flow. */
Expand Down

0 comments on commit 2494ccd

Please sign in to comment.