From 8a3efffa5b3fde252675239914118664d36a2c24 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 14 May 2008 17:49:44 +0200 Subject: 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! --- include/netlink-local.h | 36 +-------- include/netlink-tc.h | 4 +- include/netlink/addr.h | 4 +- include/netlink/cache.h | 18 +++-- include/netlink/errno.h | 59 +++++++++++++++ include/netlink/fib_lookup/lookup.h | 7 +- include/netlink/genl/ctrl.h | 5 +- include/netlink/netfilter/ct.h | 128 ++++++++++++++++---------------- include/netlink/netfilter/log.h | 30 ++++---- include/netlink/netfilter/log_msg.h | 5 +- include/netlink/netfilter/queue.h | 38 +++++----- include/netlink/netfilter/queue_msg.h | 3 +- include/netlink/netlink.h | 1 + include/netlink/object.h | 5 +- include/netlink/route/addr.h | 79 +++++++++----------- include/netlink/route/class.h | 16 ++-- include/netlink/route/classifier.h | 25 ++++--- include/netlink/route/link.h | 130 ++++++++++++++------------------- include/netlink/route/neighbour.h | 44 +++++------ include/netlink/route/neightbl.h | 9 ++- include/netlink/route/qdisc.h | 96 +++++++++++------------- include/netlink/route/route.h | 133 ++++++++++++++++------------------ include/netlink/route/rule.h | 13 ++-- include/netlink/utils.h | 6 +- lib/addr.c | 73 +++++++++++-------- lib/attr.c | 16 ++-- lib/cache.c | 67 ++++++++++------- lib/cache_mngr.c | 77 +++++++++----------- lib/cache_mngt.c | 15 ++-- lib/data.c | 5 +- lib/error.c | 106 +++++++++++++++++++++++++++ lib/fib_lookup/lookup.c | 27 ++++--- lib/fib_lookup/request.c | 8 +- lib/genl/ctrl.c | 32 +++----- lib/genl/family.c | 2 +- lib/genl/genl.c | 4 +- lib/genl/mngt.c | 30 +++----- lib/handlers.c | 14 ++-- lib/msg.c | 20 ++--- lib/netfilter/ct.c | 87 ++++++++++------------ lib/netfilter/ct_obj.c | 14 ++-- lib/netfilter/log.c | 93 +++++++++++++----------- lib/netfilter/log_msg.c | 20 ++--- lib/netfilter/log_msg_obj.c | 4 +- lib/netfilter/nfnl.c | 6 +- lib/netfilter/queue.c | 93 +++++++++++++----------- lib/netfilter/queue_msg.c | 21 +++--- lib/netfilter/queue_msg_obj.c | 2 +- lib/nl.c | 40 +++++----- lib/object.c | 19 +++-- lib/route/addr.c | 91 ++++++++++------------- lib/route/class.c | 51 +++++++------ lib/route/class_api.c | 6 +- lib/route/classifier.c | 97 +++++++++++++------------ lib/route/cls/fw.c | 23 ++---- lib/route/cls/u32.c | 31 ++++---- lib/route/cls_api.c | 6 +- lib/route/link.c | 58 ++++++--------- lib/route/link/api.c | 8 +- lib/route/link/vlan.c | 51 ++++++------- lib/route/neigh.c | 103 +++++++++++--------------- lib/route/neightbl.c | 107 ++++++++++++++------------- lib/route/nexthop.c | 4 +- lib/route/qdisc.c | 125 ++++++++++++++------------------ lib/route/qdisc_api.c | 4 +- lib/route/route.c | 59 ++++++++------- lib/route/route_obj.c | 54 ++++++-------- lib/route/rule.c | 108 ++++++++++++--------------- lib/route/sch/cbq.c | 6 +- lib/route/sch/dsmark.c | 26 +++---- lib/route/sch/fifo.c | 10 +-- lib/route/sch/netem.c | 118 +++++++++++++----------------- lib/route/sch/prio.c | 23 +++--- lib/route/sch/red.c | 10 +-- lib/route/sch/sfq.c | 20 ++--- lib/route/sch/tbf.c | 25 +++---- lib/route/tc.c | 38 +++++----- lib/socket.c | 39 ++++------ lib/utils.c | 96 ++---------------------- 79 files changed, 1517 insertions(+), 1669 deletions(-) create mode 100644 include/netlink/errno.h create mode 100644 lib/error.c 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 @@ struct trans_list { 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 -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 @@ static inline int __trans_list_add(int i, const char *a, 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_TC_PRIV_H_ @@ -51,7 +51,7 @@ extern void tca_set_kind(struct rtnl_tca *, const char *); 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 @@ struct nl_addr; 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_valid(char *, int); 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_CACHE_H_ @@ -39,7 +39,11 @@ extern struct nl_object * nl_cache_get_prev(struct nl_object *); /* 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 @@ struct nl_cache_mngr; #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 + */ + +#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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_FIB_LOOKUP_H_ @@ -28,8 +28,9 @@ extern void flnl_result_put(struct flnl_result *); 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_GENL_CTRL_H_ @@ -22,7 +22,8 @@ extern "C" { 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 + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ @@ -27,95 +27,95 @@ struct nfnl_ct; 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 @@ enum nfnl_log_flags { /* 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 unsigned int nfnl_log_get_flags(const struct nfnl_log *); 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 + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2008 Patrick McHardy @@ -29,7 +29,8 @@ extern struct nl_object_ops log_msg_obj_ops; /* 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 void nfnl_queue_set_copy_range(struct nfnl_queue *, 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 struct nl_msg * nfnl_queue_build_pf_unbind(uint8_t); -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 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 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_pf_bind(uint8_t, struct nl_msg **); +extern int nfnl_queue_pf_bind(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 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 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 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 @@ extern struct nl_object_ops queue_msg_obj_ops; /* 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 #include #include +#include #include #include #include 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_OBJECT_H_ @@ -27,7 +27,8 @@ struct nl_object_ops; /* 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 - * Baruch Even , + * Copyright (c) 2003-2008 Thomas Graf + * Copyright (c) 2003-2006 Baruch Even , * Mediatrix Telecom, inc. */ @@ -26,63 +26,56 @@ struct rtnl_addr; /* 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_CLASS_H_ @@ -24,20 +24,20 @@ struct rtnl_class; 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_CLASSIFIER_H_ @@ -23,21 +23,22 @@ extern "C" { 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_LINK_H_ @@ -58,109 +58,91 @@ enum rtnl_link_st { #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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_NEIGHBOUR_H_ @@ -22,39 +22,31 @@ extern "C" { 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_NEIGHTBL_H_ @@ -25,14 +25,15 @@ struct rtnl_neightbl; 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_QDISC_H_ @@ -24,60 +24,46 @@ struct rtnl_qdisc; 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 *); - -/* 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); - -/* 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); - -/* 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 *); - -/* 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 *); - -/* 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); - -/* 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_cls(struct rtnl_qdisc *, - struct nl_cache *, - void (*cb)(struct nl_object *, - void *), - void *); - -/* qdisc specific options */ +extern struct rtnl_qdisc *rtnl_qdisc_alloc(void); +extern void rtnl_qdisc_put(struct rtnl_qdisc *); + +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); + +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); + +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 *); + +extern int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *, + struct nl_msg **); +extern int rtnl_qdisc_delete(struct nl_handle *, struct rtnl_qdisc *); + +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_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 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 @@ struct rtnl_rtcacheinfo 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_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 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 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_foreach_nexthop(struct rtnl_route *r, +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 int rtnl_route_parse(struct nlmsghdr *, struct rtnl_route **); +extern int rtnl_route_build_msg(struct nl_msg *, struct rtnl_route *); + +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_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, 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_RULE_H_ @@ -27,14 +27,15 @@ struct rtnl_rule; 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 + * Copyright (c) 2003-2008 Thomas Graf */ #ifndef NETLINK_UTILS_H_ @@ -38,10 +38,6 @@ extern "C" { /** @} */ -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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -140,11 +140,11 @@ static inline int dnet_pton(const char *src, char *addrbuf) 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 *nl_addr_alloc(size_t maxsize) 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 @@ struct nl_addr *nl_addr_alloc_from_attr(struct nlattr *nla, int family) * 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 @@ struct nl_addr *nl_addr_alloc_from_attr(struct nlattr *nla, int family) * 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 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) str = strdup(addrstr); if (!str) { - err = nl_errno(ENOMEM); + err = -NLE_NOMEM; goto errout; } @@ -289,8 +288,7 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) goto prefix; default: - err = nl_error(EINVAL, "Unsuported address" \ - "family for default address"); + err = -NLE_AF_NOSUPPORT; goto errout; } } @@ -304,7 +302,7 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) goto prefix; } if (hint == AF_INET) { - err = nl_error(EINVAL, "Invalid IPv4 address"); + err = -NLE_NOADDR; goto errout; } } @@ -316,7 +314,7 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) goto prefix; } if (hint == AF_INET6) { - err = nl_error(EINVAL, "Invalid IPv6 address"); + err = -NLE_NOADDR; goto errout; } } @@ -338,7 +336,7 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) } if (hint == AF_LLC) { - err = nl_error(EINVAL, "Invalid link layer address"); + err = -NLE_NOADDR; goto errout; } } @@ -351,7 +349,7 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) goto prefix; } if (hint == AF_DECnet) { - err = nl_error(EINVAL, "Invalid DECnet address"); + err = -NLE_NOADDR; goto errout; } } @@ -363,7 +361,7 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) 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 @@ struct nl_addr *nl_addr_parse(const char *addrstr, int hint) 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 @@ prefix: 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 @@ int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa, 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 @@ int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa, 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 @@ int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa, break; default: - return -EINVAL; + return -NLE_INVAL; } return 0; @@ -672,6 +671,7 @@ int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa, /** * 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 @@ int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa, * @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 @@ struct addrinfo *nl_addr_info(struct nl_addr *addr) 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_get_family(struct nl_addr *addr) 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 @@ static int validate_nla(struct nlattr *nla, int maxtype, 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 @@ struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen) 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 @@ int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -175,10 +175,8 @@ struct nl_cache *nl_cache_alloc(struct nl_cache_ops *ops) 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 @@ struct nl_cache *nl_cache_alloc(struct nl_cache_ops *ops) 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; + + if (!(cache = nl_cache_alloc(ops))) + return -NLE_NOMEM; - return nl_cache_alloc(ops); + *result = cache; + return 0; } /** @@ -307,12 +326,12 @@ int nl_cache_add(struct nl_cache *cache, struct nl_object *obj) 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_add(struct nl_cache *cache, struct nl_object *obj) 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 @@ int nl_cache_request_full_dump(struct nl_handle *handle, struct nl_cache *cache) 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 @@ int __cache_pickup(struct nl_handle *handle, struct nl_cache *cache, 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 @@ int __cache_pickup(struct nl_handle *handle, struct nl_cache *cache, 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 nl_cache_include(struct nl_cache *cache, struct nl_object *obj, 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 nl_cache_parse(struct nl_cache_ops *ops, struct sockaddr_nl *who, { 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -146,17 +146,18 @@ found: * * @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 @@ struct nl_cache_mngr *nl_cache_mngr_alloc(struct nl_handle *handle, 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 @@ struct nl_cache_mngr *nl_cache_mngr_alloc(struct nl_handle *handle, /* 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 @@ errout: * @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 @@ errout: * 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 @@ struct nl_cache *nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name, 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 @@ retry: 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 @@ retry: } 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 @@ retry: 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_drop_membership: errout_free_cache: nl_cache_free(cache); - return NULL; + return err; } /** @@ -334,7 +323,7 @@ int nl_cache_mngr_poll(struct nl_cache_mngr *mngr, int timeout) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -129,15 +129,12 @@ void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *arg) */ 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 @@ int nl_cache_mngt_unregister(struct nl_cache_ops *ops) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -56,7 +56,6 @@ struct nl_data *nl_data_alloc(void *buf, size_t size) return data; errout: - nl_errno(ENOMEM); return NULL; } @@ -105,7 +104,7 @@ int nl_data_append(struct nl_data *data, void *buf, size_t size) 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 + */ + +#include +#include + +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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -63,7 +63,7 @@ static int result_clone(struct nl_object *_dst, struct nl_object *_src) 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 @@ static int result_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 @@ struct nl_cache *flnl_result_alloc_cache(void) * @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 @@ struct nl_msg *flnl_lookup_build_request(struct flnl_request *req, int flags) 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 @@ int flnl_lookup(struct nl_handle *handle, struct flnl_request *req, 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -48,11 +48,9 @@ static int request_clone(struct nl_object *_dst, struct nl_object *_src) 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_get_table(struct flnl_request *req) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -61,17 +61,17 @@ static int ctrl_msg_parser(struct nl_cache_ops *ops, struct genl_cmd *cmd, 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 @@ static int ctrl_msg_parser(struct nl_cache_ops *ops, struct genl_cmd *cmd, goto errout; if (tb[CTRL_ATTR_OP_ID] == NULL) { - err = nl_errno(EINVAL); + err = -NLE_MISSING_ATTR; goto errout; } @@ -143,20 +143,9 @@ errout: * @{ */ -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 @@ int genl_ctrl_resolve(struct nl_handle *handle, const char *name) 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 @@ int genl_family_add_op(struct genl_family *family, int id, int flags) 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 @@ int genlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, 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 @@ int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -108,12 +108,12 @@ static int genl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 genl_register(struct nl_cache_ops *ops) 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 @@ static int __genl_ops_resolve(struct nl_cache *ctrl, struct genl_ops *ops) 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 @@ int genl_ops_resolve(struct nl_handle *handle, struct genl_ops *ops) 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 @@ int genl_mngt_resolve(struct nl_handle *handle) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -140,7 +140,7 @@ static int nl_error_handler_verbose(struct sockaddr_nl *who, 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 @@ struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind) return NULL; cb = calloc(1, sizeof(*cb)); - if (!cb) { - nl_errno(ENOMEM); + if (!cb) return NULL; - } cb->cb_refcnt = 1; @@ -338,10 +336,10 @@ int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, 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 @@ int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -320,7 +320,7 @@ int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], 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 @@ int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, 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 @@ static struct nl_msg *__nlmsg_alloc(size_t len) return nm; errout: free(nm); - nl_errno(ENOMEM); return NULL; } @@ -519,10 +518,8 @@ void *nlmsg_reserve(struct nl_msg *n, size_t len, int pad) 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 @@ int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad) 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 @@ int nlmsg_expand(struct nl_msg *n, size_t newlen) 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 @@ int nl_msg_parse(struct nl_msg *msg, void (*cb)(struct nl_object *, void *), 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 + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c= 2008 Patrick McHardy @@ -152,7 +152,7 @@ static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) return 0; errout_errno: - return nl_get_errno(); + err = -NLE_NOMEM; errout: return err; } @@ -287,7 +287,7 @@ int nfnlmsg_ct_group(struct nlmsghdr *nlh) } } -struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh) +int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result) { struct nfnl_ct *ct; struct nlattr *tb[CTA_MAX+1]; @@ -295,7 +295,7 @@ struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh) ct = nfnl_ct_alloc(); if (!ct) - return NULL; + return -NLE_NOMEM; ct->ce_msgtype = nlh->nlmsg_type; @@ -346,11 +346,12 @@ struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh) goto errout; } - return ct; + *result = ct; + return 0; errout: nfnl_ct_put(ct); - return NULL; + return err; } static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, @@ -359,9 +360,8 @@ static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nfnl_ct *ct; int err; - ct = nfnlmsg_ct_parse(nlh); - if (ct == NULL) - goto errout_errno; + if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0) + goto errout; err = pp->pp_cb((struct nl_object *) ct, pp); if (err < 0) @@ -372,10 +372,6 @@ static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, errout: nfnl_ct_put(ct); return err; - -errout_errno: - err = nl_get_errno(); - goto errout; } int nfnl_ct_dump_request(struct nl_handle *h) @@ -453,31 +449,35 @@ static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct, return 0; nla_put_failure: - return -1; + return -NLE_MSGSIZE; } -static struct nl_msg *nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags) +static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags, + struct nl_msg **result) { struct nl_msg *msg; + int err; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags, nfnl_ct_get_family(ct), 0); if (msg == NULL) - return NULL; + return -NLE_NOMEM; - if (nfnl_ct_build_tuple(msg, ct, 0) < 0) + if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0) goto err_out; - return msg; + *result = msg; + return 0; err_out: nlmsg_free(msg); - return NULL; + return err; } -struct nl_msg *nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags) +int nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags, + struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags); + return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result); } int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags) @@ -485,9 +485,8 @@ int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags) struct nl_msg *msg; int err; - msg = nfnl_ct_build_add_request(ct, flags); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0) + return err; err = nl_send_auto_complete(h, msg); nlmsg_free(msg); @@ -497,9 +496,10 @@ int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags) return nl_wait_for_ack(h); } -struct nl_msg *nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags) +int nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags, + struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags); + return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result); } int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags) @@ -507,9 +507,8 @@ int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags) struct nl_msg *msg; int err; - msg = nfnl_ct_build_delete_request(ct, flags); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0) + return err; err = nl_send_auto_complete(h, msg); nlmsg_free(msg); @@ -519,9 +518,10 @@ int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags) return nl_wait_for_ack(h); } -struct nl_msg *nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags) +int nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags, + struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags); + return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result); } int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags) @@ -529,9 +529,8 @@ int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags) struct nl_msg *msg; int err; - msg = nfnl_ct_build_query_request(ct, flags); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0) + return err; err = nl_send_auto_complete(h, msg); nlmsg_free(msg); @@ -549,28 +548,16 @@ int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags) /** * Build a conntrack cache holding all conntrack currently in the kernel * @arg handle netlink handle + * @arg result Pointer to store resulting cache. * * Allocates a new cache, initializes it properly and updates it to * contain all conntracks currently in the kernel. * - * @note The caller is responsible for destroying and freeing the - * cache after using it. - * @return The cache or NULL if an error has occured. + * @return 0 on success or a negative error code. */ -struct nl_cache *nfnl_ct_alloc_cache(struct nl_handle *handle) +int nfnl_ct_alloc_cache(struct nl_handle *sock, struct nl_cache **result) { - struct nl_cache *cache; - - cache = nl_cache_alloc(&nfnl_ct_ops); - if (!cache) - return NULL; - - if (handle && nl_cache_refill(handle, cache) < 0) { - free(cache); - return NULL; - } - - return cache; + return nl_cache_alloc_and_fill(&nfnl_ct_ops, sock, result); } /** @} */ diff --git a/lib/netfilter/ct_obj.c b/lib/netfilter/ct_obj.c index 96e5db6..1625efc 100644 --- a/lib/netfilter/ct_obj.c +++ b/lib/netfilter/ct_obj.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ @@ -75,34 +75,32 @@ static int ct_clone(struct nl_object *_dst, struct nl_object *_src) if (src->ct_orig.src) { addr = nl_addr_clone(src->ct_orig.src); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_orig.src = addr; } if (src->ct_orig.dst) { addr = nl_addr_clone(src->ct_orig.dst); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_orig.dst = addr; } if (src->ct_repl.src) { addr = nl_addr_clone(src->ct_repl.src); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_repl.src = addr; } if (src->ct_repl.dst) { addr = nl_addr_clone(src->ct_repl.dst); if (!addr) - goto errout; + return -NLE_NOMEM; dst->ct_repl.dst = addr; } return 0; -errout: - return nl_get_errno(); } static void ct_dump_dir(struct nfnl_ct *ct, int repl, @@ -458,7 +456,7 @@ static int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr, { if (ct->ce_mask & CT_ATTR_FAMILY) { if (addr->a_family != ct->ct_family) - return nl_error(EINVAL, "Address family mismatch"); + return -NLE_AF_MISMATCH; } else nfnl_ct_set_family(ct, addr->a_family); diff --git a/lib/netfilter/log.c b/lib/netfilter/log.c index 41a131c..0cfbc87 100644 --- a/lib/netfilter/log.c +++ b/lib/netfilter/log.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ @@ -31,8 +31,8 @@ * @{ */ -static struct nl_msg *build_log_cmd_request(uint8_t family, uint16_t queuenum, - uint8_t command) +static int build_log_cmd_request(uint8_t family, uint16_t queuenum, + uint8_t command, struct nl_msg **result) { struct nl_msg *msg; struct nfulnl_msg_config_cmd cmd; @@ -40,17 +40,18 @@ static struct nl_msg *build_log_cmd_request(uint8_t family, uint16_t queuenum, msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, family, queuenum); if (msg == NULL) - return NULL; + return -NLE_NOMEM; cmd.command = command; if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; - return msg; + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } static int send_log_request(struct nl_handle *handle, struct nl_msg *msg) @@ -65,49 +66,50 @@ static int send_log_request(struct nl_handle *handle, struct nl_msg *msg) return nl_wait_for_ack(handle); } -struct nl_msg *nfnl_log_build_pf_bind(uint8_t pf) +int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result) { - return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND); + return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result); } int nfnl_log_pf_bind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_pf_bind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -struct nl_msg *nfnl_log_build_pf_unbind(uint8_t pf) +int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result) { - return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND); + return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result); } int nfnl_log_pf_unbind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_pf_unbind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -static struct nl_msg *nfnl_log_build_request(const struct nfnl_log *log) +static int nfnl_log_build_request(const struct nfnl_log *log, + struct nl_msg **result) { struct nl_msg *msg; if (!nfnl_log_test_group(log)) - return NULL; + return -NLE_MISSING_ATTR; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, 0, nfnl_log_get_group(log)); if (msg == NULL) - return NULL; + return -NLE_NOMEM; /* This sucks. The nfnetlink_log interface always expects both * parameters to be present. Needs to be done properly. @@ -148,77 +150,80 @@ static struct nl_msg *nfnl_log_build_request(const struct nfnl_log *log) htonl(nfnl_log_get_queue_threshold(log))) < 0) goto nla_put_failure; - return msg; + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } -struct nl_msg *nfnl_log_build_create_request(const struct nfnl_log *log) +int nfnl_log_build_create_request(const struct nfnl_log *log, + struct nl_msg **result) { - struct nl_msg *msg; struct nfulnl_msg_config_cmd cmd; + int err; - msg = nfnl_log_build_request(log); - if (msg == NULL) - return NULL; + if ((err = nfnl_log_build_request(log, result)) < 0) + return err; cmd.command = NFULNL_CFG_CMD_BIND; - if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) + if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; - return msg; + return 0; nla_put_failure: - nlmsg_free(msg); - return NULL; + nlmsg_free(*result); + return -NLE_MSGSIZE; } int nfnl_log_create(struct nl_handle *nlh, const struct nfnl_log *log) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_create_request(log); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_log_build_create_request(log, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -struct nl_msg *nfnl_log_build_change_request(const struct nfnl_log *log) +int nfnl_log_build_change_request(const struct nfnl_log *log, + struct nl_msg **result) { - return nfnl_log_build_request(log); + return nfnl_log_build_request(log, result); } int nfnl_log_change(struct nl_handle *nlh, const struct nfnl_log *log) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_change_request(log); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_log_build_change_request(log, &msg)) < 0) + return err; return send_log_request(nlh, msg); } -struct nl_msg *nfnl_log_build_delete_request(const struct nfnl_log *log) +int nfnl_log_build_delete_request(const struct nfnl_log *log, + struct nl_msg **result) { if (!nfnl_log_test_group(log)) - return NULL; + return -NLE_MISSING_ATTR; return build_log_cmd_request(0, nfnl_log_get_group(log), - NFULNL_CFG_CMD_UNBIND); + NFULNL_CFG_CMD_UNBIND, result); } int nfnl_log_delete(struct nl_handle *nlh, const struct nfnl_log *log) { struct nl_msg *msg; + int err; - msg = nfnl_log_build_delete_request(log); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_log_build_delete_request(log, &msg)) < 0) + return err; return send_log_request(nlh, msg); } diff --git a/lib/netfilter/log_msg.c b/lib/netfilter/log_msg.c index 5243338..33de482 100644 --- a/lib/netfilter/log_msg.c +++ b/lib/netfilter/log_msg.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation * Copyright (c) 2008 Patrick McHardy @@ -62,7 +62,7 @@ static struct nla_policy log_msg_policy[NFULA_MAX+1] = { [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 }, }; -struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh) +int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result) { struct nfnl_log_msg *msg; struct nlattr *tb[NFULA_MAX+1]; @@ -71,7 +71,7 @@ struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh) msg = nfnl_log_msg_alloc(); if (!msg) - return NULL; + return -NLE_NOMEM; msg->ce_msgtype = nlh->nlmsg_type; @@ -158,11 +158,12 @@ struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh) if (attr) nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr))); - return msg; + *result = msg; + return 0; errout: nfnl_log_msg_put(msg); - return NULL; + return err; } static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, @@ -171,9 +172,8 @@ static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nfnl_log_msg *msg; int err; - msg = nfnlmsg_log_msg_parse(nlh); - if (log == NULL) - goto errout_errno; + if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0) + goto errout; err = pp->pp_cb((struct nl_object *) msg, pp); if (err < 0) @@ -184,10 +184,6 @@ static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, errout: nfnl_log_msg_put(msg); return err; - -errout_errno: - err = nl_get_errno(); - goto errout; } /** @} */ diff --git a/lib/netfilter/log_msg_obj.c b/lib/netfilter/log_msg_obj.c index ee85090..b2cd9ef 100644 --- a/lib/netfilter/log_msg_obj.c +++ b/lib/netfilter/log_msg_obj.c @@ -341,7 +341,7 @@ int nfnl_log_msg_set_payload(struct nfnl_log_msg *msg, uint8_t *payload, int len free(msg->log_msg_payload); msg->log_msg_payload = malloc(len); if (!msg->log_msg_payload) - return nl_errno(ENOMEM); + return -NLE_NOMEM; memcpy(msg->log_msg_payload, payload, len); msg->log_msg_payload_len = len; @@ -365,7 +365,7 @@ int nfnl_log_msg_set_prefix(struct nfnl_log_msg *msg, void *prefix) free(msg->log_msg_prefix); msg->log_msg_prefix = strdup(prefix); if (!msg->log_msg_prefix) - return nl_errno(ENOMEM); + return -NLE_NOMEM; msg->ce_mask |= LOG_MSG_ATTR_PREFIX; return 0; diff --git a/lib/netfilter/nfnl.c b/lib/netfilter/nfnl.c index 554e234..2441f69 100644 --- a/lib/netfilter/nfnl.c +++ b/lib/netfilter/nfnl.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2006 Thomas Graf + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2007 Philip Craig * Copyright (c) 2007 Secure Computing Corporation */ @@ -178,7 +178,7 @@ static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id) nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO); if (nfg == NULL) - return nl_errno(ENOMEM); + return -NLE_NOMEM; nfg->nfgen_family = family; nfg->version = NFNETLINK_V0; @@ -236,7 +236,7 @@ int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags); if (nlh == NULL) - return nl_get_errno(); + return -NLE_MSGSIZE; return nfnlmsg_append(msg, family, res_id); } diff --git a/lib/netfilter/queue.c b/lib/netfilter/queue.c index 2bd719a..7f31c66 100644 --- a/lib/netfilter/queue.c +++ b/lib/netfilter/queue.c @@ -41,8 +41,8 @@ static int send_queue_request(struct nl_handle *handle, struct nl_msg *msg) * @{ */ -static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum, - uint8_t command) +static int build_queue_cmd_request(uint8_t family, uint16_t queuenum, + uint8_t command, struct nl_msg **result) { struct nl_msg *msg; struct nfqnl_msg_config_cmd cmd; @@ -50,7 +50,7 @@ static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum, msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0, family, queuenum); if (msg == NULL) - return NULL; + return -NLE_NOMEM; cmd.pf = htons(family); cmd._pad = 0; @@ -58,56 +58,58 @@ static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum, if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0) goto nla_put_failure; - return msg; + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } -struct nl_msg *nfnl_queue_build_pf_bind(uint8_t pf) +int nfnl_queue_build_pf_bind(uint8_t pf, struct nl_msg **result) { - return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND); + return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND, result); } int nfnl_queue_pf_bind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_pf_bind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_queue_build_pf_bind(pf, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -struct nl_msg *nfnl_queue_build_pf_unbind(uint8_t pf) +int nfnl_queue_build_pf_unbind(uint8_t pf, struct nl_msg **result) { - return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND); + return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND, result); } int nfnl_queue_pf_unbind(struct nl_handle *nlh, uint8_t pf) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_pf_unbind(pf); - if (!msg) - return nl_get_errno(); + if ((err = nfnl_queue_build_pf_unbind(pf, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -static struct nl_msg *nfnl_queue_build_request(const struct nfnl_queue *queue) +static int nfnl_queue_build_request(const struct nfnl_queue *queue, + struct nl_msg **result) { struct nl_msg *msg; if (!nfnl_queue_test_group(queue)) - return NULL; + return -NLE_MISSING_ATTR; msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0, 0, nfnl_queue_get_group(queue)); if (msg == NULL) - return NULL; + return -NLE_NOMEM; if (nfnl_queue_test_maxlen(queue) && nla_put_u32(msg, NFQA_CFG_QUEUE_MAXLEN, @@ -136,79 +138,82 @@ static struct nl_msg *nfnl_queue_build_request(const struct nfnl_queue *queue) if (nla_put(msg, NFQA_CFG_PARAMS, sizeof(params), ¶ms) < 0) goto nla_put_failure; } - return msg; + + *result = msg; + return 0; nla_put_failure: nlmsg_free(msg); - return NULL; + return -NLE_MSGSIZE; } -struct nl_msg *nfnl_queue_build_create_request(const struct nfnl_queue *queue) +int nfnl_queue_build_create_request(const struct nfnl_queue *queue, + struct nl_msg **result) { - struct nl_msg *msg; struct nfqnl_msg_config_cmd cmd; + int err; - msg = nfnl_queue_build_request(queue); - if (msg == NULL) - return NULL; + if ((err = nfnl_queue_build_request(queue, result)) < 0) + return err; cmd.pf = 0; cmd._pad = 0; cmd.command = NFQNL_CFG_CMD_BIND; - if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0) - goto nla_put_failure; + NLA_PUT(*result, NFQA_CFG_CMD, sizeof(cmd), &cmd); - return msg; + return 0; nla_put_failure: - nlmsg_free(msg); - return NULL; + nlmsg_free(*result); + return -NLE_MSGSIZE; } int nfnl_queue_create(struct nl_handle *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_create_request(queue); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_queue_build_create_request(queue, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -struct nl_msg *nfnl_queue_build_change_request(const struct nfnl_queue *queue) +int nfnl_queue_build_change_request(const struct nfnl_queue *queue, + struct nl_msg **result) { - return nfnl_queue_build_request(queue); + return nfnl_queue_build_request(queue, result); } int nfnl_queue_change(struct nl_handle *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_change_request(queue); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_queue_build_change_request(queue, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } -struct nl_msg *nfnl_queue_build_delete_request(const struct nfnl_queue *queue) +int nfnl_queue_build_delete_request(const struct nfnl_queue *queue, + struct nl_msg **result) { if (!nfnl_queue_test_group(queue)) - return NULL; + return -NLE_MISSING_ATTR; return build_queue_cmd_request(0, nfnl_queue_get_group(queue), - NFQNL_CFG_CMD_UNBIND); + NFQNL_CFG_CMD_UNBIND, result); } int nfnl_queue_delete(struct nl_handle *nlh, const struct nfnl_queue *queue) { struct nl_msg *msg; + int err; - msg = nfnl_queue_build_delete_request(queue); - if (msg == NULL) - return nl_errno(ENOMEM); + if ((err = nfnl_queue_build_delete_request(queue, &msg)) < 0) + return err; return send_queue_request(nlh, msg); } diff --git a/lib/netfilter/queue_msg.c b/lib/netfilter/queue_msg.c index a097b68..6d6ca73 100644 --- a/lib/netfilter/queue_msg.c +++ b/lib/netfilter/queue_msg.c @@ -58,7 +58,8 @@ static struct nla_policy queue_policy[NFQA_MAX+1] = { }, }; -struct nfnl_queue_msg *nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh) +int nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh, + struct nfnl_queue_msg **result) { struct nfnl_queue_msg *msg; struct nlattr *tb[NFQA_MAX+1]; @@ -67,7 +68,7 @@ struct nfnl_queue_msg *nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh) msg = nfnl_queue_msg_alloc(); if (!msg) - return NULL; + return -NLE_NOMEM; msg->ce_msgtype = nlh->nlmsg_type; @@ -135,11 +136,12 @@ struct nfnl_queue_msg *nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh) goto errout; } - return msg; + *result = msg; + return 0; errout: nfnl_queue_msg_put(msg); - return NULL; + return err; } static int queue_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, @@ -148,9 +150,8 @@ static int queue_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nfnl_queue_msg *msg; int err; - msg = nfnlmsg_queue_msg_parse(nlh); - if (msg == NULL) - goto errout_errno; + if ((err = nfnlmsg_queue_msg_parse(nlh, &msg)) < 0) + goto errout; err = pp->pp_cb((struct nl_object *) msg, pp); if (err < 0) @@ -161,10 +162,6 @@ static int queue_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, errout: nfnl_queue_msg_put(msg); return err; - -errout_errno: - err = nl_get_errno(); - goto errout; } /** @} */ @@ -205,7 +202,7 @@ int nfnl_queue_msg_send_verdict(struct nl_handle *nlh, nlmsg = nfnl_queue_msg_build_verdict(msg); if (nlmsg == NULL) - return nl_errno(ENOMEM); + return -NLE_NOMEM; err = nl_send_auto_complete(nlh, nlmsg); nlmsg_free(nlmsg); diff --git a/lib/netfilter/queue_msg_obj.c b/lib/netfilter/queue_msg_obj.c index 476d920..5796c34 100644 --- a/lib/netfilter/queue_msg_obj.c +++ b/lib/netfilter/queue_msg_obj.c @@ -400,7 +400,7 @@ int nfnl_queue_msg_set_payload(struct nfnl_queue_msg *msg, uint8_t *payload, free(msg->queue_msg_payload); msg->queue_msg_payload = malloc(len); if (!msg->queue_msg_payload) - return nl_errno(ENOMEM); + return -NLE_NOMEM; memcpy(msg->queue_msg_payload, payload, len); msg->queue_msg_payload_len = len; 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -195,7 +195,7 @@ int nl_connect(struct nl_handle *handle, int protocol) 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 @@ int nl_connect(struct nl_handle *handle, int protocol) 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 @@ int nl_connect(struct nl_handle *handle, int protocol) 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 @@ int nl_sendto(struct nl_handle *handle, void *buf, size_t size) 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 @@ int nl_sendmsg(struct nl_handle *handle, struct nl_msg *msg, struct msghdr *hdr) ret = sendmsg(handle->h_fd, hdr, 0); if (ret < 0) - return nl_errno(errno); + return -nl_syserr2nlerr(errno); return ret; } @@ -415,7 +415,7 @@ int nl_send_simple(struct nl_handle *handle, int type, int flags, void *buf, 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 @@ retry: } else { free(msg.msg_control); free(*buf); - return nl_error(errno, "recvmsg failed"); + return -nl_syserr2nlerr(errno); } } @@ -527,7 +527,7 @@ retry: 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 @@ continue_reading: 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 @@ continue_reading: 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 @@ continue_reading: 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 @@ continue_reading: 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 @@ continue_reading: 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 @@ int nl_wait_for_ack(struct nl_handle *handle) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -47,10 +47,8 @@ struct nl_object *nl_object_alloc(struct nl_object_ops *ops) 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 @@ struct nl_object *nl_object_alloc(struct nl_object_ops *ops) * @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; + + if (!(*result = nl_object_alloc(ops->co_obj_ops))) + return -NLE_NOMEM; - return nl_object_alloc(ops->co_obj_ops); + 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 - * Baruch Even , + * Copyright (c) 2003-2008 Thomas Graf + * Copyright (c) 2003-2006 Baruch Even , * Mediatrix Telecom, inc. */ @@ -154,27 +154,25 @@ static int addr_clone(struct nl_object *_dst, struct nl_object *_src) 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 @@ static int addr_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 @@ void rtnl_addr_put(struct rtnl_addr *addr) * @{ */ -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 @@ static struct nl_msg *build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags) 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 @@ static struct nl_msg *build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags) 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 @@ nla_put_failure: * 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 @@ nla_put_failure: * 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 @@ int rtnl_addr_add(struct nl_handle *handle, struct rtnl_addr *addr, int flags) 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 @@ int rtnl_addr_add(struct nl_handle *handle, struct rtnl_addr *addr, int flags) * 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 @@ int rtnl_addr_add(struct nl_handle *handle, struct rtnl_addr *addr, int flags) * - 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 @@ int rtnl_addr_delete(struct nl_handle *handle, struct rtnl_addr *addr, 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 @@ static inline int __assign_addr(struct rtnl_addr *addr, struct nl_addr **pos, { 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -36,7 +36,7 @@ static int class_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 int class_request_update(struct nl_cache *cache, * @{ */ -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 @@ static struct nl_msg *class_build(struct rtnl_class *class, int type, int flags) 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 @@ errout: * 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 @@ int rtnl_class_add(struct nl_handle *handle, struct rtnl_class *class, 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 @@ int rtnl_class_add(struct nl_handle *handle, struct rtnl_class *class, * * @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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -43,7 +43,7 @@ int rtnl_class_register(struct rtnl_class_ops *cops) 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 @@ int rtnl_class_unregister(struct rtnl_class_ops *cops) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -44,7 +44,7 @@ static int cls_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 int cls_request_update(struct nl_cache *cache, struct nl_handle *handle) } -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 @@ static struct nl_msg *cls_build(struct rtnl_cls *cls, int type, int flags) 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 @@ errout: * 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 @@ errout: * 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 @@ struct nl_msg * rtnl_cls_build_add_request(struct rtnl_cls *cls, int flags) */ 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 @@ int rtnl_cls_add(struct nl_handle *handle, struct rtnl_cls *cls, int flags) * 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 @@ struct nl_msg *rtnl_cls_build_change_request(struct rtnl_cls *cls, int flags) 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 @@ int rtnl_cls_change(struct nl_handle *handle, struct rtnl_cls *cls, * 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 @@ struct nl_msg *rtnl_cls_build_delete_request(struct rtnl_cls *cls, int flags) */ 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 @@ int rtnl_cls_delete(struct nl_handle *handle, struct rtnl_cls *cls, int flags) * @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 + * Copyright (c) 2003-2008 Thomas Graf * Copyright (c) 2006 Petr Gotthard * Copyright (c) 2006 Siemens AG Oesterreich */ @@ -63,7 +63,7 @@ static int fw_msg_parser(struct rtnl_cls *cls) 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 @@ static int fw_msg_parser(struct rtnl_cls *cls) 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 @@ static int fw_msg_parser(struct rtnl_cls *cls) } return 0; - -errout_nomem: - err = nl_errno(ENOMEM); - - return err; } static void fw_free_data(struct rtnl_cls *cls) @@ -119,19 +114,17 @@ static int fw_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src) 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 @@ int rtnl_fw_set_classid(struct rtnl_cls *cls, uint32_t classid) 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 @@ static int u32_msg_parser(struct rtnl_cls *cls) 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 @@ static int u32_msg_parser(struct rtnl_cls *cls) 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 @@ static int u32_msg_parser(struct rtnl_cls *cls) return 0; errout_nomem: - err = nl_errno(ENOMEM); + err = -NLE_NOMEM; errout: return err; } @@ -193,27 +192,25 @@ static int u32_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src) 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 @@ int rtnl_u32_set_classid(struct rtnl_cls *cls, uint32_t classid) 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 @@ int rtnl_u32_set_flags(struct rtnl_cls *cls, int flags) 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 @@ int rtnl_u32_add_key(struct rtnl_cls *cls, uint32_t val, uint32_t mask, 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 rtnl_u32_add_key_uint16(struct rtnl_cls *cls, uint16_t val, uint16_t mask, { 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -44,7 +44,7 @@ int rtnl_cls_register(struct rtnl_cls_ops *cops) 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 @@ int rtnl_cls_unregister(struct rtnl_cls_ops *cops) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -215,21 +215,19 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src) 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 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, link = rtnl_link_alloc(); if (link == NULL) { - err = nl_errno(ENOMEM); + err = -NLE_NOMEM; goto errout; } @@ -276,7 +274,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 @@ void rtnl_link_put(struct rtnl_link *link) /** * 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 @@ struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, * @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 @@ struct nl_msg * rtnl_link_build_change_request(struct rtnl_link *old, 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 @@ struct nl_msg * rtnl_link_build_change_request(struct rtnl_link *old, 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 @@ nla_put_failure: 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 rtnl_link_set_info_type(struct rtnl_link *link, const char *type) 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 @@ struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *name) 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 @@ int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -73,7 +73,7 @@ static int vlan_alloc(struct rtnl_link *link) 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 @@ static int vlan_parse(struct rtnl_link *link, struct nlattr *data, 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 @@ static int vlan_parse(struct rtnl_link *link, struct nlattr *data, 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 @@ static int vlan_parse(struct rtnl_link *link, struct nlattr *data, 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 @@ static int vlan_clone(struct rtnl_link *dst, struct rtnl_link *src) 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 @@ static int vlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) 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 @@ int rtnl_link_vlan_set_id(struct rtnl_link *link, int id) 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 @@ int rtnl_link_vlan_get_id(struct rtnl_link *link) 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 @@ int rtnl_link_vlan_set_flags(struct rtnl_link *link, unsigned int flags) 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 @@ int rtnl_link_vlan_unset_flags(struct rtnl_link *link, unsigned int flags) 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 @@ unsigned int rtnl_link_vlan_get_flags(struct rtnl_link *link) 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 @@ int rtnl_link_vlan_set_ingress_map(struct rtnl_link *link, int from, 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 @@ uint32_t *rtnl_link_vlan_get_ingress_map(struct rtnl_link *link) { 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 @@ int rtnl_link_vlan_set_egress_map(struct rtnl_link *link, uint32_t from, int to) 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 @@ int rtnl_link_vlan_set_egress_map(struct rtnl_link *link, uint32_t from, int to) 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_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *link, { 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -187,15 +187,13 @@ static int neigh_clone(struct nl_object *_dst, struct nl_object *_src) 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 @@ static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, neigh = rtnl_neigh_alloc(); if (!neigh) { - err = nl_errno(ENOMEM); + err = -NLE_NOMEM; goto errout; } @@ -523,30 +521,16 @@ void rtnl_neigh_put(struct rtnl_neigh *neigh) /** * 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 @@ struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex, * @{ */ -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 @@ static struct nl_msg * build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, 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 @@ static struct nl_msg * build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, 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 @@ nla_put_failure: * - 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 rtnl_neigh_add(struct nl_handle *handle, struct rtnl_neigh *tmpl, int flags) 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 @@ int rtnl_neigh_add(struct nl_handle *handle, struct rtnl_neigh *tmpl, int flags) * 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 @@ int rtnl_neigh_add(struct nl_handle *handle, struct rtnl_neigh *tmpl, int flags) * 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 @@ struct nl_msg *rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, 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 @@ int rtnl_neigh_delete(struct nl_handle *handle, struct rtnl_neigh *neigh, * 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 @@ struct nl_msg *rtnl_neigh_build_change_request(struct rtnl_neigh *neigh, 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 @@ static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos, 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -129,7 +129,7 @@ static int neightbl_msg_parser(struct nl_cache_ops *ops, ntbl = rtnl_neightbl_alloc(); if (!ntbl) { - err = nl_errno(ENOMEM); + err = -NLE_NOMEM; goto errout; } @@ -143,7 +143,7 @@ static int neightbl_msg_parser(struct nl_cache_ops *ops, 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 @@ void rtnl_neightbl_put(struct rtnl_neightbl *neightbl) /** * 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 @@ struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *cache, * 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 @@ struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *cache, * 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; + + if (nlmsg_append(m, &ndt, sizeof(ndt), NLMSG_ALIGNTO) < 0) + goto nla_put_failure; - nla_put_string(m, NDTA_NAME, old->nt_name); + 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); + + if (nla_put_nested(m, NDTA_PARMS, parms) < 0) + goto nla_put_failure; - nla_put_nested(m, NDTA_PARMS, parms); 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 @@ struct nl_msg * rtnl_neightbl_build_change_request(struct rtnl_neightbl *old, 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 *rtnl_route_nh_alloc(void) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -98,13 +98,13 @@ static struct nl_cache_ops rtnl_qdisc_ops; 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 int qdisc_request_update(struct nl_cache *c, struct nl_handle *h) * @{ */ -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 @@ static struct nl_msg *qdisc_build(struct rtnl_qdisc *qdisc, int type, int flags) 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 @@ static struct nl_msg *qdisc_build(struct rtnl_qdisc *qdisc, int type, int flags) * 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 @@ errout: * 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 @@ int rtnl_qdisc_add(struct nl_handle *handle, struct rtnl_qdisc *qdisc, 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 @@ int rtnl_qdisc_add(struct nl_handle *handle, struct rtnl_qdisc *qdisc, * 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 @@ int rtnl_qdisc_change(struct nl_handle *handle, struct rtnl_qdisc *qdisc, 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 @@ int rtnl_qdisc_change(struct nl_handle *handle, struct rtnl_qdisc *qdisc, /** * 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 @@ struct nl_msg *rtnl_qdisc_build_delete_request(struct rtnl_qdisc *qdisc) msg = nlmsg_alloc_simple(RTM_DELQDISC, 0); if (!msg) - return NULL; - - 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); + 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; + 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 @@ int rtnl_qdisc_delete(struct nl_handle *handle, struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_delete(struct nl_handle *handle, struct rtnl_qdisc *qdisc) /** * 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 @@ int rtnl_qdisc_register(struct rtnl_qdisc_ops *qops) 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 @@ int rtnl_qdisc_unregister(struct rtnl_qdisc_ops *qops) 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 @@ static int route_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 @@ static int route_request_update(struct nl_cache *c, struct nl_handle *h) * 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 @@ struct nl_cache *rtnl_route_alloc_cache(struct nl_handle *handle, * @{ */ -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 @@ int rtnl_route_add(struct nl_handle *handle, struct rtnl_route *route, 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 @@ int rtnl_route_add(struct nl_handle *handle, struct rtnl_route *route, 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 @@ int rtnl_route_delete(struct nl_handle *handle, struct rtnl_route *route, 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 @@ static int route_clone(struct nl_object *_dst, struct nl_object *_src) 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 @@ uint32_t rtnl_route_get_priority(struct rtnl_route *route) 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 @@ int rtnl_route_set_dst(struct rtnl_route *route, struct nl_addr *addr) { 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 @@ struct nl_addr *rtnl_route_get_dst(struct rtnl_route *route) 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 @@ struct nl_addr *rtnl_route_get_src(struct rtnl_route *route) 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 @@ uint32_t rtnl_route_get_flags(struct rtnl_route *route) 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_set_metric(struct rtnl_route *route, int metric, uint32_t value) 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_unset_metric(struct rtnl_route *route, int metric) 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 @@ int rtnl_route_set_pref_src(struct rtnl_route *route, struct nl_addr *addr) { 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 @@ static struct nla_policy route_policy[RTA_MAX+1] = { [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 @@ struct rtnl_route *rtnl_route_parse(struct nlmsghdr *nlh) route = rtnl_route_alloc(); if (!route) { - err = nl_errno(ENOMEM); + err = -NLE_NOMEM; goto errout; } @@ -1034,8 +1027,7 @@ struct rtnl_route *rtnl_route_parse(struct nlmsghdr *nlh) 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 @@ struct rtnl_route *rtnl_route_parse(struct nlmsghdr *nlh) } } - 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 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route) }; 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 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -60,15 +60,13 @@ static int rule_clone(struct nl_object *_dst, struct nl_object *_src) 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 @@ static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, rule = rtnl_rule_alloc(); if (!rule) { - err = nl_errno(ENOMEM); + err = -NLE_NOMEM; goto errout; } @@ -118,7 +116,7 @@ static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 @@ static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 @@ static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 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 @@ void rtnl_rule_put(struct rtnl_rule *rule) */ /** - * Build a rule cache including all rules of the specified family currently configured in the kernel. + * Build a rule cache including all rules currently configured in the kernel. * @arg handle netlink handle - * @arg family address family + * @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 of the specified address family currently - * configured in the kernel. + * 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_by_family(struct nl_handle *handle, - int family) +int rtnl_rule_alloc_cache(struct nl_handle *sock, int family, + struct nl_cache **result) { struct nl_cache * cache; + int err; - cache = nl_cache_alloc(&rtnl_rule_ops); - if (cache == NULL) - return NULL; + if (!(cache = nl_cache_alloc(&rtnl_rule_ops))) + return -NLE_NOMEM; - /* XXX RULE_CACHE_FAMILY(cache) = family; */ + cache->c_iarg1 = family; - if (handle && nl_cache_refill(handle, cache) < 0) { + if (sock && (err = nl_cache_refill(sock, cache)) < 0) { free(cache); - return NULL; + return err; } - return cache; -} - -/** - * Build a rule cache including all rules currently configured in the kernel. - * @arg handle netlink handle - * - * 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. - */ -struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *handle) -{ - return rtnl_rule_alloc_cache_by_family(handle, AF_UNSPEC); + *result = cache; + return 0; } /** @} */ @@ -494,7 +475,8 @@ struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *handle) * @{ */ -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 @@ static struct nl_msg *build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags) 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 @@ static struct nl_msg *build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags) 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 @@ nla_put_failure: * * @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 @@ struct nl_msg *rtnl_rule_build_add_request(struct rtnl_rule *tmpl, int flags) */ 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 @@ int rtnl_rule_add(struct nl_handle *handle, struct rtnl_rule *tmpl, int flags) * * @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 @@ struct nl_msg *rtnl_rule_build_delete_request(struct rtnl_rule *rule, int flags) 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 @@ static inline int __assign_addr(struct rtnl_rule *rule, struct nl_addr **pos, { 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 @@ struct nl_addr *rtnl_rule_get_dst(struct rtnl_rule *rule) 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 @@ int rtnl_rule_get_action(struct rtnl_rule *rule) 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 + * Copyright (c) 2003-2008 Thomas Graf */ #include @@ -99,7 +99,7 @@ static int cbq_msg_parser(struct rtnl_tca *tca) 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 @@ static int cbq_clone(struct rtnl_tca *_dst, struct rtnl_tca *_src) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -70,7 +70,7 @@ static int dsmark_qdisc_msg_parser(struct rtnl_qdisc *qdisc) 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 @@ static int dsmark_class_msg_parser(struct rtnl_class *class) 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 @@ int rtnl_class_dsmark_set_bitmask(struct rtnl_class *class, uint8_t mask) 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 @@ int rtnl_class_dsmark_get_bitmask(struct rtnl_class *class) 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 @@ int rtnl_class_dsmark_set_value(struct rtnl_class *class, uint8_t value) 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 @@ int rtnl_class_dsmark_get_value(struct rtnl_class *class) 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 @@ int rtnl_qdisc_dsmark_set_indices(struct rtnl_qdisc *qdisc, uint16_t indices) 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 @@ int rtnl_qdisc_dsmark_get_indices(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_dsmark_set_default_index(struct rtnl_qdisc *qdisc, 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 @@ int rtnl_qdisc_dsmark_get_default_index(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_dsmark_set_set_tc_index(struct rtnl_qdisc *qdisc, int flag) 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 @@ int rtnl_qdisc_dsmark_get_set_tc_index(struct rtnl_qdisc *qdisc) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -60,11 +60,11 @@ static int fifo_msg_parser(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_fifo_set_limit(struct rtnl_qdisc *qdisc, int limit) 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 @@ int rtnl_qdisc_fifo_get_limit(struct rtnl_qdisc *qdisc) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -69,11 +69,11 @@ static int netem_msg_parser(struct rtnl_qdisc *qdisc) 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 @@ int netem_build_msg(struct rtnl_qdisc *qdisc, struct nl_msg *msg) 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 @@ int netem_build_msg(struct rtnl_qdisc *qdisc, struct nl_msg *msg) 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 @@ int netem_build_msg(struct rtnl_qdisc *qdisc, struct nl_msg *msg) 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 @@ int netem_build_msg(struct rtnl_qdisc *qdisc, struct nl_msg *msg) msg->nm_nlh->nlmsg_len += (head->nla_len - old_len); return err; +nla_put_failure: + return -NLE_MSGSIZE; } /** @@ -348,7 +331,7 @@ int rtnl_netem_set_limit(struct rtnl_qdisc *qdisc, int limit) 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 @@ int rtnl_netem_get_limit(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_gap(struct rtnl_qdisc *qdisc, int gap) 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 @@ int rtnl_netem_get_gap(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_reorder_probability(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_reorder_probability(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_reorder_correlation(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_reorder_correlation(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_corruption_probability(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_corruption_probability(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_corruption_correlation(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_corruption_correlation(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_loss(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_loss(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_loss_correlation(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_loss_correlation(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_duplicate(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_duplicate(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_duplicate_correlation(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_duplicate_correlation(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_delay(struct rtnl_qdisc *qdisc, int delay) 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 @@ int rtnl_netem_get_delay(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_jitter(struct rtnl_qdisc *qdisc, int jitter) 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 @@ int rtnl_netem_get_jitter(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_set_delay_correlation(struct rtnl_qdisc *qdisc, int prob) 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 @@ int rtnl_netem_get_delay_correlation(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_get_delay_distribution_size(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_netem_get_delay_distribution(struct rtnl_qdisc *qdisc, int16_t **dist_p return 0; } else - return nl_errno(ENOENT); + return -NLE_NOATTR; } /** @@ -884,7 +867,7 @@ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist netem = netem_alloc(qdisc); if (!netem) - return nl_errno(ENOMEM); + return -NLE_NOMEM; FILE *f = NULL; int i, n = 0; @@ -906,7 +889,8 @@ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist 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 @@ int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -58,11 +58,11 @@ static int prio_msg_parser(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_prio_set_bands(struct rtnl_qdisc *qdisc, int bands) 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 @@ int rtnl_qdisc_prio_get_bands(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_prio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[], 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 @@ uint8_t *rtnl_qdisc_prio_get_priomap(struct rtnl_qdisc *qdisc) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -66,11 +66,11 @@ static int red_msg_parser(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_red_set_limit(struct rtnl_qdisc *qdisc, int limit) 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 @@ int rtnl_red_get_limit(struct rtnl_qdisc *qdisc) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -61,11 +61,11 @@ static int sfq_msg_parser(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_sfq_set_quantum(struct rtnl_qdisc *qdisc, int quantum) 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 @@ int rtnl_sfq_get_quantum(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_sfq_set_limit(struct rtnl_qdisc *qdisc, int limit) 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 @@ int rtnl_sfq_get_limit(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_sfq_set_perturb(struct rtnl_qdisc *qdisc, int perturb) 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 @@ int rtnl_sfq_get_perturb(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_sfq_get_divisor(struct rtnl_qdisc *qdisc) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -64,7 +64,7 @@ static int tbf_msg_parser(struct rtnl_qdisc *q) 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 @@ int rtnl_qdisc_tbf_set_limit(struct rtnl_qdisc *qdisc, int limit) 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 @@ int rtnl_qdisc_tbf_set_limit_by_latency(struct rtnl_qdisc *qdisc, int latency) 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 @@ int rtnl_qdisc_tbf_get_limit(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_tbf_set_mpu(struct rtnl_qdisc *qdisc, int mpu) 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 @@ int rtnl_qdisc_tbf_get_mpu(struct rtnl_qdisc *qdisc) 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 @@ int rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *qdisc, int rate, int bucket, 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 @@ int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *qdisc, int rate, int bucket, 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -66,7 +66,7 @@ int tca_msg_parser(struct nlmsghdr *n, struct rtnl_tca *g) 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 @@ int tca_msg_parser(struct nlmsghdr *n, struct rtnl_tca *g) 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 @@ int tca_msg_parser(struct nlmsghdr *n, struct rtnl_tca *g) 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 @@ compat_xstats: 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 @@ int tca_clone(struct rtnl_tca *dst, struct rtnl_tca *src) 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 @@ uint64_t tca_get_stat(struct rtnl_tca *t, int id) 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 @@ struct nl_msg *tca_build_msg(struct rtnl_tca *tca, int type, int flags) 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 @@ struct nl_msg *tca_build_msg(struct rtnl_tca *tca, int type, int flags) 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 @@ int rtnl_tc_calc_cell_log(int cell_size) if ((1 << i) == cell_size) return i; - return nl_errno(EINVAL); + return -NLE_INVAL; } @@ -546,13 +546,13 @@ int rtnl_tc_str2handle(const char *name, uint32_t *res) /* :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 @@ int rtnl_tc_str2handle(const char *name, uint32_t *res) /* 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 @@ int rtnl_tc_str2handle(const char *name, uint32_t *res) /* 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -166,10 +166,8 @@ static struct nl_handle *__alloc_handle(struct nl_cb *cb) 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 @@ static struct nl_handle *__alloc_handle(struct nl_cb *cb) 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_handle *nl_handle_alloc(void) 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 nl_socket_add_membership(struct nl_handle *handle, int group) 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 nl_socket_drop_membership(struct nl_handle *handle, int group) 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_get_fd(struct nl_handle *handle) 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 @@ int nl_set_buffer_size(struct nl_handle *handle, int rxbuf, int txbuf) 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 nl_set_passcred(struct nl_handle *handle, int state) 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 nl_socket_recv_pktinfo(struct nl_handle *handle, int state) 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 + * Copyright (c) 2003-2008 Thomas Graf */ /** @@ -41,48 +41,6 @@ static void __init nl_debug_init(void) 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 @@ int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)) 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 @@ int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)) 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 @@ int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)) 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 * @{ -- cgit v0.12