mirror of
https://gitee.com/openharmony/third_party_libnl
synced 2024-11-24 02:29:50 +00:00
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:
parent
85f932552e
commit
8a3efffa5b
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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
59
include/netlink/errno.h
Normal 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
|
@ -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 *);
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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>
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 *,
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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 **);
|
||||
|
73
lib/addr.c
73
lib/addr.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -140,11 +140,11 @@ 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);
|
||||
|
16
lib/attr.c
16
lib/attr.c
@ -267,7 +267,7 @@
|
||||
* return 0;
|
||||
*
|
||||
* nla_put_failure:
|
||||
* return -ENOMEM;
|
||||
* return -NLE_NOMEM;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
@ -544,18 +544,18 @@ static int validate_nla(struct nlattr *nla, int maxtype,
|
||||
minlen = nla_attr_minlen[pt->type];
|
||||
|
||||
if (pt->type == NLA_FLAG && nla_len(nla) > 0)
|
||||
return nl_errno(ERANGE);
|
||||
return -NLE_RANGE;
|
||||
|
||||
if (nla_len(nla) < minlen)
|
||||
return nl_errno(ERANGE);
|
||||
return -NLE_RANGE;
|
||||
|
||||
if (pt->maxlen && nla_len(nla) > pt->maxlen)
|
||||
return nl_errno(ERANGE);
|
||||
return -NLE_RANGE;
|
||||
|
||||
if (pt->type == NLA_STRING) {
|
||||
char *data = nla_data(nla);
|
||||
if (data[nla_len(nla) - 1] != '\0')
|
||||
return nl_errno(EINVAL);
|
||||
return -NLE_INVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -802,10 +802,8 @@ struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
|
||||
|
||||
tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
|
||||
|
||||
if ((tlen + msg->nm_nlh->nlmsg_len) > msg->nm_size) {
|
||||
nl_errno(ENOBUFS);
|
||||
if ((tlen + msg->nm_nlh->nlmsg_len) > msg->nm_size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
|
||||
nla->nla_type = attrtype;
|
||||
@ -842,7 +840,7 @@ int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
|
||||
|
||||
nla = nla_reserve(msg, attrtype, datalen);
|
||||
if (!nla)
|
||||
return nl_errno(ENOMEM);
|
||||
return -NLE_NOMEM;
|
||||
|
||||
memcpy(nla_data(nla), data, datalen);
|
||||
NL_DBG(2, "msg %p: Wrote %d bytes at offset +%td for attr %d\n",
|
||||
|
67
lib/cache.c
67
lib/cache.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -175,10 +175,8 @@ struct nl_cache *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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
106
lib/error.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
20
lib/msg.c
20
lib/msg.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -320,7 +320,7 @@ int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
|
||||
int maxtype, struct nla_policy *policy)
|
||||
{
|
||||
if (!nlmsg_valid_hdr(nlh, hdrlen))
|
||||
return nl_errno(EINVAL);
|
||||
return -NLE_MSG_TOOSHORT;
|
||||
|
||||
return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
|
||||
nlmsg_attrlen(nlh, hdrlen), policy);
|
||||
@ -351,7 +351,7 @@ int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
|
||||
struct nla_policy *policy)
|
||||
{
|
||||
if (!nlmsg_valid_hdr(nlh, hdrlen))
|
||||
return nl_errno(EINVAL);
|
||||
return -NLE_MSG_TOOSHORT;
|
||||
|
||||
return nla_validate(nlmsg_attrdata(nlh, hdrlen),
|
||||
nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
|
||||
@ -387,7 +387,6 @@ static struct nl_msg *__nlmsg_alloc(size_t len)
|
||||
return nm;
|
||||
errout:
|
||||
free(nm);
|
||||
nl_errno(ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -519,10 +518,8 @@ void *nlmsg_reserve(struct nl_msg *n, size_t len, int pad)
|
||||
|
||||
tlen = pad ? ((len + (pad - 1)) & ~(pad - 1)) : len;
|
||||
|
||||
if ((tlen + nlmsg_len) > n->nm_size) {
|
||||
nl_errno(ENOBUFS);
|
||||
if ((tlen + nlmsg_len) > n->nm_size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf += nlmsg_len;
|
||||
n->nm_nlh->nlmsg_len += tlen;
|
||||
@ -554,7 +551,7 @@ int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
|
||||
|
||||
tmp = nlmsg_reserve(n, len, pad);
|
||||
if (tmp == NULL)
|
||||
return nl_errno(ENOMEM);
|
||||
return -NLE_NOMEM;
|
||||
|
||||
memcpy(tmp, data, len);
|
||||
NL_DBG(2, "msg %p: Appended %zu bytes with padding %d\n", n, len, pad);
|
||||
@ -581,11 +578,11 @@ int nlmsg_expand(struct nl_msg *n, size_t newlen)
|
||||
void *tmp;
|
||||
|
||||
if (newlen <= n->nm_size)
|
||||
return nl_errno(EINVAL);
|
||||
return -NLE_INVAL;
|
||||
|
||||
tmp = realloc(n->nm_nlh, newlen);
|
||||
if (tmp == NULL)
|
||||
return nl_errno(ENOMEM);
|
||||
return -NLE_NOMEM;
|
||||
|
||||
n->nm_nlh = tmp;
|
||||
n->nm_size = newlen;
|
||||
@ -823,8 +820,7 @@ int nl_msg_parse(struct nl_msg *msg, void (*cb)(struct nl_object *, void *),
|
||||
ops = nl_cache_ops_associate(nlmsg_get_proto(msg),
|
||||
nlmsg_hdr(msg)->nlmsg_type);
|
||||
if (ops == NULL)
|
||||
return nl_error(ENOENT, "Unknown message type %d",
|
||||
nlmsg_hdr(msg)->nlmsg_type);
|
||||
return -NLE_MSGTYPE_NOSUPPORT;
|
||||
p.pp_arg = &x;
|
||||
|
||||
return nl_cache_parse(ops, NULL, nlmsg_hdr(msg), &p);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ static int send_queue_request(struct nl_handle *handle, struct nl_msg *msg)
|
||||
* @{
|
||||
*/
|
||||
|
||||
static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum,
|
||||
uint8_t command)
|
||||
static int build_queue_cmd_request(uint8_t family, uint16_t queuenum,
|
||||
uint8_t command, struct nl_msg **result)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
struct nfqnl_msg_config_cmd cmd;
|
||||
@ -50,7 +50,7 @@ static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum,
|
||||
msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0,
|
||||
family, queuenum);
|
||||
if (msg == NULL)
|
||||
return NULL;
|
||||
return -NLE_NOMEM;
|
||||
|
||||
cmd.pf = htons(family);
|
||||
cmd._pad = 0;
|
||||
@ -58,56 +58,58 @@ static struct nl_msg *build_queue_cmd_request(uint8_t family, uint16_t queuenum,
|
||||
if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
return msg;
|
||||
*result = msg;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(msg);
|
||||
return NULL;
|
||||
return -NLE_MSGSIZE;
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_queue_build_pf_bind(uint8_t pf)
|
||||
int nfnl_queue_build_pf_bind(uint8_t pf, struct nl_msg **result)
|
||||
{
|
||||
return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND);
|
||||
return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND, result);
|
||||
}
|
||||
|
||||
int nfnl_queue_pf_bind(struct nl_handle *nlh, uint8_t pf)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
msg = nfnl_queue_build_pf_bind(pf);
|
||||
if (!msg)
|
||||
return nl_get_errno();
|
||||
if ((err = nfnl_queue_build_pf_bind(pf, &msg)) < 0)
|
||||
return err;
|
||||
|
||||
return send_queue_request(nlh, msg);
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_queue_build_pf_unbind(uint8_t pf)
|
||||
int nfnl_queue_build_pf_unbind(uint8_t pf, struct nl_msg **result)
|
||||
{
|
||||
return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND);
|
||||
return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND, result);
|
||||
}
|
||||
|
||||
int nfnl_queue_pf_unbind(struct nl_handle *nlh, uint8_t pf)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
msg = nfnl_queue_build_pf_unbind(pf);
|
||||
if (!msg)
|
||||
return nl_get_errno();
|
||||
if ((err = nfnl_queue_build_pf_unbind(pf, &msg)) < 0)
|
||||
return err;
|
||||
|
||||
return send_queue_request(nlh, msg);
|
||||
}
|
||||
|
||||
static struct nl_msg *nfnl_queue_build_request(const struct nfnl_queue *queue)
|
||||
static int nfnl_queue_build_request(const struct nfnl_queue *queue,
|
||||
struct nl_msg **result)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
|
||||
if (!nfnl_queue_test_group(queue))
|
||||
return NULL;
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0,
|
||||
0, nfnl_queue_get_group(queue));
|
||||
if (msg == NULL)
|
||||
return NULL;
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (nfnl_queue_test_maxlen(queue) &&
|
||||
nla_put_u32(msg, NFQA_CFG_QUEUE_MAXLEN,
|
||||
@ -136,79 +138,82 @@ static struct nl_msg *nfnl_queue_build_request(const struct nfnl_queue *queue)
|
||||
if (nla_put(msg, NFQA_CFG_PARAMS, sizeof(params), ¶ms) < 0)
|
||||
goto nla_put_failure;
|
||||
}
|
||||
return msg;
|
||||
|
||||
*result = msg;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(msg);
|
||||
return NULL;
|
||||
return -NLE_MSGSIZE;
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_queue_build_create_request(const struct nfnl_queue *queue)
|
||||
int nfnl_queue_build_create_request(const struct nfnl_queue *queue,
|
||||
struct nl_msg **result)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
struct nfqnl_msg_config_cmd cmd;
|
||||
int err;
|
||||
|
||||
msg = nfnl_queue_build_request(queue);
|
||||
if (msg == NULL)
|
||||
return NULL;
|
||||
if ((err = nfnl_queue_build_request(queue, result)) < 0)
|
||||
return err;
|
||||
|
||||
cmd.pf = 0;
|
||||
cmd._pad = 0;
|
||||
cmd.command = NFQNL_CFG_CMD_BIND;
|
||||
|
||||
if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0)
|
||||
goto nla_put_failure;
|
||||
NLA_PUT(*result, NFQA_CFG_CMD, sizeof(cmd), &cmd);
|
||||
|
||||
return msg;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(msg);
|
||||
return NULL;
|
||||
nlmsg_free(*result);
|
||||
return -NLE_MSGSIZE;
|
||||
}
|
||||
|
||||
int nfnl_queue_create(struct nl_handle *nlh, const struct nfnl_queue *queue)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
msg = nfnl_queue_build_create_request(queue);
|
||||
if (msg == NULL)
|
||||
return nl_errno(ENOMEM);
|
||||
if ((err = nfnl_queue_build_create_request(queue, &msg)) < 0)
|
||||
return err;
|
||||
|
||||
return send_queue_request(nlh, msg);
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_queue_build_change_request(const struct nfnl_queue *queue)
|
||||
int nfnl_queue_build_change_request(const struct nfnl_queue *queue,
|
||||
struct nl_msg **result)
|
||||
{
|
||||
return nfnl_queue_build_request(queue);
|
||||
return nfnl_queue_build_request(queue, result);
|
||||
}
|
||||
|
||||
int nfnl_queue_change(struct nl_handle *nlh, const struct nfnl_queue *queue)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
msg = nfnl_queue_build_change_request(queue);
|
||||
if (msg == NULL)
|
||||
return nl_errno(ENOMEM);
|
||||
if ((err = nfnl_queue_build_change_request(queue, &msg)) < 0)
|
||||
return err;
|
||||
|
||||
return send_queue_request(nlh, msg);
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_queue_build_delete_request(const struct nfnl_queue *queue)
|
||||
int nfnl_queue_build_delete_request(const struct nfnl_queue *queue,
|
||||
struct nl_msg **result)
|
||||
{
|
||||
if (!nfnl_queue_test_group(queue))
|
||||
return NULL;
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
return build_queue_cmd_request(0, nfnl_queue_get_group(queue),
|
||||
NFQNL_CFG_CMD_UNBIND);
|
||||
NFQNL_CFG_CMD_UNBIND, result);
|
||||
}
|
||||
|
||||
int nfnl_queue_delete(struct nl_handle *nlh, const struct nfnl_queue *queue)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
msg = nfnl_queue_build_delete_request(queue);
|
||||
if (msg == NULL)
|
||||
return nl_errno(ENOMEM);
|
||||
if ((err = nfnl_queue_build_delete_request(queue, &msg)) < 0)
|
||||
return err;
|
||||
|
||||
return send_queue_request(nlh, msg);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
40
lib/nl.c
40
lib/nl.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -195,7 +195,7 @@ int nl_connect(struct nl_handle *handle, int protocol)
|
||||
|
||||
handle->h_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
|
||||
if (handle->h_fd < 0) {
|
||||
err = nl_error(1, "socket(AF_NETLINK, ...) failed");
|
||||
err = -nl_syserr2nlerr(errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ int nl_connect(struct nl_handle *handle, int protocol)
|
||||
err = bind(handle->h_fd, (struct sockaddr*) &handle->h_local,
|
||||
sizeof(handle->h_local));
|
||||
if (err < 0) {
|
||||
err = nl_error(1, "bind() failed");
|
||||
err = -nl_syserr2nlerr(errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@ -216,17 +216,17 @@ int nl_connect(struct nl_handle *handle, int protocol)
|
||||
err = getsockname(handle->h_fd, (struct sockaddr *) &handle->h_local,
|
||||
&addrlen);
|
||||
if (err < 0) {
|
||||
err = nl_error(1, "getsockname failed");
|
||||
err = -nl_syserr2nlerr(errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (addrlen != sizeof(handle->h_local)) {
|
||||
err = nl_error(EADDRNOTAVAIL, "Invalid address length");
|
||||
err = -NLE_NOADDR;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (handle->h_local.nl_family != AF_NETLINK) {
|
||||
err = nl_error(EPFNOSUPPORT, "Address format not supported");
|
||||
err = -NLE_AF_NOSUPPORT;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ int nl_sendto(struct nl_handle *handle, void *buf, size_t size)
|
||||
ret = sendto(handle->h_fd, buf, size, 0, (struct sockaddr *)
|
||||
&handle->h_peer, sizeof(handle->h_peer));
|
||||
if (ret < 0)
|
||||
return nl_errno(errno);
|
||||
return -nl_syserr2nlerr(errno);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -309,7 +309,7 @@ int nl_sendmsg(struct nl_handle *handle, struct nl_msg *msg, struct msghdr *hdr)
|
||||
|
||||
ret = sendmsg(handle->h_fd, hdr, 0);
|
||||
if (ret < 0)
|
||||
return nl_errno(errno);
|
||||
return -nl_syserr2nlerr(errno);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -415,7 +415,7 @@ int nl_send_simple(struct nl_handle *handle, int type, int flags, void *buf,
|
||||
|
||||
msg = nlmsg_alloc_simple(type, flags);
|
||||
if (!msg)
|
||||
return nl_errno(ENOMEM);
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (buf && size) {
|
||||
err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
|
||||
@ -503,7 +503,7 @@ retry:
|
||||
} else {
|
||||
free(msg.msg_control);
|
||||
free(*buf);
|
||||
return nl_error(errno, "recvmsg failed");
|
||||
return -nl_syserr2nlerr(errno);
|
||||
}
|
||||
}
|
||||
|
||||
@ -527,7 +527,7 @@ retry:
|
||||
if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
|
||||
free(msg.msg_control);
|
||||
free(*buf);
|
||||
return nl_error(EADDRNOTAVAIL, "socket address size mismatch");
|
||||
return -NLE_NOADDR;
|
||||
}
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
@ -611,7 +611,7 @@ continue_reading:
|
||||
free_msg = 1; /* By default, we free the message data */
|
||||
msg = nlmsg_convert(hdr);
|
||||
if (!msg) {
|
||||
err = nl_errno(ENOMEM);
|
||||
err = -NLE_NOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -634,8 +634,7 @@ continue_reading:
|
||||
if (cb->cb_set[NL_CB_INVALID])
|
||||
NL_CB_CALL(cb, NL_CB_INVALID, msg);
|
||||
else {
|
||||
err = nl_error(EINVAL,
|
||||
"Sequence number mismatch");
|
||||
err = -NLE_SEQ_MISMATCH;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -692,7 +691,7 @@ continue_reading:
|
||||
if (cb->cb_set[NL_CB_OVERRUN])
|
||||
NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
|
||||
else {
|
||||
err = nl_error(EOVERFLOW, "Overrun");
|
||||
err = -NLE_MSG_OVERFLOW;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -709,8 +708,7 @@ continue_reading:
|
||||
if (cb->cb_set[NL_CB_INVALID])
|
||||
NL_CB_CALL(cb, NL_CB_INVALID, msg);
|
||||
else {
|
||||
err = nl_error(EINVAL,
|
||||
"Truncated error message");
|
||||
err = -NLE_MSG_TRUNC;
|
||||
goto out;
|
||||
}
|
||||
} else if (e->error) {
|
||||
@ -723,13 +721,11 @@ continue_reading:
|
||||
else if (err == NL_SKIP)
|
||||
goto skip;
|
||||
else if (err == NL_STOP) {
|
||||
err = nl_error(-e->error,
|
||||
"Netlink Error");
|
||||
err = -nl_syserr2nlerr(e->error);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
err = nl_error(-e->error,
|
||||
"Netlink Error");
|
||||
err = -nl_syserr2nlerr(e->error);
|
||||
goto out;
|
||||
}
|
||||
} else if (cb->cb_set[NL_CB_ACK])
|
||||
@ -823,7 +819,7 @@ int nl_wait_for_ack(struct nl_handle *handle)
|
||||
|
||||
cb = nl_cb_clone(handle->h_cb);
|
||||
if (cb == NULL)
|
||||
return nl_get_errno();
|
||||
return -NLE_NOMEM;
|
||||
|
||||
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
|
||||
err = nl_recvmsgs(handle, cb);
|
||||
|
19
lib/object.c
19
lib/object.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -47,10 +47,8 @@ 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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
118
lib/route/rule.c
118
lib/route/rule.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -60,15 +60,13 @@ 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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
39
lib/socket.c
39
lib/socket.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -166,10 +166,8 @@ 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;
|
||||
}
|
||||
|
96
lib/utils.c
96
lib/utils.c
@ -6,7 +6,7 @@
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
|
||||
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -41,48 +41,6 @@ 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
|
||||
* @{
|
||||
|
Loading…
Reference in New Issue
Block a user