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