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