]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
Thread-safe error handling
authorThomas Graf <tgr@lsx.localdomain>
Wed, 14 May 2008 15:49:44 +0000 (17:49 +0200)
committerThomas Graf <tgr@lsx.localdomain>
Wed, 14 May 2008 15:49:44 +0000 (17:49 +0200)
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!

79 files changed:
include/netlink-local.h
include/netlink-tc.h
include/netlink/addr.h
include/netlink/cache.h
include/netlink/errno.h [new file with mode: 0644]
include/netlink/fib_lookup/lookup.h
include/netlink/genl/ctrl.h
include/netlink/netfilter/ct.h
include/netlink/netfilter/log.h
include/netlink/netfilter/log_msg.h
include/netlink/netfilter/queue.h
include/netlink/netfilter/queue_msg.h
include/netlink/netlink.h
include/netlink/object.h
include/netlink/route/addr.h
include/netlink/route/class.h
include/netlink/route/classifier.h
include/netlink/route/link.h
include/netlink/route/neighbour.h
include/netlink/route/neightbl.h
include/netlink/route/qdisc.h
include/netlink/route/route.h
include/netlink/route/rule.h
include/netlink/utils.h
lib/addr.c
lib/attr.c
lib/cache.c
lib/cache_mngr.c
lib/cache_mngt.c
lib/data.c
lib/error.c [new file with mode: 0644]
lib/fib_lookup/lookup.c
lib/fib_lookup/request.c
lib/genl/ctrl.c
lib/genl/family.c
lib/genl/genl.c
lib/genl/mngt.c
lib/handlers.c
lib/msg.c
lib/netfilter/ct.c
lib/netfilter/ct_obj.c
lib/netfilter/log.c
lib/netfilter/log_msg.c
lib/netfilter/log_msg_obj.c
lib/netfilter/nfnl.c
lib/netfilter/queue.c
lib/netfilter/queue_msg.c
lib/netfilter/queue_msg_obj.c
lib/nl.c
lib/object.c
lib/route/addr.c
lib/route/class.c
lib/route/class_api.c
lib/route/classifier.c
lib/route/cls/fw.c
lib/route/cls/u32.c
lib/route/cls_api.c
lib/route/link.c
lib/route/link/api.c
lib/route/link/vlan.c
lib/route/neigh.c
lib/route/neightbl.c
lib/route/nexthop.c
lib/route/qdisc.c
lib/route/qdisc_api.c
lib/route/route.c
lib/route/route_obj.c
lib/route/rule.c
lib/route/sch/cbq.c
lib/route/sch/dsmark.c
lib/route/sch/fifo.c
lib/route/sch/netem.c
lib/route/sch/prio.c
lib/route/sch/red.c
lib/route/sch/sfq.c
lib/route/sch/tbf.c
lib/route/tc.c
lib/socket.c
lib/utils.c

index 10619ace40ff8ce42939efaee3a78ed83e558e8a..1592138605351190850ed3c31e94bff27cd45e10 100644 (file)
@@ -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 <assert.h>
-static inline int __assert_error(const char *file, int line, char *func,
-       const char *fmt, ...)
-{
-       va_list args;
-       fprintf(stderr, "%s:%d:%s: ", file, line, func);
-       va_start(args, fmt);
-       vfprintf(stderr, fmt, args);
-       va_end(args);
-       fprintf(stderr, "\n");
-       assert(0);
-       return 0;
-}
-#define nl_error(E, FMT,ARG...) \
-       __assert_error(__FILE__, __LINE__, __FUNCTION__, FMT, ##ARG)
-
-#else
-#define nl_error(E, FMT,ARG...) \
-       __nl_error(E, __FILE__, __LINE__, __FUNCTION__, FMT, ##ARG)
-
-#endif
-
-#define nl_errno(E)    nl_error(E, NULL)
-
 /* backwards compat */
 #define dp_new_line(params, line)      nl_new_line(params)
 #define dp_dump(params, fmt, arg...)   nl_dump(params, fmt, ##arg)
@@ -129,7 +95,7 @@ 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);
index 65be58840d51c672f191b4a225378520c31d1d6a..691969d3a4469ee71c34c59c4c4086930c573298 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_TC_PRIV_H_
@@ -51,7 +51,7 @@ extern 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)
 {
index 8464a0cdc13c269eac3c4c2468cd7a0762350657..00868d2261a5a0c4589deb0d6678dfb07d1758d3 100644 (file)
@@ -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 */
index cb7741bff0121f6b95601ae47c0e73c912434226..b437d76f169f50586e904f44b02b170ffc1c9b90 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_CACHE_H_
@@ -39,7 +39,11 @@ 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 (file)
index 0000000..0b43da0
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * netlink/errno.h             Error Numbers
+ *
+ *     This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU Lesser General Public
+ *     License as published by the Free Software Foundation version 2.1
+ *     of the License.
+ *
+ * Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
+ */
+
+#ifndef NETLINK_ERRNO_H_
+#define NETLINK_ERRNO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NLE_SUCCESS            0
+#define NLE_FAILURE            1
+#define NLE_INTR               2
+#define NLE_BAD_SOCK           3
+#define NLE_AGAIN              4
+#define NLE_NOMEM              5
+#define NLE_EXIST              6
+#define NLE_INVAL              7
+#define NLE_RANGE              8
+#define NLE_MSGSIZE            9
+#define NLE_OPNOTSUPP          10
+#define NLE_AF_NOSUPPORT       11
+#define NLE_OBJ_NOTFOUND       12
+#define NLE_NOATTR             13
+#define NLE_MISSING_ATTR       14
+#define NLE_AF_MISMATCH                15
+#define NLE_SEQ_MISMATCH       16
+#define NLE_MSG_OVERFLOW       17
+#define NLE_MSG_TRUNC          18
+#define NLE_NOADDR             19
+#define NLE_SRCRT_NOSUPPORT    20
+#define NLE_MSG_TOOSHORT       21
+#define NLE_MSGTYPE_NOSUPPORT  22
+#define NLE_OBJ_MISMATCH       23
+#define NLE_NOCACHE            24
+#define NLE_BUSY               25
+#define NLE_PROTO_MISMATCH     26
+#define NLE_NOACCESS           27
+#define NLE_PERM               28
+
+#define NLE_MAX                        NLE_PERM
+
+extern const char *    nl_geterror(int);
+extern void            nl_perror(int, const char *);
+extern int             nl_syserr2nlerr(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 29c7ee8c265750f1409e3176fc99394681136dd6..201a7a0887784f210c1da326c3fc2b94a6d153b2 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_FIB_LOOKUP_H_
@@ -28,8 +28,9 @@ extern 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 *);
index 5d65c6853685f2045f2851f4f4f1d0246d5c810e..f66338e10f9570ee2ef6532918df0e8595014948 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_GENL_CTRL_H_
@@ -22,7 +22,8 @@ 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 *);
index f5540177f08e8d5db4c14d8dcf62055110a36378..2e08228703b69b370f3be0e92d1625f6bae1193c 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
  * Copyright (c) 2007 Secure Computing Corporation
  */
