Dump flow rules. */
| 3725 | |
| 3726 | /** Dump flow rules. */ |
| 3727 | int |
| 3728 | port_flow_dump(portid_t port_id, bool dump_all, uint64_t rule_id, |
| 3729 | const char *file_name, bool is_user_id) |
| 3730 | { |
| 3731 | int ret = 0; |
| 3732 | FILE *file = stdout; |
| 3733 | struct rte_flow_error error; |
| 3734 | struct rte_port *port; |
| 3735 | struct port_flow *pflow; |
| 3736 | struct rte_flow *tmpFlow = NULL; |
| 3737 | bool found = false; |
| 3738 | |
| 3739 | if (port_id_is_invalid(port_id, ENABLED_WARN) || |
| 3740 | port_id == (portid_t)RTE_PORT_ALL) |
| 3741 | return -EINVAL; |
| 3742 | |
| 3743 | if (!dump_all) { |
| 3744 | port = &ports[port_id]; |
| 3745 | pflow = port->flow_list; |
| 3746 | while (pflow) { |
| 3747 | if (rule_id != |
| 3748 | (is_user_id ? pflow->user_id : pflow->id)) { |
| 3749 | pflow = pflow->next; |
| 3750 | } else { |
| 3751 | tmpFlow = pflow->flow; |
| 3752 | if (tmpFlow) |
| 3753 | found = true; |
| 3754 | break; |
| 3755 | } |
| 3756 | } |
| 3757 | if (found == false) { |
| 3758 | fprintf(stderr, "Failed to dump to flow %"PRIu64"\n", |
| 3759 | rule_id); |
| 3760 | return -EINVAL; |
| 3761 | } |
| 3762 | } |
| 3763 | |
| 3764 | if (file_name && strlen(file_name)) { |
| 3765 | file = fopen(file_name, "w"); |
| 3766 | if (!file) { |
| 3767 | fprintf(stderr, "Failed to create file %s: %s\n", |
| 3768 | file_name, strerror(errno)); |
| 3769 | return -errno; |
| 3770 | } |
| 3771 | } |
| 3772 | |
| 3773 | if (!dump_all) |
| 3774 | ret = rte_flow_dev_dump(port_id, tmpFlow, file, &error); |
| 3775 | else |
| 3776 | ret = rte_flow_dev_dump(port_id, NULL, file, &error); |
| 3777 | if (ret) { |
| 3778 | port_flow_complain(&error); |
| 3779 | fprintf(stderr, "Failed to dump flow: %s\n", strerror(-ret)); |
| 3780 | } else |
| 3781 | printf("Flow dump finished\n"); |
| 3782 | if (file_name && strlen(file_name)) |
| 3783 | fclose(file); |
| 3784 | return ret; |
no test coverage detected