diff options
author | David Howells <dhowells@redhat.com> | 2016-04-04 09:00:40 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2016-07-06 05:49:35 -0400 |
commit | 7877a4a4bdf0d782276f1cba868878aee77718ee (patch) | |
tree | d7bbda493ebfda88069805ac2b19a21e3ef5e771 /net/rxrpc | |
parent | c6d2b8d764f5edd79f708bdc49d1176072ee77a1 (diff) |
rxrpc: Split service connection code out into its own file
Split the service-specific connection code out into into its own file. The
client-specific code has already been split out. This will leave just the
common code in the original file.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc')
-rw-r--r-- | net/rxrpc/Makefile | 1 | ||||
-rw-r--r-- | net/rxrpc/ar-internal.h | 13 | ||||
-rw-r--r-- | net/rxrpc/conn_object.c | 132 | ||||
-rw-r--r-- | net/rxrpc/conn_service.c | 145 |
4 files changed, 156 insertions, 135 deletions
diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile index 6522e50fb750..10f3f48a16a8 100644 --- a/net/rxrpc/Makefile +++ b/net/rxrpc/Makefile | |||
@@ -10,6 +10,7 @@ af-rxrpc-y := \ | |||
10 | conn_client.o \ | 10 | conn_client.o \ |
11 | conn_event.o \ | 11 | conn_event.o \ |
12 | conn_object.o \ | 12 | conn_object.o \ |
13 | conn_service.o \ | ||
13 | input.o \ | 14 | input.o \ |
14 | insecure.o \ | 15 | insecure.o \ |
15 | key.o \ | 16 | key.o \ |
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 021d28b54282..e1af258a7ac9 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h | |||
@@ -563,6 +563,9 @@ extern unsigned int rxrpc_connection_expiry; | |||
563 | extern struct list_head rxrpc_connections; | 563 | extern struct list_head rxrpc_connections; |
564 | extern rwlock_t rxrpc_connection_lock; | 564 | extern rwlock_t rxrpc_connection_lock; |
565 | 565 | ||
566 | void rxrpc_conn_hash_proto_key(struct rxrpc_conn_proto *); | ||
567 | void rxrpc_extract_conn_params(struct rxrpc_conn_proto *, | ||
568 | struct rxrpc_local *, struct sk_buff *); | ||
566 | struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); | 569 | struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); |
567 | struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *, | 570 | struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *, |
568 | struct rxrpc_peer *, | 571 | struct rxrpc_peer *, |
@@ -571,9 +574,6 @@ void __rxrpc_disconnect_call(struct rxrpc_call *); | |||
571 | void rxrpc_disconnect_call(struct rxrpc_call *); | 574 | void rxrpc_disconnect_call(struct rxrpc_call *); |
572 | void rxrpc_put_connection(struct rxrpc_connection *); | 575 | void rxrpc_put_connection(struct rxrpc_connection *); |
573 | void __exit rxrpc_destroy_all_connections(void); | 576 | void __exit rxrpc_destroy_all_connections(void); |
574 | struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *, | ||
575 | struct rxrpc_peer *, | ||
576 | struct sk_buff *); | ||
577 | 577 | ||
578 | static inline bool rxrpc_conn_is_client(const struct rxrpc_connection *conn) | 578 | static inline bool rxrpc_conn_is_client(const struct rxrpc_connection *conn) |
579 | { | 579 | { |
@@ -604,6 +604,13 @@ static inline void rxrpc_queue_conn(struct rxrpc_connection *conn) | |||
604 | } | 604 | } |
605 | 605 | ||
606 | /* | 606 | /* |
607 | * conn_service.c | ||
608 | */ | ||
609 | struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *, | ||
610 | struct rxrpc_peer *, | ||
611 | struct sk_buff *); | ||
612 | |||
613 | /* | ||
607 | * input.c | 614 | * input.c |
608 | */ | 615 | */ |
609 | void rxrpc_data_ready(struct sock *); | 616 | void rxrpc_data_ready(struct sock *); |
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index ab5c8c2960e4..8379e3748d13 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c | |||
@@ -61,138 +61,6 @@ struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * get a record of an incoming connection | ||
65 | */ | ||
66 | struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *local, | ||
67 | struct rxrpc_peer *peer, | ||
68 | struct sk_buff *skb) | ||
69 | { | ||
70 | struct rxrpc_connection *conn, *candidate = NULL; | ||
71 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | ||
72 | struct rb_node *p, **pp; | ||
73 | const char *new = "old"; | ||
74 | u32 epoch, cid; | ||
75 | |||
76 | _enter(""); | ||
77 | |||
78 | ASSERT(sp->hdr.flags & RXRPC_CLIENT_INITIATED); | ||
79 | |||
80 | epoch = sp->hdr.epoch; | ||
81 | cid = sp->hdr.cid & RXRPC_CIDMASK; | ||
82 | |||
83 | /* search the connection list first */ | ||
84 | read_lock_bh(&peer->conn_lock); | ||
85 | |||
86 | p = peer->service_conns.rb_node; | ||
87 | while (p) { | ||
88 | conn = rb_entry(p, struct rxrpc_connection, service_node); | ||
89 | |||
90 | _debug("maybe %x", conn->proto.cid); | ||
91 | |||
92 | if (epoch < conn->proto.epoch) | ||
93 | p = p->rb_left; | ||
94 | else if (epoch > conn->proto.epoch) | ||
95 | p = p->rb_right; | ||
96 | else if (cid < conn->proto.cid) | ||
97 | p = p->rb_left; | ||
98 | else if (cid > conn->proto.cid) | ||
99 | p = p->rb_right; | ||
100 | else | ||
101 | goto found_extant_connection; | ||
102 | } | ||
103 | read_unlock_bh(&peer->conn_lock); | ||
104 | |||
105 | /* not yet present - create a candidate for a new record and then | ||
106 | * redo the search */ | ||
107 | candidate = rxrpc_alloc_connection(GFP_NOIO); | ||
108 | if (!candidate) { | ||
109 | _leave(" = -ENOMEM"); | ||
110 | return ERR_PTR(-ENOMEM); | ||
111 | } | ||
112 | |||
113 | candidate->proto.local = local; | ||
114 | candidate->proto.epoch = sp->hdr.epoch; | ||
115 | candidate->proto.cid = sp->hdr.cid & RXRPC_CIDMASK; | ||
116 | candidate->proto.in_clientflag = RXRPC_CLIENT_INITIATED; | ||
117 | candidate->params.local = local; | ||
118 | candidate->params.peer = peer; | ||
119 | candidate->params.service_id = sp->hdr.serviceId; | ||
120 | candidate->security_ix = sp->hdr.securityIndex; | ||
121 | candidate->out_clientflag = 0; | ||
122 | candidate->state = RXRPC_CONN_SERVICE; | ||
123 | if (candidate->params.service_id) | ||
124 | candidate->state = RXRPC_CONN_SERVICE_UNSECURED; | ||
125 | |||
126 | write_lock_bh(&peer->conn_lock); | ||
127 | |||
128 | pp = &peer->service_conns.rb_node; | ||
129 | p = NULL; | ||
130 | while (*pp) { | ||
131 | p = *pp; | ||
132 | conn = rb_entry(p, struct rxrpc_connection, service_node); | ||
133 | |||
134 | if (epoch < conn->proto.epoch) | ||
135 | pp = &(*pp)->rb_left; | ||
136 | else if (epoch > conn->proto.epoch) | ||
137 | pp = &(*pp)->rb_right; | ||
138 | else if (cid < conn->proto.cid) | ||
139 | pp = &(*pp)->rb_left; | ||
140 | else if (cid > conn->proto.cid) | ||
141 | pp = &(*pp)->rb_right; | ||
142 | else | ||
143 | goto found_extant_second; | ||
144 | } | ||
145 | |||
146 | /* we can now add the new candidate to the list */ | ||
147 | conn = candidate; | ||
148 | candidate = NULL; | ||
149 | rb_link_node(&conn->service_node, p, pp); | ||
150 | rb_insert_color(&conn->service_node, &peer->service_conns); | ||
151 | rxrpc_get_peer(peer); | ||
152 | rxrpc_get_local(local); | ||
153 | |||
154 | write_unlock_bh(&peer->conn_lock); | ||
155 | |||
156 | write_lock(&rxrpc_connection_lock); | ||
157 | list_add_tail(&conn->link, &rxrpc_connections); | ||
158 | write_unlock(&rxrpc_connection_lock); | ||
159 | |||
160 | new = "new"; | ||
161 | |||
162 | success: | ||
163 | _net("CONNECTION %s %d {%x}", new, conn->debug_id, conn->proto.cid); | ||
164 | |||
165 | _leave(" = %p {u=%d}", conn, atomic_read(&conn->usage)); | ||
166 | return conn; | ||
167 | |||
168 | /* we found the connection in the list immediately */ | ||
169 | found_extant_connection: | ||
170 | if (sp->hdr.securityIndex != conn->security_ix) { | ||
171 | read_unlock_bh(&peer->conn_lock); | ||
172 | goto security_mismatch; | ||
173 | } | ||
174 | rxrpc_get_connection(conn); | ||
175 | read_unlock_bh(&peer->conn_lock); | ||
176 | goto success; | ||
177 | |||
178 | /* we found the connection on the second time through the list */ | ||
179 | found_extant_second: | ||
180 | if (sp->hdr.securityIndex != conn->security_ix) { | ||
181 | write_unlock_bh(&peer->conn_lock); | ||
182 | goto security_mismatch; | ||
183 | } | ||
184 | rxrpc_get_connection(conn); | ||
185 | write_unlock_bh(&peer->conn_lock); | ||
186 | kfree(candidate); | ||
187 | goto success; | ||
188 | |||
189 | security_mismatch: | ||
190 | kfree(candidate); | ||
191 | _leave(" = -EKEYREJECTED"); | ||
192 | return ERR_PTR(-EKEYREJECTED); | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * find a connection based on transport and RxRPC connection ID for an incoming | 64 | * find a connection based on transport and RxRPC connection ID for an incoming |
197 | * packet | 65 | * packet |
198 | */ | 66 | */ |
diff --git a/net/rxrpc/conn_service.c b/net/rxrpc/conn_service.c new file mode 100644 index 000000000000..cdcac50cd1a8 --- /dev/null +++ b/net/rxrpc/conn_service.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* Service connection management | ||
2 | * | ||
3 | * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/slab.h> | ||
13 | #include "ar-internal.h" | ||
14 | |||
15 | /* | ||
16 | * get a record of an incoming connection | ||
17 | */ | ||
18 | struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *local, | ||
19 | struct rxrpc_peer *peer, | ||
20 | struct sk_buff *skb) | ||
21 | { | ||
22 | struct rxrpc_connection *conn, *candidate = NULL; | ||
23 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | ||
24 | struct rb_node *p, **pp; | ||
25 | const char *new = "old"; | ||
26 | u32 epoch, cid; | ||
27 | |||
28 | _enter(""); | ||
29 | |||
30 | ASSERT(sp->hdr.flags & RXRPC_CLIENT_INITIATED); | ||
31 | |||
32 | epoch = sp->hdr.epoch; | ||
33 | cid = sp->hdr.cid & RXRPC_CIDMASK; | ||
34 | |||
35 | /* search the connection list first */ | ||
36 | read_lock_bh(&peer->conn_lock); | ||
37 | |||
38 | p = peer->service_conns.rb_node; | ||
39 | while (p) { | ||
40 | conn = rb_entry(p, struct rxrpc_connection, service_node); | ||
41 | |||
42 | _debug("maybe %x", conn->proto.cid); | ||
43 | |||
44 | if (epoch < conn->proto.epoch) | ||
45 | p = p->rb_left; | ||
46 | else if (epoch > conn->proto.epoch) | ||
47 | p = p->rb_right; | ||
48 | else if (cid < conn->proto.cid) | ||
49 | p = p->rb_left; | ||
50 | else if (cid > conn->proto.cid) | ||
51 | p = p->rb_right; | ||
52 | else | ||
53 | goto found_extant_connection; | ||
54 | } | ||
55 | read_unlock_bh(&peer->conn_lock); | ||
56 | |||
57 | /* not yet present - create a candidate for a new record and then | ||
58 | * redo the search */ | ||
59 | candidate = rxrpc_alloc_connection(GFP_NOIO); | ||
60 | if (!candidate) { | ||
61 | _leave(" = -ENOMEM"); | ||
62 | return ERR_PTR(-ENOMEM); | ||
63 | } | ||
64 | |||
65 | candidate->proto.local = local; | ||
66 | candidate->proto.epoch = sp->hdr.epoch; | ||
67 | candidate->proto.cid = sp->hdr.cid & RXRPC_CIDMASK; | ||
68 | candidate->proto.in_clientflag = RXRPC_CLIENT_INITIATED; | ||
69 | candidate->params.local = local; | ||
70 | candidate->params.peer = peer; | ||
71 | candidate->params.service_id = sp->hdr.serviceId; | ||
72 | candidate->security_ix = sp->hdr.securityIndex; | ||
73 | candidate->out_clientflag = 0; | ||
74 | candidate->state = RXRPC_CONN_SERVICE; | ||
75 | if (candidate->params.service_id) | ||
76 | candidate->state = RXRPC_CONN_SERVICE_UNSECURED; | ||
77 | |||
78 | write_lock_bh(&peer->conn_lock); | ||
79 | |||
80 | pp = &peer->service_conns.rb_node; | ||
81 | p = NULL; | ||
82 | while (*pp) { | ||
83 | p = *pp; | ||
84 | conn = rb_entry(p, struct rxrpc_connection, service_node); | ||
85 | |||
86 | if (epoch < conn->proto.epoch) | ||
87 | pp = &(*pp)->rb_left; | ||
88 | else if (epoch > conn->proto.epoch) | ||
89 | pp = &(*pp)->rb_right; | ||
90 | else if (cid < conn->proto.cid) | ||
91 | pp = &(*pp)->rb_left; | ||
92 | else if (cid > conn->proto.cid) | ||
93 | pp = &(*pp)->rb_right; | ||
94 | else | ||
95 | goto found_extant_second; | ||
96 | } | ||
97 | |||
98 | /* we can now add the new candidate to the list */ | ||
99 | conn = candidate; | ||
100 | candidate = NULL; | ||
101 | rb_link_node(&conn->service_node, p, pp); | ||
102 | rb_insert_color(&conn->service_node, &peer->service_conns); | ||
103 | rxrpc_get_peer(peer); | ||
104 | rxrpc_get_local(local); | ||
105 | |||
106 | write_unlock_bh(&peer->conn_lock); | ||
107 | |||
108 | write_lock(&rxrpc_connection_lock); | ||
109 | list_add_tail(&conn->link, &rxrpc_connections); | ||
110 | write_unlock(&rxrpc_connection_lock); | ||
111 | |||
112 | new = "new"; | ||
113 | |||
114 | success: | ||
115 | _net("CONNECTION %s %d {%x}", new, conn->debug_id, conn->proto.cid); | ||
116 | |||
117 | _leave(" = %p {u=%d}", conn, atomic_read(&conn->usage)); | ||
118 | return conn; | ||
119 | |||
120 | /* we found the connection in the list immediately */ | ||
121 | found_extant_connection: | ||
122 | if (sp->hdr.securityIndex != conn->security_ix) { | ||
123 | read_unlock_bh(&peer->conn_lock); | ||
124 | goto security_mismatch; | ||
125 | } | ||
126 | rxrpc_get_connection(conn); | ||
127 | read_unlock_bh(&peer->conn_lock); | ||
128 | goto success; | ||
129 | |||
130 | /* we found the connection on the second time through the list */ | ||
131 | found_extant_second: | ||
132 | if (sp->hdr.securityIndex != conn->security_ix) { | ||
133 | write_unlock_bh(&peer->conn_lock); | ||
134 | goto security_mismatch; | ||
135 | } | ||
136 | rxrpc_get_connection(conn); | ||
137 | write_unlock_bh(&peer->conn_lock); | ||
138 | kfree(candidate); | ||
139 | goto success; | ||
140 | |||
141 | security_mismatch: | ||
142 | kfree(candidate); | ||
143 | _leave(" = -EKEYREJECTED"); | ||
144 | return ERR_PTR(-EKEYREJECTED); | ||
145 | } | ||