@@ -27,95 +27,95 @@ 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
 }
index 51f4a90446e41d08759f1a3158a5b81dcce30da4..be8dd3258b61ef4d4918a8137322dcb783e597fa 100644 (file)
@@ -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
 }
index 0cdb6c6131718afb36a0285e32012eac5b2d60be..42e1f70c20c00de090b033e46d7d242f9009fd53 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
  * Copyright (c) 2007 Secure Computing Corporation
  * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
@@ -29,7 +29,8 @@ 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 *);
index c88abe25c96bbd37b62291d937d0af989616c188..d480135dfc4e8889f12aee7afe0a4f37522b8699 100644 (file)
@@ -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
 }
index bb63236d0991611eb7df8025d7ea85a9cc7eecaf..f8f034c90bdb197d063cd54879a24acbe1007c0f 100644 (file)
@@ -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 *);
index bfae9094cc7d20bceef96dcbd5c56c6a902c0f6c..eff4b16c06106a0eb177057445ffaf26120428e8 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/genetlink.h>
 #include <linux/netfilter/nfnetlink.h>
 #include <netlink/version.h>
+#include <netlink/errno.h>
 #include <netlink/types.h>
 #include <netlink/handlers.h>
 #include <netlink/socket.h>
index 751a1b32f206c1881b69c8751ae6a4db9438c7ad..bae2bf413a7c11431fa2a976ef3d202cd17cf9eb 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_OBJECT_H_
@@ -27,7 +27,8 @@ 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 *);
index 71a90e0f8207bd2c6daca394cce61b07c3384f19..9004ca039666fd4fc45e01ef763fe729b0058c71 100644 (file)
@@ -6,8 +6,8 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
- *                         Baruch Even <baruch@ev-en.org>,
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>,
  *                         Mediatrix Telecom, inc. <ericb@mediatrix.com>
  */
 
@@ -26,63 +26,56 @@ 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
 }
index a624ef6173b70d75bde8b8793b8207edab845f22..a704ed157fc863e54954b61b5b557ed4f02aa19f 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_CLASS_H_
@@ -24,20 +24,20 @@ 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);
index 7ef0da4a25390d75bd3750ca672a489a84814d48..0ee563e5d1bedcead9802c9b341a66c2a26dfd60 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_CLASSIFIER_H_
@@ -23,21 +23,22 @@ extern "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);
index caaa7928a602e7530d9dec051ad6152670ee3a52..87e5adaff006728010d5c24c0b55a79b1797a4da 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_LINK_H_
@@ -58,109 +58,91 @@ 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
 }
index 078c3f4f192ce7c1eb026d7f0ae2d8aff9281401..7b5ed248c5b414c29cd5bb73e0f2cfd1a5a6c3b4 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_NEIGHBOUR_H_
@@ -22,39 +22,31 @@ 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 *,
index 20285eec8148c4faa7dafdb076098f13f891fa30..7120053fa1771cc8c67b318eaecbb79226f2b70e 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_NEIGHTBL_H_
@@ -25,14 +25,15 @@ 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 *);
 
index ee71304ad53699893a2cdb361372d089f77d39b5..d3bc99bd4f0d53d04a1c66b5337f3ea62500fb55 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_QDISC_H_
@@ -24,60 +24,46 @@ 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
index 071f2c5c3e4473d6226577931473b650c7db050b..b3a9b9e9abc2180ce065aab098095d0d1aae33fb 100644 (file)
@@ -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
 }
