Merge branch 'master' of /repos/git/libnl
This commit is contained in:
commit
47a4c5a4c0
|
@ -66,8 +66,4 @@ nobase_include_HEADERS = \
|
|||
netlink/socket.h \
|
||||
netlink/types.h \
|
||||
netlink/utils.h \
|
||||
netlink/version.h \
|
||||
netlink-generic.h \
|
||||
netlink-local.h \
|
||||
netlink-tc.h \
|
||||
netlink-types.h
|
||||
netlink/version.h
|
||||
|
|
|
@ -93,7 +93,9 @@ extern unsigned int nfnl_queue_msg_get_verdict(const struct nfnl_queue_msg *);
|
|||
extern struct nl_msg * nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *);
|
||||
extern int nfnl_queue_msg_send_verdict(struct nl_sock *,
|
||||
const struct nfnl_queue_msg *);
|
||||
|
||||
extern int nfnl_queue_msg_send_verdict_payload(struct nl_sock *,
|
||||
const struct nfnl_queue_msg *,
|
||||
const void *, unsigned );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -51,6 +51,10 @@ extern int nl_sendto(struct nl_sock *, void *, size_t);
|
|||
extern int nl_sendmsg(struct nl_sock *, struct nl_msg *,
|
||||
struct msghdr *);
|
||||
extern int nl_send(struct nl_sock *, struct nl_msg *);
|
||||
extern int nl_send_iovec(struct nl_sock *, struct nl_msg *,
|
||||
const struct iovec *, unsigned);
|
||||
extern void nl_auto_complete(struct nl_sock *,
|
||||
struct nl_msg *);
|
||||
extern int nl_send_auto_complete(struct nl_sock *,
|
||||
struct nl_msg *);
|
||||
extern int nl_send_simple(struct nl_sock *, int, int,
|
||||
|
|
|
@ -200,6 +200,17 @@ extern "C" {
|
|||
*/
|
||||
#define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR))
|
||||
|
||||
/**
|
||||
* Return true if attribute is available in only one of both objects
|
||||
* @arg A an object
|
||||
* @arg B another object
|
||||
* @arg ATTR attribute bit
|
||||
*
|
||||
* @return True if the attribute is available in only one of both objects,
|
||||
* otherwise false is returned.
|
||||
*/
|
||||
#define AVAILABLE_MISMATCH(A, B, ATTR) (((A)->ce_mask ^ (B)->ce_mask) & (ATTR))
|
||||
|
||||
/**
|
||||
* Return true if attributes mismatch
|
||||
* @arg A an object
|
||||
|
@ -215,7 +226,8 @@ extern "C" {
|
|||
*
|
||||
* @return True if the attribute mismatch, or false if they match.
|
||||
*/
|
||||
#define ATTR_MISMATCH(A, B, ATTR, EXPR) (!AVAILABLE(A, B, ATTR) || (EXPR))
|
||||
#define ATTR_MISMATCH(A, B, ATTR, EXPR) (AVAILABLE_MISMATCH(A, B, ATTR) || \
|
||||
(AVAILABLE(A, B, ATTR) && (EXPR)))
|
||||
|
||||
/**
|
||||
* Return attribute bit if attribute does not match
|
||||
|
|
|
@ -74,6 +74,9 @@ extern struct nl_addr *rtnl_addr_get_broadcast(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_anycast(struct rtnl_addr *, struct nl_addr *);
|
||||
extern struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *);
|
||||
|
||||
extern uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *);
|
||||
extern void rtnl_addr_set_valid_lifetime(struct rtnl_addr *, uint32_t);
|
||||
extern uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *);
|
||||
|
|
10
lib/cache.c
10
lib/cache.c
|
@ -605,9 +605,15 @@ int nl_cache_resync(struct nl_sock *sk, struct nl_cache *cache,
|
|||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
nl_list_for_each_entry_safe(obj, next, &cache->c_items, ce_list)
|
||||
if (nl_object_is_marked(obj))
|
||||
nl_list_for_each_entry_safe(obj, next, &cache->c_items, ce_list) {
|
||||
if (nl_object_is_marked(obj)) {
|
||||
nl_object_get(obj);
|
||||
nl_cache_remove(obj);
|
||||
if (change_cb)
|
||||
change_cb(cache, obj, NL_ACT_DEL);
|
||||
nl_object_put(obj);
|
||||
}
|
||||
}
|
||||
|
||||
NL_DBG(1, "Finished resyncing %p <%s>\n", cache, nl_cache_name(cache));
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
|
||||
* Copyright (c) 2010 Karl Hiramoto <karl@hiramoto.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -189,6 +190,12 @@ nla_put_failure:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message verdict/mark
|
||||
* @arg nlh netlink messsage header
|
||||
* @arg msg queue msg
|
||||
* @return 0 on OK or error code
|
||||
*/
|
||||
int nfnl_queue_msg_send_verdict(struct nl_sock *nlh,
|
||||
const struct nfnl_queue_msg *msg)
|
||||
{
|
||||
|
@ -206,6 +213,51 @@ int nfnl_queue_msg_send_verdict(struct nl_sock *nlh,
|
|||
return wait_for_ack(nlh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message verdict including the payload
|
||||
* @arg nlh netlink messsage header
|
||||
* @arg msg queue msg
|
||||
* @arg payload_data packet payload data
|
||||
* @arg payload_len payload length
|
||||
* @return 0 on OK or error code
|
||||
*/
|
||||
int nfnl_queue_msg_send_verdict_payload(struct nl_sock *nlh,
|
||||
const struct nfnl_queue_msg *msg,
|
||||
const void *payload_data, unsigned payload_len)
|
||||
{
|
||||
struct nl_msg *nlmsg;
|
||||
int err;
|
||||
struct iovec iov[3];
|
||||
struct nlattr nla;
|
||||
|
||||
nlmsg = nfnl_queue_msg_build_verdict(msg);
|
||||
if (nlmsg == NULL)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
memset(iov, 0, sizeof(iov));
|
||||
|
||||
iov[0].iov_base = (void *) nlmsg_hdr(nlmsg);
|
||||
iov[0].iov_len = nlmsg_hdr(nlmsg)->nlmsg_len;
|
||||
|
||||
nla.nla_type = NFQA_PAYLOAD;
|
||||
nla.nla_len = payload_len + sizeof(nla);
|
||||
nlmsg_hdr(nlmsg)->nlmsg_len += nla.nla_len;
|
||||
|
||||
iov[1].iov_base = (void *) &nla;
|
||||
iov[1].iov_len = sizeof(nla);
|
||||
|
||||
iov[2].iov_base = (void *) payload_data;
|
||||
iov[2].iov_len = NLA_ALIGN(payload_len);
|
||||
|
||||
nl_auto_complete(nlh, nlmsg);
|
||||
err = nl_send_iovec(nlh, nlmsg, iov, 3);
|
||||
|
||||
nlmsg_free(nlmsg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return wait_for_ack(nlh);
|
||||
}
|
||||
|
||||
#define NFNLMSG_QUEUE_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_QUEUE, (type))
|
||||
static struct nl_cache_ops nfnl_queue_msg_ops = {
|
||||
.co_name = "netfilter/queue_msg",
|
||||
|
|
|
@ -197,6 +197,11 @@ uint16_t nfnl_queue_msg_get_group(const struct nfnl_queue_msg *msg)
|
|||
return msg->queue_msg_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the protocol family
|
||||
* @arg msg NF queue message
|
||||
* @arg family AF_XXX address family example: AF_INET, AF_UNIX, etc
|
||||
*/
|
||||
void nfnl_queue_msg_set_family(struct nfnl_queue_msg *msg, uint8_t family)
|
||||
{
|
||||
msg->queue_msg_family = family;
|
||||
|
@ -424,6 +429,11 @@ const void *nfnl_queue_msg_get_payload(const struct nfnl_queue_msg *msg, int *le
|
|||
return msg->queue_msg_payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of items matching a filter in the cache
|
||||
* @arg msg queue msg
|
||||
* @arg verdict NF_DROP, NF_ACCEPT, NF_REPEAT, etc
|
||||
*/
|
||||
void nfnl_queue_msg_set_verdict(struct nfnl_queue_msg *msg,
|
||||
unsigned int verdict)
|
||||
{
|
||||
|
|
61
lib/nl.c
61
lib/nl.c
|
@ -207,14 +207,6 @@ int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
|
|||
struct nl_cb *cb;
|
||||
int ret;
|
||||
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *) nlmsg_hdr(msg),
|
||||
.iov_len = nlmsg_hdr(msg)->nlmsg_len,
|
||||
};
|
||||
|
||||
hdr->msg_iov = &iov;
|
||||
hdr->msg_iovlen = 1;
|
||||
|
||||
nlmsg_set_src(msg, &sk->s_local);
|
||||
|
||||
cb = sk->s_cb;
|
||||
|
@ -226,6 +218,7 @@ int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
|
|||
if (ret < 0)
|
||||
return -nl_syserr2nlerr(errno);
|
||||
|
||||
NL_DBG(4, "sent %d bytes\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -234,17 +227,20 @@ int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
|
|||
* Send netlink message.
|
||||
* @arg sk Netlink socket.
|
||||
* @arg msg Netlink message to be sent.
|
||||
* @arg iov iovec to be sent.
|
||||
* @arg iovlen number of struct iovec to be sent.
|
||||
* @see nl_sendmsg()
|
||||
* @return Number of characters sent on success or a negative error code.
|
||||
*/
|
||||
int nl_send(struct nl_sock *sk, struct nl_msg *msg)
|
||||
int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, const struct iovec *iov, unsigned iovlen)
|
||||
{
|
||||
struct sockaddr_nl *dst;
|
||||
struct ucred *creds;
|
||||
|
||||
struct msghdr hdr = {
|
||||
.msg_name = (void *) &sk->s_peer,
|
||||
.msg_namelen = sizeof(struct sockaddr_nl),
|
||||
.msg_iov = iov,
|
||||
.msg_iovlen = iovlen,
|
||||
};
|
||||
|
||||
/* Overwrite destination if specified in the message itself, defaults
|
||||
|
@ -273,22 +269,28 @@ int nl_send(struct nl_sock *sk, struct nl_msg *msg)
|
|||
return nl_sendmsg(sk, msg, &hdr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send netlink message and check & extend header values as needed.
|
||||
* Send netlink message.
|
||||
* @arg sk Netlink socket.
|
||||
* @arg msg Netlink message to be sent.
|
||||
*
|
||||
* Checks the netlink message \c nlh for completness and extends it
|
||||
* as required before sending it out. Checked fields include pid,
|
||||
* sequence nr, and flags.
|
||||
*
|
||||
* @see nl_send()
|
||||
* @return Number of characters sent or a negative error code.
|
||||
* @see nl_sendmsg()
|
||||
* @return Number of characters sent on success or a negative error code.
|
||||
*/
|
||||
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
|
||||
int nl_send(struct nl_sock *sk, struct nl_msg *msg)
|
||||
{
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *) nlmsg_hdr(msg),
|
||||
.iov_len = nlmsg_hdr(msg)->nlmsg_len,
|
||||
};
|
||||
|
||||
return nl_send_iovec(sk, msg, &iov, 1);
|
||||
}
|
||||
|
||||
void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct nl_cb *cb = sk->s_cb;
|
||||
|
||||
nlh = nlmsg_hdr(msg);
|
||||
if (nlh->nlmsg_pid == 0)
|
||||
|
@ -304,6 +306,25 @@ int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
|
|||
|
||||
if (!(sk->s_flags & NL_NO_AUTO_ACK))
|
||||
nlh->nlmsg_flags |= NLM_F_ACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send netlink message and check & extend header values as needed.
|
||||
* @arg sk Netlink socket.
|
||||
* @arg msg Netlink message to be sent.
|
||||
*
|
||||
* Checks the netlink message \c nlh for completness and extends it
|
||||
* as required before sending it out. Checked fields include pid,
|
||||
* sequence nr, and flags.
|
||||
*
|
||||
* @see nl_send()
|
||||
* @return Number of characters sent or a negative error code.
|
||||
*/
|
||||
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
|
||||
{
|
||||
struct nl_cb *cb = sk->s_cb;
|
||||
|
||||
nl_auto_complete(sk, msg);
|
||||
|
||||
if (cb->cb_send_ow)
|
||||
return cb->cb_send_ow(sk, msg);
|
||||
|
|
|
@ -265,6 +265,8 @@ int nl_object_identical(struct nl_object *a, struct nl_object *b)
|
|||
return 0;
|
||||
|
||||
req_attrs = ops->oo_id_attrs;
|
||||
if (req_attrs == ~0)
|
||||
req_attrs = a->ce_mask & b->ce_mask;
|
||||
|
||||
/* Both objects must provide all required attributes to uniquely
|
||||
* identify an object */
|
||||
|
|
108
lib/route/addr.c
108
lib/route/addr.c
|
@ -126,6 +126,7 @@
|
|||
#define ADDR_ATTR_LOCAL 0x0100
|
||||
#define ADDR_ATTR_BROADCAST 0x0200
|
||||
#define ADDR_ATTR_MULTICAST 0x0400
|
||||
#define ADDR_ATTR_ANYCAST 0x0800
|
||||
|
||||
static struct nl_cache_ops rtnl_addr_ops;
|
||||
static struct nl_object_ops addr_obj_ops;
|
||||
|
@ -149,6 +150,7 @@ static void addr_free_data(struct nl_object *obj)
|
|||
nl_addr_put(addr->a_local);
|
||||
nl_addr_put(addr->a_bcast);
|
||||
nl_addr_put(addr->a_multicast);
|
||||
nl_addr_put(addr->a_anycast);
|
||||
}
|
||||
|
||||
static int addr_clone(struct nl_object *_dst, struct nl_object *_src)
|
||||
|
@ -172,6 +174,10 @@ static int addr_clone(struct nl_object *_dst, struct nl_object *_src)
|
|||
if (!(dst->a_multicast = nl_addr_clone(src->a_multicast)))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (src->a_anycast)
|
||||
if (!(dst->a_anycast = nl_addr_clone(src->a_anycast)))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -273,6 +279,15 @@ static int addr_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
|||
addr->ce_mask |= ADDR_ATTR_MULTICAST;
|
||||
}
|
||||
|
||||
if (tb[IFA_ANYCAST]) {
|
||||
addr->a_anycast = nl_addr_alloc_attr(tb[IFA_ANYCAST],
|
||||
family);
|
||||
if (!addr->a_anycast)
|
||||
goto errout_nomem;
|
||||
|
||||
addr->ce_mask |= ADDR_ATTR_ANYCAST;
|
||||
}
|
||||
|
||||
err = pp->pp_cb((struct nl_object *) addr, pp);
|
||||
errout:
|
||||
rtnl_addr_put(addr);
|
||||
|
@ -349,6 +364,11 @@ static void addr_dump_details(struct nl_object *obj, struct nl_dump_params *p)
|
|||
nl_addr2str(addr->a_multicast, buf,
|
||||
sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_ANYCAST)
|
||||
nl_dump(p, " anycast %s",
|
||||
nl_addr2str(addr->a_anycast, buf,
|
||||
sizeof(buf)));
|
||||
|
||||
nl_dump(p, "\n");
|
||||
}
|
||||
|
||||
|
@ -380,6 +400,81 @@ static void addr_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
|
|||
addr_dump_details(obj, p);
|
||||
}
|
||||
|
||||
static void addr_dump_env(struct nl_object *obj, struct nl_dump_params *p)
|
||||
{
|
||||
struct rtnl_addr *addr = (struct rtnl_addr *) obj;
|
||||
struct nl_cache *link_cache;
|
||||
char buf[128];
|
||||
|
||||
nl_dump_line(p, "ADDR_FAMILY=%s\n",
|
||||
nl_af2str(addr->a_family, buf, sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_LOCAL)
|
||||
nl_dump_line(p, "ADDR_LOCAL=%s\n",
|
||||
nl_addr2str(addr->a_local, buf, sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_PEER)
|
||||
nl_dump_line(p, "ADDR_PEER=%s\n",
|
||||
nl_addr2str(addr->a_peer, buf, sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_BROADCAST)
|
||||
nl_dump_line(p, "ADDR_BROADCAST=%s\n",
|
||||
nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_ANYCAST)
|
||||
nl_dump_line(p, "ADDR_ANYCAST=%s\n",
|
||||
nl_addr2str(addr->a_anycast, buf, sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_MULTICAST)
|
||||
nl_dump_line(p, "ADDR_MULTICAST=%s\n",
|
||||
nl_addr2str(addr->a_multicast, buf,
|
||||
sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
|
||||
nl_dump_line(p, "ADDR_PREFIXLEN=%u\n",
|
||||
addr->a_prefixlen);
|
||||
link_cache = nl_cache_mngt_require("route/link");
|
||||
|
||||
nl_dump_line(p, "ADDR_IFINDEX=%u\n", addr->a_ifindex);
|
||||
if (link_cache)
|
||||
nl_dump_line(p, "ADDR_IFNAME=%s\n",
|
||||
rtnl_link_i2name(link_cache, addr->a_ifindex,
|
||||
buf, sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_SCOPE)
|
||||
nl_dump_line(p, "ADDR_SCOPE=%s\n",
|
||||
rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_LABEL)
|
||||
nl_dump_line(p, "ADDR_LABEL=%s\n", addr->a_label);
|
||||
|
||||
rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
|
||||
if (buf[0])
|
||||
nl_dump_line(p, "ADDR_FLAGS=%s\n", buf);
|
||||
|
||||
if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
|
||||
struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
|
||||
|
||||
nl_dump_line(p, "ADDR_CACHEINFO_VALID=%s\n",
|
||||
ci->aci_valid == 0xFFFFFFFFU ? "forever" :
|
||||
nl_msec2str(ci->aci_valid * 1000,
|
||||
buf, sizeof(buf)));
|
||||
|
||||
nl_dump_line(p, "ADDR_CACHEINFO_PREFERED=%s\n",
|
||||
ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
|
||||
nl_msec2str(ci->aci_prefered * 1000,
|
||||
buf, sizeof(buf)));
|
||||
|
||||
nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%s\n",
|
||||
nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
|
||||
buf, sizeof(buf)));
|
||||
|
||||
nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%s\n",
|
||||
nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
|
||||
buf, sizeof(buf)));
|
||||
}
|
||||
}
|
||||
|
||||
static int addr_compare(struct nl_object *_a, struct nl_object *_b,
|
||||
uint32_t attrs, int flags)
|
||||
{
|
||||
|
@ -398,6 +493,7 @@ static int addr_compare(struct nl_object *_a, struct nl_object *_b,
|
|||
diff |= ADDR_DIFF(MULTICAST, nl_addr_cmp(a->a_multicast,
|
||||
b->a_multicast));
|
||||
diff |= ADDR_DIFF(BROADCAST, nl_addr_cmp(a->a_bcast, b->a_bcast));
|
||||
diff |= ADDR_DIFF(ANYCAST, nl_addr_cmp(a->a_anycast, b->a_anycast));
|
||||
|
||||
if (flags & LOOSE_COMPARISON)
|
||||
diff |= ADDR_DIFF(FLAGS,
|
||||
|
@ -825,6 +921,17 @@ struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr)
|
|||
return addr->a_multicast;
|
||||
}
|
||||
|
||||
int rtnl_addr_set_anycast(struct rtnl_addr *addr, struct nl_addr *anycast)
|
||||
{
|
||||
return __assign_addr(addr, &addr->a_anycast, anycast,
|
||||
ADDR_ATTR_ANYCAST);
|
||||
}
|
||||
|
||||
struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *addr)
|
||||
{
|
||||
return addr->a_anycast;
|
||||
}
|
||||
|
||||
uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *addr)
|
||||
{
|
||||
if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
|
||||
|
@ -903,6 +1010,7 @@ static struct nl_object_ops addr_obj_ops = {
|
|||
[NL_DUMP_LINE] = addr_dump_line,
|
||||
[NL_DUMP_DETAILS] = addr_dump_details,
|
||||
[NL_DUMP_STATS] = addr_dump_stats,
|
||||
[NL_DUMP_ENV] = addr_dump_env,
|
||||
},
|
||||
.oo_compare = addr_compare,
|
||||
.oo_attrs2str = addr_attrs2str,
|
||||
|
|
|
@ -850,7 +850,7 @@ static struct nl_object_ops neigh_obj_ops = {
|
|||
},
|
||||
.oo_compare = neigh_compare,
|
||||
.oo_attrs2str = neigh_attrs2str,
|
||||
.oo_id_attrs = (NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
|
||||
.oo_id_attrs = (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
|
||||
};
|
||||
|
||||
static struct nl_af_group neigh_groups[] = {
|
||||
|
|
17
lib/utils.c
17
lib/utils.c
|
@ -285,7 +285,7 @@ static void __init get_psched_settings(void)
|
|||
{
|
||||
char name[FILENAME_MAX];
|
||||
FILE *fd;
|
||||
int got_hz = 0, got_tick = 0;
|
||||
int got_hz = 0;
|
||||
|
||||
if (getenv("HZ")) {
|
||||
long hz = strtol(getenv("HZ"), NULL, 0);
|
||||
|
@ -301,12 +301,9 @@ static void __init get_psched_settings(void)
|
|||
|
||||
if (getenv("TICKS_PER_USEC")) {
|
||||
double t = strtod(getenv("TICKS_PER_USEC"), NULL);
|
||||
|
||||
ticks_per_usec = t;
|
||||
got_tick = 1;
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
if (getenv("PROC_NET_PSCHED"))
|
||||
snprintf(name, sizeof(name), "%s", getenv("PROC_NET_PSCHED"));
|
||||
else if (getenv("PROC_ROOT"))
|
||||
|
@ -316,15 +313,15 @@ static void __init get_psched_settings(void)
|
|||
strncpy(name, "/proc/net/psched", sizeof(name) - 1);
|
||||
|
||||
if ((fd = fopen(name, "r"))) {
|
||||
uint32_t tick, us, nom;
|
||||
int r = fscanf(fd, "%08x%08x%08x%*08x", &tick, &us, &nom);
|
||||
|
||||
if (4 == r && nom == 1000000 && !got_tick)
|
||||
uint32_t tick, us;
|
||||
/* the file contains 4 hexadecimals, but we just use
|
||||
the first two of them */
|
||||
int r = fscanf(fd, "%08x %08x", &tick, &us);
|
||||
ticks_per_usec = (double)tick/(double)us;
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* src/nf-log.c Monitor netfilter queue events
|
||||
* src/nf-queue.c Monitor netfilter queue events
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -7,6 +7,7 @@
|
|||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
|
||||
* Copyright (c) 2010 Karl Hiramoto <karl@hiramoto.org>
|
||||
*/
|
||||
|
||||
|
||||
|
@ -40,7 +41,31 @@ static void obj_input(struct nl_object *obj, void *arg)
|
|||
.dp_fd = stdout,
|
||||
.dp_dump_msgtype = 1,
|
||||
};
|
||||
uint32_t packet_id = nfnl_queue_msg_get_packetid(msg);
|
||||
static uint32_t next_packet_id = 0;
|
||||
struct nfnl_queue_msg *lost_msg = NULL;
|
||||
uint8_t family;
|
||||
uint16_t group;
|
||||
|
||||
if (packet_id > next_packet_id) {
|
||||
printf("Warning: %d Out of order packets. Queue or socket overload \n", packet_id - next_packet_id);
|
||||
group = nfnl_queue_msg_get_group(msg);
|
||||
family = nfnl_queue_msg_get_family(msg);
|
||||
lost_msg = nfnl_queue_msg_alloc();
|
||||
|
||||
do {
|
||||
nfnl_queue_msg_set_group(lost_msg, group);
|
||||
nfnl_queue_msg_set_family(lost_msg, family);
|
||||
nfnl_queue_msg_set_packetid(lost_msg, next_packet_id);
|
||||
nfnl_queue_msg_set_verdict(lost_msg, NF_ACCEPT);
|
||||
nfnl_queue_msg_send_verdict(nf_sock, lost_msg);
|
||||
next_packet_id++;
|
||||
} while (packet_id > next_packet_id);
|
||||
|
||||
nfnl_queue_msg_put(lost_msg);
|
||||
}
|
||||
|
||||
next_packet_id = packet_id + 1;
|
||||
nfnl_queue_msg_set_verdict(msg, NF_ACCEPT);
|
||||
nl_object_dump(obj, &dp);
|
||||
nfnl_queue_msg_send_verdict(nf_sock, msg);
|
||||
|
@ -75,6 +100,9 @@ int main(int argc, char *argv[])
|
|||
if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
|
||||
printf("Usage: nf-queue family group [ copy_mode ] "
|
||||
"[ copy_range ]\n");
|
||||
printf("family: [ inet | inet6 | ... ] \n");
|
||||
printf("group: the --queue-num arg that you gave to iptables\n");
|
||||
printf("copy_mode: [ none | meta | packet ] \n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -113,6 +141,8 @@ int main(int argc, char *argv[])
|
|||
nl_cli_connect(rt_sock, NETLINK_ROUTE);
|
||||
link_cache = nl_cli_link_alloc_cache(rt_sock);
|
||||
|
||||
nl_socket_set_buffer_size(nf_sock, 1024*127, 1024*127);
|
||||
|
||||
while (1) {
|
||||
fd_set rfds;
|
||||
int nffd, rtfd, maxfd, retval;
|
||||
|
|
Reference in New Issue