180ee5cbfSDavid du Colombier #include "u.h"
280ee5cbfSDavid du Colombier #include "../port/lib.h"
380ee5cbfSDavid du Colombier #include "mem.h"
480ee5cbfSDavid du Colombier #include "dat.h"
580ee5cbfSDavid du Colombier #include "fns.h"
680ee5cbfSDavid du Colombier #include "../port/error.h"
780ee5cbfSDavid du Colombier
880ee5cbfSDavid du Colombier #include "ip.h"
980ee5cbfSDavid du Colombier
1080ee5cbfSDavid du Colombier enum
1180ee5cbfSDavid du Colombier {
1280ee5cbfSDavid du Colombier Maxtu= 16*1024,
1380ee5cbfSDavid du Colombier };
1480ee5cbfSDavid du Colombier
1580ee5cbfSDavid du Colombier typedef struct LB LB;
1680ee5cbfSDavid du Colombier struct LB
1780ee5cbfSDavid du Colombier {
1880ee5cbfSDavid du Colombier Proc *readp;
1980ee5cbfSDavid du Colombier Queue *q;
2080ee5cbfSDavid du Colombier Fs *f;
2180ee5cbfSDavid du Colombier };
2280ee5cbfSDavid du Colombier
2380ee5cbfSDavid du Colombier static void loopbackread(void *a);
2480ee5cbfSDavid du Colombier
2580ee5cbfSDavid du Colombier static void
loopbackbind(Ipifc * ifc,int,char **)2680ee5cbfSDavid du Colombier loopbackbind(Ipifc *ifc, int, char**)
2780ee5cbfSDavid du Colombier {
2880ee5cbfSDavid du Colombier LB *lb;
2980ee5cbfSDavid du Colombier
3080ee5cbfSDavid du Colombier lb = smalloc(sizeof(*lb));
3180ee5cbfSDavid du Colombier lb->f = ifc->conv->p->f;
32*dc5a79c1SDavid du Colombier lb->q = qopen(1024*1024, Qmsg, nil, nil);
3380ee5cbfSDavid du Colombier ifc->arg = lb;
34*dc5a79c1SDavid du Colombier ifc->mbps = 1000;
3580ee5cbfSDavid du Colombier
3680ee5cbfSDavid du Colombier kproc("loopbackread", loopbackread, ifc);
3780ee5cbfSDavid du Colombier
3880ee5cbfSDavid du Colombier }
3980ee5cbfSDavid du Colombier
4080ee5cbfSDavid du Colombier static void
loopbackunbind(Ipifc * ifc)4180ee5cbfSDavid du Colombier loopbackunbind(Ipifc *ifc)
4280ee5cbfSDavid du Colombier {
4380ee5cbfSDavid du Colombier LB *lb = ifc->arg;
4480ee5cbfSDavid du Colombier
4580ee5cbfSDavid du Colombier if(lb->readp)
4680ee5cbfSDavid du Colombier postnote(lb->readp, 1, "unbind", 0);
4780ee5cbfSDavid du Colombier
4880ee5cbfSDavid du Colombier /* wait for reader to die */
4980ee5cbfSDavid du Colombier while(lb->readp != 0)
5080ee5cbfSDavid du Colombier tsleep(&up->sleep, return0, 0, 300);
5180ee5cbfSDavid du Colombier
5280ee5cbfSDavid du Colombier /* clean up */
5380ee5cbfSDavid du Colombier qfree(lb->q);
5480ee5cbfSDavid du Colombier free(lb);
5580ee5cbfSDavid du Colombier }
5680ee5cbfSDavid du Colombier
5780ee5cbfSDavid du Colombier static void
loopbackbwrite(Ipifc * ifc,Block * bp,int,uchar *)5880ee5cbfSDavid du Colombier loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*)
5980ee5cbfSDavid du Colombier {
6080ee5cbfSDavid du Colombier LB *lb;
6180ee5cbfSDavid du Colombier
6280ee5cbfSDavid du Colombier lb = ifc->arg;
6380ee5cbfSDavid du Colombier if(qpass(lb->q, bp) < 0)
6480ee5cbfSDavid du Colombier ifc->outerr++;
6580ee5cbfSDavid du Colombier ifc->out++;
6680ee5cbfSDavid du Colombier }
6780ee5cbfSDavid du Colombier
6880ee5cbfSDavid du Colombier static void
loopbackread(void * a)6980ee5cbfSDavid du Colombier loopbackread(void *a)
7080ee5cbfSDavid du Colombier {
7180ee5cbfSDavid du Colombier Ipifc *ifc;
7280ee5cbfSDavid du Colombier Block *bp;
7380ee5cbfSDavid du Colombier LB *lb;
7480ee5cbfSDavid du Colombier
7580ee5cbfSDavid du Colombier ifc = a;
7680ee5cbfSDavid du Colombier lb = ifc->arg;
7780ee5cbfSDavid du Colombier lb->readp = up; /* hide identity under a rock for unbind */
7880ee5cbfSDavid du Colombier if(waserror()){
7980ee5cbfSDavid du Colombier lb->readp = 0;
8080ee5cbfSDavid du Colombier pexit("hangup", 1);
8180ee5cbfSDavid du Colombier }
8280ee5cbfSDavid du Colombier for(;;){
8380ee5cbfSDavid du Colombier bp = qbread(lb->q, Maxtu);
8480ee5cbfSDavid du Colombier if(bp == nil)
8580ee5cbfSDavid du Colombier continue;
8680ee5cbfSDavid du Colombier ifc->in++;
8780ee5cbfSDavid du Colombier if(!canrlock(ifc)){
8880ee5cbfSDavid du Colombier freeb(bp);
8980ee5cbfSDavid du Colombier continue;
9080ee5cbfSDavid du Colombier }
9180ee5cbfSDavid du Colombier if(waserror()){
9280ee5cbfSDavid du Colombier runlock(ifc);
9380ee5cbfSDavid du Colombier nexterror();
9480ee5cbfSDavid du Colombier }
9580ee5cbfSDavid du Colombier if(ifc->lifc == nil)
9680ee5cbfSDavid du Colombier freeb(bp);
9780ee5cbfSDavid du Colombier else
983ff48bf5SDavid du Colombier ipiput4(lb->f, ifc, bp);
9980ee5cbfSDavid du Colombier runlock(ifc);
10080ee5cbfSDavid du Colombier poperror();
10180ee5cbfSDavid du Colombier }
10280ee5cbfSDavid du Colombier }
10380ee5cbfSDavid du Colombier
10480ee5cbfSDavid du Colombier Medium loopbackmedium =
10580ee5cbfSDavid du Colombier {
10680ee5cbfSDavid du Colombier .hsize= 0,
1073f695129SDavid du Colombier .mintu= 0,
1083f695129SDavid du Colombier .maxtu= Maxtu,
10980ee5cbfSDavid du Colombier .maclen= 0,
11080ee5cbfSDavid du Colombier .name= "loopback",
11180ee5cbfSDavid du Colombier .bind= loopbackbind,
11280ee5cbfSDavid du Colombier .unbind= loopbackunbind,
11380ee5cbfSDavid du Colombier .bwrite= loopbackbwrite,
11480ee5cbfSDavid du Colombier };
11580ee5cbfSDavid du Colombier
11680ee5cbfSDavid du Colombier void
loopbackmediumlink(void)11780ee5cbfSDavid du Colombier loopbackmediumlink(void)
11880ee5cbfSDavid du Colombier {
11980ee5cbfSDavid du Colombier addipmedium(&loopbackmedium);
12080ee5cbfSDavid du Colombier }
121