aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-09-28 13:46:28 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2012-09-28 14:50:15 -0400
commitdaa22703f14c007e93b464c45fa60019a36f546d (patch)
treea1a130b6e128dc9d57c35c026977e1b4953105e1 /net/ipv6
parent5aa287dcf1b5879aa0150b0511833c52885f5b4c (diff)
Apply k4412 kernel from HardKernel for ODROID-X.
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c69
-rw-r--r--net/ipv6/af_inet6.c34
-rw-r--r--net/ipv6/netfilter/Kconfig12
-rw-r--r--net/ipv6/netfilter/ip6_tables.c14
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c9
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
69static inline int current_has_network(void)
70{
71 return in_egroup_p(AID_INET) || capable(CAP_NET_RAW);
72}
73#else
74static inline int current_has_network(void)
75{
76 return 1;
77}
78#endif
79
66MODULE_AUTHOR("Cast of dozens"); 80MODULE_AUTHOR("Cast of dozens");
67MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); 81MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
68MODULE_LICENSE("GPL"); 82MODULE_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
478EXPORT_SYMBOL(inet6_getname); 495EXPORT_SYMBOL(inet6_getname);
479 496
497int 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
480int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 512int 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
177config 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
177config IP6_NF_MANGLE 189config 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 */
2306int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, 2305int 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
182static unsigned int 191static unsigned int