blob: 49cec5831c1550c25f90a599370a2ac43bd072bc [file] [log] [blame]
Ben Menchaca84f36632014-02-28 20:57:38 +00001/*
2 **************************************************************************
Gareth Williamsd5618a82015-05-20 11:13:32 +01003 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Ben Menchaca84f36632014-02-28 20:57:38 +00004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
16
17struct ecm_tracker_instance;
18
19/*
20 * Data tracking data limits - system global and per-connection - defaults.
21 */
22#define ECM_TRACKER_GLOBAL_DATA_LIMIT_DEFAULT (1024 * 1024 * 8)
23#define ECM_TRACKER_GLOBAL_DATA_BUFFER_LIMIT_DEFAULT (1024 * 1024 * 64)
24#define ECM_TRACKER_CONNECTION_TRACKING_LIMIT_DEFAULT (1024 * 1024)
25#define ECM_TRACKER_CONNECTION_TRACKING_LIMIT_MAX ECM_TRACKER_GLOBAL_DATA_LIMIT_DEFAULT
26
27enum ecm_tracker_sender_types {
28 ECM_TRACKER_SENDER_TYPE_SRC = 0, /* Sender of tracked data is the source of the connection (who established the connection) */
29 ECM_TRACKER_SENDER_TYPE_DEST = 1, /* Sender of tracked data is the destination of the connection (to whom connection was established) */
30 ECM_TRACKER_SENDER_MAX, /* MUST BE LAST */
31};
32typedef enum ecm_tracker_sender_types ecm_tracker_sender_type_t;
33
34/*
35 * enum ecm_tracker_sender_states
36 * Notional states of senders of a tracker
37 *
38 * Order is important here - don't change them as logic depends on their numerical value.
39 */
40enum ecm_tracker_sender_states {
41 ECM_TRACKER_SENDER_STATE_UNKNOWN = 0, /* Endpoint has not sent any packets yet */
42 ECM_TRACKER_SENDER_STATE_ESTABLISHING, /* Endpoint has not yet given any indication it is established */
43 ECM_TRACKER_SENDER_STATE_ESTABLISHED, /* Endpoint has indicated that it is established */
44 ECM_TRACKER_SENDER_STATE_CLOSING, /* Endpoint has indicated that it wants to close down its side of the connection */
45 ECM_TRACKER_SENDER_STATE_CLOSED, /* Endpoint has closed, connection remains to service any late packets */
46 ECM_TRACKER_SENDER_STATE_FAULT, /* Endpoint experienced a fault */
47 ECM_TRACKER_SENDER_STATE_MAX, /* MUST BE LAST */
48};
49typedef enum ecm_tracker_sender_states ecm_tracker_sender_state_t;
50
51/*
52 * ecm_tracker_sender_state_to_string[]
53 * Convert a sender state to a string
54 */
Nicolas Costa1d9eb992014-05-15 10:01:03 -050055const char *
56ecm_tracker_sender_state_to_string(enum ecm_tracker_sender_states);
Ben Menchaca84f36632014-02-28 20:57:38 +000057
58/*
59 * enum ecm_tracker_connection_states
60 * Notional states of connection being monitored by the tracker
61 *
62 * Order is important here - don't change them as logic depends on their numerical value.
63 */
64enum ecm_tracker_connection_states {
65 ECM_TRACKER_CONNECTION_STATE_ESTABLISHING = 0, /* Not yet given any indication it is established */
66 ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, /* It is established */
67 ECM_TRACKER_CONNECTION_STATE_CLOSING, /* Connection has begun process of closing */
68 ECM_TRACKER_CONNECTION_STATE_CLOSED, /* Has closed, connection remains to service any late packets */
69 ECM_TRACKER_CONNECTION_STATE_FAULT, /* Experienced a fault */
70 ECM_TRACKER_CONNECTION_STATE_MAX, /* MUST BE LAST */
71};
72typedef enum ecm_tracker_connection_states ecm_tracker_connection_state_t;
73
74/*
Nicolas Costa1d9eb992014-05-15 10:01:03 -050075 * ecm_tracker_connection_state_to_string
Ben Menchaca84f36632014-02-28 20:57:38 +000076 * Convert a connection state to a string
77 */
Gareth Williamsd5618a82015-05-20 11:13:32 +010078const char *ecm_tracker_connection_state_to_string(enum ecm_tracker_connection_states);
Ben Menchaca84f36632014-02-28 20:57:38 +000079
80/*
81 * enum ecm_tracker_ip_protocol_types
82 * A list of protocol types that can be recorded in the ecm_ip_header
83 *
84 * This is especially useful for IPv6 where the ip header can contain many sub headers.
85 * But it is also useful for IPv4 where you might have IP following a GRE header, for example.
86 * An ECM IP header may record only ONE of each type of header, if more are found the header is considered invalid.
87 *
88 * These constants are used to index into the ecm_tracker_ip_header.headers[]
89 */
90enum ecm_tracker_ip_protocol_types {
Gareth Williams8ac34292015-03-17 14:06:58 +000091 ECM_TRACKER_IP_PROTOCOL_TYPE_UNKNOWN, /* A protocol that is unrecognised */
Ben Menchaca84f36632014-02-28 20:57:38 +000092 ECM_TRACKER_IP_PROTOCOL_TYPE_ICMP,
93 ECM_TRACKER_IP_PROTOCOL_TYPE_UDP,
94 ECM_TRACKER_IP_PROTOCOL_TYPE_TCP,
95 ECM_TRACKER_IP_PROTOCOL_TYPE_GRE,
Gareth Williams8ac34292015-03-17 14:06:58 +000096#ifdef ECM_IPV6_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +000097 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_ROUTING,
98 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_FRAGMENT,
99 ECM_TRACKER_IP_PROTOCOL_TYPE_AH,
100 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_ICMP,
101 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_DO,
Gareth Williams8ac34292015-03-17 14:06:58 +0000102 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_HBH, /* IPv6 hop-by-hop header */
103#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000104 ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT /* Must be last, do not use */
105};
106typedef enum ecm_tracker_ip_protocol_types ecm_tracker_ip_protocol_type_t;
107
108/*
109 * struct ecm_tracker_ip_protocol_header
110 * Records a protocol header as stored within an IP datagram
111 */
112struct ecm_tracker_ip_protocol_header {
113 uint8_t protocol_number; /* IP protocol number */
114 uint16_t header_size; /* Size of the protocol header */
115 uint16_t size; /* Size of the header_size + its payload */
116 uint16_t offset; /* Offset from the start of the skb where this header is located */
117};
118
119/*
120 * struct ecm_tracker_ip_header
121 * An IP header in the ECM can deal with V4 and V6 headers.
122 *
123 * WARNING: An ecm_ip_header is ONLY VALID while the skb from which it was initialised remains untouched.
124 */
125struct ecm_tracker_ip_header {
126 /*
Gareth Williams8ac34292015-03-17 14:06:58 +0000127 * h is a union of IP version headers.
Gareth Williams75086b22015-04-28 12:52:08 +0100128 * These are ONLY used as buffers where skb_header_pointer() needs them to perform a skb_copy_bits() operation.
129 * WARNING: You should NOT rely on the content of these structures because skb_header_pointer() may not have used them!
130 * Use the actual fields below instead.
Ben Menchaca84f36632014-02-28 20:57:38 +0000131 */
132 union {
133 struct iphdr v4_hdr;
Gareth Williams8ac34292015-03-17 14:06:58 +0000134#ifdef ECM_IPV6_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000135 struct ipv6hdr v6_hdr;
Gareth Williams8ac34292015-03-17 14:06:58 +0000136#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000137 } h;
138
Gareth Williams75086b22015-04-28 12:52:08 +0100139 struct sk_buff *skb; /* COPY of POINTER to the skb this header relates to. This ecm_tracker_ip_header is ONLY VALID for as long as the skb it relates to remains UNTOUCHED */
Ben Menchaca84f36632014-02-28 20:57:38 +0000140 bool is_v4; /* True when v4, else v6 */
141 ip_addr_t src_addr; /* ECM ip address equivalent */
142 ip_addr_t dest_addr; /* ECM ip address equivalent */
143 int protocol; /* The upper layer transport protocol */
144 bool fragmented; /* True when fragmented */
Gareth Williams8932a912014-06-11 18:06:25 -0700145 uint8_t ds; /* DS field from packet */
Shyam Sunderf0b6a592015-07-23 18:06:45 +0530146 uint8_t ttl; /* v4 TTL or v6 hop limit */
Ben Menchaca84f36632014-02-28 20:57:38 +0000147 uint32_t ip_header_length; /* Length of the IP header plus any variable sized intrinsically attached options */
148 uint32_t total_length; /* total length of IP header including all extensions and payload. For v4 this is total_len, for v6 this is payload_len + size of the IP 6 header */
149 uint32_t payload_length; /* total_length - ip_header_length */
150 struct ecm_tracker_ip_protocol_header headers[ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT];
151 /* Use one of the ECM_TRACKER_IP_PROTOCOL_TYPE_XYZ constants to index into this to locate the header you want to inspect. If the size is zero then the header was not found. */
152};
153
Gareth Williams88be3722015-03-23 19:51:01 +0000154#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000155typedef int32_t (*ecm_tracker_datagram_count_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender);
156 /* Return number of available datagrams sent by the sender */
157typedef void (*ecm_tracker_datagram_discard_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t n);
158 /* Discard n number of datagrams at the head of the datagram list that were sent by the sender */
159typedef int32_t (*ecm_tracker_datagram_size_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i);
160 /* Return size in bytes of datagram at index i that was sent by the sender */
161typedef int (*ecm_tracker_datagram_read_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer);
162 /* Read size bytes from datagram at index i into the buffer */
163typedef bool (*ecm_tracker_datagram_add_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct sk_buff *skb);
164 /* Add (append) the datagram into the tracker */
Ben Menchaca84f36632014-02-28 20:57:38 +0000165typedef void (*ecm_tracker_discard_all_method_t)(struct ecm_tracker_instance *ti);
166 /* Discard all tracked data */
167typedef int32_t (*ecm_tracker_data_total_get_method_t)(struct ecm_tracker_instance *ti);
168 /* Return number of bytes of tracked data in total */
169typedef int32_t (*ecm_tracker_data_limit_get_method_t)(struct ecm_tracker_instance *ti);
170 /* Return the limit on the number of bytes we can track */
171typedef void (*ecm_tracker_data_limit_set_method_t)(struct ecm_tracker_instance *ti, int32_t data_limit);
172 /* Set the limit on the number of bytes we can track */
Gareth Williams88be3722015-03-23 19:51:01 +0000173#endif
174typedef void (*ecm_tracker_ref_method_t)(struct ecm_tracker_instance *ti);
175typedef int (*ecm_tracker_deref_method_t)(struct ecm_tracker_instance *ti);
176
Ben Menchaca84f36632014-02-28 20:57:38 +0000177typedef void (*ecm_tracker_state_update_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb);
178 /* Update state of the sender */
179typedef void (*ecm_tracker_state_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_state_t *src_state, ecm_tracker_sender_state_t *dest_state, ecm_tracker_connection_state_t *state, ecm_db_timer_group_t *tg);
180 /* State of the connection */
Gareth Williamsf98d4192015-03-11 16:55:41 +0000181#ifdef ECM_STATE_OUTPUT_ENABLE
Gareth Williamsd5618a82015-05-20 11:13:32 +0100182typedef int (*ecm_tracker_state_get_callback_t)(struct ecm_tracker_instance *ti, struct ecm_state_file_instance *sfi);
183 /*
184 * Get state output.
185 * Returns zero on success.
Ben Menchaca84f36632014-02-28 20:57:38 +0000186 */
Gareth Williamsf98d4192015-03-11 16:55:41 +0000187#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000188
189/*
190 * struct ecm_tracker_instance
191 * Base class of all trackers
192 *
193 * ALL trackers must implement these features in addition to their own.
194 * ALL trackers must be castable to a type of this, i.e. this structure must be the first element of their own data type.
195 */
196struct ecm_tracker_instance {
Gareth Williams88be3722015-03-23 19:51:01 +0000197#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000198 ecm_tracker_data_total_get_method_t data_total_get;
199 ecm_tracker_data_limit_get_method_t data_limit_get;
200 ecm_tracker_data_limit_set_method_t data_limit_set;
201 ecm_tracker_datagram_count_get_method_t datagram_count_get;
202 ecm_tracker_datagram_discard_method_t datagram_discard;
203 ecm_tracker_datagram_size_get_method_t datagram_size_get;
204 ecm_tracker_datagram_read_method_t datagram_read;
205 ecm_tracker_datagram_add_method_t datagram_add;
206 ecm_tracker_discard_all_method_t discard_all;
Gareth Williams88be3722015-03-23 19:51:01 +0000207#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000208 ecm_tracker_state_update_method_t state_update;
209 ecm_tracker_state_get_method_t state_get;
Gareth Williamsf98d4192015-03-11 16:55:41 +0000210#ifdef ECM_STATE_OUTPUT_ENABLE
Gareth Williamsd5618a82015-05-20 11:13:32 +0100211 ecm_tracker_state_get_callback_t state_text_get; /* Return text containing its state */
Gareth Williamsf98d4192015-03-11 16:55:41 +0000212#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000213 ecm_tracker_ref_method_t ref;
214 ecm_tracker_deref_method_t deref;
215};
216
217bool ecm_tracker_ip_check_header_and_read(struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb);
Gareth Williams88be3722015-03-23 19:51:01 +0000218#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000219uint32_t ecm_tracker_data_limit_get(void);
220void ecm_tracker_data_limit_set(uint32_t limit);
221uint32_t ecm_tracker_data_total_get(void);
222uint32_t ecm_tracker_data_buffer_total_get(void);
223bool ecm_tracker_data_total_increase(uint32_t n, uint32_t data_bufer_size);
224void ecm_tracker_data_total_decrease(uint32_t n, uint32_t data_bufer_size);
Gareth Williams88be3722015-03-23 19:51:01 +0000225#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000226