FreeBSD/Linux Kernel Cross Reference
sys/sys/socketvar.h
1 /* $NetBSD: socketvar.h,v 1.116.4.2 2009/04/04 23:36:28 snj Exp $ */
2
3 /*-
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*-
33 * Copyright (c) 1982, 1986, 1990, 1993
34 * The Regents of the University of California. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)socketvar.h 8.3 (Berkeley) 2/19/95
61 */
62
63 #ifndef _SYS_SOCKETVAR_H_
64 #define _SYS_SOCKETVAR_H_
65
66 #include <sys/select.h>
67 #include <sys/selinfo.h> /* for struct selinfo */
68 #include <sys/queue.h>
69 #include <sys/mutex.h>
70 #include <sys/condvar.h>
71 #ifdef ACCEPT_FILTER_MOD
72 #include <sys/lkm.h>
73 #endif
74
75 #if !defined(_KERNEL)
76 struct uio;
77 struct lwp;
78 struct uidinfo;
79 #else
80 #include <sys/uidinfo.h>
81 #endif
82
83 TAILQ_HEAD(soqhead, socket);
84
85 /*
86 * Variables for socket buffering.
87 */
88 struct sockbuf {
89 struct selinfo sb_sel; /* process selecting read/write */
90 struct mowner *sb_mowner; /* who owns data for this sockbuf */
91 struct socket *sb_so; /* back pointer to socket */
92 kcondvar_t sb_cv; /* notifier */
93 /* When re-zeroing this struct, we zero from sb_startzero to the end */
94 #define sb_startzero sb_cc
95 u_long sb_cc; /* actual chars in buffer */
96 u_long sb_hiwat; /* max actual char count */
97 u_long sb_mbcnt; /* chars of mbufs used */
98 u_long sb_mbmax; /* max chars of mbufs to use */
99 long sb_lowat; /* low water mark */
100 struct mbuf *sb_mb; /* the mbuf chain */
101 struct mbuf *sb_mbtail; /* the last mbuf in the chain */
102 struct mbuf *sb_lastrecord; /* first mbuf of last record in
103 socket buffer */
104 int sb_flags; /* flags, see below */
105 int sb_timeo; /* timeout for read/write */
106 u_long sb_overflowed; /* # of drops due to full buffer */
107 };
108
109 #ifndef SB_MAX
110 #define SB_MAX (256*1024) /* default for max chars in sockbuf */
111 #endif
112
113 #define SB_LOCK 0x01 /* lock on data queue */
114 #define SB_NOTIFY 0x04 /* someone is waiting for data/space */
115 #define SB_ASYNC 0x10 /* ASYNC I/O, need signals */
116 #define SB_UPCALL 0x20 /* someone wants an upcall */
117 #define SB_NOINTR 0x40 /* operations not interruptible */
118 #define SB_KNOTE 0x100 /* kernel note attached */
119 #define SB_AUTOSIZE 0x800 /* automatically size socket buffer */
120
121 /*
122 * Kernel structure per socket.
123 * Contains send and receive buffer queues,
124 * handle on protocol and pointer to protocol
125 * private data and error information.
126 */
127 struct socket {
128 kmutex_t * volatile so_lock; /* pointer to lock on structure */
129 kcondvar_t so_cv; /* notifier */
130 short so_type; /* generic type, see socket.h */
131 short so_options; /* from socket call, see socket.h */
132 u_short so_linger; /* time to linger while closing */
133 short so_state; /* internal state flags SS_*, below */
134 int so_nbio; /* non-blocking I/O enabled */
135 void *so_pcb; /* protocol control block */
136 const struct protosw *so_proto; /* protocol handle */
137 /*
138 * Variables for connection queueing.
139 * Socket where accepts occur is so_head in all subsidiary sockets.
140 * If so_head is 0, socket is not related to an accept.
141 * For head socket so_q0 queues partially completed connections,
142 * while so_q is a queue of connections ready to be accepted.
143 * If a connection is aborted and it has so_head set, then
144 * it has to be pulled out of either so_q0 or so_q.
145 * We allow connections to queue up based on current queue lengths
146 * and limit on number of queued connections for this socket.
147 */
148 struct socket *so_head; /* back pointer to accept socket */
149 struct soqhead *so_onq; /* queue (q or q0) that we're on */
150 struct soqhead so_q0; /* queue of partial connections */
151 struct soqhead so_q; /* queue of incoming connections */
152 TAILQ_ENTRY(socket) so_qe; /* our queue entry (q or q0) */
153 short so_q0len; /* partials on so_q0 */
154 short so_qlen; /* number of connections on so_q */
155 short so_qlimit; /* max number queued connections */
156 short so_timeo; /* connection timeout */
157 u_short so_error; /* error affecting connection */
158 u_short so_aborting; /* references from soabort() */
159 pid_t so_pgid; /* pgid for signals */
160 u_long so_oobmark; /* chars to oob mark */
161 struct sockbuf so_snd; /* send buffer */
162 struct sockbuf so_rcv; /* receive buffer */
163
164 void *so_internal; /* Space for svr4 stream data */
165 void (*so_upcall) (struct socket *, void *, int);
166 void * so_upcallarg; /* Arg for above */
167 int (*so_send) (struct socket *, struct mbuf *,
168 struct uio *, struct mbuf *,
169 struct mbuf *, int, struct lwp *);
170 int (*so_receive) (struct socket *,
171 struct mbuf **,
172 struct uio *, struct mbuf **,
173 struct mbuf **, int *);
174 struct mowner *so_mowner; /* who owns mbufs for this socket */
175 struct uidinfo *so_uidinfo; /* who opened the socket */
176 gid_t so_egid; /* creator effective gid */
177 pid_t so_cpid; /* creator pid */
178 struct so_accf {
179 struct accept_filter *so_accept_filter;
180 void *so_accept_filter_arg; /* saved filter args */
181 char *so_accept_filter_str; /* saved user args */
182 } *so_accf;
183 };
184
185 #define SB_EMPTY_FIXUP(sb) \
186 do { \
187 KASSERT(solocked((sb)->sb_so)); \
188 if ((sb)->sb_mb == NULL) { \
189 (sb)->sb_mbtail = NULL; \
190 (sb)->sb_lastrecord = NULL; \
191 } \
192 } while (/*CONSTCOND*/0)
193
194 /*
195 * Socket state bits.
196 */
197 #define SS_NOFDREF 0x001 /* no file table ref any more */
198 #define SS_ISCONNECTED 0x002 /* socket connected to a peer */
199 #define SS_ISCONNECTING 0x004 /* in process of connecting to peer */
200 #define SS_ISDISCONNECTING 0x008 /* in process of disconnecting */
201 #define SS_CANTSENDMORE 0x010 /* can't send more data to peer */
202 #define SS_CANTRCVMORE 0x020 /* can't receive more data from peer */
203 #define SS_RCVATMARK 0x040 /* at mark on input */
204 #define SS_ISDRAINING 0x080 /* draining fd references */
205 #define SS_ISDISCONNECTED 0x800 /* socket disconnected from peer */
206
207 #define SS_ASYNC 0x100 /* async i/o notify */
208 #define SS_ISCONFIRMING 0x200 /* deciding to accept connection req */
209 #define SS_MORETOCOME 0x400 /*
210 * hint from sosend to lower layer;
211 * more data coming
212 */
213 #define SS_ISAPIPE 0x1000 /* socket is implementing a pipe */
214
215 #ifdef _KERNEL
216
217 struct accept_filter {
218 char accf_name[16];
219 void (*accf_callback)
220 (struct socket *so, void *arg, int waitflag);
221 void * (*accf_create)
222 (struct socket *so, char *arg);
223 void (*accf_destroy)
224 (struct socket *so);
225 LIST_ENTRY(accept_filter) accf_next;
226 u_int accf_refcnt;
227 };
228
229 struct sockopt {
230 int sopt_level; /* option level */
231 int sopt_name; /* option name */
232 size_t sopt_size; /* data length */
233 void * sopt_data; /* data pointer */
234 uint8_t sopt_buf[sizeof(int)]; /* internal storage */
235 };
236
237 extern u_long sb_max;
238 extern int somaxkva;
239 extern int sock_loan_thresh;
240 extern kmutex_t *softnet_lock;
241
242 struct mbuf;
243 struct sockaddr;
244 struct lwp;
245 struct msghdr;
246 struct stat;
247 struct knote;
248
249 struct mbuf *getsombuf(struct socket *, int);
250
251 /*
252 * File operations on sockets.
253 */
254 int soo_read(file_t *, off_t *, struct uio *, kauth_cred_t, int);
255 int soo_write(file_t *, off_t *, struct uio *, kauth_cred_t, int);
256 int soo_fcntl(file_t *, u_int cmd, void *);
257 int soo_ioctl(file_t *, u_long cmd, void *);
258 int soo_poll(file_t *, int);
259 int soo_kqfilter(file_t *, struct knote *);
260 int soo_close(file_t *);
261 int soo_stat(file_t *, struct stat *);
262 void soo_drain(file_t *);
263 void sbappend(struct sockbuf *, struct mbuf *);
264 void sbappendstream(struct sockbuf *, struct mbuf *);
265 int sbappendaddr(struct sockbuf *, const struct sockaddr *, struct mbuf *,
266 struct mbuf *);
267 int sbappendaddrchain(struct sockbuf *, const struct sockaddr *,
268 struct mbuf *, int);
269 int sbappendcontrol(struct sockbuf *, struct mbuf *, struct mbuf *);
270 void sbappendrecord(struct sockbuf *, struct mbuf *);
271 void sbcheck(struct sockbuf *);
272 void sbcompress(struct sockbuf *, struct mbuf *, struct mbuf *);
273 struct mbuf *
274 sbcreatecontrol(void *, int, int, int);
275 void sbdrop(struct sockbuf *, int);
276 void sbdroprecord(struct sockbuf *);
277 void sbflush(struct sockbuf *);
278 void sbinsertoob(struct sockbuf *, struct mbuf *);
279 void sbrelease(struct sockbuf *, struct socket *);
280 int sbreserve(struct sockbuf *, u_long, struct socket *);
281 int sbwait(struct sockbuf *);
282 int sb_max_set(u_long);
283 void soinit(void);
284 void soinit2(void);
285 int soabort(struct socket *);
286 int soaccept(struct socket *, struct mbuf *);
287 int sobind(struct socket *, struct mbuf *, struct lwp *);
288 void socantrcvmore(struct socket *);
289 void socantsendmore(struct socket *);
290 int soclose(struct socket *);
291 int soconnect(struct socket *, struct mbuf *, struct lwp *);
292 int soconnect2(struct socket *, struct socket *);
293 int socreate(int, struct socket **, int, int, struct lwp *,
294 struct socket *);
295 int fsocreate(int, struct socket **, int, int, struct lwp *, int *);
296 int sodisconnect(struct socket *);
297 void sofree(struct socket *);
298 int sogetopt(struct socket *, struct sockopt *);
299 void sohasoutofband(struct socket *);
300 void soisconnected(struct socket *);
301 void soisconnecting(struct socket *);
302 void soisdisconnected(struct socket *);
303 void soisdisconnecting(struct socket *);
304 int solisten(struct socket *, int, struct lwp *);
305 struct socket *
306 sonewconn(struct socket *, int);
307 void soqinsque(struct socket *, struct socket *, int);
308 int soqremque(struct socket *, int);
309 int soreceive(struct socket *, struct mbuf **, struct uio *,
310 struct mbuf **, struct mbuf **, int *);
311 int soreserve(struct socket *, u_long, u_long);
312 void sorflush(struct socket *);
313 int sosend(struct socket *, struct mbuf *, struct uio *,
314 struct mbuf *, struct mbuf *, int, struct lwp *);
315 int sosetopt(struct socket *, struct sockopt *);
316 int so_setsockopt(struct lwp *, struct socket *, int, int, const void *, size_t);
317 int soshutdown(struct socket *, int);
318 int sodrain(struct socket *);
319 void sowakeup(struct socket *, struct sockbuf *, int);
320 int sockargs(struct mbuf **, const void *, size_t, int);
321 int sopoll(struct socket *, int);
322 struct socket *soget(bool);
323 void soput(struct socket *);
324 bool solocked(struct socket *);
325 bool solocked2(struct socket *, struct socket *);
326 int sblock(struct sockbuf *, int);
327 void sbunlock(struct sockbuf *);
328 int sowait(struct socket *, bool, int);
329 void solockretry(struct socket *, kmutex_t *);
330 void sosetlock(struct socket *);
331 void solockreset(struct socket *, kmutex_t *);
332
333 void sockopt_init(struct sockopt *, int, int, size_t);
334 void sockopt_destroy(struct sockopt *);
335 int sockopt_set(struct sockopt *, const void *, size_t);
336 int sockopt_setint(struct sockopt *, int);
337 int sockopt_get(const struct sockopt *, void *, size_t);
338 int sockopt_getint(const struct sockopt *, int *);
339 int sockopt_setmbuf(struct sockopt *, struct mbuf *);
340 struct mbuf *sockopt_getmbuf(const struct sockopt *);
341
342 int copyout_sockname(struct sockaddr *, unsigned int *, int, struct mbuf *);
343 int copyout_msg_control(struct lwp *, struct msghdr *, struct mbuf *);
344 void free_control_mbuf(struct lwp *, struct mbuf *, struct mbuf *);
345
346 int do_sys_getsockname(struct lwp *, int, int, struct mbuf **);
347 int do_sys_sendmsg(struct lwp *, int, struct msghdr *, int, register_t *);
348 int do_sys_recvmsg(struct lwp *, int, struct msghdr *, struct mbuf **,
349 struct mbuf **, register_t *);
350
351 int do_sys_bind(struct lwp *, int, struct mbuf *);
352 int do_sys_connect(struct lwp *, int, struct mbuf *);
353 int do_sys_accept(struct lwp *, int, struct mbuf **, register_t *);
354
355 /*
356 * Inline functions for sockets and socket buffering.
357 */
358
359 #include <sys/protosw.h>
360 #include <sys/mbuf.h>
361
362 /*
363 * Do we need to notify the other side when I/O is possible?
364 */
365 static inline int
366 sb_notify(struct sockbuf *sb)
367 {
368
369 KASSERT(solocked(sb->sb_so));
370
371 return sb->sb_flags & (SB_NOTIFY | SB_ASYNC | SB_UPCALL | SB_KNOTE);
372 }
373
374 /*
375 * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
376 * This is problematical if the fields are unsigned, as the space might
377 * still be negative (cc > hiwat or mbcnt > mbmax). Should detect
378 * overflow and return 0.
379 */
380 static inline long
381 sbspace(struct sockbuf *sb)
382 {
383
384 KASSERT(solocked(sb->sb_so));
385
386 return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
387 }
388
389 /* do we have to send all at once on a socket? */
390 static inline int
391 sosendallatonce(struct socket *so)
392 {
393
394 return so->so_proto->pr_flags & PR_ATOMIC;
395 }
396
397 /* can we read something from so? */
398 static inline int
399 soreadable(struct socket *so)
400 {
401
402 KASSERT(solocked(so));
403
404 return so->so_rcv.sb_cc >= so->so_rcv.sb_lowat ||
405 (so->so_state & SS_CANTRCVMORE) != 0 ||
406 so->so_qlen != 0 || so->so_error != 0;
407 }
408
409 /* can we write something to so? */
410 static inline int
411 sowritable(struct socket *so)
412 {
413
414 KASSERT(solocked(so));
415
416 return (sbspace(&so->so_snd) >= so->so_snd.sb_lowat &&
417 ((so->so_state & SS_ISCONNECTED) != 0 ||
418 (so->so_proto->pr_flags & PR_CONNREQUIRED) == 0)) ||
419 (so->so_state & SS_CANTSENDMORE) != 0 ||
420 so->so_error != 0;
421 }
422
423 /* adjust counters in sb reflecting allocation of m */
424 static inline void
425 sballoc(struct sockbuf *sb, struct mbuf *m)
426 {
427
428 KASSERT(solocked(sb->sb_so));
429
430 sb->sb_cc += m->m_len;
431 sb->sb_mbcnt += MSIZE;
432 if (m->m_flags & M_EXT)
433 sb->sb_mbcnt += m->m_ext.ext_size;
434 }
435
436 /* adjust counters in sb reflecting freeing of m */
437 static inline void
438 sbfree(struct sockbuf *sb, struct mbuf *m)
439 {
440
441 KASSERT(solocked(sb->sb_so));
442
443 sb->sb_cc -= m->m_len;
444 sb->sb_mbcnt -= MSIZE;
445 if (m->m_flags & M_EXT)
446 sb->sb_mbcnt -= m->m_ext.ext_size;
447 }
448
449 static inline void
450 sorwakeup(struct socket *so)
451 {
452
453 KASSERT(solocked(so));
454
455 if (sb_notify(&so->so_rcv))
456 sowakeup(so, &so->so_rcv, POLL_IN);
457 }
458
459 static inline void
460 sowwakeup(struct socket *so)
461 {
462
463 KASSERT(solocked(so));
464
465 if (sb_notify(&so->so_snd))
466 sowakeup(so, &so->so_snd, POLL_OUT);
467 }
468
469 static inline void
470 solock(struct socket *so)
471 {
472 kmutex_t *lock;
473
474 lock = so->so_lock;
475 mutex_enter(lock);
476 if (__predict_false(lock != so->so_lock))
477 solockretry(so, lock);
478 }
479
480 static inline void
481 sounlock(struct socket *so)
482 {
483
484 mutex_exit(so->so_lock);
485 }
486
487 #ifdef SOCKBUF_DEBUG
488 /*
489 * SBLASTRECORDCHK: check sb->sb_lastrecord is maintained correctly.
490 * SBLASTMBUFCHK: check sb->sb_mbtail is maintained correctly.
491 *
492 * => panic if the socket buffer is inconsistent.
493 * => 'where' is used for a panic message.
494 */
495 void sblastrecordchk(struct sockbuf *, const char *);
496 #define SBLASTRECORDCHK(sb, where) sblastrecordchk((sb), (where))
497
498 void sblastmbufchk(struct sockbuf *, const char *);
499 #define SBLASTMBUFCHK(sb, where) sblastmbufchk((sb), (where))
500 #define SBCHECK(sb) sbcheck(sb)
501 #else
502 #define SBLASTRECORDCHK(sb, where) /* nothing */
503 #define SBLASTMBUFCHK(sb, where) /* nothing */
504 #define SBCHECK(sb) /* nothing */
505 #endif /* SOCKBUF_DEBUG */
506
507 /* sosend loan */
508 vaddr_t sokvaalloc(vsize_t, struct socket *);
509 void sokvafree(vaddr_t, vsize_t);
510 void soloanfree(struct mbuf *, void *, size_t, void *);
511
512 /*
513 * Values for socket-buffer-append priority argument to sbappendaddrchain().
514 * The following flags are reserved for future implementation:
515 *
516 * SB_PRIO_NONE: honour normal socket-buffer limits.
517 *
518 * SB_PRIO_ONESHOT_OVERFLOW: if the socket has any space,
519 * deliver the entire chain. Intended for large requests
520 * that should be delivered in their entirety, or not at all.
521 *
522 * SB_PRIO_OVERDRAFT: allow a small (2*MLEN) overflow, over and
523 * aboce normal socket limits. Intended messages indicating
524 * buffer overflow in earlier normal/lower-priority messages .
525 *
526 * SB_PRIO_BESTEFFORT: Ignore limits entirely. Intended only for
527 * kernel-generated messages to specially-marked scokets which
528 * require "reliable" delivery, nd where the source socket/protocol
529 * message generator enforce some hard limit (but possibly well
530 * above kern.sbmax). It is entirely up to the in-kernel source to
531 * avoid complete mbuf exhaustion or DoS scenarios.
532 */
533 #define SB_PRIO_NONE 0
534 #define SB_PRIO_ONESHOT_OVERFLOW 1
535 #define SB_PRIO_OVERDRAFT 2
536 #define SB_PRIO_BESTEFFORT 3
537
538 /*
539 * Accept filter functions (duh).
540 */
541 int accept_filt_getopt(struct socket *, struct sockopt *);
542 int accept_filt_setopt(struct socket *, const struct sockopt *);
543 int accept_filt_clear(struct socket *);
544 int accept_filt_add(struct accept_filter *);
545 int accept_filt_del(struct accept_filter *);
546 struct accept_filter *accept_filt_get(char *);
547 #ifdef ACCEPT_FILTER_MOD
548 #ifdef SYSCTL_DECL
549 SYSCTL_DECL(_net_inet_accf);
550 #endif
551 void accept_filter_init(void);
552 int accept_filt_generic_mod_event(struct lkm_table *lkmtp, int event, void *data);
553 #endif
554
555 #endif /* _KERNEL */
556
557 #endif /* !_SYS_SOCKETVAR_H_ */
Cache object: f0bf2fb621220cf34987999949203bcf
|