LCOV - code coverage report
Current view: top level - dpdklibs/src - FlowControl.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 79 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 3 0

            Line data    Source code
       1              : /* SPDX-License-Identifier: BSD-3-Clause
       2              :  * Copyright 2017 Mellanox Technologies, Ltd
       3              :  */
       4              : 
       5              : #include "dpdklibs/FlowControl.hpp"
       6              : 
       7              : #include "logging/Logging.hpp"
       8              : 
       9              : #include <rte_byteorder.h>
      10              : #include <rte_ether.h>
      11              : #include <rte_flow.h>
      12              : #include <rte_ip.h>
      13              : 
      14              : namespace dunedaq {
      15              : namespace dpdklibs {
      16              : 
      17              : /**
      18              :  * create a flow rule that sends packets with matching src and dest ip
      19              :  * to selected queue.
      20              :  *
      21              :  * @param port_id
      22              :  *   The selected port.
      23              :  * @param rx_q
      24              :  *   The selected target queue.
      25              :  * @param src_ip
      26              :  *   The src ip value to match the input packet.
      27              :  * @param src_mask
      28              :  *   The mask to apply to the src ip.
      29              :  * @param dest_ip
      30              :  *   The dest ip value to match the input packet.
      31              :  * @param dest_mask
      32              :  *   The mask to apply to the dest ip.
      33              :  * @param[out] error
      34              :  *   Perform verbose error reporting if not NULL.
      35              :  *
      36              :  * @return
      37              :  *   A flow if the rule could be created else return NULL.
      38              :  */
      39              : 
      40              : /* Function responsible for creating the flow rule. 8< */
      41              : struct rte_flow*
      42            0 : generate_ipv4_flow(uint16_t port_id,
      43              :                    uint16_t rx_q,
      44              :                    uint32_t src_ip,
      45              :                    uint32_t src_mask,
      46              :                    uint32_t dest_ip,
      47              :                    uint32_t dest_mask,
      48              :                    struct rte_flow_error* error)
      49              : {
      50              :   // Declaring structs being used.
      51            0 :   struct rte_flow_attr attr;
      52            0 :   struct rte_flow_item pattern[MAX_PATTERN_NUM];
      53            0 :   struct rte_flow_action action[MAX_ACTION_NUM];
      54            0 :   struct rte_flow* flow = NULL;
      55            0 :   struct rte_flow_action_queue queue = { .index = rx_q };
      56            0 :   struct rte_flow_item_ipv4 ip_spec;
      57            0 :   struct rte_flow_item_ipv4 ip_mask;
      58              : 
      59            0 :   int res;
      60              : 
      61            0 :   memset(pattern, 0, sizeof(pattern));
      62            0 :   memset(action, 0, sizeof(action));
      63              : 
      64              :   // Set the rule attribute, only ingress packets will be checked.
      65            0 :   memset(&attr, 0, sizeof(struct rte_flow_attr));
      66            0 :   attr.ingress = 1;
      67              : 
      68              :   /*
      69              :    * create the action sequence.
      70              :    * one action only,  move packet to queue
      71              :    */
      72            0 :   action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
      73            0 :   action[0].conf = &queue;
      74            0 :   action[1].type = RTE_FLOW_ACTION_TYPE_END;
      75              : 
      76              :   /*
      77              :    * set the first level of the pattern (ETH).
      78              :    * since in this example we just want to get the
      79              :    * ipv4 we set this level to allow all.
      80              :    */
      81              : 
      82              :   // Set this level to allow all.
      83              : 
      84              :   /*
      85              :    * setting the second level of the pattern (IP).
      86              :    * in this example this is the level we care about
      87              :    * so we set it according to the parameters.
      88              :    */
      89              : 
      90              :   // Setting the second level of the pattern.
      91            0 :   memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4));
      92            0 :   memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4));
      93            0 :   ip_spec.hdr.dst_addr = htonl(dest_ip);
      94            0 :   ip_mask.hdr.dst_addr = 0;
      95            0 :   ip_spec.hdr.src_addr = htonl(src_ip);
      96            0 :   ip_mask.hdr.src_addr = src_mask;
      97              : 
      98            0 :   pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
      99              : 
     100            0 :   pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
     101            0 :   pattern[1].spec = &ip_spec;
     102            0 :   pattern[1].mask = &ip_mask;
     103              : 
     104            0 :   pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
     105              : 
     106              :   // Validate the rule and create it.
     107            0 :   res = rte_flow_validate(port_id, &attr, pattern, action, error);
     108            0 :   if (not res) {
     109            0 :     flow = rte_flow_create(port_id, &attr, pattern, action, error);
     110              :   }
     111              : 
     112            0 :   return flow;
     113              : }
     114              : 
     115              : // Droppign all the traffic that did pass a flow with higher priority
     116              : struct rte_flow*
     117            0 : generate_drop_flow(uint16_t port_id, struct rte_flow_error* error)
     118              : {
     119            0 :   struct rte_flow_attr attr;
     120            0 :   struct rte_flow_item pattern[MAX_PATTERN_NUM];
     121            0 :   struct rte_flow_action action[MAX_ACTION_NUM];
     122            0 :   struct rte_flow* flow = NULL;
     123            0 :   int res;
     124              : 
     125            0 :   memset(pattern, 0, sizeof(pattern));
     126            0 :   memset(action, 0, sizeof(action));
     127              : 
     128              :   // Set the rule attribute, only ingress packets will be checked.
     129            0 :   memset(&attr, 0, sizeof(struct rte_flow_attr));
     130            0 :   attr.ingress = 1;
     131            0 :   attr.egress = 0;
     132            0 :   attr.priority = 1; // TODO the higher the lower?
     133              : 
     134              :   /*
     135              :    * create the action sequence.
     136              :    * one action only,  Drop the packet
     137              :    */
     138            0 :   action[0].type = RTE_FLOW_ACTION_TYPE_DROP;
     139            0 :   action[1].type = RTE_FLOW_ACTION_TYPE_END;
     140              : 
     141              :   /*
     142              :    * set the first level of the pattern (ETH).
     143              :    * since in this example we just want to get the
     144              :    * ipv4 we set this level to allow all.
     145              :    */
     146              : 
     147              :   // Set this level to allow all.
     148            0 :   pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
     149              : 
     150              :   /*
     151              :    * setting the second level of the pattern (IP).
     152              :    * in this example this is the level we care about
     153              :    * so we set it according to the parameters.
     154              :    */
     155              : 
     156              :   // The final level must be always type end.
     157            0 :   pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
     158              : 
     159              :   // Validate the rule and create it.
     160            0 :   res = rte_flow_validate(port_id, &attr, pattern, action, error);
     161            0 :   if (not res) {
     162            0 :     flow = rte_flow_create(port_id, &attr, pattern, action, error);
     163              :   }
     164              : 
     165            0 :   return flow;
     166              : }
     167              : 
     168              : // ARP packets to specific
     169              : struct rte_flow*
     170            0 : generate_arp_flow(uint16_t port_id, uint16_t rx_q, struct rte_flow_error* error)
     171              : {
     172            0 :   struct rte_flow_attr attr;
     173            0 :   struct rte_flow_item pattern[MAX_PATTERN_NUM];
     174            0 :   struct rte_flow_action action[MAX_ACTION_NUM];
     175            0 :   struct rte_flow* flow = NULL;
     176            0 :   struct rte_flow_action_queue queue = { .index = rx_q };
     177            0 :   int res;
     178              : 
     179            0 :   memset(pattern, 0, sizeof(pattern));
     180            0 :   memset(action, 0, sizeof(action));
     181              : 
     182              :   // Set the rule attribute, only ingress packets will be checked.
     183            0 :   memset(&attr, 0, sizeof(struct rte_flow_attr));
     184            0 :   attr.ingress = 1;
     185            0 :   attr.egress = 0;
     186            0 :   attr.priority = 1; // TODO the higher the lower?
     187              : 
     188              :   // Action -> queue steering
     189            0 :   action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
     190            0 :   action[0].conf = &queue;
     191            0 :   action[1].type = RTE_FLOW_ACTION_TYPE_END;
     192              : 
     193              :   // Rule prep
     194            0 :   struct rte_flow_item_eth item_eth_mask = {};
     195            0 :   struct rte_flow_item_eth item_eth_spec = {};
     196              :   // Rule marker
     197            0 :   item_eth_spec.hdr.ether_type = RTE_BE16(RTE_ETHER_TYPE_ARP);
     198            0 :   item_eth_mask.hdr.ether_type = RTE_BE16(0xFFFF);
     199              :   // Rule pattern
     200            0 :   pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
     201            0 :   pattern[0].mask = &item_eth_mask;
     202            0 :   pattern[0].spec = &item_eth_spec;
     203            0 :   pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
     204              : 
     205              :   // Validate the rule and create it.
     206            0 :   res = rte_flow_validate(port_id, &attr, pattern, action, error);
     207            0 :   if (not res) {
     208            0 :     flow = rte_flow_create(port_id, &attr, pattern, action, error);
     209              :   }
     210              : 
     211            0 :   return flow;
     212              : }
     213              : 
     214              : } // namespace dpdklibs
     215              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1