Thread-safe error handling

In order for the interface to become more thread safe, the error
handling was revised to no longer depend on a static errno and
error string buffer.

This patch converts all error paths to return a libnl specific
error code which can be translated to a error message using
nl_geterror(int error). The functions nl_error() and
nl_get_errno() are therefore obsolete.

This change required various sets of function prototypes to be
changed in order to return an error code, the most prominent
are:

    struct nl_cache *foo_alloc_cache(...);
changed to:
    int foo_alloc_cache(..., struct nl_cache **);

    struct nl_msg *foo_build_request(...);
changed to:
    int foo_build_request(..., struct nl_msg **);

    struct foo *foo_parse(...);
changed to:
    int foo_parse(..., struct foo **);

This pretty much only leaves trivial allocation functions to
still return a pointer object which can still return NULL to
signal out of memory.

This change is a serious API and ABI breaker, sorry!
This commit is contained in:
Thomas Graf 2008-05-14 17:49:44 +02:00
parent 85f932552e
commit 8a3efffa5b
79 changed files with 1503 additions and 1655 deletions

View 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);

View 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)
{

View 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 */

View 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);

59
include/netlink/errno.h Normal file
View File

@ -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

View 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 *);

View 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 *);

View 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
}

View 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
}

View 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 *);

View 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 int nfnl_queue_build_pf_bind(uint8_t, struct nl_msg **);
extern int nfnl_queue_pf_bind(struct nl_handle *, uint8_t);
extern struct nl_msg * nfnl_queue_build_pf_unbind(uint8_t);
extern int nfnl_queue_pf_unbind(struct nl_handle *, uint8_t);
extern int nfnl_queue_build_pf_unbind(uint8_t, struct nl_msg **);
extern int nfnl_queue_pf_unbind(struct nl_handle *, uint8_t);
extern struct nl_msg * nfnl_queue_build_create_request(const struct nfnl_queue *);
extern int nfnl_queue_create(struct nl_handle *,
const struct nfnl_queue *);
extern int nfnl_queue_build_create_request(const struct nfnl_queue *,
struct nl_msg **);
extern int nfnl_queue_create(struct nl_handle *,
const struct nfnl_queue *);
extern struct nl_msg * nfnl_queue_build_change_request(const struct nfnl_queue *);
extern int nfnl_queue_change(struct nl_handle *,
const struct nfnl_queue *);
extern int nfnl_queue_build_change_request(const struct nfnl_queue *,
struct nl_msg **);
extern int nfnl_queue_change(struct nl_handle *,
const struct nfnl_queue *);
extern struct nl_msg * nfnl_queue_build_delete_request(const struct nfnl_queue *);
extern int nfnl_queue_delete(struct nl_handle *,
const struct nfnl_queue *);
extern int nfnl_queue_build_delete_request(const struct nfnl_queue *,
struct nl_msg **);
extern int nfnl_queue_delete(struct nl_handle *,
const struct nfnl_queue *);
#ifdef __cplusplus
}

View 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 *);

View 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>

View 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 *);

View 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
}

View 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);

View 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);

View 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
}

View 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 *,

View 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 *);

