[LIBNL]: Support conntrack add/delete/query requests
Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
2f4f8a5094
commit
596d3bc2e9
2 changed files with 162 additions and 0 deletions
|
@ -39,6 +39,15 @@ extern void nfnl_ct_put(struct nfnl_ct *);
|
|||
|
||||
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 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 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 void nfnl_ct_set_family(struct nfnl_ct *, uint8_t);
|
||||
extern uint8_t nfnl_ct_get_family(const struct nfnl_ct *);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* Copyright (c) 2003-2006 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -388,6 +389,158 @@ static int ct_request_update(struct nl_cache *c, struct nl_handle *h)
|
|||
return nfnl_ct_dump_request(h);
|
||||
}
|
||||
|
||||
static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct,
|
||||
int repl)
|
||||
{
|
||||
struct nlattr *tuple, *ip, *proto;
|
||||
struct nl_addr *addr;
|
||||
int family;
|
||||
|
||||
family = nfnl_ct_get_family(ct);
|
||||
|
||||
tuple = nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG);
|
||||
if (!tuple)
|
||||
goto nla_put_failure;
|
||||
|
||||
ip = nla_nest_start(msg, CTA_TUPLE_IP);
|
||||
if (!ip)
|
||||
goto nla_put_failure;
|
||||
|
||||
addr = nfnl_ct_get_src(ct, repl);
|
||||
if (addr)
|
||||
NLA_PUT_ADDR(msg,
|
||||
family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC,
|
||||
addr);
|
||||
|
||||
addr = nfnl_ct_get_dst(ct, repl);
|
||||
if (addr)
|
||||
NLA_PUT_ADDR(msg,
|
||||
family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST,
|
||||
addr);
|
||||
|
||||
nla_nest_end(msg, ip);
|
||||
|
||||
proto = nla_nest_start(msg, CTA_TUPLE_PROTO);
|
||||
if (!proto)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nfnl_ct_test_proto(ct))
|
||||
NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_ct_get_proto(ct));
|
||||
|
||||
if (nfnl_ct_test_src_port(ct, repl))
|
||||
NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT,
|
||||
nfnl_ct_get_src_port(ct, repl));
|
||||
|
||||
if (nfnl_ct_test_dst_port(ct, repl))
|
||||
NLA_PUT_U16(msg, CTA_PROTO_DST_PORT,
|
||||
nfnl_ct_get_dst_port(ct, repl));
|
||||
|
||||
if (nfnl_ct_test_icmp_id(ct, repl))
|
||||
NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID,
|
||||
nfnl_ct_get_icmp_id(ct, repl));
|
||||
|
||||
if (nfnl_ct_test_icmp_type(ct, repl))
|
||||
NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE,
|
||||
nfnl_ct_get_icmp_type(ct, repl));
|
||||
|
||||
if (nfnl_ct_test_icmp_code(ct, repl))
|
||||
NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE,
|
||||
nfnl_ct_get_icmp_code(ct, repl));
|
||||
|
||||
nla_nest_end(msg, proto);
|
||||
|
||||
nla_nest_end(msg, tuple);
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct nl_msg *nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
|
||||
msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags,
|
||||
nfnl_ct_get_family(ct), 0);
|
||||
if (msg == NULL)
|
||||
return NULL;
|
||||
|
||||
if (nfnl_ct_build_tuple(msg, ct, 0) < 0)
|
||||
goto err_out;
|
||||
|
||||
return msg;
|
||||
|
||||
err_out:
|
||||
nlmsg_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags)
|
||||
{
|
||||
return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
err = nl_send_auto_complete(h, msg);
|
||||
nlmsg_free(msg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return nl_wait_for_ack(h);
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags)
|
||||
{
|
||||
return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
err = nl_send_auto_complete(h, msg);
|
||||
nlmsg_free(msg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return nl_wait_for_ack(h);
|
||||
}
|
||||
|
||||
struct nl_msg *nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags)
|
||||
{
|
||||
return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
err = nl_send_auto_complete(h, msg);
|
||||
nlmsg_free(msg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return nl_wait_for_ack(h);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Cache Management
|
||||
* @{
|
||||
|
|
Loading…
Add table
Reference in a new issue