mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	rxrpc: Add IPv6 support
Add IPv6 support to AF_RXRPC. With this, AF_RXRPC sockets can be created: service = socket(AF_RXRPC, SOCK_DGRAM, PF_INET6); instead of: service = socket(AF_RXRPC, SOCK_DGRAM, PF_INET); The AFS filesystem doesn't support IPv6 at the moment, though, since that requires upgrades to some of the RPC calls. Note that a good portion of this patch is replacing "%pI4:%u" in print statements with "%pISpc" which is able to handle both protocols and print the port. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
		
							parent
							
								
									1c2bc7b948
								
							
						
					
					
						commit
						75b54cb57c
					
				
					 7 changed files with 154 additions and 83 deletions
				
			
		| 
						 | 
					@ -106,19 +106,23 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
 | 
				
			||||||
	case AF_INET:
 | 
						case AF_INET:
 | 
				
			||||||
		if (srx->transport_len < sizeof(struct sockaddr_in))
 | 
							if (srx->transport_len < sizeof(struct sockaddr_in))
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		_debug("INET: %x @ %pI4",
 | 
					 | 
				
			||||||
		       ntohs(srx->transport.sin.sin_port),
 | 
					 | 
				
			||||||
		       &srx->transport.sin.sin_addr);
 | 
					 | 
				
			||||||
		tail = offsetof(struct sockaddr_rxrpc, transport.sin.__pad);
 | 
							tail = offsetof(struct sockaddr_rxrpc, transport.sin.__pad);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case AF_INET6:
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							if (srx->transport_len < sizeof(struct sockaddr_in6))
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							tail = offsetof(struct sockaddr_rxrpc, transport) +
 | 
				
			||||||
 | 
								sizeof(struct sockaddr_in6);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EAFNOSUPPORT;
 | 
							return -EAFNOSUPPORT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tail < len)
 | 
						if (tail < len)
 | 
				
			||||||
		memset((void *)srx + tail, 0, len - tail);
 | 
							memset((void *)srx + tail, 0, len - tail);
 | 
				
			||||||
 | 
						_debug("INET: %pISp", &srx->transport);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -409,6 +413,9 @@ static int rxrpc_sendmsg(struct socket *sock, struct msghdr *m, size_t len)
 | 
				
			||||||
		case AF_INET:
 | 
							case AF_INET:
 | 
				
			||||||
			rx->srx.transport_len = sizeof(struct sockaddr_in);
 | 
								rx->srx.transport_len = sizeof(struct sockaddr_in);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case AF_INET6:
 | 
				
			||||||
 | 
								rx->srx.transport_len = sizeof(struct sockaddr_in6);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			ret = -EAFNOSUPPORT;
 | 
								ret = -EAFNOSUPPORT;
 | 
				
			||||||
			goto error_unlock;
 | 
								goto error_unlock;
 | 
				
			||||||
