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