add loopback medium, tweak spatch files.
[akaros.git] / kern / src / net / loopbackmedium.c
1 // INFERNO
2 #include <vfs.h>
3 #include <kfs.h>
4 #include <slab.h>
5 #include <kmalloc.h>
6 #include <kref.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <assert.h>
10 #include <error.h>
11 #include <cpio.h>
12 #include <pmap.h>
13 #include <smp.h>
14 #include <ip.h>
15
16 enum
17 {
18         Maxtu=  16*1024,
19 };
20
21 typedef struct LB LB;
22 struct LB
23 {
24         struct proc     *readp;
25         struct queue    *q;
26         struct Fs       *f;
27 };
28
29 static void loopbackread(void *a);
30
31 static void
32 loopbackbind(struct Ipifc *ifc, int unused_int, char **unused_char_pp_t)
33 {
34         LB *lb;
35
36         lb = kzmalloc(sizeof(*lb), 0);
37         lb->f = ifc->conv->p->f;
38         /* TO DO: make queue size a function of kernel memory */
39         lb->q = qopen(128*1024, Qmsg, NULL, NULL);
40         ifc->arg = lb;
41         ifc->mbps = 1000;
42
43         kproc("loopbackread", loopbackread, ifc, 0);
44
45 }
46
47 static void
48 loopbackunbind(struct Ipifc *ifc)
49 {
50         LB *lb = ifc->arg;
51
52         /*if(lb->readp)
53           postnote(lb->readp, 1, "unbind", 0);
54         */
55
56         /* wait for reader to die */
57 #warning "how to sleep 5 minutes"
58 //      while(lb->readp != 0)
59 //              tsleep(&current->sleep, return0, 0, 300);
60
61         /* clean up */
62         qfree(lb->q);
63         kfree(lb);
64 }
65
66 static void
67 loopbackbwrite(struct Ipifc *ifc, struct block *bp, int unused_int, uint8_t *unused_uint8_p_t)
68 {
69         LB *lb;
70
71         lb = ifc->arg;
72         if(qpass(lb->q, bp) < 0)
73                 ifc->outerr++;
74         ifc->out++;
75 }
76
77 static void
78 loopbackread(void *a)
79 {
80         ERRSTACK(2);
81         struct Ipifc *ifc;
82         struct block *bp;
83         LB *lb;
84
85         ifc = a;
86         lb = ifc->arg;
87         lb->readp = current;    /* hide identity under a rock for unbind */
88         if(waserror()){
89                 lb->readp = 0;
90                 /* kill the proc. */
91 #warning "pexit"
92 //              pexit("hangup", 1);
93         }
94         for(;;){
95                 bp = qbread(lb->q, Maxtu);
96                 if(bp == NULL)
97                         continue;
98                 ifc->in++;
99                 if(!canrlock(&ifc->rwlock)){
100                         freeb(bp);
101                         continue;
102                 }
103                 if(waserror()){
104                         runlock(&ifc->rwlock);
105                         nexterror();
106                 }
107                 if(ifc->lifc == NULL)
108                         freeb(bp);
109                 else
110                         ipiput4(lb->f, ifc, bp);
111                 runlock(&ifc->rwlock);
112                 poperror();
113         }
114 }
115
116 struct medium loopbackmedium =
117 {
118 .hsize=         0,
119 .mintu=         0,
120 .maxtu=         Maxtu,
121 .maclen=        0,
122 .name=          "loopback",
123 .bind=          loopbackbind,
124 .unbind=        loopbackunbind,
125 .bwrite=        loopbackbwrite,
126 };
127
128 void
129 loopbackmediumlink(void)
130 {
131         addipmedium(&loopbackmedium);
132 }