View 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 *);
extern struct rtnl_qdisc *rtnl_qdisc_alloc(void);
extern void rtnl_qdisc_put(struct rtnl_qdisc *);
/* Cache Management */
extern struct nl_cache * rtnl_qdisc_alloc_cache(struct nl_handle *);
extern struct rtnl_qdisc * rtnl_qdisc_get(struct nl_cache *,
int, uint32_t);
extern struct rtnl_qdisc * rtnl_qdisc_get_by_parent(struct nl_cache *,
int, uint32_t);
extern int rtnl_qdisc_alloc_cache(struct nl_handle *, struct nl_cache **);
extern struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *, int, uint32_t);
extern struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *,
int, uint32_t);
/* qdisc addition */
extern struct nl_msg * rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int);
extern int rtnl_qdisc_add(struct nl_handle *, struct rtnl_qdisc *,
int);
extern int rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int,
struct nl_msg **);
extern int rtnl_qdisc_add(struct nl_handle *, struct rtnl_qdisc *, int);
/* qdisc modification */
extern struct nl_msg * rtnl_qdisc_build_change_request(struct rtnl_qdisc *,
struct rtnl_qdisc *);
extern int rtnl_qdisc_change(struct nl_handle *,
struct rtnl_qdisc *,
struct rtnl_qdisc *);
extern int rtnl_qdisc_build_change_request(struct rtnl_qdisc *,
struct rtnl_qdisc *,
struct nl_msg **);
extern int rtnl_qdisc_change(struct nl_handle *, struct rtnl_qdisc *,
struct rtnl_qdisc *);
/* qdisc deletion */
extern struct nl_msg * rtnl_qdisc_build_delete_request(struct rtnl_qdisc *);
extern int rtnl_qdisc_delete(struct nl_handle *,
struct rtnl_qdisc *);
extern int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *,
struct nl_msg **);
extern int rtnl_qdisc_delete(struct nl_handle *, struct rtnl_qdisc *);
/* attribute modifications */
extern void rtnl_qdisc_set_ifindex(struct rtnl_qdisc *, int);
extern int rtnl_qdisc_get_ifindex(struct rtnl_qdisc *);
extern void rtnl_qdisc_set_handle(struct rtnl_qdisc *, uint32_t);
extern uint32_t rtnl_qdisc_get_handle(struct rtnl_qdisc *);
extern void rtnl_qdisc_set_parent(struct rtnl_qdisc *, uint32_t);
extern uint32_t rtnl_qdisc_get_parent(struct rtnl_qdisc *);
extern void rtnl_qdisc_set_kind(struct rtnl_qdisc *, const char *);
extern char * rtnl_qdisc_get_kind(struct rtnl_qdisc *);
extern uint64_t rtnl_qdisc_get_stat(struct rtnl_qdisc *,
enum rtnl_tc_stats_id);
extern void rtnl_qdisc_set_ifindex(struct rtnl_qdisc *, int);
extern int rtnl_qdisc_get_ifindex(struct rtnl_qdisc *);
extern void rtnl_qdisc_set_handle(struct rtnl_qdisc *, uint32_t);
extern uint32_t rtnl_qdisc_get_handle(struct rtnl_qdisc *);
extern void rtnl_qdisc_set_parent(struct rtnl_qdisc *, uint32_t);
extern uint32_t rtnl_qdisc_get_parent(struct rtnl_qdisc *);
extern void rtnl_qdisc_set_kind(struct rtnl_qdisc *, const char *);
extern char * rtnl_qdisc_get_kind(struct rtnl_qdisc *);
extern uint64_t rtnl_qdisc_get_stat(struct rtnl_qdisc *, enum rtnl_tc_stats_id);
/* iterators */
extern void rtnl_qdisc_foreach_child(struct rtnl_qdisc *,
struct nl_cache *,
void (*cb)(struct nl_object *,
void *),
void *);
extern void rtnl_qdisc_foreach_child(struct rtnl_qdisc *, struct nl_cache *,
void (*cb)(struct nl_object *, void *),
void *);
extern void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *,
struct nl_cache *,
void (*cb)(struct nl_object *,
void *),
void *);
extern void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *, struct nl_cache *,
void (*cb)(struct nl_object *, void *),
void *);
/* qdisc specific options */
extern struct nl_msg * rtnl_qdisc_get_opts(struct rtnl_qdisc *);
#ifdef __cplusplus

