4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
22 #include <linux/if.h> /* IFNAMSIZ */
26 static void explain(void)
28 fprintf(stderr
, "Usage: ... fw [ classid CLASSID ] [ police POLICE_SPEC ]\n");
29 fprintf(stderr
, " POLICE_SPEC := ... look at TBF\n");
30 fprintf(stderr
, " CLASSID := X:Y\n");
33 #define usage() return(-1)
35 static int fw_parse_opt(struct filter_util
*qu
, char *handle
, int argc
, char **argv
, struct nlmsghdr
*n
)
38 struct tcmsg
*t
= NLMSG_DATA(n
);
41 memset(&tp
, 0, sizeof(tp
));
44 if (get_u32(&t
->tcm_handle
, handle
, 0)) {
45 fprintf(stderr
, "Illegal \"handle\"\n");
54 addattr_l(n
, 4096, TCA_OPTIONS
, NULL
, 0);
57 if (matches(*argv
, "classid") == 0 ||
58 matches(*argv
, "flowid") == 0) {
61 if (get_tc_classid(&handle
, *argv
)) {
62 fprintf(stderr
, "Illegal \"classid\"\n");
65 addattr_l(n
, 4096, TCA_FW_CLASSID
, &handle
, 4);
66 } else if (matches(*argv
, "police") == 0) {
68 if (parse_police(&argc
, &argv
, TCA_FW_POLICE
, n
)) {
69 fprintf(stderr
, "Illegal \"police\"\n");
73 } else if (matches(*argv
, "action") == 0) {
75 if (parse_action(&argc
, &argv
, TCA_FW_ACT
, n
)) {
76 fprintf(stderr
, "Illegal fw \"action\"\n");
80 } else if (strcmp(*argv
, "indev") == 0) {
82 memset(d
, 0, sizeof (d
));
86 fprintf(stderr
, "Illegal indev\n");
89 strncpy(d
, *argv
, sizeof (d
) - 1);
90 addattr_l(n
, MAX_MSG
, TCA_FW_INDEV
, d
, strlen(d
) + 1);
91 } else if (strcmp(*argv
, "help") == 0) {
95 fprintf(stderr
, "What is \"%s\"?\n", *argv
);
101 tail
->rta_len
= (void *) NLMSG_TAIL(n
) - (void *) tail
;
105 static int fw_print_opt(struct filter_util
*qu
, FILE *f
, struct rtattr
*opt
, __u32 handle
)
107 struct rtattr
*tb
[TCA_FW_MAX
+1];
112 parse_rtattr_nested(tb
, TCA_FW_MAX
, opt
);
115 fprintf(f
, "handle 0x%x ", handle
);
117 if (tb
[TCA_FW_CLASSID
]) {
119 fprintf(f
, "classid %s ", sprint_tc_classid(*(__u32
*)RTA_DATA(tb
[TCA_FW_CLASSID
]), b1
));
122 if (tb
[TCA_FW_POLICE
])
123 tc_print_police(f
, tb
[TCA_FW_POLICE
]);
124 if (tb
[TCA_FW_INDEV
]) {
125 struct rtattr
*idev
= tb
[TCA_FW_INDEV
];
126 fprintf(f
, "input dev %s ",(char *)RTA_DATA(idev
));
129 if (tb
[TCA_FW_ACT
]) {
131 tc_print_action(f
, tb
[TCA_FW_ACT
]);
136 struct filter_util fw_filter_util
= {
138 .parse_fopt
= fw_parse_opt
,
139 .print_fopt
= fw_print_opt
,