23 #include <sys/types.h>
24 #include <linux/netfilter/nfnetlink_conntrack.h>
26 #include <netlink-private/netlink.h>
27 #include <netlink/attr.h>
28 #include <netlink/netfilter/nfnl.h>
29 #include <netlink/netfilter/ct.h>
31 static struct nl_cache_ops nfnl_ct_ops;
33 #if __BYTE_ORDER == __BIG_ENDIAN
34 static uint64_t ntohll(uint64_t x)
38 #elif __BYTE_ORDER == __LITTLE_ENDIAN
39 static uint64_t ntohll(uint64_t x)
45 static struct nla_policy ct_policy[CTA_MAX+1] = {
48 [CTA_STATUS] = { .type =
NLA_U32 },
52 [CTA_TIMEOUT] = { .type =
NLA_U32 },
53 [CTA_MARK] = { .type =
NLA_U32 },
56 [CTA_USE] = { .type =
NLA_U32 },
61 static struct nla_policy ct_tuple_policy[CTA_TUPLE_MAX+1] = {
66 static struct nla_policy ct_ip_policy[CTA_IP_MAX+1] = {
68 [CTA_IP_V4_DST] = { .type =
NLA_U32 },
69 [CTA_IP_V6_SRC] = { .minlen = 16 },
70 [CTA_IP_V6_DST] = { .minlen = 16 },
73 static struct nla_policy ct_proto_policy[CTA_PROTO_MAX+1] = {
75 [CTA_PROTO_SRC_PORT] = { .type =
NLA_U16 },
76 [CTA_PROTO_DST_PORT] = { .type =
NLA_U16 },
77 [CTA_PROTO_ICMP_ID] = { .type =
NLA_U16 },
78 [CTA_PROTO_ICMP_TYPE] = { .type =
NLA_U8 },
79 [CTA_PROTO_ICMP_CODE] = { .type =
NLA_U8 },
80 [CTA_PROTO_ICMPV6_ID] = { .type =
NLA_U16 },
81 [CTA_PROTO_ICMPV6_TYPE] = { .type =
NLA_U8 },
82 [CTA_PROTO_ICMPV6_CODE] = { .type =
NLA_U8 },
85 static struct nla_policy ct_protoinfo_policy[CTA_PROTOINFO_MAX+1] = {
89 static struct nla_policy ct_protoinfo_tcp_policy[CTA_PROTOINFO_TCP_MAX+1] = {
90 [CTA_PROTOINFO_TCP_STATE] = { .
type =
NLA_U8 },
91 [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type =
NLA_U8 },
92 [CTA_PROTOINFO_TCP_WSCALE_REPLY] = { .type =
NLA_U8 },
93 [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .minlen = 2 },
94 [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .minlen = 2 },
98 static struct nla_policy ct_counters_policy[CTA_COUNTERS_MAX+1] = {
100 [CTA_COUNTERS_BYTES] = { .type =
NLA_U64 },
101 [CTA_COUNTERS32_PACKETS]= { .type =
NLA_U32 },
102 [CTA_COUNTERS32_BYTES] = { .type =
NLA_U32 },
105 static int ct_parse_ip(
struct nfnl_ct *ct,
int repl,
struct nlattr *attr)
107 struct nlattr *tb[CTA_IP_MAX+1];
108 struct nl_addr *addr;
115 if (tb[CTA_IP_V4_SRC]) {
119 err = nfnl_ct_set_src(ct, repl, addr);
124 if (tb[CTA_IP_V4_DST]) {
128 err = nfnl_ct_set_dst(ct, repl, addr);
133 if (tb[CTA_IP_V6_SRC]) {
137 err = nfnl_ct_set_src(ct, repl, addr);
142 if (tb[CTA_IP_V6_DST]) {
146 err = nfnl_ct_set_dst(ct, repl, addr);
160 static int ct_parse_proto(
struct nfnl_ct *ct,
int repl,
struct nlattr *attr)
162 struct nlattr *tb[CTA_PROTO_MAX+1];
169 if (!repl && tb[CTA_PROTO_NUM])
170 nfnl_ct_set_proto(ct,
nla_get_u8(tb[CTA_PROTO_NUM]));
171 if (tb[CTA_PROTO_SRC_PORT])
172 nfnl_ct_set_src_port(ct, repl,
174 if (tb[CTA_PROTO_DST_PORT])
175 nfnl_ct_set_dst_port(ct, repl,
178 if (ct->ct_family == AF_INET) {
179 if (tb[CTA_PROTO_ICMP_ID])
180 nfnl_ct_set_icmp_id(ct, repl,
182 if (tb[CTA_PROTO_ICMP_TYPE])
183 nfnl_ct_set_icmp_type(ct, repl,
185 if (tb[CTA_PROTO_ICMP_CODE])
186 nfnl_ct_set_icmp_code(ct, repl,
188 }
else if (ct->ct_family == AF_INET6) {
189 if (tb[CTA_PROTO_ICMPV6_ID])
190 nfnl_ct_set_icmp_id(ct, repl,
192 if (tb[CTA_PROTO_ICMPV6_TYPE])
193 nfnl_ct_set_icmp_type(ct, repl,
195 if (tb[CTA_PROTO_ICMPV6_CODE])
196 nfnl_ct_set_icmp_code(ct, repl,
203 static int ct_parse_tuple(
struct nfnl_ct *ct,
int repl,
struct nlattr *attr)
205 struct nlattr *tb[CTA_TUPLE_MAX+1];
212 if (tb[CTA_TUPLE_IP]) {
213 err = ct_parse_ip(ct, repl, tb[CTA_TUPLE_IP]);
218 if (tb[CTA_TUPLE_PROTO]) {
219 err = ct_parse_proto(ct, repl, tb[CTA_TUPLE_PROTO]);
227 static int ct_parse_protoinfo_tcp(
struct nfnl_ct *ct,
struct nlattr *attr)
229 struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
233 ct_protoinfo_tcp_policy);
237 if (tb[CTA_PROTOINFO_TCP_STATE])
238 nfnl_ct_set_tcp_state(ct,
244 static int ct_parse_protoinfo(
struct nfnl_ct *ct,
struct nlattr *attr)
246 struct nlattr *tb[CTA_PROTOINFO_MAX+1];
250 ct_protoinfo_policy);
254 if (tb[CTA_PROTOINFO_TCP]) {
255 err = ct_parse_protoinfo_tcp(ct, tb[CTA_PROTOINFO_TCP]);
263 static int ct_parse_counters(
struct nfnl_ct *ct,
int repl,
struct nlattr *attr)
265 struct nlattr *tb[CTA_COUNTERS_MAX+1];
272 if (tb[CTA_COUNTERS_PACKETS])
273 nfnl_ct_set_packets(ct, repl,
275 if (tb[CTA_COUNTERS32_PACKETS])
276 nfnl_ct_set_packets(ct, repl,
278 if (tb[CTA_COUNTERS_BYTES])
279 nfnl_ct_set_bytes(ct, repl,
281 if (tb[CTA_COUNTERS32_BYTES])
282 nfnl_ct_set_bytes(ct, repl,
288 int nfnlmsg_ct_group(
struct nlmsghdr *nlh)
291 case IPCTNL_MSG_CT_NEW:
292 if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL))
293 return NFNLGRP_CONNTRACK_NEW;
295 return NFNLGRP_CONNTRACK_UPDATE;
296 case IPCTNL_MSG_CT_DELETE:
297 return NFNLGRP_CONNTRACK_DESTROY;
303 int nfnlmsg_ct_parse(
struct nlmsghdr *nlh,
struct nfnl_ct **result)
306 struct nlattr *tb[CTA_MAX+1];
309 ct = nfnl_ct_alloc();
313 ct->ce_msgtype = nlh->nlmsg_type;
315 err =
nlmsg_parse(nlh,
sizeof(
struct nfgenmsg), tb, CTA_MAX,
322 if (tb[CTA_TUPLE_ORIG]) {
323 err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]);
327 if (tb[CTA_TUPLE_REPLY]) {
328 err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]);
333 if (tb[CTA_PROTOINFO]) {
334 err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]);
340 nfnl_ct_set_status(ct, ntohl(
nla_get_u32(tb[CTA_STATUS])));
342 nfnl_ct_set_timeout(ct, ntohl(
nla_get_u32(tb[CTA_TIMEOUT])));
344 nfnl_ct_set_mark(ct, ntohl(
nla_get_u32(tb[CTA_MARK])));
346 nfnl_ct_set_use(ct, ntohl(
nla_get_u32(tb[CTA_USE])));
348 nfnl_ct_set_id(ct, ntohl(
nla_get_u32(tb[CTA_ID])));
350 if (tb[CTA_COUNTERS_ORIG]) {
351 err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]);
356 if (tb[CTA_COUNTERS_REPLY]) {
357 err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]);
370 static int ct_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
371 struct nlmsghdr *nlh,
struct nl_parser_param *pp)
376 if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0)
379 err = pp->pp_cb((
struct nl_object *) ct, pp);
385 int nfnl_ct_dump_request(
struct nl_sock *sk)
388 NLM_F_DUMP, AF_UNSPEC, 0);
391 static int ct_request_update(
struct nl_cache *cache,
struct nl_sock *sk)
393 return nfnl_ct_dump_request(sk);
396 static int nfnl_ct_build_tuple(
struct nl_msg *msg,
const struct nfnl_ct *ct,
399 struct nlattr *tuple, *ip, *proto;
400 struct nl_addr *addr;
403 family = nfnl_ct_get_family(ct);
405 tuple =
nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG);
407 goto nla_put_failure;
411 goto nla_put_failure;
413 addr = nfnl_ct_get_src(ct, repl);
416 family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC,
419 addr = nfnl_ct_get_dst(ct, repl);
422 family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST,
429 goto nla_put_failure;
431 if (nfnl_ct_test_proto(ct))
432 NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_ct_get_proto(ct));
434 if (nfnl_ct_test_src_port(ct, repl))
436 htons(nfnl_ct_get_src_port(ct, repl)));
438 if (nfnl_ct_test_dst_port(ct, repl))
440 htons(nfnl_ct_get_dst_port(ct, repl)));
442 if (family == AF_INET) {
443 if (nfnl_ct_test_icmp_id(ct, repl))
445 htons(nfnl_ct_get_icmp_id(ct, repl)));
447 if (nfnl_ct_test_icmp_type(ct, repl))
449 nfnl_ct_get_icmp_type(ct, repl));
451 if (nfnl_ct_test_icmp_code(ct, repl))
453 nfnl_ct_get_icmp_code(ct, repl));
454 }
else if (family == AF_INET6) {
455 if (nfnl_ct_test_icmp_id(ct, repl))
457 htons(nfnl_ct_get_icmp_id(ct, repl)));
459 if (nfnl_ct_test_icmp_type(ct, repl))
461 nfnl_ct_get_icmp_type(ct, repl));
463 if (nfnl_ct_test_icmp_code(ct, repl))
465 nfnl_ct_get_icmp_code(ct, repl));
477 static int nfnl_ct_build_message(
const struct nfnl_ct *ct,
int cmd,
int flags,
478 struct nl_msg **result)
484 nfnl_ct_get_family(ct), 0);
488 if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0)
499 int nfnl_ct_build_add_request(
const struct nfnl_ct *ct,
int flags,
500 struct nl_msg **result)
502 return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result);
505 int nfnl_ct_add(
struct nl_sock *sk,
const struct nfnl_ct *ct,
int flags)
510 if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0)
518 return wait_for_ack(sk);
521 int nfnl_ct_build_delete_request(
const struct nfnl_ct *ct,
int flags,
522 struct nl_msg **result)
524 return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result);
527 int nfnl_ct_del(
struct nl_sock *sk,
const struct nfnl_ct *ct,
int flags)
532 if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0)
540 return wait_for_ack(sk);
543 int nfnl_ct_build_query_request(
const struct nfnl_ct *ct,
int flags,
544 struct nl_msg **result)
546 return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result);
549 int nfnl_ct_query(
struct nl_sock *sk,
const struct nfnl_ct *ct,
int flags)
554 if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0)
562 return wait_for_ack(sk);
594 static struct nl_af_group ct_groups[] = {
595 { AF_UNSPEC, NFNLGRP_CONNTRACK_NEW },
596 { AF_UNSPEC, NFNLGRP_CONNTRACK_UPDATE },
597 { AF_UNSPEC, NFNLGRP_CONNTRACK_DESTROY },
598 { END_OF_GROUP_LIST },
601 #define NFNLMSG_CT_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_CTNETLINK, (type))
602 static struct nl_cache_ops nfnl_ct_ops = {
603 .co_name =
"netfilter/ct",
604 .co_hdrsize = NFNL_HDRLEN,
606 { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_NEW), NL_ACT_NEW,
"new" },
607 { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_GET), NL_ACT_GET,
"get" },
608 { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_DELETE), NL_ACT_DEL,
"del" },
609 END_OF_MSGTYPES_LIST,
611 .co_protocol = NETLINK_NETFILTER,
612 .co_groups = ct_groups,
613 .co_request_update = ct_request_update,
614 .co_msg_parser = ct_msg_parser,
615 .co_obj_ops = &ct_obj_ops,
618 static void __init ct_init(
void)
623 static void __exit ct_exit(
void)