19fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai/*
29fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai * Definitions and Declarations for tuple.
39fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai *
49fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
59fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai *	- generalize L3 protocol dependent part.
69fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai *
79fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
89fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai */
99fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
109fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai#ifndef _NF_CONNTRACK_TUPLE_H
119fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai#define _NF_CONNTRACK_TUPLE_H
129fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
13643a2c15a407faf08101a20e1a3461160711899dJan Engelhardt#include <linux/netfilter/x_tables.h>
149fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai#include <linux/netfilter/nf_conntrack_tuple_common.h>
15ea781f197d6a835cbb93a0bf88ee1696296ed8aaEric Dumazet#include <linux/list_nulls.h>
169fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
179fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai/* A `tuple' is a structure containing the information to uniquely
189fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai  identify a connection.  ie. if two packets have the same tuple, they
199fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai  are in the same connection; if not, they are not.
209fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
219fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai  We divide the structure along "manipulatable" and
229fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai  "non-manipulatable" lines, for the benefit of the NAT code.
239fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai*/
249fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
25643a2c15a407faf08101a20e1a3461160711899dJan Engelhardt#define NF_CT_TUPLE_L3SIZE	ARRAY_SIZE(((union nf_inet_addr *)NULL)->all)
269fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
279fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai/* The manipulable part of the tuple. */
28fd2c3ef761fbc5e6c27fa7d40b30cda06bfcd7d8Eric Dumazetstruct nf_conntrack_man {
29643a2c15a407faf08101a20e1a3461160711899dJan Engelhardt	union nf_inet_addr u3;
309fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	union nf_conntrack_man_proto u;
319fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	/* Layer 3 protocol */
329fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	u_int16_t l3num;
339fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai};
349fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
359fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai/* This contains the information to distinguish a connection. */
36fd2c3ef761fbc5e6c27fa7d40b30cda06bfcd7d8Eric Dumazetstruct nf_conntrack_tuple {
379fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	struct nf_conntrack_man src;
389fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
399fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	/* These are the parts of the tuple which are fixed. */
409fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	struct {
41643a2c15a407faf08101a20e1a3461160711899dJan Engelhardt		union nf_inet_addr u3;
429fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		union {
439fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			/* Add other protocols here. */
44a34c45896a723ee7b13128ac8bf564ea42fcd1ebAl Viro			__be16 all;
459fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
469fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			struct {
47bff9a89bcac5b68ac0a1ea856b1726a35ae1eabbPatrick McHardy				__be16 port;
489fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			} tcp;
499fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			struct {
50bff9a89bcac5b68ac0a1ea856b1726a35ae1eabbPatrick McHardy				__be16 port;
519fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			} udp;
529fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			struct {
539fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai				u_int8_t type, code;
549fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			} icmp;
559fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			struct {
56bff9a89bcac5b68ac0a1ea856b1726a35ae1eabbPatrick McHardy				__be16 port;
572bc780499aa33311ec0f3e42624dfaa7be0ade5ePatrick McHardy			} dccp;
582bc780499aa33311ec0f3e42624dfaa7be0ade5ePatrick McHardy			struct {
592bc780499aa33311ec0f3e42624dfaa7be0ade5ePatrick McHardy				__be16 port;
609fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai			} sctp;
61f09943fefe6b702e40893d35b4f10fd1064037fePatrick McHardy			struct {
62f09943fefe6b702e40893d35b4f10fd1064037fePatrick McHardy				__be16 key;
63f09943fefe6b702e40893d35b4f10fd1064037fePatrick McHardy			} gre;
649fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		} u;
659fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
669fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		/* The protocol. */
679fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		u_int8_t protonum;
689fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
699fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		/* The direction (for tuplehash) */
709fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		u_int8_t dir;
719fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	} dst;
729fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai};
739fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
74fd2c3ef761fbc5e6c27fa7d40b30cda06bfcd7d8Eric Dumazetstruct nf_conntrack_tuple_mask {
75d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	struct {
76643a2c15a407faf08101a20e1a3461160711899dJan Engelhardt		union nf_inet_addr u3;
77d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy		union nf_conntrack_man_proto u;
78d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	} src;
79d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy};
80d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy
81ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardystatic inline void nf_ct_dump_tuple_ip(const struct nf_conntrack_tuple *t)
82ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy{
83ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy#ifdef DEBUG
843685f25de1b0447fff381c420de1e25bd57c9efbHarvey Harrison	printk("tuple %p: %u %pI4:%hu -> %pI4:%hu\n",
85ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy	       t, t->dst.protonum,
863685f25de1b0447fff381c420de1e25bd57c9efbHarvey Harrison	       &t->src.u3.ip, ntohs(t->src.u.all),
873685f25de1b0447fff381c420de1e25bd57c9efbHarvey Harrison	       &t->dst.u3.ip, ntohs(t->dst.u.all));
88ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy#endif
89ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy}
90ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy
91ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardystatic inline void nf_ct_dump_tuple_ipv6(const struct nf_conntrack_tuple *t)
92ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy{
93ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy#ifdef DEBUG
945b095d98928fdb9e3b75be20a54b7a6cbf6ca9adHarvey Harrison	printk("tuple %p: %u %pI6 %hu -> %pI6 %hu\n",
95ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy	       t, t->dst.protonum,
960c6ce78abf6e228d44c3840edb8a4ae0c1299825Harvey Harrison	       t->src.u3.all, ntohs(t->src.u.all),
970c6ce78abf6e228d44c3840edb8a4ae0c1299825Harvey Harrison	       t->dst.u3.all, ntohs(t->dst.u.all));
98ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy#endif
99ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy}
100ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy
101ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardystatic inline void nf_ct_dump_tuple(const struct nf_conntrack_tuple *t)
102ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy{
103ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy	switch (t->src.l3num) {
104ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy	case AF_INET:
105ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy		nf_ct_dump_tuple_ip(t);
106ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy		break;
107ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy	case AF_INET6:
108ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy		nf_ct_dump_tuple_ipv6(t);
109ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy		break;
110ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy	}
111ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy}
112ef27559b70bd5312dfcbeab3b9ab0296206413c4Patrick McHardy
1139fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai/* If we're the first tuple, it's the original dir. */
1149fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai#define NF_CT_DIRECTION(h)						\
1159fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	((enum ip_conntrack_dir)(h)->tuple.dst.dir)
1169fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
1179fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai/* Connections have two entries in the hash table: one for each way */
118ea781f197d6a835cbb93a0bf88ee1696296ed8aaEric Dumazetstruct nf_conntrack_tuple_hash {
119ea781f197d6a835cbb93a0bf88ee1696296ed8aaEric Dumazet	struct hlist_nulls_node hnnode;
1209fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai	struct nf_conntrack_tuple tuple;
1219fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai};
1229fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
1235f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtstatic inline bool __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
1245f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt					   const struct nf_conntrack_tuple *t2)
1259fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai{
126b8beedd25d3913d45b8330a08ab88fdf90eb54b8Patrick McHardy	return (nf_inet_addr_cmp(&t1->src.u3, &t2->src.u3) &&
1279fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		t1->src.u.all == t2->src.u.all &&
128380517dead6ab86d7249a1723f07f2f1b10af5f6Patrick McHardy		t1->src.l3num == t2->src.l3num);
1299fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai}
1309fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
1315f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtstatic inline bool __nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
1325f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt					   const struct nf_conntrack_tuple *t2)
1339fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai{
134b8beedd25d3913d45b8330a08ab88fdf90eb54b8Patrick McHardy	return (nf_inet_addr_cmp(&t1->dst.u3, &t2->dst.u3) &&
1359fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		t1->dst.u.all == t2->dst.u.all &&
1369fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai		t1->dst.protonum == t2->dst.protonum);
1379fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai}
1389fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
1395f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtstatic inline bool nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
1405f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt				     const struct nf_conntrack_tuple *t2)
1419fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai{
142380517dead6ab86d7249a1723f07f2f1b10af5f6Patrick McHardy	return __nf_ct_tuple_src_equal(t1, t2) &&
143380517dead6ab86d7249a1723f07f2f1b10af5f6Patrick McHardy	       __nf_ct_tuple_dst_equal(t1, t2);
1449fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai}
1459fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
1465f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtstatic inline bool
1475f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtnf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
1485f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt		       const struct nf_conntrack_tuple_mask *m2)
149d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy{
150b8beedd25d3913d45b8330a08ab88fdf90eb54b8Patrick McHardy	return (nf_inet_addr_cmp(&m1->src.u3, &m2->src.u3) &&
151d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy		m1->src.u.all == m2->src.u.all);
152d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy}
153d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy
1545f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtstatic inline bool
1555f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtnf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1,
1565f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt			 const struct nf_conntrack_tuple *t2,
1575f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt			 const struct nf_conntrack_tuple_mask *mask)
158d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy{
159d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	int count;
160d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy
161d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) {
162d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy		if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) &
163d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy		    mask->src.u3.all[count])
1645f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt			return false;
165d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	}
166d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy
167d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all)
1685f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt		return false;
169d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy
170d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	if (t1->src.l3num != t2->src.l3num ||
171d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	    t1->dst.protonum != t2->dst.protonum)
1725f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt		return false;
173d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy
1745f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt	return true;
175d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy}
176d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy
1775f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtstatic inline bool
1785f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardtnf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
1795f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt		     const struct nf_conntrack_tuple *tuple,
1805f2b4c9006fc667c4614f0b079efab3721f68316Jan Engelhardt		     const struct nf_conntrack_tuple_mask *mask)
1819fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai{
182d4156e8cd93f5772483928aaf4960120caebd789Patrick McHardy	return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
183380517dead6ab86d7249a1723f07f2f1b10af5f6Patrick McHardy	       __nf_ct_tuple_dst_equal(t, tuple);
1849fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai}
1859fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai
1869fb9cbb1082d6b31fb45aa1a14432449a0df6cf1Yasuyuki Kozakai#endif /* _NF_CONNTRACK_TUPLE_H */
187