diff options
| author | Ingo Molnar <mingo@elte.hu> | 2011-09-26 06:53:42 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2011-09-26 06:54:28 -0400 |
| commit | ed3982cf3748b657ffb79d9d1c2e4a562661db2d (patch) | |
| tree | 6e3654f460e23aa1b1512896aa3f03886a69be1b /net/ipv4 | |
| parent | cba9bd22a5f8f857534b9a7f3fb3cafa0ac5fb75 (diff) | |
| parent | d93dc5c4478c1fd5de85a3e8aece9aad7bbae044 (diff) | |
Merge commit 'v3.1-rc7' into perf/core
Merge reason: Pick up the latest upstream fixes.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/af_inet.c | 7 | ||||
| -rw-r--r-- | net/ipv4/fib_semantics.c | 10 | ||||
| -rw-r--r-- | net/ipv4/igmp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 12 | ||||
| -rw-r--r-- | net/ipv4/proc.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 49 |
7 files changed, 52 insertions, 32 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 1b745d412cf6..dd2b9478ddd1 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -466,8 +466,13 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 466 | goto out; | 466 | goto out; |
| 467 | 467 | ||
| 468 | if (addr->sin_family != AF_INET) { | 468 | if (addr->sin_family != AF_INET) { |
| 469 | /* Compatibility games : accept AF_UNSPEC (mapped to AF_INET) | ||
| 470 | * only if s_addr is INADDR_ANY. | ||
| 471 | */ | ||
| 469 | err = -EAFNOSUPPORT; | 472 | err = -EAFNOSUPPORT; |
| 470 | goto out; | 473 | if (addr->sin_family != AF_UNSPEC || |
| 474 | addr->sin_addr.s_addr != htonl(INADDR_ANY)) | ||
| 475 | goto out; | ||
| 471 | } | 476 | } |
| 472 | 477 | ||
| 473 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); | 478 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 33e2c35b74b7..80106d89d548 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
| @@ -142,6 +142,14 @@ const struct fib_prop fib_props[RTN_MAX + 1] = { | |||
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | /* Release a nexthop info record */ | 144 | /* Release a nexthop info record */ |
| 145 | static void free_fib_info_rcu(struct rcu_head *head) | ||
| 146 | { | ||
| 147 | struct fib_info *fi = container_of(head, struct fib_info, rcu); | ||
| 148 | |||
| 149 | if (fi->fib_metrics != (u32 *) dst_default_metrics) | ||
| 150 | kfree(fi->fib_metrics); | ||
| 151 | kfree(fi); | ||
| 152 | } | ||
| 145 | 153 | ||
| 146 | void free_fib_info(struct fib_info *fi) | 154 | void free_fib_info(struct fib_info *fi) |
| 147 | { | 155 | { |
| @@ -156,7 +164,7 @@ void free_fib_info(struct fib_info *fi) | |||
| 156 | } endfor_nexthops(fi); | 164 | } endfor_nexthops(fi); |
| 157 | fib_info_cnt--; | 165 | fib_info_cnt--; |
| 158 | release_net(fi->fib_net); | 166 | release_net(fi->fib_net); |
| 159 | kfree_rcu(fi, rcu); | 167 | call_rcu(&fi->rcu, free_fib_info_rcu); |
| 160 | } | 168 | } |
| 161 | 169 | ||
| 162 | void fib_release_info(struct fib_info *fi) | 170 | void fib_release_info(struct fib_info *fi) |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 283c0a26e03f..d577199eabd5 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -767,7 +767,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) | |||
| 767 | break; | 767 | break; |
| 768 | for (i=0; i<nsrcs; i++) { | 768 | for (i=0; i<nsrcs; i++) { |
| 769 | /* skip inactive filters */ | 769 | /* skip inactive filters */ |
| 770 | if (pmc->sfcount[MCAST_INCLUDE] || | 770 | if (psf->sf_count[MCAST_INCLUDE] || |
| 771 | pmc->sfcount[MCAST_EXCLUDE] != | 771 | pmc->sfcount[MCAST_EXCLUDE] != |
| 772 | psf->sf_count[MCAST_EXCLUDE]) | 772 | psf->sf_count[MCAST_EXCLUDE]) |
| 773 | continue; | 773 | continue; |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 5c9b9d963918..e59aabd0eae4 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -218,6 +218,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
| 218 | return skb; | 218 | return skb; |
| 219 | 219 | ||
| 220 | nlmsg_failure: | 220 | nlmsg_failure: |
| 221 | kfree_skb(skb); | ||
| 221 | *errp = -EINVAL; | 222 | *errp = -EINVAL; |
| 222 | printk(KERN_ERR "ip_queue: error creating packet message\n"); | 223 | printk(KERN_ERR "ip_queue: error creating packet message\n"); |
| 223 | return NULL; | 224 | return NULL; |
| @@ -313,7 +314,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len) | |||
| 313 | { | 314 | { |
| 314 | struct nf_queue_entry *entry; | 315 | struct nf_queue_entry *entry; |
| 315 | 316 | ||
| 316 | if (vmsg->value > NF_MAX_VERDICT) | 317 | if (vmsg->value > NF_MAX_VERDICT || vmsg->value == NF_STOLEN) |
| 317 | return -EINVAL; | 318 | return -EINVAL; |
| 318 | 319 | ||
| 319 | entry = ipq_find_dequeue_entry(vmsg->id); | 320 | entry = ipq_find_dequeue_entry(vmsg->id); |
| @@ -358,12 +359,9 @@ ipq_receive_peer(struct ipq_peer_msg *pmsg, | |||
| 358 | break; | 359 | break; |
| 359 | 360 | ||
| 360 | case IPQM_VERDICT: | 361 | case IPQM_VERDICT: |
| 361 | if (pmsg->msg.verdict.value > NF_MAX_VERDICT) | 362 | status = ipq_set_verdict(&pmsg->msg.verdict, |
| 362 | status = -EINVAL; | 363 | len - sizeof(*pmsg)); |
| 363 | else | 364 | break; |
| 364 | status = ipq_set_verdict(&pmsg->msg.verdict, | ||
| 365 | len - sizeof(*pmsg)); | ||
| 366 | break; | ||
| 367 | default: | 365 | default: |
| 368 | status = -EINVAL; | 366 | status = -EINVAL; |
| 369 | } | 367 | } |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index b14ec7d03b6e..4bfad5da94f4 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -254,6 +254,8 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
| 254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), | 254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), |
| 255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), | 255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), |
| 256 | SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), | 256 | SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), |
| 257 | SNMP_MIB_ITEM("TCPReqQFullDoCookies", LINUX_MIB_TCPREQQFULLDOCOOKIES), | ||
| 258 | SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP), | ||
| 257 | SNMP_MIB_SENTINEL | 259 | SNMP_MIB_SENTINEL |
| 258 | }; | 260 | }; |
| 259 | 261 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ea0d2183df4b..21fab3edb92c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -1124,7 +1124,7 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, | |||
| 1124 | return 0; | 1124 | return 0; |
| 1125 | 1125 | ||
| 1126 | /* ...Then it's D-SACK, and must reside below snd_una completely */ | 1126 | /* ...Then it's D-SACK, and must reside below snd_una completely */ |
| 1127 | if (!after(end_seq, tp->snd_una)) | 1127 | if (after(end_seq, tp->snd_una)) |
| 1128 | return 0; | 1128 | return 0; |
| 1129 | 1129 | ||
| 1130 | if (!before(start_seq, tp->undo_marker)) | 1130 | if (!before(start_seq, tp->undo_marker)) |
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) { |
