diff options
| author | Christopher Kenna <cjk@cs.unc.edu> | 2012-09-28 13:46:28 -0400 |
|---|---|---|
| committer | Christopher Kenna <cjk@cs.unc.edu> | 2012-09-28 14:50:15 -0400 |
| commit | daa22703f14c007e93b464c45fa60019a36f546d (patch) | |
| tree | a1a130b6e128dc9d57c35c026977e1b4953105e1 /net/ipv4 | |
| parent | 5aa287dcf1b5879aa0150b0511833c52885f5b4c (diff) | |
Apply k4412 kernel from HardKernel for ODROID-X.
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/Makefile | 1 | ||||
| -rw-r--r-- | net/ipv4/af_inet.c | 18 | ||||
| -rw-r--r-- | net/ipv4/devinet.c | 8 | ||||
| -rw-r--r-- | net/ipv4/netfilter/Kconfig | 12 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ipt_REJECT.c | 8 | ||||
| -rw-r--r-- | net/ipv4/sysfs_net_ipv4.c | 88 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 121 |
7 files changed, 254 insertions, 2 deletions
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index f2dc69cffb5..681084d76a9 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile | |||
| @@ -14,6 +14,7 @@ obj-y := route.o inetpeer.o protocol.o \ | |||
| 14 | inet_fragment.o ping.o | 14 | inet_fragment.o ping.o |
| 15 | 15 | ||
| 16 | obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o | 16 | obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o |
| 17 | obj-$(CONFIG_SYSFS) += sysfs_net_ipv4.o | ||
| 17 | obj-$(CONFIG_PROC_FS) += proc.o | 18 | obj-$(CONFIG_PROC_FS) += proc.o |
| 18 | obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o | 19 | obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o |
| 19 | obj-$(CONFIG_IP_MROUTE) += ipmr.o | 20 | obj-$(CONFIG_IP_MROUTE) += ipmr.o |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index ef1528af7ab..4d60f12c7b6 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -118,6 +118,19 @@ | |||
| 118 | #include <linux/mroute.h> | 118 | #include <linux/mroute.h> |
| 119 | #endif | 119 | #endif |
| 120 | 120 | ||
| 121 | #ifdef CONFIG_ANDROID_PARANOID_NETWORK | ||
| 122 | #include <linux/android_aid.h> | ||
| 123 | |||
| 124 | static inline int current_has_network(void) | ||
| 125 | { | ||
| 126 | return in_egroup_p(AID_INET) || capable(CAP_NET_RAW); | ||
| 127 | } | ||
| 128 | #else | ||
| 129 | static inline int current_has_network(void) | ||
| 130 | { | ||
| 131 | return 1; | ||
| 132 | } | ||
| 133 | #endif | ||
| 121 | 134 | ||
| 122 | /* The inetsw table contains everything that inet_create needs to | 135 | /* The inetsw table contains everything that inet_create needs to |
| 123 | * build a new socket. | 136 | * build a new socket. |
| @@ -258,6 +271,7 @@ static inline int inet_netns_ok(struct net *net, int protocol) | |||
| 258 | return ipprot->netns_ok; | 271 | return ipprot->netns_ok; |
| 259 | } | 272 | } |
| 260 | 273 | ||
| 274 | |||
| 261 | /* | 275 | /* |
| 262 | * Create an inet socket. | 276 | * Create an inet socket. |
| 263 | */ | 277 | */ |
| @@ -274,6 +288,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol, | |||
| 274 | int try_loading_module = 0; | 288 | int try_loading_module = 0; |
| 275 | int err; | 289 | int err; |
| 276 | 290 | ||
| 291 | if (!current_has_network()) | ||
| 292 | return -EACCES; | ||
| 293 | |||
| 277 | if (unlikely(!inet_ehash_secret)) | 294 | if (unlikely(!inet_ehash_secret)) |
| 278 | if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) | 295 | if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) |
| 279 | build_ehash_secret(); | 296 | build_ehash_secret(); |
| @@ -874,6 +891,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
| 874 | case SIOCSIFPFLAGS: | 891 | case SIOCSIFPFLAGS: |
| 875 | case SIOCGIFPFLAGS: | 892 | case SIOCGIFPFLAGS: |
| 876 | case SIOCSIFFLAGS: | 893 | case SIOCSIFFLAGS: |
| 894 | case SIOCKILLADDR: | ||
| 877 | err = devinet_ioctl(net, cmd, (void __user *)arg); | 895 | err = devinet_ioctl(net, cmd, (void __user *)arg); |
| 878 | break; | 896 | break; |
| 879 | default: | 897 | default: |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 7d7fb20b0a1..c48323ad268 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -59,6 +59,7 @@ | |||
| 59 | 59 | ||
| 60 | #include <net/arp.h> | 60 | #include <net/arp.h> |
| 61 | #include <net/ip.h> | 61 | #include <net/ip.h> |
| 62 | #include <net/tcp.h> | ||
| 62 | #include <net/route.h> | 63 | #include <net/route.h> |
| 63 | #include <net/ip_fib.h> | 64 | #include <net/ip_fib.h> |
| 64 | #include <net/rtnetlink.h> | 65 | #include <net/rtnetlink.h> |
| @@ -735,6 +736,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
| 735 | case SIOCSIFBRDADDR: /* Set the broadcast address */ | 736 | case SIOCSIFBRDADDR: /* Set the broadcast address */ |
| 736 | case SIOCSIFDSTADDR: /* Set the destination address */ | 737 | case SIOCSIFDSTADDR: /* Set the destination address */ |
| 737 | case SIOCSIFNETMASK: /* Set the netmask for the interface */ | 738 | case SIOCSIFNETMASK: /* Set the netmask for the interface */ |
| 739 | case SIOCKILLADDR: /* Nuke all sockets on this address */ | ||
| 738 | ret = -EACCES; | 740 | ret = -EACCES; |
| 739 | if (!capable(CAP_NET_ADMIN)) | 741 | if (!capable(CAP_NET_ADMIN)) |
| 740 | goto out; | 742 | goto out; |
| @@ -786,7 +788,8 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
| 786 | } | 788 | } |
| 787 | 789 | ||
| 788 | ret = -EADDRNOTAVAIL; | 790 | ret = -EADDRNOTAVAIL; |
| 789 | if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) | 791 | if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS |
| 792 | && cmd != SIOCKILLADDR) | ||
| 790 | goto done; | 793 | goto done; |
| 791 | 794 | ||
| 792 | switch (cmd) { | 795 | switch (cmd) { |
| @@ -912,6 +915,9 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
| 912 | inet_insert_ifa(ifa); | 915 | inet_insert_ifa(ifa); |
| 913 | } | 916 | } |
| 914 | break; | 917 | break; |
| 918 | case SIOCKILLADDR: /* Nuke all connections on this address */ | ||
| 919 | ret = tcp_nuke_addr(net, (struct sockaddr *) sin); | ||
| 920 | break; | ||
| 915 | } | 921 | } |
| 916 | done: | 922 | done: |
| 917 | rtnl_unlock(); | 923 | rtnl_unlock(); |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 1dfc18a03fd..73b4e91a87e 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
| @@ -113,6 +113,18 @@ config IP_NF_TARGET_REJECT | |||
| 113 | 113 | ||
| 114 | To compile it as a module, choose M here. If unsure, say N. | 114 | To compile it as a module, choose M here. If unsure, say N. |
| 115 | 115 | ||
| 116 | config IP_NF_TARGET_REJECT_SKERR | ||
| 117 | bool "Force socket error when rejecting with icmp*" | ||
| 118 | depends on IP_NF_TARGET_REJECT | ||
| 119 | default n | ||
| 120 | help | ||
| 121 | This option enables turning a "--reject-with icmp*" into a matching | ||
| 122 | socket error also. | ||
| 123 | The REJECT target normally allows sending an ICMP message. But it | ||
| 124 | leaves the local socket unaware of any ingress rejects. | ||
| 125 | |||
| 126 | If unsure, say N. | ||
| 127 | |||
| 116 | config IP_NF_TARGET_LOG | 128 | config IP_NF_TARGET_LOG |
| 117 | tristate "LOG target support" | 129 | tristate "LOG target support" |
| 118 | default m if NETFILTER_ADVANCED=n | 130 | default m if NETFILTER_ADVANCED=n |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 51f13f8ec72..9dd754c7f2b 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
| @@ -128,6 +128,14 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
| 128 | static inline void send_unreach(struct sk_buff *skb_in, int code) | 128 | static inline void send_unreach(struct sk_buff *skb_in, int code) |
| 129 | { | 129 | { |
| 130 | icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0); | 130 | icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0); |
| 131 | #ifdef CONFIG_IP_NF_TARGET_REJECT_SKERR | ||
| 132 | if (skb_in->sk) { | ||
| 133 | skb_in->sk->sk_err = icmp_err_convert[code].errno; | ||
| 134 | skb_in->sk->sk_error_report(skb_in->sk); | ||
| 135 | pr_debug("ipt_REJECT: sk_err=%d for skb=%p sk=%p\n", | ||
| 136 | skb_in->sk->sk_err, skb_in, skb_in->sk); | ||
| 137 | } | ||
| 138 | #endif | ||
| 131 | } | 139 | } |
| 132 | 140 | ||
| 133 | static unsigned int | 141 | static unsigned int |
diff --git a/net/ipv4/sysfs_net_ipv4.c b/net/ipv4/sysfs_net_ipv4.c new file mode 100644 index 00000000000..0cbbf10026a --- /dev/null +++ b/net/ipv4/sysfs_net_ipv4.c | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | /* | ||
| 2 | * net/ipv4/sysfs_net_ipv4.c | ||
| 3 | * | ||
| 4 | * sysfs-based networking knobs (so we can, unlike with sysctl, control perms) | ||
| 5 | * | ||
| 6 | * Copyright (C) 2008 Google, Inc. | ||
| 7 | * | ||
| 8 | * Robert Love <rlove@google.com> | ||
| 9 | * | ||
| 10 | * This software is licensed under the terms of the GNU General Public | ||
| 11 | * License version 2, as published by the Free Software Foundation, and | ||
| 12 | * may be copied, distributed, and modified under those terms. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/kobject.h> | ||
| 21 | #include <linux/string.h> | ||
| 22 | #include <linux/sysfs.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <net/tcp.h> | ||
| 25 | |||
| 26 | #define CREATE_IPV4_FILE(_name, _var) \ | ||
| 27 | static ssize_t _name##_show(struct kobject *kobj, \ | ||
| 28 | struct kobj_attribute *attr, char *buf) \ | ||
| 29 | { \ | ||
| 30 | return sprintf(buf, "%d\n", _var); \ | ||
| 31 | } \ | ||
| 32 | static ssize_t _name##_store(struct kobject *kobj, \ | ||
| 33 | struct kobj_attribute *attr, \ | ||
| 34 | const char *buf, size_t count) \ | ||
| 35 | { \ | ||
| 36 | int val, ret; \ | ||
| 37 | ret = sscanf(buf, "%d", &val); \ | ||
| 38 | if (ret != 1) \ | ||
| 39 | return -EINVAL; \ | ||
| 40 | if (val < 0) \ | ||
| 41 | return -EINVAL; \ | ||
| 42 | _var = val; \ | ||
| 43 | return count; \ | ||
| 44 | } \ | ||
| 45 | static struct kobj_attribute _name##_attr = \ | ||
| 46 | __ATTR(_name, 0644, _name##_show, _name##_store) | ||
| 47 | |||
| 48 | CREATE_IPV4_FILE(tcp_wmem_min, sysctl_tcp_wmem[0]); | ||
| 49 | CREATE_IPV4_FILE(tcp_wmem_def, sysctl_tcp_wmem[1]); | ||
| 50 | CREATE_IPV4_FILE(tcp_wmem_max, sysctl_tcp_wmem[2]); | ||
| 51 | |||
| 52 | CREATE_IPV4_FILE(tcp_rmem_min, sysctl_tcp_rmem[0]); | ||
| 53 | CREATE_IPV4_FILE(tcp_rmem_def, sysctl_tcp_rmem[1]); | ||
| 54 | CREATE_IPV4_FILE(tcp_rmem_max, sysctl_tcp_rmem[2]); | ||
| 55 | |||
| 56 | static struct attribute *ipv4_attrs[] = { | ||
| 57 | &tcp_wmem_min_attr.attr, | ||
| 58 | &tcp_wmem_def_attr.attr, | ||
| 59 | &tcp_wmem_max_attr.attr, | ||
| 60 | &tcp_rmem_min_attr.attr, | ||
| 61 | &tcp_rmem_def_attr.attr, | ||
| 62 | &tcp_rmem_max_attr.attr, | ||
| 63 | NULL | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct attribute_group ipv4_attr_group = { | ||
| 67 | .attrs = ipv4_attrs, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static __init int sysfs_ipv4_init(void) | ||
| 71 | { | ||
| 72 | struct kobject *ipv4_kobject; | ||
| 73 | int ret; | ||
| 74 | |||
| 75 | ipv4_kobject = kobject_create_and_add("ipv4", kernel_kobj); | ||
| 76 | if (!ipv4_kobject) | ||
| 77 | return -ENOMEM; | ||
| 78 | |||
| 79 | ret = sysfs_create_group(ipv4_kobject, &ipv4_attr_group); | ||
| 80 | if (ret) { | ||
| 81 | kobject_put(ipv4_kobject); | ||
| 82 | return ret; | ||
| 83 | } | ||
| 84 | |||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | subsys_initcall(sysfs_ipv4_init); | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b6ec23c7ffc..31741cf9bb6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -266,11 +266,15 @@ | |||
| 266 | #include <linux/crypto.h> | 266 | #include <linux/crypto.h> |
| 267 | #include <linux/time.h> | 267 | #include <linux/time.h> |
| 268 | #include <linux/slab.h> | 268 | #include <linux/slab.h> |
| 269 | #include <linux/uid_stat.h> | ||
| 269 | 270 | ||
| 270 | #include <net/icmp.h> | 271 | #include <net/icmp.h> |
| 271 | #include <net/tcp.h> | 272 | #include <net/tcp.h> |
| 272 | #include <net/xfrm.h> | 273 | #include <net/xfrm.h> |
| 273 | #include <net/ip.h> | 274 | #include <net/ip.h> |
| 275 | #include <net/ip6_route.h> | ||
| 276 | #include <net/ipv6.h> | ||
| 277 | #include <net/transp_v6.h> | ||
| 274 | #include <net/netdma.h> | 278 | #include <net/netdma.h> |
| 275 | #include <net/sock.h> | 279 | #include <net/sock.h> |
| 276 | 280 | ||
| @@ -1111,6 +1115,9 @@ out: | |||
| 1111 | if (copied) | 1115 | if (copied) |
| 1112 | tcp_push(sk, flags, mss_now, tp->nonagle); | 1116 | tcp_push(sk, flags, mss_now, tp->nonagle); |
| 1113 | release_sock(sk); | 1117 | release_sock(sk); |
| 1118 | |||
| 1119 | if (copied > 0) | ||
| 1120 | uid_stat_tcp_snd(current_uid(), copied); | ||
| 1114 | return copied; | 1121 | return copied; |
| 1115 | 1122 | ||
| 1116 | do_fault: | 1123 | do_fault: |
| @@ -1387,8 +1394,11 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
| 1387 | tcp_rcv_space_adjust(sk); | 1394 | tcp_rcv_space_adjust(sk); |
| 1388 | 1395 | ||
| 1389 | /* Clean up data we have read: This will do ACK frames. */ | 1396 | /* Clean up data we have read: This will do ACK frames. */ |
| 1390 | if (copied > 0) | 1397 | if (copied > 0) { |
| 1391 | tcp_cleanup_rbuf(sk, copied); | 1398 | tcp_cleanup_rbuf(sk, copied); |
| 1399 | uid_stat_tcp_rcv(current_uid(), copied); | ||
| 1400 | } | ||
| 1401 | |||
| 1392 | return copied; | 1402 | return copied; |
| 1393 | } | 1403 | } |
| 1394 | EXPORT_SYMBOL(tcp_read_sock); | 1404 | EXPORT_SYMBOL(tcp_read_sock); |
| @@ -1770,6 +1780,9 @@ skip_copy: | |||
| 1770 | tcp_cleanup_rbuf(sk, copied); | 1780 | tcp_cleanup_rbuf(sk, copied); |
| 1771 | 1781 | ||
| 1772 | release_sock(sk); | 1782 | release_sock(sk); |
| 1783 | |||
| 1784 | if (copied > 0) | ||
| 1785 | uid_stat_tcp_rcv(current_uid(), copied); | ||
| 1773 | return copied; | 1786 | return copied; |
| 1774 | 1787 | ||
| 1775 | out: | 1788 | out: |
| @@ -1778,6 +1791,8 @@ out: | |||
| 1778 | 1791 | ||
| 1779 | recv_urg: | 1792 | recv_urg: |
| 1780 | err = tcp_recv_urg(sk, msg, len, flags); | 1793 | err = tcp_recv_urg(sk, msg, len, flags); |
| 1794 | if (err > 0) | ||
| 1795 | uid_stat_tcp_rcv(current_uid(), err); | ||
| 1781 | goto out; | 1796 | goto out; |
| 1782 | } | 1797 | } |
| 1783 | EXPORT_SYMBOL(tcp_recvmsg); | 1798 | EXPORT_SYMBOL(tcp_recvmsg); |
| @@ -3313,3 +3328,107 @@ void __init tcp_init(void) | |||
| 3313 | tcp_secret_retiring = &tcp_secret_two; | 3328 | tcp_secret_retiring = &tcp_secret_two; |
| 3314 | tcp_secret_secondary = &tcp_secret_two; | 3329 | tcp_secret_secondary = &tcp_secret_two; |
| 3315 | } | 3330 | } |
| 3331 | |||
| 3332 | static int tcp_is_local(struct net *net, __be32 addr) { | ||
| 3333 | struct rtable *rt; | ||
| 3334 | struct flowi4 fl4 = { .daddr = addr }; | ||
| 3335 | rt = ip_route_output_key(net, &fl4); | ||
| 3336 | if (IS_ERR_OR_NULL(rt)) | ||
| 3337 | return 0; | ||
| 3338 | return rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK); | ||
| 3339 | } | ||
| 3340 | |||
| 3341 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 3342 | static int tcp_is_local6(struct net *net, struct in6_addr *addr) { | ||
| 3343 | struct rt6_info *rt6 = rt6_lookup(net, addr, addr, 0, 0); | ||
| 3344 | return rt6 && rt6->rt6i_dev && (rt6->rt6i_dev->flags & IFF_LOOPBACK); | ||
| 3345 | } | ||
| 3346 | #endif | ||
| 3347 | |||
| 3348 | /* | ||
| 3349 | * tcp_nuke_addr - destroy all sockets on the given local address | ||
| 3350 | * if local address is the unspecified address (0.0.0.0 or ::), destroy all | ||
| 3351 | * sockets with local addresses that are not configured. | ||
| 3352 | */ | ||
| 3353 | int tcp_nuke_addr(struct net *net, struct sockaddr *addr) | ||
| 3354 | { | ||
| 3355 | int family = addr->sa_family; | ||
| 3356 | unsigned int bucket; | ||
| 3357 | |||
| 3358 | struct in_addr *in; | ||
| 3359 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 3360 | struct in6_addr *in6; | ||
| 3361 | #endif | ||
| 3362 | if (family == AF_INET) { | ||
| 3363 | in = &((struct sockaddr_in *)addr)->sin_addr; | ||
| 3364 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 3365 | } else if (family == AF_INET6) { | ||
| 3366 | in6 = &((struct sockaddr_in6 *)addr)->sin6_addr; | ||
| 3367 | #endif | ||
| 3368 | } else { | ||
| 3369 | return -EAFNOSUPPORT; | ||
| 3370 | } | ||
| 3371 | |||
| 3372 | for (bucket = 0; bucket < tcp_hashinfo.ehash_mask; bucket++) { | ||
| 3373 | struct hlist_nulls_node *node; | ||
| 3374 | struct sock *sk; | ||
| 3375 | spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, bucket); | ||
| 3376 | |||
| 3377 | restart: | ||
| 3378 | spin_lock_bh(lock); | ||
| 3379 | sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[bucket].chain) { | ||
| 3380 | struct inet_sock *inet = inet_sk(sk); | ||
| 3381 | |||
| 3382 | if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT) | ||
| 3383 | continue; | ||
| 3384 | if (sock_flag(sk, SOCK_DEAD)) | ||
| 3385 | continue; | ||
| 3386 | |||
| 3387 | if (family == AF_INET) { | ||
| 3388 | __be32 s4 = inet->inet_rcv_saddr; | ||
| 3389 | if (s4 == LOOPBACK4_IPV6) | ||
| 3390 | continue; | ||
| 3391 | |||
| 3392 | if (in->s_addr != s4 && | ||
| 3393 | !(in->s_addr == INADDR_ANY && | ||
| 3394 | !tcp_is_local(net, s4))) | ||
| 3395 | continue; | ||
| 3396 | } | ||
| 3397 | |||
| 3398 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 3399 | if (family == AF_INET6) { | ||
| 3400 | struct in6_addr *s6; | ||
| 3401 | if (!inet->pinet6) | ||
| 3402 | continue; | ||
| 3403 | |||
| 3404 | s6 = &inet->pinet6->rcv_saddr; | ||
| 3405 | if (ipv6_addr_type(s6) == IPV6_ADDR_MAPPED) | ||
| 3406 | continue; | ||
| 3407 | |||
| 3408 | if (!ipv6_addr_equal(in6, s6) && | ||
| 3409 | !(ipv6_addr_equal(in6, &in6addr_any) && | ||
| 3410 | !tcp_is_local6(net, s6))) | ||
| 3411 | continue; | ||
| 3412 | } | ||
| 3413 | #endif | ||
| 3414 | |||
| 3415 | sock_hold(sk); | ||
| 3416 | spin_unlock_bh(lock); | ||
| 3417 | |||
| 3418 | local_bh_disable(); | ||
| 3419 | bh_lock_sock(sk); | ||
| 3420 | sk->sk_err = ETIMEDOUT; | ||
| 3421 | sk->sk_error_report(sk); | ||
| 3422 | |||
| 3423 | tcp_done(sk); | ||
| 3424 | bh_unlock_sock(sk); | ||
| 3425 | local_bh_enable(); | ||
| 3426 | sock_put(sk); | ||
| 3427 | |||
| 3428 | goto restart; | ||
| 3429 | } | ||
| 3430 | spin_unlock_bh(lock); | ||
| 3431 | } | ||
| 3432 | |||
| 3433 | return 0; | ||
| 3434 | } | ||
