1947ddbace504d6166ce9f12b2c49aa609c48705
[strongswan.git] / src / pluto / kernel_netlink.c
1 /* netlink interface to the kernel's IPsec mechanism
2 * Copyright (C) 2003 Herbert Xu.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * RCSID $Id: kernel_netlink.c,v 1.24 2006/03/10 14:49:43 as Exp $
15 */
16
17 #if defined(linux) && defined(KERNEL26_SUPPORT)
18
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <string.h>
22 #include <sys/queue.h>
23 #include <sys/socket.h>
24 #include <sys/types.h>
25 #include <sys/queue.h>
26 #include <unistd.h>
27
28 #include "kameipsec.h"
29 #include "linux26/rtnetlink.h"
30 #include "linux26/xfrm.h"
31
32 #include <freeswan.h>
33 #include <pfkeyv2.h>
34 #include <pfkey.h>
35
36 #include "constants.h"
37 #include "defs.h"
38 #include "kernel.h"
39 #include "kernel_netlink.h"
40 #include "kernel_pfkey.h"
41 #include "log.h"
42 #include "whack.h" /* for RC_LOG_SERIOUS */
43 #include "kernel_alg.h"
44
45 /* Minimum priority number in SPD used by pluto. */
46 #define MIN_SPD_PRIORITY 1024
47
48 static int netlinkfd = NULL_FD;
49 static int netlink_bcast_fd = NULL_FD;
50
51 #define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
52
53 static sparse_names xfrm_type_names = {
54 NE(NLMSG_NOOP),
55 NE(NLMSG_ERROR),
56 NE(NLMSG_DONE),
57 NE(NLMSG_OVERRUN),
58
59 NE(XFRM_MSG_NEWSA),
60 NE(XFRM_MSG_DELSA),
61 NE(XFRM_MSG_GETSA),
62
63 NE(XFRM_MSG_NEWPOLICY),
64 NE(XFRM_MSG_DELPOLICY),
65 NE(XFRM_MSG_GETPOLICY),
66
67 NE(XFRM_MSG_ALLOCSPI),
68 NE(XFRM_MSG_ACQUIRE),
69 NE(XFRM_MSG_EXPIRE),
70
71 NE(XFRM_MSG_UPDPOLICY),
72 NE(XFRM_MSG_UPDSA),
73
74 NE(XFRM_MSG_POLEXPIRE),
75
76 NE(XFRM_MSG_MAX),
77
78 { 0, sparse_end }
79 };
80
81 #undef NE
82
83 /* Authentication algorithms */
84 static sparse_names aalg_list = {
85 { SADB_X_AALG_NULL, "digest_null" },
86 { SADB_AALG_MD5_HMAC, "md5" },
87 { SADB_AALG_SHA1_HMAC, "sha1" },
88 { SADB_AALG_SHA2_256_HMAC, "sha256" },
89 { SADB_AALG_SHA2_384_HMAC, "sha384" },
90 { SADB_AALG_SHA2_512_HMAC, "sha512" },
91 { SADB_AALG_RIPEMD_160_HMAC, "ripemd160" },
92 { SADB_X_AALG_NULL, "null" },
93 { 0, sparse_end }
94 };
95
96 /* Encryption algorithms */
97 static sparse_names ealg_list = {
98 { SADB_EALG_NULL, "cipher_null" },
99 { SADB_EALG_DES_CBC, "des" },
100 { SADB_EALG_3DES_CBC, "des3_ede" },
101 { SADB_EALG_IDEA_CBC, "idea" },
102 { SADB_EALG_CAST_CBC, "cast128" },
103 { SADB_EALG_BLOWFISH_CBC, "blowfish" },
104 { SADB_EALG_AES_CBC, "aes" },
105 { SADB_X_EALG_SERPENT_CBC, "serpent" },
106 { SADB_X_EALG_TWOFISH_CBC, "twofish" },
107 { 0, sparse_end }
108 };
109
110 /* Compression algorithms */
111 static sparse_names calg_list = {
112 { SADB_X_CALG_DEFLATE, "deflate" },
113 { SADB_X_CALG_LZS, "lzs" },
114 { SADB_X_CALG_LZJH, "lzjh" },
115 { 0, sparse_end }
116 };
117
118 /** ip2xfrm - Take an IP address and convert to an xfrm.
119 *
120 * @param addr ip_address
121 * @param xaddr xfrm_address_t - IPv[46] Address from addr is copied here.
122 */
123 static void
124 ip2xfrm(const ip_address *addr, xfrm_address_t *xaddr)
125 {
126 if (addr->u.v4.sin_family == AF_INET)
127 {
128 xaddr->a4 = addr->u.v4.sin_addr.s_addr;
129 }
130 else
131 {
132 memcpy(xaddr->a6, &addr->u.v6.sin6_addr, sizeof(xaddr->a6));
133 }
134 }
135
136 /** init_netlink - Initialize the netlink inferface. Opens the sockets and
137 * then binds to the broadcast socket.
138 */
139 static void
140 init_netlink(void)
141 {
142 struct sockaddr_nl addr;
143
144 netlinkfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
145
146 if (netlinkfd < 0)
147 exit_log_errno((e, "socket() in init_netlink()"));
148
149 if (fcntl(netlinkfd, F_SETFD, FD_CLOEXEC) != 0)
150 exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_netlink()"));
151
152 netlink_bcast_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
153
154 if (netlink_bcast_fd < 0)
155 exit_log_errno((e, "socket() for bcast in init_netlink()"));
156
157 if (fcntl(netlink_bcast_fd, F_SETFD, FD_CLOEXEC) != 0)
158 exit_log_errno((e, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"));
159
160 if (fcntl(netlink_bcast_fd, F_SETFL, O_NONBLOCK) != 0)
161 exit_log_errno((e, "fcntl(O_NONBLOCK) for bcast in init_netlink()"));
162
163 addr.nl_family = AF_NETLINK;
164 addr.nl_pid = getpid();
165 addr.nl_groups = XFRMGRP_ACQUIRE | XFRMGRP_EXPIRE;
166 if (bind(netlink_bcast_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
167 exit_log_errno((e, "Failed to bind bcast socket in init_netlink()"));
168 }
169
170 /** send_netlink_msg
171 *
172 * @param hdr - Data to be sent.
173 * @param rbuf - Return Buffer - contains data returned from the send.
174 * @param rbuf_len - Length of rbuf
175 * @param description - String - user friendly description of what is
176 * being attempted. Used for diagnostics
177 * @param text_said - String
178 * @return bool True if the message was succesfully sent.
179 */
180 static bool
181 send_netlink_msg(struct nlmsghdr *hdr, struct nlmsghdr *rbuf, size_t rbuf_len
182 , const char *description, const char *text_said)
183 {
184 struct {
185 struct nlmsghdr n;
186 struct nlmsgerr e;
187 char data[1024];
188 } rsp;
189
190 size_t len;
191 ssize_t r;
192 struct sockaddr_nl addr;
193 static uint32_t seq;
194
195 if (no_klips)
196 {
197 return TRUE;
198 }
199
200 hdr->nlmsg_seq = ++seq;
201 len = hdr->nlmsg_len;
202 do {
203 r = write(netlinkfd, hdr, len);
204 } while (r < 0 && errno == EINTR);
205 if (r < 0)
206 {
207 log_errno((e
208 , "netlink write() of %s message"
209 " for %s %s failed"
210 , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
211 , description, text_said));
212 return FALSE;
213 }
214 else if ((size_t)r != len)
215 {
216 loglog(RC_LOG_SERIOUS
217 , "ERROR: netlink write() of %s message"
218 " for %s %s truncated: %ld instead of %lu"
219 , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
220 , description, text_said
221 , (long)r, (unsigned long)len);
222 return FALSE;
223 }
224
225 for (;;) {
226 socklen_t alen;
227
228 alen = sizeof(addr);
229 r = recvfrom(netlinkfd, &rsp, sizeof(rsp), 0
230 , (struct sockaddr *)&addr, &alen);
231 if (r < 0)
232 {
233 if (errno == EINTR)
234 {
235 continue;
236 }
237 log_errno((e
238 , "netlink recvfrom() of response to our %s message"
239 " for %s %s failed"
240 , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
241 , description, text_said));
242 return FALSE;
243 }
244 else if ((size_t) r < sizeof(rsp.n))
245 {
246 plog("netlink read truncated message: %ld bytes; ignore message"
247 , (long) r);
248 continue;
249 }
250 else if (addr.nl_pid != 0)
251 {
252 /* not for us: ignore */
253 DBG(DBG_KLIPS,
254 DBG_log("netlink: ignoring %s message from process %u"
255 , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
256 , addr.nl_pid));
257 continue;
258 }
259 else if (rsp.n.nlmsg_seq != seq)
260 {
261 DBG(DBG_KLIPS,
262 DBG_log("netlink: ignoring out of sequence (%u/%u) message %s"
263 , rsp.n.nlmsg_seq, seq
264 , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
265 continue;
266 }
267 break;
268 }
269
270 if (rsp.n.nlmsg_len > (size_t) r)
271 {
272 loglog(RC_LOG_SERIOUS
273 , "netlink recvfrom() of response to our %s message"
274 " for %s %s was truncated: %ld instead of %lu"
275 , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
276 , description, text_said
277 , (long) len, (unsigned long) rsp.n.nlmsg_len);
278 return FALSE;
279 }
280 else if (rsp.n.nlmsg_type != NLMSG_ERROR
281 && (rbuf && rsp.n.nlmsg_type != rbuf->nlmsg_type))
282 {
283 loglog(RC_LOG_SERIOUS
284 , "netlink recvfrom() of response to our %s message"
285 " for %s %s was of wrong type (%s)"
286 , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
287 , description, text_said
288 , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type));
289 return FALSE;
290 }
291 else if (rbuf)
292 {
293 if ((size_t) r > rbuf_len)
294 {
295 loglog(RC_LOG_SERIOUS
296 , "netlink recvfrom() of response to our %s message"
297 " for %s %s was too long: %ld > %lu"
298 , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
299 , description, text_said
300 , (long)r, (unsigned long)rbuf_len);
301 return FALSE;
302 }
303 memcpy(rbuf, &rsp, r);
304 return TRUE;
305 }
306 else if (rsp.n.nlmsg_type == NLMSG_ERROR && rsp.e.error)
307 {
308 loglog(RC_LOG_SERIOUS
309 , "ERROR: netlink response for %s %s included errno %d: %s"
310 , description, text_said
311 , -rsp.e.error
312 , strerror(-rsp.e.error));
313 return FALSE;
314 }
315
316 return TRUE;
317 }
318
319 /** netlink_policy -
320 *
321 * @param hdr - Data to check
322 * @param enoent_ok - Boolean - OK or not OK.
323 * @param text_said - String
324 * @return boolean
325 */
326 static bool
327 netlink_policy(struct nlmsghdr *hdr, bool enoent_ok, const char *text_said)
328 {
329 struct {
330 struct nlmsghdr n;
331 struct nlmsgerr e;
332 } rsp;
333 int error;
334
335 rsp.n.nlmsg_type = NLMSG_ERROR;
336 if (!send_netlink_msg(hdr, &rsp.n, sizeof(rsp), "policy", text_said))
337 {
338 return FALSE;
339 }
340
341 error = -rsp.e.error;
342 if (!error)
343 {
344 return TRUE;
345 }
346
347 if (error == ENOENT && enoent_ok)
348 {
349 return TRUE;
350 }
351
352 loglog(RC_LOG_SERIOUS
353 , "ERROR: netlink %s response for flow %s included errno %d: %s"
354 , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
355 , text_said
356 , error
357 , strerror(error));
358 return FALSE;
359 }
360
361 /** netlink_raw_eroute
362 *
363 * @param this_host ip_address
364 * @param this_client ip_subnet
365 * @param that_host ip_address
366 * @param that_client ip_subnet
367 * @param spi
368 * @param proto int (Currently unused) Contains protocol (u=tcp, 17=udp, etc...)
369 * @param transport_proto int (Currently unused) 0=tunnel, 1=transport
370 * @param satype int
371 * @param proto_info
372 * @param lifetime (Currently unused)
373 * @param ip int
374 * @return boolean True if successful
375 */
376 static bool
377 netlink_raw_eroute(const ip_address *this_host
378 , const ip_subnet *this_client
379 , const ip_address *that_host
380 , const ip_subnet *that_client
381 , ipsec_spi_t spi
382 , unsigned int satype
383 , unsigned int transport_proto
384 , const struct pfkey_proto_info *proto_info
385 , time_t use_lifetime UNUSED
386 , unsigned int op
387 , const char *text_said)
388 {
389 struct {
390 struct nlmsghdr n;
391 union {
392 struct xfrm_userpolicy_info p;
393 struct xfrm_userpolicy_id id;
394 } u;
395 char data[1024];
396 } req;
397 int shift;
398 int dir;
399 int family;
400 int policy;
401 bool ok;
402 bool enoent_ok;
403
404 policy = IPSEC_POLICY_IPSEC;
405
406 if (satype == SADB_X_SATYPE_INT)
407 {
408 /* shunt route */
409 switch (ntohl(spi))
410 {
411 case SPI_PASS:
412 policy = IPSEC_POLICY_NONE;
413 break;
414 case SPI_DROP:
415 case SPI_REJECT:
416 default:
417 policy = IPSEC_POLICY_DISCARD;
418 break;
419 case SPI_TRAP:
420 case SPI_TRAPSUBNET:
421 case SPI_HOLD:
422 if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
423 {
424 return TRUE;
425 }
426 break;
427 }
428 }
429
430 memset(&req, 0, sizeof(req));
431 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
432
433 family = that_client->addr.u.v4.sin_family;
434 shift = (family == AF_INET) ? 5 : 7;
435
436 req.u.p.sel.sport = portof(&this_client->addr);
437 req.u.p.sel.dport = portof(&that_client->addr);
438 req.u.p.sel.sport_mask = (req.u.p.sel.sport) ? ~0:0;
439 req.u.p.sel.dport_mask = (req.u.p.sel.dport) ? ~0:0;
440 ip2xfrm(&this_client->addr, &req.u.p.sel.saddr);
441 ip2xfrm(&that_client->addr, &req.u.p.sel.daddr);
442 req.u.p.sel.prefixlen_s = this_client->maskbits;
443 req.u.p.sel.prefixlen_d = that_client->maskbits;
444 req.u.p.sel.proto = transport_proto;
445 req.u.p.sel.family = family;
446
447 dir = XFRM_POLICY_OUT;
448 if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
449 {
450 dir = XFRM_POLICY_IN;
451 }
452
453 if ((op & ERO_MASK) == ERO_DELETE)
454 {
455 req.u.id.dir = dir;
456 req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
457 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.id)));
458 }
459 else
460 {
461 int src, dst;
462
463 req.u.p.dir = dir;
464
465 src = req.u.p.sel.prefixlen_s;
466 dst = req.u.p.sel.prefixlen_d;
467 if (dir != XFRM_POLICY_OUT) {
468 src = req.u.p.sel.prefixlen_d;
469 dst = req.u.p.sel.prefixlen_s;
470 }
471 req.u.p.priority = MIN_SPD_PRIORITY
472 + (((2 << shift) - src) << shift)
473 + (2 << shift) - dst;
474
475 req.u.p.action = XFRM_POLICY_ALLOW;
476 if (policy == IPSEC_POLICY_DISCARD)
477 {
478 req.u.p.action = XFRM_POLICY_BLOCK;
479 }
480 req.u.p.lft.soft_use_expires_seconds = use_lifetime;
481 req.u.p.lft.soft_byte_limit = XFRM_INF;
482 req.u.p.lft.soft_packet_limit = XFRM_INF;
483 req.u.p.lft.hard_byte_limit = XFRM_INF;
484 req.u.p.lft.hard_packet_limit = XFRM_INF;
485
486 req.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
487 if (op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
488 {
489 req.n.nlmsg_type = XFRM_MSG_UPDPOLICY;
490 }
491 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)));
492 }
493
494 if (policy == IPSEC_POLICY_IPSEC && (op & ERO_MASK) != ERO_DELETE)
495 {
496 struct rtattr *attr;
497 struct xfrm_user_tmpl tmpl[4];
498 int i;
499
500 memset(tmpl, 0, sizeof(tmpl));
501 for (i = 0; proto_info[i].proto; i++)
502 {
503 tmpl[i].reqid = proto_info[i].reqid;
504 tmpl[i].id.proto = proto_info[i].proto;
505 tmpl[i].optional =
506 proto_info[i].proto == IPPROTO_COMP && dir != XFRM_POLICY_OUT;
507 tmpl[i].aalgos = tmpl[i].ealgos = tmpl[i].calgos = ~0;
508 tmpl[i].mode =
509 proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
510
511 if (!tmpl[i].mode)
512 {
513 continue;
514 }
515
516 ip2xfrm(this_host, &tmpl[i].saddr);
517 ip2xfrm(that_host, &tmpl[i].id.daddr);
518 }
519
520 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
521 attr->rta_type = XFRMA_TMPL;
522 attr->rta_len = i * sizeof(tmpl[0]);
523 memcpy(RTA_DATA(attr), tmpl, attr->rta_len);
524 attr->rta_len = RTA_LENGTH(attr->rta_len);
525 req.n.nlmsg_len += attr->rta_len;
526 }
527
528 enoent_ok = FALSE;
529 if (op == ERO_DEL_INBOUND)
530 {
531 enoent_ok = TRUE;
532 }
533 else if (op == ERO_DELETE && ntohl(spi) == SPI_HOLD)
534 {
535 enoent_ok = TRUE;
536 }
537
538 ok = netlink_policy(&req.n, enoent_ok, text_said);
539 switch (dir)
540 {
541 case XFRM_POLICY_IN:
542 if (req.n.nlmsg_type == XFRM_MSG_DELPOLICY)
543 {
544 req.u.id.dir = XFRM_POLICY_FWD;
545 }
546 else if (!ok)
547 {
548 break;
549 }
550 else if (proto_info[0].encapsulation != ENCAPSULATION_MODE_TUNNEL
551 && satype != SADB_X_SATYPE_INT)
552 {
553 break;
554 }
555 else
556 {
557 req.u.p.dir = XFRM_POLICY_FWD;
558 }
559 ok &= netlink_policy(&req.n, enoent_ok, text_said);
560 break;
561 }
562
563 return ok;
564 }
565
566 /** netlink_add_sa - Add an SA into the kernel SPDB via netlink
567 *
568 * @param sa Kernel SA to add/modify
569 * @param replace boolean - true if this replaces an existing SA
570 * @return bool True if successfull
571 */
572 static bool
573 netlink_add_sa(const struct kernel_sa *sa, bool replace)
574 {
575 struct {
576 struct nlmsghdr n;
577 struct xfrm_usersa_info p;
578 char data[1024];
579 } req;
580 struct rtattr *attr;
581
582 memset(&req, 0, sizeof(req));
583 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
584 req.n.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
585
586 ip2xfrm(sa->src, &req.p.saddr);
587 ip2xfrm(sa->dst, &req.p.id.daddr);
588
589 req.p.id.spi = sa->spi;
590 req.p.id.proto = satype2proto(sa->satype);
591 req.p.family = sa->src->u.v4.sin_family;
592 req.p.mode = (sa->encapsulation == ENCAPSULATION_MODE_TUNNEL);
593 req.p.replay_window = sa->replay_window;
594 req.p.reqid = sa->reqid;
595 req.p.lft.soft_byte_limit = XFRM_INF;
596 req.p.lft.soft_packet_limit = XFRM_INF;
597 req.p.lft.hard_byte_limit = XFRM_INF;
598 req.p.lft.hard_packet_limit = XFRM_INF;
599
600 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.p)));
601
602 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
603
604 if (sa->authalg)
605 {
606 struct xfrm_algo algo;
607 const char *name;
608
609 name = sparse_name(aalg_list, sa->authalg);
610 if (!name) {
611 loglog(RC_LOG_SERIOUS, "unknown authentication algorithm: %u"
612 , sa->authalg);
613 return FALSE;
614 }
615
616 strcpy(algo.alg_name, name);
617 algo.alg_key_len = sa->authkeylen * BITS_PER_BYTE;
618
619 attr->rta_type = XFRMA_ALG_AUTH;
620 attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->authkeylen);
621
622 memcpy(RTA_DATA(attr), &algo, sizeof(algo));
623 memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->authkey
624 , sa->authkeylen);
625
626 req.n.nlmsg_len += attr->rta_len;
627 attr = (struct rtattr *)((char *)attr + attr->rta_len);
628 }
629
630 if (sa->encalg)
631 {
632 struct xfrm_algo algo;
633 const char *name;
634
635 name = sparse_name(ealg_list, sa->encalg);
636 if (!name) {
637 loglog(RC_LOG_SERIOUS, "unknown encryption algorithm: %u"
638 , sa->encalg);
639 return FALSE;
640 }
641
642 strcpy(algo.alg_name, name);
643 algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE;
644
645 attr->rta_type = XFRMA_ALG_CRYPT;
646 attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen);
647
648 memcpy(RTA_DATA(attr), &algo, sizeof(algo));
649 memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->enckey
650 , sa->enckeylen);
651
652 req.n.nlmsg_len += attr->rta_len;
653 attr = (struct rtattr *)((char *)attr + attr->rta_len);
654 }
655
656 if (sa->compalg)
657 {
658 struct xfrm_algo algo;
659 const char *name;
660
661 name = sparse_name(calg_list, sa->compalg);
662 if (!name) {
663 loglog(RC_LOG_SERIOUS, "unknown compression algorithm: %u"
664 , sa->compalg);
665 return FALSE;
666 }
667
668 strcpy(algo.alg_name, name);
669 algo.alg_key_len = 0;
670
671 attr->rta_type = XFRMA_ALG_COMP;
672 attr->rta_len = RTA_LENGTH(sizeof(algo));
673
674 memcpy(RTA_DATA(attr), &algo, sizeof(algo));
675
676 req.n.nlmsg_len += attr->rta_len;
677 attr = (struct rtattr *)((char *)attr + attr->rta_len);
678 }
679
680 if (sa->natt_type)
681 {
682 struct xfrm_encap_tmpl natt;
683
684 natt.encap_type = sa->natt_type;
685 natt.encap_sport = ntohs(sa->natt_sport);
686 natt.encap_dport = ntohs(sa->natt_dport);
687 memset (&natt.encap_oa, 0, sizeof (natt.encap_oa));
688
689 attr->rta_type = XFRMA_ENCAP;
690 attr->rta_len = RTA_LENGTH(sizeof(natt));
691
692 memcpy(RTA_DATA(attr), &natt, sizeof(natt));
693
694 req.n.nlmsg_len += attr->rta_len;
695 attr = (struct rtattr *)((char *)attr + attr->rta_len);
696 }
697
698 return send_netlink_msg(&req.n, NULL, 0, "Add SA", sa->text_said);
699 }
700
701 /** netlink_del_sa - Delete an SA from the Kernel
702 *
703 * @param sa Kernel SA to be deleted
704 * @return bool True if successfull
705 */
706 static bool
707 netlink_del_sa(const struct kernel_sa *sa)
708 {
709 struct {
710 struct nlmsghdr n;
711 struct xfrm_usersa_id id;
712 char data[1024];
713 } req;
714
715 memset(&req, 0, sizeof(req));
716 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
717 req.n.nlmsg_type = XFRM_MSG_DELSA;
718
719 ip2xfrm(sa->dst, &req.id.daddr);
720
721 req.id.spi = sa->spi;
722 req.id.family = sa->src->u.v4.sin_family;
723 req.id.proto = sa->proto;
724
725 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
726
727 return send_netlink_msg(&req.n, NULL, 0, "Del SA", sa->text_said);
728 }
729
730 static bool
731 netlink_error(const char *req_type, const struct nlmsghdr *n
732 , const struct nlmsgerr *e, int rsp_size)
733 {
734 if (n->nlmsg_type == NLMSG_ERROR)
735 {
736 DBG(DBG_KLIPS,
737 DBG_log("%s returned with errno %d: %s"
738 , req_type
739 , -e->error
740 , strerror(-e->error))
741 )
742 return TRUE;
743 }
744 if (n->nlmsg_len < NLMSG_LENGTH(rsp_size))
745 {
746 plog("%s returned message with length %lu < %lu bytes"
747 , req_type
748 , (unsigned long) n->nlmsg_len
749 , (unsigned long) rsp_size);
750 return TRUE;
751 }
752 return FALSE;
753 }
754
755 static bool
756 netlink_get_policy(const struct kernel_sa *sa, bool inbound, time_t *use_time)
757 {
758 struct {
759 struct nlmsghdr n;
760 struct xfrm_userpolicy_id id;
761 } req;
762
763 struct {
764 struct nlmsghdr n;
765 union {
766 struct nlmsgerr e;
767 struct xfrm_userpolicy_info info;
768 } u;
769 char data[1024];
770 } rsp;
771
772 memset(&req, 0, sizeof(req));
773 req.n.nlmsg_flags = NLM_F_REQUEST;
774 req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
775
776 req.id.sel.sport = portof(&sa->src_client->addr);
777 req.id.sel.dport = portof(&sa->dst_client->addr);
778 req.id.sel.sport_mask = (req.id.sel.sport) ? ~0:0;
779 req.id.sel.dport_mask = (req.id.sel.dport) ? ~0:0;
780 ip2xfrm(&sa->src_client->addr, &req.id.sel.saddr);
781 ip2xfrm(&sa->dst_client->addr, &req.id.sel.daddr);
782 req.id.sel.prefixlen_s = sa->src_client->maskbits;
783 req.id.sel.prefixlen_d = sa->dst_client->maskbits;
784 req.id.sel.proto = sa->transport_proto;
785 req.id.sel.family = sa->dst_client->addr.u.v4.sin_family;
786
787 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
788 rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
789
790 req.id.dir = (inbound)? XFRM_POLICY_IN:XFRM_POLICY_OUT;
791
792 if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
793 return FALSE;
794
795 if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
796 return FALSE;
797
798 *use_time = (time_t)rsp.u.info.curlft.use_time;
799
800 if (inbound && sa->encapsulation == ENCAPSULATION_MODE_TUNNEL)
801 {
802 time_t use_time_fwd;
803
804 req.id.dir = XFRM_POLICY_FWD;
805
806 if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
807 return FALSE;
808
809 if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
810 return FALSE;
811
812 use_time_fwd = (time_t)rsp.u.info.curlft.use_time;
813 *use_time = (*use_time > use_time_fwd)? *use_time : use_time_fwd;
814 }
815 return TRUE;
816 }
817
818
819 /** netlink_get_sa - Get information about an SA from the Kernel
820 *
821 * @param sa Kernel SA to be queried
822 * @return bool True if successfull
823 */
824 static bool
825 netlink_get_sa(const struct kernel_sa *sa, u_int *bytes)
826 {
827 struct {
828 struct nlmsghdr n;
829 struct xfrm_usersa_id id;
830 } req;
831
832 struct {
833 struct nlmsghdr n;
834 union {
835 struct nlmsgerr e;
836 struct xfrm_usersa_info info;
837 } u;
838 char data[1024];
839 } rsp;
840
841 memset(&req, 0, sizeof(req));
842 req.n.nlmsg_flags = NLM_F_REQUEST;
843 req.n.nlmsg_type = XFRM_MSG_GETSA;
844
845 ip2xfrm(sa->dst, &req.id.daddr);
846
847 req.id.spi = sa->spi;
848 req.id.family = sa->src->u.v4.sin_family;
849 req.id.proto = sa->proto;
850
851 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
852 rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
853
854 if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SA", sa->text_said))
855 return FALSE;
856
857 if (netlink_error("XFRM_MSG_GETSA", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
858 return FALSE;
859
860 *bytes = (u_int) rsp.u.info.curlft.bytes;
861
862 return TRUE;
863 }
864
865 static void
866 linux_pfkey_register_response(const struct sadb_msg *msg)
867 {
868 switch (msg->sadb_msg_satype)
869 {
870 case SADB_SATYPE_ESP:
871 #ifndef NO_KERNEL_ALG
872 kernel_alg_register_pfkey(msg, msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
873 #endif
874 break;
875 case SADB_X_SATYPE_IPCOMP:
876 can_do_IPcomp = TRUE;
877 break;
878 default:
879 break;
880 }
881 }
882
883 /** linux_pfkey_register - Register via PFKEY our capabilities
884 *
885 */
886 static void
887 linux_pfkey_register(void)
888 {
889 pfkey_register_proto(SADB_SATYPE_AH, "AH");
890 pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
891 pfkey_register_proto(SADB_X_SATYPE_IPCOMP, "IPCOMP");
892 pfkey_close();
893 }
894
895 /** Create ip_address out of xfrm_address_t.
896 *
897 * @param family
898 * @param src xfrm formatted IP address
899 * @param dst ip_address formatted destination
900 * @return err_t NULL if okay, otherwise an error
901 */
902 static err_t
903 xfrm_to_ip_address(unsigned family, const xfrm_address_t *src, ip_address *dst)
904 {
905 switch (family)
906 {
907 case AF_INET: /* IPv4 */
908 case AF_UNSPEC: /* Unspecified, we assume IPv4 */
909 initaddr((const void *) &src->a4, sizeof(src->a4), AF_INET, dst);
910 return NULL;
911 case AF_INET6: /* IPv6 */
912 initaddr((const void *) &src->a6, sizeof(src->a6), AF_INET6, dst);
913 return NULL;
914 default:
915 return "unknown address family";
916 }
917 }
918
919 /* Create a pair of ip_address's out of xfrm_sel.
920 *
921 * @param sel xfrm selector
922 * @param src ip_address formatted source
923 * @param dst ip_address formatted destination
924 * @return err_t NULL if okay, otherwise an error
925 */
926 static err_t
927 xfrm_sel_to_ip_pair(const struct xfrm_selector *sel
928 , ip_address *src
929 , ip_address *dst)
930 {
931 int family;
932 err_t ugh;
933
934 family = sel->family;
935
936 if ((ugh = xfrm_to_ip_address(family, &sel->saddr, src))
937 || (ugh = xfrm_to_ip_address(family, &sel->daddr, dst)))
938 return ugh;
939
940 /* family has been verified in xfrm_to_ip_address. */
941 if (family == AF_INET)
942 {
943 src->u.v4.sin_port = sel->sport;
944 dst->u.v4.sin_port = sel->dport;
945 }
946 else
947 {
948 src->u.v6.sin6_port = sel->sport;
949 dst->u.v6.sin6_port = sel->dport;
950 }
951
952 return NULL;
953 }
954
955 static void
956 netlink_acquire(struct nlmsghdr *n)
957 {
958 struct xfrm_user_acquire *acquire;
959 ip_address src, dst;
960 ip_subnet ours, his;
961 unsigned transport_proto;
962 err_t ugh = NULL;
963
964 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire)))
965 {
966 plog("netlink_acquire got message with length %lu < %lu bytes; ignore message"
967 , (unsigned long) n->nlmsg_len
968 , (unsigned long) sizeof(*acquire));
969 return;
970 }
971
972 acquire = NLMSG_DATA(n);
973 transport_proto = acquire->sel.proto;
974
975 /* XXX also the type of src/dst should be checked to make sure
976 * that they aren't v4 to v6 or something goofy
977 */
978
979 if (!(ugh = xfrm_sel_to_ip_pair(&acquire->sel, &src, &dst))
980 && !(ugh = addrtosubnet(&src, &ours))
981 && !(ugh = addrtosubnet(&dst, &his)))
982 record_and_initiate_opportunistic(&ours, &his, transport_proto
983 , "%acquire-netlink");
984
985 if (ugh != NULL)
986 plog("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh);
987 }
988
989 static void
990 netlink_shunt_expire(struct xfrm_userpolicy_info *pol)
991 {
992 ip_address src, dst;
993 unsigned transport_proto;
994 err_t ugh = NULL;
995
996 transport_proto = pol->sel.proto;
997
998 if (!(ugh = xfrm_sel_to_ip_pair(&pol->sel, &src, &dst)))
999 {
1000 plog("XFRM_MSG_POLEXPIRE message from kernel malformed: %s", ugh);
1001 return;
1002 }
1003
1004 replace_bare_shunt(&src, &dst, BOTTOM_PRIO, SPI_PASS, FALSE, transport_proto
1005 , "delete expired bare shunt");
1006 }
1007
1008 static void
1009 netlink_policy_expire(struct nlmsghdr *n)
1010 {
1011 struct xfrm_user_polexpire *upe;
1012 struct {
1013 struct nlmsghdr n;
1014 struct xfrm_userpolicy_id id;
1015 } req;
1016
1017 struct {
1018 struct nlmsghdr n;
1019 union {
1020 struct nlmsgerr e;
1021 struct xfrm_userpolicy_info pol;
1022 } u;
1023 char data[1024];
1024 } rsp;
1025
1026 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*upe)))
1027 {
1028 plog("netlink_policy_expire got message with length %lu < %lu bytes; ignore message"
1029 , (unsigned long) n->nlmsg_len
1030 , (unsigned long) sizeof(*upe));
1031 return;
1032 }
1033
1034 upe = NLMSG_DATA(n);
1035 req.id.dir = upe->pol.dir;
1036 req.id.index = upe->pol.index;
1037 req.n.nlmsg_flags = NLM_F_REQUEST;
1038 req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
1039 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
1040
1041 rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
1042
1043 if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
1044 return;
1045
1046 if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.pol)))
1047 return;
1048
1049 if (req.id.index != rsp.u.pol.index)
1050 {
1051 DBG(DBG_KLIPS,
1052 DBG_log("netlink_policy_expire: policy was replaced: "
1053 "dir=%d, oldindex=%d, newindex=%d"
1054 , req.id.dir, req.id.index, rsp.u.pol.index));
1055 return;
1056 }
1057
1058 if (upe->pol.curlft.add_time != rsp.u.pol.curlft.add_time)
1059 {
1060 DBG(DBG_KLIPS,
1061 DBG_log("netlink_policy_expire: policy was replaced "
1062 " and you have won the lottery: "
1063 "dir=%d, index=%d"
1064 , req.id.dir, req.id.index));
1065 return;
1066 }
1067
1068 switch (upe->pol.dir)
1069 {
1070 case XFRM_POLICY_OUT:
1071 netlink_shunt_expire(&rsp.u.pol);
1072 break;
1073 }
1074 }
1075
1076 static bool
1077 netlink_get(void)
1078 {
1079 struct {
1080 struct nlmsghdr n;
1081 char data[1024];
1082 } rsp;
1083 ssize_t r;
1084 struct sockaddr_nl addr;
1085 socklen_t alen;
1086
1087 alen = sizeof(addr);
1088 r = recvfrom(netlink_bcast_fd, &rsp, sizeof(rsp), 0
1089 , (struct sockaddr *)&addr, &alen);
1090 if (r < 0)
1091 {
1092 if (errno == EAGAIN)
1093 return FALSE;
1094 if (errno != EINTR)
1095 log_errno((e, "recvfrom() failed in netlink_get"));
1096 return TRUE;
1097 }
1098 else if ((size_t) r < sizeof(rsp.n))
1099 {
1100 plog("netlink_get read truncated message: %ld bytes; ignore message"
1101 , (long) r);
1102 return TRUE;
1103 }
1104 else if (addr.nl_pid != 0)
1105 {
1106 /* not for us: ignore */
1107 DBG(DBG_KLIPS,
1108 DBG_log("netlink_get: ignoring %s message from process %u"
1109 , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
1110 , addr.nl_pid));
1111 return TRUE;
1112 }
1113 else if ((size_t) r != rsp.n.nlmsg_len)
1114 {
1115 plog("netlink_get read message with length %ld that doesn't equal nlmsg_len %lu bytes; ignore message"
1116 , (long) r
1117 , (unsigned long) rsp.n.nlmsg_len);
1118 return TRUE;
1119 }
1120
1121 DBG(DBG_KLIPS,
1122 DBG_log("netlink_get: %s message"
1123 , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
1124
1125 switch (rsp.n.nlmsg_type)
1126 {
1127 case XFRM_MSG_ACQUIRE:
1128 netlink_acquire(&rsp.n);
1129 break;
1130 case XFRM_MSG_POLEXPIRE:
1131 netlink_policy_expire(&rsp.n);
1132 break;
1133 default:
1134 /* ignored */
1135 break;
1136 }
1137
1138 return TRUE;
1139 }
1140
1141 static void
1142 netlink_process_msg(void)
1143 {
1144 while (netlink_get())
1145 ;
1146 }
1147
1148 static ipsec_spi_t
1149 netlink_get_spi(const ip_address *src
1150 , const ip_address *dst
1151 , int proto
1152 , bool tunnel_mode
1153 , unsigned reqid
1154 , ipsec_spi_t min
1155 , ipsec_spi_t max
1156 , const char *text_said)
1157 {
1158 struct {
1159 struct nlmsghdr n;
1160 struct xfrm_userspi_info spi;
1161 } req;
1162
1163 struct {
1164 struct nlmsghdr n;
1165 union {
1166 struct nlmsgerr e;
1167 struct xfrm_usersa_info sa;
1168 } u;
1169 char data[1024];
1170 } rsp;
1171
1172 memset(&req, 0, sizeof(req));
1173 req.n.nlmsg_flags = NLM_F_REQUEST;
1174 req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
1175
1176 ip2xfrm(src, &req.spi.info.saddr);
1177 ip2xfrm(dst, &req.spi.info.id.daddr);
1178 req.spi.info.mode = tunnel_mode;
1179 req.spi.info.reqid = reqid;
1180 req.spi.info.id.proto = proto;
1181 req.spi.info.family = src->u.v4.sin_family;
1182 req.spi.min = min;
1183 req.spi.max = max;
1184
1185 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.spi)));
1186 rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
1187
1188 if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SPI", text_said))
1189 return 0;
1190
1191 if (netlink_error("XFRM_MSG_ALLOCSPI", &rsp.n, &rsp.u.e, sizeof(rsp.u.sa)))
1192 return 0;
1193
1194 DBG(DBG_KLIPS,
1195 DBG_log("netlink_get_spi: allocated 0x%x for %s"
1196 , ntohl(rsp.u.sa.id.spi), text_said));
1197 return rsp.u.sa.id.spi;
1198 }
1199
1200 const struct kernel_ops linux_kernel_ops = {
1201 type: KERNEL_TYPE_LINUX,
1202 inbound_eroute: 1,
1203 policy_lifetime: 1,
1204 async_fdp: &netlink_bcast_fd,
1205
1206 init: init_netlink,
1207 pfkey_register: linux_pfkey_register,
1208 pfkey_register_response: linux_pfkey_register_response,
1209 process_msg: netlink_process_msg,
1210 raw_eroute: netlink_raw_eroute,
1211 get_policy: netlink_get_policy,
1212 add_sa: netlink_add_sa,
1213 del_sa: netlink_del_sa,
1214 get_sa: netlink_get_sa,
1215 process_queue: NULL,
1216 grp_sa: NULL,
1217 get_spi: netlink_get_spi,
1218 };
1219 #endif /* linux && KLIPS */