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!
diff --git a/include/netlink-local.h b/include/netlink-local.h
index 10619ac..1592138 100644
--- a/include/netlink-local.h
+++ b/include/netlink-local.h
@@ -81,43 +81,9 @@
assert(0); \
} while (0)
-#define RET_ERR(R, E) \
- do { \
- errno = E; \
- return -R; \
- } while (0)
-
-extern int __nl_error(int, const char *, unsigned int,
- const char *, const char *, ...);
-
extern int __nl_read_num_str_file(const char *path,
int (*cb)(long, const char *));
-#ifdef NL_ERROR_ASSERT
-#include <assert.h>
-static inline int __assert_error(const char *file, int line, char *func,
- const char *fmt, ...)
-{
- va_list args;
- fprintf(stderr, "%s:%d:%s: ", file, line, func);
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- fprintf(stderr, "\n");
- assert(0);
- return 0;
-}
-#define nl_error(E, FMT,ARG...) \
- __assert_error(__FILE__, __LINE__, __FUNCTION__, FMT, ##ARG)
-
-#else
-#define nl_error(E, FMT,ARG...) \
- __nl_error(E, __FILE__, __LINE__, __FUNCTION__, FMT, ##ARG)
-
-#endif
-
-#define nl_errno(E) nl_error(E, NULL)
-
/* backwards compat */
#define dp_new_line(params, line) nl_new_line(params)
#define dp_dump(params, fmt, arg...) nl_dump(params, fmt, ##arg)
@@ -129,7 +95,7 @@
tl = calloc(1, sizeof(*tl));
if (!tl)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
tl->i = i;
tl->a = strdup(a);
diff --git a/include/netlink-tc.h b/include/netlink-tc.h
index 65be588..691969d 100644
--- a/include/netlink-tc.h
+++ b/include/netlink-tc.h
@@ -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>
*/
#ifndef NETLINK_TC_PRIV_H_
@@ -51,7 +51,7 @@
extern char *tca_get_kind(struct rtnl_tca *);
extern uint64_t tca_get_stat(struct rtnl_tca *, int );
-extern struct nl_msg *tca_build_msg(struct rtnl_tca *tca, int type, int flags);
+extern int tca_build_msg(struct rtnl_tca *, int, int, struct nl_msg **);
static inline void *tca_priv(struct rtnl_tca *tca)
{
diff --git a/include/netlink/addr.h b/include/netlink/addr.h
index 8464a0c..00868d2 100644
--- a/include/netlink/addr.h
+++ b/include/netlink/addr.h
@@ -24,7 +24,7 @@
extern struct nl_addr * nl_addr_alloc(size_t);
extern struct nl_addr * nl_addr_alloc_from_attr(struct nlattr *, int);
extern struct nl_addr * nl_addr_build(int, void *, size_t);
-extern struct nl_addr * nl_addr_parse(const char *, int);
+extern int nl_addr_parse(const char *, int, struct nl_addr **);
extern struct nl_addr * nl_addr_clone(struct nl_addr *);
/* Destroyage */
@@ -42,7 +42,7 @@
extern int nl_addr_guess_family(struct nl_addr *);
extern int nl_addr_fill_sockaddr(struct nl_addr *,
struct sockaddr *, socklen_t *);
-extern struct addrinfo *nl_addr_info(struct nl_addr *addr);
+extern int nl_addr_info(struct nl_addr *, struct addrinfo **);
extern int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen);
/* Access Functions */
diff --git a/include/netlink/cache.h b/include/netlink/cache.h
index cb7741b..b437d76 100644
--- a/include/netlink/cache.h
+++ b/include/netlink/cache.h
@@ -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>
*/
#ifndef NETLINK_CACHE_H_
@@ -39,7 +39,11 @@
/* Cache creation/deletion */
#define nl_cache_alloc_from_ops(ptr) nl_cache_alloc(ptr)
extern struct nl_cache * nl_cache_alloc(struct nl_cache_ops *);
-extern struct nl_cache * nl_cache_alloc_name(const char *);
+extern int nl_cache_alloc_and_fill(struct nl_cache_ops *,
+ struct nl_handle *,
+ struct nl_cache **);
+extern int nl_cache_alloc_name(const char *,
+ struct nl_cache **);
extern struct nl_cache * nl_cache_subset(struct nl_cache *,
struct nl_object *);
extern void nl_cache_clear(struct nl_cache *);
@@ -106,11 +110,13 @@
#define NL_AUTO_PROVIDE 1
-extern struct nl_cache_mngr * nl_cache_mngr_alloc(struct nl_handle *,
- int, int);
-extern struct nl_cache * nl_cache_mngr_add(struct nl_cache_mngr *,
+extern int nl_cache_mngr_alloc(struct nl_handle *,
+ int, int,
+ struct nl_cache_mngr **);
+extern int nl_cache_mngr_add(struct nl_cache_mngr *,
const char *,
- change_func_t);
+ change_func_t,
+ struct nl_cache **);
extern int nl_cache_mngr_get_fd(struct nl_cache_mngr *);
extern int nl_cache_mngr_poll(struct nl_cache_mngr *,
int);
diff --git a/include/netlink/errno.h b/include/netlink/errno.h
new file mode 100644
index 0000000..0b43da0
--- /dev/null
+++ b/include/netlink/errno.h
@@ -0,0 +1,59 @@
+/*
+ * netlink/errno.h Error Numbers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
+ */
+
+#ifndef NETLINK_ERRNO_H_
+#define NETLINK_ERRNO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NLE_SUCCESS 0
+#define NLE_FAILURE 1
+#define NLE_INTR 2
+#define NLE_BAD_SOCK 3
+#define NLE_AGAIN 4
+#define NLE_NOMEM 5
+#define NLE_EXIST 6
+#define NLE_INVAL 7
+#define NLE_RANGE 8
+#define NLE_MSGSIZE 9
+#define NLE_OPNOTSUPP 10
+#define NLE_AF_NOSUPPORT 11
+#define NLE_OBJ_NOTFOUND 12
+#define NLE_NOATTR 13
+#define NLE_MISSING_ATTR 14
+#define NLE_AF_MISMATCH 15
+#define NLE_SEQ_MISMATCH 16
+#define NLE_MSG_OVERFLOW 17
+#define NLE_MSG_TRUNC 18
+#define NLE_NOADDR 19
+#define NLE_SRCRT_NOSUPPORT 20
+#define NLE_MSG_TOOSHORT 21
+#define NLE_MSGTYPE_NOSUPPORT 22
+#define NLE_OBJ_MISMATCH 23
+#define NLE_NOCACHE 24
+#define NLE_BUSY 25
+#define NLE_PROTO_MISMATCH 26
+#define NLE_NOACCESS 27
+#define NLE_PERM 28
+
+#define NLE_MAX NLE_PERM
+
+extern const char * nl_geterror(int);
+extern void nl_perror(int, const char *);
+extern int nl_syserr2nlerr(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netlink/fib_lookup/lookup.h b/include/netlink/fib_lookup/lookup.h
index 29c7ee8..201a7a0 100644
--- a/include/netlink/fib_lookup/lookup.h
+++ b/include/netlink/fib_lookup/lookup.h
@@ -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>
*/
#ifndef NETLINK_FIB_LOOKUP_H_
@@ -28,8 +28,9 @@
extern struct nl_cache * flnl_result_alloc_cache(void);
-extern struct nl_msg * flnl_lookup_build_request(struct flnl_request *,
- int);
+extern int flnl_lookup_build_request(struct flnl_request *,
+ int,
+ struct nl_msg **);
extern int flnl_lookup(struct nl_handle *,
struct flnl_request *,
struct nl_cache *);
diff --git a/include/netlink/genl/ctrl.h b/include/netlink/genl/ctrl.h
index 5d65c68..f66338e 100644
--- a/include/netlink/genl/ctrl.h
+++ b/include/netlink/genl/ctrl.h
@@ -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>
*/
#ifndef NETLINK_GENL_CTRL_H_
@@ -22,7 +22,8 @@
struct genl_family;
-extern struct nl_cache * genl_ctrl_alloc_cache(struct nl_handle *);
+extern int genl_ctrl_alloc_cache(struct nl_handle *,
+ struct nl_cache **);
extern struct genl_family * genl_ctrl_search(struct nl_cache *, int);
extern struct genl_family * genl_ctrl_search_by_name(struct nl_cache *,
const char *);
diff --git a/include/netlink/netfilter/ct.h b/include/netlink/netfilter/ct.h
index f554017..2e08228 100644
--- a/include/netlink/netfilter/ct.h
+++ b/include/netlink/netfilter/ct.h
@@ -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
*/
@@ -27,95 +27,95 @@
extern struct nl_object_ops ct_obj_ops;
-/* General */
extern struct nfnl_ct * nfnl_ct_alloc(void);
-extern struct nl_cache *nfnl_ct_alloc_cache(struct nl_handle *);
+extern int nfnl_ct_alloc_cache(struct nl_handle *, struct nl_cache **);
-extern int nfnlmsg_ct_group(struct nlmsghdr *);
-extern struct nfnl_ct * nfnlmsg_ct_parse(struct nlmsghdr *);
+extern int nfnlmsg_ct_group(struct nlmsghdr *);
+extern int nfnlmsg_ct_parse(struct nlmsghdr *, struct nfnl_ct **);
-extern void nfnl_ct_get(struct nfnl_ct *);
-extern void nfnl_ct_put(struct nfnl_ct *);
+extern void nfnl_ct_get(struct nfnl_ct *);
+extern void nfnl_ct_put(struct nfnl_ct *);
-extern int nfnl_ct_dump_request(struct nl_handle *);
+extern int nfnl_ct_dump_request(struct nl_handle *);
-extern struct nl_msg * nfnl_ct_build_add_request(const struct nfnl_ct *, int);
-extern int nfnl_ct_add(struct nl_handle *, const struct nfnl_ct *, int);
+extern int nfnl_ct_build_add_request(const struct nfnl_ct *, int,
+ struct nl_msg **);
+extern int nfnl_ct_add(struct nl_handle *, const struct nfnl_ct *, int);
-extern struct nl_msg * nfnl_ct_build_delete_request(const struct nfnl_ct *, int);
-extern int nfnl_ct_delete(struct nl_handle *, const struct nfnl_ct *, int);
+extern int nfnl_ct_build_delete_request(const struct nfnl_ct *, int,
+ struct nl_msg **);
+extern int nfnl_ct_delete(struct nl_handle *, const struct nfnl_ct *, int);
-extern struct nl_msg * nfnl_ct_build_query_request(const struct nfnl_ct *, int);
-extern int nfnl_ct_query(struct nl_handle *, const struct nfnl_ct *, int);
+extern int nfnl_ct_build_query_request(const struct nfnl_ct *, int,
+ struct nl_msg **);
+extern int nfnl_ct_query(struct nl_handle *, const struct nfnl_ct *, int);
-extern void nfnl_ct_set_family(struct nfnl_ct *, uint8_t);
-extern uint8_t nfnl_ct_get_family(const struct nfnl_ct *);
+extern void nfnl_ct_set_family(struct nfnl_ct *, uint8_t);
+extern uint8_t nfnl_ct_get_family(const struct nfnl_ct *);
-extern void nfnl_ct_set_proto(struct nfnl_ct *, uint8_t);
-extern int nfnl_ct_test_proto(const struct nfnl_ct *);
-extern uint8_t nfnl_ct_get_proto(const struct nfnl_ct *);
+extern void nfnl_ct_set_proto(struct nfnl_ct *, uint8_t);
+extern int nfnl_ct_test_proto(const struct nfnl_ct *);
+extern uint8_t nfnl_ct_get_proto(const struct nfnl_ct *);
-extern void nfnl_ct_set_tcp_state(struct nfnl_ct *, uint8_t);
-extern int nfnl_ct_test_tcp_state(const struct nfnl_ct *);
-extern uint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *);
-extern char * nfnl_ct_tcp_state2str(uint8_t, char *, size_t);
-extern int nfnl_ct_str2tcp_state(const char *name);
+extern void nfnl_ct_set_tcp_state(struct nfnl_ct *, uint8_t);
+extern int nfnl_ct_test_tcp_state(const struct nfnl_ct *);
+extern uint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *);
+extern char * nfnl_ct_tcp_state2str(uint8_t, char *, size_t);
+extern int nfnl_ct_str2tcp_state(const char *name);
-extern void nfnl_ct_set_status(struct nfnl_ct *, uint32_t);
-extern void nfnl_ct_unset_status(struct nfnl_ct *, uint32_t);
-extern uint32_t nfnl_ct_get_status(const struct nfnl_ct *);
+extern void nfnl_ct_set_status(struct nfnl_ct *, uint32_t);
+extern void nfnl_ct_unset_status(struct nfnl_ct *, uint32_t);
+extern uint32_t nfnl_ct_get_status(const struct nfnl_ct *);
-extern void nfnl_ct_set_timeout(struct nfnl_ct *, uint32_t);
-extern int nfnl_ct_test_timeout(const struct nfnl_ct *);
-extern uint32_t nfnl_ct_get_timeout(const struct nfnl_ct *);
+extern void nfnl_ct_set_timeout(struct nfnl_ct *, uint32_t);
+extern int nfnl_ct_test_timeout(const struct nfnl_ct *);
+extern uint32_t nfnl_ct_get_timeout(const struct nfnl_ct *);
-extern void nfnl_ct_set_mark(struct nfnl_ct *, uint32_t);
-extern int nfnl_ct_test_mark(const struct nfnl_ct *);
-extern uint32_t nfnl_ct_get_mark(const struct nfnl_ct *);
+extern void nfnl_ct_set_mark(struct nfnl_ct *, uint32_t);
+extern int nfnl_ct_test_mark(const struct nfnl_ct *);
+extern uint32_t nfnl_ct_get_mark(const struct nfnl_ct *);
-extern void nfnl_ct_set_use(struct nfnl_ct *, uint32_t);
-extern int nfnl_ct_test_use(const struct nfnl_ct *);
-extern uint32_t nfnl_ct_get_use(const struct nfnl_ct *);
+extern void nfnl_ct_set_use(struct nfnl_ct *, uint32_t);
+extern int nfnl_ct_test_use(const struct nfnl_ct *);
+extern uint32_t nfnl_ct_get_use(const struct nfnl_ct *);
-extern void nfnl_ct_set_id(struct nfnl_ct *, uint32_t);
-extern int nfnl_ct_test_id(const struct nfnl_ct *);
-extern uint32_t nfnl_ct_get_id(const struct nfnl_ct *);
+extern void nfnl_ct_set_id(struct nfnl_ct *, uint32_t);
+extern int nfnl_ct_test_id(const struct nfnl_ct *);
+extern uint32_t nfnl_ct_get_id(const struct nfnl_ct *);
-extern int nfnl_ct_set_src(struct nfnl_ct *, int,
- struct nl_addr *);
+extern int nfnl_ct_set_src(struct nfnl_ct *, int, struct nl_addr *);
extern struct nl_addr * nfnl_ct_get_src(const struct nfnl_ct *, int);
-extern int nfnl_ct_set_dst(struct nfnl_ct *, int,
- struct nl_addr *);
+extern int nfnl_ct_set_dst(struct nfnl_ct *, int, struct nl_addr *);
extern struct nl_addr * nfnl_ct_get_dst(const struct nfnl_ct *, int);
-extern void nfnl_ct_set_src_port(struct nfnl_ct *, int, uint16_t);
-extern int nfnl_ct_test_src_port(const struct nfnl_ct *, int);
-extern uint16_t nfnl_ct_get_src_port(const struct nfnl_ct *, int);
+extern void nfnl_ct_set_src_port(struct nfnl_ct *, int, uint16_t);
+extern int nfnl_ct_test_src_port(const struct nfnl_ct *, int);
+extern uint16_t nfnl_ct_get_src_port(const struct nfnl_ct *, int);
-extern void nfnl_ct_set_dst_port(struct nfnl_ct *, int, uint16_t);
-extern int nfnl_ct_test_dst_port(const struct nfnl_ct *, int);
-extern uint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *, int);
+extern void nfnl_ct_set_dst_port(struct nfnl_ct *, int, uint16_t);
+extern int nfnl_ct_test_dst_port(const struct nfnl_ct *, int);
+extern uint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *, int);
-extern void nfnl_ct_set_icmp_id(struct nfnl_ct *, int, uint16_t);
-extern int nfnl_ct_test_icmp_id(const struct nfnl_ct *, int);
-extern uint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *, int);
+extern void nfnl_ct_set_icmp_id(struct nfnl_ct *, int, uint16_t);
+extern int nfnl_ct_test_icmp_id(const struct nfnl_ct *, int);
+extern uint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *, int);
-extern void nfnl_ct_set_icmp_type(struct nfnl_ct *, int, uint8_t);
-extern int nfnl_ct_test_icmp_type(const struct nfnl_ct *, int);
-extern uint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *, int);
+extern void nfnl_ct_set_icmp_type(struct nfnl_ct *, int, uint8_t);
+extern int nfnl_ct_test_icmp_type(const struct nfnl_ct *, int);
+extern uint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *, int);
-extern void nfnl_ct_set_icmp_code(struct nfnl_ct *, int, uint8_t);
-extern int nfnl_ct_test_icmp_code(const struct nfnl_ct *, int);
-extern uint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *, int);
+extern void nfnl_ct_set_icmp_code(struct nfnl_ct *, int, uint8_t);
+extern int nfnl_ct_test_icmp_code(const struct nfnl_ct *, int);
+extern uint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *, int);
-extern void nfnl_ct_set_packets(struct nfnl_ct *, int, uint64_t);
-extern int nfnl_ct_test_packets(const struct nfnl_ct *, int);
-extern uint64_t nfnl_ct_get_packets(const struct nfnl_ct *,int);
+extern void nfnl_ct_set_packets(struct nfnl_ct *, int, uint64_t);
+extern int nfnl_ct_test_packets(const struct nfnl_ct *, int);
+extern uint64_t nfnl_ct_get_packets(const struct nfnl_ct *,int);
-extern void nfnl_ct_set_bytes(struct nfnl_ct *, int, uint64_t);
-extern int nfnl_ct_test_bytes(const struct nfnl_ct *, int);
-extern uint64_t nfnl_ct_get_bytes(const struct nfnl_ct *, int);
+extern void nfnl_ct_set_bytes(struct nfnl_ct *, int, uint64_t);
+extern int nfnl_ct_test_bytes(const struct nfnl_ct *, int);
+extern uint64_t nfnl_ct_get_bytes(const struct nfnl_ct *, int);
#ifdef __cplusplus
}
diff --git a/include/netlink/netfilter/log.h b/include/netlink/netfilter/log.h
index 51f4a90..be8dd32 100644
--- a/include/netlink/netfilter/log.h
+++ b/include/netlink/netfilter/log.h
@@ -40,7 +40,8 @@
/* General */
extern struct nfnl_log * nfnl_log_alloc(void);
-extern struct nfnl_log * nfnlmsg_log_parse(struct nlmsghdr *);
+extern int nfnlmsg_log_parse(struct nlmsghdr *,
+ struct nfnl_log **);
extern void nfnl_log_get(struct nfnl_log *);
extern void nfnl_log_put(struct nfnl_log *);
@@ -82,24 +83,23 @@
extern char * nfnl_log_flags2str(unsigned int, char *, size_t);
extern unsigned int nfnl_log_str2flags(const char *);
-/* Message construction / sending */
-extern struct nl_msg * nfnl_log_build_pf_bind(uint8_t);
-extern int nfnl_log_pf_bind(struct nl_handle *, uint8_t);
+extern int nfnl_log_build_pf_bind(uint8_t, struct nl_msg **);
+extern int nfnl_log_pf_bind(struct nl_handle *, uint8_t);
-extern struct nl_msg * nfnl_log_build_pf_unbind(uint8_t);
-extern int nfnl_log_pf_unbind(struct nl_handle *, uint8_t);
+extern int nfnl_log_build_pf_unbind(uint8_t, struct nl_msg **);
+extern int nfnl_log_pf_unbind(struct nl_handle *, uint8_t);
-extern struct nl_msg * nfnl_log_build_create_request(const struct nfnl_log *);
-extern int nfnl_log_create(struct nl_handle *,
- const struct nfnl_log *);
+extern int nfnl_log_build_create_request(const struct nfnl_log *,
+ struct nl_msg **);
+extern int nfnl_log_create(struct nl_handle *, const struct nfnl_log *);
-extern struct nl_msg * nfnl_log_build_change_request(const struct nfnl_log *);
-extern int nfnl_log_change(struct nl_handle *,
- const struct nfnl_log *);
+extern int nfnl_log_build_change_request(const struct nfnl_log *,
+ struct nl_msg **);
+extern int nfnl_log_change(struct nl_handle *, const struct nfnl_log *);
-extern struct nl_msg * nfnl_log_build_delete_request(const struct nfnl_log *);
-extern int nfnl_log_delete(struct nl_handle *,
- const struct nfnl_log *);
+extern int nfnl_log_build_delete_request(const struct nfnl_log *,
+ struct nl_msg **);
+extern int nfnl_log_delete(struct nl_handle *, const struct nfnl_log *);
#ifdef __cplusplus
}
diff --git a/include/netlink/netfilter/log_msg.h b/include/netlink/netfilter/log_msg.h
index 0cdb6c6..42e1f70 100644
--- a/include/netlink/netfilter/log_msg.h
+++ b/include/netlink/netfilter/log_msg.h
@@ -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>
@@ -29,7 +29,8 @@
/* General */
extern struct nfnl_log_msg *nfnl_log_msg_alloc(void);
-extern struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *);
+extern int nfnlmsg_log_msg_parse(struct nlmsghdr *,
+ struct nfnl_log_msg **);
extern void nfnl_log_msg_get(struct nfnl_log_msg *);
extern void nfnl_log_msg_put(struct nfnl_log_msg *);
diff --git a/include/netlink/netfilter/queue.h b/include/netlink/netfilter/queue.h
index c88abe2..d480135 100644
--- a/include/netlink/netfilter/queue.h
+++ b/include/netlink/netfilter/queue.h
@@ -59,24 +59,26 @@
extern int nfnl_queue_test_copy_range(const struct nfnl_queue *);
extern uint32_t nfnl_queue_get_copy_range(const struct nfnl_queue *);
-/* Message construction / sending */
-extern struct nl_msg * nfnl_queue_build_pf_bind(uint8_t);
-extern int nfnl_queue_pf_bind(struct nl_handle *, uint8_t);
+extern int nfnl_queue_build_pf_bind(uint8_t, struct nl_msg **);
+extern int nfnl_queue_pf_bind(struct nl_handle *, uint8_t);
-extern struct nl_msg * nfnl_queue_build_pf_unbind(uint8_t);
-extern int nfnl_queue_pf_unbind(struct nl_handle *, uint8_t);
+extern int nfnl_queue_build_pf_unbind(uint8_t, struct nl_msg **);
+extern int nfnl_queue_pf_unbind(struct nl_handle *, uint8_t);
-extern struct nl_msg * nfnl_queue_build_create_request(const struct nfnl_queue *);
-extern int nfnl_queue_create(struct nl_handle *,
- const struct nfnl_queue *);
+extern int nfnl_queue_build_create_request(const struct nfnl_queue *,
+ struct nl_msg **);
+extern int nfnl_queue_create(struct nl_handle *,
+ const struct nfnl_queue *);
-extern struct nl_msg * nfnl_queue_build_change_request(const struct nfnl_queue *);
-extern int nfnl_queue_change(struct nl_handle *,
- const struct nfnl_queue *);
+extern int nfnl_queue_build_change_request(const struct nfnl_queue *,
+ struct nl_msg **);
+extern int nfnl_queue_change(struct nl_handle *,
+ const struct nfnl_queue *);
-extern struct nl_msg * nfnl_queue_build_delete_request(const struct nfnl_queue *);
-extern int nfnl_queue_delete(struct nl_handle *,
- const struct nfnl_queue *);
+extern int nfnl_queue_build_delete_request(const struct nfnl_queue *,
+ struct nl_msg **);
+extern int nfnl_queue_delete(struct nl_handle *,
+ const struct nfnl_queue *);
#ifdef __cplusplus
}
diff --git a/include/netlink/netfilter/queue_msg.h b/include/netlink/netfilter/queue_msg.h
index bb63236..f8f034c 100644
--- a/include/netlink/netfilter/queue_msg.h
+++ b/include/netlink/netfilter/queue_msg.h
@@ -26,7 +26,8 @@
/* General */
extern struct nfnl_queue_msg * nfnl_queue_msg_alloc(void);
-extern struct nfnl_queue_msg * nfnlmsg_queue_msg_parse(struct nlmsghdr *);
+extern int nfnlmsg_queue_msg_parse(struct nlmsghdr *,
+ struct nfnl_queue_msg **);
extern void nfnl_queue_msg_get(struct nfnl_queue_msg *);
extern void nfnl_queue_msg_put(struct nfnl_queue_msg *);
diff --git a/include/netlink/netlink.h b/include/netlink/netlink.h
index bfae909..eff4b16 100644
--- a/include/netlink/netlink.h
+++ b/include/netlink/netlink.h
@@ -26,6 +26,7 @@
#include <linux/genetlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <netlink/version.h>
+#include <netlink/errno.h>
#include <netlink/types.h>
#include <netlink/handlers.h>
#include <netlink/socket.h>
diff --git a/include/netlink/object.h b/include/netlink/object.h
index 751a1b3..bae2bf4 100644
--- a/include/netlink/object.h
+++ b/include/netlink/object.h
@@ -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>
*/
#ifndef NETLINK_OBJECT_H_
@@ -27,7 +27,8 @@
/* General */
extern struct nl_object * nl_object_alloc(struct nl_object_ops *);
-extern struct nl_object * nl_object_alloc_name(const char *);
+extern int nl_object_alloc_name(const char *,
+ struct nl_object **);
extern void nl_object_free(struct nl_object *);
extern struct nl_object * nl_object_clone(struct nl_object *obj);
extern void nl_object_get(struct nl_object *);
diff --git a/include/netlink/route/addr.h b/include/netlink/route/addr.h
index 71a90e0..9004ca0 100644
--- a/include/netlink/route/addr.h
+++ b/include/netlink/route/addr.h
@@ -6,8 +6,8 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
- * Baruch Even <baruch@ev-en.org>,
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>,
* Mediatrix Telecom, inc. <ericb@mediatrix.com>
*/
@@ -26,63 +26,56 @@
/* General */
extern struct rtnl_addr *rtnl_addr_alloc(void);
-extern void rtnl_addr_put(struct rtnl_addr *);
+extern void rtnl_addr_put(struct rtnl_addr *);
-extern struct nl_cache *rtnl_addr_alloc_cache(struct nl_handle *);
+extern int rtnl_addr_alloc_cache(struct nl_handle *, struct nl_cache **);
-/* Address Addition */
-extern struct nl_msg * rtnl_addr_build_add_request(struct rtnl_addr *, int);
-extern int rtnl_addr_add(struct nl_handle *, struct rtnl_addr *,
- int);
+extern int rtnl_addr_build_add_request(struct rtnl_addr *, int,
+ struct nl_msg **);
+extern int rtnl_addr_add(struct nl_handle *, struct rtnl_addr *, int);
-/* Address Deletion */
-extern struct nl_msg * rtnl_addr_build_delete_request(struct rtnl_addr *, int);
-extern int rtnl_addr_delete(struct nl_handle *,
- struct rtnl_addr *, int);
+extern int rtnl_addr_build_delete_request(struct rtnl_addr *, int,
+ struct nl_msg **);
+extern int rtnl_addr_delete(struct nl_handle *,
+ struct rtnl_addr *, int);
-/* Address Flags Translations */
-extern char * rtnl_addr_flags2str(int, char *, size_t);
-extern int rtnl_addr_str2flags(const char *);
+extern char * rtnl_addr_flags2str(int, char *, size_t);
+extern int rtnl_addr_str2flags(const char *);
-/* Attribute Access */
-extern void rtnl_addr_set_label(struct rtnl_addr *, const char *);
-extern char * rtnl_addr_get_label(struct rtnl_addr *);
+extern void rtnl_addr_set_label(struct rtnl_addr *, const char *);
+extern char * rtnl_addr_get_label(struct rtnl_addr *);
-extern void rtnl_addr_set_ifindex(struct rtnl_addr *, int);
-extern int rtnl_addr_get_ifindex(struct rtnl_addr *);
+extern void rtnl_addr_set_ifindex(struct rtnl_addr *, int);
+extern int rtnl_addr_get_ifindex(struct rtnl_addr *);
-extern void rtnl_addr_set_family(struct rtnl_addr *, int);
-extern int rtnl_addr_get_family(struct rtnl_addr *);
+extern void rtnl_addr_set_family(struct rtnl_addr *, int);
+extern int rtnl_addr_get_family(struct rtnl_addr *);
-extern void rtnl_addr_set_prefixlen(struct rtnl_addr *, int);
-extern int rtnl_addr_get_prefixlen(struct rtnl_addr *);
+extern void rtnl_addr_set_prefixlen(struct rtnl_addr *, int);
+extern int rtnl_addr_get_prefixlen(struct rtnl_addr *);
-extern void rtnl_addr_set_scope(struct rtnl_addr *, int);
-extern int rtnl_addr_get_scope(struct rtnl_addr *);
+extern void rtnl_addr_set_scope(struct rtnl_addr *, int);
+extern int rtnl_addr_get_scope(struct rtnl_addr *);
-extern void rtnl_addr_set_flags(struct rtnl_addr *, unsigned int);
-extern void rtnl_addr_unset_flags(struct rtnl_addr *, unsigned int);
-extern unsigned int rtnl_addr_get_flags(struct rtnl_addr *);
+extern void rtnl_addr_set_flags(struct rtnl_addr *, unsigned int);
+extern void rtnl_addr_unset_flags(struct rtnl_addr *, unsigned int);
+extern unsigned int rtnl_addr_get_flags(struct rtnl_addr *);
-extern int rtnl_addr_set_local(struct rtnl_addr *,
+extern int rtnl_addr_set_local(struct rtnl_addr *,
struct nl_addr *);
-extern struct nl_addr * rtnl_addr_get_local(struct rtnl_addr *);
+extern struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *);
-extern int rtnl_addr_set_peer(struct rtnl_addr *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_addr_get_peer(struct rtnl_addr *);
+extern int rtnl_addr_set_peer(struct rtnl_addr *, struct nl_addr *);
+extern struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *);
-extern int rtnl_addr_set_broadcast(struct rtnl_addr *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_addr_get_broadcast(struct rtnl_addr *);
+extern int rtnl_addr_set_broadcast(struct rtnl_addr *, struct nl_addr *);
+extern struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *);
-extern int rtnl_addr_set_anycast(struct rtnl_addr *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_addr_get_anycast(struct rtnl_addr *);
+extern int rtnl_addr_set_anycast(struct rtnl_addr *, struct nl_addr *);
+extern struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *);
-extern int rtnl_addr_set_multicast(struct rtnl_addr *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_addr_get_multicast(struct rtnl_addr *);
+extern int rtnl_addr_set_multicast(struct rtnl_addr *, struct nl_addr *);
+extern struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *);
#ifdef __cplusplus
}
diff --git a/include/netlink/route/class.h b/include/netlink/route/class.h
index a624ef6..a704ed1 100644
--- a/include/netlink/route/class.h
+++ b/include/netlink/route/class.h
@@ -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>
*/
#ifndef NETLINK_CLASS_H_
@@ -24,20 +24,20 @@
extern struct nl_object_ops class_obj_ops;
-/* General */
extern struct rtnl_class * rtnl_class_alloc(void);
-extern void rtnl_class_put(struct rtnl_class *);
-extern struct nl_cache * rtnl_class_alloc_cache(struct nl_handle *, int);
+extern void rtnl_class_put(struct rtnl_class *);
+extern int rtnl_class_alloc_cache(struct nl_handle *, int,
+ struct nl_cache **);
/* leaf qdisc access */
extern struct rtnl_qdisc * rtnl_class_leaf_qdisc(struct rtnl_class *,
struct nl_cache *);
-/* class addition */
-extern struct nl_msg * rtnl_class_build_add_request(struct rtnl_class *, int);
-extern int rtnl_class_add(struct nl_handle *, struct rtnl_class *, int);
+extern int rtnl_class_build_add_request(struct rtnl_class *, int,
+ struct nl_msg **);
+extern int rtnl_class_add(struct nl_handle *, struct rtnl_class *,
+ int);
-/* attribute modification */
extern void rtnl_class_set_ifindex(struct rtnl_class *, int);
extern int rtnl_class_get_ifindex(struct rtnl_class *);
extern void rtnl_class_set_handle(struct rtnl_class *, uint32_t);
diff --git a/include/netlink/route/classifier.h b/include/netlink/route/classifier.h
index 7ef0da4..0ee563e 100644
--- a/include/netlink/route/classifier.h
+++ b/include/netlink/route/classifier.h
@@ -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>
*/
#ifndef NETLINK_CLASSIFIER_H_
@@ -23,21 +23,22 @@
extern struct nl_object_ops cls_obj_ops;
-extern struct rtnl_cls *rtnl_cls_alloc(void);
-extern void rtnl_cls_put(struct rtnl_cls *);
+extern struct rtnl_cls *rtnl_cls_alloc(void);
+extern void rtnl_cls_put(struct rtnl_cls *);
-extern struct nl_cache *rtnl_cls_alloc_cache(struct nl_handle *, int, uint32_t);
+extern int rtnl_cls_alloc_cache(struct nl_handle *, int, uint32_t,
+ struct nl_cache **);
-/* classifier addition */
-extern int rtnl_cls_add(struct nl_handle *, struct rtnl_cls *,
- int);
-extern struct nl_msg * rtnl_cls_build_add_request(struct rtnl_cls *, int);
+extern int rtnl_cls_build_add_request(struct rtnl_cls *, int,
+ struct nl_msg **);
+extern int rtnl_cls_add(struct nl_handle *, struct rtnl_cls *, int);
-extern struct nl_msg *rtnl_cls_build_change_request(struct rtnl_cls *, int);
-extern struct nl_msg *rtnl_cls_build_delete_request(struct rtnl_cls *, int);
-extern int rtnl_cls_delete(struct nl_handle *, struct rtnl_cls *, int);
+extern int rtnl_cls_build_change_request(struct rtnl_cls *, int,
+ struct nl_msg **);
+extern int rtnl_cls_build_delete_request(struct rtnl_cls *, int,
+ struct nl_msg **);
+extern int rtnl_cls_delete(struct nl_handle *, struct rtnl_cls *, int);
-/* attribute modification */
extern void rtnl_cls_set_ifindex(struct rtnl_cls *, int);
extern void rtnl_cls_set_handle(struct rtnl_cls *, uint32_t);
extern void rtnl_cls_set_parent(struct rtnl_cls *, uint32_t);
diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h
index caaa792..87e5ada 100644
--- a/include/netlink/route/link.h
+++ b/include/netlink/route/link.h
@@ -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>
*/
#ifndef NETLINK_LINK_H_
@@ -58,109 +58,91 @@
#define RTNL_LINK_NOT_FOUND -1
/* link object allocation/freeage */
-extern struct rtnl_link * rtnl_link_alloc(void);
-extern void rtnl_link_put(struct rtnl_link *);
-extern void rtnl_link_free(struct rtnl_link *);
+extern struct rtnl_link *rtnl_link_alloc(void);
+extern void rtnl_link_put(struct rtnl_link *);
+extern void rtnl_link_free(struct rtnl_link *);
/* link cache management */
-extern struct nl_cache * rtnl_link_alloc_cache(struct nl_handle *);
-extern struct rtnl_link * rtnl_link_get(struct nl_cache *, int);
-extern struct rtnl_link * rtnl_link_get_by_name(struct nl_cache *,
- const char *);
+extern int rtnl_link_alloc_cache(struct nl_handle *, struct nl_cache **);
+extern struct rtnl_link *rtnl_link_get(struct nl_cache *, int);
+extern struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *, const char *);
-/* Link Modifications */
-extern struct nl_msg * rtnl_link_build_change_request(struct rtnl_link *,
- struct rtnl_link *,
- int);
-extern int rtnl_link_change(struct nl_handle *,
- struct rtnl_link *,
- struct rtnl_link *, int);
+extern int rtnl_link_build_change_request(struct rtnl_link *,
+ struct rtnl_link *, int,
+ struct nl_msg **);
+extern int rtnl_link_change(struct nl_handle *, struct rtnl_link *,
+ struct rtnl_link *, int);
/* Name <-> Index Translations */
-extern char * rtnl_link_i2name(struct nl_cache *, int,
- char *, size_t);
-extern int rtnl_link_name2i(struct nl_cache *,
- const char *);
+extern char * rtnl_link_i2name(struct nl_cache *, int, char *, size_t);
+extern int rtnl_link_name2i(struct nl_cache *, const char *);
/* Name <-> Statistic Translations */
-extern char * rtnl_link_stat2str(int, char *, size_t);
-extern int rtnl_link_str2stat(const char *);
+extern char * rtnl_link_stat2str(int, char *, size_t);
+extern int rtnl_link_str2stat(const char *);
/* Link Flags Translations */
-extern char * rtnl_link_flags2str(int, char *, size_t);
-extern int rtnl_link_str2flags(const char *);
+extern char * rtnl_link_flags2str(int, char *, size_t);
+extern int rtnl_link_str2flags(const char *);
-extern char * rtnl_link_operstate2str(int, char *, size_t);
-extern int rtnl_link_str2operstate(const char *);
+extern char * rtnl_link_operstate2str(int, char *, size_t);
+extern int rtnl_link_str2operstate(const char *);
-extern char * rtnl_link_mode2str(int, char *, size_t);
-extern int rtnl_link_str2mode(const char *);
+extern char * rtnl_link_mode2str(int, char *, size_t);
+extern int rtnl_link_str2mode(const char *);
/* Access Functions */
-extern void rtnl_link_set_qdisc(struct rtnl_link *,
- const char *);
-extern char * rtnl_link_get_qdisc(struct rtnl_link *);
+extern void rtnl_link_set_qdisc(struct rtnl_link *, const char *);
+extern char * rtnl_link_get_qdisc(struct rtnl_link *);
-extern void rtnl_link_set_name(struct rtnl_link *,
- const char *);
-extern char * rtnl_link_get_name(struct rtnl_link *);
+extern void rtnl_link_set_name(struct rtnl_link *, const char *);
+extern char * rtnl_link_get_name(struct rtnl_link *);
-extern void rtnl_link_set_flags(struct rtnl_link *,
- unsigned int);
-extern void rtnl_link_unset_flags(struct rtnl_link *,
- unsigned int);
-extern unsigned int rtnl_link_get_flags(struct rtnl_link *);
+extern void rtnl_link_set_flags(struct rtnl_link *, unsigned int);
+extern void rtnl_link_unset_flags(struct rtnl_link *, unsigned int);
+extern unsigned int rtnl_link_get_flags(struct rtnl_link *);
-extern void rtnl_link_set_mtu(struct rtnl_link *,
- unsigned int);
-extern unsigned int rtnl_link_get_mtu(struct rtnl_link *);
+extern void rtnl_link_set_mtu(struct rtnl_link *, unsigned int);
+extern unsigned int rtnl_link_get_mtu(struct rtnl_link *);
-extern void rtnl_link_set_txqlen(struct rtnl_link *,
- unsigned int);
-extern unsigned int rtnl_link_get_txqlen(struct rtnl_link *);
+extern void rtnl_link_set_txqlen(struct rtnl_link *, unsigned int);
+extern unsigned int rtnl_link_get_txqlen(struct rtnl_link *);
-extern void rtnl_link_set_weight(struct rtnl_link *,
- unsigned int);
-extern unsigned int rtnl_link_get_weight(struct rtnl_link *);
+extern void rtnl_link_set_weight(struct rtnl_link *, unsigned int);
+extern unsigned int rtnl_link_get_weight(struct rtnl_link *);
-extern void rtnl_link_set_ifindex(struct rtnl_link *, int);
-extern int rtnl_link_get_ifindex(struct rtnl_link *);
+extern void rtnl_link_set_ifindex(struct rtnl_link *, int);
+extern int rtnl_link_get_ifindex(struct rtnl_link *);
-extern void rtnl_link_set_family(struct rtnl_link *, int);
-extern int rtnl_link_get_family(struct rtnl_link *);
+extern void rtnl_link_set_family(struct rtnl_link *, int);
+extern int rtnl_link_get_family(struct rtnl_link *);
-extern void rtnl_link_set_arptype(struct rtnl_link *,
- unsigned int);
-extern unsigned int rtnl_link_get_arptype(struct rtnl_link *);
+extern void rtnl_link_set_arptype(struct rtnl_link *, unsigned int);
+extern unsigned int rtnl_link_get_arptype(struct rtnl_link *);
-extern void rtnl_link_set_addr(struct rtnl_link *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_link_get_addr(struct rtnl_link *);
+extern void rtnl_link_set_addr(struct rtnl_link *, struct nl_addr *);
+extern struct nl_addr *rtnl_link_get_addr(struct rtnl_link *);
-extern void rtnl_link_set_broadcast(struct rtnl_link *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_link_get_broadcast(struct rtnl_link *);
+extern void rtnl_link_set_broadcast(struct rtnl_link *, struct nl_addr *);
+extern struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *);
-extern void rtnl_link_set_link(struct rtnl_link *, int);
-extern int rtnl_link_get_link(struct rtnl_link *);
+extern void rtnl_link_set_link(struct rtnl_link *, int);
+extern int rtnl_link_get_link(struct rtnl_link *);
-extern void rtnl_link_set_master(struct rtnl_link *, int);
-extern int rtnl_link_get_master(struct rtnl_link *);
+extern void rtnl_link_set_master(struct rtnl_link *, int);
+extern int rtnl_link_get_master(struct rtnl_link *);
-extern void rtnl_link_set_operstate(struct rtnl_link *,
- uint8_t);
-extern uint8_t rtnl_link_get_operstate(struct rtnl_link *);
+extern void rtnl_link_set_operstate(struct rtnl_link *, uint8_t);
+extern uint8_t rtnl_link_get_operstate(struct rtnl_link *);
-extern void rtnl_link_set_linkmode(struct rtnl_link *,
- uint8_t);
-extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *);
+extern void rtnl_link_set_linkmode(struct rtnl_link *, uint8_t);
+extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *);
-extern uint64_t rtnl_link_get_stat(struct rtnl_link *, int);
+extern uint64_t rtnl_link_get_stat(struct rtnl_link *, int);
-extern int rtnl_link_set_info_type(struct rtnl_link *,
- const char *);
-extern char * rtnl_link_get_info_type(struct rtnl_link *);
+extern int rtnl_link_set_info_type(struct rtnl_link *, const char *);
+extern char * rtnl_link_get_info_type(struct rtnl_link *);
#ifdef __cplusplus
}
diff --git a/include/netlink/route/neighbour.h b/include/netlink/route/neighbour.h
index 078c3f4..7b5ed24 100644
--- a/include/netlink/route/neighbour.h
+++ b/include/netlink/route/neighbour.h
@@ -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>
*/
#ifndef NETLINK_NEIGHBOUR_H_
@@ -22,39 +22,31 @@
struct rtnl_neigh;
-/* neighbour object allocation/freeage */
-extern struct rtnl_neigh * rtnl_neigh_alloc(void);
-extern void rtnl_neigh_put(struct rtnl_neigh *);
+extern struct rtnl_neigh *rtnl_neigh_alloc(void);
+extern void rtnl_neigh_put(struct rtnl_neigh *);
-/* neighbour cache management */
-extern struct nl_cache * rtnl_neigh_alloc_cache(struct nl_handle *);
-extern struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *, int,
+extern int rtnl_neigh_alloc_cache(struct nl_handle *, struct nl_cache **);
+extern struct rtnl_neigh *rtnl_neigh_get(struct nl_cache *, int,
struct nl_addr *);
-/* Neigbour state translations */
-extern char * rtnl_neigh_state2str(int, char *, size_t);
-extern int rtnl_neigh_str2state(const char *);
+extern char * rtnl_neigh_state2str(int, char *, size_t);
+extern int rtnl_neigh_str2state(const char *);
-/* Neighbour flags translations */
-extern char * rtnl_neigh_flags2str(int, char *, size_t);
-extern int rtnl_neigh_str2flag(const char *);
+extern char * rtnl_neigh_flags2str(int, char *, size_t);
+extern int rtnl_neigh_str2flag(const char *);
-/* Neighbour Addition */
-extern int rtnl_neigh_add(struct nl_handle *,
- struct rtnl_neigh *, int);
-extern struct nl_msg * rtnl_neigh_build_add_request(struct rtnl_neigh *, int);
+extern int rtnl_neigh_add(struct nl_handle *, struct rtnl_neigh *, int);
+extern int rtnl_neigh_build_add_request(struct rtnl_neigh *, int,
+ struct nl_msg **);
-/* Neighbour Modification */
-extern int rtnl_neigh_change(struct nl_handle *,
- struct rtnl_neigh *, int);
-extern struct nl_msg * rtnl_neigh_build_change_request(struct rtnl_neigh *, int);
+extern int rtnl_neigh_change(struct nl_handle *, struct rtnl_neigh *, int);
+extern int rtnl_neigh_build_change_request(struct rtnl_neigh *, int,
+ struct nl_msg **);
-/* Neighbour Deletion */
-extern int rtnl_neigh_delete(struct nl_handle *,
- struct rtnl_neigh *, int);
-extern struct nl_msg * rtnl_neigh_build_delete_request(struct rtnl_neigh *, int);
+extern int rtnl_neigh_delete(struct nl_handle *, struct rtnl_neigh *, int);
+extern int rtnl_neigh_build_delete_request(struct rtnl_neigh *, int,
+ struct nl_msg **);
-/* Access functions */
extern void rtnl_neigh_set_state(struct rtnl_neigh *, int);
extern int rtnl_neigh_get_state(struct rtnl_neigh *);
extern void rtnl_neigh_unset_state(struct rtnl_neigh *,
diff --git a/include/netlink/route/neightbl.h b/include/netlink/route/neightbl.h
index 20285ee..7120053 100644
--- a/include/netlink/route/neightbl.h
+++ b/include/netlink/route/neightbl.h
@@ -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>
*/
#ifndef NETLINK_NEIGHTBL_H_
@@ -25,14 +25,15 @@
extern struct rtnl_neightbl *rtnl_neightbl_alloc(void);
extern void rtnl_neightbl_put(struct rtnl_neightbl *);
extern void rtnl_neightbl_free(struct rtnl_neightbl *);
-extern struct nl_cache *rtnl_neightbl_alloc_cache(struct nl_handle *);
+extern int rtnl_neightbl_alloc_cache(struct nl_handle *, struct nl_cache **);
extern struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *,
const char *, int);
extern void rtnl_neightbl_dump(struct rtnl_neightbl *, FILE *,
struct nl_dump_params *);
-extern struct nl_msg *rtnl_neightbl_build_change_request(struct rtnl_neightbl *,
- struct rtnl_neightbl *);
+extern int rtnl_neightbl_build_change_request(struct rtnl_neightbl *,
+ struct rtnl_neightbl *,
+ struct nl_msg **);
extern int rtnl_neightbl_change(struct nl_handle *, struct rtnl_neightbl *,
struct rtnl_neightbl *);
diff --git a/include/netlink/route/qdisc.h b/include/netlink/route/qdisc.h
index ee71304..d3bc99b 100644
--- a/include/netlink/route/qdisc.h
+++ b/include/netlink/route/qdisc.h
@@ -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>
*/
#ifndef NETLINK_QDISC_H_
@@ -24,60 +24,46 @@
extern struct nl_object_ops qdisc_obj_ops;
-/* General */
-extern struct rtnl_qdisc * rtnl_qdisc_alloc(void);
-extern void rtnl_qdisc_put(struct rtnl_qdisc *);
+extern struct rtnl_qdisc *rtnl_qdisc_alloc(void);
+extern void rtnl_qdisc_put(struct rtnl_qdisc *);
-/* Cache Management */
-extern struct nl_cache * rtnl_qdisc_alloc_cache(struct nl_handle *);
-extern struct rtnl_qdisc * rtnl_qdisc_get(struct nl_cache *,
- int, uint32_t);
-extern struct rtnl_qdisc * rtnl_qdisc_get_by_parent(struct nl_cache *,
- int, uint32_t);
+extern int rtnl_qdisc_alloc_cache(struct nl_handle *, struct nl_cache **);
+extern struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *, int, uint32_t);
+extern struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *,
+ int, uint32_t);
-/* qdisc addition */
-extern struct nl_msg * rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int);
-extern int rtnl_qdisc_add(struct nl_handle *, struct rtnl_qdisc *,
- int);
+extern int rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int,
+ struct nl_msg **);
+extern int rtnl_qdisc_add(struct nl_handle *, struct rtnl_qdisc *, int);
-/* qdisc modification */
-extern struct nl_msg * rtnl_qdisc_build_change_request(struct rtnl_qdisc *,
- struct rtnl_qdisc *);
-extern int rtnl_qdisc_change(struct nl_handle *,
- struct rtnl_qdisc *,
- struct rtnl_qdisc *);
+extern int rtnl_qdisc_build_change_request(struct rtnl_qdisc *,
+ struct rtnl_qdisc *,
+ struct nl_msg **);
+extern int rtnl_qdisc_change(struct nl_handle *, struct rtnl_qdisc *,
+ struct rtnl_qdisc *);
-/* qdisc deletion */
-extern struct nl_msg * rtnl_qdisc_build_delete_request(struct rtnl_qdisc *);
-extern int rtnl_qdisc_delete(struct nl_handle *,
- struct rtnl_qdisc *);
+extern int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *,
+ struct nl_msg **);
+extern int rtnl_qdisc_delete(struct nl_handle *, struct rtnl_qdisc *);
-/* attribute modifications */
-extern void rtnl_qdisc_set_ifindex(struct rtnl_qdisc *, int);
-extern int rtnl_qdisc_get_ifindex(struct rtnl_qdisc *);
-extern void rtnl_qdisc_set_handle(struct rtnl_qdisc *, uint32_t);
-extern uint32_t rtnl_qdisc_get_handle(struct rtnl_qdisc *);
-extern void rtnl_qdisc_set_parent(struct rtnl_qdisc *, uint32_t);
-extern uint32_t rtnl_qdisc_get_parent(struct rtnl_qdisc *);
-extern void rtnl_qdisc_set_kind(struct rtnl_qdisc *, const char *);
-extern char * rtnl_qdisc_get_kind(struct rtnl_qdisc *);
-extern uint64_t rtnl_qdisc_get_stat(struct rtnl_qdisc *,
- enum rtnl_tc_stats_id);
+extern void rtnl_qdisc_set_ifindex(struct rtnl_qdisc *, int);
+extern int rtnl_qdisc_get_ifindex(struct rtnl_qdisc *);
+extern void rtnl_qdisc_set_handle(struct rtnl_qdisc *, uint32_t);
+extern uint32_t rtnl_qdisc_get_handle(struct rtnl_qdisc *);
+extern void rtnl_qdisc_set_parent(struct rtnl_qdisc *, uint32_t);
+extern uint32_t rtnl_qdisc_get_parent(struct rtnl_qdisc *);
+extern void rtnl_qdisc_set_kind(struct rtnl_qdisc *, const char *);
+extern char * rtnl_qdisc_get_kind(struct rtnl_qdisc *);
+extern uint64_t rtnl_qdisc_get_stat(struct rtnl_qdisc *, enum rtnl_tc_stats_id);
-/* iterators */
-extern void rtnl_qdisc_foreach_child(struct rtnl_qdisc *,
- struct nl_cache *,
- void (*cb)(struct nl_object *,
- void *),
- void *);
+extern void rtnl_qdisc_foreach_child(struct rtnl_qdisc *, struct nl_cache *,
+ void (*cb)(struct nl_object *, void *),
+ void *);
-extern void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *,
- struct nl_cache *,
- void (*cb)(struct nl_object *,
- void *),
- void *);
+extern void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *, struct nl_cache *,
+ void (*cb)(struct nl_object *, void *),
+ void *);
-/* qdisc specific options */
extern struct nl_msg * rtnl_qdisc_get_opts(struct rtnl_qdisc *);
#ifdef __cplusplus
diff --git a/include/netlink/route/route.h b/include/netlink/route/route.h
index 071f2c5..b3a9b9e 100644
--- a/include/netlink/route/route.h
+++ b/include/netlink/route/route.h
@@ -42,84 +42,79 @@
extern struct nl_object_ops route_obj_ops;
-/* General */
extern struct rtnl_route * rtnl_route_alloc(void);
-extern void rtnl_route_put(struct rtnl_route *);
-extern struct nl_cache * rtnl_route_alloc_cache(struct nl_handle *,
- int, int);
+extern void rtnl_route_put(struct rtnl_route *);
+extern int rtnl_route_alloc_cache(struct nl_handle *, int, int,
+ struct nl_cache **);
-extern void rtnl_route_get(struct rtnl_route *);
-extern void rtnl_route_put(struct rtnl_route *);
+extern void rtnl_route_get(struct rtnl_route *);
+extern void rtnl_route_put(struct rtnl_route *);
-extern struct rtnl_route *rtnl_route_parse(struct nlmsghdr *);
-extern int rtnl_route_build_msg(struct nl_msg *,
- struct rtnl_route *);
+extern int rtnl_route_parse(struct nlmsghdr *, struct rtnl_route **);
+extern int rtnl_route_build_msg(struct nl_msg *, struct rtnl_route *);
-extern struct nl_msg *rtnl_route_build_add_request(struct rtnl_route *, int);
-extern int rtnl_route_add(struct nl_handle *, struct rtnl_route *, int);
-extern struct nl_msg *rtnl_route_build_del_request(struct rtnl_route *, int);
-extern int rtnl_route_delete(struct nl_handle *, struct rtnl_route *, int);
+extern int rtnl_route_build_add_request(struct rtnl_route *, int,
+ struct nl_msg **);
+extern int rtnl_route_add(struct nl_handle *, struct rtnl_route *, int);
+extern int rtnl_route_build_del_request(struct rtnl_route *, int,
+ struct nl_msg **);
+extern int rtnl_route_delete(struct nl_handle *, struct rtnl_route *, int);
-extern void rtnl_route_set_table(struct rtnl_route *, uint32_t);
-extern uint32_t rtnl_route_get_table(struct rtnl_route *);
-extern void rtnl_route_set_scope(struct rtnl_route *, uint8_t);
-extern uint8_t rtnl_route_get_scope(struct rtnl_route *);
-extern void rtnl_route_set_tos(struct rtnl_route *, uint8_t);
-extern uint8_t rtnl_route_get_tos(struct rtnl_route *);
-extern void rtnl_route_set_protocol(struct rtnl_route *, uint8_t);
-extern uint8_t rtnl_route_get_protocol(struct rtnl_route *);
-extern void rtnl_route_set_priority(struct rtnl_route *, uint32_t);
-extern uint32_t rtnl_route_get_priority(struct rtnl_route *);
-extern int rtnl_route_set_family(struct rtnl_route *, uint8_t);
-extern uint8_t rtnl_route_get_family(struct rtnl_route *);
-extern int rtnl_route_set_type(struct rtnl_route *, uint8_t);
-extern uint8_t rtnl_route_get_type(struct rtnl_route *);
-extern void rtnl_route_set_flags(struct rtnl_route *, uint32_t);
-extern void rtnl_route_unset_flags(struct rtnl_route *, uint32_t);
-extern uint32_t rtnl_route_get_flags(struct rtnl_route *);
-extern int rtnl_route_set_metric(struct rtnl_route *, int,
- unsigned int);
-extern int rtnl_route_unset_metric(struct rtnl_route *, int);
-extern int rtnl_route_get_metric(struct rtnl_route *, int,
- uint32_t *);
-extern int rtnl_route_set_dst(struct rtnl_route *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_route_get_dst(struct rtnl_route *);
-extern int rtnl_route_set_src(struct rtnl_route *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_route_get_src(struct rtnl_route *);
-extern int rtnl_route_set_pref_src(struct rtnl_route *,
- struct nl_addr *);
-extern struct nl_addr * rtnl_route_get_pref_src(struct rtnl_route *);
-extern void rtnl_route_set_iif(struct rtnl_route *, int);
-extern int rtnl_route_get_iif(struct rtnl_route *);
-extern int rtnl_route_get_src_len(struct rtnl_route *);
+extern void rtnl_route_set_table(struct rtnl_route *, uint32_t);
+extern uint32_t rtnl_route_get_table(struct rtnl_route *);
+extern void rtnl_route_set_scope(struct rtnl_route *, uint8_t);
+extern uint8_t rtnl_route_get_scope(struct rtnl_route *);
+extern void rtnl_route_set_tos(struct rtnl_route *, uint8_t);
+extern uint8_t rtnl_route_get_tos(struct rtnl_route *);
+extern void rtnl_route_set_protocol(struct rtnl_route *, uint8_t);
+extern uint8_t rtnl_route_get_protocol(struct rtnl_route *);
+extern void rtnl_route_set_priority(struct rtnl_route *, uint32_t);
+extern uint32_t rtnl_route_get_priority(struct rtnl_route *);
+extern int rtnl_route_set_family(struct rtnl_route *, uint8_t);
+extern uint8_t rtnl_route_get_family(struct rtnl_route *);
+extern int rtnl_route_set_type(struct rtnl_route *, uint8_t);
+extern uint8_t rtnl_route_get_type(struct rtnl_route *);
+extern void rtnl_route_set_flags(struct rtnl_route *, uint32_t);
+extern void rtnl_route_unset_flags(struct rtnl_route *, uint32_t);
+extern uint32_t rtnl_route_get_flags(struct rtnl_route *);
+extern int rtnl_route_set_metric(struct rtnl_route *, int, unsigned int);
+extern int rtnl_route_unset_metric(struct rtnl_route *, int);
+extern int rtnl_route_get_metric(struct rtnl_route *, int, uint32_t *);
+extern int rtnl_route_set_dst(struct rtnl_route *, struct nl_addr *);
+extern struct nl_addr *rtnl_route_get_dst(struct rtnl_route *);
+extern int rtnl_route_set_src(struct rtnl_route *, struct nl_addr *);
+extern struct nl_addr *rtnl_route_get_src(struct rtnl_route *);
+extern int rtnl_route_set_pref_src(struct rtnl_route *, struct nl_addr *);
+extern struct nl_addr *rtnl_route_get_pref_src(struct rtnl_route *);
+extern void rtnl_route_set_iif(struct rtnl_route *, int);
+extern int rtnl_route_get_iif(struct rtnl_route *);
+extern int rtnl_route_get_src_len(struct rtnl_route *);
-extern void rtnl_route_add_nexthop(struct rtnl_route *,
- struct rtnl_nexthop *);
-extern void rtnl_route_remove_nexthop(struct rtnl_route *,
- struct rtnl_nexthop *);
-extern struct nl_list_head * rtnl_route_get_nexthops(struct rtnl_route *);
-extern int rtnl_route_get_nnexthops(struct rtnl_route *);
+extern void rtnl_route_add_nexthop(struct rtnl_route *,
+ struct rtnl_nexthop *);
+extern void rtnl_route_remove_nexthop(struct rtnl_route *,
+ struct rtnl_nexthop *);
+extern struct nl_list_head *rtnl_route_get_nexthops(struct rtnl_route *);
+extern int rtnl_route_get_nnexthops(struct rtnl_route *);
-extern void rtnl_route_foreach_nexthop(struct rtnl_route *r,
+extern void rtnl_route_foreach_nexthop(struct rtnl_route *r,
void (*cb)(struct rtnl_nexthop *, void *),
void *arg);
extern struct rtnl_nexthop * rtnl_route_nexthop_n(struct rtnl_route *r, int n);
-extern int rtnl_route_guess_scope(struct rtnl_route *);
+extern int rtnl_route_guess_scope(struct rtnl_route *);
-extern char * rtnl_route_table2str(int, char *, size_t);
-extern int rtnl_route_str2table(const char *);
-extern int rtnl_route_read_table_names(const char *);
+extern char * rtnl_route_table2str(int, char *, size_t);
+extern int rtnl_route_str2table(const char *);
+extern int rtnl_route_read_table_names(const char *);
-extern char * rtnl_route_proto2str(int, char *, size_t);
-extern int rtnl_route_str2proto(const char *);
-extern int rtnl_route_read_protocol_names(const char *);
+extern char * rtnl_route_proto2str(int, char *, size_t);
+extern int rtnl_route_str2proto(const char *);
+extern int rtnl_route_read_protocol_names(const char *);
-extern char * rtnl_route_metric2str(int, char *, size_t);
-extern int rtnl_route_str2metric(const char *);
+extern char * rtnl_route_metric2str(int, char *, size_t);
+extern int rtnl_route_str2metric(const char *);
#ifdef __cplusplus
}
diff --git a/include/netlink/route/rule.h b/include/netlink/route/rule.h
index e57ef53..1555185 100644
--- a/include/netlink/route/rule.h
+++ b/include/netlink/route/rule.h
@@ -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>
*/
#ifndef NETLINK_RULE_H_
@@ -27,14 +27,15 @@
extern struct rtnl_rule * rtnl_rule_alloc(void);
extern void rtnl_rule_put(struct rtnl_rule *);
-extern struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *);
-extern struct nl_cache * rtnl_rule_alloc_cache_by_family(struct nl_handle *,
- int);
+extern int rtnl_rule_alloc_cache(struct nl_handle *, int,
+ struct nl_cache **);
extern void rtnl_rule_dump(struct rtnl_rule *, FILE *, struct nl_dump_params *);
-extern struct nl_msg * rtnl_rule_build_add_request(struct rtnl_rule *, int);
+extern int rtnl_rule_build_add_request(struct rtnl_rule *, int,
+ struct nl_msg **);
extern int rtnl_rule_add(struct nl_handle *, struct rtnl_rule *, int);
-extern struct nl_msg * rtnl_rule_build_delete_request(struct rtnl_rule *, int);
+extern int rtnl_rule_build_delete_request(struct rtnl_rule *, int,
+ struct nl_msg **);
extern int rtnl_rule_delete(struct nl_handle *, struct rtnl_rule *, int);
diff --git a/include/netlink/utils.h b/include/netlink/utils.h
index 207e8ec..2b6bcb7 100644
--- a/include/netlink/utils.h
+++ b/include/netlink/utils.h
@@ -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>
*/
#ifndef NETLINK_UTILS_H_
@@ -38,10 +38,6 @@
/** @} */
-extern char * nl_geterror(void);
-extern int nl_get_errno(void);
-extern void nl_perror(const char *);
-
/* unit pretty-printing */
extern double nl_cancel_down_bytes(unsigned long long, char **);
extern double nl_cancel_down_bits(unsigned long long, char **);
diff --git a/lib/addr.c b/lib/addr.c
index 70e4b1d..258084e 100644
--- a/lib/addr.c
+++ b/lib/addr.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>
*/
/**
@@ -140,11 +140,11 @@
pos = dnet_num(src, &area);
if ((pos == 0) || (area > 63) ||
((*(src + pos) != '.') && (*(src + pos) != ',')))
- return -EINVAL;
+ return -NLE_INVAL;
pos = dnet_num(src + pos + 1, &node);
if ((pos == 0) || (node > 1023))
- return -EINVAL;
+ return -NLE_INVAL;
*(uint16_t *)addrbuf = dn_ntohs((area << 10) | node);
@@ -166,10 +166,8 @@
struct nl_addr *addr;
addr = calloc(1, sizeof(*addr) + maxsize);
- if (!addr) {
- nl_errno(ENOMEM);
+ if (!addr)
return NULL;
- }
addr->a_refcnt = 1;
addr->a_maxsize = maxsize;
@@ -221,6 +219,7 @@
* Allocate abstract address object based on a character string
* @arg addrstr Address represented as character string.
* @arg hint Address family hint or AF_UNSPEC.
+ * @arg result Pointer to store resulting address.
*
* Regognizes the following address formats:
*@code
@@ -241,9 +240,9 @@
* The prefix length may be appened at the end prefixed with a
* slash, e.g. 10.0.0.0/8.
*
- * @return Newly allocated abstract address object or NULL.
+ * @return 0 on success or a negative error code.
*/
-struct nl_addr *nl_addr_parse(const char *addrstr, int hint)
+int nl_addr_parse(const char *addrstr, int hint, struct nl_addr **result)
{
int err, copy = 0, len = 0, family = AF_UNSPEC;
char *str, *prefix, buf[32];
@@ -251,7 +250,7 @@
str = strdup(addrstr);
if (!str) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -289,8 +288,7 @@
goto prefix;
default:
- err = nl_error(EINVAL, "Unsuported address" \
- "family for default address");
+ err = -NLE_AF_NOSUPPORT;
goto errout;
}
}
@@ -304,7 +302,7 @@
goto prefix;
}
if (hint == AF_INET) {
- err = nl_error(EINVAL, "Invalid IPv4 address");
+ err = -NLE_NOADDR;
goto errout;
}
}
@@ -316,7 +314,7 @@
goto prefix;
}
if (hint == AF_INET6) {
- err = nl_error(EINVAL, "Invalid IPv6 address");
+ err = -NLE_NOADDR;
goto errout;
}
}
@@ -338,7 +336,7 @@
}
if (hint == AF_LLC) {
- err = nl_error(EINVAL, "Invalid link layer address");
+ err = -NLE_NOADDR;
goto errout;
}
}
@@ -351,7 +349,7 @@
goto prefix;
}
if (hint == AF_DECnet) {
- err = nl_error(EINVAL, "Invalid DECnet address");
+ err = -NLE_NOADDR;
goto errout;
}
}
@@ -363,7 +361,7 @@
long l = strtol(s, &p, 16);
if (s == p || l > 0xff || i >= sizeof(buf)) {
- err = -EINVAL;
+ err = -NLE_INVAL;
goto errout;
}
@@ -378,13 +376,13 @@
goto prefix;
}
- err = nl_error(EINVAL, "Invalid address");
+ err = -NLE_NOADDR;
goto errout;
prefix:
addr = nl_addr_alloc(len);
if (!addr) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -398,18 +396,19 @@
long pl = strtol(++prefix, &p, 0);
if (p == prefix) {
nl_addr_destroy(addr);
- err = -EINVAL;
+ err = -NLE_INVAL;
goto errout;
}
nl_addr_set_prefixlen(addr, pl);
} else
nl_addr_set_prefixlen(addr, len * 8);
+ *result = addr;
err = 0;
errout:
free(str);
- return err ? NULL : addr;
+ return err;
}
/**
@@ -634,7 +633,7 @@
struct sockaddr_in *sai = (struct sockaddr_in *) sa;
if (*salen < sizeof(*sai))
- return -EINVAL;
+ return -NLE_INVAL;
sai->sin_family = addr->a_family;
memcpy(&sai->sin_addr, addr->a_addr, 4);
@@ -646,7 +645,7 @@
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
if (*salen < sizeof(*sa6))
- return -EINVAL;
+ return -NLE_INVAL;
sa6->sin6_family = addr->a_family;
memcpy(&sa6->sin6_addr, addr->a_addr, 16);
@@ -655,7 +654,7 @@
break;
default:
- return -EINVAL;
+ return -NLE_INVAL;
}
return 0;
@@ -672,6 +671,7 @@
/**
* Call getaddrinfo() for an abstract address object.
* @arg addr Abstract address object.
+ * @arg result Pointer to store resulting address list.
*
* Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST
* mode.
@@ -679,13 +679,11 @@
* @note The caller is responsible for freeing the linked list using the
* interface provided by getaddrinfo(3).
*
- * @return A linked list of addrinfo handles or NULL with an error message
- * associated.
+ * @return 0 on success or a negative error code.
*/
-struct addrinfo *nl_addr_info(struct nl_addr *addr)
+int nl_addr_info(struct nl_addr *addr, struct addrinfo **result)
{
int err;
- struct addrinfo *res;
char buf[INET6_ADDRSTRLEN+5];
struct addrinfo hint = {
.ai_flags = AI_NUMERICHOST,
@@ -694,13 +692,24 @@
nl_addr2str(addr, buf, sizeof(buf));
- err = getaddrinfo(buf, NULL, &hint, &res);
+ err = getaddrinfo(buf, NULL, &hint, result);
if (err != 0) {
- nl_error(err, gai_strerror(err));
- return NULL;
+ switch (err) {
+ case EAI_ADDRFAMILY: return -NLE_AF_NOSUPPORT;
+ case EAI_AGAIN: return -NLE_AGAIN;
+ case EAI_BADFLAGS: return -NLE_INVAL;
+ case EAI_FAIL: return -NLE_NOADDR;
+ case EAI_FAMILY: return -NLE_AF_NOSUPPORT;
+ case EAI_MEMORY: return -NLE_NOMEM;
+ case EAI_NODATA: return -NLE_NOADDR;
+ case EAI_NONAME: return -NLE_OBJ_NOTFOUND;
+ case EAI_SERVICE: return -NLE_OPNOTSUPP;
+ case EAI_SOCKTYPE: return -NLE_BAD_SOCK;
+ default: return -NLE_FAILURE;
+ }
}
- return res;
+ return 0;
}
/**
@@ -756,7 +765,7 @@
int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
{
if (len > addr->a_maxsize)
- return -ERANGE;
+ return -NLE_RANGE;
addr->a_len = len;
memcpy(addr->a_addr, buf, len);
diff --git a/lib/attr.c b/lib/attr.c
index 875c881..0143be7 100644
--- a/lib/attr.c
+++ b/lib/attr.c
@@ -267,7 +267,7 @@
* return 0;
*
* nla_put_failure:
- * return -ENOMEM;
+ * return -NLE_NOMEM;
* }
* @endcode
*
@@ -544,18 +544,18 @@
minlen = nla_attr_minlen[pt->type];
if (pt->type == NLA_FLAG && nla_len(nla) > 0)
- return nl_errno(ERANGE);
+ return -NLE_RANGE;
if (nla_len(nla) < minlen)
- return nl_errno(ERANGE);
+ return -NLE_RANGE;
if (pt->maxlen && nla_len(nla) > pt->maxlen)
- return nl_errno(ERANGE);
+ return -NLE_RANGE;
if (pt->type == NLA_STRING) {
char *data = nla_data(nla);
if (data[nla_len(nla) - 1] != '\0')
- return nl_errno(EINVAL);
+ return -NLE_INVAL;
}
return 0;
@@ -802,10 +802,8 @@
tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
- if ((tlen + msg->nm_nlh->nlmsg_len) > msg->nm_size) {
- nl_errno(ENOBUFS);
+ if ((tlen + msg->nm_nlh->nlmsg_len) > msg->nm_size)
return NULL;
- }
nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
nla->nla_type = attrtype;
@@ -842,7 +840,7 @@
nla = nla_reserve(msg, attrtype, datalen);
if (!nla)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
memcpy(nla_data(nla), data, datalen);
NL_DBG(2, "msg %p: Wrote %d bytes at offset +%td for attr %d\n",
diff --git a/lib/cache.c b/lib/cache.c
index e7ba5b9..bc360f0 100644
--- a/lib/cache.c
+++ b/lib/cache.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>
*/
/**
@@ -175,10 +175,8 @@
struct nl_cache *cache;
cache = calloc(1, sizeof(*cache));
- if (!cache) {
- nl_errno(ENOMEM);
+ if (!cache)
return NULL;
- }
nl_init_list_head(&cache->c_items);
cache->c_ops = ops;
@@ -188,22 +186,43 @@
return cache;
}
+int nl_cache_alloc_and_fill(struct nl_cache_ops *ops, struct nl_handle *sock,
+ struct nl_cache **result)
+{
+ struct nl_cache *cache;
+ int err;
+
+ if (!(cache = nl_cache_alloc(ops)))
+ return -NLE_NOMEM;
+
+ if (sock && (err = nl_cache_refill(sock, cache)) < 0) {
+ nl_cache_free(cache);
+ return err;
+ }
+
+ *result = cache;
+ return 0;
+}
+
/**
* Allocate an empty cache based on type name
* @arg kind Name of cache type
* @return A newly allocated and initialized cache.
*/
-struct nl_cache *nl_cache_alloc_name(const char *kind)
+int nl_cache_alloc_name(const char *kind, struct nl_cache **result)
{
struct nl_cache_ops *ops;
+ struct nl_cache *cache;
ops = nl_cache_ops_lookup(kind);
- if (!ops) {
- nl_error(ENOENT, "Unable to lookup cache \"%s\"", kind);
- return NULL;
- }
+ if (!ops)
+ return -NLE_NOCACHE;
- return nl_cache_alloc(ops);
+ if (!(cache = nl_cache_alloc(ops)))
+ return -NLE_NOMEM;
+
+ *result = cache;
+ return 0;
}
/**
@@ -307,12 +326,12 @@
struct nl_object *new;
if (cache->c_ops->co_obj_ops != obj->ce_ops)
- return nl_error(EINVAL, "Object mismatches cache type");
+ return -NLE_OBJ_MISMATCH;
if (!nl_list_empty(&obj->ce_list)) {
new = nl_object_clone(obj);
if (!new)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
} else {
nl_object_get(obj);
new = obj;
@@ -334,7 +353,7 @@
int nl_cache_move(struct nl_cache *cache, struct nl_object *obj)
{
if (cache->c_ops->co_obj_ops != obj->ce_ops)
- return nl_error(EINVAL, "Object mismatches cache type");
+ return -NLE_OBJ_MISMATCH;
NL_DBG(3, "Moving object %p to cache %p\n", obj, cache);
@@ -423,7 +442,7 @@
cache, nl_cache_name(cache));
if (cache->c_ops->co_request_update == NULL)
- return nl_error(EOPNOTSUPP, "Operation not supported");
+ return -NLE_OPNOTSUPP;
return cache->c_ops->co_request_update(cache, handle);
}
@@ -457,7 +476,7 @@
cb = nl_cb_clone(handle->h_cb);
if (cb == NULL)
- return nl_get_errno();
+ return -NLE_NOMEM;
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, update_msg_parser, &x);
@@ -465,7 +484,7 @@
if (err < 0)
NL_DBG(2, "While picking up for %p <%s>, recvmsgs() returned " \
"%d: %s", cache, nl_cache_name(cache),
- err, nl_geterror());
+ err, nl_geterror(err));
nl_cb_put(cb);
@@ -542,14 +561,14 @@
int i;
if (ops->co_obj_ops != obj->ce_ops)
- return nl_error(EINVAL, "Object mismatches cache type");
+ return -NLE_OBJ_MISMATCH;
for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
if (ops->co_msgtypes[i].mt_id == obj->ce_msgtype)
return cache_include(cache, obj, &ops->co_msgtypes[i],
change_cb);
- return nl_errno(EINVAL);
+ return -NLE_MSGTYPE_NOSUPPORT;
}
static int resync_cb(struct nl_object *c, struct nl_parser_param *p)
@@ -610,23 +629,19 @@
{
int i, err;
- if (!nlmsg_valid_hdr(nlh, ops->co_hdrsize)) {
- err = nl_error(EINVAL, "netlink message too short to be "
- "of kind %s", ops->co_name);
- goto errout;
- }
+ if (!nlmsg_valid_hdr(nlh, ops->co_hdrsize))
+ return -NLE_MSG_TOOSHORT;
for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) {
if (ops->co_msgtypes[i].mt_id == nlh->nlmsg_type) {
err = ops->co_msg_parser(ops, who, nlh, params);
- if (err != -ENOENT)
+ if (err != -NLE_OPNOTSUPP)
goto errout;
}
}
- err = nl_error(EINVAL, "Unsupported netlink message type %d",
- nlh->nlmsg_type);
+ err = -NLE_MSGTYPE_NOSUPPORT;
errout:
return err;
}
diff --git a/lib/cache_mngr.c b/lib/cache_mngr.c
index dffba90..5909795 100644
--- a/lib/cache_mngr.c
+++ b/lib/cache_mngr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2007 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
/**
@@ -146,17 +146,18 @@
*
* @return Newly allocated cache manager or NULL on failure.
*/
-struct nl_cache_mngr *nl_cache_mngr_alloc(struct nl_handle *handle,
- int protocol, int flags)
+int nl_cache_mngr_alloc(struct nl_handle *handle, int protocol, int flags,
+ struct nl_cache_mngr **result)
{
struct nl_cache_mngr *mngr;
+ int err = -NLE_NOMEM;
if (handle == NULL)
BUG();
mngr = calloc(1, sizeof(*mngr));
if (!mngr)
- goto enomem;
+ goto errout;
mngr->cm_handle = handle;
mngr->cm_nassocs = 32;
@@ -165,8 +166,7 @@
mngr->cm_assocs = calloc(mngr->cm_nassocs,
sizeof(struct nl_cache_assoc));
if (!mngr->cm_assocs)
- goto enomem;
-
+ goto errout;
nl_socket_modify_cb(mngr->cm_handle, NL_CB_VALID, NL_CB_CUSTOM,
event_input, mngr);
@@ -174,22 +174,21 @@
/* Required to receive async event notifications */
nl_disable_sequence_check(mngr->cm_handle);
- if (nl_connect(mngr->cm_handle, protocol) < 0)
+ if ((err = nl_connect(mngr->cm_handle, protocol) < 0))
goto errout;
- if (nl_socket_set_nonblocking(mngr->cm_handle) < 0)
+ if ((err = nl_socket_set_nonblocking(mngr->cm_handle) < 0))
goto errout;
NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
mngr, protocol, mngr->cm_nassocs);
- return mngr;
+ *result = mngr;
+ return 0;
-enomem:
- nl_errno(ENOMEM);
errout:
nl_cache_mngr_free(mngr);
- return NULL;
+ return err;
}
/**
@@ -197,6 +196,7 @@
* @arg mngr Cache manager.
* @arg name Name of cache to keep track of
* @arg cb Function to be called upon changes.
+ * @arg result Pointer to store added cache.
*
* Allocates a new cache of the specified type and adds it to the manager.
* The operation will trigger a full dump request from the kernel to
@@ -204,10 +204,10 @@
* to the notification group of the cache to keep track of any further
* changes.
*
- * @return The newly allocated cache or NULL on failure.
+ * @return 0 on success or a negative error code.
*/
-struct nl_cache *nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
- change_func_t cb)
+int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
+ change_func_t cb, struct nl_cache **result)
{
struct nl_cache_ops *ops;
struct nl_cache *cache;
@@ -215,28 +215,19 @@
int err, i;
ops = nl_cache_ops_lookup(name);
- if (!ops) {
- nl_error(ENOENT, "Unknown cache type");
- return NULL;
- }
+ if (!ops)
+ return -NLE_NOCACHE;
- if (ops->co_protocol != mngr->cm_protocol) {
- nl_error(EINVAL, "Netlink protocol mismatch");
- return NULL;
- }
+ if (ops->co_protocol != mngr->cm_protocol)
+ return -NLE_PROTO_MISMATCH;
- if (ops->co_groups == NULL) {
- nl_error(EOPNOTSUPP, NULL);
- return NULL;
- }
+ if (ops->co_groups == NULL)
+ return -NLE_OPNOTSUPP;
- for (i = 0; i < mngr->cm_nassocs; i++) {
+ for (i = 0; i < mngr->cm_nassocs; i++)
if (mngr->cm_assocs[i].ca_cache &&
- mngr->cm_assocs[i].ca_cache->c_ops == ops) {
- nl_error(EEXIST, "Cache of this type already managed");
- return NULL;
- }
- }
+ mngr->cm_assocs[i].ca_cache->c_ops == ops)
+ return -NLE_EXIST;
retry:
for (i = 0; i < mngr->cm_nassocs; i++)
@@ -248,10 +239,9 @@
mngr->cm_assocs = realloc(mngr->cm_assocs,
mngr->cm_nassocs *
sizeof(struct nl_cache_assoc));
- if (mngr->cm_assocs == NULL) {
- nl_errno(ENOMEM);
- return NULL;
- } else {
+ if (mngr->cm_assocs == NULL)
+ return -NLE_NOMEM;
+ else {
NL_DBG(1, "Increased capacity of cache manager %p " \
"to %d\n", mngr, mngr->cm_nassocs);
goto retry;
@@ -259,10 +249,8 @@
}
cache = nl_cache_alloc(ops);
- if (!cache) {
- nl_errno(ENOMEM);
- return NULL;
- }
+ if (!cache)
+ return -NLE_NOMEM;
for (grp = ops->co_groups; grp->ag_group; grp++) {
err = nl_socket_add_membership(mngr->cm_handle, grp->ag_group);
@@ -283,7 +271,8 @@
NL_DBG(1, "Added cache %p <%s> to cache manager %p\n",
cache, nl_cache_name(cache), mngr);
- return cache;
+ *result = cache;
+ return 0;
errout_drop_membership:
for (grp = ops->co_groups; grp->ag_group; grp++)
@@ -291,7 +280,7 @@
errout_free_cache:
nl_cache_free(cache);
- return NULL;
+ return err;
}
/**
@@ -334,7 +323,7 @@
ret = poll(&fds, 1, timeout);
NL_DBG(3, "Cache manager %p, poll() returned %d\n", mngr, ret);
if (ret < 0)
- return nl_errno(errno);
+ return -nl_syserr2nlerr(errno);
if (ret == 0)
return 0;
diff --git a/lib/cache_mngt.c b/lib/cache_mngt.c
index 137d6c9..4fede92 100644
--- a/lib/cache_mngt.c
+++ b/lib/cache_mngt.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>
*/
/**
@@ -129,15 +129,12 @@
*/
int nl_cache_mngt_register(struct nl_cache_ops *ops)
{
- if (!ops->co_name)
- return nl_error(EINVAL, "No cache name specified");
-
- if (!ops->co_obj_ops)
- return nl_error(EINVAL, "No obj cache ops specified");
+ if (!ops->co_name || !ops->co_obj_ops)
+ return -NLE_INVAL;
if (nl_cache_ops_lookup(ops->co_name))
- return nl_error(EEXIST, "Cache operations already exist");
-
+ return -NLE_EXIST;
+
ops->co_next = cache_ops;
cache_ops = ops;
@@ -166,7 +163,7 @@
break;
if (!t)
- return nl_error(ENOENT, "No such cache operations");
+ return -NLE_NOCACHE;
NL_DBG(1, "Unregistered cache operations %s\n", ops->co_name);
diff --git a/lib/data.c b/lib/data.c
index 7b81ceb..7bde598 100644
--- a/lib/data.c
+++ b/lib/data.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>
*/
/**
@@ -56,7 +56,6 @@
return data;
errout:
- nl_errno(ENOMEM);
return NULL;
}
@@ -105,7 +104,7 @@
if (size > 0) {
data->d_data = realloc(data->d_data, data->d_size + size);
if (!data->d_data)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (buf)
memcpy(data->d_data + data->d_size, buf, size);
diff --git a/lib/error.c b/lib/error.c
new file mode 100644
index 0000000..1ef7e5e
--- /dev/null
+++ b/lib/error.c
@@ -0,0 +1,106 @@
+/*
+ * lib/error.c Error Handling
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <netlink-local.h>
+#include <netlink/netlink.h>
+
+static const char *errmsg[NLE_MAX+1] = {
+[NLE_SUCCESS] = "Success",
+[NLE_FAILURE] = "Unspecific failure",
+[NLE_INTR] = "Interrupted system call",
+[NLE_BAD_SOCK] = "Bad socket",
+[NLE_AGAIN] = "Try again",
+[NLE_NOMEM] = "Out of memory",
+[NLE_EXIST] = "Object exists",
+[NLE_INVAL] = "Invalid input data or parameter",
+[NLE_RANGE] = "Input data out of range",
+[NLE_MSGSIZE] = "Message size not sufficient",
+[NLE_OPNOTSUPP] = "Operation not supported",
+[NLE_AF_NOSUPPORT] = "Address family not supported",
+[NLE_OBJ_NOTFOUND] = "Object not found",
+[NLE_NOATTR] = "Attribute not available",
+[NLE_MISSING_ATTR] = "Missing attribute",
+[NLE_AF_MISMATCH] = "Address family mismatch",
+[NLE_SEQ_MISMATCH] = "Message sequence number mismatch",
+[NLE_MSG_OVERFLOW] = "Kernel reported message overflow",
+[NLE_MSG_TRUNC] = "Kernel reported truncated message",
+[NLE_NOADDR] = "Invalid address for specified address family",
+[NLE_SRCRT_NOSUPPORT] = "Source based routing not supported",
+[NLE_MSG_TOOSHORT] = "Netlink message is too short",
+[NLE_MSGTYPE_NOSUPPORT] = "Netlink message type is not supported",
+[NLE_OBJ_MISMATCH] = "Object type does not match cache",
+[NLE_NOCACHE] = "Unknown or invalid cache type",
+[NLE_BUSY] = "Object busy",
+[NLE_PROTO_MISMATCH] = "Protocol mismatch",
+[NLE_NOACCESS] = "No Access",
+[NLE_PERM] = "Operation not permitted",
+};
+
+/**
+ * Return error message for an error code
+ * @return error message
+ */
+const char *nl_geterror(int error)
+{
+ error = abs(error);
+
+ if (error > NLE_MAX)
+ error = NLE_FAILURE;
+
+ return errmsg[error];
+}
+
+/**
+ * Print a libnl error message
+ * @arg s error message prefix
+ *
+ * Prints the error message of the call that failed last.
+ *
+ * If s is not NULL and *s is not a null byte the argument
+ * string is printed, followed by a colon and a blank. Then
+ * the error message and a new-line.
+ */
+void nl_perror(int error, const char *s)
+{
+ if (s && *s)
+ fprintf(stderr, "%s: %s\n", s, nl_geterror(error));
+ else
+ fprintf(stderr, "%s\n", nl_geterror(error));
+}
+
+int nl_syserr2nlerr(int error)
+{
+ error = abs(error);
+
+ switch (error) {
+ case EBADF: return NLE_BAD_SOCK;
+ case EADDRINUSE: return NLE_EXIST;
+ case EADDRNOTAVAIL: return NLE_NOADDR;
+ case ENOENT: return NLE_OBJ_NOTFOUND;
+ case EINTR: return NLE_INTR;
+ case EAGAIN: return NLE_AGAIN;
+ case ENOTSOCK: return NLE_BAD_SOCK;
+ case ENOPROTOOPT: return NLE_INVAL;
+ case EFAULT: return NLE_INVAL;
+ case EACCES: return NLE_NOACCESS;
+ case EINVAL: return NLE_INVAL;
+ case ENOBUFS: return NLE_NOMEM;
+ case ENOMEM: return NLE_NOMEM;
+ case EAFNOSUPPORT: return NLE_AF_NOSUPPORT;
+ case EPROTONOSUPPORT: return NLE_PROTO_MISMATCH;
+ case EOPNOTSUPP: return NLE_OPNOTSUPP;
+ case EPERM: return NLE_PERM;
+ default: return NLE_FAILURE;
+ }
+}
+
+/** @} */
+
diff --git a/lib/fib_lookup/lookup.c b/lib/fib_lookup/lookup.c
index 5766035..b769246 100644
--- a/lib/fib_lookup/lookup.c
+++ b/lib/fib_lookup/lookup.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>
*/
/**
@@ -63,7 +63,7 @@
if (src->fr_req)
if (!(dst->fr_req = (struct flnl_request *)
nl_object_clone(OBJ_CAST(src->fr_req))))
- return nl_get_errno();
+ return -NLE_NOMEM;
return 0;
}
@@ -74,7 +74,7 @@
struct flnl_result *res;
struct fib_result_nl *fr;
struct nl_addr *addr;
- int err = -EINVAL;
+ int err = -NLE_INVAL;
res = flnl_result_alloc();
if (!res)
@@ -209,7 +209,8 @@
* @note Not all attributes can be changed, see
* \ref link_changeable "Changeable Attributes" for more details.
*/
-struct nl_msg *flnl_lookup_build_request(struct flnl_request *req, int flags)
+int flnl_lookup_build_request(struct flnl_request *req, int flags,
+ struct nl_msg **result)
{
struct nl_msg *msg;
struct nl_addr *addr;
@@ -228,25 +229,24 @@
fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC;
addr = flnl_request_get_addr(req);
- if (!addr) {
- nl_error(EINVAL, "Request must specify the address");
- return NULL;
- }
+ if (!addr)
+ return -NLE_MISSING_ATTR;
fr.fl_addr = *(uint32_t *) nl_addr_get_binary_addr(addr);
msg = nlmsg_alloc_simple(0, flags);
if (!msg)
- goto errout;
+ return -NLE_NOMEM;
if (nlmsg_append(msg, &fr, sizeof(fr), NLMSG_ALIGNTO) < 0)
goto errout;
- return msg;
+ *result = msg;
+ return 0;
errout:
nlmsg_free(msg);
- return NULL;
+ return -NLE_MSGSIZE;
}
/**
@@ -266,9 +266,8 @@
struct nl_msg *msg;
int err;
- msg = flnl_lookup_build_request(req, 0);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = flnl_lookup_build_request(req, 0, &msg)) < 0)
+ return err;
err = nl_send_auto_complete(handle, msg);
nlmsg_free(msg);
diff --git a/lib/fib_lookup/request.c b/lib/fib_lookup/request.c
index 8b00224..ffcf8f5 100644
--- a/lib/fib_lookup/request.c
+++ b/lib/fib_lookup/request.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>
*/
/**
@@ -48,11 +48,9 @@
if (src->lr_addr)
if (!(dst->lr_addr = nl_addr_clone(src->lr_addr)))
- goto errout;
+ return -NLE_NOMEM;
return 0;
-errout:
- return nl_get_errno();
}
static int request_compare(struct nl_object *_a, struct nl_object *_b,
@@ -152,7 +150,7 @@
int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
{
if (addr->a_family != AF_INET)
- return nl_error(EINVAL, "Address must be an IPv4 address");
+ return -NLE_AF_NOSUPPORT;
if (req->lr_addr)
nl_addr_put(req->lr_addr);
diff --git a/lib/genl/ctrl.c b/lib/genl/ctrl.c
index 9948a57..fc08e14 100644
--- a/lib/genl/ctrl.c
+++ b/lib/genl/ctrl.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>
*/
/**
@@ -61,17 +61,17 @@
family = genl_family_alloc();
if (family == NULL) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
if (info->attrs[CTRL_ATTR_FAMILY_NAME] == NULL) {
- err = nl_error(EINVAL, "Missing family name TLV");
+ err = -NLE_MISSING_ATTR;
goto errout;
}
if (info->attrs[CTRL_ATTR_FAMILY_ID] == NULL) {
- err = nl_error(EINVAL, "Missing family id TLV");
+ err = -NLE_MISSING_ATTR;
goto errout;
}
@@ -111,7 +111,7 @@
goto errout;
if (tb[CTRL_ATTR_OP_ID] == NULL) {
- err = nl_errno(EINVAL);
+ err = -NLE_MISSING_ATTR;
goto errout;
}
@@ -143,20 +143,9 @@
* @{
*/
-struct nl_cache *genl_ctrl_alloc_cache(struct nl_handle *handle)
+int genl_ctrl_alloc_cache(struct nl_handle *sock, struct nl_cache **result)
{
- struct nl_cache * cache;
-
- cache = nl_cache_alloc(&genl_ctrl_ops);
- if (cache == NULL)
- return NULL;
-
- if (handle && nl_cache_refill(handle, cache) < 0) {
- nl_cache_free(cache);
- return NULL;
- }
-
- return cache;
+ return nl_cache_alloc_and_fill(&genl_ctrl_ops, sock, result);
}
/**
@@ -241,13 +230,12 @@
struct genl_family *family;
int err;
- cache = genl_ctrl_alloc_cache(handle);
- if (cache == NULL)
- return nl_get_errno();
+ if ((err = genl_ctrl_alloc_cache(handle, &cache)) < 0)
+ return err;
family = genl_ctrl_search_by_name(cache, name);
if (family == NULL) {
- err = nl_error(ENOENT, "Generic Netlink Family not found");
+ err = -NLE_OBJ_NOTFOUND;
goto errout;
}
diff --git a/lib/genl/family.c b/lib/genl/family.c
index e05b52c..ec52b73 100644
--- a/lib/genl/family.c
+++ b/lib/genl/family.c
@@ -250,7 +250,7 @@
op = calloc(1, sizeof(*op));
if (op == NULL)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
op->o_id = id;
op->o_flags = flags;
diff --git a/lib/genl/genl.c b/lib/genl/genl.c
index 04cfebf..cee7efd 100644
--- a/lib/genl/genl.c
+++ b/lib/genl/genl.c
@@ -164,7 +164,7 @@
struct genlmsghdr *ghdr;
if (!genlmsg_valid_hdr(nlh, hdrlen))
- return nl_errno(EINVAL);
+ return -NLE_MSG_TOOSHORT;
ghdr = nlmsg_data(nlh);
return nla_validate(genlmsg_attrdata(ghdr, hdrlen),
@@ -177,7 +177,7 @@
struct genlmsghdr *ghdr;
if (!genlmsg_valid_hdr(nlh, hdrlen))
- return nl_errno(EINVAL);
+ return -NLE_MSG_TOOSHORT;
ghdr = nlmsg_data(nlh);
return nla_parse(tb, maxtype, genlmsg_attrdata(ghdr, hdrlen),
diff --git a/lib/genl/mngt.c b/lib/genl/mngt.c
index d737697..7644352 100644
--- a/lib/genl/mngt.c
+++ b/lib/genl/mngt.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>
*/
/**
@@ -108,12 +108,12 @@
goto found;
}
- err = nl_errno(ENOENT);
+ err = -NLE_MSGTYPE_NOSUPPORT;
goto errout;
found:
if (cmd->c_msg_parser == NULL)
- err = nl_error(EOPNOTSUPP, "No message parser found.");
+ err = -NLE_OPNOTSUPP;
else {
struct nlattr *tb[cmd->c_maxattr + 1];
struct genl_info info = {
@@ -174,22 +174,17 @@
int err;
if (ops->co_protocol != NETLINK_GENERIC) {
- err = nl_error(EINVAL, "cache operations not for protocol " \
- "NETLINK_GENERIC (protocol=%s)",
- ops->co_protocol);
+ err = -NLE_PROTO_MISMATCH;
goto errout;
}
if (ops->co_hdrsize < GENL_HDRSIZE(0)) {
- err = nl_error(EINVAL, "co_hdrsize too short, probably " \
- "not including genlmsghdr, minsize=%d",
- GENL_HDRSIZE(0));
+ err = -NLE_INVAL;
goto errout;
}
if (ops->co_genl == NULL) {
- err = nl_error(EINVAL, "co_genl is NULL, must provide " \
- "valid genl operations");
+ err = -NLE_INVAL;
goto errout;
}
@@ -236,8 +231,7 @@
return 0;
}
- return nl_error(ENOENT, "Unable to find generic netlink family \"%s\"",
- ops->o_name);
+ return -NLE_OBJ_NOTFOUND;
}
int genl_ops_resolve(struct nl_handle *handle, struct genl_ops *ops)
@@ -245,11 +239,8 @@
struct nl_cache *ctrl;
int err;
- ctrl = genl_ctrl_alloc_cache(handle);
- if (ctrl == NULL) {
- err = nl_get_errno();
+ if ((err = genl_ctrl_alloc_cache(handle, &ctrl)) < 0)
goto errout;
- }
err = __genl_ops_resolve(ctrl, ops);
@@ -264,11 +255,8 @@
struct genl_ops *ops;
int err = 0;
- ctrl = genl_ctrl_alloc_cache(handle);
- if (ctrl == NULL) {
- err = nl_get_errno();
+ if ((err = genl_ctrl_alloc_cache(handle, &ctrl)) < 0)
goto errout;
- }
nl_list_for_each_entry(ops, &genl_ops_list, o_list) {
err = __genl_ops_resolve(ctrl, ops);
diff --git a/lib/handlers.c b/lib/handlers.c
index 1797e4f..480df59 100644
--- a/lib/handlers.c
+++ b/lib/handlers.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>
*/
/**
@@ -140,7 +140,7 @@
print_header_content(ofd, &e->msg);
fprintf(ofd, "\n");
- return e->error;
+ return -nl_syserr2nlerr(e->error);
}
static int nl_valid_handler_debug(struct nl_msg *msg, void *arg)
@@ -261,10 +261,8 @@
return NULL;
cb = calloc(1, sizeof(*cb));
- if (!cb) {
- nl_errno(ENOMEM);
+ if (!cb)
return NULL;
- }
cb->cb_refcnt = 1;
@@ -338,10 +336,10 @@
nl_recvmsg_msg_cb_t func, void *arg)
{
if (type < 0 || type > NL_CB_TYPE_MAX)
- return nl_error(ERANGE, "Callback type out of range");
+ return -NLE_RANGE;
if (kind < 0 || kind > NL_CB_KIND_MAX)
- return nl_error(ERANGE, "Callback kind out of range");
+ return -NLE_RANGE;
if (kind == NL_CB_CUSTOM) {
cb->cb_set[type] = func;
@@ -388,7 +386,7 @@
nl_recvmsg_err_cb_t func, void *arg)
{
if (kind < 0 || kind > NL_CB_KIND_MAX)
- return nl_error(ERANGE, "Callback kind out of range");
+ return -NLE_RANGE;
if (kind == NL_CB_CUSTOM) {
cb->cb_err = func;
diff --git a/lib/msg.c b/lib/msg.c
index c5cb7b4..ad6f5a1 100644
--- a/lib/msg.c
+++ b/lib/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>
*/
/**
@@ -320,7 +320,7 @@
int maxtype, struct nla_policy *policy)
{
if (!nlmsg_valid_hdr(nlh, hdrlen))
- return nl_errno(EINVAL);
+ return -NLE_MSG_TOOSHORT;
return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
nlmsg_attrlen(nlh, hdrlen), policy);
@@ -351,7 +351,7 @@
struct nla_policy *policy)
{
if (!nlmsg_valid_hdr(nlh, hdrlen))
- return nl_errno(EINVAL);
+ return -NLE_MSG_TOOSHORT;
return nla_validate(nlmsg_attrdata(nlh, hdrlen),
nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
@@ -387,7 +387,6 @@
return nm;
errout:
free(nm);
- nl_errno(ENOMEM);
return NULL;
}
@@ -519,10 +518,8 @@
tlen = pad ? ((len + (pad - 1)) & ~(pad - 1)) : len;
- if ((tlen + nlmsg_len) > n->nm_size) {
- nl_errno(ENOBUFS);
+ if ((tlen + nlmsg_len) > n->nm_size)
return NULL;
- }
buf += nlmsg_len;
n->nm_nlh->nlmsg_len += tlen;
@@ -554,7 +551,7 @@
tmp = nlmsg_reserve(n, len, pad);
if (tmp == NULL)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
memcpy(tmp, data, len);
NL_DBG(2, "msg %p: Appended %zu bytes with padding %d\n", n, len, pad);
@@ -581,11 +578,11 @@
void *tmp;
if (newlen <= n->nm_size)
- return nl_errno(EINVAL);
+ return -NLE_INVAL;
tmp = realloc(n->nm_nlh, newlen);
if (tmp == NULL)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
n->nm_nlh = tmp;
n->nm_size = newlen;
@@ -823,8 +820,7 @@
ops = nl_cache_ops_associate(nlmsg_get_proto(msg),
nlmsg_hdr(msg)->nlmsg_type);
if (ops == NULL)
- return nl_error(ENOENT, "Unknown message type %d",
- nlmsg_hdr(msg)->nlmsg_type);
+ return -NLE_MSGTYPE_NOSUPPORT;
p.pp_arg = &x;
return nl_cache_parse(ops, NULL, nlmsg_hdr(msg), &p);
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 @@
return 0;
errout_errno:
- return nl_get_errno();
+ err = -NLE_NOMEM;
errout:
return err;
}
@@ -287,7 +287,7 @@
}
}
-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 @@
ct = nfnl_ct_alloc();
if (!ct)
- return NULL;
+ return -NLE_NOMEM;
ct->ce_msgtype = nlh->nlmsg_type;
@@ -346,11 +346,12 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
/**
* 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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
[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 @@
msg = nfnl_log_msg_alloc();
if (!msg)
- return NULL;
+ return -NLE_NOMEM;
msg->ce_msgtype = nlh->nlmsg_type;
@@ -158,11 +158,12 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
},
};
-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 @@
msg = nfnl_queue_msg_alloc();
if (!msg)
- return NULL;
+ return -NLE_NOMEM;
msg->ce_msgtype = nlh->nlmsg_type;
@@ -135,11 +136,12 @@
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 @@
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 @@
errout:
nfnl_queue_msg_put(msg);
return err;
-
-errout_errno:
- err = nl_get_errno();
- goto errout;
}
/** @} */
@@ -205,7 +202,7 @@
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 @@
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;
diff --git a/lib/nl.c b/lib/nl.c
index 9b6fb9b..ba5262b 100644
--- a/lib/nl.c
+++ b/lib/nl.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>
*/
/**
@@ -195,7 +195,7 @@
handle->h_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
if (handle->h_fd < 0) {
- err = nl_error(1, "socket(AF_NETLINK, ...) failed");
+ err = -nl_syserr2nlerr(errno);
goto errout;
}
@@ -208,7 +208,7 @@
err = bind(handle->h_fd, (struct sockaddr*) &handle->h_local,
sizeof(handle->h_local));
if (err < 0) {
- err = nl_error(1, "bind() failed");
+ err = -nl_syserr2nlerr(errno);
goto errout;
}
@@ -216,17 +216,17 @@
err = getsockname(handle->h_fd, (struct sockaddr *) &handle->h_local,
&addrlen);
if (err < 0) {
- err = nl_error(1, "getsockname failed");
+ err = -nl_syserr2nlerr(errno);
goto errout;
}
if (addrlen != sizeof(handle->h_local)) {
- err = nl_error(EADDRNOTAVAIL, "Invalid address length");
+ err = -NLE_NOADDR;
goto errout;
}
if (handle->h_local.nl_family != AF_NETLINK) {
- err = nl_error(EPFNOSUPPORT, "Address format not supported");
+ err = -NLE_AF_NOSUPPORT;
goto errout;
}
@@ -275,7 +275,7 @@
ret = sendto(handle->h_fd, buf, size, 0, (struct sockaddr *)
&handle->h_peer, sizeof(handle->h_peer));
if (ret < 0)
- return nl_errno(errno);
+ return -nl_syserr2nlerr(errno);
return ret;
}
@@ -309,7 +309,7 @@
ret = sendmsg(handle->h_fd, hdr, 0);
if (ret < 0)
- return nl_errno(errno);
+ return -nl_syserr2nlerr(errno);
return ret;
}
@@ -415,7 +415,7 @@
msg = nlmsg_alloc_simple(type, flags);
if (!msg)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (buf && size) {
err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
@@ -503,7 +503,7 @@
} else {
free(msg.msg_control);
free(*buf);
- return nl_error(errno, "recvmsg failed");
+ return -nl_syserr2nlerr(errno);
}
}
@@ -527,7 +527,7 @@
if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
free(msg.msg_control);
free(*buf);
- return nl_error(EADDRNOTAVAIL, "socket address size mismatch");
+ return -NLE_NOADDR;
}
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
@@ -611,7 +611,7 @@
free_msg = 1; /* By default, we free the message data */
msg = nlmsg_convert(hdr);
if (!msg) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto out;
}
@@ -634,8 +634,7 @@
if (cb->cb_set[NL_CB_INVALID])
NL_CB_CALL(cb, NL_CB_INVALID, msg);
else {
- err = nl_error(EINVAL,
- "Sequence number mismatch");
+ err = -NLE_SEQ_MISMATCH;
goto out;
}
}
@@ -692,7 +691,7 @@
if (cb->cb_set[NL_CB_OVERRUN])
NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
else {
- err = nl_error(EOVERFLOW, "Overrun");
+ err = -NLE_MSG_OVERFLOW;
goto out;
}
}
@@ -709,8 +708,7 @@
if (cb->cb_set[NL_CB_INVALID])
NL_CB_CALL(cb, NL_CB_INVALID, msg);
else {
- err = nl_error(EINVAL,
- "Truncated error message");
+ err = -NLE_MSG_TRUNC;
goto out;
}
} else if (e->error) {
@@ -723,13 +721,11 @@
else if (err == NL_SKIP)
goto skip;
else if (err == NL_STOP) {
- err = nl_error(-e->error,
- "Netlink Error");
+ err = -nl_syserr2nlerr(e->error);
goto out;
}
} else {
- err = nl_error(-e->error,
- "Netlink Error");
+ err = -nl_syserr2nlerr(e->error);
goto out;
}
} else if (cb->cb_set[NL_CB_ACK])
@@ -823,7 +819,7 @@
cb = nl_cb_clone(handle->h_cb);
if (cb == NULL)
- return nl_get_errno();
+ return -NLE_NOMEM;
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
err = nl_recvmsgs(handle, cb);
diff --git a/lib/object.c b/lib/object.c
index 72e4ba4..3771af9 100644
--- a/lib/object.c
+++ b/lib/object.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>
*/
/**
@@ -47,10 +47,8 @@
BUG();
new = calloc(1, ops->oo_size);
- if (!new) {
- nl_errno(ENOMEM);
+ if (!new)
return NULL;
- }
new->ce_refcnt = 1;
nl_init_list_head(&new->ce_list);
@@ -69,17 +67,18 @@
* @arg kind name of object type
* @return The new object or nULL
*/
-struct nl_object *nl_object_alloc_name(const char *kind)
+int nl_object_alloc_name(const char *kind, struct nl_object **result)
{
struct nl_cache_ops *ops;
ops = nl_cache_ops_lookup(kind);
- if (!ops) {
- nl_error(ENOENT, "Unable to lookup cache kind \"%s\"", kind);
- return NULL;
- }
+ if (!ops)
+ return -NLE_OPNOTSUPP;
- return nl_object_alloc(ops->co_obj_ops);
+ if (!(*result = nl_object_alloc(ops->co_obj_ops)))
+ return -NLE_NOMEM;
+
+ return 0;
}
struct nl_derived_object {
diff --git a/lib/route/addr.c b/lib/route/addr.c
index a4a9acf..0d86293 100644
--- a/lib/route/addr.c
+++ b/lib/route/addr.c
@@ -6,8 +6,8 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
- * Baruch Even <baruch@ev-en.org>,
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>,
* Mediatrix Telecom, inc. <ericb@mediatrix.com>
*/
@@ -154,27 +154,25 @@
if (src->a_peer)
if (!(dst->a_peer = nl_addr_clone(src->a_peer)))
- goto errout;
+ return -NLE_NOMEM;
if (src->a_local)
if (!(dst->a_local = nl_addr_clone(src->a_local)))
- goto errout;
+ return -NLE_NOMEM;
if (src->a_bcast)
if (!(dst->a_bcast = nl_addr_clone(src->a_bcast)))
- goto errout;
+ return -NLE_NOMEM;
if (src->a_anycast)
if (!(dst->a_anycast = nl_addr_clone(src->a_anycast)))
- goto errout;
+ return -NLE_NOMEM;
if (src->a_multicast)
if (!(dst->a_multicast = nl_addr_clone(src->a_multicast)))
- goto errout;
+ return -NLE_NOMEM;
return 0;
-errout:
- return nl_get_errno();
}
static struct nla_policy addr_policy[IFA_MAX+1] = {
@@ -189,11 +187,11 @@
struct rtnl_addr *addr;
struct ifaddrmsg *ifa;
struct nlattr *tb[IFA_MAX+1];
- int err = -ENOMEM, peer_prefix = 0;
+ int err, peer_prefix = 0;
addr = rtnl_addr_alloc();
if (!addr) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
addr->ce_msgtype = nlh->nlmsg_type;
@@ -639,25 +637,15 @@
* @{
*/
-struct nl_cache *rtnl_addr_alloc_cache(struct nl_handle *handle)
+int rtnl_addr_alloc_cache(struct nl_handle *sock, struct nl_cache **result)
{
- struct nl_cache *cache;
-
- cache = nl_cache_alloc(&rtnl_addr_ops);
- if (!cache)
- return NULL;
-
- if (handle && nl_cache_refill(handle, cache) < 0) {
- nl_cache_free(cache);
- return NULL;
- }
-
- return cache;
+ return nl_cache_alloc_and_fill(&rtnl_addr_ops, sock, result);
}
/** @} */
-static struct nl_msg *build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags)
+static int build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags,
+ struct nl_msg **result)
{
struct nl_msg *msg;
struct ifaddrmsg am = {
@@ -680,7 +668,7 @@
msg = nlmsg_alloc_simple(cmd, flags);
if (!msg)
- goto nla_put_failure;
+ return -NLE_NOMEM;
if (nlmsg_append(msg, &am, sizeof(am), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
@@ -702,11 +690,12 @@
if (tmpl->ce_mask & ADDR_ATTR_ANYCAST)
NLA_PUT_ADDR(msg, IFA_ANYCAST, tmpl->a_anycast);
- return msg;
+ *result = msg;
+ return 0;
nla_put_failure:
nlmsg_free(msg);
- return NULL;
+ return -NLE_MSGSIZE;
}
/**
@@ -718,6 +707,7 @@
* Build netlink request message to request addition of new address
* @arg addr Address object representing the new address.
* @arg flags Additional netlink message flags.
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting the addition of a new
* address. The netlink message header isn't fully equipped with
@@ -732,20 +722,19 @@
* which case a host scope is used if not specified otherwise.
*
* @note Free the memory after usage using nlmsg_free().
- * @return Newly allocated netlink message or NULL if an error occured.
+ *
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_addr_build_add_request(struct rtnl_addr *addr, int flags)
+int rtnl_addr_build_add_request(struct rtnl_addr *addr, int flags,
+ struct nl_msg **result)
{
int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY |
ADDR_ATTR_PREFIXLEN | ADDR_ATTR_LOCAL;
- if ((addr->ce_mask & required) != required) {
- nl_error(EINVAL, "Missing mandatory attributes, required are: "
- "ifindex, family, prefixlen, local address.");
- return NULL;
- }
+ if ((addr->ce_mask & required) != required)
+ return -NLE_MISSING_ATTR;
- return build_addr_msg(addr, RTM_NEWADDR, NLM_F_CREATE | flags);
+ return build_addr_msg(addr, RTM_NEWADDR, NLM_F_CREATE | flags, result);
}
/**
@@ -767,9 +756,8 @@
struct nl_msg *msg;
int err;
- msg = rtnl_addr_build_add_request(addr, flags);
- if (!msg)
- return nl_get_errno();
+ if ((err = rtnl_addr_build_add_request(addr, flags, &msg)) < 0)
+ return err;
err = nl_send_auto_complete(handle, msg);
nlmsg_free(msg);
@@ -790,6 +778,7 @@
* Build a netlink request message to request deletion of an address
* @arg addr Address object to be deleteted.
* @arg flags Additional netlink message flags.
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a deletion of an address.
* The netlink message header isn't fully equipped with all relevant
@@ -806,19 +795,18 @@
* - peer address (rtnl_addr_set_peer(), IPv4 only)
*
* @note Free the memory after usage using nlmsg_free().
- * @return Newly allocated netlink message or NULL if an error occured.
+ *
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_addr_build_delete_request(struct rtnl_addr *addr, int flags)
+int rtnl_addr_build_delete_request(struct rtnl_addr *addr, int flags,
+ struct nl_msg **result)
{
int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY;
- if ((addr->ce_mask & required) != required) {
- nl_error(EINVAL, "Missing mandatory attributes, required are: "
- "ifindex, family");
- return NULL;
- }
-
- return build_addr_msg(addr, RTM_DELADDR, flags);
+ if ((addr->ce_mask & required) != required)
+ return -NLE_MISSING_ATTR;
+
+ return build_addr_msg(addr, RTM_DELADDR, flags, result);
}
/**
@@ -841,9 +829,8 @@
struct nl_msg *msg;
int err;
- msg = rtnl_addr_build_delete_request(addr, flags);
- if (!msg)
- return nl_get_errno();
+ if ((err = rtnl_addr_build_delete_request(addr, flags, &msg)) < 0)
+ return err;
err = nl_send_auto_complete(handle, msg);
nlmsg_free(msg);
@@ -954,7 +941,7 @@
{
if (addr->ce_mask & ADDR_ATTR_FAMILY) {
if (new->a_family != addr->a_family)
- return nl_error(EINVAL, "Address family mismatch");
+ return -NLE_AF_MISMATCH;
} else
addr->a_family = new->a_family;
diff --git a/lib/route/class.c b/lib/route/class.c
index 7966b09..9a1784f 100644
--- a/lib/route/class.c
+++ b/lib/route/class.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>
*/
/**
@@ -36,7 +36,7 @@
class = rtnl_class_alloc();
if (!class) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
class->ce_msgtype = n->nlmsg_type;
@@ -81,15 +81,15 @@
* @{
*/
-static struct nl_msg *class_build(struct rtnl_class *class, int type, int flags)
+static int class_build(struct rtnl_class *class, int type, int flags,
+ struct nl_msg **result)
{
struct rtnl_class_ops *cops;
- struct nl_msg *msg;
int err;
- msg = tca_build_msg((struct rtnl_tca *) class, type, flags);
- if (!msg)
- goto errout;
+ err = tca_build_msg((struct rtnl_tca *) class, type, flags, result);
+ if (err < 0)
+ return err;
cops = rtnl_class_lookup_ops(class);
if (cops && cops->co_get_opts) {
@@ -97,23 +97,24 @@
opts = cops->co_get_opts(class);
if (opts) {
- err = nla_put_nested(msg, TCA_OPTIONS, opts);
+ err = nla_put_nested(*result, TCA_OPTIONS, opts);
nlmsg_free(opts);
if (err < 0)
goto errout;
}
}
- return msg;
+ return 0;
errout:
- nlmsg_free(msg);
- return NULL;
+ nlmsg_free(*result);
+ return err;
}
/**
* Build a netlink message to add a new class
* @arg class class to add
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting an addition of a class.
* The netlink message header isn't fully equipped with all relevant
@@ -123,11 +124,12 @@
* Common message flags
* - NLM_F_REPLACE - replace possibly existing classes
*
- * @return New netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_class_build_add_request(struct rtnl_class *class, int flags)
+int rtnl_class_build_add_request(struct rtnl_class *class, int flags,
+ struct nl_msg **result)
{
- return class_build(class, RTM_NEWTCLASS, NLM_F_CREATE | flags);
+ return class_build(class, RTM_NEWTCLASS, NLM_F_CREATE | flags, result);
}
/**
@@ -151,12 +153,10 @@
struct nl_msg *msg;
int err;
- msg = rtnl_class_build_add_request(class, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_class_build_add_request(class, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -181,22 +181,25 @@
*
* @return The cache or NULL if an error has occured.
*/
-struct nl_cache * rtnl_class_alloc_cache(struct nl_handle *handle, int ifindex)
+int rtnl_class_alloc_cache(struct nl_handle *handle, int ifindex,
+ struct nl_cache **result)
{
struct nl_cache * cache;
+ int err;
cache = nl_cache_alloc(&rtnl_class_ops);
if (!cache)
- return NULL;
+ return -NLE_NOMEM;
cache->c_iarg1 = ifindex;
- if (handle && nl_cache_refill(handle, cache) < 0) {
+ if (handle && (err = nl_cache_refill(handle, cache)) < 0) {
nl_cache_free(cache);
- return NULL;
+ return err;
}
- return cache;
+ *result = cache;
+ return 0;
}
/** @} */
diff --git a/lib/route/class_api.c b/lib/route/class_api.c
index c814486..374cf0f 100644
--- a/lib/route/class_api.c
+++ b/lib/route/class_api.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>
*/
/**
@@ -43,7 +43,7 @@
for (op = &class_ops_list; (o = *op) != NULL; op = &o->co_next)
if (!strcasecmp(cops->co_kind, o->co_kind))
- return nl_errno(EEXIST);
+ return -NLE_EXIST;
cops->co_next = NULL;
*op = cops;
@@ -64,7 +64,7 @@
break;
if (!o)
- return nl_errno(ENOENT);
+ return -NLE_OBJ_NOTFOUND;
*op = cops->co_next;
diff --git a/lib/route/classifier.c b/lib/route/classifier.c
index df6d3ae..8008bc4 100644
--- a/lib/route/classifier.c
+++ b/lib/route/classifier.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>
*/
/**
@@ -44,7 +44,7 @@
cls = rtnl_cls_alloc();
if (!cls) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
cls->ce_msgtype = nlh->nlmsg_type;
@@ -88,18 +88,18 @@
}
-static struct nl_msg *cls_build(struct rtnl_cls *cls, int type, int flags)
+static int cls_build(struct rtnl_cls *cls, int type, int flags,
+ struct nl_msg **result)
{
- struct nl_msg *msg;
struct rtnl_cls_ops *cops;
int err, prio, proto;
struct tcmsg *tchdr;
- msg = tca_build_msg((struct rtnl_tca *) cls, type, flags);
- if (!msg)
- goto errout;
+ err = tca_build_msg((struct rtnl_tca *) cls, type, flags, result);
+ if (err < 0)
+ return err;
- tchdr = nlmsg_data(nlmsg_hdr(msg));
+ tchdr = nlmsg_data(nlmsg_hdr(*result));
prio = rtnl_cls_get_prio(cls);
proto = rtnl_cls_get_protocol(cls);
tchdr->tcm_info = TC_H_MAKE(prio << 16, htons(proto)),
@@ -110,17 +110,17 @@
opts = cops->co_get_opts(cls);
if (opts) {
- err = nla_put_nested(msg, TCA_OPTIONS, opts);
+ err = nla_put_nested(*result, TCA_OPTIONS, opts);
nlmsg_free(opts);
if (err < 0)
goto errout;
}
}
- return msg;
+ return 0;
errout:
- nlmsg_free(msg);
- return NULL;
+ nlmsg_free(*result);
+ return err;
}
/**
@@ -132,6 +132,7 @@
* Build a netlink message to add a new classifier
* @arg cls classifier to add
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting an addition of a classifier
* The netlink message header isn't fully equipped with all relevant
@@ -140,11 +141,12 @@
* the new classifier set via \c rtnl_cls_set_* functions. \a opts
* may point to the clsasifier specific options.
*
- * @return New netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg * rtnl_cls_build_add_request(struct rtnl_cls *cls, int flags)
+int rtnl_cls_build_add_request(struct rtnl_cls *cls, int flags,
+ struct nl_msg **result)
{
- return cls_build(cls, RTM_NEWTFILTER, NLM_F_CREATE | flags);
+ return cls_build(cls, RTM_NEWTFILTER, NLM_F_CREATE | flags, result);
}
/**
@@ -161,15 +163,13 @@
*/
int rtnl_cls_add(struct nl_handle *handle, struct rtnl_cls *cls, int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_cls_build_add_request(cls, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_cls_build_add_request(cls, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -180,17 +180,19 @@
* Build a netlink message to change classifier attributes
* @arg cls classifier to change
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a change of a neigh
* attributes. The netlink message header isn't fully equipped with
* all relevant fields and must thus be sent out via nl_send_auto_complete()
* or supplemented as needed.
*
- * @return The netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_cls_build_change_request(struct rtnl_cls *cls, int flags)
+int rtnl_cls_build_change_request(struct rtnl_cls *cls, int flags,
+ struct nl_msg **result)
{
- return cls_build(cls, RTM_NEWTFILTER, NLM_F_REPLACE | flags);
+ return cls_build(cls, RTM_NEWTFILTER, NLM_F_REPLACE | flags, result);
}
/**
@@ -208,15 +210,13 @@
int rtnl_cls_change(struct nl_handle *handle, struct rtnl_cls *cls,
int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_cls_build_change_request(cls, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_cls_build_change_request(cls, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -227,17 +227,19 @@
* Build a netlink request message to delete a classifier
* @arg cls classifier to delete
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a deletion of a classifier.
* The netlink message header isn't fully equipped with all relevant
* fields and must thus be sent out via nl_send_auto_complete()
* or supplemented as needed.
*
- * @return New netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_cls_build_delete_request(struct rtnl_cls *cls, int flags)
+int rtnl_cls_build_delete_request(struct rtnl_cls *cls, int flags,
+ struct nl_msg **result)
{
- return cls_build(cls, RTM_DELTFILTER, flags);
+ return cls_build(cls, RTM_DELTFILTER, flags, result);
}
@@ -255,15 +257,13 @@
*/
int rtnl_cls_delete(struct nl_handle *handle, struct rtnl_cls *cls, int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_cls_build_delete_request(cls, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_cls_build_delete_request(cls, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -284,32 +284,33 @@
* @arg ifindex interface index of the link the classes are
* attached to.
* @arg parent parent qdisc/class
+ * @arg result Pointer to store resulting cache.
*
* Allocates a new cache, initializes it properly and updates it to
* include all classes attached to the specified interface.
*
* @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 *rtnl_cls_alloc_cache(struct nl_handle *handle,
- int ifindex, uint32_t parent)
+int rtnl_cls_alloc_cache(struct nl_handle *handle, int ifindex, uint32_t parent, struct nl_cache **result)
{
struct nl_cache * cache;
+ int err;
- cache = nl_cache_alloc(&rtnl_cls_ops);
- if (cache == NULL)
- return NULL;
+ if (!(cache = nl_cache_alloc(&rtnl_cls_ops)))
+ return -NLE_NOMEM;
cache->c_iarg1 = ifindex;
cache->c_iarg2 = parent;
- if (handle && nl_cache_refill(handle, cache) < 0) {
+ if (handle && (err = nl_cache_refill(handle, cache)) < 0) {
nl_cache_free(cache);
- return NULL;
+ return err;
}
- return cache;
+ *result = cache;
+ return 0;
}
/** @} */
diff --git a/lib/route/cls/fw.c b/lib/route/cls/fw.c
index 7ca7619..61972de 100644
--- a/lib/route/cls/fw.c
+++ b/lib/route/cls/fw.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) 2006 Petr Gotthard <petr.gotthard@siemens.com>
* Copyright (c) 2006 Siemens AG Oesterreich
*/
@@ -63,7 +63,7 @@
f = fw_alloc(cls);
if (!f)
- goto errout_nomem;
+ return -NLE_NOMEM;
if (tb[TCA_FW_CLASSID]) {
f->cf_classid = nla_get_u32(tb[TCA_FW_CLASSID]);
@@ -73,14 +73,14 @@
if (tb[TCA_FW_ACT]) {
f->cf_act = nla_get_data(tb[TCA_FW_ACT]);
if (!f->cf_act)
- goto errout_nomem;
+ return -NLE_NOMEM;
f->cf_mask |= FW_ATTR_ACTION;
}
if (tb[TCA_FW_POLICE]) {
f->cf_police = nla_get_data(tb[TCA_FW_POLICE]);
if (!f->cf_police)
- goto errout_nomem;
+ return -NLE_NOMEM;
f->cf_mask |= FW_ATTR_POLICE;
}
@@ -90,11 +90,6 @@
}
return 0;
-
-errout_nomem:
- err = nl_errno(ENOMEM);
-
- return err;
}
static void fw_free_data(struct rtnl_cls *cls)
@@ -119,19 +114,17 @@
dst = fw_alloc(_dst);
if (!dst)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (src->cf_act)
if (!(dst->cf_act = nl_data_clone(src->cf_act)))
- goto errout;
+ return -NLE_NOMEM;
if (src->cf_police)
if (!(dst->cf_police = nl_data_clone(src->cf_police)))
- goto errout;
+ return -NLE_NOMEM;
return 0;
-errout:
- return nl_get_errno();
}
static int fw_dump_brief(struct rtnl_cls *cls, struct nl_dump_params *p,
@@ -217,7 +210,7 @@
f = fw_alloc(cls);
if (!f)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
f->cf_classid = classid;
f->cf_mask |= FW_ATTR_CLASSID;
diff --git a/lib/route/cls/u32.c b/lib/route/cls/u32.c
index 596e63f..1f881d3 100644
--- a/lib/route/cls/u32.c
+++ b/lib/route/cls/u32.c
@@ -137,8 +137,7 @@
int pcnt_size;
if (!tb[TCA_U32_SEL]) {
- err = nl_error(EINVAL, "Missing TCA_U32_SEL required "
- "for TCA_U32_PCNT");
+ err = -NLE_MISSING_ATTR;
goto errout;
}
@@ -146,7 +145,7 @@
pcnt_size = sizeof(struct tc_u32_pcnt) +
(sel->nkeys * sizeof(uint64_t));
if (nla_len(tb[TCA_U32_PCNT]) < pcnt_size) {
- err = nl_error(EINVAL, "Invalid size for TCA_U32_PCNT");
+ err = -NLE_INVAL;
goto errout;
}
@@ -164,7 +163,7 @@
return 0;
errout_nomem:
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
errout:
return err;
}
@@ -193,27 +192,25 @@
dst = u32_alloc(_dst);
if (!dst)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (src->cu_selector)
if (!(dst->cu_selector = nl_data_clone(src->cu_selector)))
- goto errout;
+ return -NLE_NOMEM;
if (src->cu_act)
if (!(dst->cu_act = nl_data_clone(src->cu_act)))
- goto errout;
+ return -NLE_NOMEM;
if (src->cu_police)
if (!(dst->cu_police = nl_data_clone(src->cu_police)))
- goto errout;
+ return -NLE_NOMEM;
if (src->cu_pcnt)
if (!(dst->cu_pcnt = nl_data_clone(src->cu_pcnt)))
- goto errout;
+ return -NLE_NOMEM;
return 0;
-errout:
- return nl_get_errno();
}
static int u32_dump_brief(struct rtnl_cls *cls, struct nl_dump_params *p,
@@ -419,7 +416,7 @@
u = u32_alloc(cls);
if (!u)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
u->cu_classid = classid;
u->cu_mask |= U32_ATTR_CLASSID;
@@ -441,11 +438,11 @@
u = u32_alloc(cls);
if (!u)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
sel = u32_selector_alloc(u);
if (!sel)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
sel->flags |= flags;
u->cu_mask |= U32_ATTR_SELECTOR;
@@ -476,11 +473,11 @@
u = u32_alloc(cls);
if (!u)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
sel = u32_selector_alloc(u);
if (!sel)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key));
if (err < 0)
@@ -523,7 +520,7 @@
{
int shift = ((off & 3) == 0 ? 16 : 0);
if (off % 2)
- return nl_error(EINVAL, "Invalid offset alignment");
+ return -NLE_INVAL;
return rtnl_u32_add_key(cls, htonl((uint32_t)val << shift),
htonl((uint32_t)mask << shift),
diff --git a/lib/route/cls_api.c b/lib/route/cls_api.c
index f5a083a..73f05df 100644
--- a/lib/route/cls_api.c
+++ b/lib/route/cls_api.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>
*/
/**
@@ -44,7 +44,7 @@
for (op = &cls_ops_list; (o = *op) != NULL; op = &o->co_next)
if (!strcasecmp(cops->co_kind, o->co_kind))
- return nl_errno(EEXIST);
+ return -NLE_EXIST;
cops->co_next = NULL;
*op = cops;
@@ -65,7 +65,7 @@
break;
if (!o)
- return nl_errno(ENOENT);
+ return -NLE_OBJ_NOTFOUND;
*op = cops->co_next;
diff --git a/lib/route/link.c b/lib/route/link.c
index 13d3e93..cd8cd8a 100644
--- a/lib/route/link.c
+++ b/lib/route/link.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>
*/
/**
@@ -215,21 +215,19 @@
if (src->l_addr)
if (!(dst->l_addr = nl_addr_clone(src->l_addr)))
- goto errout;
+ return -NLE_NOMEM;
if (src->l_bcast)
if (!(dst->l_bcast = nl_addr_clone(src->l_bcast)))
- goto errout;
+ return -NLE_NOMEM;
if (src->l_info_ops && src->l_info_ops->io_clone) {
err = src->l_info_ops->io_clone(dst, src);
if (err < 0)
- goto errout;
+ return err;
}
return 0;
-errout:
- return nl_get_errno();
}
static struct nla_policy link_policy[IFLA_MAX+1] = {
@@ -265,7 +263,7 @@
link = rtnl_link_alloc();
if (link == NULL) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -276,7 +274,7 @@
goto errout;
if (tb[IFLA_IFNAME] == NULL) {
- err = nl_error(EINVAL, "Missing link name TLV");
+ err = -NLE_MISSING_ATTR;
goto errout;
}
@@ -859,27 +857,16 @@
/**
* Allocate link cache and fill in all configured links.
* @arg handle Netlink handle.
+ * @arg result Pointer to store resulting cache.
*
* Allocates a new link cache, initializes it properly and updates it
* to include all links currently configured in the kernel.
*
- * @note Free the memory after usage.
- * @return Newly allocated cache or NULL if an error occured.
+ * @return 0 on success or a negative error code.
*/
-struct nl_cache *rtnl_link_alloc_cache(struct nl_handle *handle)
+int rtnl_link_alloc_cache(struct nl_handle *sock, struct nl_cache **result)
{
- struct nl_cache * cache;
-
- cache = nl_cache_alloc(&rtnl_link_ops);
- if (cache == NULL)
- return NULL;
-
- if (handle && nl_cache_refill(handle, cache) < 0) {
- nl_cache_free(cache);
- return NULL;
- }
-
- return cache;
+ return nl_cache_alloc_and_fill(&rtnl_link_ops, sock, result);
}
/**
@@ -962,9 +949,9 @@
* @note Not all attributes can be changed, see
* \ref link_changeable "Changeable Attributes" for more details.
*/
-struct nl_msg * rtnl_link_build_change_request(struct rtnl_link *old,
- struct rtnl_link *tmpl,
- int flags)
+int rtnl_link_build_change_request(struct rtnl_link *old,
+ struct rtnl_link *tmpl, int flags,
+ struct nl_msg **result)
{
struct nl_msg *msg;
struct ifinfomsg ifi = {
@@ -979,7 +966,7 @@
msg = nlmsg_alloc_simple(RTM_SETLINK, flags);
if (!msg)
- goto nla_put_failure;
+ return -NLE_NOMEM;
if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
@@ -1023,11 +1010,12 @@
nla_nest_end(msg, info);
}
- return msg;
+ *result = msg;
+ return 0;
nla_put_failure:
nlmsg_free(msg);
- return NULL;
+ return -NLE_MSGSIZE;
}
/**
@@ -1048,15 +1036,13 @@
int rtnl_link_change(struct nl_handle *handle, struct rtnl_link *old,
struct rtnl_link *tmpl, int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_link_build_change_request(old, tmpl, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_link_build_change_request(old, tmpl, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -1504,7 +1490,7 @@
int err;
if ((io = rtnl_link_info_ops_lookup(type)) == NULL)
- return nl_error(ENOENT, "No such link info type exists");
+ return -NLE_OPNOTSUPP;
if (link->l_info_ops)
release_link_info(link);
diff --git a/lib/route/link/api.c b/lib/route/link/api.c
index afe00b1..a0e7679 100644
--- a/lib/route/link/api.c
+++ b/lib/route/link/api.c
@@ -61,10 +61,10 @@
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
{
if (ops->io_name == NULL)
- return nl_error(EINVAL, "No name specified");
+ return -NLE_INVAL;
if (rtnl_link_info_ops_lookup(ops->io_name))
- return nl_error(EEXIST, "Link info operations already exist");
+ return -NLE_EXIST;
NL_DBG(1, "Registered link info operations %s\n", ops->io_name);
@@ -83,10 +83,10 @@
break;
if (!t)
- return nl_error(ENOENT, "No such link info operations");
+ return -NLE_OPNOTSUPP;
if (t->io_refcnt > 0)
- return nl_error(EBUSY, "Info operations in use");
+ return -NLE_BUSY;
NL_DBG(1, "Unregistered link info perations %s\n", ops->io_name);
diff --git a/lib/route/link/vlan.c b/lib/route/link/vlan.c
index c148dca..ea5699f 100644
--- a/lib/route/link/vlan.c
+++ b/lib/route/link/vlan.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2007 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
/**
@@ -73,7 +73,7 @@
struct vlan_info *vi;
if ((vi = calloc(1, sizeof(*vi))) == NULL)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
link->l_info = vi;
@@ -119,12 +119,11 @@
nla_for_each_nested(nla, tb[IFLA_VLAN_INGRESS_QOS], remaining) {
if (nla_len(nla) < sizeof(*map))
- return nl_error(EINVAL, "Malformed mapping");
+ return -NLE_INVAL;
map = nla_data(nla);
if (map->from < 0 || map->from > VLAN_PRIO_MAX) {
- return nl_error(EINVAL, "VLAN prio %d out of "
- "range", map->from);
+ return -NLE_INVAL;
}
vi->vi_ingress_qos[map->from] = map->to;
@@ -140,7 +139,7 @@
nla_for_each_nested(nla, tb[IFLA_VLAN_EGRESS_QOS], remaining) {
if (nla_len(nla) < sizeof(*map))
- return nl_error(EINVAL, "Malformed mapping");
+ return -NLE_INVAL;
i++;
}
@@ -148,7 +147,7 @@
vi->vi_egress_size = (i + 32) & ~31;
vi->vi_egress_qos = calloc(vi->vi_egress_size, sizeof(*map));
if (vi->vi_egress_qos == NULL)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
i = 0;
nla_for_each_nested(nla, tb[IFLA_VLAN_EGRESS_QOS], remaining) {
@@ -260,7 +259,7 @@
vdst->vi_egress_qos = calloc(vsrc->vi_egress_size,
sizeof(struct vlan_map));
if (!vdst->vi_egress_qos)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
memcpy(vdst->vi_egress_qos, vsrc->vi_egress_qos,
vsrc->vi_egress_size * sizeof(struct vlan_map));
@@ -274,7 +273,7 @@
struct nlattr *data;
if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
- return nl_errno(ENOBUFS);
+ return -NLE_MSGSIZE;
if (vi->vi_mask & VLAN_HAS_ID)
NLA_PUT_U16(msg, IFLA_VLAN_ID, vi->vi_vlan_id);
@@ -349,7 +348,7 @@
struct vlan_info *vi = link->l_info;
if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
- return nl_error(EOPNOTSUPP, "Not a VLAN link");
+ return -NLE_OPNOTSUPP;
vi->vi_vlan_id = id;
vi->vi_mask |= VLAN_HAS_ID;
@@ -362,7 +361,7 @@
struct vlan_info *vi = link->l_info;
if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
- return nl_error(EOPNOTSUPP, "Not a VLAN link");
+ return -NLE_OPNOTSUPP;
if (vi->vi_mask & VLAN_HAS_ID)
return vi->vi_vlan_id;
@@ -375,7 +374,7 @@
struct vlan_info *vi = link->l_info;
if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
- return nl_error(EOPNOTSUPP, "Not a VLAN link");
+ return -NLE_OPNOTSUPP;
vi->vi_flags_mask |= flags;
vi->vi_flags |= flags;
@@ -389,7 +388,7 @@
struct vlan_info *vi = link->l_info;
if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
- return nl_error(EOPNOTSUPP, "Not a VLAN link");
+ return -NLE_OPNOTSUPP;
vi->vi_flags_mask |= flags;
vi->vi_flags &= ~flags;
@@ -403,7 +402,7 @@
struct vlan_info *vi = link->l_info;
if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
- return nl_error(EOPNOTSUPP, "Not a VLAN link");
+ return -NLE_OPNOTSUPP;
return vi->vi_flags;
}
@@ -414,11 +413,10 @@
struct vlan_info *vi = link->l_info;
if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
- return nl_error(EOPNOTSUPP, "Not a VLAN link");
+ return -NLE_OPNOTSUPP;
if (from < 0 || from > VLAN_PRIO_MAX)
- return nl_error(EINVAL, "Invalid vlan prio 0..%d",
- VLAN_PRIO_MAX);
+ return -NLE_INVAL;
vi->vi_ingress_qos[from] = to;
vi->vi_mask |= VLAN_HAS_INGRESS_QOS;
@@ -430,10 +428,8 @@
{
struct vlan_info *vi = link->l_info;
- if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) {
- nl_error(EOPNOTSUPP, "Not a VLAN link");
+ if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
return NULL;
- }
if (vi->vi_mask & VLAN_HAS_INGRESS_QOS)
return vi->vi_ingress_qos;
@@ -446,11 +442,10 @@
struct vlan_info *vi = link->l_info;
if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
- return nl_error(EOPNOTSUPP, "Not a VLAN link");
+ return -NLE_OPNOTSUPP;
if (to < 0 || to > VLAN_PRIO_MAX)
- return nl_error(EINVAL, "Invalid vlan prio 0..%d",
- VLAN_PRIO_MAX);
+ return -NLE_INVAL;
if (vi->vi_negress >= vi->vi_egress_size) {
int new_size = vi->vi_egress_size + 32;
@@ -458,7 +453,7 @@
ptr = realloc(vi->vi_egress_qos, new_size);
if (!ptr)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
vi->vi_egress_qos = ptr;
vi->vi_egress_size = new_size;
@@ -477,15 +472,11 @@
{
struct vlan_info *vi = link->l_info;
- if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops) {
- nl_error(EOPNOTSUPP, "Not a VLAN link");
+ if (link->l_info_ops != &vlan_info_ops || !link->l_info_ops)
return NULL;
- }
- if (negress == NULL) {
- nl_error(EINVAL, "Require pointer to store negress");
+ if (negress == NULL)
return NULL;
- }
if (vi->vi_mask & VLAN_HAS_EGRESS_QOS) {
*negress = vi->vi_negress;
diff --git a/lib/route/neigh.c b/lib/route/neigh.c
index fa1dc59..b3c8e5e 100644
--- a/lib/route/neigh.c
+++ b/lib/route/neigh.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>
*/
/**
@@ -187,15 +187,13 @@
if (src->n_lladdr)
if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr)))
- goto errout;
+ return -NLE_NOMEM;
if (src->n_dst)
if (!(dst->n_dst = nl_addr_clone(src->n_dst)))
- goto errout;
+ return -NLE_NOMEM;
return 0;
-errout:
- return nl_get_errno();
}
static int neigh_compare(struct nl_object *_a, struct nl_object *_b,
@@ -261,7 +259,7 @@
neigh = rtnl_neigh_alloc();
if (!neigh) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -523,30 +521,16 @@
/**
* Build a neighbour cache including all neighbours currently configured in the kernel.
* @arg handle netlink handle
+ * @arg result Pointer to store resulting cache.
*
* Allocates a new neighbour cache, initializes it properly and updates it
* to include all neighbours currently configured in the kernel.
*
- * @note The caller is responsible for destroying and freeing the
- * cache after using it.
- * @return The new cache or NULL if an error occured.
+ * @return 0 on success or a negative error code.
*/
-struct nl_cache *rtnl_neigh_alloc_cache(struct nl_handle *handle)
+int rtnl_neigh_alloc_cache(struct nl_handle *sock, struct nl_cache **result)
{
- struct nl_cache *cache;
-
- cache = nl_cache_alloc(&rtnl_neigh_ops);
- if (cache == NULL)
- return NULL;
-
- if (handle && nl_cache_refill(handle, cache) < 0) {
- nl_cache_free(cache);
- return NULL;
- }
-
- NL_DBG(2, "Returning new cache %p\n", cache);
-
- return cache;
+ return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result);
}
/**
@@ -579,8 +563,8 @@
* @{
*/
-static struct nl_msg * build_neigh_msg(struct rtnl_neigh *tmpl, int cmd,
- int flags)
+static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags,
+ struct nl_msg **result)
{
struct nl_msg *msg;
struct ndmsg nhdr = {
@@ -594,7 +578,7 @@
msg = nlmsg_alloc_simple(cmd, flags);
if (!msg)
- return NULL;
+ return -NLE_NOMEM;
if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
@@ -604,17 +588,19 @@
if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr);
- return msg;
+ *result = msg;
+ return 0;
nla_put_failure:
nlmsg_free(msg);
- return NULL;
+ return -NLE_MSGSIZE;
}
/**
* Build netlink request message to add a new neighbour
* @arg tmpl template with data of new neighbour
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a addition of a new
* neighbour. The netlink message header isn't fully equipped with
@@ -628,11 +614,13 @@
* - Destination address (rtnl_neigh_set_dst())
* - Link layer address (rtnl_neigh_set_lladdr())
*
- * @return The netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg * rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags)
+int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags,
+ struct nl_msg **result)
{
- return build_neigh_msg(tmpl, RTM_NEWNEIGH, NLM_F_CREATE | flags);
+ return build_neigh_msg(tmpl, RTM_NEWNEIGH, NLM_F_CREATE | flags,
+ result);
}
/**
@@ -658,12 +646,10 @@
int err;
struct nl_msg *msg;
- msg = rtnl_neigh_build_add_request(tmpl, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -681,6 +667,7 @@
* Build a netlink request message to delete a neighbour
* @arg neigh neighbour to delete
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a deletion of a neighbour.
* The netlink message header isn't fully equipped with all relevant
@@ -688,12 +675,12 @@
* or supplemented as needed. \a neigh must point to an existing
* neighbour.
*
- * @return The netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh,
- int flags)
+int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags,
+ struct nl_msg **result)
{
- return build_neigh_msg(neigh, RTM_DELNEIGH, flags);
+ return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result);
}
/**
@@ -711,15 +698,13 @@
int rtnl_neigh_delete(struct nl_handle *handle, struct rtnl_neigh *neigh,
int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_neigh_build_delete_request(neigh, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -737,20 +722,23 @@
* Build a netlink request message to change neighbour attributes
* @arg neigh the neighbour to change
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a change of a neigh
* attributes. The netlink message header isn't fully equipped with
* all relevant fields and must thus be sent out via nl_send_auto_complete()
* or supplemented as needed.
*
- * @return The netlink message
* @note Not all attributes can be changed, see
* \ref neigh_changeable "Changeable Attributes" for a list.
+ *
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_neigh_build_change_request(struct rtnl_neigh *neigh,
- int flags)
+int rtnl_neigh_build_change_request(struct rtnl_neigh *neigh, int flags,
+ struct nl_msg **result)
{
- return build_neigh_msg(neigh, RTM_NEWNEIGH, NLM_F_REPLACE | flags);
+ return build_neigh_msg(neigh, RTM_NEWNEIGH, NLM_F_REPLACE | flags,
+ result);
}
/**
@@ -770,15 +758,13 @@
int rtnl_neigh_change(struct nl_handle *handle, struct rtnl_neigh *neigh,
int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_neigh_build_change_request(neigh, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_neigh_build_change_request(neigh, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -905,8 +891,7 @@
if (!nocheck) {
if (neigh->ce_mask & NEIGH_ATTR_FAMILY) {
if (new->a_family != neigh->n_family)
- return nl_error(EINVAL,
- "Address family mismatch");
+ return -NLE_AF_MISMATCH;
} else {
neigh->n_family = new->a_family;
neigh->ce_mask |= NEIGH_ATTR_FAMILY;
diff --git a/lib/route/neightbl.c b/lib/route/neightbl.c
index 3191b5b..6010da0 100644
--- a/lib/route/neightbl.c
+++ b/lib/route/neightbl.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>
*/
/**
@@ -129,7 +129,7 @@
ntbl = rtnl_neightbl_alloc();
if (!ntbl) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -143,7 +143,7 @@
ntbl->nt_family = rtmsg->rtgen_family;
if (tb[NDTA_NAME] == NULL) {
- err = nl_error(EINVAL, "NDTA_NAME is missing");
+ return -NLE_MISSING_ATTR;
goto errout;
}
@@ -395,29 +395,17 @@
/**
* Build a neighbour table cache including all neighbour tables currently configured in the kernel.
* @arg handle netlink handle
+ * @arg result Pointer to store resulting cache.
*
* Allocates a new neighbour table cache, initializes it properly and
* updates it to include all neighbour tables currently configured in
* the kernel.
*
- * @note The caller is responsible for destroying and freeing the
- * cache after using it.
- * @return The new cache or NULL if an error occured.
+ * @return 0 on success or a negative error code.
*/
-struct nl_cache * rtnl_neightbl_alloc_cache(struct nl_handle *handle)
+int rtnl_neightbl_alloc_cache(struct nl_handle *sock, struct nl_cache **result)
{
- struct nl_cache * cache;
-
- cache = nl_cache_alloc(&rtnl_neightbl_ops);
- if (cache == NULL)
- return NULL;
-
- if (handle && nl_cache_refill(handle, cache) < 0) {
- nl_cache_free(cache);
- return NULL;
- }
-
- return cache;
+ return nl_cache_alloc_and_fill(&rtnl_neightbl_ops, sock, result);
}
/**
@@ -464,6 +452,7 @@
* Builds a netlink change request message to change neighbour table attributes
* @arg old neighbour table to change
* @arg tmpl template with requested changes
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a change of neighbour table
* attributes. The netlink message header isn't fully equipped with all
@@ -473,93 +462,110 @@
* kernel and \a tmpl must contain the attributes to be changed set via
* \c rtnl_neightbl_set_* functions.
*
- * @return New netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg * rtnl_neightbl_build_change_request(struct rtnl_neightbl *old,
- struct rtnl_neightbl *tmpl)
+int rtnl_neightbl_build_change_request(struct rtnl_neightbl *old,
+ struct rtnl_neightbl *tmpl,
+ struct nl_msg **result)
{
- struct nl_msg *m;
+ struct nl_msg *m, *parms = NULL;
struct ndtmsg ndt = {
.ndtm_family = old->nt_family,
};
m = nlmsg_alloc_simple(RTM_SETNEIGHTBL, 0);
- nlmsg_append(m, &ndt, sizeof(ndt), NLMSG_ALIGNTO);
+ if (!m)
+ return -NLE_NOMEM;
- nla_put_string(m, NDTA_NAME, old->nt_name);
+ if (nlmsg_append(m, &ndt, sizeof(ndt), NLMSG_ALIGNTO) < 0)
+ goto nla_put_failure;
+
+ NLA_PUT_STRING(m, NDTA_NAME, old->nt_name);
if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH1)
- nla_put_u32(m, NDTA_THRESH1, tmpl->nt_gc_thresh1);
+ NLA_PUT_U32(m, NDTA_THRESH1, tmpl->nt_gc_thresh1);
if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2)
- nla_put_u32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
+ NLA_PUT_U32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2)
- nla_put_u32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
+ NLA_PUT_U32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
if (tmpl->ce_mask & NEIGHTBL_ATTR_GC_INTERVAL)
- nla_put_u64(m, NDTA_GC_INTERVAL,
+ NLA_PUT_U64(m, NDTA_GC_INTERVAL,
tmpl->nt_gc_interval);
if (tmpl->ce_mask & NEIGHTBL_ATTR_PARMS) {
struct rtnl_neightbl_parms *p = &tmpl->nt_parms;
- struct nl_msg *parms = nlmsg_alloc();
+
+ parms = nlmsg_alloc();
+ if (!parms)
+ goto nla_put_failure;
if (old->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX)
- nla_put_u32(parms, NDTPA_IFINDEX,
+ NLA_PUT_U32(parms, NDTPA_IFINDEX,
old->nt_parms.ntp_ifindex);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_QUEUE_LEN)
- nla_put_u32(parms, NDTPA_QUEUE_LEN, p->ntp_queue_len);
+ NLA_PUT_U32(parms, NDTPA_QUEUE_LEN, p->ntp_queue_len);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_APP_PROBES)
- nla_put_u32(parms, NDTPA_APP_PROBES, p->ntp_app_probes);
+ NLA_PUT_U32(parms, NDTPA_APP_PROBES, p->ntp_app_probes);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_UCAST_PROBES)
- nla_put_u32(parms, NDTPA_UCAST_PROBES,
+ NLA_PUT_U32(parms, NDTPA_UCAST_PROBES,
p->ntp_ucast_probes);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_MCAST_PROBES)
- nla_put_u32(parms, NDTPA_MCAST_PROBES,
+ NLA_PUT_U32(parms, NDTPA_MCAST_PROBES,
p->ntp_mcast_probes);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_QLEN)
- nla_put_u32(parms, NDTPA_PROXY_QLEN,
+ NLA_PUT_U32(parms, NDTPA_PROXY_QLEN,
p->ntp_proxy_qlen);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME)
- nla_put_u64(parms, NDTPA_BASE_REACHABLE_TIME,
+ NLA_PUT_U64(parms, NDTPA_BASE_REACHABLE_TIME,
p->ntp_base_reachable_time);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_RETRANS_TIME)
- nla_put_u64(parms, NDTPA_RETRANS_TIME,
+ NLA_PUT_U64(parms, NDTPA_RETRANS_TIME,
p->ntp_retrans_time);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_GC_STALETIME)
- nla_put_u64(parms, NDTPA_GC_STALETIME,
+ NLA_PUT_U64(parms, NDTPA_GC_STALETIME,
p->ntp_gc_stale_time);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME)
- nla_put_u64(parms, NDTPA_DELAY_PROBE_TIME,
+ NLA_PUT_U64(parms, NDTPA_DELAY_PROBE_TIME,
p->ntp_proxy_delay);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_ANYCAST_DELAY)
- nla_put_u64(parms, NDTPA_ANYCAST_DELAY,
+ NLA_PUT_U64(parms, NDTPA_ANYCAST_DELAY,
p->ntp_anycast_delay);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_DELAY)
- nla_put_u64(parms, NDTPA_PROXY_DELAY,
+ NLA_PUT_U64(parms, NDTPA_PROXY_DELAY,
p->ntp_proxy_delay);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_LOCKTIME)
- nla_put_u64(parms, NDTPA_LOCKTIME, p->ntp_locktime);
+ NLA_PUT_U64(parms, NDTPA_LOCKTIME, p->ntp_locktime);
- nla_put_nested(m, NDTA_PARMS, parms);
+ if (nla_put_nested(m, NDTA_PARMS, parms) < 0)
+ goto nla_put_failure;
+
nlmsg_free(parms);
}
-
- return m;
+
+ *result = m;
+ return 0;
+
+nla_put_failure:
+ if (parms)
+ nlmsg_free(parms);
+ nlmsg_free(m);
+ return -NLE_MSGSIZE;
}
/**
@@ -578,12 +584,13 @@
int rtnl_neightbl_change(struct nl_handle *handle, struct rtnl_neightbl *old,
struct rtnl_neightbl *tmpl)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_neightbl_build_change_request(old, tmpl);
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = rtnl_neightbl_build_change_request(old, tmpl, &msg)) < 0)
+ return err;
+
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
diff --git a/lib/route/nexthop.c b/lib/route/nexthop.c
index 2db6d90..e5348b0 100644
--- a/lib/route/nexthop.c
+++ b/lib/route/nexthop.c
@@ -39,10 +39,8 @@
struct rtnl_nexthop *nh;
nh = calloc(1, sizeof(*nh));
- if (!nh) {
- nl_errno(ENOMEM);
+ if (!nh)
return NULL;
- }
nl_init_list_head(&nh->rtnh_list);
diff --git a/lib/route/qdisc.c b/lib/route/qdisc.c
index bc89663..8b2de2f 100644
--- a/lib/route/qdisc.c
+++ b/lib/route/qdisc.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>
*/
/**
@@ -98,13 +98,13 @@
static int qdisc_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, struct nl_parser_param *pp)
{
- int err = -ENOMEM;
+ int err;
struct rtnl_qdisc *qdisc;
struct rtnl_qdisc_ops *qops;
qdisc = rtnl_qdisc_alloc();
if (!qdisc) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -149,15 +149,15 @@
* @{
*/
-static struct nl_msg *qdisc_build(struct rtnl_qdisc *qdisc, int type, int flags)
+static int qdisc_build(struct rtnl_qdisc *qdisc, int type, int flags,
+ struct nl_msg **result)
{
struct rtnl_qdisc_ops *qops;
- struct nl_msg *msg;
int err;
- msg = tca_build_msg((struct rtnl_tca *) qdisc, type, flags);
- if (!msg)
- goto errout;
+ err = tca_build_msg((struct rtnl_tca *) qdisc, type, flags, result);
+ if (err < 0)
+ return err;
qops = rtnl_qdisc_lookup_ops(qdisc);
if (qops && qops->qo_get_opts) {
@@ -165,7 +165,7 @@
opts = qops->qo_get_opts(qdisc);
if (opts) {
- err = nla_put_nested(msg, TCA_OPTIONS, opts);
+ err = nla_put_nested(*result, TCA_OPTIONS, opts);
nlmsg_free(opts);
if (err < 0)
goto errout;
@@ -175,22 +175,23 @@
* accomodate for this, they can complete the message themselves.
*/
else if (qops && qops->qo_build_msg) {
- err = qops->qo_build_msg(qdisc, msg);
- if ( err < 0 )
+ err = qops->qo_build_msg(qdisc, *result);
+ if (err < 0)
goto errout;
}
- return msg;
+ return 0;
errout:
- nlmsg_free(msg);
+ nlmsg_free(*result);
- return NULL;
+ return err;
}
/**
* Build a netlink message to add a new qdisc
* @arg qdisc qdisc to add
* @arg flags additional netlink message flags
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting an addition of a qdisc.
* The netlink message header isn't fully equipped with all relevant
@@ -200,18 +201,12 @@
* Common message flags used:
* - NLM_F_REPLACE - replace a potential existing qdisc
*
- * @return New netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_qdisc_build_add_request(struct rtnl_qdisc *qdisc,
- int flags)
+int rtnl_qdisc_build_add_request(struct rtnl_qdisc *qdisc, int flags,
+ struct nl_msg **result)
{
- struct nl_msg *msg;
-
- msg = qdisc_build(qdisc, RTM_NEWQDISC, NLM_F_CREATE | flags);
- if (!msg)
- nl_errno(ENOMEM);
-
- return msg;
+ return qdisc_build(qdisc, RTM_NEWQDISC, NLM_F_CREATE | flags, result);
}
/**
@@ -235,12 +230,10 @@
struct nl_msg *msg;
int err;
- msg = rtnl_qdisc_build_add_request(qdisc, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_qdisc_build_add_request(qdisc, flags, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -258,18 +251,20 @@
* Build a netlink message to change attributes of a existing qdisc
* @arg qdisc qdisc to change
* @arg new new qdisc attributes
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting an change of qdisc
* attributes. The netlink message header isn't fully equipped
* with all relevant fields and must be sent out via
* nl_send_auto_complete() or supplemented as needed.
*
- * @return New netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_qdisc_build_change_request(struct rtnl_qdisc *qdisc,
- struct rtnl_qdisc *new)
+int rtnl_qdisc_build_change_request(struct rtnl_qdisc *qdisc,
+ struct rtnl_qdisc *new,
+ struct nl_msg **result)
{
- return qdisc_build(qdisc, RTM_NEWQDISC, NLM_F_REPLACE);
+ return qdisc_build(qdisc, RTM_NEWQDISC, NLM_F_REPLACE, result);
}
/**
@@ -290,12 +285,10 @@
struct nl_msg *msg;
int err;
- msg = rtnl_qdisc_build_change_request(qdisc, new);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_qdisc_build_change_request(qdisc, new, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -312,15 +305,17 @@
/**
* Build a netlink request message to delete a qdisc
* @arg qdisc qdisc to delete
+ * @arg result Pointer to store resulting message.
*
* Builds a new netlink message requesting a deletion of a qdisc.
* The netlink message header isn't fully equipped with all relevant
* fields and must thus be sent out via nl_send_auto_complete()
* or supplemented as needed.
*
- * @return New netlink message
+ * @return 0 on success or a negative error code.
*/
-struct nl_msg *rtnl_qdisc_build_delete_request(struct rtnl_qdisc *qdisc)
+int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *qdisc,
+ struct nl_msg **result)
{
struct nl_msg *msg;
struct tcmsg tchdr;
@@ -331,15 +326,19 @@
msg = nlmsg_alloc_simple(RTM_DELQDISC, 0);
if (!msg)
- return NULL;
+ return -NLE_NOMEM;
- tchdr.tcm_family = AF_UNSPEC,
- tchdr.tcm_handle = qdisc->q_handle,
- tchdr.tcm_parent = qdisc->q_parent,
- tchdr.tcm_ifindex = qdisc->q_ifindex,
- nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO);
+ tchdr.tcm_family = AF_UNSPEC;
+ tchdr.tcm_handle = qdisc->q_handle;
+ tchdr.tcm_parent = qdisc->q_parent;
+ tchdr.tcm_ifindex = qdisc->q_ifindex;
+ if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0) {
+ nlmsg_free(msg);
+ return -NLE_MSGSIZE;
+ }
- return msg;
+ *result = msg;
+ return 0;
}
/**
@@ -358,12 +357,10 @@
struct nl_msg *msg;
int err;
- msg = rtnl_qdisc_build_delete_request(qdisc);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_qdisc_build_delete_request(qdisc, &msg)) < 0)
+ return err;
- err = nl_send_auto_complete(handle, msg);
- if (err < 0)
+ if ((err = nl_send_auto_complete(handle, msg)) < 0)
return err;
nlmsg_free(msg);
@@ -380,29 +377,17 @@
/**
* Build a qdisc cache including all qdiscs currently configured in
* the kernel
- * @arg handle netlink handle
+ * @arg sock netlink handle
+ * @arg result Pointer to store resulting message.
*
* Allocates a new cache, initializes it properly and updates it to
* include all qdiscs currently configured 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 * rtnl_qdisc_alloc_cache(struct nl_handle *handle)
+int rtnl_qdisc_alloc_cache(struct nl_handle *sock, struct nl_cache **result)
{
- struct nl_cache * cache;
-
- cache = nl_cache_alloc(&rtnl_qdisc_ops);
- if (cache == NULL)
- return NULL;
-
- if (handle && nl_cache_refill(handle, cache) < 0) {
- nl_cache_free(cache);
- return NULL;
- }
-
- return cache;
+ return nl_cache_alloc_and_fill(&rtnl_qdisc_ops, sock, result);
}
/**
diff --git a/lib/route/qdisc_api.c b/lib/route/qdisc_api.c
index ef4d07a..089f212 100644
--- a/lib/route/qdisc_api.c
+++ b/lib/route/qdisc_api.c
@@ -46,7 +46,7 @@
for (op = &qdisc_ops_list; (o = *op) != NULL; op = &o->qo_next)
if (!strcasecmp(qops->qo_kind, o->qo_kind))
- return nl_errno(EEXIST);
+ return -NLE_EXIST;
qops->qo_next = NULL;
*op = qops;
@@ -67,7 +67,7 @@
break;
if (!o)
- return nl_errno(ENOENT);
+ return -NLE_OBJ_NOTFOUND;
*op = qops->qo_next;
diff --git a/lib/route/route.c b/lib/route/route.c
index 260d3e2..823d695 100644
--- a/lib/route/route.c
+++ b/lib/route/route.c
@@ -33,8 +33,8 @@
struct rtnl_route *route;
int err;
- if (!(route = rtnl_route_parse(nlh)))
- return -EINVAL;
+ if ((err = rtnl_route_parse(nlh, &route)) < 0)
+ return err;
if ((err = pp->pp_cb((struct nl_object *) route, pp)) < 0)
goto errout;
@@ -76,24 +76,25 @@
* cache after using it.
* @return The cache or NULL if an error has occured.
*/
-struct nl_cache *rtnl_route_alloc_cache(struct nl_handle *handle,
- int family, int flags)
+int rtnl_route_alloc_cache(struct nl_handle *handle, int family, int flags,
+ struct nl_cache **result)
{
struct nl_cache *cache;
+ int err;
- cache = nl_cache_alloc(&rtnl_route_ops);
- if (!cache)
- return NULL;
+ if (!(cache = nl_cache_alloc(&rtnl_route_ops)))
+ return -NLE_NOMEM;
cache->c_iarg1 = family;
cache->c_iarg2 = flags;
- if (handle && nl_cache_refill(handle, cache) < 0) {
+ if (handle && (err = nl_cache_refill(handle, cache)) < 0) {
free(cache);
- return NULL;
+ return err;
}
- return cache;
+ *result = cache;
+ return 0;
}
/** @} */
@@ -103,26 +104,29 @@
* @{
*/
-static struct nl_msg *build_route_msg(struct rtnl_route *tmpl, int cmd,
- int flags)
+static int build_route_msg(struct rtnl_route *tmpl, int cmd, int flags,
+ struct nl_msg **result)
{
struct nl_msg *msg;
+ int err;
- msg = nlmsg_alloc_simple(cmd, flags);
- if (msg == NULL)
- return NULL;
+ if (!(msg = nlmsg_alloc_simple(cmd, flags)))
+ return -NLE_NOMEM;
- if (rtnl_route_build_msg(msg, tmpl) < 0) {
+ if ((err = rtnl_route_build_msg(msg, tmpl)) < 0) {
nlmsg_free(msg);
- return NULL;
+ return err;
}
- return msg;
+ *result = msg;
+ return 0;
}
-struct nl_msg *rtnl_route_build_add_request(struct rtnl_route *tmpl, int flags)
+int rtnl_route_build_add_request(struct rtnl_route *tmpl, int flags,
+ struct nl_msg **result)
{
- return build_route_msg(tmpl, RTM_NEWROUTE, NLM_F_CREATE | flags);
+ return build_route_msg(tmpl, RTM_NEWROUTE, NLM_F_CREATE | flags,
+ result);
}
int rtnl_route_add(struct nl_handle *handle, struct rtnl_route *route,
@@ -131,9 +135,8 @@
struct nl_msg *msg;
int err;
- msg = rtnl_route_build_add_request(route, flags);
- if (!msg)
- return nl_get_errno();
+ if ((err = rtnl_route_build_add_request(route, flags, &msg)) < 0)
+ return err;
err = nl_send_auto_complete(handle, msg);
nlmsg_free(msg);
@@ -143,9 +146,10 @@
return nl_wait_for_ack(handle);
}
-struct nl_msg *rtnl_route_build_del_request(struct rtnl_route *tmpl, int flags)
+int rtnl_route_build_del_request(struct rtnl_route *tmpl, int flags,
+ struct nl_msg **result)
{
- return build_route_msg(tmpl, RTM_DELROUTE, flags);
+ return build_route_msg(tmpl, RTM_DELROUTE, flags, result);
}
int rtnl_route_delete(struct nl_handle *handle, struct rtnl_route *route,
@@ -154,9 +158,8 @@
struct nl_msg *msg;
int err;
- msg = rtnl_route_build_del_request(route, flags);
- if (!msg)
- return nl_get_errno();
+ if ((err = rtnl_route_build_del_request(route, flags, &msg)) < 0)
+ return err;
err = nl_send_auto_complete(handle, msg);
nlmsg_free(msg);
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c
index 200f561..2be6d62 100644
--- a/lib/route/route_obj.c
+++ b/lib/route/route_obj.c
@@ -100,28 +100,26 @@
if (src->rt_dst)
if (!(dst->rt_dst = nl_addr_clone(src->rt_dst)))
- goto errout;
+ return -NLE_NOMEM;
if (src->rt_src)
if (!(dst->rt_src = nl_addr_clone(src->rt_src)))
- goto errout;
+ return -NLE_NOMEM;
if (src->rt_pref_src)
if (!(dst->rt_pref_src = nl_addr_clone(src->rt_pref_src)))
- goto errout;
+ return -NLE_NOMEM;
nl_init_list_head(&dst->rt_nexthops);
nl_list_for_each_entry(nh, &src->rt_nexthops, rtnh_list) {
new = rtnl_route_nh_clone(nh);
if (!new)
- goto errout;
+ return -NLE_NOMEM;
rtnl_route_add_nexthop(dst, new);
}
return 0;
-errout:
- return nl_get_errno();
}
static int route_dump_oneline(struct nl_object *a, struct nl_dump_params *p)
@@ -559,8 +557,7 @@
int rtnl_route_set_family(struct rtnl_route *route, uint8_t family)
{
if (family != AF_INET && family != AF_INET6 && family != AF_DECnet)
- return nl_error(EINVAL, "Unsupported address family, "
- "supported: { INET | INET6 | DECnet }");
+ return -NLE_AF_NOSUPPORT;
route->rt_family = family;
route->ce_mask |= ROUTE_ATTR_FAMILY;
@@ -577,7 +574,7 @@
{
if (route->ce_mask & ROUTE_ATTR_FAMILY) {
if (addr->a_family != route->rt_family)
- return nl_error(EINVAL, "Address family mismatch");
+ return -NLE_AF_MISMATCH;
} else
route->rt_family = addr->a_family;
@@ -600,12 +597,11 @@
int rtnl_route_set_src(struct rtnl_route *route, struct nl_addr *addr)
{
if (addr->a_family == AF_INET)
- return nl_error(EINVAL, "IPv4 does not support source based "
- "routing.");
+ return -NLE_SRCRT_NOSUPPORT;
if (route->ce_mask & ROUTE_ATTR_FAMILY) {
if (addr->a_family != route->rt_family)
- return nl_error(EINVAL, "Address family mismatch");
+ return -NLE_AF_MISMATCH;
} else
route->rt_family = addr->a_family;
@@ -627,8 +623,8 @@
int rtnl_route_set_type(struct rtnl_route *route, uint8_t type)
{
if (type > RTN_MAX)
- return nl_error(ERANGE, "Invalid route type %d, valid range "
- "is 0..%d", type, RTN_MAX);
+ return -NLE_RANGE;
+
route->rt_type = type;
route->ce_mask |= ROUTE_ATTR_TYPE;
@@ -662,8 +658,7 @@
int rtnl_route_set_metric(struct rtnl_route *route, int metric, uint32_t value)
{
if (metric > RTAX_MAX || metric < 1)
- return nl_error(EINVAL, "Metric out of range (1..%d)",
- RTAX_MAX);
+ return -NLE_RANGE;
route->rt_metrics[metric - 1] = value;
@@ -680,8 +675,7 @@
int rtnl_route_unset_metric(struct rtnl_route *route, int metric)
{
if (metric > RTAX_MAX || metric < 1)
- return nl_error(EINVAL, "Metric out of range (1..%d)",
- RTAX_MAX);
+ return -NLE_RANGE;
if (route->rt_metrics_mask & (1 << (metric - 1))) {
route->rt_nmetrics--;
@@ -694,11 +688,10 @@
int rtnl_route_get_metric(struct rtnl_route *route, int metric, uint32_t *value)
{
if (metric > RTAX_MAX || metric < 1)
- return nl_error(EINVAL, "Metric out of range (1..%d)",
- RTAX_MAX);
+ return -NLE_RANGE;
if (!(route->rt_metrics_mask & (1 << (metric - 1))))
- return nl_error(ENOENT, "Metric %d not available", metric);
+ return -NLE_OBJ_NOTFOUND;
if (value)
*value = route->rt_metrics[metric - 1];
@@ -710,7 +703,7 @@
{
if (route->ce_mask & ROUTE_ATTR_FAMILY) {
if (addr->a_family != route->rt_family)
- return nl_error(EINVAL, "Address family mismatch");
+ return -NLE_AF_MISMATCH;
} else
route->rt_family = addr->a_family;
@@ -844,7 +837,7 @@
[RTA_MULTIPATH] = { .type = NLA_NESTED },
};
-struct rtnl_route *rtnl_route_parse(struct nlmsghdr *nlh)
+int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
{
struct rtmsg *rtm;
struct rtnl_route *route;
@@ -855,7 +848,7 @@
route = rtnl_route_alloc();
if (!route) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -1034,8 +1027,7 @@
if (rtnl_route_nh_compare(old_nh, first,
old_nh->ce_mask, 0)) {
- nl_error(EINVAL, "Mismatch of multipath "
- "configuration.");
+ err = -NLE_INVAL;
goto errout;
}
@@ -1043,11 +1035,12 @@
}
}
- return route;
+ *result = route;
+ return 0;
errout:
rtnl_route_put(route);
- return NULL;
+ return err;
}
int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)
@@ -1065,8 +1058,7 @@
};
if (route->rt_dst == NULL)
- return nl_error(EINVAL, "Cannot build route message, please "
- "specify route destination.");
+ return -NLE_MISSING_ATTR;
rtmsg.rtm_dst_len = nl_addr_get_prefixlen(route->rt_dst);
if (route->rt_src)
@@ -1145,7 +1137,7 @@
return 0;
nla_put_failure:
- return -ENOBUFS;
+ return -NLE_MSGSIZE;
}
/** @cond SKIP */
diff --git a/lib/route/rule.c b/lib/route/rule.c
index 0493818..8684cf2 100644
--- a/lib/route/rule.c
+++ b/lib/route/rule.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>
*/
/**
@@ -60,15 +60,13 @@
if (src->r_src)
if (!(dst->r_src = nl_addr_clone(src->r_src)))
- goto errout;
+ return -NLE_NOMEM;
if (src->r_dst)
if (!(dst->r_dst = nl_addr_clone(src->r_dst)))
- goto errout;
+ return -NLE_NOMEM;
return 0;
-errout:
- return nl_get_errno();
}
static struct nla_policy rule_policy[RTA_MAX+1] = {
@@ -89,7 +87,7 @@
rule = rtnl_rule_alloc();
if (!rule) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
@@ -118,7 +116,7 @@
if (tb[RTA_SRC]) {
rule->r_src = nla_get_addr(tb[RTA_SRC], r->rtm_family);
if (!rule->r_src) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
nl_addr_set_prefixlen(rule->r_src, r->rtm_src_len);
@@ -128,7 +126,7 @@
if (tb[RTA_DST]) {
rule->r_dst = nla_get_addr(tb[RTA_DST], r->rtm_family);
if (!rule->r_dst) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
nl_addr_set_prefixlen(rule->r_dst, r->rtm_dst_len);
@@ -153,7 +151,7 @@
if (tb[RTA_GATEWAY]) {
rule->r_srcmap = nla_get_addr(tb[RTA_GATEWAY], r->rtm_family);
if (!rule->r_srcmap) {
- err = nl_errno(ENOMEM);
+ err = -NLE_NOMEM;
goto errout;
}
rule->ce_mask |= RULE_ATTR_SRCMAP;
@@ -440,51 +438,34 @@
*/
/**
- * Build a rule cache including all rules of the specified family currently configured in the kernel.
- * @arg handle netlink handle
- * @arg family address family
- *
- * Allocates a new rule cache, initializes it properly and updates it
- * to include all rules of the specified address family currently
- * configured in the kernel.
- *
- * @note The caller is responsible for destroying and freeing the
- * cache after using it. (nl_cache_destroy_and_free())
- * @return The new cache or NULL if an error occured.
- */
-struct nl_cache * rtnl_rule_alloc_cache_by_family(struct nl_handle *handle,
- int family)
-{
- struct nl_cache * cache;
-
- cache = nl_cache_alloc(&rtnl_rule_ops);
- if (cache == NULL)
- return NULL;
-
- /* XXX RULE_CACHE_FAMILY(cache) = family; */
-
- if (handle && nl_cache_refill(handle, cache) < 0) {
- free(cache);
- return NULL;
- }
-
- return cache;
-}
-
-/**
* Build a rule cache including all rules currently configured in the kernel.
* @arg handle netlink handle
+ * @arg family Address family or AF_UNSPEC.
+ * @arg result Pointer to store resulting cache.
*
* Allocates a new rule cache, initializes it properly and updates it
* to include all rules currently configured in the kernel.
*
- * @note The caller is responsible for destroying and freeing the
- * cache after using it. (nl_cache_destroy_and_free())
- * @return The new cache or NULL if an error occured.
+ * @return 0 on success or a negative error code.
*/
-struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *handle)
+int rtnl_rule_alloc_cache(struct nl_handle *sock, int family,
+ struct nl_cache **result)
{
- return rtnl_rule_alloc_cache_by_family(handle, AF_UNSPEC);
+ struct nl_cache * cache;
+ int err;
+
+ if (!(cache = nl_cache_alloc(&rtnl_rule_ops)))
+ return -NLE_NOMEM;
+
+ cache->c_iarg1 = family;
+
+ if (sock && (err = nl_cache_refill(sock, cache)) < 0) {
+ free(cache);
+ return err;
+ }
+
+ *result = cache;
+ return 0;
}
/** @} */
@@ -494,7 +475,8 @@
* @{
*/
-static struct nl_msg *build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags)
+static int build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags,
+ struct nl_msg **result)
{
struct nl_msg *msg;
struct rtmsg rtm = {
@@ -524,7 +506,7 @@
msg = nlmsg_alloc_simple(cmd, flags);
if (!msg)
- goto nla_put_failure;
+ return -NLE_NOMEM;
if (nlmsg_append(msg, &rtm, sizeof(rtm), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
@@ -547,11 +529,12 @@
if (tmpl->ce_mask & RULE_ATTR_IIF)
NLA_PUT_STRING(msg, RTA_IIF, tmpl->r_iif);
- return msg;
+ *result = msg;
+ return 0;
nla_put_failure:
nlmsg_free(msg);
- return NULL;
+ return -NLE_MSGSIZE;
}
/**
@@ -567,9 +550,11 @@
*
* @return The netlink message
*/
-struct nl_msg *rtnl_rule_build_add_request(struct rtnl_rule *tmpl, int flags)
+int rtnl_rule_build_add_request(struct rtnl_rule *tmpl, int flags,
+ struct nl_msg **result)
{
- return build_rule_msg(tmpl, RTM_NEWRULE, NLM_F_CREATE | flags);
+ return build_rule_msg(tmpl, RTM_NEWRULE, NLM_F_CREATE | flags,
+ result);
}
/**
@@ -586,18 +571,17 @@
*/
int rtnl_rule_add(struct nl_handle *handle, struct rtnl_rule *tmpl, int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_rule_build_add_request(tmpl, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_rule_build_add_request(tmpl, flags, &msg)) < 0)
+ return err;
err = nl_send_auto_complete(handle, msg);
+ nlmsg_free(msg);
if (err < 0)
return err;
- nlmsg_free(msg);
return nl_wait_for_ack(handle);
}
@@ -621,9 +605,10 @@
*
* @return The netlink message
*/
-struct nl_msg *rtnl_rule_build_delete_request(struct rtnl_rule *rule, int flags)
+int rtnl_rule_build_delete_request(struct rtnl_rule *rule, int flags,
+ struct nl_msg **result)
{
- return build_rule_msg(rule, RTM_DELRULE, flags);
+ return build_rule_msg(rule, RTM_DELRULE, flags, result);
}
/**
@@ -641,18 +626,17 @@
int rtnl_rule_delete(struct nl_handle *handle, struct rtnl_rule *rule,
int flags)
{
- int err;
struct nl_msg *msg;
+ int err;
- msg = rtnl_rule_build_delete_request(rule, flags);
- if (!msg)
- return nl_errno(ENOMEM);
+ if ((err = rtnl_rule_build_delete_request(rule, flags, &msg)) < 0)
+ return err;
err = nl_send_auto_complete(handle, msg);
+ nlmsg_free(msg);
if (err < 0)
return err;
- nlmsg_free(msg);
return nl_wait_for_ack(handle);
}
@@ -770,7 +754,7 @@
{
if (rule->ce_mask & RULE_ATTR_FAMILY) {
if (new->a_family != rule->r_family)
- return nl_error(EINVAL, "Address family mismatch");
+ return -NLE_AF_MISMATCH;
} else
rule->r_family = new->a_family;
@@ -817,7 +801,7 @@
int rtnl_rule_set_iif(struct rtnl_rule *rule, const char *dev)
{
if (strlen(dev) > IFNAMSIZ-1)
- return nl_errno(ERANGE);
+ return -NLE_RANGE;
strcpy(rule->r_iif, dev);
rule->ce_mask |= RULE_ATTR_IIF;
@@ -843,7 +827,7 @@
if (rule->ce_mask & RULE_ATTR_TYPE)
return rule->r_type;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
void rtnl_rule_set_realms(struct rtnl_rule *rule, uint32_t realms)
diff --git a/lib/route/sch/cbq.c b/lib/route/sch/cbq.c
index 9808509..50fb7b2 100644
--- a/lib/route/sch/cbq.c
+++ b/lib/route/sch/cbq.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>
*/
#include <netlink-local.h>
@@ -99,7 +99,7 @@
cbq = cbq_alloc(tca);
if (!cbq)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
nla_memcpy(&cbq->cbq_lss, tb[TCA_CBQ_LSSOPT], sizeof(cbq->cbq_lss));
nla_memcpy(&cbq->cbq_rate, tb[TCA_CBQ_RATE], sizeof(cbq->cbq_rate));
@@ -133,7 +133,7 @@
struct rtnl_cbq *src = cbq_qdisc(_src);
if (src && !cbq_alloc(_dst))
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
else
return 0;
}
diff --git a/lib/route/sch/dsmark.c b/lib/route/sch/dsmark.c
index 5ba6b92..b0787a9 100644
--- a/lib/route/sch/dsmark.c
+++ b/lib/route/sch/dsmark.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>
*/
/**
@@ -70,7 +70,7 @@
dsmark = dsmark_qdisc_alloc(qdisc);
if (!dsmark)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (tb[TCA_DSMARK_INDICES]) {
dsmark->qdm_indices = nla_get_u16(tb[TCA_DSMARK_INDICES]);
@@ -118,7 +118,7 @@
dsmark = dsmark_class_alloc(class);
if (!dsmark)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (tb[TCA_DSMARK_MASK]) {
dsmark->cdm_bmask = nla_get_u8(tb[TCA_DSMARK_MASK]);
@@ -251,7 +251,7 @@
dsmark = dsmark_class(class);
if (!dsmark)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
dsmark->cdm_bmask = mask;
dsmark->cdm_mask |= SCH_DSMARK_ATTR_MASK;
@@ -272,7 +272,7 @@
if (dsmark && dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK)
return dsmark->cdm_bmask;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -287,7 +287,7 @@
dsmark = dsmark_class(class);
if (!dsmark)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
dsmark->cdm_value = value;
dsmark->cdm_mask |= SCH_DSMARK_ATTR_VALUE;
@@ -308,7 +308,7 @@
if (dsmark && dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE)
return dsmark->cdm_value;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
@@ -329,7 +329,7 @@
dsmark = dsmark_qdisc(qdisc);
if (!dsmark)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
dsmark->qdm_indices = indices;
dsmark->qdm_mask |= SCH_DSMARK_ATTR_INDICES;
@@ -350,7 +350,7 @@
if (dsmark && dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES)
return dsmark->qdm_indices;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -366,7 +366,7 @@
dsmark = dsmark_qdisc(qdisc);
if (!dsmark)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
dsmark->qdm_default_index = default_index;
dsmark->qdm_mask |= SCH_DSMARK_ATTR_DEFAULT_INDEX;
@@ -387,7 +387,7 @@
if (dsmark && dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX)
return dsmark->qdm_default_index;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -402,7 +402,7 @@
dsmark = dsmark_qdisc(qdisc);
if (!dsmark)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
dsmark->qdm_set_tc_index = !!flag;
dsmark->qdm_mask |= SCH_DSMARK_ATTR_SET_TC_INDEX;
@@ -424,7 +424,7 @@
if (dsmark && dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX)
return dsmark->qdm_set_tc_index;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
diff --git a/lib/route/sch/fifo.c b/lib/route/sch/fifo.c
index 4f8d202..a8953f9 100644
--- a/lib/route/sch/fifo.c
+++ b/lib/route/sch/fifo.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>
*/
/**
@@ -60,11 +60,11 @@
struct tc_fifo_qopt *opt;
if (qdisc->q_opts->d_size < sizeof(struct tc_fifo_qopt))
- return nl_error(EINVAL, "FIFO options size mismatch");
+ return -NLE_INVAL;
fifo = fifo_alloc(qdisc);
if (!fifo)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
opt = (struct tc_fifo_qopt *) qdisc->q_opts->d_data;
fifo->qf_limit = opt->limit;
@@ -148,7 +148,7 @@
fifo = fifo_alloc(qdisc);
if (!fifo)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
fifo->qf_limit = limit;
fifo->qf_mask |= SCH_FIFO_ATTR_LIMIT;
@@ -169,7 +169,7 @@
if (fifo && fifo->qf_mask & SCH_FIFO_ATTR_LIMIT)
return fifo->qf_limit;
else
- return nl_errno(ENOMEM);
+ return -NLE_NOATTR;
}
/** @} */
diff --git a/lib/route/sch/netem.c b/lib/route/sch/netem.c
index cb9eca7..34a3d14 100644
--- a/lib/route/sch/netem.c
+++ b/lib/route/sch/netem.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>
*/
/**
@@ -69,11 +69,11 @@
struct tc_netem_qopt *opts;
if (qdisc->q_opts->d_size < sizeof(*opts))
- return nl_error(EINVAL, "Netem specific options size mismatch");
+ return -NLE_INVAL;
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
opts = (struct tc_netem_qopt *) qdisc->q_opts->d_data;
netem->qnm_latency = opts->latency;
@@ -202,56 +202,48 @@
if ( netem->qnm_ro.nmro_probability != 0 ) {
if (netem->qnm_latency == 0) {
- return nl_error(EINVAL,
- "netem: Specified reorder gap without latency.");
+ return -NLE_MISSING_ATTR;
}
if (netem->qnm_gap == 0) netem->qnm_gap = 1;
}
else if ( netem->qnm_gap ) {
- return nl_error(EINVAL,
- "netem: Specified reorder gap without reorder probability.");
+ return -NLE_MISSING_ATTR;
}
if ( netem->qnm_corr.nmc_delay != 0 ) {
if ( netem->qnm_latency == 0 || netem->qnm_jitter == 0) {
- return nl_error(EINVAL,
- "netem: Specified delay correlation without delay size / jitter.");
+ return -NLE_MISSING_ATTR;
}
set_correlation = 1;
}
if ( netem->qnm_corr.nmc_loss != 0 ) {
if ( netem->qnm_loss == 0 ) {
- return nl_error(EINVAL,
- "netem: Specified loss correlation without loss probability.");
+ return -NLE_MISSING_ATTR;
}
set_correlation = 1;
}
if ( netem->qnm_corr.nmc_duplicate != 0 ) {
if ( netem->qnm_duplicate == 0 ) {
- return nl_error(EINVAL,
- "netem: Specified dup correlation without duplication probability.");
+ return -NLE_MISSING_ATTR;
}
set_correlation = 1;
}
if ( netem->qnm_ro.nmro_probability != 0 ) set_reorder = 1;
else if ( netem->qnm_ro.nmro_correlation != 0 ) {
- return nl_error(EINVAL,
- "netem: Specified reorder correlation without reorder probability.");
+ return -NLE_MISSING_ATTR;
}
if ( netem->qnm_crpt.nmcr_probability != 0 ) set_corrupt = 1;
else if ( netem->qnm_crpt.nmcr_correlation != 0 ) {
- return nl_error(EINVAL,
- "netem: Specified corrupt correlation without corrupt probability.");
+ return -NLE_MISSING_ATTR;
}
if ( netem->qnm_dist.dist_data && netem->qnm_dist.dist_size ) {
if (netem->qnm_latency == 0 || netem->qnm_jitter == 0) {
- return nl_error(EINVAL,
- "netem: Distribution specified with empty latency and jitter values.");
+ return -NLE_MISSING_ATTR;
}
else {
/* Resize to accomodate the large distribution table */
@@ -260,8 +252,7 @@
msg->nm_nlh = (struct nlmsghdr *) realloc(msg->nm_nlh, new_msg_len);
if ( msg->nm_nlh == NULL )
- return nl_error(ENOMEM,
- "netem: Unable to reallocate message size to contain delay distribution data.");
+ return -NLE_NOMEM;
msg->nm_size = new_msg_len;
set_dist = 1;
}
@@ -274,44 +265,34 @@
opts.duplicate = netem->qnm_duplicate;
opts.jitter = netem->qnm_jitter;
- err = nla_put(msg, TCA_OPTIONS, sizeof(opts), &opts);
- if (err)
- return nl_error(err, "netem: Unable to add TCA_OPTIONS to nl_msg.");
+ NLA_PUT(msg, TCA_OPTIONS, sizeof(opts), &opts);
if ( set_correlation ) {
cor.delay_corr = netem->qnm_corr.nmc_delay;
cor.loss_corr = netem->qnm_corr.nmc_loss;
cor.dup_corr = netem->qnm_corr.nmc_duplicate;
- err = nla_put(msg, TCA_NETEM_CORR, sizeof(cor), &cor);
- if (err)
- return nl_error(err, "netem: Unable to add TCA_NETEM_CORR to nl_msg.");
+ NLA_PUT(msg, TCA_NETEM_CORR, sizeof(cor), &cor);
}
if ( set_reorder ) {
reorder.probability = netem->qnm_ro.nmro_probability;
reorder.correlation = netem->qnm_ro.nmro_correlation;
- err = nla_put(msg, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
- if (err)
- return nl_error(err, "netem: Unable to add TCA_NETEM_REORDER to nl_msg.");
+ NLA_PUT(msg, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
}
if ( set_corrupt ) {
corrupt.probability = netem->qnm_crpt.nmcr_probability;
corrupt.correlation = netem->qnm_crpt.nmcr_correlation;
- err = nla_put(msg, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
- if (err)
- return nl_error(err, "netem: Unable to add TCA_NETEM_CORRUPT to nl_msg.");
+ NLA_PUT(msg, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
}
if ( set_dist ) {
- err = nla_put(msg, TCA_NETEM_DELAY_DIST,
+ NLA_PUT(msg, TCA_NETEM_DELAY_DIST,
netem->qnm_dist.dist_size * sizeof(netem->qnm_dist.dist_data[0]),
netem->qnm_dist.dist_data);
- if (err)
- return nl_error(err, "netem: Unable to add TCA_NETEM_DELAY_DIST to nl_msg.");
}
/* Length specified in the TCA_OPTIONS section must span the entire
@@ -329,6 +310,8 @@
msg->nm_nlh->nlmsg_len += (head->nla_len - old_len);
return err;
+nla_put_failure:
+ return -NLE_MSGSIZE;
}
/**
@@ -348,7 +331,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_limit = limit;
netem->qnm_mask |= SCH_NETEM_ATTR_LIMIT;
@@ -369,7 +352,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LIMIT))
return netem->qnm_limit;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
@@ -391,7 +374,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_gap = gap;
netem->qnm_mask |= SCH_NETEM_ATTR_GAP;
@@ -412,7 +395,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_GAP))
return netem->qnm_gap;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -427,7 +410,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_ro.nmro_probability = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_RO_PROB;
@@ -448,7 +431,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_RO_PROB))
return netem->qnm_ro.nmro_probability;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -463,7 +446,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_ro.nmro_correlation = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_RO_CORR;
@@ -484,7 +467,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_RO_CORR))
return netem->qnm_ro.nmro_correlation;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
@@ -506,7 +489,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_crpt.nmcr_probability = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_CORRUPT_PROB;
@@ -527,7 +510,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_PROB))
return netem->qnm_crpt.nmcr_probability;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -542,7 +525,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_crpt.nmcr_correlation = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_CORRUPT_CORR;
@@ -563,7 +546,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_CORR))
return netem->qnm_crpt.nmcr_correlation;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
@@ -585,7 +568,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_loss = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_LOSS;
@@ -606,7 +589,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LOSS))
return netem->qnm_loss;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -621,7 +604,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_corr.nmc_loss = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_LOSS_CORR;
@@ -642,7 +625,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LOSS_CORR))
return netem->qnm_corr.nmc_loss;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
@@ -664,7 +647,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_duplicate = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_DUPLICATE;
@@ -685,7 +668,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_DUPLICATE))
return netem->qnm_duplicate;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -700,7 +683,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_corr.nmc_duplicate = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_DUP_CORR;
@@ -721,7 +704,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_DUP_CORR))
return netem->qnm_corr.nmc_duplicate;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
@@ -743,7 +726,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_latency = nl_us2ticks(delay);
netem->qnm_mask |= SCH_NETEM_ATTR_LATENCY;
@@ -764,7 +747,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_LATENCY))
return nl_ticks2us(netem->qnm_latency);
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -779,7 +762,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_jitter = nl_us2ticks(jitter);
netem->qnm_mask |= SCH_NETEM_ATTR_JITTER;
@@ -800,7 +783,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_JITTER))
return nl_ticks2us(netem->qnm_jitter);
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -814,7 +797,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
netem->qnm_corr.nmc_delay = prob;
netem->qnm_mask |= SCH_NETEM_ATTR_DELAY_CORR;
@@ -835,7 +818,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_DELAY_CORR))
return netem->qnm_corr.nmc_delay;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -851,7 +834,7 @@
if (netem && (netem->qnm_mask & SCH_NETEM_ATTR_DIST))
return netem->qnm_dist.dist_size;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -870,7 +853,7 @@
return 0;
}
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -884,7 +867,7 @@
netem = netem_alloc(qdisc);
if (!netem)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
FILE *f = NULL;
int i, n = 0;
@@ -906,7 +889,8 @@
f = fopen(name, "r");
}
- if ( f == NULL ) return nl_error(errno, "netem: Unable to open distribution file.");
+ if ( f == NULL )
+ return -nl_syserr2nlerr(errno);
netem->qnm_dist.dist_data = (int16_t *) calloc (MAXDIST, sizeof(int16_t));
@@ -925,7 +909,7 @@
if (n >= MAXDIST) {
free(line);
fclose(f);
- return nl_error(EINVAL, "netem: Distribution file too long.");
+ return -NLE_INVAL;
}
netem->qnm_dist.dist_data[n++] = x;
}
diff --git a/lib/route/sch/prio.c b/lib/route/sch/prio.c
index 4e3d624..cd5526c 100644
--- a/lib/route/sch/prio.c
+++ b/lib/route/sch/prio.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>
*/
/**
@@ -58,11 +58,11 @@
struct tc_prio_qopt *opt;
if (qdisc->q_opts->d_size < sizeof(*opt))
- return nl_error(EINVAL, "prio specific option size mismatch");
+ return -NLE_INVAL;
prio = prio_alloc(qdisc);
if (!prio)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
opt = (struct tc_prio_qopt *) qdisc->q_opts->d_data;
prio->qp_bands = opt->bands;
@@ -173,7 +173,7 @@
prio = prio_alloc(qdisc);
if (!prio)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
prio->qp_bands = bands;
prio->qp_mask |= SCH_PRIO_ATTR_BANDS;
@@ -194,7 +194,7 @@
if (prio && prio->qp_mask & SCH_PRIO_ATTR_BANDS)
return prio->qp_bands;
else
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
}
/**
@@ -212,18 +212,17 @@
prio = prio_alloc(qdisc);
if (!prio)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (!(prio->qp_mask & SCH_PRIO_ATTR_BANDS))
- return nl_error(EINVAL, "Set number of bands first");
+ return -NLE_MISSING_ATTR;
if ((len / sizeof(uint8_t)) > (TC_PRIO_MAX+1))
- return nl_error(ERANGE, "priomap length out of bounds");
+ return -NLE_RANGE;
for (i = 0; i <= TC_PRIO_MAX; i++) {
if (priomap[i] > prio->qp_bands)
- return nl_error(ERANGE, "priomap element %d " \
- "out of bounds, increase bands number");
+ return -NLE_RANGE;
}
memcpy(prio->qp_priomap, priomap, len);
@@ -245,10 +244,8 @@
prio = prio_qdisc(qdisc);
if (prio && prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP)
return prio->qp_priomap;
- else {
- nl_errno(ENOENT);
+ else
return NULL;
- }
}
/** @} */
diff --git a/lib/route/sch/red.c b/lib/route/sch/red.c
index a31c358..40481de 100644
--- a/lib/route/sch/red.c
+++ b/lib/route/sch/red.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>
*/
/**
@@ -66,11 +66,11 @@
return err;
if (!tb[TCA_RED_PARMS])
- return nl_error(EINVAL, "Missing TCA_RED_PARMS");
+ return -NLE_MISSING_ATTR;
red = red_alloc(qdisc);
if (!red)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
opts = nla_data(tb[TCA_RED_PARMS]);
@@ -171,7 +171,7 @@
red = red_alloc(qdisc);
if (!red)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
red->qr_limit = limit;
red->qr_mask |= RED_ATTR_LIMIT;
@@ -192,7 +192,7 @@
if (red && (red->qr_mask & RED_ATTR_LIMIT))
return red->qr_limit;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
diff --git a/lib/route/sch/sfq.c b/lib/route/sch/sfq.c
index d530c0f..eaac58b 100644
--- a/lib/route/sch/sfq.c
+++ b/lib/route/sch/sfq.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>
*/
/**
@@ -61,11 +61,11 @@
return 0;
if (qdisc->q_opts->d_size < sizeof(*opts))
- return nl_error(EINVAL, "SFQ specific options size mismatch");
+ return -NLE_INVAL;
sfq = sfq_alloc(qdisc);
if (!sfq)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
opts = (struct tc_sfq_qopt *) qdisc->q_opts->d_data;
@@ -157,7 +157,7 @@
sfq = sfq_alloc(qdisc);
if (!sfq)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
sfq->qs_quantum = quantum;
sfq->qs_mask |= SCH_SFQ_ATTR_QUANTUM;
@@ -178,7 +178,7 @@
if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_QUANTUM)
return sfq->qs_quantum;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -193,7 +193,7 @@
sfq = sfq_alloc(qdisc);
if (!sfq)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
sfq->qs_limit = limit;
sfq->qs_mask |= SCH_SFQ_ATTR_LIMIT;
@@ -214,7 +214,7 @@
if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_LIMIT)
return sfq->qs_limit;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -230,7 +230,7 @@
sfq = sfq_alloc(qdisc);
if (!sfq)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
sfq->qs_perturb = perturb;
sfq->qs_mask |= SCH_SFQ_ATTR_PERTURB;
@@ -251,7 +251,7 @@
if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_PERTURB)
return sfq->qs_perturb;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/**
@@ -267,7 +267,7 @@
if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_DIVISOR)
return sfq->qs_divisor;
else
- return nl_errno(ENOENT);
+ return -NLE_NOATTR;
}
/** @} */
diff --git a/lib/route/sch/tbf.c b/lib/route/sch/tbf.c
index 8dd5e0a..a23c338 100644
--- a/lib/route/sch/tbf.c
+++ b/lib/route/sch/tbf.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>
*/
/**
@@ -64,7 +64,7 @@
tbf = tbf_alloc(q);
if (!tbf)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (tb[TCA_TBF_PARMS]) {
struct tc_tbf_qopt opts;
@@ -226,7 +226,7 @@
tbf = tbf_alloc(qdisc);
if (!tbf)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
tbf->qt_limit = limit;
tbf->qt_mask |= TBF_ATTR_LIMIT;
@@ -270,11 +270,10 @@
tbf = tbf_alloc(qdisc);
if (!tbf)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
if (!(tbf->qt_mask & TBF_ATTR_RATE))
- return nl_error(EINVAL, "The rate must be specified before "
- "limit can be calculated based on latency.");
+ return -NLE_MISSING_ATTR;
limit = calc_limit(&tbf->qt_rate, latency, tbf->qt_rate_bucket);
@@ -301,8 +300,8 @@
tbf = tbf_qdisc(qdisc);
if (tbf && (tbf->qt_mask & TBF_ATTR_LIMIT))
return tbf->qt_limit;
- return
- nl_errno(ENOENT);
+ else
+ return -NLE_NOATTR;
}
/**
@@ -317,7 +316,7 @@
tbf = tbf_alloc(qdisc);
if (!tbf)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
tbf->qt_mpu = mpu;
tbf->qt_mask |= TBF_ATTR_MPU;
@@ -337,8 +336,8 @@
tbf = tbf_qdisc(qdisc);
if (tbf && (tbf->qt_mask & TBF_ATTR_MPU))
return tbf->qt_mpu;
- return
- nl_errno(ENOENT);
+ else
+ return -NLE_NOATTR;
}
static inline int calc_cell_log(int cell, int bucket)
@@ -374,7 +373,7 @@
tbf = tbf_alloc(qdisc);
if (!tbf)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
cell_log = calc_cell_log(cell, bucket);
if (cell_log < 0)
@@ -453,7 +452,7 @@
tbf = tbf_alloc(qdisc);
if (!tbf)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
cell_log = calc_cell_log(cell, bucket);
if (cell_log < 0)
diff --git a/lib/route/tc.c b/lib/route/tc.c
index 1351fa2..1114eac 100644
--- a/lib/route/tc.c
+++ b/lib/route/tc.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>
*/
/**
@@ -66,7 +66,7 @@
return err;
if (tb[TCA_KIND] == NULL)
- return nl_error(EINVAL, "Missing tca kind TLV");
+ return -NLE_MISSING_ATTR;
nla_strlcpy(g->tc_kind, tb[TCA_KIND], TCKINDSIZ);
@@ -83,7 +83,7 @@
if (tb[TCA_OPTIONS]) {
g->tc_opts = nla_get_data(tb[TCA_OPTIONS]);
if (!g->tc_opts)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
g->ce_mask |= TCA_ATTR_OPTS;
}
@@ -128,7 +128,7 @@
if (tbs[TCA_STATS_APP]) {
g->tc_xstats = nla_get_data(tbs[TCA_STATS_APP]);
if (g->tc_xstats == NULL)
- return -ENOMEM;
+ return -NLE_NOMEM;
} else
goto compat_xstats;
} else {
@@ -151,7 +151,7 @@
if (tb[TCA_XSTATS]) {
g->tc_xstats = nla_get_data(tb[TCA_XSTATS]);
if (g->tc_xstats == NULL)
- return -ENOMEM;
+ return -NLE_NOMEM;
g->ce_mask |= TCA_ATTR_XSTATS;
}
}
@@ -171,18 +171,16 @@
if (src->tc_opts) {
dst->tc_opts = nl_data_clone(src->tc_opts);
if (!dst->tc_opts)
- goto errout;
+ return -NLE_NOMEM;
}
if (src->tc_xstats) {
dst->tc_xstats = nl_data_clone(src->tc_xstats);
if (!dst->tc_xstats)
- goto errout;
+ return -NLE_NOMEM;
}
return 0;
-errout:
- return nl_get_errno();
}
int tca_dump_brief(struct rtnl_tca *g, const char *type,
@@ -332,7 +330,8 @@
return t->tc_stats[id];
}
-struct nl_msg *tca_build_msg(struct rtnl_tca *tca, int type, int flags)
+int tca_build_msg(struct rtnl_tca *tca, int type, int flags,
+ struct nl_msg **result)
{
struct nl_msg *msg;
struct tcmsg tchdr = {
@@ -344,7 +343,7 @@
msg = nlmsg_alloc_simple(type, flags);
if (!msg)
- goto nla_put_failure;
+ return -NLE_NOMEM;
if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
@@ -352,11 +351,12 @@
if (tca->ce_mask & TCA_ATTR_KIND)
NLA_PUT_STRING(msg, TCA_KIND, tca->tc_kind);
- return msg;
+ *result = msg;
+ return 0;
nla_put_failure:
nlmsg_free(msg);
- return NULL;
+ return -NLE_MSGSIZE;
}
/** @endcond */
@@ -425,7 +425,7 @@
if ((1 << i) == cell_size)
return i;
- return nl_errno(EINVAL);
+ return -NLE_INVAL;
}
@@ -546,13 +546,13 @@
/* :YYYY */
h = 0;
if (':' != *colon)
- return -EINVAL;
+ return -NLE_INVAL;
}
if (':' == *colon) {
/* check if we would lose bits */
if (TC_H_MAJ(h))
- return -ERANGE;
+ return -NLE_RANGE;
h <<= 16;
if ('\0' == colon[1]) {
@@ -564,10 +564,10 @@
/* check if we overlap with major part */
if (TC_H_MAJ(l))
- return -ERANGE;
+ return -NLE_RANGE;
if ('\0' != *end)
- return -EINVAL;
+ return -NLE_INVAL;
*res = (h | l);
}
@@ -575,7 +575,7 @@
/* XXXXYYYY */
*res = h;
} else
- return -EINVAL;
+ return -NLE_INVAL;
return 0;
}
diff --git a/lib/socket.c b/lib/socket.c
index aae8f54..088cd10 100644
--- a/lib/socket.c
+++ b/lib/socket.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>
*/
/**
@@ -166,10 +166,8 @@
struct nl_handle *handle;
handle = calloc(1, sizeof(*handle));
- if (!handle) {
- nl_errno(ENOMEM);
+ if (!handle)
return NULL;
- }
handle->h_fd = -1;
handle->h_cb = cb;
@@ -179,7 +177,6 @@
handle->h_local.nl_pid = generate_local_port();
if (handle->h_local.nl_pid == UINT_MAX) {
nl_handle_destroy(handle);
- nl_error(ENOBUFS, "Out of local ports");
return NULL;
}
@@ -196,10 +193,8 @@
struct nl_cb *cb;
cb = nl_cb_alloc(default_cb);
- if (!cb) {
- nl_errno(ENOMEM);
+ if (!cb)
return NULL;
- }
return __alloc_handle(cb);
}
@@ -345,13 +340,12 @@
int err;
if (handle->h_fd == -1)
- return nl_error(EBADFD, "Socket not connected");
+ return -NLE_BAD_SOCK;
err = setsockopt(handle->h_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
&group, sizeof(group));
if (err < 0)
- return nl_error(errno, "setsockopt(NETLINK_ADD_MEMBERSHIP) "
- "failed");
+ return -nl_syserr2nlerr(errno);
return 0;
}
@@ -372,13 +366,12 @@
int err;
if (handle->h_fd == -1)
- return nl_error(EBADFD, "Socket not connected");
+ return -NLE_BAD_SOCK;
err = setsockopt(handle->h_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
&group, sizeof(group));
if (err < 0)
- return nl_error(errno, "setsockopt(NETLINK_DROP_MEMBERSHIP) "
- "failed");
+ return -nl_syserr2nlerr(errno);
return 0;
}
@@ -436,10 +429,10 @@
int nl_socket_set_nonblocking(struct nl_handle *handle)
{
if (handle->h_fd == -1)
- return nl_error(EBADFD, "Socket not connected");
+ return -NLE_BAD_SOCK;
if (fcntl(handle->h_fd, F_SETFL, O_NONBLOCK) < 0)
- return nl_error(errno, "fcntl(F_SETFL, O_NONBLOCK) failed");
+ return -nl_syserr2nlerr(errno);
return 0;
}
@@ -528,17 +521,17 @@
txbuf = 32768;
if (handle->h_fd == -1)
- return nl_error(EBADFD, "Socket not connected");
+ return -NLE_BAD_SOCK;
err = setsockopt(handle->h_fd, SOL_SOCKET, SO_SNDBUF,
&txbuf, sizeof(txbuf));
if (err < 0)
- return nl_error(errno, "setsockopt(SO_SNDBUF) failed");
+ return -nl_syserr2nlerr(errno);
err = setsockopt(handle->h_fd, SOL_SOCKET, SO_RCVBUF,
&rxbuf, sizeof(rxbuf));
if (err < 0)
- return nl_error(errno, "setsockopt(SO_RCVBUF) failed");
+ return -nl_syserr2nlerr(errno);
handle->h_flags |= NL_SOCK_BUFSIZE_SET;
@@ -557,12 +550,12 @@
int err;
if (handle->h_fd == -1)
- return nl_error(EBADFD, "Socket not connected");
+ return -NLE_BAD_SOCK;
err = setsockopt(handle->h_fd, SOL_SOCKET, SO_PASSCRED,
&state, sizeof(state));
if (err < 0)
- return nl_error(errno, "setsockopt(SO_PASSCRED) failed");
+ return -nl_syserr2nlerr(errno);
if (state)
handle->h_flags |= NL_SOCK_PASSCRED;
@@ -584,12 +577,12 @@
int err;
if (handle->h_fd == -1)
- return nl_error(EBADFD, "Socket not connected");
+ return -NLE_BAD_SOCK;
err = setsockopt(handle->h_fd, SOL_NETLINK, NETLINK_PKTINFO,
&state, sizeof(state));
if (err < 0)
- return nl_error(errno, "setsockopt(NETLINK_PKTINFO) failed");
+ return -nl_syserr2nlerr(errno);
return 0;
}
diff --git a/lib/utils.c b/lib/utils.c
index db11fb8..5c4c476 100644
--- a/lib/utils.c
+++ b/lib/utils.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>
*/
/**
@@ -41,48 +41,6 @@
nl_debug_dp.dp_fd = stderr;
}
-/**
- * @name Error Code Helpers
- * @{
- */
-
-static char *errbuf;
-static int nlerrno;
-
-/** @cond SKIP */
-int __nl_error(int err, const char *file, unsigned int line, const char *func,
- const char *fmt, ...)
-{
- char *user_err;
- va_list args;
-
- if (errbuf) {
- free(errbuf);
- errbuf = NULL;
- }
-
- nlerrno = err;
-
- if (fmt) {
- va_start(args, fmt);
- vasprintf(&user_err, fmt, args);
- va_end(args);
- }
-
-#ifdef VERBOSE_ERRORS
- asprintf(&errbuf, "%s:%u:%s: %s (errno = %s)",
- file, line, func, fmt ? user_err : "", strerror(err));
-#else
- asprintf(&errbuf, "%s (errno = %s)",
- fmt ? user_err : "", strerror(err));
-#endif
-
- if (fmt)
- free(user_err);
-
- return -err;
-}
-
int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *))
{
FILE *fd;
@@ -90,8 +48,7 @@
fd = fopen(path, "r");
if (fd == NULL)
- return nl_error(errno, "Unable to open file %s for reading",
- path);
+ return -nl_syserr2nlerr(errno);
while (fgets(buf, sizeof(buf), fd)) {
int goodlen, err;
@@ -103,17 +60,17 @@
num = strtol(buf, &end, 0);
if (end == buf)
- return nl_error(EINVAL, "Parsing error");
+ return -NLE_INVAL;
if (num == LONG_MIN || num == LONG_MAX)
- return nl_error(errno, "Number of out range");
+ return -NLE_RANGE;
while (*end == ' ' || *end == '\t')
end++;
goodlen = strcspn(end, "#\r\n\t ");
if (goodlen == 0)
- return nl_error(EINVAL, "Empty string");
+ return -NLE_INVAL;
end[goodlen] = '\0';
@@ -127,49 +84,6 @@
return 0;
}
-/** @endcond */
-
-int nl_get_errno(void)
-{
- return nlerrno;
-}
-
-
-/**
- * Return error message for an error code
- * @return error message
- */
-char *nl_geterror(void)
-{
- if (errbuf)
- return errbuf;
-
- if (nlerrno)
- return strerror(nlerrno);
-
- return "Success\n";
-}
-
-/**
- * Print a libnl error message
- * @arg s error message prefix
- *
- * Prints the error message of the call that failed last.
- *
- * If s is not NULL and *s is not a null byte the argument
- * string is printed, followed by a colon and a blank. Then
- * the error message and a new-line.
- */
-void nl_perror(const char *s)
-{
- if (s && *s)
- fprintf(stderr, "%s: %s\n", s, nl_geterror());
- else
- fprintf(stderr, "%s\n", nl_geterror());
-}
-
-/** @} */
-
/**
* @name Unit Pretty-Printing
* @{