4 * This program is free software; you can distribute 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: Herbert Xu <herbert@gondor.apana.org.au>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
24 #include <linux/tc_act/tc_nat.h>
29 fprintf(stderr
, "Usage: ... nat NAT\n"
30 "NAT := DIRECTION OLD NEW\n"
31 "DIRECTION := { ingress | egress }\n"
44 parse_nat_args(int *argc_p
, char ***argv_p
,struct tc_nat
*sel
)
47 char **argv
= *argv_p
;
53 if (matches(*argv
, "egress") == 0)
54 sel
->flags
|= TCA_NAT_FLAG_EGRESS
;
55 else if (matches(*argv
, "ingress") != 0)
60 if (get_prefix_1(&addr
, *argv
, AF_INET
))
63 sel
->old_addr
= addr
.data
[0];
64 sel
->mask
= htonl(~0u << (32 - addr
.bitlen
));
68 if (get_prefix_1(&addr
, *argv
, AF_INET
))
71 sel
->new_addr
= addr
.data
[0];
85 parse_nat(struct action_util
*a
, int *argc_p
, char ***argv_p
, int tca_id
, struct nlmsghdr
*n
)
90 char **argv
= *argv_p
;
94 memset(&sel
, 0, sizeof(sel
));
97 if (matches(*argv
, "nat") == 0) {
99 if (parse_nat_args(&argc
, &argv
, &sel
)) {
100 fprintf(stderr
, "Illegal nat construct (%s) \n",
107 } else if (matches(*argv
, "help") == 0) {
121 if (matches(*argv
, "reclassify") == 0) {
122 sel
.action
= TC_ACT_RECLASSIFY
;
125 } else if (matches(*argv
, "pipe") == 0) {
126 sel
.action
= TC_ACT_PIPE
;
129 } else if (matches(*argv
, "drop") == 0 ||
130 matches(*argv
, "shot") == 0) {
131 sel
.action
= TC_ACT_SHOT
;
134 } else if (matches(*argv
, "continue") == 0) {
135 sel
.action
= TC_ACT_UNSPEC
;
138 } else if (matches(*argv
, "pass") == 0) {
139 sel
.action
= TC_ACT_OK
;
146 if (matches(*argv
, "index") == 0) {
148 if (get_u32(&sel
.index
, *argv
, 10)) {
149 fprintf(stderr
, "Pedit: Illegal \"index\"\n");
157 tail
= NLMSG_TAIL(n
);
158 addattr_l(n
, MAX_MSG
, tca_id
, NULL
, 0);
159 addattr_l(n
, MAX_MSG
, TCA_NAT_PARMS
, &sel
, sizeof(sel
));
160 tail
->rta_len
= (char *)NLMSG_TAIL(n
) - (char *)tail
;
168 print_nat(struct action_util
*au
,FILE * f
, struct rtattr
*arg
)
171 struct rtattr
*tb
[TCA_NAT_MAX
+ 1];
180 parse_rtattr_nested(tb
, TCA_NAT_MAX
, arg
);
182 if (tb
[TCA_NAT_PARMS
] == NULL
) {
183 fprintf(f
, "[NULL nat parameters]");
186 sel
= RTA_DATA(tb
[TCA_NAT_PARMS
]);
188 len
= ffs(sel
->mask
);
189 len
= len
? 33 - len
: 0;
191 fprintf(f
, " nat %s %s/%d %s %s", sel
->flags
& TCA_NAT_FLAG_EGRESS
?
192 "egress" : "ingress",
193 format_host(AF_INET
, 4, &sel
->old_addr
, buf1
, sizeof(buf1
)),
195 format_host(AF_INET
, 4, &sel
->new_addr
, buf2
, sizeof(buf2
)),
196 action_n2a(sel
->action
, buf3
, sizeof (buf3
)));
199 if (tb
[TCA_NAT_TM
]) {
200 struct tcf_t
*tm
= RTA_DATA(tb
[TCA_NAT_TM
]);
208 struct action_util nat_action_util
= {
210 .parse_aopt
= parse_nat
,
211 .print_aopt
= print_nat
,