fprintf(stderr, "Usage: ... fw [ classid CLASSID ] [ police POLICE_SPEC ]\n");
fprintf(stderr, " POLICE_SPEC := ... look at TBF\n");
fprintf(stderr, " CLASSID := X:Y\n");
+ fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
-#define usage() return(-1)
-
static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
struct tc_police tp;
struct tcmsg *t = NLMSG_DATA(n);
struct rtattr *tail;
+ __u32 mask = 0;
+ int mask_set = 0;
memset(&tp, 0, sizeof(tp));
if (handle) {
+ char *slash;
+ if ((slash = strchr(handle, '/')) != NULL)
+ *slash = '\0';
if (get_u32(&t->tcm_handle, handle, 0)) {
fprintf(stderr, "Illegal \"handle\"\n");
return -1;
}
+ if (slash) {
+ if (get_u32(&mask, slash+1, 0)) {
+ fprintf(stderr, "Illegal \"handle\" mask\n");
+ return -1;
+ }
+ mask_set = 1;
+ }
}
if (argc == 0)
return 0;
- tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
+ tail = NLMSG_TAIL(n);
addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
+ if (mask_set)
+ addattr32(n, MAX_MSG, TCA_FW_MASK, mask);
+
while (argc > 0) {
if (matches(*argv, "classid") == 0 ||
matches(*argv, "flowid") == 0) {
}
argc--; argv++;
}
- tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail;
+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
return 0;
}
if (opt == NULL)
return 0;
- memset(tb, 0, sizeof(tb));
- if (opt)
- parse_rtattr(tb, TCA_FW_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt));
-
- if (handle)
- fprintf(f, "handle 0x%x ", handle);
+ parse_rtattr_nested(tb, TCA_FW_MAX, opt);
+
+ if (handle || tb[TCA_FW_MASK]) {
+ __u32 mark = 0, mask = 0;
+ if(handle)
+ mark = handle;
+ if(tb[TCA_FW_MASK] &&
+ (mask = rta_getattr_u32(tb[TCA_FW_MASK])) != 0xFFFFFFFF)
+ fprintf(f, "handle 0x%x/0x%x ", mark, mask);
+ else
+ fprintf(f, "handle 0x%x ", handle);
+ }
if (tb[TCA_FW_CLASSID]) {
SPRINT_BUF(b1);
- fprintf(f, "classid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_FW_CLASSID]), b1));
+ fprintf(f, "classid %s ", sprint_tc_classid(rta_getattr_u32(tb[TCA_FW_CLASSID]), b1));
}
if (tb[TCA_FW_POLICE])
tc_print_police(f, tb[TCA_FW_POLICE]);
if (tb[TCA_FW_INDEV]) {
struct rtattr *idev = tb[TCA_FW_INDEV];
- fprintf(f, "input dev %s ",(char *)RTA_DATA(idev));
+ fprintf(f, "input dev %s ",rta_getattr_str(idev));
}
-
+
if (tb[TCA_FW_ACT]) {
fprintf(f, "\n");
tc_print_action(f, tb[TCA_FW_ACT]);
return 0;
}
-struct filter_util fw_util = {
- NULL,
- "fw",
- fw_parse_opt,
- fw_print_opt,
+struct filter_util fw_filter_util = {
+ .id = "fw",
+ .parse_fopt = fw_parse_opt,
+ .print_fopt = fw_print_opt,
};