From 1c8b8ac9e44aa7f187906255f7873501fc6aa5d4 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Tue, 6 Aug 2024 11:34:28 +0900 Subject: [PATCH] Make use of Netlink extack for additional error reporting Resolves: RHEL-51881 Signed-off-by: Daiki Ueno --- libreswan-4.15-netlink-extack.patch | 153 ++++++++++++++++++++++++++++ libreswan.spec | 2 + 2 files changed, 155 insertions(+) create mode 100644 libreswan-4.15-netlink-extack.patch diff --git a/libreswan-4.15-netlink-extack.patch b/libreswan-4.15-netlink-extack.patch new file mode 100644 index 0000000..92cf5e7 --- /dev/null +++ b/libreswan-4.15-netlink-extack.patch @@ -0,0 +1,153 @@ +From 4f2af7c8c3afaaa63e8e16467de3441622a5314d Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +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 +Signed-off-by: Andrew Cagney +--- + 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 + diff --git a/libreswan.spec b/libreswan.spec index 3c6c925..c8acb10 100644 --- a/libreswan.spec +++ b/libreswan.spec @@ -42,6 +42,7 @@ Source3: https://download.libreswan.org/cavs/ikev2.fax.bz2 %endif Patch: libreswan-4.6-ikev1-policy-defaults-to-drop.patch Patch: libreswan-4.15-ondemand-tcp.patch +Patch: libreswan-4.15-netlink-extack.patch BuildRequires: audit-libs-devel BuildRequires: bison @@ -199,6 +200,7 @@ certutil -N -d sql:$tmpdir --empty-password %changelog * Tue Aug 6 2024 Daiki Ueno - 4.15-2 - Fix auto=ondemand connection initialization with TCP (RHEL-51879) +- Make use of Netlink extack for additional error reporting (RHEL-51881) * Tue Jul 30 2024 Daiki Ueno - 4.15-1 - Update to 4.15 (RHEL-50006)