summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Egerer <thomas.egerer@secunet.com>2016-06-10 09:57:57 (GMT)
committerThomas Haller <thaller@redhat.com>2016-06-25 15:31:38 (GMT)
commit6db1547c0d51b4cdd6c1601484788a758181bd54 (patch)
treef52ce22fb712ad989e106923ae0b8d2583a28788
parent01bd6ef7e048f23564587865ad0d2e7103bd384b (diff)
downloadlibnl-6db1547c0d51b4cdd6c1601484788a758181bd54.zip
libnl-6db1547c0d51b4cdd6c1601484788a758181bd54.tar.gz
libnl-6db1547c0d51b4cdd6c1601484788a758181bd54.tar.bz2
xfrm: attach only one xfrm alg attribute to netlink message
The kernel only uses the xfrm alg auth attribute if the xfrm alg auth truncated attribute is not present. Hence sending both attributes in one message does not make sense. This piece of code also removes the call to nla_reserve in favor of the NLA_PUT macro. Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com> Signed-off-by: Thomas Haller <thaller@redhat.com> http://lists.infradead.org/pipermail/libnl/2016-June/002139.html
-rw-r--r--lib/xfrm/sa.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c
index 999df3b..4995207 100644
--- a/lib/xfrm/sa.c
+++ b/lib/xfrm/sa.c
@@ -1157,20 +1157,25 @@ static int build_xfrm_sa_message(struct xfrmnl_sa *tmpl, int cmd, int flags, str
}
if (tmpl->ce_mask & XFRM_SA_ATTR_ALG_AUTH) {
- struct xfrm_algo* auth;
- struct nlattr * auth_attr;
-
- len = sizeof (struct xfrm_algo) + ((tmpl->auth->alg_key_len + 7) / 8);
- auth_attr = nla_reserve(msg, XFRMA_ALG_AUTH, len);
- if (!auth_attr)
- goto nla_put_failure;
- auth = nla_data (auth_attr);
- strcpy(auth->alg_name, tmpl->auth->alg_name);
- memcpy(auth->alg_key, tmpl->auth->alg_key, (tmpl->auth->alg_key_len + 7) / 8);
- auth->alg_key_len = tmpl->auth->alg_key_len;
-
- len = sizeof (struct xfrm_algo_auth) + ((tmpl->auth->alg_key_len + 7) / 8);
- NLA_PUT (msg, XFRMA_ALG_AUTH_TRUNC, len, tmpl->auth);
+ /* kernel prefers XFRMA_ALG_AUTH_TRUNC over XFRMA_ALG_AUTH, so only
+ * one of the attributes needs to be present */
+ if (tmpl->auth->alg_trunc_len) {
+ len = sizeof (struct xfrm_algo_auth) + ((tmpl->auth->alg_key_len + 7) / 8);
+ NLA_PUT (msg, XFRMA_ALG_AUTH_TRUNC, len, tmpl->auth);
+ } else {
+ struct xfrm_algo *auth;
+
+ len = sizeof (struct xfrm_algo) + ((tmpl->auth->alg_key_len + 7) / 8);
+ auth = malloc(len);
+ if (!auth)
+ return -NLE_NOMEM;
+
+ strncpy(auth->alg_name, tmpl->auth->alg_name, sizeof(auth->alg_name));
+ auth->alg_key_len = tmpl->auth->alg_key_len;
+ memcpy(auth->alg_key, tmpl->auth->alg_key, (tmpl->auth->alg_key_len + 7) / 8);
+ NLA_PUT(msg, XFRMA_ALG_AUTH, len, auth);
+ free(auth);
+ }
}
if (tmpl->ce_mask & XFRM_SA_ATTR_ALG_CRYPT) {