xref: /dpdk/doc/guides/howto/rte_flow.rst (revision 41dd9a6bc2d9c6e20e139ad713cc9d172572dd43)
1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright 2017 Mellanox Technologies, Ltd
3
4Generic flow API - examples
5===========================
6
7This document demonstrates some concrete examples for programming flow rules
8with the ``rte_flow`` APIs.
9
10* Detail of the rte_flow APIs can be found in the following link:
11  :doc:`../prog_guide/ethdev/flow_offload`.
12
13* Details of the TestPMD commands to set the flow rules can be found in the
14  following link: :ref:`TestPMD Flow rules <testpmd_rte_flow>`
15
16Simple IPv4 drop
17----------------
18
19Description
20~~~~~~~~~~~
21
22In this example we will create a simple rule that drops packets whose IPv4
23destination equals 192.168.3.2. This code is equivalent to the following
24testpmd command (wrapped for clarity)::
25
26  testpmd> flow create 0 ingress pattern eth / vlan /
27                    ipv4 dst is 192.168.3.2 / end actions drop / end
28
29Code
30~~~~
31
32.. code-block:: c
33
34  /* create the attribute structure */
35  struct rte_flow_attr attr = { .ingress = 1 };
36  struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW];
37  struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW];
38  struct rte_flow_item_eth eth;
39  struct rte_flow_item_vlan vlan;
40  struct rte_flow_item_ipv4 ipv4;
41  struct rte_flow *flow;
42  struct rte_flow_error error;
43
44  /* setting the eth to pass all packets */
45  pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
46  pattern[0].spec = &eth;
47
48  /* set the vlan to pass all packets */
49  pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
50  pattern[1].spec = &vlan;
51
52  /* set the dst ipv4 packet to the required value */
53  ipv4.hdr.dst_addr = htonl(0xc0a80302);
54  pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4;
55  pattern[2].spec = &ipv4;
56
57  /* end the pattern array */
58  pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
59
60  /* create the drop action */
61  actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
62  actions[1].type = RTE_FLOW_ACTION_TYPE_END;
63
64  /* validate and create the flow rule */
65  if (!rte_flow_validate(port_id, &attr, pattern, actions, &error))
66      flow = rte_flow_create(port_id, &attr, pattern, actions, &error);
67
68Output
69~~~~~~
70
71Terminal 1: running sample app with the flow rule disabled::
72
73  ./filter-program disable
74  [waiting for packets]
75
76Terminal 2: running scapy::
77
78  $scapy
79  welcome to Scapy
80  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \
81           iface='some interface', count=1)
82  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \
83           iface='some interface', count=1)
84
85Terminal 1: output log::
86
87  received packet with src ip = 176.80.50.4
88  received packet with src ip = 176.80.50.5
89
90Terminal 1: running sample the app flow rule enabled::
91
92  ./filter-program enabled
93  [waiting for packets]
94
95Terminal 2: running scapy::
96
97  $scapy
98  welcome to Scapy
99  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'),  \
100           iface='some interface', count=1)
101  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst ='192.168.3.2'), \
102           iface='some interface', count=1)
103
104Terminal 1: output log::
105
106  received packet with src ip = 176.80.50.4
107
108Range IPv4 drop
109----------------
110
111Description
112~~~~~~~~~~~
113
114In this example we will create a simple rule that drops packets whose IPv4
115destination is in the range 192.168.3.0 to 192.168.3.255. This is done using
116a mask.
117
118This code is equivalent to the following testpmd command (wrapped for
119clarity)::
120
121  testpmd> flow create 0 ingress pattern eth / vlan /
122                    ipv4 dst spec 192.168.3.0 dst mask 255.255.255.0 /
123                    end actions drop / end
124
125Code
126~~~~
127
128.. code-block:: c
129
130  struct rte_flow_attr attr = {.ingress = 1};
131  struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW];
132  struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW];
133  struct rte_flow_item_eth eth;
134  struct rte_flow_item_vlan vlan;
135  struct rte_flow_item_ipv4 ipv4;
136  struct rte_flow_item_ipv4 ipv4_mask;
137  struct rte_flow *flow;
138  struct rte_flow_error error;
139
140  /* setting the eth to pass all packets */
141  pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
142  pattern[0].spec = &eth;
143
144  /* set the vlan to pass all packets */
145  pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
146  pattern[1].spec = &vlan;
147
148  /* set the dst ipv4 packet to the required value */
149  ipv4.hdr.dst_addr = htonl(0xc0a80300);
150  ipv4_mask.hdr.dst_addr = htonl(0xffffff00);
151  pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4;
152  pattern[2].spec = &ipv4;
153  pattern[2].mask = &ipv4_mask;
154
155  /* end the pattern array */
156  pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
157
158  /* create the drop action */
159  actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
160  actions[1].type = RTE_FLOW_ACTION_TYPE_END;
161
162  /* validate and create the flow rule */
163  if (!rte_flow_validate(port_id, &attr, pattern, actions, &error))
164      flow = rte_flow_create(port_id, &attr, pattern, actions, &error);
165
166Output
167~~~~~~
168
169Terminal 1: running sample app flow rule disabled::
170
171  ./filter-program disable
172  [waiting for packets]
173
174Terminal 2: running scapy::
175
176  $scapy
177  welcome to Scapy
178  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \
179           iface='some interface', count=1)
180  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \
181           iface='some interface', count=1)
182  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.6', dst='192.168.5.2'), \
183           iface='some interface', count=1)
184
185Terminal 1: output log::
186
187  received packet with src ip = 176.80.50.4
188  received packet with src ip = 176.80.50.5
189  received packet with src ip = 176.80.50.6
190
191Terminal 1: running sample app flow rule enabled::
192
193  ./filter-program enabled
194  [waiting for packets]
195
196Terminal 2: running scapy::
197
198  $scapy
199  welcome to Scapy
200  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \
201           iface='some interface', count=1)
202  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \
203           iface='some interface', count=1)
204  >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.6', dst='192.168.5.2'), \
205           iface='some interface', count=1)
206
207Terminal 1: output log::
208
209  received packet with src ip = 176.80.50.6
210
211Send vlan to queue
212------------------
213
214Description
215~~~~~~~~~~~
216
217In this example we will create a rule that routes all vlan id 123 to queue 3.
218
219This code is equivalent to the following testpmd command (wrapped for
220clarity)::
221
222  testpmd> flow create 0 ingress pattern eth / vlan vid spec 123 /
223                    end actions queue index 3 / end
224
225Code
226~~~~
227
228.. code-block:: c
229
230  struct rte_flow_attr attr = { .ingress = 1 };
231  struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW];
232  struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW];
233  struct rte_flow_item_eth eth;
234  struct rte_flow_item_vlan vlan;
235  struct rte_flow_action_queue queue = { .index = 3 };
236  struct rte_flow *flow;
237  struct rte_flow_error error;
238
239  /* setting the eth to pass all packets */
240  pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
241  pattern[0].spec = &eth;
242
243  /* set the vlan to pas all packets */
244  vlan.vid = 123;
245  pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN;
246  pattern[1].spec = &vlan;
247
248  /* end the pattern array */
249  pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
250
251  /* create the queue action */
252  actions[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
253  actions[0].conf = &queue;
254  actions[1].type = RTE_FLOW_ACTION_TYPE_END;
255
256  /* validate and create the flow rule */
257  if (!rte_flow_validate(port_id, &attr, pattern, actions, &error))
258      flow = rte_flow_create(port_id, &attr, pattern, actions, &error);
259
260Output
261~~~~~~
262
263Terminal 1: running sample app flow rule disabled::
264
265  ./filter-program disable
266  [waiting for packets]
267
268Terminal 2: running scapy::
269
270  $scapy
271  welcome to Scapy
272  >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.4', dst='192.168.3.1'), \
273           iface='some interface', count=1)
274  >> sendp(Ether()/Dot1Q(vlan=50)/IP(src='176.80.50.5', dst='192.168.3.2'),  \
275           iface='some interface', count=1)
276  >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.6', dst='192.168.5.2'), \
277           iface='some interface', count=1)
278
279Terminal 1: output log::
280
281  received packet with src ip = 176.80.50.4 sent to queue 2
282  received packet with src ip = 176.80.50.5 sent to queue 1
283  received packet with src ip = 176.80.50.6 sent to queue 0
284
285Terminal 1: running sample app flow rule enabled::
286
287  ./filter-program enabled
288  [waiting for packets]
289
290Terminal 2: running scapy::
291
292  $scapy
293  welcome to Scapy
294  >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.4', dst='192.168.3.1'), \
295           iface='some interface', count=1)
296  >> sendp(Ether()/Dot1Q(vlan=50)/IP(src='176.80.50.5', dst='192.168.3.2'),  \
297           iface='some interface', count=1)
298  >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.6', dst='192.168.5.2'), \
299           iface='some interface', count=1)
300
301Terminal 1: output log::
302
303  received packet with src ip = 176.80.50.4 sent to queue 3
304  received packet with src ip = 176.80.50.5 sent to queue 1
305  received packet with src ip = 176.80.50.6 sent to queue 3
306