diff options
author | Thomas Graf <tgr@lsx.localdomain> | 2008-05-14 15:49:44 (GMT) |
---|---|---|
committer | Thomas Graf <tgr@lsx.localdomain> | 2008-05-14 15:49:44 (GMT) |
commit | 8a3efffa5b3fde252675239914118664d36a2c24 (patch) | |
tree | f8efc71b2bd4736f2a56084efea05d7ee191a422 /lib/netfilter | |
parent | 85f932552e61c5997c1e83fe386098c94d93c273 (diff) | |
download | libnl-8a3efffa5b3fde252675239914118664d36a2c24.zip libnl-8a3efffa5b3fde252675239914118664d36a2c24.tar.gz libnl-8a3efffa5b3fde252675239914118664d36a2c24.tar.bz2 |
Thread-safe error handling
In order for the interface to become more thread safe, the error
handling was revised to no longer depend on a static errno and
error string buffer.
This patch converts all error paths to return a libnl specific
error code which can be translated to a error message using
nl_geterror(int error). The functions nl_error() and
nl_get_errno() are therefore obsolete.
This change required various sets of function prototypes to be
changed in order to return an error code, the most prominent
are:
struct nl_cache *foo_alloc_cache(...);
changed to:
int foo_alloc_cache(..., struct nl_cache **);
struct nl_msg *foo_build_request(...);
changed to:
int foo_build_request(..., struct nl_msg **);
struct foo *foo_parse(...);
changed to:
int foo_parse(..., struct foo **);
This pretty much only leaves trivial allocation functions to
still return a pointer object which can still return NULL to
signal out of memory.
This change is a serious API and ABI breaker, sorry!
Diffstat (limited to 'lib/netfilter')
-rw-r--r-- | lib/netfilter/ct.c | 87 | ||||
-rw-r--r-- | lib/netfilter/ct_obj.c | 14 | ||||
-rw-r--r-- | lib/netfilter/log.c | 93 | ||||
-rw-r--r-- | lib/netfilter/log_msg.c | 20 | ||||
-rw-r--r-- | lib/netfilter/log_msg_obj.c | 4 | ||||
-rw-r--r-- | lib/netfilter/nfnl.c | 6 | ||||
-rw-r--r-- | lib/netfilter/queue.c | 93 | ||||
-rw-r--r-- | lib/netfilter/queue_msg.c | 21 | ||||
-rw-r--r-- | lib/netfilter/queue_msg_obj.c | 2 |
9 files changed, 164 insertions, 176 deletions
diff --git a/lib/netfilter/ct.c b/lib/netfilter/ct.c index e16a606..de561d2 100644 --- a/lib/netfilter/ct.c +++ b/lib/netfilter/ct.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> * Copyright (c) 2007 Secure Computing Corporation * Copyright (c= 2008 Patrick McHardy <kaber@trash.net> @@ -152,7 +152,7 @@ static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) return 0; errout_errno: - return nl_get_errno(); + err = -NLE_NOMEM; errout: return err; } @@ -287,7 +287,7 @@ int nfnlmsg_ct_group(struct nlmsghdr *nlh) } } -struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh) +int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result) { struct nfnl_ct *ct; struct nlattr *tb[CTA_MAX+1]; @@ -295,7 +295,7 @@ struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh) ct = nfnl_ct_alloc(); if (!ct) - return NULL; + return -NLE_NOMEM; ct->ce_msgtype = nlh->nlmsg_type; @@ -346,11 +346,12 @@ struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh) goto errout; } - return ct; + *result = ct; + return 0; errout: nfnl_ct_put(ct); - return NULL; + return err; } static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, @@ -359,9 +360,8 @@ static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nfnl_ct *ct; int err; - ct = nfnlmsg_ct_parse(nlh); - if (ct == NULL) - goto errout_errno; + if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0) + goto errout; err = pp->pp_cb((struct nl_object *) ct, pp); if (err < 0) @@ -372,10 +372,6 @@ static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, errout: nfnl_ct_put(ct); return err; - -errout_errno: - err = nl_get_errno(); - goto errout; } int nfnl_ct_dump_request(struct nl_handle *h) @@ -453,31 +449,35 @@ static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct, return 0; nla_put_failure: - return -1; + return -NLE_MSGSIZE; } -static struct nl_msg *nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags) +static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags, + struct nl_msg **result) { struct nl_msg *msg; + int err; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags, nfnl_ct_get_family(ct), 0); if (msg == NULL) - return NULL; + return -NLE_NOMEM; - if (nfnl_ct_build_tuple(msg, ct, 0) < 0) + if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0) goto err_out; - return msg; + *result = msg; + return 0; err_out: nlmsg_free(msg); - return NULL; + return err; } -struct nl_msg *nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags) +int nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags, + struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags); + return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result); } int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags) @@ -485,9 +485,8 @@ int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags) struct nl_msg *msg; int err; - msg = nfnl_ct_build_add_request(ct, flags); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0) + return err; err = nl_send_auto_complete(h, msg); nlmsg_free(msg); @@ -497,9 +496,10 @@ int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags) return nl_wait_for_ack(h); } -struct nl_msg *nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags) +int nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags, + struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags); + return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result); } int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags) @@ -507,9 +507,8 @@ int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags) struct nl_msg *msg; int err; - msg = nfnl_ct_build_delete_request(ct, flags); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0) + return err; err = nl_send_auto_complete(h, msg); nlmsg_free(msg); @@ -519,9 +518,10 @@ int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags) return nl_wait_for_ack(h); } -struct nl_msg *nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags) +int nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags, + struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags); + return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result); } int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags) @@ -529,9 +529,8 @@ int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags) struct nl_msg *msg; int err; - msg = nfnl_ct_build_query_request(ct, flags); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0) + return err; err = nl_send_auto_complete(h, msg); nlmsg_free(msg); @@ -549,28 +548,16 @@ int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags) /** * Build a conntrack cache holding all conntrack currently in the kernel * @arg handle netlink handle + * @arg result Pointer to store resulting cache. * * Allocates a new cache, initializes it properly and updates it to * contain all conntracks currently in the kernel. * - * @note The caller is responsible for destroying and freeing the - * cache after using it. - * @return The cache or NULL if an error has occured. + * @return 0 on success or a negative error code. */ -struct nl_cache *nfnl_ct_alloc_cache(struct nl_handle *handle) +int nfnl_ct_alloc_cache(struct nl_handle *sock, struct nl_cache **result) { - struct nl_cache *cache; - - cache = nl_cache_alloc(&nfnl_ct_ops); - if (!cache) - return NULL; - - if (handle && nl_cache_refill(handle, cache) < 0) { - free(cache); - return NULL; - } - - return cache; + return nl_cache_alloc_and_fill(&nfnl_ct_ops, sock, result); } /** @} */ diff --git a/lib/netfilter/ct_obj.c b/lib/netfilter/ct_obj.c index 96e5db6..1625efc 100644 --- a/lib/netfilter/ct_obj.c +++ b/lib/netfilter/ct_obj.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> * Copyright (c) 2007 Secure Computing Corporation */ @@ -75,34 +75,32 @@ static int ct_clone(struct nl_object *_dst, struct nl_object *_src) if (src->ct_orig.src) { addr = nl_addr_clone(src->ct_orig.src); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_orig.src = addr; } if (src->ct_orig.dst) { addr = nl_addr_clone(src->ct_orig.dst); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_orig.dst = addr; } if (src->ct_repl.src) { addr = nl_addr_clone(src->ct_repl.src); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_repl.src = addr; } if (src->ct_repl.dst) { addr = nl_addr_clone(src->ct_repl.dst); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_repl.dst = addr; } return 0; -errout: - return nl_get_errno(); } static void ct_dump_dir(struct nfnl_ct *ct, int repl, @@ -458,7 +456,7 @@ static int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr, { if (ct->ce_mask & CT_ATTR_FAMILY) { if (addr->a_family != ct->ct_family) - return nl_error(EINVAL, "Address family mismatch"); + return -NLE_AF_MISMATCH; } else nfnl_ct_set_family(ct, addr->a_family); diff --git a/lib/netfilter/log.c b/lib/netfilter/log.c index 41a131c..0cfbc87 100644 --- a/lib/netfilter/log.c +++ b/lib/netfilter/log.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> * Copyright (c) 2007 Secure Computing Corporation */ @@ -31,8 +31,8 @@ * @{ */ -static struct nl_msg *build_log_cmd_request(uint8_t family, uint16_t queuenum, - uint8_t command) +static int build_log_cmd_request(uint8_t family, uint16_t queuenum, + uint8_t command, struct nl_msg **result) { struct nl_msg *msg; struct nfulnl_msg_config_cmd cmd; @@ -40,17 +40,18 @@ static struct nl_msg *build_log_cmd_request(uint8_t family, uint16_t queuenum, msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, family, queuenum); if (msg == NULL) - return NULL; + return -NLE_NOMEM; cmd.command = command; if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; - return msg; + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } static int send_log_request(struct nl_handle *handle, struct nl_msg *msg) @@ -65,49 +66,50 @@ static int send_log_request(struct nl_handle *handle, struct nl_msg *msg) return nl_wait_for_ack(handle); } -struct nl_msg *nfnl_log_build_pf_bind(uint8_t pf) +int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result) { - return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND); + return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result); } int nfnl_log_pf_bind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_pf_bind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -struct nl_msg *nfnl_log_build_pf_unbind(uint8_t pf) +int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result) { - return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND); + return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result); } int nfnl_log_pf_unbind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_pf_unbind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -static struct nl_msg *nfnl_log_build_request(const struct nfnl_log *log) +static int nfnl_log_build_request(const struct nfnl_log *log, + struct nl_msg **result) { struct nl_msg *msg; if (!nfnl_log_test_group(log)) - return NULL; + return -NLE_MISSING_ATTR; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, 0, nfnl_log_get_group(log)); if (msg == NULL) - return NULL; + return -NLE_NOMEM; /* This sucks. The nfnetlink_log interface always expects both * parameters to be present. Needs to be done properly. @@ -148,77 +150,80 @@ static struct nl_msg *nfnl_log_build_request(const struct nfnl_log *log) htonl(nfnl_log_get_queue_threshold(log))) < 0) goto nla_put_failure; - return msg; + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } -struct nl_msg *nfnl_log_build_create_request(const struct nfnl_log *log) +int nfnl_log_build_create_request(const struct nfnl_log *log, + struct nl_msg **result) { - struct nl_msg *msg; struct nfulnl_msg_config_cmd cmd; + int err; - msg = nfnl_log_build_request(log); - if (msg == NULL) - return NULL; + if ((err = nfnl_log_build_request(log, result)) < 0) + return err; cmd.command = NFULNL_CFG_CMD_BIND; - if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) + if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; - return msg; + return 0; nla_put_failure: - nlmsg_free(msg); - return NULL; + nlmsg_free(*result); + return -NLE_MSGSIZE; } int nfnl_log_create(struct nl_handle *nlh, const struct nfnl_log *log) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_create_request(log); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_log_build_create_request(log, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -struct nl_msg *nfnl_log_build_change_request(const struct nfnl_log *log) +int nfnl_log_build_change_request(const struct nfnl_log *log, + struct nl_msg **result) { - return nfnl_log_build_request(log); + return nfnl_log_build_request(log, result); } int nfnl_log_change(struct nl_handle *nlh, const struct nfnl_log *log) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_change_request(log); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_log_build_change_request(log, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -struct nl_msg *nfnl_log_build_delete_request(const struct nfnl_log *log) +int nfnl_log_build_delete_request(const struct nfnl_log *log, + struct nl_msg **result) { if (!nfnl_log_test_group(log)) - return NULL; + return -NLE_MISSING_ATTR; return build_log_cmd_request(0, nfnl_log_get_group(log), - NFULNL_CFG_CMD_UNBIND); + NFULNL_CFG_CMD_UNBIND, result); } int nfnl_log_delete(struct nl_handle *nlh, const struct nfnl_log *log) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_delete_request(log); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_log_build_delete_request(log, &msg)) < 0) + return err; return send_log_request(nlh, msg); } diff --git a/lib/netfilter/log_msg.c b/lib/netfilter/log_msg.c index 5243338..33de482 100644 --- a/lib/netfilter/log_msg.c +++ b/lib/netfilter/log_msg.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2008 Patrick McHardy <kaber@trash.net> @@ -62,7 +62,7 @@ static struct nla_policy log_msg_policy[NFULA_MAX+1] = { [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 }, }; -struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh) +int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result) { struct nfnl_log_msg *msg; struct nlattr *tb[NFULA_MAX+1]; @@ -71,7 +71,7 @@ struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh) msg = nfnl_log_msg_alloc(); if (!msg) - return NULL; + return -NLE_NOMEM; msg->ce_msgtype = nlh->nlmsg_type; @@ -158,11 +158,12 @@ struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh) if (attr) nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr))); - return msg; + *result = msg; + return 0; errout: nfnl_log_msg_put(msg); - return NULL; + return err; } static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, @@ -171,9 +172,8 @@ static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nfnl_log_msg *msg; int err; - msg = nfnlmsg_log_msg_parse(nlh); - if (log == NULL) - goto errout_errno; + if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0) + goto errout; err = pp->pp_cb((struct nl_object *) msg, pp); if (err < 0) @@ -184,10 +184,6 @@ static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, errout: nfnl_log_msg_put(msg); return err; - -errout_errno: - err = nl_get_errno(); - goto errout; } /** @} */ diff --git a/lib/netfilter/log_msg_obj.c b/lib/netfilter/log_msg_obj.c index ee85090..b2cd9ef 100644 --- a/lib/netfilter/log_msg_obj.c +++ b/lib/netfilter/log_msg_obj.c @@ -341,7 +341,7 @@ int nfnl_log_msg_set_payload(struct nfnl_log_msg *msg, uint8_t *payload, int len free(msg->log_msg_payload); msg->log_msg_payload = malloc(len); if (!msg->log_msg_payload) - return nl_errno(ENOMEM); + return -NLE_NOMEM; memcpy(msg->log_msg_payload, payload, len); msg->log_msg_payload_len = len; @@ -365,7 +365,7 @@ int nfnl_log_msg_set_prefix(struct nfnl_log_msg *msg, void *prefix) free(msg->log_msg_prefix); msg->log_msg_prefix = strdup(prefix); if (!msg->log_msg_prefix) - return nl_errno(ENOMEM); + return -NLE_NOMEM; msg->ce_mask |= LOG_MSG_ATTR_PREFIX; return 0; diff --git a/lib/netfilter/nfnl.c b/lib/netfilter/nfnl.c index 554e234..2441f69 100644 --- a/lib/netfilter/nfnl.c +++ b/lib/netfilter/nfnl.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> * Copyright (c) 2007 Secure Computing Corporation */ @@ -178,7 +178,7 @@ static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id) nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO); if (nfg == NULL) - return nl_errno(ENOMEM); + return -NLE_NOMEM; nfg->nfgen_family = family; nfg->version = NFNETLINK_V0; @@ -236,7 +236,7 @@ int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags); if (nlh == NULL) - return nl_get_errno(); + return -NLE_MSGSIZE; return nfnlmsg_append(msg, family, res_id); } diff --git a/lib/netfilter/queue.c b/lib/netfilter/queue.c index 2bd719a..7f31c66 100644 --- a/lib/netfilter/queue.c +++ b/lib/netfilter/queue.c @@ -41,8 +41,8 @@ static int send_queue_request(struct nl_handle *handle, struct nl_msg *msg) * @{ */ -static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum, - uint8_t command) +static int build_queue_cmd_request(uint8_t family, uint16_t queuenum, + uint8_t command, struct nl_msg **result) { struct nl_msg *msg; struct nfqnl_msg_config_cmd cmd; @@ -50,7 +50,7 @@ static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum, msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0, family, queuenum); if (msg == NULL) - return NULL; + return -NLE_NOMEM; cmd.pf = htons(family); cmd._pad = 0; @@ -58,56 +58,58 @@ static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum, if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; - return msg; + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } -struct nl_msg *nfnl_queue_build_pf_bind(uint8_t pf) +int nfnl_queue_build_pf_bind(uint8_t pf, struct nl_msg **result) { - return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND); + return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND, result); } int nfnl_queue_pf_bind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_pf_bind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_queue_build_pf_bind(pf, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -struct nl_msg *nfnl_queue_build_pf_unbind(uint8_t pf) +int nfnl_queue_build_pf_unbind(uint8_t pf, struct nl_msg **result) { - return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND); + return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND, result); } int nfnl_queue_pf_unbind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_pf_unbind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_queue_build_pf_unbind(pf, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -static struct nl_msg *nfnl_queue_build_request(const struct nfnl_queue *queue) +static int nfnl_queue_build_request(const struct nfnl_queue *queue, + struct nl_msg **result) { struct nl_msg *msg; if (!nfnl_queue_test_group(queue)) - return NULL; + return -NLE_MISSING_ATTR; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0, 0, nfnl_queue_get_group(queue)); if (msg == NULL) - return NULL; + return -NLE_NOMEM; if (nfnl_queue_test_maxlen(queue) && nla_put_u32(msg, NFQA_CFG_QUEUE_MAXLEN, @@ -136,79 +138,82 @@ static struct nl_msg *nfnl_queue_build_request(const struct nfnl_queue *queue) if (nla_put(msg, NFQA_CFG_PARAMS, sizeof(params), ¶ms) < 0) goto nla_put_failure; } - return msg; + + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } -struct nl_msg *nfnl_queue_build_create_request(const struct nfnl_queue *queue) +int nfnl_queue_build_create_request(const struct nfnl_queue *queue, + struct nl_msg **result) { - struct nl_msg *msg; struct nfqnl_msg_config_cmd cmd; + int err; - msg = nfnl_queue_build_request(queue); - if (msg == NULL) - return NULL; + if ((err = nfnl_queue_build_request(queue, result)) < 0) + return err; cmd.pf = 0; cmd._pad = 0; cmd.command = NFQNL_CFG_CMD_BIND; - if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0) - goto nla_put_failure; + NLA_PUT(*result, NFQA_CFG_CMD, sizeof(cmd), &cmd); - return msg; + return 0; nla_put_failure: - nlmsg_free(msg); - return NULL; + nlmsg_free(*result); + return -NLE_MSGSIZE; } int nfnl_queue_create(struct nl_handle *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_create_request(queue); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_queue_build_create_request(queue, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -struct nl_msg *nfnl_queue_build_change_request(const struct nfnl_queue *queue) +int nfnl_queue_build_change_request(const struct nfnl_queue *queue, + struct nl_msg **result) { - return nfnl_queue_build_request(queue); + return nfnl_queue_build_request(queue, result); } int nfnl_queue_change(struct nl_handle *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_change_request(queue); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_queue_build_change_request(queue, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -struct nl_msg *nfnl_queue_build_delete_request(const struct nfnl_queue *queue) +int nfnl_queue_build_delete_request(const struct nfnl_queue *queue, + struct nl_msg **result) { if (!nfnl_queue_test_group(queue)) - return NULL; + return -NLE_MISSING_ATTR; return build_queue_cmd_request(0, nfnl_queue_get_group(queue), - NFQNL_CFG_CMD_UNBIND); + NFQNL_CFG_CMD_UNBIND, result); } int nfnl_queue_delete(struct nl_handle *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_delete_request(queue); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_queue_build_delete_request(queue, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } diff --git a/lib/netfilter/queue_msg.c b/lib/netfilter/queue_msg.c index a097b68..6d6ca73 100644 --- a/lib/netfilter/queue_msg.c +++ b/lib/netfilter/queue_msg.c @@ -58,7 +58,8 @@ static struct nla_policy queue_policy[NFQA_MAX+1] = { }, }; -struct nfnl_queue_msg *nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh) +int nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh, + struct nfnl_queue_msg **result) { struct nfnl_queue_msg *msg; struct nlattr *tb[NFQA_MAX+1]; @@ -67,7 +68,7 @@ struct nfnl_queue_msg *nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh) msg = nfnl_queue_msg_alloc(); if (!msg) - return NULL; + return -NLE_NOMEM; msg->ce_msgtype = nlh->nlmsg_type; @@ -135,11 +136,12 @@ struct nfnl_queue_msg *nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh) goto errout; } - return msg; + *result = msg; + return 0; errout: nfnl_queue_msg_put(msg); - return NULL; + return err; } static int queue_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, @@ -148,9 +150,8 @@ static int queue_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nfnl_queue_msg *msg; int err; - msg = nfnlmsg_queue_msg_parse(nlh); - if (msg == NULL) - goto errout_errno; + if ((err = nfnlmsg_queue_msg_parse(nlh, &msg)) < 0) + goto errout; err = pp->pp_cb((struct nl_object *) msg, pp); if (err < 0) @@ -161,10 +162,6 @@ static int queue_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, errout: nfnl_queue_msg_put(msg); return err; - -errout_errno: - err = nl_get_errno(); - goto errout; } /** @} */ @@ -205,7 +202,7 @@ int nfnl_queue_msg_send_verdict(struct nl_handle *nlh, nlmsg = nfnl_queue_msg_build_verdict(msg); if (nlmsg == NULL) - return nl_errno(ENOMEM); + return -NLE_NOMEM; err = nl_send_auto_complete(nlh, nlmsg); nlmsg_free(nlmsg); diff --git a/lib/netfilter/queue_msg_obj.c b/lib/netfilter/queue_msg_obj.c index 476d920..5796c34 100644 --- a/lib/netfilter/queue_msg_obj.c +++ b/lib/netfilter/queue_msg_obj.c @@ -400,7 +400,7 @@ int nfnl_queue_msg_set_payload(struct nfnl_queue_msg *msg, uint8_t *payload, free(msg->queue_msg_payload); msg->queue_msg_payload = malloc(len); if (!msg->queue_msg_payload) - return nl_errno(ENOMEM); + return -NLE_NOMEM; memcpy(msg->queue_msg_payload, payload, len); msg->queue_msg_payload_len = len; |