]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/ip/loopbackmedium.c
devip: fix router adv/sol options validation (options padded to 8 bytes)
[plan9front.git] / sys / src / 9 / ip / loopbackmedium.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7
8 #include "ip.h"
9
10 enum
11 {
12         Maxtu=  16*1024,
13 };
14
15 typedef struct LB LB;
16 struct LB
17 {
18         Proc    *readp;
19         Queue   *q;
20         Fs      *f;
21 };
22
23 static void loopbackread(void *a);
24
25 static void
26 loopbackbind(Ipifc *ifc, int, char**)
27 {
28         LB *lb;
29
30         lb = smalloc(sizeof(*lb));
31         lb->f = ifc->conv->p->f;
32         lb->q = qopen(1024*1024, Qmsg, nil, nil);
33         ifc->arg = lb;
34
35         kproc("loopbackread", loopbackread, ifc);
36
37 }
38
39 static void
40 loopbackunbind(Ipifc *ifc)
41 {
42         LB *lb = ifc->arg;
43
44         if(lb->readp)
45                 postnote(lb->readp, 1, "unbind", 0);
46
47         /* wait for reader to die */
48         while(lb->readp != 0)
49                 tsleep(&up->sleep, return0, 0, 300);
50
51         /* clean up */
52         qfree(lb->q);
53         free(lb);
54 }
55
56 static void
57 loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*)
58 {
59         LB *lb;
60
61         lb = ifc->arg;
62         if(qpass(lb->q, bp) < 0)
63                 ifc->outerr++;
64         ifc->out++;
65 }
66
67 static void
68 loopbackread(void *a)
69 {
70         Ipifc *ifc;
71         Block *bp;
72         LB *lb;
73
74         ifc = a;
75         lb = ifc->arg;
76         lb->readp = up; /* hide identity under a rock for unbind */
77         if(waserror()){
78                 lb->readp = nil;
79                 pexit("hangup", 1);
80         }
81         for(;;){
82                 bp = qbread(lb->q, Maxtu);
83                 if(bp == nil)
84                         continue;
85                 if(!canrlock(ifc)){
86                         freeb(bp);
87                         continue;
88                 }
89                 if(waserror()){
90                         runlock(ifc);
91                         nexterror();
92                 }
93                 ifc->in++;
94                 if(ifc->lifc == nil)
95                         freeb(bp);
96                 else
97                         ipiput4(lb->f, ifc, bp);
98                 runlock(ifc);
99                 poperror();
100         }
101 }
102
103 Medium loopbackmedium =
104 {
105 .hsize=         0,
106 .mintu=         0,
107 .maxtu=         Maxtu,
108 .maclen=        0,
109 .name=          "loopback",
110 .bind=          loopbackbind,
111 .unbind=        loopbackunbind,
112 .bwrite=        loopbackbwrite,
113 };
114
115 void
116 loopbackmediumlink(void)
117 {
118         addipmedium(&loopbackmedium);
119 }