diff options
| author | Lorenzo Colitti <lorenzo@google.com> | 2014-03-31 16:23:51 +0900 | 
|---|---|---|
| committer | Simon Wilson <simonwilson@google.com> | 2014-09-04 17:41:23 -0700 | 
| commit | dbd37aae078b14794161b5e37a700d9847c7f95f (patch) | |
| tree | 54933cfadb7ef633b7b6955d0486265fdf31163b /net/ipv6 | |
| parent | 8440dace67872c28b11c1a438a0ec0501e2effcc (diff) | |
| download | olio-linux-3.10-dbd37aae078b14794161b5e37a700d9847c7f95f.tar.xz olio-linux-3.10-dbd37aae078b14794161b5e37a700d9847c7f95f.zip  | |
net: core: Support UID-based routing.
This contains the following commits:
1. cc2f522 net: core: Add a UID range to fib rules.
2. d7ed2bd net: core: Use the socket UID in routing lookups.
3. 2f9306a net: core: Add a RTA_UID attribute to routes.
    This is so that userspace can do per-UID route lookups.
4. 8e46efb net: ipv6: Use the UID in IPv6 PMTUD
    IPv4 PMTUD already does this because ipv4_sk_update_pmtu
    uses __build_flow_key, which includes the UID.
Bug: 15413527
Change-Id: I81bd31dae655de9cce7d7a1f9a905dc1c2feba7c
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/af_inet6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/ah6.c | 2 | ||||
| -rw-r--r-- | net/ipv6/datagram.c | 1 | ||||
| -rw-r--r-- | net/ipv6/esp6.c | 2 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 2 | ||||
| -rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ipcomp6.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ping.c | 1 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 1 | ||||
| -rw-r--r-- | net/ipv6/route.c | 12 | ||||
| -rw-r--r-- | net/ipv6/syncookies.c | 1 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 1 | 
13 files changed, 23 insertions, 6 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index f0081f9cc84..ae17f62189a 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -695,6 +695,7 @@ int inet6_sk_rebuild_header(struct sock *sk)  		fl6.flowi6_mark = sk->sk_mark;  		fl6.fl6_dport = inet->inet_dport;  		fl6.fl6_sport = inet->inet_sport; +		fl6.flowi6_uid = sock_i_uid(sk);  		security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));  		final_p = fl6_update_dst(&fl6, np->opt, &final); diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index bb02e176cb7..b903e19463c 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -630,7 +630,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  	if (type == NDISC_REDIRECT)  		ip6_redirect(skb, net, 0, 0);  	else -		ip6_update_pmtu(skb, net, info, 0, 0); +		ip6_update_pmtu(skb, net, info, 0, 0, INVALID_UID);  	xfrm_state_put(x);  } diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 4b56cbbc789..00b4a5f6eea 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -162,6 +162,7 @@ ipv4_connected:  	fl6.flowi6_mark = sk->sk_mark;  	fl6.fl6_dport = inet->inet_dport;  	fl6.fl6_sport = inet->inet_sport; +	fl6.flowi6_uid = sock_i_uid(sk);  	if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))  		fl6.flowi6_oif = np->mcast_oif; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 40ffd72243a..fdc81cb29e8 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -449,7 +449,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  	if (type == NDISC_REDIRECT)  		ip6_redirect(skb, net, 0, 0);  	else -		ip6_update_pmtu(skb, net, info, 0, 0); +		ip6_update_pmtu(skb, net, info, 0, 0, INVALID_UID);  	xfrm_state_put(x);  } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 28da4003e84..12b1a942dc9 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -90,7 +90,7 @@ static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  	struct net *net = dev_net(skb->dev);  	if (type == ICMPV6_PKT_TOOBIG) -		ip6_update_pmtu(skb, net, info, 0, 0); +		ip6_update_pmtu(skb, net, info, 0, 0, INVALID_UID);  	else if (type == NDISC_REDIRECT)  		ip6_redirect(skb, net, 0, 0); diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index f1493138d21..65a46058c85 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -84,6 +84,7 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,  	fl6->flowi6_mark = inet_rsk(req)->ir_mark;  	fl6->fl6_dport = inet_rsk(req)->rmt_port;  	fl6->fl6_sport = inet_rsk(req)->loc_port; +	fl6->flowi6_uid = sock_i_uid(sk);  	security_req_classify_flow(req, flowi6_to_flowi(fl6));  	dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); @@ -211,6 +212,7 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,  	fl6->flowi6_mark = sk->sk_mark;  	fl6->fl6_sport = inet->inet_sport;  	fl6->fl6_dport = inet->inet_dport; +	fl6->flowi6_uid = sock_i_uid(sk);  	security_sk_classify_flow(sk, flowi6_to_flowi(fl6));  	final_p = fl6_update_dst(fl6, np->opt, &final); diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 7af5aee75d9..a1beb59a841 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -78,7 +78,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  	if (type == NDISC_REDIRECT)  		ip6_redirect(skb, net, 0, 0);  	else -		ip6_update_pmtu(skb, net, info, 0, 0); +		ip6_update_pmtu(skb, net, info, 0, 0, INVALID_UID);  	xfrm_state_put(x);  } diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 8d1c2064056..5f0d294b36c 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -159,6 +159,7 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,  	fl6.saddr = np->saddr;  	fl6.daddr = *daddr;  	fl6.flowi6_mark = sk->sk_mark; +	fl6.flowi6_uid = sock_i_uid(sk);  	fl6.fl6_icmp_type = user_icmph.icmp6_type;  	fl6.fl6_icmp_code = user_icmph.icmp6_code;  	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index eedff8ccded..dfef31581f8 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -761,6 +761,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,  	memset(&fl6, 0, sizeof(fl6));  	fl6.flowi6_mark = sk->sk_mark; +	fl6.flowi6_uid = sock_i_uid(sk);  	if (sin6) {  		if (addr_len < SIN6_LEN_RFC2133) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8ecf44af7c2..bad36468dcd 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1099,7 +1099,7 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,  }  void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, -		     int oif, u32 mark) +		     int oif, u32 mark, kuid_t uid)  {  	const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;  	struct dst_entry *dst; @@ -1112,6 +1112,7 @@ void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,  	fl6.daddr = iph->daddr;  	fl6.saddr = iph->saddr;  	fl6.flowlabel = ip6_flowinfo(iph); +	fl6.flowi6_uid = uid;  	dst = ip6_route_output(net, NULL, &fl6);  	if (!dst->error) @@ -1123,7 +1124,7 @@ EXPORT_SYMBOL_GPL(ip6_update_pmtu);  void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)  {  	ip6_update_pmtu(skb, sock_net(sk), mtu, -			sk->sk_bound_dev_if, sk->sk_mark); +			sk->sk_bound_dev_if, sk->sk_mark, sock_i_uid(sk));  }  EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu); @@ -2199,6 +2200,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {  	[RTA_PRIORITY]          = { .type = NLA_U32 },  	[RTA_METRICS]           = { .type = NLA_NESTED },  	[RTA_MULTIPATH]		= { .len = sizeof(struct rtnexthop) }, +	[RTA_UID]		= { .type = NLA_U32 },  };  static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, @@ -2585,6 +2587,12 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh)  	if (tb[RTA_OIF])  		oif = nla_get_u32(tb[RTA_OIF]); +	if (tb[RTA_UID]) +		fl6.flowi6_uid = make_kuid(current_user_ns(), +					   nla_get_u32(tb[RTA_UID])); +	else +		fl6.flowi6_uid = iif ? INVALID_UID : current_uid(); +  	if (iif) {  		struct net_device *dev;  		int flags = 0; diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 1efbc6f44a6..ba8622daffd 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -243,6 +243,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)  		fl6.flowi6_mark = ireq->ir_mark;  		fl6.fl6_dport = inet_rsk(req)->rmt_port;  		fl6.fl6_sport = inet_sk(sk)->inet_sport; +		fl6.flowi6_uid = sock_i_uid(sk);  		security_req_classify_flow(req, flowi6_to_flowi(&fl6));  		dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 6e882dadb4f..a4fc647deb0 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -252,6 +252,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  	fl6.flowi6_mark = sk->sk_mark;  	fl6.fl6_dport = usin->sin6_port;  	fl6.fl6_sport = inet->inet_sport; +	fl6.flowi6_uid = sock_i_uid(sk);  	final_p = fl6_update_dst(&fl6, np->opt, &final); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 42923b14dfa..e6dd85da906 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1147,6 +1147,7 @@ do_udp_sendmsg:  		fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;  	fl6.flowi6_mark = sk->sk_mark; +	fl6.flowi6_uid = sock_i_uid(sk);  	if (msg->msg_controllen) {  		opt = &opt_space;  |