"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-netdev.c" (15 Mar 2019, 4569 Bytes) of package /linux/privat/stress-ng-0.09.56.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.49_vs_0.09.50.

    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 #if defined(__linux__)
   28 
   29 /*
   30  *  stress_netdev_check()
   31  *  helper to perform netdevice ioctl and check for failure
   32  */
   33 static void stress_netdev_check(
   34     const args_t *args,
   35     struct ifreq *ifr,
   36     const int fd,
   37     const int cmd,
   38     const char *cmd_name)
   39 {
   40     if (ioctl(fd, cmd, ifr) < 0) {
   41         if ((errno != ENOTTY) &&
   42             (errno != EINVAL) &&
   43             (errno != EADDRNOTAVAIL))
   44             pr_fail("%s: interface '%s' ioctl %s failed, errno=%d (%s)\n",
   45                 args->name, ifr->ifr_name, cmd_name,
   46                 errno, strerror(errno));
   47     }
   48 }
   49 
   50 /*
   51  *  stress_netdev
   52  *  stress by heavy socket I/O
   53  */
   54 static int stress_netdev(const args_t *args)
   55 {
   56     int fd, rc = EXIT_SUCCESS;
   57 
   58     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
   59         pr_fail_dbg("socket");
   60         /* failed, kick parent to finish */
   61         return EXIT_NO_RESOURCE;
   62     }
   63 
   64     do {
   65         int i, n;
   66         struct ifconf ifc;
   67 
   68         /* Get list of transport layer addresses */
   69         (void)memset(&ifc, 0, sizeof(ifc));
   70         rc = ioctl(fd, SIOCGIFCONF, &ifc);
   71         if (rc < 0) {
   72             pr_fail("%s: ioctl SIOCGIFCONF failed, errno=%d (%s)\n",
   73                 args->name, errno, strerror(errno));
   74             rc = EXIT_FAILURE;
   75             break;
   76         }
   77 
   78         /* Do we have any? We should normally have at least lo */
   79         n = ifc.ifc_len / sizeof(struct ifreq);
   80         if (!n) {
   81             pr_dbg("%s: no network interfaces found, skipping.\n",
   82                 args->name);
   83             break;
   84         }
   85 
   86         /* Allocate buffer for the addresses */
   87         ifc.ifc_buf = malloc(ifc.ifc_len);
   88         if (!ifc.ifc_buf) {
   89             pr_fail("%s: out of memory allocating interface buffer\n",
   90                 args->name);
   91             rc = EXIT_NO_RESOURCE;
   92         }
   93 
   94         /* Fetch the addresses */
   95         if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
   96             pr_fail("%s: ioctl SIOCGIFCONF failed, errno=%d (%s)\n",
   97                 args->name, errno, strerror(errno));
   98             rc = EXIT_FAILURE;
   99             break;
  100         }
  101 
  102         /* And get info on each network device */
  103         for (i = 0; i < n; i++) {
  104             struct ifreq *ifr = &ifc.ifc_req[i];
  105 
  106             /* We got the name, check it's index */
  107             if (ioctl(fd, SIOCGIFINDEX, ifr) < 0)
  108                 continue;
  109 
  110             ifr->ifr_ifindex = i;
  111             /* Get name */
  112             if (ioctl(fd, SIOCGIFNAME, ifr) < 0)
  113                 continue;
  114 
  115             /* Check index is sane */
  116             if (ifr->ifr_ifindex != i) {
  117                 pr_fail("%s: interface '%s' returned "
  118                     "index %d, expected %d\n",
  119                     args->name, ifr->ifr_name,
  120                     ifr->ifr_ifindex, i);
  121             }
  122 
  123             /* Get flags */
  124             stress_netdev_check(args, ifr, fd,
  125                 SIOCGIFFLAGS, "SIOCGIFFLAGS");
  126 
  127             /* Get extended flags */
  128             /*
  129             stress_netdev_check(args, ifr, fd,
  130                 SIOCGIFPFLAGS, "SIOCGIFPFLAGS");
  131             */
  132 
  133             /* Get address */
  134             stress_netdev_check(args, ifr, fd,
  135                 SIOCGIFADDR, "SIOCGIFADDR");
  136 
  137             /* Get netmask */
  138             stress_netdev_check(args, ifr, fd,
  139                 SIOCGIFNETMASK, "SIOCGIFNETMASK");
  140 
  141             /* Get metric (currently not supported) */
  142             stress_netdev_check(args, ifr, fd,
  143                 SIOCGIFMETRIC, "SIOCGIFMETRIC");
  144 
  145             /* Get the MTU */
  146             stress_netdev_check(args, ifr, fd,
  147                 SIOCGIFMTU, "SIOCGIFMTU");
  148 
  149             /* Get the hardware address */
  150             stress_netdev_check(args, ifr, fd,
  151                 SIOCGIFHWADDR, "SIOCGIFHWADDR");
  152 
  153             /* Get the hardware parameters */
  154             stress_netdev_check(args, ifr, fd,
  155                 SIOCGIFMAP, "SIOCGIFMAP");
  156 
  157             /* Get the transmit queue length */
  158             stress_netdev_check(args, ifr, fd,
  159                 SIOCGIFTXQLEN, "SIOCGIFTXQLEN");
  160         }
  161         free(ifc.ifc_buf);
  162         inc_counter(args);
  163     } while (keep_stressing());
  164 
  165     (void)close(fd);
  166 
  167     return rc;
  168 }
  169 
  170 stressor_info_t stress_netdev_info = {
  171     .stressor = stress_netdev,
  172     .class = CLASS_NETWORK
  173 };
  174 #else
  175 stressor_info_t stress_netdev_info = {
  176     .stressor = stress_not_implemented,
  177     .class = CLASS_NETWORK
  178 };
  179 #endif