summaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2020-05-10 01:30:22 +0300
committerMichael Bestas <mkbestas@lineageos.org>2020-05-14 20:02:37 +0300
commit5d60efc89fa6e5a6616bd9dfa2b0702756b7404e (patch)
tree87757b8f716c565352758d964f4fead762d7e139 /net/ipv6
parent47adfb24dc4eabe3507c89902c5068f501b01b13 (diff)
parent96b09cba55905a34aa152a9689a43d6d3c78b04d (diff)
Merge branch 'android-4.4-p' of https://android.googlesource.com/kernel/common into lineage-17.1-caf-msm8998
This brings LA.UM.8.4.r1-05400-8x98.0 up to date with https://android.googlesource.com/kernel/common/ android-4.4-p at commit: 96b09cba55905 UPSTREAM: net: socket: set sock->sk to NULL after calling proto_ops::release() Conflicts: drivers/scsi/ufs/ufshcd.c drivers/usb/gadget/composite.c drivers/usb/gadget/function/f_fs.c Change-Id: I3e79c0d20e3eb3246a50c9a1e815cdf030a4232e
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ipv6_sockglue.c13
-rw-r--r--net/ipv6/raw.c12
-rw-r--r--net/ipv6/route.c40
-rw-r--r--net/ipv6/xfrm6_output.c2
4 files changed, 54 insertions, 13 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index bd2a6ec7572a..e5513b7b5abf 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -185,15 +185,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = -EBUSY;
break;
}
- } else if (sk->sk_protocol == IPPROTO_TCP) {
- if (sk->sk_prot != &tcpv6_prot) {
- retv = -EBUSY;
- break;
- }
- break;
- } else {
+ }
+ if (sk->sk_protocol == IPPROTO_TCP &&
+ sk->sk_prot != &tcpv6_prot) {
+ retv = -EBUSY;
break;
}
+ if (sk->sk_protocol != IPPROTO_TCP)
+ break;
if (sk->sk_state != TCP_ESTABLISHED) {
retv = -ENOTCONN;
break;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 30db0167bd19..1a940af30300 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -757,6 +757,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
int hlimit = -1;
int tclass = -1;
int dontfrag = -1;
+ int hdrincl;
u16 proto;
int err;
@@ -770,6 +771,13 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (msg->msg_flags & MSG_OOB)
return -EOPNOTSUPP;
+ /* hdrincl should be READ_ONCE(inet->hdrincl)
+ * but READ_ONCE() doesn't work with bit fields.
+ * Doing this indirectly yields the same result.
+ */
+ hdrincl = inet->hdrincl;
+ hdrincl = READ_ONCE(hdrincl);
+
/*
* Get and verify the address.
*/
@@ -879,7 +887,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
fl6.flowi6_oif = np->ucast_oif;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- if (inet->hdrincl)
+ if (hdrincl)
fl6.flowi6_flags |= FLOWI_FLAG_KNOWN_NH;
dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
@@ -900,7 +908,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
goto do_confirm;
back_from_confirm:
- if (inet->hdrincl)
+ if (hdrincl)
err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, msg->msg_flags);
else {
lock_sock(sk);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 2ffc5862eeb5..0b74b01db2f6 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1763,6 +1763,37 @@ static int ip6_convert_metrics(struct mx6_config *mxc,
return -EINVAL;
}
+static struct rt6_info *ip6_nh_lookup_table(struct net *net,
+ struct fib6_config *cfg,
+ const struct in6_addr *gw_addr)
+{
+ struct flowi6 fl6 = {
+ .flowi6_oif = cfg->fc_ifindex,
+ .daddr = *gw_addr,
+ .saddr = cfg->fc_prefsrc,
+ };
+ struct fib6_table *table;
+ struct rt6_info *rt;
+ int flags = 0;
+
+ table = fib6_get_table(net, cfg->fc_table);
+ if (!table)
+ return NULL;
+
+ if (!ipv6_addr_any(&cfg->fc_prefsrc))
+ flags |= RT6_LOOKUP_F_HAS_SADDR;
+
+ rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, flags);
+
+ /* if table lookup failed, fall back to full lookup */
+ if (rt == net->ipv6.ip6_null_entry) {
+ ip6_rt_put(rt);
+ rt = NULL;
+ }
+
+ return rt;
+}
+
static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg)
{
struct net *net = cfg->fc_nlinfo.nl_net;
@@ -1938,7 +1969,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg)
rt->rt6i_gateway = *gw_addr;
if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
- struct rt6_info *grt;
+ struct rt6_info *grt = NULL;
/* IPv6 strictly inhibits using not link-local
addresses as nexthop address.
@@ -1950,7 +1981,12 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg)
if (!(gwa_type & IPV6_ADDR_UNICAST))
goto out;
- grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1);
+ if (cfg->fc_table)
+ grt = ip6_nh_lookup_table(net, cfg, gw_addr);
+
+ if (!grt)
+ grt = rt6_lookup(net, gw_addr, NULL,
+ cfg->fc_ifindex, 1);
err = -EHOSTUNREACH;
if (!grt)
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 64862c5084ee..b2dc9a820c6a 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -125,9 +125,7 @@ int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb)
{
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
-#ifdef CONFIG_NETFILTER
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
-#endif
return xfrm_output(sk, skb);
}