Loading net/rxrpc/ar-internal.h +0 −3 Original line number Diff line number Diff line Loading @@ -564,7 +564,6 @@ void rxrpc_extract_conn_params(struct rxrpc_conn_proto *, struct rxrpc_local *, struct sk_buff *); struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *, struct rxrpc_peer *, struct sk_buff *); void __rxrpc_disconnect_call(struct rxrpc_call *); void rxrpc_disconnect_call(struct rxrpc_call *); Loading Loading @@ -768,8 +767,6 @@ static inline void rxrpc_sysctl_exit(void) {} /* * utils.c */ void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *, struct sockaddr_rxrpc *); int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *); /* Loading net/rxrpc/conn_object.c +56 −17 Original line number Diff line number Diff line Loading @@ -68,52 +68,91 @@ struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp) * packet */ struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *local, struct rxrpc_peer *peer, struct sk_buff *skb) { struct rxrpc_connection *conn; struct rxrpc_conn_proto k; struct rxrpc_skb_priv *sp = rxrpc_skb(skb); struct sockaddr_rxrpc srx; struct rxrpc_peer *peer; struct rb_node *p; u32 epoch, cid; _enter(",{%x,%x}", sp->hdr.cid, sp->hdr.flags); read_lock_bh(&peer->conn_lock); if (rxrpc_extract_addr_from_skb(&srx, skb) < 0) goto not_found; /* We may have to handle mixing IPv4 and IPv6 */ if (srx.transport.family != local->srx.transport.family) { pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n", srx.transport.family, local->srx.transport.family); goto not_found; } cid = sp->hdr.cid & RXRPC_CIDMASK; epoch = sp->hdr.epoch; k.epoch = sp->hdr.epoch; k.cid = sp->hdr.cid & RXRPC_CIDMASK; if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) { /* We need to look up service connections by the full protocol * parameter set. We look up the peer first as an intermediate * step and then the connection from the peer's tree. */ peer = rxrpc_lookup_peer_rcu(local, &srx); if (!peer) goto not_found; read_lock_bh(&peer->conn_lock); p = peer->service_conns.rb_node; while (p) { conn = rb_entry(p, struct rxrpc_connection, service_node); _debug("maybe %x", conn->proto.cid); if (epoch < conn->proto.epoch) if (k.epoch < conn->proto.epoch) p = p->rb_left; else if (epoch > conn->proto.epoch) else if (k.epoch > conn->proto.epoch) p = p->rb_right; else if (cid < conn->proto.cid) else if (k.cid < conn->proto.cid) p = p->rb_left; else if (cid > conn->proto.cid) else if (k.cid > conn->proto.cid) p = p->rb_right; else goto found; goto found_service_conn; } read_unlock_bh(&peer->conn_lock); } else { conn = idr_find(&rxrpc_client_conn_ids, cid >> RXRPC_CIDSHIFT); if (conn && conn->proto.epoch == epoch && conn->params.peer == peer) goto found; conn = idr_find(&rxrpc_client_conn_ids, k.cid >> RXRPC_CIDSHIFT); if (!conn || conn->proto.epoch != k.epoch || conn->params.local != local) goto not_found; peer = conn->params.peer; switch (srx.transport.family) { case AF_INET: if (peer->srx.transport.sin.sin_port != srx.transport.sin.sin_port || peer->srx.transport.sin.sin_addr.s_addr != srx.transport.sin.sin_addr.s_addr) goto not_found; break; default: BUG(); } read_unlock_bh(&peer->conn_lock); conn = rxrpc_get_connection_maybe(conn); _leave(" = %p", conn); return conn; } not_found: _leave(" = NULL"); return NULL; found: found_service_conn: conn = rxrpc_get_connection_maybe(conn); read_unlock_bh(&peer->conn_lock); _leave(" = %p", conn); Loading net/rxrpc/input.c +3 −27 Original line number Diff line number Diff line Loading @@ -626,32 +626,6 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb) return 0; } static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local, struct sk_buff *skb) { struct rxrpc_peer *peer; struct rxrpc_connection *conn; struct sockaddr_rxrpc srx; rxrpc_get_addr_from_skb(local, skb, &srx); rcu_read_lock(); peer = rxrpc_lookup_peer_rcu(local, &srx); if (!peer) goto cant_find_peer; conn = rxrpc_find_connection(local, peer, skb); rcu_read_unlock(); if (!conn) goto cant_find_conn; return conn; cant_find_peer: rcu_read_unlock(); cant_find_conn: return NULL; } /* * handle data received on the local endpoint * - may be called in interrupt context Loading Loading @@ -731,7 +705,9 @@ void rxrpc_data_ready(struct sock *sk) * old-fashioned way doesn't really hurt */ struct rxrpc_connection *conn; conn = rxrpc_conn_from_local(local, skb); rcu_read_lock(); conn = rxrpc_find_connection(local, skb); rcu_read_unlock(); if (!conn) goto cant_route_call; Loading net/rxrpc/utils.c +0 −27 Original line number Diff line number Diff line Loading @@ -14,33 +14,6 @@ #include <linux/udp.h> #include "ar-internal.h" /* * Set up an RxRPC address from a socket buffer. */ void rxrpc_get_addr_from_skb(struct rxrpc_local *local, const struct sk_buff *skb, struct sockaddr_rxrpc *srx) { memset(srx, 0, sizeof(*srx)); srx->transport_type = local->srx.transport_type; srx->transport.family = local->srx.transport.family; /* Can we see an ipv4 UDP packet on an ipv6 UDP socket? and vice * versa? */ switch (srx->transport.family) { case AF_INET: srx->transport.sin.sin_port = udp_hdr(skb)->source; srx->transport_len = sizeof(struct sockaddr_in); memcpy(&srx->transport.sin.sin_addr, &ip_hdr(skb)->saddr, sizeof(struct in_addr)); break; default: BUG(); } } /* * Fill out a peer address from a socket buffer containing a packet. */ Loading Loading
net/rxrpc/ar-internal.h +0 −3 Original line number Diff line number Diff line Loading @@ -564,7 +564,6 @@ void rxrpc_extract_conn_params(struct rxrpc_conn_proto *, struct rxrpc_local *, struct sk_buff *); struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *, struct rxrpc_peer *, struct sk_buff *); void __rxrpc_disconnect_call(struct rxrpc_call *); void rxrpc_disconnect_call(struct rxrpc_call *); Loading Loading @@ -768,8 +767,6 @@ static inline void rxrpc_sysctl_exit(void) {} /* * utils.c */ void rxrpc_get_addr_from_skb(struct rxrpc_local *, const struct sk_buff *, struct sockaddr_rxrpc *); int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *); /* Loading
net/rxrpc/conn_object.c +56 −17 Original line number Diff line number Diff line Loading @@ -68,52 +68,91 @@ struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp) * packet */ struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *local, struct rxrpc_peer *peer, struct sk_buff *skb) { struct rxrpc_connection *conn; struct rxrpc_conn_proto k; struct rxrpc_skb_priv *sp = rxrpc_skb(skb); struct sockaddr_rxrpc srx; struct rxrpc_peer *peer; struct rb_node *p; u32 epoch, cid; _enter(",{%x,%x}", sp->hdr.cid, sp->hdr.flags); read_lock_bh(&peer->conn_lock); if (rxrpc_extract_addr_from_skb(&srx, skb) < 0) goto not_found; /* We may have to handle mixing IPv4 and IPv6 */ if (srx.transport.family != local->srx.transport.family) { pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n", srx.transport.family, local->srx.transport.family); goto not_found; } cid = sp->hdr.cid & RXRPC_CIDMASK; epoch = sp->hdr.epoch; k.epoch = sp->hdr.epoch; k.cid = sp->hdr.cid & RXRPC_CIDMASK; if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) { /* We need to look up service connections by the full protocol * parameter set. We look up the peer first as an intermediate * step and then the connection from the peer's tree. */ peer = rxrpc_lookup_peer_rcu(local, &srx); if (!peer) goto not_found; read_lock_bh(&peer->conn_lock); p = peer->service_conns.rb_node; while (p) { conn = rb_entry(p, struct rxrpc_connection, service_node); _debug("maybe %x", conn->proto.cid); if (epoch < conn->proto.epoch) if (k.epoch < conn->proto.epoch) p = p->rb_left; else if (epoch > conn->proto.epoch) else if (k.epoch > conn->proto.epoch) p = p->rb_right; else if (cid < conn->proto.cid) else if (k.cid < conn->proto.cid) p = p->rb_left; else if (cid > conn->proto.cid) else if (k.cid > conn->proto.cid) p = p->rb_right; else goto found; goto found_service_conn; } read_unlock_bh(&peer->conn_lock); } else { conn = idr_find(&rxrpc_client_conn_ids, cid >> RXRPC_CIDSHIFT); if (conn && conn->proto.epoch == epoch && conn->params.peer == peer) goto found; conn = idr_find(&rxrpc_client_conn_ids, k.cid >> RXRPC_CIDSHIFT); if (!conn || conn->proto.epoch != k.epoch || conn->params.local != local) goto not_found; peer = conn->params.peer; switch (srx.transport.family) { case AF_INET: if (peer->srx.transport.sin.sin_port != srx.transport.sin.sin_port || peer->srx.transport.sin.sin_addr.s_addr != srx.transport.sin.sin_addr.s_addr) goto not_found; break; default: BUG(); } read_unlock_bh(&peer->conn_lock); conn = rxrpc_get_connection_maybe(conn); _leave(" = %p", conn); return conn; } not_found: _leave(" = NULL"); return NULL; found: found_service_conn: conn = rxrpc_get_connection_maybe(conn); read_unlock_bh(&peer->conn_lock); _leave(" = %p", conn); Loading
net/rxrpc/input.c +3 −27 Original line number Diff line number Diff line Loading @@ -626,32 +626,6 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb) return 0; } static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local, struct sk_buff *skb) { struct rxrpc_peer *peer; struct rxrpc_connection *conn; struct sockaddr_rxrpc srx; rxrpc_get_addr_from_skb(local, skb, &srx); rcu_read_lock(); peer = rxrpc_lookup_peer_rcu(local, &srx); if (!peer) goto cant_find_peer; conn = rxrpc_find_connection(local, peer, skb); rcu_read_unlock(); if (!conn) goto cant_find_conn; return conn; cant_find_peer: rcu_read_unlock(); cant_find_conn: return NULL; } /* * handle data received on the local endpoint * - may be called in interrupt context Loading Loading @@ -731,7 +705,9 @@ void rxrpc_data_ready(struct sock *sk) * old-fashioned way doesn't really hurt */ struct rxrpc_connection *conn; conn = rxrpc_conn_from_local(local, skb); rcu_read_lock(); conn = rxrpc_find_connection(local, skb); rcu_read_unlock(); if (!conn) goto cant_route_call; Loading
net/rxrpc/utils.c +0 −27 Original line number Diff line number Diff line Loading @@ -14,33 +14,6 @@ #include <linux/udp.h> #include "ar-internal.h" /* * Set up an RxRPC address from a socket buffer. */ void rxrpc_get_addr_from_skb(struct rxrpc_local *local, const struct sk_buff *skb, struct sockaddr_rxrpc *srx) { memset(srx, 0, sizeof(*srx)); srx->transport_type = local->srx.transport_type; srx->transport.family = local->srx.transport.family; /* Can we see an ipv4 UDP packet on an ipv6 UDP socket? and vice * versa? */ switch (srx->transport.family) { case AF_INET: srx->transport.sin.sin_port = udp_hdr(skb)->source; srx->transport_len = sizeof(struct sockaddr_in); memcpy(&srx->transport.sin.sin_addr, &ip_hdr(skb)->saddr, sizeof(struct in_addr)); break; default: BUG(); } } /* * Fill out a peer address from a socket buffer containing a packet. */ Loading