(this->sa_lastused ? KERNEL_SA_USE_TIME : 0);
}
+/**
+ * Format the mark for debug messages
+ */
+static void format_mark(char *buf, int buflen, mark_t mark)
+{
+ if (mark.value | mark.mask)
+ {
+ snprintf(buf, buflen, " (mark %u/0x%08x)", mark.value, mark.mask);
+ }
+}
+
+/**
+ * Add a XFRM mark to message if required
+ */
+static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark)
+{
+ if (mark.value | mark.mask)
+ {
+ struct xfrm_mark *xmrk;
+
+ xmrk = netlink_reserve(hdr, buflen, XFRMA_MARK, sizeof(*xmrk));
+ if (!xmrk)
+ {
+ return FALSE;
+ }
+ xmrk->v = mark.value;
+ xmrk->m = mark.mask;
+ }
+ return TRUE;
+}
+
+/**
+ * Format the security label for debug messages
+ */
+static void format_label(char *buf, int buflen, sec_label_t *label)
+{
+ if (label)
+ {
+ snprintf(buf, buflen, " (ctx %s)", label->get_string(label));
+ }
+}
+
+/**
+ * Add a security label to message if required
+ */
+static bool add_label(struct nlmsghdr *hdr, int buflen, sec_label_t *label)
+{
+ if (label)
+ {
+#ifdef USE_SELINUX
+ struct xfrm_user_sec_ctx *ctx;
+ chunk_t enc = label->get_encoding(label);
+ int len = sizeof(*ctx) + enc.len;
+
+ ctx = netlink_reserve(hdr, buflen, XFRMA_SEC_CTX, len);
+ if (!ctx)
+ {
+ return FALSE;
+ }
+ /* this attribute for some reason duplicates the generic header */
+ ctx->exttype = XFRMA_SEC_CTX;
+ ctx->len = len;
+
+ ctx->ctx_doi = XFRM_SC_DOI_LSM;
+ ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
+ ctx->ctx_len = enc.len;
+ memcpy((void*)(ctx + 1), enc.ptr, enc.len);
+#endif
+ }
+ return TRUE;
+}
+
+/**
+ * Add a uint32 attribute to message
+ */
+static bool add_uint32(struct nlmsghdr *hdr, int buflen,
+ enum xfrm_attr_type_t type, uint32_t value)
+{
+ uint32_t *xvalue;
+
+ xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue));
+ if (!xvalue)
+ {
+ return FALSE;
+ }
+ *xvalue = value;
+ return TRUE;
+}
+
+/**
+ * Add a uint8 attribute to message
+ */
+static bool add_uint8(struct nlmsghdr *hdr, int buflen,
+ enum xfrm_attr_type_t type, uint8_t value)
+{
+ uint8_t *xvalue;
+
+ xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue));
+ if (!xvalue)
+ {
+ return FALSE;
+ }
+ *xvalue = value;
+ return TRUE;
+}
+
/**
* Get an SPI for a specific protocol from the kernel.
*/
userspi->min = min;
userspi->max = max;
+ if (!add_uint8(hdr, sizeof(request), XFRMA_SA_DIR, XFRM_SA_DIR_IN))
+ {
+ return FAILED;
+ }
+
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
{
hdr = out;
return SUCCESS;
}
-/**
- * Format the mark for debug messages
- */
-static void format_mark(char *buf, int buflen, mark_t mark)
-{
- if (mark.value | mark.mask)
- {
- snprintf(buf, buflen, " (mark %u/0x%08x)", mark.value, mark.mask);
- }
-}
-
-/**
- * Add a XFRM mark to message if required
- */
-static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark)
-{
- if (mark.value | mark.mask)
- {
- struct xfrm_mark *xmrk;
-
- xmrk = netlink_reserve(hdr, buflen, XFRMA_MARK, sizeof(*xmrk));
- if (!xmrk)
- {
- return FALSE;
- }
- xmrk->v = mark.value;
- xmrk->m = mark.mask;
- }
- return TRUE;
-}
-
-/**
- * Format the security label for debug messages
- */
-static void format_label(char *buf, int buflen, sec_label_t *label)
-{
- if (label)
- {
- snprintf(buf, buflen, " (ctx %s)", label->get_string(label));
- }
-}
-
-/**
- * Add a security label to message if required
- */
-static bool add_label(struct nlmsghdr *hdr, int buflen, sec_label_t *label)
-{
- if (label)
- {
-#ifdef USE_SELINUX
- struct xfrm_user_sec_ctx *ctx;
- chunk_t enc = label->get_encoding(label);
- int len = sizeof(*ctx) + enc.len;
-
- ctx = netlink_reserve(hdr, buflen, XFRMA_SEC_CTX, len);
- if (!ctx)
- {
- return FALSE;
- }
- /* this attribute for some reason duplicates the generic header */
- ctx->exttype = XFRMA_SEC_CTX;
- ctx->len = len;
-
- ctx->ctx_doi = XFRM_SC_DOI_LSM;
- ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
- ctx->ctx_len = enc.len;
- memcpy((void*)(ctx + 1), enc.ptr, enc.len);
-#endif
- }
- return TRUE;
-}
-
-/**
- * Add a uint32 attribute to message
- */
-static bool add_uint32(struct nlmsghdr *hdr, int buflen,
- enum xfrm_attr_type_t type, uint32_t value)
-{
- uint32_t *xvalue;
-
- xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue));
- if (!xvalue)
- {
- return FALSE;
- }
- *xvalue = value;
- return TRUE;
-}
-
/* ETHTOOL_GSSET_INFO is available since 2.6.34 and ETH_SS_FEATURES (enum) and
* ETHTOOL_GFEATURES since 2.6.39, so check for the latter */
#ifdef ETHTOOL_GFEATURES
}
}
+ if (!add_uint8(hdr, sizeof(request), XFRMA_SA_DIR,
+ data->inbound ? XFRM_SA_DIR_IN : XFRM_SA_DIR_OUT))
+ {
+ goto failed;
+ }
+
if (id->proto != IPPROTO_COMP)
{
/* generally, we don't need a replay window for outbound SAs, however,