Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : /*
3 : : * linux/include/linux/sunrpc/svc_xprt.h
4 : : *
5 : : * RPC server transport I/O
6 : : */
7 : :
8 : : #ifndef SUNRPC_SVC_XPRT_H
9 : : #define SUNRPC_SVC_XPRT_H
10 : :
11 : : #include <linux/sunrpc/svc.h>
12 : :
13 : : struct module;
14 : :
15 : : struct svc_xprt_ops {
16 : : struct svc_xprt *(*xpo_create)(struct svc_serv *,
17 : : struct net *net,
18 : : struct sockaddr *, int,
19 : : int);
20 : : struct svc_xprt *(*xpo_accept)(struct svc_xprt *);
21 : : int (*xpo_has_wspace)(struct svc_xprt *);
22 : : int (*xpo_recvfrom)(struct svc_rqst *);
23 : : int (*xpo_sendto)(struct svc_rqst *);
24 : : int (*xpo_read_payload)(struct svc_rqst *, unsigned int,
25 : : unsigned int);
26 : : void (*xpo_release_rqst)(struct svc_rqst *);
27 : : void (*xpo_detach)(struct svc_xprt *);
28 : : void (*xpo_free)(struct svc_xprt *);
29 : : void (*xpo_secure_port)(struct svc_rqst *rqstp);
30 : : void (*xpo_kill_temp_xprt)(struct svc_xprt *);
31 : : };
32 : :
33 : : struct svc_xprt_class {
34 : : const char *xcl_name;
35 : : struct module *xcl_owner;
36 : : const struct svc_xprt_ops *xcl_ops;
37 : : struct list_head xcl_list;
38 : : u32 xcl_max_payload;
39 : : int xcl_ident;
40 : : };
41 : :
42 : : /*
43 : : * This is embedded in an object that wants a callback before deleting
44 : : * an xprt; intended for use by NFSv4.1, which needs to know when a
45 : : * client's tcp connection (and hence possibly a backchannel) goes away.
46 : : */
47 : : struct svc_xpt_user {
48 : : struct list_head list;
49 : : void (*callback)(struct svc_xpt_user *);
50 : : };
51 : :
52 : : struct svc_xprt {
53 : : struct svc_xprt_class *xpt_class;
54 : : const struct svc_xprt_ops *xpt_ops;
55 : : struct kref xpt_ref;
56 : : struct list_head xpt_list;
57 : : struct list_head xpt_ready;
58 : : unsigned long xpt_flags;
59 : : #define XPT_BUSY 0 /* enqueued/receiving */
60 : : #define XPT_CONN 1 /* conn pending */
61 : : #define XPT_CLOSE 2 /* dead or dying */
62 : : #define XPT_DATA 3 /* data pending */
63 : : #define XPT_TEMP 4 /* connected transport */
64 : : #define XPT_DEAD 6 /* transport closed */
65 : : #define XPT_CHNGBUF 7 /* need to change snd/rcv buf sizes */
66 : : #define XPT_DEFERRED 8 /* deferred request pending */
67 : : #define XPT_OLD 9 /* used for xprt aging mark+sweep */
68 : : #define XPT_LISTENER 10 /* listening endpoint */
69 : : #define XPT_CACHE_AUTH 11 /* cache auth info */
70 : : #define XPT_LOCAL 12 /* connection from loopback interface */
71 : : #define XPT_KILL_TEMP 13 /* call xpo_kill_temp_xprt before closing */
72 : : #define XPT_CONG_CTRL 14 /* has congestion control */
73 : :
74 : : struct svc_serv *xpt_server; /* service for transport */
75 : : atomic_t xpt_reserved; /* space on outq that is rsvd */
76 : : atomic_t xpt_nr_rqsts; /* Number of requests */
77 : : struct mutex xpt_mutex; /* to serialize sending data */
78 : : spinlock_t xpt_lock; /* protects sk_deferred
79 : : * and xpt_auth_cache */
80 : : void *xpt_auth_cache;/* auth cache */
81 : : struct list_head xpt_deferred; /* deferred requests that need
82 : : * to be revisted */
83 : : struct sockaddr_storage xpt_local; /* local address */
84 : : size_t xpt_locallen; /* length of address */
85 : : struct sockaddr_storage xpt_remote; /* remote peer's address */
86 : : size_t xpt_remotelen; /* length of address */
87 : : char xpt_remotebuf[INET6_ADDRSTRLEN + 10];
88 : : struct list_head xpt_users; /* callbacks on free */
89 : :
90 : : struct net *xpt_net;
91 : : const struct cred *xpt_cred;
92 : : struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */
93 : : struct rpc_xprt_switch *xpt_bc_xps; /* NFSv4.1 backchannel */
94 : : };
95 : :
96 : : static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
97 : : {
98 : : spin_lock(&xpt->xpt_lock);
99 : : list_del_init(&u->list);
100 : : spin_unlock(&xpt->xpt_lock);
101 : : }
102 : :
103 : : static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
104 : : {
105 : : spin_lock(&xpt->xpt_lock);
106 : : if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) {
107 : : /*
108 : : * The connection is about to be deleted soon (or,
109 : : * worse, may already be deleted--in which case we've
110 : : * already notified the xpt_users).
111 : : */
112 : : spin_unlock(&xpt->xpt_lock);
113 : : return -ENOTCONN;
114 : : }
115 : : list_add(&u->list, &xpt->xpt_users);
116 : : spin_unlock(&xpt->xpt_lock);
117 : : return 0;
118 : : }
119 : :
120 : : int svc_reg_xprt_class(struct svc_xprt_class *);
121 : : void svc_unreg_xprt_class(struct svc_xprt_class *);
122 : : void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
123 : : struct svc_serv *);
124 : : int svc_create_xprt(struct svc_serv *, const char *, struct net *,
125 : : const int, const unsigned short, int,
126 : : const struct cred *);
127 : : void svc_xprt_do_enqueue(struct svc_xprt *xprt);
128 : : void svc_xprt_enqueue(struct svc_xprt *xprt);
129 : : void svc_xprt_put(struct svc_xprt *xprt);
130 : : void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt);
131 : : void svc_close_xprt(struct svc_xprt *xprt);
132 : : int svc_port_is_privileged(struct sockaddr *sin);
133 : : int svc_print_xprts(char *buf, int maxlen);
134 : : struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
135 : : struct net *net, const sa_family_t af,
136 : : const unsigned short port);
137 : : int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
138 : : void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt);
139 : : void svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *);
140 : :
141 : : static inline void svc_xprt_get(struct svc_xprt *xprt)
142 : : {
143 : : kref_get(&xprt->xpt_ref);
144 : : }
145 : : static inline void svc_xprt_set_local(struct svc_xprt *xprt,
146 : : const struct sockaddr *sa,
147 : : const size_t salen)
148 : : {
149 : 0 : memcpy(&xprt->xpt_local, sa, salen);
150 : 0 : xprt->xpt_locallen = salen;
151 : : }
152 : 0 : static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
153 : : const struct sockaddr *sa,
154 : : const size_t salen)
155 : : {
156 : 0 : memcpy(&xprt->xpt_remote, sa, salen);
157 : 0 : xprt->xpt_remotelen = salen;
158 : 0 : snprintf(xprt->xpt_remotebuf, sizeof(xprt->xpt_remotebuf) - 1,
159 : : "%pISpc", sa);
160 : 0 : }
161 : :
162 : : static inline unsigned short svc_addr_port(const struct sockaddr *sa)
163 : : {
164 : : const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
165 : : const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
166 : :
167 [ # # # # : 0 : switch (sa->sa_family) {
# # # #
# ]
168 : : case AF_INET:
169 : 0 : return ntohs(sin->sin_port);
170 : : case AF_INET6:
171 : 0 : return ntohs(sin6->sin6_port);
172 : : }
173 : :
174 : : return 0;
175 : : }
176 : :
177 : 0 : static inline size_t svc_addr_len(const struct sockaddr *sa)
178 : : {
179 [ # # # ]: 0 : switch (sa->sa_family) {
180 : : case AF_INET:
181 : : return sizeof(struct sockaddr_in);
182 : : case AF_INET6:
183 : 0 : return sizeof(struct sockaddr_in6);
184 : : }
185 : 0 : BUG();
186 : : }
187 : :
188 : : static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt)
189 : : {
190 : : return svc_addr_port((const struct sockaddr *)&xprt->xpt_local);
191 : : }
192 : :
193 : : static inline unsigned short svc_xprt_remote_port(const struct svc_xprt *xprt)
194 : : {
195 : : return svc_addr_port((const struct sockaddr *)&xprt->xpt_remote);
196 : : }
197 : :
198 : 0 : static inline char *__svc_print_addr(const struct sockaddr *addr,
199 : : char *buf, const size_t len)
200 : : {
201 : : const struct sockaddr_in *sin = (const struct sockaddr_in *)addr;
202 : : const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)addr;
203 : :
204 [ # # # ]: 0 : switch (addr->sa_family) {
205 : : case AF_INET:
206 : 0 : snprintf(buf, len, "%pI4, port=%u", &sin->sin_addr,
207 : 0 : ntohs(sin->sin_port));
208 : 0 : break;
209 : :
210 : : case AF_INET6:
211 : 0 : snprintf(buf, len, "%pI6, port=%u",
212 : : &sin6->sin6_addr,
213 : 0 : ntohs(sin6->sin6_port));
214 : 0 : break;
215 : :
216 : : default:
217 : 0 : snprintf(buf, len, "unknown address type: %d", addr->sa_family);
218 : 0 : break;
219 : : }
220 : :
221 : 0 : return buf;
222 : : }
223 : : #endif /* SUNRPC_SVC_XPRT_H */
|