10 #include "internal/internal.h"
12 static void __build_tuple_ip(
struct nfnlhdr *req,
14 const struct __nfct_tuple *t)
18 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP);
20 switch(t->l3protonum) {
22 nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4,
24 nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4,
28 nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_SRC, &t->src.v6,
29 sizeof(
struct in6_addr));
30 nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_DST, &t->dst.v6,
31 sizeof(
struct in6_addr));
37 nfnl_nest_end(&req->nlh, nest);
40 static void __build_tuple_proto(
struct nfnlhdr *req,
42 const struct __nfct_tuple *t)
46 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_PROTO);
48 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_NUM, &t->protonum,
58 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_SRC_PORT,
59 &t->l4src.tcp.port,
sizeof(uint16_t));
60 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_DST_PORT,
61 &t->l4dst.tcp.port,
sizeof(uint16_t));
65 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_CODE,
66 &t->l4dst.icmp.code,
sizeof(uint8_t));
67 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_TYPE,
68 &t->l4dst.icmp.type,
sizeof(uint8_t));
69 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_ID,
70 &t->l4src.icmp.id,
sizeof(uint16_t));
74 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMPV6_CODE,
75 &t->l4dst.icmp.code,
sizeof(uint8_t));
76 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMPV6_TYPE,
77 &t->l4dst.icmp.type,
sizeof(uint8_t));
78 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMPV6_ID,
79 &t->l4src.icmp.id,
sizeof(uint16_t));
86 nfnl_nest_end(&req->nlh, nest);
89 static void __build_tuple_raw(
struct nfnlhdr *req,
size_t size,
90 const struct __nfct_tuple *t)
92 __build_tuple_ip(req, size, t);
93 __build_tuple_proto(req, size, t);
96 void __build_tuple(
struct nfnlhdr *req,
size_t size,
97 const struct __nfct_tuple *t,
const int type)
101 nest = nfnl_nest(&req->nlh, size, type);
102 __build_tuple_raw(req, size, t);
103 nfnl_nest_end(&req->nlh, nest);
106 static void __build_protoinfo(
struct nfnlhdr *req,
size_t size,
107 const struct nf_conntrack *ct)
109 struct nfattr *nest, *nest_proto;
111 switch(ct->head.orig.protonum) {
116 if (!(test_bit(ATTR_TCP_STATE, ct->head.set) ||
117 test_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set) ||
118 test_bit(ATTR_TCP_FLAGS_REPL, ct->head.set) ||
119 test_bit(ATTR_TCP_MASK_ORIG, ct->head.set) ||
120 test_bit(ATTR_TCP_MASK_REPL, ct->head.set) ||
121 test_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set) ||
122 test_bit(ATTR_TCP_WSCALE_REPL, ct->head.set))) {
125 nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
126 nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP);
127 if (test_bit(ATTR_TCP_STATE, ct->head.set))
128 nfnl_addattr_l(&req->nlh, size,
129 CTA_PROTOINFO_TCP_STATE,
130 &ct->protoinfo.tcp.state,
132 if (test_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set) &&
133 test_bit(ATTR_TCP_MASK_ORIG, ct->head.set))
134 nfnl_addattr_l(&req->nlh, size,
135 CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
136 &ct->protoinfo.tcp.flags[0],
137 sizeof(
struct nf_ct_tcp_flags));
138 if (test_bit(ATTR_TCP_FLAGS_REPL, ct->head.set) &&
139 test_bit(ATTR_TCP_MASK_REPL, ct->head.set))
140 nfnl_addattr_l(&req->nlh, size,
141 CTA_PROTOINFO_TCP_FLAGS_REPLY,
142 &ct->protoinfo.tcp.flags[1],
143 sizeof(
struct nf_ct_tcp_flags));
144 if (test_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set))
145 nfnl_addattr_l(&req->nlh, size,
146 CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
147 &ct->protoinfo.tcp.wscale[__DIR_ORIG],
149 if (test_bit(ATTR_TCP_WSCALE_REPL, ct->head.set))
150 nfnl_addattr_l(&req->nlh, size,
151 CTA_PROTOINFO_TCP_WSCALE_REPLY,
152 &ct->protoinfo.tcp.wscale[__DIR_REPL],
154 nfnl_nest_end(&req->nlh, nest_proto);
155 nfnl_nest_end(&req->nlh, nest);
159 if (!(test_bit(ATTR_SCTP_STATE, ct->head.set) ||
160 test_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set) ||
161 test_bit(ATTR_SCTP_VTAG_REPL, ct->head.set))) {
164 nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
165 nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_SCTP);
166 if (test_bit(ATTR_SCTP_STATE, ct->head.set))
167 nfnl_addattr_l(&req->nlh, size,
168 CTA_PROTOINFO_SCTP_STATE,
169 &ct->protoinfo.sctp.state,
171 if (test_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set))
172 nfnl_addattr32(&req->nlh, size,
173 CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
174 htonl(ct->protoinfo.sctp.vtag[__DIR_ORIG]));
175 if (test_bit(ATTR_SCTP_VTAG_REPL, ct->head.set))
176 nfnl_addattr32(&req->nlh, size,
177 CTA_PROTOINFO_SCTP_VTAG_REPLY,
178 htonl(ct->protoinfo.sctp.vtag[__DIR_REPL]));
179 nfnl_nest_end(&req->nlh, nest_proto);
180 nfnl_nest_end(&req->nlh, nest);
184 if (!(test_bit(ATTR_DCCP_STATE, ct->head.set) ||
185 test_bit(ATTR_DCCP_ROLE, ct->head.set) ||
186 test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set))) {
189 nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
190 nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_DCCP);
191 if (test_bit(ATTR_DCCP_STATE, ct->head.set))
192 nfnl_addattr_l(&req->nlh, size,
193 CTA_PROTOINFO_DCCP_STATE,
194 &ct->protoinfo.dccp.state,
196 if (test_bit(ATTR_DCCP_ROLE, ct->head.set))
197 nfnl_addattr_l(&req->nlh, size,
198 CTA_PROTOINFO_DCCP_ROLE,
199 &ct->protoinfo.dccp.role,
201 if (test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set)) {
205 uint64_t handshake_seq =
206 __be64_to_cpu(ct->protoinfo.dccp.handshake_seq);
208 nfnl_addattr_l(&req->nlh, size,
209 CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
213 nfnl_nest_end(&req->nlh, nest_proto);
214 nfnl_nest_end(&req->nlh, nest);
221 __nat_seq_adj(
struct nfnlhdr *req,
223 const struct nf_conntrack *ct,
226 nfnl_addattr32(&req->nlh,
228 CTA_NAT_SEQ_CORRECTION_POS,
229 htonl(ct->natseq[dir].correction_pos));
230 nfnl_addattr32(&req->nlh,
232 CTA_NAT_SEQ_OFFSET_BEFORE,
233 htonl(ct->natseq[dir].offset_before));
234 nfnl_addattr32(&req->nlh,
236 CTA_NAT_SEQ_OFFSET_AFTER,
237 htonl(ct->natseq[dir].offset_after));
241 __build_nat_seq_adj(
struct nfnlhdr *req,
243 const struct nf_conntrack *ct,
247 int type = (dir == __DIR_ORIG) ? CTA_NAT_SEQ_ADJ_ORIG :
248 CTA_NAT_SEQ_ADJ_REPLY;
250 nest = nfnl_nest(&req->nlh, size, type);
251 __nat_seq_adj(req, size, ct, dir);
252 nfnl_nest_end(&req->nlh, nest);
255 static void __build_protonat(
struct nfnlhdr *req,
257 const struct nf_conntrack *ct,
258 const struct __nfct_nat *nat)
262 nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO);
264 switch (ct->head.orig.protonum) {
267 nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MIN,
268 &nat->l4min.tcp.port,
sizeof(uint16_t));
269 nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MAX,
270 &nat->l4max.tcp.port,
sizeof(uint16_t));
273 nfnl_nest_end(&req->nlh, nest);
276 static void __build_nat(
struct nfnlhdr *req,
278 const struct __nfct_nat *nat,
281 switch (l3protonum) {
283 nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
284 &nat->min_ip.v4,
sizeof(uint32_t));
287 nfnl_addattr_l(&req->nlh, size, CTA_NAT_V6_MINIP,
288 &nat->min_ip.v6,
sizeof(
struct in6_addr));
295 static void __build_snat(
struct nfnlhdr *req,
297 const struct nf_conntrack *ct,
302 nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
303 __build_nat(req, size, &ct->snat, l3protonum);
304 __build_protonat(req, size, ct, &ct->snat);
305 nfnl_nest_end(&req->nlh, nest);
308 static void __build_snat_ipv4(
struct nfnlhdr *req,
310 const struct nf_conntrack *ct)
314 nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
315 __build_nat(req, size, &ct->snat, AF_INET);
316 nfnl_nest_end(&req->nlh, nest);
319 static void __build_snat_ipv6(
struct nfnlhdr *req,
321 const struct nf_conntrack *ct)
325 nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
326 __build_nat(req, size, &ct->snat, AF_INET6);
327 nfnl_nest_end(&req->nlh, nest);
330 static void __build_snat_port(
struct nfnlhdr *req,
332 const struct nf_conntrack *ct)
336 nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
337 __build_protonat(req, size, ct, &ct->snat);
338 nfnl_nest_end(&req->nlh, nest);
341 static void __build_dnat(
struct nfnlhdr *req,
343 const struct nf_conntrack *ct,
348 nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
349 __build_nat(req, size, &ct->dnat, l3protonum);
350 __build_protonat(req, size, ct, &ct->dnat);
351 nfnl_nest_end(&req->nlh, nest);
354 static void __build_dnat_ipv4(
struct nfnlhdr *req,
356 const struct nf_conntrack *ct)
360 nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
361 __build_nat(req, size, &ct->dnat, AF_INET);
362 nfnl_nest_end(&req->nlh, nest);
365 static void __build_dnat_ipv6(
struct nfnlhdr *req,
367 const struct nf_conntrack *ct)
371 nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
372 __build_nat(req, size, &ct->dnat, AF_INET6);
373 nfnl_nest_end(&req->nlh, nest);
376 static void __build_dnat_port(
struct nfnlhdr *req,
378 const struct nf_conntrack *ct)
382 nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
383 __build_protonat(req, size, ct, &ct->dnat);
384 nfnl_nest_end(&req->nlh, nest);
387 static void __build_status(
struct nfnlhdr *req,
389 const struct nf_conntrack *ct)
391 nfnl_addattr32(&req->nlh, size, CTA_STATUS,
392 htonl(ct->status | IPS_CONFIRMED));
395 static void __build_timeout(
struct nfnlhdr *req,
397 const struct nf_conntrack *ct)
399 nfnl_addattr32(&req->nlh, size, CTA_TIMEOUT, htonl(ct->timeout));
402 static void __build_mark(
struct nfnlhdr *req,
404 const struct nf_conntrack *ct)
406 nfnl_addattr32(&req->nlh, size, CTA_MARK, htonl(ct->mark));
409 static void __build_secmark(
struct nfnlhdr *req,
411 const struct nf_conntrack *ct)
413 nfnl_addattr32(&req->nlh, size, CTA_SECMARK, htonl(ct->secmark));
416 static void __build_helper_name(
struct nfnlhdr *req,
418 const struct nf_conntrack *ct)
422 nest = nfnl_nest(&req->nlh, size, CTA_HELP);
423 nfnl_addattr_l(&req->nlh,
427 strlen(ct->helper_name)+1);
428 nfnl_nest_end(&req->nlh, nest);
431 static void __build_zone(
struct nfnlhdr *req,
433 const struct nf_conntrack *ct)
435 nfnl_addattr16(&req->nlh, size, CTA_ZONE, htons(ct->zone));
438 static void __build_labels(
struct nfnlhdr *req,
440 const struct nf_conntrack *ct)
442 struct nfct_bitmask *b = ct->connlabels;
443 unsigned int b_size = b->words *
sizeof(b->bits[0]);
445 nfnl_addattr_l(&req->nlh,
451 if (test_bit(ATTR_CONNLABELS_MASK, ct->head.set)) {
452 b = ct->connlabels_mask;
453 if (b_size == (b->words *
sizeof(b->bits[0])))
454 nfnl_addattr_l(&req->nlh,
462 int __build_conntrack(
struct nfnl_subsys_handle *ssh,
467 const struct nf_conntrack *ct)
469 uint8_t l3num = ct->head.orig.l3protonum;
471 if (!test_bit(ATTR_ORIG_L3PROTO, ct->head.set)) {
476 memset(req, 0, size);
478 nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags);
480 if (test_bit(ATTR_ORIG_IPV4_SRC, ct->head.set) ||
481 test_bit(ATTR_ORIG_IPV4_DST, ct->head.set) ||
482 test_bit(ATTR_ORIG_IPV6_SRC, ct->head.set) ||
483 test_bit(ATTR_ORIG_IPV6_DST, ct->head.set) ||
484 test_bit(ATTR_ORIG_PORT_SRC, ct->head.set) ||
485 test_bit(ATTR_ORIG_PORT_DST, ct->head.set) ||
486 test_bit(ATTR_ORIG_L3PROTO, ct->head.set) ||
487 test_bit(ATTR_ORIG_L4PROTO, ct->head.set) ||
488 test_bit(ATTR_ORIG_ZONE, ct->head.set) ||
489 test_bit(ATTR_ICMP_TYPE, ct->head.set) ||
490 test_bit(ATTR_ICMP_CODE, ct->head.set) ||
491 test_bit(ATTR_ICMP_ID, ct->head.set)) {
492 const struct __nfct_tuple *t = &ct->head.orig;
495 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_ORIG);
496 __build_tuple_raw(req, size, t);
497 if (test_bit(ATTR_ORIG_ZONE, ct->head.set))
498 nfnl_addattr16(&req->nlh, size, CTA_TUPLE_ZONE,
500 nfnl_nest_end(&req->nlh, nest);
503 if (test_bit(ATTR_REPL_IPV4_SRC, ct->head.set) ||
504 test_bit(ATTR_REPL_IPV4_DST, ct->head.set) ||
505 test_bit(ATTR_REPL_IPV6_SRC, ct->head.set) ||
506 test_bit(ATTR_REPL_IPV6_DST, ct->head.set) ||
507 test_bit(ATTR_REPL_PORT_SRC, ct->head.set) ||
508 test_bit(ATTR_REPL_PORT_DST, ct->head.set) ||
509 test_bit(ATTR_REPL_L3PROTO, ct->head.set) ||
510 test_bit(ATTR_REPL_L4PROTO, ct->head.set) ||
511 test_bit(ATTR_REPL_ZONE, ct->head.set)) {
512 const struct __nfct_tuple *t = &ct->repl;
515 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_REPLY);
516 __build_tuple_raw(req, size, t);
517 if (test_bit(ATTR_REPL_ZONE, ct->head.set))
518 nfnl_addattr16(&req->nlh, size, CTA_TUPLE_ZONE,
520 nfnl_nest_end(&req->nlh, nest);
523 if (test_bit(ATTR_MASTER_IPV4_SRC, ct->head.set) ||
524 test_bit(ATTR_MASTER_IPV4_DST, ct->head.set) ||
525 test_bit(ATTR_MASTER_IPV6_SRC, ct->head.set) ||
526 test_bit(ATTR_MASTER_IPV6_DST, ct->head.set) ||
527 test_bit(ATTR_MASTER_PORT_SRC, ct->head.set) ||
528 test_bit(ATTR_MASTER_PORT_DST, ct->head.set) ||
529 test_bit(ATTR_MASTER_L3PROTO, ct->head.set) ||
530 test_bit(ATTR_MASTER_L4PROTO, ct->head.set))
531 __build_tuple(req, size, &ct->master, CTA_TUPLE_MASTER);
533 if (test_bit(ATTR_STATUS, ct->head.set))
534 __build_status(req, size, ct);
537 if (type == IPCTNL_MSG_CT_NEW && flags & NLM_F_CREATE)
538 __build_status(req, size, ct);
541 if (test_bit(ATTR_TIMEOUT, ct->head.set))
542 __build_timeout(req, size, ct);
544 if (test_bit(ATTR_MARK, ct->head.set))
545 __build_mark(req, size, ct);
547 if (test_bit(ATTR_SECMARK, ct->head.set))
548 __build_secmark(req, size, ct);
550 __build_protoinfo(req, size, ct);
552 if (test_bit(ATTR_SNAT_IPV4, ct->head.set) &&
553 test_bit(ATTR_SNAT_PORT, ct->head.set))
554 __build_snat(req, size, ct, AF_INET);
555 else if (test_bit(ATTR_SNAT_IPV6, ct->head.set) &&
556 test_bit(ATTR_SNAT_PORT, ct->head.set))
557 __build_snat(req, size, ct, AF_INET6);
558 else if (test_bit(ATTR_SNAT_IPV4, ct->head.set))
559 __build_snat_ipv4(req, size, ct);
560 else if (test_bit(ATTR_SNAT_IPV6, ct->head.set))
561 __build_snat_ipv6(req, size, ct);
562 else if (test_bit(ATTR_SNAT_PORT, ct->head.set))
563 __build_snat_port(req, size, ct);
565 if (test_bit(ATTR_DNAT_IPV4, ct->head.set) &&
566 test_bit(ATTR_DNAT_PORT, ct->head.set))
567 __build_dnat(req, size, ct, AF_INET);
568 else if (test_bit(ATTR_DNAT_IPV6, ct->head.set) &&
569 test_bit(ATTR_DNAT_PORT, ct->head.set))
570 __build_dnat(req, size, ct, AF_INET6);
571 else if (test_bit(ATTR_DNAT_IPV4, ct->head.set))
572 __build_dnat_ipv4(req, size, ct);
573 else if (test_bit(ATTR_DNAT_IPV6, ct->head.set))
574 __build_dnat_ipv6(req, size, ct);
575 else if (test_bit(ATTR_DNAT_PORT, ct->head.set))
576 __build_dnat_port(req, size, ct);
578 if (test_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->head.set) &&
579 test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->head.set) &&
580 test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->head.set))
581 __build_nat_seq_adj(req, size, ct, __DIR_ORIG);
583 if (test_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->head.set) &&
584 test_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->head.set) &&
585 test_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->head.set))
586 __build_nat_seq_adj(req, size, ct, __DIR_REPL);
588 if (test_bit(ATTR_HELPER_NAME, ct->head.set))
589 __build_helper_name(req, size, ct);
591 if (test_bit(ATTR_ZONE, ct->head.set))
592 __build_zone(req, size, ct);
594 if (test_bit(ATTR_CONNLABELS, ct->head.set))
595 __build_labels(req, size, ct);