LCOV - code coverage report
Current view: top level - root/contrail/vrouter/dpdk - vr_dpdk_ddp.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 131 0.0 %
Date: 2026-11-09 02:10:49 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * vr_dpdk_ddp.c - DDP specific API's for adding/deleting the firmware.
       3             :  *
       4             :  * Copyright (c) 2020 Juniper Networks, Inc. All rights reserved.
       5             :  * Copyright Contributors to the OpenSDN project
       6             :  */
       7             : #include <sys/types.h>
       8             : #include <sys/stat.h>
       9             : #include <fcntl.h>
      10             : 
      11             : #include "vr_dpdk.h"
      12             : 
      13             : #include <rte_eth_bond.h>
      14             : #include <rte_pmd_i40e.h>
      15             : #include <rte_errno.h>
      16             : 
      17             : /* By default, DDP disabled for X710 series NIC's, pass --ddp command line 
      18             :  * argument to enable it */
      19             : static bool vr_dpdk_enable_ddp = false;
      20             : const char ddp_fpath[] = "/opt/contrail/ddp/mplsogreudp.pkg";
      21             : const char ddp_fbkp[] = "/opt/contrail/ddp/mplsogreudp.bkp";
      22             : 
      23             : 
      24             : bool
      25           0 : vr_dpdk_get_ddp(void)
      26             : {
      27           0 :     return vr_dpdk_enable_ddp;
      28             : }
      29             : 
      30             : void
      31           0 : vr_dpdk_set_ddp(void)
      32             : {
      33           0 :     vr_dpdk_enable_ddp = true;
      34           0 : }
      35             : 
      36             : void
      37           0 : vr_dpdk_reset_ddp(void)
      38             : {
      39           0 :     vr_dpdk_enable_ddp = false;
      40           0 : }
      41             : 
      42             : static int
      43           0 : vr_dpdk_ddp_add(uint16_t port_id)
      44             : {
      45           0 :     int ddp_fd, ret = -ENOTSUP;
      46             :     uint8_t *buf;
      47             :     struct stat st_buf;
      48             :     FILE *ddp_bkp_fd;
      49             : 
      50           0 :     if(!rte_eth_dev_is_valid_port(port_id)) {
      51           0 :         RTE_LOG(ERR, VROUTER, "%s : DDP port_id is invalid \n", __func__);
      52           0 :         return VR_DPDK_DDP_FAILED;
      53             :     }
      54             : 
      55           0 :     ddp_fd = open(ddp_fpath, O_RDONLY);
      56           0 :     if(ddp_fd == -1) {
      57           0 :         RTE_LOG(ERR, VROUTER, "%s: Failed to open %s file \n",
      58             :                     __func__, ddp_fpath);
      59           0 :         return VR_DPDK_DDP_FAILED;
      60             :     }
      61           0 :     if ((fstat(ddp_fd, &st_buf) != 0) || (!S_ISREG(st_buf.st_mode))) {
      62           0 :         close(ddp_fd);
      63           0 :         RTE_LOG(ERR, VROUTER, "%s: File operation failed for %s\n",
      64             :                     __func__, ddp_fpath);
      65           0 :         return VR_DPDK_DDP_FAILED;
      66             :     }
      67             : 
      68           0 :     if(st_buf.st_size < 0) {
      69           0 :         close(ddp_fd);
      70           0 :         RTE_LOG(ERR, VROUTER, "%s: File operation failed for %s while reading"
      71             :                 "size %ld \n", __func__, ddp_fpath, st_buf.st_size);
      72           0 :         return VR_DPDK_DDP_FAILED;
      73             :     }
      74             : 
      75           0 :     buf = (uint8_t *)vr_zalloc(st_buf.st_size, VR_INFO_REQ_OBJECT);
      76           0 :     if(!buf) {
      77           0 :         close(ddp_fd);
      78           0 :         RTE_LOG(ERR, VROUTER, "%s: Memory allocation failed for size %ld\n",
      79             :                     __func__, st_buf.st_size);
      80           0 :         return VR_DPDK_DDP_FAILED;
      81             :     }
      82             : 
      83           0 :     ret = read(ddp_fd, buf, st_buf.st_size);
      84           0 :     if(ret < 0) {
      85           0 :         close(ddp_fd);
      86           0 :         vr_free(buf, VR_INFO_REQ_OBJECT);
      87           0 :         RTE_LOG(ERR, VROUTER, "%s: File read operation failed for %s\n",
      88             :                     __func__, ddp_fpath);
      89           0 :         return VR_DPDK_DDP_FAILED;
      90             :     }
      91             : 
      92           0 :     ret = rte_pmd_i40e_process_ddp_package(port_id, buf, st_buf.st_size,
      93             :             RTE_PMD_I40E_PKG_OP_WR_ADD);
      94             : 
      95           0 :     if(ret == -ENOTSUP) {
      96           0 :         RTE_LOG(ERR, VROUTER, "%s: DDP works only on X710 NIC series \n",
      97             :                     __func__);
      98           0 :     } else if (ret == -EEXIST) {
      99           0 :         RTE_LOG(DEBUG, VROUTER, "%s: DDP Profile already exist\n", __func__);
     100           0 :     } else if(ret < 0) {
     101           0 :         RTE_LOG(ERR, VROUTER, "%s: Failed to load profile return value is %d\n",
     102             :                     __func__, ret);
     103             :     } else {
     104           0 :         RTE_LOG(INFO, VROUTER, "%s DDP programming was successful\n",
     105             :                     __func__);
     106           0 :         ddp_bkp_fd = fopen(ddp_fbkp, "wb");
     107           0 :         if(ddp_bkp_fd == NULL) {
     108           0 :             close(ddp_fd);
     109           0 :             vr_free(buf, VR_INFO_REQ_OBJECT);
     110           0 :             RTE_LOG(ERR, VROUTER, "%s: Failed to open %s\n",
     111             :                         __func__, ddp_fbkp);
     112           0 :             return VR_DPDK_DDP_FAILED;
     113             :         }
     114             : 
     115           0 :         if(fwrite(buf, 1, st_buf.st_size, ddp_bkp_fd) != st_buf.st_size) {
     116           0 :             close(ddp_fd);
     117           0 :             fclose(ddp_bkp_fd);
     118           0 :             vr_free(buf, VR_INFO_REQ_OBJECT);
     119           0 :             RTE_LOG(ERR, VROUTER, "%s: Failed to write %s\n", __func__, ddp_fbkp);
     120           0 :             return VR_DPDK_DDP_FAILED;
     121             :         }
     122           0 :         fclose(ddp_bkp_fd);
     123             :     }
     124             : 
     125           0 :     if (ddp_fd) {
     126           0 :         close(ddp_fd);
     127             :     }
     128             : 
     129           0 :     if (buf) {
     130           0 :         vr_free(buf, VR_INFO_REQ_OBJECT);
     131             :     }
     132             : 
     133           0 :     return ret;
     134             : }
     135             : 
     136             : static int
     137           0 : vr_dpdk_ddp_del(uint16_t port_id)
     138             : {
     139           0 :     int ddp_fd, ret = -ENOTSUP;
     140             :     uint8_t *buf;
     141             :     struct stat st_buf;
     142             : 
     143           0 :     if(!rte_eth_dev_is_valid_port(port_id)) {
     144           0 :         RTE_LOG(ERR, VROUTER, "%s: DDP port_id is invalid \n", __func__);
     145           0 :         return VR_DPDK_DDP_FAILED;
     146             :     }
     147             : 
     148           0 :     ddp_fd = open(ddp_fbkp, O_RDONLY);
     149           0 :     if(ddp_fd == -1) {
     150           0 :         RTE_LOG(ERR, VROUTER, "%s: Failed to open %s file\n", __func__,
     151             :                     ddp_fbkp);
     152           0 :         return VR_DPDK_DDP_FAILED;
     153             :     }
     154             : 
     155           0 :     if ((fstat(ddp_fd, &st_buf) != 0) || (!S_ISREG(st_buf.st_mode))) {
     156           0 :         close(ddp_fd);
     157           0 :         RTE_LOG(ERR, VROUTER, "%s: File operation failed for %s\n",
     158             :                     __func__, ddp_fbkp);
     159           0 :         return VR_DPDK_DDP_FAILED;
     160             :     }
     161             : 
     162           0 :     if(st_buf.st_size < 0) {
     163           0 :         close(ddp_fd);
     164           0 :         RTE_LOG(ERR, VROUTER, "%s: File operation failed for %s while reading"
     165             :                     "size %ld \n", __func__, ddp_fbkp, st_buf.st_size);
     166           0 :         return VR_DPDK_DDP_FAILED;
     167             :     }
     168             : 
     169           0 :     buf = (uint8_t *)vr_zalloc(st_buf.st_size, VR_INFO_REQ_OBJECT);
     170           0 :     if(!buf) {
     171           0 :         close(ddp_fd);
     172           0 :         RTE_LOG(ERR, VROUTER, "%s: Memory allocation failed for size %ld\n",
     173             :                     __func__, st_buf.st_size);
     174           0 :         return VR_DPDK_DDP_FAILED;
     175             :     }
     176             : 
     177           0 :     ret = read(ddp_fd, buf, st_buf.st_size);
     178           0 :     if(ret < 0) {
     179           0 :         close(ddp_fd);
     180           0 :         vr_free(buf, VR_INFO_REQ_OBJECT);
     181           0 :         RTE_LOG(ERR, VROUTER, "%s: File read operation failed for %s\n",
     182             :                     __func__, ddp_fbkp);
     183           0 :         return VR_DPDK_DDP_FAILED;
     184             :     }
     185             : 
     186           0 :     ret = rte_pmd_i40e_process_ddp_package(port_id, buf, st_buf.st_size,
     187             :             RTE_PMD_I40E_PKG_OP_WR_DEL);
     188           0 :     if(ret == -ENOTSUP) {
     189           0 :         RTE_LOG(ERR, VROUTER, "%s: DDP works only on X710 NIC series\n",
     190             :                     __func__);
     191           0 :     } else if(ret == -EACCES) {
     192           0 :         RTE_LOG(DEBUG, VROUTER, "%s: DDP profile doesn't exist\n", __func__);
     193           0 :     } else if(ret < 0) {
     194           0 :         RTE_LOG(ERR, VROUTER, "%s: Failed to delete profile return value is %d\n",
     195             :                     __func__, ret);
     196             :     } else {
     197           0 :         RTE_LOG(INFO, VROUTER, "%s: Removed DDP image mplsogreudp - success\n",
     198             :                     __func__);
     199             :     }
     200             : 
     201           0 :     if(ddp_fd) {
     202           0 :         close(ddp_fd);
     203             :     }
     204             : 
     205           0 :     if(buf) {
     206           0 :         vr_free(buf, VR_INFO_REQ_OBJECT);
     207             :     }
     208             : 
     209           0 :     return ret;
     210             : }
     211             : 
     212             : int
     213           0 : vr_dpdk_process_ddp_package(unsigned ddp_op)
     214             : {
     215             :     int i, ret;
     216             :     struct vr_dpdk_ethdev *ethdev;
     217             :     struct rte_eth_dev *dev;
     218           0 :     uint16_t slave_port_id, port_id = vr_dpdk_master_port_id;
     219             : 
     220           0 :     if(rte_eth_dev_is_valid_port(port_id)) {
     221           0 :          ethdev = &vr_dpdk.ethdevs[port_id];
     222             : 
     223           0 :     if (ethdev->ethdev_nb_slaves > 0) {
     224           0 :         for (i = 0; i < ethdev->ethdev_nb_slaves; i++) {
     225           0 :             slave_port_id = ethdev->ethdev_slaves[i];
     226           0 :             dev = &rte_eth_devices[slave_port_id];
     227           0 :             if(!strcmp(dev->device->driver->name, "net_i40e")) {
     228           0 :                  if(ddp_op == VR_DPDK_DDP_ADD) {
     229           0 :                      ret = vr_dpdk_ddp_add((uint16_t)slave_port_id);
     230           0 :                      if(!(ret == -EEXIST || ret == 0))
     231           0 :                          return ret;
     232           0 :                  } else if(ddp_op == VR_DPDK_DDP_DELETE) {
     233           0 :                      ret = vr_dpdk_ddp_del((uint16_t)slave_port_id);
     234           0 :                      if(!(ret == -EACCES || ret == 0))
     235           0 :                          return ret;
     236             :                  }
     237             :             } else {
     238           0 :                 RTE_LOG(DEBUG, VROUTER, "%s: DDP supports only on X710 series"
     239             :                             "NIC cardsi\n", __func__);
     240           0 :                 return VR_DPDK_DDP_NOT_SUPPORTED;
     241             :             }
     242             :         }
     243             :     } else {
     244           0 :             dev = &rte_eth_devices[ethdev->ethdev_port_id];
     245           0 :             if(!strcmp(dev->device->driver->name, "net_i40e")) {
     246           0 :                  if(ddp_op == VR_DPDK_DDP_ADD) {
     247           0 :                      return vr_dpdk_ddp_add((uint16_t)ethdev->ethdev_port_id);
     248           0 :                  } else if(ddp_op == VR_DPDK_DDP_DELETE) {
     249           0 :                      return vr_dpdk_ddp_del((uint16_t)ethdev->ethdev_port_id);
     250             :                  }
     251             :             } else {
     252           0 :                 RTE_LOG(DEBUG, VROUTER, "%s: DDP supports only on X710 series"
     253             :                             "NIC cards", __func__);
     254           0 :                 return VR_DPDK_DDP_NOT_SUPPORTED;
     255             :             }
     256             :         }
     257             :     }
     258           0 :     return 0;
     259             : }

Generated by: LCOV version 1.14