| 
						 | 
					@ -563,7 +570,7 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
 | 
				
			||||||
		return -EAFNOSUPPORT;
 | 
							return -EAFNOSUPPORT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* we support transport protocol UDP/UDP6 only */
 | 
						/* we support transport protocol UDP/UDP6 only */
 | 
				
			||||||
	if (protocol != PF_INET)
 | 
						if (protocol != PF_INET && protocol != PF_INET6)
 | 
				
			||||||
		return -EPROTONOSUPPORT;
 | 
							return -EPROTONOSUPPORT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sock->type != SOCK_DGRAM)
 | 
						if (sock->type != SOCK_DGRAM)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,6 +134,14 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
 | 
				
			||||||
			    srx.transport.sin.sin_addr.s_addr)
 | 
								    srx.transport.sin.sin_addr.s_addr)
 | 
				
			||||||
				goto not_found;
 | 
									goto not_found;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case AF_INET6:
 | 
				
			||||||
 | 
								if (peer->srx.transport.sin6.sin6_port !=
 | 
				
			||||||
 | 
								    srx.transport.sin6.sin6_port ||
 | 
				
			||||||
 | 
								    memcmp(&peer->srx.transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
									   &srx.transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
									   sizeof(struct in6_addr)) != 0)
 | 
				
			||||||
 | 
									goto not_found;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			BUG();
 | 
								BUG();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,15 @@ static long rxrpc_local_cmp_key(const struct rxrpc_local *local,
 | 
				
			||||||
			memcmp(&local->srx.transport.sin.sin_addr,
 | 
								memcmp(&local->srx.transport.sin.sin_addr,
 | 
				
			||||||
			       &srx->transport.sin.sin_addr,
 | 
								       &srx->transport.sin.sin_addr,
 | 
				
			||||||
			       sizeof(struct in_addr));
 | 
								       sizeof(struct in_addr));
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							/* If the choice of UDP6 port is left up to the transport, then
 | 
				
			||||||
 | 
							 * the endpoint record doesn't match.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							return ((u16 __force)local->srx.transport.sin6.sin6_port -
 | 
				
			||||||
 | 
								(u16 __force)srx->transport.sin6.sin6_port) ?:
 | 
				
			||||||
 | 
								memcmp(&local->srx.transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
								       &srx->transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
								       sizeof(struct in6_addr));
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		BUG();
 | 
							BUG();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -100,7 +109,8 @@ static int rxrpc_open_socket(struct rxrpc_local *local)
 | 
				
			||||||
	struct sock *sock;
 | 
						struct sock *sock;
 | 
				
			||||||
	int ret, opt;
 | 
						int ret, opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_enter("%p{%d}", local, local->srx.transport_type);
 | 
						_enter("%p{%d,%d}",
 | 
				
			||||||
 | 
						       local, local->srx.transport_type, local->srx.transport.family);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* create a socket to represent the local endpoint */
 | 
						/* create a socket to represent the local endpoint */
 | 
				
			||||||
	ret = sock_create_kern(&init_net, local->srx.transport.family,
 | 
						ret = sock_create_kern(&init_net, local->srx.transport.family,
 | 
				
			||||||
| 
						 | 
					@ -169,18 +179,8 @@ struct rxrpc_local *rxrpc_lookup_local(const struct sockaddr_rxrpc *srx)
 | 
				
			||||||
	long diff;
 | 
						long diff;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (srx->transport.family == AF_INET) {
 | 
						_enter("{%d,%d,%pISp}",
 | 
				
			||||||
		_enter("{%d,%u,%pI4+%hu}",
 | 
						       srx->transport_type, srx->transport.family, &srx->transport);
 | 
				
			||||||
		       srx->transport_type,
 | 
					 | 
				
			||||||
		       srx->transport.family,
 | 
					 | 
				
			||||||
		       &srx->transport.sin.sin_addr,
 | 
					 | 
				
			||||||
		       ntohs(srx->transport.sin.sin_port));
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		_enter("{%d,%u}",
 | 
					 | 
				
			||||||
		       srx->transport_type,
 | 
					 | 
				
			||||||
		       srx->transport.family);
 | 
					 | 
				
			||||||
		return ERR_PTR(-EAFNOSUPPORT);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&rxrpc_local_mutex);
 | 
						mutex_lock(&rxrpc_local_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -233,13 +233,8 @@ struct rxrpc_local *rxrpc_lookup_local(const struct sockaddr_rxrpc *srx)
 | 
				
			||||||
found:
 | 
					found:
 | 
				
			||||||
	mutex_unlock(&rxrpc_local_mutex);
 | 
						mutex_unlock(&rxrpc_local_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_net("LOCAL %s %d {%d,%u,%pI4+%hu}",
 | 
						_net("LOCAL %s %d {%pISp}",
 | 
				
			||||||
	     age,
 | 
						     age, local->debug_id, &local->srx.transport);
 | 
				
			||||||
	     local->debug_id,
 | 
					 | 
				
			||||||
	     local->srx.transport_type,
 | 
					 | 
				
			||||||
	     local->srx.transport.family,
 | 
					 | 
				
			||||||
	     &local->srx.transport.sin.sin_addr,
 | 
					 | 
				
			||||||
	     ntohs(local->srx.transport.sin.sin_port));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_leave(" = %p", local);
 | 
						_leave(" = %p", local);
 | 
				
			||||||
	return local;
 | 
						return local;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,6 +258,22 @@ int rxrpc_send_data_packet(struct rxrpc_connection *conn, struct sk_buff *skb)
 | 
				
			||||||
					  (char *)&opt, sizeof(opt));
 | 
										  (char *)&opt, sizeof(opt));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							opt = IPV6_PMTUDISC_DONT;
 | 
				
			||||||
 | 
							ret = kernel_setsockopt(conn->params.local->socket,
 | 
				
			||||||
 | 
										SOL_IPV6, IPV6_MTU_DISCOVER,
 | 
				
			||||||
 | 
										(char *)&opt, sizeof(opt));
 | 
				
			||||||
 | 
							if (ret == 0) {
 | 
				
			||||||
 | 
								ret = kernel_sendmsg(conn->params.local->socket, &msg,
 | 
				
			||||||
 | 
										     iov, 1, iov[0].iov_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								opt = IPV6_PMTUDISC_DO;
 | 
				
			||||||
 | 
								kernel_setsockopt(conn->params.local->socket,
 | 
				
			||||||
 | 
										  SOL_IPV6, IPV6_MTU_DISCOVER,
 | 
				
			||||||
 | 
										  (char *)&opt, sizeof(opt));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	up_write(&conn->params.local->defrag_sem);
 | 
						up_write(&conn->params.local->defrag_sem);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,6 +66,30 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							srx.transport.sin6.sin6_port = serr->port;
 | 
				
			||||||
 | 
							srx.transport_len = sizeof(struct sockaddr_in6);
 | 
				
			||||||
 | 
							switch (serr->ee.ee_origin) {
 | 
				
			||||||
 | 
							case SO_EE_ORIGIN_ICMP6:
 | 
				
			||||||
 | 
								_net("Rx ICMP6");
 | 
				
			||||||
 | 
								memcpy(&srx.transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
								       skb_network_header(skb) + serr->addr_offset,
 | 
				
			||||||
 | 
								       sizeof(struct in6_addr));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SO_EE_ORIGIN_ICMP:
 | 
				
			||||||
 | 
								_net("Rx ICMP on v6 sock");
 | 
				
			||||||
 | 
								memcpy(&srx.transport.sin6.sin6_addr.s6_addr + 12,
 | 
				
			||||||
 | 
								       skb_network_header(skb) + serr->addr_offset,
 | 
				
			||||||
 | 
								       sizeof(struct in_addr));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								memcpy(&srx.transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
								       &ipv6_hdr(skb)->saddr,
 | 
				
			||||||
 | 
								       sizeof(struct in6_addr));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		BUG();
 | 
							BUG();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,12 +16,14 @@
 | 
				
			||||||
#include <linux/skbuff.h>
 | 
					#include <linux/skbuff.h>
 | 
				
			||||||
#include <linux/udp.h>
 | 
					#include <linux/udp.h>
 | 
				
			||||||
#include <linux/in.h>
 | 
					#include <linux/in.h>
 | 
				
			||||||
 | 
					#include <linux/in6.h>
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/hashtable.h>
 | 
					#include <linux/hashtable.h>
 | 
				
			||||||
#include <net/sock.h>
 | 
					#include <net/sock.h>
 | 
				
			||||||
#include <net/af_rxrpc.h>
 | 
					#include <net/af_rxrpc.h>
 | 
				
			||||||
#include <net/ip.h>
 | 
					#include <net/ip.h>
 | 
				
			||||||
#include <net/route.h>
 | 
					#include <net/route.h>
 | 
				
			||||||
 | 
					#include <net/ip6_route.h>
 | 
				
			||||||
#include "ar-internal.h"
 | 
					#include "ar-internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DEFINE_HASHTABLE(rxrpc_peer_hash, 10);
 | 
					static DEFINE_HASHTABLE(rxrpc_peer_hash, 10);
 | 
				
			||||||
| 
						 | 
					@ -50,6 +52,11 @@ static unsigned long rxrpc_peer_hash_key(struct rxrpc_local *local,
 | 
				
			||||||
		size = sizeof(srx->transport.sin.sin_addr);
 | 
							size = sizeof(srx->transport.sin.sin_addr);
 | 
				
			||||||
		p = (u16 *)&srx->transport.sin.sin_addr;
 | 
							p = (u16 *)&srx->transport.sin.sin_addr;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							hash_key += (u16 __force)srx->transport.sin.sin_port;
 | 
				
			||||||
 | 
							size = sizeof(srx->transport.sin6.sin6_addr);
 | 
				
			||||||
 | 
							p = (u16 *)&srx->transport.sin6.sin6_addr;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		WARN(1, "AF_RXRPC: Unsupported transport address family\n");
 | 
							WARN(1, "AF_RXRPC: Unsupported transport address family\n");
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -93,6 +100,12 @@ static long rxrpc_peer_cmp_key(const struct rxrpc_peer *peer,
 | 
				
			||||||
			memcmp(&peer->srx.transport.sin.sin_addr,
 | 
								memcmp(&peer->srx.transport.sin.sin_addr,
 | 
				
			||||||
			       &srx->transport.sin.sin_addr,
 | 
								       &srx->transport.sin.sin_addr,
 | 
				
			||||||
			       sizeof(struct in_addr));
 | 
								       sizeof(struct in_addr));
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							return ((u16 __force)peer->srx.transport.sin6.sin6_port -
 | 
				
			||||||
 | 
								(u16 __force)srx->transport.sin6.sin6_port) ?:
 | 
				
			||||||
 | 
								memcmp(&peer->srx.transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
								       &srx->transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
								       sizeof(struct in6_addr));
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		BUG();
 | 
							BUG();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -130,17 +143,7 @@ struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *local,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
 | 
						peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
 | 
				
			||||||
	if (peer) {
 | 
						if (peer) {
 | 
				
			||||||
		switch (srx->transport.family) {
 | 
							_net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
 | 
				
			||||||
		case AF_INET:
 | 
					 | 
				
			||||||
			_net("PEER %d {%d,%u,%pI4+%hu}",
 | 
					 | 
				
			||||||
			     peer->debug_id,
 | 
					 | 
				
			||||||
			     peer->srx.transport_type,
 | 
					 | 
				
			||||||
			     peer->srx.transport.family,
 | 
					 | 
				
			||||||
			     &peer->srx.transport.sin.sin_addr,
 | 
					 | 
				
			||||||
			     ntohs(peer->srx.transport.sin.sin_port));
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		_leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
 | 
							_leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return peer;
 | 
						return peer;
 | 
				
			||||||
| 
						 | 
					@ -152,22 +155,49 @@ struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *local,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
 | 
					static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct dst_entry *dst;
 | 
				
			||||||
	struct rtable *rt;
 | 
						struct rtable *rt;
 | 
				
			||||||
	struct flowi4 fl4;
 | 
						struct flowi fl;
 | 
				
			||||||
 | 
						struct flowi4 *fl4 = &fl.u.ip4;
 | 
				
			||||||
 | 
						struct flowi6 *fl6 = &fl.u.ip6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	peer->if_mtu = 1500;
 | 
						peer->if_mtu = 1500;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt = ip_route_output_ports(&init_net, &fl4, NULL,
 | 
						memset(&fl, 0, sizeof(fl));
 | 
				
			||||||
 | 
						switch (peer->srx.transport.family) {
 | 
				
			||||||
 | 
						case AF_INET:
 | 
				
			||||||
 | 
							rt = ip_route_output_ports(
 | 
				
			||||||
 | 
								&init_net, fl4, NULL,
 | 
				
			||||||
			peer->srx.transport.sin.sin_addr.s_addr, 0,
 | 
								peer->srx.transport.sin.sin_addr.s_addr, 0,
 | 
				
			||||||
				   htons(7000), htons(7001),
 | 
								htons(7000), htons(7001), IPPROTO_UDP, 0, 0);
 | 
				
			||||||
				   IPPROTO_UDP, 0, 0);
 | 
					 | 
				
			||||||
		if (IS_ERR(rt)) {
 | 
							if (IS_ERR(rt)) {
 | 
				
			||||||
			_leave(" [route err %ld]", PTR_ERR(rt));
 | 
								_leave(" [route err %ld]", PTR_ERR(rt));
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							dst = &rt->dst;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	peer->if_mtu = dst_mtu(&rt->dst);
 | 
						case AF_INET6:
 | 
				
			||||||
	dst_release(&rt->dst);
 | 
							fl6->flowi6_iif = LOOPBACK_IFINDEX;
 | 
				
			||||||
 | 
							fl6->flowi6_scope = RT_SCOPE_UNIVERSE;
 | 
				
			||||||
 | 
							fl6->flowi6_proto = IPPROTO_UDP;
 | 
				
			||||||
 | 
							memcpy(&fl6->daddr, &peer->srx.transport.sin6.sin6_addr,
 | 
				
			||||||
 | 
							       sizeof(struct in6_addr));
 | 
				
			||||||
 | 
							fl6->fl6_dport = htons(7001);
 | 
				
			||||||
 | 
							fl6->fl6_sport = htons(7000);
 | 
				
			||||||
 | 
							dst = ip6_route_output(&init_net, NULL, fl6);
 | 
				
			||||||
 | 
							if (IS_ERR(dst)) {
 | 
				
			||||||
 | 
								_leave(" [route err %ld]", PTR_ERR(dst));
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							BUG();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						peer->if_mtu = dst_mtu(dst);
 | 
				
			||||||
 | 
						dst_release(dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_leave(" [if_mtu %u]", peer->if_mtu);
 | 
						_leave(" [if_mtu %u]", peer->if_mtu);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -207,18 +237,23 @@ static void rxrpc_init_peer(struct rxrpc_peer *peer, unsigned long hash_key)
 | 
				
			||||||
	rxrpc_assess_MTU_size(peer);
 | 
						rxrpc_assess_MTU_size(peer);
 | 
				
			||||||
	peer->mtu = peer->if_mtu;
 | 
						peer->mtu = peer->if_mtu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (peer->srx.transport.family == AF_INET) {
 | 
						switch (peer->srx.transport.family) {
 | 
				
			||||||
 | 
						case AF_INET:
 | 
				
			||||||
		peer->hdrsize = sizeof(struct iphdr);
 | 
							peer->hdrsize = sizeof(struct iphdr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							peer->hdrsize = sizeof(struct ipv6hdr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							BUG();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (peer->srx.transport_type) {
 | 
						switch (peer->srx.transport_type) {
 | 
				
			||||||
	case SOCK_DGRAM:
 | 
						case SOCK_DGRAM:
 | 
				
			||||||
		peer->hdrsize += sizeof(struct udphdr);
 | 
							peer->hdrsize += sizeof(struct udphdr);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		BUG();
 | 
							BUG();
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		BUG();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	peer->hdrsize += sizeof(struct rxrpc_wire_header);
 | 
						peer->hdrsize += sizeof(struct rxrpc_wire_header);
 | 
				
			||||||
| 
						 | 
					@ -285,11 +320,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *local,
 | 
				
			||||||
	struct rxrpc_peer *peer, *candidate;
 | 
						struct rxrpc_peer *peer, *candidate;
 | 
				
			||||||
	unsigned long hash_key = rxrpc_peer_hash_key(local, srx);
 | 
						unsigned long hash_key = rxrpc_peer_hash_key(local, srx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_enter("{%d,%d,%pI4+%hu}",
 | 
						_enter("{%pISp}", &srx->transport);
 | 
				
			||||||
	       srx->transport_type,
 | 
					 | 
				
			||||||
	       srx->transport_len,
 | 
					 | 
				
			||||||
	       &srx->transport.sin.sin_addr,
 | 
					 | 
				
			||||||
	       ntohs(srx->transport.sin.sin_port));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* search the peer list first */
 | 
						/* search the peer list first */
 | 
				
			||||||
	rcu_read_lock();
 | 
						rcu_read_lock();
 | 
				
			||||||
| 
						 | 
					@ -326,11 +357,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *local,
 | 
				
			||||||
			peer = candidate;
 | 
								peer = candidate;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_net("PEER %d {%d,%pI4+%hu}",
 | 
						_net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
 | 
				
			||||||
	     peer->debug_id,
 | 
					 | 
				
			||||||
	     peer->srx.transport_type,
 | 
					 | 
				
			||||||
	     &peer->srx.transport.sin.sin_addr,
 | 
					 | 
				
			||||||
	     ntohs(peer->srx.transport.sin.sin_port));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
 | 
						_leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
 | 
				
			||||||
	return peer;
 | 
						return peer;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,11 +52,12 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
 | 
				
			||||||
	struct rxrpc_sock *rx;
 | 
						struct rxrpc_sock *rx;
 | 
				
			||||||
	struct rxrpc_peer *peer;
 | 
						struct rxrpc_peer *peer;
 | 
				
			||||||
	struct rxrpc_call *call;
 | 
						struct rxrpc_call *call;
 | 
				
			||||||
	char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
 | 
						char lbuff[50], rbuff[50];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (v == &rxrpc_calls) {
 | 
						if (v == &rxrpc_calls) {
 | 
				
			||||||
		seq_puts(seq,
 | 
							seq_puts(seq,
 | 
				
			||||||
			 "Proto Local                  Remote                "
 | 
								 "Proto Local                                          "
 | 
				
			||||||
 | 
								 " Remote                                         "
 | 
				
			||||||
			 " SvID ConnID   CallID   End Use State    Abort   "
 | 
								 " SvID ConnID   CallID   End Use State    Abort   "
 | 
				
			||||||
			 " UserID\n");
 | 
								 " UserID\n");
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -68,9 +69,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
 | 
				
			||||||
	if (rx) {
 | 
						if (rx) {
 | 
				
			||||||
		local = READ_ONCE(rx->local);
 | 
							local = READ_ONCE(rx->local);
 | 
				
			||||||
		if (local)
 | 
							if (local)
 | 
				
			||||||
			sprintf(lbuff, "%pI4:%u",
 | 
								sprintf(lbuff, "%pISpc", &local->srx.transport);
 | 
				
			||||||
				&local->srx.transport.sin.sin_addr,
 | 
					 | 
				
			||||||
				ntohs(local->srx.transport.sin.sin_port));
 | 
					 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			strcpy(lbuff, "no_local");
 | 
								strcpy(lbuff, "no_local");
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -79,14 +78,12 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	peer = call->peer;
 | 
						peer = call->peer;
 | 
				
			||||||
	if (peer)
 | 
						if (peer)
 | 
				
			||||||
		sprintf(rbuff, "%pI4:%u",
 | 
							sprintf(rbuff, "%pISpc", &peer->srx.transport);
 | 
				
			||||||
			&peer->srx.transport.sin.sin_addr,
 | 
					 | 
				
			||||||
			ntohs(peer->srx.transport.sin.sin_port));
 | 
					 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		strcpy(rbuff, "no_connection");
 | 
							strcpy(rbuff, "no_connection");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seq_printf(seq,
 | 
						seq_printf(seq,
 | 
				
			||||||
		   "UDP   %-22.22s %-22.22s %4x %08x %08x %s %3u"
 | 
							   "UDP   %-47.47s %-47.47s %4x %08x %08x %s %3u"
 | 
				
			||||||
		   " %-8.8s %08x %lx\n",
 | 
							   " %-8.8s %08x %lx\n",
 | 
				
			||||||
		   lbuff,
 | 
							   lbuff,
 | 
				
			||||||
		   rbuff,
 | 
							   rbuff,
 | 
				
			||||||
| 
						 | 
					@ -145,11 +142,12 @@ static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v)
 | 
				
			||||||
static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
 | 
					static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rxrpc_connection *conn;
 | 
						struct rxrpc_connection *conn;
 | 
				
			||||||
	char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
 | 
						char lbuff[50], rbuff[50];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (v == &rxrpc_connection_proc_list) {
 | 
						if (v == &rxrpc_connection_proc_list) {
 | 
				
			||||||
		seq_puts(seq,
 | 
							seq_puts(seq,
 | 
				
			||||||
			 "Proto Local                  Remote                "
 | 
								 "Proto Local                                          "
 | 
				
			||||||
 | 
								 " Remote                                         "
 | 
				
			||||||
			 " SvID ConnID   End Use State    Key     "
 | 
								 " SvID ConnID   End Use State    Key     "
 | 
				
			||||||
			 " Serial   ISerial\n"
 | 
								 " Serial   ISerial\n"
 | 
				
			||||||
			 );
 | 
								 );
 | 
				
			||||||
| 
						 | 
					@ -163,16 +161,12 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
 | 
				
			||||||
		goto print;
 | 
							goto print;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sprintf(lbuff, "%pI4:%u",
 | 
						sprintf(lbuff, "%pISpc", &conn->params.local->srx.transport);
 | 
				
			||||||
		&conn->params.local->srx.transport.sin.sin_addr,
 | 
					 | 
				
			||||||
		ntohs(conn->params.local->srx.transport.sin.sin_port));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sprintf(rbuff, "%pI4:%u",
 | 
						sprintf(rbuff, "%pISpc", &conn->params.peer->srx.transport);
 | 
				
			||||||
		&conn->params.peer->srx.transport.sin.sin_addr,
 | 
					 | 
				
			||||||
		ntohs(conn->params.peer->srx.transport.sin.sin_port));
 | 
					 | 
				
			||||||
print:
 | 
					print:
 | 
				
			||||||
	seq_printf(seq,
 | 
						seq_printf(seq,
 | 
				
			||||||
		   "UDP   %-22.22s %-22.22s %4x %08x %s %3u"
 | 
							   "UDP   %-47.47s %-47.47s %4x %08x %s %3u"
 | 
				
			||||||
		   " %s %08x %08x %08x\n",
 | 
							   " %s %08x %08x %08x\n",
 | 
				
			||||||
		   lbuff,
 | 
							   lbuff,
 | 
				
			||||||
		   rbuff,
 | 
							   rbuff,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue