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