1 /* 2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo (at) netfilter.org> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10 #include "internal/internal.h" 11 12 static void __build_tuple_ip(struct nfnlhdr *req, 13 size_t size, 14 const struct __nfct_tuple *t) 15 { 16 struct nfattr *nest; 17 18 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP); 19 20 switch(t->l3protonum) { 21 case AF_INET: 22 nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4, 23 sizeof(uint32_t)); 24 nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4, 25 sizeof(uint32_t)); 26 break; 27 case AF_INET6: 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)); 32 break; 33 default: 34 break; 35 } 36 37 nfnl_nest_end(&req->nlh, nest); 38 } 39 40 static void __build_tuple_proto(struct nfnlhdr *req, 41 size_t size, 42 const struct __nfct_tuple *t) 43 { 44 struct nfattr *nest; 45 46 nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_PROTO); 47 48 nfnl_addattr_l(&req->nlh, size, CTA_PROTO_NUM, &t->protonum, 49 sizeof(uint8_t)); 50 51 switch(t->protonum) { 52 case IPPROTO_UDP: 53 case IPPROTO_TCP: 54 case IPPROTO_SCTP: 55 case IPPROTO_DCCP: 56 case IPPROTO_GRE: 57 case IPPROTO_UDPLITE: 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)); 62 break; 63 64 case IPPROTO_ICMP: 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)); 71 break; 72 73 case IPPROTO_ICMPV6: 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)); 80 break; 81 82 default: 83 break; 84 } 85 86 nfnl_nest_end(&req->nlh, nest); 87 } 88 89 static void __build_tuple_raw(struct nfnlhdr *req, size_t size, 90 const struct __nfct_tuple *t) 91 { 92 __build_tuple_ip(req, size, t); 93 __build_tuple_proto(req, size, t); 94 } 95 96 void __build_tuple(struct nfnlhdr *req, size_t size, 97 const struct __nfct_tuple *t, const int type) 98 { 99 struct nfattr *nest; 100 101 nest = nfnl_nest(&req->nlh, size, type); 102 __build_tuple_raw(req, size, t); 103 nfnl_nest_end(&req->nlh, nest); 104 } 105 106 static void __build_protoinfo(struct nfnlhdr *req, size_t size, 107 const struct nf_conntrack *ct) 108 { 109 struct nfattr *nest, *nest_proto; 110 111 switch(ct->head.orig.protonum) { 112 case IPPROTO_TCP: 113 /* Preliminary attribute check to avoid sending an empty 114 * CTA_PROTOINFO_TCP nest, which results in EINVAL in 115 * Linux kernel <= 2.6.25. */ 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))) { 123 break; 124 } 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, 131 sizeof(uint8_t)); 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], 148 sizeof(uint8_t)); 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], 153 sizeof(uint8_t)); 154 nfnl_nest_end(&req->nlh, nest_proto); 155 nfnl_nest_end(&req->nlh, nest); 156 break; 157 case IPPROTO_SCTP: 158 /* See comment above on TCP. */ 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))) { 162 break; 163 } 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, 170 sizeof(uint8_t)); 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); 181 break; 182 case IPPROTO_DCCP: 183 /* See comment above on TCP. */ 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))) { 187 break; 188 } 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, 195 sizeof(uint8_t)); 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, 200 sizeof(uint8_t)); 201 if (test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set)) { 202 /* FIXME: use __cpu_to_be64() instead which is the 203 * correct operation. This is a semantic abuse but 204 * we have no function to do it in libnfnetlink. */ 205 uint64_t handshake_seq = 206 __be64_to_cpu(ct->protoinfo.dccp.handshake_seq); 207 208 nfnl_addattr_l(&req->nlh, size, 209 CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ, 210 &handshake_seq, 211 sizeof(uint64_t)); 212 } 213 nfnl_nest_end(&req->nlh, nest_proto); 214 nfnl_nest_end(&req->nlh, nest); 215 default: 216 break; 217 } 218 } 219 220 static inline void 221 __nat_seq_adj(struct nfnlhdr *req, 222 size_t size, 223 const struct nf_conntrack *ct, 224 int dir) 225 { 226 nfnl_addattr32(&req->nlh, 227 size, 228 CTA_NAT_SEQ_CORRECTION_POS, 229 htonl(ct->natseq[dir].correction_pos)); 230 nfnl_addattr32(&req->nlh, 231 size, 232 CTA_NAT_SEQ_OFFSET_BEFORE, 233 htonl(ct->natseq[dir].offset_before)); 234 nfnl_addattr32(&req->nlh, 235 size, 236 CTA_NAT_SEQ_OFFSET_AFTER, 237 htonl(ct->natseq[dir].offset_after)); 238 } 239 240 static void 241 __build_nat_seq_adj(struct nfnlhdr *req, 242 size_t size, 243 const struct nf_conntrack *ct, 244 int dir) 245 { 246 struct nfattr *nest; 247 int type = (dir == __DIR_ORIG) ? CTA_NAT_SEQ_ADJ_ORIG : 248 CTA_NAT_SEQ_ADJ_REPLY; 249 250 nest = nfnl_nest(&req->nlh, size, type); 251 __nat_seq_adj(req, size, ct, dir); 252 nfnl_nest_end(&req->nlh, nest); 253 } 254 255 static void __build_protonat(struct nfnlhdr *req, 256 size_t size, 257 const struct nf_conntrack *ct, 258 const struct __nfct_nat *nat) 259 { 260 struct nfattr *nest; 261 262 nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO); 263 264 switch (ct->head.orig.protonum) { 265 case IPPROTO_TCP: 266 case IPPROTO_UDP: 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)); 271 break; 272 } 273 nfnl_nest_end(&req->nlh, nest); 274 } 275 276 static void __build_nat(struct nfnlhdr *req, 277 size_t size, 278 const struct __nfct_nat *nat, 279 uint8_t l3protonum) 280 { 281 switch (l3protonum) { 282 case AF_INET: 283 nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP, 284 &nat->min_ip.v4, sizeof(uint32_t)); 285 break; 286 case AF_INET6: 287 nfnl_addattr_l(&req->nlh, size, CTA_NAT_V6_MINIP, 288 &nat->min_ip.v6, sizeof(struct in6_addr)); 289 break; 290 default: 291 break; 292 } 293 } 294 295 static void __build_snat(struct nfnlhdr *req, 296 size_t size, 297 const struct nf_conntrack *ct, 298 uint8_t l3protonum) 299 { 300 struct nfattr *nest; 301 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); 306 } 307 308 static void __build_snat_ipv4(struct nfnlhdr *req, 309 size_t size, 310 const struct nf_conntrack *ct) 311 { 312 struct nfattr *nest; 313 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); 317 } 318 319 static void __build_snat_ipv6(struct nfnlhdr *req, 320 size_t size, 321 const struct nf_conntrack *ct) 322 { 323 struct nfattr *nest; 324 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); 328 } 329 330 static void __build_snat_port(struct nfnlhdr *req, 331 size_t size, 332 const struct nf_conntrack *ct) 333 { 334 struct nfattr *nest; 335 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); 339 } 340 341 static void __build_dnat(struct nfnlhdr *req, 342 size_t size, 343 const struct nf_conntrack *ct, 344 uint8_t l3protonum) 345 { 346 struct nfattr *nest; 347 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); 352 } 353 354 static void __build_dnat_ipv4(struct nfnlhdr *req, 355 size_t size, 356 const struct nf_conntrack *ct) 357 { 358 struct nfattr *nest; 359 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); 363 } 364 365 static void __build_dnat_ipv6(struct nfnlhdr *req, 366 size_t size, 367 const struct nf_conntrack *ct) 368 { 369 struct nfattr *nest; 370 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); 374 } 375 376 static void __build_dnat_port(struct nfnlhdr *req, 377 size_t size, 378 const struct nf_conntrack *ct) 379 { 380 struct nfattr *nest; 381 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); 385 } 386 387 static void __build_status(struct nfnlhdr *req, 388 size_t size, 389 const struct nf_conntrack *ct) 390 { 391 nfnl_addattr32(&req->nlh, size, CTA_STATUS, 392 htonl(ct->status | IPS_CONFIRMED)); 393 } 394 395 static void __build_timeout(struct nfnlhdr *req, 396 size_t size, 397 const struct nf_conntrack *ct) 398 { 399 nfnl_addattr32(&req->nlh, size, CTA_TIMEOUT, htonl(ct->timeout)); 400 } 401 402 static void __build_mark(struct nfnlhdr *req, 403 size_t size, 404 const struct nf_conntrack *ct) 405 { 406 nfnl_addattr32(&req->nlh, size, CTA_MARK, htonl(ct->mark)); 407 } 408 409 static void __build_secmark(struct nfnlhdr *req, 410 size_t size, 411 const struct nf_conntrack *ct) 412 { 413 nfnl_addattr32(&req->nlh, size, CTA_SECMARK, htonl(ct->secmark)); 414 } 415 416 static void __build_helper_name(struct nfnlhdr *req, 417 size_t size, 418 const struct nf_conntrack *ct) 419 { 420 struct nfattr *nest; 421 422 nest = nfnl_nest(&req->nlh, size, CTA_HELP); 423 nfnl_addattr_l(&req->nlh, 424 size, 425 CTA_HELP_NAME, 426 ct->helper_name, 427 strlen(ct->helper_name)+1); 428 nfnl_nest_end(&req->nlh, nest); 429 } 430 431 static void __build_zone(struct nfnlhdr *req, 432 size_t size, 433 const struct nf_conntrack *ct) 434 { 435 nfnl_addattr16(&req->nlh, size, CTA_ZONE, htons(ct->zone)); 436 } 437 438 static void __build_labels(struct nfnlhdr *req, 439 size_t size, 440 const struct nf_conntrack *ct) 441 { 442 struct nfct_bitmask *b = ct->connlabels; 443 unsigned int b_size = b->words * sizeof(b->bits[0]); 444 445 nfnl_addattr_l(&req->nlh, 446 size, 447 CTA_LABELS, 448 b->bits, 449 b_size); 450 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, 455 size, 456 CTA_LABELS_MASK, 457 b->bits, 458 b_size); 459 } 460 } 461 462 int __build_conntrack(struct nfnl_subsys_handle *ssh, 463 struct nfnlhdr *req, 464 size_t size, 465 uint16_t type, 466 uint16_t flags, 467 const struct nf_conntrack *ct) 468 { 469 uint8_t l3num = ct->head.orig.l3protonum; 470 471 if (!test_bit(ATTR_ORIG_L3PROTO, ct->head.set)) { 472 errno = EINVAL; 473 return -1; 474 } 475 476 memset(req, 0, size); 477 478 nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags); 479 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; 493 struct nfattr *nest; 494 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, 499 htons(t->zone)); 500 nfnl_nest_end(&req->nlh, nest); 501 } 502 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; 513 struct nfattr *nest; 514 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, 519 htons(t->zone)); 520 nfnl_nest_end(&req->nlh, nest); 521 } 522 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); 532 533 if (test_bit(ATTR_STATUS, ct->head.set)) 534 __build_status(req, size, ct); 535 else { 536 /* build IPS_CONFIRMED if we're creating a new conntrack */ 537 if (type == IPCTNL_MSG_CT_NEW && flags & NLM_F_CREATE) 538 __build_status(req, size, ct); 539 } 540 541 if (test_bit(ATTR_TIMEOUT, ct->head.set)) 542 __build_timeout(req, size, ct); 543 544 if (test_bit(ATTR_MARK, ct->head.set)) 545 __build_mark(req, size, ct); 546 547 if (test_bit(ATTR_SECMARK, ct->head.set)) 548 __build_secmark(req, size, ct); 549 550 __build_protoinfo(req, size, ct); 551 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); 564 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); 577 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); 582 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); 587 588 if (test_bit(ATTR_HELPER_NAME, ct->head.set)) 589 __build_helper_name(req, size, ct); 590 591 if (test_bit(ATTR_ZONE, ct->head.set)) 592 __build_zone(req, size, ct); 593 594 if (test_bit(ATTR_CONNLABELS, ct->head.set)) 595 __build_labels(req, size, ct); 596 597 return 0; 598 } 599