chiark / gitweb /
netlink: report why a packet is bad
[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_output_config(void *sst, struct buffer_if *buf)
807 {
808 /*    struct netlink_client *c=sst; */
809 /*    struct netlink *st=c->nst; */
810
811     /* For now we don't output anything */
812     BUF_ASSERT_USED(buf);
813 }
814
815 static bool_t netlink_inst_check_config(void *sst, struct buffer_if *buf)
816 {
817 /*    struct netlink_client *c=sst; */
818 /*    struct netlink *st=c->nst; */
819
820     BUF_ASSERT_USED(buf);
821     /* We need to eat all of the configuration information from the buffer
822        for backward compatibility. */
823     buf->size=0;
824     return True;
825 }
826
827 static void netlink_inst_set_mtu(void *sst, int32_t new_mtu)
828 {
829     struct netlink_client *c=sst;
830
831     c->mtu=new_mtu;
832 }
833
834 static void netlink_inst_reg(void *sst, netlink_deliver_fn *deliver, 
835                              void *dst, int32_t max_start_pad,
836                              int32_t max_end_pad)
837 {
838     struct netlink_client *c=sst;
839     struct netlink *st=c->nst;
840
841     if (max_start_pad > st->max_start_pad) st->max_start_pad=max_start_pad;
842     if (max_end_pad > st->max_end_pad) st->max_end_pad=max_end_pad;
843     c->deliver=deliver;
844     c->dst=dst;
845 }
846
847 static struct flagstr netlink_option_table[]={
848     { "soft", OPT_SOFTROUTE },
849     { "allow-route", OPT_ALLOWROUTE },
850     { NULL, 0}
851 };
852 /* This is the routine that gets called when the closure that's
853    returned by an invocation of a netlink device closure (eg. tun,
854    userv-ipif) is invoked.  It's used to create routes and pass in
855    information about them; the closure it returns is used by site
856    code.  */
857 static closure_t *netlink_inst_create(struct netlink *st,
858                                       struct cloc loc, dict_t *dict)
859 {
860     struct netlink_client *c;
861     string_t name;
862     struct ipset *networks;
863     uint32_t options,priority;
864     int32_t mtu;
865     list_t *l;
866
867     name=dict_read_string(dict, "name", True, st->name, loc);
868
869     l=dict_lookup(dict,"routes");
870     if (!l)
871         cfgfatal(loc,st->name,"required parameter \"routes\" not found\n");
872     networks=string_list_to_ipset(l,loc,st->name,"routes");
873     options=string_list_to_word(dict_lookup(dict,"options"),
874                                 netlink_option_table,st->name);
875
876     priority=dict_read_number(dict,"priority",False,st->name,loc,0);
877     mtu=dict_read_number(dict,"mtu",False,st->name,loc,0);
878
879     if ((options&OPT_SOFTROUTE) && !st->set_routes) {
880         cfgfatal(loc,st->name,"this netlink device does not support "
881                  "soft routes.\n");
882         return NULL;
883     }
884
885     if (options&OPT_SOFTROUTE) {
886         /* XXX for now we assume that soft routes require root privilege;
887            this may not always be true. The device driver can tell us. */
888         require_root_privileges=True;
889         require_root_privileges_explanation="netlink: soft routes";
890         if (st->ptp) {
891             cfgfatal(loc,st->name,"point-to-point netlinks do not support "
892                      "soft routes.\n");
893             return NULL;
894         }
895     }
896
897     /* Check that nets are a subset of st->remote_networks;
898        refuse to register if they are not. */
899     if (!ipset_is_subset(st->remote_networks,networks)) {
900         cfgfatal(loc,st->name,"routes are not allowed\n");
901         return NULL;
902     }
903
904     c=safe_malloc(sizeof(*c),"netlink_inst_create");
905     c->cl.description=name;
906     c->cl.type=CL_NETLINK;
907     c->cl.apply=NULL;
908     c->cl.interface=&c->ops;
909     c->ops.st=c;
910     c->ops.reg=netlink_inst_reg;
911     c->ops.deliver=netlink_inst_incoming;
912     c->ops.set_quality=netlink_set_quality;
913     c->ops.output_config=netlink_inst_output_config;
914     c->ops.check_config=netlink_inst_check_config;
915     c->ops.set_mtu=netlink_inst_set_mtu;
916     c->nst=st;
917
918     c->networks=networks;
919     c->subnets=ipset_to_subnet_list(networks);
920     c->priority=priority;
921     c->deliver=NULL;
922     c->dst=NULL;
923     c->name=name;
924     c->link_quality=LINK_QUALITY_UNUSED;
925     c->mtu=mtu?mtu:st->mtu;
926     c->options=options;
927     c->outcount=0;
928     c->up=False;
929     c->kup=False;
930     c->next=st->clients;
931     st->clients=c;
932     assert(st->n_clients < INT_MAX);
933     st->n_clients++;
934
935     return &c->cl;
936 }
937
938 static list_t *netlink_inst_apply(closure_t *self, struct cloc loc,
939                                   dict_t *context, list_t *args)
940 {
941     struct netlink *st=self->interface;
942
943     dict_t *dict;
944     item_t *item;
945     closure_t *cl;
946
947     item=list_elem(args,0);
948     if (!item || item->type!=t_dict) {
949         cfgfatal(loc,st->name,"must have a dictionary argument\n");
950     }
951     dict=item->data.dict;
952
953     cl=netlink_inst_create(st,loc,dict);
954
955     return new_closure(cl);
956 }
957
958 netlink_deliver_fn *netlink_init(struct netlink *st,
959                                  void *dst, struct cloc loc,
960                                  dict_t *dict, cstring_t description,
961                                  netlink_route_fn *set_routes,
962                                  netlink_deliver_fn *to_host)
963 {
964     item_t *sa, *ptpa;
965     list_t *l;
966
967     st->dst=dst;
968     st->cl.description=description;
969     st->cl.type=CL_PURE;
970     st->cl.apply=netlink_inst_apply;
971     st->cl.interface=st;
972     st->max_start_pad=0;
973     st->max_end_pad=0;
974     st->clients=NULL;
975     st->routes=NULL;
976     st->n_clients=0;
977     st->set_routes=set_routes;
978     st->deliver_to_host=to_host;
979
980     st->name=dict_read_string(dict,"name",False,description,loc);
981     if (!st->name) st->name=description;
982     l=dict_lookup(dict,"networks");
983     if (l) 
984         st->networks=string_list_to_ipset(l,loc,st->name,"networks");
985     else {
986         struct ipset *empty;
987         empty=ipset_new();
988         st->networks=ipset_complement(empty);
989         ipset_free(empty);
990     }
991     l=dict_lookup(dict,"remote-networks");
992     if (l) {
993         st->remote_networks=string_list_to_ipset(l,loc,st->name,
994                                                  "remote-networks");
995     } else {
996         struct ipset *empty;
997         empty=ipset_new();
998         st->remote_networks=ipset_complement(empty);
999         ipset_free(empty);
1000     }
1001
1002     sa=dict_find_item(dict,"secnet-address",False,"netlink",loc);
1003     ptpa=dict_find_item(dict,"ptp-address",False,"netlink",loc);
1004     if (sa && ptpa) {
1005         cfgfatal(loc,st->name,"you may not specify secnet-address and "
1006                  "ptp-address in the same netlink device\n");
1007     }
1008     if (!(sa || ptpa)) {
1009         cfgfatal(loc,st->name,"you must specify secnet-address or "
1010                  "ptp-address for this netlink device\n");
1011     }
1012     if (sa) {
1013         st->secnet_address=string_item_to_ipaddr(sa,"netlink");
1014         st->ptp=False;
1015     } else {
1016         st->secnet_address=string_item_to_ipaddr(ptpa,"netlink");
1017         st->ptp=True;
1018     }
1019     /* To be strictly correct we could subtract secnet_address from
1020        networks here.  It shouldn't make any practical difference,
1021        though, and will make the route dump look complicated... */
1022     st->subnets=ipset_to_subnet_list(st->networks);
1023     st->mtu=dict_read_number(dict, "mtu", False, "netlink", loc, DEFAULT_MTU);
1024     buffer_new(&st->icmp,ICMP_BUFSIZE);
1025     st->outcount=0;
1026     st->localcount=0;
1027
1028     add_hook(PHASE_SETUP,netlink_phase_hook,st);
1029     request_signal_notification(SIGUSR1, netlink_signal_handler, st);
1030
1031     /* If we're point-to-point then we return a CL_NETLINK directly,
1032        rather than a CL_NETLINK_OLD or pure closure (depending on
1033        compatibility).  This CL_NETLINK is for our one and only
1034        client.  Our cl.apply function is NULL. */
1035     if (st->ptp) {
1036         closure_t *cl;
1037         cl=netlink_inst_create(st,loc,dict);
1038         st->cl=*cl;
1039     }
1040     return netlink_dev_incoming;
1041 }
1042
1043 /* No connection to the kernel at all... */
1044
1045 struct null {
1046     struct netlink nl;
1047 };
1048
1049 static bool_t null_set_route(void *sst, struct netlink_client *routes)
1050 {
1051     struct null *st=sst;
1052
1053     if (routes->up!=routes->kup) {
1054         Message(M_INFO,"%s: setting routes for tunnel %s to state %s\n",
1055                 st->nl.name,routes->name,
1056                 routes->up?"up":"down");
1057         routes->kup=routes->up;
1058         return True;
1059     }
1060     return False;
1061 }
1062             
1063 static void null_deliver(void *sst, struct buffer_if *buf)
1064 {
1065     return;
1066 }
1067
1068 static list_t *null_apply(closure_t *self, struct cloc loc, dict_t *context,
1069                           list_t *args)
1070 {
1071     struct null *st;
1072     item_t *item;
1073     dict_t *dict;
1074
1075     st=safe_malloc(sizeof(*st),"null_apply");
1076
1077     item=list_elem(args,0);
1078     if (!item || item->type!=t_dict)
1079         cfgfatal(loc,"null-netlink","parameter must be a dictionary\n");
1080     
1081     dict=item->data.dict;
1082
1083     netlink_init(&st->nl,st,loc,dict,"null-netlink",null_set_route,
1084                  null_deliver);
1085
1086     return new_closure(&st->nl.cl);
1087 }
1088
1089 void netlink_module(dict_t *dict)
1090 {
1091     add_closure(dict,"null-netlink",null_apply);
1092 }