changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/9/ip/ip.h

changeset 7233: 24d21d7c0868
parent: a0387db0dcba
child: 88a2f67638e2
author: cinap_lenrek@felloff.net
date: Sun, 12 May 2019 01:20:21 +0200
permissions: -rw-r--r--
description: devip: do not lock selftab in ipselftabread(), remove unused fields from Ipself

the Ipselftab is designed to not require locking on read
operation. locking the selftab in ipselftabread() risks
deadlock when accessing the user buffer creates a fault.

remove unused fields from the Ipself struct.
1 typedef struct Conv Conv;
2 typedef struct Fragment4 Fragment4;
3 typedef struct Fragment6 Fragment6;
4 typedef struct Fs Fs;
5 typedef union Hwaddr Hwaddr;
6 typedef struct IP IP;
7 typedef struct IPaux IPaux;
8 typedef struct Ip4hdr Ip4hdr;
9 typedef struct Ipfrag Ipfrag;
10 typedef struct Ipself Ipself;
11 typedef struct Ipselftab Ipselftab;
12 typedef struct Iplink Iplink;
13 typedef struct Iplifc Iplifc;
14 typedef struct Ipmulti Ipmulti;
15 typedef struct Ipifc Ipifc;
16 typedef struct Iphash Iphash;
17 typedef struct Ipht Ipht;
18 typedef struct Netlog Netlog;
19 typedef struct Medium Medium;
20 typedef struct Proto Proto;
21 typedef struct Arpent Arpent;
22 typedef struct Arp Arp;
23 typedef struct Route Route;
24 typedef struct Routehint Routehint;
25 
26 typedef struct Routerparams Routerparams;
27 typedef struct Hostparams Hostparams;
28 typedef struct v6params v6params;
29 
30 #pragma incomplete Arp
31 #pragma incomplete Ipself
32 #pragma incomplete Ipselftab
33 #pragma incomplete IP
34 #pragma incomplete Netlog
35 
36 enum
37 {
38  Addrlen= 64,
39  Maxproto= 20,
40  Maxincall= 10,
41  Nchans= 1024,
42  MAClen= 8, /* longest mac address */
43 
44  MAXTTL= 255,
45  DFLTTOS= 0,
46 
47  IPaddrlen= 16,
48  IPv4addrlen= 4,
49  IPv4off= 12,
50  IPllen= 4,
51 
52  /* ip versions */
53  V4= 4,
54  V6= 6,
55  IP_VER4= 0x40,
56  IP_VER6= 0x60,
57  IP_HLEN4= 5, /* v4: Header length in words */
58  IP_DF= 0x4000, /* v4: Don't fragment */
59  IP_MF= 0x2000, /* v4: More fragments */
60  IP_FO= 0x1fff, /* v4: Fragment offset */
61  IP4HDR= IP_HLEN4<<2, /* sizeof(Ip4hdr) */
62  IP_MAX= 64*1024, /* Max. Internet packet size, v4 & v6 */
63 
64  /* 2^Lroot trees in the root table */
65  Lroot= 10,
66 
67  Maxpath = 64,
68 };
69 
70 enum
71 {
72  Idle= 0,
73  Announcing= 1,
74  Announced= 2,
75  Connecting= 3,
76  Connected= 4,
77 };
78 
79 /* MIB II counters */
80 enum
81 {
82  Forwarding,
83  DefaultTTL,
84  InReceives,
85  InHdrErrors,
86  InAddrErrors,
87  ForwDatagrams,
88  InUnknownProtos,
89  InDiscards,
90  InDelivers,
91  OutRequests,
92  OutDiscards,
93  OutNoRoutes,
94  ReasmTimeout,
95  ReasmReqds,
96  ReasmOKs,
97  ReasmFails,
98  FragOKs,
99  FragFails,
100  FragCreates,
101 
102  Nipstats,
103 };
104 
105 struct Fragment4
106 {
107  Block* blist;
108  Fragment4* next;
109  ulong src;
110  ulong dst;
111  ushort id;
112  ulong age;
113 };
114 
115 struct Fragment6
116 {
117  Block* blist;
118  Fragment6* next;
119  uchar src[IPaddrlen];
120  uchar dst[IPaddrlen];
121  uint id;
122  ulong age;
123 };
124 
125 struct Ipfrag
126 {
127  ushort foff;
128  ushort flen;
129  uchar payload[];
130 };
131 
132 #define IPFRAGSZ offsetof(Ipfrag, payload[0])
133 
134 /* an instance of IP */
135 struct IP
136 {
137  uvlong stats[Nipstats];
138 
139  QLock fraglock4;
140  Fragment4* flisthead4;
141  Fragment4* fragfree4;
142  Ref id4;
143 
144  QLock fraglock6;
145  Fragment6* flisthead6;
146  Fragment6* fragfree6;
147  Ref id6;
148 
149  int iprouting; /* true if we route like a gateway */
150 };
151 
152 /* on the wire packet header */
153 struct Ip4hdr
154 {
155  uchar vihl; /* Version and header length */
156  uchar tos; /* Type of service */
157  uchar length[2]; /* packet length */
158  uchar id[2]; /* ip->identification */
159  uchar frag[2]; /* Fragment information */
160  uchar ttl; /* Time to live */
161  uchar proto; /* Protocol */
162  uchar cksum[2]; /* Header checksum */
163  uchar src[4]; /* IP source */
164  uchar dst[4]; /* IP destination */
165 };
166 
167 struct Routehint
168 {
169  Route *r; /* last route used */
170  ulong rgen; /* routetable generation for *r */
171 };
172 
173 /*
174  * one per conversation directory
175  */
176 struct Conv
177 {
178  QLock;
179 
180  int x; /* conversation index */
181  Proto* p;
182 
183  int restricted; /* remote port is restricted */
184  int ignoreadvice; /* don't terminate connection on icmp errors */
185  uint ttl; /* max time to live */
186  uint tos; /* type of service */
187 
188  uchar ipversion;
189  uchar laddr[IPaddrlen]; /* local IP address */
190  uchar raddr[IPaddrlen]; /* remote IP address */
191  ushort lport; /* local port number */
192  ushort rport; /* remote port number */
193 
194  char *owner; /* protections */
195  int perm;
196  int inuse; /* opens of listen/data/ctl */
197  int length;
198  int state;
199 
200  /* udp specific */
201  int headers; /* data src/dst headers in udp */
202  int reliable; /* true if reliable udp */
203 
204  Conv* incall; /* calls waiting to be listened for */
205  Conv* next;
206 
207  Queue* rq; /* queued data waiting to be read */
208  Queue* wq; /* queued data waiting to be written */
209  Queue* eq; /* returned error packets */
210  Queue* sq; /* snooping queue */
211  Ref snoopers; /* number of processes with snoop open */
212 
213  Rendez cr;
214  char cerr[ERRMAX];
215 
216  QLock listenq;
217  Rendez listenr;
218 
219  Ipmulti *multi; /* multicast bindings for this interface */
220 
221  void* ptcl; /* protocol specific stuff */
222 
223  Routehint;
224 };
225 
226 struct Medium
227 {
228  char *name;
229  int hsize; /* medium header size */
230  int mintu; /* default min mtu */
231  int maxtu; /* default max mtu */
232  int maclen; /* mac address length */
233  void (*bind)(Ipifc*, int, char**);
234  void (*unbind)(Ipifc*);
235  void (*bwrite)(Ipifc *ifc, Block *b, int version, uchar *ip);
236 
237  /* for arming interfaces to receive multicast */
238  void (*addmulti)(Ipifc *ifc, uchar *a, uchar *ia);
239  void (*remmulti)(Ipifc *ifc, uchar *a, uchar *ia);
240 
241  /* process packets written to 'data' */
242  void (*pktin)(Fs *f, Ipifc *ifc, Block *bp);
243 
244  /* address resolution */
245  void (*areg)(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *ip);
246 
247  /* v6 address generation */
248  void (*pref2addr)(uchar *pref, uchar *ea);
249 
250  int unbindonclose; /* if non-zero, unbind on last close */
251 };
252 
253 /* logical interface associated with a physical one */
254 struct Iplifc
255 {
256  uchar local[IPaddrlen];
257  uchar mask[IPaddrlen];
258  uchar remote[IPaddrlen];
259  uchar net[IPaddrlen];
260  uchar type; /* route type */
261  uchar tentative; /* =1 => v6 dup disc on, =0 => confirmed unique */
262  uchar onlink; /* =1 => onlink, =0 offlink. */
263  uchar autoflag; /* v6 autonomous flag */
264  ulong validlt; /* v6 valid lifetime */
265  ulong preflt; /* v6 preferred lifetime */
266  ulong origint; /* time when addr was added */
267  Iplink *link; /* addresses linked to this lifc */
268  Iplifc *next;
269 };
270 
271 /* binding twixt Ipself and Iplifc */
272 struct Iplink
273 {
274  Ipself *self;
275  Iplifc *lifc;
276  Iplink *selflink; /* next link for this local address */
277  Iplink *lifclink; /* next link for this lifc */
278  Iplink *next; /* free list */
279  ulong expire;
280  int ref;
281 };
282 
283 /* rfc 2461, pp.40—43. */
284 
285 /* default values, one per stack */
286 struct Routerparams {
287  int mflag; /* flag: managed address configuration */
288  int oflag; /* flag: other stateful configuration */
289  int maxraint; /* max. router adv interval (ms) */
290  int minraint; /* min. router adv interval (ms) */
291  int linkmtu; /* mtu options */
292  int reachtime; /* reachable time */
293  int rxmitra; /* retransmit interval */
294  int ttl; /* cur hop count limit */
295  int routerlt; /* router lifetime */
296 };
297 
298 struct Hostparams {
299  int rxmithost;
300 };
301 
302 struct Ipifc
303 {
304  RWlock;
305 
306  Conv *conv; /* link to its conversation structure */
307  char dev[64]; /* device we're attached to */
308  Medium *m; /* Media pointer */
309  int maxtu; /* Maximum transfer unit */
310  int mintu; /* Minumum tranfer unit */
311  void *arg; /* medium specific */
312 
313  uchar reflect; /* allow forwarded packets to go out the same interface */
314  uchar reassemble; /* reassemble IP packets before forwarding to this interface */
315 
316  uchar ifcid; /* incremented each 'bind/unbind/add/remove' */
317 
318  uchar mac[MAClen]; /* MAC address */
319 
320  Iplifc *lifc; /* logical interfaces on this physical one */
321 
322  ulong in, out; /* message statistics */
323  ulong inerr, outerr; /* ... */
324 
325  uchar sendra6; /* flag: send router advs on this ifc */
326  uchar recvra6; /* flag: recv router advs on this ifc */
327  Routerparams rp; /* router parameters as in RFC 2461, pp.40—43.
328  used only if node is router */
329 
330  int speed; /* link speed in bits per second */
331  int delay; /* burst delay in ms */
332  int burst; /* burst delay in bytes */
333  int load; /* bytes in flight */
334  ulong ticks;
335 };
336 
337 /*
338  * one per multicast-lifc pair used by a Conv
339  */
340 struct Ipmulti
341 {
342  uchar ma[IPaddrlen];
343  uchar ia[IPaddrlen];
344  Ipmulti *next;
345 };
346 
347 /*
348  * hash table for 2 ip addresses + 2 ports
349  */
350 enum
351 {
352  Nipht= 521, /* convenient prime */
353 
354  IPmatchexact= 0, /* match on 4 tuple */
355  IPmatchany, /* *!* */
356  IPmatchport, /* *!port */
357  IPmatchaddr, /* addr!* */
358  IPmatchpa, /* addr!port */
359 };
360 struct Iphash
361 {
362  Iphash *next;
363  Conv *c;
364  int match;
365 };
366 struct Ipht
367 {
368  Lock;
369  Iphash *tab[Nipht];
370 };
371 void iphtadd(Ipht*, Conv*);
372 void iphtrem(Ipht*, Conv*);
373 Conv* iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp);
374 
375 /*
376  * one per multiplexed protocol
377  */
378 struct Proto
379 {
380  QLock;
381  char* name; /* protocol name */
382  int x; /* protocol index */
383  int ipproto; /* ip protocol type */
384 
385  char* (*connect)(Conv*, char**, int);
386  char* (*announce)(Conv*, char**, int);
387  char* (*bind)(Conv*, char**, int);
388  int (*state)(Conv*, char*, int);
389  void (*create)(Conv*);
390  void (*close)(Conv*);
391  void (*rcv)(Proto*, Ipifc*, Block*);
392  char* (*ctl)(Conv*, char**, int);
393  void (*advise)(Proto*, Block*, char*);
394  int (*stats)(Proto*, char*, int);
395  int (*local)(Conv*, char*, int);
396  int (*remote)(Conv*, char*, int);
397  int (*inuse)(Conv*);
398  int (*gc)(Proto*); /* returns true if any conversations are freed */
399 
400  Fs *f; /* file system this proto is part of */
401  Conv **conv; /* array of conversations */
402  int ptclsize; /* size of per protocol ctl block */
403  int nc; /* number of conversations */
404  int ac;
405  Qid qid; /* qid for protocol directory */
406  ushort nextrport;
407 
408  void *priv;
409 };
410 
411 
412 /*
413  * one per IP protocol stack
414  */
415 struct Fs
416 {
417  RWlock;
418  int dev;
419 
420  int np;
421  Proto* p[Maxproto+1]; /* list of supported protocols */
422  Proto* t2p[256]; /* vector of all protocols */
423  Proto* ipifc; /* kludge for ipifcremroute & ipifcaddroute */
424  Proto* ipmux; /* kludge for finding an ip multiplexor */
425 
426  IP *ip;
427  Ipselftab *self;
428  Arp *arp;
429  v6params *v6p;
430 
431  Route *v4root[1<<Lroot]; /* v4 routing forest */
432  Route *v6root[1<<Lroot]; /* v6 routing forest */
433  Route *queue; /* used as temp when reinjecting routes */
434 
435  Netlog *alog;
436 
437  char ndb[1024]; /* an ndb entry for this interface */
438  int ndbvers;
439  long ndbmtime;
440 };
441 
442 struct v6params
443 {
444  Routerparams rp; /* v6 params, one copy per node now */
445  Hostparams hp;
446 };
447 
448 
449 int Fsconnected(Conv*, char*);
450 Conv* Fsnewcall(Conv*, uchar*, ushort, uchar*, ushort, uchar);
451 int Fspcolstats(char*, int);
452 int Fsproto(Fs*, Proto*);
453 int Fsbuiltinproto(Fs*, uchar);
454 Conv* Fsprotoclone(Proto*, char*);
455 Proto* Fsrcvpcol(Fs*, uchar);
456 Proto* Fsrcvpcolx(Fs*, uchar);
457 char* Fsstdconnect(Conv*, char**, int);
458 char* Fsstdannounce(Conv*, char**, int);
459 char* Fsstdbind(Conv*, char**, int);
460 ulong scalednconv(void);
461 void closeconv(Conv*);
462 /*
463  * logging
464  */
465 enum
466 {
467  Logip= 1<<1,
468  Logtcp= 1<<2,
469  Logfs= 1<<3,
470  Logil= 1<<4,
471  Logicmp= 1<<5,
472  Logudp= 1<<6,
473  Logcompress= 1<<7,
474  Logilmsg= 1<<8,
475  Loggre= 1<<9,
476  Logppp= 1<<10,
477  Logtcprxmt= 1<<11,
478  Logigmp= 1<<12,
479  Logudpmsg= 1<<13,
480  Logipmsg= 1<<14,
481  Logrudp= 1<<15,
482  Logrudpmsg= 1<<16,
483  Logesp= 1<<17,
484  Logtcpwin= 1<<18,
485 };
486 
487 void netloginit(Fs*);
488 void netlogopen(Fs*);
489 void netlogclose(Fs*);
490 void netlogctl(Fs*, char*, int);
491 long netlogread(Fs*, void*, ulong, long);
492 void netlog(Fs*, int, char*, ...);
493 void ifcloginit(Fs*);
494 long ifclogread(Fs*, Chan *,void*, ulong, long);
495 void ifclog(Fs*, uchar *, int);
496 void ifclogopen(Fs*, Chan*);
497 void ifclogclose(Fs*, Chan*);
498 
499 #pragma varargck argpos netlog 3
500 
501 /*
502  * iproute.c
503  */
504 typedef struct RouteTree RouteTree;
505 typedef struct V4route V4route;
506 typedef struct V6route V6route;
507 
508 enum
509 {
510  /* type bits */
511  Rv4= (1<<0), /* this is a version 4 route */
512  Rifc= (1<<1), /* this route is a directly connected interface */
513  Rptpt= (1<<2), /* this route is a pt to pt interface */
514  Runi= (1<<3), /* a unicast self address */
515  Rbcast= (1<<4), /* a broadcast self address */
516  Rmulti= (1<<5), /* a multicast self address */
517  Rproxy= (1<<6), /* this route should be proxied */
518  Rsrc= (1<<7), /* source specific route */
519 };
520 
521 struct RouteTree
522 {
523  Route *mid;
524  Route *left;
525  Route *right;
526  Ipifc *ifc;
527  uchar ifcid; /* must match ifc->id */
528  uchar depth;
529  uchar type;
530  char tag[4];
531  int ref;
532 };
533 
534 struct V4route
535 {
536  ulong address;
537  ulong endaddress;
538 
539  ulong source;
540  ulong endsource;
541 
542  uchar gate[IPv4addrlen];
543 };
544 
545 struct V6route
546 {
547  ulong address[IPllen];
548  ulong endaddress[IPllen];
549 
550  ulong source[IPllen];
551  ulong endsource[IPllen];
552 
553  uchar gate[IPaddrlen];
554 };
555 
556 struct Route
557 {
558  RouteTree;
559 
560  union {
561  V6route v6;
562  V4route v4;
563  };
564 };
565 
566 extern void addroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
567 extern void remroute(Fs *f, uchar *a, uchar *mask, uchar *s, uchar *smask, uchar *gate, int type, Ipifc *ifc, char *tag);
568 extern Route* v4lookup(Fs *f, uchar *a, uchar *s, Routehint *h);
569 extern Route* v6lookup(Fs *f, uchar *a, uchar *s, Routehint *h);
570 extern long routeread(Fs *f, char*, ulong, int);
571 extern long routewrite(Fs *f, Chan*, char*, int);
572 extern void routetype(int type, char p[8]);
573 
574 /*
575  * devip.c
576  */
577 
578 /*
579  * Hanging off every ip channel's ->aux is the following structure.
580  * It maintains the state used by devip and iproute.
581  */
582 struct IPaux
583 {
584  char *owner; /* the user that did the attach */
585  char tag[4];
586 };
587 
588 extern IPaux* newipaux(char*, char*);
589 
590 /*
591  * arp.c
592  */
593 struct Arpent
594 {
595  uchar ip[IPaddrlen];
596  uchar mac[MAClen];
597  Arpent *hash;
598  Arpent *nextrxt; /* re-transmit chain */
599  Block *hold;
600  Block *last;
601  Ipifc *ifc;
602  uchar ifcid; /* must match ifc->id */
603  uchar state;
604  uchar rxtsrem; /* re-tranmissions remaining */
605  ulong ctime; /* time entry was created or refreshed */
606  ulong utime; /* time entry was last used */
607 };
608 
609 extern void arpinit(Fs*);
610 extern int arpread(Arp*, char*, ulong, int);
611 extern int arpwrite(Fs*, char*, int);
612 extern Arpent* arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *h);
613 extern void arprelease(Arp*, Arpent *a);
614 extern Block* arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
615 extern int arpenter(Fs*, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *ifc, int refresh);
616 extern void ndpsendsol(Fs*, Ipifc*, Arpent*);
617 
618 /*
619  * ipaux.c
620  */
621 
622 extern int parseether(uchar*, char*);
623 extern vlong parseip(uchar*, char*);
624 extern vlong parseipmask(uchar*, char*);
625 extern vlong parseipandmask(uchar*, uchar*, char*, char*);
626 extern char* v4parseip(uchar*, char*);
627 extern void maskip(uchar *from, uchar *mask, uchar *to);
628 extern int parsemac(uchar *to, char *from, int len);
629 extern uchar* defmask(uchar*);
630 extern int isv4(uchar*);
631 extern void v4tov6(uchar *v6, uchar *v4);
632 extern int v6tov4(uchar *v4, uchar *v6);
633 extern int eipfmt(Fmt*);
634 extern int convipvers(Conv *c);
635 
636 #define ipmove(x, y) memmove(x, y, IPaddrlen)
637 #define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
638 
639 extern uchar IPv4bcast[IPaddrlen];
640 extern uchar IPv4bcastobs[IPaddrlen];
641 extern uchar IPv4allsys[IPaddrlen];
642 extern uchar IPv4allrouter[IPaddrlen];
643 extern uchar IPnoaddr[IPaddrlen];
644 extern uchar v4prefix[IPaddrlen];
645 extern uchar IPallbits[IPaddrlen];
646 
647 #define NOW TK2MS(MACHP(0)->ticks)
648 
649 /*
650  * media
651  */
652 extern Medium ethermedium;
653 extern Medium nullmedium;
654 extern Medium pktmedium;
655 
656 /*
657  * ipifc.c
658  */
659 extern Medium* ipfindmedium(char *name);
660 extern void addipmedium(Medium *med);
661 extern void ipifcoput(Ipifc *ifc, Block *bp, int version, uchar *ip);
662 extern int ipforme(Fs*, uchar *addr);
663 extern int ipismulticast(uchar *ip);
664 extern Ipifc* findipifc(Fs*, uchar *local, uchar *remote, int type);
665 extern Ipifc* findipifcstr(Fs *f, char *s);
666 extern void findlocalip(Fs*, uchar *local, uchar *remote);
667 extern int ipv4local(Ipifc *ifc, uchar *local, uchar *remote);
668 extern int ipv6local(Ipifc *ifc, uchar *local, uchar *remote);
669 extern Iplifc* iplocalonifc(Ipifc *ifc, uchar *ip);
670 extern Iplifc* ipremoteonifc(Ipifc *ifc, uchar *ip);
671 extern int ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip);
672 extern void ipifcremmulti(Conv *c, uchar *ma, uchar *ia);
673 extern void ipifcaddmulti(Conv *c, uchar *ma, uchar *ia);
674 extern char* ipifcrem(Ipifc *ifc, char **argv, int argc);
675 extern char* ipifcadd(Ipifc *ifc, char **argv, int argc, int tentative, Iplifc *lifcp);
676 extern long ipselftabread(Fs*, char *a, ulong offset, int n);
677 extern char* ipifcadd6(Ipifc *ifc, char**argv, int argc);
678 extern char* ipifcremove6(Ipifc *ifc, char**argv, int argc);
679 /*
680  * ip.c
681  */
682 extern void iprouting(Fs*, int);
683 extern void icmpnoconv(Fs*, Block*);
684 extern void icmpcantfrag(Fs*, Block*, int);
685 extern void icmpttlexceeded(Fs*, Ipifc*, Block*);
686 extern ushort ipcsum(uchar*);
687 extern void ipiput4(Fs*, Ipifc*, Block*);
688 extern void ipiput6(Fs*, Ipifc*, Block*);
689 extern int ipoput4(Fs*, Block*, int, int, int, Routehint*);
690 extern int ipoput6(Fs*, Block*, int, int, int, Routehint*);
691 extern int ipstats(Fs*, char*, int);
692 extern ushort ptclbsum(uchar*, int);
693 extern ushort ptclcsum(Block*, int, int);
694 extern void ip_init(Fs*);
695 extern void ip_init_6(Fs*);
696 
697 /*
698  * bootp.c
699  */
700 extern int bootpread(char*, ulong, int);
701 
702 /*
703  * resolving inferno/plan9 differences
704  */
705 char* commonuser(void);
706 char* commonerror(void);
707 
708 /*
709  * chandial.c
710  */
711 extern Chan* chandial(char*, char*, char*, Chan**);
712 
713 /*
714  * global to all of the stack
715  */
716 extern void (*igmpreportfn)(Ipifc*, uchar*);