blob: 9293d6e39a5deb2f336a19e6a665780a32fb9cb9 [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
Murat Sezgin109b2ce2017-06-08 11:56:56 -070027/*
28 * Definitions for IPv6 version-class-flow_label field.
29 */
30#define ECM_TRACKER_IPV6_FLOW_LBL_PRIORITY_MASK 0xC0
31#define ECM_TRACKER_IPV6_FLOW_LBL_PRIORITY_SHIFT 6
32#define ECM_TRACKER_IPV6_PRIORITY_SHIFT 2
33
Ben Menchaca84f36632014-02-28 20:57:38 +000034enum ecm_tracker_sender_types {
35 ECM_TRACKER_SENDER_TYPE_SRC = 0, /* Sender of tracked data is the source of the connection (who established the connection) */
36 ECM_TRACKER_SENDER_TYPE_DEST = 1, /* Sender of tracked data is the destination of the connection (to whom connection was established) */
37 ECM_TRACKER_SENDER_MAX, /* MUST BE LAST */
38};
39typedef enum ecm_tracker_sender_types ecm_tracker_sender_type_t;
40
41/*
42 * enum ecm_tracker_sender_states
43 * Notional states of senders of a tracker
44 *
45 * Order is important here - don't change them as logic depends on their numerical value.
46 */
47enum ecm_tracker_sender_states {
48 ECM_TRACKER_SENDER_STATE_UNKNOWN = 0, /* Endpoint has not sent any packets yet */
49 ECM_TRACKER_SENDER_STATE_ESTABLISHING, /* Endpoint has not yet given any indication it is established */
50 ECM_TRACKER_SENDER_STATE_ESTABLISHED, /* Endpoint has indicated that it is established */
51 ECM_TRACKER_SENDER_STATE_CLOSING, /* Endpoint has indicated that it wants to close down its side of the connection */
52 ECM_TRACKER_SENDER_STATE_CLOSED, /* Endpoint has closed, connection remains to service any late packets */
53 ECM_TRACKER_SENDER_STATE_FAULT, /* Endpoint experienced a fault */
54 ECM_TRACKER_SENDER_STATE_MAX, /* MUST BE LAST */
55};
56typedef enum ecm_tracker_sender_states ecm_tracker_sender_state_t;
57
58/*
59 * ecm_tracker_sender_state_to_string[]
60 * Convert a sender state to a string
61 */
Nicolas Costa1d9eb992014-05-15 10:01:03 -050062const char *
63ecm_tracker_sender_state_to_string(enum ecm_tracker_sender_states);
Ben Menchaca84f36632014-02-28 20:57:38 +000064
65/*
66 * enum ecm_tracker_connection_states
67 * Notional states of connection being monitored by the tracker
68 *
69 * Order is important here - don't change them as logic depends on their numerical value.
70 */
71enum ecm_tracker_connection_states {
72 ECM_TRACKER_CONNECTION_STATE_ESTABLISHING = 0, /* Not yet given any indication it is established */
73 ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, /* It is established */
74 ECM_TRACKER_CONNECTION_STATE_CLOSING, /* Connection has begun process of closing */
75 ECM_TRACKER_CONNECTION_STATE_CLOSED, /* Has closed, connection remains to service any late packets */
76 ECM_TRACKER_CONNECTION_STATE_FAULT, /* Experienced a fault */
77 ECM_TRACKER_CONNECTION_STATE_MAX, /* MUST BE LAST */
78};
79typedef enum ecm_tracker_connection_states ecm_tracker_connection_state_t;
80
81/*
Nicolas Costa1d9eb992014-05-15 10:01:03 -050082 * ecm_tracker_connection_state_to_string
Ben Menchaca84f36632014-02-28 20:57:38 +000083 * Convert a connection state to a string
84 */
Gareth Williamsd5618a82015-05-20 11:13:32 +010085const char *ecm_tracker_connection_state_to_string(enum ecm_tracker_connection_states);
Ben Menchaca84f36632014-02-28 20:57:38 +000086
87/*
88 * enum ecm_tracker_ip_protocol_types
89 * A list of protocol types that can be recorded in the ecm_ip_header
90 *
91 * This is especially useful for IPv6 where the ip header can contain many sub headers.
92 * But it is also useful for IPv4 where you might have IP following a GRE header, for example.
93 * An ECM IP header may record only ONE of each type of header, if more are found the header is considered invalid.
94 *
95 * These constants are used to index into the ecm_tracker_ip_header.headers[]
96 */
97enum ecm_tracker_ip_protocol_types {
Gareth Williams8ac34292015-03-17 14:06:58 +000098 ECM_TRACKER_IP_PROTOCOL_TYPE_UNKNOWN, /* A protocol that is unrecognised */
Ben Menchaca84f36632014-02-28 20:57:38 +000099 ECM_TRACKER_IP_PROTOCOL_TYPE_ICMP,
100 ECM_TRACKER_IP_PROTOCOL_TYPE_UDP,
101 ECM_TRACKER_IP_PROTOCOL_TYPE_TCP,
102 ECM_TRACKER_IP_PROTOCOL_TYPE_GRE,
Gareth Williams8ac34292015-03-17 14:06:58 +0000103#ifdef ECM_IPV6_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000104 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_ROUTING,
105 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_FRAGMENT,
106 ECM_TRACKER_IP_PROTOCOL_TYPE_AH,
107 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_ICMP,
108 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_DO,
Gareth Williams8ac34292015-03-17 14:06:58 +0000109 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_HBH, /* IPv6 hop-by-hop header */
110#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000111 ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT /* Must be last, do not use */
112};
113typedef enum ecm_tracker_ip_protocol_types ecm_tracker_ip_protocol_type_t;
114
115/*
116 * struct ecm_tracker_ip_protocol_header
117 * Records a protocol header as stored within an IP datagram
118 */
119struct ecm_tracker_ip_protocol_header {
120 uint8_t protocol_number; /* IP protocol number */
121 uint16_t header_size; /* Size of the protocol header */
122 uint16_t size; /* Size of the header_size + its payload */
123 uint16_t offset; /* Offset from the start of the skb where this header is located */
124};
125
126/*
127 * struct ecm_tracker_ip_header
128 * An IP header in the ECM can deal with V4 and V6 headers.
129 *
130 * WARNING: An ecm_ip_header is ONLY VALID while the skb from which it was initialised remains untouched.
131 */
132struct ecm_tracker_ip_header {
133 /*
Gareth Williams8ac34292015-03-17 14:06:58 +0000134 * h is a union of IP version headers.
Gareth Williams75086b22015-04-28 12:52:08 +0100135 * These are ONLY used as buffers where skb_header_pointer() needs them to perform a skb_copy_bits() operation.
136 * WARNING: You should NOT rely on the content of these structures because skb_header_pointer() may not have used them!
137 * Use the actual fields below instead.
Ben Menchaca84f36632014-02-28 20:57:38 +0000138 */
139 union {
140 struct iphdr v4_hdr;
Gareth Williams8ac34292015-03-17 14:06:58 +0000141#ifdef ECM_IPV6_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000142 struct ipv6hdr v6_hdr;
Gareth Williams8ac34292015-03-17 14:06:58 +0000143#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000144 } h;
145
Gareth Williams75086b22015-04-28 12:52:08 +0100146 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 +0000147 bool is_v4; /* True when v4, else v6 */
148 ip_addr_t src_addr; /* ECM ip address equivalent */
149 ip_addr_t dest_addr; /* ECM ip address equivalent */
150 int protocol; /* The upper layer transport protocol */
151 bool fragmented; /* True when fragmented */
Murat Sezgin109b2ce2017-06-08 11:56:56 -0700152 uint8_t dscp; /* DSCP field from the packet */
Gareth Williams8932a912014-06-11 18:06:25 -0700153 uint8_t ds; /* DS field from packet */
Shyam Sunderf0b6a592015-07-23 18:06:45 +0530154 uint8_t ttl; /* v4 TTL or v6 hop limit */
Ben Menchaca84f36632014-02-28 20:57:38 +0000155 uint32_t ip_header_length; /* Length of the IP header plus any variable sized intrinsically attached options */
156 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 */
157 uint32_t payload_length; /* total_length - ip_header_length */
158 struct ecm_tracker_ip_protocol_header headers[ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT];
159 /* 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. */
160};
161
Gareth Williams88be3722015-03-23 19:51:01 +0000162#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000163typedef int32_t (*ecm_tracker_datagram_count_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender);
164 /* Return number of available datagrams sent by the sender */
165typedef void (*ecm_tracker_datagram_discard_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t n);
166 /* Discard n number of datagrams at the head of the datagram list that were sent by the sender */
167typedef int32_t (*ecm_tracker_datagram_size_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i);
168 /* Return size in bytes of datagram at index i that was sent by the sender */
169typedef 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);
170 /* Read size bytes from datagram at index i into the buffer */
171typedef bool (*ecm_tracker_datagram_add_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct sk_buff *skb);
172 /* Add (append) the datagram into the tracker */
Ben Menchaca84f36632014-02-28 20:57:38 +0000173typedef void (*ecm_tracker_discard_all_method_t)(struct ecm_tracker_instance *ti);
174 /* Discard all tracked data */
175typedef int32_t (*ecm_tracker_data_total_get_method_t)(struct ecm_tracker_instance *ti);
176 /* Return number of bytes of tracked data in total */
177typedef int32_t (*ecm_tracker_data_limit_get_method_t)(struct ecm_tracker_instance *ti);
178 /* Return the limit on the number of bytes we can track */
179typedef void (*ecm_tracker_data_limit_set_method_t)(struct ecm_tracker_instance *ti, int32_t data_limit);
180 /* Set the limit on the number of bytes we can track */
Gareth Williams88be3722015-03-23 19:51:01 +0000181#endif
182typedef void (*ecm_tracker_ref_method_t)(struct ecm_tracker_instance *ti);
183typedef int (*ecm_tracker_deref_method_t)(struct ecm_tracker_instance *ti);
184
Ben Menchaca84f36632014-02-28 20:57:38 +0000185typedef 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);
186 /* Update state of the sender */
187typedef 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);
188 /* State of the connection */
Gareth Williamsf98d4192015-03-11 16:55:41 +0000189#ifdef ECM_STATE_OUTPUT_ENABLE
Gareth Williamsd5618a82015-05-20 11:13:32 +0100190typedef int (*ecm_tracker_state_get_callback_t)(struct ecm_tracker_instance *ti, struct ecm_state_file_instance *sfi);
191 /*
192 * Get state output.
193 * Returns zero on success.
Ben Menchaca84f36632014-02-28 20:57:38 +0000194 */
Gareth Williamsf98d4192015-03-11 16:55:41 +0000195#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000196
197/*
198 * struct ecm_tracker_instance
199 * Base class of all trackers
200 *
201 * ALL trackers must implement these features in addition to their own.
202 * ALL trackers must be castable to a type of this, i.e. this structure must be the first element of their own data type.
203 */
204struct ecm_tracker_instance {
Gareth Williams88be3722015-03-23 19:51:01 +0000205#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000206 ecm_tracker_data_total_get_method_t data_total_get;
207 ecm_tracker_data_limit_get_method_t data_limit_get;
208 ecm_tracker_data_limit_set_method_t data_limit_set;
209 ecm_tracker_datagram_count_get_method_t datagram_count_get;
210 ecm_tracker_datagram_discard_method_t datagram_discard;
211 ecm_tracker_datagram_size_get_method_t datagram_size_get;
212 ecm_tracker_datagram_read_method_t datagram_read;
213 ecm_tracker_datagram_add_method_t datagram_add;
214 ecm_tracker_discard_all_method_t discard_all;
Gareth Williams88be3722015-03-23 19:51:01 +0000215#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000216 ecm_tracker_state_update_method_t state_update;
217 ecm_tracker_state_get_method_t state_get;
Gareth Williamsf98d4192015-03-11 16:55:41 +0000218#ifdef ECM_STATE_OUTPUT_ENABLE
Gareth Williamsd5618a82015-05-20 11:13:32 +0100219 ecm_tracker_state_get_callback_t state_text_get; /* Return text containing its state */
Gareth Williamsf98d4192015-03-11 16:55:41 +0000220#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000221 ecm_tracker_ref_method_t ref;
222 ecm_tracker_deref_method_t deref;
223};
224
225bool 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 +0000226#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
Ben Menchaca84f36632014-02-28 20:57:38 +0000227uint32_t ecm_tracker_data_limit_get(void);
228void ecm_tracker_data_limit_set(uint32_t limit);
229uint32_t ecm_tracker_data_total_get(void);
230uint32_t ecm_tracker_data_buffer_total_get(void);
231bool ecm_tracker_data_total_increase(uint32_t n, uint32_t data_bufer_size);
232void ecm_tracker_data_total_decrease(uint32_t n, uint32_t data_bufer_size);
Gareth Williams88be3722015-03-23 19:51:01 +0000233#endif
Ben Menchaca84f36632014-02-28 20:57:38 +0000234