xref: /dpdk/doc/guides/howto/rte_flow.rst (revision 3e0ceb9f17fff027fc6c8f18de35e11719ffa61e)
1..  BSD LICENSE
2    Copyright(c) 2017 Mellanox Corporation. All rights reserved.
3    All rights reserved.
4
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8
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
14    distribution.
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.
18
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.
30
31
32Generic flow API - examples
33===========================
34
35This document demonstrates some concrete examples for programming flow rules
36with the ``rte_flow`` APIs.
37
38* Detail of the rte_flow APIs can be found in the following link:
39  :ref:`Generic flow API <Generic_flow_API>` .
40
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>`
43
44Simple IPv4 drop
45----------------
46
47Description
48~~~~~~~~~~~
49
50In this example we will create a simple rule that drops packets whose IPv4
51destination equals 192.168.3.2. This code is equivalent to the following
52testpmd command (wrapped for clarity)::
53
54  tpmd> flow create 0 ingress pattern eth / vlan /
55                    ipv4 dst is 192.168.3.2 / end actions drop / end
56
57Code
58~~~~
59
60.. code-block:: c
61
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;
71
72  /* setting the eth to pass all packets */
73  pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
74  pattern[0].spec = &eth;
75
76  /* set the vlan to pas all packets */
77  pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
78  pattern[1].spec = &vlan;
79
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;
84
85  /* end the pattern array */
86  pattern[3].type = RTE_FLOW_ITEM)TYPE_END;
87
88  /* create the drop action */
89  actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
90  actions[1].type = RTE_FLOW_ACTION_TYPE_END;
91
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)
95
96Output
97~~~~~~
98
99Terminal 1: running sample app with the flow rule disabled::
100
101  ./filter-program disable
102  [waiting for packets]
103
104Terminal 2: running scapy::
105
106  $scapy
107  welcome to 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)
112
113Terminal 1: output log::
114
115  received packet with src ip = 176.80.50.4
116  received packet with src ip = 176.80.50.5
117
118Terminal 1: running sample the app flow rule enabled::
119
120  ./filter-program enabled
121  [waiting for packets]
122
123Terminal 2: running scapy::
124
125  $scapy
126  welcome to 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)
131
132Terminal 1: output log::
133
134  received packet with src ip = 176.80.50.4
135
136Range IPv4 drop
137----------------
138
139Description
140~~~~~~~~~~~
141
142In this example we will create a simple rule that drops packets whose IPv4
143destination is in the range 192.168.3.0 to 192.168.3.255. This is done using
144a mask.
145
146This code is equivalent to the following testpmd command (wrapped for
147clarity)::
148
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
152
153Code
154~~~~
155
156.. code-block:: c
157
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;
167
168  /* setting the eth to pass all packets */
169  pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
170  pattern[0].spec = &eth;
171
172  /* set the vlan to pas all packets */
173  pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
174  pattern[1].spec = &vlan;
175
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;
182
183  /* end the pattern array */
184  pattern[3].type = RTE_FLOW_ITEM)TYPE_END;
185
186  /* create the drop action */
187  actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
188  actions[1].type = RTE_FLOW_ACTION_TYPE_END;
189
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)
193
194Output
195~~~~~~
196
197Terminal 1: running sample app flow rule disabled::
198
199  ./filter-program disable
200  [waiting for packets]
201
202Terminal 2: running scapy::
203
204  $scapy
205  welcome to 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)
212
213Terminal 1: output log::
214
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
218
219Terminal 1: running sample app flow rule enabled::
220
221  ./filter-program enabled
222  [waiting for packets]
223
224Terminal 2: running scapy::
225
226  $scapy
227  welcome to 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)
234
235Terminal 1: output log::
236
237  received packet with src ip = 176.80.50.6
238
239Send vlan to queue
240------------------
241
242Description
243~~~~~~~~~~~
244
245In this example we will create a rule that routes all vlan id 123 to queue 3.
246
247This code is equivalent to the following testpmd command (wrapped for
248clarity)::
249
250  tpmd> flow create 0 ingress pattern eth / vlan vid spec 123 /
251                    end actions queue index 3 / end
252
253Code
254~~~~
255
256.. code-block:: c
257
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;
266
267  /* setting the eth to pass all packets */
268  pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
269  pattern[0].spec = &eth;
270
271  /* set the vlan to pas all packets */
272  vlan.vid = 123;
273  pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
274  pattern[1].spec = &vlan;
275
276  /* end the pattern array */
277  pattern[2].type = RTE_FLOW_ITEM)TYPE_END;
278
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;
283
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)
287
288Output
289~~~~~~
290
291Terminal 1: running sample app flow rule disabled::
292
293  ./filter-program disable
294  [waiting for packets]
295
296Terminal 2: running scapy::
297
298  $scapy
299  welcome to 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)
306
307Terminal 1: output log::
308
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
312
313Terminal 1: running sample app flow rule enabled::
314
315  ./filter-program enabled
316  [waiting for packets]
317
318Terminal 2: running scapy::
319
320  $scapy
321  welcome to 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)
328
329Terminal 1: output log::
330
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
334