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