1ea9382dcSThomas Monjalon.. SPDX-License-Identifier: BSD-3-Clause 2ea9382dcSThomas Monjalon Copyright 2017 Mellanox Technologies, Ltd 33e0ceb9fSOri Kam 43e0ceb9fSOri KamGeneric flow API - examples 53e0ceb9fSOri Kam=========================== 63e0ceb9fSOri Kam 73e0ceb9fSOri KamThis document demonstrates some concrete examples for programming flow rules 83e0ceb9fSOri Kamwith the ``rte_flow`` APIs. 93e0ceb9fSOri Kam 103e0ceb9fSOri Kam* Detail of the rte_flow APIs can be found in the following link: 11*41dd9a6bSDavid Young :doc:`../prog_guide/ethdev/flow_offload`. 123e0ceb9fSOri Kam 133e0ceb9fSOri Kam* Details of the TestPMD commands to set the flow rules can be found in the 143e0ceb9fSOri Kam following link: :ref:`TestPMD Flow rules <testpmd_rte_flow>` 153e0ceb9fSOri Kam 163e0ceb9fSOri KamSimple IPv4 drop 173e0ceb9fSOri Kam---------------- 183e0ceb9fSOri Kam 193e0ceb9fSOri KamDescription 203e0ceb9fSOri Kam~~~~~~~~~~~ 213e0ceb9fSOri Kam 223e0ceb9fSOri KamIn this example we will create a simple rule that drops packets whose IPv4 233e0ceb9fSOri Kamdestination equals 192.168.3.2. This code is equivalent to the following 243e0ceb9fSOri Kamtestpmd command (wrapped for clarity):: 253e0ceb9fSOri Kam 26d629b7b5SJohn McNamara testpmd> flow create 0 ingress pattern eth / vlan / 273e0ceb9fSOri Kam ipv4 dst is 192.168.3.2 / end actions drop / end 283e0ceb9fSOri Kam 293e0ceb9fSOri KamCode 303e0ceb9fSOri Kam~~~~ 313e0ceb9fSOri Kam 323e0ceb9fSOri Kam.. code-block:: c 333e0ceb9fSOri Kam 343e0ceb9fSOri Kam /* create the attribute structure */ 353e0ceb9fSOri Kam struct rte_flow_attr attr = { .ingress = 1 }; 363e0ceb9fSOri Kam struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW]; 373e0ceb9fSOri Kam struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW]; 38293a649cSIlya Maximets struct rte_flow_item_eth eth; 393e0ceb9fSOri Kam struct rte_flow_item_vlan vlan; 403e0ceb9fSOri Kam struct rte_flow_item_ipv4 ipv4; 413e0ceb9fSOri Kam struct rte_flow *flow; 423e0ceb9fSOri Kam struct rte_flow_error error; 433e0ceb9fSOri Kam 443e0ceb9fSOri Kam /* setting the eth to pass all packets */ 453e0ceb9fSOri Kam pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; 463e0ceb9fSOri Kam pattern[0].spec = ð 473e0ceb9fSOri Kam 48bbf708e5SXiaolong Ye /* set the vlan to pass all packets */ 493e0ceb9fSOri Kam pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN; 503e0ceb9fSOri Kam pattern[1].spec = &vlan; 513e0ceb9fSOri Kam 523e0ceb9fSOri Kam /* set the dst ipv4 packet to the required value */ 533e0ceb9fSOri Kam ipv4.hdr.dst_addr = htonl(0xc0a80302); 543e0ceb9fSOri Kam pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4; 553e0ceb9fSOri Kam pattern[2].spec = &ipv4; 563e0ceb9fSOri Kam 573e0ceb9fSOri Kam /* end the pattern array */ 58293a649cSIlya Maximets pattern[3].type = RTE_FLOW_ITEM_TYPE_END; 593e0ceb9fSOri Kam 603e0ceb9fSOri Kam /* create the drop action */ 613e0ceb9fSOri Kam actions[0].type = RTE_FLOW_ACTION_TYPE_DROP; 623e0ceb9fSOri Kam actions[1].type = RTE_FLOW_ACTION_TYPE_END; 633e0ceb9fSOri Kam 643e0ceb9fSOri Kam /* validate and create the flow rule */ 651334586bSIlya Maximets if (!rte_flow_validate(port_id, &attr, pattern, actions, &error)) 661334586bSIlya Maximets flow = rte_flow_create(port_id, &attr, pattern, actions, &error); 673e0ceb9fSOri Kam 683e0ceb9fSOri KamOutput 693e0ceb9fSOri Kam~~~~~~ 703e0ceb9fSOri Kam 713e0ceb9fSOri KamTerminal 1: running sample app with the flow rule disabled:: 723e0ceb9fSOri Kam 733e0ceb9fSOri Kam ./filter-program disable 743e0ceb9fSOri Kam [waiting for packets] 753e0ceb9fSOri Kam 763e0ceb9fSOri KamTerminal 2: running scapy:: 773e0ceb9fSOri Kam 783e0ceb9fSOri Kam $scapy 793e0ceb9fSOri Kam welcome to Scapy 803e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \ 813e0ceb9fSOri Kam iface='some interface', count=1) 823e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \ 833e0ceb9fSOri Kam iface='some interface', count=1) 843e0ceb9fSOri Kam 853e0ceb9fSOri KamTerminal 1: output log:: 863e0ceb9fSOri Kam 873e0ceb9fSOri Kam received packet with src ip = 176.80.50.4 883e0ceb9fSOri Kam received packet with src ip = 176.80.50.5 893e0ceb9fSOri Kam 903e0ceb9fSOri KamTerminal 1: running sample the app flow rule enabled:: 913e0ceb9fSOri Kam 923e0ceb9fSOri Kam ./filter-program enabled 933e0ceb9fSOri Kam [waiting for packets] 943e0ceb9fSOri Kam 953e0ceb9fSOri KamTerminal 2: running scapy:: 963e0ceb9fSOri Kam 973e0ceb9fSOri Kam $scapy 983e0ceb9fSOri Kam welcome to Scapy 993e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \ 1003e0ceb9fSOri Kam iface='some interface', count=1) 1013e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst ='192.168.3.2'), \ 1023e0ceb9fSOri Kam iface='some interface', count=1) 1033e0ceb9fSOri Kam 1043e0ceb9fSOri KamTerminal 1: output log:: 1053e0ceb9fSOri Kam 1063e0ceb9fSOri Kam received packet with src ip = 176.80.50.4 1073e0ceb9fSOri Kam 1083e0ceb9fSOri KamRange IPv4 drop 1093e0ceb9fSOri Kam---------------- 1103e0ceb9fSOri Kam 1113e0ceb9fSOri KamDescription 1123e0ceb9fSOri Kam~~~~~~~~~~~ 1133e0ceb9fSOri Kam 1143e0ceb9fSOri KamIn this example we will create a simple rule that drops packets whose IPv4 1153e0ceb9fSOri Kamdestination is in the range 192.168.3.0 to 192.168.3.255. This is done using 1163e0ceb9fSOri Kama mask. 1173e0ceb9fSOri Kam 1183e0ceb9fSOri KamThis code is equivalent to the following testpmd command (wrapped for 1193e0ceb9fSOri Kamclarity):: 1203e0ceb9fSOri Kam 121d629b7b5SJohn McNamara testpmd> flow create 0 ingress pattern eth / vlan / 1223e0ceb9fSOri Kam ipv4 dst spec 192.168.3.0 dst mask 255.255.255.0 / 1233e0ceb9fSOri Kam end actions drop / end 1243e0ceb9fSOri Kam 1253e0ceb9fSOri KamCode 1263e0ceb9fSOri Kam~~~~ 1273e0ceb9fSOri Kam 1283e0ceb9fSOri Kam.. code-block:: c 1293e0ceb9fSOri Kam 1303e0ceb9fSOri Kam struct rte_flow_attr attr = {.ingress = 1}; 1313e0ceb9fSOri Kam struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW]; 1323e0ceb9fSOri Kam struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW]; 133293a649cSIlya Maximets struct rte_flow_item_eth eth; 1343e0ceb9fSOri Kam struct rte_flow_item_vlan vlan; 1353e0ceb9fSOri Kam struct rte_flow_item_ipv4 ipv4; 1363e0ceb9fSOri Kam struct rte_flow_item_ipv4 ipv4_mask; 1373e0ceb9fSOri Kam struct rte_flow *flow; 1383e0ceb9fSOri Kam struct rte_flow_error error; 1393e0ceb9fSOri Kam 1403e0ceb9fSOri Kam /* setting the eth to pass all packets */ 1413e0ceb9fSOri Kam pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; 1423e0ceb9fSOri Kam pattern[0].spec = ð 1433e0ceb9fSOri Kam 144bbf708e5SXiaolong Ye /* set the vlan to pass all packets */ 1453e0ceb9fSOri Kam pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN; 1463e0ceb9fSOri Kam pattern[1].spec = &vlan; 1473e0ceb9fSOri Kam 1483e0ceb9fSOri Kam /* set the dst ipv4 packet to the required value */ 1493e0ceb9fSOri Kam ipv4.hdr.dst_addr = htonl(0xc0a80300); 1503e0ceb9fSOri Kam ipv4_mask.hdr.dst_addr = htonl(0xffffff00); 1513e0ceb9fSOri Kam pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4; 1523e0ceb9fSOri Kam pattern[2].spec = &ipv4; 1533e0ceb9fSOri Kam pattern[2].mask = &ipv4_mask; 1543e0ceb9fSOri Kam 1553e0ceb9fSOri Kam /* end the pattern array */ 156293a649cSIlya Maximets pattern[3].type = RTE_FLOW_ITEM_TYPE_END; 1573e0ceb9fSOri Kam 1583e0ceb9fSOri Kam /* create the drop action */ 1593e0ceb9fSOri Kam actions[0].type = RTE_FLOW_ACTION_TYPE_DROP; 1603e0ceb9fSOri Kam actions[1].type = RTE_FLOW_ACTION_TYPE_END; 1613e0ceb9fSOri Kam 1623e0ceb9fSOri Kam /* validate and create the flow rule */ 1631334586bSIlya Maximets if (!rte_flow_validate(port_id, &attr, pattern, actions, &error)) 1641334586bSIlya Maximets flow = rte_flow_create(port_id, &attr, pattern, actions, &error); 1653e0ceb9fSOri Kam 1663e0ceb9fSOri KamOutput 1673e0ceb9fSOri Kam~~~~~~ 1683e0ceb9fSOri Kam 1693e0ceb9fSOri KamTerminal 1: running sample app flow rule disabled:: 1703e0ceb9fSOri Kam 1713e0ceb9fSOri Kam ./filter-program disable 1723e0ceb9fSOri Kam [waiting for packets] 1733e0ceb9fSOri Kam 1743e0ceb9fSOri KamTerminal 2: running scapy:: 1753e0ceb9fSOri Kam 1763e0ceb9fSOri Kam $scapy 1773e0ceb9fSOri Kam welcome to Scapy 1783e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \ 1793e0ceb9fSOri Kam iface='some interface', count=1) 1803e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \ 1813e0ceb9fSOri Kam iface='some interface', count=1) 1823e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.6', dst='192.168.5.2'), \ 1833e0ceb9fSOri Kam iface='some interface', count=1) 1843e0ceb9fSOri Kam 1853e0ceb9fSOri KamTerminal 1: output log:: 1863e0ceb9fSOri Kam 1873e0ceb9fSOri Kam received packet with src ip = 176.80.50.4 1883e0ceb9fSOri Kam received packet with src ip = 176.80.50.5 1893e0ceb9fSOri Kam received packet with src ip = 176.80.50.6 1903e0ceb9fSOri Kam 1913e0ceb9fSOri KamTerminal 1: running sample app flow rule enabled:: 1923e0ceb9fSOri Kam 1933e0ceb9fSOri Kam ./filter-program enabled 1943e0ceb9fSOri Kam [waiting for packets] 1953e0ceb9fSOri Kam 1963e0ceb9fSOri KamTerminal 2: running scapy:: 1973e0ceb9fSOri Kam 1983e0ceb9fSOri Kam $scapy 1993e0ceb9fSOri Kam welcome to Scapy 2003e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.4', dst='192.168.3.1'), \ 2013e0ceb9fSOri Kam iface='some interface', count=1) 2023e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.5', dst='192.168.3.2'), \ 2033e0ceb9fSOri Kam iface='some interface', count=1) 2043e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q()/IP(src='176.80.50.6', dst='192.168.5.2'), \ 2053e0ceb9fSOri Kam iface='some interface', count=1) 2063e0ceb9fSOri Kam 2073e0ceb9fSOri KamTerminal 1: output log:: 2083e0ceb9fSOri Kam 2093e0ceb9fSOri Kam received packet with src ip = 176.80.50.6 2103e0ceb9fSOri Kam 2113e0ceb9fSOri KamSend vlan to queue 2123e0ceb9fSOri Kam------------------ 2133e0ceb9fSOri Kam 2143e0ceb9fSOri KamDescription 2153e0ceb9fSOri Kam~~~~~~~~~~~ 2163e0ceb9fSOri Kam 2173e0ceb9fSOri KamIn this example we will create a rule that routes all vlan id 123 to queue 3. 2183e0ceb9fSOri Kam 2193e0ceb9fSOri KamThis code is equivalent to the following testpmd command (wrapped for 2203e0ceb9fSOri Kamclarity):: 2213e0ceb9fSOri Kam 222d629b7b5SJohn McNamara testpmd> flow create 0 ingress pattern eth / vlan vid spec 123 / 2233e0ceb9fSOri Kam end actions queue index 3 / end 2243e0ceb9fSOri Kam 2253e0ceb9fSOri KamCode 2263e0ceb9fSOri Kam~~~~ 2273e0ceb9fSOri Kam 2283e0ceb9fSOri Kam.. code-block:: c 2293e0ceb9fSOri Kam 2303e0ceb9fSOri Kam struct rte_flow_attr attr = { .ingress = 1 }; 2313e0ceb9fSOri Kam struct rte_flow_item pattern[MAX_PATTERN_IN_FLOW]; 2323e0ceb9fSOri Kam struct rte_flow_action actions[MAX_ACTIONS_IN_FLOW]; 233293a649cSIlya Maximets struct rte_flow_item_eth eth; 2343e0ceb9fSOri Kam struct rte_flow_item_vlan vlan; 2353e0ceb9fSOri Kam struct rte_flow_action_queue queue = { .index = 3 }; 2363e0ceb9fSOri Kam struct rte_flow *flow; 2373e0ceb9fSOri Kam struct rte_flow_error error; 2383e0ceb9fSOri Kam 2393e0ceb9fSOri Kam /* setting the eth to pass all packets */ 2403e0ceb9fSOri Kam pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; 2413e0ceb9fSOri Kam pattern[0].spec = ð 2423e0ceb9fSOri Kam 2433e0ceb9fSOri Kam /* set the vlan to pas all packets */ 2443e0ceb9fSOri Kam vlan.vid = 123; 2453e0ceb9fSOri Kam pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN; 2463e0ceb9fSOri Kam pattern[1].spec = &vlan; 2473e0ceb9fSOri Kam 2483e0ceb9fSOri Kam /* end the pattern array */ 249293a649cSIlya Maximets pattern[2].type = RTE_FLOW_ITEM_TYPE_END; 2503e0ceb9fSOri Kam 251d80e42ccSJerin Jacob /* create the queue action */ 2523e0ceb9fSOri Kam actions[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; 2531334586bSIlya Maximets actions[0].conf = &queue; 2543e0ceb9fSOri Kam actions[1].type = RTE_FLOW_ACTION_TYPE_END; 2553e0ceb9fSOri Kam 2563e0ceb9fSOri Kam /* validate and create the flow rule */ 2571334586bSIlya Maximets if (!rte_flow_validate(port_id, &attr, pattern, actions, &error)) 2581334586bSIlya Maximets flow = rte_flow_create(port_id, &attr, pattern, actions, &error); 2593e0ceb9fSOri Kam 2603e0ceb9fSOri KamOutput 2613e0ceb9fSOri Kam~~~~~~ 2623e0ceb9fSOri Kam 2633e0ceb9fSOri KamTerminal 1: running sample app flow rule disabled:: 2643e0ceb9fSOri Kam 2653e0ceb9fSOri Kam ./filter-program disable 2663e0ceb9fSOri Kam [waiting for packets] 2673e0ceb9fSOri Kam 2683e0ceb9fSOri KamTerminal 2: running scapy:: 2693e0ceb9fSOri Kam 2703e0ceb9fSOri Kam $scapy 2713e0ceb9fSOri Kam welcome to Scapy 2723e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.4', dst='192.168.3.1'), \ 2733e0ceb9fSOri Kam iface='some interface', count=1) 2743e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q(vlan=50)/IP(src='176.80.50.5', dst='192.168.3.2'), \ 2753e0ceb9fSOri Kam iface='some interface', count=1) 2763e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.6', dst='192.168.5.2'), \ 2773e0ceb9fSOri Kam iface='some interface', count=1) 2783e0ceb9fSOri Kam 2793e0ceb9fSOri KamTerminal 1: output log:: 2803e0ceb9fSOri Kam 2813e0ceb9fSOri Kam received packet with src ip = 176.80.50.4 sent to queue 2 2823e0ceb9fSOri Kam received packet with src ip = 176.80.50.5 sent to queue 1 2833e0ceb9fSOri Kam received packet with src ip = 176.80.50.6 sent to queue 0 2843e0ceb9fSOri Kam 2853e0ceb9fSOri KamTerminal 1: running sample app flow rule enabled:: 2863e0ceb9fSOri Kam 2873e0ceb9fSOri Kam ./filter-program enabled 2883e0ceb9fSOri Kam [waiting for packets] 2893e0ceb9fSOri Kam 2903e0ceb9fSOri KamTerminal 2: running scapy:: 2913e0ceb9fSOri Kam 2923e0ceb9fSOri Kam $scapy 2933e0ceb9fSOri Kam welcome to Scapy 2943e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.4', dst='192.168.3.1'), \ 2953e0ceb9fSOri Kam iface='some interface', count=1) 2963e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q(vlan=50)/IP(src='176.80.50.5', dst='192.168.3.2'), \ 2973e0ceb9fSOri Kam iface='some interface', count=1) 2983e0ceb9fSOri Kam >> sendp(Ether()/Dot1Q(vlan=123)/IP(src='176.80.50.6', dst='192.168.5.2'), \ 2993e0ceb9fSOri Kam iface='some interface', count=1) 3003e0ceb9fSOri Kam 3013e0ceb9fSOri KamTerminal 1: output log:: 3023e0ceb9fSOri Kam 3033e0ceb9fSOri Kam received packet with src ip = 176.80.50.4 sent to queue 3 3043e0ceb9fSOri Kam received packet with src ip = 176.80.50.5 sent to queue 1 3053e0ceb9fSOri Kam received packet with src ip = 176.80.50.6 sent to queue 3 306