static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { struct { struct tc_u32_sel sel; struct tc_u32_key keys[128]; } sel; struct tcmsg *t = NLMSG_DATA(n); struct rtattr *tail; int sel_ok = 0; int sample_ok = 0; __u32 htid = 0; __u32 order = 0; memset(&sel, 0, sizeof(sel)); if (handle && get_u32_handle(&t->tcm_handle, handle)) { fprintf(stderr, "Illegal filter ID\n"); return -1; } if (argc == 0) return 0; tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len)); addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); while (argc > 0) { if (matches(*argv, "match") == 0) { NEXT_ARG(); if (parse_selector(&argc, &argv, &sel.sel)) { fprintf(stderr, "Illegal \"match\"\n"); return -1; } sel_ok++; continue; } else if (matches(*argv, "offset") == 0) { NEXT_ARG(); if (parse_offset(&argc, &argv, &sel.sel)) { fprintf(stderr, "Illegal \"offset\"\n"); return -1; } continue; } else if (matches(*argv, "hashkey") == 0) { NEXT_ARG(); if (parse_hashkey(&argc, &argv, &sel.sel)) { fprintf(stderr, "Illegal \"hashkey\"\n"); return -1; } continue; } else if (matches(*argv, "classid") == 0 || strcmp(*argv, "flowid") == 0) { unsigned handle; NEXT_ARG(); if (get_tc_classid(&handle, *argv)) { fprintf(stderr, "Illegal \"classid\"\n"); return -1; } addattr_l(n, 4096, TCA_U32_CLASSID, &handle, 4); sel.sel.flags |= TC_U32_TERMINAL; } else if (matches(*argv, "divisor") == 0) { unsigned divisor; NEXT_ARG(); if (get_unsigned(&divisor, *argv, 0) || divisor == 0 || divisor > 0x100) { fprintf(stderr, "Illegal \"divisor\"\n"); return -1; } addattr_l(n, 4096, TCA_U32_DIVISOR, &divisor, 4); } else if (matches(*argv, "order") == 0) { NEXT_ARG(); if (get_u32(&order, *argv, 0)) { fprintf(stderr, "Illegal \"order\"\n"); return -1; } } else if (strcmp(*argv, "link") == 0) { unsigned handle; NEXT_ARG(); if (get_u32_handle(&handle, *argv)) { fprintf(stderr, "Illegal \"link\"\n"); return -1; } if (handle && TC_U32_NODE(handle)) { fprintf(stderr, "\"link\" must be a hash table.\n"); return -1; } addattr_l(n, 4096, TCA_U32_LINK, &handle, 4); } else if (strcmp(*argv, "ht") == 0) { unsigned handle; NEXT_ARG(); if (get_u32_handle(&handle, *argv)) { fprintf(stderr, "Illegal \"ht\"\n"); return -1; } if (handle && TC_U32_NODE(handle)) { fprintf(stderr, "\"ht\" must be a hash table.\n"); return -1; } if (sample_ok) htid = (htid&0xFF000)|(handle&0xFFF00000); else htid = (handle&0xFFFFF000); } else if (strcmp(*argv, "sample") == 0) { __u32 hash; struct { struct tc_u32_sel sel; struct tc_u32_key keys[4]; } sel2; NEXT_ARG(); if (parse_selector(&argc, &argv, &sel2.sel)) { fprintf(stderr, "Illegal \"sample\"\n"); return -1; } if (sel2.sel.nkeys != 1) { fprintf(stderr, "\"sample\" must contain exactly ONE key.\n"); return -1; } hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask; hash ^= hash>>16; hash ^= hash>>8; htid = ((hash<<12)&0xFF000)|(htid&0xFFF00000); sample_ok = 1; continue; #ifdef TC_CONFIG_ALL } else if (matches(*argv, "police") == 0) {
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { struct { struct tc_u32_sel sel; struct tc_u32_key keys[128]; } sel; struct tcmsg *t = NLMSG_DATA(n); struct rtattr *tail; int sel_ok = 0; int sample_ok = 0; __u32 htid = 0; __u32 order = 0; memset(&sel, 0, sizeof(sel)); //fprintf(stderr, "handle[%s]\n", handle); if (handle && get_u32_handle(&t->tcm_handle, handle)) { fprintf(stderr, "Illegal filter ID\n"); return -1; } if (argc == 0) return 0; tail = NLMSG_TAIL(n); addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0); while (argc > 0) { if (matches(*argv, "match") == 0) { NEXT_ARG(); if (parse_selector(&argc, &argv, &sel.sel, n)) { fprintf(stderr, "Illegal \"match\"\n"); return -1; } sel_ok++; continue; } else if (matches(*argv, "offset") == 0) { NEXT_ARG(); if (parse_offset(&argc, &argv, &sel.sel)) { fprintf(stderr, "Illegal \"offset\"\n"); return -1; } continue; } else if (matches(*argv, "hashkey") == 0) { NEXT_ARG(); if (parse_hashkey(&argc, &argv, &sel.sel)) { fprintf(stderr, "Illegal \"hashkey\"\n"); return -1; } continue; } else if (matches(*argv, "classid") == 0 || strcmp(*argv, "flowid") == 0) { unsigned handle; NEXT_ARG(); if (get_tc_classid(&handle, *argv)) { fprintf(stderr, "Illegal \"classid\"\n"); return -1; } addattr_l(n, MAX_MSG, TCA_U32_CLASSID, &handle, 4); sel.sel.flags |= TC_U32_TERMINAL; } else if (matches(*argv, "divisor") == 0) { unsigned int divisor; fprintf(stderr, "parse divisor\n"); NEXT_ARG(); if (get_unsigned(&divisor, *argv, 0) || divisor == 0 || //divisor > 0x100 || ((divisor - 1) & divisor)) {//richie1124 divisor > 0x1000 || ((divisor - 1) & divisor)) { fprintf(stderr, "Illegal \"divisor\"\n"); return -1; } addattr_l(n, MAX_MSG, TCA_U32_DIVISOR, &divisor, 4); } else if (matches(*argv, "order") == 0) { NEXT_ARG(); if (get_u32(&order, *argv, 0)) { fprintf(stderr, "Illegal \"order\"\n"); return -1; } } else if (strcmp(*argv, "link") == 0) { unsigned handle; NEXT_ARG(); if (get_u32_handle(&handle, *argv)) { fprintf(stderr, "Illegal \"link\"\n"); return -1; } if (handle && TC_U32_NODE(handle)) { fprintf(stderr, "\"link\" must be a hash table.\n"); return -1; } addattr_l(n, MAX_MSG, TCA_U32_LINK, &handle, 4); } else if (strcmp(*argv, "ht") == 0) { unsigned handle; NEXT_ARG(); if (get_u32_handle(&handle, *argv)) { fprintf(stderr, "Illegal \"ht\"\n"); return -1; } //fprintf(stderr, "f_u32, handle[%x]\n", handle); if (handle && TC_U32_NODE(handle)) { fprintf(stderr, "\"ht\" must be a hash table.\n"); return -1; } if (sample_ok) { //htid = (htid&0xFF000)|(handle&0xFFF00000); //htid = (htid&0xFFF00)|(handle&0xFFF00000); htid = (htid&0xFFF00)|(handle&0xFFF00000);//richie1124 } else { //htid = (handle&0xFFFFF000); htid = (handle&0xFFFFFF00); //htid = (handle&0xFFFFFF00);//richie1124 } } else if (strcmp(*argv, "sample") == 0) { __u32 hash; unsigned divisor = 0x100; struct { struct tc_u32_sel sel; struct tc_u32_key keys[4]; } sel2; memset(&sel2, 0, sizeof(sel2)); NEXT_ARG(); if (parse_selector(&argc, &argv, &sel2.sel, n)) { fprintf(stderr, "Illegal \"sample\"\n"); return -1; } if (sel2.sel.nkeys != 1) { fprintf(stderr, "\"sample\" must contain exactly ONE key.\n"); return -1; } if (*argv != 0 && strcmp(*argv, "divisor") == 0) { NEXT_ARG(); if (get_unsigned(&divisor, *argv, 0) || divisor == 0 || divisor > 0x100 || ((divisor - 1) & divisor)) { fprintf(stderr, "Illegal sample \"divisor\"\n"); return -1; } NEXT_ARG(); } hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask; hash ^= hash>>16; hash ^= hash>>8; htid = ((hash%divisor)<<12)|(htid&0xFFF00000); sample_ok = 1; continue; } else if (strcmp(*argv, "indev") == 0) {