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 | |
Murat Sezgin | 109b2ce | 2017-06-08 11:56:56 -0700 | [diff] [blame] | 27 | /* |
| 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 34 | enum 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 | }; |
| 39 | typedef 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 | */ |
| 47 | enum 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 | }; |
| 56 | typedef 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 Costa | 1d9eb99 | 2014-05-15 10:01:03 -0500 | [diff] [blame] | 62 | const char * |
| 63 | ecm_tracker_sender_state_to_string(enum ecm_tracker_sender_states); |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 64 | |
| 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 | */ |
| 71 | enum 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 | }; |
| 79 | typedef enum ecm_tracker_connection_states ecm_tracker_connection_state_t; |
| 80 | |
| 81 | /* |
Nicolas Costa | 1d9eb99 | 2014-05-15 10:01:03 -0500 | [diff] [blame] | 82 | * ecm_tracker_connection_state_to_string |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 83 | * Convert a connection state to a string |
| 84 | */ |
Gareth Williams | d5618a8 | 2015-05-20 11:13:32 +0100 | [diff] [blame] | 85 | 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] | 86 | |
| 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 | */ |
| 97 | enum ecm_tracker_ip_protocol_types { |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 98 | ECM_TRACKER_IP_PROTOCOL_TYPE_UNKNOWN, /* A protocol that is unrecognised */ |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 99 | 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 Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 103 | #ifdef ECM_IPV6_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 104 | 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 Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 109 | ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_HBH, /* IPv6 hop-by-hop header */ |
| 110 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 111 | ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT /* Must be last, do not use */ |
| 112 | }; |
| 113 | typedef 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 | */ |
| 119 | struct 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 | */ |
| 132 | struct ecm_tracker_ip_header { |
| 133 | /* |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 134 | * h is a union of IP version headers. |
Gareth Williams | 75086b2 | 2015-04-28 12:52:08 +0100 | [diff] [blame] | 135 | * 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 138 | */ |
| 139 | union { |
| 140 | struct iphdr v4_hdr; |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 141 | #ifdef ECM_IPV6_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 142 | struct ipv6hdr v6_hdr; |
Gareth Williams | 8ac3429 | 2015-03-17 14:06:58 +0000 | [diff] [blame] | 143 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 144 | } h; |
| 145 | |
Gareth Williams | 75086b2 | 2015-04-28 12:52:08 +0100 | [diff] [blame] | 146 | 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] | 147 | 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 Sezgin | 109b2ce | 2017-06-08 11:56:56 -0700 | [diff] [blame] | 152 | uint8_t dscp; /* DSCP field from the packet */ |
Gareth Williams | 8932a91 | 2014-06-11 18:06:25 -0700 | [diff] [blame] | 153 | uint8_t ds; /* DS field from packet */ |
Shyam Sunder | f0b6a59 | 2015-07-23 18:06:45 +0530 | [diff] [blame] | 154 | uint8_t ttl; /* v4 TTL or v6 hop limit */ |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 155 | 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 Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 162 | #ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 163 | typedef 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 */ |
| 165 | typedef 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 */ |
| 167 | typedef 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 */ |
| 169 | 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); |
| 170 | /* Read size bytes from datagram at index i into the buffer */ |
| 171 | typedef 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 173 | typedef void (*ecm_tracker_discard_all_method_t)(struct ecm_tracker_instance *ti); |
| 174 | /* Discard all tracked data */ |
| 175 | typedef int32_t (*ecm_tracker_data_total_get_method_t)(struct ecm_tracker_instance *ti); |
| 176 | /* Return number of bytes of tracked data in total */ |
| 177 | typedef 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 */ |
| 179 | typedef 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 Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 181 | #endif |
| 182 | typedef void (*ecm_tracker_ref_method_t)(struct ecm_tracker_instance *ti); |
| 183 | typedef int (*ecm_tracker_deref_method_t)(struct ecm_tracker_instance *ti); |
| 184 | |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 185 | 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); |
| 186 | /* Update state of the sender */ |
| 187 | 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); |
| 188 | /* State of the connection */ |
Gareth Williams | f98d419 | 2015-03-11 16:55:41 +0000 | [diff] [blame] | 189 | #ifdef ECM_STATE_OUTPUT_ENABLE |
Gareth Williams | d5618a8 | 2015-05-20 11:13:32 +0100 | [diff] [blame] | 190 | typedef 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 Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 194 | */ |
Gareth Williams | f98d419 | 2015-03-11 16:55:41 +0000 | [diff] [blame] | 195 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 196 | |
| 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 | */ |
| 204 | struct ecm_tracker_instance { |
Gareth Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 205 | #ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 206 | 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 Williams | 88be372 | 2015-03-23 19:51:01 +0000 | [diff] [blame] | 215 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 216 | ecm_tracker_state_update_method_t state_update; |
| 217 | ecm_tracker_state_get_method_t state_get; |
Gareth Williams | f98d419 | 2015-03-11 16:55:41 +0000 | [diff] [blame] | 218 | #ifdef ECM_STATE_OUTPUT_ENABLE |
Gareth Williams | d5618a8 | 2015-05-20 11:13:32 +0100 | [diff] [blame] | 219 | 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] | 220 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 221 | ecm_tracker_ref_method_t ref; |
| 222 | ecm_tracker_deref_method_t deref; |
| 223 | }; |
| 224 | |
| 225 | 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] | 226 | #ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 227 | uint32_t ecm_tracker_data_limit_get(void); |
| 228 | void ecm_tracker_data_limit_set(uint32_t limit); |
| 229 | uint32_t ecm_tracker_data_total_get(void); |
| 230 | uint32_t ecm_tracker_data_buffer_total_get(void); |
| 231 | bool ecm_tracker_data_total_increase(uint32_t n, uint32_t data_bufer_size); |
| 232 | 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] | 233 | #endif |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 234 | |