LCOV - code coverage report
Current view: top level - root/contrail/vrouter/dpdk/n3k - vr_dpdk_n3k_offloads.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 140 0.0 %
Date: 2026-08-03 02:19:58 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* SPDX-License-Identifier: BSD-2-Clause
       2             :  * Copyright(c) HCL TECHNOLOGIES LTD
       3             :  * Submitted on behalf of a third-party: Intel Corporation, a
       4             :  * Delaware corporation, having its principal place of business
       5             :  * at 2200 Mission College Boulevard,
       6             :  * Santa Clara, California 95052, USA
       7             :  */
       8             : 
       9             : #include "vr_dpdk_n3k_offloads.h"
      10             : 
      11             : #include <stdio.h>
      12             : #include <stdbool.h>
      13             : 
      14             : #include <arpa/inet.h>
      15             : 
      16             : #include <rte_byteorder.h>
      17             : #include <rte_common.h>
      18             : #include <rte_log.h>
      19             : 
      20             : #include <vr_dpdk.h>
      21             : #include <vr_flow.h>
      22             : #include <vr_offloads.h>
      23             : 
      24             : #include "vr_dpdk_n3k_interface.h"
      25             : #include "vr_dpdk_n3k_missing_mirror.h"
      26             : #include "vr_dpdk_n3k_mpls.h"
      27             : #include "vr_dpdk_n3k_flow.h"
      28             : #include "vr_dpdk_n3k_vxlan.h"
      29             : #include "vr_dpdk_n3k_packet_metadata.h"
      30             : #include "vr_dpdk_n3k_packet_parser.h"
      31             : #include "vr_dpdk_n3k_config.h"
      32             : #include "vr_dpdk_n3k_offload_hold.h"
      33             : 
      34             : extern unsigned int vr_bridge_entries;
      35             : extern unsigned int datapath_offloads;
      36             : 
      37             : rte_spinlock_t vr_dpdk_n3k_offload_spinlock __rte_cache_aligned;
      38             : 
      39             : static void
      40           0 : debug_print_packet_key_and_metadata(
      41             :         const struct vr_packet *pkt,
      42             :         const struct vr_dpdk_n3k_packet_key *key,
      43             :         const struct vr_dpdk_n3k_packet_metadata *metadata)
      44             : {
      45             :     char ip_addr[40];
      46             : 
      47           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: printing parsed packet\n", __func__);
      48           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: pkt=%p\n", __func__, pkt);
      49             : 
      50           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: key\n", __func__);
      51           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: key->nh_id    = %u\n", __func__,
      52             :         key->nh_id);
      53             : 
      54           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: key->src_ip   = %s\n", __func__,
      55             :         vr_dpdk_n3k_convert_ip_to_str(ip_addr, &key->ip.src, key->ip.type));
      56           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: key->dst_ip   = %s\n", __func__,
      57             :         vr_dpdk_n3k_convert_ip_to_str(ip_addr, &key->ip.dst, key->ip.type));
      58             : 
      59           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: key->proto    = %u\n", __func__,
      60             :         key->proto);
      61           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: key->src_port = %u\n", __func__,
      62             :         rte_be_to_cpu_16(key->src_port));
      63           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: key->dst_port = %u\n", __func__,
      64             :         rte_be_to_cpu_16(key->dst_port));
      65             : 
      66           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s: metadata\n", __func__);
      67             : 
      68           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET,
      69             :         "%s: metadata->eth_hdr      = %u\n", __func__,
      70             :         metadata->eth_hdr_present);
      71             : 
      72           0 :     if (metadata->eth_hdr_present) {
      73           0 :         RTE_LOG(DEBUG, OFFLOAD_PACKET,
      74             :             "%s: metadata->inner_src_mac  = " MAC_FORMAT "\n", __func__,
      75             :             MAC_VALUE(&metadata->inner_src_mac[0]));
      76           0 :         RTE_LOG(DEBUG, OFFLOAD_PACKET,
      77             :             "%s: metadata->inner_dst_mac  = " MAC_FORMAT "\n", __func__,
      78             :             MAC_VALUE(&metadata->inner_dst_mac[0]));
      79             :     }
      80           0 : }
      81             : 
      82             : static int
      83           0 : vr_dpdk_n3k_offload_packet_parse(struct vr_packet *pkt)
      84             : {
      85           0 :     RTE_LOG(DEBUG, OFFLOAD_PACKET, "%s() called; pkt=%p\n", __func__, pkt);
      86             : 
      87             :     struct vr_dpdk_n3k_packet_key key;
      88             :     struct vr_dpdk_n3k_packet_metadata metadata;
      89             :     int ret;
      90             : 
      91           0 :     ret = vr_dpdk_n3k_parse_packet(pkt, &key, &metadata);
      92           0 :     if (ret != 0) {
      93           0 :         RTE_LOG(DEBUG, OFFLOAD_PACKET,
      94             :             "%s(): vr_dpdk_n3k_parse_packet() returned %d for pkt=%p\n",
      95             :             __func__, ret, pkt);
      96           0 :         return ret;
      97             :     } else
      98           0 :         debug_print_packet_key_and_metadata(pkt, &key, &metadata);
      99             : 
     100           0 :     ret = vr_dpdk_n3k_packet_metadata_insert_copy(&key, &metadata, false);
     101           0 :     if (ret != 0) {
     102           0 :         RTE_LOG(DEBUG, OFFLOAD_PACKET,
     103             :             "%s(): vr_dpdk_n3k_packet_metadata_insert_copy() returned %d for pkt=%p\n",
     104             :             __func__, ret, pkt);
     105             :     }
     106           0 :     return ret;
     107             : }
     108             : 
     109             : /* When vrouter calls this function, all the packet processing had stopped (by
     110             :  * shutting interfaces) and all the structures have been re-initialized.
     111             :  * Because of that, we don't need to consider interaction of this callback with
     112             :  * other threads, except of interaction with service cores (which are
     113             :  * unaffected by the reset) -- we need to provide thread safety wrt to
     114             :  * aging_service_core and remove_unused_metadata_service_core.
     115             :  */
     116             : static int
     117           0 : vr_dpdk_n3k_offload_soft_reset(void)
     118             : {
     119           0 :     struct vrouter *router = vrouter_get(0);
     120             :     int ret;
     121             : 
     122           0 :     vr_dpdk_n3k_offload_interface_exit();
     123           0 :     ret = vr_dpdk_n3k_offload_interface_init(router->vr_max_interfaces);
     124           0 :     if (ret)
     125           0 :         return ret;
     126             : 
     127           0 :     vr_dpdk_n3k_offload_vxlan_exit();
     128           0 :     ret = vr_dpdk_n3k_offload_vxlan_init(router->vr_max_nexthops);
     129           0 :     if (ret)
     130           0 :         return ret;
     131             : 
     132           0 :     vr_dpdk_n3k_offload_mpls_exit();
     133           0 :     ret = vr_dpdk_n3k_offload_mpls_init(router->vr_max_nexthops);
     134           0 :     if (ret)
     135           0 :         return ret;
     136             : 
     137           0 :     vr_dpdk_n3k_offload_missing_mirror_exit_all();
     138           0 :     ret = vr_dpdk_n3k_offload_missing_mirror_init_all();
     139           0 :     if (ret)
     140           0 :         return ret;
     141             : 
     142             :     /* We don't need to reset offload_hold, as it's cleared by
     143             :      * vr_dpdk_n3k_offload_flow_reset_unlocked */
     144             : 
     145           0 :     vr_dpdk_n3k_packet_metadata_reset();
     146             : 
     147           0 :     vr_dpdk_n3k_offload_lock();
     148           0 :     vr_dpdk_n3k_offload_flow_reset_unlocked();
     149           0 :     vr_dpdk_n3k_offload_unlock();
     150             : 
     151           0 :     return 0;
     152             : }
     153             : 
     154             : static int
     155           0 : vr_dpdk_n3k_offload_flow_set_threadsafe(
     156             :     struct vr_flow_entry *fe, uint32_t fe_index, struct vr_flow_entry *rfe)
     157             : {
     158           0 :     int ret = 0;
     159           0 :     vr_dpdk_n3k_offload_lock();
     160           0 :     ret = vr_dpdk_n3k_offload_flow_set_unlocked(fe, fe_index, rfe);
     161           0 :     vr_dpdk_n3k_offload_unlock();
     162           0 :     return ret;
     163             : }
     164             : 
     165             : static int
     166           0 : vr_dpdk_n3k_offload_flow_del_threadsafe(struct vr_flow_entry *fe)
     167             : {
     168           0 :     vr_dpdk_n3k_offload_lock();
     169           0 :     int ret = vr_dpdk_n3k_offload_flow_del_unlocked(fe);
     170           0 :     vr_dpdk_n3k_offload_unlock();
     171           0 :     return ret;
     172             : }
     173             : 
     174             : static int
     175           0 : vr_dpdk_n3k_offload_flow_stats_update_threadsafe(struct vr_flow_entry *fe)
     176             : {
     177           0 :     vr_dpdk_n3k_offload_lock();
     178           0 :     int ret = vr_dpdk_n3k_offload_flow_stats_update_unlocked(fe);
     179           0 :     vr_dpdk_n3k_offload_unlock();
     180           0 :     return ret;
     181             : }
     182             : 
     183             : static int
     184           0 : vr_dpdk_n3k_offload_mirror_add_threadsafe(
     185             :     struct vr_mirror_entry *mirror, unsigned int index)
     186             : {
     187           0 :     vr_dpdk_n3k_offload_lock();
     188           0 :     if (mirror->mir_rid == 0) {
     189           0 :         vr_dpdk_n3k_offload_missing_mirror_flows_unlocked(index);
     190             :     }
     191           0 :     vr_dpdk_n3k_offload_unlock();
     192           0 :     return 0;
     193             : }
     194             : 
     195             : static int
     196           0 : vr_dpdk_n3k_offload_nexthop_add_threadsafe(struct vr_nexthop *nh)
     197             : {
     198           0 :     vr_dpdk_n3k_offload_lock();
     199           0 :     if (vr_dpdk_n3k_offload_nexthop_validate(nh) == 0) {
     200           0 :         vr_dpdk_n3k_offload_missing_nexthop_flows_unlocked(nh->nh_id);
     201             :     }
     202           0 :     vr_dpdk_n3k_offload_unlock();
     203           0 :     return 0;
     204             : }
     205             : 
     206             : static char n3k_voo_handler_id[] = "N3K offloads";
     207             : 
     208             : static const struct vr_offload_ops vr_dpdk_n3k_offload_ops = {
     209             :     .voo_handler_id = n3k_voo_handler_id,
     210             : 
     211             :     .voo_soft_reset = vr_dpdk_n3k_offload_soft_reset,
     212             : 
     213             :     .voo_packet_parse = vr_dpdk_n3k_offload_packet_parse,
     214             : 
     215             :     .voo_flow_set = vr_dpdk_n3k_offload_flow_set_threadsafe,
     216             :     .voo_flow_del = vr_dpdk_n3k_offload_flow_del_threadsafe,
     217             :     .voo_flow_stats_update = vr_dpdk_n3k_offload_flow_stats_update_threadsafe,
     218             : 
     219             :     .voo_interface_add = vr_dpdk_n3k_offload_interface_add,
     220             :     .voo_interface_del = vr_dpdk_n3k_offload_interface_del,
     221             : 
     222             :     .voo_mpls_add = vr_dpdk_n3k_offload_mpls_add,
     223             :     .voo_mpls_del = vr_dpdk_n3k_offload_mpls_del,
     224             : 
     225             :     .voo_vxlan_add = vr_dpdk_n3k_offload_vxlan_add,
     226             :     .voo_vxlan_del = vr_dpdk_n3k_offload_vxlan_del,
     227             : 
     228             :     .voo_mirror_add = vr_dpdk_n3k_offload_mirror_add_threadsafe,
     229             : 
     230             :     .voo_nexthop_add = vr_dpdk_n3k_offload_nexthop_add_threadsafe,
     231             : };
     232             : 
     233             : static const struct vr_offload_ops *n3k_offload_ops = NULL;
     234             : 
     235             : static void
     236           0 : vr_dpdk_n3k_offload_ops_exit(void)
     237             : {
     238           0 :     n3k_offload_ops = NULL;
     239             : 
     240           0 :     vr_dpdk_n3k_offload_lock();
     241             : 
     242           0 :     vr_dpdk_n3k_offload_missing_mirror_exit_all();
     243           0 :     vr_dpdk_n3k_offload_flow_exit();
     244           0 :     vr_dpdk_n3k_offload_mpls_exit();
     245           0 :     vr_dpdk_n3k_offload_vxlan_exit();
     246           0 :     vr_dpdk_n3k_offload_interface_exit();
     247           0 :     vr_dpdk_n3k_packet_metadata_exit();
     248           0 :     vr_dpdk_n3k_offload_hold_exit();
     249           0 :     vr_dpdk_n3k_offload_unlock();
     250           0 : }
     251             : 
     252             : static int
     253           0 : vr_dpdk_n3k_offload_ops_init(struct vrouter *router)
     254             : {
     255           0 :     int ret = 0;
     256             : 
     257           0 :     vr_compute_size_oflow_table();
     258           0 :     const unsigned int flow_entries = vr_flow_entries + vr_oflow_entries;
     259             : 
     260           0 :     rte_spinlock_init(&vr_dpdk_n3k_offload_spinlock);
     261             : 
     262           0 :     ret = vr_dpdk_n3k_offload_interface_init(router->vr_max_interfaces);
     263           0 :     if (ret)
     264           0 :         goto error;
     265             : 
     266           0 :     ret = vr_dpdk_n3k_offload_vxlan_init(router->vr_max_nexthops);
     267           0 :     if (ret)
     268           0 :         goto error;
     269             : 
     270           0 :     ret = vr_dpdk_n3k_offload_mpls_init(router->vr_max_nexthops);
     271           0 :     if (ret)
     272           0 :         goto error;
     273             : 
     274           0 :     ret = vr_dpdk_n3k_offload_flow_init(flow_entries);
     275           0 :     if (ret)
     276           0 :         goto error;
     277             : 
     278           0 :     ret = vr_dpdk_n3k_offload_missing_mirror_init_all();
     279           0 :     if (ret)
     280           0 :         goto error;
     281             : 
     282           0 :     ret = vr_dpdk_n3k_packet_metadata_init(2 * flow_entries);
     283           0 :     if (ret)
     284           0 :         goto error;
     285             : 
     286           0 :     ret = vr_dpdk_n3k_offload_hold_init(flow_entries);
     287           0 :     if (ret)
     288           0 :         goto error;
     289             : 
     290           0 :     n3k_offload_ops = &vr_dpdk_n3k_offload_ops;
     291             : 
     292           0 :     return 0;
     293             : 
     294           0 : error:
     295           0 :     vr_dpdk_n3k_offload_ops_exit();
     296           0 :     return ret;
     297             : }
     298             : 
     299             : void
     300           0 : vr_dpdk_n3k_offload_exit(void)
     301             : {
     302           0 :     if (!datapath_offloads) {
     303           0 :         return;
     304             :     }
     305             : 
     306           0 :     vr_offload_unregister();
     307           0 :     vr_dpdk_n3k_offload_ops_exit();
     308             : }
     309             : 
     310             : int
     311           0 : vr_dpdk_n3k_offload_init(void)
     312             : {
     313           0 :     if (!datapath_offloads) {
     314           0 :         return 0;
     315             :     }
     316             : 
     317             :     /* TODO(n3k): Handle multiple vrouters */
     318           0 :     int ret = vr_dpdk_n3k_offload_ops_init(vrouter_get(0));
     319           0 :     if (ret != 0) {
     320           0 :         RTE_LOG(ERR, VROUTER, "Initialization of N3K vr_offload_ops failed; ret = %s\n",
     321             :             rte_strerror(ret));
     322           0 :         return ret;
     323             :     }
     324             : 
     325           0 :     vr_offload_unregister();
     326           0 :     ret = vr_offload_register(n3k_offload_ops);
     327           0 :     if (ret != 0) {
     328           0 :         RTE_LOG(ERR, VROUTER, "vr_offload_register() failed; ret = %s\n",
     329             :             rte_strerror(ret));
     330             : 
     331           0 :         vr_dpdk_n3k_offload_ops_exit();
     332             : 
     333           0 :         return ret;
     334             :     }
     335             : 
     336           0 :     return 0;
     337             : }

Generated by: LCOV version 1.14