View 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_put(struct rtnl_route *);
extern int rtnl_route_alloc_cache(struct nl_handle *, int, int,
struct nl_cache **);
extern void rtnl_route_get(struct rtnl_route *);
extern void rtnl_route_put(struct rtnl_route *);
extern void rtnl_route_get(struct rtnl_route *);
extern void rtnl_route_put(struct rtnl_route *);
extern struct rtnl_route *rtnl_route_parse(struct nlmsghdr *);
extern int rtnl_route_build_msg(struct nl_msg *,
struct rtnl_route *);
extern int rtnl_route_parse(struct nlmsghdr *, struct rtnl_route **);
extern int rtnl_route_build_msg(struct nl_msg *, struct rtnl_route *);
extern struct nl_msg *rtnl_route_build_add_request(struct rtnl_route *, int);
extern int rtnl_route_add(struct nl_handle *, struct rtnl_route *, int);
extern struct nl_msg *rtnl_route_build_del_request(struct rtnl_route *, int);
extern int rtnl_route_delete(struct nl_handle *, struct rtnl_route *, int);
extern int rtnl_route_build_add_request(struct rtnl_route *, int,
struct nl_msg **);
extern int rtnl_route_add(struct nl_handle *, struct rtnl_route *, int);
extern int rtnl_route_build_del_request(struct rtnl_route *, int,
struct nl_msg **);
extern int rtnl_route_delete(struct nl_handle *, struct rtnl_route *, int);
extern void rtnl_route_set_table(struct rtnl_route *, uint32_t);
extern uint32_t rtnl_route_get_table(struct rtnl_route *);
extern void rtnl_route_set_scope(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_scope(struct rtnl_route *);
extern void rtnl_route_set_tos(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_tos(struct rtnl_route *);
extern void rtnl_route_set_protocol(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_protocol(struct rtnl_route *);
extern void rtnl_route_set_priority(struct rtnl_route *, uint32_t);
extern uint32_t rtnl_route_get_priority(struct rtnl_route *);
extern int rtnl_route_set_family(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_family(struct rtnl_route *);
extern int rtnl_route_set_type(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_type(struct rtnl_route *);
extern void rtnl_route_set_flags(struct rtnl_route *, uint32_t);
extern void rtnl_route_unset_flags(struct rtnl_route *, uint32_t);
extern uint32_t rtnl_route_get_flags(struct rtnl_route *);
extern int rtnl_route_set_metric(struct rtnl_route *, int,
unsigned int);
extern int rtnl_route_unset_metric(struct rtnl_route *, int);
extern int rtnl_route_get_metric(struct rtnl_route *, int,
uint32_t *);
extern int rtnl_route_set_dst(struct rtnl_route *,
struct nl_addr *);
extern struct nl_addr * rtnl_route_get_dst(struct rtnl_route *);
extern int rtnl_route_set_src(struct rtnl_route *,
struct nl_addr *);
extern struct nl_addr * rtnl_route_get_src(struct rtnl_route *);
extern int rtnl_route_set_pref_src(struct rtnl_route *,
struct nl_addr *);
extern struct nl_addr * rtnl_route_get_pref_src(struct rtnl_route *);
extern void rtnl_route_set_iif(struct rtnl_route *, int);
extern int rtnl_route_get_iif(struct rtnl_route *);
extern int rtnl_route_get_src_len(struct rtnl_route *);
extern void rtnl_route_set_table(struct rtnl_route *, uint32_t);
extern uint32_t rtnl_route_get_table(struct rtnl_route *);
extern void rtnl_route_set_scope(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_scope(struct rtnl_route *);
extern void rtnl_route_set_tos(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_tos(struct rtnl_route *);
extern void rtnl_route_set_protocol(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_protocol(struct rtnl_route *);
extern void rtnl_route_set_priority(struct rtnl_route *, uint32_t);
extern uint32_t rtnl_route_get_priority(struct rtnl_route *);
extern int rtnl_route_set_family(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_family(struct rtnl_route *);
extern int rtnl_route_set_type(struct rtnl_route *, uint8_t);
extern uint8_t rtnl_route_get_type(struct rtnl_route *);
extern void rtnl_route_set_flags(struct rtnl_route *, uint32_t);
extern void rtnl_route_unset_flags(struct rtnl_route *, uint32_t);
extern uint32_t rtnl_route_get_flags(struct rtnl_route *);
extern int rtnl_route_set_metric(struct rtnl_route *, int, unsigned int);
extern int rtnl_route_unset_metric(struct rtnl_route *, int);
extern int rtnl_route_get_metric(struct rtnl_route *, int, uint32_t *);
extern int rtnl_route_set_dst(struct rtnl_route *, struct nl_addr *);
extern struct nl_addr *rtnl_route_get_dst(struct rtnl_route *);
extern int rtnl_route_set_src(struct rtnl_route *, struct nl_addr *);
extern struct nl_addr *rtnl_route_get_src(struct rtnl_route *);
extern int rtnl_route_set_pref_src(struct rtnl_route *, struct nl_addr *);
extern struct nl_addr *rtnl_route_get_pref_src(struct rtnl_route *);
extern void rtnl_route_set_iif(struct rtnl_route *, int);
extern int rtnl_route_get_iif(struct rtnl_route *);
extern int rtnl_route_get_src_len(struct rtnl_route *);
extern void rtnl_route_add_nexthop(struct rtnl_route *,
struct rtnl_nexthop *);
extern void rtnl_route_remove_nexthop(struct rtnl_route *,
struct rtnl_nexthop *);
extern struct nl_list_head * rtnl_route_get_nexthops(struct rtnl_route *);
extern int rtnl_route_get_nnexthops(struct rtnl_route *);
extern void rtnl_route_add_nexthop(struct rtnl_route *,
struct rtnl_nexthop *);
extern void rtnl_route_remove_nexthop(struct rtnl_route *,
struct rtnl_nexthop *);
extern struct nl_list_head *rtnl_route_get_nexthops(struct rtnl_route *);
extern int rtnl_route_get_nnexthops(struct rtnl_route *);
extern void rtnl_route_foreach_nexthop(struct rtnl_route *r,
extern void rtnl_route_foreach_nexthop(struct rtnl_route *r,
void (*cb)(struct rtnl_nexthop *, void *),
void *arg);
extern struct rtnl_nexthop * rtnl_route_nexthop_n(struct rtnl_route *r, int n);
extern int rtnl_route_guess_scope(struct rtnl_route *);
extern int rtnl_route_guess_scope(struct rtnl_route *);
extern char * rtnl_route_table2str(int, char *, size_t);
extern int rtnl_route_str2table(const char *);
extern int rtnl_route_read_table_names(const char *);
extern char * rtnl_route_table2str(int, char *, size_t);
extern int rtnl_route_str2table(const char *);
extern int rtnl_route_read_table_names(const char *);
extern char * rtnl_route_proto2str(int, char *, size_t);
extern int rtnl_route_str2proto(const char *);
extern int rtnl_route_read_protocol_names(const char *);
extern char * rtnl_route_proto2str(int, char *, size_t);
extern int rtnl_route_str2proto(const char *);
extern int rtnl_route_read_protocol_names(const char *);
extern char * rtnl_route_metric2str(int, char *, size_t);
extern int rtnl_route_str2metric(const char *);
extern char * rtnl_route_metric2str(int, char *, size_t);
extern int rtnl_route_str2metric(const char *);
#ifdef __cplusplus
}

View 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);

View 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 **);

View 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);

View File

@ -267,7 +267,7 @@
* return 0;
*
* nla_put_failure:
* return -ENOMEM;
* return -NLE_NOMEM;
* }
* @endcode
*
@ -544,18 +544,18 @@ static int validate_nla(struct nlattr *nla, int maxtype,
minlen = nla_attr_minlen[pt->type];
if (pt->type == NLA_FLAG && nla_len(nla) > 0)
return nl_errno(ERANGE);
return -NLE_RANGE;
if (nla_len(nla) < minlen)
return nl_errno(ERANGE);
return -NLE_RANGE;
if (pt->maxlen && nla_len(nla) > pt->maxlen)
return nl_errno(ERANGE);
return -NLE_RANGE;
if (pt->type == NLA_STRING) {
char *data = nla_data(nla);
if (data[nla_len(nla) - 1] != '\0')
return nl_errno(EINVAL);
return -NLE_INVAL;
}
return 0;
@ -802,10 +802,8 @@ struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
if ((tlen + msg->nm_nlh->nlmsg_len) > msg->nm_size) {
nl_errno(ENOBUFS);
if ((tlen + msg->nm_nlh->nlmsg_len) > msg->nm_size)
return NULL;
}
nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
nla->nla_type = attrtype;
@ -842,7 +840,7 @@ int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
nla = nla_reserve(msg, attrtype, datalen);
if (!nla)
return nl_errno(ENOMEM);
return -NLE_NOMEM;
memcpy(nla_data(nla), data, datalen);
NL_DBG(2, "msg %p: Wrote %d bytes at offset +%td for attr %d\n",

View 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;
return nl_cache_alloc(ops);
if (!(cache = nl_cache_alloc(ops)))
return -NLE_NOMEM;
*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;
}

View 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;

View 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);

View 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);

106
lib/error.c Normal file
View File

@ -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;
}
}
/** @} */

View 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);

View 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);

