summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-11-29 16:03:56 +0100
committerThomas Haller <thaller@redhat.com>2023-11-29 16:03:56 +0100
commit30d6e63cc0b17a10b37f3ed31ee0e49e38ed6bc8 (patch)
treeb7cbe44047ecb862c7b1f0f868d61a20db1873e2
parentcd4016bab267e6984693032338c8f43232ff6a3e (diff)
parent2f485cc7e4ff0d15f203ddf54702f65aed0a427a (diff)
downloadlibnl-30d6e63cc0b17a10b37f3ed31ee0e49e38ed6bc8.tar.gz
xfrm: erge branch 'th/xfrm-addr-cleanup'
https://github.com/thom311/libnl/pull/367
-rw-r--r--Makefile.am1
-rw-r--r--include/base/nl-base-utils.h11
-rw-r--r--include/nl-aux-core/nl-core.h7
-rw-r--r--include/nl-aux-xfrm/README.md18
-rw-r--r--include/nl-aux-xfrm/nl-xfrm.h26
-rw-r--r--lib/xfrm/ae.c32
-rw-r--r--lib/xfrm/sa.c134
-rw-r--r--lib/xfrm/sp.c90
8 files changed, 155 insertions, 164 deletions
diff --git a/Makefile.am b/Makefile.am
index 0e5998ae..ff2ce329 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -315,6 +315,7 @@ noinst_HEADERS = \
include/linux-private/linux/xfrm.h \
include/nl-aux-core/nl-core.h \
include/nl-aux-route/nl-route.h \
+ include/nl-aux-xfrm/nl-xfrm.h \
include/nl-default.h \
include/nl-priv-dynamic-core/cache-api.h \
include/nl-priv-dynamic-core/nl-core.h \
diff --git a/include/base/nl-base-utils.h b/include/base/nl-base-utils.h
index fb6bdf2d..6dd9c49f 100644
--- a/include/base/nl-base-utils.h
+++ b/include/base/nl-base-utils.h
@@ -663,6 +663,17 @@ static inline void *_nl_memdup(const void *ptr, size_t len)
/*****************************************************************************/
+static inline size_t _nl_addr_family_to_size(int addr_family)
+{
+ if (addr_family == AF_INET)
+ return sizeof(in_addr_t);
+ if (addr_family == AF_INET6)
+ return sizeof(struct in6_addr);
+ return 0;
+}
+
+/*****************************************************************************/
+
typedef union {
in_addr_t addr4;
struct in_addr a4;
diff --git a/include/nl-aux-core/nl-core.h b/include/nl-aux-core/nl-core.h
index 36bce3a0..5b34bcb0 100644
--- a/include/nl-aux-core/nl-core.h
+++ b/include/nl-aux-core/nl-core.h
@@ -49,4 +49,11 @@ void nl_socket_free(struct nl_sock *);
_NL_AUTO_DEFINE_FCN_TYPED0(struct nl_sock *, _nl_auto_nl_socket_fcn,
nl_socket_free);
+struct nl_addr *nl_addr_build(int, const void *, size_t);
+
+static inline struct nl_addr *_nl_addr_build(int family, const void *buf)
+{
+ return nl_addr_build(family, buf, _nl_addr_family_to_size(family));
+}
+
#endif /* NETLINK_NL_AUTO_H_ */
diff --git a/include/nl-aux-xfrm/README.md b/include/nl-aux-xfrm/README.md
new file mode 100644
index 00000000..9a4b6e2f
--- /dev/null
+++ b/include/nl-aux-xfrm/README.md
@@ -0,0 +1,18 @@
+include/nl-aux-xfrm
+===================
+
+This contains private/internal helpers that depend on the public libnl-3 (core)
+and libnl-xfrm-3.
+
+Itself, it must only rely on C, include/base/ and public headers of libnl-3 (core)
+and libnl-xfrm-3.
+
+They can be used by all internal code that uses the public API of both libnl-3 (core)
+and libnl-xfrm-3.
+
+It can also be used by lib/xfrm itself (that is, the implementation of
+libnl-xfrm-3).
+
+It must not be used in public headers, it's internal only.
+
+Currently this is header-only, it does not require any additional linking.
diff --git a/include/nl-aux-xfrm/nl-xfrm.h b/include/nl-aux-xfrm/nl-xfrm.h
new file mode 100644
index 00000000..0f7e7a71
--- /dev/null
+++ b/include/nl-aux-xfrm/nl-xfrm.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+#ifndef __NETLINK_NL_AUX_XFRM_NL_XFRM_H__
+#define __NETLINK_NL_AUX_XFRM_NL_XFRM_H__
+
+#include "base/nl-base-utils.h"
+
+struct xfrmnl_sp;
+void xfrmnl_sp_put(struct xfrmnl_sp *sp);
+#define _nl_auto_xfrmnl_sp _nl_auto(_nl_auto_xfrmnl_sp_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct xfrmnl_sp *, _nl_auto_xfrmnl_sp_fcn,
+ xfrmnl_sp_put);
+
+struct xfrmnl_sa;
+void xfrmnl_sa_put(struct xfrmnl_sa *sa);
+#define _nl_auto_xfrmnl_sa _nl_auto(_nl_auto_xfrmnl_sa_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct xfrmnl_sa *, _nl_auto_xfrmnl_sa_fcn,
+ xfrmnl_sa_put);
+
+struct xfrmnl_ae;
+void xfrmnl_ae_put(struct xfrmnl_ae *ae);
+#define _nl_auto_xfrmnl_ae _nl_auto(_nl_auto_xfrmnl_ae_fcn)
+_NL_AUTO_DEFINE_FCN_TYPED0(struct xfrmnl_ae *, _nl_auto_xfrmnl_ae_fcn,
+ xfrmnl_ae_put);
+
+#endif /* __NETLINK_NL_AUX_XFRM_NL_XFRM_H__ */
diff --git a/lib/xfrm/ae.c b/lib/xfrm/ae.c
index 4f56690e..9af73a87 100644
--- a/lib/xfrm/ae.c
+++ b/lib/xfrm/ae.c
@@ -133,6 +133,8 @@
#include "nl-priv-dynamic-core/object-api.h"
#include "nl-priv-dynamic-core/nl-core.h"
#include "nl-priv-dynamic-core/cache-api.h"
+#include "nl-aux-core/nl-core.h"
+#include "nl-aux-xfrm/nl-xfrm.h"
/** @cond SKIP */
@@ -522,29 +524,30 @@ static struct nla_policy xfrm_ae_policy[XFRMA_MAX+1] = {
int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
{
- struct xfrmnl_ae* ae;
+ _nl_auto_xfrmnl_ae struct xfrmnl_ae *ae = NULL;
struct nlattr *tb[XFRMA_MAX + 1];
struct xfrm_aevent_id* ae_id;
int err;
ae = xfrmnl_ae_alloc();
- if (!ae) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!ae)
+ return -NLE_NOMEM;
ae->ce_msgtype = n->nlmsg_type;
ae_id = nlmsg_data(n);
err = nlmsg_parse(n, sizeof(struct xfrm_aevent_id), tb, XFRMA_MAX, xfrm_ae_policy);
if (err < 0)
- goto errout;
+ return err;
- ae->sa_id.daddr = nl_addr_build(ae_id->sa_id.family, &ae_id->sa_id.daddr, sizeof (ae_id->sa_id.daddr));
+ if (!(ae->sa_id.daddr =
+ _nl_addr_build(ae_id->sa_id.family, &ae_id->sa_id.daddr)))
+ return -NLE_NOMEM;
ae->sa_id.family= ae_id->sa_id.family;
ae->sa_id.spi = ntohl(ae_id->sa_id.spi);
ae->sa_id.proto = ae_id->sa_id.proto;
- ae->saddr = nl_addr_build(ae_id->sa_id.family, &ae_id->saddr, sizeof (ae_id->saddr));
+ if (!(ae->saddr = _nl_addr_build(ae_id->sa_id.family, &ae_id->saddr)))
+ return -NLE_NOMEM;
ae->reqid = ae_id->reqid;
ae->flags = ae_id->flags;
ae->ce_mask |= (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_FAMILY | XFRM_AE_ATTR_SPI |
@@ -560,6 +563,7 @@ int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
if (tb[XFRMA_LTIME_VAL]) {
struct xfrm_lifetime_cur* cur = nla_data(tb[XFRMA_LTIME_VAL]);
+
ae->lifetime_cur.bytes = cur->bytes;
ae->lifetime_cur.packets = cur->packets;
ae->lifetime_cur.add_time = cur->add_time;
@@ -581,10 +585,8 @@ int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
struct xfrm_replay_state_esn* esn = nla_data (tb[XFRMA_REPLAY_ESN_VAL]);
uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * esn->bmp_len);
- if ((ae->replay_state_esn = calloc (1, len)) == NULL) {
- err = -ENOMEM;
- goto errout;
- }
+ if ((ae->replay_state_esn = calloc (1, len)) == NULL)
+ return -NLE_NOMEM;
ae->replay_state_esn->oseq = esn->oseq;
ae->replay_state_esn->seq = esn->seq;
ae->replay_state_esn->oseq_hi = esn->oseq_hi;
@@ -605,12 +607,8 @@ int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
ae->replay_state_esn = NULL;
}
- *result = ae;
+ *result = _nl_steal_pointer(&ae);
return 0;
-
-errout:
- xfrmnl_ae_put(ae);
- return err;
}
static int xfrm_ae_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c
index 44faa896..0970b441 100644
--- a/lib/xfrm/sa.c
+++ b/lib/xfrm/sa.c
@@ -54,6 +54,8 @@
#include "nl-priv-dynamic-core/object-api.h"
#include "nl-priv-dynamic-core/nl-core.h"
#include "nl-priv-dynamic-core/cache-api.h"
+#include "nl-aux-core/nl-core.h"
+#include "nl-aux-xfrm/nl-xfrm.h"
/** @cond SKIP */
@@ -770,18 +772,17 @@ static int xfrm_sa_request_update(struct nl_cache *c, struct nl_sock *h)
int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
{
- struct xfrmnl_sa* sa;
+ _nl_auto_nl_addr struct nl_addr *addr1 = NULL;
+ _nl_auto_nl_addr struct nl_addr *addr2 = NULL;
+ _nl_auto_xfrmnl_sa struct xfrmnl_sa *sa = NULL;
struct nlattr *tb[XFRMA_MAX + 1];
struct xfrm_usersa_info* sa_info;
struct xfrm_user_expire* ue;
int len, err;
- struct nl_addr* addr;
sa = xfrmnl_sa_alloc();
- if (!sa) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!sa)
+ return -NLE_NOMEM;
sa->ce_msgtype = n->nlmsg_type;
if (n->nlmsg_type == XFRM_MSG_EXPIRE)
@@ -802,26 +803,18 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
err = nlmsg_parse(n, sizeof(struct xfrm_usersa_info), tb, XFRMA_MAX, xfrm_sa_policy);
if (err < 0)
- goto errout;
+ return err;
- if (sa_info->sel.family == AF_INET)
- addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.daddr.a4, sizeof (sa_info->sel.daddr.a4));
- else
- addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.daddr.a6, sizeof (sa_info->sel.daddr.a6));
- nl_addr_set_prefixlen (addr, sa_info->sel.prefixlen_d);
- xfrmnl_sel_set_daddr (sa->sel, addr);
- /* Drop the reference count from the above set operation */
- nl_addr_put(addr);
+ if (!(addr1 = _nl_addr_build(sa_info->sel.family, &sa_info->sel.daddr)))
+ return -NLE_NOMEM;
+ nl_addr_set_prefixlen (addr1, sa_info->sel.prefixlen_d);
+ xfrmnl_sel_set_daddr (sa->sel, addr1);
xfrmnl_sel_set_prefixlen_d (sa->sel, sa_info->sel.prefixlen_d);
- if (sa_info->sel.family == AF_INET)
- addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.saddr.a4, sizeof (sa_info->sel.saddr.a4));
- else
- addr = nl_addr_build (sa_info->sel.family, &sa_info->sel.saddr.a6, sizeof (sa_info->sel.saddr.a6));
- nl_addr_set_prefixlen (addr, sa_info->sel.prefixlen_s);
- xfrmnl_sel_set_saddr (sa->sel, addr);
- /* Drop the reference count from the above set operation */
- nl_addr_put(addr);
+ if (!(addr2 = _nl_addr_build(sa_info->sel.family, &sa_info->sel.saddr)))
+ return -NLE_NOMEM;
+ nl_addr_set_prefixlen (addr2, sa_info->sel.prefixlen_s);
+ xfrmnl_sel_set_saddr (sa->sel, addr2);
xfrmnl_sel_set_prefixlen_s (sa->sel, sa_info->sel.prefixlen_s);
xfrmnl_sel_set_dport (sa->sel, ntohs(sa_info->sel.dport));
@@ -834,18 +827,14 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
xfrmnl_sel_set_userid (sa->sel, sa_info->sel.user);
sa->ce_mask |= XFRM_SA_ATTR_SEL;
- if (sa_info->family == AF_INET)
- sa->id.daddr = nl_addr_build (sa_info->family, &sa_info->id.daddr.a4, sizeof (sa_info->id.daddr.a4));
- else
- sa->id.daddr = nl_addr_build (sa_info->family, &sa_info->id.daddr.a6, sizeof (sa_info->id.daddr.a6));
+ if (!(sa->id.daddr = _nl_addr_build(sa_info->family, &sa_info->id.daddr)))
+ return -NLE_NOMEM;
sa->id.spi = ntohl(sa_info->id.spi);
sa->id.proto = sa_info->id.proto;
sa->ce_mask |= (XFRM_SA_ATTR_DADDR | XFRM_SA_ATTR_SPI | XFRM_SA_ATTR_PROTO);
- if (sa_info->family == AF_INET)
- sa->saddr = nl_addr_build (sa_info->family, &sa_info->saddr.a4, sizeof (sa_info->saddr.a4));
- else
- sa->saddr = nl_addr_build (sa_info->family, &sa_info->saddr.a6, sizeof (sa_info->saddr.a6));
+ if (!(sa->saddr = _nl_addr_build(sa_info->family, &sa_info->saddr)))
+ return -NLE_NOMEM;
sa->ce_mask |= XFRM_SA_ATTR_SADDR;
sa->lft->soft_byte_limit = sa_info->lft.soft_byte_limit;
@@ -881,36 +870,30 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_ALG_AEAD]) {
struct xfrm_algo_aead* aead = nla_data(tb[XFRMA_ALG_AEAD]);
+
len = sizeof (struct xfrmnl_algo_aead) + ((aead->alg_key_len + 7) / 8);
if ((sa->aead = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->aead, (void *)aead, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_AEAD;
}
if (tb[XFRMA_ALG_AUTH_TRUNC]) {
struct xfrm_algo_auth* auth = nla_data(tb[XFRMA_ALG_AUTH_TRUNC]);
+
len = sizeof (struct xfrmnl_algo_auth) + ((auth->alg_key_len + 7) / 8);
if ((sa->auth = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->auth, (void *)auth, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_AUTH;
}
if (tb[XFRMA_ALG_AUTH] && !sa->auth) {
struct xfrm_algo* auth = nla_data(tb[XFRMA_ALG_AUTH]);
+
len = sizeof (struct xfrmnl_algo_auth) + ((auth->alg_key_len + 7) / 8);
if ((sa->auth = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
strcpy(sa->auth->alg_name, auth->alg_name);
memcpy(sa->auth->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8);
sa->auth->alg_key_len = auth->alg_key_len;
@@ -919,43 +902,36 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_ALG_CRYPT]) {
struct xfrm_algo* crypt = nla_data(tb[XFRMA_ALG_CRYPT]);
+
len = sizeof (struct xfrmnl_algo) + ((crypt->alg_key_len + 7) / 8);
if ((sa->crypt = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->crypt, (void *)crypt, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_CRYPT;
}
if (tb[XFRMA_ALG_COMP]) {
struct xfrm_algo* comp = nla_data(tb[XFRMA_ALG_COMP]);
+
len = sizeof (struct xfrmnl_algo) + ((comp->alg_key_len + 7) / 8);
if ((sa->comp = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->comp, (void *)comp, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_COMP;
}
if (tb[XFRMA_ENCAP]) {
struct xfrm_encap_tmpl* encap = nla_data(tb[XFRMA_ENCAP]);
+
len = sizeof (struct xfrmnl_encap_tmpl);
if ((sa->encap = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
sa->encap->encap_type = encap->encap_type;
sa->encap->encap_sport = ntohs(encap->encap_sport);
sa->encap->encap_dport = ntohs(encap->encap_dport);
- if (sa_info->family == AF_INET)
- sa->encap->encap_oa = nl_addr_build (sa_info->family, &encap->encap_oa.a4, sizeof (encap->encap_oa.a4));
- else
- sa->encap->encap_oa = nl_addr_build (sa_info->family, &encap->encap_oa.a6, sizeof (encap->encap_oa.a6));
+ if (!(sa->encap->encap_oa = _nl_addr_build(sa_info->family,
+ &encap->encap_oa)))
+ return -NLE_NOMEM;
sa->ce_mask |= XFRM_SA_ATTR_ENCAP;
}
@@ -965,21 +941,15 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
}
if (tb[XFRMA_COADDR]) {
- if (sa_info->family == AF_INET)
- {
- sa->coaddr = nl_addr_build(sa_info->family, nla_data(tb[XFRMA_COADDR]),
- sizeof (uint32_t));
- }
- else
- {
- sa->coaddr = nl_addr_build(sa_info->family, nla_data(tb[XFRMA_COADDR]),
- sizeof (uint32_t) * 4);
- }
+ if (!(sa->coaddr = _nl_addr_build(
+ sa_info->family, nla_data(tb[XFRMA_COADDR]))))
+ return -NLE_NOMEM;
sa->ce_mask |= XFRM_SA_ATTR_COADDR;
}
if (tb[XFRMA_MARK]) {
struct xfrm_mark* m = nla_data(tb[XFRMA_MARK]);
+
sa->mark.m = m->m;
sa->mark.v = m->v;
sa->ce_mask |= XFRM_SA_ATTR_MARK;
@@ -987,12 +957,10 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_SEC_CTX]) {
struct xfrm_user_sec_ctx* sec_ctx = nla_data(tb[XFRMA_SEC_CTX]);
+
len = sizeof (struct xfrmnl_user_sec_ctx) + sec_ctx->ctx_len;
if ((sa->sec_ctx = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy (sa->sec_ctx, sec_ctx, len);
sa->ce_mask |= XFRM_SA_ATTR_SECCTX;
}
@@ -1009,12 +977,10 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_REPLAY_ESN_VAL]) {
struct xfrm_replay_state_esn* esn = nla_data (tb[XFRMA_REPLAY_ESN_VAL]);
+
len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * esn->bmp_len);
if ((sa->replay_state_esn = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->replay_state_esn, (void *)esn, len);
sa->ce_mask |= XFRM_SA_ATTR_REPLAY_STATE;
}
@@ -1032,24 +998,16 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
struct xfrm_user_offload *offload;
len = sizeof(struct xfrmnl_user_offload);
-
- if ((sa->user_offload = calloc(1, len)) == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
-
+ if ((sa->user_offload = calloc(1, len)) == NULL)
+ return -NLE_NOMEM;
offload = nla_data(tb[XFRMA_OFFLOAD_DEV]);
sa->user_offload->ifindex = offload->ifindex;
sa->user_offload->flags = offload->flags;
sa->ce_mask |= XFRM_SA_ATTR_OFFLOAD_DEV;
}
- *result = sa;
+ *result = _nl_steal_pointer(&sa);
return 0;
-
-errout:
- xfrmnl_sa_put(sa);
- return err;
}
static int xfrm_sa_update_cache (struct nl_cache *cache, struct nl_object *obj,
diff --git a/lib/xfrm/sp.c b/lib/xfrm/sp.c
index 5a96ac93..e98339c0 100644
--- a/lib/xfrm/sp.c
+++ b/lib/xfrm/sp.c
@@ -53,6 +53,8 @@
#include "nl-priv-dynamic-core/object-api.h"
#include "nl-priv-dynamic-core/nl-core.h"
#include "nl-priv-dynamic-core/cache-api.h"
+#include "nl-aux-core/nl-core.h"
+#include "nl-aux-xfrm/nl-xfrm.h"
struct xfrmnl_userpolicy_type {
uint8_t type;
@@ -561,53 +563,37 @@ static int xfrm_sp_request_update(struct nl_cache *c, struct nl_sock *h)
int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
{
- struct xfrmnl_sp *sp;
+ _nl_auto_nl_addr struct nl_addr *addr1 = NULL;
+ _nl_auto_nl_addr struct nl_addr *addr2 = NULL;
+ _nl_auto_xfrmnl_sp struct xfrmnl_sp *sp = NULL;
struct nlattr *tb[XFRMA_MAX + 1];
struct xfrm_userpolicy_info *sp_info;
int len, err;
- struct nl_addr* addr;
sp = xfrmnl_sp_alloc();
- if (!sp) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!sp)
+ return -NLE_NOMEM;
sp->ce_msgtype = n->nlmsg_type;
if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
- {
sp_info = (struct xfrm_userpolicy_info*)((char *)nlmsg_data(n) + sizeof (struct xfrm_userpolicy_id) + NLA_HDRLEN);
- }
else
- {
sp_info = nlmsg_data(n);
- }
err = nlmsg_parse(n, sizeof(struct xfrm_userpolicy_info), tb, XFRMA_MAX, xfrm_sp_policy);
if (err < 0)
- {
- printf ("parse error: %d \n", err);
- goto errout;
- }
+ return err;
- if (sp_info->sel.family == AF_INET)
- addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.daddr.a4, sizeof (sp_info->sel.daddr.a4));
- else
- addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.daddr.a6, sizeof (sp_info->sel.daddr.a6));
- nl_addr_set_prefixlen (addr, sp_info->sel.prefixlen_d);
- xfrmnl_sel_set_daddr (sp->sel, addr);
- /* Drop the reference count from the above set operation */
- nl_addr_put(addr);
+ if (!(addr1 = _nl_addr_build(sp_info->sel.family, &sp_info->sel.daddr)))
+ return -NLE_NOMEM;
+ nl_addr_set_prefixlen (addr1, sp_info->sel.prefixlen_d);
+ xfrmnl_sel_set_daddr (sp->sel, addr1);
xfrmnl_sel_set_prefixlen_d (sp->sel, sp_info->sel.prefixlen_d);
- if (sp_info->sel.family == AF_INET)
- addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.saddr.a4, sizeof (sp_info->sel.saddr.a4));
- else
- addr = nl_addr_build (sp_info->sel.family, &sp_info->sel.saddr.a6, sizeof (sp_info->sel.saddr.a6));
- nl_addr_set_prefixlen (addr, sp_info->sel.prefixlen_s);
- xfrmnl_sel_set_saddr (sp->sel, addr);
- /* Drop the reference count from the above set operation */
- nl_addr_put(addr);
+ if (!(addr2 = _nl_addr_build(sp_info->sel.family, &sp_info->sel.saddr)))
+ return -NLE_NOMEM;
+ nl_addr_set_prefixlen (addr2, sp_info->sel.prefixlen_s);
+ xfrmnl_sel_set_saddr (sp->sel, addr2);
xfrmnl_sel_set_prefixlen_s (sp->sel, sp_info->sel.prefixlen_s);
xfrmnl_sel_set_dport (sp->sel, ntohs (sp_info->sel.dport));
@@ -648,18 +634,17 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
if (tb[XFRMA_SEC_CTX]) {
struct xfrm_user_sec_ctx* ctx = nla_data(tb[XFRMA_SEC_CTX]);
+
len = sizeof (struct xfrmnl_user_sec_ctx) + ctx->ctx_len;
if ((sp->sec_ctx = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sp->sec_ctx, (void *)ctx, len);
sp->ce_mask |= XFRM_SP_ATTR_SECCTX;
}
if (tb[XFRMA_POLICY_TYPE]) {
struct xfrm_userpolicy_type* up = nla_data(tb[XFRMA_POLICY_TYPE]);
+
memcpy ((void *)&sp->uptype, (void *)up, sizeof (struct xfrm_userpolicy_type));
sp->ce_mask |= XFRM_SP_ATTR_POLTYPE;
}
@@ -669,34 +654,25 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
struct xfrmnl_user_tmpl* sputmpl;
uint32_t i;
uint32_t num_tmpls = nla_len(tb[XFRMA_TMPL]) / sizeof (*tmpl);
- struct nl_addr* addr;
for (i = 0; (i < num_tmpls) && (tmpl); i ++, tmpl++)
{
+ _nl_auto_nl_addr struct nl_addr *addr1 = NULL;
+ _nl_auto_nl_addr struct nl_addr *addr2 = NULL;
+
if ((sputmpl = xfrmnl_user_tmpl_alloc ()) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
-
- if (tmpl->family == AF_INET)
- addr = nl_addr_build(tmpl->family, &tmpl->id.daddr.a4, sizeof (tmpl->id.daddr.a4));
- else
- addr = nl_addr_build(tmpl->family, &tmpl->id.daddr.a6, sizeof (tmpl->id.daddr.a6));
- xfrmnl_user_tmpl_set_daddr (sputmpl, addr);
- /* Drop the reference count from the above set operation */
- nl_addr_put(addr);
+ return -NLE_NOMEM;
+
+ if (!(addr1 = _nl_addr_build(tmpl->family, &tmpl->id.daddr)))
+ return -NLE_NOMEM;
+ xfrmnl_user_tmpl_set_daddr (sputmpl, addr1);
xfrmnl_user_tmpl_set_spi (sputmpl, ntohl(tmpl->id.spi));
xfrmnl_user_tmpl_set_proto (sputmpl, tmpl->id.proto);
xfrmnl_user_tmpl_set_family (sputmpl, tmpl->family);
- if (tmpl->family == AF_INET)
- addr = nl_addr_build(tmpl->family, &tmpl->saddr.a4, sizeof (tmpl->saddr.a4));
- else
- addr = nl_addr_build(tmpl->family, &tmpl->saddr.a6, sizeof (tmpl->saddr.a6));
- xfrmnl_user_tmpl_set_saddr (sputmpl, addr);
- /* Drop the reference count from the above set operation */
- nl_addr_put(addr);
+ if (!(addr2 = _nl_addr_build(tmpl->family, &tmpl->saddr)))
+ return -NLE_NOMEM;
+ xfrmnl_user_tmpl_set_saddr (sputmpl, addr2);
xfrmnl_user_tmpl_set_reqid (sputmpl, tmpl->reqid);
xfrmnl_user_tmpl_set_mode (sputmpl, tmpl->mode);
@@ -718,12 +694,8 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
sp->ce_mask |= XFRM_SP_ATTR_MARK;
}
- *result = sp;
+ *result = _nl_steal_pointer(&sp);
return 0;
-
-errout:
- xfrmnl_sp_put(sp);
- return err;
}
static int xfrm_sp_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,