index e57ef5346c19eddf94a46b8d7fad341db9d979ef..15551850a504ed87db460cf59397c91716a9be2e 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_RULE_H_
@@ -27,14 +27,15 @@ 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);
 
 
index 207e8ec3e895b8b5b795221e73c31248f5bdd861..2b6bcb7837cb119c9cad8addbe046a089428fb88 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #ifndef NETLINK_UTILS_H_
@@ -38,10 +38,6 @@ extern "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 **);
index 70e4b1d2ffda7b3ae97a9c6622cdbfb8a96ad58c..258084eb6a73551a92959be4998973f2cf3ff2bb 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -140,11 +140,11 @@ 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);
index 875c881b8585c32cf745839a5f6c5419d99aef17..0143be7e22fba04ad955d7b2f565473a9ae239a2 100644 (file)
  *     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",
index e7ba5b92b477d3088b8838886a6ead8c449f7775..bc360f0a6f358d41f46814f4138a0001062f0c23 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -175,10 +175,8 @@ struct nl_cache *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;
 }
index dffba90f339ffb90d7d4f422528d97d9423b4b8c..590979539c74395534d709c662aae4b4537ca18d 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2007 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -146,17 +146,18 @@ 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;
index 137d6c92e17c2d7580e6a6f72ccd63cc80f6f547..4fede92cb8dab78eb1c19496d7b6d0035ec3d884 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -129,15 +129,12 @@ 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);
 
index 7b81ceb15d00f57afbd7f7587de63c7c62112f5c..7bde598f40bf259ca48df7f5274d6645b3680f88 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -56,7 +56,6 @@ 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 (file)
index 0000000..1ef7e5e
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * lib/error.c         Error Handling
+ *
+ *     This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU Lesser General Public
+ *     License as published by the Free Software Foundation version 2.1
+ *     of the License.
+ *
+ * Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <netlink-local.h>
+#include <netlink/netlink.h>
+
+static const char *errmsg[NLE_MAX+1] = {
+[NLE_SUCCESS]          = "Success",
+[NLE_FAILURE]          = "Unspecific failure",
+[NLE_INTR]             = "Interrupted system call",
+[NLE_BAD_SOCK]         = "Bad socket",
+[NLE_AGAIN]            = "Try again",
+[NLE_NOMEM]            = "Out of memory",
+[NLE_EXIST]            = "Object exists",
+[NLE_INVAL]            = "Invalid input data or parameter",
+[NLE_RANGE]            = "Input data out of range",
+[NLE_MSGSIZE]          = "Message size not sufficient",
+[NLE_OPNOTSUPP]                = "Operation not supported",
+[NLE_AF_NOSUPPORT]     = "Address family not supported",
+[NLE_OBJ_NOTFOUND]     = "Object not found",
+[NLE_NOATTR]           = "Attribute not available",
+[NLE_MISSING_ATTR]     = "Missing attribute",
+[NLE_AF_MISMATCH]      = "Address family mismatch",
+[NLE_SEQ_MISMATCH]     = "Message sequence number mismatch",
+[NLE_MSG_OVERFLOW]     = "Kernel reported message overflow",
+[NLE_MSG_TRUNC]                = "Kernel reported truncated message",
+[NLE_NOADDR]           = "Invalid address for specified address family",
+[NLE_SRCRT_NOSUPPORT]  = "Source based routing not supported",
+[NLE_MSG_TOOSHORT]     = "Netlink message is too short",
+[NLE_MSGTYPE_NOSUPPORT]        = "Netlink message type is not supported",
+[NLE_OBJ_MISMATCH]     = "Object type does not match cache",
+[NLE_NOCACHE]          = "Unknown or invalid cache type",
+[NLE_BUSY]             = "Object busy",
+[NLE_PROTO_MISMATCH]   = "Protocol mismatch",
+[NLE_NOACCESS]         = "No Access",
+[NLE_PERM]             = "Operation not permitted",
+};
+
+/**
+ * Return error message for an error code
+ * @return error message
+ */
+const char *nl_geterror(int error)
+{
+       error = abs(error);
+
+       if (error > NLE_MAX)
+               error = NLE_FAILURE;
+
+       return errmsg[error];
+}
+
+/**
+ * Print a libnl error message
+ * @arg s              error message prefix
+ *
+ * Prints the error message of the call that failed last.
+ *
+ * If s is not NULL and *s is not a null byte the argument
+ * string is printed, followed by a colon and a blank. Then
+ * the error message and a new-line.
+ */
+void nl_perror(int error, const char *s)
+{
+       if (s && *s)
+               fprintf(stderr, "%s: %s\n", s, nl_geterror(error));
+       else
+               fprintf(stderr, "%s\n", nl_geterror(error));
+}
+
+int nl_syserr2nlerr(int error)
+{
+       error = abs(error);
+
+       switch (error) {
+       case EBADF:             return NLE_BAD_SOCK;
+       case EADDRINUSE:        return NLE_EXIST;
+       case EADDRNOTAVAIL:     return NLE_NOADDR;
+       case ENOENT:            return NLE_OBJ_NOTFOUND;
+       case EINTR:             return NLE_INTR;
+       case EAGAIN:            return NLE_AGAIN;
+       case ENOTSOCK:          return NLE_BAD_SOCK;
+       case ENOPROTOOPT:       return NLE_INVAL;
+       case EFAULT:            return NLE_INVAL;
+       case EACCES:            return NLE_NOACCESS;
+       case EINVAL:            return NLE_INVAL;
+       case ENOBUFS:           return NLE_NOMEM;
+       case ENOMEM:            return NLE_NOMEM;
+       case EAFNOSUPPORT:      return NLE_AF_NOSUPPORT;
+       case EPROTONOSUPPORT:   return NLE_PROTO_MISMATCH;
+       case EOPNOTSUPP:        return NLE_OPNOTSUPP;
+       case EPERM:             return NLE_PERM;
+       default:                return NLE_FAILURE;
+       }
+}
+
+/** @} */
+
index 576603518cd20052532fad1d05e216c4c6280f8c..b7692460c266ae7c21ae578524931ebe20fce074 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -63,7 +63,7 @@ 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);
index 8b002244cffd020165f71f8387584f3b1f7815c4..ffcf8f5d6b4f7c1f36d8e01a309c0f2d15824ff3 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -48,11 +48,9 @@ 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);
index 9948a57f19da98447f4a7b81d3e46147eb0064f6..fc08e148fc45e112eeb97a9349c18e7c17232a36 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -61,17 +61,17 @@ 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;
        }
 
