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