+int
+odp_action_len(uint16_t type)
+{
+ if (type > ODPAT_MAX) {
+ return -1;
+ }
+
+ switch ((enum odp_action_type) type) {
+ case ODPAT_OUTPUT: return 4;
+ case ODPAT_CONTROLLER: return 8;
+ case ODPAT_SET_DL_TCI: return 2;
+ case ODPAT_STRIP_VLAN: return 0;
+ case ODPAT_SET_DL_SRC: return ETH_ADDR_LEN;
+ case ODPAT_SET_DL_DST: return ETH_ADDR_LEN;
+ case ODPAT_SET_NW_SRC: return 4;
+ case ODPAT_SET_NW_DST: return 4;
+ case ODPAT_SET_NW_TOS: return 1;
+ case ODPAT_SET_TP_SRC: return 2;
+ case ODPAT_SET_TP_DST: return 2;
+ case ODPAT_SET_TUNNEL: return 8;
+ case ODPAT_SET_PRIORITY: return 4;
+ case ODPAT_POP_PRIORITY: return 0;
+ case ODPAT_DROP_SPOOFED_ARP: return 0;
+
+ case ODPAT_UNSPEC:
+ case __ODPAT_MAX:
+ return -1;
+ }
+
+ return -1;
+}
+
+static void
+format_generic_odp_action(struct ds *ds, const struct nlattr *a)
+{
+ ds_put_format(ds, "action%"PRId16, nl_attr_type(a));
+ if (a->nla_len) {
+ const uint8_t *unspec;
+ unsigned int i;
+
+ unspec = nl_attr_get(a);
+ for (i = 0; i < a->nla_len; i++) {
+ ds_put_char(ds, i ? ' ': '(');
+ ds_put_format(ds, "%02x", unspec[i]);
+ }
+ ds_put_char(ds, ')');
+ }
+}
+