New upstream version 17.11-rc3
[deb_dpdk.git] / doc / guides / howto / rte_flow.rst
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
32 Generic flow API - examples
33 ===========================
34
35 This document demonstrates some concrete examples for programming flow rules
36 with 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
44 Simple IPv4 drop
45 ----------------
46
47 Description
48 ~~~~~~~~~~~
49
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)::
53
54   tpmd> flow create 0 ingress pattern eth / vlan /
55                     ipv4 dst is 192.168.3.2 / end actions drop / end
56
57 Code
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
96 Output
97 ~~~~~~
98
99 Terminal 1: running sample app with the flow rule disabled::
100
101   ./filter-program disable
102   [waiting for packets]
103
104 Terminal 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
113 Terminal 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
118 Terminal 1: running sample the app flow rule enabled::
119
120   ./filter-program enabled
121   [waiting for packets]
122
123 Terminal 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
132 Terminal 1: output log::
133
134   received packet with src ip = 176.80.50.4
135
136 Range IPv4 drop
137 ----------------
138
139 Description
140 ~~~~~~~~~~~
141
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
144 a mask.
145
146 This code is equivalent to the following testpmd command (wrapped for
147 clarity)::
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
153 Code
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
194 Output
195 ~~~~~~
196
197 Terminal 1: running sample app flow rule disabled::
198
199   ./filter-program disable
200   [waiting for packets]
201
202 Terminal 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
213 Terminal 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
219 Terminal 1: running sample app flow rule enabled::
220
221   ./filter-program enabled
222   [waiting for packets]
223
224 Terminal 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
235 Terminal 1: output log::
236
237   received packet with src ip = 176.80.50.6
238
239 Send vlan to queue
240 ------------------
241
242 Description
243 ~~~~~~~~~~~
244
245 In this example we will create a rule that routes all vlan id 123 to queue 3.
246
247 This code is equivalent to the following testpmd command (wrapped for
248 clarity)::
249
250   tpmd> flow create 0 ingress pattern eth / vlan vid spec 123 /
251                     end actions queue index 3 / end
252
253 Code
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
288 Output
289 ~~~~~~
290
291 Terminal 1: running sample app flow rule disabled::
292
293   ./filter-program disable
294   [waiting for packets]
295
296 Terminal 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
307 Terminal 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
313 Terminal 1: running sample app flow rule enabled::
314
315   ./filter-program enabled
316   [waiting for packets]
317
318 Terminal 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
329 Terminal 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