summaryrefslogtreecommitdiff
path: root/src/pluto/kernel_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/kernel_netlink.c')
-rw-r--r--src/pluto/kernel_netlink.c1748
1 files changed, 873 insertions, 875 deletions
diff --git a/src/pluto/kernel_netlink.c b/src/pluto/kernel_netlink.c
index 4269de66e..b4b4774c7 100644
--- a/src/pluto/kernel_netlink.c
+++ b/src/pluto/kernel_netlink.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_netlink.c 3850 2008-04-18 20:01:49Z andreas $
*/
#if defined(linux) && defined(KERNEL26_SUPPORT)
@@ -39,7 +37,7 @@
#include "kernel_netlink.h"
#include "kernel_pfkey.h"
#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include "kernel_alg.h"
/* Minimum priority number in SPD used by pluto. */
@@ -48,72 +46,72 @@
static int netlinkfd = NULL_FD;
static int netlink_bcast_fd = NULL_FD;
-#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
+#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
static sparse_names xfrm_type_names = {
- NE(NLMSG_NOOP),
- NE(NLMSG_ERROR),
- NE(NLMSG_DONE),
- NE(NLMSG_OVERRUN),
+ NE(NLMSG_NOOP),
+ NE(NLMSG_ERROR),
+ NE(NLMSG_DONE),
+ NE(NLMSG_OVERRUN),
- NE(XFRM_MSG_NEWSA),
- NE(XFRM_MSG_DELSA),
- NE(XFRM_MSG_GETSA),
+ NE(XFRM_MSG_NEWSA),
+ NE(XFRM_MSG_DELSA),
+ NE(XFRM_MSG_GETSA),
- NE(XFRM_MSG_NEWPOLICY),
- NE(XFRM_MSG_DELPOLICY),
- NE(XFRM_MSG_GETPOLICY),
+ NE(XFRM_MSG_NEWPOLICY),
+ NE(XFRM_MSG_DELPOLICY),
+ NE(XFRM_MSG_GETPOLICY),
- NE(XFRM_MSG_ALLOCSPI),
- NE(XFRM_MSG_ACQUIRE),
- NE(XFRM_MSG_EXPIRE),
+ NE(XFRM_MSG_ALLOCSPI),
+ NE(XFRM_MSG_ACQUIRE),
+ NE(XFRM_MSG_EXPIRE),
- NE(XFRM_MSG_UPDPOLICY),
- NE(XFRM_MSG_UPDSA),
+ NE(XFRM_MSG_UPDPOLICY),
+ NE(XFRM_MSG_UPDSA),
- NE(XFRM_MSG_POLEXPIRE),
+ NE(XFRM_MSG_POLEXPIRE),
- NE(XFRM_MSG_MAX),
+ NE(XFRM_MSG_MAX),
- { 0, sparse_end }
+ { 0, sparse_end }
};
#undef NE
/* Authentication algorithms */
static sparse_names aalg_list = {
- { SADB_X_AALG_NULL, "digest_null" },
- { SADB_AALG_MD5HMAC, "md5" },
- { SADB_AALG_SHA1HMAC, "sha1" },
- { SADB_X_AALG_SHA2_256HMAC, "sha256" },
- { SADB_X_AALG_SHA2_384HMAC, "sha384" },
- { SADB_X_AALG_SHA2_512HMAC, "sha512" },
- { SADB_X_AALG_RIPEMD160HMAC, "ripemd160" },
- { SADB_X_AALG_AES_XCBC_MAC, "xcbc(aes)"},
- { SADB_X_AALG_NULL, "null" },
- { 0, sparse_end }
+ { SADB_X_AALG_NULL, "digest_null" },
+ { SADB_AALG_MD5HMAC, "md5" },
+ { SADB_AALG_SHA1HMAC, "sha1" },
+ { SADB_X_AALG_SHA2_256HMAC, "sha256" },
+ { SADB_X_AALG_SHA2_384HMAC, "sha384" },
+ { SADB_X_AALG_SHA2_512HMAC, "sha512" },
+ { SADB_X_AALG_RIPEMD160HMAC, "ripemd160" },
+ { SADB_X_AALG_AES_XCBC_MAC, "xcbc(aes)"},
+ { SADB_X_AALG_NULL, "null" },
+ { 0, sparse_end }
};
/* Encryption algorithms */
static sparse_names ealg_list = {
- { SADB_EALG_NULL, "cipher_null" },
- { SADB_EALG_DESCBC, "des" },
- { SADB_EALG_3DESCBC, "des3_ede" },
- { SADB_X_EALG_CASTCBC, "cast128" },
- { SADB_X_EALG_BLOWFISHCBC, "blowfish" },
- { SADB_X_EALG_AESCBC, "aes" },
- { SADB_X_EALG_CAMELLIACBC, "cbc(camellia)" },
- { SADB_X_EALG_SERPENTCBC, "serpent" },
- { SADB_X_EALG_TWOFISHCBC, "twofish" },
- { 0, sparse_end }
+ { SADB_EALG_NULL, "cipher_null" },
+ { SADB_EALG_DESCBC, "des" },
+ { SADB_EALG_3DESCBC, "des3_ede" },
+ { SADB_X_EALG_CASTCBC, "cast128" },
+ { SADB_X_EALG_BLOWFISHCBC, "blowfish" },
+ { SADB_X_EALG_AESCBC, "aes" },
+ { SADB_X_EALG_CAMELLIACBC, "cbc(camellia)" },
+ { SADB_X_EALG_SERPENTCBC, "serpent" },
+ { SADB_X_EALG_TWOFISHCBC, "twofish" },
+ { 0, sparse_end }
};
/* Compression algorithms */
static sparse_names calg_list = {
- { SADB_X_CALG_DEFLATE, "deflate" },
- { SADB_X_CALG_LZS, "lzs" },
- { SADB_X_CALG_LZJH, "lzjh" },
- { 0, sparse_end }
+ { SADB_X_CALG_DEFLATE, "deflate" },
+ { SADB_X_CALG_LZS, "lzs" },
+ { SADB_X_CALG_LZJH, "lzjh" },
+ { 0, sparse_end }
};
/** ip2xfrm - Take an IP address and convert to an xfrm.
@@ -124,14 +122,14 @@ static sparse_names calg_list = {
static void
ip2xfrm(const ip_address *addr, xfrm_address_t *xaddr)
{
- if (addr->u.v4.sin_family == AF_INET)
- {
- xaddr->a4 = addr->u.v4.sin_addr.s_addr;
- }
- else
- {
- memcpy(xaddr->a6, &addr->u.v6.sin6_addr, sizeof(xaddr->a6));
- }
+ if (addr->u.v4.sin_family == AF_INET)
+ {
+ xaddr->a4 = addr->u.v4.sin_addr.s_addr;
+ }
+ else
+ {
+ memcpy(xaddr->a6, &addr->u.v6.sin6_addr, sizeof(xaddr->a6));
+ }
}
/** init_netlink - Initialize the netlink inferface. Opens the sockets and
@@ -140,32 +138,32 @@ ip2xfrm(const ip_address *addr, xfrm_address_t *xaddr)
static void
init_netlink(void)
{
- struct sockaddr_nl addr;
+ struct sockaddr_nl addr;
- netlinkfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
+ netlinkfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
- if (netlinkfd < 0)
- exit_log_errno((e, "socket() in init_netlink()"));
+ if (netlinkfd < 0)
+ exit_log_errno((e, "socket() in init_netlink()"));
- if (fcntl(netlinkfd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_netlink()"));
+ if (fcntl(netlinkfd, F_SETFD, FD_CLOEXEC) != 0)
+ exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_netlink()"));
- netlink_bcast_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
+ netlink_bcast_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
- if (netlink_bcast_fd < 0)
- exit_log_errno((e, "socket() for bcast in init_netlink()"));
+ if (netlink_bcast_fd < 0)
+ exit_log_errno((e, "socket() for bcast in init_netlink()"));
- if (fcntl(netlink_bcast_fd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"));
+ if (fcntl(netlink_bcast_fd, F_SETFD, FD_CLOEXEC) != 0)
+ exit_log_errno((e, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"));
- if (fcntl(netlink_bcast_fd, F_SETFL, O_NONBLOCK) != 0)
- exit_log_errno((e, "fcntl(O_NONBLOCK) for bcast in init_netlink()"));
+ if (fcntl(netlink_bcast_fd, F_SETFL, O_NONBLOCK) != 0)
+ exit_log_errno((e, "fcntl(O_NONBLOCK) for bcast in init_netlink()"));
- addr.nl_family = AF_NETLINK;
- addr.nl_pid = getpid();
- addr.nl_groups = XFRMGRP_ACQUIRE | XFRMGRP_EXPIRE;
- if (bind(netlink_bcast_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
- exit_log_errno((e, "Failed to bind bcast socket in init_netlink()"));
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pid = getpid();
+ addr.nl_groups = XFRMGRP_ACQUIRE | XFRMGRP_EXPIRE;
+ if (bind(netlink_bcast_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
+ exit_log_errno((e, "Failed to bind bcast socket in init_netlink()"));
}
/** send_netlink_msg
@@ -182,139 +180,139 @@ static bool
send_netlink_msg(struct nlmsghdr *hdr, struct nlmsghdr *rbuf, size_t rbuf_len
, const char *description, const char *text_said)
{
- struct {
- struct nlmsghdr n;
- struct nlmsgerr e;
- char data[1024];
- } rsp;
-
- size_t len;
- ssize_t r;
- struct sockaddr_nl addr;
- static uint32_t seq;
-
- if (no_klips)
- {
- return TRUE;
- }
-
- hdr->nlmsg_seq = ++seq;
- len = hdr->nlmsg_len;
- do {
- r = write(netlinkfd, hdr, len);
- } while (r < 0 && errno == EINTR);
- if (r < 0)
- {
- log_errno((e
- , "netlink write() of %s message"
- " for %s %s failed"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said));
- return FALSE;
- }
- else if ((size_t)r != len)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink write() of %s message"
- " for %s %s truncated: %ld instead of %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long)r, (unsigned long)len);
- return FALSE;
- }
-
- for (;;) {
- socklen_t alen;
+ struct {
+ struct nlmsghdr n;
+ struct nlmsgerr e;
+ char data[1024];
+ } rsp;
+
+ size_t len;
+ ssize_t r;
+ struct sockaddr_nl addr;
+ static uint32_t seq;
+
+ if (no_klips)
+ {
+ return TRUE;
+ }
- alen = sizeof(addr);
- r = recvfrom(netlinkfd, &rsp, sizeof(rsp), 0
- , (struct sockaddr *)&addr, &alen);
+ hdr->nlmsg_seq = ++seq;
+ len = hdr->nlmsg_len;
+ do {
+ r = write(netlinkfd, hdr, len);
+ } while (r < 0 && errno == EINTR);
if (r < 0)
{
- if (errno == EINTR)
- {
- continue;
- }
- log_errno((e
- , "netlink recvfrom() of response to our %s message"
- " for %s %s failed"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said));
- return FALSE;
+ log_errno((e
+ , "netlink write() of %s message"
+ " for %s %s failed"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said));
+ return FALSE;
}
- else if ((size_t) r < sizeof(rsp.n))
+ else if ((size_t)r != len)
{
- plog("netlink read truncated message: %ld bytes; ignore message"
- , (long) r);
- continue;
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: netlink write() of %s message"
+ " for %s %s truncated: %ld instead of %lu"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , (long)r, (unsigned long)len);
+ return FALSE;
}
- else if (addr.nl_pid != 0)
+
+ for (;;) {
+ socklen_t alen;
+
+ alen = sizeof(addr);
+ r = recvfrom(netlinkfd, &rsp, sizeof(rsp), 0
+ , (struct sockaddr *)&addr, &alen);
+ if (r < 0)
+ {
+ if (errno == EINTR)
+ {
+ continue;
+ }
+ log_errno((e
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s failed"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said));
+ return FALSE;
+ }
+ else if ((size_t) r < sizeof(rsp.n))
+ {
+ plog("netlink read truncated message: %ld bytes; ignore message"
+ , (long) r);
+ continue;
+ }
+ else if (addr.nl_pid != 0)
+ {
+ /* not for us: ignore */
+ DBG(DBG_KLIPS,
+ DBG_log("netlink: ignoring %s message from process %u"
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
+ , addr.nl_pid));
+ continue;
+ }
+ else if (rsp.n.nlmsg_seq != seq)
+ {
+ DBG(DBG_KLIPS,
+ 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)));
+ continue;
+ }
+ break;
+ }
+
+ if (rsp.n.nlmsg_len > (size_t) r)
{
- /* not for us: ignore */
- DBG(DBG_KLIPS,
- DBG_log("netlink: ignoring %s message from process %u"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
- , addr.nl_pid));
- continue;
+ loglog(RC_LOG_SERIOUS
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s was truncated: %ld instead of %lu"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , (long) len, (unsigned long) rsp.n.nlmsg_len);
+ return FALSE;
}
- else if (rsp.n.nlmsg_seq != seq)
+ else if (rsp.n.nlmsg_type != NLMSG_ERROR
+ && (rbuf && rsp.n.nlmsg_type != rbuf->nlmsg_type))
{
- DBG(DBG_KLIPS,
- 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)));
- continue;
+ loglog(RC_LOG_SERIOUS
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s was of wrong type (%s)"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type));
+ return FALSE;
}
- break;
- }
-
- if (rsp.n.nlmsg_len > (size_t) r)
- {
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was truncated: %ld instead of %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long) len, (unsigned long) rsp.n.nlmsg_len);
- return FALSE;
- }
- else if (rsp.n.nlmsg_type != NLMSG_ERROR
- && (rbuf && rsp.n.nlmsg_type != rbuf->nlmsg_type))
- {
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was of wrong type (%s)"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type));
- return FALSE;
- }
- else if (rbuf)
- {
- if ((size_t) r > rbuf_len)
+ else if (rbuf)
{
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was too long: %ld > %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long)r, (unsigned long)rbuf_len);
- return FALSE;
+ if ((size_t) r > rbuf_len)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s was too long: %ld > %lu"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , (long)r, (unsigned long)rbuf_len);
+ return FALSE;
+ }
+ memcpy(rbuf, &rsp, r);
+ return TRUE;
+ }
+ else if (rsp.n.nlmsg_type == NLMSG_ERROR && rsp.e.error)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: netlink response for %s %s included errno %d: %s"
+ , description, text_said
+ , -rsp.e.error
+ , strerror(-rsp.e.error));
+ return FALSE;
}
- memcpy(rbuf, &rsp, r);
- return TRUE;
- }
- else if (rsp.n.nlmsg_type == NLMSG_ERROR && rsp.e.error)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink response for %s %s included errno %d: %s"
- , description, text_said
- , -rsp.e.error
- , strerror(-rsp.e.error));
- return FALSE;
- }
- return TRUE;
+ return TRUE;
}
/** netlink_policy -
@@ -327,36 +325,36 @@ send_netlink_msg(struct nlmsghdr *hdr, struct nlmsghdr *rbuf, size_t rbuf_len
static bool
netlink_policy(struct nlmsghdr *hdr, bool enoent_ok, const char *text_said)
{
- struct {
- struct nlmsghdr n;
- struct nlmsgerr e;
- } rsp;
- int error;
-
- rsp.n.nlmsg_type = NLMSG_ERROR;
- if (!send_netlink_msg(hdr, &rsp.n, sizeof(rsp), "policy", text_said))
- {
- return FALSE;
- }
+ struct {
+ struct nlmsghdr n;
+ struct nlmsgerr e;
+ } rsp;
+ int error;
+
+ rsp.n.nlmsg_type = NLMSG_ERROR;
+ if (!send_netlink_msg(hdr, &rsp.n, sizeof(rsp), "policy", text_said))
+ {
+ return FALSE;
+ }
- error = -rsp.e.error;
- if (!error)
- {
- return TRUE;
- }
+ error = -rsp.e.error;
+ if (!error)
+ {
+ return TRUE;
+ }
- if (error == ENOENT && enoent_ok)
- {
- return TRUE;
- }
-
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink %s response for flow %s included errno %d: %s"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , text_said
- , error
- , strerror(error));
- return FALSE;
+ if (error == ENOENT && enoent_ok)
+ {
+ return TRUE;
+ }
+
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: netlink %s response for flow %s included errno %d: %s"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , text_said
+ , error
+ , strerror(error));
+ return FALSE;
}
/** netlink_raw_eroute
@@ -376,192 +374,192 @@ netlink_policy(struct nlmsghdr *hdr, bool enoent_ok, const char *text_said)
*/
static bool
netlink_raw_eroute(const ip_address *this_host
- , const ip_subnet *this_client
- , const ip_address *that_host
- , const ip_subnet *that_client
- , ipsec_spi_t spi
- , unsigned int satype
- , unsigned int transport_proto
- , const struct pfkey_proto_info *proto_info
- , time_t use_lifetime UNUSED
- , unsigned int op
- , const char *text_said)
+ , const ip_subnet *this_client
+ , const ip_address *that_host
+ , const ip_subnet *that_client
+ , ipsec_spi_t spi
+ , unsigned int satype
+ , unsigned int transport_proto
+ , const struct pfkey_proto_info *proto_info
+ , time_t use_lifetime UNUSED
+ , unsigned int op
+ , const char *text_said)
{
- struct {
- struct nlmsghdr n;
- union {
- struct xfrm_userpolicy_info p;
- struct xfrm_userpolicy_id id;
- } u;
- char data[1024];
- } req;
- int shift;
- int dir;
- int family;
- int policy;
- bool ok;
- bool enoent_ok;
-
- policy = IPSEC_POLICY_IPSEC;
-
- if (satype == SADB_X_SATYPE_INT)
- {
- /* shunt route */
- switch (ntohl(spi))
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct xfrm_userpolicy_info p;
+ struct xfrm_userpolicy_id id;
+ } u;
+ char data[1024];
+ } req;
+ int shift;
+ int dir;
+ int family;
+ int policy;
+ bool ok;
+ bool enoent_ok;
+
+ policy = IPSEC_POLICY_IPSEC;
+
+ if (satype == SADB_X_SATYPE_INT)
{
- case SPI_PASS:
- policy = IPSEC_POLICY_NONE;
- break;
- case SPI_DROP:
- case SPI_REJECT:
- default:
- policy = IPSEC_POLICY_DISCARD;
- break;
- case SPI_TRAP:
- case SPI_TRAPSUBNET:
- case SPI_HOLD:
- if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
- {
- return TRUE;
- }
- break;
- }
- }
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-
- family = that_client->addr.u.v4.sin_family;
- shift = (family == AF_INET) ? 5 : 7;
-
- req.u.p.sel.sport = portof(&this_client->addr);
- req.u.p.sel.dport = portof(&that_client->addr);
- req.u.p.sel.sport_mask = (req.u.p.sel.sport) ? ~0:0;
- req.u.p.sel.dport_mask = (req.u.p.sel.dport) ? ~0:0;
- ip2xfrm(&this_client->addr, &req.u.p.sel.saddr);
- ip2xfrm(&that_client->addr, &req.u.p.sel.daddr);
- req.u.p.sel.prefixlen_s = this_client->maskbits;
- req.u.p.sel.prefixlen_d = that_client->maskbits;
- req.u.p.sel.proto = transport_proto;
- req.u.p.sel.family = family;
-
- dir = XFRM_POLICY_OUT;
- if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
- {
- dir = XFRM_POLICY_IN;
- }
-
- if ((op & ERO_MASK) == ERO_DELETE)
- {
- req.u.id.dir = dir;
- req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.id)));
- }
- else
- {
- int src, dst;
-
- req.u.p.dir = dir;
-
- src = req.u.p.sel.prefixlen_s;
- dst = req.u.p.sel.prefixlen_d;
- if (dir != XFRM_POLICY_OUT) {
- src = req.u.p.sel.prefixlen_d;
- dst = req.u.p.sel.prefixlen_s;
+ /* shunt route */
+ switch (ntohl(spi))
+ {
+ case SPI_PASS:
+ policy = IPSEC_POLICY_NONE;
+ break;
+ case SPI_DROP:
+ case SPI_REJECT:
+ default:
+ policy = IPSEC_POLICY_DISCARD;
+ break;
+ case SPI_TRAP:
+ case SPI_TRAPSUBNET:
+ case SPI_HOLD:
+ if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
+ {
+ return TRUE;
+ }
+ break;
+ }
}
- req.u.p.priority = MIN_SPD_PRIORITY
- + (((2 << shift) - src) << shift)
- + (2 << shift) - dst;
- req.u.p.action = XFRM_POLICY_ALLOW;
- if (policy == IPSEC_POLICY_DISCARD)
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+
+ family = that_client->addr.u.v4.sin_family;
+ shift = (family == AF_INET) ? 5 : 7;
+
+ req.u.p.sel.sport = portof(&this_client->addr);
+ req.u.p.sel.dport = portof(&that_client->addr);
+ req.u.p.sel.sport_mask = (req.u.p.sel.sport) ? ~0:0;
+ req.u.p.sel.dport_mask = (req.u.p.sel.dport) ? ~0:0;
+ ip2xfrm(&this_client->addr, &req.u.p.sel.saddr);
+ ip2xfrm(&that_client->addr, &req.u.p.sel.daddr);
+ req.u.p.sel.prefixlen_s = this_client->maskbits;
+ req.u.p.sel.prefixlen_d = that_client->maskbits;
+ req.u.p.sel.proto = transport_proto;
+ req.u.p.sel.family = family;
+
+ dir = XFRM_POLICY_OUT;
+ if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
{
- req.u.p.action = XFRM_POLICY_BLOCK;
+ dir = XFRM_POLICY_IN;
}
- req.u.p.lft.soft_use_expires_seconds = use_lifetime;
- req.u.p.lft.soft_byte_limit = XFRM_INF;
- req.u.p.lft.soft_packet_limit = XFRM_INF;
- req.u.p.lft.hard_byte_limit = XFRM_INF;
- req.u.p.lft.hard_packet_limit = XFRM_INF;
-
- req.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
- if (op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
+
+ if ((op & ERO_MASK) == ERO_DELETE)
{
- req.n.nlmsg_type = XFRM_MSG_UPDPOLICY;
+ req.u.id.dir = dir;
+ req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.id)));
}
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)));
- }
-
- if (policy == IPSEC_POLICY_IPSEC && (op & ERO_MASK) != ERO_DELETE)
- {
- struct rtattr *attr;
- struct xfrm_user_tmpl tmpl[4];
- int i;
-
- memset(tmpl, 0, sizeof(tmpl));
- for (i = 0; proto_info[i].proto; i++)
+ else
{
- tmpl[i].reqid = proto_info[i].reqid;
- tmpl[i].id.proto = proto_info[i].proto;
- tmpl[i].optional =
- proto_info[i].proto == IPPROTO_COMP && dir != XFRM_POLICY_OUT;
- tmpl[i].aalgos = tmpl[i].ealgos = tmpl[i].calgos = ~0;
- tmpl[i].mode =
- proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
-
- if (!tmpl[i].mode)
- {
- continue;
- }
-
- ip2xfrm(this_host, &tmpl[i].saddr);
- ip2xfrm(that_host, &tmpl[i].id.daddr);
+ int src, dst;
+
+ req.u.p.dir = dir;
+
+ src = req.u.p.sel.prefixlen_s;
+ dst = req.u.p.sel.prefixlen_d;
+ if (dir != XFRM_POLICY_OUT) {
+ src = req.u.p.sel.prefixlen_d;
+ dst = req.u.p.sel.prefixlen_s;
+ }
+ req.u.p.priority = MIN_SPD_PRIORITY
+ + (((2 << shift) - src) << shift)
+ + (2 << shift) - dst;
+
+ req.u.p.action = XFRM_POLICY_ALLOW;
+ if (policy == IPSEC_POLICY_DISCARD)
+ {
+ req.u.p.action = XFRM_POLICY_BLOCK;
+ }
+ req.u.p.lft.soft_use_expires_seconds = use_lifetime;
+ req.u.p.lft.soft_byte_limit = XFRM_INF;
+ req.u.p.lft.soft_packet_limit = XFRM_INF;
+ req.u.p.lft.hard_byte_limit = XFRM_INF;
+ req.u.p.lft.hard_packet_limit = XFRM_INF;
+
+ req.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
+ if (op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
+ {
+ req.n.nlmsg_type = XFRM_MSG_UPDPOLICY;
+ }
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)));
}
- attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
- attr->rta_type = XFRMA_TMPL;
- attr->rta_len = i * sizeof(tmpl[0]);
- memcpy(RTA_DATA(attr), tmpl, attr->rta_len);
- attr->rta_len = RTA_LENGTH(attr->rta_len);
- req.n.nlmsg_len += attr->rta_len;
- }
-
- enoent_ok = FALSE;
- if (op == ERO_DEL_INBOUND)
- {
- enoent_ok = TRUE;
- }
- else if (op == ERO_DELETE && ntohl(spi) == SPI_HOLD)
- {
- enoent_ok = TRUE;
- }
-
- ok = netlink_policy(&req.n, enoent_ok, text_said);
- switch (dir)
- {
- case XFRM_POLICY_IN:
- if (req.n.nlmsg_type == XFRM_MSG_DELPOLICY)
+ if (policy == IPSEC_POLICY_IPSEC && (op & ERO_MASK) != ERO_DELETE)
{
- req.u.id.dir = XFRM_POLICY_FWD;
+ struct rtattr *attr;
+ struct xfrm_user_tmpl tmpl[4];
+ int i;
+
+ memset(tmpl, 0, sizeof(tmpl));
+ for (i = 0; proto_info[i].proto; i++)
+ {
+ tmpl[i].reqid = proto_info[i].reqid;
+ tmpl[i].id.proto = proto_info[i].proto;
+ tmpl[i].optional =
+ proto_info[i].proto == IPPROTO_COMP && dir != XFRM_POLICY_OUT;
+ tmpl[i].aalgos = tmpl[i].ealgos = tmpl[i].calgos = ~0;
+ tmpl[i].mode =
+ proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
+
+ if (!tmpl[i].mode)
+ {
+ continue;
+ }
+
+ ip2xfrm(this_host, &tmpl[i].saddr);
+ ip2xfrm(that_host, &tmpl[i].id.daddr);
+ }
+
+ attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
+ attr->rta_type = XFRMA_TMPL;
+ attr->rta_len = i * sizeof(tmpl[0]);
+ memcpy(RTA_DATA(attr), tmpl, attr->rta_len);
+ attr->rta_len = RTA_LENGTH(attr->rta_len);
+ req.n.nlmsg_len += attr->rta_len;
}
- else if (!ok)
+
+ enoent_ok = FALSE;
+ if (op == ERO_DEL_INBOUND)
{
- break;
+ enoent_ok = TRUE;
}
- else if (proto_info[0].encapsulation != ENCAPSULATION_MODE_TUNNEL
- && satype != SADB_X_SATYPE_INT)
+ else if (op == ERO_DELETE && ntohl(spi) == SPI_HOLD)
{
- break;
+ enoent_ok = TRUE;
}
- else
+
+ ok = netlink_policy(&req.n, enoent_ok, text_said);
+ switch (dir)
{
- req.u.p.dir = XFRM_POLICY_FWD;
+ case XFRM_POLICY_IN:
+ if (req.n.nlmsg_type == XFRM_MSG_DELPOLICY)
+ {
+ req.u.id.dir = XFRM_POLICY_FWD;
+ }
+ else if (!ok)
+ {
+ break;
+ }
+ else if (proto_info[0].encapsulation != ENCAPSULATION_MODE_TUNNEL
+ && satype != SADB_X_SATYPE_INT)
+ {
+ break;
+ }
+ else
+ {
+ req.u.p.dir = XFRM_POLICY_FWD;
+ }
+ ok &= netlink_policy(&req.n, enoent_ok, text_said);
+ break;
}
- ok &= netlink_policy(&req.n, enoent_ok, text_said);
- break;
- }
- return ok;
+ return ok;
}
/** netlink_add_sa - Add an SA into the kernel SPDB via netlink
@@ -573,130 +571,130 @@ netlink_raw_eroute(const ip_address *this_host
static bool
netlink_add_sa(const struct kernel_sa *sa, bool replace)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_info p;
- char data[1024];
- } req;
- struct rtattr *attr;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.n.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
-
- ip2xfrm(sa->src, &req.p.saddr);
- ip2xfrm(sa->dst, &req.p.id.daddr);
-
- req.p.id.spi = sa->spi;
- req.p.id.proto = satype2proto(sa->satype);
- req.p.family = sa->src->u.v4.sin_family;
- req.p.mode = (sa->encapsulation == ENCAPSULATION_MODE_TUNNEL);
- req.p.replay_window = sa->replay_window;
- req.p.reqid = sa->reqid;
- req.p.lft.soft_byte_limit = XFRM_INF;
- req.p.lft.soft_packet_limit = XFRM_INF;
- req.p.lft.hard_byte_limit = XFRM_INF;
- req.p.lft.hard_packet_limit = XFRM_INF;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.p)));
-
- attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
-
- if (sa->authalg)
- {
- struct xfrm_algo algo;
- const char *name;
-
- name = sparse_name(aalg_list, sa->authalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown authentication algorithm: %u"
- , sa->authalg);
- return FALSE;
- }
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_info p;
+ char data[1024];
+ } req;
+ struct rtattr *attr;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ req.n.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
- strcpy(algo.alg_name, name);
- algo.alg_key_len = sa->authkeylen * BITS_PER_BYTE;
+ ip2xfrm(sa->src, &req.p.saddr);
+ ip2xfrm(sa->dst, &req.p.id.daddr);
- attr->rta_type = XFRMA_ALG_AUTH;
- attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->authkeylen);
+ req.p.id.spi = sa->spi;
+ req.p.id.proto = satype2proto(sa->satype);
+ req.p.family = sa->src->u.v4.sin_family;
+ req.p.mode = (sa->encapsulation == ENCAPSULATION_MODE_TUNNEL);
+ req.p.replay_window = sa->replay_window;
+ req.p.reqid = sa->reqid;
+ req.p.lft.soft_byte_limit = XFRM_INF;
+ req.p.lft.soft_packet_limit = XFRM_INF;
+ req.p.lft.hard_byte_limit = XFRM_INF;
+ req.p.lft.hard_packet_limit = XFRM_INF;
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->authkey
- , sa->authkeylen);
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.p)));
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
+
+ if (sa->authalg)
+ {
+ struct xfrm_algo algo;
+ const char *name;
- if (sa->encalg)
- {
- struct xfrm_algo algo;
- const char *name;
+ name = sparse_name(aalg_list, sa->authalg);
+ if (!name) {
+ loglog(RC_LOG_SERIOUS, "unknown authentication algorithm: %u"
+ , sa->authalg);
+ return FALSE;
+ }
- name = sparse_name(ealg_list, sa->encalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown encryption algorithm: %u"
- , sa->encalg);
- return FALSE;
+ strcpy(algo.alg_name, name);
+ algo.alg_key_len = sa->authkeylen * BITS_PER_BYTE;
+
+ attr->rta_type = XFRMA_ALG_AUTH;
+ attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->authkeylen);
+
+ memcpy(RTA_DATA(attr), &algo, sizeof(algo));
+ memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->authkey
+ , sa->authkeylen);
+
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
}
- strcpy(algo.alg_name, name);
- algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE;
+ if (sa->encalg)
+ {
+ struct xfrm_algo algo;
+ const char *name;
- attr->rta_type = XFRMA_ALG_CRYPT;
- attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen);
+ name = sparse_name(ealg_list, sa->encalg);
+ if (!name) {
+ loglog(RC_LOG_SERIOUS, "unknown encryption algorithm: %u"
+ , sa->encalg);
+ return FALSE;
+ }
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->enckey
- , sa->enckeylen);
+ strcpy(algo.alg_name, name);
+ algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE;
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ attr->rta_type = XFRMA_ALG_CRYPT;
+ attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen);
- if (sa->compalg)
- {
- struct xfrm_algo algo;
- const char *name;
+ memcpy(RTA_DATA(attr), &algo, sizeof(algo));
+ memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->enckey
+ , sa->enckeylen);
- name = sparse_name(calg_list, sa->compalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown compression algorithm: %u"
- , sa->compalg);
- return FALSE;
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
}
- strcpy(algo.alg_name, name);
- algo.alg_key_len = 0;
+ if (sa->compalg)
+ {
+ struct xfrm_algo algo;
+ const char *name;
- attr->rta_type = XFRMA_ALG_COMP;
- attr->rta_len = RTA_LENGTH(sizeof(algo));
+ name = sparse_name(calg_list, sa->compalg);
+ if (!name) {
+ loglog(RC_LOG_SERIOUS, "unknown compression algorithm: %u"
+ , sa->compalg);
+ return FALSE;
+ }
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
+ strcpy(algo.alg_name, name);
+ algo.alg_key_len = 0;
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ attr->rta_type = XFRMA_ALG_COMP;
+ attr->rta_len = RTA_LENGTH(sizeof(algo));
- if (sa->natt_type)
- {
- struct xfrm_encap_tmpl natt;
+ memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- natt.encap_type = sa->natt_type;
- natt.encap_sport = ntohs(sa->natt_sport);
- natt.encap_dport = ntohs(sa->natt_dport);
- memset (&natt.encap_oa, 0, sizeof (natt.encap_oa));
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
+ }
- attr->rta_type = XFRMA_ENCAP;
- attr->rta_len = RTA_LENGTH(sizeof(natt));
+ if (sa->natt_type)
+ {
+ struct xfrm_encap_tmpl natt;
+
+ natt.encap_type = sa->natt_type;
+ natt.encap_sport = ntohs(sa->natt_sport);
+ natt.encap_dport = ntohs(sa->natt_dport);
+ memset (&natt.encap_oa, 0, sizeof (natt.encap_oa));
- memcpy(RTA_DATA(attr), &natt, sizeof(natt));
+ attr->rta_type = XFRMA_ENCAP;
+ attr->rta_len = RTA_LENGTH(sizeof(natt));
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ memcpy(RTA_DATA(attr), &natt, sizeof(natt));
- return send_netlink_msg(&req.n, NULL, 0, "Add SA", sa->text_said);
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
+ }
+
+ return send_netlink_msg(&req.n, NULL, 0, "Add SA", sa->text_said);
}
/** netlink_del_sa - Delete an SA from the Kernel
@@ -707,113 +705,113 @@ netlink_add_sa(const struct kernel_sa *sa, bool replace)
static bool
netlink_del_sa(const struct kernel_sa *sa)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_id id;
- char data[1024];
- } req;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_id id;
+ char data[1024];
+ } req;
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.n.nlmsg_type = XFRM_MSG_DELSA;
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ req.n.nlmsg_type = XFRM_MSG_DELSA;
- ip2xfrm(sa->dst, &req.id.daddr);
+ ip2xfrm(sa->dst, &req.id.daddr);
- req.id.spi = sa->spi;
- req.id.family = sa->src->u.v4.sin_family;
- req.id.proto = sa->proto;
+ req.id.spi = sa->spi;
+ req.id.family = sa->src->u.v4.sin_family;
+ req.id.proto = sa->proto;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- return send_netlink_msg(&req.n, NULL, 0, "Del SA", sa->text_said);
+ return send_netlink_msg(&req.n, NULL, 0, "Del SA", sa->text_said);
}
static bool
netlink_error(const char *req_type, const struct nlmsghdr *n
, const struct nlmsgerr *e, int rsp_size)
{
- if (n->nlmsg_type == NLMSG_ERROR)
- {
- DBG(DBG_KLIPS,
- DBG_log("%s returned with errno %d: %s"
- , req_type
- , -e->error
- , strerror(-e->error))
- )
- return TRUE;
- }
- if (n->nlmsg_len < NLMSG_LENGTH(rsp_size))
- {
- plog("%s returned message with length %lu < %lu bytes"
- , req_type
- , (unsigned long) n->nlmsg_len
- , (unsigned long) rsp_size);
- return TRUE;
- }
- return FALSE;
+ if (n->nlmsg_type == NLMSG_ERROR)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("%s returned with errno %d: %s"
+ , req_type
+ , -e->error
+ , strerror(-e->error))
+ )
+ return TRUE;
+ }
+ if (n->nlmsg_len < NLMSG_LENGTH(rsp_size))
+ {
+ plog("%s returned message with length %lu < %lu bytes"
+ , req_type
+ , (unsigned long) n->nlmsg_len
+ , (unsigned long) rsp_size);
+ return TRUE;
+ }
+ return FALSE;
}
static bool
netlink_get_policy(const struct kernel_sa *sa, bool inbound, time_t *use_time)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_userpolicy_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_userpolicy_info info;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
-
- req.id.sel.sport = portof(&sa->src_client->addr);
- req.id.sel.dport = portof(&sa->dst_client->addr);
- req.id.sel.sport_mask = (req.id.sel.sport) ? ~0:0;
- req.id.sel.dport_mask = (req.id.sel.dport) ? ~0:0;
- ip2xfrm(&sa->src_client->addr, &req.id.sel.saddr);
- ip2xfrm(&sa->dst_client->addr, &req.id.sel.daddr);
- req.id.sel.prefixlen_s = sa->src_client->maskbits;
- req.id.sel.prefixlen_d = sa->dst_client->maskbits;
- req.id.sel.proto = sa->transport_proto;
- req.id.sel.family = sa->dst_client->addr.u.v4.sin_family;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
-
- req.id.dir = (inbound)? XFRM_POLICY_IN:XFRM_POLICY_OUT;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return FALSE;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userpolicy_id id;
+ } req;
+
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_userpolicy_info info;
+ } u;
+ char data[1024];
+ } rsp;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
+
+ req.id.sel.sport = portof(&sa->src_client->addr);
+ req.id.sel.dport = portof(&sa->dst_client->addr);
+ req.id.sel.sport_mask = (req.id.sel.sport) ? ~0:0;
+ req.id.sel.dport_mask = (req.id.sel.dport) ? ~0:0;
+ ip2xfrm(&sa->src_client->addr, &req.id.sel.saddr);
+ ip2xfrm(&sa->dst_client->addr, &req.id.sel.daddr);
+ req.id.sel.prefixlen_s = sa->src_client->maskbits;
+ req.id.sel.prefixlen_d = sa->dst_client->maskbits;
+ req.id.sel.proto = sa->transport_proto;
+ req.id.sel.family = sa->dst_client->addr.u.v4.sin_family;
+
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+ rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
+
+ req.id.dir = (inbound)? XFRM_POLICY_IN:XFRM_POLICY_OUT;
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
+ return FALSE;
+
+ if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
+ return FALSE;
- *use_time = (time_t)rsp.u.info.curlft.use_time;
+ *use_time = (time_t)rsp.u.info.curlft.use_time;
- if (inbound && sa->encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- time_t use_time_fwd;
+ if (inbound && sa->encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ {
+ time_t use_time_fwd;
- req.id.dir = XFRM_POLICY_FWD;
+ req.id.dir = XFRM_POLICY_FWD;
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return FALSE;
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
+ return FALSE;
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
+ if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
+ return FALSE;
- use_time_fwd = (time_t)rsp.u.info.curlft.use_time;
- *use_time = (*use_time > use_time_fwd)? *use_time : use_time_fwd;
- }
- return TRUE;
+ use_time_fwd = (time_t)rsp.u.info.curlft.use_time;
+ *use_time = (*use_time > use_time_fwd)? *use_time : use_time_fwd;
+ }
+ return TRUE;
}
@@ -825,60 +823,60 @@ netlink_get_policy(const struct kernel_sa *sa, bool inbound, time_t *use_time)
static bool
netlink_get_sa(const struct kernel_sa *sa, u_int *bytes)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_usersa_info info;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETSA;
-
- ip2xfrm(sa->dst, &req.id.daddr);
-
- req.id.spi = sa->spi;
- req.id.family = sa->src->u.v4.sin_family;
- req.id.proto = sa->proto;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SA", sa->text_said))
- return FALSE;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_id id;
+ } req;
- if (netlink_error("XFRM_MSG_GETSA", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_usersa_info info;
+ } u;
+ char data[1024];
+ } rsp;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_GETSA;
+
+ ip2xfrm(sa->dst, &req.id.daddr);
- *bytes = (u_int) rsp.u.info.curlft.bytes;
+ req.id.spi = sa->spi;
+ req.id.family = sa->src->u.v4.sin_family;
+ req.id.proto = sa->proto;
- return TRUE;
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+ rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
+
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SA", sa->text_said))
+ return FALSE;
+
+ if (netlink_error("XFRM_MSG_GETSA", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
+ return FALSE;
+
+ *bytes = (u_int) rsp.u.info.curlft.bytes;
+
+ return TRUE;
}
static void
linux_pfkey_register_response(const struct sadb_msg *msg)
{
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_ESP:
+ switch (msg->sadb_msg_satype)
+ {
+ case SADB_SATYPE_ESP:
#ifndef NO_KERNEL_ALG
- kernel_alg_register_pfkey(msg, msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
+ kernel_alg_register_pfkey(msg, msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
#endif
- break;
- case SADB_X_SATYPE_IPCOMP:
- can_do_IPcomp = TRUE;
- break;
- default:
- break;
- }
+ break;
+ case SADB_X_SATYPE_IPCOMP:
+ can_do_IPcomp = TRUE;
+ break;
+ default:
+ break;
+ }
}
/** linux_pfkey_register - Register via PFKEY our capabilities
@@ -887,10 +885,10 @@ linux_pfkey_register_response(const struct sadb_msg *msg)
static void
linux_pfkey_register(void)
{
- pfkey_register_proto(SADB_SATYPE_AH, "AH");
- pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
- pfkey_register_proto(SADB_X_SATYPE_IPCOMP, "IPCOMP");
- pfkey_close();
+ pfkey_register_proto(SADB_SATYPE_AH, "AH");
+ pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
+ pfkey_register_proto(SADB_X_SATYPE_IPCOMP, "IPCOMP");
+ pfkey_close();
}
/** Create ip_address out of xfrm_address_t.
@@ -903,18 +901,18 @@ linux_pfkey_register(void)
static err_t
xfrm_to_ip_address(unsigned family, const xfrm_address_t *src, ip_address *dst)
{
- switch (family)
- {
- case AF_INET: /* IPv4 */
- case AF_UNSPEC: /* Unspecified, we assume IPv4 */
- initaddr((const void *) &src->a4, sizeof(src->a4), AF_INET, dst);
- return NULL;
- case AF_INET6: /* IPv6 */
- initaddr((const void *) &src->a6, sizeof(src->a6), AF_INET6, dst);
- return NULL;
- default:
- return "unknown address family";
- }
+ switch (family)
+ {
+ case AF_INET: /* IPv4 */
+ case AF_UNSPEC: /* Unspecified, we assume IPv4 */
+ initaddr((const void *) &src->a4, sizeof(src->a4), AF_INET, dst);
+ return NULL;
+ case AF_INET6: /* IPv6 */
+ initaddr((const void *) &src->a6, sizeof(src->a6), AF_INET6, dst);
+ return NULL;
+ default:
+ return "unknown address family";
+ }
}
/* Create a pair of ip_address's out of xfrm_sel.
@@ -926,29 +924,29 @@ xfrm_to_ip_address(unsigned family, const xfrm_address_t *src, ip_address *dst)
*/
static err_t
xfrm_sel_to_ip_pair(const struct xfrm_selector *sel
- , ip_address *src
- , ip_address *dst)
+ , ip_address *src
+ , ip_address *dst)
{
- int family;
- err_t ugh;
-
- family = sel->family;
-
- if ((ugh = xfrm_to_ip_address(family, &sel->saddr, src))
- || (ugh = xfrm_to_ip_address(family, &sel->daddr, dst)))
- return ugh;
-
- /* family has been verified in xfrm_to_ip_address. */
- if (family == AF_INET)
- {
- src->u.v4.sin_port = sel->sport;
- dst->u.v4.sin_port = sel->dport;
- }
- else
- {
- src->u.v6.sin6_port = sel->sport;
- dst->u.v6.sin6_port = sel->dport;
- }
+ int family;
+ err_t ugh;
+
+ family = sel->family;
+
+ if ((ugh = xfrm_to_ip_address(family, &sel->saddr, src))
+ || (ugh = xfrm_to_ip_address(family, &sel->daddr, dst)))
+ return ugh;
+
+ /* family has been verified in xfrm_to_ip_address. */
+ if (family == AF_INET)
+ {
+ src->u.v4.sin_port = sel->sport;
+ dst->u.v4.sin_port = sel->dport;
+ }
+ else
+ {
+ src->u.v6.sin6_port = sel->sport;
+ dst->u.v6.sin6_port = sel->dport;
+ }
return NULL;
}
@@ -956,194 +954,194 @@ xfrm_sel_to_ip_pair(const struct xfrm_selector *sel
static void
netlink_acquire(struct nlmsghdr *n)
{
- struct xfrm_user_acquire *acquire;
- ip_address src, dst;
- ip_subnet ours, his;
- unsigned transport_proto;
- err_t ugh = NULL;
-
- if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire)))
- {
- plog("netlink_acquire got message with length %lu < %lu bytes; ignore message"
- , (unsigned long) n->nlmsg_len
- , (unsigned long) sizeof(*acquire));
- return;
- }
-
- acquire = NLMSG_DATA(n);
- transport_proto = acquire->sel.proto;
-
- /* XXX also the type of src/dst should be checked to make sure
- * that they aren't v4 to v6 or something goofy
- */
-
- if (!(ugh = xfrm_sel_to_ip_pair(&acquire->sel, &src, &dst))
- && !(ugh = addrtosubnet(&src, &ours))
- && !(ugh = addrtosubnet(&dst, &his)))
- record_and_initiate_opportunistic(&ours, &his, transport_proto
- , "%acquire-netlink");
-
- if (ugh != NULL)
- plog("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh);
+ struct xfrm_user_acquire *acquire;
+ ip_address src, dst;
+ ip_subnet ours, his;
+ unsigned transport_proto;
+ err_t ugh = NULL;
+
+ if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire)))
+ {
+ plog("netlink_acquire got message with length %lu < %lu bytes; ignore message"
+ , (unsigned long) n->nlmsg_len
+ , (unsigned long) sizeof(*acquire));
+ return;
+ }
+
+ acquire = NLMSG_DATA(n);
+ transport_proto = acquire->sel.proto;
+
+ /* XXX also the type of src/dst should be checked to make sure
+ * that they aren't v4 to v6 or something goofy
+ */
+
+ if (!(ugh = xfrm_sel_to_ip_pair(&acquire->sel, &src, &dst))
+ && !(ugh = addrtosubnet(&src, &ours))
+ && !(ugh = addrtosubnet(&dst, &his)))
+ record_and_initiate_opportunistic(&ours, &his, transport_proto
+ , "%acquire-netlink");
+
+ if (ugh != NULL)
+ plog("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh);
}
static void
netlink_shunt_expire(struct xfrm_userpolicy_info *pol)
{
- ip_address src, dst;
- unsigned transport_proto;
- err_t ugh = NULL;
-
- transport_proto = pol->sel.proto;
-
- if (!(ugh = xfrm_sel_to_ip_pair(&pol->sel, &src, &dst)))
- {
- plog("XFRM_MSG_POLEXPIRE message from kernel malformed: %s", ugh);
- return;
- }
-
- replace_bare_shunt(&src, &dst, BOTTOM_PRIO, SPI_PASS, FALSE, transport_proto
- , "delete expired bare shunt");
+ ip_address src, dst;
+ unsigned transport_proto;
+ err_t ugh = NULL;
+
+ transport_proto = pol->sel.proto;
+
+ if (!(ugh = xfrm_sel_to_ip_pair(&pol->sel, &src, &dst)))
+ {
+ plog("XFRM_MSG_POLEXPIRE message from kernel malformed: %s", ugh);
+ return;
+ }
+
+ replace_bare_shunt(&src, &dst, BOTTOM_PRIO, SPI_PASS, FALSE, transport_proto
+ , "delete expired bare shunt");
}
static void
netlink_policy_expire(struct nlmsghdr *n)
{
- struct xfrm_user_polexpire *upe;
- struct {
- struct nlmsghdr n;
- struct xfrm_userpolicy_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_userpolicy_info pol;
- } u;
- char data[1024];
- } rsp;
-
- if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*upe)))
- {
- plog("netlink_policy_expire got message with length %lu < %lu bytes; ignore message"
- , (unsigned long) n->nlmsg_len
- , (unsigned long) sizeof(*upe));
- return;
- }
-
- upe = NLMSG_DATA(n);
- req.id.dir = upe->pol.dir;
- req.id.index = upe->pol.index;
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
-
- rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return;
-
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.pol)))
- return;
-
- if (req.id.index != rsp.u.pol.index)
- {
- DBG(DBG_KLIPS,
- DBG_log("netlink_policy_expire: policy was replaced: "
- "dir=%d, oldindex=%d, newindex=%d"
- , req.id.dir, req.id.index, rsp.u.pol.index));
- return;
- }
-
- if (upe->pol.curlft.add_time != rsp.u.pol.curlft.add_time)
- {
- DBG(DBG_KLIPS,
- DBG_log("netlink_policy_expire: policy was replaced "
- " and you have won the lottery: "
- "dir=%d, index=%d"
- , req.id.dir, req.id.index));
- return;
- }
-
- switch (upe->pol.dir)
- {
- case XFRM_POLICY_OUT:
- netlink_shunt_expire(&rsp.u.pol);
- break;
- }
+ struct xfrm_user_polexpire *upe;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userpolicy_id id;
+ } req;
+
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_userpolicy_info pol;
+ } u;
+ char data[1024];
+ } rsp;
+
+ if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*upe)))
+ {
+ plog("netlink_policy_expire got message with length %lu < %lu bytes; ignore message"
+ , (unsigned long) n->nlmsg_len
+ , (unsigned long) sizeof(*upe));
+ return;
+ }
+
+ upe = NLMSG_DATA(n);
+ req.id.dir = upe->pol.dir;
+ req.id.index = upe->pol.index;
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+
+ rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
+
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
+ return;
+
+ if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.pol)))
+ return;
+
+ if (req.id.index != rsp.u.pol.index)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_policy_expire: policy was replaced: "
+ "dir=%d, oldindex=%d, newindex=%d"
+ , req.id.dir, req.id.index, rsp.u.pol.index));
+ return;
+ }
+
+ if (upe->pol.curlft.add_time != rsp.u.pol.curlft.add_time)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_policy_expire: policy was replaced "
+ " and you have won the lottery: "
+ "dir=%d, index=%d"
+ , req.id.dir, req.id.index));
+ return;
+ }
+
+ switch (upe->pol.dir)
+ {
+ case XFRM_POLICY_OUT:
+ netlink_shunt_expire(&rsp.u.pol);
+ break;
+ }
}
static bool
netlink_get(void)
{
- struct {
- struct nlmsghdr n;
- char data[1024];
- } rsp;
- ssize_t r;
- struct sockaddr_nl addr;
- socklen_t alen;
-
- alen = sizeof(addr);
- r = recvfrom(netlink_bcast_fd, &rsp, sizeof(rsp), 0
- , (struct sockaddr *)&addr, &alen);
- if (r < 0)
- {
- if (errno == EAGAIN)
- return FALSE;
- if (errno != EINTR)
- log_errno((e, "recvfrom() failed in netlink_get"));
- return TRUE;
- }
- else if ((size_t) r < sizeof(rsp.n))
- {
- plog("netlink_get read truncated message: %ld bytes; ignore message"
- , (long) r);
- return TRUE;
- }
- else if (addr.nl_pid != 0)
- {
- /* not for us: ignore */
+ struct {
+ struct nlmsghdr n;
+ char data[1024];
+ } rsp;
+ ssize_t r;
+ struct sockaddr_nl addr;
+ socklen_t alen;
+
+ alen = sizeof(addr);
+ r = recvfrom(netlink_bcast_fd, &rsp, sizeof(rsp), 0
+ , (struct sockaddr *)&addr, &alen);
+ if (r < 0)
+ {
+ if (errno == EAGAIN)
+ return FALSE;
+ if (errno != EINTR)
+ log_errno((e, "recvfrom() failed in netlink_get"));
+ return TRUE;
+ }
+ else if ((size_t) r < sizeof(rsp.n))
+ {
+ plog("netlink_get read truncated message: %ld bytes; ignore message"
+ , (long) r);
+ return TRUE;
+ }
+ else if (addr.nl_pid != 0)
+ {
+ /* not for us: ignore */
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_get: ignoring %s message from process %u"
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
+ , addr.nl_pid));
+ return TRUE;
+ }
+ else if ((size_t) r != rsp.n.nlmsg_len)
+ {
+ plog("netlink_get read message with length %ld that doesn't equal nlmsg_len %lu bytes; ignore message"
+ , (long) r
+ , (unsigned long) rsp.n.nlmsg_len);
+ return TRUE;
+ }
+
DBG(DBG_KLIPS,
- DBG_log("netlink_get: ignoring %s message from process %u"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
- , addr.nl_pid));
- return TRUE;
- }
- else if ((size_t) r != rsp.n.nlmsg_len)
- {
- plog("netlink_get read message with length %ld that doesn't equal nlmsg_len %lu bytes; ignore message"
- , (long) r
- , (unsigned long) rsp.n.nlmsg_len);
+ DBG_log("netlink_get: %s message"
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
+
+ switch (rsp.n.nlmsg_type)
+ {
+ case XFRM_MSG_ACQUIRE:
+ netlink_acquire(&rsp.n);
+ break;
+ case XFRM_MSG_POLEXPIRE:
+ netlink_policy_expire(&rsp.n);
+ break;
+ default:
+ /* ignored */
+ break;
+ }
+
return TRUE;
- }
-
- DBG(DBG_KLIPS,
- DBG_log("netlink_get: %s message"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
-
- switch (rsp.n.nlmsg_type)
- {
- case XFRM_MSG_ACQUIRE:
- netlink_acquire(&rsp.n);
- break;
- case XFRM_MSG_POLEXPIRE:
- netlink_policy_expire(&rsp.n);
- break;
- default:
- /* ignored */
- break;
- }
-
- return TRUE;
}
static void
netlink_process_msg(void)
{
- while (netlink_get())
- ;
+ while (netlink_get())
+ ;
}
static ipsec_spi_t
@@ -1156,65 +1154,65 @@ netlink_get_spi(const ip_address *src
, ipsec_spi_t max
, const char *text_said)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_userspi_info spi;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_usersa_info sa;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
-
- ip2xfrm(src, &req.spi.info.saddr);
- ip2xfrm(dst, &req.spi.info.id.daddr);
- req.spi.info.mode = tunnel_mode;
- req.spi.info.reqid = reqid;
- req.spi.info.id.proto = proto;
- req.spi.info.family = src->u.v4.sin_family;
- req.spi.min = min;
- req.spi.max = max;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.spi)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SPI", text_said))
- return 0;
-
- if (netlink_error("XFRM_MSG_ALLOCSPI", &rsp.n, &rsp.u.e, sizeof(rsp.u.sa)))
- return 0;
-
- DBG(DBG_KLIPS,
- DBG_log("netlink_get_spi: allocated 0x%x for %s"
- , ntohl(rsp.u.sa.id.spi), text_said));
- return rsp.u.sa.id.spi;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userspi_info spi;
+ } req;
+
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_usersa_info sa;
+ } u;
+ char data[1024];
+ } rsp;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
+
+ ip2xfrm(src, &req.spi.info.saddr);
+ ip2xfrm(dst, &req.spi.info.id.daddr);
+ req.spi.info.mode = tunnel_mode;
+ req.spi.info.reqid = reqid;
+ req.spi.info.id.proto = proto;
+ req.spi.info.family = src->u.v4.sin_family;
+ req.spi.min = min;
+ req.spi.max = max;
+
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.spi)));
+ rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
+
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SPI", text_said))
+ return 0;
+
+ if (netlink_error("XFRM_MSG_ALLOCSPI", &rsp.n, &rsp.u.e, sizeof(rsp.u.sa)))
+ return 0;
+
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_get_spi: allocated 0x%x for %s"
+ , ntohl(rsp.u.sa.id.spi), text_said));
+ return rsp.u.sa.id.spi;
}
const struct kernel_ops linux_kernel_ops = {
- type: KERNEL_TYPE_LINUX,
- inbound_eroute: 1,
- policy_lifetime: 1,
- async_fdp: &netlink_bcast_fd,
-
- init: init_netlink,
- pfkey_register: linux_pfkey_register,
- pfkey_register_response: linux_pfkey_register_response,
- process_msg: netlink_process_msg,
- raw_eroute: netlink_raw_eroute,
- get_policy: netlink_get_policy,
- add_sa: netlink_add_sa,
- del_sa: netlink_del_sa,
- get_sa: netlink_get_sa,
- process_queue: NULL,
- grp_sa: NULL,
- get_spi: netlink_get_spi,
+ type: KERNEL_TYPE_LINUX,
+ inbound_eroute: 1,
+ policy_lifetime: 1,
+ async_fdp: &netlink_bcast_fd,
+
+ init: init_netlink,
+ pfkey_register: linux_pfkey_register,
+ pfkey_register_response: linux_pfkey_register_response,
+ process_msg: netlink_process_msg,
+ raw_eroute: netlink_raw_eroute,
+ get_policy: netlink_get_policy,
+ add_sa: netlink_add_sa,
+ del_sa: netlink_del_sa,
+ get_sa: netlink_get_sa,
+ process_queue: NULL,
+ grp_sa: NULL,
+ get_spi: netlink_get_spi,
};
#endif /* linux && KLIPS */