New upstream version 18.11-rc1
[deb_dpdk.git] / doc / guides / howto / rte_flow.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright 2017 Mellanox Technologies, Ltd
3
4 Generic flow API - examples
5 ===========================
6
7 This document demonstrates some concrete examples for programming flow rules
8 with the ``rte_flow`` APIs.
9
10 * Detail of the rte_flow APIs can be found in the following link:
11   :ref:`Generic flow API <Generic_flow_API>` .
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
16 Simple IPv4 drop
17 ----------------
18
19 Description
20 ~~~~~~~~~~~
21
22 In this example we will create a simple rule that drops packets whose IPv4
23 destination equals 192.168.3.2. This code is equivalent to the following
24 testpmd command (wrapped for clarity)::
25
26   tpmd> flow create 0 ingress pattern eth / vlan /
27                     ipv4 dst is 192.168.3.2 / end actions drop / end
28
29 Code
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 pas 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
68 Output
69 ~~~~~~
70
71 Terminal 1: running sample app with the flow rule disabled::
72
73   ./filter-program disable
74   [waiting for packets]
75
76 Terminal 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
85 Terminal 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
90 Terminal 1: running sample the app flow rule enabled::
91
92   ./filter-program enabled
93   [waiting for packets]
94
95 Terminal 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
104 Terminal 1: output log::
105
106   received packet with src ip = 176.80.50.4
107
108 Range IPv4 drop
109 ----------------
110
111 Description
112 ~~~~~~~~~~~
113
114 In this example we will create a simple rule that drops packets whose IPv4
115 destination is in the range 192.168.3.0 to 192.168.3.255. This is done using
116 a mask.
117
118 This code is equivalent to the following testpmd command (wrapped for
119 clarity)::
120
121   tpmd> 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
125 Code
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 pas 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
166 Output
167 ~~~~~~
168
169 Terminal 1: running sample app flow rule disabled::
170
171   ./filter-program disable
172   [waiting for packets]
173
174 Terminal 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
185 Terminal 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
191 Terminal 1: running sample app flow rule enabled::
192
193   ./filter-program enabled
194   [waiting for packets]
195
196 Terminal 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
207 Terminal 1: output log::
208
209   received packet with src ip = 176.80.50.6
210
211 Send vlan to queue
212 ------------------
213
214 Description
215 ~~~~~~~~~~~
216
217 In this example we will create a rule that routes all vlan id 123 to queue 3.
218
219 This code is equivalent to the following testpmd command (wrapped for
220 clarity)::
221
222   tpmd> flow create 0 ingress pattern eth / vlan vid spec 123 /
223                     end actions queue index 3 / end
224
225 Code
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
260 Output
261 ~~~~~~
262
263 Terminal 1: running sample app flow rule disabled::
264
265   ./filter-program disable
266   [waiting for packets]
267
268 Terminal 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
279 Terminal 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
285 Terminal 1: running sample app flow rule enabled::
286
287   ./filter-program enabled
288   [waiting for packets]
289
290 Terminal 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
301 Terminal 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