2 Copyright(c) 2017 Mellanox Corporation. All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the
15 * Neither the name of Mellanox Corporation nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 Generic flow API - examples
33 ===========================
35 This document demonstrates some concrete examples for programming flow rules
36 with the ``rte_flow`` APIs.
38 * Detail of the rte_flow APIs can be found in the following link:
39 :ref:`Generic flow API <Generic_flow_API>` .
41 * Details of the TestPMD commands to set the flow rules can be found in the
42 following link: :ref:`TestPMD Flow rules <testpmd_rte_flow>`
50 In this example we will create a simple rule that drops packets whose IPv4
51 destination equals 192.168.3.2. This code is equivalent to the following
52 testpmd command (wrapped for clarity)::
54 tpmd> flow create 0 ingress pattern eth / vlan /
55 ipv4 dst is 192.168.3.2 / end actions drop / end
62 /* create the attribute structure */
63 struct rte_flow_attr attr = {.ingress = 1};
64 struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW];
65 struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW];
66 struct rte_flow_item_etc eth;
67 struct rte_flow_item_vlan vlan;
68 struct rte_flow_item_ipv4 ipv4;
69 struct rte_flow *flow;
70 struct rte_flow_error error;
72 /* setting the eth to pass all packets */
73 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
74 pattern[0].spec = ð
76 /* set the vlan to pas all packets */
77 pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
78 pattern[1].spec = &vlan;
80 /* set the dst ipv4 packet to the required value */
81 ipv4.hdr.dst_addr = htonl(0xc0a80302);
82 pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4;
83 pattern[2].spec = &ipv4;
85 /* end the pattern array */
86 pattern[3].type = RTE_FLOW_ITEM)TYPE_END;
88 /* create the drop action */
89 actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
90 actions[1].type = RTE_FLOW_ACTION_TYPE_END;
92 /* validate and create the flow rule */
93 if (!rte_flow_validate(port_id, &attr, pattern, actions, &error)
94 flow = rte_flow_create(port_id, &attr, pattern, actions, &error)
99 Terminal 1: running sample app with the flow rule disabled::
101 ./filter-program disable
102 [waiting for packets]
104 Terminal 2: running scapy::
108 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \
109 iface='some interface', count=1)
110 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \
111 iface='some interface', count=1)
113 Terminal 1: output log::
115 received packet with src ip = 176.80.50.4
116 received packet with src ip = 176.80.50.5
118 Terminal 1: running sample the app flow rule enabled::
120 ./filter-program enabled
121 [waiting for packets]
123 Terminal 2: running scapy::
127 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \
128 iface='some interface', count=1)
129 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst ='192.168.3.2'), \
130 iface='some interface', count=1)
132 Terminal 1: output log::
134 received packet with src ip = 176.80.50.4
142 In this example we will create a simple rule that drops packets whose IPv4
143 destination is in the range 192.168.3.0 to 192.168.3.255. This is done using
146 This code is equivalent to the following testpmd command (wrapped for
149 tpmd> flow create 0 ingress pattern eth / vlan /
150 ipv4 dst spec 192.168.3.0 dst mask 255.255.255.0 /
151 end actions drop / end
158 struct rte_flow_attr attr = {.ingress = 1};
159 struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW];
160 struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW];
161 struct rte_flow_item_etc eth;
162 struct rte_flow_item_vlan vlan;
163 struct rte_flow_item_ipv4 ipv4;
164 struct rte_flow_item_ipv4 ipv4_mask;
165 struct rte_flow *flow;
166 struct rte_flow_error error;
168 /* setting the eth to pass all packets */
169 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
170 pattern[0].spec = ð
172 /* set the vlan to pas all packets */
173 pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
174 pattern[1].spec = &vlan;
176 /* set the dst ipv4 packet to the required value */
177 ipv4.hdr.dst_addr = htonl(0xc0a80300);
178 ipv4_mask.hdr.dst_addr = htonl(0xffffff00);
179 pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4;
180 pattern[2].spec = &ipv4;
181 pattern[2].mask = &ipv4_mask;
183 /* end the pattern array */
184 pattern[3].type = RTE_FLOW_ITEM)TYPE_END;
186 /* create the drop action */
187 actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
188 actions[1].type = RTE_FLOW_ACTION_TYPE_END;
190 /* validate and create the flow rule */
191 if (!rte_flow_validate(port_id, &attr, pattern, actions, &error)
192 flow = rte_flow_create(port_id, &attr, pattern, actions, &error)
197 Terminal 1: running sample app flow rule disabled::
199 ./filter-program disable
200 [waiting for packets]
202 Terminal 2: running scapy::
206 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \
207 iface='some interface', count=1)
208 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \
209 iface='some interface', count=1)
210 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.6', dst='192.168.5.2'), \
211 iface='some interface', count=1)
213 Terminal 1: output log::
215 received packet with src ip = 176.80.50.4
216 received packet with src ip = 176.80.50.5
217 received packet with src ip = 176.80.50.6
219 Terminal 1: running sample app flow rule enabled::
221 ./filter-program enabled
222 [waiting for packets]
224 Terminal 2: running scapy::
228 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \
229 iface='some interface', count=1)
230 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \
231 iface='some interface', count=1)
232 >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.6', dst='192.168.5.2'), \
233 iface='some interface', count=1)
235 Terminal 1: output log::
237 received packet with src ip = 176.80.50.6
245 In this example we will create a rule that routes all vlan id 123 to queue 3.
247 This code is equivalent to the following testpmd command (wrapped for
250 tpmd> flow create 0 ingress pattern eth / vlan vid spec 123 /
251 end actions queue index 3 / end
258 struct rte_flow_attr attr = {.ingress = 1};
259 struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW];
260 struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW];
261 struct rte_flow_item_etc eth;
262 struct rte_flow_item_vlan vlan;
263 struct rte_flow_action_queue queue = { .index = 3 };
264 struct rte_flow *flow;
265 struct rte_flow_error error;
267 /* setting the eth to pass all packets */
268 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
269 pattern[0].spec = ð
271 /* set the vlan to pas all packets */
273 pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
274 pattern[1].spec = &vlan;
276 /* end the pattern array */
277 pattern[2].type = RTE_FLOW_ITEM)TYPE_END;
279 /* create the drop action */
280 actions[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
281 actions[0].conf = &queue
282 actions[1].type = RTE_FLOW_ACTION_TYPE_END;
284 /* validate and create the flow rule */
285 if (!rte_flow_validate(port_id, &attr, pattern, actions, &error)
286 flow = rte_flow_create(port_id, &attr, pattern, actions, &error)
291 Terminal 1: running sample app flow rule disabled::
293 ./filter-program disable
294 [waiting for packets]
296 Terminal 2: running scapy::
300 >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.4', dst='192.168.3.1'), \
301 iface='some interface', count=1)
302 >> sendp(Ether()/Dot1Q(vlan=50)/IP(src='176.80.50.5', dst='192.168.3.2'), \
303 iface='some interface', count=1)
304 >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.6', dst='192.168.5.2'), \
305 iface='some interface', count=1)
307 Terminal 1: output log::
309 received packet with src ip = 176.80.50.4 sent to queue 2
310 received packet with src ip = 176.80.50.5 sent to queue 1
311 received packet with src ip = 176.80.50.6 sent to queue 0
313 Terminal 1: running sample app flow rule enabled::
315 ./filter-program enabled
316 [waiting for packets]
318 Terminal 2: running scapy::
322 >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.4', dst='192.168.3.1'), \
323 iface='some interface', count=1)
324 >> sendp(Ether()/Dot1Q(vlan=50)/IP(src='176.80.50.5', dst='192.168.3.2'), \
325 iface='some interface', count=1)
326 >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.6', dst='192.168.5.2'), \
327 iface='some interface', count=1)
329 Terminal 1: output log::
331 received packet with src ip = 176.80.50.4 sent to queue 3
332 received packet with src ip = 176.80.50.5 sent to queue 1
333 received packet with src ip = 176.80.50.6 sent to queue 3