static int cgroup_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { struct tcmsg *t = NLMSG_DATA(n); struct rtattr *tail; long h = 0; if (handle) { h = strtol(handle, NULL, 0); if (h == LONG_MIN || h == LONG_MAX) { fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n", handle); return -1; } } t->tcm_handle = h; tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len)); addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0); while (argc > 0) { if (matches(*argv, "match") == 0) { NEXT_ARG(); if (parse_ematch(&argc, &argv, TCA_CGROUP_EMATCHES, n)) { fprintf(stderr, "Illegal \"ematch\"\n"); return -1; } continue; } else if (matches(*argv, "action") == 0) { NEXT_ARG(); if (parse_action(&argc, &argv, TCA_CGROUP_ACT, n)) { fprintf(stderr, "Illegal \"action\"\n"); return -1; } continue; } else if (matches(*argv, "police") == 0) { NEXT_ARG(); if (parse_police(&argc, &argv, TCA_CGROUP_POLICE, n)) { fprintf(stderr, "Illegal \"police\"\n"); return -1; } continue; } else if (strcmp(*argv, "help") == 0) { explain(); return -1; } else { fprintf(stderr, "What is \"%s\"?\n", *argv); explain(); return -1; } argc--; argv++; } tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail; return 0; }
static int flow_parse_opt(struct filter_util *fu, char *handle, int argc, char **argv, struct nlmsghdr *n) { struct tc_police tp; struct tcmsg *t = NLMSG_DATA(n); struct rtattr *tail; __u32 mask = ~0U, xor = 0; __u32 keys = 0, nkeys = 0; __u32 mode = FLOW_MODE_MAP; __u32 tmp; memset(&tp, 0, sizeof(tp)); if (handle) { if (get_u32(&t->tcm_handle, handle, 0)) { fprintf(stderr, "Illegal \"handle\"\n"); return -1; } } tail = NLMSG_TAIL(n); addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); while (argc > 0) { if (matches(*argv, "map") == 0) { mode = FLOW_MODE_MAP; } else if (matches(*argv, "hash") == 0) { mode = FLOW_MODE_HASH; } else if (matches(*argv, "keys") == 0) { NEXT_ARG(); if (flow_parse_keys(&keys, &nkeys, *argv)) return -1; addattr32(n, 4096, TCA_FLOW_KEYS, keys); } else if (matches(*argv, "and") == 0) { NEXT_ARG(); if (get_u32(&tmp, *argv, 0)) { fprintf(stderr, "Illegal \"mask\"\n"); return -1; } transfer_bitop(&mask, &xor, tmp, 0); } else if (matches(*argv, "or") == 0) { NEXT_ARG(); if (get_u32(&tmp, *argv, 0)) { fprintf(stderr, "Illegal \"or\"\n"); return -1; } transfer_bitop(&mask, &xor, ~tmp, tmp); } else if (matches(*argv, "xor") == 0) { NEXT_ARG(); if (get_u32(&tmp, *argv, 0)) { fprintf(stderr, "Illegal \"xor\"\n"); return -1; } transfer_bitop(&mask, &xor, ~0, tmp); } else if (matches(*argv, "rshift") == 0) { NEXT_ARG(); if (get_u32(&tmp, *argv, 0)) { fprintf(stderr, "Illegal \"rshift\"\n"); return -1; } addattr32(n, 4096, TCA_FLOW_RSHIFT, tmp); } else if (matches(*argv, "addend") == 0) { NEXT_ARG(); if (get_addend(&tmp, *argv, keys)) { fprintf(stderr, "Illegal \"addend\"\n"); return -1; } addattr32(n, 4096, TCA_FLOW_ADDEND, tmp); } else if (matches(*argv, "divisor") == 0) { NEXT_ARG(); if (get_u32(&tmp, *argv, 0)) { fprintf(stderr, "Illegal \"divisor\"\n"); return -1; } addattr32(n, 4096, TCA_FLOW_DIVISOR, tmp); } else if (matches(*argv, "baseclass") == 0) { NEXT_ARG(); if (get_tc_classid(&tmp, *argv) || TC_H_MIN(tmp) == 0) { fprintf(stderr, "Illegal \"baseclass\"\n"); return -1; } addattr32(n, 4096, TCA_FLOW_BASECLASS, tmp); } else if (matches(*argv, "perturb") == 0) { NEXT_ARG(); if (get_u32(&tmp, *argv, 0)) { fprintf(stderr, "Illegal \"perturb\"\n"); return -1; } addattr32(n, 4096, TCA_FLOW_PERTURB, tmp); } else if (matches(*argv, "police") == 0) { NEXT_ARG(); if (parse_police(&argc, &argv, TCA_FLOW_POLICE, n)) { fprintf(stderr, "Illegal \"police\"\n"); return -1; } continue; } else if (matches(*argv, "action") == 0) { NEXT_ARG(); if (parse_action(&argc, &argv, TCA_FLOW_ACT, n)) { fprintf(stderr, "Illegal \"action\"\n"); return -1; } continue; } else if (matches(*argv, "match") == 0) { NEXT_ARG(); if (parse_ematch(&argc, &argv, TCA_FLOW_EMATCHES, n)) { fprintf(stderr, "Illegal \"ematch\"\n"); return -1; } continue; } else if (matches(*argv, "help") == 0) { explain(); return -1; } else { fprintf(stderr, "What is \"%s\"?\n", *argv); explain(); return -1; } argv++, argc--; } if (nkeys > 1 && mode != FLOW_MODE_HASH) { fprintf(stderr, "Invalid mode \"map\" for multiple keys\n"); return -1; } addattr32(n, 4096, TCA_FLOW_MODE, mode); if (mask != ~0 || xor != 0) { addattr32(n, 4096, TCA_FLOW_MASK, mask); addattr32(n, 4096, TCA_FLOW_XOR, xor); } tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail; return 0; }