DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
FlowControl.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017 Mellanox Technologies, Ltd
3 */
4
6
7#include "logging/Logging.hpp"
8
9#include <rte_byteorder.h>
10#include <rte_ether.h>
11#include <rte_flow.h>
12#include <rte_ip.h>
13
14namespace dunedaq {
15namespace dpdklibs {
16
39
40/* Function responsible for creating the flow rule. 8< */
41struct rte_flow*
42generate_ipv4_flow(uint16_t port_id,
43 uint16_t rx_q,
44 uint32_t src_ip,
45 uint32_t src_mask,
46 uint32_t dest_ip,
47 uint32_t dest_mask,
48 struct rte_flow_error* error)
49{
50 // Declaring structs being used.
51 struct rte_flow_attr attr;
52 struct rte_flow_item pattern[MAX_PATTERN_NUM];
53 struct rte_flow_action action[MAX_ACTION_NUM];
54 struct rte_flow* flow = NULL;
55 struct rte_flow_action_queue queue = { .index = rx_q };
56 struct rte_flow_item_ipv4 ip_spec;
57 struct rte_flow_item_ipv4 ip_mask;
58
59 int res;
60
61 memset(pattern, 0, sizeof(pattern));
62 memset(action, 0, sizeof(action));
63
64 // Set the rule attribute, only ingress packets will be checked.
65 memset(&attr, 0, sizeof(struct rte_flow_attr));
66 attr.ingress = 1;
67
68 /*
69 * create the action sequence.
70 * one action only, move packet to queue
71 */
72 action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
73 action[0].conf = &queue;
74 action[1].type = RTE_FLOW_ACTION_TYPE_END;
75
76 /*
77 * set the first level of the pattern (ETH).
78 * since in this example we just want to get the
79 * ipv4 we set this level to allow all.
80 */
81
82 // Set this level to allow all.
83
84 /*
85 * setting the second level of the pattern (IP).
86 * in this example this is the level we care about
87 * so we set it according to the parameters.
88 */
89
90 // Setting the second level of the pattern.
91 memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4));
92 memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4));
93 ip_spec.hdr.dst_addr = htonl(dest_ip);
94 ip_mask.hdr.dst_addr = 0;
95 ip_spec.hdr.src_addr = htonl(src_ip);
96 ip_mask.hdr.src_addr = src_mask;
97
98 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
99
100 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
101 pattern[1].spec = &ip_spec;
102 pattern[1].mask = &ip_mask;
103
104 pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
105
106 // Validate the rule and create it.
107 res = rte_flow_validate(port_id, &attr, pattern, action, error);
108 if (not res) {
109 flow = rte_flow_create(port_id, &attr, pattern, action, error);
110 }
111
112 return flow;
113}
114
115// Droppign all the traffic that did pass a flow with higher priority
116struct rte_flow*
117generate_drop_flow(uint16_t port_id, struct rte_flow_error* error)
118{
119 struct rte_flow_attr attr;
120 struct rte_flow_item pattern[MAX_PATTERN_NUM];
121 struct rte_flow_action action[MAX_ACTION_NUM];
122 struct rte_flow* flow = NULL;
123 int res;
124
125 memset(pattern, 0, sizeof(pattern));
126 memset(action, 0, sizeof(action));
127
128 // Set the rule attribute, only ingress packets will be checked.
129 memset(&attr, 0, sizeof(struct rte_flow_attr));
130 attr.ingress = 1;
131 attr.egress = 0;
132 attr.priority = 1; // TODO the higher the lower?
133
134 /*
135 * create the action sequence.
136 * one action only, Drop the packet
137 */
138 action[0].type = RTE_FLOW_ACTION_TYPE_DROP;
139 action[1].type = RTE_FLOW_ACTION_TYPE_END;
140
141 /*
142 * set the first level of the pattern (ETH).
143 * since in this example we just want to get the
144 * ipv4 we set this level to allow all.
145 */
146
147 // Set this level to allow all.
148 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
149
150 /*
151 * setting the second level of the pattern (IP).
152 * in this example this is the level we care about
153 * so we set it according to the parameters.
154 */
155
156 // The final level must be always type end.
157 pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
158
159 // Validate the rule and create it.
160 res = rte_flow_validate(port_id, &attr, pattern, action, error);
161 if (not res) {
162 flow = rte_flow_create(port_id, &attr, pattern, action, error);
163 }
164
165 return flow;
166}
167
168// ARP packets to specific
169struct rte_flow*
170generate_arp_flow(uint16_t port_id, uint16_t rx_q, struct rte_flow_error* error)
171{
172 struct rte_flow_attr attr;
173 struct rte_flow_item pattern[MAX_PATTERN_NUM];
174 struct rte_flow_action action[MAX_ACTION_NUM];
175 struct rte_flow* flow = NULL;
176 struct rte_flow_action_queue queue = { .index = rx_q };
177 int res;
178
179 memset(pattern, 0, sizeof(pattern));
180 memset(action, 0, sizeof(action));
181
182 // Set the rule attribute, only ingress packets will be checked.
183 memset(&attr, 0, sizeof(struct rte_flow_attr));
184 attr.ingress = 1;
185 attr.egress = 0;
186 attr.priority = 1; // TODO the higher the lower?
187
188 // Action -> queue steering
189 action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
190 action[0].conf = &queue;
191 action[1].type = RTE_FLOW_ACTION_TYPE_END;
192
193 // Rule prep
194 struct rte_flow_item_eth item_eth_mask = {};
195 struct rte_flow_item_eth item_eth_spec = {};
196 // Rule marker
197 item_eth_spec.hdr.ether_type = RTE_BE16(RTE_ETHER_TYPE_ARP);
198 item_eth_mask.hdr.ether_type = RTE_BE16(0xFFFF);
199 // Rule pattern
200 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
201 pattern[0].mask = &item_eth_mask;
202 pattern[0].spec = &item_eth_spec;
203 pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
204
205 // Validate the rule and create it.
206 res = rte_flow_validate(port_id, &attr, pattern, action, error);
207 if (not res) {
208 flow = rte_flow_create(port_id, &attr, pattern, action, error);
209 }
210
211 return flow;
212}
213
214} // namespace dpdklibs
215} // namespace dunedaq
static constexpr uint32_t MAX_ACTION_NUM
struct rte_flow * generate_ipv4_flow(uint16_t port_id, uint16_t rx_q, uint32_t src_ip, uint32_t src_mask, uint32_t dest_ip, uint32_t dest_mask, struct rte_flow_error *error)
static constexpr uint32_t MAX_PATTERN_NUM
struct rte_flow * generate_arp_flow(uint16_t port_id, uint16_t rx_q, struct rte_flow_error *error)
struct rte_flow * generate_drop_flow(uint16_t port_id, struct rte_flow_error *error)
The DUNE-DAQ namespace.
CIB Buffer std::string descriptor Message from std::string descriptor CIB process error