20 #define KMSG_COMPONENT "IPVS"
21 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
23 #include <linux/kernel.h>
25 #include <linux/tcp.h>
29 #include <linux/netfilter.h>
30 #include <linux/netfilter_ipv4.h>
43 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
45 th = skb_header_pointer(skb, iph.
len,
sizeof(_tcph), &_tcph);
57 if (ip_vs_todrop(net_ipvs(net))) {
62 ip_vs_service_put(svc);
72 if (!*cpp && ignored <= 0) {
76 ip_vs_service_put(svc);
81 ip_vs_service_put(svc);
89 tcp_fast_csum_update(
int af,
struct tcphdr *tcph,
94 #ifdef CONFIG_IP_VS_IPV6
97 csum_fold(ip_vs_check_diff16(oldip->
ip6, newip->
ip6,
98 ip_vs_check_diff2(oldport, newport,
99 ~csum_unfold(tcph->
check))));
103 csum_fold(ip_vs_check_diff4(oldip->
ip, newip->
ip,
104 ip_vs_check_diff2(oldport, newport,
105 ~csum_unfold(tcph->
check))));
110 tcp_partial_csum_update(
int af,
struct tcphdr *tcph,
115 #ifdef CONFIG_IP_VS_IPV6
118 ~csum_fold(ip_vs_check_diff16(oldip->
ip6, newip->
ip6,
119 ip_vs_check_diff2(oldlen, newlen,
120 csum_unfold(tcph->
check))));
124 ~csum_fold(ip_vs_check_diff4(oldip->
ip, newip->
ip,
125 ip_vs_check_diff2(oldlen, newlen,
126 csum_unfold(tcph->
check))));
135 unsigned int tcphoff;
137 int payload_csum = 0;
139 #ifdef CONFIG_IP_VS_IPV6
141 tcphoff =
sizeof(
struct ipv6hdr);
144 tcphoff = ip_hdrlen(skb);
145 oldlen = skb->
len - tcphoff;
163 oldlen = skb->
len - tcphoff;
168 tcph = (
void *)skb_network_header(skb) + tcphoff;
173 tcp_partial_csum_update(cp->
af, tcph, &cp->
daddr, &cp->
vaddr,
176 }
else if (!payload_csum) {
178 tcp_fast_csum_update(cp->
af, tcph, &cp->
daddr, &cp->
vaddr,
187 #ifdef CONFIG_IP_VS_IPV6
202 IP_VS_DBG(11,
"O-pkt: %s O-csum=%d (+%zd)\n",
204 (
char*)&(tcph->
check) - (
char*)tcph);
211 tcp_dnat_handler(
struct sk_buff *skb,
215 unsigned int tcphoff;
217 int payload_csum = 0;
219 #ifdef CONFIG_IP_VS_IPV6
221 tcphoff =
sizeof(
struct ipv6hdr);
224 tcphoff = ip_hdrlen(skb);
225 oldlen = skb->
len - tcphoff;
246 oldlen = skb->
len - tcphoff;
251 tcph = (
void *)skb_network_header(skb) + tcphoff;
258 tcp_partial_csum_update(cp->
af, tcph, &cp->
vaddr, &cp->
daddr,
261 }
else if (!payload_csum) {
263 tcp_fast_csum_update(cp->
af, tcph, &cp->
vaddr, &cp->
daddr,
272 #ifdef CONFIG_IP_VS_IPV6
294 unsigned int tcphoff;
296 #ifdef CONFIG_IP_VS_IPV6
298 tcphoff =
sizeof(
struct ipv6hdr);
301 tcphoff = ip_hdrlen(skb);
307 #ifdef CONFIG_IP_VS_IPV6
310 &ipv6_hdr(skb)->
daddr,
315 "Failed checksum for");
326 "Failed checksum for");
339 #define TCP_DIR_INPUT 0
340 #define TCP_DIR_OUTPUT 4
341 #define TCP_DIR_INPUT_ONLY 8
382 #define sNO IP_VS_TCP_S_NONE
383 #define sES IP_VS_TCP_S_ESTABLISHED
384 #define sSS IP_VS_TCP_S_SYN_SENT
385 #define sSR IP_VS_TCP_S_SYN_RECV
386 #define sFW IP_VS_TCP_S_FIN_WAIT
387 #define sTW IP_VS_TCP_S_TIME_WAIT
388 #define sCL IP_VS_TCP_S_CLOSE
389 #define sCW IP_VS_TCP_S_CLOSE_WAIT
390 #define sLA IP_VS_TCP_S_LAST_ACK
391 #define sLI IP_VS_TCP_S_LISTEN
392 #define sSA IP_VS_TCP_S_SYNACK
398 static const char * tcp_state_name(
int state)
402 return tcp_state_name_table[
state] ? tcp_state_name_table[
state] :
"?";
408 {{
sSR,
sES,
sES,
sSR,
sSR,
sSR,
sSR,
sSR,
sSR,
sSR, sSR }},
409 {{
sCL,
sCW,
sSS,
sTW,
sTW,
sTW,
sCL,
sCW,
sLA,
sLI, sTW }},
410 {{
sCL,
sES,
sSS,
sES,
sFW,
sTW,
sCL,
sCW,
sCL,
sLI, sES }},
411 {{
sCL,
sCL,
sCL,
sSR,
sCL,
sCL,
sCL,
sCL,
sLA,
sLI, sSR }},
415 {{
sSS,
sES,
sSS,
sSR,
sSS,
sSS,
sSS,
sSS,
sSS,
sLI, sSR }},
416 {{
sTW,
sFW,
sSS,
sTW,
sFW,
sTW,
sCL,
sTW,
sLA,
sLI, sTW }},
417 {{
sES,
sES,
sSS,
sES,
sFW,
sTW,
sCL,
sCW,
sLA,
sES, sES }},
418 {{
sCL,
sCL,
sSS,
sCL,
sCL,
sTW,
sCL,
sCL,
sCL,
sCL, sCL }},
422 {{
sSR,
sES,
sES,
sSR,
sSR,
sSR,
sSR,
sSR,
sSR,
sSR, sSR }},
423 {{
sCL,
sFW,
sSS,
sTW,
sFW,
sTW,
sCL,
sCW,
sLA,
sLI, sTW }},
424 {{
sCL,
sES,
sSS,
sES,
sFW,
sTW,
sCL,
sCW,
sCL,
sLI, sES }},
425 {{
sCL,
sCL,
sCL,
sSR,
sCL,
sCL,
sCL,
sCL,
sLA,
sLI, sCL }},
431 {{
sSR,
sES,
sES,
sSR,
sSR,
sSR,
sSR,
sSR,
sSR,
sSR,
sSA }},
432 {{
sCL,
sCW,
sSS,
sTW,
sTW,
sTW,
sCL,
sCW,
sLA,
sLI,
sSA }},
433 {{
sCL,
sES,
sSS,
sSR,
sFW,
sTW,
sCL,
sCW,
sCL,
sLI,
sSA }},
434 {{
sCL,
sCL,
sCL,
sSR,
sCL,
sCL,
sCL,
sCL,
sLA,
sLI, sCL }},
438 {{
sSS,
sES,
sSS,
sSA,
sSS,
sSS,
sSS,
sSS,
sSS,
sLI, sSA }},
439 {{
sTW,
sFW,
sSS,
sTW,
sFW,
sTW,
sCL,
sTW,
sLA,
sLI, sTW }},
440 {{
sES,
sES,
sSS,
sES,
sFW,
sTW,
sCL,
sCW,
sLA,
sES, sES }},
441 {{
sCL,
sCL,
sSS,
sCL,
sCL,
sTW,
sCL,
sCL,
sCL,
sCL, sCL }},
445 {{
sSA,
sES,
sES,
sSR,
sSA,
sSA,
sSA,
sSA,
sSA,
sSA, sSA }},
446 {{
sCL,
sFW,
sSS,
sTW,
sFW,
sTW,
sCL,
sCW,
sLA,
sLI, sTW }},
447 {{
sCL,
sES,
sSS,
sES,
sFW,
sTW,
sCL,
sCW,
sCL,
sLI, sES }},
448 {{
sCL,
sCL,
sCL,
sSR,
sCL,
sCL,
sCL,
sCL,
sLA,
sLI, sCL }},
453 int on = (flags & 1);
464 static inline int tcp_state_idx(
struct tcphdr *
th)
483 int state_off = tcp_state_off[
direction];
496 if ((state_idx = tcp_state_idx(th)) < 0) {
497 IP_VS_DBG(8,
"tcp_state_idx=%d!!!\n", state_idx);
505 if (new_state != cp->
state) {
509 "%s:%d state: %s->%s conn->refcnt:%d\n",
512 "output " :
"input "),
517 IP_VS_DBG_ADDR(cp->
af, &cp->
daddr),
519 IP_VS_DBG_ADDR(cp->
af, &cp->
caddr),
521 tcp_state_name(cp->
state),
522 tcp_state_name(new_state),
550 tcp_state_transition(
struct ip_vs_conn *cp,
int direction,
556 #ifdef CONFIG_IP_VS_IPV6
559 int ihl = ip_hdrlen(skb);
562 th = skb_header_pointer(skb, ihl,
sizeof(_tcph), &_tcph);
566 spin_lock(&cp->
lock);
567 set_tcp_state(pd, cp, direction, th);
568 spin_unlock(&cp->
lock);
587 hash = tcp_app_hashkey(port);
589 spin_lock_bh(&ipvs->tcp_app_lock);
591 if (i->
port == port) {
596 list_add(&inc->
p_list, &ipvs->tcp_apps[hash]);
600 spin_unlock_bh(&ipvs->tcp_app_lock);
606 tcp_unregister_app(
struct net *net,
struct ip_vs_app *inc)
611 spin_lock_bh(&ipvs->tcp_app_lock);
614 spin_unlock_bh(&ipvs->tcp_app_lock);
621 struct netns_ipvs *ipvs = net_ipvs(ip_vs_conn_net(cp));
631 hash = tcp_app_hashkey(cp->
vport);
633 spin_lock(&ipvs->tcp_app_lock);
638 spin_unlock(&ipvs->tcp_app_lock);
641 "%s:%u to app %s on port %u\n",
643 IP_VS_DBG_ADDR(cp->
af, &cp->
caddr),
645 IP_VS_DBG_ADDR(cp->
af, &cp->
vaddr),
655 spin_unlock(&ipvs->tcp_app_lock);
669 spin_lock(&cp->
lock);
673 spin_unlock(&cp->
lock);
687 sizeof(tcp_timeouts));
707 .init_netns = __ip_vs_tcp_init,
708 .exit_netns = __ip_vs_tcp_exit,
709 .register_app = tcp_register_app,
710 .unregister_app = tcp_unregister_app,
711 .conn_schedule = tcp_conn_schedule,
714 .snat_handler = tcp_snat_handler,
715 .dnat_handler = tcp_dnat_handler,
716 .csum_check = tcp_csum_check,
717 .state_name = tcp_state_name,
718 .state_transition = tcp_state_transition,
719 .app_conn_bind = tcp_app_conn_bind,
721 .timeout_change = tcp_timeout_change,