parent
58448edb48
commit
34d0f3e173
@ -1,4 +1,4 @@
|
|||||||
SOURCES/ikev1_dsa.fax.bz2
|
SOURCES/ikev1_dsa.fax.bz2
|
||||||
SOURCES/ikev1_psk.fax.bz2
|
SOURCES/ikev1_psk.fax.bz2
|
||||||
SOURCES/ikev2.fax.bz2
|
SOURCES/ikev2.fax.bz2
|
||||||
SOURCES/libreswan-4.12.tar.gz
|
SOURCES/libreswan-4.15.tar.gz
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
b35cd50b8bc0a08b9c07713bf19c72d53bfe66bb SOURCES/ikev1_dsa.fax.bz2
|
b35cd50b8bc0a08b9c07713bf19c72d53bfe66bb SOURCES/ikev1_dsa.fax.bz2
|
||||||
861d97bf488f9e296cad8c43ab72f111a5b1a848 SOURCES/ikev1_psk.fax.bz2
|
861d97bf488f9e296cad8c43ab72f111a5b1a848 SOURCES/ikev1_psk.fax.bz2
|
||||||
fcaf77f3deae3d8e99cdb3b1f8abea63167a0633 SOURCES/ikev2.fax.bz2
|
fcaf77f3deae3d8e99cdb3b1f8abea63167a0633 SOURCES/ikev2.fax.bz2
|
||||||
786c14a4755311ea3103683a3294e1536b1e44a6 SOURCES/libreswan-4.12.tar.gz
|
861eaeefff1c2f3862a8bfe0295b3e307f8e3055 SOURCES/libreswan-4.15.tar.gz
|
||||||
|
@ -0,0 +1,153 @@
|
|||||||
|
From 4f2af7c8c3afaaa63e8e16467de3441622a5314d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daiki Ueno <dueno@redhat.com>
|
||||||
|
Date: Tue, 21 May 2024 20:12:17 +0900
|
||||||
|
Subject: [PATCH] kernel_xfrm: record extended ack from netlink response
|
||||||
|
|
||||||
|
This enables pluto to log any error message reported through extended
|
||||||
|
ACK attributes[1] in a netlink response, to make diagnostic easier
|
||||||
|
when an error occurs. Suggested by Sabrina Dubroca.
|
||||||
|
|
||||||
|
1. https://docs.kernel.org/userspace-api/netlink/intro.html#ext-ack
|
||||||
|
|
||||||
|
Signed-off-by: Daiki Ueno <dueno@redhat.com>
|
||||||
|
Signed-off-by: Andrew Cagney <cagney@gnu.org>
|
||||||
|
---
|
||||||
|
include/netlink_attrib.h | 4 +++
|
||||||
|
lib/libswan/netlink_attrib.c | 29 +++++++++++++++++++++
|
||||||
|
programs/pluto/kernel_xfrm.c | 49 ++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 82 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/include/netlink_attrib.h b/include/netlink_attrib.h
|
||||||
|
index 4c952ae3e9..fff35d83f1 100644
|
||||||
|
--- a/include/netlink_attrib.h
|
||||||
|
+++ b/include/netlink_attrib.h
|
||||||
|
@@ -46,4 +46,8 @@ void nl_addattrstrz(struct nlmsghdr *n, int maxlen, int type,
|
||||||
|
const char *str);
|
||||||
|
void nl_addattr32(struct nlmsghdr *n, int maxlen, int type, const uint32_t data);
|
||||||
|
|
||||||
|
+const struct nlattr *nl_getattr(const struct nlmsghdr *n, size_t *offset);
|
||||||
|
+const char *nl_getattrvalstrz(const struct nlmsghdr *n,
|
||||||
|
+ const struct nlattr *attr);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/lib/libswan/netlink_attrib.c b/lib/libswan/netlink_attrib.c
|
||||||
|
index 34bb4bec83..ccc08cba8f 100644
|
||||||
|
--- a/lib/libswan/netlink_attrib.c
|
||||||
|
+++ b/lib/libswan/netlink_attrib.c
|
||||||
|
@@ -66,3 +66,32 @@ void nl_addattr32(struct nlmsghdr *n, int maxlen, int type, const uint32_t data)
|
||||||
|
{
|
||||||
|
nl_addattr_l(n, maxlen, type, &data, sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+const struct nlattr *nl_getattr(const struct nlmsghdr *n, size_t *offset)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *attr = (void *)n + NLMSG_HDRLEN + NLMSG_ALIGN(*offset);
|
||||||
|
+ struct nlattr *tail = (void *)n + NLMSG_ALIGN(n->nlmsg_len);
|
||||||
|
+
|
||||||
|
+ if (attr == tail) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *offset += NLA_ALIGN(attr->nla_len);
|
||||||
|
+ return attr;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const char *nl_getattrvalstrz(const struct nlmsghdr *n,
|
||||||
|
+ const struct nlattr *attr)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *tail = (void *)n + NLMSG_ALIGN(n->nlmsg_len);
|
||||||
|
+
|
||||||
|
+ ptrdiff_t len = (void *)tail - (void *)attr;
|
||||||
|
+ if (len < (ptrdiff_t)sizeof(struct nlattr) ||
|
||||||
|
+ attr->nla_len <= sizeof(struct nlattr) ||
|
||||||
|
+ attr->nla_len > len ||
|
||||||
|
+ !memchr(attr + NLA_HDRLEN, '\0', attr->nla_len - NLA_HDRLEN)) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (void *)attr + NLA_HDRLEN;
|
||||||
|
+}
|
||||||
|
diff --git a/programs/pluto/kernel_xfrm.c b/programs/pluto/kernel_xfrm.c
|
||||||
|
index eed307f42b..25d1b16bc9 100644
|
||||||
|
--- a/programs/pluto/kernel_xfrm.c
|
||||||
|
+++ b/programs/pluto/kernel_xfrm.c
|
||||||
|
@@ -260,6 +260,22 @@ static void init_netlink(struct logger *logger)
|
||||||
|
"socket() in init_netlink()");
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef SOL_NETLINK
|
||||||
|
+ const int on = true;
|
||||||
|
+ if (setsockopt(nl_send_fd, SOL_NETLINK, NETLINK_CAP_ACK,
|
||||||
|
+ (const void *)&on, sizeof(on)) < 0) {
|
||||||
|
+ llog_errno(RC_LOG, logger, errno, "xfrm: setsockopt(NETLINK_CAP_ACK) failed: ");
|
||||||
|
+ } else {
|
||||||
|
+ ldbg(logger, "xfrm: setsockopt(NETLINK_CAP_ACK) ok");
|
||||||
|
+ }
|
||||||
|
+ if (setsockopt(nl_send_fd, SOL_NETLINK, NETLINK_EXT_ACK,
|
||||||
|
+ (const void *)&on, sizeof(on)) < 0) {
|
||||||
|
+ llog_errno(RC_LOG, logger, errno, "xfrm: setsockopt(NETLINK_EXT_ACK) failed: ");
|
||||||
|
+ } else {
|
||||||
|
+ ldbg(logger, "xfrm: setsockopt(NETLINK_EXT_ACK) ok");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
nl_xfrm_fd = cloexec_socket(AF_NETLINK, SOCK_DGRAM|SOCK_NONBLOCK, NETLINK_XFRM);
|
||||||
|
if (nl_xfrm_fd < 0) {
|
||||||
|
fatal_errno(PLUTO_EXIT_FAIL, logger, errno,
|
||||||
|
@@ -301,6 +317,37 @@ static void init_netlink(struct logger *logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void llog_ext_ack(lset_t rc_flags, struct logger *logger,
|
||||||
|
+ const struct nlmsghdr *n)
|
||||||
|
+{
|
||||||
|
+#ifdef SOL_NETLINK
|
||||||
|
+ if (n->nlmsg_type != NLMSG_ERROR ||
|
||||||
|
+ !(n->nlmsg_flags & NLM_F_ACK_TLVS)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct nlmsgerr *err = (void *)n + NLMSG_HDRLEN;
|
||||||
|
+ size_t offset = sizeof(*err);
|
||||||
|
+ if (!(n->nlmsg_flags & NLM_F_CAPPED)) {
|
||||||
|
+ offset += err->msg.nlmsg_len - NLMSG_HDRLEN;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (const struct nlattr *attr = nl_getattr(n, &offset);
|
||||||
|
+ attr != NULL; attr = nl_getattr(n, &offset)) {
|
||||||
|
+ if ((attr->nla_type & NLA_TYPE_MASK) == NLMSGERR_ATTR_MSG) {
|
||||||
|
+ const char *msg = nl_getattrvalstrz(n, attr);
|
||||||
|
+ if (msg) {
|
||||||
|
+ llog(rc_flags, logger, "netlink ext_ack: %s",
|
||||||
|
+ msg);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
+ /* use the arguments */
|
||||||
|
+ ldbg(logger, "ignoring "PRI_LSET" %p", rc_flags, n);
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* sendrecv_xfrm_msg()
|
||||||
|
*
|
||||||
|
@@ -403,6 +450,7 @@ static bool sendrecv_xfrm_msg(struct nlmsghdr *hdr,
|
||||||
|
if (rsp.u.e.error != 0) {
|
||||||
|
llog_error(logger, -rsp.u.e.error,
|
||||||
|
"netlink response for %s %s", description, story);
|
||||||
|
+ llog_ext_ack(RC_LOG, logger, &rsp.n);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
@@ -413,6 +461,7 @@ static bool sendrecv_xfrm_msg(struct nlmsghdr *hdr,
|
||||||
|
*/
|
||||||
|
dbg("netlink response for %s %s included non-error error",
|
||||||
|
description, story);
|
||||||
|
+ llog_ext_ack(DEBUG_STREAM, logger, &rsp.n);
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
if (rbuf == NULL) {
|
||||||
|
--
|
||||||
|
2.45.2
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
From 0b91406427cf7292d61900991fd665f076b6d43f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daiki Ueno <dueno@redhat.com>
|
||||||
|
Date: Tue, 2 Jul 2024 20:37:07 +0900
|
||||||
|
Subject: [PATCH] tcp: call kernel_ops->poke_ipsec_policy_hole before connect
|
||||||
|
|
||||||
|
This fixes ondemand initiation with TCP. Without the policy hole, a
|
||||||
|
TCP handshake will not complete, as it cannot receive SYN-ACK packet
|
||||||
|
in plaintext and thus connect blocks until timeout.
|
||||||
|
|
||||||
|
Signed-off-by: Daiki Ueno <dueno@redhat.com>
|
||||||
|
Signed-off-by: Andrew Cagney <cagney@gnu.org>
|
||||||
|
---
|
||||||
|
programs/pluto/iface_tcp.c | 16 +++++++++-------
|
||||||
|
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/programs/pluto/iface_tcp.c b/programs/pluto/iface_tcp.c
|
||||||
|
index c63e8bfe4d..55fe639174 100644
|
||||||
|
--- a/programs/pluto/iface_tcp.c
|
||||||
|
+++ b/programs/pluto/iface_tcp.c
|
||||||
|
@@ -473,6 +473,15 @@ struct iface_endpoint *connect_to_tcp_endpoint(struct iface_dev *local_dev,
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* This needs to be called before connect, so TCP handshake
|
||||||
|
+ * (in plaintext) completes. */
|
||||||
|
+ if (kernel_ops->poke_ipsec_policy_hole != NULL &&
|
||||||
|
+ !kernel_ops->poke_ipsec_policy_hole(fd, afi, logger)) {
|
||||||
|
+ /* already logged */
|
||||||
|
+ close(fd);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Connect
|
||||||
|
*
|
||||||
|
@@ -551,13 +560,6 @@ struct iface_endpoint *connect_to_tcp_endpoint(struct iface_dev *local_dev,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (kernel_ops->poke_ipsec_policy_hole != NULL &&
|
||||||
|
- !kernel_ops->poke_ipsec_policy_hole(fd, afi, logger)) {
|
||||||
|
- /* already logged */
|
||||||
|
- close(fd);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
struct iface_endpoint *ifp =
|
||||||
|
alloc_iface_endpoint(fd, local_dev, &iketcp_iface_io,
|
||||||
|
/*esp_encapsulation_enabled*/true,
|
||||||
|
--
|
||||||
|
2.45.2
|
||||||
|
|
Loading…
Reference in new issue