diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 49 | 
1 files changed, 28 insertions, 21 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1c12b8ec849d..c34f01513945 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c  | |||
| @@ -808,20 +808,38 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req) | |||
| 808 | kfree(inet_rsk(req)->opt); | 808 | kfree(inet_rsk(req)->opt); | 
| 809 | } | 809 | } | 
| 810 | 810 | ||
| 811 | static void syn_flood_warning(const struct sk_buff *skb) | 811 | /* | 
| 812 | * Return 1 if a syncookie should be sent | ||
| 813 | */ | ||
| 814 | int tcp_syn_flood_action(struct sock *sk, | ||
| 815 | const struct sk_buff *skb, | ||
| 816 | const char *proto) | ||
| 812 | { | 817 | { | 
| 813 | const char *msg; | 818 | const char *msg = "Dropping request"; | 
| 819 | int want_cookie = 0; | ||
| 820 | struct listen_sock *lopt; | ||
| 821 | |||
| 822 | |||
| 814 | 823 | ||
| 815 | #ifdef CONFIG_SYN_COOKIES | 824 | #ifdef CONFIG_SYN_COOKIES | 
| 816 | if (sysctl_tcp_syncookies) | 825 | if (sysctl_tcp_syncookies) { | 
| 817 | msg = "Sending cookies"; | 826 | msg = "Sending cookies"; | 
| 818 | else | 827 | want_cookie = 1; | 
| 828 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDOCOOKIES); | ||
| 829 | } else | ||
| 819 | #endif | 830 | #endif | 
| 820 | msg = "Dropping request"; | 831 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDROP); | 
| 821 | 832 | ||
| 822 | pr_info("TCP: Possible SYN flooding on port %d. %s.\n", | 833 | lopt = inet_csk(sk)->icsk_accept_queue.listen_opt; | 
| 823 | ntohs(tcp_hdr(skb)->dest), msg); | 834 | if (!lopt->synflood_warned) { | 
| 835 | lopt->synflood_warned = 1; | ||
| 836 | pr_info("%s: Possible SYN flooding on port %d. %s. " | ||
| 837 | " Check SNMP counters.\n", | ||
| 838 | proto, ntohs(tcp_hdr(skb)->dest), msg); | ||
| 839 | } | ||
| 840 | return want_cookie; | ||
| 824 | } | 841 | } | 
| 842 | EXPORT_SYMBOL(tcp_syn_flood_action); | ||
| 825 | 843 | ||
| 826 | /* | 844 | /* | 
| 827 | * Save and compile IPv4 options into the request_sock if needed. | 845 | * Save and compile IPv4 options into the request_sock if needed. | 
| @@ -1235,11 +1253,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
| 1235 | __be32 saddr = ip_hdr(skb)->saddr; | 1253 | __be32 saddr = ip_hdr(skb)->saddr; | 
| 1236 | __be32 daddr = ip_hdr(skb)->daddr; | 1254 | __be32 daddr = ip_hdr(skb)->daddr; | 
| 1237 | __u32 isn = TCP_SKB_CB(skb)->when; | 1255 | __u32 isn = TCP_SKB_CB(skb)->when; | 
| 1238 | #ifdef CONFIG_SYN_COOKIES | ||
| 1239 | int want_cookie = 0; | 1256 | int want_cookie = 0; | 
| 1240 | #else | ||
| 1241 | #define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */ | ||
| 1242 | #endif | ||
| 1243 | 1257 | ||
| 1244 | /* Never answer to SYNs send to broadcast or multicast */ | 1258 | /* Never answer to SYNs send to broadcast or multicast */ | 
| 1245 | if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) | 1259 | if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) | 
| @@ -1250,14 +1264,9 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
| 1250 | * evidently real one. | 1264 | * evidently real one. | 
| 1251 | */ | 1265 | */ | 
| 1252 | if (inet_csk_reqsk_queue_is_full(sk) && !isn) { | 1266 | if (inet_csk_reqsk_queue_is_full(sk) && !isn) { | 
| 1253 | if (net_ratelimit()) | 1267 | want_cookie = tcp_syn_flood_action(sk, skb, "TCP"); | 
| 1254 | syn_flood_warning(skb); | 1268 | if (!want_cookie) | 
| 1255 | #ifdef CONFIG_SYN_COOKIES | 1269 | goto drop; | 
| 1256 | if (sysctl_tcp_syncookies) { | ||
| 1257 | want_cookie = 1; | ||
| 1258 | } else | ||
| 1259 | #endif | ||
| 1260 | goto drop; | ||
| 1261 | } | 1270 | } | 
| 1262 | 1271 | ||
| 1263 | /* Accept backlog is full. If we have already queued enough | 1272 | /* Accept backlog is full. If we have already queued enough | 
| @@ -1303,9 +1312,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
| 1303 | while (l-- > 0) | 1312 | while (l-- > 0) | 
| 1304 | *c++ ^= *hash_location++; | 1313 | *c++ ^= *hash_location++; | 
| 1305 | 1314 | ||
| 1306 | #ifdef CONFIG_SYN_COOKIES | ||
| 1307 | want_cookie = 0; /* not our kind of cookie */ | 1315 | want_cookie = 0; /* not our kind of cookie */ | 
| 1308 | #endif | ||
| 1309 | tmp_ext.cookie_out_never = 0; /* false */ | 1316 | tmp_ext.cookie_out_never = 0; /* false */ | 
| 1310 | tmp_ext.cookie_plus = tmp_opt.cookie_plus; | 1317 | tmp_ext.cookie_plus = tmp_opt.cookie_plus; | 
| 1311 | } else if (!tp->rx_opt.cookie_in_always) { | 1318 | } else if (!tp->rx_opt.cookie_in_always) { | 
