}
static void
-dpif_linux_operate(struct dpif *dpif_, union dpif_op **ops, size_t n_ops)
+dpif_linux_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops)
{
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
struct nl_transaction **txnsp;
txns = xmalloc(n_ops * sizeof *txns);
for (i = 0; i < n_ops; i++) {
struct nl_transaction *txn = &txns[i];
- union dpif_op *op = ops[i];
+ struct dpif_op *op = ops[i];
if (op->type == DPIF_OP_FLOW_PUT) {
- struct dpif_flow_put *put = &op->flow_put;
+ struct dpif_flow_put *put = &op->u.flow_put;
struct dpif_linux_flow request;
dpif_linux_init_flow_put(dpif_, put->flags, put->key, put->key_len,
txn->request = ofpbuf_new(1024);
dpif_linux_flow_to_ofpbuf(&request, txn->request);
} else if (op->type == DPIF_OP_EXECUTE) {
- struct dpif_execute *execute = &op->execute;
+ struct dpif_execute *execute = &op->u.execute;
txn->request = dpif_linux_encode_execute(
dpif->dp_ifindex, execute->key, execute->key_len,
for (i = 0; i < n_ops; i++) {
struct nl_transaction *txn = &txns[i];
- union dpif_op *op = ops[i];
+ struct dpif_op *op = ops[i];
if (op->type == DPIF_OP_FLOW_PUT) {
- struct dpif_flow_put *put = &op->flow_put;
+ struct dpif_flow_put *put = &op->u.flow_put;
int error = txn->error;
if (!error && put->stats) {
dpif_linux_flow_get_stats(&reply, put->stats);
}
}
- put->error = error;
+ op->error = error;
} else if (op->type == DPIF_OP_EXECUTE) {
- struct dpif_execute *execute = &op->execute;
-
- execute->error = txn->error;
+ op->error = txn->error;
} else {
NOT_REACHED();
}
*
* This function is optional. It is only worthwhile to implement it if
* 'dpif' can perform operations in batch faster than individually. */
- void (*operate)(struct dpif *dpif, union dpif_op **ops, size_t n_ops);
+ void (*operate)(struct dpif *dpif, struct dpif_op **ops, size_t n_ops);
/* Enables or disables receiving packets with dpif_recv() for 'dpif'.
* Turning packet receive off and then back on is allowed to change Netlink
* This function exists because some datapaths can perform batched operations
* faster than individual operations. */
void
-dpif_operate(struct dpif *dpif, union dpif_op **ops, size_t n_ops)
+dpif_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops)
{
size_t i;
}
for (i = 0; i < n_ops; i++) {
- union dpif_op *op = ops[i];
+ struct dpif_op *op = ops[i];
struct dpif_flow_put *put;
struct dpif_execute *execute;
switch (op->type) {
case DPIF_OP_FLOW_PUT:
- put = &op->flow_put;
- put->error = dpif_flow_put(dpif, put->flags,
- put->key, put->key_len,
- put->actions, put->actions_len,
- put->stats);
+ put = &op->u.flow_put;
+ op->error = dpif_flow_put(dpif, put->flags,
+ put->key, put->key_len,
+ put->actions, put->actions_len,
+ put->stats);
break;
case DPIF_OP_EXECUTE:
- execute = &op->execute;
- execute->error = dpif_execute(dpif, execute->key, execute->key_len,
- execute->actions,
- execute->actions_len,
- execute->packet);
+ execute = &op->u.execute;
+ op->error = dpif_execute(dpif, execute->key, execute->key_len,
+ execute->actions,
+ execute->actions_len,
+ execute->packet);
break;
default:
};
struct dpif_flow_put {
- enum dpif_op_type type; /* Always DPIF_OP_FLOW_PUT. */
-
/* Input. */
enum dpif_flow_put_flags flags; /* DPIF_FP_*. */
const struct nlattr *key; /* Flow to put. */
/* Output. */
struct dpif_flow_stats *stats; /* Optional flow statistics. */
- int error; /* 0 or positive errno value. */
};
struct dpif_execute {
- enum dpif_op_type type; /* Always DPIF_OP_EXECUTE. */
-
- /* Input. */
const struct nlattr *key; /* Partial flow key (only for metadata). */
size_t key_len; /* Length of 'key' in bytes. */
const struct nlattr *actions; /* Actions to execute on packet. */
size_t actions_len; /* Length of 'actions' in bytes. */
const struct ofpbuf *packet; /* Packet to execute. */
-
- /* Output. */
- int error; /* 0 or positive errno value. */
};
-union dpif_op {
+struct dpif_op {
enum dpif_op_type type;
- struct dpif_flow_put flow_put;
- struct dpif_execute execute;
+ int error;
+ union {
+ struct dpif_flow_put flow_put;
+ struct dpif_execute execute;
+ } u;
};
-void dpif_operate(struct dpif *, union dpif_op **ops, size_t n_ops);
+void dpif_operate(struct dpif *, struct dpif_op **ops, size_t n_ops);
\f
/* Upcalls. */
};
struct flow_miss_op {
- union dpif_op dpif_op;
+ struct dpif_op dpif_op;
struct subfacet *subfacet;
};
}
op = &ops[(*n_ops)++];
- execute = &op->dpif_op.execute;
+ execute = &op->dpif_op.u.execute;
op->subfacet = subfacet;
- execute->type = DPIF_OP_EXECUTE;
+ op->dpif_op.type = DPIF_OP_EXECUTE;
execute->key = miss->key;
execute->key_len = miss->key_len;
execute->actions = (facet->may_install
if (facet->may_install && subfacet->key_fitness != ODP_FIT_TOO_LITTLE) {
struct flow_miss_op *op = &ops[(*n_ops)++];
- struct dpif_flow_put *put = &op->dpif_op.flow_put;
+ struct dpif_flow_put *put = &op->dpif_op.u.flow_put;
op->subfacet = subfacet;
- put->type = DPIF_OP_FLOW_PUT;
+ op->dpif_op.type = DPIF_OP_FLOW_PUT;
put->flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
put->key = miss->key;
put->key_len = miss->key_len;
struct dpif_upcall *upcall;
struct flow_miss *miss, *next_miss;
struct flow_miss_op flow_miss_ops[FLOW_MISS_MAX_BATCH * 2];
- union dpif_op *dpif_ops[FLOW_MISS_MAX_BATCH * 2];
+ struct dpif_op *dpif_ops[FLOW_MISS_MAX_BATCH * 2];
struct hmap todo;
size_t n_ops;
size_t i;
for (i = 0; i < n_ops; i++) {
struct flow_miss_op *op = &flow_miss_ops[i];
struct dpif_execute *execute;
- struct dpif_flow_put *put;
switch (op->dpif_op.type) {
case DPIF_OP_EXECUTE:
- execute = &op->dpif_op.execute;
+ execute = &op->dpif_op.u.execute;
if (op->subfacet->actions != execute->actions) {
free((struct nlattr *) execute->actions);
}
break;
case DPIF_OP_FLOW_PUT:
- put = &op->dpif_op.flow_put;
- if (!put->error) {
+ if (!op->dpif_op.error) {
op->subfacet->installed = true;
}
break;