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

Generated by: LCOV version 1.14