index e05b52c38c481b2ef4f13061a08d4facf63a5186..ec52b738a9a628fd71cf204cccce0fd505b482e7 100644 (file)
@@ -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;
index 04cfebf6954549a5a1d8b509c70bbd74b5e9de09..cee7efde5ada526d11d27e2a7be49a056ee170d4 100644 (file)
@@ -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),
index d737697083335a7b35fba1bac10b400996f2068a..76443525180b54d145d829c860e388f6014cf090 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -108,12 +108,12 @@ 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);
index 1797e4faadd062a788571562ee9ebe733362f262..480df596f6f753f126dddb8240d8ec8ab76d90a0 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -140,7 +140,7 @@ 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;
index c5cb7b42687da4050e04da413560f28a212456b1..ad6f5a1626add8550e79512192c1ffd6fa4ea57f 100644 (file)
--- a/lib/msg.c
+++ b/lib/msg.c
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -320,7 +320,7 @@ int 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);
index e16a60698d51442ab7f49a4c33bc5b293973c75e..de561d21f72cb3ca69b00f4ec0dde2240dfb2360 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
  * Copyright (c) 2007 Secure Computing Corporation
  * Copyright (c= 2008 Patrick McHardy <kaber@trash.net>
@@ -152,7 +152,7 @@ static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr)
        return 0;
 
 errout_errno:
-       return nl_get_errno();
+       err = -NLE_NOMEM;
 errout:
        return err;
 }
@@ -287,7 +287,7 @@ int nfnlmsg_ct_group(struct nlmsghdr *nlh)
        }
 }
 
-struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh)
+int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result)
 {
        struct nfnl_ct *ct;
        struct nlattr *tb[CTA_MAX+1];
@@ -295,7 +295,7 @@ struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh)
 
        ct = nfnl_ct_alloc();
        if (!ct)
-               return NULL;
+               return -NLE_NOMEM;
 
        ct->ce_msgtype = nlh->nlmsg_type;
 
@@ -346,11 +346,12 @@ struct nfnl_ct *nfnlmsg_ct_parse(struct nlmsghdr *nlh)
                        goto errout;
        }
 
-       return ct;
+       *result = ct;
+       return 0;
 
 errout:
        nfnl_ct_put(ct);
-       return NULL;
+       return err;
 }
 
 static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
@@ -359,9 +360,8 @@ static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
        struct nfnl_ct *ct;
        int err;
 
-       ct = nfnlmsg_ct_parse(nlh);
-       if (ct == NULL)
-               goto errout_errno;
+       if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0)
+               goto errout;
 
        err = pp->pp_cb((struct nl_object *) ct, pp);
        if (err < 0)
@@ -372,10 +372,6 @@ static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
 errout:
        nfnl_ct_put(ct);
        return err;
-
-errout_errno:
-       err = nl_get_errno();
-       goto errout;
 }
 
 int nfnl_ct_dump_request(struct nl_handle *h)
@@ -453,31 +449,35 @@ static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct,
        return 0;
 
 nla_put_failure:
-       return -1;
+       return -NLE_MSGSIZE;
 }
 
-static struct nl_msg *nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags)
+static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags,
+                                struct nl_msg **result)
 {
        struct nl_msg *msg;
+       int err;
 
        msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags,
                                   nfnl_ct_get_family(ct), 0);
        if (msg == NULL)
-               return NULL;
+               return -NLE_NOMEM;
 
-       if (nfnl_ct_build_tuple(msg, ct, 0) < 0)
+       if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0)
                goto err_out;
 
-       return msg;
+       *result = msg;
+       return 0;
 
 err_out:
        nlmsg_free(msg);
-       return NULL;
+       return err;
 }
 
-struct nl_msg *nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags)
+int nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags,
+                             struct nl_msg **result)
 {
-       return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags);
+       return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result);
 }
 
 int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
