diff options
author | Thomas Haller <thaller@redhat.com> | 2016-06-25 15:36:07 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-06-25 15:36:07 (GMT) |
commit | a24319393ced15d611645fec6004284d96c042cd (patch) | |
tree | 1bdeb294c3fc6888ae134afdabc046022fc630c9 | |
parent | 6a9b59ca731c739fd4a5e3cbcac28309ec427f4b (diff) | |
parent | 49f612f1883e1a525229cce37f9380ae52ef8ad2 (diff) | |
download | libnl-a24319393ced15d611645fec6004284d96c042cd.zip libnl-a24319393ced15d611645fec6004284d96c042cd.tar.gz libnl-a24319393ced15d611645fec6004284d96c042cd.tar.bz2 |
xfrm: merge branch 'xfrm/various-fixes'
http://lists.infradead.org/pipermail/libnl/2016-June/002138.html
-rw-r--r-- | lib/xfrm/sa.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c index 0b813c4..a1abfe7 100644 --- a/lib/xfrm/sa.c +++ b/lib/xfrm/sa.c @@ -110,8 +110,11 @@ static void xfrm_sa_free_data(struct nl_object *c) free (sa->crypt); if (sa->comp) free (sa->comp); - if (sa->encap) - free (sa->encap); + if (sa->encap) { + if (sa->encap->encap_oa) + nl_addr_put(sa->encap->encap_oa); + free(sa->encap); + } if (sa->coaddr) nl_addr_put (sa->coaddr); if (sa->sec_ctx) @@ -1154,20 +1157,27 @@ 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; + /* 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) { + nlmsg_free(msg); + return -NLE_NOMEM; + } - len = sizeof (struct xfrm_algo_auth) + ((tmpl->auth->alg_key_len + 7) / 8); - NLA_PUT (msg, XFRMA_ALG_AUTH_TRUNC, len, tmpl->auth); + 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) { @@ -1773,9 +1783,13 @@ int xfrmnl_sa_get_encap_tmpl (struct xfrmnl_sa* sa, unsigned int* encap_type, un int xfrmnl_sa_set_encap_tmpl (struct xfrmnl_sa* sa, unsigned int encap_type, unsigned int encap_sport, unsigned int encap_dport, struct nl_addr* encap_oa) { - /* Free up the old encap OA */ - if (sa->encap->encap_oa) - nl_addr_put (sa->encap->encap_oa); + if (sa->encap) { + /* Free up the old encap OA */ + if (sa->encap->encap_oa) + nl_addr_put(sa->encap->encap_oa); + memset(sa->encap, 0, sizeof (*sa->encap)); + } else if ((sa->encap = calloc(1, sizeof(*sa->encap))) == NULL) + return -1; /* Save the new info */ sa->encap->encap_type = encap_type; |