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/ipv6 | |
parent | 5aa287dcf1b5879aa0150b0511833c52885f5b4c (diff) |
Apply k4412 kernel from HardKernel for ODROID-X.
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 69 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 34 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 12 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 14 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 9 |
5 files changed, 111 insertions, 27 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index be29337ea39..8a4bf719c25 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -828,12 +828,13 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i | |||
828 | { | 828 | { |
829 | struct inet6_dev *idev = ifp->idev; | 829 | struct inet6_dev *idev = ifp->idev; |
830 | struct in6_addr addr, *tmpaddr; | 830 | struct in6_addr addr, *tmpaddr; |
831 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age; | 831 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_tstamp, age; |
832 | unsigned long regen_advance; | 832 | unsigned long regen_advance; |
833 | int tmp_plen; | 833 | int tmp_plen; |
834 | int ret = 0; | 834 | int ret = 0; |
835 | int max_addresses; | 835 | int max_addresses; |
836 | u32 addr_flags; | 836 | u32 addr_flags; |
837 | unsigned long now = jiffies; | ||
837 | 838 | ||
838 | write_lock(&idev->lock); | 839 | write_lock(&idev->lock); |
839 | if (ift) { | 840 | if (ift) { |
@@ -878,7 +879,7 @@ retry: | |||
878 | goto out; | 879 | goto out; |
879 | } | 880 | } |
880 | memcpy(&addr.s6_addr[8], idev->rndid, 8); | 881 | memcpy(&addr.s6_addr[8], idev->rndid, 8); |
881 | age = (jiffies - ifp->tstamp) / HZ; | 882 | age = (now - ifp->tstamp) / HZ; |
882 | tmp_valid_lft = min_t(__u32, | 883 | tmp_valid_lft = min_t(__u32, |
883 | ifp->valid_lft, | 884 | ifp->valid_lft, |
884 | idev->cnf.temp_valid_lft + age); | 885 | idev->cnf.temp_valid_lft + age); |
@@ -888,7 +889,6 @@ retry: | |||
888 | idev->cnf.max_desync_factor); | 889 | idev->cnf.max_desync_factor); |
889 | tmp_plen = ifp->prefix_len; | 890 | tmp_plen = ifp->prefix_len; |
890 | max_addresses = idev->cnf.max_addresses; | 891 | max_addresses = idev->cnf.max_addresses; |
891 | tmp_cstamp = ifp->cstamp; | ||
892 | tmp_tstamp = ifp->tstamp; | 892 | tmp_tstamp = ifp->tstamp; |
893 | spin_unlock_bh(&ifp->lock); | 893 | spin_unlock_bh(&ifp->lock); |
894 | 894 | ||
@@ -933,7 +933,7 @@ retry: | |||
933 | ift->ifpub = ifp; | 933 | ift->ifpub = ifp; |
934 | ift->valid_lft = tmp_valid_lft; | 934 | ift->valid_lft = tmp_valid_lft; |
935 | ift->prefered_lft = tmp_prefered_lft; | 935 | ift->prefered_lft = tmp_prefered_lft; |
936 | ift->cstamp = tmp_cstamp; | 936 | ift->cstamp = now; |
937 | ift->tstamp = tmp_tstamp; | 937 | ift->tstamp = tmp_tstamp; |
938 | spin_unlock_bh(&ift->lock); | 938 | spin_unlock_bh(&ift->lock); |
939 | 939 | ||
@@ -1992,25 +1992,50 @@ ok: | |||
1992 | #ifdef CONFIG_IPV6_PRIVACY | 1992 | #ifdef CONFIG_IPV6_PRIVACY |
1993 | read_lock_bh(&in6_dev->lock); | 1993 | read_lock_bh(&in6_dev->lock); |
1994 | /* update all temporary addresses in the list */ | 1994 | /* update all temporary addresses in the list */ |
1995 | list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) { | 1995 | list_for_each_entry(ift, &in6_dev->tempaddr_list, |
1996 | /* | 1996 | tmp_list) { |
1997 | * When adjusting the lifetimes of an existing | 1997 | int age, max_valid, max_prefered; |
1998 | * temporary address, only lower the lifetimes. | 1998 | |
1999 | * Implementations must not increase the | ||
2000 | * lifetimes of an existing temporary address | ||
2001 | * when processing a Prefix Information Option. | ||
2002 | */ | ||
2003 | if (ifp != ift->ifpub) | 1999 | if (ifp != ift->ifpub) |
2004 | continue; | 2000 | continue; |
2005 | 2001 | ||
2002 | /* | ||
2003 | * RFC 4941 section 3.3: | ||
2004 | * If a received option will extend the lifetime | ||
2005 | * of a public address, the lifetimes of | ||
2006 | * temporary addresses should be extended, | ||
2007 | * subject to the overall constraint that no | ||
2008 | * temporary addresses should ever remain | ||
2009 | * "valid" or "preferred" for a time longer than | ||
2010 | * (TEMP_VALID_LIFETIME) or | ||
2011 | * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), | ||
2012 | * respectively. | ||
2013 | */ | ||
2014 | age = (now - ift->cstamp) / HZ; | ||
2015 | max_valid = in6_dev->cnf.temp_valid_lft - age; | ||
2016 | if (max_valid < 0) | ||
2017 | max_valid = 0; | ||
2018 | |||
2019 | max_prefered = in6_dev->cnf.temp_prefered_lft - | ||
2020 | in6_dev->cnf.max_desync_factor - | ||
2021 | age; | ||
2022 | if (max_prefered < 0) | ||
2023 | max_prefered = 0; | ||
2024 | |||
2025 | if (valid_lft > max_valid) | ||
2026 | valid_lft = max_valid; | ||
2027 | |||
2028 | if (prefered_lft > max_prefered) | ||
2029 | prefered_lft = max_prefered; | ||
2030 | |||
2006 | spin_lock(&ift->lock); | 2031 | spin_lock(&ift->lock); |
2007 | flags = ift->flags; | 2032 | flags = ift->flags; |
2008 | if (ift->valid_lft > valid_lft && | 2033 | ift->valid_lft = valid_lft; |
2009 | ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ) | 2034 | ift->prefered_lft = prefered_lft; |
2010 | ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ; | 2035 | ift->tstamp = now; |
2011 | if (ift->prefered_lft > prefered_lft && | 2036 | if (prefered_lft > 0) |
2012 | ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ) | 2037 | ift->flags &= ~IFA_F_DEPRECATED; |
2013 | ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ; | 2038 | |
2014 | spin_unlock(&ift->lock); | 2039 | spin_unlock(&ift->lock); |
2015 | if (!(flags&IFA_F_TENTATIVE)) | 2040 | if (!(flags&IFA_F_TENTATIVE)) |
2016 | ipv6_ifa_notify(0, ift); | 2041 | ipv6_ifa_notify(0, ift); |
@@ -2018,9 +2043,11 @@ ok: | |||
2018 | 2043 | ||
2019 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { | 2044 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { |
2020 | /* | 2045 | /* |
2021 | * When a new public address is created as described in [ADDRCONF], | 2046 | * When a new public address is created as |
2022 | * also create a new temporary address. Also create a temporary | 2047 | * described in [ADDRCONF], also create a new |
2023 | * address if it's enabled but no temporary address currently exists. | 2048 | * temporary address. Also create a temporary |
2049 | * address if it's enabled but no temporary | ||
2050 | * address currently exists. | ||
2024 | */ | 2051 | */ |
2025 | read_unlock_bh(&in6_dev->lock); | 2052 | read_unlock_bh(&in6_dev->lock); |
2026 | ipv6_create_tempaddr(ifp, NULL); | 2053 | ipv6_create_tempaddr(ifp, NULL); |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 559123644e5..7e8340ef5a2 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -63,6 +63,20 @@ | |||
63 | #include <asm/system.h> | 63 | #include <asm/system.h> |
64 | #include <linux/mroute6.h> | 64 | #include <linux/mroute6.h> |
65 | 65 | ||
66 | #ifdef CONFIG_ANDROID_PARANOID_NETWORK | ||
67 | #include <linux/android_aid.h> | ||
68 | |||
69 | static inline int current_has_network(void) | ||
70 | { | ||
71 | return in_egroup_p(AID_INET) || capable(CAP_NET_RAW); | ||
72 | } | ||
73 | #else | ||
74 | static inline int current_has_network(void) | ||
75 | { | ||
76 | return 1; | ||
77 | } | ||
78 | #endif | ||
79 | |||
66 | MODULE_AUTHOR("Cast of dozens"); | 80 | MODULE_AUTHOR("Cast of dozens"); |
67 | MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); | 81 | MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); |
68 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
@@ -109,6 +123,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, | |||
109 | int try_loading_module = 0; | 123 | int try_loading_module = 0; |
110 | int err; | 124 | int err; |
111 | 125 | ||
126 | if (!current_has_network()) | ||
127 | return -EACCES; | ||
128 | |||
112 | if (sock->type != SOCK_RAW && | 129 | if (sock->type != SOCK_RAW && |
113 | sock->type != SOCK_DGRAM && | 130 | sock->type != SOCK_DGRAM && |
114 | !inet_ehash_secret) | 131 | !inet_ehash_secret) |
@@ -477,6 +494,21 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, | |||
477 | 494 | ||
478 | EXPORT_SYMBOL(inet6_getname); | 495 | EXPORT_SYMBOL(inet6_getname); |
479 | 496 | ||
497 | int inet6_killaddr_ioctl(struct net *net, void __user *arg) { | ||
498 | struct in6_ifreq ireq; | ||
499 | struct sockaddr_in6 sin6; | ||
500 | |||
501 | if (!capable(CAP_NET_ADMIN)) | ||
502 | return -EACCES; | ||
503 | |||
504 | if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) | ||
505 | return -EFAULT; | ||
506 | |||
507 | sin6.sin6_family = AF_INET6; | ||
508 | ipv6_addr_copy(&sin6.sin6_addr, &ireq.ifr6_addr); | ||
509 | return tcp_nuke_addr(net, (struct sockaddr *) &sin6); | ||
510 | } | ||
511 | |||
480 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 512 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
481 | { | 513 | { |
482 | struct sock *sk = sock->sk; | 514 | struct sock *sk = sock->sk; |
@@ -501,6 +533,8 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
501 | return addrconf_del_ifaddr(net, (void __user *) arg); | 533 | return addrconf_del_ifaddr(net, (void __user *) arg); |
502 | case SIOCSIFDSTADDR: | 534 | case SIOCSIFDSTADDR: |
503 | return addrconf_set_dstaddr(net, (void __user *) arg); | 535 | return addrconf_set_dstaddr(net, (void __user *) arg); |
536 | case SIOCKILLADDR: | ||
537 | return inet6_killaddr_ioctl(net, (void __user *) arg); | ||
504 | default: | 538 | default: |
505 | if (!sk->sk_prot->ioctl) | 539 | if (!sk->sk_prot->ioctl) |
506 | return -ENOIOCTLCMD; | 540 | return -ENOIOCTLCMD; |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 448464844a2..5bbf5316920 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -174,6 +174,18 @@ config IP6_NF_TARGET_REJECT | |||
174 | 174 | ||
175 | To compile it as a module, choose M here. If unsure, say N. | 175 | To compile it as a module, choose M here. If unsure, say N. |
176 | 176 | ||
177 | config IP6_NF_TARGET_REJECT_SKERR | ||
178 | bool "Force socket error when rejecting with icmp*" | ||
179 | depends on IP6_NF_TARGET_REJECT | ||
180 | default n | ||
181 | help | ||
182 | This option enables turning a "--reject-with icmp*" into a matching | ||
183 | socket error also. | ||
184 | The REJECT target normally allows sending an ICMP message. But it | ||
185 | leaves the local socket unaware of any ingress rejects. | ||
186 | |||
187 | If unsure, say N. | ||
188 | |||
177 | config IP6_NF_MANGLE | 189 | config IP6_NF_MANGLE |
178 | tristate "Packet mangling" | 190 | tristate "Packet mangling" |
179 | default m if NETFILTER_ADVANCED=n | 191 | default m if NETFILTER_ADVANCED=n |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 94874b0bdcd..14cb310064f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -2292,16 +2292,15 @@ static void __exit ip6_tables_fini(void) | |||
2292 | * "No next header". | 2292 | * "No next header". |
2293 | * | 2293 | * |
2294 | * If target header is found, its offset is set in *offset and return protocol | 2294 | * If target header is found, its offset is set in *offset and return protocol |
2295 | * number. Otherwise, return -1. | 2295 | * number. Otherwise, return -ENOENT or -EBADMSG. |
2296 | * | 2296 | * |
2297 | * If the first fragment doesn't contain the final protocol header or | 2297 | * If the first fragment doesn't contain the final protocol header or |
2298 | * NEXTHDR_NONE it is considered invalid. | 2298 | * NEXTHDR_NONE it is considered invalid. |
2299 | * | 2299 | * |
2300 | * Note that non-1st fragment is special case that "the protocol number | 2300 | * Note that non-1st fragment is special case that "the protocol number |
2301 | * of last header" is "next header" field in Fragment header. In this case, | 2301 | * of last header" is "next header" field in Fragment header. In this case, |
2302 | * *offset is meaningless and fragment offset is stored in *fragoff if fragoff | 2302 | * *offset is meaningless. If fragoff is not NULL, the fragment offset is |
2303 | * isn't NULL. | 2303 | * stored in *fragoff; if it is NULL, return -EINVAL. |
2304 | * | ||
2305 | */ | 2304 | */ |
2306 | int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | 2305 | int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, |
2307 | int target, unsigned short *fragoff) | 2306 | int target, unsigned short *fragoff) |
@@ -2342,9 +2341,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
2342 | if (target < 0 && | 2341 | if (target < 0 && |
2343 | ((!ipv6_ext_hdr(hp->nexthdr)) || | 2342 | ((!ipv6_ext_hdr(hp->nexthdr)) || |
2344 | hp->nexthdr == NEXTHDR_NONE)) { | 2343 | hp->nexthdr == NEXTHDR_NONE)) { |
2345 | if (fragoff) | 2344 | if (fragoff) { |
2346 | *fragoff = _frag_off; | 2345 | *fragoff = _frag_off; |
2347 | return hp->nexthdr; | 2346 | return hp->nexthdr; |
2347 | } else { | ||
2348 | return -EINVAL; | ||
2349 | } | ||
2348 | } | 2350 | } |
2349 | return -ENOENT; | 2351 | return -ENOENT; |
2350 | } | 2352 | } |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index a5a4c5dd539..09d30498c92 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -177,6 +177,15 @@ send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code, | |||
177 | skb_in->dev = net->loopback_dev; | 177 | skb_in->dev = net->loopback_dev; |
178 | 178 | ||
179 | icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0); | 179 | icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0); |
180 | #ifdef CONFIG_IP6_NF_TARGET_REJECT_SKERR | ||
181 | if (skb_in->sk) { | ||
182 | icmpv6_err_convert(ICMPV6_DEST_UNREACH, code, | ||
183 | &skb_in->sk->sk_err); | ||
184 | skb_in->sk->sk_error_report(skb_in->sk); | ||
185 | pr_debug("ip6t_REJECT: sk_err=%d for skb=%p sk=%p\n", | ||
186 | skb_in->sk->sk_err, skb_in, skb_in->sk); | ||
187 | } | ||
188 | #endif | ||
180 | } | 189 | } |
181 | 190 | ||
182 | static unsigned int | 191 | static unsigned int |