@@ -485,9 +485,8 @@ int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
        struct nl_msg *msg;
        int err;
 
-       msg = nfnl_ct_build_add_request(ct, flags);
-       if (msg == NULL)
-               return nl_errno(ENOMEM);
+       if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0)
+               return err;
 
        err = nl_send_auto_complete(h, msg);
        nlmsg_free(msg);
@@ -497,9 +496,10 @@ int nfnl_ct_add(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
        return nl_wait_for_ack(h);
 }
 
-struct nl_msg *nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags)
+int nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags,
+                                struct nl_msg **result)
 {
-       return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags);
+       return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result);
 }
 
 int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
@@ -507,9 +507,8 @@ int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
        struct nl_msg *msg;
        int err;
 
-       msg = nfnl_ct_build_delete_request(ct, flags);
-       if (msg == NULL)
-               return nl_errno(ENOMEM);
+       if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0)
+               return err;
 
        err = nl_send_auto_complete(h, msg);
        nlmsg_free(msg);
@@ -519,9 +518,10 @@ int nfnl_ct_del(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
        return nl_wait_for_ack(h);
 }
 
-struct nl_msg *nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags)
+int nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags,
+                               struct nl_msg **result)
 {
-       return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags);
+       return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result);
 }
 
 int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
@@ -529,9 +529,8 @@ int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
        struct nl_msg *msg;
        int err;
 
-       msg = nfnl_ct_build_query_request(ct, flags);
-       if (msg == NULL)
-               return nl_errno(ENOMEM);
+       if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0)
+               return err;
 
        err = nl_send_auto_complete(h, msg);
        nlmsg_free(msg);
@@ -549,28 +548,16 @@ int nfnl_ct_query(struct nl_handle *h, const struct nfnl_ct *ct, int flags)
 /**
  * Build a conntrack cache holding all conntrack currently in the kernel
  * @arg handle         netlink handle
+ * @arg result         Pointer to store resulting cache.
  *
  * Allocates a new cache, initializes it properly and updates it to
  * contain all conntracks currently in the kernel.
  *
- * @note The caller is responsible for destroying and freeing the
- *       cache after using it.
- * @return The cache or NULL if an error has occured.
+ * @return 0 on success or a negative error code.
  */
-struct nl_cache *nfnl_ct_alloc_cache(struct nl_handle *handle)
+int nfnl_ct_alloc_cache(struct nl_handle *sock, struct nl_cache **result)
 {
-       struct nl_cache *cache;
-
-       cache = nl_cache_alloc(&nfnl_ct_ops);
-       if (!cache)
-               return NULL;
-
-       if (handle && nl_cache_refill(handle, cache) < 0) {
-               free(cache);
-               return NULL;
-       }
-
-       return cache;
+       return nl_cache_alloc_and_fill(&nfnl_ct_ops, sock, result);
 }
 
 /** @} */
index 96e5db60b61bbc42e17303372c67a87313de4213..1625efcb8bbefbd641ee5311a910119ebb46fe04 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
  * Copyright (c) 2007 Secure Computing Corporation
  */
@@ -75,34 +75,32 @@ static int ct_clone(struct nl_object *_dst, struct nl_object *_src)
        if (src->ct_orig.src) {
                addr = nl_addr_clone(src->ct_orig.src);
                if (!addr)
-                       goto errout;
+                       return -NLE_NOMEM;
                dst->ct_orig.src = addr;
        }
 
        if (src->ct_orig.dst) {
                addr = nl_addr_clone(src->ct_orig.dst);
                if (!addr)
-                       goto errout;
+                       return -NLE_NOMEM;
                dst->ct_orig.dst = addr;
        }
 
        if (src->ct_repl.src) {
                addr = nl_addr_clone(src->ct_repl.src);
                if (!addr)
-                       goto errout;
+                       return -NLE_NOMEM;
                dst->ct_repl.src = addr;
        }
 
        if (src->ct_repl.dst) {
                addr = nl_addr_clone(src->ct_repl.dst);
                if (!addr)
-                       goto errout;
+                       return -NLE_NOMEM;
                dst->ct_repl.dst = addr;
        }
 
        return 0;
