diff options
author | Rich Fought <Rich.Fought@watchguard.com> | 2012-10-08 22:26:55 (GMT) |
---|---|---|
committer | Rich Fought <Rich.Fought@watchguard.com> | 2012-10-08 22:26:55 (GMT) |
commit | c675bf048669e6387213018298787f4f9415401f (patch) | |
tree | 5753d946a0461106412b600e540b9ce424c49eee /lib | |
parent | e8b3356dd2d61f27b2506528e291fc051e8340bc (diff) | |
download | libnl-c675bf048669e6387213018298787f4f9415401f.zip libnl-c675bf048669e6387213018298787f4f9415401f.tar.gz libnl-c675bf048669e6387213018298787f4f9415401f.tar.bz2 |
Checkpoint before compilation attempt
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 3 | ||||
-rw-r--r-- | lib/netfilter/exp.c | 423 | ||||
-rw-r--r-- | lib/netfilter/exp_obj.c | 339 |
3 files changed, 395 insertions, 370 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 9e5efd8..e31e594 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -29,7 +29,8 @@ libnl_nf_3_la_SOURCES = \ netfilter/ct.c netfilter/ct_obj.c netfilter/log.c \ netfilter/log_msg.c netfilter/log_msg_obj.c netfilter/log_obj.c \ netfilter/netfilter.c netfilter/nfnl.c netfilter/queue.c \ - netfilter/queue_msg.c netfilter/queue_msg_obj.c netfilter/queue_obj.c + netfilter/queue_msg.c netfilter/queue_msg_obj.c netfilter/queue_obj.c \ + netfilter/exp.c netfilter/exp_obj.c CLEANFILES = \ route/pktloc_grammar.c route/pktloc_grammar.h \ diff --git a/lib/netfilter/exp.c b/lib/netfilter/exp.c index 59ee1d9..9e29c35 100644 --- a/lib/netfilter/exp.c +++ b/lib/netfilter/exp.c @@ -1,5 +1,5 @@ /* - * lib/netfilter/ct.c Conntrack + * lib/netfilter/ct.c Conntrack Expectation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,7 +14,7 @@ /** * @ingroup nfnl - * @defgroup ct Conntrack + * @defgroup exp Expectation * @brief * @{ */ @@ -26,9 +26,9 @@ #include <netlink-local.h> #include <netlink/attr.h> #include <netlink/netfilter/nfnl.h> -#include <netlink/netfilter/ct.h> +#include <netlink/netfilter/exp.h> -static struct nl_cache_ops nfnl_ct_ops; +static struct nl_cache_ops nfnl_exp_ops; #if __BYTE_ORDER == __BIG_ENDIAN static uint64_t ntohll(uint64_t x) @@ -42,35 +42,33 @@ static uint64_t ntohll(uint64_t x) } #endif -static struct nla_policy ct_policy[CTA_MAX+1] = { - [CTA_TUPLE_ORIG] = { .type = NLA_NESTED }, - [CTA_TUPLE_REPLY] = { .type = NLA_NESTED }, - [CTA_STATUS] = { .type = NLA_U32 }, - [CTA_PROTOINFO] = { .type = NLA_NESTED }, - //[CTA_HELP] - //[CTA_NAT_SRC] - [CTA_TIMEOUT] = { .type = NLA_U32 }, - [CTA_MARK] = { .type = NLA_U32 }, - [CTA_COUNTERS_ORIG] = { .type = NLA_NESTED }, - [CTA_COUNTERS_REPLY] = { .type = NLA_NESTED }, - [CTA_USE] = { .type = NLA_U32 }, - [CTA_ID] = { .type = NLA_U32 }, - //[CTA_NAT_DST] +static struct nla_policy exp_policy[CTA_EXPECT_MAX+1] = { + [CTA_EXPECT_MASTER] = { .type = NLA_NESTED }, + [CTA_EXPECT_TUPLE] = { .type = NLA_NESTED }, + [CTA_EXPECT_MASK] = { .type = NLA_NESTED }, + [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 }, + [CTA_EXPECT_ID] = { .type = NLA_U32 }, + [CTA_EXPECT_HELP_NAME] = { .type = NLA_STRING }, + //[CTA_EXPECT_ZONE] = { .type = NLA_U16 }, // In latest kernel header + //[CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, // In latest kernel header + //[CTA_EXPECT_CLASS] = { .type = NLA_U32 }, // In libnetfilter_conntrack include/linux/linux_nfnetlink_conntrack.h + //[CTA_EXPECT_NAT] = { .type = NLA_NESTED }, // In libnetfilter_conntrack include/linux/linux_nfnetlink_conntrack.h + //[CTA_EXPECT_FN] = { .type = NLA_STRING }, // In libnetfilter_conntrack include/linux/linux_nfnetlink_conntrack.h }; -static struct nla_policy ct_tuple_policy[CTA_TUPLE_MAX+1] = { +static struct nla_policy exp_tuple_policy[CTA_TUPLE_MAX+1] = { [CTA_TUPLE_IP] = { .type = NLA_NESTED }, [CTA_TUPLE_PROTO] = { .type = NLA_NESTED }, }; -static struct nla_policy ct_ip_policy[CTA_IP_MAX+1] = { +static struct nla_policy exp_ip_policy[CTA_IP_MAX+1] = { [CTA_IP_V4_SRC] = { .type = NLA_U32 }, [CTA_IP_V4_DST] = { .type = NLA_U32 }, [CTA_IP_V6_SRC] = { .minlen = 16 }, [CTA_IP_V6_DST] = { .minlen = 16 }, }; -static struct nla_policy ct_proto_policy[CTA_PROTO_MAX+1] = { +static struct nla_policy exp_proto_policy[CTA_PROTO_MAX+1] = { [CTA_PROTO_NUM] = { .type = NLA_U8 }, [CTA_PROTO_SRC_PORT] = { .type = NLA_U16 }, [CTA_PROTO_DST_PORT] = { .type = NLA_U16 }, @@ -82,33 +80,14 @@ static struct nla_policy ct_proto_policy[CTA_PROTO_MAX+1] = { [CTA_PROTO_ICMPV6_CODE] = { .type = NLA_U8 }, }; -static struct nla_policy ct_protoinfo_policy[CTA_PROTOINFO_MAX+1] = { - [CTA_PROTOINFO_TCP] = { .type = NLA_NESTED }, -}; - -static struct nla_policy ct_protoinfo_tcp_policy[CTA_PROTOINFO_TCP_MAX+1] = { - [CTA_PROTOINFO_TCP_STATE] = { .type = NLA_U8 }, - [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 }, - [CTA_PROTOINFO_TCP_WSCALE_REPLY] = { .type = NLA_U8 }, - [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .minlen = 2 }, - [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .minlen = 2 }, - -}; -static struct nla_policy ct_counters_policy[CTA_COUNTERS_MAX+1] = { - [CTA_COUNTERS_PACKETS] = { .type = NLA_U64 }, - [CTA_COUNTERS_BYTES] = { .type = NLA_U64 }, - [CTA_COUNTERS32_PACKETS]= { .type = NLA_U32 }, - [CTA_COUNTERS32_BYTES] = { .type = NLA_U32 }, -}; - -static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) +static int exp_parse_ip(struct nfnl_exp *exp, int tuple, struct nlattr *attr) { struct nlattr *tb[CTA_IP_MAX+1]; struct nl_addr *addr; int err; - err = nla_parse_nested(tb, CTA_IP_MAX, attr, ct_ip_policy); + err = nla_parse_nested(tb, CTA_IP_MAX, attr, exp_ip_policy); if (err < 0) goto errout; @@ -116,7 +95,7 @@ static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) addr = nl_addr_alloc_attr(tb[CTA_IP_V4_SRC], AF_INET); if (addr == NULL) goto errout_enomem; - err = nfnl_ct_set_src(ct, repl, addr); + err = nfnl_exp_set_src(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; @@ -125,7 +104,7 @@ static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) addr = nl_addr_alloc_attr(tb[CTA_IP_V4_DST], AF_INET); if (addr == NULL) goto errout_enomem; - err = nfnl_ct_set_dst(ct, repl, addr); + err = nfnl_exp_set_dst(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; @@ -134,7 +113,7 @@ static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) addr = nl_addr_alloc_attr(tb[CTA_IP_V6_SRC], AF_INET6); if (addr == NULL) goto errout_enomem; - err = nfnl_ct_set_src(ct, repl, addr); + err = nfnl_exp_set_src(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; @@ -143,7 +122,7 @@ static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr) addr = nl_addr_alloc_attr(tb[CTA_IP_V6_DST], AF_INET6); if (addr == NULL) goto errout_enomem; - err = nfnl_ct_set_dst(ct, repl, addr); + err = nfnl_exp_set_dst(exp, tuple, addr); nl_addr_put(addr); if (err < 0) goto errout; @@ -157,89 +136,55 @@ errout: return err; } -static int ct_parse_proto(struct nfnl_ct *ct, int repl, struct nlattr *attr) +static int exp_parse_proto(struct nfnl_exp *exp, int tuple, struct nlattr *attr) { struct nlattr *tb[CTA_PROTO_MAX+1]; int err; + uint16_t srcport = 0, dstport = 0, icmpid = 0; + uint8_t icmptype = 0, icmpcode = 0; - err = nla_parse_nested(tb, CTA_PROTO_MAX, attr, ct_proto_policy); + err = nla_parse_nested(tb, CTA_PROTO_MAX, attr, exp_proto_policy); if (err < 0) return err; - if (!repl && tb[CTA_PROTO_NUM]) - nfnl_ct_set_proto(ct, nla_get_u8(tb[CTA_PROTO_NUM])); + if (tb[CTA_PROTO_NUM]) + nfnl_exp_set_l4protonum(exp, tuple, nla_get_u8(tb[CTA_PROTO_NUM])); + if (tb[CTA_PROTO_SRC_PORT]) - nfnl_ct_set_src_port(ct, repl, - ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT]))); + srcport = ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT])); if (tb[CTA_PROTO_DST_PORT]) - nfnl_ct_set_dst_port(ct, repl, - ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT]))); + dstport = ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT])); + if (tb[CTA_PROTO_SRC_PORT] || tb[CTA_PROTO_DST_PORT]) + nfnl_exp_set_ports(exp, tuple, srcport, dstport); + if (tb[CTA_PROTO_ICMP_ID]) - nfnl_ct_set_icmp_id(ct, repl, - ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID]))); + icmpid = ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])); if (tb[CTA_PROTO_ICMP_TYPE]) - nfnl_ct_set_icmp_type(ct, repl, - nla_get_u8(tb[CTA_PROTO_ICMP_TYPE])); + icmptype = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]); if (tb[CTA_PROTO_ICMP_CODE]) - nfnl_ct_set_icmp_code(ct, repl, - nla_get_u8(tb[CTA_PROTO_ICMP_CODE])); - + icmpcode = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]); + if (tb[CTA_PROTO_ICMP_ID] || tb[CTA_PROTO_ICMP_TYPE] || tb[CTA_PROTO_ICMP_CODE]) + nfnl_exp_set_icmp(exp, tuple, icmpid, icmptype, icmpcode); return 0; } -static int ct_parse_tuple(struct nfnl_ct *ct, int repl, struct nlattr *attr) +static int exp_parse_tuple(struct nfnl_exp *exp, int tuple, struct nlattr *attr) { struct nlattr *tb[CTA_TUPLE_MAX+1]; int err; - err = nla_parse_nested(tb, CTA_TUPLE_MAX, attr, ct_tuple_policy); + err = nla_parse_nested(tb, CTA_TUPLE_MAX, attr, exp_tuple_policy); if (err < 0) return err; if (tb[CTA_TUPLE_IP]) { - err = ct_parse_ip(ct, repl, tb[CTA_TUPLE_IP]); + err = exp_parse_ip(exp, tuple, tb[CTA_TUPLE_IP]); if (err < 0) return err; } if (tb[CTA_TUPLE_PROTO]) { - err = ct_parse_proto(ct, repl, tb[CTA_TUPLE_PROTO]); - if (err < 0) - return err; - } - - return 0; -} - -static int ct_parse_protoinfo_tcp(struct nfnl_ct *ct, struct nlattr *attr) -{ - struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1]; - int err; - - err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, - ct_protoinfo_tcp_policy); - if (err < 0) - return err; - - if (tb[CTA_PROTOINFO_TCP_STATE]) - nfnl_ct_set_tcp_state(ct, - nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE])); - - return 0; -} - -static int ct_parse_protoinfo(struct nfnl_ct *ct, struct nlattr *attr) -{ - struct nlattr *tb[CTA_PROTOINFO_MAX+1]; - int err; - - err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, - ct_protoinfo_policy); - if (err < 0) - return err; - - if (tb[CTA_PROTOINFO_TCP]) { - err = ct_parse_protoinfo_tcp(ct, tb[CTA_PROTOINFO_TCP]); + err = exp_parse_proto(exp, tuple, tb[CTA_TUPLE_PROTO]); if (err < 0) return err; } @@ -247,149 +192,132 @@ static int ct_parse_protoinfo(struct nfnl_ct *ct, struct nlattr *attr) return 0; } -static int ct_parse_counters(struct nfnl_ct *ct, int repl, struct nlattr *attr) -{ - struct nlattr *tb[CTA_COUNTERS_MAX+1]; - int err; - - err = nla_parse_nested(tb, CTA_COUNTERS_MAX, attr, ct_counters_policy); - if (err < 0) - return err; - - if (tb[CTA_COUNTERS_PACKETS]) - nfnl_ct_set_packets(ct, repl, - ntohll(nla_get_u64(tb[CTA_COUNTERS_PACKETS]))); - if (tb[CTA_COUNTERS32_PACKETS]) - nfnl_ct_set_packets(ct, repl, - ntohl(nla_get_u32(tb[CTA_COUNTERS32_PACKETS]))); - if (tb[CTA_COUNTERS_BYTES]) - nfnl_ct_set_bytes(ct, repl, - ntohll(nla_get_u64(tb[CTA_COUNTERS_BYTES]))); - if (tb[CTA_COUNTERS32_BYTES]) - nfnl_ct_set_bytes(ct, repl, - ntohl(nla_get_u32(tb[CTA_COUNTERS32_BYTES]))); - - return 0; -} - -int nfnlmsg_ct_group(struct nlmsghdr *nlh) +int nfnlmsg_exp_group(struct nlmsghdr *nlh) { switch (nfnlmsg_subtype(nlh)) { - case IPCTNL_MSG_CT_NEW: + case IPCTNL_MSG_EXP_NEW: if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL)) - return NFNLGRP_CONNTRACK_NEW; + return NFNLGRP_CONNTRACK_EXP_NEW; else - return NFNLGRP_CONNTRACK_UPDATE; - case IPCTNL_MSG_CT_DELETE: - return NFNLGRP_CONNTRACK_DESTROY; + return NFNLGRP_CONNTRACK_EXP_UPDATE; + case IPCTNL_MSG_EXP_DELETE: + return NFNLGRP_CONNTRACK_EXP_DESTROY; default: return NFNLGRP_NONE; } } -int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result) +int nfnlmsg_exp_parse(struct nlmsghdr *nlh, struct nfnl_exp **result) { - struct nfnl_ct *ct; + struct nfnl_exp *exp; struct nlattr *tb[CTA_MAX+1]; int err; - ct = nfnl_ct_alloc(); - if (!ct) + exp = nfnl_exp_alloc(); + if (!exp) return -NLE_NOMEM; - ct->ce_msgtype = nlh->nlmsg_type; + exp->ce_msgtype = nlh->nlmsg_type; - err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX, - ct_policy); + err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_EXPECT_MAX, + exp_policy); if (err < 0) goto errout; - nfnl_ct_set_family(ct, nfnlmsg_family(nlh)); - - if (tb[CTA_TUPLE_ORIG]) { - err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]); - if (err < 0) - goto errout; - } - if (tb[CTA_TUPLE_REPLY]) { - err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]); - if (err < 0) - goto errout; - } + nfnl_exp_set_family(exp, nfnlmsg_family(nlh)); - if (tb[CTA_PROTOINFO]) { - err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]); + if (tb[CTA_EXPECT_TUPLE]) { + err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_EXPECT, tb[CTA_EXPECT_TUPLE]); + if (err < 0) + goto errout; + } + if (tb[CTA_EXPECT_MASTER]) { + err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_MASTER, tb[CTA_EXPECT_MASTER]); if (err < 0) goto errout; } - - if (tb[CTA_STATUS]) - nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS]))); - if (tb[CTA_TIMEOUT]) - nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT]))); - if (tb[CTA_MARK]) - nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK]))); - if (tb[CTA_USE]) - nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE]))); - if (tb[CTA_ID]) - nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID]))); - - if (tb[CTA_COUNTERS_ORIG]) { - err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]); + if (tb[CTA_EXPECT_MASK]) { + err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_MASK, tb[CTA_EXPECT_MASK]); if (err < 0) goto errout; } - if (tb[CTA_COUNTERS_REPLY]) { - err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]); - if (err < 0) - goto errout; - } + if (tb[CTA_EXPECT_TIMEOUT]) + nfnl_exp_set_timeout(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_TIMEOUT]))); + if (tb[CTA_EXPECT_ID]) + nfnl_exp_set_id(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_ID]))); + if (tb[CTA_EXPECT_HELP_NAME]) + nfnl_exp_set_helper_name(exp, nla_data(tb[CTA_EXPECT_HELP_NAME])); - *result = ct; + *result = exp; return 0; errout: - nfnl_ct_put(ct); + nfnl_exp_put(exp); return err; } -static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, +static int exp_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct nlmsghdr *nlh, struct nl_parser_param *pp) { - struct nfnl_ct *ct; + struct nfnl_exp *exp; int err; - if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0) + if ((err = nfnlmsg_exp_parse(nlh, &exp)) < 0) goto errout; - err = pp->pp_cb((struct nl_object *) ct, pp); + err = pp->pp_cb((struct nl_object *) exp, pp); errout: - nfnl_ct_put(ct); + nfnl_exp_put(exp); return err; } -int nfnl_ct_dump_request(struct nl_sock *sk) +int nfnl_exp_dump_request(struct nl_sock *sk) { - return nfnl_send_simple(sk, NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET, + return nfnl_send_simple(sk, NFNL_SUBSYS_CTNETLINK_EXP, IPCTNL_MSG_EXP_GET, NLM_F_DUMP, AF_UNSPEC, 0); } -static int ct_request_update(struct nl_cache *cache, struct nl_sock *sk) +static int exp_request_update(struct nl_cache *cache, struct nl_sock *sk) +{ + return nfnl_exp_dump_request(sk); +} + +static int exp_get_tuple_attr(int tuple) { - return nfnl_ct_dump_request(sk); + int attr = 0; + + switch (tuple) { + case NFNL_EXP_TUPLE_MASTER: + attr = CTA_EXPECT_MASTER; + break; + case NFNL_EXP_TUPLE_MASK: + attr = CTA_EXPECT_MASK; + break; + //case NFNL_EXP_TUPLE_NAT: + // attr = EXP_ATTR_NAT_L4PROTO_NUM; + // break; + case NFNL_EXP_TUPLE_EXPECT: + default : + attr = CTA_EXPECT_TUPLE; + break; + } + + return attr; } -static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct, - int repl) +static int nfnl_exp_build_tuple(struct nl_msg *msg, const struct nfnl_exp *exp, + int type) { struct nlattr *tuple, *ip, *proto; struct nl_addr *addr; int family; - family = nfnl_ct_get_family(ct); + int tupattr = exp_get_tuple_attr(type); - tuple = nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG); + family = nfnl_exp_get_family(exp); + + tuple = nla_nest_start(msg, tupattr); if (!tuple) goto nla_put_failure; @@ -397,13 +325,13 @@ static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct, if (!ip) goto nla_put_failure; - addr = nfnl_ct_get_src(ct, repl); + addr = nfnl_exp_get_src(exp, type); 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); + addr = nfnl_exp_get_dst(exp, type); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST, @@ -415,28 +343,27 @@ static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct, 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_exp_test_l4protonum(exp, type)) + NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_exp_get_l4protonum(exp, type)); - if (nfnl_ct_test_src_port(ct, repl)) + if (nfnl_exp_test_ports(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT, - htons(nfnl_ct_get_src_port(ct, repl))); + htons(nfnl_exp_get_src_port(exp, type))); - if (nfnl_ct_test_dst_port(ct, repl)) NLA_PUT_U16(msg, CTA_PROTO_DST_PORT, - htons(nfnl_ct_get_dst_port(ct, repl))); + htons(nfnl_exp_get_dst_port(exp, type))); + } - if (nfnl_ct_test_icmp_id(ct, repl)) + if (nfnl_exp_test_icmp(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID, - htons(nfnl_ct_get_icmp_id(ct, repl))); + htons(nfnl_exp_get_icmp_id(exp, type))); - if (nfnl_ct_test_icmp_type(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE, - nfnl_ct_get_icmp_type(ct, repl)); + nfnl_exp_get_icmp_type(exp, type)); - if (nfnl_ct_test_icmp_code(ct, repl)) NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE, - nfnl_ct_get_icmp_code(ct, repl)); + nfnl_exp_get_icmp_code(exp, type)); + } nla_nest_end(msg, proto); @@ -447,20 +374,36 @@ nla_put_failure: return -NLE_MSGSIZE; } -static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags, +static int nfnl_exp_build_message(const struct nfnl_exp *exp, 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); + msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK_EXP, cmd, flags, + nfnl_exp_get_family(exp), 0); if (msg == NULL) return -NLE_NOMEM; - if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0) + if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_TUPLE)) < 0) goto err_out; + if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASTER)) < 0) + goto err_out; + + if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASK)) < 0) + goto err_out; + + // FIXME timeout and helper name + if (nfnl_exp_test_id(exp)) + NLA_PUT_U32(msg, CTA_EXPECT_ID, htonl(nfnl_exp_get_id(exp))); + + if (nfnl_exp_test_timeout(exp)) + NLA_PUT_U32(msg, CTA_EXPECT_TIMEOUT, htonl(nfnl_exp_get_timeout(exp))); + + if (nfnl_exp_test_helper_name(exp)) + NLA_PUT_STRING(msg, CTA_EXPECT_HELP_NAME, nfnl_exp_get_helper_name(exp)); + *result = msg; return 0; @@ -469,18 +412,18 @@ err_out: return err; } -int nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags, +int nfnl_exp_build_add_request(const struct nfnl_exp *exp, int flags, struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result); + return nfnl_exp_build_message(exp, IPCTNL_MSG_EXP_NEW, flags, result); } -int nfnl_ct_add(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) +int nfnl_exp_add(struct nl_sock *sk, const struct nfnl_exp *exp, int flags) { struct nl_msg *msg; int err; - if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0) + if ((err = nfnl_exp_build_add_request(exp, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); @@ -491,18 +434,18 @@ int nfnl_ct_add(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) return wait_for_ack(sk); } -int nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags, +int nfnl_exp_build_delete_request(const struct nfnl_exp *exp, int flags, struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result); + return nfnl_exp_build_message(exp, IPCTNL_MSG_EXP_DELETE, flags, result); } -int nfnl_ct_del(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) +int nfnl_exp_del(struct nl_sock *sk, const struct nfnl_exp *exp, int flags) { struct nl_msg *msg; int err; - if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0) + if ((err = nfnl_exp_build_delete_request(exp, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); @@ -513,18 +456,18 @@ int nfnl_ct_del(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) return wait_for_ack(sk); } -int nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags, +int nfnl_exp_build_query_request(const struct nfnl_exp *exp, int flags, struct nl_msg **result) { - return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result); + return nfnl_exp_build_message(exp, IPCTNL_MSG_EXP_GET, flags, result); } -int nfnl_ct_query(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) +int nfnl_exp_query(struct nl_sock *sk, const struct nfnl_exp *exp, int flags) { struct nl_msg *msg; int err; - if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0) + if ((err = nfnl_exp_build_query_request(exp, flags, &msg)) < 0) return err; err = nl_send_auto_complete(sk, msg); @@ -541,61 +484,61 @@ int nfnl_ct_query(struct nl_sock *sk, const struct nfnl_ct *ct, int flags) */ /** - * Build a conntrack cache holding all conntrack currently in the kernel + * Build a expectation cache holding all expectations currently in the kernel * @arg sk Netlink socket. * @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. + * contain all expectations currently in the kernel. * * @return 0 on success or a negative error code. */ -int nfnl_ct_alloc_cache(struct nl_sock *sk, struct nl_cache **result) +int nfnl_exp_alloc_cache(struct nl_sock *sk, struct nl_cache **result) { - return nl_cache_alloc_and_fill(&nfnl_ct_ops, sk, result); + return nl_cache_alloc_and_fill(&nfnl_exp_ops, sk, result); } /** @} */ /** - * @name Conntrack Addition + * @name Expectation Addition * @{ */ /** @} */ -static struct nl_af_group ct_groups[] = { - { AF_UNSPEC, NFNLGRP_CONNTRACK_NEW }, - { AF_UNSPEC, NFNLGRP_CONNTRACK_UPDATE }, - { AF_UNSPEC, NFNLGRP_CONNTRACK_DESTROY }, +static struct nl_af_group exp_groups[] = { + { AF_UNSPEC, NFNLGRP_CONNTRACK_EXP_NEW }, + { AF_UNSPEC, NFNLGRP_CONNTRACK_EXP_UPDATE }, + { AF_UNSPEC, NFNLGRP_CONNTRACK_EXP_DESTROY }, { END_OF_GROUP_LIST }, }; -#define NFNLMSG_CT_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_CTNETLINK, (type)) -static struct nl_cache_ops nfnl_ct_ops = { - .co_name = "netfilter/ct", +#define NFNLMSG_EXP_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_CTNETLINK_EXP, (type)) +static struct nl_cache_ops nfnl_exp_ops = { + .co_name = "netfilter/exp", .co_hdrsize = NFNL_HDRLEN, .co_msgtypes = { - { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_NEW), NL_ACT_NEW, "new" }, - { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_GET), NL_ACT_GET, "get" }, - { NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_DELETE), NL_ACT_DEL, "del" }, + { NFNLMSG_CT_TYPE(IPCTNL_MSG_EXP_NEW), NL_ACT_NEW, "new" }, + { NFNLMSG_CT_TYPE(IPCTNL_MSG_EXP_GET), NL_ACT_GET, "get" }, + { NFNLMSG_CT_TYPE(IPCTNL_MSG_EXP_DELETE), NL_ACT_DEL, "del" }, END_OF_MSGTYPES_LIST, }, .co_protocol = NETLINK_NETFILTER, - .co_groups = ct_groups, - .co_request_update = ct_request_update, - .co_msg_parser = ct_msg_parser, - .co_obj_ops = &ct_obj_ops, + .co_groups = exp_groups, + .co_request_update = exp_request_update, + .co_msg_parser = exp_msg_parser, + .co_obj_ops = &exp_obj_ops, }; -static void __init ct_init(void) +static void __init exp_init(void) { - nl_cache_mngt_register(&nfnl_ct_ops); + nl_cache_mngt_register(&nfnl_exp_ops); } -static void __exit ct_exit(void) +static void __exit exp_exit(void) { - nl_cache_mngt_unregister(&nfnl_ct_ops); + nl_cache_mngt_unregister(&nfnl_exp_ops); } /** @} */ diff --git a/lib/netfilter/exp_obj.c b/lib/netfilter/exp_obj.c index 2a45f3e..160c939 100644 --- a/lib/netfilter/exp_obj.c +++ b/lib/netfilter/exp_obj.c @@ -33,9 +33,9 @@ #define EXP_ATTR_ID (1UL << 2) // 32-bit #define EXP_ATTR_HELPER_NAME (1UL << 3) // string (16 bytes max) #define EXP_ATTR_ZONE (1UL << 4) // 16-bit -#define EXP_ATTR_CLASS (1UL << 5) // 32-bit +#define EXP_ATTR_CLASS (1UL << 5) // 32-bit ??? #define EXP_ATTR_FLAGS (1UL << 6) // 32-bit -#define EXP_ATTR_FN (1UL << 7) // String +#define EXP_ATTR_FN (1UL << 7) // String ??? // Tuples #define EXP_ATTR_EXPECT_IP_SRC (1UL << 8) @@ -59,7 +59,7 @@ #define EXP_ATTR_NAT_L4PROTO_PORTS (1UL << 26) #define EXP_ATTR_NAT_L4PROTO_ICMP (1UL << 27) -#define EXP_ATTR_NAT_DIR (1UL << 28) +#define EXP_ATTR_NAT_DIR (1UL << 28) // 8-bit /** @endcond */ static void exp_free_data(struct nl_object *c) @@ -150,7 +150,7 @@ static int exp_clone(struct nl_object *_dst, struct nl_object *_src) } if (src->exp_fn) - dst->exp_fn = strdup(src->exp_fn) + dst->exp_fn = strdup(src->exp_fn); if (src->exp_helper_name) dst->exp_helper_name = strdup(src->exp_helper_name); @@ -171,23 +171,26 @@ static void dump_addr(struct nl_dump_params *p, struct nl_addr *addr, int port) nl_dump(p, " "); } -static void dump_icmp(struct nl_dump_params *p, struct nfnl_ct *ct, int tuple) +static void dump_icmp(struct nl_dump_params *p, struct nfnl_exp *exp, int tuple) { - nl_dump(p, "icmp type %d ", nfnl_exp_get_icmp_type(ct, tuple)); + if (nfnl_exp_test_icmp(exp, tuple)) { - nl_dump(p, "code %d ", nfnl_exp_get_icmp_code(ct, tuple)); + nl_dump(p, "icmp type %d ", nfnl_exp_get_icmp_type(exp, tuple)); - nl_dump(p, "id %d ", nfnl_exp_get_icmp_id(ct, tuple)); + nl_dump(p, "code %d ", nfnl_exp_get_icmp_code(exp, tuple)); + + nl_dump(p, "id %d ", nfnl_exp_get_icmp_id(exp, tuple)); + } } -static void ct_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p) +static void exp_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p) { struct nl_addr *tuple_src, *tuple_dst; int tuple_sport = 0, tuple_dport = 0; - int i = NFNL_EXP_TUPLE_EXPECT; - int icmp = 0; + int i = 0; + char buf[64]; - for (i; i <= NFNL_EXP_TUPLE_NAT; i++) { + for (i = NFNL_EXP_TUPLE_EXPECT; i <= NFNL_EXP_TUPLE_NAT; i++) { // Test needed for NAT case if (nfnl_exp_test_src(exp, i)) @@ -196,65 +199,68 @@ static void ct_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p) tuple_dst = nfnl_exp_get_dst(exp, i); // Don't have tests for individual ports/types/codes/ids, - // just test L4 Proto. Ugly, but can't do much else without - // more mask bits - - if (nfnl_exp_test_l4proto(exp, i)) { - int l4proto = nfnl_exp_get_l4proto(exp, i); - if ( !(l4proto == IPPROTO_ICMP || - l4proto == IPPROTO_ICMPV6) ) { - tuple_sport = nfnl_exp_get_src_port(exp, i); - tuple_dport = nfnl_exp_get_dst_port(exp, i); - } else { - icmp = 1; - } + if (nfnl_exp_test_l4protonum(exp)) { + nl_dump(p, "%s ", + nl_ip_proto2str(nfnl_exp_get_l4protonum(exp), buf, sizeof(buf))); + } + + if (nfnl_exp_test_ports(exp, i)) { + tuple_sport = nfnl_exp_get_src_port(exp, i); + tuple_dport = nfnl_exp_get_dst_port(exp, i); } dump_addr(p, tuple_src, tuple_sport); dump_addr(p, tuple_dst, tuple_dport); - if (icmp) - dump_icmp(p, exp, 0); + dump_icmp(p, exp, 0); } + + if (nfnl_exp_test_nat_dir(exp)) + nl_dump(p, "nat dir %s ", exp->exp_nat_dir); + } -/* Compatible with /proc/net/nf_conntrack */ -static void ct_dump_line(struct nl_object *a, struct nl_dump_params *p) +/* FIXME Compatible with /proc/net/nf_conntrack */ +static void exp_dump_line(struct nl_object *a, struct nl_dump_params *p) { - struct nfnl_ct *ct = (struct nfnl_ct *) a; - char buf[64]; + struct nfnl_exp *exp = (struct nfnl_exp *) a; nl_new_line(p); - if (nfnl_ct_test_proto(ct)) - nl_dump(p, "%s ", - nl_ip_proto2str(nfnl_ct_get_proto(ct), buf, sizeof(buf))); - - ct_dump_tuples(ct, p); + exp_dump_tuples(exp, p); nl_dump(p, "\n"); } -static void ct_dump_details(struct nl_object *a, struct nl_dump_params *p) +static void exp_dump_details(struct nl_object *a, struct nl_dump_params *p) { - struct nfnl_ct *ct = (struct nfnl_ct *) a; + struct nfnl_exp *exp = (struct nfnl_exp *) a; char buf[64]; int fp = 0; ct_dump_line(a, p); - nl_dump(p, " id 0x%x ", ct->ct_id); + nl_dump(p, " id 0x%x ", exp->exp_id); nl_dump_line(p, "family %s ", - nl_af2str(ct->ct_family, buf, sizeof(buf))); - - if (nfnl_ct_test_use(ct)) - nl_dump(p, "refcnt %u ", nfnl_ct_get_use(ct)); + nl_af2str(exp->exp_family, buf, sizeof(buf))); - if (nfnl_ct_test_timeout(ct)) { - uint64_t timeout_ms = nfnl_ct_get_timeout(ct) * 1000UL; + if (nfnl_exp_test_timeout(exp)) { + uint64_t timeout_ms = nfnl_ct_get_timeout(exp) * 1000UL; nl_dump(p, "timeout %s ", nl_msec2str(timeout_ms, buf, sizeof(buf))); } - if (ct->ct_status) + if (nfnl_exp_test_helper_name(exp)) + nl_dump(p, "helper %s ", exp->exp_helper_name); + + if (nfnl_exp_test_fn(exp)) + nl_dump(p, "fn %s ", exp->exp_fn); + + if (nfnl_exp_test_zone(exp)) + nl_dump(p, "zone %u ", nfnl_exp_get_zone(exp)); + + if (nfnl_exp_test_class(exp)) + nl_dump(p, "class %u ", nfnl_exp_get_class(exp)); + + if (nfnl_exp_test_flags(exp)) nl_dump(p, "<"); #define PRINT_FLAG(str) \ @@ -268,7 +274,7 @@ static void ct_dump_details(struct nl_object *a, struct nl_dump_params *p) PRINT_FLAG("USERSPACE"); #undef PRINT_FLAG - if (exp->exp_flags) + if (nfnl_exp_test_flags(exp)) nl_dump(p, ">"); nl_dump(p, "\n"); } @@ -360,23 +366,23 @@ static int exp_compare(struct nl_object *_a, struct nl_object *_b, diff |= EXP_DIFF_L4PROTO_PORTS(EXPECT_L4PROTO_PORTS, exp_expect.proto.l4protodata.port); diff |= EXP_DIFF_L4PROTO_ICMP(EXPECT_L4PROTO_ICMP, exp_expect.proto.l4protodata.icmp); - diff |= EXP_DIFF_ADDR(MASTER_IP_SRC, exp_master.src); - diff |= EXP_DIFF_ADDR(MASTER_IP_DST, exp_master.dst); + diff |= EXP_DIFF_ADDR(MASTER_IP_SRC, exp_master.src); + diff |= EXP_DIFF_ADDR(MASTER_IP_DST, exp_master.dst); diff |= EXP_DIFF_VAL(MASTER_L4PROTO_NUM, exp_master.proto.l4protonum); diff |= EXP_DIFF_L4PROTO_PORTS(MASTER_L4PROTO_PORTS, exp_master.proto.l4protodata.port); - diff |= EXP_DIFF_L4PROTO_ICMP(MASTER_L4PROTO_ICMP, exp_master.proto.l4protodata.icmp); + diff |= EXP_DIFF_L4PROTO_ICMP(MASTER_L4PROTO_ICMP, exp_master.proto.l4protodata.icmp); - diff |= EXP_DIFF_ADDR(MASK_IP_SRC, exp_mask.src); - diff |= EXP_DIFF_ADDR(MASK_IP_DST, exp_mask.dst); + diff |= EXP_DIFF_ADDR(MASK_IP_SRC, exp_mask.src); + diff |= EXP_DIFF_ADDR(MASK_IP_DST, exp_mask.dst); diff |= EXP_DIFF_VAL(MASK_L4PROTO_NUM, exp_mask.proto.l4protonum); diff |= EXP_DIFF_L4PROTO_PORTS(MASK_L4PROTO_PORTS, exp_mask.proto.l4protodata.port); - diff |= EXP_DIFF_L4PROTO_ICMP(MASK_L4PROTO_ICMP, exp_mask.proto.l4protodata.icmp); + diff |= EXP_DIFF_L4PROTO_ICMP(MASK_L4PROTO_ICMP, exp_mask.proto.l4protodata.icmp); - diff |= EXP_DIFF_ADDR(NAT_IP_SRC, exp_nat.src); - diff |= EXP_DIFF_ADDR(NAT_IP_DST, exp_nat.dst); + diff |= EXP_DIFF_ADDR(NAT_IP_SRC, exp_nat.src); + diff |= EXP_DIFF_ADDR(NAT_IP_DST, exp_nat.dst); diff |= EXP_DIFF_VAL(NAT_L4PROTO_NUM, exp_nat.proto.l4protonum); diff |= EXP_DIFF_L4PROTO_PORTS(NAT_L4PROTO_PORTS, exp_nat.proto.l4protodata.port); - diff |= EXP_DIFF_L4PROTO_ICMP(NAT_L4PROTO_ICMP, exp_nat.proto.l4protodata.icmp); + diff |= EXP_DIFF_L4PROTO_ICMP(NAT_L4PROTO_ICMP, exp_nat.proto.l4protodata.icmp); #undef EXP_DIFF #undef EXP_DIFF_VAL @@ -390,35 +396,35 @@ static int exp_compare(struct nl_object *_a, struct nl_object *_b, // CLI arguments? static const struct trans_tbl exp_attrs[] = { - __ADD(EXP_ATTR_FAMILY, family) - __ADD(EXP_ATTR_TIMEOUT, timeout) - __ADD(EXP_ATTR_ID, id) - __ADD(EXP_ATTR_HELPER_NAME, helpername) - __ADD(EXP_ATTR_ZONE, zone) - __ADD(EXP_ATTR_CLASS, class) - __ADD(EXP_ATTR_FLAGS, flags) - __ADD(EXP_ATTR_FN, function) - __ADD(EXP_ATTR_EXPECT_IP_SRC, expectipsrc) - __ADD(EXP_ATTR_EXPECT_IP_DST, expectipdst) - __ADD(EXP_ATTR_EXPECT_L4PROTO_NUM, expectprotonum) - __ADD(EXP_ATTR_EXPECT_L4PROTO_PORTS,expectports) - __ADD(EXP_ATTR_EXPECT_L4PROTO_ICMP ,expecticmp) - __ADD(EXP_ATTR_MASTER_IP_SRC, masteripsrc) - __ADD(EXP_ATTR_MASTER_IP_DST, masteripdst) - __ADD(EXP_ATTR_MASTER_L4PROTO_NUM, masterprotonum) - __ADD(EXP_ATTR_MASTER_L4PROTO_PORTS,masterports) - __ADD(EXP_ATTR_MASTER_L4PROTO_ICMP ,mastericmp) - __ADD(EXP_ATTR_MASK_IP_SRC, maskipsrc) - __ADD(EXP_ATTR_MASK_IP_DST, maskipdst) - __ADD(EXP_ATTR_MASK_L4PROTO_NUM, maskprotonum) - __ADD(EXP_ATTR_MASK_L4PROTO_PORTS, maskports) - __ADD(EXP_ATTR_MASK_L4PROTO_ICMP , maskicmp) - __ADD(EXP_ATTR_NAT_IP_SRC, natipsrc) - __ADD(EXP_ATTR_NAT_IP_DST, natipdst) - __ADD(EXP_ATTR_NAT_L4PROTO_NUM, natprotonum) - __ADD(EXP_ATTR_NAT_L4PROTO_PORTS, natports) - __ADD(EXP_ATTR_NAT_L4PROTO_ICMP, naticmp) - __ADD(EXP_ATTR_NAT_DIR, natdir) + __ADD(EXP_ATTR_FAMILY, family) + __ADD(EXP_ATTR_TIMEOUT, timeout) + __ADD(EXP_ATTR_ID, id) + __ADD(EXP_ATTR_HELPER_NAME, helpername) + __ADD(EXP_ATTR_ZONE, zone) + __ADD(EXP_ATTR_CLASS, class) + __ADD(EXP_ATTR_FLAGS, flags) + __ADD(EXP_ATTR_FN, function) + __ADD(EXP_ATTR_EXPECT_IP_SRC, expectipsrc) + __ADD(EXP_ATTR_EXPECT_IP_DST, expectipdst) + __ADD(EXP_ATTR_EXPECT_L4PROTO_NUM, expectprotonum) + __ADD(EXP_ATTR_EXPECT_L4PROTO_PORTS, expectports) + __ADD(EXP_ATTR_EXPECT_L4PROTO_ICMP , expecticmp) + __ADD(EXP_ATTR_MASTER_IP_SRC, masteripsrc) + __ADD(EXP_ATTR_MASTER_IP_DST, masteripdst) + __ADD(EXP_ATTR_MASTER_L4PROTO_NUM, masterprotonum) + __ADD(EXP_ATTR_MASTER_L4PROTO_PORTS, masterports) + __ADD(EXP_ATTR_MASTER_L4PROTO_ICMP , mastericmp) + __ADD(EXP_ATTR_MASK_IP_SRC, maskipsrc) + __ADD(EXP_ATTR_MASK_IP_DST, maskipdst) + __ADD(EXP_ATTR_MASK_L4PROTO_NUM, maskprotonum) + __ADD(EXP_ATTR_MASK_L4PROTO_PORTS, maskports) + __ADD(EXP_ATTR_MASK_L4PROTO_ICMP , maskicmp) + __ADD(EXP_ATTR_NAT_IP_SRC, natipsrc) + __ADD(EXP_ATTR_NAT_IP_DST, natipdst) + __ADD(EXP_ATTR_NAT_L4PROTO_NUM, natprotonum) + __ADD(EXP_ATTR_NAT_L4PROTO_PORTS, natports) + __ADD(EXP_ATTR_NAT_L4PROTO_ICMP, naticmp) + __ADD(EXP_ATTR_NAT_DIR, natdir) }; static char *exp_attrs2str(int attrs, char *buf, size_t len) @@ -533,6 +539,112 @@ uint32_t nfnl_exp_get_id(const struct nfnl_exp *exp) return exp->exp_id; } +int nfnl_exp_set_helper_name(struct nfnl_exp *exp, void *name) +{ + free(exp->exp_helper_name); + exp->exp_helper_name = strdup(name); + if (!exp->exp_helper_name) + return -NLE_NOMEM; + + exp->ce_mask |= EXP_ATTR_HELPER_NAME; + return 0; +} + +int nfnl_exp_test_helper_name(const struct nfnl_exp *exp) +{ + return !!(exp->ce_mask & EXP_ATTR_HELPER_NAME); +} + +const char * nfnl_exp_get_helper_name(const struct nfnl_exp *exp) +{ + return exp->exp_helper_name; +} + +void nfnl_exp_set_zone(struct nfnl_exp *exp, uint16_t zone) +{ + exp->exp_zone = zone; + exp->ce_mask |= EXP_ATTR_ZONE; +} + +int nfnl_exp_test_zone(const struct nfnl_exp *exp) +{ + return !!(exp->ce_mask & EXP_ATTR_ZONE); +} + +uint16_t nfnl_exp_get_zone(const struct nfnl_exp *exp) +{ + return exp->exp_zone; +} + +void nfnl_exp_set_class(struct nfnl_exp *exp, uint32_t class) +{ + exp->exp_class = class; + exp->ce_mask |= EXP_ATTR_CLASS; +} + +int nfnl_exp_test_class(const struct nfnl_exp *exp) +{ + return !!(exp->ce_mask & EXP_ATTR_CLASS); +} + +uint32_t nfnl_exp_get_class(const struct nfnl_exp *exp) +{ + return exp->exp_class; +} + +void nfnl_exp_set_flags(struct nfnl_exp *exp, uint32_t flags) +{ + exp->exp_flags = flags; + exp->ce_mask |= EXP_ATTR_FLAGS; +} + +int nfnl_exp_test_flags(const struct nfnl_exp *exp) +{ + return !!(exp->ce_mask & EXP_ATTR_FLAGS); +} + +uint32_t nfnl_exp_get_flags(const struct nfnl_exp *exp) +{ + return exp->exp_flags; +} + +int nfnl_exp_set_fn(struct nfnl_exp *exp, void *fn) +{ + free(exp->exp_fn); + exp->exp_fn = strdup(fn); + if (!exp->exp_fn) + return -NLE_NOMEM; + + exp->ce_mask |= EXP_ATTR_FN; + return 0; +} + +int nfnl_exp_test_fn(const struct nfnl_exp *exp) +{ + return !!(exp->ce_mask & EXP_ATTR_FN); +} + +const char * nfnl_exp_get_fn(const struct nfnl_exp *exp) +{ + return exp->exp_fn; +} + +void nfnl_exp_set_nat_dir(struct nfnl_exp *exp, uint8_t nat_dir) +{ + exp->exp_nat_dir = nat_dir; + exp->ce_mask |= EXP_ATTR_NAT_DIR; +} + +int nfnl_exp_test_nat_dir(const struct nfnl_exp *exp) +{ + return !!(exp->ce_mask & EXP_ATTR_NAT_DIR); +} + +uint8_t nfnl_exp_get_nat_dir(const struct nfnl_exp *exp) +{ + return exp->exp_nat_dir; +} + static struct nfnl_exp_dir *exp_get_dir(struct nfnl_exp *exp, int tuple) { struct nfnl_exp_dir *dir = NULL; @@ -729,7 +841,7 @@ static int exp_get_l4ports_attr(int tuple) return attr; } -void nfnl_exp_set_src_ports(struct nfnl_exp *exp, int tuple, uint16_t srcport, uint16_t dstport) +void nfnl_exp_set_ports(struct nfnl_exp *exp, int tuple, uint16_t srcport, uint16_t dstport) { struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple); @@ -780,7 +892,7 @@ static int exp_get_l4icmp_attr(int tuple) return attr; } -void nfnl_ct_set_icmp(struct nfnl_exp *exp, int tuple, uint16_t id, uint8_t type, uint8_t, code) +void nfnl_exp_set_icmp(struct nfnl_exp *exp, int tuple, uint16_t id, uint8_t type, uint8_t, code) { struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple); @@ -791,61 +903,31 @@ void nfnl_ct_set_icmp(struct nfnl_exp *exp, int tuple, uint16_t id, uint8_t type exp->ce_mask |= exp_get_l4icmp_attr(tuple); } -int nfnl_ct_test_icmp_id(const struct nfnl_ct *ct, int repl) +int nfnl_exp_test_icmp(const struct nfnl_exp *exp, int tuple) { - int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; - return !!(ct->ce_mask & attr); + int attr = exp_get_l4icmp_attr(tuple); + return !!(exp->ce_mask & attr); } -uint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *ct, int repl) +uint16_t nfnl_exp_get_icmp_id(const struct nfnl_exp *exp, int tuple) { - const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; - - return dir->proto.icmp.id; -} - -void nfnl_ct_set_icmp_type(struct nfnl_ct *ct, int repl, uint8_t type) -{ - struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; - int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; - - dir->proto.icmp.type = type; - ct->ce_mask |= attr; -} - -int nfnl_ct_test_icmp_type(const struct nfnl_ct *ct, int repl) -{ - int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; - return !!(ct->ce_mask & attr); -} - -uint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *ct, int repl) -{ - const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; + const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple); - return dir->proto.icmp.type; + return dir->proto.l4protodata.icmp.id; } -void nfnl_ct_set_icmp_code(struct nfnl_ct *ct, int repl, uint8_t code) +uint8_t nfnl_exp_get_icmp_type(const struct nfnl_exp *exp, int tuple) { - struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; - int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; + const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple); - dir->proto.icmp.code = code; - ct->ce_mask |= attr; + return dir->proto.l4protodata.icmp.type; } -int nfnl_ct_test_icmp_code(const struct nfnl_ct *ct, int repl) +uint8_t nfnl_ct_get_icmp_code(const struct nfnl_exp *exp, int tuple) { - int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; - return !!(ct->ce_mask & attr); -} - -uint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *ct, int tuple) -{ - const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; + const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple); - return dir->proto.icmp.code; + return dir->proto.l4protodata.icmp.code; } /** @} */ @@ -858,7 +940,6 @@ struct nl_object_ops exp_obj_ops = { .oo_dump = { [NL_DUMP_LINE] = exp_dump_line, [NL_DUMP_DETAILS] = exp_dump_details, - [NL_DUMP_STATS] = exp_dump_stats, }, .oo_compare = exp_compare, .oo_attrs2str = exp_attrs2str, |