NXAST_POP_QUEUE, /* struct nx_action_pop_queue */
NXAST_REG_MOVE, /* struct nx_action_reg_move */
NXAST_REG_LOAD, /* struct nx_action_reg_load */
+ NXAST_NOTE /* struct nx_action_note */
};
/* Header for Nicira-defined actions. */
};
OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24);
+/* Action structure for NXAST_NOTE.
+ *
+ * This action has no effect. It is variable length. The switch does not
+ * attempt to interpret the user-defined 'note' data in any way. A controller
+ * can use this action to attach arbitrary metadata to a flow.
+ *
+ * This action might go away in the future.
+ */
+struct nx_action_note {
+ uint16_t type; /* OFPAT_VENDOR. */
+ uint16_t len; /* A multiple of 8, but at least 16. */
+ uint32_t vendor; /* NX_VENDOR_ID. */
+ uint16_t subtype; /* NXAST_NOTE. */
+ uint8_t note[6]; /* Start of user-defined data. */
+ /* Possibly followed by additional user-defined data. */
+};
+OFP_ASSERT(sizeof(struct nx_action_note) == 16);
+
/* Wildcard for tunnel ID. */
#define NXFW_TUN_ID (1 << 25)
nah = put_action(b, sizeof *nah, OFPAT_VENDOR);
nah->vendor = htonl(NX_VENDOR_ID);
nah->subtype = htons(NXAST_POP_QUEUE);
+ } else if (!strcasecmp(act, "note")) {
+ size_t start_ofs = b->size;
+ struct nx_action_note *nan;
+ int remainder;
+ size_t len;
+
+ nan = put_action(b, sizeof *nan, OFPAT_VENDOR);
+ nan->vendor = htonl(NX_VENDOR_ID);
+ nan->subtype = htons(NXAST_NOTE);
+
+ b->size -= sizeof nan->note;
+ while (arg && *arg != '\0') {
+ int high, low;
+ uint8_t byte;
+
+ if (*arg == '.') {
+ arg++;
+ }
+ if (*arg == '\0') {
+ break;
+ }
+
+ high = hexit_value(*arg++);
+ if (high >= 0) {
+ low = hexit_value(*arg++);
+ }
+ if (high < 0 || low < 0) {
+ ovs_fatal(0, "bad hex digit in `note' argument");
+ }
+
+ byte = high * 16 + low;
+ ofpbuf_put(b, &byte, 1);
+ }
+
+ len = b->size - start_ofs;
+ remainder = len % OFP_ACTION_ALIGN;
+ if (remainder) {
+ ofpbuf_put_zeros(b, OFP_ACTION_ALIGN - remainder);
+ }
+ nan->len = htons(b->size - start_ofs);
} else if (!strcasecmp(act, "output")) {
put_output_action(b, str_to_u32(arg));
} else if (!strcasecmp(act, "enqueue")) {
ds_put_cstr(string, name);
}
+static void
+print_note(struct ds *string, const struct nx_action_note *nan)
+{
+ size_t len;
+ size_t i;
+
+ ds_put_cstr(string, "note:");
+ len = ntohs(nan->len) - offsetof(struct nx_action_note, note);
+ for (i = 0; i < len; i++) {
+ if (i) {
+ ds_put_char(string, '.');
+ }
+ ds_put_format(string, "%02"PRIx8, nan->note[i]);
+ }
+}
+
static void
ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah)
{
ds_put_cstr(string, "pop_queue");
break;
+ case NXAST_NOTE:
+ print_note(string, (const struct nx_action_note *) nah);
+ break;
+
default:
ds_put_format(string, "***unknown Nicira action:%d***",
ntohs(nah->subtype));
case NXAST_SET_QUEUE:
case NXAST_POP_QUEUE:
return check_action_exact_len(a, len, 16);
+
case NXAST_REG_MOVE:
error = check_action_exact_len(a, len,
sizeof(struct nx_action_reg_move));
return error;
}
return nxm_check_reg_move((const struct nx_action_reg_move *) a, flow);
+
case NXAST_REG_LOAD:
error = check_action_exact_len(a, len,
sizeof(struct nx_action_reg_load));
return error;
}
return nxm_check_reg_load((const struct nx_action_reg_load *) a, flow);
+
+ case NXAST_NOTE:
+ return 0;
+
default:
return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE);
}
case NXAST_REG_LOAD:
nxm_execute_reg_load((const struct nx_action_reg_load *) nah,
&ctx->flow);
+
+ case NXAST_NOTE:
+ /* Nothing to do. */
break;
/* If you add a new action here that modifies flow data, don't forget to
tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
cookie=0x123456789abcdef hard_timeout=10 priority=60000 actions=controller
+actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
actions=drop
])
AT_CHECK([ovs-ofctl parse-flows flows.txt], [0], [stdout])
flow_mod: tcp,nw_src=192.168.0.3,tp_dst=80, ADD: actions=set_queue:37,output:1
flow_mod: udp,nw_src=192.168.0.3,tp_dst=53, ADD: actions=pop_queue,output:1
flow_mod: ADD: cookie:0x123456789abcdef hard:10 pri:60000 actions=CONTROLLER:65535
+flow_mod: ADD: actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.00.00.00.00.00.00,note:00.00.00.00.00.00
flow_mod: ADD: actions=drop
])
AT_CLEANUP
Restores the queue to the value it was before any \fBset_queue\fR
actions were applied.
.
+.IP \fBnote:\fR[\fIhh\fR]...
+Does nothing at all. Any number of bytes represented as hex digits
+\fIhh\fR may be included. Pairs of hex digits may be separated by
+periods for readability.
.RE
.
.IP