Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 1 | /* |
| 2 | ************************************************************************** |
Gareth Williams | d5618a8 | 2015-05-20 11:13:32 +0100 | [diff] [blame] | 3 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 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 | |
| 17 | struct 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 | |
| 27 | enum 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 | }; |
| 32 | typedef 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 | */ |
| 40 | enum 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 | }; |
| 49 | typedef 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 Costa | 1d9eb99 | 2014-05-15 10:01:03 -0500 | [diff] [blame] | 55 | const char * |
| 56 | ecm_tracker_sender_state_to_string(enum ecm_tracker_sender_states); |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 57 | |
| 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 | */ |
| 64 | enum 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 | }; |
| 72 | typedef enum ecm_tracker_connection_states ecm_tracker_connection_state_t; |
| 73 | |
| 74 | /* |
Nicolas Costa | 1d9eb99 | 2014-05-15 10:01:03 -0500 | [diff] [blame] | 75 | * ecm_tracker_connection_state_to_string |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 76 | * Convert a connection state to a string |
| 77 | */ |
Gareth Williams | d5618a8 | 2015-05-20 11:13:32 +0100 | [diff] [blame] | 78 | const char *ecm_tracker_connection_state_to_string(enum ecm_tracker_connection_states); |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 79 | |
| 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 | */ |
| 90 | enum ecm_tracker_ip_protocol_types { |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 91 | ECM_TRACKER_IP_PROTOCOL_TYPE_UNKNOWN, /* A protocol that is unrecognised */ |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 92 | 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 Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 96 | #ifdef ECM_IPV6_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 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, |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 102 | ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_HBH, /* IPv6 hop-by-hop header */ |
| 103 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 104 | ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT /* Must be last, do not use */ |
| 105 | }; |
| 106 | typedef 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 | */ |
| 112 | struct 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 | */ |
| 125 | struct ecm_tracker_ip_header { |
| 126 | /* |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 127 | * h is a union of IP version headers. |
Gareth Williams | 75086b2 | 2015-04-28 12:52:08 +0100 | [diff] [blame] | 128 | * 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 131 | */ |
| 132 | union { |
| 133 | struct iphdr v4_hdr; |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 134 | #ifdef ECM_IPV6_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 135 | struct ipv6hdr v6_hdr; |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 136 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 137 | } h; |
| 138 | |
Gareth Williams | 75086b2 | 2015-04-28 12:52:08 +0100 | [diff] [blame] | 139 | 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 140 | 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 Williams | 8932a91 | 2014-06-11 18:06:25 -0700 | [diff] [blame] | 145 | uint8_t ds; /* DS field from packet */ |
Shyam Sunder | f0b6a59 | 2015-07-23 18:06:45 +0530 | [diff] [blame] | 146 | uint8_t ttl; /* v4 TTL or v6 hop limit */ |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 147 | 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 Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 154 | #ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 155 | typedef 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 */ |
| 157 | typedef 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 */ |
| 159 | typedef 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 */ |
| 161 | typedef 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 */ |
| 163 | typedef 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 165 | typedef void (*ecm_tracker_discard_all_method_t)(struct ecm_tracker_instance *ti); |
| 166 | /* Discard all tracked data */ |
| 167 | typedef int32_t (*ecm_tracker_data_total_get_method_t)(struct ecm_tracker_instance *ti); |
| 168 | /* Return number of bytes of tracked data in total */ |
| 169 | typedef 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 */ |
| 171 | typedef 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 Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 173 | #endif |
| 174 | typedef void (*ecm_tracker_ref_method_t)(struct ecm_tracker_instance *ti); |
| 175 | typedef int (*ecm_tracker_deref_method_t)(struct ecm_tracker_instance *ti); |
| 176 | |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 177 | typedef 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 */ |
| 179 | typedef 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 Williams | f98d419 | 2015-03-11 16:55:41 +0000 | [diff] [blame] | 181 | #ifdef ECM_STATE_OUTPUT_ENABLE |
Gareth Williams | d5618a8 | 2015-05-20 11:13:32 +0100 | [diff] [blame] | 182 | typedef 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 186 | */ |
Gareth Williams | f98d419 | 2015-03-11 16:55:41 +0000 | [diff] [blame] | 187 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 188 | |
| 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 | */ |
| 196 | struct ecm_tracker_instance { |
Gareth Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 197 | #ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 198 | 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 Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 207 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 208 | ecm_tracker_state_update_method_t state_update; |
| 209 | ecm_tracker_state_get_method_t state_get; |
Gareth Williams | f98d419 | 2015-03-11 16:55:41 +0000 | [diff] [blame] | 210 | #ifdef ECM_STATE_OUTPUT_ENABLE |
Gareth Williams | d5618a8 | 2015-05-20 11:13:32 +0100 | [diff] [blame] | 211 | ecm_tracker_state_get_callback_t state_text_get; /* Return text containing its state */ |
Gareth Williams | f98d419 | 2015-03-11 16:55:41 +0000 | [diff] [blame] | 212 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 213 | ecm_tracker_ref_method_t ref; |
| 214 | ecm_tracker_deref_method_t deref; |
| 215 | }; |
| 216 | |
| 217 | bool ecm_tracker_ip_check_header_and_read(struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb); |
Gareth Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 218 | #ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 219 | uint32_t ecm_tracker_data_limit_get(void); |
| 220 | void ecm_tracker_data_limit_set(uint32_t limit); |
| 221 | uint32_t ecm_tracker_data_total_get(void); |
| 222 | uint32_t ecm_tracker_data_buffer_total_get(void); |
| 223 | bool ecm_tracker_data_total_increase(uint32_t n, uint32_t data_bufer_size); |
| 224 | void ecm_tracker_data_total_decrease(uint32_t n, uint32_t data_bufer_size); |
Gareth Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 225 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 226 | |