#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
static void explain(void)
{
- 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,
+ "Usage: ... fw [ classid CLASSID ] [ indev DEV ] [ action ACTION_SPEC ]\n");
+ fprintf(stderr,
+ " CLASSID := Push matching packets to the class identified by CLASSID with format X:Y\n");
+ fprintf(stderr,
+ " CLASSID is parsed as hexadecimal input.\n");
+ fprintf(stderr,
+ " DEV := specify device for incoming device classification.\n");
+ fprintf(stderr,
+ " ACTION_SPEC := Apply an action on matching packets.\n");
+ fprintf(stderr,
+ " NOTE: handle is represented as HANDLE[/FWMASK].\n");
+ fprintf(stderr, " FWMASK is 0xffffffff by default.\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;
-
- memset(&tp, 0, sizeof(tp));
+ __u32 mask = 0;
+ int mask_set = 0;
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));
- addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
+ tail = addattr_nest(n, 4096, TCA_OPTIONS);
+
+ if (mask_set)
+ addattr32(n, MAX_MSG, TCA_FW_MASK, mask);
while (argc > 0) {
if (matches(*argv, "classid") == 0 ||
matches(*argv, "flowid") == 0) {
- unsigned handle;
+ unsigned int handle;
+
NEXT_ARG();
if (get_tc_classid(&handle, *argv)) {
fprintf(stderr, "Illegal \"classid\"\n");
}
continue;
} else if (strcmp(*argv, "indev") == 0) {
- char d[IFNAMSIZ+1];
- memset(d, 0, sizeof (d));
+ char d[IFNAMSIZ+1] = {};
+
argc--;
argv++;
if (argc < 1) {
fprintf(stderr, "Illegal indev\n");
return -1;
}
- strncpy(d, *argv, sizeof (d) - 1);
+ strncpy(d, *argv, sizeof(d) - 1);
addattr_l(n, MAX_MSG, TCA_FW_INDEV, d, strlen(d) + 1);
} else if (strcmp(*argv, "help") == 0) {
explain();
}
argc--; argv++;
}
- tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail;
+ addattr_nest_end(n, 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));
+ parse_rtattr_nested(tb, TCA_FW_MAX, opt);
+
+ if (handle || tb[TCA_FW_MASK]) {
+ __u32 mark = 0, mask = 0;
- if (handle)
- fprintf(f, "handle 0x%x ", handle);
+ 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]);
+ tc_print_action(f, tb[TCA_FW_ACT], 0);
}
return 0;
}