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 = ð 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 = ð 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 = ð 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