View 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;
}

View 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;

View 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),

View 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);

View 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;

View 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>
*/
/**
@ -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);

View 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);
}
/** @} */

View 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);

View 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);
}

View 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;
}
/** @} */

View 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;

View 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);
}

View 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);
}

View 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);

View 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;

View 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>
*/
/**
@ -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);

View 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;
return nl_object_alloc(ops->co_obj_ops);
if (!(*result = nl_object_alloc(ops->co_obj_ops)))
return -NLE_NOMEM;
return 0;
}
struct nl_derived_object {

View 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;

View 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;
}
/** @} */

View 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;

View 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;
}
/** @} */

View 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;

View 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),

View 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;

View 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);

View 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);

View 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;

View 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;

View 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;
nla_put_string(m, NDTA_NAME, old->nt_name);
if (nlmsg_append(m, &ndt, sizeof(ndt), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
NLA_PUT_STRING(m, NDTA_NAME, old->nt_name);
if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH1)
nla_put_u32(m, NDTA_THRESH1, tmpl->nt_gc_thresh1);
NLA_PUT_U32(m, NDTA_THRESH1, tmpl->nt_gc_thresh1);
if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2)
nla_put_u32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
NLA_PUT_U32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2)
nla_put_u32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
NLA_PUT_U32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
if (tmpl->ce_mask & NEIGHTBL_ATTR_GC_INTERVAL)
nla_put_u64(m, NDTA_GC_INTERVAL,
NLA_PUT_U64(m, NDTA_GC_INTERVAL,
tmpl->nt_gc_interval);
if (tmpl->ce_mask & NEIGHTBL_ATTR_PARMS) {
struct rtnl_neightbl_parms *p = &tmpl->nt_parms;
struct nl_msg *parms = nlmsg_alloc();
parms = nlmsg_alloc();
if (!parms)
goto nla_put_failure;
if (old->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX)
nla_put_u32(parms, NDTPA_IFINDEX,
NLA_PUT_U32(parms, NDTPA_IFINDEX,
old->nt_parms.ntp_ifindex);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_QUEUE_LEN)
nla_put_u32(parms, NDTPA_QUEUE_LEN, p->ntp_queue_len);
NLA_PUT_U32(parms, NDTPA_QUEUE_LEN, p->ntp_queue_len);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_APP_PROBES)
nla_put_u32(parms, NDTPA_APP_PROBES, p->ntp_app_probes);
NLA_PUT_U32(parms, NDTPA_APP_PROBES, p->ntp_app_probes);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_UCAST_PROBES)
nla_put_u32(parms, NDTPA_UCAST_PROBES,
NLA_PUT_U32(parms, NDTPA_UCAST_PROBES,
p->ntp_ucast_probes);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_MCAST_PROBES)
nla_put_u32(parms, NDTPA_MCAST_PROBES,
NLA_PUT_U32(parms, NDTPA_MCAST_PROBES,
p->ntp_mcast_probes);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_QLEN)
nla_put_u32(parms, NDTPA_PROXY_QLEN,
NLA_PUT_U32(parms, NDTPA_PROXY_QLEN,
p->ntp_proxy_qlen);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME)
nla_put_u64(parms, NDTPA_BASE_REACHABLE_TIME,
NLA_PUT_U64(parms, NDTPA_BASE_REACHABLE_TIME,
p->ntp_base_reachable_time);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_RETRANS_TIME)
nla_put_u64(parms, NDTPA_RETRANS_TIME,
NLA_PUT_U64(parms, NDTPA_RETRANS_TIME,
p->ntp_retrans_time);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_GC_STALETIME)
nla_put_u64(parms, NDTPA_GC_STALETIME,
NLA_PUT_U64(parms, NDTPA_GC_STALETIME,
p->ntp_gc_stale_time);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME)
nla_put_u64(parms, NDTPA_DELAY_PROBE_TIME,
NLA_PUT_U64(parms, NDTPA_DELAY_PROBE_TIME,
p->ntp_proxy_delay);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_ANYCAST_DELAY)
nla_put_u64(parms, NDTPA_ANYCAST_DELAY,
NLA_PUT_U64(parms, NDTPA_ANYCAST_DELAY,
p->ntp_anycast_delay);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_DELAY)
nla_put_u64(parms, NDTPA_PROXY_DELAY,
NLA_PUT_U64(parms, NDTPA_PROXY_DELAY,
p->ntp_proxy_delay);
if (p->ntp_mask & NEIGHTBLPARM_ATTR_LOCKTIME)
nla_put_u64(parms, NDTPA_LOCKTIME, p->ntp_locktime);
NLA_PUT_U64(parms, NDTPA_LOCKTIME, p->ntp_locktime);
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);

