diff options
Diffstat (limited to 'net/ipv4/raw.c')
| -rw-r--r-- | net/ipv4/raw.c | 33 | 
1 files changed, 29 insertions, 4 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index ecbe5a7c2d6d..2300fae11b22 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -89,9 +89,10 @@ struct raw_frag_vec {  	int hlen;  }; -static struct raw_hashinfo raw_v4_hashinfo = { +struct raw_hashinfo raw_v4_hashinfo = {  	.lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock),  }; +EXPORT_SYMBOL_GPL(raw_v4_hashinfo);  int raw_hash_sk(struct sock *sk)  { @@ -120,7 +121,7 @@ void raw_unhash_sk(struct sock *sk)  }  EXPORT_SYMBOL_GPL(raw_unhash_sk); -static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, +struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,  		unsigned short num, __be32 raddr, __be32 laddr, int dif)  {  	sk_for_each_from(sk) { @@ -136,6 +137,7 @@ static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,  found:  	return sk;  } +EXPORT_SYMBOL_GPL(__raw_v4_lookup);  /*   *	0 - deliver @@ -604,7 +606,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)  			   inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,  			   inet_sk_flowi_flags(sk) |  			    (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), -			   daddr, saddr, 0, 0); +			   daddr, saddr, 0, 0, sk->sk_uid);  	if (!inet->hdrincl) {  		rfv.msg = msg; @@ -693,12 +695,20 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)  {  	struct inet_sock *inet = inet_sk(sk);  	struct sockaddr_in *addr = (struct sockaddr_in *) uaddr; +	u32 tb_id = RT_TABLE_LOCAL;  	int ret = -EINVAL;  	int chk_addr_ret;  	if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))  		goto out; -	chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); + +	if (sk->sk_bound_dev_if) +		tb_id = l3mdev_fib_table_by_index(sock_net(sk), +						 sk->sk_bound_dev_if) ? : tb_id; + +	chk_addr_ret = inet_addr_type_table(sock_net(sk), addr->sin_addr.s_addr, +					    tb_id); +  	ret = -EADDRNOTAVAIL;  	if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&  	    chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) @@ -912,6 +922,20 @@ static int compat_raw_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg  }  #endif +int raw_abort(struct sock *sk, int err) +{ +	lock_sock(sk); + +	sk->sk_err = err; +	sk->sk_error_report(sk); +	__udp_disconnect(sk, 0); + +	release_sock(sk); + +	return 0; +} +EXPORT_SYMBOL_GPL(raw_abort); +  struct proto raw_prot = {  	.name		   = "RAW",  	.owner		   = THIS_MODULE, @@ -937,6 +961,7 @@ struct proto raw_prot = {  	.compat_getsockopt = compat_raw_getsockopt,  	.compat_ioctl	   = compat_raw_ioctl,  #endif +	.diag_destroy	   = raw_abort,  };  #ifdef CONFIG_PROC_FS  |