- int i;
- for (i = 0; i < n_actions; i++) {
- const union odp_action *a = &actions[i];
-
- switch (a->type) {
- case ODPAT_OUTPUT:
- dp_netdev_output_port(dp, packet, a->output.port);
- break;
-
- case ODPAT_OUTPUT_GROUP:
- dp_netdev_output_group(dp, a->output_group.group, key->in_port,
- packet);
- break;
-
- case ODPAT_CONTROLLER:
- dp_netdev_output_control(dp, packet, _ODPL_ACTION_NR,
- key->in_port, a->controller.arg);
- break;
-
- case ODPAT_SET_VLAN_VID:
- dp_netdev_modify_vlan_tci(packet, key, ntohs(a->vlan_vid.vlan_vid),
- VLAN_VID_MASK);
+ const struct nlattr *a;
+ unsigned int left;
+
+ NL_ATTR_FOR_EACH_UNSAFE (a, left, actions, actions_len) {
+ switch (nl_attr_type(a)) {
+ case ODP_ACTION_ATTR_OUTPUT:
+ dp_netdev_output_port(dp, packet, nl_attr_get_u32(a));
+ break;
+
+ case ODP_ACTION_ATTR_CONTROLLER:
+ dp_netdev_output_control(dp, packet, DPIF_UC_ACTION,
+ key, nl_attr_get_u64(a));
+ break;
+
+ case ODP_ACTION_ATTR_SET_DL_TCI:
+ dp_netdev_set_dl_tci(packet, nl_attr_get_be16(a));
+ break;
+
+ case ODP_ACTION_ATTR_STRIP_VLAN:
+ dp_netdev_strip_vlan(packet);
+ break;
+
+ case ODP_ACTION_ATTR_SET_DL_SRC:
+ dp_netdev_set_dl_src(packet, nl_attr_get_unspec(a, ETH_ADDR_LEN));
+ break;
+
+ case ODP_ACTION_ATTR_SET_DL_DST:
+ dp_netdev_set_dl_dst(packet, nl_attr_get_unspec(a, ETH_ADDR_LEN));
+ break;
+
+ case ODP_ACTION_ATTR_SET_NW_SRC:
+ case ODP_ACTION_ATTR_SET_NW_DST:
+ dp_netdev_set_nw_addr(packet, key, a);
+ break;
+
+ case ODP_ACTION_ATTR_SET_NW_TOS:
+ dp_netdev_set_nw_tos(packet, key, nl_attr_get_u8(a));