-errout:
-       return nl_get_errno();
 }
 
 static void ct_dump_dir(struct nfnl_ct *ct, int repl,
@@ -458,7 +456,7 @@ static int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr,
 {
        if (ct->ce_mask & CT_ATTR_FAMILY) {
                if (addr->a_family != ct->ct_family)
-                       return nl_error(EINVAL, "Address family mismatch");
+                       return -NLE_AF_MISMATCH;
        } else
                nfnl_ct_set_family(ct, addr->a_family);
 
index 41a131cc6c671bbc7aa95a291e51c29997c02e3e..0cfbc87fe6a4eb4056f76e001fae382d35c08efe 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
  * Copyright (c) 2007 Secure Computing Corporation
  */
@@ -31,8 +31,8 @@
  * @{
  */
 
-static struct nl_msg *build_log_cmd_request(uint8_t family, uint16_t queuenum,
-                                           uint8_t command)
+static int build_log_cmd_request(uint8_t family, uint16_t queuenum,
+                                uint8_t command, struct nl_msg **result)
 {
        struct nl_msg *msg;
        struct nfulnl_msg_config_cmd cmd;
@@ -40,17 +40,18 @@ static struct nl_msg *build_log_cmd_request(uint8_t family, uint16_t queuenum,
        msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
                                   family, queuenum);
        if (msg == NULL)
-               return NULL;
+               return -NLE_NOMEM;
 
        cmd.command = command;
        if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
                goto nla_put_failure;
 
-       return msg;
+       *result = msg;
+       return 0;
 
 nla_put_failure:
        nlmsg_free(msg);
-       return NULL;
+       return -NLE_MSGSIZE;
 }
 
 static int send_log_request(struct nl_handle *handle, struct nl_msg *msg)
@@ -65,49 +66,50 @@ static int send_log_request(struct nl_handle *handle, struct nl_msg *msg)
        return nl_wait_for_ack(handle);
 }
 
-struct nl_msg *nfnl_log_build_pf_bind(uint8_t pf)
+int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result)
 {
-       return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND);
+       return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result);
 }
 
 int nfnl_log_pf_bind(struct nl_handle *nlh, uint8_t pf)
 {
        struct nl_msg *msg;
+       int err;
 
-       msg = nfnl_log_build_pf_bind(pf);
-       if (!msg)
-               return nl_get_errno();
+       if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0)
+               return err;
 
        return send_log_request(nlh, msg);
 }
 
-struct nl_msg *nfnl_log_build_pf_unbind(uint8_t pf)
+int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result)
 {
-       return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND);
+       return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result);
 }
 
 int nfnl_log_pf_unbind(struct nl_handle *nlh, uint8_t pf)
 {
        struct nl_msg *msg;
+       int err;
 
-       msg = nfnl_log_build_pf_unbind(pf);
-       if (!msg)
-               return nl_get_errno();
+       if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0)
+               return err;
 
        return send_log_request(nlh, msg);
 }
 
-static struct nl_msg *nfnl_log_build_request(const struct nfnl_log *log)
+static int nfnl_log_build_request(const struct nfnl_log *log,
+                                 struct nl_msg **result)
 {
        struct nl_msg *msg;
 
        if (!nfnl_log_test_group(log))
-               return NULL;
+               return -NLE_MISSING_ATTR;
 
        msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
                                   0, nfnl_log_get_group(log));
        if (msg == NULL)
-               return NULL;
+               return -NLE_NOMEM;
 
        /* This sucks. The nfnetlink_log interface always expects both
         * parameters to be present. Needs to be done properly.
@@ -148,77 +150,80 @@ static struct nl_msg *nfnl_log_build_request(const struct nfnl_log *log)
                        htonl(nfnl_log_get_queue_threshold(log))) < 0)
                goto nla_put_failure;
 
-       return msg;
+       *result = msg;
+       return 0;
 
 nla_put_failure:
        nlmsg_free(msg);
-       return NULL;
+       return -NLE_MSGSIZE;
 }
 
-struct nl_msg *nfnl_log_build_create_request(const struct nfnl_log *log)
+int nfnl_log_build_create_request(const struct nfnl_log *log,
+                                 struct nl_msg **result)
 {
-       struct nl_msg *msg;
        struct nfulnl_msg_config_cmd cmd;
+       int err;
 
-       msg = nfnl_log_build_request(log);
-       if (msg == NULL)
-               return NULL;
+       if ((err = nfnl_log_build_request(log, result)) < 0)
+               return err;
 
        cmd.command = NFULNL_CFG_CMD_BIND;
 
-       if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
+       if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
                goto nla_put_failure;
 
-       return msg;
+       return 0;
 
 nla_put_failure:
-       nlmsg_free(msg);
-       return NULL;
+       nlmsg_free(*result);
+       return -NLE_MSGSIZE;
 }
 
 int nfnl_log_create(struct nl_handle *nlh, const struct nfnl_log *log)
 {
        struct nl_msg *msg;
+       int err;
 
-       msg = nfnl_log_build_create_request(log);
-       if (msg == NULL)
-               return nl_errno(ENOMEM);
+       if ((err = nfnl_log_build_create_request(log, &msg)) < 0)
+               return err;
 
        return send_log_request(nlh, msg);
 }
 
-struct nl_msg *nfnl_log_build_change_request(const struct nfnl_log *log)
+int nfnl_log_build_change_request(const struct nfnl_log *log,
+                                 struct nl_msg **result)
 {
-       return nfnl_log_build_request(log);
+       return nfnl_log_build_request(log, result);
 }
 
 int nfnl_log_change(struct nl_handle *nlh, const struct nfnl_log *log)
 {
        struct nl_msg *msg;
+       int err;
 
-       msg = nfnl_log_build_change_request(log);
-       if (msg == NULL)
-               return nl_errno(ENOMEM);
+       if ((err = nfnl_log_build_change_request(log, &msg)) < 0)
+               return err;
 
        return send_log_request(nlh, msg);
 }
 
-struct nl_msg *nfnl_log_build_delete_request(const struct nfnl_log *log)
+int nfnl_log_build_delete_request(const struct nfnl_log *log,
+                                 struct nl_msg **result)
 {
        if (!nfnl_log_test_group(log))
-               return NULL;
+               return -NLE_MISSING_ATTR;
 
        return build_log_cmd_request(0, nfnl_log_get_group(log),
-                                    NFULNL_CFG_CMD_UNBIND);
+                                    NFULNL_CFG_CMD_UNBIND, result);
 }
 
 int nfnl_log_delete(struct nl_handle *nlh, const struct nfnl_log *log)
 {
        struct nl_msg *msg;
+       int err;
 
-       msg = nfnl_log_build_delete_request(log);
-       if (msg == NULL)
-               return nl_errno(ENOMEM);
+       if ((err = nfnl_log_build_delete_request(log, &msg)) < 0)
+               return err;
 
        return send_log_request(nlh, msg);
 }
index 5243338769a3db756961d8ed6b169db219adbb23..33de482535a3959f5cebea70e754b39f9c4b7f20 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
  * Copyright (c) 2007 Secure Computing Corporation
  * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
@@ -62,7 +62,7 @@ static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
        [NFULA_SEQ_GLOBAL]              = { .type = NLA_U32 },
 };
 
-struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh)
+int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
 {
        struct nfnl_log_msg *msg;
        struct nlattr *tb[NFULA_MAX+1];
@@ -71,7 +71,7 @@ struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh)
 
        msg = nfnl_log_msg_alloc();
        if (!msg)
-               return NULL;
+               return -NLE_NOMEM;
 
        msg->ce_msgtype = nlh->nlmsg_type;
 
@@ -158,11 +158,12 @@ struct nfnl_log_msg *nfnlmsg_log_msg_parse(struct nlmsghdr *nlh)
        if (attr)
                nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr)));
 
-       return msg;
+       *result = msg;
+       return 0;
 
 errout:
        nfnl_log_msg_put(msg);
-       return NULL;
+       return err;
 }
 
 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
@@ -171,9 +172,8 @@ static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
        struct nfnl_log_msg *msg;
        int err;
 
-       msg = nfnlmsg_log_msg_parse(nlh);
-       if (log == NULL)
-               goto errout_errno;
+       if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0)
+               goto errout;
 
        err = pp->pp_cb((struct nl_object *) msg, pp);
        if (err < 0)
@@ -184,10 +184,6 @@ static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
 errout:
        nfnl_log_msg_put(msg);
        return err;
-
-errout_errno:
-       err = nl_get_errno();
-       goto errout;
 }
 
 /** @} */
