diff options
author | Thomas Egerer <thomas.egerer@secunet.com> | 2016-06-10 09:57:57 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-06-25 15:31:38 (GMT) |
commit | 6db1547c0d51b4cdd6c1601484788a758181bd54 (patch) | |
tree | f52ce22fb712ad989e106923ae0b8d2583a28788 | |
parent | 01bd6ef7e048f23564587865ad0d2e7103bd384b (diff) | |
download | libnl-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.c | 33 |
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) { |