void ni_netdev_set_ethtool(ni_netdev_t *dev, ni_ethtool_t *ethtool) { if (dev->ethtool) ni_ethtool_free(dev->ethtool); dev->ethtool = ethtool; }
int ni_do_ethtool(const char *caller, int argc, char **argv) { enum { OPT_HELP }; static struct option options[] = { { "help", no_argument, NULL, OPT_HELP }, { NULL, no_argument, NULL, 0 } }; int c, n, status = NI_WICKED_RC_USAGE; const struct ethtool_opt *opt; ni_netdev_ref_t ref = { 0, NULL }; ni_ethtool_t *ethtool = NULL; optind = 1; while ((c = getopt_long(argc, argv, "+", options, NULL)) != EOF) { switch (c) { case OPT_HELP: status = NI_WICKED_RC_SUCCESS; /* fall through */ default: usage: fprintf(stderr, "wicked %s [global options ...] <ifname> <action options [arguments] > ...\n" "\n" "Supported global options:\n" " --help\n" " Show this help text.\n" "\n" "Supported action options:\n" , argv[0] ); for (opt = ethtool_opts; opt && opt->name; opt++) ethtool_opt_usage(opt); goto cleanup; } } if (optind >= argc) { fprintf(stderr, "%s: missing interface argument\n\n", argv[0]); goto usage; } if (optind + 1 >= argc) { fprintf(stderr, "%s: missing interface action option\n\n", argv[0]); goto usage; } status = NI_WICKED_RC_ERROR; ni_netdev_ref_init(&ref, argv[optind], if_nametoindex(argv[optind])); if (!ref.index) { fprintf(stderr, "%s: cannot find interface with name '%s'\n", argv[0], argv[optind]); goto cleanup; } if (!(ethtool = ni_ethtool_new())) { fprintf(stderr, "%s: cannot allocate ethtool parameters for '%s'\n", argv[0], ref.name); goto cleanup; } status = NI_WICKED_RC_SUCCESS; for (n = ++optind; n < argc; ) { if ((opt = ethtool_opt_find(ethtool_opts, argv[n]))) { struct ethtool_args args; char * argn; ethtool_args_set(&args, &argn, argc - n - 1, argv + n + 1); n += args.argc + 1; if (opt->func(&ref, ethtool, &args) < 0) status = NI_WICKED_RC_ERROR; argv[n] = argn; } else if (!ni_string_eq(argv[n], "--")) { fprintf(stderr, "%s: unknown interface action option '%s'\n\n", argv[0], argv[n]); status = NI_WICKED_RC_USAGE; goto cleanup; } else n++; } cleanup: ni_ethtool_free(ethtool); ni_netdev_ref_destroy(&ref); return status; }