index ee850908c6aeed4c22e0bd805bdc9d16e988a54b..b2cd9ef3de15710e14b279e92c9b3fdc48f2e64a 100644 (file)
@@ -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;
index 554e234f68ae89b805cb1d19edb7bee8f43b72f8..2441f6968f2e75107820b33cfb14e5e71582d2de 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
  * Copyright (c) 2007 Secure Computing Corporation
  */
@@ -178,7 +178,7 @@ static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id)
 
        nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO);
        if (nfg == NULL)
-               return nl_errno(ENOMEM);
+               return -NLE_NOMEM;
 
        nfg->nfgen_family = family;
        nfg->version = NFNETLINK_V0;
@@ -236,7 +236,7 @@ int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq,
 
        nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags);
        if (nlh == NULL)
-               return nl_get_errno();
+               return -NLE_MSGSIZE;
 
        return nfnlmsg_append(msg, family, res_id);
 }
index 2bd719a0a721bf8d7855ba7a3e9efdd86d084071..7f31c666dd93b08d6a81eaf75a4fd63585210886 100644 (file)
@@ -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), &params) < 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);
 }
index a097b684b24434876d60b6eec35bc971ec9c5982..6d6ca739e8e7881dc40c2b5edece29d7af2dc600 100644 (file)
@@ -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);
index 476d920a9a25c422f2873d863b0241ea5799af51..5796c3471206379e698065b37ded3f642d197ad4 100644 (file)
@@ -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;
index 9b6fb9b65a76e3e5de1789a706083f409fbc29ef..ba5262b4b51ca729868ff165efd694ac23976ed1 100644 (file)
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -195,7 +195,7 @@ 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);
index 72e4ba4a6ba8886ae88d4c1f1d4130f02e5a7d73..3771af9d804afeea5d2a7c5a9a8d253179da7223 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -47,10 +47,8 @@ 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 {
index a4a9acf8f488033b928a00406386251945f1993b..0d86293c131355df6e4b684ea63a1d695da6ce26 100644 (file)
@@ -6,8 +6,8 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
- *                         Baruch Even <baruch@ev-en.org>,
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2006 Baruch Even <baruch@ev-en.org>,
  *                         Mediatrix Telecom, inc. <ericb@mediatrix.com>
  */
 
@@ -154,27 +154,25 @@ 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;
 
index 7966b09a9da954ca22df7555ca357a71c6e2c689..9a1784fa7159efe86149a167316457675ca2e2b6 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -36,7 +36,7 @@ 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;
 }
 
 /** @} */
index c8144867365fe239093ce9f70c70d9512e701dad..374cf0f871d1cd47d0bddfd440a31849ce43dce4 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -43,7 +43,7 @@ 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;
 
index df6d3ae6e3cf06e86cbaded359d5feecdca1990c..8008bc49cc5b39d9761d72a8cf608d6d93f949de 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -44,7 +44,7 @@ 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;
 }
 
 /** @} */
