"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.59.1/stress-netdev.c" (8 Jun 2019, 5494 Bytes) of package /linux/privat/stress-ng-0.09.59.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-netdev.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.58_vs_0.09.59.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 static const help_t help[] = {
   28     { NULL, "netdev N", "start N workers exercising netdevice ioctls" },
   29     { NULL, "netdev-ops N", "stop netdev workers after N bogo operations" },
   30     { NULL, NULL,       NULL }
   31 };
   32 
   33 #if defined(__linux__) &&   \
   34     defined(SIOCGIFCONF)
   35 
   36 /*
   37  *  stress_netdev_check()
   38  *  helper to perform netdevice ioctl and check for failure
   39  */
   40 static void stress_netdev_check(
   41     const args_t *args,
   42     struct ifreq *ifr,
   43     const int fd,
   44     const int cmd,
   45     const char *cmd_name)
   46 {
   47     if (ioctl(fd, cmd, ifr) < 0) {
   48         if ((errno != ENOTTY) &&
   49             (errno != EINVAL) &&
   50             (errno != EADDRNOTAVAIL))
   51             pr_fail("%s: interface '%s' ioctl %s failed, errno=%d (%s)\n",
   52                 args->name, ifr->ifr_name, cmd_name,
   53                 errno, strerror(errno));
   54     }
   55 }
   56 
   57 /*
   58  *  stress_netdev
   59  *  stress by heavy socket I/O
   60  */
   61 static int stress_netdev(const args_t *args)
   62 {
   63     int fd, rc = EXIT_SUCCESS;
   64 
   65     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
   66         pr_fail_dbg("socket");
   67         /* failed, kick parent to finish */
   68         return EXIT_NO_RESOURCE;
   69     }
   70 
   71     do {
   72         int i, n;
   73         struct ifconf ifc;
   74 
   75         /* Get list of transport layer addresses */
   76         (void)memset(&ifc, 0, sizeof(ifc));
   77         rc = ioctl(fd, SIOCGIFCONF, &ifc);
   78         if (rc < 0) {
   79             pr_fail("%s: ioctl SIOCGIFCONF failed, errno=%d (%s)\n",
   80                 args->name, errno, strerror(errno));
   81             rc = EXIT_FAILURE;
   82             break;
   83         }
   84 
   85         /* Do we have any? We should normally have at least lo */
   86         n = ifc.ifc_len / sizeof(struct ifreq);
   87         if (!n) {
   88             pr_dbg("%s: no network interfaces found, skipping.\n",
   89                 args->name);
   90             break;
   91         }
   92 
   93         /* Allocate buffer for the addresses */
   94         ifc.ifc_buf = malloc(ifc.ifc_len);
   95         if (!ifc.ifc_buf) {
   96             pr_fail("%s: out of memory allocating interface buffer\n",
   97                 args->name);
   98             rc = EXIT_NO_RESOURCE;
   99         }
  100 
  101         /* Fetch the addresses */
  102         if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
  103             pr_fail("%s: ioctl SIOCGIFCONF failed, errno=%d (%s)\n",
  104                 args->name, errno, strerror(errno));
  105             rc = EXIT_FAILURE;
  106             break;
  107         }
  108 
  109         /* And get info on each network device */
  110         for (i = 0; i < n; i++) {
  111             struct ifreq *ifr = &ifc.ifc_req[i];
  112 
  113 #if defined(SIOCGIFINDEX)
  114             /* We got the name, check it's index */
  115             if (ioctl(fd, SIOCGIFINDEX, ifr) < 0)
  116                 continue;
  117 #endif
  118 
  119 #if defined(SIOCGIFNAME)
  120             ifr->ifr_ifindex = i;
  121             /* Get name */
  122             if (ioctl(fd, SIOCGIFNAME, ifr) < 0)
  123                 continue;
  124 
  125             /* Check index is sane */
  126             if (ifr->ifr_ifindex != i) {
  127                 pr_fail("%s: interface '%s' returned "
  128                     "index %d, expected %d\n",
  129                     args->name, ifr->ifr_name,
  130                     ifr->ifr_ifindex, i);
  131             }
  132 #endif
  133 
  134 #if defined(SIOCGIFFLAGS)
  135             /* Get flags */
  136             stress_netdev_check(args, ifr, fd,
  137                 SIOCGIFFLAGS, "SIOCGIFFLAGS");
  138 #endif
  139 
  140 #if defined(SIOCGIFPFLAGS)
  141             /* Get extended flags */
  142             stress_netdev_check(args, ifr, fd,
  143                 SIOCGIFPFLAGS, "SIOCGIFPFLAGS");
  144 #endif
  145 
  146 #if defined(stress_netdev_check)
  147             /* Get address */
  148             stress_netdev_check(args, ifr, fd,
  149                 SIOCGIFADDR, "SIOCGIFADDR");
  150 #endif
  151 
  152 #if defined(SIOCGIFNETMASK)
  153             /* Get netmask */
  154             stress_netdev_check(args, ifr, fd,
  155                 SIOCGIFNETMASK, "SIOCGIFNETMASK");
  156 #endif
  157 
  158 #if defined(SIOCGIFNETMASK)
  159             /* Get metric (currently not supported) */
  160             stress_netdev_check(args, ifr, fd,
  161                 SIOCGIFMETRIC, "SIOCGIFMETRIC");
  162 #endif
  163 
  164 #if defined(SIOCGIFNETMASK)
  165             /* Get the MTU */
  166             stress_netdev_check(args, ifr, fd,
  167                 SIOCGIFMTU, "SIOCGIFMTU");
  168 #endif
  169 
  170 #if defined(SIOCGIFNETMASK)
  171             /* Get the hardware address */
  172             stress_netdev_check(args, ifr, fd,
  173                 SIOCGIFHWADDR, "SIOCGIFHWADDR");
  174 #endif
  175 
  176 #if defined(SIOCGIFMAP)
  177             /* Get the hardware parameters */
  178             stress_netdev_check(args, ifr, fd,
  179                 SIOCGIFMAP, "SIOCGIFMAP");
  180 #endif
  181 
  182 #if defined(SIOCGIFTXQLEN)
  183             /* Get the transmit queue length */
  184             stress_netdev_check(args, ifr, fd,
  185                 SIOCGIFTXQLEN, "SIOCGIFTXQLEN");
  186 #endif
  187 
  188 #if defined(SIOCGIFDSTADDR)
  189             /* Get the destination address */
  190             stress_netdev_check(args, ifr, fd,
  191                 SIOCGIFDSTADDR, "SIOCGIFDSTADDR");
  192 #endif
  193 
  194 #if defined(SIOCGIFBRDADDR)
  195             /* Get the broadcast address */
  196             stress_netdev_check(args, ifr, fd,
  197                 SIOCGIFBRDADDR, "SIOCGIFBRDADDR");
  198 #endif
  199         }
  200         free(ifc.ifc_buf);
  201         inc_counter(args);
  202     } while (keep_stressing());
  203 
  204     (void)close(fd);
  205 
  206     return rc;
  207 }
  208 
  209 stressor_info_t stress_netdev_info = {
  210     .stressor = stress_netdev,
  211     .class = CLASS_NETWORK,
  212     .help = help
  213 };
  214 #else
  215 stressor_info_t stress_netdev_info = {
  216     .stressor = stress_not_implemented,
  217     .class = CLASS_NETWORK,
  218     .help = help
  219 };
  220 #endif