13#include <linux/netfilter/nfnetlink_conntrack.h>
14#include <linux/netfilter/nf_conntrack_common.h>
16#include <linux/netfilter/nf_conntrack_tcp.h>
18#include <netlink/netfilter/nfnl.h>
19#include <netlink/netfilter/exp.h>
21#include "nl-priv-dynamic-core/object-api.h"
22#include "nl-netfilter.h"
23#include "nl-priv-dynamic-core/nl-core.h"
32#define EXP_ATTR_FAMILY (1UL << 0)
33#define EXP_ATTR_TIMEOUT (1UL << 1)
34#define EXP_ATTR_ID (1UL << 2)
35#define EXP_ATTR_HELPER_NAME (1UL << 3)
36#define EXP_ATTR_ZONE (1UL << 4)
37#define EXP_ATTR_FLAGS (1UL << 5)
38#define EXP_ATTR_CLASS (1UL << 6)
39#define EXP_ATTR_FN (1UL << 7)
41#define EXP_ATTR_EXPECT_IP_SRC (1UL << 8)
42#define EXP_ATTR_EXPECT_IP_DST (1UL << 9)
43#define EXP_ATTR_EXPECT_L4PROTO_NUM (1UL << 10)
44#define EXP_ATTR_EXPECT_L4PROTO_PORTS (1UL << 11)
45#define EXP_ATTR_EXPECT_L4PROTO_ICMP (1UL << 12)
46#define EXP_ATTR_MASTER_IP_SRC (1UL << 13)
47#define EXP_ATTR_MASTER_IP_DST (1UL << 14)
48#define EXP_ATTR_MASTER_L4PROTO_NUM (1UL << 15)
49#define EXP_ATTR_MASTER_L4PROTO_PORTS (1UL << 16)
50#define EXP_ATTR_MASTER_L4PROTO_ICMP (1UL << 17)
51#define EXP_ATTR_MASK_IP_SRC (1UL << 18)
52#define EXP_ATTR_MASK_IP_DST (1UL << 19)
53#define EXP_ATTR_MASK_L4PROTO_NUM (1UL << 20)
54#define EXP_ATTR_MASK_L4PROTO_PORTS (1UL << 21)
55#define EXP_ATTR_MASK_L4PROTO_ICMP (1UL << 22)
56#define EXP_ATTR_NAT_IP_SRC (1UL << 23)
57#define EXP_ATTR_NAT_IP_DST (1UL << 24)
58#define EXP_ATTR_NAT_L4PROTO_NUM (1UL << 25)
59#define EXP_ATTR_NAT_L4PROTO_PORTS (1UL << 26)
60#define EXP_ATTR_NAT_L4PROTO_ICMP (1UL << 27)
61#define EXP_ATTR_NAT_DIR (1UL << 28)
64static void exp_free_data(
struct nl_object *c)
81 free(exp->exp_helper_name);
84static int exp_clone(
struct nl_object *_dst,
struct nl_object *_src)
90 dst->exp_helper_name = NULL;
92 dst->exp_expect.src = NULL;
93 dst->exp_expect.dst = NULL;
94 dst->exp_master.src = NULL;
95 dst->exp_master.dst = NULL;
96 dst->exp_mask.src = NULL;
97 dst->exp_mask.dst = NULL;
98 dst->exp_nat.src = NULL;
99 dst->exp_nat.dst = NULL;
101 if (src->exp_expect.src) {
105 dst->exp_expect.src = addr;
108 if (src->exp_expect.dst) {
112 dst->exp_expect.dst = addr;
115 if (src->exp_master.src) {
119 dst->exp_master.src = addr;
122 if (src->exp_master.dst) {
126 dst->exp_master.dst = addr;
129 if (src->exp_mask.src) {
133 dst->exp_mask.src = addr;
136 if (src->exp_mask.dst) {
140 dst->exp_mask.dst = addr;
143 if (src->exp_nat.src) {
147 dst->exp_nat.src = addr;
150 if (src->exp_nat.dst) {
154 dst->exp_nat.dst = addr;
158 dst->exp_fn = strdup(src->exp_fn);
160 if (src->exp_helper_name)
161 dst->exp_helper_name = strdup(src->exp_helper_name);
166static void dump_addr(
struct nl_dump_params *p,
struct nl_addr *addr,
int port)
181 if (nfnl_exp_test_icmp(exp, tuple)) {
183 nl_dump(p,
"icmp type %d ", nfnl_exp_get_icmp_type(exp, tuple));
185 nl_dump(p,
"code %d ", nfnl_exp_get_icmp_code(exp, tuple));
187 nl_dump(p,
"id %d ", nfnl_exp_get_icmp_id(exp, tuple));
193 struct nl_addr *tuple_src, *tuple_dst;
194 int tuple_sport, tuple_dport;
198 for (i = NFNL_EXP_TUPLE_EXPECT; i < NFNL_EXP_TUPLE_MAX; i++) {
205 if (nfnl_exp_test_src(exp, i))
206 tuple_src = nfnl_exp_get_src(exp, i);
207 if (nfnl_exp_test_dst(exp, i))
208 tuple_dst = nfnl_exp_get_dst(exp, i);
211 if (nfnl_exp_test_l4protonum(exp, i)) {
213 nl_ip_proto2str(nfnl_exp_get_l4protonum(exp, i), buf,
sizeof(buf)));
216 if (nfnl_exp_test_ports(exp, i)) {
217 tuple_sport = nfnl_exp_get_src_port(exp, i);
218 tuple_dport = nfnl_exp_get_dst_port(exp, i);
221 dump_addr(p, tuple_src, tuple_sport);
222 dump_addr(p, tuple_dst, tuple_dport);
223 dump_icmp(p, exp, 0);
226 if (nfnl_exp_test_nat_dir(exp))
227 nl_dump(p,
"nat dir %u ", exp->exp_nat_dir);
232static void exp_dump_line(
struct nl_object *a,
struct nl_dump_params *p)
238 exp_dump_tuples(exp, p);
243static void exp_dump_details(
struct nl_object *a,
struct nl_dump_params *p)
251 nl_dump(p,
" id 0x%x ", exp->exp_id);
252 nl_dump_line(p,
"family %s ",
253 nl_af2str(exp->exp_family, buf,
sizeof(buf)));
255 if (nfnl_exp_test_timeout(exp)) {
256 uint64_t timeout_ms = nfnl_exp_get_timeout(exp) * 1000UL;
261 if (nfnl_exp_test_helper_name(exp))
262 nl_dump(p,
"helper %s ", exp->exp_helper_name);
264 if (nfnl_exp_test_fn(exp))
265 nl_dump(p,
"fn %s ", exp->exp_fn);
267 if (nfnl_exp_test_class(exp))
268 nl_dump(p,
"class %u ", nfnl_exp_get_class(exp));
270 if (nfnl_exp_test_zone(exp))
271 nl_dump(p,
"zone %u ", nfnl_exp_get_zone(exp));
273 if (nfnl_exp_test_flags(exp))
275#define PRINT_FLAG(str) \
276 { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); }
278 if (exp->exp_flags & NF_CT_EXPECT_PERMANENT)
279 PRINT_FLAG(
"PERMANENT");
280 if (exp->exp_flags & NF_CT_EXPECT_INACTIVE)
281 PRINT_FLAG(
"INACTIVE");
282 if (exp->exp_flags & NF_CT_EXPECT_USERSPACE)
283 PRINT_FLAG(
"USERSPACE");
286 if (nfnl_exp_test_flags(exp))
295 d = ( (a->port.src != b->port.src) ||
296 (a->port.dst != b->port.dst) );
304 d = ( (a->icmp.code != b->icmp.code) ||
305 (a->icmp.type != b->icmp.type) ||
306 (a->icmp.id != b->icmp.id) );
311static uint64_t exp_compare(
struct nl_object *_a,
struct nl_object *_b,
312 uint64_t attrs,
int flags)
318#define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
319#define _DIFF_VAL(ATTR, FIELD) _DIFF(ATTR, a->FIELD != b->FIELD)
320#define _DIFF_STRING(ATTR, FIELD) _DIFF(ATTR, (strcmp(a->FIELD, b->FIELD) != 0))
321#define _DIFF_ADDR(ATTR, FIELD) \
322 ((flags & LOOSE_COMPARISON) ? \
323 _DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) : \
324 _DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD)))
325#define _DIFF_L4PROTO_PORTS(ATTR, FIELD) \
326 _DIFF(ATTR, exp_cmp_l4proto_ports(&(a->FIELD), &(b->FIELD)))
327#define _DIFF_L4PROTO_ICMP(ATTR, FIELD) \
328 _DIFF(ATTR, exp_cmp_l4proto_icmp(&(a->FIELD), &(b->FIELD)))
329 diff |= _DIFF_VAL(EXP_ATTR_FAMILY, exp_family);
330 diff |= _DIFF_VAL(EXP_ATTR_TIMEOUT, exp_timeout);
331 diff |= _DIFF_VAL(EXP_ATTR_ID, exp_id);
332 diff |= _DIFF_VAL(EXP_ATTR_ZONE, exp_zone);
333 diff |= _DIFF_VAL(EXP_ATTR_CLASS, exp_class);
334 diff |= _DIFF_VAL(EXP_ATTR_FLAGS, exp_flags);
335 diff |= _DIFF_VAL(EXP_ATTR_NAT_DIR, exp_nat_dir);
337 diff |= _DIFF_STRING(EXP_ATTR_FN, exp_fn);
338 diff |= _DIFF_STRING(EXP_ATTR_HELPER_NAME, exp_helper_name);
340 diff |= _DIFF_ADDR(EXP_ATTR_EXPECT_IP_SRC, exp_expect.src);
341 diff |= _DIFF_ADDR(EXP_ATTR_EXPECT_IP_DST, exp_expect.dst);
342 diff |= _DIFF_VAL(EXP_ATTR_EXPECT_L4PROTO_NUM,
343 exp_expect.proto.l4protonum);
344 diff |= _DIFF_L4PROTO_PORTS(EXP_ATTR_EXPECT_L4PROTO_PORTS,
345 exp_expect.proto.l4protodata);
346 diff |= _DIFF_L4PROTO_ICMP(EXP_ATTR_EXPECT_L4PROTO_ICMP,
347 exp_expect.proto.l4protodata);
349 diff |= _DIFF_ADDR(EXP_ATTR_MASTER_IP_SRC, exp_master.src);
350 diff |= _DIFF_ADDR(EXP_ATTR_MASTER_IP_DST, exp_master.dst);
351 diff |= _DIFF_VAL(EXP_ATTR_MASTER_L4PROTO_NUM,
352 exp_master.proto.l4protonum);
353 diff |= _DIFF_L4PROTO_PORTS(EXP_ATTR_MASTER_L4PROTO_PORTS,
354 exp_master.proto.l4protodata);
355 diff |= _DIFF_L4PROTO_ICMP(EXP_ATTR_MASTER_L4PROTO_ICMP,
356 exp_master.proto.l4protodata);
358 diff |= _DIFF_ADDR(EXP_ATTR_MASK_IP_SRC, exp_mask.src);
359 diff |= _DIFF_ADDR(EXP_ATTR_MASK_IP_DST, exp_mask.dst);
360 diff |= _DIFF_VAL(EXP_ATTR_MASK_L4PROTO_NUM, exp_mask.proto.l4protonum);
361 diff |= _DIFF_L4PROTO_PORTS(EXP_ATTR_MASK_L4PROTO_PORTS,
362 exp_mask.proto.l4protodata);
363 diff |= _DIFF_L4PROTO_ICMP(EXP_ATTR_MASK_L4PROTO_ICMP,
364 exp_mask.proto.l4protodata);
366 diff |= _DIFF_ADDR(EXP_ATTR_NAT_IP_SRC, exp_nat.src);
367 diff |= _DIFF_ADDR(EXP_ATTR_NAT_IP_DST, exp_nat.dst);
368 diff |= _DIFF_VAL(EXP_ATTR_NAT_L4PROTO_NUM, exp_nat.proto.l4protonum);
369 diff |= _DIFF_L4PROTO_PORTS(EXP_ATTR_NAT_L4PROTO_PORTS,
370 exp_nat.proto.l4protodata);
371 diff |= _DIFF_L4PROTO_ICMP(EXP_ATTR_NAT_L4PROTO_ICMP,
372 exp_nat.proto.l4protodata);
377#undef _DIFF_L4PROTO_PORTS
378#undef _DIFF_L4PROTO_ICMP
384static const struct trans_tbl exp_attrs[] = {
385 __ADD(EXP_ATTR_FAMILY, family),
386 __ADD(EXP_ATTR_TIMEOUT, timeout),
387 __ADD(EXP_ATTR_ID,
id),
388 __ADD(EXP_ATTR_HELPER_NAME, helpername),
389 __ADD(EXP_ATTR_ZONE, zone),
390 __ADD(EXP_ATTR_CLASS,
class),
391 __ADD(EXP_ATTR_FLAGS, flags),
392 __ADD(EXP_ATTR_FN, function),
393 __ADD(EXP_ATTR_EXPECT_IP_SRC, expectipsrc),
394 __ADD(EXP_ATTR_EXPECT_IP_DST, expectipdst),
395 __ADD(EXP_ATTR_EXPECT_L4PROTO_NUM, expectprotonum),
396 __ADD(EXP_ATTR_EXPECT_L4PROTO_PORTS, expectports),
397 __ADD(EXP_ATTR_EXPECT_L4PROTO_ICMP, expecticmp),
398 __ADD(EXP_ATTR_MASTER_IP_SRC, masteripsrc),
399 __ADD(EXP_ATTR_MASTER_IP_DST, masteripdst),
400 __ADD(EXP_ATTR_MASTER_L4PROTO_NUM, masterprotonum),
401 __ADD(EXP_ATTR_MASTER_L4PROTO_PORTS, masterports),
402 __ADD(EXP_ATTR_MASTER_L4PROTO_ICMP, mastericmp),
403 __ADD(EXP_ATTR_MASK_IP_SRC, maskipsrc),
404 __ADD(EXP_ATTR_MASK_IP_DST, maskipdst),
405 __ADD(EXP_ATTR_MASK_L4PROTO_NUM, maskprotonum),
406 __ADD(EXP_ATTR_MASK_L4PROTO_PORTS, maskports),
407 __ADD(EXP_ATTR_MASK_L4PROTO_ICMP, maskicmp),
408 __ADD(EXP_ATTR_NAT_IP_SRC, natipsrc),
409 __ADD(EXP_ATTR_NAT_IP_DST, natipdst),
410 __ADD(EXP_ATTR_NAT_L4PROTO_NUM, natprotonum),
411 __ADD(EXP_ATTR_NAT_L4PROTO_PORTS, natports),
412 __ADD(EXP_ATTR_NAT_L4PROTO_ICMP, naticmp),
413 __ADD(EXP_ATTR_NAT_DIR, natdir),
416static char *exp_attrs2str(
int attrs,
char *buf,
size_t len)
418 return __flags2str(attrs, buf, len, exp_attrs, ARRAY_SIZE(exp_attrs));
426struct nfnl_exp *nfnl_exp_alloc(
void)
431void nfnl_exp_get(
struct nfnl_exp *exp)
436void nfnl_exp_put(
struct nfnl_exp *exp)
448void nfnl_exp_set_family(
struct nfnl_exp *exp, uint8_t family)
450 exp->exp_family = family;
451 exp->ce_mask |= EXP_ATTR_FAMILY;
454uint8_t nfnl_exp_get_family(
const struct nfnl_exp *exp)
456 if (exp->ce_mask & EXP_ATTR_FAMILY)
457 return exp->exp_family;
462void nfnl_exp_set_flags(
struct nfnl_exp *exp, uint32_t flags)
464 exp->exp_flags |= flags;
465 exp->ce_mask |= EXP_ATTR_FLAGS;
468int nfnl_exp_test_flags(
const struct nfnl_exp *exp)
470 return !!(exp->ce_mask & EXP_ATTR_FLAGS);
473void nfnl_exp_unset_flags(
struct nfnl_exp *exp, uint32_t flags)
475 exp->exp_flags &= ~flags;
476 exp->ce_mask |= EXP_ATTR_FLAGS;
479uint32_t nfnl_exp_get_flags(
const struct nfnl_exp *exp)
481 return exp->exp_flags;
484static const struct trans_tbl flag_table[] = {
485 __ADD(IPS_EXPECTED, expected),
486 __ADD(IPS_SEEN_REPLY, seen_reply),
487 __ADD(IPS_ASSURED, assured),
490char * nfnl_exp_flags2str(
int flags,
char *buf,
size_t len)
492 return __flags2str(flags, buf, len, flag_table,
493 ARRAY_SIZE(flag_table));
496int nfnl_exp_str2flags(
const char *name)
498 return __str2flags(name, flag_table, ARRAY_SIZE(flag_table));
501void nfnl_exp_set_timeout(
struct nfnl_exp *exp, uint32_t timeout)
503 exp->exp_timeout = timeout;
504 exp->ce_mask |= EXP_ATTR_TIMEOUT;
507int nfnl_exp_test_timeout(
const struct nfnl_exp *exp)
509 return !!(exp->ce_mask & EXP_ATTR_TIMEOUT);
512uint32_t nfnl_exp_get_timeout(
const struct nfnl_exp *exp)
514 return exp->exp_timeout;
517void nfnl_exp_set_id(
struct nfnl_exp *exp, uint32_t
id)
520 exp->ce_mask |= EXP_ATTR_ID;
523int nfnl_exp_test_id(
const struct nfnl_exp *exp)
525 return !!(exp->ce_mask & EXP_ATTR_ID);
528uint32_t nfnl_exp_get_id(
const struct nfnl_exp *exp)
533int nfnl_exp_set_helper_name(
struct nfnl_exp *exp,
void *name)
535 free(exp->exp_helper_name);
536 exp->exp_helper_name = strdup(name);
537 if (!exp->exp_helper_name)
540 exp->ce_mask |= EXP_ATTR_HELPER_NAME;
544int nfnl_exp_test_helper_name(
const struct nfnl_exp *exp)
546 return !!(exp->ce_mask & EXP_ATTR_HELPER_NAME);
549const char * nfnl_exp_get_helper_name(
const struct nfnl_exp *exp)
551 return exp->exp_helper_name;
554void nfnl_exp_set_zone(
struct nfnl_exp *exp, uint16_t zone)
556 exp->exp_zone = zone;
557 exp->ce_mask |= EXP_ATTR_ZONE;
560int nfnl_exp_test_zone(
const struct nfnl_exp *exp)
562 return !!(exp->ce_mask & EXP_ATTR_ZONE);
565uint16_t nfnl_exp_get_zone(
const struct nfnl_exp *exp)
567 return exp->exp_zone;
570void nfnl_exp_set_class(
struct nfnl_exp *exp, uint32_t
class)
572 exp->exp_class =
class;
573 exp->ce_mask |= EXP_ATTR_CLASS;
576int nfnl_exp_test_class(
const struct nfnl_exp *exp)
578 return !!(exp->ce_mask & EXP_ATTR_CLASS);
581uint32_t nfnl_exp_get_class(
const struct nfnl_exp *exp)
583 return exp->exp_class;
586int nfnl_exp_set_fn(
struct nfnl_exp *exp,
void *fn)
589 exp->exp_fn = strdup(fn);
593 exp->ce_mask |= EXP_ATTR_FN;
597int nfnl_exp_test_fn(
const struct nfnl_exp *exp)
599 return !!(exp->ce_mask & EXP_ATTR_FN);
602const char * nfnl_exp_get_fn(
const struct nfnl_exp *exp)
607void nfnl_exp_set_nat_dir(
struct nfnl_exp *exp, uint8_t nat_dir)
609 exp->exp_nat_dir = nat_dir;
610 exp->ce_mask |= EXP_ATTR_NAT_DIR;
613int nfnl_exp_test_nat_dir(
const struct nfnl_exp *exp)
615 return !!(exp->ce_mask & EXP_ATTR_NAT_DIR);
618uint8_t nfnl_exp_get_nat_dir(
const struct nfnl_exp *exp)
620 return exp->exp_nat_dir;
623#define EXP_GET_TUPLE(e, t) \
624 (t == NFNL_EXP_TUPLE_MASTER) ? \
626 (t == NFNL_EXP_TUPLE_MASK) ? \
628 (t == NFNL_EXP_TUPLE_NAT) ? \
629 &(e->exp_nat) : &(exp->exp_expect)
631static int exp_get_src_attr(
int tuple)
636 case NFNL_EXP_TUPLE_MASTER:
637 attr = EXP_ATTR_MASTER_IP_SRC;
639 case NFNL_EXP_TUPLE_MASK:
640 attr = EXP_ATTR_MASK_IP_SRC;
642 case NFNL_EXP_TUPLE_NAT:
643 attr = EXP_ATTR_NAT_IP_SRC;
645 case NFNL_EXP_TUPLE_EXPECT:
647 attr = EXP_ATTR_EXPECT_IP_SRC;
653static int exp_get_dst_attr(
int tuple)
658 case NFNL_EXP_TUPLE_MASTER:
659 attr = EXP_ATTR_MASTER_IP_DST;
661 case NFNL_EXP_TUPLE_MASK:
662 attr = EXP_ATTR_MASK_IP_DST;
664 case NFNL_EXP_TUPLE_NAT:
665 attr = EXP_ATTR_NAT_IP_DST;
667 case NFNL_EXP_TUPLE_EXPECT:
669 attr = EXP_ATTR_EXPECT_IP_DST;
676static int exp_set_addr(
struct nfnl_exp *exp,
struct nl_addr *addr,
677 int attr,
struct nl_addr ** exp_addr)
679 if (exp->ce_mask & EXP_ATTR_FAMILY) {
680 if (addr->a_family != exp->exp_family)
681 return -NLE_AF_MISMATCH;
683 nfnl_exp_set_family(exp, addr->a_family);
690 exp->ce_mask |= attr;
695int nfnl_exp_set_src(
struct nfnl_exp *exp,
int tuple,
struct nl_addr *addr)
699 return exp_set_addr(exp, addr, exp_get_src_attr(tuple), &dir->src);
702int nfnl_exp_set_dst(
struct nfnl_exp *exp,
int tuple,
struct nl_addr *addr)
706 return exp_set_addr(exp, addr, exp_get_dst_attr(tuple), &dir->dst);
709int nfnl_exp_test_src(
const struct nfnl_exp *exp,
int tuple)
711 return !!(exp->ce_mask & exp_get_src_attr(tuple));
714int nfnl_exp_test_dst(
const struct nfnl_exp *exp,
int tuple)
716 return !!(exp->ce_mask & exp_get_dst_attr(tuple));
719struct nl_addr *nfnl_exp_get_src(
const struct nfnl_exp *exp,
int tuple)
721 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
723 if (!(exp->ce_mask & exp_get_src_attr(tuple)))
728struct nl_addr *nfnl_exp_get_dst(
const struct nfnl_exp *exp,
int tuple)
730 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
732 if (!(exp->ce_mask & exp_get_dst_attr(tuple)))
737static int exp_get_l4protonum_attr(
int tuple)
742 case NFNL_EXP_TUPLE_MASTER:
743 attr = EXP_ATTR_MASTER_L4PROTO_NUM;
745 case NFNL_EXP_TUPLE_MASK:
746 attr = EXP_ATTR_MASK_L4PROTO_NUM;
748 case NFNL_EXP_TUPLE_NAT:
749 attr = EXP_ATTR_NAT_L4PROTO_NUM;
751 case NFNL_EXP_TUPLE_EXPECT:
753 attr = EXP_ATTR_EXPECT_L4PROTO_NUM;
759void nfnl_exp_set_l4protonum(
struct nfnl_exp *exp,
int tuple, uint8_t l4protonum)
763 dir->proto.l4protonum = l4protonum;
764 exp->ce_mask |= exp_get_l4protonum_attr(tuple);
767int nfnl_exp_test_l4protonum(
const struct nfnl_exp *exp,
int tuple)
769 return !!(exp->ce_mask & exp_get_l4protonum_attr(tuple));
772uint8_t nfnl_exp_get_l4protonum(
const struct nfnl_exp *exp,
int tuple)
774 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
775 return dir->proto.l4protonum;
778static int exp_get_l4ports_attr(
int tuple)
783 case NFNL_EXP_TUPLE_MASTER:
784 attr = EXP_ATTR_MASTER_L4PROTO_PORTS;
786 case NFNL_EXP_TUPLE_MASK:
787 attr = EXP_ATTR_MASK_L4PROTO_PORTS;
789 case NFNL_EXP_TUPLE_NAT:
790 attr = EXP_ATTR_NAT_L4PROTO_PORTS;
792 case NFNL_EXP_TUPLE_EXPECT:
794 attr = EXP_ATTR_EXPECT_L4PROTO_PORTS;
800void nfnl_exp_set_ports(
struct nfnl_exp *exp,
int tuple, uint16_t srcport, uint16_t dstport)
804 dir->proto.l4protodata.port.src = srcport;
805 dir->proto.l4protodata.port.dst = dstport;
807 exp->ce_mask |= exp_get_l4ports_attr(tuple);
810int nfnl_exp_test_ports(
const struct nfnl_exp *exp,
int tuple)
812 return !!(exp->ce_mask & exp_get_l4ports_attr(tuple));
815uint16_t nfnl_exp_get_src_port(
const struct nfnl_exp *exp,
int tuple)
817 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
818 return dir->proto.l4protodata.port.src;
821uint16_t nfnl_exp_get_dst_port(
const struct nfnl_exp *exp,
int tuple)
823 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
825 return dir->proto.l4protodata.port.dst;
828static int exp_get_l4icmp_attr(
int tuple)
833 case NFNL_EXP_TUPLE_MASTER:
834 attr = EXP_ATTR_MASTER_L4PROTO_ICMP;
836 case NFNL_EXP_TUPLE_MASK:
837 attr = EXP_ATTR_MASK_L4PROTO_ICMP;
839 case NFNL_EXP_TUPLE_NAT:
840 attr = EXP_ATTR_NAT_L4PROTO_ICMP;
842 case NFNL_EXP_TUPLE_EXPECT:
844 attr = EXP_ATTR_EXPECT_L4PROTO_ICMP;
850void nfnl_exp_set_icmp(
struct nfnl_exp *exp,
int tuple, uint16_t
id, uint8_t type, uint8_t code)
854 dir->proto.l4protodata.icmp.id = id;
855 dir->proto.l4protodata.icmp.type = type;
856 dir->proto.l4protodata.icmp.code = code;
858 exp->ce_mask |= exp_get_l4icmp_attr(tuple);
861int nfnl_exp_test_icmp(
const struct nfnl_exp *exp,
int tuple)
863 int attr = exp_get_l4icmp_attr(tuple);
864 return !!(exp->ce_mask & attr);
867uint16_t nfnl_exp_get_icmp_id(
const struct nfnl_exp *exp,
int tuple)
869 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
871 return dir->proto.l4protodata.icmp.id;
874uint8_t nfnl_exp_get_icmp_type(
const struct nfnl_exp *exp,
int tuple)
876 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
878 return dir->proto.l4protodata.icmp.type;
881uint8_t nfnl_exp_get_icmp_code(
const struct nfnl_exp *exp,
int tuple)
883 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
885 return dir->proto.l4protodata.icmp.code;
890struct nl_object_ops exp_obj_ops = {
891 .oo_name =
"netfilter/exp",
893 .oo_free_data = exp_free_data,
894 .oo_clone = exp_clone,
899 .oo_compare = exp_compare,
900 .oo_attrs2str = exp_attrs2str,
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
void nl_new_line(struct nl_dump_params *params)
Handle a new line while dumping.
char * nl_msec2str(uint64_t msec, char *buf, size_t len)
Convert milliseconds to a character string.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.