index 7ca76191cfc891af6c7b91f23ae9c14968b259bb..61972de426b81e9ddb82c656cf038b368eb686fd 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2006 Petr Gotthard <petr.gotthard@siemens.com>
  * Copyright (c) 2006 Siemens AG Oesterreich
  */
@@ -63,7 +63,7 @@ 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;
index 596e63fb48a6ddc8465dc885d811ece0057ef458..1f881d34698dc967e32388a5d2a4419c3a93e331 100644 (file)
@@ -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),
index f5a083aeb74ac79bc73f58f151e8160bb7495759..73f05dfbf85109d96fd02bb725d60fe68b68c708 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -44,7 +44,7 @@ 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;
 
index 13d3e93ec5c05de37db7a3ad8ae159df2547175b..cd8cd8a186521f39e1cf7f84adfe375445a6ae79 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -215,21 +215,19 @@ 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);
index afe00b11891504f1bb17f2e6b3084b0a9e2b2db7..a0e7679f89531c405f230640da7a9d408e472496 100644 (file)
@@ -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);
 
index c148dcac5137b6ad7b364dd77e8b88166d5700df..ea5699f4968beb160f84e897acee8c1cff93b7e8 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2007 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -73,7 +73,7 @@ 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;
index fa1dc59f1e9553846b0d85fba80fcc51b96ea889..b3c8e5e50fa91660326c4b0e6a5fc48cc994697d 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -187,15 +187,13 @@ 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;
index 3191b5b1397eefb706f64fd075871a8b87a87fe5..6010da004084267c35fe1af05b2e23458d2318cf 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -129,7 +129,7 @@ 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);
index 2db6d9081b4dfc9fad7ee5edc9107fe06c49c6e9..e5348b0afc38d01f91ac72f1b2c3df9034423276 100644 (file)
@@ -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);
 
index bc89663d96841b5c74ca370aeb9d6d4342546df3..8b2de2fce3cd842e44656e3590e4a3ae8b572cf5 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -98,13 +98,13 @@ static 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);
 }
 
 /**
index ef4d07a2d15ad193d17e5d31a4cc18e19c694061..089f21230d469cb74f1b0d0b4a27f48c2f1b4b76 100644 (file)
@@ -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;
 
index 260d3e282ae1d03972277b7896ba3a94fb2eef6f..823d6954d424ef5c5f0939b5525b854f53122476 100644 (file)
@@ -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);
index 200f56159066665819fd5090006e1c2654ec2213..2be6d62ac7f664357dc6006ee4952612a62db8e2 100644 (file)
@@ -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 */
index 04938189e24451962ecc503405fbf31a0ccb7342..8684cf2838a726f4ae963a2e30ff64766bb3a517 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -60,15 +60,13 @@ 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)
index 9808509931b9404c1f415f3150b0769bb2e258aa..50fb7b2e1374834bb06780a592e5735817f255d6 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 #include <netlink-local.h>
@@ -99,7 +99,7 @@ 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;
 }
index 5ba6b928ee045db4978ad3b7539caf21e4145922..b0787a941dc18a6827c45698826d02f603175ce7 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -70,7 +70,7 @@ 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;
 }
 
 /** @} */
index 4f8d202e285b207411a9e84133ce7fa9f9253cfa..a8953f94c4d592ec3acb187d32d7d056635d3fad 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -60,11 +60,11 @@ 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;
 }
 
 /** @} */
index cb9eca77d1364631b05c531c0ddaae67a271a83f..34a3d14be331225684fbd3818ab730e7b0d75af2 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -69,11 +69,11 @@ 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;
                }               
index 4e3d6244c813287cbea839d7c5ebdfbaa7f4469a..cd5526cb2a3dc91dc1dcf4e813db9314ec226099 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -58,11 +58,11 @@ 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;
-       }
 }
 
 /** @} */
index a31c358758369a54b09b065875a10a5bdb4d2c15..40481de86454f77ad50ff757a64ff5cbf6c977bf 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -66,11 +66,11 @@ 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;
 }
 
 /** @} */
index d530c0f8934386f44b0b0e305d62be19973604d9..eaac58b27fcd88f6b0224f99c171dfca31c8aaa5 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -61,11 +61,11 @@ 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;
 }
 
 /** @} */
index 8dd5e0aebf86be0905ba320b3c098824b578c4d9..a23c33800c6dfe71aa6e135182b4650d4201d954 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -64,7 +64,7 @@ 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)
index 1351fa21b1cacc537629fdc136f9a45b0a5acf68..1114eac804a028dbf49c83e43f242fc632657533 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -66,7 +66,7 @@ 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;
 }
index aae8f5434a6888aacf6a78b762f6034f51ea6bab..088cd100dee8035681d0974ba51e52223f03040d 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -166,10 +166,8 @@ 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;
 }
index db11fb8cecba9611587faf42b9884b755117b348..5c4c47698dc15d24f7a17bd4d2365f749927457c 100644 (file)
@@ -6,7 +6,7 @@
  *     License as published by the Free Software Foundation version 2.1
  *     of the License.
  *
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  */
 
 /**
@@ -41,48 +41,6 @@ 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
  * @{