static int hfsc_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n, const char *dev) { struct tc_service_curve rsc = {}, fsc = {}, usc = {}; int rsc_ok = 0, fsc_ok = 0, usc_ok = 0; struct rtattr *tail; while (argc > 0) { if (matches(*argv, "rt") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &rsc, dev) < 0) { explain1("rt"); return -1; } rsc_ok = 1; } else if (matches(*argv, "ls") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &fsc, dev) < 0) { explain1("ls"); return -1; } fsc_ok = 1; } else if (matches(*argv, "sc") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &rsc, dev) < 0) { explain1("sc"); return -1; } memcpy(&fsc, &rsc, sizeof(fsc)); rsc_ok = 1; fsc_ok = 1; } else if (matches(*argv, "ul") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &usc, dev) < 0) { explain1("ul"); return -1; } usc_ok = 1; } else if (matches(*argv, "help") == 0) { explain_class(); return -1; } else { fprintf(stderr, "HFSC: What is \"%s\" ?\n", *argv); explain_class(); return -1; } argc--, argv++; } if (!(rsc_ok || fsc_ok || usc_ok)) { fprintf(stderr, "HFSC: no parameters given\n"); explain_class(); return -1; } if (usc_ok && !fsc_ok) { fprintf(stderr, "HFSC: Upper-limit Service Curve without Link-Share Service Curve\n"); explain_class(); return -1; } tail = addattr_nest(n, 1024, TCA_OPTIONS); if (rsc_ok) addattr_l(n, 1024, TCA_HFSC_RSC, &rsc, sizeof(rsc)); if (fsc_ok) addattr_l(n, 1024, TCA_HFSC_FSC, &fsc, sizeof(fsc)); if (usc_ok) addattr_l(n, 1024, TCA_HFSC_USC, &usc, sizeof(usc)); addattr_nest_end(n, tail); return 0; }
static void hfsc_parse_class_argv(struct rtnl_tc *tc, int argc, char **argv) { struct rtnl_class *class = (struct rtnl_class *) tc; int arg_ok = 0, ret = -EINVAL; for (;;) { int c, optidx = 0; enum { ARG_RT = 257, ARG_LS = 258, ARG_SC, ARG_UL, }; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "rt", 1, 0, ARG_RT }, { "ls", 1, 0, ARG_LS }, { "sc", 1, 0, ARG_SC }, { "ul", 1, 0, ARG_UL }, { 0, 0, 0, 0 } }; struct tc_service_curve tsc; c = getopt_long(argc, argv, "h", long_opts, &optidx); if (c == -1) break; switch (c) { case 'h': print_class_usage(); return; case ARG_RT: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_rsc(class, &tsc); arg_ok++; break; case ARG_LS: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_fsc(class, &tsc); arg_ok++; break; case ARG_SC: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_rsc(class, &tsc); rtnl_class_hfsc_set_fsc(class, &tsc); arg_ok++; break; case ARG_UL: ret = hfsc_get_sc(optarg, &tsc); if (ret < 0) { nl_cli_fatal(ret, "Unable to parse sc " "\"%s\": Invalid format.", optarg); } rtnl_class_hfsc_set_usc(class, &tsc); arg_ok++; break; } } if (!arg_ok) nl_cli_fatal(ret, "Invalid arguments"); }
static int hfsc_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { struct tc_service_curve rsc, fsc, usc; int rsc_ok, fsc_ok, usc_ok; struct rtattr *tail; memset(&rsc, 0, sizeof(rsc)); memset(&fsc, 0, sizeof(fsc)); memset(&usc, 0, sizeof(usc)); rsc_ok = fsc_ok = usc_ok = 0; while (argc > 0) { if (matches(*argv, "rt") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &rsc) < 0) { explain1("rt"); return -1; } rsc_ok = 1; } else if (matches(*argv, "ls") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &fsc) < 0) { explain1("ls"); return -1; } fsc_ok = 1; } else if (matches(*argv, "sc") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &rsc) < 0) { explain1("sc"); return -1; } memcpy(&fsc, &rsc, sizeof(fsc)); rsc_ok = 1; fsc_ok = 1; } else if (matches(*argv, "ul") == 0) { NEXT_ARG(); if (hfsc_get_sc(&argc, &argv, &usc) < 0) { explain1("ul"); return -1; } usc_ok = 1; } else if (matches(*argv, "help") == 0) { explain_class(); return -1; } else { fprintf(stderr, "HFSC: What is \"%s\" ?\n", *argv); explain_class(); return -1; } argc--, argv++; } if (!(rsc_ok || fsc_ok || usc_ok)) { fprintf(stderr, "HFSC: no parameters given\n"); explain_class(); return -1; } if (usc_ok && !fsc_ok) { fprintf(stderr, "HFSC: Upper-limit Service Curve without " "Link-Share Service Curve\n"); explain_class(); return -1; } tail = NLMSG_TAIL(n); addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); if (rsc_ok) addattr_l(n, 1024, TCA_HFSC_RSC, &rsc, sizeof(rsc)); if (fsc_ok) addattr_l(n, 1024, TCA_HFSC_FSC, &fsc, sizeof(fsc)); if (usc_ok) addattr_l(n, 1024, TCA_HFSC_USC, &usc, sizeof(usc)); tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; return 0; }