Bug Summary

File:programs/pluto/kernel_xfrm.c
Warning:line 1617, column 3
Value stored to 'attr' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name kernel_xfrm.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -pic-is-pie -mthread-model posix -mdisable-fp-elim -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib64/clang/8.0.0 -D TimeZoneOffset=timezone -D linux -D PIE -D NSS_IPSEC_PROFILE -D XFRM_SUPPORT -D USE_XFRM_INTERFACE -D USE_DNSSEC -D DEFAULT_DNSSEC_ROOTKEY_FILE="/var/lib/unbound/root.key" -D HAVE_LABELED_IPSEC -D HAVE_SECCOMP -D LIBCURL -D USE_LINUX_AUDIT -D USE_SYSTEMD_WATCHDOG -D HAVE_NM -D XAUTH_HAVE_PAM -D USE_3DES -D USE_AES -D USE_CAMELLIA -D USE_CHACHA -D USE_DH31 -D USE_MD5 -D USE_SHA1 -D USE_SHA2 -D USE_PRF_AES_XCBC -D DEFAULT_RUNDIR="/run/pluto" -D IPSEC_CONF="/etc/ipsec.conf" -D IPSEC_CONFDDIR="/etc/ipsec.d" -D IPSEC_NSSDIR="/etc/ipsec.d" -D IPSEC_CONFDIR="/etc" -D IPSEC_EXECDIR="/usr/local/libexec/ipsec" -D IPSEC_SBINDIR="/usr/local/sbin" -D IPSEC_VARDIR="/var" -D POLICYGROUPSDIR="/etc/ipsec.d/policies" -D IPSEC_SECRETS_FILE="/etc/ipsec.secrets" -D FORCE_PR_ASSERT -D USE_FORK=1 -D USE_VFORK=0 -D USE_DAEMON=0 -D USE_PTHREAD_SETSCHEDPRIO=1 -D GCC_LINT -D HAVE_LIBCAP_NG -I . -I ../../OBJ.linux.x86_64/programs/pluto -I ../../include -I /usr/include/nss3 -I /usr/include/nspr4 -I /home/build/libreswan/programs/pluto/linux-copy -D HERE_BASENAME="kernel_xfrm.c" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/8.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-field-initializers -std=gnu99 -fdebug-compilation-dir /home/build/libreswan/programs/pluto -ferror-limit 19 -fmessage-length 0 -stack-protector 3 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -o /tmp/scan-build-2020-09-09-193337-25440-1 -x c /home/build/libreswan/programs/pluto/kernel_xfrm.c -faddrsig
1/*
2 * netlink interface to the kernel's IPsec mechanism
3 *
4 * Copyright (C) 2003-2008 Herbert Xu
5 * Copyright (C) 2006-2008 Michael Richardson <mcr@xelerance.com>
6 * Copyright (C) 2006 Ken Bantoft <ken@xelerance.com>
7 * Copyright (C) 2007 Bart Trojanowski <bart@jukie.net>
8 * Copyright (C) 2007 Ilia Sotnikov
9 * Copyright (C) 2009 Carsten Schlote <c.schlote@konzeptpark.de>
10 * Copyright (C) 2008 Andreas Steffen
11 * Copyright (C) 2008 Neil Horman <nhorman@redhat.com>
12 * Copyright (C) 2008-2010 David McCullough <david_mccullough@securecomputing.com>
13 * Copyright (C) 2006-2010 Paul Wouters <paul@xelerance.com>
14 * Copyright (C) 2010-2017 Tuomo Soini <tis@foobar.fi>
15 * Copyright (C) 2010 Mika Ilmaranta <ilmis@foobar.fi>
16 * Copyright (C) 2010 Roman Hoog Antink <rha@open.ch>
17 * Copyright (C) 2010 D. Hugh Redelmeier
18 * Copyright (C) 2012 Avesh Agarwal <avagarwa@redhat.com>
19 * Copyright (C) 2013 Kim B. Heino <b@bbbs.net>
20 * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
21 * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
22 * Copyright (C) 2017 Richard Guy Briggs <rgb@tricolour.ca>
23 * Copyright (C) 2016-2019 Andrew Cagney <cagney@gnu.org>
24 * Copyright (C) 2019 Paul Wouters <pwouters@redhat.com>
25 * Copyright (C) 2019 Antony Antony <antony@phenome.org>
26 * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com>
27 *
28 * This program is free software; you can redistribute it and/or modify it
29 * under the terms of the GNU General Public License as published by the
30 * Free Software Foundation; either version 2 of the License, or (at your
31 * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
32 *
33 * This program is distributed in the hope that it will be useful, but
34 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
35 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36 * for more details.
37 */
38
39#include <errno(*__errno_location ()).h>
40#include <fcntl.h>
41#include <string.h>
42
43#include <sys/socket.h>
44
45#include <sys/types.h>
46#include <sys/ioctl.h>
47#include <stdint.h>
48#include <linux1/ethtool.h>
49#include <linux1/sockios.h>
50
51#include <linux1/udp.h> /* for TCP_ENCAP_ESPINTCP and UDP_ENCAP_ESPINUDP */
52#ifndef TCP_ENCAP_ESPINTCP7
53#define TCP_ENCAP_ESPINTCP7 7
54#endif
55
56#include <unistd.h>
57#include <sys/stat.h>
58
59#include <linux1/rtnetlink.h>
60#include <linux1/if_addr.h>
61#include <linux1/if_link.h>
62
63/* work around weird combo's of glibc and kernel header conflicts */
64#ifndef GLIBC_KERN_FLIP_HEADERS
65# include "linux/xfrm.h" /* local (if configured) or system copy */
66# include "libreswan.h"
67#else
68# include "libreswan.h"
69# include "linux/xfrm.h" /* local (if configured) or system copy */
70#endif
71#include "lsw-pfkeyv2.h" /* for SADB_X_CALG_DEFLATE et.al., grrr */
72
73#include "sysdep.h"
74#include "socketwrapper.h"
75#include "constants.h"
76#include "defs.h"
77#include "id.h"
78#include "state.h"
79#include "connections.h"
80#include "kernel.h"
81#include "server.h"
82#include "nat_traversal.h"
83#include "state.h"
84#include "kernel_xfrm.h"
85#include "log.h"
86#include "whack.h" /* for RC_LOG_SERIOUS */
87#include "kernel_alg.h"
88#include "ike_alg.h"
89#include "ike_alg_integ.h"
90#include "ike_alg_encrypt.h"
91#include "ip_address.h"
92#include "ip_info.h"
93# include "kernel_xfrm_interface.h"
94#include "iface.h"
95#include "ip_selector.h"
96#include "ip_encap.h"
97
98/* required for Linux 2.6.26 kernel and later */
99#ifndef XFRM_STATE_AF_UNSPEC32
100#define XFRM_STATE_AF_UNSPEC32 32
101#endif
102
103static int nl_send_fd = NULL_FD(-1); /* to send to NETLINK_XFRM */
104static int nl_xfrm_fd = NULL_FD(-1); /* listen to NETLINK_XFRM broadcast */
105static int nl_route_fd = NULL_FD(-1); /* listen to NETLINK_ROUTE broadcast */
106
107static int kernel_mobike_supprt ; /* kernel xfrm_migrate_support */
108
109#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
110
111enum {
112 IPSEC_POLICY_DISCARD = 0,
113 IPSEC_POLICY_NONE = 1,
114 IPSEC_POLICY_IPSEC = 2,
115 IPSEC_POLICY_ENTRUST = 3,
116 IPSEC_POLICY_BYPASS = 4
117};
118
119static sparse_names xfrm_type_names = {
120 NE(NLMSG_NOOP0x1),
121 NE(NLMSG_ERROR0x2),
122 NE(NLMSG_DONE0x3),
123 NE(NLMSG_OVERRUN0x4),
124
125 NE(XFRM_MSG_NEWSAXFRM_MSG_NEWSA),
126 NE(XFRM_MSG_DELSAXFRM_MSG_DELSA),
127 NE(XFRM_MSG_GETSAXFRM_MSG_GETSA),
128
129 NE(XFRM_MSG_NEWPOLICYXFRM_MSG_NEWPOLICY),
130 NE(XFRM_MSG_DELPOLICYXFRM_MSG_DELPOLICY),
131 NE(XFRM_MSG_GETPOLICYXFRM_MSG_GETPOLICY),
132
133 NE(XFRM_MSG_ALLOCSPIXFRM_MSG_ALLOCSPI),
134 NE(XFRM_MSG_ACQUIREXFRM_MSG_ACQUIRE),
135 NE(XFRM_MSG_EXPIREXFRM_MSG_EXPIRE),
136
137 NE(XFRM_MSG_UPDPOLICYXFRM_MSG_UPDPOLICY),
138 NE(XFRM_MSG_UPDSAXFRM_MSG_UPDSA),
139
140 NE(XFRM_MSG_POLEXPIREXFRM_MSG_POLEXPIRE),
141
142 NE(XFRM_MSG_MAX(__XFRM_MSG_MAX - 1)),
143
144 { 0, sparse_end }
145};
146
147static sparse_names rtm_type_names = {
148 NE(RTM_BASERTM_BASE),
149 NE(RTM_NEWADDRRTM_NEWADDR),
150 NE(RTM_DELADDRRTM_DELADDR),
151 NE(RTM_MAX(((__RTM_MAX + 3) & ~3) - 1)),
152 { 0, sparse_end }
153};
154#undef NE
155
156#define RTA_TAIL(rta)((struct rtattr *) (((void *) (rta)) + ( (((rta)->rta_len)
+4U -1) & ~(4U -1) )))
((struct rtattr *) (((void *) (rta)) + \
157 RTA_ALIGN((rta)->rta_len)( (((rta)->rta_len)+4U -1) & ~(4U -1) )))
158
159#define NLMSG_TAIL(nmsg)((struct rtattr *) (((void *) (nmsg)) + ( (((nmsg)->nlmsg_len
)+4U -1) & ~(4U -1) )))
\
160 ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)( (((nmsg)->nlmsg_len)+4U -1) & ~(4U -1) )))
161
162/* Compress Algs */
163static sparse_names calg_list = {
164 { SADB_X_CALG_DEFLATE2, "deflate" },
165 { SADB_X_CALG_LZS3, "lzs" },
166 { SADB_X_CALG_LZJH4, "lzjh" },
167 { 0, sparse_end }
168};
169
170/*
171 * xfrm2ip - Take an xfrm and convert to an IP address
172 *
173 * @param xaddr xfrm_address_t
174 * @param addr ip_address IPv[46] Address from addr is copied here.
175 */
176static void xfrm2ip(const xfrm_address_t *xaddr, ip_address *addr, const sa_family_t family)
177{
178 shunk_t x = THING_AS_SHUNK(*xaddr)shunk2(&(*xaddr), sizeof(*xaddr));
179
180 const struct ip_info *afi = aftoinfo(family);
181 passert(afi != NULL){ _Bool assertion__ = afi != ((void*)0); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 181}, "%s", "afi != NULL"); } }
;
182
183 *addr = afi->any_address; /* initialize dst type and zero */
184 chunk_t a = address_as_chunk(addr);
185
186 /* a = x */
187 passert(x.len >= a.len){ _Bool assertion__ = x.len >= a.len; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 187}, "%s", "x.len >= a.len"); } }
;
188 memcpy(a.ptr, x.ptr, a.len);
189}
190
191/*
192 * xfrm_from-address - Take an IP address and convert to an xfrm.
193 */
194static xfrm_address_t xfrm_from_address(const ip_address *addr)
195{
196 xfrm_address_t xaddr;
197 zero(&xaddr)memset((&xaddr), '\0', sizeof(*(&xaddr)));
198
199 shunk_t a = address_as_shunk(addr);
200 /* .len == ipv6 len */
201 chunk_t x = THING_AS_CHUNK(xaddr)chunk2(&(xaddr), sizeof(xaddr));
202 /* x = a */
203 passert(x.len >= a.len){ _Bool assertion__ = x.len >= a.len; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 203}, "%s", "x.len >= a.len"); } }
;
204 memcpy(x.ptr, a.ptr, a.len);
205 return xaddr;
206}
207
208#define SELECTOR_TO_XFRM(CLIENT, REQ, L){ ip_selector client_ = *(CLIENT); ip_address address = selector_prefix
(&client_); (REQ).Laddr = xfrm_from_address(&address)
; (REQ).prefixlen_L = selector_maskbits(&client_); (REQ).
Lport = nport(selector_port(&client_)); }
\
209 { \
210 ip_selector client_ = *(CLIENT); \
211 ip_address address = selector_prefix(&client_); \
212 (REQ).L##addr = xfrm_from_address(&address); \
213 (REQ).prefixlen_##L = selector_maskbits(&client_); \
214 (REQ).L##port = nport(selector_port(&client_)); \
215 }
216
217static void init_netlink_route_fd(void)
218{
219 nl_route_fd = safe_socket(AF_NETLINK16, SOCK_RAWSOCK_RAW, NETLINK_ROUTE0);
220 if (nl_route_fd < 0) {
221 FATAL_ERRNO(errno, "socket()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "socket()"". ""Errno %d: %s", (e_), strerror(e_))
; jambuf_to_error_stream(buf); } libreswan_exit(PLUTO_EXIT_FAIL
); }
;
222 }
223
224 if (fcntl(nl_route_fd, F_SETFD2, FD_CLOEXEC1) != 0) {
225 FATAL_ERRNO(errno, "fcntl(FD_CLOEXEC) for bcast NETLINK_ROUTE "){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "fcntl(FD_CLOEXEC) for bcast NETLINK_ROUTE "". ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } libreswan_exit
(PLUTO_EXIT_FAIL); }
;
226 }
227
228 if (fcntl(nl_route_fd, F_SETFL4, O_NONBLOCK04000) != 0) {
229 FATAL_ERRNO(errno, "fcntl(O_NONBLOCK) for bcast NETLINK_ROUTE"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "fcntl(O_NONBLOCK) for bcast NETLINK_ROUTE"". ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } libreswan_exit
(PLUTO_EXIT_FAIL); }
;
230 }
231
232 struct sockaddr_nl addr = {
233 .nl_family = AF_NETLINK16,
234 .nl_pid = getpid(),
235 .nl_groups = RTMGRP_IPV4_IFADDR0x10 | RTMGRP_IPV6_IFADDR0x100 |
236 RTMGRP_IPV4_ROUTE0x40 | RTMGRP_IPV6_ROUTE0x400 | RTMGRP_LINK1,
237 };
238
239 if (bind(nl_route_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
240 FATAL_ERRNO(errno, "Failed to bind NETLINK_ROUTE bcast socket - Perhaps kernel was not compiled with CONFIG_XFRM"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "Failed to bind NETLINK_ROUTE bcast socket - Perhaps kernel was not compiled with CONFIG_XFRM"
". ""Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream
(buf); } libreswan_exit(PLUTO_EXIT_FAIL); }
;
241 }
242}
243
244
245/*
246 * init_netlink - Initialize the netlink inferface. Opens the sockets and
247 * then binds to the broadcast socket.
248 */
249static void init_netlink(void)
250{
251 struct sockaddr_nl addr;
252
253 nl_send_fd = safe_socket(AF_NETLINK16, SOCK_DGRAMSOCK_DGRAM, NETLINK_XFRM6);
254
255 if (nl_send_fd < 0) {
256 FATAL_ERRNO(errno, "socket() in init_netlink()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "socket() in init_netlink()"". ""Errno %d: %s", (
e_), strerror(e_)); jambuf_to_error_stream(buf); } libreswan_exit
(PLUTO_EXIT_FAIL); }
;
257 }
258
259 if (fcntl(nl_send_fd, F_SETFD2, FD_CLOEXEC1) != 0) {
260 FATAL_ERRNO(errno, "fcntl(FD_CLOEXEC) in init_netlink()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "fcntl(FD_CLOEXEC) in init_netlink()"". ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } libreswan_exit
(PLUTO_EXIT_FAIL); }
;
261 }
262
263 nl_xfrm_fd = safe_socket(AF_NETLINK16, SOCK_DGRAMSOCK_DGRAM, NETLINK_XFRM6);
264 if (nl_xfrm_fd < 0) {
265 FATAL_ERRNO(errno, "socket() for bcast in init_netlink()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "socket() for bcast in init_netlink()"". ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } libreswan_exit
(PLUTO_EXIT_FAIL); }
;
266 }
267
268 if (fcntl(nl_xfrm_fd, F_SETFD2, FD_CLOEXEC1) != 0) {
269 FATAL_ERRNO(errno, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"". "
"Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream(buf
); } libreswan_exit(PLUTO_EXIT_FAIL); }
;
270 }
271
272 if (fcntl(nl_xfrm_fd, F_SETFL4, O_NONBLOCK04000) != 0) {
273 FATAL_ERRNO(errno, "fcntl(O_NONBLOCK) for bcast in init_netlink()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "fcntl(O_NONBLOCK) for bcast in init_netlink()"". "
"Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream(buf
); } libreswan_exit(PLUTO_EXIT_FAIL); }
;
274 }
275
276 addr.nl_family = AF_NETLINK16;
277 addr.nl_pid = getpid();
278 addr.nl_pad = 0; /* make coverity happy */
279 addr.nl_groups = XFRMGRP_ACQUIRE1 | XFRMGRP_EXPIRE2;
280 if (bind(nl_xfrm_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
281 FATAL_ERRNO(errno, "Failed to bind bcast socket in init_netlink() - Perhaps kernel was not compiled with CONFIG_XFRM"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "FATAL ERROR: "); jam_cur_prefix(buf
); jam(buf, "Failed to bind bcast socket in init_netlink() - Perhaps kernel was not compiled with CONFIG_XFRM"
". ""Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream
(buf); } libreswan_exit(PLUTO_EXIT_FAIL); }
;
282 }
283
284 init_netlink_route_fd();
285
286 /*
287 * pfkey_register_response() does not register an entry for
288 * msg->sadb_msg_satype=10 to indicate IPCOMP, so we override
289 * detection here. Seems the PF_KEY API in Linux with netkey
290 * is a joke that should be abandoned for a "linux children"
291 * native netlink query/response
292 *
293 * XXX: Given KLIPS defines K_SADB_X_SATYPE_COMP=9, and
294 * IPIP=10 which conflicts with the aboe, that might be the
295 * source of the problem?
296 */
297 can_do_IPcomp = TRUE1;
298
299 /*
300 * Just assume any algorithm with a NETLINK_XFRM name works.
301 *
302 * Kind of lame since pluto should query the kernel for what
303 * it supports. OTOH, the query might happen before the
304 * crypto module gets loaded.
305 */
306 dbg("Hard-wiring algorithms"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("Hard-wiring algorithms"); } }
;
307 for (const struct encrypt_desc **algp = next_encrypt_desc(NULL((void*)0));
308 algp != NULL((void*)0); algp = next_encrypt_desc(algp)) {
309 const struct encrypt_desc *alg = *algp;
310 if (alg->encrypt_netlink_xfrm_name != NULL((void*)0)) {
311 kernel_encrypt_add(alg);
312 }
313 }
314 for (const struct integ_desc **algp = next_integ_desc(NULL((void*)0));
315 algp != NULL((void*)0); algp = next_integ_desc(algp)) {
316 const struct integ_desc *alg = *algp;
317 if (alg->integ_netlink_xfrm_name != NULL((void*)0)) {
318 kernel_integ_add(alg);
319 }
320 }
321}
322
323struct nlm_resp {
324 struct nlmsghdr n;
325 union {
326 struct nlmsgerr e;
327 struct xfrm_userpolicy_info pol; /* netlink_policy_expire */
328 struct xfrm_usersa_info sa; /* netlink_get_spi */
329 struct xfrm_usersa_info info; /* netlink_get_sa */
330 char data[MAX_NETLINK_DATA_SIZE8192];
331 } u;
332};
333
334/*
335 * send_netlink_msg
336 *
337 * @param hdr - Data to be sent.
338 * @param expected_resp_type - type of message expected from netlink
339 * @param rbuf - Return Buffer - contains data returned from the send.
340 * @param description - String - user friendly description of what is
341 * being attempted. Used for diagnostics
342 * @param text_said - String
343 * @return bool True if the message was successfully sent.
344 */
345static int netlink_errno; /* side-channel result of send_netlink_msg */
346
347static bool_Bool send_netlink_msg(struct nlmsghdr *hdr,
348 unsigned expected_resp_type, struct nlm_resp *rbuf,
349 const char *description, const char *text_said)
350{
351 struct nlm_resp rsp;
352 size_t len;
353 ssize_t r;
354 struct sockaddr_nl addr;
355 static uint32_t seq = 0; /* STATIC */
356
357 netlink_errno = 0;
358
359 hdr->nlmsg_seq = ++seq;
360 len = hdr->nlmsg_len;
361 do {
362 r = write(nl_send_fd, hdr, len);
363 } while (r < 0 && errno(*__errno_location ()) == EINTR4);
364 if (r < 0) {
365 LOG_ERRNO(errno, "netlink write() of %s message for %s %s failed",{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink write() of %s message for %s %s failed", sparse_val_show
(xfrm_type_names, hdr->nlmsg_type), description, text_said
); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror
(e_)); jambuf_to_error_stream(buf); } }
366 sparse_val_show(xfrm_type_names,{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink write() of %s message for %s %s failed", sparse_val_show
(xfrm_type_names, hdr->nlmsg_type), description, text_said
); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror
(e_)); jambuf_to_error_stream(buf); } }
367 hdr->nlmsg_type),{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink write() of %s message for %s %s failed", sparse_val_show
(xfrm_type_names, hdr->nlmsg_type), description, text_said
); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror
(e_)); jambuf_to_error_stream(buf); } }
368 description, text_said){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink write() of %s message for %s %s failed", sparse_val_show
(xfrm_type_names, hdr->nlmsg_type), description, text_said
); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror
(e_)); jambuf_to_error_stream(buf); } }
;
369 return FALSE0;
370 } else if ((size_t)r != len) {
371 loglog(RC_LOG_SERIOUS,
372 "ERROR: netlink write() of %s message for %s %s truncated: %zd instead of %zu",
373 sparse_val_show(xfrm_type_names, hdr->nlmsg_type),
374 description, text_said, r, len);
375 return FALSE0;
376 }
377
378 for (;;) {
379 socklen_t alen = sizeof(addr);
380
381 r = recvfrom(nl_send_fd, &rsp, sizeof(rsp), 0,
382 (struct sockaddr *)&addr, &alen);
383 if (r < 0) {
384 if (errno(*__errno_location ()) == EINTR4)
385 continue;
386 netlink_errno = errno(*__errno_location ());
387 LOG_ERRNO(errno,{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink recvfrom() of response to our %s message for %s %s failed"
, sparse_val_show(xfrm_type_names, hdr->nlmsg_type), description
, text_said); jam_string(buf, "."); jam(buf, " ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } }
388 "netlink recvfrom() of response to our %s message for %s %s failed",{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink recvfrom() of response to our %s message for %s %s failed"
, sparse_val_show(xfrm_type_names, hdr->nlmsg_type), description
, text_said); jam_string(buf, "."); jam(buf, " ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } }
389 sparse_val_show(xfrm_type_names,{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink recvfrom() of response to our %s message for %s %s failed"
, sparse_val_show(xfrm_type_names, hdr->nlmsg_type), description
, text_said); jam_string(buf, "."); jam(buf, " ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } }
390 hdr->nlmsg_type),{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink recvfrom() of response to our %s message for %s %s failed"
, sparse_val_show(xfrm_type_names, hdr->nlmsg_type), description
, text_said); jam_string(buf, "."); jam(buf, " ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } }
391 description, text_said){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink recvfrom() of response to our %s message for %s %s failed"
, sparse_val_show(xfrm_type_names, hdr->nlmsg_type), description
, text_said); jam_string(buf, "."); jam(buf, " ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } }
;
392 return FALSE0;
393 } else if ((size_t) r < sizeof(rsp.n)) {
394 libreswan_log(loglog(RC_LOG, "netlink read truncated message: %zd bytes; ignore message"
, r)
395 "netlink read truncated message: %zd bytes; ignore message",loglog(RC_LOG, "netlink read truncated message: %zd bytes; ignore message"
, r)
396 r)loglog(RC_LOG, "netlink read truncated message: %zd bytes; ignore message"
, r)
;
397 continue;
398 } else if (addr.nl_pid != 0) {
399 /* not for us: ignore */
400 dbg("netlink: ignoring %s message from process %u",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: ignoring %s message from process %u"
, sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type), addr.nl_pid
); } }
401 sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: ignoring %s message from process %u"
, sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type), addr.nl_pid
); } }
402 addr.nl_pid){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: ignoring %s message from process %u"
, sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type), addr.nl_pid
); } }
;
403 continue;
404 } else if (rsp.n.nlmsg_seq != seq) {
405 dbg("netlink: ignoring out of sequence (%u/%u) message %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: ignoring out of sequence (%u/%u) message %s"
, rsp.n.nlmsg_seq, seq, sparse_val_show(xfrm_type_names, rsp.
n.nlmsg_type)); } }
406 rsp.n.nlmsg_seq, seq,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: ignoring out of sequence (%u/%u) message %s"
, rsp.n.nlmsg_seq, seq, sparse_val_show(xfrm_type_names, rsp.
n.nlmsg_type)); } }
407 sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: ignoring out of sequence (%u/%u) message %s"
, rsp.n.nlmsg_seq, seq, sparse_val_show(xfrm_type_names, rsp.
n.nlmsg_type)); } }
;
408 continue;
409 }
410 break;
411 }
412
413 if (rsp.n.nlmsg_len > (size_t) r) {
414 loglog(RC_LOG_SERIOUS,
415 "netlink recvfrom() of response to our %s message for %s %s was truncated: %zd instead of %zu",
416 sparse_val_show(xfrm_type_names, hdr->nlmsg_type),
417 description, text_said,
418 len, (size_t) rsp.n.nlmsg_len);
419 return FALSE0;
420 }
421
422 if (rsp.n.nlmsg_type != expected_resp_type && rsp.n.nlmsg_type == NLMSG_ERROR0x2) {
423 if (rsp.u.e.error != 0) {
424 loglog(RC_LOG_SERIOUS,
425 "ERROR: netlink response for %s %s included errno %d: %s",
426 description, text_said, -rsp.u.e.error,
427 strerror(-rsp.u.e.error));
428 return FALSE0;
429 }
430 /*
431 * What the heck does a 0 error mean?
432 * Since the caller doesn't depend on the result
433 * we'll let it pass.
434 * This really happens for netlink_add_sa().
435 */
436 dbg("netlink response for %s %s included non-error error",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink response for %s %s included non-error error"
, description, text_said); } }
437 description, text_said){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink response for %s %s included non-error error"
, description, text_said); } }
;
438 /* ignore */
439 }
440 if (rbuf == NULL((void*)0)) {
441 return TRUE1;
442 }
443 if (rsp.n.nlmsg_type != expected_resp_type) {
444 loglog(RC_LOG_SERIOUS,
445 "netlink recvfrom() of response to our %s message for %s %s was of wrong type (%s)",
446 sparse_val_show(xfrm_type_names, hdr->nlmsg_type),
447 description, text_said,
448 sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type));
449 return FALSE0;
450 }
451 memcpy(rbuf, &rsp, r);
452 return TRUE1;
453}
454
455/*
456 * netlink_policy -
457 *
458 * @param hdr - Data to check
459 * @param enoent_ok - Boolean - OK or not OK.
460 * @param text_said - String
461 * @return boolean
462 */
463static bool_Bool netlink_policy(struct nlmsghdr *hdr, bool_Bool enoent_ok,
464 const char *text_said)
465{
466 struct nlm_resp rsp;
467
468 if (!send_netlink_msg(hdr, NLMSG_ERROR0x2, &rsp, "policy", text_said))
469 return FALSE0;
470
471 /* kind of surprising: we get here by success which implies an error structure! */
472
473 int error = -rsp.u.e.error;
474
475 if (error == 0 || (error == ENOENT2 && enoent_ok))
476 return TRUE1;
477
478 loglog(RC_LOG_SERIOUS,
479 "ERROR: netlink %s response for flow %s included errno %d: %s",
480 sparse_val_show(xfrm_type_names, hdr->nlmsg_type),
481 text_said, error, strerror(error));
482 return FALSE0;
483}
484
485/*
486 * netlink_raw_eroute
487 *
488 * @param this_host ip_address
489 * @param this_client ip_subnet
490 * @param that_host ip_address
491 * @param that_client ip_subnet
492 * @param spi
493 * @param sa_proto int (4=tunnel, 50=esp, 108=ipcomp, etc ...)
494 * @param transport_proto unsigned int Contains protocol
495 * (6=tcp, 17=udp, etc...)
496 * @param esatype int
497 * @param pfkey_proto_info proto_info
498 * @param use_lifetime monotime_t (Currently unused)
499 * @param pluto_sadb_opterations sadb_op (operation - ie: ERO_DELETE)
500 * @param text_said char
501 * @return boolean True if successful
502 */
503static bool_Bool netlink_raw_eroute(const ip_address *this_host,
504 const ip_subnet *this_client,
505 const ip_address *that_host,
506 const ip_subnet *that_client,
507 ipsec_spi_t cur_spi, /* current SPI */
508 ipsec_spi_t new_spi, /* new SPI */
509 const struct ip_protocol *sa_proto,
510 unsigned int transport_proto,
511 enum eroute_type esatype,
512 const struct pfkey_proto_info *proto_info,
513 deltatime_t use_lifetime UNUSED__attribute__ ((unused)),
514 uint32_t sa_priority,
515 const struct sa_marks *sa_marks,
516 const uint32_t xfrm_if_id,
517 enum pluto_sadb_operations sadb_op,
518 const char *text_said,
519 const char *policy_label)
520{
521 struct {
522 struct nlmsghdr n;
523 union {
524 struct xfrm_userpolicy_info p;
525 struct xfrm_userpolicy_id id;
526 } u;
527 char data[MAX_NETLINK_DATA_SIZE8192];
528 } req;
529
530 int policy = IPSEC_POLICY_IPSEC;
531
532 if (sadb_op == ERO_DELETE && proto_info[0].reqid == 0 &&
533 (ntohl(new_spi) == SPI_PASS256 || ntohl(new_spi) == SPI_HOLD259) &&
534 strstr("IGNORE_ON_XFRM", text_said) != NULL((void*)0)) {
535 dbg("request to delete an opportunistic bare shunt ignored - XFRM already deleted it when it installed IPsec SA, text_said:%s", text_said){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("request to delete an opportunistic bare shunt ignored - XFRM already deleted it when it installed IPsec SA, text_said:%s"
, text_said); } }
;
536 return TRUE1;
537 }
538
539 switch (esatype) {
540 case ET_UNSPEC:
541 case ET_AH:
542 case ET_ESP:
543 case ET_IPCOMP:
544 case ET_IPIP:
545
546 break;
547
548 case ET_INT:
549 /* shunt route */
550 switch (ntohl(new_spi)) {
551 case SPI_PASS256:
552 dbg("netlink_raw_eroute: SPI_PASS"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_raw_eroute: SPI_PASS"); } }
;
553 policy = IPSEC_POLICY_NONE;
554 break;
555 case SPI_HOLD259:
556 /*
557 * We don't know how to implement %hold, but it is okay.
558 * When we need a hold, the kernel XFRM acquire state
559 * will do the job (by dropping or holding the packet)
560 * until this entry expires. See /proc/sys/net/core/xfrm_acq_expires
561 * After expiration, the underlying policy causing the original acquire
562 * will fire again, dropping further packets.
563 */
564 dbg("netlink_raw_eroute: SPI_HOLD implemented as no-op"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_raw_eroute: SPI_HOLD implemented as no-op"
); } }
;
565 return TRUE1; /* yes really */
566 case SPI_DROP257:
567 case SPI_REJECT258:
568 case 0: /* used with type=passthrough - can it not use SPI_PASS ?? */
569 policy = IPSEC_POLICY_DISCARD;
570 break;
571 case SPI_TRAP260:
572 if (sadb_op == ERO_ADD_INBOUND ||
573 sadb_op == ERO_DEL_INBOUND)
574 return TRUE1;
575
576 break;
577 case SPI_TRAPSUBNET261: /* unused in our code */
578 default:
579 bad_case(ntohl(new_spi))libreswan_bad_case("ntohl(new_spi)", (ntohl(new_spi)), (where_t
) { .func = __func__, .basename = "kernel_xfrm.c" , .line = 579
})
;
580 }
581 break;
582
583 default:
584 bad_case(esatype)libreswan_bad_case("esatype", (esatype), (where_t) { .func = __func__
, .basename = "kernel_xfrm.c" , .line = 584})
;
585 }
586
587 const int dir = (sadb_op == ERO_ADD_INBOUND || sadb_op == ERO_DEL_INBOUND) ?
588 XFRM_POLICY_IN : XFRM_POLICY_OUT;
589
590 /*
591 * Bug #1004 fix.
592 * There really isn't "client" with XFRM and transport mode
593 * so eroute must be done to natted, visible ip. If we don't hide
594 * internal IP, communication doesn't work.
595 */
596 ip_selector local_client;
597
598 if (esatype == ET_ESP || esatype == ET_IPCOMP || sa_proto == &ip_protocol_esp) {
599 /*
600 * Variable "that" should be remote, but here it's not.
601 * We must check "dir" to find out remote address.
602 */
603 int local_port;
604
605 if (dir == XFRM_POLICY_OUT) {
606 local_port = portof(&that_client->addr)nport(endpoint_port((&that_client->addr)));
607 local_client = subnet_from_address(that_host);
608 that_client = &local_client;
609 } else {
610 local_port = portof(&this_client->addr)nport(endpoint_port((&this_client->addr)));
611 local_client = subnet_from_address(this_host);
612 this_client = &local_client;
613 }
614 setportof(local_port, &local_client.addr){ *(&local_client.addr) = set_endpoint_hport((&local_client
.addr), ntohs(local_port)); }
;
615 dbg("%s: using host address instead of client subnet", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s: using host address instead of client subnet"
, __func__); } }
;
616 }
617
618 zero(&req)memset((&req), '\0', sizeof(*(&req)));
619 req.n.nlmsg_flags = NLM_F_REQUEST0x01 | NLM_F_ACK0x04;
620
621 const int family = subnet_type(that_client)->af;
622
623 /* .[sd]addr, .prefixlen_[sd], .[sd]port */
624 SELECTOR_TO_XFRM(this_client, req.u.p.sel, s){ ip_selector client_ = *(this_client); ip_address address = selector_prefix
(&client_); (req.u.p.sel).saddr = xfrm_from_address(&
address); (req.u.p.sel).prefixlen_s = selector_maskbits(&
client_); (req.u.p.sel).sport = nport(selector_port(&client_
)); }
;
625 SELECTOR_TO_XFRM(that_client, req.u.p.sel, d){ ip_selector client_ = *(that_client); ip_address address = selector_prefix
(&client_); (req.u.p.sel).daddr = xfrm_from_address(&
address); (req.u.p.sel).prefixlen_d = selector_maskbits(&
client_); (req.u.p.sel).dport = nport(selector_port(&client_
)); }
;
626
627 /*
628 * Munge .[sd]port?
629 *
630 * As per RFC 4301/5996, icmp type is put in the most significant
631 * 8 bits and icmp code is in the least significant 8 bits of port
632 * field.
633 * Although Libreswan does not have any configuration options for
634 * icmp type/code values, it is possible to specify icmp type and code
635 * using protoport option. For example, icmp echo request
636 * (type 8/code 0) needs to be encoded as 0x0800 in the port field
637 * and can be specified as left/rightprotoport=icmp/2048. Now with
638 * XFRM, icmp type and code need to be passed as source and
639 * destination ports, respectively. Therefore, this code extracts
640 * upper 8 bits and lower 8 bits and puts into source and destination
641 * ports before passing to XFRM.
642 */
643 if (transport_proto == IPPROTO_ICMPIPPROTO_ICMP ||
644 transport_proto == IPPROTO_ICMPV658) {
645 uint16_t icmp_type;
646 uint16_t icmp_code;
647
648 icmp_type = ntohs(req.u.p.sel.sport) >> 8;
649 icmp_code = ntohs(req.u.p.sel.sport) & 0xFF;
650
651 req.u.p.sel.sport = htons(icmp_type);
652 req.u.p.sel.dport = htons(icmp_code);
653 }
654
655 req.u.p.sel.sport_mask = req.u.p.sel.sport == 0 ? 0 : ~0;
656 req.u.p.sel.dport_mask = req.u.p.sel.dport == 0 ? 0 : ~0;
657 req.u.p.sel.proto = transport_proto;
658 req.u.p.sel.family = family;
659
660 if (sadb_op == ERO_DELETE || sadb_op == ERO_DEL_INBOUND) {
661 req.u.id.dir = dir;
662 req.n.nlmsg_type = XFRM_MSG_DELPOLICYXFRM_MSG_DELPOLICY;
663 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.id)))( ((((sizeof(req.u.id)) + ((int) ( ((sizeof(struct nlmsghdr))
+4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
664 } else {
665 req.u.p.dir = dir;
666
667 /* The caller should have set the proper priority by now */
668 req.u.p.priority = sa_priority;
669 dbg("IPsec SA SPD priority set to %d", req.u.p.priority){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("IPsec SA SPD priority set to %d", req.u.p.priority
); } }
;
670
671 req.u.p.action = XFRM_POLICY_ALLOW0;
672 if (policy == IPSEC_POLICY_DISCARD)
673 req.u.p.action = XFRM_POLICY_BLOCK1;
674 /* req.u.p.lft.soft_use_expires_seconds = deltasecs(use_lifetime); */
675 req.u.p.lft.soft_byte_limit = XFRM_INF(~(__u64)0);
676 req.u.p.lft.soft_packet_limit = XFRM_INF(~(__u64)0);
677 req.u.p.lft.hard_byte_limit = XFRM_INF(~(__u64)0);
678 req.u.p.lft.hard_packet_limit = XFRM_INF(~(__u64)0);
679
680 /*
681 * NEW will fail when an existing policy, UPD always works.
682 * This seems to happen in cases with NAT'ed XP clients, or
683 * quick recycling/resurfacing of roadwarriors on the same IP.
684 *
685 * UPD is also needed for two separate tunnels with same end
686 * subnets
687 * Like A = B = C config where both A - B and B - C have
688 * tunnel A = C configured.
689 */
690 req.n.nlmsg_type = XFRM_MSG_UPDPOLICYXFRM_MSG_UPDPOLICY;
691 if (sadb_op == ERO_REPLACE)
692 req.n.nlmsg_type = XFRM_MSG_UPDPOLICYXFRM_MSG_UPDPOLICY;
693 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)))( ((((sizeof(req.u.p)) + ((int) ( ((sizeof(struct nlmsghdr))+
4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
694 }
695
696 if (policy == IPSEC_POLICY_IPSEC || policy == IPSEC_POLICY_DISCARD) {
697 if (sadb_op != ERO_DELETE) {
698 struct rtattr *attr;
699
700 struct xfrm_user_tmpl tmpl[4];
701 int i;
702
703 zero(&tmpl)memset((&tmpl), '\0', sizeof(*(&tmpl)));
704 for (i = 0; proto_info[i].proto; i++) {
705 tmpl[i].reqid = proto_info[i].reqid;
706 tmpl[i].id.proto = proto_info[i].proto;
707 tmpl[i].optional = proto_info[i].proto == IPPROTO_COMPIPPROTO_COMP && dir != XFRM_POLICY_OUT;
708 tmpl[i].aalgos = tmpl[i].ealgos = tmpl[i].calgos = ~0;
709 tmpl[i].family = addrtypeof(that_host);
710 tmpl[i].mode = proto_info[i].mode == ENCAPSULATION_MODE_TUNNEL1;
711
712 if (!tmpl[i].mode)
713 continue;
714
715 tmpl[i].saddr = xfrm_from_address(this_host);
716 tmpl[i].id.daddr = xfrm_from_address(that_host);
717 }
718
719 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
720 attr->rta_type = XFRMA_TMPL;
721 attr->rta_len = i * sizeof(tmpl[0]);
722 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, tmpl, attr->rta_len);
723 attr->rta_len = RTA_LENGTH(attr->rta_len)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (attr->
rta_len))
;
724 req.n.nlmsg_len += attr->rta_len;
725 }
726
727 /* mark policy extension */
728 {
729 struct sa_mark sa_mark = (dir == XFRM_POLICY_IN) ? sa_marks->in : sa_marks->out;
730
731 if (sa_mark.val != 0 && sa_mark.mask != 0) {
732 struct xfrm_mark xfrm_mark;
733 struct rtattr* mark_attr;
734
735 xfrm_mark.v = sa_mark.val;
736 xfrm_mark.m = sa_mark.mask;
737 mark_attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
738 mark_attr->rta_type = XFRMA_MARK;
739 mark_attr->rta_len = sizeof(xfrm_mark);
740 memcpy(RTA_DATA(mark_attr)((void*)(((char*)(mark_attr)) + (( ((sizeof(struct rtattr))+4U
-1) & ~(4U -1) ) + (0))))
, &xfrm_mark, mark_attr->rta_len);
741 mark_attr->rta_len = RTA_LENGTH(mark_attr->rta_len)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (mark_attr
->rta_len))
;
742 req.n.nlmsg_len += mark_attr->rta_len;
743 }
744 }
745 if (xfrm_if_id > 0) {
746#ifdef USE_XFRM_INTERFACE1
747 struct rtattr *attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
748 dbg("%s netlink: XFRMA_IF_ID %" PRIu32 " req.n.nlmsg_type=%" PRIu32,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s netlink: XFRMA_IF_ID %" "u" " req.n.nlmsg_type=%"
"u", __func__, xfrm_if_id, req.n.nlmsg_type); } }
749 __func__, xfrm_if_id, req.n.nlmsg_type){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s netlink: XFRMA_IF_ID %" "u" " req.n.nlmsg_type=%"
"u", __func__, xfrm_if_id, req.n.nlmsg_type); } }
;
750 attr->rta_type = XFRMA_IF_ID;
751 attr->rta_len = RTA_LENGTH(sizeof(uint32_t))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(uint32_t)))
;
752 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &xfrm_if_id, sizeof(uint32_t));
753 req.n.nlmsg_len += attr->rta_len;
754
755 /* XFRMA_SET_MARK = XFRMA_IF_ID/0xffffffff */
756 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
757 attr->rta_type = XFRMA_SET_MARK;
758 attr->rta_len = RTA_LENGTH(sizeof(uint32_t))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(uint32_t)))
;
759 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &xfrm_if_id, sizeof(uint32_t));
760 req.n.nlmsg_len += attr->rta_len;
761#endif
762 }
763
764 }
765
766 if (policy_label != NULL((void*)0)) {
767 size_t len = strlen(policy_label) + 1;
768 struct rtattr *attr = (struct rtattr *)
769 ((char *)&req + req.n.nlmsg_len);
770 struct xfrm_user_sec_ctx *uctx;
771
772 passert(len <= MAX_SECCTX_LEN){ _Bool assertion__ = len <= 4096; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 772}, "%s", "len <= MAX_SECCTX_LEN"); } }
;
773 attr->rta_type = XFRMA_SEC_CTX;
774
775 dbg("passing security label \"%s\" to kernel", policy_label){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("passing security label \"%s\" to kernel", policy_label
); } }
;
776 attr->rta_len =
777 RTA_LENGTH(sizeof(struct xfrm_user_sec_ctx) + len)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(struct xfrm_user_sec_ctx) + len))
;
778 uctx = RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
;
779 uctx->exttype = XFRMA_SEC_CTX;
780 uctx->len = sizeof(struct xfrm_user_sec_ctx) + len;
781 uctx->ctx_doi = 1; /* ??? hardwired and nameless */
782 uctx->ctx_alg = 1; /* ??? hardwired and nameless */
783 uctx->ctx_len = len;
784 memcpy(uctx + 1, policy_label, len);
785 req.n.nlmsg_len += attr->rta_len;
786 }
787
788 bool_Bool enoent_ok = sadb_op == ERO_DEL_INBOUND ||
789 (sadb_op == ERO_DELETE && ntohl(cur_spi) == SPI_HOLD259);
790
791 bool_Bool ok = netlink_policy(&req.n, enoent_ok, text_said);
792
793 /* ??? deal with any forwarding policy */
794 switch (dir) {
795 case XFRM_POLICY_IN:
796 if (req.n.nlmsg_type == XFRM_MSG_DELPOLICYXFRM_MSG_DELPOLICY) {
797 /* ??? we will call netlink_policy even if !ok. */
798 req.u.id.dir = XFRM_POLICY_FWD;
799 } else if (!ok) {
800 break;
801 } else if (proto_info[0].mode != ENCAPSULATION_MODE_TUNNEL1 &&
802 esatype != ET_INT) {
803 break;
804 } else {
805 req.u.p.dir = XFRM_POLICY_FWD;
806 }
807 ok &= netlink_policy(&req.n, enoent_ok, text_said);
808 break;
809 }
810
811 return ok;
812}
813
814static void netlink_sa_policy_to_id(struct xfrm_userpolicy_id *id,
815 struct xfrm_userpolicy_info *pol)
816{
817 id->sel = pol->sel;
818 id->index = pol->index;
819 id->dir = pol->dir;
820}
821
822static bool_Bool netlink_get_sa_policy(const struct kernel_sa *sa,
823 struct xfrm_userpolicy_id *id)
824{
825 struct {
826 struct nlmsghdr n;
827 struct xfrm_userpolicy_id id;
828 } req;
829 struct nlm_resp rsp;
830
831 zero(&req)memset((&req), '\0', sizeof(*(&req)));
832 zero(&rsp)memset((&rsp), '\0', sizeof(*(&rsp)));
833
834 req.n.nlmsg_flags = NLM_F_REQUEST0x01;
835 req.n.nlmsg_type = XFRM_MSG_GETPOLICYXFRM_MSG_GETPOLICY;
836 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)))( ((((sizeof(req.id)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
837
838 req.id.dir = sa->nk_dir; /* clang 6.0.0 thinks RHS is garbage or undefined */
839 req.id.sel.family = address_type(sa->src.address)->af;
840
841 /* .[sd]addr, .prefixlen_[sd], .[sd]port */
842 SELECTOR_TO_XFRM(sa->src.client, req.id.sel, s){ ip_selector client_ = *(sa->src.client); ip_address address
= selector_prefix(&client_); (req.id.sel).saddr = xfrm_from_address
(&address); (req.id.sel).prefixlen_s = selector_maskbits(
&client_); (req.id.sel).sport = nport(selector_port(&
client_)); }
;
843 SELECTOR_TO_XFRM(sa->dst.client, req.id.sel, d){ ip_selector client_ = *(sa->dst.client); ip_address address
= selector_prefix(&client_); (req.id.sel).daddr = xfrm_from_address
(&address); (req.id.sel).prefixlen_d = selector_maskbits(
&client_); (req.id.sel).dport = nport(selector_port(&
client_)); }
;
844
845 /*
846 * XXX: the other calls to CLIENT_TO_XFRM() also munge the
847 * .[sd]port per ICMP, and set .[sd]port_mask.
848 *
849 * This code does not.
850 *
851 * Presumably this code, which is called from
852 * netlink_migrate_sa(), and is handling MOBIKE only allows
853 * addresses (no port, no rotocol). Hence the default value
854 * of .[sd]port_mask (0), is correct.
855 */
856
857 if (!send_netlink_msg(&req.n, XFRM_MSG_NEWPOLICYXFRM_MSG_NEWPOLICY, &rsp, "Get policy",
858 sa->text_said)) {
859 dbg(" netlink_get_sa_policy : policy died on us: %s, index=%d %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" netlink_get_sa_policy : policy died on us: %s, index=%d %s"
, enum_name(&netkey_sa_dir_names, req.id.dir), req.id.index
, sa->text_said); } }
860 enum_name(&netkey_sa_dir_names, req.id.dir),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" netlink_get_sa_policy : policy died on us: %s, index=%d %s"
, enum_name(&netkey_sa_dir_names, req.id.dir), req.id.index
, sa->text_said); } }
861 req.id.index, sa->text_said){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" netlink_get_sa_policy : policy died on us: %s, index=%d %s"
, enum_name(&netkey_sa_dir_names, req.id.dir), req.id.index
, sa->text_said); } }
;
862 return FALSE0;
863 } else if (rsp.n.nlmsg_len < NLMSG_LENGTH(sizeof(rsp.u.pol))((sizeof(rsp.u.pol)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) )))
) {
864 libreswan_log(" netlink_get_sa_policy: XFRM_MSG_GETPOLICY %s "loglog(RC_LOG, " netlink_get_sa_policy: XFRM_MSG_GETPOLICY %s "
"returned message with length %zu < %zu " "bytes; ignore message"
, enum_name(&netkey_sa_dir_names, req.id.dir), (size_t) rsp
.n.nlmsg_len, sizeof(rsp.u.pol))
865 "returned message with length %zu < %zu "loglog(RC_LOG, " netlink_get_sa_policy: XFRM_MSG_GETPOLICY %s "
"returned message with length %zu < %zu " "bytes; ignore message"
, enum_name(&netkey_sa_dir_names, req.id.dir), (size_t) rsp
.n.nlmsg_len, sizeof(rsp.u.pol))
866 "bytes; ignore message",loglog(RC_LOG, " netlink_get_sa_policy: XFRM_MSG_GETPOLICY %s "
"returned message with length %zu < %zu " "bytes; ignore message"
, enum_name(&netkey_sa_dir_names, req.id.dir), (size_t) rsp
.n.nlmsg_len, sizeof(rsp.u.pol))
867 enum_name(&netkey_sa_dir_names, req.id.dir),loglog(RC_LOG, " netlink_get_sa_policy: XFRM_MSG_GETPOLICY %s "
"returned message with length %zu < %zu " "bytes; ignore message"
, enum_name(&netkey_sa_dir_names, req.id.dir), (size_t) rsp
.n.nlmsg_len, sizeof(rsp.u.pol))
868 (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.pol))loglog(RC_LOG, " netlink_get_sa_policy: XFRM_MSG_GETPOLICY %s "
"returned message with length %zu < %zu " "bytes; ignore message"
, enum_name(&netkey_sa_dir_names, req.id.dir), (size_t) rsp
.n.nlmsg_len, sizeof(rsp.u.pol))
;
869 return FALSE0;
870 }
871
872 netlink_sa_policy_to_id(id, &rsp.u.pol);
873
874 return TRUE1;
875}
876
877static void set_migration_attr(const struct kernel_sa *sa,
878 struct xfrm_user_migrate *m)
879{
880 m->old_saddr = xfrm_from_address(sa->src.address);
881 m->old_daddr = xfrm_from_address(sa->dst.address);
882 m->new_saddr = xfrm_from_address(sa->src.new_address);
883 m->new_daddr = xfrm_from_address(sa->dst.new_address);
884
885 m->proto = sa->proto->ipproto;
886 m->mode = XFRM_MODE_TUNNEL1; /* AA_201705 hard coded how to figure this out */
887 m->reqid = sa->reqid;
888 m->old_family = m->new_family = address_type(sa->src.address)->af;
889}
890
891static bool_Bool create_xfrm_migrate_sa(struct state *st, const int dir,
892 struct kernel_sa *ret_sa, char *text_said)
893{
894 const struct connection *const c = st->st_connection;
895
896 const struct ip_encap *encap_type =
897 (st->st_interface->protocol == &ip_protocol_tcp) ? &ip_encap_esp_in_tcp :
898 (st->hidden_variables.st_nat_traversal & NAT_T_DETECTED( ((lset_t)1 << (NATED_HOST)) | ((lset_t)1 << (NATED_PEER
)) )
) ? &ip_encap_esp_in_udp :
899 NULL((void*)0);
900 dbg("TCP/NAT: encap type "PRI_IP_ENCAP, pri_ip_encap(encap_type)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("TCP/NAT: encap type ""%u(%s)", (encap_type) ==
((void*)0) ? 0 : (encap_type)->encap_type, (encap_type) ==
((void*)0) ? "none" : (encap_type)->name); } }
;
901
902 const struct ip_protocol *proto;
903 struct ipsec_proto_info *proto_info;
904
905 if (st->st_esp.present) {
906 proto = &ip_protocol_esp;
907 proto_info = &st->st_esp;
908 } else if (st->st_ah.present) {
909 proto = &ip_protocol_ah;
910 proto_info = &st->st_ah;
911 } else {
912 return FALSE0;
913 }
914
915 struct kernel_sa sa = {
916 .nk_dir = dir,
917 .proto = proto,
918 .reqid = reqid_esp(c->spd.reqid),
919 .encap_type = encap_type,
920 };
921
922 ip_endpoint new_endpoint;
923 uint16_t old_port;
924 uint16_t encap_sport = 0;
925 uint16_t encap_dport = 0;
926 const ip_address *src, *dst;
927 const ip_subnet *src_client, *dst_client;
928
929 if (endpoint_type(&st->st_mobike_local_endpoint) != NULL((void*)0)) {
930 char *n = jam_str(text_said, SAMIGTOT_BUF(16 + sizeof(said_buf) + sizeof(address_reversed_buf)), "initiator migrate kernel SA ");
931 passert((SAMIGTOT_BUF - strlen(text_said)) > SATOT_BUF){ _Bool assertion__ = ((16 + sizeof(said_buf) + sizeof(address_reversed_buf
)) - strlen(text_said)) > sizeof(said_buf); if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"kernel_xfrm.c" , .line = 931}, "%s", "(SAMIGTOT_BUF - strlen(text_said)) > SATOT_BUF"
); } }
;
932 pexpect_st_local_endpoint(st);
933 old_port = endpoint_hport(&st->st_interface->local_endpoint);
934 new_endpoint = st->st_mobike_local_endpoint;
935
936 if (dir == XFRM_POLICY_IN || dir == XFRM_POLICY_FWD) {
937 src = &c->spd.that.host_addr;
938 dst = &c->spd.this.host_addr;
939 src_client = &c->spd.that.client;
940 dst_client = &c->spd.this.client;
941 sa.src.new_address = src;
942 sa.dst.new_address = &st->st_mobike_local_endpoint;
943 sa.spi = proto_info->our_spi;
944 set_text_said(n, dst, sa.spi, proto);
945 if (encap_type != NULL((void*)0)) {
946 encap_sport = endpoint_hport(&st->st_remote_endpoint);
947 encap_dport = endpoint_hport(&st->st_mobike_local_endpoint);
948 }
949 } else {
950 src = &c->spd.this.host_addr;
951 dst = &c->spd.that.host_addr;
952 src_client = &c->spd.this.client;
953 dst_client = &c->spd.that.client;
954 sa.src.new_address = &st->st_mobike_local_endpoint;
955 sa.dst.new_address = dst;
956 sa.spi = proto_info->attrs.spi;
957 set_text_said(n, src, sa.spi, proto);
958 if (encap_type != NULL((void*)0)) {
959 encap_sport = endpoint_hport(&st->st_mobike_local_endpoint);
960 encap_dport = endpoint_hport(&st->st_remote_endpoint);
961 }
962 }
963 } else {
964 char *n = jam_str(text_said, SAMIGTOT_BUF(16 + sizeof(said_buf) + sizeof(address_reversed_buf)), "responder migrate kernel SA ");
965 passert((SAMIGTOT_BUF - strlen(text_said)) > SATOT_BUF){ _Bool assertion__ = ((16 + sizeof(said_buf) + sizeof(address_reversed_buf
)) - strlen(text_said)) > sizeof(said_buf); if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"kernel_xfrm.c" , .line = 965}, "%s", "(SAMIGTOT_BUF - strlen(text_said)) > SATOT_BUF"
); } }
;
966 old_port = endpoint_hport(&st->st_remote_endpoint);
967 new_endpoint = st->st_mobike_remote_endpoint;
968
969 if (dir == XFRM_POLICY_IN || dir == XFRM_POLICY_FWD) {
970 src = &c->spd.that.host_addr;
971 dst = &c->spd.this.host_addr;
972 src_client = &c->spd.that.client;
973 dst_client = &c->spd.this.client;
974 sa.src.new_address = &st->st_mobike_remote_endpoint;
975 sa.dst.new_address = &c->spd.this.host_addr;
976 sa.spi = proto_info->our_spi;
977 set_text_said(n, src, sa.spi, proto);
978 if (encap_type != NULL((void*)0)) {
979 encap_sport = endpoint_hport(&st->st_mobike_remote_endpoint);
980 pexpect_st_local_endpoint(st);
981 encap_dport = endpoint_hport(&st->st_interface->local_endpoint);
982 }
983 } else {
984 src = &c->spd.this.host_addr;
985 dst = &c->spd.that.host_addr;
986 src_client = &c->spd.this.client;
987 dst_client = &c->spd.that.client;
988 sa.src.new_address = &c->spd.this.host_addr;
989 sa.dst.new_address = &st->st_mobike_remote_endpoint;
990 sa.spi = proto_info->attrs.spi;
991 set_text_said(n, dst, sa.spi, proto);
992
993 if (encap_type != NULL((void*)0)) {
994 pexpect_st_local_endpoint(st);
995 encap_sport = endpoint_hport(&st->st_interface->local_endpoint);
996 encap_dport = endpoint_hport(&st->st_mobike_remote_endpoint);
997 }
998 }
999 }
1000
1001 sa.src.address = src;
1002 sa.dst.address = dst;
1003 sa.text_said = text_said;
1004 sa.src.client = src_client;
1005 sa.dst.client = dst_client;
1006 sa.src.encap_port = encap_sport;
1007 sa.dst.encap_port = encap_dport;
1008
1009 char reqid_buf[ULTOT_BUF(22 + 1) + 32];
1010 endpoint_buf ra;
1011 snprintf(reqid_buf, sizeof(reqid_buf), ":%u to %s reqid=%u %s",
1012 old_port,
1013 str_endpoint(&new_endpoint, &ra),
1014 sa.reqid,
1015 enum_name(&netkey_sa_dir_names, dir));
1016 add_str(text_said, SAMIGTOT_BUF(16 + sizeof(said_buf) + sizeof(address_reversed_buf)), text_said, reqid_buf);
1017
1018 dbg("%s", text_said){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s", text_said); } }
;
1019
1020 *ret_sa = sa;
1021 return TRUE1;
1022}
1023
1024static bool_Bool migrate_xfrm_sa(const struct kernel_sa *sa)
1025{
1026 struct {
1027 struct nlmsghdr n;
1028 struct xfrm_userpolicy_id id;
1029 char data[MAX_NETLINK_DATA_SIZE8192];
1030 } req;
1031 struct nlm_resp rsp;
1032 struct rtattr *attr;
1033
1034 zero(&req)memset((&req), '\0', sizeof(*(&req)));
1035
1036 if (!netlink_get_sa_policy(sa, &req.id)) {
1037 return FALSE0;
1038 }
1039
1040 req.n.nlmsg_flags = NLM_F_REQUEST0x01 | NLM_F_ACK0x04;
1041 req.n.nlmsg_type = XFRM_MSG_MIGRATEXFRM_MSG_MIGRATE;
1042 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)))( ((((sizeof(req.id)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
1043
1044
1045 /* add attrs[XFRM_MSG_MIGRATE] */
1046 {
1047 struct xfrm_user_migrate migrate;
1048
1049 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
1050 attr->rta_type = XFRMA_MIGRATE;
1051 attr->rta_len = sizeof(migrate);
1052
1053 set_migration_attr(sa, &migrate);
1054
1055 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &migrate, attr->rta_len);
1056 attr->rta_len = RTA_LENGTH(attr->rta_len)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (attr->
rta_len))
;
1057 req.n.nlmsg_len += attr->rta_len;
1058 }
1059
1060 if (sa->encap_type != NULL((void*)0)) {
1061 dbg("adding xfrm_encap_templ when migrating sa encap_type="PRI_IP_ENCAP" sport=%d dport=%d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding xfrm_encap_templ when migrating sa encap_type="
"%u(%s)"" sport=%d dport=%d", (sa->encap_type) == ((void*)
0) ? 0 : (sa->encap_type)->encap_type, (sa->encap_type
) == ((void*)0) ? "none" : (sa->encap_type)->name, sa->
src.encap_port, sa->dst.encap_port); } }
1062 pri_ip_encap(sa->encap_type),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding xfrm_encap_templ when migrating sa encap_type="
"%u(%s)"" sport=%d dport=%d", (sa->encap_type) == ((void*)
0) ? 0 : (sa->encap_type)->encap_type, (sa->encap_type
) == ((void*)0) ? "none" : (sa->encap_type)->name, sa->
src.encap_port, sa->dst.encap_port); } }
1063 sa->src.encap_port, sa->dst.encap_port){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding xfrm_encap_templ when migrating sa encap_type="
"%u(%s)"" sport=%d dport=%d", (sa->encap_type) == ((void*)
0) ? 0 : (sa->encap_type)->encap_type, (sa->encap_type
) == ((void*)0) ? "none" : (sa->encap_type)->name, sa->
src.encap_port, sa->dst.encap_port); } }
;
1064 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
1065 struct xfrm_encap_tmpl natt;
1066
1067 natt.encap_type = sa->encap_type->encap_type;
1068 natt.encap_sport = ntohs(sa->src.encap_port);
1069 natt.encap_dport = ntohs(sa->dst.encap_port);
1070 zero(&natt.encap_oa)memset((&natt.encap_oa), '\0', sizeof(*(&natt.encap_oa
)))
;
1071
1072 attr->rta_type = XFRMA_ENCAP;
1073 attr->rta_len = RTA_LENGTH(sizeof(natt))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(natt)))
;
1074
1075 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &natt, sizeof(natt));
1076
1077 req.n.nlmsg_len += attr->rta_len;
1078 }
1079
1080 bool_Bool r = send_netlink_msg(&req.n, NLMSG_ERROR0x2, &rsp, "mobike",
1081 sa->text_said);
1082 if (!r)
1083 return FALSE0;
1084
1085 if (rsp.u.e.error < 0) {
1086 /* error is already logged */
1087 return FALSE0;
1088 }
1089
1090 return TRUE1;
1091}
1092
1093static bool_Bool netlink_migrate_sa(struct state *st)
1094{
1095 struct kernel_sa sa;
1096 char mig_said[SAMIGTOT_BUF(16 + sizeof(said_buf) + sizeof(address_reversed_buf))];
1097
1098 return
1099 create_xfrm_migrate_sa(st, XFRM_POLICY_OUT, &sa, mig_said) &&
1100 migrate_xfrm_sa(&sa) &&
1101
1102 create_xfrm_migrate_sa(st, XFRM_POLICY_IN, &sa, mig_said) &&
1103 migrate_xfrm_sa(&sa) &&
1104
1105 create_xfrm_migrate_sa(st, XFRM_POLICY_FWD, &sa, mig_said) &&
1106 migrate_xfrm_sa(&sa);
1107}
1108
1109
1110/* see /usr/include/linux/ethtool.h */
1111
1112enum nic_offload_state {
1113 NIC_OFFLOAD_UNKNOWN,
1114 NIC_OFFLOAD_UNSUPPORTED,
1115 NIC_OFFLOAD_SUPPORTED
1116};
1117
1118static struct {
1119 unsigned int bit;
1120 unsigned int total_blocks;
1121 enum nic_offload_state state;
1122} netlink_esp_hw_offload;
1123
1124static bool_Bool siocethtool(const char *ifname, void *data, const char *action)
1125{
1126 struct ifreq ifr = { .ifr_dataifr_ifru.ifru_data = data };
1127 jam_str(ifr.ifr_nameifr_ifrn.ifrn_name, sizeof(ifr.ifr_nameifr_ifrn.ifrn_name), ifname);
1128 if (ioctl(nl_send_fd, SIOCETHTOOL0x8946, &ifr) != 0) {
1129 /* EOPNOTSUPP is expected if kernel doesn't support this */
1130 if (errno(*__errno_location ()) == EOPNOTSUPP95) {
1131 dbg("cannot offload to %s because SIOCETHTOOL %s failed: %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("cannot offload to %s because SIOCETHTOOL %s failed: %s"
, ifname, action, strerror((*__errno_location ()))); } }
1132 ifname, action, strerror(errno)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("cannot offload to %s because SIOCETHTOOL %s failed: %s"
, ifname, action, strerror((*__errno_location ()))); } }
;
1133 } else {
1134 LOG_ERRNO(errno, "can't offload to %s because SIOCETHTOOL %s failed",{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "can't offload to %s because SIOCETHTOOL %s failed", ifname
, action); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (
e_), strerror(e_)); jambuf_to_error_stream(buf); } }
1135 ifname, action){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "can't offload to %s because SIOCETHTOOL %s failed", ifname
, action); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (
e_), strerror(e_)); jambuf_to_error_stream(buf); } }
;
1136 }
1137 return false0;
1138 } else {
1139 return true1;
1140 }
1141}
1142
1143static void netlink_find_offload_feature(const char *ifname)
1144{
1145 netlink_esp_hw_offload.state = NIC_OFFLOAD_UNSUPPORTED;
1146
1147 /* Determine number of device-features */
1148
1149 struct ethtool_sset_info *sset_info = alloc_bytes(
1150 sizeof(*sset_info) + sizeof(sset_info->data[0]),
1151 "ethtool_sset_info");
1152 sset_info->cmd = ETHTOOL_GSSET_INFO0x00000037;
1153 sset_info->sset_mask = 1ULL << ETH_SS_FEATURES;
1154
1155 if (!siocethtool(ifname, sset_info, "ETHTOOL_GSSET_INFO") ||
1156 sset_info->sset_mask != 1ULL << ETH_SS_FEATURES) {
1157 pfree(sset_info);
1158 libreswan_log("Kernel does not support NIC esp-hw-offload (ETHTOOL_GSSET_INFO failed)")loglog(RC_LOG, "Kernel does not support NIC esp-hw-offload (ETHTOOL_GSSET_INFO failed)"
)
;
1159 return;
1160 }
1161
1162 uint32_t sset_len = sset_info->data[0];
1163
1164 pfree(sset_info);
1165
1166 /* Retrieve names of device-features */
1167
1168 struct ethtool_gstrings *cmd = alloc_bytes(
1169 sizeof(*cmd) + ETH_GSTRING_LEN32 * sset_len, "ethtool_gstrings");
1170 cmd->cmd = ETHTOOL_GSTRINGS0x0000001b;
1171 cmd->string_set = ETH_SS_FEATURES;
1172
1173 if (siocethtool(ifname, cmd, "ETHTOOL_GSTRINGS")) {
1174 /* Look for the ESP_HW feature bit */
1175 char *str = (char *)cmd->data;
1176 for (uint32_t i = 0; i < cmd->len; i++) {
1177 if (strneq(str, "esp-hw-offload", ETH_GSTRING_LEN)(strncmp((str), ("esp-hw-offload"), (32)) == 0)) {
1178 netlink_esp_hw_offload.bit = i;
1179 netlink_esp_hw_offload.total_blocks = (sset_len + 31) / 32;
1180 netlink_esp_hw_offload.state = NIC_OFFLOAD_SUPPORTED;
1181 break;
1182 }
1183 str += ETH_GSTRING_LEN32;
1184 }
1185 }
1186
1187 pfree(cmd);
1188
1189 if (netlink_esp_hw_offload.state == NIC_OFFLOAD_SUPPORTED) {
1190 libreswan_log("Kernel supports NIC esp-hw-offload")loglog(RC_LOG, "Kernel supports NIC esp-hw-offload");
1191 } else {
1192 libreswan_log("Kernel does not support NIC esp-hw-offload")loglog(RC_LOG, "Kernel does not support NIC esp-hw-offload");
1193 }
1194}
1195
1196static bool_Bool netlink_detect_offload(const struct raw_iface *ifp)
1197{
1198 const char *ifname = ifp->name;
1199 /*
1200 * Kernel requires a real interface in order to query the kernel-wide
1201 * capability, so we do it here on first invocation.
1202 */
1203 if (netlink_esp_hw_offload.state == NIC_OFFLOAD_UNKNOWN)
1204 netlink_find_offload_feature(ifname);
1205
1206 if (netlink_esp_hw_offload.state == NIC_OFFLOAD_UNSUPPORTED) {
1207 return false0;
1208 }
1209
1210 /* Feature is supported by kernel. Query device features */
1211
1212 struct ethtool_gfeatures *cmd = alloc_bytes(
1213 sizeof(*cmd) + sizeof(cmd->features[0]) * netlink_esp_hw_offload.total_blocks,
1214 "ethtool_gfeatures");
1215
1216 cmd->cmd = ETHTOOL_GFEATURES0x0000003a;
1217 cmd->size = netlink_esp_hw_offload.total_blocks;
1218
1219 bool_Bool ret = false0;
1220
1221 if (siocethtool(ifname, cmd, "ETHTOOL_GFEATURES")) {
1222 int block = netlink_esp_hw_offload.bit / 32;
1223 uint32_t feature_bit = 1U << (netlink_esp_hw_offload.bit % 32);
1224 if (cmd->features[block].active & feature_bit)
1225 ret = true1;
1226 }
1227 pfree(cmd);
1228 return ret;
1229}
1230
1231/*
1232 * netlink_add_sa - Add an SA into the kernel SPDB via netlink
1233 *
1234 * @param sa Kernel SA to add/modify
1235 * @param replace boolean - true if this replaces an existing SA
1236 * @return bool True if successful
1237 */
1238static bool_Bool netlink_add_sa(const struct kernel_sa *sa, bool_Bool replace)
1239{
1240 struct {
1241 struct nlmsghdr n;
1242 struct xfrm_usersa_info p;
1243 char data[MAX_NETLINK_DATA_SIZE8192];
1244 } req;
1245 struct rtattr *attr;
1246 int ret;
1247
1248 zero(&req)memset((&req), '\0', sizeof(*(&req)));
1249 req.n.nlmsg_flags = NLM_F_REQUEST0x01 | NLM_F_ACK0x04;
1250 req.n.nlmsg_type = replace ? XFRM_MSG_UPDSAXFRM_MSG_UPDSA : XFRM_MSG_NEWSAXFRM_MSG_NEWSA;
1251
1252 req.p.saddr = xfrm_from_address(sa->src.address);
1253 req.p.id.daddr = xfrm_from_address(sa->dst.address);
1254
1255 req.p.id.spi = sa->spi;
1256 req.p.id.proto = esatype2proto(sa->esatype)((int)(sa->esatype));
1257 req.p.family = addrtypeof(sa->src.address);
1258 /*
1259 * This requires ipv6 modules. It is required to support 6in4 and 4in6
1260 * tunnels in linux 2.6.25+
1261 */
1262 if (sa->mode == ENCAPSULATION_MODE_TUNNEL1) {
1263 dbg("netlink: enabling tunnel mode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: enabling tunnel mode"); } }
;
1264 req.p.mode = XFRM_MODE_TUNNEL1;
1265 req.p.flags |= XFRM_STATE_AF_UNSPEC32;
1266 } else {
1267 dbg("netlink: enabling transport mode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: enabling transport mode"); } }
;
1268 req.p.mode = XFRM_MODE_TRANSPORT0;
1269 }
1270
1271 /*
1272 * We only add traffic selectors for transport mode. The problem is
1273 * that Tunnel mode ipsec with ipcomp is layered so that ipcomp
1274 * tunnel is protected with transport mode ipsec but in this case we
1275 * shouldn't any more add traffic selectors. Caller function will
1276 * inform us if we need or don't need selectors.
1277 */
1278 if (sa->add_selector) {
1279 ip_selector src = *sa->src.client;
1280 ip_selector dst = *sa->dst.client;
1281
1282 /*
1283 * With XFRM/NETKEY and transport mode with nat-traversal we
1284 * need to change outbound IPsec SA to point to external ip of
1285 * the peer. Here we substitute real client ip with NATD ip.
1286 *
1287 * XXX: unset_protoport is technically wrong - the
1288 * protocol is sa->transport_proto(?) and . Code
1289 * further down will fix up the .sport / .dport in the
1290 * xfrm structure.
1291 *
1292 * XXX: is .src.address / .dst.address an address or
1293 * endpoint in disguise?
1294 */
1295 if (sa->inbound) {
1296 /* inbound; fix this end */
1297 ip_port port = selector_port(sa->src.client);
1298 ip_protoport protoport = protoport2(sa->transport_proto, port);
1299 src = selector_from_address(sa->src.address, &protoport);
1300 } else {
1301 /* outbound; fix other end */
1302 ip_port port = selector_port(sa->dst.client);
1303 ip_protoport protoport = protoport2(sa->transport_proto, port);
1304 dst = selector_from_address(sa->dst.address, &protoport);
1305 }
1306
1307 /* .[sd]addr, .prefixlen_[sd], .[sd]port */
1308 SELECTOR_TO_XFRM(&src, req.p.sel, s){ ip_selector client_ = *(&src); ip_address address = selector_prefix
(&client_); (req.p.sel).saddr = xfrm_from_address(&address
); (req.p.sel).prefixlen_s = selector_maskbits(&client_);
(req.p.sel).sport = nport(selector_port(&client_)); }
;
1309 SELECTOR_TO_XFRM(&dst, req.p.sel, d){ ip_selector client_ = *(&dst); ip_address address = selector_prefix
(&client_); (req.p.sel).daddr = xfrm_from_address(&address
); (req.p.sel).prefixlen_d = selector_maskbits(&client_);
(req.p.sel).dport = nport(selector_port(&client_)); }
;
1310
1311 /*
1312 * Munge .[sd]port?
1313 *
1314 * As per RFC 4301/5996, icmp type is put in the most
1315 * significant 8 bits and icmp code is in the least
1316 * significant 8 bits of port field. Although Libreswan does
1317 * not have any configuration options for
1318 * icmp type/code values, it is possible to specify icmp type
1319 * and code using protoport option. For example,
1320 * icmp echo request (type 8/code 0) needs to be encoded as
1321 * 0x0800 in the port field and can be specified
1322 * as left/rightprotoport=icmp/2048. Now with XFRM,
1323 * icmp type and code need to be passed as source and
1324 * destination ports, respectively. Therefore, this code
1325 * extracts upper 8 bits and lower 8 bits and puts
1326 * into source and destination ports before passing to XFRM.
1327 */
1328 if (IPPROTO_ICMPIPPROTO_ICMP == sa->transport_proto ||
1329 IPPROTO_ICMPV658 == sa->transport_proto) {
1330 uint16_t icmp_type;
1331 uint16_t icmp_code;
1332
1333 icmp_type = ntohs(req.p.sel.sport) >> 8;
1334 icmp_code = ntohs(req.p.sel.sport) & 0xFF;
1335
1336 req.p.sel.sport = htons(icmp_type);
1337 req.p.sel.dport = htons(icmp_code);
1338 }
1339
1340 req.p.sel.sport_mask = req.p.sel.sport == 0 ? 0 : ~0;
1341 req.p.sel.dport_mask = req.p.sel.dport == 0 ? 0 : ~0;
1342 req.p.sel.proto = sa->transport_proto;
1343 req.p.sel.family = subnet_type(&src)->af;
1344 }
1345
1346 req.p.reqid = sa->reqid;
1347 dbg("XFRM: adding IPsec SA with reqid %d", sa->reqid){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("XFRM: adding IPsec SA with reqid %d", sa->
reqid); } }
;
1348
1349 /* TODO expose limits to kernel_sa via config */
1350 req.p.lft.soft_byte_limit = XFRM_INF(~(__u64)0);
1351 req.p.lft.soft_packet_limit = XFRM_INF(~(__u64)0);
1352 req.p.lft.hard_byte_limit = XFRM_INF(~(__u64)0);
1353 req.p.lft.hard_packet_limit = XFRM_INF(~(__u64)0);
1354
1355 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.p)))( ((((sizeof(req.p)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
1356
1357 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
1358
1359 /*
1360 * The Linux IPv4 AH stack aligns the AH header on a 64 bit boundary
1361 * (like in IPv6). This is not RFC compliant (see RFC4302, Section
1362 * 3.3.3.2.1), it should be aligned on 32 bits.
1363 *
1364 * For most of the authentication algorithms, the ICV size is 96 bits.
1365 * The AH header alignment on 32 or 64 bits gives the same results.
1366 *
1367 * However for SHA-256-128 for instance, the wrong 64 bit alignment results
1368 * in adding useless padding in IPv4 AH, which is forbidden by the RFC.
1369 *
1370 * To avoid breaking backward compatibility, we use a new flag
1371 * (XFRM_STATE_ALIGN4) do change original behavior.
1372 */
1373 if (sa->esatype == ET_AH && addrtypeof(sa->src.address) == AF_INET2) {
1374 dbg("netlink: aligning IPv4 AH to 32bits as per RFC-4302, Section 3.3.3.2.1"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: aligning IPv4 AH to 32bits as per RFC-4302, Section 3.3.3.2.1"
); } }
;
1375 req.p.flags |= XFRM_STATE_ALIGN464;
1376 }
1377
1378 if (sa->esatype != ET_IPCOMP) {
1379 if (sa->esn) {
1380 dbg("netlink: enabling ESN"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: enabling ESN"); } }
;
1381 req.p.flags |= XFRM_STATE_ESN128;
1382 }
1383 if (sa->decap_dscp) {
1384 dbg("netlink: enabling Decap DSCP"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: enabling Decap DSCP"); } }
;
1385 req.p.flags |= XFRM_STATE_DECAP_DSCP2;
1386 }
1387 if (sa->nopmtudisc) {
1388 dbg("netlink: disabling Path MTU Discovery"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: disabling Path MTU Discovery"); } }
;
1389 req.p.flags |= XFRM_STATE_NOPMTUDISC4;
1390 }
1391
1392 if (sa->replay_window <= 32 && !sa->esn) {
1393 /* this only works up to 32, for > 32 and for ESN, we need struct xfrm_replay_state_esn */
1394 req.p.replay_window = sa->replay_window;
1395 dbg("netlink: setting IPsec SA replay-window to %d using old-style req",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: setting IPsec SA replay-window to %d using old-style req"
, req.p.replay_window); } }
1396 req.p.replay_window){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: setting IPsec SA replay-window to %d using old-style req"
, req.p.replay_window); } }
;
1397 } else {
1398 uint32_t bmp_size = BYTES_FOR_BITS(sa->replay_window +(((sa->replay_window + (((sizeof(uint32_t) * 8) - 1) - (((
sa->replay_window) + (sizeof(uint32_t) * 8) - 1) % (sizeof
(uint32_t) * 8)))) + 8 - 1) / 8)
1399 pad_up(sa->replay_window, sizeof(uint32_t) * BITS_PER_BYTE) )(((sa->replay_window + (((sizeof(uint32_t) * 8) - 1) - (((
sa->replay_window) + (sizeof(uint32_t) * 8) - 1) % (sizeof
(uint32_t) * 8)))) + 8 - 1) / 8)
;
1400 /* this is where we could fill in sequence numbers for this SA */
1401 struct xfrm_replay_state_esn xre = {
1402 /* replay_window must be multiple of 8 */
1403 .replay_window = sa->replay_window,
1404 .bmp_len = bmp_size / sizeof(uint32_t),
1405 };
1406 dbg("netlink: setting IPsec SA replay-window to %" PRIu32 " using xfrm_replay_state_esn",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: setting IPsec SA replay-window to %"
"u" " using xfrm_replay_state_esn", xre.replay_window); } }
1407 xre.replay_window){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: setting IPsec SA replay-window to %"
"u" " using xfrm_replay_state_esn", xre.replay_window); } }
;
1408
1409 attr->rta_type = XFRMA_REPLAY_ESN_VAL;
1410 attr->rta_len = RTA_LENGTH(sizeof(xre) + bmp_size)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(xre) + bmp_size))
;
1411 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &xre, sizeof(xre));
1412 req.n.nlmsg_len += attr->rta_len;
1413 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
1414 }
1415 }
1416
1417 if (sa->authkeylen != 0) {
1418 const char *name = sa->integ->integ_netlink_xfrm_name;
1419 if (name == NULL((void*)0)) {
1420 loglog(RC_LOG_SERIOUS,
1421 "XFRM: unknown authentication algorithm: %s",
1422 sa->integ->common.fqn);
1423 return FALSE0;
1424 }
1425
1426 /*
1427 * According to RFC-4868 the hash should be nnn/2, so
1428 * 128 bits for SHA256 and 256 for SHA512. The XFRM
1429 * kernel uses a default of 96, which was the value in
1430 * an earlier draft. The kernel then introduced a new struct
1431 * xfrm_algo_auth to replace struct xfrm_algo to deal with
1432 * this.
1433 */
1434
1435 struct xfrm_algo_auth algo = {
1436 .alg_key_len = sa->integ->integ_keymat_size * BITS_PER_BYTE8,
1437 .alg_trunc_len = sa->integ->integ_output_size * BITS_PER_BYTE8,
1438 };
1439
1440 attr->rta_type = XFRMA_ALG_AUTH_TRUNC;
1441 attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->authkeylen)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(algo) + sa->authkeylen))
;
1442
1443 fill_and_terminate(algo.alg_name, name, sizeof(algo.alg_name)){ strncpy((algo.alg_name), (name), (sizeof(algo.alg_name))-1)
; (algo.alg_name)[(sizeof(algo.alg_name))-1] = '\0'; }
;
1444 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &algo, sizeof(algo));
1445 memcpy((char *)RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
+ sizeof(algo),
1446 sa->authkey, sa->authkeylen);
1447
1448 req.n.nlmsg_len += attr->rta_len;
1449 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1450 }
1451
1452 /*
1453 * ??? why does IPCOMP trump aead and ESP?
1454 * Shouldn't all be bundled?
1455 */
1456 if (sa->esatype == ET_IPCOMP) {
1457 struct xfrm_algo algo;
1458 const char *name = sparse_name(calg_list, sa->compalg);
1459
1460 if (name == NULL((void*)0)) {
1461 loglog(RC_LOG_SERIOUS,
1462 "unknown compression algorithm: %u",
1463 sa->compalg);
1464 return FALSE0;
1465 }
1466
1467 fill_and_terminate(algo.alg_name, name, sizeof(algo.alg_name)){ strncpy((algo.alg_name), (name), (sizeof(algo.alg_name))-1)
; (algo.alg_name)[(sizeof(algo.alg_name))-1] = '\0'; }
;
1468 algo.alg_key_len = 0;
1469
1470 attr->rta_type = XFRMA_ALG_COMP;
1471 attr->rta_len = RTA_LENGTH(sizeof(algo))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(algo)))
;
1472
1473 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &algo, sizeof(algo));
1474
1475 req.n.nlmsg_len += attr->rta_len;
1476 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1477 } else if (sa->esatype == ET_ESP) {
1478 const char *name = sa->encrypt->encrypt_netlink_xfrm_name;
1479
1480 if (name == NULL((void*)0)) {
1481 loglog(RC_LOG_SERIOUS,
1482 "unknown encryption algorithm: %s",
1483 sa->encrypt->common.fqn);
1484 return FALSE0;
1485 }
1486
1487 if (encrypt_desc_is_aead(sa->encrypt)) {
1488 struct xfrm_algo_aead algo;
1489
1490 fill_and_terminate(algo.alg_name, name,{ strncpy((algo.alg_name), (name), (sizeof(algo.alg_name))-1)
; (algo.alg_name)[(sizeof(algo.alg_name))-1] = '\0'; }
1491 sizeof(algo.alg_name)){ strncpy((algo.alg_name), (name), (sizeof(algo.alg_name))-1)
; (algo.alg_name)[(sizeof(algo.alg_name))-1] = '\0'; }
;
1492 algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE8;
1493 algo.alg_icv_len = sa->encrypt->aead_tag_size * BITS_PER_BYTE8;
1494
1495 attr->rta_type = XFRMA_ALG_AEAD;
1496 attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(algo) + sa->enckeylen))
;
1497
1498 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &algo, sizeof(algo));
1499 memcpy((char *)RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
+ sizeof(algo),
1500 sa->enckey, sa->enckeylen);
1501
1502 req.n.nlmsg_len += attr->rta_len;
1503 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1504
1505 } else {
1506 struct xfrm_algo algo;
1507
1508 fill_and_terminate(algo.alg_name, name,{ strncpy((algo.alg_name), (name), (sizeof(algo.alg_name))-1)
; (algo.alg_name)[(sizeof(algo.alg_name))-1] = '\0'; }
1509 sizeof(algo.alg_name)){ strncpy((algo.alg_name), (name), (sizeof(algo.alg_name))-1)
; (algo.alg_name)[(sizeof(algo.alg_name))-1] = '\0'; }
;
1510 algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE8;
1511
1512 attr->rta_type = XFRMA_ALG_CRYPT;
1513 attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(algo) + sa->enckeylen))
;
1514
1515 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &algo, sizeof(algo));
1516 memcpy((char *)RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
+ sizeof(algo),
1517 sa->enckey,
1518 sa->enckeylen);
1519
1520 req.n.nlmsg_len += attr->rta_len;
1521 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1522
1523 /* Traffic Flow Confidentiality is only for ESP tunnel mode */
1524 if (sa->tfcpad != 0 &&
1525 sa->mode == ENCAPSULATION_MODE_TUNNEL1) {
1526 dbg("netlink: setting TFC to %" PRIu32 " (up to PMTU)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: setting TFC to %" "u" " (up to PMTU)"
, sa->tfcpad); } }
1527 sa->tfcpad){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: setting TFC to %" "u" " (up to PMTU)"
, sa->tfcpad); } }
;
1528
1529 attr->rta_type = XFRMA_TFCPAD;
1530 attr->rta_len = RTA_LENGTH(sizeof(sa->tfcpad))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(sa->tfcpad)))
;
1531 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &sa->tfcpad, sizeof(sa->tfcpad));
1532 req.n.nlmsg_len += attr->rta_len;
1533 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1534
1535 }
1536 }
1537 }
1538
1539 if (sa->encap_type != NULL((void*)0)) {
1540 dbg("adding xfrm-encap-tmpl when adding sa encap_type="PRI_IP_ENCAP" sport=%d dport=%d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding xfrm-encap-tmpl when adding sa encap_type="
"%u(%s)"" sport=%d dport=%d", (sa->encap_type) == ((void*)
0) ? 0 : (sa->encap_type)->encap_type, (sa->encap_type
) == ((void*)0) ? "none" : (sa->encap_type)->name, sa->
src.encap_port, sa->dst.encap_port); } }
1541 pri_ip_encap(sa->encap_type),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding xfrm-encap-tmpl when adding sa encap_type="
"%u(%s)"" sport=%d dport=%d", (sa->encap_type) == ((void*)
0) ? 0 : (sa->encap_type)->encap_type, (sa->encap_type
) == ((void*)0) ? "none" : (sa->encap_type)->name, sa->
src.encap_port, sa->dst.encap_port); } }
1542 sa->src.encap_port, sa->dst.encap_port){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("adding xfrm-encap-tmpl when adding sa encap_type="
"%u(%s)"" sport=%d dport=%d", (sa->encap_type) == ((void*)
0) ? 0 : (sa->encap_type)->encap_type, (sa->encap_type
) == ((void*)0) ? "none" : (sa->encap_type)->name, sa->
src.encap_port, sa->dst.encap_port); } }
;
1543 struct xfrm_encap_tmpl natt;
1544
1545 natt.encap_type = sa->encap_type->encap_type;
1546 natt.encap_sport = ntohs(sa->src.encap_port);
1547 natt.encap_dport = ntohs(sa->dst.encap_port);
1548 zero(&natt.encap_oa)memset((&natt.encap_oa), '\0', sizeof(*(&natt.encap_oa
)))
;
1549
1550 attr->rta_type = XFRMA_ENCAP;
1551 attr->rta_len = RTA_LENGTH(sizeof(natt))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(natt)))
;
1552
1553 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &natt, sizeof(natt));
1554
1555 req.n.nlmsg_len += attr->rta_len;
1556 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1557 }
1558
1559 if (sa->xfrm_if_id > 0) {
1560#ifdef USE_XFRM_INTERFACE1
1561 dbg("%s netlink: XFRMA_IF_ID %" PRIu32 " req.n.nlmsg_type=%" PRIu32,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s netlink: XFRMA_IF_ID %" "u" " req.n.nlmsg_type=%"
"u", __func__, sa->xfrm_if_id, req.n.nlmsg_type); } }
1562 __func__, sa->xfrm_if_id, req.n.nlmsg_type){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s netlink: XFRMA_IF_ID %" "u" " req.n.nlmsg_type=%"
"u", __func__, sa->xfrm_if_id, req.n.nlmsg_type); } }
;
1563 attr->rta_type = XFRMA_IF_ID;
1564 attr->rta_len = RTA_LENGTH(sizeof(uint32_t))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(uint32_t)))
;
1565 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &sa->xfrm_if_id, sizeof(uint32_t));
1566 req.n.nlmsg_len += attr->rta_len;
1567 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1568
1569 /* XFRMA_SET_MARK = XFRMA_IF_ID/0xffffffff */
1570 attr->rta_type = XFRMA_SET_MARK;
1571 attr->rta_len = RTA_LENGTH(sizeof(uint32_t))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(uint32_t)))
;
1572 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &sa->xfrm_if_id, sizeof(uint32_t));
1573 req.n.nlmsg_len += attr->rta_len;
1574 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1575#endif
1576 }
1577
1578 if (sa->nic_offload_dev) {
1579 struct xfrm_user_offload xuo = {
1580 .flags = (sa->inbound ? XFRM_OFFLOAD_INBOUND2 : 0) |
1581 (addrtypeof(sa->src.address) == AF_INET610 ? XFRM_OFFLOAD_IPV61 : 0),
1582 .ifindex = if_nametoindex(sa->nic_offload_dev),
1583 };
1584
1585 attr->rta_type = XFRMA_OFFLOAD_DEV;
1586 attr->rta_len = RTA_LENGTH(sizeof(xuo))(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (sizeof
(xuo)))
;
1587
1588 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &xuo, sizeof(xuo));
1589
1590 req.n.nlmsg_len += attr->rta_len;
1591 attr = (struct rtattr *)((char *)attr + attr->rta_len);
1592 dbg("netlink: esp-hw-offload set via interface %s for IPsec SA", sa->nic_offload_dev){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: esp-hw-offload set via interface %s for IPsec SA"
, sa->nic_offload_dev); } }
;
1593 } else {
1594 dbg("netlink: esp-hw-offload not set for IPsec SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink: esp-hw-offload not set for IPsec SA"
); } }
;
1595 }
1596
1597 if (sa->sec_ctx != NULL((void*)0)) {
1598 size_t len = sa->sec_ctx->ctx.ctx_len;
1599 struct xfrm_user_sec_ctx xuctx;
1600
1601 xuctx.len = sizeof(struct xfrm_user_sec_ctx) + len;
1602 xuctx.exttype = XFRMA_SEC_CTX;
1603 xuctx.ctx_alg = 1; /* ??? sa->sec_ctx.ctx_alg? */
1604 xuctx.ctx_doi = 1; /* ??? sa->sec_ctx.ctx_doi? */
1605 xuctx.ctx_len = len;
1606
1607 attr->rta_type = XFRMA_SEC_CTX;
1608 attr->rta_len = RTA_LENGTH(xuctx.len)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (xuctx.
len))
;
1609
1610 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &xuctx, sizeof(xuctx));
1611 memcpy((char *)RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
+ sizeof(xuctx),
1612 sa->sec_ctx->sec_ctx_value, len);
1613
1614 req.n.nlmsg_len += attr->rta_len;
1615
1616 /* attr not subsequently used */
1617 attr = (struct rtattr *)((char *)attr + attr->rta_len);
Value stored to 'attr' is never read
1618 }
1619
1620 ret = send_netlink_msg(&req.n, NLMSG_NOOP0x1, NULL((void*)0), "Add SA", sa->text_said);
1621 if (!ret && netlink_errno == ESRCH3 &&
1622 req.n.nlmsg_type == XFRM_MSG_UPDSAXFRM_MSG_UPDSA) {
1623 loglog(RC_LOG_SERIOUS,
1624 "Warning: kernel expired our reserved IPsec SA SPI - negotiation took too long? Try increasing /proc/sys/net/core/xfrm_acq_expires");
1625 }
1626 return ret;
1627}
1628
1629/*
1630 * netlink_del_sa - Delete an SA from the Kernel
1631 *
1632 * @param sa Kernel SA to be deleted
1633 * @return bool True if successful
1634 */
1635static bool_Bool netlink_del_sa(const struct kernel_sa *sa)
1636{
1637 struct {
1638 struct nlmsghdr n;
1639 struct xfrm_usersa_id id;
1640 char data[MAX_NETLINK_DATA_SIZE8192];
1641 } req;
1642
1643 zero(&req)memset((&req), '\0', sizeof(*(&req)));
1644 req.n.nlmsg_flags = NLM_F_REQUEST0x01 | NLM_F_ACK0x04;
1645 req.n.nlmsg_type = XFRM_MSG_DELSAXFRM_MSG_DELSA;
1646
1647 req.id.daddr = xfrm_from_address(sa->dst.address);
1648
1649 req.id.spi = sa->spi;
1650 req.id.family = addrtypeof(sa->src.address);
1651 req.id.proto = sa->proto->ipproto;
1652
1653 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)))( ((((sizeof(req.id)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
1654
1655 dbg("XFRM: deleting IPsec SA with reqid %d", sa->reqid){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("XFRM: deleting IPsec SA with reqid %d", sa->
reqid); } }
;
1656
1657 return send_netlink_msg(&req.n, NLMSG_NOOP0x1, NULL((void*)0), "Del SA", sa->text_said);
1658}
1659
1660/*
1661 * Create ip_address out of xfrm_address_t.
1662 *
1663 * @param family
1664 * @param src xfrm formatted IP address
1665 * @param dst ip_address formatted destination
1666 * @return err_t NULL if okay, otherwise an error
1667 */
1668static ip_address address_from_xfrm(const struct ip_info *afi,
1669 const xfrm_address_t *xaddr)
1670{
1671 /* .len == ipv6 size */
1672 shunk_t x = THING_AS_SHUNK(*xaddr)shunk2(&(*xaddr), sizeof(*xaddr));
1673
1674 ip_address addr = afi->any_address; /* "zero" it & set type */
1675 chunk_t a = address_as_chunk(&addr);
1676
1677 /* a = x */
1678 passert(a.len <= x.len){ _Bool assertion__ = a.len <= x.len; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 1678}, "%s", "a.len <= x.len"); } }
;
1679 memcpy(a.ptr, x.ptr, a.len);
1680
1681 return addr;
1682}
1683
1684/*
1685 * Create ip_selector / ip_client out of xfrm_address_t:NPORT.
1686 */
1687
1688static ip_selector selector_from_xfrm(const struct ip_info *afi, unsigned ipproto,
1689 const xfrm_address_t *src, uint16_t nport)
1690{
1691 ip_address address = address_from_xfrm(afi, src);
1692 ip_protoport protoport = protoport2(ipproto, ip_nport(nport));
1693 return selector_from_address(&address, &protoport);
1694}
1695
1696static void netlink_acquire(struct nlmsghdr *n)
1697{
1698 struct xfrm_user_acquire *acquire;
1699 struct xfrm_user_sec_ctx_ike *uctx = NULL((void*)0);
1700 struct xfrm_user_sec_ctx_ike uctx_space;
1701
1702 dbg("xfrm netlink msg len %zu", (size_t) n->nlmsg_len){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm netlink msg len %zu", (size_t) n->nlmsg_len
); } }
;
1703
1704 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire))((sizeof(*acquire)) + ((int) ( ((sizeof(struct nlmsghdr))+4U -
1) & ~(4U -1) )))
) {
1705 libreswan_log(loglog(RC_LOG, "netlink_acquire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*acquire))
1706 "netlink_acquire got message with length %zu < %zu bytes; ignore message",loglog(RC_LOG, "netlink_acquire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*acquire))
1707 (size_t) n->nlmsg_len,loglog(RC_LOG, "netlink_acquire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*acquire))
1708 sizeof(*acquire))loglog(RC_LOG, "netlink_acquire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*acquire))
;
1709 return;
1710 }
1711
1712 /*
1713 * WARNING: netlink only guarantees 32-bit alignment.
1714 * See NLMSG_ALIGNTO in the kernel's include/uapi/linux/netlink.h.
1715 * BUT some fields in struct xfrm_user_acquire are 64-bit and so access
1716 * may be improperly aligned. This will fail on a few strict
1717 * architectures (it does break C rules).
1718 *
1719 * WARNING: this code's understanding to the XFRM netlink
1720 * messages is from programs/pluto/linux26/xfrm.h.
1721 * There is no guarantee that this matches the kernel's
1722 * understanding.
1723 *
1724 * Many things are defined to be int or unsigned int.
1725 * This isn't safe when the kernel and userland may
1726 * be compiled with different models.
1727 */
1728 acquire = NLMSG_DATA(n)((void*)(((char*)n) + ((0) + ((int) ( ((sizeof(struct nlmsghdr
))+4U -1) & ~(4U -1) )))))
; /* insufficiently aligned */
1729
1730 const struct ip_info *afi = aftoinfo(acquire->policy.sel.family);
1731 if (afi == NULL((void*)0)) {
1732 libreswan_log("XFRM_MSG_ACQUIRE message from kernel malformed: family %u unknown",loglog(RC_LOG, "XFRM_MSG_ACQUIRE message from kernel malformed: family %u unknown"
, acquire->policy.sel.family)
1733 acquire->policy.sel.family)loglog(RC_LOG, "XFRM_MSG_ACQUIRE message from kernel malformed: family %u unknown"
, acquire->policy.sel.family)
;
1734 return;
1735 }
1736 ip_selector ours = selector_from_xfrm(afi, acquire->sel.proto,
1737 &acquire->sel.saddr,
1738 acquire->sel.sport);
1739 ip_selector theirs = selector_from_xfrm(afi, acquire->sel.proto,
1740 &acquire->sel.daddr,
1741 acquire->sel.dport);
1742
1743 /*
1744 * Run through rtattributes looking for XFRMA_SEC_CTX
1745 * Instead, it should loop through all (known rtattributes
1746 * and use/log them.
1747 */
1748 struct rtattr *attr = (struct rtattr *)
1749 ((char*) NLMSG_DATA(n)((void*)(((char*)n) + ((0) + ((int) ( ((sizeof(struct nlmsghdr
))+4U -1) & ~(4U -1) )))))
+
1750 NLMSG_ALIGN(sizeof(struct xfrm_user_acquire))( ((sizeof(struct xfrm_user_acquire))+4U -1) & ~(4U -1) ));
1751 size_t remaining = n->nlmsg_len -
1752 NLMSG_SPACE(sizeof(struct xfrm_user_acquire))( ((((sizeof(struct xfrm_user_acquire)) + ((int) ( ((sizeof(struct
nlmsghdr))+4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
1753
1754 while (remaining > 0) {
1755 dbg("xfrm acquire rtattribute type %u ...", attr->rta_type){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm acquire rtattribute type %u ...", attr->
rta_type); } }
;
1756 switch (attr->rta_type) {
1757 case XFRMA_TMPL:
1758 {
1759 struct xfrm_user_tmpl* tmpl = (struct xfrm_user_tmpl *) RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
;
1760 dbg("... xfrm template attribute with reqid:%d, spi:%d, proto:%d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... xfrm template attribute with reqid:%d, spi:%d, proto:%d"
, tmpl->reqid, tmpl->id.spi, tmpl->id.proto); } }
1761 tmpl->reqid, tmpl->id.spi, tmpl->id.proto){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... xfrm template attribute with reqid:%d, spi:%d, proto:%d"
, tmpl->reqid, tmpl->id.spi, tmpl->id.proto); } }
;
1762 break;
1763 }
1764 case XFRMA_POLICY_TYPE:
1765 /* discard */
1766 dbg("... xfrm policy type ignored"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... xfrm policy type ignored"); } }
;
1767 break;
1768 case XFRMA_SEC_CTX:
1769 {
1770 struct xfrm_user_sec_ctx *xuctx = (struct xfrm_user_sec_ctx *) RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
;
1771 /* length of text of label */
1772 size_t len = xuctx->ctx_len;
1773
1774 dbg("... xfrm xuctx: exttype=%d, len=%d, ctx_doi=%d, ctx_alg=%d, ctx_len=%zu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... xfrm xuctx: exttype=%d, len=%d, ctx_doi=%d, ctx_alg=%d, ctx_len=%zu"
, xuctx->exttype, xuctx->len, xuctx->ctx_doi, xuctx->
ctx_alg, len); } }
1775 xuctx->exttype, xuctx->len,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... xfrm xuctx: exttype=%d, len=%d, ctx_doi=%d, ctx_alg=%d, ctx_len=%zu"
, xuctx->exttype, xuctx->len, xuctx->ctx_doi, xuctx->
ctx_alg, len); } }
1776 xuctx->ctx_doi, xuctx->ctx_alg,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... xfrm xuctx: exttype=%d, len=%d, ctx_doi=%d, ctx_alg=%d, ctx_len=%zu"
, xuctx->exttype, xuctx->len, xuctx->ctx_doi, xuctx->
ctx_alg, len); } }
1777 len){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... xfrm xuctx: exttype=%d, len=%d, ctx_doi=%d, ctx_alg=%d, ctx_len=%zu"
, xuctx->exttype, xuctx->len, xuctx->ctx_doi, xuctx->
ctx_alg, len); } }
;
1778
1779 if (uctx != NULL((void*)0)) {
1780 libreswan_log("Second Sec Ctx label in a single Acquire message; ignoring Acquire message")loglog(RC_LOG, "Second Sec Ctx label in a single Acquire message; ignoring Acquire message"
)
;
1781 return;
1782 }
1783
1784 if (len > MAX_SECCTX_LEN4096) {
1785 libreswan_log("Sec Ctx label of length %zu, longer than MAX_SECCTX_LEN; ignoring Acquire message",loglog(RC_LOG, "Sec Ctx label of length %zu, longer than MAX_SECCTX_LEN; ignoring Acquire message"
, len)
1786 len)loglog(RC_LOG, "Sec Ctx label of length %zu, longer than MAX_SECCTX_LEN; ignoring Acquire message"
, len)
;
1787 return;
1788 }
1789
1790 /*
1791 * note: xuctx + 1 is tricky:
1792 * first byte after header
1793 */
1794 dbg("xfrm: xuctx security context value: %.*s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm: xuctx security context value: %.*s", xuctx
->ctx_len, (const char *) (xuctx + 1)); } }
1795 xuctx->ctx_len,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm: xuctx security context value: %.*s", xuctx
->ctx_len, (const char *) (xuctx + 1)); } }
1796 (const char *) (xuctx + 1)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm: xuctx security context value: %.*s", xuctx
->ctx_len, (const char *) (xuctx + 1)); } }
;
1797
1798 zero(&uctx_space)memset((&uctx_space), '\0', sizeof(*(&uctx_space)));
1799 uctx = &uctx_space;
1800
1801 memcpy(uctx->sec_ctx_value, (xuctx + 1),
1802 xuctx->ctx_len);
1803
1804 if (len == 0 || uctx->sec_ctx_value[len-1] != '\0') {
1805 if (len == MAX_SECCTX_LEN4096) {
1806 libreswan_log("Sec Ctx label missing final NUL and too long to add; ignoring Acquire message")loglog(RC_LOG, "Sec Ctx label missing final NUL and too long to add; ignoring Acquire message"
)
;
1807 return;
1808 }
1809 libreswan_log("Sec Ctx label missing final NUL; we're adding it")loglog(RC_LOG, "Sec Ctx label missing final NUL; we're adding it"
)
;
1810 uctx->sec_ctx_value[len] = '\0';
1811 len++;
1812 }
1813
1814 if (strlen(uctx->sec_ctx_value) + 1 != len) {
1815 libreswan_log("Sec Ctx label contains embedded NUL; ignoring Acquire message")loglog(RC_LOG, "Sec Ctx label contains embedded NUL; ignoring Acquire message"
)
;
1816 return;
1817 }
1818
1819 uctx->ctx.ctx_alg = xuctx->ctx_alg;
1820 uctx->ctx.ctx_doi = xuctx->ctx_doi;
1821 /* Length includes '\0'*/
1822 uctx->ctx.ctx_len = len;
1823
1824 break;
1825 }
1826 default:
1827 dbg("... ignoring unknown xfrm acquire payload type %u",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... ignoring unknown xfrm acquire payload type %u"
, attr->rta_type); } }
1828 attr->rta_type){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("... ignoring unknown xfrm acquire payload type %u"
, attr->rta_type); } }
;
1829 break;
1830 }
1831 /* updates remaining too */
1832 attr = RTA_NEXT(attr, remaining)((remaining) -= ( (((attr)->rta_len)+4U -1) & ~(4U -1)
), (struct rtattr*)(((char*)(attr)) + ( (((attr)->rta_len
)+4U -1) & ~(4U -1) )))
;
1833 }
1834
1835 /*
1836 * XXX also the type of src/dst should be checked to make sure
1837 * that they aren't v4 to v6 or something goofy
1838 */
1839 record_and_initiate_opportunistic(&ours, &theirs,
1840 acquire->sel.proto, uctx,
1841 "%acquire-netlink");
1842}
1843
1844static void netlink_shunt_expire(struct xfrm_userpolicy_info *pol)
1845{
1846 const xfrm_address_t *srcx = &pol->sel.saddr;
1847 const xfrm_address_t *dstx = &pol->sel.daddr;
1848 unsigned transport_proto = pol->sel.proto;
1849
1850 const struct ip_info *afi = aftoinfo(pol->sel.family);
1851 if (afi == NULL((void*)0)) {
1852 libreswan_log("XFRM_MSG_POLEXPIRE message from kernel malformed: address family %u unknown",loglog(RC_LOG, "XFRM_MSG_POLEXPIRE message from kernel malformed: address family %u unknown"
, pol->sel.family)
1853 pol->sel.family)loglog(RC_LOG, "XFRM_MSG_POLEXPIRE message from kernel malformed: address family %u unknown"
, pol->sel.family)
;
1854 return;
1855 }
1856
1857 ip_address src = address_from_xfrm(afi, srcx);
1858 ip_address dst = address_from_xfrm(afi, dstx);
1859
1860 if (delete_bare_shunt(&src, &dst,
1861 transport_proto, SPI_HOLD259 /* why spi to use? */,
1862 "delete expired bare shunt")) {
1863 dbg("netlink_shunt_expire() called delete_bare_shunt() with success"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_shunt_expire() called delete_bare_shunt() with success"
); } }
;
1864 } else {
1865 libreswan_log("netlink_shunt_expire() called delete_bare_shunt() which failed!")loglog(RC_LOG, "netlink_shunt_expire() called delete_bare_shunt() which failed!"
)
;
1866 }
1867}
1868
1869static void process_addr_chage(struct nlmsghdr *n)
1870{
1871 struct ifaddrmsg *nl_msg = NLMSG_DATA(n)((void*)(((char*)n) + ((0) + ((int) ( ((sizeof(struct nlmsghdr
))+4U -1) & ~(4U -1) )))))
;
1872 struct rtattr *rta = IFLA_RTA(nl_msg)((struct rtattr*)(((char*)(nl_msg)) + ( ((sizeof(struct ifinfomsg
))+4U -1) & ~(4U -1) )))
;
1873 size_t msg_size = IFA_PAYLOAD (n)((n)->nlmsg_len - ( (((((sizeof(struct ifaddrmsg))) + ((int
) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) ))))+4U -
1) & ~(4U -1) ))
;
1874 ip_address ip;
1875
1876 dbg("xfrm netlink address change %s msg len %zu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm netlink address change %s msg len %zu", sparse_val_show
(rtm_type_names, n->nlmsg_type), (size_t) n->nlmsg_len)
; } }
1877 sparse_val_show(rtm_type_names, n->nlmsg_type),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm netlink address change %s msg len %zu", sparse_val_show
(rtm_type_names, n->nlmsg_type), (size_t) n->nlmsg_len)
; } }
1878 (size_t) n->nlmsg_len){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("xfrm netlink address change %s msg len %zu", sparse_val_show
(rtm_type_names, n->nlmsg_type), (size_t) n->nlmsg_len)
; } }
;
1879
1880 while (RTA_OK(rta, msg_size)((msg_size) >= (int)sizeof(struct rtattr) && (rta)
->rta_len >= sizeof(struct rtattr) && (rta)->
rta_len <= (msg_size))
) {
1881 err_t ugh;
1882
1883 switch (rta->rta_type) {
1884 case IFA_LOCAL:
1885 ugh = data_to_address(RTA_DATA(rta)((void*)(((char*)(rta)) + (( ((sizeof(struct rtattr))+4U -1) &
~(4U -1) ) + (0))))
, RTA_PAYLOAD(rta)((int)((rta)->rta_len) - (( ((sizeof(struct rtattr))+4U -1
) & ~(4U -1) ) + (0)))
/*size*/,
1886 aftoinfo(nl_msg->ifa_family), &ip);
1887 if (ugh != NULL((void*)0)) {
1888 libreswan_log("ERROR IFA_LOCAL invalid %s", ugh)loglog(RC_LOG, "ERROR IFA_LOCAL invalid %s", ugh);
1889 } else {
1890 if (n->nlmsg_type == RTM_DELADDRRTM_DELADDR)
1891 record_deladdr(&ip, "IFA_LOCAL");
1892 else if (n->nlmsg_type == RTM_NEWADDRRTM_NEWADDR)
1893 record_newaddr(&ip, "IFA_LOCAL");
1894 }
1895 break;
1896
1897 case IFA_ADDRESS:
1898 ugh = data_to_address(RTA_DATA(rta)((void*)(((char*)(rta)) + (( ((sizeof(struct rtattr))+4U -1) &
~(4U -1) ) + (0))))
, RTA_PAYLOAD(rta)((int)((rta)->rta_len) - (( ((sizeof(struct rtattr))+4U -1
) & ~(4U -1) ) + (0)))
/*size*/,
1899 aftoinfo(nl_msg->ifa_family), &ip);
1900 if (ugh != NULL((void*)0)) {
1901 libreswan_log("ERROR IFA_ADDRESS invalid %s", ugh)loglog(RC_LOG, "ERROR IFA_ADDRESS invalid %s", ugh);
1902 } else {
1903 address_buf ip_str;
1904 dbg("XFRM IFA_ADDRESS %s IFA_ADDRESS is this PPP?",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("XFRM IFA_ADDRESS %s IFA_ADDRESS is this PPP?"
, str_address(&ip, &ip_str)); } }
1905 str_address(&ip, &ip_str)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("XFRM IFA_ADDRESS %s IFA_ADDRESS is this PPP?"
, str_address(&ip, &ip_str)); } }
;
1906 }
1907 break;
1908
1909 default:
1910 dbg("IKEv2 received address %s type %u",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("IKEv2 received address %s type %u", sparse_val_show
(rtm_type_names, n->nlmsg_type), rta->rta_type); } }
1911 sparse_val_show(rtm_type_names, n->nlmsg_type),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("IKEv2 received address %s type %u", sparse_val_show
(rtm_type_names, n->nlmsg_type), rta->rta_type); } }
1912 rta->rta_type){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("IKEv2 received address %s type %u", sparse_val_show
(rtm_type_names, n->nlmsg_type), rta->rta_type); } }
;
1913 break;
1914 }
1915
1916 rta = RTA_NEXT(rta, msg_size)((msg_size) -= ( (((rta)->rta_len)+4U -1) & ~(4U -1) )
, (struct rtattr*)(((char*)(rta)) + ( (((rta)->rta_len)+4U
-1) & ~(4U -1) )))
;
1917 }
1918}
1919
1920static void netlink_policy_expire(struct nlmsghdr *n)
1921{
1922 struct xfrm_user_polexpire *upe;
1923 ip_address src, dst;
1924
1925 struct {
1926 struct nlmsghdr n;
1927 struct xfrm_userpolicy_id id;
1928 } req;
1929 struct nlm_resp rsp;
1930
1931 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*upe))((sizeof(*upe)) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) &
~(4U -1) )))
) {
1932 libreswan_log(loglog(RC_LOG, "netlink_policy_expire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*upe))
1933 "netlink_policy_expire got message with length %zu < %zu bytes; ignore message",loglog(RC_LOG, "netlink_policy_expire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*upe))
1934 (size_t) n->nlmsg_len,loglog(RC_LOG, "netlink_policy_expire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*upe))
1935 sizeof(*upe))loglog(RC_LOG, "netlink_policy_expire got message with length %zu < %zu bytes; ignore message"
, (size_t) n->nlmsg_len, sizeof(*upe))
;
1936 return;
1937 }
1938
1939 upe = NLMSG_DATA(n)((void*)(((char*)n) + ((0) + ((int) ( ((sizeof(struct nlmsghdr
))+4U -1) & ~(4U -1) )))))
;
1940 xfrm2ip(&upe->pol.sel.saddr, &src, upe->pol.sel.family);
1941 xfrm2ip(&upe->pol.sel.daddr, &dst, upe->pol.sel.family);
1942 address_buf a;
1943 address_buf b;
1944 dbg("%s src %s/%u dst %s/%u dir %d index %d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s src %s/%u dst %s/%u dir %d index %d", __func__
, str_address(&src, &a), upe->pol.sel.prefixlen_s,
str_address(&dst, &b), upe->pol.sel.prefixlen_d, upe
->pol.dir, upe->pol.index); } }
1945 __func__,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s src %s/%u dst %s/%u dir %d index %d", __func__
, str_address(&src, &a), upe->pol.sel.prefixlen_s,
str_address(&dst, &b), upe->pol.sel.prefixlen_d, upe
->pol.dir, upe->pol.index); } }
1946 str_address(&src, &a), upe->pol.sel.prefixlen_s,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s src %s/%u dst %s/%u dir %d index %d", __func__
, str_address(&src, &a), upe->pol.sel.prefixlen_s,
str_address(&dst, &b), upe->pol.sel.prefixlen_d, upe
->pol.dir, upe->pol.index); } }
1947 str_address(&dst, &b), upe->pol.sel.prefixlen_d,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s src %s/%u dst %s/%u dir %d index %d", __func__
, str_address(&src, &a), upe->pol.sel.prefixlen_s,
str_address(&dst, &b), upe->pol.sel.prefixlen_d, upe
->pol.dir, upe->pol.index); } }
1948 upe->pol.dir, upe->pol.index){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s src %s/%u dst %s/%u dir %d index %d", __func__
, str_address(&src, &a), upe->pol.sel.prefixlen_s,
str_address(&dst, &b), upe->pol.sel.prefixlen_d, upe
->pol.dir, upe->pol.index); } }
;
1949
1950 req.id.dir = upe->pol.dir;
1951 req.id.index = upe->pol.index;
1952 req.n.nlmsg_flags = NLM_F_REQUEST0x01;
1953 req.n.nlmsg_type = XFRM_MSG_GETPOLICYXFRM_MSG_GETPOLICY;
1954 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)))( ((((sizeof(req.id)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
1955
1956 if (!send_netlink_msg(&req.n, XFRM_MSG_NEWPOLICYXFRM_MSG_NEWPOLICY, &rsp, "Get policy", "?")) {
1957 dbg("netlink_policy_expire: policy died on us: dir=%d, index=%d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_policy_expire: policy died on us: dir=%d, index=%d"
, req.id.dir, req.id.index); } }
1958 req.id.dir, req.id.index){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_policy_expire: policy died on us: dir=%d, index=%d"
, req.id.dir, req.id.index); } }
;
1959 } else if (rsp.n.nlmsg_len < NLMSG_LENGTH(sizeof(rsp.u.pol))((sizeof(rsp.u.pol)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) )))
) {
1960 libreswan_log(loglog(RC_LOG, "netlink_policy_expire: XFRM_MSG_GETPOLICY returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.pol))
1961 "netlink_policy_expire: XFRM_MSG_GETPOLICY returned message with length %zu < %zu bytes; ignore message",loglog(RC_LOG, "netlink_policy_expire: XFRM_MSG_GETPOLICY returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.pol))
1962 (size_t) rsp.n.nlmsg_len,loglog(RC_LOG, "netlink_policy_expire: XFRM_MSG_GETPOLICY returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.pol))
1963 sizeof(rsp.u.pol))loglog(RC_LOG, "netlink_policy_expire: XFRM_MSG_GETPOLICY returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.pol))
;
1964 } else if (req.id.index != rsp.u.pol.index) {
1965 dbg("netlink_policy_expire: policy was replaced: dir=%d, oldindex=%d, newindex=%d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_policy_expire: policy was replaced: dir=%d, oldindex=%d, newindex=%d"
, req.id.dir, req.id.index, rsp.u.pol.index); } }
1966 req.id.dir, req.id.index, rsp.u.pol.index){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_policy_expire: policy was replaced: dir=%d, oldindex=%d, newindex=%d"
, req.id.dir, req.id.index, rsp.u.pol.index); } }
;
1967 } else if (upe->pol.curlft.add_time != rsp.u.pol.curlft.add_time) {
1968 dbg("netlink_policy_expire: policy was replaced and you have won the lottery: dir=%d, index=%d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_policy_expire: policy was replaced and you have won the lottery: dir=%d, index=%d"
, req.id.dir, req.id.index); } }
1969 req.id.dir, req.id.index){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_policy_expire: policy was replaced and you have won the lottery: dir=%d, index=%d"
, req.id.dir, req.id.index); } }
;
1970 } else {
1971 switch (upe->pol.dir) {
1972 case XFRM_POLICY_OUT:
1973 netlink_shunt_expire(&rsp.u.pol);
1974 break;
1975 }
1976 }
1977}
1978
1979/* returns FALSE iff EAGAIN */
1980static bool_Bool netlink_get(int fd)
1981{
1982 struct nlm_resp rsp;
1983 struct sockaddr_nl addr;
1984 socklen_t alen = sizeof(addr);
1985 ssize_t r = recvfrom(fd, &rsp, sizeof(rsp), 0,
1986 (struct sockaddr *)&addr, &alen);
1987
1988 if (r < 0) {
1989 if (errno(*__errno_location ()) == EAGAIN11)
1990 return FALSE0;
1991
1992 if (errno(*__errno_location ()) != EINTR4) {
1993 LOG_ERRNO(errno, "recvfrom() failed in netlink_get: errno(%d): %s",{ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "recvfrom() failed in netlink_get: errno(%d): %s", (*__errno_location
()), strerror((*__errno_location ()))); jam_string(buf, ".")
; jam(buf, " ""Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream
(buf); } }
1994 errno, strerror(errno)){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "recvfrom() failed in netlink_get: errno(%d): %s", (*__errno_location
()), strerror((*__errno_location ()))); jam_string(buf, ".")
; jam(buf, " ""Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream
(buf); } }
;
1995 }
1996 return TRUE1;
1997 } else if ((size_t)r < sizeof(rsp.n)) {
1998 libreswan_log(loglog(RC_LOG, "netlink_get read truncated message: %zd bytes; ignore message"
, r)
1999 "netlink_get read truncated message: %zd bytes; ignore message",loglog(RC_LOG, "netlink_get read truncated message: %zd bytes; ignore message"
, r)
2000 r)loglog(RC_LOG, "netlink_get read truncated message: %zd bytes; ignore message"
, r)
;
2001 return TRUE1;
2002 } else if (addr.nl_pid != 0) {
2003 /* not for us: ignore */
2004 dbg("netlink_get: ignoring %s message from process %u",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_get: ignoring %s message from process %u"
, sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type), addr.nl_pid
); } }
2005 sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_get: ignoring %s message from process %u"
, sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type), addr.nl_pid
); } }
2006 addr.nl_pid){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_get: ignoring %s message from process %u"
, sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type), addr.nl_pid
); } }
;
2007 return TRUE1;
2008 } else if ((size_t)r != rsp.n.nlmsg_len) {
2009 libreswan_log(loglog(RC_LOG, "netlink_get read message with length %zd that doesn't equal nlmsg_len %zu bytes; ignore message"
, r, (size_t) rsp.n.nlmsg_len)
2010 "netlink_get read message with length %zd that doesn't equal nlmsg_len %zu bytes; ignore message",loglog(RC_LOG, "netlink_get read message with length %zd that doesn't equal nlmsg_len %zu bytes; ignore message"
, r, (size_t) rsp.n.nlmsg_len)
2011 r, (size_t) rsp.n.nlmsg_len)loglog(RC_LOG, "netlink_get read message with length %zd that doesn't equal nlmsg_len %zu bytes; ignore message"
, r, (size_t) rsp.n.nlmsg_len)
;
2012 return TRUE1;
2013 }
2014
2015 dbg("netlink_get: %s message",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_get: %s message", sparse_val_show(xfrm_type_names
, rsp.n.nlmsg_type)); } }
2016 sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_get: %s message", sparse_val_show(xfrm_type_names
, rsp.n.nlmsg_type)); } }
;
2017
2018 switch (rsp.n.nlmsg_type) {
2019 case XFRM_MSG_ACQUIREXFRM_MSG_ACQUIRE:
2020 netlink_acquire(&rsp.n);
2021 break;
2022 case XFRM_MSG_POLEXPIREXFRM_MSG_POLEXPIRE:
2023 netlink_policy_expire(&rsp.n);
2024 break;
2025
2026 case RTM_NEWADDRRTM_NEWADDR:
2027 process_addr_chage(&rsp.n);
2028 break;
2029
2030 case RTM_DELADDRRTM_DELADDR:
2031 process_addr_chage(&rsp.n);
2032 break;
2033
2034 default:
2035 /* ignored */
2036 break;
2037 }
2038
2039 return TRUE1;
2040}
2041
2042static void netlink_process_msg(int fd)
2043{
2044 do {} while (netlink_get(fd));
2045}
2046
2047static ipsec_spi_t netlink_get_spi(const ip_address *src,
2048 const ip_address *dst,
2049 const struct ip_protocol *proto,
2050 bool_Bool tunnel_mode,
2051 reqid_t reqid,
2052 ipsec_spi_t min,
2053 ipsec_spi_t max,
2054 const char *text_said)
2055{
2056 struct {
2057 struct nlmsghdr n;
2058 struct xfrm_userspi_info spi;
2059 } req;
2060 struct nlm_resp rsp;
2061
2062 zero(&req)memset((&req), '\0', sizeof(*(&req)));
2063 req.n.nlmsg_flags = NLM_F_REQUEST0x01;
2064 req.n.nlmsg_type = XFRM_MSG_ALLOCSPIXFRM_MSG_ALLOCSPI;
2065
2066 req.spi.info.saddr = xfrm_from_address(src);
2067 req.spi.info.id.daddr = xfrm_from_address(dst);
2068 req.spi.info.mode = tunnel_mode;
2069 req.spi.info.reqid = reqid;
2070 req.spi.info.id.proto = proto->ipproto;
2071 req.spi.info.family = addrtypeof(src);
2072
2073 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.spi)))( ((((sizeof(req.spi)) + ((int) ( ((sizeof(struct nlmsghdr))+
4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
2074
2075 req.spi.min = min;
2076 req.spi.max = max;
2077
2078 if (!send_netlink_msg(&req.n, XFRM_MSG_NEWSAXFRM_MSG_NEWSA, &rsp, "Get SPI",
2079 text_said)) {
2080 return 0;
2081 }
2082
2083 if (rsp.n.nlmsg_len < NLMSG_LENGTH(sizeof(rsp.u.sa))((sizeof(rsp.u.sa)) + ((int) ( ((sizeof(struct nlmsghdr))+4U -
1) & ~(4U -1) )))
) {
2084 libreswan_log(loglog(RC_LOG, "netlink_get_spi: XFRM_MSG_ALLOCSPI returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.sa))
2085 "netlink_get_spi: XFRM_MSG_ALLOCSPI returned message with length %zu < %zu bytes; ignore message",loglog(RC_LOG, "netlink_get_spi: XFRM_MSG_ALLOCSPI returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.sa))
2086 (size_t) rsp.n.nlmsg_len,loglog(RC_LOG, "netlink_get_spi: XFRM_MSG_ALLOCSPI returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.sa))
2087 sizeof(rsp.u.sa))loglog(RC_LOG, "netlink_get_spi: XFRM_MSG_ALLOCSPI returned message with length %zu < %zu bytes; ignore message"
, (size_t) rsp.n.nlmsg_len, sizeof(rsp.u.sa))
;
2088 return 0;
2089 }
2090
2091 dbg("netlink_get_spi: allocated 0x%x for %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_get_spi: allocated 0x%x for %s", ntohl
(rsp.u.sa.id.spi), text_said); } }
2092 ntohl(rsp.u.sa.id.spi), text_said){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("netlink_get_spi: allocated 0x%x for %s", ntohl
(rsp.u.sa.id.spi), text_said); } }
;
2093 return rsp.u.sa.id.spi;
2094}
2095
2096/*
2097 * install or remove eroute for SA Group
2098 *
2099 * (identical to KLIPS version, but refactoring isn't waranteed yet
2100 */
2101static bool_Bool netlink_sag_eroute(const struct state *st, const struct spd_route *sr,
2102 unsigned op, const char *opname)
2103{
2104 struct connection *c = st->st_connection;
2105 enum eroute_type inner_esatype;
2106 ipsec_spi_t inner_spi;
2107 struct pfkey_proto_info proto_info[4];
2108 int i;
2109 bool_Bool tunnel;
2110
2111 /*
2112 * figure out the SPI and protocol (in two forms)
2113 * for the innermost transformation.
2114 */
2115 i = elemsof(proto_info)(sizeof(proto_info) / sizeof(*(proto_info))) - 1;
2116 proto_info[i].proto = 0;
2117 tunnel = FALSE0;
2118
2119 const struct ip_protocol *inner_proto = NULL((void*)0);
2120 inner_esatype = ET_UNSPEC;
2121 inner_spi = 0;
2122
2123 if (st->st_ah.present) {
2124 inner_spi = st->st_ah.attrs.spi;
2125 inner_proto = &ip_protocol_ah;
2126 inner_esatype = ET_AH;
2127
2128 i--;
2129 proto_info[i].proto = IPPROTO_AHIPPROTO_AH;
2130 proto_info[i].mode = st->st_ah.attrs.mode;
2131 tunnel |= proto_info[i].mode ==
2132 ENCAPSULATION_MODE_TUNNEL1;
2133 proto_info[i].reqid = reqid_ah(sr->reqid);
2134 }
2135
2136 if (st->st_esp.present) {
2137 inner_spi = st->st_esp.attrs.spi;
2138 inner_proto = &ip_protocol_esp;
2139 inner_esatype = ET_ESP;
2140
2141 i--;
2142 proto_info[i].proto = IPPROTO_ESPIPPROTO_ESP;
2143 proto_info[i].mode = st->st_esp.attrs.mode;
2144 tunnel |= proto_info[i].mode ==
2145 ENCAPSULATION_MODE_TUNNEL1;
2146 proto_info[i].reqid = reqid_esp(sr->reqid);
2147 }
2148
2149 if (st->st_ipcomp.present) {
2150 inner_spi = st->st_ipcomp.attrs.spi;
2151 inner_proto = &ip_protocol_comp;
2152 inner_esatype = ET_IPCOMP;
2153
2154 i--;
2155 proto_info[i].proto = IPPROTO_COMPIPPROTO_COMP;
2156 proto_info[i].mode =
2157 st->st_ipcomp.attrs.mode;
2158 tunnel |= proto_info[i].mode ==
2159 ENCAPSULATION_MODE_TUNNEL1;
2160 proto_info[i].reqid = reqid_ipcomp(sr->reqid);
2161 }
2162
2163 /* check for no transform at all */
2164 passert(st->st_ipcomp.present || st->st_esp.present ||{ _Bool assertion__ = st->st_ipcomp.present || st->st_esp
.present || st->st_ah.present; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 2165}, "%s", "st->st_ipcomp.present || st->st_esp.present || st->st_ah.present"
); } }
2165 st->st_ah.present){ _Bool assertion__ = st->st_ipcomp.present || st->st_esp
.present || st->st_ah.present; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 2165}, "%s", "st->st_ipcomp.present || st->st_esp.present || st->st_ah.present"
); } }
;
2166
2167 if (tunnel) {
2168 int j;
2169
2170 inner_spi = st->st_tunnel_out_spi;
2171 inner_proto = &ip_protocol_ipip;
2172 inner_esatype = ET_IPIP;
2173
2174 proto_info[i].mode = ENCAPSULATION_MODE_TUNNEL1;
2175 for (j = i + 1; proto_info[j].proto; j++)
2176 proto_info[j].mode =
2177 ENCAPSULATION_MODE_TRANSPORT2;
2178 }
2179
2180 uint32_t xfrm_if_id = c->xfrmi != NULL((void*)0) ? c->xfrmi->if_id : 0;
2181
2182 return eroute_connection(sr, inner_spi, inner_spi, inner_proto,
2183 inner_esatype, proto_info + i,
2184 calculate_sa_prio(c, FALSE0), &c->sa_marks,
2185 xfrm_if_id, op, opname,
2186 st->st_connection->policy_label);
2187}
2188
2189/* Check if there was traffic on given SA during the last idle_max
2190 * seconds. If TRUE, the SA was idle and DPD exchange should be performed.
2191 * If FALSE, DPD is not necessary. We also return TRUE for errors, as they
2192 * could mean that the SA is broken and needs to be replace anyway.
2193 *
2194 * note: this mutates *st by calling get_sa_info
2195 */
2196static bool_Bool netlink_eroute_idle(struct state *st, deltatime_t idle_max)
2197{
2198 deltatime_t idle_time;
2199
2200 passert(st != NULL){ _Bool assertion__ = st != ((void*)0); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "kernel_xfrm.c" , .
line = 2200}, "%s", "st != NULL"); } }
;
2201 return !get_sa_info(st, TRUE1, &idle_time) ||
2202 deltatime_cmp(idle_time, >=, idle_max)(deltatime_cmp_sign(idle_time, idle_max) >= 0);
2203}
2204
2205static bool_Bool netlink_shunt_eroute(const struct connection *c,
2206 const struct spd_route *sr,
2207 enum routing_t rt_kind,
2208 enum pluto_sadb_operations op,
2209 const char *opname)
2210{
2211 ipsec_spi_t spi;
2212
2213 /*
2214 * We are constructing a special SAID for the eroute.
2215 * The destination doesn't seem to matter, but the family does.
2216 * The protocol is &ip_protocol_internal -- mark this as shunt.
2217 * The satype has no meaning, but is required for PF_KEY header!
2218 * The SPI signifies the kind of shunt.
2219 */
2220 spi = shunt_policy_spi(c, rt_kind == RT_ROUTED_PROSPECTIVE);
2221
2222 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
2223 selector_buf this_buf, that_buf;
2224 DBG_log("netlink_shunt_eroute for proto %d, and source %s dest %s",
2225 sr->this.protocol,
2226 str_selector(&sr->this.client, &this_buf),
2227 str_selector(&sr->that.client, &that_buf));
2228 }
2229
2230 if (spi == 0) {
2231 /*
2232 * we're supposed to end up with no eroute: rejig op and
2233 * opname
2234 */
2235 switch (op) {
2236 case ERO_REPLACE:
2237 /* replace with nothing == delete */
2238 op = ERO_DELETE;
2239 opname = "delete";
2240 break;
2241 case ERO_ADD:
2242 /* add nothing == do nothing */
2243 return TRUE1;
2244
2245 case ERO_DELETE:
2246 /* delete remains delete */
2247 break;
2248
2249 case ERO_ADD_INBOUND:
2250 break;
2251
2252 case ERO_DEL_INBOUND:
2253 break;
2254
2255 default:
2256 bad_case(op)libreswan_bad_case("op", (op), (where_t) { .func = __func__, .
basename = "kernel_xfrm.c" , .line = 2256})
;
2257 }
2258 }
2259
2260 if (sr->routing == RT_ROUTED_ECLIPSED && c->kind == CK_TEMPLATE) {
2261 /*
2262 * We think that we have an eroute, but we don't.
2263 * Adjust the request and account for eclipses.
2264 */
2265 passert(eclipsable(sr)){ _Bool assertion__ = (subnetishost(&(sr)->this.client
) && subnetishost(&(sr)->that.client)); if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"kernel_xfrm.c" , .line = 2265}, "%s", "eclipsable(sr)"); } }
;
2266 switch (op) {
2267 case ERO_REPLACE:
2268 /* really an add */
2269 op = ERO_ADD;
2270 opname = "replace eclipsed";
2271 eclipse_count--;
2272 break;
2273 case ERO_DELETE:
2274 /*
2275 * delete unnecessary:
2276 * we don't actually have an eroute
2277 */
2278 eclipse_count--;
2279 return TRUE1;
2280
2281 case ERO_ADD:
2282 default:
2283 bad_case(op)libreswan_bad_case("op", (op), (where_t) { .func = __func__, .
basename = "kernel_xfrm.c" , .line = 2283})
;
2284 }
2285 } else if (eclipse_count > 0 && op == ERO_DELETE && eclipsable(sr)(subnetishost(&(sr)->this.client) && subnetishost
(&(sr)->that.client))
) {
2286 /* maybe we are uneclipsing something */
2287 struct spd_route *esr;
2288 struct connection *ue = eclipsed(c, &esr);
2289
2290 if (ue != NULL((void*)0)) {
2291 esr->routing = RT_ROUTED_PROSPECTIVE;
2292 return netlink_shunt_eroute(ue, esr,
2293 RT_ROUTED_PROSPECTIVE,
2294 ERO_REPLACE,
2295 "restoring eclipsed");
2296 }
2297 }
2298
2299 char buf2[256];
2300
2301 snprintf(buf2, sizeof(buf2), "eroute_connection %s", opname);
2302
2303 /*
2304 * XXX: the two calls below to netlink_raw_eroute() (not
2305 * raw_eroute()) seems to be the only place where SA_PROTO and
2306 * ESATYPE disagree - when ENCAPSULATION_MODE_TRANSPORT
2307 * SA_PROTO==&ip_protocol_esp and ESATYPE==ET_INT!?! Looking in the
2308 * function there's a weird test involving both SA_PROTO and
2309 * ESATYPE.
2310 */
2311 const struct ip_protocol *sa_proto = c->ipsec_mode == ENCAPSULATION_MODE_TRANSPORT2 ?
2312 &ip_protocol_esp : &ip_protocol_internal;
2313
2314 if (!netlink_raw_eroute(&sr->this.host_addr, &sr->this.client,
2315 &sr->that.host_addr, &sr->that.client,
2316 htonl(spi), htonl(spi),
2317 sa_proto,
2318 sr->this.protocol,
2319 ET_INT,
2320 null_proto_info,
2321 deltatime(0),
2322 calculate_sa_prio(c, FALSE0),
2323 &c->sa_marks,
2324 0 /* xfrm_if_id needed for shunt? */,
2325 op, buf2,
2326 c->policy_label))
2327 return FALSE0;
2328
2329 switch (op) {
2330 case ERO_ADD:
2331 op = ERO_ADD_INBOUND;
2332 break;
2333 case ERO_DELETE:
2334 op = ERO_DEL_INBOUND;
2335 break;
2336 default:
2337 return TRUE1;
2338 }
2339
2340 snprintf(buf2, sizeof(buf2), "eroute_connection %s inbound", opname);
2341
2342 return netlink_raw_eroute(&sr->that.host_addr, &sr->that.client,
2343 &sr->this.host_addr, &sr->this.client,
2344 htonl(spi), htonl(spi),
2345 sa_proto,
2346 sr->this.protocol,
2347 ET_INT,
2348 null_proto_info,
2349 deltatime(0),
2350 calculate_sa_prio(c, FALSE0),
2351 &c->sa_marks,
2352 0, /* xfrm_if_id needed for shunt? */
2353 op, buf2,
2354 c->policy_label);
2355}
2356
2357static void netlink_process_raw_ifaces(struct raw_iface *rifaces)
2358{
2359 struct raw_iface *ifp;
2360 ip_address lip; /* --listen filter option */
2361
2362 if (pluto_listen) {
2363 err_t e = ttoaddr_num(pluto_listen, 0, AF_UNSPEC0, &lip);
2364
2365 if (e != NULL((void*)0)) {
2366 DBG_log("invalid listen= option ignored: %s", e);
2367 pluto_listen = NULL((void*)0);
2368 }
2369 address_buf b;
2370 dbg("Only looking to listen on %s", str_address(&lip, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("Only looking to listen on %s", str_address(&
lip, &b)); } }
;
2371 }
2372
2373 /*
2374 * Find all virtual/real interface pairs.
2375 * For each real interface...
2376 */
2377 for (ifp = rifaces; ifp != NULL((void*)0); ifp = ifp->next) {
2378 struct raw_iface *v = NULL((void*)0); /* matching ipsecX interface */
2379 bool_Bool after = FALSE0; /* has vfp passed ifp on the list? */
2380 bool_Bool bad = FALSE0;
2381 struct raw_iface *vfp;
2382
2383 /* ignore if virtual (ipsec*) interface */
2384 if (startswith(ifp->name, IPSECDEVPREFIX)(strncmp(((ifp->name)), (("ipsec")), (strlen("ipsec"))) ==
0)
)
2385 continue;
2386
2387 /* ignore if virtual (mast*) interface */
2388 if (startswith(ifp->name, MASTDEVPREFIX)(strncmp(((ifp->name)), (("mast")), (strlen("mast"))) == 0
)
)
2389 continue;
2390
2391 for (vfp = rifaces; vfp != NULL((void*)0); vfp = vfp->next) {
2392 if (vfp == ifp) {
2393 after = true1;
2394 } else if (sameaddr(&ifp->addr, &vfp->addr)) {
2395 /*
2396 * Different entries with matching IP
2397 * addresses.
2398 *
2399 * Many interesting cases.
2400 */
2401 if (startswith(vfp->name, IPSECDEVPREFIX)(strncmp(((vfp->name)), (("ipsec")), (strlen("ipsec"))) ==
0)
) {
2402 if (v != NULL((void*)0)) {
2403 ipstr_buf b;
2404
2405 loglog(RC_LOG_SERIOUS,
2406 "ipsec interfaces %s and %s share same address %s",
2407 v->name, vfp->name,
2408 ipstr(&ifp->addr, &b));
2409 bad = TRUE1;
2410 } else {
2411 /* current winner */
2412 v = vfp;
2413 }
2414 } else {
2415 /*
2416 * ugh: a second real interface with
2417 * the same IP address "after" allows
2418 * us to avoid double reporting.
2419 */
2420 /* XXX: isn't this always true? */
2421 if (kernel_ops->type == USE_XFRM) {
2422 if (after) {
2423 bad = TRUE1;
2424 break;
2425 }
2426 continue;
2427 }
2428 if (after) {
2429 ipstr_buf b;
2430
2431 loglog(RC_LOG_SERIOUS,
2432 "IP interfaces %s and %s share address %s!",
2433 ifp->name, vfp->name,
2434 ipstr(&ifp->addr, &b));
2435 }
2436 bad = TRUE1;
2437 }
2438 }
2439 }
2440
2441 if (bad)
2442 continue;
2443
2444 /* XXX: isn't this always true? */
2445 if (kernel_ops->type == USE_XFRM) {
2446 v = ifp;
2447 }
2448
2449 /* what if we didn't find a virtual interface? */
2450 if (v == NULL((void*)0)) {
2451 address_buf b;
2452 dbg("IP interface %s %s has no matching ipsec* interface -- ignored",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
, ifp->name, str_address(&ifp->addr, &b)); } }
2453 ifp->name, str_address(&ifp->addr, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
, ifp->name, str_address(&ifp->addr, &b)); } }
;
2454 continue;
2455 }
2456
2457 /*
2458 * We've got all we need; see if this is a new thing:
2459 * search old interfaces list.
2460 */
2461
2462 /*
2463 * last check before we actually add the entry.
2464 *
2465 * ignore if --listen is specified and we do not match
2466 */
2467 if (pluto_listen != NULL((void*)0) && !sameaddr(&lip, &ifp->addr)) {
2468 ipstr_buf b;
2469
2470 libreswan_log("skipping interface %s with %s",loglog(RC_LOG, "skipping interface %s with %s", ifp->name,
ipstr(&ifp->addr, &b))
2471 ifp->name, ipstr(&ifp->addr, &b))loglog(RC_LOG, "skipping interface %s with %s", ifp->name,
ipstr(&ifp->addr, &b))
;
2472 continue;
2473 }
2474
2475 add_or_keep_iface_dev(ifp);
2476 }
2477
2478 /* delete the raw interfaces list */
2479 while (rifaces != NULL((void*)0)) {
2480 struct raw_iface *t = rifaces;
2481
2482 rifaces = t->next;
2483 pfree(t);
2484 }
2485}
2486
2487/*
2488 * netlink_get_sa - Get SA information from the kernel
2489 *
2490 * @param sa Kernel SA to be queried
2491 * @param bytes octets processed by IPsec SA
2492 * @param add_time timestamp when IPsec SA added
2493 * @return bool True if successful
2494 */
2495static bool_Bool netlink_get_sa(const struct kernel_sa *sa, uint64_t *bytes,
2496 uint64_t *add_time)
2497{
2498 struct {
2499 struct nlmsghdr n;
2500 struct xfrm_usersa_id id;
2501 } req;
2502
2503 struct nlm_resp rsp;
2504
2505 zero(&req)memset((&req), '\0', sizeof(*(&req)));
2506 req.n.nlmsg_flags = NLM_F_REQUEST0x01;
2507 req.n.nlmsg_type = XFRM_MSG_GETSAXFRM_MSG_GETSA;
2508
2509 req.id.daddr = xfrm_from_address(sa->dst.address);
2510
2511 req.id.spi = sa->spi;
2512 req.id.family = addrtypeof(sa->src.address);
2513 req.id.proto = sa->proto->ipproto;
2514
2515 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)))( ((((sizeof(req.id)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
2516
2517 if (!send_netlink_msg(&req.n, XFRM_MSG_NEWSAXFRM_MSG_NEWSA, &rsp, "Get SA", sa->text_said))
2518 return FALSE0;
2519
2520 *bytes = rsp.u.info.curlft.bytes;
2521 *add_time = rsp.u.info.curlft.add_time;
2522 return TRUE1;
2523}
2524
2525static bool_Bool netkey_do_command(const struct connection *c, const struct spd_route *sr,
2526 const char *verb, const char *verb_suffix, struct state *st)
2527{
2528 char cmd[2048]; /* arbitrary limit on shell command length */
2529 char common_shell_out_str[2048];
2530
2531 if (!fmt_common_shell_out(common_shell_out_str,
2532 sizeof(common_shell_out_str),
2533 c, sr, st)) {
2534 loglog(RC_LOG_SERIOUS, "%s%s command too long!", verb,
2535 verb_suffix);
2536 return FALSE0;
2537 }
2538
2539 if (-1 == snprintf(cmd, sizeof(cmd),
2540 "PLUTO_VERB='%s%s' %s%s 2>&1",
2541 verb, verb_suffix,
2542 common_shell_out_str,
2543 sr->this.updown)) {
2544 loglog(RC_LOG_SERIOUS, "%s%s command too long!", verb,
2545 verb_suffix);
2546 return FALSE0;
2547 }
2548
2549 return invoke_command(verb, verb_suffix, cmd);
2550}
2551
2552/* add bypass policies/holes icmp */
2553static bool_Bool netlink_bypass_policy(int family, int proto, int port)
2554{
2555 struct {
2556 struct nlmsghdr n;
2557 union {
2558 struct xfrm_userpolicy_info p;
2559 struct xfrm_userpolicy_id id;
2560 } u;
2561 char data[MAX_NETLINK_DATA_SIZE8192];
2562 } req;
2563
2564 zero(&req)memset((&req), '\0', sizeof(*(&req)));
2565
2566 req.n.nlmsg_flags = NLM_F_REQUEST0x01 | NLM_F_ACK0x04;
2567
2568 req.n.nlmsg_type = XFRM_MSG_UPDPOLICYXFRM_MSG_UPDPOLICY;
2569 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)))( ((((sizeof(req.u.p)) + ((int) ( ((sizeof(struct nlmsghdr))+
4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
2570
2571 req.u.p.dir = XFRM_POLICY_IN;
2572 req.u.p.priority = 1; /* give admin prio 0 as override */
2573 req.u.p.action = XFRM_POLICY_ALLOW0;
2574 req.u.p.share = XFRM_SHARE_ANY;
2575
2576 req.u.p.lft.soft_byte_limit = XFRM_INF(~(__u64)0);
2577 req.u.p.lft.soft_packet_limit = XFRM_INF(~(__u64)0);
2578 req.u.p.lft.hard_byte_limit = XFRM_INF(~(__u64)0);
2579 req.u.p.lft.hard_packet_limit = XFRM_INF(~(__u64)0);
2580
2581 req.u.p.sel.proto = proto;
2582 req.u.p.sel.family = family;
2583
2584 const char* text = "add port bypass";
2585
2586 if (proto == IPPROTO_ICMPV658) {
2587 uint16_t icmp_type;
2588 uint16_t icmp_code;
2589
2590 icmp_type = port >> 8;
2591 icmp_code = port & 0xFF;
2592 req.u.p.sel.sport = htons(icmp_type);
2593 req.u.p.sel.dport = htons(icmp_code);
2594 req.u.p.sel.sport_mask = 0xffff;
2595
2596 if (!netlink_policy(&req.n, 1, text))
2597 return FALSE0;
2598
2599 req.u.p.dir = XFRM_POLICY_FWD;
2600
2601 if (!netlink_policy(&req.n, 1, text))
2602 return FALSE0;
2603
2604 req.u.p.dir = XFRM_POLICY_OUT;
2605
2606 if (!netlink_policy(&req.n, 1, text))
2607 return FALSE0;
2608 } else {
2609 req.u.p.sel.dport = htons(port);
2610 req.u.p.sel.dport_mask = 0xffff;
2611
2612 if (!netlink_policy(&req.n, 1, text))
2613 return FALSE0;
2614
2615 req.u.p.dir = XFRM_POLICY_OUT;
2616
2617 req.u.p.sel.sport = htons(port);
2618 req.u.p.sel.sport_mask = 0xffff;
2619 req.u.p.sel.dport = 0;
2620 req.u.p.sel.dport_mask = 0;
2621
2622 if (!netlink_policy(&req.n, 1, text))
2623 return FALSE0;
2624 }
2625
2626 return TRUE1;
2627}
2628
2629static bool_Bool netlink_v6holes(void)
2630{
2631 /* this could be per interface specific too */
2632 char proc_f[] = "/proc/sys/net/ipv6/conf/all/disable_ipv6";
2633 int disable_ipv6 = -1;
2634 bool_Bool ret = FALSE0;
2635 struct stat sts;
2636
2637 if (stat(proc_f, &sts) == 0) {
2638 FILE *f = fopen(proc_f, "r");
2639 if (f != NULL((void*)0)) {
2640 char buf[64];
2641 if (fgets(buf, sizeof(buf), f) != NULL((void*)0)) {
2642 disable_ipv6 = atoi(buf);
2643 }
2644 (void) fclose(f);
2645 } else {
2646 LOG_ERRNO(errno, "\"%s\"", proc_f){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "\"%s\"", proc_f); jam_string(buf, "."); jam(buf, " ""Errno %d: %s"
, (e_), strerror(e_)); jambuf_to_error_stream(buf); } }
;
2647 }
2648 } else {
2649 dbg("starting without ipv6 support! could not stat \"%s\"" PRI_ERRNO,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("starting without ipv6 support! could not stat \"%s\""
"Errno %d: %s", proc_f, ((*__errno_location ())), strerror((
*__errno_location ()))); } }
2650 proc_f, pri_errno(errno)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("starting without ipv6 support! could not stat \"%s\""
"Errno %d: %s", proc_f, ((*__errno_location ())), strerror((
*__errno_location ()))); } }
;
2651 /*
2652 * pretend success, do not exit pluto,
2653 * likely IPv6 is disabled in kernel at compile time. e.g. OpenWRT.
2654 */
2655 ret = TRUE1;
2656 }
2657
2658 if (disable_ipv6 == 1) {
2659 dbg("net.ipv6.conf.all.disable_ipv6=1 ignore ipv6 holes"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("net.ipv6.conf.all.disable_ipv6=1 ignore ipv6 holes"
); } }
;
2660 ret = TRUE1; /* pretend success, do not exit pluto */
2661 } else if (disable_ipv6 == 0) {
2662 ret = netlink_bypass_policy(AF_INET610, IPPROTO_ICMPV658,
2663 ICMP_NEIGHBOR_DISCOVERY34816);
2664 ret &= netlink_bypass_policy(AF_INET610, IPPROTO_ICMPV658,
2665 ICMP_NEIGHBOR_SOLICITATION34560);
2666 }
2667
2668 return ret;
2669}
2670
2671static bool_Bool qry_xfrm_mirgrate_support(struct nlmsghdr *hdr)
2672{
2673 struct nlm_resp rsp;
2674 size_t len;
2675 ssize_t r;
2676 struct sockaddr_nl addr;
2677 int nl_fd = socket(AF_NETLINK16, SOCK_DGRAMSOCK_DGRAM, NETLINK_XFRM6);
2678
2679 if (nl_fd < 0) {
2680 LOG_ERRNO(errno, "socket() in qry_xfrm_mirgrate_support()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "socket() in qry_xfrm_mirgrate_support()"); jam_string(
buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream
(buf); } }
;
2681 return FALSE0;
2682 }
2683
2684 if (fcntl(nl_fd, F_SETFL4, O_NONBLOCK04000) != 0) {
2685 LOG_ERRNO(errno, "fcntl(O_NONBLOCK in qry_xfrm_mirgrate_support()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "fcntl(O_NONBLOCK in qry_xfrm_mirgrate_support()"); jam_string
(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream
(buf); } }
;
2686 close(nl_fd);
2687
2688 return FALSE0;
2689 }
2690
2691 /* hdr->nlmsg_seq = ++seq; */
2692 len = hdr->nlmsg_len;
2693 do {
2694 r = write(nl_fd, hdr, len);
2695 } while (r < 0 && errno(*__errno_location ()) == EINTR4);
2696 if (r < 0) {
2697 LOG_ERRNO(errno, "netlink write() xfrm_migrate_support lookup"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "netlink write() xfrm_migrate_support lookup"); jam_string
(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror(e_)); jambuf_to_error_stream
(buf); } }
;
2698 close(nl_fd);
2699 return FALSE0;
2700 } else if ((size_t)r != len) {
2701 loglog(RC_LOG_SERIOUS,
2702 "ERROR: netlink write() xfrm_migrate_support message truncated: %zd instead of %zu",
2703 r, len);
2704 close(nl_fd);
2705 return FALSE0;
2706 }
2707
2708 for (;;) {
2709 socklen_t alen = sizeof(addr);
2710
2711 r = recvfrom(nl_fd, &rsp, sizeof(rsp), 0,
2712 (struct sockaddr *)&addr, &alen);
2713 if (r < 0) {
2714 if (errno(*__errno_location ()) == EINTR4) {
2715 continue;
2716 } else if (errno(*__errno_location ()) == EAGAIN11) {
2717 /* old kernel F22 - dos not return proper error ??? */
2718 dbg("ignore EAGAIN in %s assume MOBIKE migration is supported", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignore EAGAIN in %s assume MOBIKE migration is supported"
, __func__); } }
;
2719 break;
2720 }
2721 }
2722 break;
2723 }
2724
2725 close(nl_fd);
2726
2727 if (rsp.n.nlmsg_type == NLMSG_ERROR0x2 && rsp.u.e.error == -ENOPROTOOPT92) {
2728 dbg("MOBIKE will fail got ENOPROTOOPT"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MOBIKE will fail got ENOPROTOOPT"); } }
;
2729 return FALSE0;
2730 }
2731
2732 return TRUE1;
2733}
2734
2735static err_t netlink_migrate_sa_check(void)
2736{
2737 if (kernel_mobike_supprt == 0) {
2738 /* check the kernel */
2739
2740 struct {
2741 struct nlmsghdr n;
2742 struct xfrm_userpolicy_id id;
2743 char data[MAX_NETLINK_DATA_SIZE8192];
2744 } req;
2745
2746 zero(&req)memset((&req), '\0', sizeof(*(&req)));
2747 req.n.nlmsg_flags = NLM_F_REQUEST0x01;
2748 req.n.nlmsg_type = XFRM_MSG_MIGRATEXFRM_MSG_MIGRATE;
2749 req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)))( ((((sizeof(req.id)) + ((int) ( ((sizeof(struct nlmsghdr))+4U
-1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
2750
2751 /* add attrs[XFRM_MSG_MIGRATE] */
2752 struct rtattr *attr;
2753 struct xfrm_user_migrate migrate;
2754
2755 zero(&migrate)memset((&migrate), '\0', sizeof(*(&migrate)));
2756 attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
2757 attr->rta_type = XFRMA_MIGRATE;
2758 attr->rta_len = sizeof(migrate);
2759
2760 memcpy(RTA_DATA(attr)((void*)(((char*)(attr)) + (( ((sizeof(struct rtattr))+4U -1)
& ~(4U -1) ) + (0))))
, &migrate, attr->rta_len);
2761 attr->rta_len = RTA_LENGTH(attr->rta_len)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (attr->
rta_len))
;
2762 req.n.nlmsg_len += attr->rta_len;
2763
2764 bool_Bool ret = qry_xfrm_mirgrate_support(&req.n);
2765 kernel_mobike_supprt = ret ? 1 : -1;
2766 }
2767
2768 if (kernel_mobike_supprt > 0) {
2769 return NULL((void*)0);
2770 } else {
2771 return "CONFIG_XFRM_MIGRATE";
2772 }
2773}
2774
2775static bool_Bool netlink_poke_ipsec_policy_hole(const struct iface_dev *ifd, int fd)
2776{
2777 const struct ip_info *type = address_type(&ifd->id_address);
2778 struct xfrm_userpolicy_info policy = {
2779 .action = XFRM_POLICY_ALLOW0,
2780 .sel = {
2781 .family = type->af,
2782 }
2783 };
2784
2785 int opt, sol;
2786
2787 if (type == &ipv6_info) {
2788 sol = IPPROTO_IPV6IPPROTO_IPV6;
2789 opt = IPV6_XFRM_POLICY35;
2790 } else {
2791 sol = SOL_IP0;
2792 opt = IP_XFRM_POLICY17;
2793 }
2794
2795 policy.dir = XFRM_POLICY_IN;
2796 if (setsockopt(fd, sol, opt, &policy, sizeof(policy)) < 0) {
2797 LOG_ERRNO(errno, "setsockopt IP_XFRM_POLICY XFRM_POLICY_IN in process_raw_ifaces()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "setsockopt IP_XFRM_POLICY XFRM_POLICY_IN in process_raw_ifaces()"
); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror
(e_)); jambuf_to_error_stream(buf); } }
;
2798 return false0;
2799 }
2800
2801 policy.dir = XFRM_POLICY_OUT;
2802 if (setsockopt(fd, sol, opt, &policy, sizeof(policy)) < 0) {
2803 LOG_ERRNO(errno, "setsockopt IP_XFRM_POLICY XFRM_POLICY_OUT in process_raw_ifaces()"){ int e_ = (*__errno_location ()); for (char lswbuf[((size_t)
1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = (
(void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) { jam(buf, "ERROR: "); jam_cur_prefix(buf); jam
(buf, "setsockopt IP_XFRM_POLICY XFRM_POLICY_OUT in process_raw_ifaces()"
); jam_string(buf, "."); jam(buf, " ""Errno %d: %s", (e_), strerror
(e_)); jambuf_to_error_stream(buf); } }
;
2804 return false0;
2805 }
2806
2807 return true1;
2808}
2809
2810const struct kernel_ops xfrm_kernel_ops = {
2811 .kern_name = "xfrm",
2812 .type = USE_XFRM,
2813 .scan_shunts = expire_bare_shunts,
2814 .async_fdp = &nl_xfrm_fd,
2815 .route_fdp = &nl_route_fd,
2816 .replay_window = IPSEC_SA_DEFAULT_REPLAY_WINDOW32,
2817
2818 .init = init_netlink,
2819#ifdef USE_XFRM_INTERFACE1
2820 .shutdown = free_xfrmi_ipsec1,
2821#else
2822 .shutdown = NULL((void*)0),
2823#endif
2824 .process_msg = netlink_process_msg,
2825 .raw_eroute = netlink_raw_eroute,
2826 .add_sa = netlink_add_sa,
2827 .del_sa = netlink_del_sa,
2828 .get_sa = netlink_get_sa,
2829 .process_queue = NULL((void*)0),
2830 .grp_sa = NULL((void*)0),
2831 .get_spi = netlink_get_spi,
2832 .exceptsocket = NULL((void*)0),
2833 .docommand = netkey_do_command,
2834 .process_raw_ifaces = netlink_process_raw_ifaces,
2835 .shunt_eroute = netlink_shunt_eroute,
2836 .sag_eroute = netlink_sag_eroute,
2837 .eroute_idle = netlink_eroute_idle,
2838 .migrate_sa_check = netlink_migrate_sa_check,
2839 .migrate_sa = netlink_migrate_sa,
2840 /*
2841 * We should implement netlink_remove_orphaned_holds
2842 * if netlink specific changes are needed.
2843 */
2844 .remove_orphaned_holds = NULL((void*)0), /* only used for klips /proc scanner */
2845 .overlap_supported = FALSE0,
2846 .sha2_truncbug_support = TRUE1,
2847 .v6holes = netlink_v6holes,
2848 .poke_ipsec_policy_hole = netlink_poke_ipsec_policy_hole,
2849 .detect_offload = netlink_detect_offload,
2850};