blob: e1381f5312d202a38cc9aa83fa141747a739ad09 [file] [log] [blame]
Ben Menchaca84f36632014-02-28 20:57:38 +00001/*
2 **************************************************************************
3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
4 * 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 */
Nicolas Costa1d9eb992014-05-15 10:01:03 -050078const char *
79ecm_tracker_connection_state_to_string(enum ecm_tracker_connection_states);
Ben Menchaca84f36632014-02-28 20:57:38 +000080
81/*
82 * enum ecm_tracker_ip_protocol_types
83 * A list of protocol types that can be recorded in the ecm_ip_header
84 *
85 * This is especially useful for IPv6 where the ip header can contain many sub headers.
86 * But it is also useful for IPv4 where you might have IP following a GRE header, for example.
87 * An ECM IP header may record only ONE of each type of header, if more are found the header is considered invalid.
88 *
89 * These constants are used to index into the ecm_tracker_ip_header.headers[]
90 */
91enum ecm_tracker_ip_protocol_types {
92 ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_HBH,
93 ECM_TRACKER_IP_PROTOCOL_TYPE_ICMP,
94 ECM_TRACKER_IP_PROTOCOL_TYPE_UDP,
95 ECM_TRACKER_IP_PROTOCOL_TYPE_TCP,
96 ECM_TRACKER_IP_PROTOCOL_TYPE_GRE,
97 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,
102 ECM_TRACKER_IP_PROTOCOL_TYPE_UNKNOWN, /* A protocol that is unrecognised */
103 ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT /* Must be last, do not use */
104};
105typedef enum ecm_tracker_ip_protocol_types ecm_tracker_ip_protocol_type_t;
106
107/*
108 * struct ecm_tracker_ip_protocol_header
109 * Records a protocol header as stored within an IP datagram
110 */
111struct ecm_tracker_ip_protocol_header {
112 uint8_t protocol_number; /* IP protocol number */
113 uint16_t header_size; /* Size of the protocol header */
114 uint16_t size; /* Size of the header_size + its payload */
115 uint16_t offset; /* Offset from the start of the skb where this header is located */
116};
117
118/*
119 * struct ecm_tracker_ip_header
120 * An IP header in the ECM can deal with V4 and V6 headers.
121 *
122 * WARNING: An ecm_ip_header is ONLY VALID while the skb from which it was initialised remains untouched.
123 */
124struct ecm_tracker_ip_header {
125 /*
126 * h is a union of v4 and v6 headers.
127 * This only works as far as the version field goes, but that's enough to know what we are dealing with.
128 * These are also used as buffers where skn_header_pointer() needs them to perform a skb_copy_bits() operation.
129 */
130 union {
131 struct iphdr v4_hdr;
132 struct ipv6hdr v6_hdr;
133 } h;
134
135 struct sk_buff *skb; /* COPY of POINTER to the skb this header relates to. This ecm_ip_header is ONLY VALID for as long as the skb it relates to remains UNTOUCHED */
136 bool is_v4; /* True when v4, else v6 */
137 ip_addr_t src_addr; /* ECM ip address equivalent */
138 ip_addr_t dest_addr; /* ECM ip address equivalent */
139 int protocol; /* The upper layer transport protocol */
140 bool fragmented; /* True when fragmented */
141 uint32_t ip_header_length; /* Length of the IP header plus any variable sized intrinsically attached options */
142 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 */
143 uint32_t payload_length; /* total_length - ip_header_length */
144 struct ecm_tracker_ip_protocol_header headers[ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT];
145 /* 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. */
146};
147
148typedef int32_t (*ecm_tracker_datagram_count_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender);
149 /* Return number of available datagrams sent by the sender */
150typedef void (*ecm_tracker_datagram_discard_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t n);
151 /* Discard n number of datagrams at the head of the datagram list that were sent by the sender */
152typedef int32_t (*ecm_tracker_datagram_size_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i);
153 /* Return size in bytes of datagram at index i that was sent by the sender */
154typedef 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);
155 /* Read size bytes from datagram at index i into the buffer */
156typedef bool (*ecm_tracker_datagram_add_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct sk_buff *skb);
157 /* Add (append) the datagram into the tracker */
158typedef void (*ecm_tracker_ref_method_t)(struct ecm_tracker_instance *ti);
159typedef int (*ecm_tracker_deref_method_t)(struct ecm_tracker_instance *ti);
160
161typedef void (*ecm_tracker_discard_all_method_t)(struct ecm_tracker_instance *ti);
162 /* Discard all tracked data */
163typedef int32_t (*ecm_tracker_data_total_get_method_t)(struct ecm_tracker_instance *ti);
164 /* Return number of bytes of tracked data in total */
165typedef int32_t (*ecm_tracker_data_limit_get_method_t)(struct ecm_tracker_instance *ti);
166 /* Return the limit on the number of bytes we can track */
167typedef void (*ecm_tracker_data_limit_set_method_t)(struct ecm_tracker_instance *ti, int32_t data_limit);
168 /* Set the limit on the number of bytes we can track */
169typedef 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);
170 /* Update state of the sender */
171typedef 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);
172 /* State of the connection */
173typedef int (*ecm_tracker_xml_state_get_callback_t)(struct ecm_tracker_instance *ti, char *buf, int buf_sz);
174 /* Get XML state output, buf has buf_sz bytes available. Returns number of bytes written.
175 * Function has failed if the return is (<= 0) || (return value == buf_sz).
176 * The return code is compatible with snprintf().
177 */
178
179/*
180 * struct ecm_tracker_instance
181 * Base class of all trackers
182 *
183 * ALL trackers must implement these features in addition to their own.
184 * ALL trackers must be castable to a type of this, i.e. this structure must be the first element of their own data type.
185 */
186struct ecm_tracker_instance {
187 ecm_tracker_data_total_get_method_t data_total_get;
188 ecm_tracker_data_limit_get_method_t data_limit_get;
189 ecm_tracker_data_limit_set_method_t data_limit_set;
190 ecm_tracker_datagram_count_get_method_t datagram_count_get;
191 ecm_tracker_datagram_discard_method_t datagram_discard;
192 ecm_tracker_datagram_size_get_method_t datagram_size_get;
193 ecm_tracker_datagram_read_method_t datagram_read;
194 ecm_tracker_datagram_add_method_t datagram_add;
195 ecm_tracker_discard_all_method_t discard_all;
196 ecm_tracker_state_update_method_t state_update;
197 ecm_tracker_state_get_method_t state_get;
198 ecm_tracker_xml_state_get_callback_t xml_state_get; /* Return an XML element containing its state */
199 ecm_tracker_ref_method_t ref;
200 ecm_tracker_deref_method_t deref;
201};
202
203bool ecm_tracker_ip_check_header_and_read(struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb);
204uint32_t ecm_tracker_data_limit_get(void);
205void ecm_tracker_data_limit_set(uint32_t limit);
206uint32_t ecm_tracker_data_total_get(void);
207uint32_t ecm_tracker_data_buffer_total_get(void);
208bool ecm_tracker_data_total_increase(uint32_t n, uint32_t data_bufer_size);
209void ecm_tracker_data_total_decrease(uint32_t n, uint32_t data_bufer_size);
210