diff options
| -rw-r--r-- | include/net/inet_sock.h | 8 | ||||
| -rw-r--r-- | include/net/ip.h | 3 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 12 |
3 files changed, 19 insertions, 4 deletions
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 139b78b4dfeb..dced3f64f975 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h | |||
| @@ -72,7 +72,8 @@ struct inet_request_sock { | |||
| 72 | sack_ok : 1, | 72 | sack_ok : 1, |
| 73 | wscale_ok : 1, | 73 | wscale_ok : 1, |
| 74 | ecn_ok : 1, | 74 | ecn_ok : 1, |
| 75 | acked : 1; | 75 | acked : 1, |
| 76 | no_srccheck: 1; | ||
| 76 | struct ip_options *opt; | 77 | struct ip_options *opt; |
| 77 | }; | 78 | }; |
| 78 | 79 | ||
| @@ -204,4 +205,9 @@ static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops | |||
| 204 | return req; | 205 | return req; |
| 205 | } | 206 | } |
| 206 | 207 | ||
| 208 | static inline __u8 inet_sk_flowi_flags(const struct sock *sk) | ||
| 209 | { | ||
| 210 | return inet_sk(sk)->transparent ? FLOWI_FLAG_ANYSRC : 0; | ||
| 211 | } | ||
| 212 | |||
| 207 | #endif /* _INET_SOCK_H */ | 213 | #endif /* _INET_SOCK_H */ |
diff --git a/include/net/ip.h b/include/net/ip.h index 250e6ef025a4..90b27f634b76 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
| @@ -140,12 +140,15 @@ static inline void ip_tr_mc_map(__be32 addr, char *buf) | |||
| 140 | 140 | ||
| 141 | struct ip_reply_arg { | 141 | struct ip_reply_arg { |
| 142 | struct kvec iov[1]; | 142 | struct kvec iov[1]; |
| 143 | int flags; | ||
| 143 | __wsum csum; | 144 | __wsum csum; |
| 144 | int csumoffset; /* u16 offset of csum in iov[0].iov_base */ | 145 | int csumoffset; /* u16 offset of csum in iov[0].iov_base */ |
| 145 | /* -1 if not needed */ | 146 | /* -1 if not needed */ |
| 146 | int bound_dev_if; | 147 | int bound_dev_if; |
| 147 | }; | 148 | }; |
| 148 | 149 | ||
| 150 | #define IP_REPLY_ARG_NOSRCCHECK 1 | ||
| 151 | |||
| 149 | void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, | 152 | void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, |
| 150 | unsigned int len); | 153 | unsigned int len); |
| 151 | 154 | ||
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 | ||
| 607 | static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, | 608 | static 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)); |