View 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);

View 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;
return -NLE_NOMEM;
tchdr.tcm_family = AF_UNSPEC,
tchdr.tcm_handle = qdisc->q_handle,
tchdr.tcm_parent = qdisc->q_parent,
tchdr.tcm_ifindex = qdisc->q_ifindex,
nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO);
tchdr.tcm_family = AF_UNSPEC;
tchdr.tcm_handle = qdisc->q_handle;
tchdr.tcm_parent = qdisc->q_parent;
tchdr.tcm_ifindex = qdisc->q_ifindex;
if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0) {
nlmsg_free(msg);
return -NLE_MSGSIZE;
}
return msg;
*result = msg;
return 0;
}
/**
@ -358,12 +357,10 @@ 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);
}
/**

View 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;

View 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);

View 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 */

View 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;
@ -439,52 +437,35 @@ void rtnl_rule_put(struct rtnl_rule *rule)
* @{
*/
/**
* Build a rule cache including all rules of the specified family currently configured in the kernel.
* @arg handle netlink handle
* @arg family address family
*
* Allocates a new rule cache, initializes it properly and updates it
* to include all rules of the specified address family currently
* configured in the kernel.
*
* @note The caller is responsible for destroying and freeing the
* cache after using it. (nl_cache_destroy_and_free())
* @return The new cache or NULL if an error occured.
*/
struct nl_cache * rtnl_rule_alloc_cache_by_family(struct nl_handle *handle,
int family)
{
struct nl_cache * cache;
cache = nl_cache_alloc(&rtnl_rule_ops);
if (cache == NULL)
return NULL;
/* XXX RULE_CACHE_FAMILY(cache) = family; */
if (handle && nl_cache_refill(handle, cache) < 0) {
free(cache);
return NULL;
}
return cache;
}
/**
* Build a rule cache including all rules currently configured in the kernel.
* @arg handle netlink handle
* @arg family Address family or AF_UNSPEC.
* @arg result Pointer to store resulting cache.
*
* Allocates a new rule cache, initializes it properly and updates it
* to include all rules currently configured in the kernel.
*
* @note The caller is responsible for destroying and freeing the
* cache after using it. (nl_cache_destroy_and_free())
* @return The new cache or NULL if an error occured.
* @return 0 on success or a negative error code.
*/
struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *handle)
int rtnl_rule_alloc_cache(struct nl_handle *sock, int family,
struct nl_cache **result)
{
return rtnl_rule_alloc_cache_by_family(handle, AF_UNSPEC);
struct nl_cache * cache;
int err;
if (!(cache = nl_cache_alloc(&rtnl_rule_ops)))
return -NLE_NOMEM;
cache->c_iarg1 = family;
if (sock && (err = nl_cache_refill(sock, cache)) < 0) {
free(cache);
return err;
}
*result = cache;
return 0;
}
/** @} */
@ -494,7 +475,8 @@ 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)

View 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;
}

View 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;
}
/** @} */

View 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;
}
/** @} */

View 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;
}

View 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;
}
}
/** @} */

View 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;
}
/** @} */

View 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;
}
/** @} */

View 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)

View 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;
}

View 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;
}

View 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
* @{