Create flow rule. */
| 3576 | |
| 3577 | /** Create flow rule. */ |
| 3578 | int |
| 3579 | port_flow_create(portid_t port_id, |
| 3580 | const struct rte_flow_attr *attr, |
| 3581 | const struct rte_flow_item *pattern, |
| 3582 | const struct rte_flow_action *actions, |
| 3583 | const struct tunnel_ops *tunnel_ops, |
| 3584 | uintptr_t user_id) |
| 3585 | { |
| 3586 | struct rte_flow *flow; |
| 3587 | struct rte_port *port; |
| 3588 | struct port_flow *pf; |
| 3589 | uint32_t id = 0; |
| 3590 | struct rte_flow_error error; |
| 3591 | struct port_flow_tunnel *pft = NULL; |
| 3592 | struct rte_flow_action_age *age = age_action_get(actions); |
| 3593 | |
| 3594 | port = &ports[port_id]; |
| 3595 | if (port->flow_list) { |
| 3596 | if (port->flow_list->id == UINT32_MAX) { |
| 3597 | fprintf(stderr, |
| 3598 | "Highest rule ID is already assigned, delete it first"); |
| 3599 | return -ENOMEM; |
| 3600 | } |
| 3601 | id = port->flow_list->id + 1; |
| 3602 | } |
| 3603 | if (tunnel_ops->enabled) { |
| 3604 | pft = port_flow_tunnel_offload_cmd_prep(port_id, pattern, |
| 3605 | actions, tunnel_ops); |
| 3606 | if (!pft) |
| 3607 | return -ENOENT; |
| 3608 | if (pft->items) |
| 3609 | pattern = pft->items; |
| 3610 | if (pft->actions) |
| 3611 | actions = pft->actions; |
| 3612 | } |
| 3613 | pf = port_flow_new(attr, pattern, actions, &error); |
| 3614 | if (!pf) |
| 3615 | return port_flow_complain(&error); |
| 3616 | if (age) { |
| 3617 | pf->age_type = ACTION_AGE_CONTEXT_TYPE_FLOW; |
| 3618 | age->context = &pf->age_type; |
| 3619 | } |
| 3620 | /* Poisoning to make sure PMDs update it in case of error. */ |
| 3621 | memset(&error, 0x22, sizeof(error)); |
| 3622 | flow = rte_flow_create(port_id, attr, pattern, actions, &error); |
| 3623 | if (!flow) { |
| 3624 | if (tunnel_ops->enabled) |
| 3625 | port_flow_tunnel_offload_cmd_release(port_id, |
| 3626 | tunnel_ops, pft); |
| 3627 | free(pf); |
| 3628 | return port_flow_complain(&error); |
| 3629 | } |
| 3630 | pf->next = port->flow_list; |
| 3631 | pf->id = id; |
| 3632 | pf->user_id = user_id; |
| 3633 | pf->flow = flow; |
| 3634 | port->flow_list = pf; |
| 3635 | if (tunnel_ops->enabled) |
no test coverage detected