Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 1 | /* |
| 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 | |
| 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 | */ |
Nicolas Costa | 1d9eb99 | 2014-05-15 10:01:03 -0500 | [diff] [blame] | 78 | const char * |
| 79 | ecm_tracker_connection_state_to_string(enum ecm_tracker_connection_states); |
Ben Menchaca | 84f3663 | 2014-02-28 20:57:38 +0000 | [diff] [blame] | 80 | |
| 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 | */ |
| 91 | enum 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 | }; |
| 105 | typedef 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 | */ |
| 111 | struct 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 | */ |
| 124 | struct 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 | |
| 148 | typedef 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 */ |
| 150 | typedef 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 */ |
| 152 | typedef 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 */ |
| 154 | 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); |
| 155 | /* Read size bytes from datagram at index i into the buffer */ |
| 156 | typedef 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 */ |
| 158 | typedef void (*ecm_tracker_ref_method_t)(struct ecm_tracker_instance *ti); |
| 159 | typedef int (*ecm_tracker_deref_method_t)(struct ecm_tracker_instance *ti); |
| 160 | |
| 161 | typedef void (*ecm_tracker_discard_all_method_t)(struct ecm_tracker_instance *ti); |
| 162 | /* Discard all tracked data */ |
| 163 | typedef int32_t (*ecm_tracker_data_total_get_method_t)(struct ecm_tracker_instance *ti); |
| 164 | /* Return number of bytes of tracked data in total */ |
| 165 | typedef 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 */ |
| 167 | typedef 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 */ |
| 169 | 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); |
| 170 | /* Update state of the sender */ |
| 171 | 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); |
| 172 | /* State of the connection */ |
| 173 | typedef 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 | */ |
| 186 | struct 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 | |
| 203 | bool ecm_tracker_ip_check_header_and_read(struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb); |
| 204 | uint32_t ecm_tracker_data_limit_get(void); |
| 205 | void ecm_tracker_data_limit_set(uint32_t limit); |
| 206 | uint32_t ecm_tracker_data_total_get(void); |
| 207 | uint32_t ecm_tracker_data_buffer_total_get(void); |
| 208 | bool ecm_tracker_data_total_increase(uint32_t n, uint32_t data_bufer_size); |
| 209 | void ecm_tracker_data_total_decrease(uint32_t n, uint32_t data_bufer_size); |
| 210 | |