chiark / gitweb /
build system: debian packaging improvements
[secnet.git] / netlink.c
1 /* User-kernel network link */
2
3 /* See RFCs 791, 792, 1123 and 1812 */
4
5 /* The netlink device is actually a router.  Tunnels are unnumbered
6    point-to-point lines (RFC1812 section 2.2.7); the router has a
7    single address (the 'router-id'). */
8
9 /* This is where we currently have the anti-spoofing paranoia - before
10    sending a packet to the kernel we check that the tunnel it came
11    over could reasonably have produced it. */
12
13
14 /* Points to note from RFC1812 (which may require changes in this
15    file):
16
17 3.3.4 Maximum Transmission Unit - MTU
18
19    The MTU of each logical interface MUST be configurable within the
20    range of legal MTUs for the interface.
21
22    Many Link Layer protocols define a maximum frame size that may be
23    sent.  In such cases, a router MUST NOT allow an MTU to be set which
24    would allow sending of frames larger than those allowed by the Link
25    Layer protocol.  However, a router SHOULD be willing to receive a
26    packet as large as the maximum frame size even if that is larger than
27    the MTU.
28
29 4.2.1  A router SHOULD count datagrams discarded.
30
31 4.2.2.1 Source route options - we probably should implement processing
32 of source routes, even though mostly the security policy will prevent
33 their use.
34
35 5.3.13.4 Source Route Options
36
37    A router MUST implement support for source route options in forwarded
38    packets.  A router MAY implement a configuration option that, when
39    enabled, causes all source-routed packets to be discarded.  However,
40    such an option MUST NOT be enabled by default.
41
42 5.3.13.5 Record Route Option
43
44    Routers MUST support the Record Route option in forwarded packets.
45
46    A router MAY provide a configuration option that, if enabled, will
47    cause the router to ignore (i.e., pass through unchanged) Record
48    Route options in forwarded packets.  If provided, such an option MUST
49    default to enabling the record-route.  This option should not affect
50    the processing of Record Route options in datagrams received by the
51    router itself (in particular, Record Route options in ICMP echo
52    requests will still be processed according to Section [4.3.3.6]).
53
54 5.3.13.6 Timestamp Option
55
56    Routers MUST support the timestamp option in forwarded packets.  A
57    timestamp value MUST follow the rules given [INTRO:2].
58
59    If the flags field = 3 (timestamp and prespecified address), the
60    router MUST add its timestamp if the next prespecified address
61    matches any of the router's IP addresses.  It is not necessary that
62    the prespecified address be either the address of the interface on
63    which the packet arrived or the address of the interface over which
64    it will be sent.
65
66
67 4.2.2.7 Fragmentation: RFC 791 Section 3.2
68
69    Fragmentation, as described in [INTERNET:1], MUST be supported by a
70    router.
71
72 4.2.2.8 Reassembly: RFC 791 Section 3.2
73
74    As specified in the corresponding section of [INTRO:2], a router MUST
75    support reassembly of datagrams that it delivers to itself.
76
77 4.2.2.9 Time to Live: RFC 791 Section 3.2
78
79    Note in particular that a router MUST NOT check the TTL of a packet
80    except when forwarding it.
81
82    A router MUST NOT discard a datagram just because it was received
83    with TTL equal to zero or one; if it is to the router and otherwise
84    valid, the router MUST attempt to receive it.
85
86    On messages the router originates, the IP layer MUST provide a means
87    for the transport layer to set the TTL field of every datagram that
88    is sent.  When a fixed TTL value is used, it MUST be configurable.
89
90
91 8.1 The Simple Network Management Protocol - SNMP
92 8.1.1 SNMP Protocol Elements
93
94    Routers MUST be manageable by SNMP [MGT:3].  The SNMP MUST operate
95    using UDP/IP as its transport and network protocols.
96
97
98 */
99
100 #include <string.h>
101 #include <assert.h>
102 #include <limits.h>
103 #include "secnet.h"
104 #include "util.h"
105 #include "ipaddr.h"
106 #include "netlink.h"
107 #include "process.h"
108
109 #define OPT_SOFTROUTE   1
110 #define OPT_ALLOWROUTE  2
111
112 #define ICMP_TYPE_ECHO_REPLY             0
113
114 #define ICMP_TYPE_UNREACHABLE            3
115 #define ICMP_CODE_NET_UNREACHABLE        0
116 #define ICMP_CODE_PROTOCOL_UNREACHABLE   2
117 #define ICMP_CODE_FRAGMENTATION_REQUIRED 4
118 #define ICMP_CODE_NET_PROHIBITED        13
119
120 #define ICMP_TYPE_ECHO_REQUEST           8
121
122 #define ICMP_TYPE_TIME_EXCEEDED         11
123 #define ICMP_CODE_TTL_EXCEEDED           0
124
125 /* Generic IP checksum routine */
126 static inline uint16_t ip_csum(uint8_t *iph,int32_t count)
127 {
128     register uint32_t sum=0;
129
130     while (count>1) {
131         sum+=ntohs(*(uint16_t *)iph);
132         iph+=2;
133         count-=2;
134     }
135     if(count>0)
136         sum+=*(uint8_t *)iph;
137     while (sum>>16)
138         sum=(sum&0xffff)+(sum>>16);
139     return htons(~sum);
140 }
141
142 #ifdef i386
143 /*
144  *      This is a version of ip_compute_csum() optimized for IP headers,
145  *      which always checksum on 4 octet boundaries.
146  *
147  *      By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
148  *      Arnt Gulbrandsen.
149  */
150 static inline uint16_t ip_fast_csum(uint8_t *iph, int32_t ihl) {
151     uint32_t sum;
152
153     __asm__ __volatile__(
154             "movl (%1), %0      ;\n"
155             "subl $4, %2        ;\n"
156             "jbe 2f             ;\n"
157             "addl 4(%1), %0     ;\n"
158             "adcl 8(%1), %0     ;\n"
159             "adcl 12(%1), %0    ;\n"
160 "1:         adcl 16(%1), %0     ;\n"
161             "lea 4(%1), %1      ;\n"
162             "decl %2            ;\n"
163             "jne 1b             ;\n"
164             "adcl $0, %0        ;\n"
165             "movl %0, %2        ;\n"
166             "shrl $16, %0       ;\n"
167             "addw %w2, %w0      ;\n"
168             "adcl $0, %0        ;\n"
169             "notl %0            ;\n"
170 "2:                             ;\n"
171         /* Since the input registers which are loaded with iph and ipl
172            are modified, we must also specify them as outputs, or gcc
173            will assume they contain their original values. */
174         : "=r" (sum), "=r" (iph), "=r" (ihl)
175         : "1" (iph), "2" (ihl)
176         : "memory");
177     return sum;
178 }
179 #else
180 static inline uint16_t ip_fast_csum(uint8_t *iph, int32_t ihl)
181 {
182     assert(ihl < INT_MAX/4);
183     return ip_csum(iph,ihl*4);
184 }
185 #endif
186
187 struct iphdr {
188 #if defined (WORDS_BIGENDIAN)
189     uint8_t    version:4,
190                ihl:4;
191 #else
192     uint8_t    ihl:4,
193                version:4;
194 #endif
195     uint8_t    tos;
196     uint16_t   tot_len;
197     uint16_t   id;
198     uint16_t   frag_off;
199     uint8_t    ttl;
200     uint8_t    protocol;
201     uint16_t   check;
202     uint32_t   saddr;
203     uint32_t   daddr;
204     /* The options start here. */
205 };
206
207 struct icmphdr {
208     struct iphdr iph;
209     uint8_t type;
210     uint8_t code;
211     uint16_t check;
212     union {
213         uint32_t unused;
214         struct {
215             uint8_t pointer;
216             uint8_t unused1;
217             uint16_t unused2;
218         } pprob;
219         uint32_t gwaddr;
220         struct {
221             uint16_t id;
222             uint16_t seq;
223         } echo;
224     } d;
225 };
226     
227 static void netlink_packet_deliver(struct netlink *st,
228                                    struct netlink_client *client,
229                                    struct buffer_if *buf);
230
231 /* XXX RFC1812 4.3.2.5:
232    All other ICMP error messages (Destination Unreachable,
233    Redirect, Time Exceeded, and Parameter Problem) SHOULD have their
234    precedence value set to 6 (INTERNETWORK CONTROL) or 7 (NETWORK
235    CONTROL).  The IP Precedence value for these error messages MAY be
236    settable.
237    */
238 static struct icmphdr *netlink_icmp_tmpl(struct netlink *st,
239                                          uint32_t dest,uint16_t len)
240 {
241     struct icmphdr *h;
242
243     BUF_ALLOC(&st->icmp,"netlink_icmp_tmpl");
244     buffer_init(&st->icmp,st->max_start_pad);
245     h=buf_append(&st->icmp,sizeof(*h));
246
247     h->iph.version=4;
248     h->iph.ihl=5;
249     h->iph.tos=0;
250     h->iph.tot_len=htons(len+(h->iph.ihl*4)+8);
251     h->iph.id=0;
252     h->iph.frag_off=0;
253     h->iph.ttl=255; /* XXX should be configurable */
254     h->iph.protocol=1;
255     h->iph.saddr=htonl(st->secnet_address);
256     h->iph.daddr=htonl(dest);
257     h->iph.check=0;
258     h->iph.check=ip_fast_csum((uint8_t *)&h->iph,h->iph.ihl);
259     h->check=0;
260     h->d.unused=0;
261
262     return h;
263 }
264
265 /* Fill in the ICMP checksum field correctly */
266 static void netlink_icmp_csum(struct icmphdr *h)
267 {
268     int32_t len;
269
270     len=ntohs(h->iph.tot_len)-(4*h->iph.ihl);
271     h->check=0;
272     h->check=ip_csum(&h->type,len);
273 }
274
275 /* RFC1122:
276  *       An ICMP error message MUST NOT be sent as the result of
277  *       receiving:
278  *
279  *       *    an ICMP error message, or
280  *
281  *       *    a datagram destined to an IP broadcast or IP multicast
282  *            address, or
283  *
284  *       *    a datagram sent as a link-layer broadcast, or
285  *
286  *       *    a non-initial fragment, or
287  *
288  *       *    a datagram whose source address does not define a single
289  *            host -- e.g., a zero address, a loopback address, a
290  *            broadcast address, a multicast address, or a Class E
291  *            address.
292  */
293 static bool_t netlink_icmp_may_reply(struct buffer_if *buf)
294 {
295     struct iphdr *iph;
296     struct icmphdr *icmph;
297     uint32_t source;
298
299     iph=(struct iphdr *)buf->start;
300     icmph=(struct icmphdr *)buf->start;
301     if (iph->protocol==1) {
302         switch(icmph->type) {
303         case 3: /* Destination unreachable */
304         case 11: /* Time Exceeded */
305         case 12: /* Parameter Problem */
306             return False;
307         }
308     }
309     /* How do we spot broadcast destination addresses? */
310     if (ntohs(iph->frag_off)&0x1fff) return False; /* Non-initial fragment */
311     source=ntohl(iph->saddr);
312     if (source==0) return False;
313     if ((source&0xff000000)==0x7f000000) return False;
314     /* How do we spot broadcast source addresses? */
315     if ((source&0xf0000000)==0xe0000000) return False; /* Multicast */
316     if ((source&0xf0000000)==0xf0000000) return False; /* Class E */
317     return True;
318 }
319
320 /* How much of the original IP packet do we include in its ICMP
321    response? The header plus up to 64 bits. */
322
323 /* XXX TODO RFC1812:
324 4.3.2.3 Original Message Header
325
326    Historically, every ICMP error message has included the Internet
327    header and at least the first 8 data bytes of the datagram that
328    triggered the error.  This is no longer adequate, due to the use of
329    IP-in-IP tunneling and other technologies.  Therefore, the ICMP
330    datagram SHOULD contain as much of the original datagram as possible
331    without the length of the ICMP datagram exceeding 576 bytes.  The
332    returned IP header (and user data) MUST be identical to that which
333    was received, except that the router is not required to undo any
334    modifications to the IP header that are normally performed in
335    forwarding that were performed before the error was detected (e.g.,
336    decrementing the TTL, or updating options).  Note that the
337    requirements of Section [4.3.3.5] supersede this requirement in some
338    cases (i.e., for a Parameter Problem message, if the problem is in a
339    modified field, the router must undo the modification).  See Section
340    [4.3.3.5]).
341    */
342 static uint16_t netlink_icmp_reply_len(struct buffer_if *buf)
343 {
344     struct iphdr *iph=(struct iphdr *)buf->start;
345     uint16_t hlen,plen;
346
347     hlen=iph->ihl*4;
348     /* We include the first 8 bytes of the packet data, provided they exist */
349     hlen+=8;
350     plen=ntohs(iph->tot_len);
351     return (hlen>plen?plen:hlen);
352 }
353
354 /* client indicates where the packet we're constructing a response to
355    comes from. NULL indicates the host. */
356 static void netlink_icmp_simple(struct netlink *st, struct buffer_if *buf,
357                                 struct netlink_client *client,
358                                 uint8_t type, uint8_t code)
359 {
360     struct iphdr *iph=(struct iphdr *)buf->start;
361     struct icmphdr *h;
362     uint16_t len;
363
364     if (netlink_icmp_may_reply(buf)) {
365         len=netlink_icmp_reply_len(buf);
366         h=netlink_icmp_tmpl(st,ntohl(iph->saddr),len);
367         h->type=type; h->code=code;
368         memcpy(buf_append(&st->icmp,len),buf->start,len);
369         netlink_icmp_csum(h);
370         netlink_packet_deliver(st,NULL,&st->icmp);
371         BUF_ASSERT_FREE(&st->icmp);
372     }
373 }
374
375 /*
376  * RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the
377  * checksum.
378  * RFC1812: 4.2.2.5 MUST discard messages containing invalid checksums.
379  *
380  * Is the datagram acceptable?
381  *
382  * 1. Length at least the size of an ip header
383  * 2. Version of 4
384  * 3. Checksums correctly.
385  * 4. Doesn't have a bogus length
386  */
387 static bool_t netlink_check(struct netlink *st, struct buffer_if *buf,
388                             char *errmsgbuf, int errmsgbuflen)
389 {
390 #define BAD(...) do{                                    \
391         snprintf(errmsgbuf,errmsgbuflen,__VA_ARGS__);   \
392         return False;                                   \
393     }while(0)
394
395     struct iphdr *iph=(struct iphdr *)buf->start;
396     int32_t len;
397
398     if (iph->ihl < 5) BAD("ihl %u",iph->ihl);
399     if (iph->version != 4) BAD("version %u",iph->version);
400     if (buf->size < iph->ihl*4) BAD("size %"PRId32"<%u*4",buf->size,iph->ihl);
401     if (ip_fast_csum((uint8_t *)iph, iph->ihl)!=0) BAD("csum");
402     len=ntohs(iph->tot_len);
403     /* There should be no padding */
404     if (buf->size!=len) BAD("len %"PRId32"!=%"PRId32,buf->size,len);
405     if (len<(iph->ihl<<2)) BAD("len %"PRId32"<(%u<<2)",len,iph->ihl);
406     /* XXX check that there's no source route specified */
407     return True;
408
409 #undef BAD
410 }
411
412 /* Deliver a packet. "client" is the _origin_ of the packet, not its
413    destination, and is NULL for packets from the host and packets
414    generated internally in secnet.  */
415 static void netlink_packet_deliver(struct netlink *st,
416                                    struct netlink_client *client,
417                                    struct buffer_if *buf)
418 {
419     struct iphdr *iph=(struct iphdr *)buf->start;
420     uint32_t dest=ntohl(iph->daddr);
421     uint32_t source=ntohl(iph->saddr);
422     uint32_t best_quality;
423     bool_t allow_route=False;
424     bool_t found_allowed=False;
425     int best_match;
426     int i;
427
428     BUF_ASSERT_USED(buf);
429
430     if (dest==st->secnet_address) {
431         Message(M_ERR,"%s: trying to deliver a packet to myself!\n",st->name);
432         BUF_FREE(buf);
433         return;
434     }
435     
436     /* Packets from the host (client==NULL) may always be routed.  Packets
437        from clients with the allow_route option will also be routed. */
438     if (!client || (client && (client->options & OPT_ALLOWROUTE)))
439         allow_route=True;
440
441     /* If !allow_route, we check the routing table anyway, and if
442        there's a suitable route with OPT_ALLOWROUTE set we use it.  If
443        there's a suitable route, but none with OPT_ALLOWROUTE set then
444        we generate ICMP 'communication with destination network
445        administratively prohibited'. */
446
447     best_quality=0;
448     best_match=-1;
449     for (i=0; i<st->n_clients; i++) {
450         if (st->routes[i]->up &&
451             ipset_contains_addr(st->routes[i]->networks,dest)) {
452             /* It's an available route to the correct destination. But is
453                it better than the one we already have? */
454
455             /* If we have already found an allowed route then we don't
456                bother looking at routes we're not allowed to use.  If
457                we don't yet have an allowed route we'll consider any.  */
458             if (!allow_route && found_allowed) {
459                 if (!(st->routes[i]->options&OPT_ALLOWROUTE)) continue;
460             }
461             
462             if (st->routes[i]->link_quality>best_quality
463                 || best_quality==0) {
464                 best_quality=st->routes[i]->link_quality;
465                 best_match=i;
466                 if (st->routes[i]->options&OPT_ALLOWROUTE)
467                     found_allowed=True;
468                 /* If quality isn't perfect we may wish to
469                    consider kicking the tunnel with a 0-length
470                    packet to prompt it to perform a key setup.
471                    Then it'll eventually decide it's up or
472                    down. */
473                 /* If quality is perfect and we're allowed to use the
474                    route we don't need to search any more. */
475                 if (best_quality>=MAXIMUM_LINK_QUALITY && 
476                     (allow_route || found_allowed)) break;
477             }
478         }
479     }
480     if (best_match==-1) {
481         /* The packet's not going down a tunnel.  It might (ought to)
482            be for the host.   */
483         if (ipset_contains_addr(st->networks,dest)) {
484             st->deliver_to_host(st->dst,buf);
485             st->outcount++;
486             BUF_ASSERT_FREE(buf);
487         } else {
488             string_t s,d;
489             s=ipaddr_to_string(source);
490             d=ipaddr_to_string(dest);
491             Message(M_DEBUG,"%s: don't know where to deliver packet "
492                     "(s=%s, d=%s)\n", st->name, s, d);
493             free(s); free(d);
494             netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE,
495                                 ICMP_CODE_NET_UNREACHABLE);
496             BUF_FREE(buf);
497         }
498     } else {
499         if (!allow_route &&
500             !(st->routes[best_match]->options&OPT_ALLOWROUTE)) {
501             string_t s,d;
502             s=ipaddr_to_string(source);
503             d=ipaddr_to_string(dest);
504             /* We have a usable route but aren't allowed to use it.
505                Generate ICMP destination unreachable: communication
506                with destination network administratively prohibited */
507             Message(M_NOTICE,"%s: denied forwarding for packet (s=%s, d=%s)\n",
508                     st->name,s,d);
509             free(s); free(d);
510                     
511             netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE,
512                                 ICMP_CODE_NET_PROHIBITED);
513             BUF_FREE(buf);
514         } else {
515             if (best_quality>0) {
516                 /* XXX Fragment if required */
517                 st->routes[best_match]->deliver(
518                     st->routes[best_match]->dst, buf);
519                 st->routes[best_match]->outcount++;
520                 BUF_ASSERT_FREE(buf);
521             } else {
522                 /* Generate ICMP destination unreachable */
523                 netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE,
524                                     ICMP_CODE_NET_UNREACHABLE); /* client==NULL */
525                 BUF_FREE(buf);
526             }
527         }
528     }
529     BUF_ASSERT_FREE(buf);
530 }
531
532 static void netlink_packet_forward(struct netlink *st, 
533                                    struct netlink_client *client,
534                                    struct buffer_if *buf)
535 {
536     struct iphdr *iph=(struct iphdr *)buf->start;
537     
538     BUF_ASSERT_USED(buf);
539
540     /* Packet has already been checked */
541     if (iph->ttl<=1) {
542         /* Generate ICMP time exceeded */
543         netlink_icmp_simple(st,buf,client,ICMP_TYPE_TIME_EXCEEDED,
544                             ICMP_CODE_TTL_EXCEEDED);
545         BUF_FREE(buf);
546         return;
547     }
548     iph->ttl--;
549     iph->check=0;
550     iph->check=ip_fast_csum((uint8_t *)iph,iph->ihl);
551
552     netlink_packet_deliver(st,client,buf);
553     BUF_ASSERT_FREE(buf);
554 }
555
556 /* Deal with packets addressed explicitly to us */
557 static void netlink_packet_local(struct netlink *st,
558                                  struct netlink_client *client,
559                                  struct buffer_if *buf)
560 {
561     struct icmphdr *h;
562
563     st->localcount++;
564
565     h=(struct icmphdr *)buf->start;
566
567     if ((ntohs(h->iph.frag_off)&0xbfff)!=0) {
568         Message(M_WARNING,"%s: fragmented packet addressed to secnet; "
569                 "ignoring it\n",st->name);
570         BUF_FREE(buf);
571         return;
572     }
573
574     if (h->iph.protocol==1) {
575         /* It's ICMP */
576         if (h->type==ICMP_TYPE_ECHO_REQUEST && h->code==0) {
577             /* ICMP echo-request. Special case: we re-use the buffer
578                to construct the reply. */
579             h->type=ICMP_TYPE_ECHO_REPLY;
580             h->iph.daddr=h->iph.saddr;
581             h->iph.saddr=htonl(st->secnet_address);
582             h->iph.ttl=255;
583             h->iph.check=0;
584             h->iph.check=ip_fast_csum((uint8_t *)h,h->iph.ihl);
585             netlink_icmp_csum(h);
586             netlink_packet_deliver(st,NULL,buf);
587             return;
588         }
589         Message(M_WARNING,"%s: unknown incoming ICMP\n",st->name);
590     } else {
591         /* Send ICMP protocol unreachable */
592         netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE,
593                             ICMP_CODE_PROTOCOL_UNREACHABLE);
594         BUF_FREE(buf);
595         return;
596     }
597
598     BUF_FREE(buf);
599 }
600
601 /* If cid==NULL packet is from host, otherwise cid specifies which tunnel 
602    it came from. */
603 static void netlink_incoming(struct netlink *st, struct netlink_client *client,
604                              struct buffer_if *buf)
605 {
606     uint32_t source,dest;
607     struct iphdr *iph;
608     char errmsgbuf[50];
609
610     BUF_ASSERT_USED(buf);
611     if (!netlink_check(st,buf,errmsgbuf,sizeof(errmsgbuf))) {
612         Message(M_WARNING,"%s: bad IP packet from %s: %s\n",
613                 st->name,client?client->name:"host",
614                 errmsgbuf);
615         BUF_FREE(buf);
616         return;
617     }
618     iph=(struct iphdr *)buf->start;
619
620     source=ntohl(iph->saddr);
621     dest=ntohl(iph->daddr);
622
623     /* Check source. If we don't like the source, there's no point
624        generating ICMP because we won't know how to get it to the
625        source of the packet. */
626     if (client) {
627         /* Check that the packet source is appropriate for the tunnel
628            it came down */
629         if (!ipset_contains_addr(client->networks,source)) {
630             string_t s,d;
631             s=ipaddr_to_string(source);
632             d=ipaddr_to_string(dest);
633             Message(M_WARNING,"%s: packet from tunnel %s with bad "
634                     "source address (s=%s,d=%s)\n",st->name,client->name,s,d);
635             free(s); free(d);
636             BUF_FREE(buf);
637             return;
638         }
639     } else {
640         /* Check that the packet originates in our configured local
641            network, and hasn't been forwarded from elsewhere or
642            generated with the wrong source address */
643         if (!ipset_contains_addr(st->networks,source)) {
644             string_t s,d;
645             s=ipaddr_to_string(source);
646             d=ipaddr_to_string(dest);
647             Message(M_WARNING,"%s: outgoing packet with bad source address "
648                     "(s=%s,d=%s)\n",st->name,s,d);
649             free(s); free(d);
650             BUF_FREE(buf);
651             return;
652         }
653     }
654
655     /* If this is a point-to-point device we don't examine the
656        destination address at all; we blindly send it down our
657        one-and-only registered tunnel, or to the host, depending on
658        where it came from.  It's up to external software to check
659        address validity and generate ICMP, etc. */
660     if (st->ptp) {
661         if (client) {
662             st->deliver_to_host(st->dst,buf);
663         } else {
664             st->clients->deliver(st->clients->dst,buf);
665         }
666         BUF_ASSERT_FREE(buf);
667         return;
668     }
669
670     /* st->secnet_address needs checking before matching destination
671        addresses */
672     if (dest==st->secnet_address) {
673         netlink_packet_local(st,client,buf);
674         BUF_ASSERT_FREE(buf);
675         return;
676     }
677     netlink_packet_forward(st,client,buf);
678     BUF_ASSERT_FREE(buf);
679 }
680
681 static void netlink_inst_incoming(void *sst, struct buffer_if *buf)
682 {
683     struct netlink_client *c=sst;
684     struct netlink *st=c->nst;
685
686     netlink_incoming(st,c,buf);
687 }
688
689 static void netlink_dev_incoming(void *sst, struct buffer_if *buf)
690 {
691     struct netlink *st=sst;
692
693     netlink_incoming(st,NULL,buf);
694 }
695
696 static void netlink_set_quality(void *sst, uint32_t quality)
697 {
698     struct netlink_client *c=sst;
699     struct netlink *st=c->nst;
700
701     c->link_quality=quality;
702     c->up=(c->link_quality==LINK_QUALITY_DOWN)?False:True;
703     if (c->options&OPT_SOFTROUTE) {
704         st->set_routes(st->dst,c);
705     }
706 }
707
708 static void netlink_output_subnets(struct netlink *st, uint32_t loglevel,
709                                    struct subnet_list *snets)
710 {
711     int32_t i;
712     string_t net;
713
714     for (i=0; i<snets->entries; i++) {
715         net=subnet_to_string(snets->list[i]);
716         Message(loglevel,"%s ",net);
717         free(net);
718     }
719 }
720
721 static void netlink_dump_routes(struct netlink *st, bool_t requested)
722 {
723     int i;
724     string_t net;
725     uint32_t c=M_INFO;
726
727     if (requested) c=M_WARNING;
728     if (st->ptp) {
729         net=ipaddr_to_string(st->secnet_address);
730         Message(c,"%s: point-to-point (remote end is %s); routes:\n",
731                 st->name, net);
732         free(net);
733         netlink_output_subnets(st,c,st->clients->subnets);
734         Message(c,"\n");
735     } else {
736         Message(c,"%s: routing table:\n",st->name);
737         for (i=0; i<st->n_clients; i++) {
738             netlink_output_subnets(st,c,st->routes[i]->subnets);
739             Message(c,"-> tunnel %s (%s,mtu %d,%s routes,%s,"
740                     "quality %d,use %d,pri %lu)\n",
741                     st->routes[i]->name,
742                     st->routes[i]->up?"up":"down",
743                     st->routes[i]->mtu,
744                     st->routes[i]->options&OPT_SOFTROUTE?"soft":"hard",
745                     st->routes[i]->options&OPT_ALLOWROUTE?"free":"restricted",
746                     st->routes[i]->link_quality,
747                     st->routes[i]->outcount,
748                     (unsigned long)st->routes[i]->priority);
749         }
750         net=ipaddr_to_string(st->secnet_address);
751         Message(c,"%s/32 -> netlink \"%s\" (use %d)\n",
752                 net,st->name,st->localcount);
753         free(net);
754         for (i=0; i<st->subnets->entries; i++) {
755             net=subnet_to_string(st->subnets->list[i]);
756             Message(c,"%s ",net);
757             free(net);
758         }
759         if (i>0)
760             Message(c,"-> host (use %d)\n",st->outcount);
761     }
762 }
763
764 /* ap is a pointer to a member of the routes array */
765 static int netlink_compare_client_priority(const void *ap, const void *bp)
766 {
767     const struct netlink_client *const*a=ap;
768     const struct netlink_client *const*b=bp;
769
770     if ((*a)->priority==(*b)->priority) return 0;
771     if ((*a)->priority<(*b)->priority) return 1;
772     return -1;
773 }
774
775 static void netlink_phase_hook(void *sst, uint32_t new_phase)
776 {
777     struct netlink *st=sst;
778     struct netlink_client *c;
779     int32_t i;
780
781     /* All the networks serviced by the various tunnels should now
782      * have been registered.  We build a routing table by sorting the
783      * clients by priority.  */
784     st->routes=safe_malloc_ary(sizeof(*st->routes),st->n_clients,
785                                "netlink_phase_hook");
786     /* Fill the table */
787     i=0;
788     for (c=st->clients; c; c=c->next) {
789         assert(i<INT_MAX);
790         st->routes[i++]=c;
791     }
792     /* Sort the table in descending order of priority */
793     qsort(st->routes,st->n_clients,sizeof(*st->routes),
794           netlink_compare_client_priority);
795
796     netlink_dump_routes(st,False);
797 }
798
799 static void netlink_signal_handler(void *sst, int signum)
800 {
801     struct netlink *st=sst;
802     Message(M_INFO,"%s: route dump requested by SIGUSR1\n",st->name);
803     netlink_dump_routes(st,True);
804 }
805
806 static void netlink_inst_set_mtu(void *sst, int32_t new_mtu)
807 {
808     struct netlink_client *c=sst;
809
810     c->mtu=new_mtu;
811 }
812
813 static void netlink_inst_reg(void *sst, netlink_deliver_fn *deliver, 
814                              void *dst, int32_t max_start_pad,
815                              int32_t max_end_pad)
816 {
817     struct netlink_client *c=sst;
818     struct netlink *st=c->nst;
819
820     if (max_start_pad > st->max_start_pad) st->max_start_pad=max_start_pad;
821     if (max_end_pad > st->max_end_pad) st->max_end_pad=max_end_pad;
822     c->deliver=deliver;
823     c->dst=dst;
824 }
825
826 static struct flagstr netlink_option_table[]={
827     { "soft", OPT_SOFTROUTE },
828     { "allow-route", OPT_ALLOWROUTE },
829     { NULL, 0}
830 };
831 /* This is the routine that gets called when the closure that's
832    returned by an invocation of a netlink device closure (eg. tun,
833    userv-ipif) is invoked.  It's used to create routes and pass in
834    information about them; the closure it returns is used by site
835    code.  */
836 static closure_t *netlink_inst_create(struct netlink *st,
837                                       struct cloc loc, dict_t *dict)
838 {
839     struct netlink_client *c;
840     string_t name;
841     struct ipset *networks;
842     uint32_t options,priority;
843     int32_t mtu;
844     list_t *l;
845
846     name=dict_read_string(dict, "name", True, st->name, loc);
847
848     l=dict_lookup(dict,"routes");
849     if (!l)
850         cfgfatal(loc,st->name,"required parameter \"routes\" not found\n");
851     networks=string_list_to_ipset(l,loc,st->name,"routes");
852     options=string_list_to_word(dict_lookup(dict,"options"),
853                                 netlink_option_table,st->name);
854
855     priority=dict_read_number(dict,"priority",False,st->name,loc,0);
856     mtu=dict_read_number(dict,"mtu",False,st->name,loc,0);
857
858     if ((options&OPT_SOFTROUTE) && !st->set_routes) {
859         cfgfatal(loc,st->name,"this netlink device does not support "
860                  "soft routes.\n");
861         return NULL;
862     }
863
864     if (options&OPT_SOFTROUTE) {
865         /* XXX for now we assume that soft routes require root privilege;
866            this may not always be true. The device driver can tell us. */
867         require_root_privileges=True;
868         require_root_privileges_explanation="netlink: soft routes";
869         if (st->ptp) {
870             cfgfatal(loc,st->name,"point-to-point netlinks do not support "
871                      "soft routes.\n");
872             return NULL;
873         }
874     }
875
876     /* Check that nets are a subset of st->remote_networks;
877        refuse to register if they are not. */
878     if (!ipset_is_subset(st->remote_networks,networks)) {
879         cfgfatal(loc,st->name,"routes are not allowed\n");
880         return NULL;
881     }
882
883     c=safe_malloc(sizeof(*c),"netlink_inst_create");
884     c->cl.description=name;
885     c->cl.type=CL_NETLINK;
886     c->cl.apply=NULL;
887     c->cl.interface=&c->ops;
888     c->ops.st=c;
889     c->ops.reg=netlink_inst_reg;
890     c->ops.deliver=netlink_inst_incoming;
891     c->ops.set_quality=netlink_set_quality;
892     c->ops.set_mtu=netlink_inst_set_mtu;
893     c->nst=st;
894
895     c->networks=networks;
896     c->subnets=ipset_to_subnet_list(networks);
897     c->priority=priority;
898     c->deliver=NULL;
899     c->dst=NULL;
900     c->name=name;
901     c->link_quality=LINK_QUALITY_UNUSED;
902     c->mtu=mtu?mtu:st->mtu;
903     c->options=options;
904     c->outcount=0;
905     c->up=False;
906     c->kup=False;
907     c->next=st->clients;
908     st->clients=c;
909     assert(st->n_clients < INT_MAX);
910     st->n_clients++;
911
912     return &c->cl;
913 }
914
915 static list_t *netlink_inst_apply(closure_t *self, struct cloc loc,
916                                   dict_t *context, list_t *args)
917 {
918     struct netlink *st=self->interface;
919
920     dict_t *dict;
921     item_t *item;
922     closure_t *cl;
923
924     item=list_elem(args,0);
925     if (!item || item->type!=t_dict) {
926         cfgfatal(loc,st->name,"must have a dictionary argument\n");
927     }
928     dict=item->data.dict;
929
930     cl=netlink_inst_create(st,loc,dict);
931
932     return new_closure(cl);
933 }
934
935 netlink_deliver_fn *netlink_init(struct netlink *st,
936                                  void *dst, struct cloc loc,
937                                  dict_t *dict, cstring_t description,
938                                  netlink_route_fn *set_routes,
939                                  netlink_deliver_fn *to_host)
940 {
941     item_t *sa, *ptpa;
942     list_t *l;
943
944     st->dst=dst;
945     st->cl.description=description;
946     st->cl.type=CL_PURE;
947     st->cl.apply=netlink_inst_apply;
948     st->cl.interface=st;
949     st->max_start_pad=0;
950     st->max_end_pad=0;
951     st->clients=NULL;
952     st->routes=NULL;
953     st->n_clients=0;
954     st->set_routes=set_routes;
955     st->deliver_to_host=to_host;
956
957     st->name=dict_read_string(dict,"name",False,description,loc);
958     if (!st->name) st->name=description;
959     l=dict_lookup(dict,"networks");
960     if (l) 
961         st->networks=string_list_to_ipset(l,loc,st->name,"networks");
962     else {
963         struct ipset *empty;
964         empty=ipset_new();
965         st->networks=ipset_complement(empty);
966         ipset_free(empty);
967     }
968     l=dict_lookup(dict,"remote-networks");
969     if (l) {
970         st->remote_networks=string_list_to_ipset(l,loc,st->name,
971                                                  "remote-networks");
972     } else {
973         struct ipset *empty;
974         empty=ipset_new();
975         st->remote_networks=ipset_complement(empty);
976         ipset_free(empty);
977     }
978
979     sa=dict_find_item(dict,"secnet-address",False,"netlink",loc);
980     ptpa=dict_find_item(dict,"ptp-address",False,"netlink",loc);
981     if (sa && ptpa) {
982         cfgfatal(loc,st->name,"you may not specify secnet-address and "
983                  "ptp-address in the same netlink device\n");
984     }
985     if (!(sa || ptpa)) {
986         cfgfatal(loc,st->name,"you must specify secnet-address or "
987                  "ptp-address for this netlink device\n");
988     }
989     if (sa) {
990         st->secnet_address=string_item_to_ipaddr(sa,"netlink");
991         st->ptp=False;
992     } else {
993         st->secnet_address=string_item_to_ipaddr(ptpa,"netlink");
994         st->ptp=True;
995     }
996     /* To be strictly correct we could subtract secnet_address from
997        networks here.  It shouldn't make any practical difference,
998        though, and will make the route dump look complicated... */
999     st->subnets=ipset_to_subnet_list(st->networks);
1000     st->mtu=dict_read_number(dict, "mtu", False, "netlink", loc, DEFAULT_MTU);
1001     buffer_new(&st->icmp,ICMP_BUFSIZE);
1002     st->outcount=0;
1003     st->localcount=0;
1004
1005     add_hook(PHASE_SETUP,netlink_phase_hook,st);
1006     request_signal_notification(SIGUSR1, netlink_signal_handler, st);
1007
1008     /* If we're point-to-point then we return a CL_NETLINK directly,
1009        rather than a CL_NETLINK_OLD or pure closure (depending on
1010        compatibility).  This CL_NETLINK is for our one and only
1011        client.  Our cl.apply function is NULL. */
1012     if (st->ptp) {
1013         closure_t *cl;
1014         cl=netlink_inst_create(st,loc,dict);
1015         st->cl=*cl;
1016     }
1017     return netlink_dev_incoming;
1018 }
1019
1020 /* No connection to the kernel at all... */
1021
1022 struct null {
1023     struct netlink nl;
1024 };
1025
1026 static bool_t null_set_route(void *sst, struct netlink_client *routes)
1027 {
1028     struct null *st=sst;
1029
1030     if (routes->up!=routes->kup) {
1031         Message(M_INFO,"%s: setting routes for tunnel %s to state %s\n",
1032                 st->nl.name,routes->name,
1033                 routes->up?"up":"down");
1034         routes->kup=routes->up;
1035         return True;
1036     }
1037     return False;
1038 }
1039             
1040 static void null_deliver(void *sst, struct buffer_if *buf)
1041 {
1042     return;
1043 }
1044
1045 static list_t *null_apply(closure_t *self, struct cloc loc, dict_t *context,
1046                           list_t *args)
1047 {
1048     struct null *st;
1049     item_t *item;
1050     dict_t *dict;
1051
1052     st=safe_malloc(sizeof(*st),"null_apply");
1053
1054     item=list_elem(args,0);
1055     if (!item || item->type!=t_dict)
1056         cfgfatal(loc,"null-netlink","parameter must be a dictionary\n");
1057     
1058     dict=item->data.dict;
1059
1060     netlink_init(&st->nl,st,loc,dict,"null-netlink",null_set_route,
1061                  null_deliver);
1062
1063     return new_closure(&st->nl.cl);
1064 }
1065
1066 void netlink_module(dict_t *dict)
1067 {
1068     add_closure(dict,"null-netlink",null_apply);
1069 }