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