Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / libcfs / include / libcfs / winnt / winnt-tcpip.h
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=4:tabstop=4:
3  *
4  * Copyright (C) 2004 Cluster File Systems, Inc.
5  *
6  * This file is part of Lustre, http://www.lustre.org.
7  *
8  * Lustre is free software; you can redistribute it and/or modify it under the
9  * terms of version 2 of the GNU General Public License as published by the
10  * Free Software Foundation.
11  *
12  * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
19  * Ave, Cambridge, MA 02139, USA.
20  *
21  * Implementation of portable time API for Winnt (kernel and user-level).
22  *
23  */
24
25 #ifndef __LIBCFS_WINNT_TCPIP_H__
26 #define __LIBCFS_WINNT_TCPIP_H__
27
28 #ifndef __LIBCFS_LIBCFS_H__
29 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
30 #endif
31
32
33 #ifdef __KERNEL__
34
35 //
36 //  ks definitions
37 //
38
39 // iovec is defined in libcfs: winnt_prim.h 
40 // lnetkiov_t is defined in lnet/types.h
41
42 typedef struct socket ksock_tconn_t;
43 typedef struct socket cfs_socket_t;
44
45 // completion notification callback routine
46
47 typedef VOID (*ksock_schedule_cb)(struct socket*, int, void *, ulong_ptr);
48
49 /* completion routine to update tx structure for async sending */
50 typedef PVOID (*ksock_update_tx)(struct socket*, PVOID tx, ulong_ptr);
51
52 //
53 // tdinal definitions
54 //
55
56
57 #if TDI_LIBCFS_DBG
58 #define KsPrint(X)     KsPrintf X
59 #else
60 #define KsPrint(X)
61 #endif
62
63
64 //
65 // Socket Addresses Related ...
66 //
67
68 #define     INADDR_ANY              (ULONG)0x00000000
69 #define     INADDR_LOOPBACK     (ULONG)0x7f000001
70 #define     INADDR_BROADCAST    (ULONG)0xffffffff
71 #define     INADDR_NONE             (ULONG)0xffffffff
72
73 /*
74  *  TCP / IP options
75  */
76
77 #define     SOL_TCP             6
78 #define     SOL_UDP                     17
79
80
81 #define TL_INSTANCE             0
82
83 #define TCP_SOCKET_NODELAY      1 //  disabling "Nagle"
84 #define TCP_SOCKET_KEEPALIVE    2
85 #define TCP_SOCKET_OOBINLINE    3
86 #define TCP_SOCKET_BSDURGENT    4
87 #define TCP_SOCKET_ATMARK       5
88 #define TCP_SOCKET_WINDOW       6
89
90
91 /* Flags we can use with send/ and recv. 
92    Added those for 1003.1g not all are supported yet
93  */
94  
95 #define MSG_OOB             1
96 #define MSG_PEEK        2
97 #define MSG_DONTROUTE   4
98 #define MSG_TRYHARD     4       /* Synonym for MSG_DONTROUTE for DECnet */
99 #define MSG_CTRUNC      8
100 #define MSG_PROBE       0x10    /* Do not send. Only probe path f.e. for MTU */
101 #define MSG_TRUNC       0x20
102 #define MSG_DONTWAIT    0x40    /* Nonblocking io                */
103 #define MSG_EOR         0x80    /* End of record */
104 #define MSG_WAITALL     0x100   /* Wait for a full request */
105 #define MSG_FIN         0x200
106 #define MSG_SYN         0x400
107 #define MSG_CONFIRM     0x800   /* Confirm path validity */
108 #define MSG_RST         0x1000
109 #define MSG_ERRQUEUE    0x2000  /* Fetch message from error queue */
110 #define MSG_NOSIGNAL    0x4000  /* Do not generate SIGPIPE */
111 #define MSG_MORE        0x8000  /* Sender will send more */
112
113 #define MSG_EOF         MSG_FIN
114
115
116 //
117 // Maximum TRANSPORT_ADDRESS Length
118 //
119 // it must >= FIELD_OFFSET(TRANSPORT_ADDRESS, Address->Address)
120 //            + TDI_ADDRESS_LENGTH_IP
121 //
122 // I define it a little large and 16 bytes aligned to avoid possible overflow.
123 //
124
125 #define MAX_ADDRESS_LENGTH              (0x30)
126
127
128 //
129 // Maximum Listers Children Sockets
130 //
131
132 #define MAX_CHILD_LISTENERS             (4)
133
134 //
135 // Maximum EA Information Length
136 //
137
138 #define EA_MAX_LENGTH                   ( sizeof(FILE_FULL_EA_INFORMATION) - 1 + \
139                                           TDI_TRANSPORT_ADDRESS_LENGTH + 1 + \
140                                           MAX_ADDRESS_LENGTH )
141
142
143 #define UDP_DEVICE_NAME L"\\Device\\Udp"
144 #define TCP_DEVICE_NAME L"\\Device\\Tcp"
145
146
147 /*
148  * TSDU definitions
149  */
150
151 #define TDINAL_TSDU_DEFAULT_SIZE  (0x10000)
152
153 #define KS_TSDU_MAGIC       'KSTD'
154
155 #define KS_TSDU_ATTACHED    0x00000001  // Attached to the socket receive tsdu list
156
157 typedef struct _KS_TSDU {
158
159     ULONG               Magic;
160     ULONG               Flags;
161
162     struct list_head    Link;
163
164     ULONG               TotalLength;    // Total size of KS_TSDU
165
166     ULONG               StartOffset;    // Start offset of the first Tsdu unit
167     ULONG               LastOffset;     // End offset of the last Tsdu unit
168
169 /*
170     union {
171         KS_TSDU_DAT[];
172         KS_TSDU_BUF[];
173         KS_TSDU_MDL[];
174     }
175 */
176
177 } KS_TSDU, *PKS_TSDU;
178
179 #define TSDU_TYPE_BUF   ((USHORT)0x5401)
180 #define TSDU_TYPE_DAT   ((USHORT)0x5402)
181 #define TSDU_TYPE_MDL   ((USHORT)0x5403)
182
183 #define KS_TSDU_BUF_RECEIVING       0x0001
184 typedef struct _KS_TSDU_BUF {
185
186     USHORT              TsduType;
187     USHORT              TsduFlags;
188
189     ULONG               DataLength;
190     ULONG               StartOffset;
191
192     PVOID               UserBuffer;
193
194 } KS_TSDU_BUF, *PKS_TSDU_BUF;
195
196 #define KS_TSDU_DAT_RECEIVING       0x0001
197
198 typedef struct _KS_TSDU_DAT {
199
200     USHORT              TsduType;
201     USHORT              TsduFlags;
202
203     ULONG               DataLength;
204     ULONG               StartOffset;
205
206     ULONG               TotalLength;
207
208     UCHAR               Data[1];
209
210 } KS_TSDU_DAT, *PKS_TSDU_DAT;
211
212 #define KS_DWORD_ALIGN(x)      (((x) + 0x03) & (~(0x03)))
213 #define KS_TSDU_STRU_SIZE(Len) (KS_DWORD_ALIGN((Len) + FIELD_OFFSET(KS_TSDU_DAT, Data)))
214
215 typedef struct _KS_TSDU_MDL {
216
217     USHORT              TsduType;
218     USHORT              TsduFlags;
219
220     ULONG               DataLength;
221     ULONG               StartOffset;    
222
223     PMDL                Mdl;
224     PVOID               Descriptor;
225
226 } KS_TSDU_MDL, *PKS_TSDU_MDL;
227
228
229 typedef struct _KS_TSDUMGR {
230
231     struct list_head    TsduList;
232     ULONG               NumOfTsdu;
233     ULONG               TotalBytes;
234     KEVENT              Event;
235
236 } KS_TSDUMGR, *PKS_TSDUMGR;
237
238
239 typedef struct _KS_CHAIN {
240
241     KS_TSDUMGR          Normal;
242     KS_TSDUMGR          Expedited;
243
244 } KS_CHAIN, *PKS_CHAIN;
245
246
247 #define TDINAL_SCHED_FACTOR (1)
248 #define CAN_BE_SCHED(Len, Limit) (Len >= ((Limit) >> TDINAL_SCHED_FACTOR))
249
250 //
251 // Handler Settings Indictor 
252 //
253
254 #define TDI_EVENT_MAXIMUM_HANDLER (TDI_EVENT_ERROR_EX + 1)
255
256
257 typedef struct _KS_EVENT_HANDLERS {
258     BOOLEAN     IsActive[TDI_EVENT_MAXIMUM_HANDLER];
259     PVOID       Handler [TDI_EVENT_MAXIMUM_HANDLER];
260 } KS_EVENT_HANDLERS, *PKS_EVENT_HANDLERS;
261
262 #define SetEventHandler(ha, ht, hr) do {        \
263             ha.IsActive[ht] = TRUE;             \
264             ha.Handler[ht] = (PVOID) (hr);      \
265         } while(0)
266
267 //
268 // KSock Internal Structures
269 //
270
271 typedef struct _KS_ADDRESS {
272
273     union {
274         TRANSPORT_ADDRESS   Tdi;
275         UCHAR               Pading[MAX_ADDRESS_LENGTH];
276     };
277
278     HANDLE                  Handle;
279     PFILE_OBJECT            FileObject;
280
281 } KS_ADDRESS, *PKS_ADDRESS;
282
283 //
284 // Structures for Disconnect Workitem
285 //
286
287 typedef struct _KS_DISCONNECT_WORKITEM {
288
289     WORK_QUEUE_ITEM         WorkItem;       // Workitem to perform disconnection
290     ksock_tconn_t *         tconn;          // tdi connecton
291     ULONG                   Flags;          // connection broken/discnnection flags
292     KEVENT                  Event;          // sync event
293
294 } KS_DISCONNECT_WORKITEM, *PKS_DISCONNECT_WORKITEM;
295
296
297 typedef struct _KS_CONNECTION {
298
299     HANDLE                      Handle;     // Handle of the tdi connection
300     PFILE_OBJECT                FileObject; // FileObject if the conn object
301
302     PTRANSPORT_ADDRESS          Remote;     // the ConnectionInfo of this connection
303     PTDI_CONNECTION_INFORMATION ConnectionInfo;
304
305     ULONG                       nagle;      // Tcp options 
306
307 } KS_CONNECTION, *PKS_CONNECTION;
308
309
310 //
311 // type definitions
312 //
313
314 typedef MDL                         ksock_mdl_t;
315 typedef UNICODE_STRING              ksock_unicode_name_t;
316 typedef WORK_QUEUE_ITEM             ksock_workitem_t;
317
318
319 typedef KS_CHAIN                    ksock_chain_t;
320 typedef KS_ADDRESS                  ksock_tdi_addr_t;
321 typedef KS_CONNECTION               ksock_tconn_info_t;
322 typedef KS_DISCONNECT_WORKITEM      ksock_disconnect_workitem_t;
323
324
325 //
326 // Structures for transmission done Workitem
327 //
328
329 typedef struct _KS_TCPX_FINILIZE {
330     ksock_workitem_t        item;
331     void *                  tx;
332 } ksock_tcpx_fini_t;
333
334
335 typedef struct ksock_backlogs {
336
337         struct list_head    list;   /* list to link the backlog connections */
338         int                 num;    /* number of backlogs in the list */
339
340 } ksock_backlogs_t;
341
342
343 typedef struct ksock_daemon {
344
345     ksock_tconn_t *         tconn;         /* the listener connection object */
346     unsigned short          nbacklogs;     /* number of listening backlog conns */
347     unsigned short          port;          /* listening port number */ 
348     int                     shutdown;      /* daemon threads is to exit */
349     struct list_head        list;          /* to be attached into ksock_nal_data_t*/
350
351 } ksock_daemon_t ;
352
353
354 typedef enum {
355
356     kstt_sender = 0,    // normal sending connection type, it's active connection, while
357                         // child tconn is for passive connection.
358
359     kstt_listener,      // listener daemon type, it just acts as a daemon, and it does
360                         // not have real connection. It manages children tcons to accept
361                         // or refuse the connecting request from remote peers.
362
363     kstt_child,         // accepted child connection type, it's parent must be Listener
364     kstt_lasttype
365 } ksock_tconn_type;
366
367 typedef enum {
368
369     ksts_uninited = 0,  // tconn is just allocated (zero values), not initialized yet
370
371     ksts_inited,        // tconn structure initialized: so it now can be identified as
372                         // a sender, listener or a child
373
374     ksts_bind,          // tconn is bound: the local address object (ip/port) is created.
375                         // after being bound, we must call ksocknal_put_tconn to release
376                         // the tconn objects, it's not safe just to free the memory of tconn.
377
378     ksts_associated,    // the connection object is created and associated with the address
379                         // object. so it's ready for connection. only for child and sender.
380
381     ksts_connecting,    // only used by child tconn: in the ConnectEvent handler routine,
382                         // it indicts the child tconn is busy to be connected to the peer.
383
384     ksts_connected,     // the connection is built already: for sender and child
385
386     ksts_listening,     // listener daemon is working, only for listener tconn
387
388     ksts_disconnected,  // disconnected by user
389     ksts_aborted,       // un-exptected broken status
390
391     ksts_last           // total number of tconn statuses
392 } ksock_tconn_state;
393
394 #define KS_TCONN_MAGIC              'KSTM'
395
396 #define KS_TCONN_HANDLERS_SET       0x00000001  // Conection handlers are set.
397 #define KS_TCONN_DISCONNECT_BUSY    0x00010000  // Disconnect Workitem is queued ...
398 #define KS_TCONN_DESTROY_BUSY       0x00020000  // Destory Workitem is queued ...
399
400 #define KS_TCONN_DAEMON_STARTED     0x00100000  // indict the daemon is started,
401                                                 // only valid for listener
402
403 struct socket {
404
405         ulong_ptr                   kstc_magic;      /* Magic & Flags */
406         ulong_ptr                   kstc_flags;
407
408         spinlock_t                  kstc_lock;       /* serialise lock*/
409         void *                      kstc_conn;       /* ksock_conn_t */
410
411         ksock_tconn_type            kstc_type;           /* tdi connection Type */
412         ksock_tconn_state           kstc_state;      /* tdi connection state flag */
413
414         ksock_unicode_name_t        kstc_dev;        /* tcp transport device name */
415
416         ksock_tdi_addr_t            kstc_addr;       /* local address handlers / Objects */
417
418         atomic_t                    kstc_refcount;   /* reference count of ksock_tconn */
419
420         struct list_head            kstc_list;       /* linked to global ksocknal_data */
421
422         union {
423
424             struct {
425                 int                 nbacklog;         /* total number of backlog tdi connections */
426                 ksock_backlogs_t    kstc_listening;   /* listeing backlog child connections */
427                 ksock_backlogs_t    kstc_accepted;    /* connected backlog child connections */
428                 event_t             kstc_accept_event;   /* Signaled by AcceptedHander, 
429                                                             ksocknal_wait_accpeted_conns waits on */
430                 event_t             kstc_destroy_event;  /* Signaled when accepted child is released */
431             } listener; 
432
433             struct  {
434                 ksock_tconn_info_t  kstc_info;      /* Connection Info if Connected */
435                 ksock_chain_t       kstc_recv;      /* tsdu engine for data receiving */
436                 ksock_chain_t       kstc_send;      /* tsdu engine for data sending */
437
438                 int                 kstc_queued;    /* Attached to Parent->ChildList ... */
439                 int                 kstc_queueno;   /* 0: Attached to Listening list 
440                                                        1: Attached to Accepted list */
441
442                 int                 kstc_busy;      /* referred by ConnectEventCallback ? */
443                 int                 kstc_accepted;  /* the connection is built ready ? */
444
445                 struct list_head    kstc_link;      /* linked to parent tdi connection */
446                 ksock_tconn_t   *   kstc_parent;    /* pointers to it's listener parent */
447             } child;
448
449             struct {
450                 ksock_tconn_info_t  kstc_info;      /* Connection Info if Connected */
451                 ksock_chain_t       kstc_recv;      /* tsdu engine for data receiving */
452                 ksock_chain_t       kstc_send;      /* tsdu engine for data sending */
453             } sender; 
454         };
455
456         ulong_ptr                   kstc_snd_wnd;   /* Sending window size */
457         ulong_ptr                   kstc_rcv_wnd;   /* Recving window size */
458
459         ksock_workitem_t            kstc_destroy;    /* tconn destruction workitem */
460         ksock_disconnect_workitem_t kstc_disconnect; /* connection disconnect workitem */
461
462         ksock_schedule_cb           kstc_sched_cb;   /* notification callback routine of completion */
463         ksock_update_tx             kstc_update_tx;  /* aync sending callback to update tx */
464 };
465
466 #define SOCK_WMEM_QUEUED(sock) (0)
467
468 #define TDINAL_WINDOW_DEFAULT_SIZE  (0x100000)
469
470
471 struct _KS_UDP_COMPLETION_CONTEXT;
472 struct _KS_TCP_COMPLETION_CONTEXT;
473
474
475 typedef
476 NTSTATUS
477 (*PKS_UDP_COMPLETION_ROUTINE) (
478     IN PIRP     Irp,
479     IN struct _KS_UDP_COMPLETION_CONTEXT
480                 *UdpContext
481     );
482
483
484 typedef
485 NTSTATUS
486 (*PKS_TCP_COMPLETION_ROUTINE) (
487     IN PIRP     Irp,
488     IN struct _KS_TCP_COMPLETION_CONTEXT
489                 *TcpContext
490     );
491
492 //
493 // Udp Irp Completion Context
494 //
495
496 typedef struct _KS_UDP_COMPLETION_CONTEXT {
497
498     PKEVENT                             Event;
499     union {
500         PFILE_OBJECT                    AddressObject;
501         ksock_tconn_t *                 tconn;
502     };
503
504     PKS_UDP_COMPLETION_ROUTINE          CompletionRoutine;
505     PVOID                               CompletionContext;
506
507 } KS_UDP_COMPLETION_CONTEXT, *PKS_UDP_COMPLETION_CONTEXT;
508
509
510 //
511 // Tcp Irp Completion Context (used by tcp data recv/send)
512 //
513
514 typedef struct _KS_TCP_COMPLETION_CONTEXT {
515
516     PKEVENT                             Event;      // Event to be waited on by Irp caller ...
517
518     ksock_tconn_t *                     tconn;      // the tdi connection
519
520     PKS_TCP_COMPLETION_ROUTINE          CompletionRoutine;
521     PVOID                               CompletionContext;
522     PVOID                               CompletionContext2;
523
524     PKS_TSDUMGR                         KsTsduMgr;  // Tsdu buffer manager
525
526     //
527     // These tow new members are for NON_BLOCKING transmission
528     //
529
530     BOOLEAN                                                         bCounted;    // To indict needing refcount to
531                                                      // execute CompetionRoutine
532     ULONG                               ReferCount;  // Refer count of this structure
533
534 } KS_TCP_COMPLETION_CONTEXT, *PKS_TCP_COMPLETION_CONTEXT;
535
536 typedef KS_TCP_COMPLETION_CONTEXT  ksock_tdi_tx_t, ksock_tdi_rx_t;
537
538
539 /*
540  * tdi extensions
541  */
542
543 #define IOCTL_TCP_QUERY_INFORMATION_EX        \
544                         CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS)
545 #define IOCTL_TCP_SET_INFORMATION_EX        \
546                         CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
547
548
549 #define TcpBuildSetInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, Buffer, BufferLen)\
550     {                                                                        \
551         PIO_STACK_LOCATION _IRPSP;                                           \
552         if ( CompRoutine != NULL) {                                          \
553             IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\
554         } else {                                                             \
555             IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE);   \
556         }                                                                    \
557         _IRPSP = IoGetNextIrpStackLocation (Irp);                            \
558         _IRPSP->MajorFunction = IRP_MJ_DEVICE_CONTROL;                       \
559         _IRPSP->DeviceObject = DevObj;                                       \
560         _IRPSP->FileObject = FileObj;                                        \
561         _IRPSP->Parameters.DeviceIoControl.OutputBufferLength = 0;           \
562         _IRPSP->Parameters.DeviceIoControl.InputBufferLength = BufferLen;    \
563         _IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_TCP_SET_INFORMATION_EX;  \
564         Irp->AssociatedIrp.SystemBuffer = Buffer;                            \
565     }
566
567
568 #define TcpBuildQueryInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, InBuffer, InLength, OutBuffer, OutLength)\
569     {                                                                        \
570         PIO_STACK_LOCATION _IRPSP;                                           \
571         if ( CompRoutine != NULL) {                                          \
572             IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\
573         } else {                                                             \
574             IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE);   \
575         }                                                                    \
576         _IRPSP = IoGetNextIrpStackLocation (Irp);                            \
577         _IRPSP->MajorFunction = IRP_MJ_DEVICE_CONTROL;                       \
578         _IRPSP->DeviceObject = DevObj;                                       \
579         _IRPSP->FileObject = FileObj;                                        \
580         _IRPSP->Parameters.DeviceIoControl.OutputBufferLength = OutLength;           \
581         _IRPSP->Parameters.DeviceIoControl.InputBufferLength = InLength;    \
582         _IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_TCP_QUERY_INFORMATION_EX;  \
583         _IRPSP->Parameters.DeviceIoControl.Type3InputBuffer = InBuffer;    \
584         Irp->UserBuffer = OutBuffer;                            \
585     }
586
587
588 typedef struct ks_addr_slot {
589     LIST_ENTRY      link;
590     int             up;
591     char            iface[40];
592     __u32           ip_addr;
593     __u32           netmask;
594     UNICODE_STRING  devname;
595     WCHAR           buffer[1];
596 } ks_addr_slot_t;
597
598 typedef struct {
599
600     /*
601      * Tdi client information
602      */
603
604     UNICODE_STRING    ksnd_client_name; /* tdi client module name */
605     HANDLE            ksnd_pnp_handle;  /* the handle for pnp changes */
606
607     spinlock_t        ksnd_addrs_lock;  /* serialize ip address list access */
608     LIST_ENTRY        ksnd_addrs_list;  /* list of the ip addresses */
609     int               ksnd_naddrs;      /* number of the ip addresses */
610
611     /*
612      *  Tdilnd internal defintions
613      */
614
615     int               ksnd_init;            /* initialisation state */
616
617     TDI_PROVIDER_INFO ksnd_provider;    /* tdi tcp/ip provider's information */
618
619     spinlock_t        ksnd_tconn_lock;      /* tdi connections access serialise */
620
621     int               ksnd_ntconns;         /* number of tconns attached in list */
622     struct list_head  ksnd_tconns;          /* tdi connections list */
623     cfs_mem_cache_t * ksnd_tconn_slab;      /* slabs for ksock_tconn_t allocations */
624     event_t           ksnd_tconn_exit;      /* exit event to be signaled by the last tconn */
625
626     spinlock_t        ksnd_tsdu_lock;       /* tsdu access serialise */
627         
628     int               ksnd_ntsdus;          /* number of tsdu buffers allocated */
629     ulong_ptr     ksnd_tsdu_size;       /* the size of a signel tsdu buffer */
630     cfs_mem_cache_t * ksnd_tsdu_slab;       /* slab cache for tsdu buffer allocation */
631
632     int               ksnd_nfreetsdus;      /* number of tsdu buffers in the freed list */
633     struct list_head  ksnd_freetsdus;          /* List of the freed Tsdu buffer. */
634
635     spinlock_t        ksnd_daemon_lock;     /* stabilize daemon ops */
636     int               ksnd_ndaemons;        /* number of listening daemons */
637     struct list_head  ksnd_daemons;         /* listening daemon list */
638     event_t           ksnd_daemon_exit;     /* the last daemon quiting should singal it */
639
640 } ks_data_t;
641
642 int
643 ks_init_tdi_data();
644
645 void
646 ks_fini_tdi_data();
647
648
649 #endif /* __KERNEL__ */
650 #endif /* __LIBCFS_WINNT_TCPIP_H__ */
651
652 /*
653  * Local variables:
654  * c-indentation-style: "K&R"
655  * c-basic-offset: 8
656  * tab-width: 8
657  * fill-column: 80
658  * scroll-step: 1
659  * End:
660  */