aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
authorKOVACS Krisztian <hidden@sch.bme.hu>2008-10-01 10:41:00 -0400
committerDavid S. Miller <davem@davemloft.net>2008-10-01 10:41:00 -0400
commit88ef4a5a78e63420dd1dd770f1bd1dc198926b04 (patch)
tree42409d6d26fb6f954c501ac156d34265437d18f9 /net/ipv4/tcp_ipv4.c
parent79876874ce20d37ecdc7f481ebf142466999152f (diff)
tcp: Handle TCP SYN+ACK/ACK/RST transparency
The TCP stack sends out SYN+ACK/ACK/RST reply packets in response to incoming packets. The non-local source address check on output bites us again, as replies for transparently redirected traffic won't have a chance to leave the node. This patch selectively sets the FLOWI_FLAG_ANYSRC flag when doing the route lookup for those replies. Transparent replies are enabled if the listening socket has the transparent socket flag set. Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d13688e3558d..8b24bd833cb4 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -591,6 +591,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
591 ip_hdr(skb)->saddr, /* XXX */ 591 ip_hdr(skb)->saddr, /* XXX */
592 sizeof(struct tcphdr), IPPROTO_TCP, 0); 592 sizeof(struct tcphdr), IPPROTO_TCP, 0);
593 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 593 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
594 arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
594 595
595 net = dev_net(skb->dst->dev); 596 net = dev_net(skb->dst->dev);
596 ip_send_reply(net->ipv4.tcp_sock, skb, 597 ip_send_reply(net->ipv4.tcp_sock, skb,
@@ -606,7 +607,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
606 607
607static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, 608static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
608 u32 win, u32 ts, int oif, 609 u32 win, u32 ts, int oif,
609 struct tcp_md5sig_key *key) 610 struct tcp_md5sig_key *key,
611 int reply_flags)
610{ 612{
611 struct tcphdr *th = tcp_hdr(skb); 613 struct tcphdr *th = tcp_hdr(skb);
612 struct { 614 struct {
@@ -659,6 +661,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
659 ip_hdr(skb)->daddr, &rep.th); 661 ip_hdr(skb)->daddr, &rep.th);
660 } 662 }
661#endif 663#endif
664 arg.flags = reply_flags;
662 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 665 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
663 ip_hdr(skb)->saddr, /* XXX */ 666 ip_hdr(skb)->saddr, /* XXX */
664 arg.iov[0].iov_len, IPPROTO_TCP, 0); 667 arg.iov[0].iov_len, IPPROTO_TCP, 0);
@@ -681,7 +684,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
681 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 684 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
682 tcptw->tw_ts_recent, 685 tcptw->tw_ts_recent,
683 tw->tw_bound_dev_if, 686 tw->tw_bound_dev_if,
684 tcp_twsk_md5_key(tcptw) 687 tcp_twsk_md5_key(tcptw),
688 tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0
685 ); 689 );
686 690
687 inet_twsk_put(tw); 691 inet_twsk_put(tw);
@@ -694,7 +698,8 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
694 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, 698 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
695 req->ts_recent, 699 req->ts_recent,
696 0, 700 0,
697 tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr)); 701 tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr),
702 inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0);
698} 703}
699 704
700/* 705/*
@@ -1244,6 +1249,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1244 ireq = inet_rsk(req); 1249 ireq = inet_rsk(req);
1245 ireq->loc_addr = daddr; 1250 ireq->loc_addr = daddr;
1246 ireq->rmt_addr = saddr; 1251 ireq->rmt_addr = saddr;
1252 ireq->no_srccheck = inet_sk(sk)->transparent;
1247 ireq->opt = tcp_v4_save_options(sk, skb); 1253 ireq->opt = tcp_v4_save_options(sk, skb);
1248 if (!want_cookie) 1254 if (!want_cookie)
1249 TCP_ECN_create_request(req, tcp_hdr(skb)); 1255 TCP_ECN_create_request(req, tcp_hdr(skb));