1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2013 Patrick McHardy <kaber@trash.net> 4 */ 5 6 #include <linux/module.h> 7 #include <linux/skbuff.h> 8 #include <asm/unaligned.h> 9 #include <net/tcp.h> 10 #include <net/netns/generic.h> 11 #include <linux/proc_fs.h> 12 13 #include <linux/netfilter_ipv6.h> 14 #include <linux/netfilter/nf_synproxy.h> 15 16 #include <net/netfilter/nf_conntrack.h> 17 #include <net/netfilter/nf_conntrack_ecache.h> 18 #include <net/netfilter/nf_conntrack_extend.h> 19 #include <net/netfilter/nf_conntrack_seqadj.h> 20 #include <net/netfilter/nf_conntrack_synproxy.h> 21 #include <net/netfilter/nf_conntrack_zones.h> 22 #include <net/netfilter/nf_synproxy.h> 23 24 unsigned int synproxy_net_id; 25 EXPORT_SYMBOL_GPL(synproxy_net_id); 26 27 bool 28 synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, 29 const struct tcphdr *th, struct synproxy_options *opts) 30 { 31 int length = (th->doff * 4) - sizeof(*th); 32 u8 buf[40], *ptr; 33 34 ptr = skb_header_pointer(skb, doff + sizeof(*th), length, buf); 35 if (ptr == NULL) 36 return false; 37 38 opts->options = 0; 39 while (length > 0) { 40 int opcode = *ptr++; 41 int opsize; 42 43 switch (opcode) { 44 case TCPOPT_EOL: 45 return true; 46 case TCPOPT_NOP: 47 length--; 48 continue; 49 default: 50 opsize = *ptr++; 51 if (opsize < 2) 52 return true; 53 if (opsize > length) 54 return true; 55 56 switch (opcode) { 57 case TCPOPT_MSS: 58 if (opsize == TCPOLEN_MSS) { 59 opts->mss_option = get_unaligned_be16(ptr); 60 opts->options |= NF_SYNPROXY_OPT_MSS; 61 } 62 break; 63 case TCPOPT_WINDOW: 64 if (opsize == TCPOLEN_WINDOW) { 65 opts->wscale = *ptr; 66 if (opts->wscale > TCP_MAX_WSCALE) 67 opts->wscale = TCP_MAX_WSCALE; 68 opts->options |= NF_SYNPROXY_OPT_WSCALE; 69 } 70 break; 71 case TCPOPT_TIMESTAMP: 72 if (opsize == TCPOLEN_TIMESTAMP) { 73 opts->tsval = get_unaligned_be32(ptr); 74 opts->tsecr = get_unaligned_be32(ptr + 4); 75 opts->options |= NF_SYNPROXY_OPT_TIMESTAMP; 76 } 77 break; 78 case TCPOPT_SACK_PERM: 79 if (opsize == TCPOLEN_SACK_PERM) 80 opts->options |= NF_SYNPROXY_OPT_SACK_PERM; 81 break; 82 } 83 84 ptr += opsize - 2; 85 length -= opsize; 86 } 87 } 88 return true; 89 } 90 EXPORT_SYMBOL_GPL(synproxy_parse_options); 91 92 static unsigned int 93 synproxy_options_size(const struct synproxy_options *opts) 94 { 95 unsigned int size = 0; 96 97 if (opts->options & NF_SYNPROXY_OPT_MSS) 98 size += TCPOLEN_MSS_ALIGNED; 99 if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 100 size += TCPOLEN_TSTAMP_ALIGNED; 101 else if (opts->options & NF_SYNPROXY_OPT_SACK_PERM) 102 size += TCPOLEN_SACKPERM_ALIGNED; 103 if (opts->options & NF_SYNPROXY_OPT_WSCALE) 104 size += TCPOLEN_WSCALE_ALIGNED; 105 106 return size; 107 } 108 109 static void 110 synproxy_build_options(struct tcphdr *th, const struct synproxy_options *opts) 111 { 112 __be32 *ptr = (__be32 *)(th + 1); 113 u8 options = opts->options; 114 115 if (options & NF_SYNPROXY_OPT_MSS) 116 *ptr++ = htonl((TCPOPT_MSS << 24) | 117 (TCPOLEN_MSS << 16) | 118 opts->mss_option); 119 120 if (options & NF_SYNPROXY_OPT_TIMESTAMP) { 121 if (options & NF_SYNPROXY_OPT_SACK_PERM) 122 *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | 123 (TCPOLEN_SACK_PERM << 16) | 124 (TCPOPT_TIMESTAMP << 8) | 125 TCPOLEN_TIMESTAMP); 126 else 127 *ptr++ = htonl((TCPOPT_NOP << 24) | 128 (TCPOPT_NOP << 16) | 129 (TCPOPT_TIMESTAMP << 8) | 130 TCPOLEN_TIMESTAMP); 131 132 *ptr++ = htonl(opts->tsval); 133 *ptr++ = htonl(opts->tsecr); 134 } else if (options & NF_SYNPROXY_OPT_SACK_PERM) 135 *ptr++ = htonl((TCPOPT_NOP << 24) | 136 (TCPOPT_NOP << 16) | 137 (TCPOPT_SACK_PERM << 8) | 138 TCPOLEN_SACK_PERM); 139 140 if (options & NF_SYNPROXY_OPT_WSCALE) 141 *ptr++ = htonl((TCPOPT_NOP << 24) | 142 (TCPOPT_WINDOW << 16) | 143 (TCPOLEN_WINDOW << 8) | 144 opts->wscale); 145 } 146 147 void synproxy_init_timestamp_cookie(const struct nf_synproxy_info *info, 148 struct synproxy_options *opts) 149 { 150 opts->tsecr = opts->tsval; 151 opts->tsval = tcp_time_stamp_raw() & ~0x3f; 152 153 if (opts->options & NF_SYNPROXY_OPT_WSCALE) { 154 opts->tsval |= opts->wscale; 155 opts->wscale = info->wscale; 156 } else 157 opts->tsval |= 0xf; 158 159 if (opts->options & NF_SYNPROXY_OPT_SACK_PERM) 160 opts->tsval |= 1 << 4; 161 162 if (opts->options & NF_SYNPROXY_OPT_ECN) 163 opts->tsval |= 1 << 5; 164 } 165 EXPORT_SYMBOL_GPL(synproxy_init_timestamp_cookie); 166 167 static void 168 synproxy_check_timestamp_cookie(struct synproxy_options *opts) 169 { 170 opts->wscale = opts->tsecr & 0xf; 171 if (opts->wscale != 0xf) 172 opts->options |= NF_SYNPROXY_OPT_WSCALE; 173 174 opts->options |= opts->tsecr & (1 << 4) ? NF_SYNPROXY_OPT_SACK_PERM : 0; 175 176 opts->options |= opts->tsecr & (1 << 5) ? NF_SYNPROXY_OPT_ECN : 0; 177 } 178 179 static unsigned int 180 synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff, 181 struct tcphdr *th, struct nf_conn *ct, 182 enum ip_conntrack_info ctinfo, 183 const struct nf_conn_synproxy *synproxy) 184 { 185 unsigned int optoff, optend; 186 __be32 *ptr, old; 187 188 if (synproxy->tsoff == 0) 189 return 1; 190 191 optoff = protoff + sizeof(struct tcphdr); 192 optend = protoff + th->doff * 4; 193 194 if (skb_ensure_writable(skb, optend)) 195 return 0; 196 197 while (optoff < optend) { 198 unsigned char *op = skb->data + optoff; 199 200 switch (op[0]) { 201 case TCPOPT_EOL: 202 return 1; 203 case TCPOPT_NOP: 204 optoff++; 205 continue; 206 default: 207 if (optoff + 1 == optend || 208 optoff + op[1] > optend || 209 op[1] < 2) 210 return 0; 211 if (op[0] == TCPOPT_TIMESTAMP && 212 op[1] == TCPOLEN_TIMESTAMP) { 213 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { 214 ptr = (__be32 *)&op[2]; 215 old = *ptr; 216 *ptr = htonl(ntohl(*ptr) - 217 synproxy->tsoff); 218 } else { 219 ptr = (__be32 *)&op[6]; 220 old = *ptr; 221 *ptr = htonl(ntohl(*ptr) + 222 synproxy->tsoff); 223 } 224 inet_proto_csum_replace4(&th->check, skb, 225 old, *ptr, false); 226 return 1; 227 } 228 optoff += op[1]; 229 } 230 } 231 return 1; 232 } 233 234 static struct nf_ct_ext_type nf_ct_synproxy_extend __read_mostly = { 235 .len = sizeof(struct nf_conn_synproxy), 236 .align = __alignof__(struct nf_conn_synproxy), 237 .id = NF_CT_EXT_SYNPROXY, 238 }; 239 240 #ifdef CONFIG_PROC_FS 241 static void *synproxy_cpu_seq_start(struct seq_file *seq, loff_t *pos) 242 { 243 struct synproxy_net *snet = synproxy_pernet(seq_file_net(seq)); 244 int cpu; 245 246 if (*pos == 0) 247 return SEQ_START_TOKEN; 248 249 for (cpu = *pos - 1; cpu < nr_cpu_ids; cpu++) { 250 if (!cpu_possible(cpu)) 251 continue; 252 *pos = cpu + 1; 253 return per_cpu_ptr(snet->stats, cpu); 254 } 255 256 return NULL; 257 } 258 259 static void *synproxy_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) 260 { 261 struct synproxy_net *snet = synproxy_pernet(seq_file_net(seq)); 262 int cpu; 263 264 for (cpu = *pos; cpu < nr_cpu_ids; cpu++) { 265 if (!cpu_possible(cpu)) 266 continue; 267 *pos = cpu + 1; 268 return per_cpu_ptr(snet->stats, cpu); 269 } 270 (*pos)++; 271 return NULL; 272 } 273 274 static void synproxy_cpu_seq_stop(struct seq_file *seq, void *v) 275 { 276 return; 277 } 278 279 static int synproxy_cpu_seq_show(struct seq_file *seq, void *v) 280 { 281 struct synproxy_stats *stats = v; 282 283 if (v == SEQ_START_TOKEN) { 284 seq_puts(seq, "entries\t\tsyn_received\t" 285 "cookie_invalid\tcookie_valid\t" 286 "cookie_retrans\tconn_reopened\n"); 287 return 0; 288 } 289 290 seq_printf(seq, "%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", 0, 291 stats->syn_received, 292 stats->cookie_invalid, 293 stats->cookie_valid, 294 stats->cookie_retrans, 295 stats->conn_reopened); 296 297 return 0; 298 } 299 300 static const struct seq_operations synproxy_cpu_seq_ops = { 301 .start = synproxy_cpu_seq_start, 302 .next = synproxy_cpu_seq_next, 303 .stop = synproxy_cpu_seq_stop, 304 .show = synproxy_cpu_seq_show, 305 }; 306 307 static int __net_init synproxy_proc_init(struct net *net) 308 { 309 if (!proc_create_net("synproxy", 0444, net->proc_net_stat, 310 &synproxy_cpu_seq_ops, sizeof(struct seq_net_private))) 311 return -ENOMEM; 312 return 0; 313 } 314 315 static void __net_exit synproxy_proc_exit(struct net *net) 316 { 317 remove_proc_entry("synproxy", net->proc_net_stat); 318 } 319 #else 320 static int __net_init synproxy_proc_init(struct net *net) 321 { 322 return 0; 323 } 324 325 static void __net_exit synproxy_proc_exit(struct net *net) 326 { 327 return; 328 } 329 #endif /* CONFIG_PROC_FS */ 330 331 static int __net_init synproxy_net_init(struct net *net) 332 { 333 struct synproxy_net *snet = synproxy_pernet(net); 334 struct nf_conn *ct; 335 int err = -ENOMEM; 336 337 ct = nf_ct_tmpl_alloc(net, &nf_ct_zone_dflt, GFP_KERNEL); 338 if (!ct) 339 goto err1; 340 341 if (!nfct_seqadj_ext_add(ct)) 342 goto err2; 343 if (!nfct_synproxy_ext_add(ct)) 344 goto err2; 345 346 __set_bit(IPS_CONFIRMED_BIT, &ct->status); 347 nf_conntrack_get(&ct->ct_general); 348 snet->tmpl = ct; 349 350 snet->stats = alloc_percpu(struct synproxy_stats); 351 if (snet->stats == NULL) 352 goto err2; 353 354 err = synproxy_proc_init(net); 355 if (err < 0) 356 goto err3; 357 358 return 0; 359 360 err3: 361 free_percpu(snet->stats); 362 err2: 363 nf_ct_tmpl_free(ct); 364 err1: 365 return err; 366 } 367 368 static void __net_exit synproxy_net_exit(struct net *net) 369 { 370 struct synproxy_net *snet = synproxy_pernet(net); 371 372 nf_ct_put(snet->tmpl); 373 synproxy_proc_exit(net); 374 free_percpu(snet->stats); 375 } 376 377 static struct pernet_operations synproxy_net_ops = { 378 .init = synproxy_net_init, 379 .exit = synproxy_net_exit, 380 .id = &synproxy_net_id, 381 .size = sizeof(struct synproxy_net), 382 }; 383 384 static int __init synproxy_core_init(void) 385 { 386 int err; 387 388 err = nf_ct_extend_register(&nf_ct_synproxy_extend); 389 if (err < 0) 390 goto err1; 391 392 err = register_pernet_subsys(&synproxy_net_ops); 393 if (err < 0) 394 goto err2; 395 396 return 0; 397 398 err2: 399 nf_ct_extend_unregister(&nf_ct_synproxy_extend); 400 err1: 401 return err; 402 } 403 404 static void __exit synproxy_core_exit(void) 405 { 406 unregister_pernet_subsys(&synproxy_net_ops); 407 nf_ct_extend_unregister(&nf_ct_synproxy_extend); 408 } 409 410 module_init(synproxy_core_init); 411 module_exit(synproxy_core_exit); 412 413 static struct iphdr * 414 synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr, 415 __be32 daddr) 416 { 417 struct iphdr *iph; 418 419 skb_reset_network_header(skb); 420 iph = skb_put(skb, sizeof(*iph)); 421 iph->version = 4; 422 iph->ihl = sizeof(*iph) / 4; 423 iph->tos = 0; 424 iph->id = 0; 425 iph->frag_off = htons(IP_DF); 426 iph->ttl = net->ipv4.sysctl_ip_default_ttl; 427 iph->protocol = IPPROTO_TCP; 428 iph->check = 0; 429 iph->saddr = saddr; 430 iph->daddr = daddr; 431 432 return iph; 433 } 434 435 static void 436 synproxy_send_tcp(struct net *net, 437 const struct sk_buff *skb, struct sk_buff *nskb, 438 struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 439 struct iphdr *niph, struct tcphdr *nth, 440 unsigned int tcp_hdr_size) 441 { 442 nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); 443 nskb->ip_summed = CHECKSUM_PARTIAL; 444 nskb->csum_start = (unsigned char *)nth - nskb->head; 445 nskb->csum_offset = offsetof(struct tcphdr, check); 446 447 skb_dst_set_noref(nskb, skb_dst(skb)); 448 nskb->protocol = htons(ETH_P_IP); 449 if (ip_route_me_harder(net, nskb, RTN_UNSPEC)) 450 goto free_nskb; 451 452 if (nfct) { 453 nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 454 nf_conntrack_get(nfct); 455 } 456 457 ip_local_out(net, nskb->sk, nskb); 458 return; 459 460 free_nskb: 461 kfree_skb(nskb); 462 } 463 464 void 465 synproxy_send_client_synack(struct net *net, 466 const struct sk_buff *skb, const struct tcphdr *th, 467 const struct synproxy_options *opts) 468 { 469 struct sk_buff *nskb; 470 struct iphdr *iph, *niph; 471 struct tcphdr *nth; 472 unsigned int tcp_hdr_size; 473 u16 mss = opts->mss_encode; 474 475 iph = ip_hdr(skb); 476 477 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 478 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 479 GFP_ATOMIC); 480 if (!nskb) 481 return; 482 skb_reserve(nskb, MAX_TCP_HEADER); 483 484 niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 485 486 skb_reset_transport_header(nskb); 487 nth = skb_put(nskb, tcp_hdr_size); 488 nth->source = th->dest; 489 nth->dest = th->source; 490 nth->seq = htonl(__cookie_v4_init_sequence(iph, th, &mss)); 491 nth->ack_seq = htonl(ntohl(th->seq) + 1); 492 tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 493 if (opts->options & NF_SYNPROXY_OPT_ECN) 494 tcp_flag_word(nth) |= TCP_FLAG_ECE; 495 nth->doff = tcp_hdr_size / 4; 496 nth->window = 0; 497 nth->check = 0; 498 nth->urg_ptr = 0; 499 500 synproxy_build_options(nth, opts); 501 502 synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 503 IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 504 } 505 EXPORT_SYMBOL_GPL(synproxy_send_client_synack); 506 507 static void 508 synproxy_send_server_syn(struct net *net, 509 const struct sk_buff *skb, const struct tcphdr *th, 510 const struct synproxy_options *opts, u32 recv_seq) 511 { 512 struct synproxy_net *snet = synproxy_pernet(net); 513 struct sk_buff *nskb; 514 struct iphdr *iph, *niph; 515 struct tcphdr *nth; 516 unsigned int tcp_hdr_size; 517 518 iph = ip_hdr(skb); 519 520 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 521 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 522 GFP_ATOMIC); 523 if (!nskb) 524 return; 525 skb_reserve(nskb, MAX_TCP_HEADER); 526 527 niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 528 529 skb_reset_transport_header(nskb); 530 nth = skb_put(nskb, tcp_hdr_size); 531 nth->source = th->source; 532 nth->dest = th->dest; 533 nth->seq = htonl(recv_seq - 1); 534 /* ack_seq is used to relay our ISN to the synproxy hook to initialize 535 * sequence number translation once a connection tracking entry exists. 536 */ 537 nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 538 tcp_flag_word(nth) = TCP_FLAG_SYN; 539 if (opts->options & NF_SYNPROXY_OPT_ECN) 540 tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 541 nth->doff = tcp_hdr_size / 4; 542 nth->window = th->window; 543 nth->check = 0; 544 nth->urg_ptr = 0; 545 546 synproxy_build_options(nth, opts); 547 548 synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, 549 niph, nth, tcp_hdr_size); 550 } 551 552 static void 553 synproxy_send_server_ack(struct net *net, 554 const struct ip_ct_tcp *state, 555 const struct sk_buff *skb, const struct tcphdr *th, 556 const struct synproxy_options *opts) 557 { 558 struct sk_buff *nskb; 559 struct iphdr *iph, *niph; 560 struct tcphdr *nth; 561 unsigned int tcp_hdr_size; 562 563 iph = ip_hdr(skb); 564 565 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 566 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 567 GFP_ATOMIC); 568 if (!nskb) 569 return; 570 skb_reserve(nskb, MAX_TCP_HEADER); 571 572 niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 573 574 skb_reset_transport_header(nskb); 575 nth = skb_put(nskb, tcp_hdr_size); 576 nth->source = th->dest; 577 nth->dest = th->source; 578 nth->seq = htonl(ntohl(th->ack_seq)); 579 nth->ack_seq = htonl(ntohl(th->seq) + 1); 580 tcp_flag_word(nth) = TCP_FLAG_ACK; 581 nth->doff = tcp_hdr_size / 4; 582 nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 583 nth->check = 0; 584 nth->urg_ptr = 0; 585 586 synproxy_build_options(nth, opts); 587 588 synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); 589 } 590 591 static void 592 synproxy_send_client_ack(struct net *net, 593 const struct sk_buff *skb, const struct tcphdr *th, 594 const struct synproxy_options *opts) 595 { 596 struct sk_buff *nskb; 597 struct iphdr *iph, *niph; 598 struct tcphdr *nth; 599 unsigned int tcp_hdr_size; 600 601 iph = ip_hdr(skb); 602 603 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 604 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 605 GFP_ATOMIC); 606 if (!nskb) 607 return; 608 skb_reserve(nskb, MAX_TCP_HEADER); 609 610 niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 611 612 skb_reset_transport_header(nskb); 613 nth = skb_put(nskb, tcp_hdr_size); 614 nth->source = th->source; 615 nth->dest = th->dest; 616 nth->seq = htonl(ntohl(th->seq) + 1); 617 nth->ack_seq = th->ack_seq; 618 tcp_flag_word(nth) = TCP_FLAG_ACK; 619 nth->doff = tcp_hdr_size / 4; 620 nth->window = htons(ntohs(th->window) >> opts->wscale); 621 nth->check = 0; 622 nth->urg_ptr = 0; 623 624 synproxy_build_options(nth, opts); 625 626 synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 627 IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 628 } 629 630 bool 631 synproxy_recv_client_ack(struct net *net, 632 const struct sk_buff *skb, const struct tcphdr *th, 633 struct synproxy_options *opts, u32 recv_seq) 634 { 635 struct synproxy_net *snet = synproxy_pernet(net); 636 int mss; 637 638 mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); 639 if (mss == 0) { 640 this_cpu_inc(snet->stats->cookie_invalid); 641 return false; 642 } 643 644 this_cpu_inc(snet->stats->cookie_valid); 645 opts->mss_option = mss; 646 opts->options |= NF_SYNPROXY_OPT_MSS; 647 648 if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 649 synproxy_check_timestamp_cookie(opts); 650 651 synproxy_send_server_syn(net, skb, th, opts, recv_seq); 652 return true; 653 } 654 EXPORT_SYMBOL_GPL(synproxy_recv_client_ack); 655 656 unsigned int 657 ipv4_synproxy_hook(void *priv, struct sk_buff *skb, 658 const struct nf_hook_state *nhs) 659 { 660 struct net *net = nhs->net; 661 struct synproxy_net *snet = synproxy_pernet(net); 662 enum ip_conntrack_info ctinfo; 663 struct nf_conn *ct; 664 struct nf_conn_synproxy *synproxy; 665 struct synproxy_options opts = {}; 666 const struct ip_ct_tcp *state; 667 struct tcphdr *th, _th; 668 unsigned int thoff; 669 670 ct = nf_ct_get(skb, &ctinfo); 671 if (!ct) 672 return NF_ACCEPT; 673 674 synproxy = nfct_synproxy(ct); 675 if (!synproxy) 676 return NF_ACCEPT; 677 678 if (nf_is_loopback_packet(skb) || 679 ip_hdr(skb)->protocol != IPPROTO_TCP) 680 return NF_ACCEPT; 681 682 thoff = ip_hdrlen(skb); 683 th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 684 if (!th) 685 return NF_DROP; 686 687 state = &ct->proto.tcp; 688 switch (state->state) { 689 case TCP_CONNTRACK_CLOSE: 690 if (th->rst && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { 691 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 692 ntohl(th->seq) + 1); 693 break; 694 } 695 696 if (!th->syn || th->ack || 697 CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 698 break; 699 700 /* Reopened connection - reset the sequence number and timestamp 701 * adjustments, they will get initialized once the connection is 702 * reestablished. 703 */ 704 nf_ct_seqadj_init(ct, ctinfo, 0); 705 synproxy->tsoff = 0; 706 this_cpu_inc(snet->stats->conn_reopened); 707 708 /* fall through */ 709 case TCP_CONNTRACK_SYN_SENT: 710 if (!synproxy_parse_options(skb, thoff, th, &opts)) 711 return NF_DROP; 712 713 if (!th->syn && th->ack && 714 CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 715 /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 716 * therefore we need to add 1 to make the SYN sequence 717 * number match the one of first SYN. 718 */ 719 if (synproxy_recv_client_ack(net, skb, th, &opts, 720 ntohl(th->seq) + 1)) { 721 this_cpu_inc(snet->stats->cookie_retrans); 722 consume_skb(skb); 723 return NF_STOLEN; 724 } else { 725 return NF_DROP; 726 } 727 } 728 729 synproxy->isn = ntohl(th->ack_seq); 730 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) 731 synproxy->its = opts.tsecr; 732 733 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 734 break; 735 case TCP_CONNTRACK_SYN_RECV: 736 if (!th->syn || !th->ack) 737 break; 738 739 if (!synproxy_parse_options(skb, thoff, th, &opts)) 740 return NF_DROP; 741 742 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) { 743 synproxy->tsoff = opts.tsval - synproxy->its; 744 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 745 } 746 747 opts.options &= ~(NF_SYNPROXY_OPT_MSS | 748 NF_SYNPROXY_OPT_WSCALE | 749 NF_SYNPROXY_OPT_SACK_PERM); 750 751 swap(opts.tsval, opts.tsecr); 752 synproxy_send_server_ack(net, state, skb, th, &opts); 753 754 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 755 nf_conntrack_event_cache(IPCT_SEQADJ, ct); 756 757 swap(opts.tsval, opts.tsecr); 758 synproxy_send_client_ack(net, skb, th, &opts); 759 760 consume_skb(skb); 761 return NF_STOLEN; 762 default: 763 break; 764 } 765 766 synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 767 return NF_ACCEPT; 768 } 769 EXPORT_SYMBOL_GPL(ipv4_synproxy_hook); 770 771 static const struct nf_hook_ops ipv4_synproxy_ops[] = { 772 { 773 .hook = ipv4_synproxy_hook, 774 .pf = NFPROTO_IPV4, 775 .hooknum = NF_INET_LOCAL_IN, 776 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 777 }, 778 { 779 .hook = ipv4_synproxy_hook, 780 .pf = NFPROTO_IPV4, 781 .hooknum = NF_INET_POST_ROUTING, 782 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 783 }, 784 }; 785 786 int nf_synproxy_ipv4_init(struct synproxy_net *snet, struct net *net) 787 { 788 int err; 789 790 if (snet->hook_ref4 == 0) { 791 err = nf_register_net_hooks(net, ipv4_synproxy_ops, 792 ARRAY_SIZE(ipv4_synproxy_ops)); 793 if (err) 794 return err; 795 } 796 797 snet->hook_ref4++; 798 return 0; 799 } 800 EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_init); 801 802 void nf_synproxy_ipv4_fini(struct synproxy_net *snet, struct net *net) 803 { 804 snet->hook_ref4--; 805 if (snet->hook_ref4 == 0) 806 nf_unregister_net_hooks(net, ipv4_synproxy_ops, 807 ARRAY_SIZE(ipv4_synproxy_ops)); 808 } 809 EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_fini); 810 811 #if IS_ENABLED(CONFIG_IPV6) 812 static struct ipv6hdr * 813 synproxy_build_ip_ipv6(struct net *net, struct sk_buff *skb, 814 const struct in6_addr *saddr, 815 const struct in6_addr *daddr) 816 { 817 struct ipv6hdr *iph; 818 819 skb_reset_network_header(skb); 820 iph = skb_put(skb, sizeof(*iph)); 821 ip6_flow_hdr(iph, 0, 0); 822 iph->hop_limit = net->ipv6.devconf_all->hop_limit; 823 iph->nexthdr = IPPROTO_TCP; 824 iph->saddr = *saddr; 825 iph->daddr = *daddr; 826 827 return iph; 828 } 829 830 static void 831 synproxy_send_tcp_ipv6(struct net *net, 832 const struct sk_buff *skb, struct sk_buff *nskb, 833 struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 834 struct ipv6hdr *niph, struct tcphdr *nth, 835 unsigned int tcp_hdr_size) 836 { 837 struct dst_entry *dst; 838 struct flowi6 fl6; 839 int err; 840 841 nth->check = ~tcp_v6_check(tcp_hdr_size, &niph->saddr, &niph->daddr, 0); 842 nskb->ip_summed = CHECKSUM_PARTIAL; 843 nskb->csum_start = (unsigned char *)nth - nskb->head; 844 nskb->csum_offset = offsetof(struct tcphdr, check); 845 846 memset(&fl6, 0, sizeof(fl6)); 847 fl6.flowi6_proto = IPPROTO_TCP; 848 fl6.saddr = niph->saddr; 849 fl6.daddr = niph->daddr; 850 fl6.fl6_sport = nth->source; 851 fl6.fl6_dport = nth->dest; 852 security_skb_classify_flow((struct sk_buff *)skb, 853 flowi6_to_flowi(&fl6)); 854 err = nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false); 855 if (err) { 856 goto free_nskb; 857 } 858 859 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); 860 if (IS_ERR(dst)) 861 goto free_nskb; 862 863 skb_dst_set(nskb, dst); 864 865 if (nfct) { 866 nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 867 nf_conntrack_get(nfct); 868 } 869 870 ip6_local_out(net, nskb->sk, nskb); 871 return; 872 873 free_nskb: 874 kfree_skb(nskb); 875 } 876 877 void 878 synproxy_send_client_synack_ipv6(struct net *net, 879 const struct sk_buff *skb, 880 const struct tcphdr *th, 881 const struct synproxy_options *opts) 882 { 883 struct sk_buff *nskb; 884 struct ipv6hdr *iph, *niph; 885 struct tcphdr *nth; 886 unsigned int tcp_hdr_size; 887 u16 mss = opts->mss_encode; 888 889 iph = ipv6_hdr(skb); 890 891 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 892 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 893 GFP_ATOMIC); 894 if (!nskb) 895 return; 896 skb_reserve(nskb, MAX_TCP_HEADER); 897 898 niph = synproxy_build_ip_ipv6(net, nskb, &iph->daddr, &iph->saddr); 899 900 skb_reset_transport_header(nskb); 901 nth = skb_put(nskb, tcp_hdr_size); 902 nth->source = th->dest; 903 nth->dest = th->source; 904 nth->seq = htonl(nf_ipv6_cookie_init_sequence(iph, th, &mss)); 905 nth->ack_seq = htonl(ntohl(th->seq) + 1); 906 tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 907 if (opts->options & NF_SYNPROXY_OPT_ECN) 908 tcp_flag_word(nth) |= TCP_FLAG_ECE; 909 nth->doff = tcp_hdr_size / 4; 910 nth->window = 0; 911 nth->check = 0; 912 nth->urg_ptr = 0; 913 914 synproxy_build_options(nth, opts); 915 916 synproxy_send_tcp_ipv6(net, skb, nskb, skb_nfct(skb), 917 IP_CT_ESTABLISHED_REPLY, niph, nth, 918 tcp_hdr_size); 919 } 920 EXPORT_SYMBOL_GPL(synproxy_send_client_synack_ipv6); 921 922 static void 923 synproxy_send_server_syn_ipv6(struct net *net, const struct sk_buff *skb, 924 const struct tcphdr *th, 925 const struct synproxy_options *opts, u32 recv_seq) 926 { 927 struct synproxy_net *snet = synproxy_pernet(net); 928 struct sk_buff *nskb; 929 struct ipv6hdr *iph, *niph; 930 struct tcphdr *nth; 931 unsigned int tcp_hdr_size; 932 933 iph = ipv6_hdr(skb); 934 935 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 936 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 937 GFP_ATOMIC); 938 if (!nskb) 939 return; 940 skb_reserve(nskb, MAX_TCP_HEADER); 941 942 niph = synproxy_build_ip_ipv6(net, nskb, &iph->saddr, &iph->daddr); 943 944 skb_reset_transport_header(nskb); 945 nth = skb_put(nskb, tcp_hdr_size); 946 nth->source = th->source; 947 nth->dest = th->dest; 948 nth->seq = htonl(recv_seq - 1); 949 /* ack_seq is used to relay our ISN to the synproxy hook to initialize 950 * sequence number translation once a connection tracking entry exists. 951 */ 952 nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 953 tcp_flag_word(nth) = TCP_FLAG_SYN; 954 if (opts->options & NF_SYNPROXY_OPT_ECN) 955 tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 956 nth->doff = tcp_hdr_size / 4; 957 nth->window = th->window; 958 nth->check = 0; 959 nth->urg_ptr = 0; 960 961 synproxy_build_options(nth, opts); 962 963 synproxy_send_tcp_ipv6(net, skb, nskb, &snet->tmpl->ct_general, 964 IP_CT_NEW, niph, nth, tcp_hdr_size); 965 } 966 967 static void 968 synproxy_send_server_ack_ipv6(struct net *net, const struct ip_ct_tcp *state, 969 const struct sk_buff *skb, 970 const struct tcphdr *th, 971 const struct synproxy_options *opts) 972 { 973 struct sk_buff *nskb; 974 struct ipv6hdr *iph, *niph; 975 struct tcphdr *nth; 976 unsigned int tcp_hdr_size; 977 978 iph = ipv6_hdr(skb); 979 980 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 981 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 982 GFP_ATOMIC); 983 if (!nskb) 984 return; 985 skb_reserve(nskb, MAX_TCP_HEADER); 986 987 niph = synproxy_build_ip_ipv6(net, nskb, &iph->daddr, &iph->saddr); 988 989 skb_reset_transport_header(nskb); 990 nth = skb_put(nskb, tcp_hdr_size); 991 nth->source = th->dest; 992 nth->dest = th->source; 993 nth->seq = htonl(ntohl(th->ack_seq)); 994 nth->ack_seq = htonl(ntohl(th->seq) + 1); 995 tcp_flag_word(nth) = TCP_FLAG_ACK; 996 nth->doff = tcp_hdr_size / 4; 997 nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 998 nth->check = 0; 999 nth->urg_ptr = 0; 1000 1001 synproxy_build_options(nth, opts); 1002 1003 synproxy_send_tcp_ipv6(net, skb, nskb, NULL, 0, niph, nth, 1004 tcp_hdr_size); 1005 } 1006 1007 static void 1008 synproxy_send_client_ack_ipv6(struct net *net, const struct sk_buff *skb, 1009 const struct tcphdr *th, 1010 const struct synproxy_options *opts) 1011 { 1012 struct sk_buff *nskb; 1013 struct ipv6hdr *iph, *niph; 1014 struct tcphdr *nth; 1015 unsigned int tcp_hdr_size; 1016 1017 iph = ipv6_hdr(skb); 1018 1019 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 1020 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 1021 GFP_ATOMIC); 1022 if (!nskb) 1023 return; 1024 skb_reserve(nskb, MAX_TCP_HEADER); 1025 1026 niph = synproxy_build_ip_ipv6(net, nskb, &iph->saddr, &iph->daddr); 1027 1028 skb_reset_transport_header(nskb); 1029 nth = skb_put(nskb, tcp_hdr_size); 1030 nth->source = th->source; 1031 nth->dest = th->dest; 1032 nth->seq = htonl(ntohl(th->seq) + 1); 1033 nth->ack_seq = th->ack_seq; 1034 tcp_flag_word(nth) = TCP_FLAG_ACK; 1035 nth->doff = tcp_hdr_size / 4; 1036 nth->window = htons(ntohs(th->window) >> opts->wscale); 1037 nth->check = 0; 1038 nth->urg_ptr = 0; 1039 1040 synproxy_build_options(nth, opts); 1041 1042 synproxy_send_tcp_ipv6(net, skb, nskb, skb_nfct(skb), 1043 IP_CT_ESTABLISHED_REPLY, niph, nth, 1044 tcp_hdr_size); 1045 } 1046 1047 bool 1048 synproxy_recv_client_ack_ipv6(struct net *net, 1049 const struct sk_buff *skb, 1050 const struct tcphdr *th, 1051 struct synproxy_options *opts, u32 recv_seq) 1052 { 1053 struct synproxy_net *snet = synproxy_pernet(net); 1054 int mss; 1055 1056 mss = nf_cookie_v6_check(ipv6_hdr(skb), th, ntohl(th->ack_seq) - 1); 1057 if (mss == 0) { 1058 this_cpu_inc(snet->stats->cookie_invalid); 1059 return false; 1060 } 1061 1062 this_cpu_inc(snet->stats->cookie_valid); 1063 opts->mss_option = mss; 1064 opts->options |= NF_SYNPROXY_OPT_MSS; 1065 1066 if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 1067 synproxy_check_timestamp_cookie(opts); 1068 1069 synproxy_send_server_syn_ipv6(net, skb, th, opts, recv_seq); 1070 return true; 1071 } 1072 EXPORT_SYMBOL_GPL(synproxy_recv_client_ack_ipv6); 1073 1074 unsigned int 1075 ipv6_synproxy_hook(void *priv, struct sk_buff *skb, 1076 const struct nf_hook_state *nhs) 1077 { 1078 struct net *net = nhs->net; 1079 struct synproxy_net *snet = synproxy_pernet(net); 1080 enum ip_conntrack_info ctinfo; 1081 struct nf_conn *ct; 1082 struct nf_conn_synproxy *synproxy; 1083 struct synproxy_options opts = {}; 1084 const struct ip_ct_tcp *state; 1085 struct tcphdr *th, _th; 1086 __be16 frag_off; 1087 u8 nexthdr; 1088 int thoff; 1089 1090 ct = nf_ct_get(skb, &ctinfo); 1091 if (!ct) 1092 return NF_ACCEPT; 1093 1094 synproxy = nfct_synproxy(ct); 1095 if (!synproxy) 1096 return NF_ACCEPT; 1097 1098 if (nf_is_loopback_packet(skb)) 1099 return NF_ACCEPT; 1100 1101 nexthdr = ipv6_hdr(skb)->nexthdr; 1102 thoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, 1103 &frag_off); 1104 if (thoff < 0 || nexthdr != IPPROTO_TCP) 1105 return NF_ACCEPT; 1106 1107 th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 1108 if (!th) 1109 return NF_DROP; 1110 1111 state = &ct->proto.tcp; 1112 switch (state->state) { 1113 case TCP_CONNTRACK_CLOSE: 1114 if (th->rst && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { 1115 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 1116 ntohl(th->seq) + 1); 1117 break; 1118 } 1119 1120 if (!th->syn || th->ack || 1121 CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 1122 break; 1123 1124 /* Reopened connection - reset the sequence number and timestamp 1125 * adjustments, they will get initialized once the connection is 1126 * reestablished. 1127 */ 1128 nf_ct_seqadj_init(ct, ctinfo, 0); 1129 synproxy->tsoff = 0; 1130 this_cpu_inc(snet->stats->conn_reopened); 1131 1132 /* fall through */ 1133 case TCP_CONNTRACK_SYN_SENT: 1134 if (!synproxy_parse_options(skb, thoff, th, &opts)) 1135 return NF_DROP; 1136 1137 if (!th->syn && th->ack && 1138 CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 1139 /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 1140 * therefore we need to add 1 to make the SYN sequence 1141 * number match the one of first SYN. 1142 */ 1143 if (synproxy_recv_client_ack_ipv6(net, skb, th, &opts, 1144 ntohl(th->seq) + 1)) { 1145 this_cpu_inc(snet->stats->cookie_retrans); 1146 consume_skb(skb); 1147 return NF_STOLEN; 1148 } else { 1149 return NF_DROP; 1150 } 1151 } 1152 1153 synproxy->isn = ntohl(th->ack_seq); 1154 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) 1155 synproxy->its = opts.tsecr; 1156 1157 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 1158 break; 1159 case TCP_CONNTRACK_SYN_RECV: 1160 if (!th->syn || !th->ack) 1161 break; 1162 1163 if (!synproxy_parse_options(skb, thoff, th, &opts)) 1164 return NF_DROP; 1165 1166 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) { 1167 synproxy->tsoff = opts.tsval - synproxy->its; 1168 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 1169 } 1170 1171 opts.options &= ~(NF_SYNPROXY_OPT_MSS | 1172 NF_SYNPROXY_OPT_WSCALE | 1173 NF_SYNPROXY_OPT_SACK_PERM); 1174 1175 swap(opts.tsval, opts.tsecr); 1176 synproxy_send_server_ack_ipv6(net, state, skb, th, &opts); 1177 1178 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 1179 nf_conntrack_event_cache(IPCT_SEQADJ, ct); 1180 1181 swap(opts.tsval, opts.tsecr); 1182 synproxy_send_client_ack_ipv6(net, skb, th, &opts); 1183 1184 consume_skb(skb); 1185 return NF_STOLEN; 1186 default: 1187 break; 1188 } 1189 1190 synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 1191 return NF_ACCEPT; 1192 } 1193 EXPORT_SYMBOL_GPL(ipv6_synproxy_hook); 1194 1195 static const struct nf_hook_ops ipv6_synproxy_ops[] = { 1196 { 1197 .hook = ipv6_synproxy_hook, 1198 .pf = NFPROTO_IPV6, 1199 .hooknum = NF_INET_LOCAL_IN, 1200 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 1201 }, 1202 { 1203 .hook = ipv6_synproxy_hook, 1204 .pf = NFPROTO_IPV6, 1205 .hooknum = NF_INET_POST_ROUTING, 1206 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 1207 }, 1208 }; 1209 1210 int 1211 nf_synproxy_ipv6_init(struct synproxy_net *snet, struct net *net) 1212 { 1213 int err; 1214 1215 if (snet->hook_ref6 == 0) { 1216 err = nf_register_net_hooks(net, ipv6_synproxy_ops, 1217 ARRAY_SIZE(ipv6_synproxy_ops)); 1218 if (err) 1219 return err; 1220 } 1221 1222 snet->hook_ref6++; 1223 return 0; 1224 } 1225 EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_init); 1226 1227 void 1228 nf_synproxy_ipv6_fini(struct synproxy_net *snet, struct net *net) 1229 { 1230 snet->hook_ref6--; 1231 if (snet->hook_ref6 == 0) 1232 nf_unregister_net_hooks(net, ipv6_synproxy_ops, 1233 ARRAY_SIZE(ipv6_synproxy_ops)); 1234 } 1235 EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_fini); 1236 #endif /* CONFIG_IPV6 */ 1237 1238 MODULE_LICENSE("GPL"); 1239 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 1240