1/* 2 ************************************************************************** 3 * Copyright (c) 2014-2015, 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#include <linux/version.h> 18#include <linux/types.h> 19#include <linux/ip.h> 20#include <linux/tcp.h> 21#include <linux/module.h> 22#include <linux/skbuff.h> 23#include <linux/icmp.h> 24#include <linux/sysctl.h> 25#include <linux/kthread.h> 26#include <linux/device.h> 27#include <linux/fs.h> 28#include <linux/pkt_sched.h> 29#include <linux/string.h> 30#include <net/route.h> 31#include <net/ip.h> 32#include <net/tcp.h> 33#include <asm/unaligned.h> 34#include <asm/uaccess.h> /* for put_user */ 35#include <net/ipv6.h> 36#include <linux/inet.h> 37#include <linux/in.h> 38#include <linux/udp.h> 39#include <linux/tcp.h> 40 41#include <linux/netfilter_ipv4.h> 42#include <linux/netfilter_bridge.h> 43#include <net/netfilter/nf_conntrack.h> 44#include <net/netfilter/nf_conntrack_helper.h> 45#include <net/netfilter/nf_conntrack_l4proto.h> 46#include <net/netfilter/nf_conntrack_l3proto.h> 47#include <net/netfilter/nf_conntrack_core.h> 48#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 49#include <net/netfilter/ipv4/nf_defrag_ipv4.h> 50 51/* 52 * Debug output levels 53 * 0 = OFF 54 * 1 = ASSERTS / ERRORS 55 * 2 = 1 + WARN 56 * 3 = 2 + INFO 57 * 4 = 3 + TRACE 58 */ 59#define DEBUG_LEVEL ECM_TRACKER_UDP_DEBUG_LEVEL 60 61#include "ecm_types.h" 62#include "ecm_db_types.h" 63#include "ecm_state.h" 64#include "ecm_tracker.h" 65#include "ecm_tracker_udp.h" 66 67/* 68 * Magic numbers 69 */ 70#define ECM_TRACKER_UDP_INSTANCE_MAGIC 0x7765 71#define ECM_TRACKER_UDP_SKB_CB_MAGIC 0xAAAB 72 73/* 74 * Useful constants 75 */ 76#define ECM_TRACKER_UDP_HEADER_SIZE 8 /* UDP header is always 8 bytes RFC 768 Page 1 */ 77 78#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 79/* 80 * struct ecm_tracker_udp_skb_cb_format 81 * Map of the cb[] array within our cached buffers - we use that area for our tracking 82 */ 83struct ecm_tracker_udp_skb_cb_format { 84 uint32_t data_offset; /* Offset in skb data to the actual datagram data - i.e. omitting headers */ 85 uint32_t data_size; /* Size of data */ 86#if (DEBUG_LEVEL > 0) 87 uint16_t magic; 88#endif 89}; 90#endif 91 92/* 93 * struct ecm_tracker_udp_internal_instance 94 */ 95struct ecm_tracker_udp_internal_instance { 96 struct ecm_tracker_udp_instance udp_base; /* MUST BE FIRST FIELD */ 97 98#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 99 /* 100 * skb-next and skb->prev pointers are leveraged for these lists 101 */ 102 struct sk_buff *src_recvd_order; /* sk buff list as sent by src */ 103 struct sk_buff *src_recvd_order_last; /* Last skb send - for fast appending of new buffers */ 104 int32_t src_count; /* Count of datagrams in list */ 105 int32_t src_bytes_total; /* Total bytes in all received datagrams */ 106 107 struct sk_buff *dest_recvd_order; /* sk buff list as sent by dest */ 108 struct sk_buff *dest_recvd_order_last; /* Last skb send - for fast appending of new buffers */ 109 int32_t dest_count; /* Count of datagrams in list */ 110 int32_t dest_bytes_total; /* Total bytes in all received datagrams */ 111 112 int32_t data_limit; /* Limit for tracked data */ 113#endif 114 115 ecm_tracker_sender_state_t sender_state[ECM_TRACKER_SENDER_MAX]; 116 /* State of each sender */ 117 ecm_db_timer_group_t timer_group; /* Recommended timer group for connection that is using this tracker */ 118 119 spinlock_t lock; /* lock */ 120 121 int refs; /* Integer to trap we never go negative */ 122#if (DEBUG_LEVEL > 0) 123 uint16_t magic; 124#endif 125}; 126 127int ecm_tracker_udp_count = 0; /* Counts the number of UDP data trackers right now */ 128static DEFINE_SPINLOCK(ecm_tracker_udp_lock); /* Global lock for the tracker globals */ 129 130/* 131 * ecm_trracker_udp_connection_state_matrix[][] 132 * Matrix to convert from/to states to connection state 133 */ 134static ecm_tracker_connection_state_t ecm_tracker_udp_connection_state_matrix[ECM_TRACKER_SENDER_STATE_MAX][ECM_TRACKER_SENDER_STATE_MAX] = 135{ /* Unknown Establishing Established Closing Closed Fault */ 136 /* Unknown */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT}, 137 /* Establishing */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT}, 138 /* Established */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT}, 139 /* Closing */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT}, 140 /* Closed */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSED, ECM_TRACKER_CONNECTION_STATE_FAULT}, 141 /* Fault */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT}, 142}; 143 144/* 145 * ecm_tracker_udp_check_header_and_read() 146 * Check for validly sized header and read the udp protocol header 147 */ 148struct udphdr *ecm_tracker_udp_check_header_and_read(struct sk_buff *skb, struct ecm_tracker_ip_header *ip_hdr, struct udphdr *port_buffer) 149{ 150 struct ecm_tracker_ip_protocol_header *header; 151 152 /* 153 * Is there a UDP header? 154 */ 155 header = &ip_hdr->headers[ECM_TRACKER_IP_PROTOCOL_TYPE_UDP]; 156 if (header->header_size != ECM_TRACKER_UDP_HEADER_SIZE) { 157 DEBUG_WARN("Skb: %p, UDP header size bad %u\n", skb, header->header_size); 158 return NULL; 159 } 160 161 return skb_header_pointer(skb, header->offset, sizeof(*port_buffer), port_buffer); 162} 163EXPORT_SYMBOL(ecm_tracker_udp_check_header_and_read); 164 165#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 166/* 167 * ecm_tracker_udp_datagram_discard() 168 * Discard n number of datagrams at the head of the datagram list that were sent to the target 169 */ 170static void ecm_tracker_udp_datagram_discard(struct ecm_tracker_udp_internal_instance *utii, ecm_tracker_sender_type_t sender, int32_t n) 171{ 172 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 173 174 DEBUG_TRACE("%p: discard %u datagrams for %d\n", utii, n, sender); 175 176 /* 177 * Which list? 178 */ 179 if (sender == ECM_TRACKER_SENDER_TYPE_SRC) { 180 /* 181 * iterate n times and discard the buffers 182 */ 183 while (n) { 184 struct sk_buff *skb; 185 186 spin_lock_bh(&utii->lock); 187 188 skb = utii->src_recvd_order; 189 DEBUG_ASSERT(skb, "%p: bad list\n", utii); 190 191 utii->src_recvd_order = skb->next; 192 if (!utii->src_recvd_order) { 193 DEBUG_ASSERT(utii->src_recvd_order_last == skb, "%p: bad list\n", utii); 194 utii->src_recvd_order_last = NULL; 195 } else { 196 utii->src_recvd_order->prev = NULL; 197 } 198 199 utii->src_count--; 200 DEBUG_ASSERT(utii->src_count >= 0, "%p: bad total\n", utii); 201 utii->src_bytes_total -= skb->truesize; 202 ecm_tracker_data_total_decrease(skb->len, skb->truesize); 203 DEBUG_ASSERT(utii->src_bytes_total >= 0, "%p: bad bytes total\n", utii); 204 205 spin_unlock_bh(&utii->lock); 206 kfree_skb(skb); 207 208 n--; 209 } 210 return; 211 } 212 213 /* 214 * iterate n times and discard the buffers 215 */ 216 while (n) { 217 struct sk_buff *skb; 218 219 spin_lock_bh(&utii->lock); 220 221 skb = utii->dest_recvd_order; 222 DEBUG_ASSERT(skb, "%p: bad list\n", utii); 223 224 utii->dest_recvd_order = skb->next; 225 if (!utii->dest_recvd_order) { 226 DEBUG_ASSERT(utii->dest_recvd_order_last == skb, "%p: bad list\n", utii); 227 utii->dest_recvd_order_last = NULL; 228 } else { 229 utii->dest_recvd_order->prev = NULL; 230 } 231 232 utii->dest_count--; 233 DEBUG_ASSERT(utii->dest_count >= 0, "%p: bad total\n", utii); 234 utii->dest_bytes_total -= skb->truesize; 235 ecm_tracker_data_total_decrease(skb->len, skb->truesize); 236 DEBUG_ASSERT(utii->dest_bytes_total >= 0, "%p: bad bytes total\n", utii); 237 238 spin_unlock_bh(&utii->lock); 239 kfree_skb(skb); 240 241 n--; 242 } 243} 244 245/* 246 * ecm_tracker_udp_discard_all() 247 * Discard all tracked data 248 */ 249void ecm_tracker_udp_discard_all(struct ecm_tracker_udp_internal_instance *utii) 250{ 251 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 252 253 /* 254 * Destroy all datagrams 255 */ 256 DEBUG_TRACE("%p: destroy all\n", utii); 257 ecm_tracker_udp_datagram_discard(utii, ECM_TRACKER_SENDER_TYPE_SRC, utii->src_count); 258 ecm_tracker_udp_datagram_discard(utii, ECM_TRACKER_SENDER_TYPE_DEST, utii->dest_count); 259} 260 261/* 262 * ecm_tracker_udp_discard_all_callback() 263 * Discard all tracked data 264 */ 265static void ecm_tracker_udp_discard_all_callback(struct ecm_tracker_instance *ti) 266{ 267 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 268 ecm_tracker_udp_discard_all(utii); 269} 270#endif 271 272/* 273 * ecm_tracker_udp_ref() 274 */ 275static void ecm_tracker_udp_ref(struct ecm_tracker_udp_internal_instance *utii) 276{ 277 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 278 279 spin_lock_bh(&utii->lock); 280 281 utii->refs++; 282 DEBUG_ASSERT(utii->refs > 0, "%p: ref wrap", utii); 283 DEBUG_TRACE("%p: ref %d\n", utii, utii->refs); 284 285 spin_unlock_bh(&utii->lock); 286} 287 288/* 289 * ecm_tracker_udp_ref_callback() 290 */ 291void ecm_tracker_udp_ref_callback(struct ecm_tracker_instance *ti) 292{ 293 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 294 ecm_tracker_udp_ref(utii); 295} 296 297/* 298 * ecm_tracker_udp_deref() 299 */ 300static int ecm_tracker_udp_deref(struct ecm_tracker_udp_internal_instance *utii) 301{ 302 int refs; 303 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 304 305 spin_lock_bh(&utii->lock); 306 utii->refs--; 307 refs = utii->refs; 308 DEBUG_ASSERT(utii->refs >= 0, "%p: ref wrap", utii); 309 DEBUG_TRACE("%p: deref %d\n", utii, utii->refs); 310 311 if (utii->refs > 0) { 312 spin_unlock_bh(&utii->lock); 313 return refs; 314 } 315 spin_unlock_bh(&utii->lock); 316 317 DEBUG_TRACE("%p: final\n", utii); 318 319#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 320 /* 321 * Destroy all datagrams 322 */ 323 ecm_tracker_udp_datagram_discard(utii, ECM_TRACKER_SENDER_TYPE_SRC, utii->src_count); 324 ecm_tracker_udp_datagram_discard(utii, ECM_TRACKER_SENDER_TYPE_DEST, utii->dest_count); 325#endif 326 327 spin_lock_bh(&ecm_tracker_udp_lock); 328 ecm_tracker_udp_count--; 329 DEBUG_ASSERT(ecm_tracker_udp_count >= 0, "%p: tracker count wrap", utii); 330 spin_unlock_bh(&ecm_tracker_udp_lock); 331 332 DEBUG_INFO("%p: Udp tracker final\n", utii); 333 DEBUG_CLEAR_MAGIC(utii); 334 kfree(utii); 335 336 return 0; 337} 338 339/* 340 * _ecm_tracker_udp_deref_callback() 341 */ 342int ecm_tracker_udp_deref_callback(struct ecm_tracker_instance *ti) 343{ 344 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 345 return ecm_tracker_udp_deref(utii); 346} 347 348#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 349/* 350 * ecm_tracker_udp_datagram_count_get() 351 * Return number of available datagrams sent to the specified target 352 */ 353static int32_t ecm_tracker_udp_datagram_count_get(struct ecm_tracker_udp_internal_instance *utii, ecm_tracker_sender_type_t sender) 354{ 355 int32_t count; 356 357 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 358 359 /* 360 * Which list? 361 */ 362 spin_lock_bh(&utii->lock); 363 if (sender == ECM_TRACKER_SENDER_TYPE_SRC) { 364 count = utii->src_count; 365 } else { 366 count = utii->dest_count; 367 } 368 spin_unlock_bh(&utii->lock); 369 370 DEBUG_TRACE("%p: datagram count get for %d is %d\n", utii, sender, count); 371 372 return count; 373} 374 375/* 376 * ecm_tracker_udp_datagram_count_get_callback() 377 * Return number of available datagrams sent to the specified target 378 */ 379static int32_t ecm_tracker_udp_datagram_count_get_callback(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender) 380{ 381 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 382 return ecm_tracker_udp_datagram_count_get(utii, sender); 383} 384 385/* 386 * ecm_tracker_udp_datagram_discard_callback() 387 * Discard n number of datagrams at the head of the datagram list that were sent to the target 388 */ 389static void ecm_tracker_udp_datagram_discard_callback(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t n) 390{ 391 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 392 393 ecm_tracker_udp_datagram_discard(utii, sender, n); 394} 395 396/* 397 * ecm_tracker_udp_datagram_size_get() 398 * Return size in bytes of datagram at index i that was sent to the target 399 */ 400int32_t ecm_tracker_udp_datagram_size_get(struct ecm_tracker_udp_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) 401{ 402 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)uti; 403 int32_t size; 404 struct sk_buff *skb; 405 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 406 407 /* 408 * Which list? 409 */ 410 spin_lock_bh(&utii->lock); 411 if (sender == ECM_TRACKER_SENDER_TYPE_SRC) { 412 skb = utii->src_recvd_order; 413 } else { 414 skb = utii->dest_recvd_order; 415 } 416 417 /* 418 * Iterate to the i'th datagram 419 */ 420 while (i) { 421 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 422 skb = skb->next; 423 i--; 424 } 425 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 426 427 size = skb->len; 428 429 spin_unlock_bh(&utii->lock); 430 return size; 431} 432 433/* 434 * ecm_tracker_udp_datagram_size_get_callback() 435 * Return size in bytes of datagram at index i that was sent to the target 436 */ 437static int32_t ecm_tracker_udp_datagram_size_get_callback(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i) 438{ 439 struct ecm_tracker_udp_instance *uti = (struct ecm_tracker_udp_instance *)ti; 440 441 return ecm_tracker_udp_datagram_size_get(uti, sender, i); 442} 443 444/* 445 * ecm_tracker_udp_datagram_read() 446 * Read size bytes from datagram at index i into the buffer 447 */ 448int ecm_tracker_udp_datagram_read(struct ecm_tracker_udp_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) 449{ 450 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)uti; 451 int res; 452 struct sk_buff *skb; 453 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 454 DEBUG_TRACE("%p: datagram %d read at offset %d for %d bytes for %d\n", utii, i, offset, size, sender); 455 456 /* 457 * Which list? 458 */ 459 spin_lock_bh(&utii->lock); 460 if (sender == ECM_TRACKER_SENDER_TYPE_SRC) { 461 skb = utii->src_recvd_order; 462 } else { 463 skb = utii->dest_recvd_order; 464 } 465 466 /* 467 * Iterate to the i'th datagram 468 */ 469 while (i) { 470 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 471 skb = skb->next; 472 i--; 473 } 474 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 475 476 /* 477 * Perform read 478 */ 479 res = skb_copy_bits(skb, offset, buffer, (unsigned int)size); 480 481 spin_unlock_bh(&utii->lock); 482 483 return res; 484} 485 486/* 487 * ecm_tracker_udp_datagram_read_callback() 488 * Read size bytes from datagram at index i into the buffer 489 */ 490static int ecm_tracker_udp_datagram_read_callback(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) 491{ 492 struct ecm_tracker_udp_instance *uti = (struct ecm_tracker_udp_instance *)ti; 493 494 return ecm_tracker_udp_datagram_read(uti, sender, i, offset, size, buffer); 495} 496 497/* 498 * ecm_tracker_udp_data_total_get_callback() 499 * Return total tracked data 500 */ 501static int32_t ecm_tracker_udp_data_total_get_callback(struct ecm_tracker_instance *ti) 502{ 503 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 504 int32_t data_total; 505 506 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 507 508 spin_lock_bh(&utii->lock); 509 data_total = utii->src_bytes_total + utii->dest_bytes_total; 510 spin_unlock_bh(&utii->lock); 511 512 return data_total; 513} 514 515/* 516 * ecm_tracker_udp_data_limit_get_callback() 517 * Return tracked data limit 518 */ 519static int32_t ecm_tracker_udp_data_limit_get_callback(struct ecm_tracker_instance *ti) 520{ 521 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 522 int32_t data_limit; 523 524 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 525 526 spin_lock_bh(&utii->lock); 527 data_limit = utii->data_limit; 528 spin_unlock_bh(&utii->lock); 529 530 return data_limit; 531} 532 533/* 534 * ecm_tracker_udp_data_limit_set_callback() 535 * Set tracked data limit 536 */ 537static void ecm_tracker_udp_data_limit_set_callback(struct ecm_tracker_instance *ti, int32_t data_limit) 538{ 539 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 540 541 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 542 543 spin_lock_bh(&utii->lock); 544 utii->data_limit = data_limit; 545 spin_unlock_bh(&utii->lock); 546} 547 548/* 549 * ecm_tracker_udp_datagram_add() 550 * Append the datagram onto the tracker queue for the given target 551 */ 552static bool ecm_tracker_udp_datagram_add(struct ecm_tracker_udp_internal_instance *utii, ecm_tracker_sender_type_t sender, 553 struct ecm_tracker_ip_header *ip_hdr, struct ecm_tracker_ip_protocol_header *ecm_udp_header, 554 struct udphdr *udp_header, struct sk_buff *skb) 555{ 556 struct sk_buff *skbc; 557 struct ecm_tracker_udp_skb_cb_format *skbc_cb; 558 559 DEBUG_TRACE("%p: datagram %p add for %d, ip_hdr_len %u, total len: %u, offset: %u, size: %u\n", 560 utii, skb, sender, ip_hdr->ip_header_length, ip_hdr->total_length, 561 ecm_udp_header->offset, ecm_udp_header->size); 562 563 /* 564 * Clone the packet 565 */ 566 skbc = skb_clone(skb, GFP_ATOMIC | __GFP_NOWARN); 567 if (!skbc) { 568 DEBUG_WARN("%p: Failed to clone packet %p\n", utii, skb); 569 return false; 570 } 571 572 DEBUG_TRACE("%p: cloned %p to %p\n", utii, skb, skbc); 573 574 /* 575 * Get the private cb area and initialise it. 576 * ALL DATAGRAMS HAVE TO HAVE ONE. 577 */ 578 skbc_cb = (struct ecm_tracker_udp_skb_cb_format *)skbc->cb; 579 DEBUG_SET_MAGIC(skbc_cb, ECM_TRACKER_UDP_SKB_CB_MAGIC); 580 skbc_cb->data_offset = ecm_udp_header->offset + ecm_udp_header->header_size; 581 if (ip_hdr->total_length < (ecm_udp_header->offset + ecm_udp_header->size)) { 582 DEBUG_WARN("%p: Invalid headers\n", utii); 583 kfree_skb(skbc); 584 return false; 585 } 586 skbc_cb->data_size = ecm_udp_header->size - ecm_udp_header->header_size; 587 588 /* 589 * Are we within instance limit? 590 */ 591 spin_lock_bh(&utii->lock); 592 DEBUG_ASSERT((utii->src_bytes_total + utii->dest_bytes_total + skbc->truesize) > 0, "%p: bad total\n", utii); 593 if ((utii->src_bytes_total + utii->dest_bytes_total + skbc->truesize) > utii->data_limit) { 594 DEBUG_TRACE("%p: over limit\n", utii); 595 spin_unlock_bh(&utii->lock); 596 kfree_skb(skbc); 597 return false; 598 } 599 600 /* 601 * Within global limit? 602 */ 603 if (!ecm_tracker_data_total_increase(skbc->len, skbc->truesize)) { 604 DEBUG_TRACE("%p: over global limit\n", utii); 605 spin_unlock_bh(&utii->lock); 606 kfree_skb(skbc); 607 return false; 608 } 609 610 /* 611 * Which list to insert the datagram in to? 612 */ 613 if (sender == ECM_TRACKER_SENDER_TYPE_SRC) { 614 skbc->next = NULL; 615 skbc->prev = utii->src_recvd_order_last; 616 utii->src_recvd_order_last = skbc; 617 if (skbc->prev) { 618 skbc->prev->next = skbc; 619 } else { 620 DEBUG_ASSERT(utii->src_recvd_order == NULL, "%p: bad list\n", utii); 621 utii->src_recvd_order = skbc; 622 } 623 624 utii->src_count++; 625 DEBUG_ASSERT(utii->src_count > 0, "%p: bad total\n", utii); 626 utii->src_bytes_total += skbc->truesize; 627 spin_unlock_bh(&utii->lock); 628 return true; 629 } 630 631 skbc->next = NULL; 632 skbc->prev = utii->dest_recvd_order_last; 633 utii->dest_recvd_order_last = skbc; 634 if (skbc->prev) { 635 skbc->prev->next = skbc; 636 } else { 637 DEBUG_ASSERT(utii->dest_recvd_order == NULL, "%p: bad list\n", utii); 638 utii->dest_recvd_order = skbc; 639 } 640 641 utii->dest_count++; 642 DEBUG_ASSERT(utii->dest_count > 0, "%p: bad total\n", utii); 643 utii->dest_bytes_total += skbc->truesize; 644 spin_unlock_bh(&utii->lock); 645 return true; 646} 647 648/* 649 * _ecm_tracker_udp_datagram_add_callback() 650 * Append the datagram onto the tracker queue for the given target 651 */ 652static bool ecm_tracker_udp_datagram_add_callback(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct sk_buff *skb) 653{ 654 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 655 struct ecm_tracker_ip_header ip_hdr; 656 struct ecm_tracker_ip_protocol_header *ecm_udp_header; 657 struct udphdr *udp_header; 658 struct udphdr udp_header_buffer; 659 660 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 661 662 /* 663 * Obtain the IP header from the skb 664 */ 665 if (!ecm_tracker_ip_check_header_and_read(&ip_hdr, skb)) { 666 DEBUG_WARN("%p: no ip_hdr for %p\n", utii, skb); 667 return false; 668 } 669 670 /* 671 * Get UDP header 672 */ 673 udp_header = ecm_tracker_udp_check_header_and_read(skb, &ip_hdr, &udp_header_buffer); 674 if (!udp_header) { 675 DEBUG_WARN("%p: not/invalid udp %d\n", utii, ip_hdr.protocol); 676 return false; 677 } 678 ecm_udp_header = &ip_hdr.headers[ECM_TRACKER_IP_PROTOCOL_TYPE_UDP]; 679 680 return ecm_tracker_udp_datagram_add(utii, sender, &ip_hdr, ecm_udp_header, udp_header, skb); 681} 682 683/* 684 * ecm_tracker_udp_datagram_add_checked_callback() 685 * Add a pre-checked datagram 686 */ 687static bool ecm_tracker_udp_datagram_add_checked_callback(struct ecm_tracker_udp_instance *uti, ecm_tracker_sender_type_t sender, 688 struct ecm_tracker_ip_header *ip_hdr, struct ecm_tracker_ip_protocol_header *ecm_udp_header, 689 struct udphdr *udp_header, struct sk_buff *skb) 690{ 691 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)uti; 692 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 693 return ecm_tracker_udp_datagram_add(utii, sender, ip_hdr, ecm_udp_header, udp_header, skb); 694} 695 696/* 697 * ecm_tracker_udp_data_read_callback() 698 * Return size bytes of datagram data at index i that was sent to the target 699 */ 700static int ecm_tracker_udp_data_read_callback(struct ecm_tracker_udp_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, 701 int32_t offset, int32_t size, void *buffer) 702 703{ 704 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)uti; 705 int res; 706 struct sk_buff *skb; 707 struct ecm_tracker_udp_skb_cb_format *skb_cb; 708 709 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 710 DEBUG_TRACE("%p: datagram data %d read at offset %d for %d bytes for %d\n", utii, i, offset, size, sender); 711 712 /* 713 * Which list? 714 */ 715 spin_lock_bh(&utii->lock); 716 if (sender == ECM_TRACKER_SENDER_TYPE_SRC) { 717 skb = utii->src_recvd_order; 718 } else { 719 skb = utii->dest_recvd_order; 720 } 721 722 /* 723 * Iterate to the i'th datagram 724 */ 725 while (i) { 726 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 727 skb = skb->next; 728 i--; 729 } 730 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 731 732 /* 733 * Perform read of data excluding headers 734 */ 735 skb_cb = (struct ecm_tracker_udp_skb_cb_format *)skb->cb; 736 DEBUG_CHECK_MAGIC(skb_cb, ECM_TRACKER_UDP_SKB_CB_MAGIC, "%p: invalid cb magic %p\n", utii, skb); 737 offset += skb_cb->data_offset; 738 DEBUG_ASSERT(size <= skb_cb->data_size, "%p: size %d too large for skb %p at %u\n", utii, size, skb, skb_cb->data_size); 739 res = skb_copy_bits(skb, offset, buffer, (unsigned int)size); 740 741 spin_unlock_bh(&utii->lock); 742 743 return res; 744} 745 746/* 747 * ecm_tracker_udp_data_size_get_callback() 748 * Read size in bytes of data at index i into the buffer 749 */ 750static int32_t ecm_tracker_udp_data_size_get_callback(struct ecm_tracker_udp_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) 751{ 752 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)uti; 753 int32_t size; 754 struct sk_buff *skb; 755 struct ecm_tracker_udp_skb_cb_format *skb_cb; 756 757 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 758 DEBUG_TRACE("%p: datagram %u data size get for %d\n", utii, i, sender); 759 760 /* 761 * Which list? 762 */ 763 spin_lock_bh(&utii->lock); 764 if (sender == ECM_TRACKER_SENDER_TYPE_SRC) { 765 skb = utii->src_recvd_order; 766 } else { 767 skb = utii->dest_recvd_order; 768 } 769 770 /* 771 * Iterate to the i'th datagram 772 */ 773 while (i) { 774 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 775 skb = skb->next; 776 i--; 777 } 778 DEBUG_ASSERT(skb, "%p: index bad\n", utii); 779 780 /* 781 * Perform read of data excluding headers 782 */ 783 skb_cb = (struct ecm_tracker_udp_skb_cb_format *)skb->cb; 784 DEBUG_CHECK_MAGIC(skb_cb, ECM_TRACKER_UDP_SKB_CB_MAGIC, "%p: invalid cb magic %p\n", utii, skb); 785 size = skb_cb->data_size; 786 spin_unlock_bh(&utii->lock); 787 788 return size; 789} 790#endif 791 792/* 793 * ecm_tracker_udp_state_update_callback() 794 * Update connection state based on the knowledge we have and the skb given 795 */ 796static void ecm_tracker_udp_state_update_callback(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb) 797{ 798 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 799 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 800 801 /* 802 * As long as a sender has seen data then we consider the sender established 803 */ 804 spin_lock_bh(&utii->lock); 805 utii->sender_state[sender] = ECM_TRACKER_SENDER_STATE_ESTABLISHED; 806 spin_unlock_bh(&utii->lock); 807} 808 809/* 810 * ecm_tracker_udp_state_get_callback() 811 * Get state 812 */ 813static void ecm_tracker_udp_state_get_callback(struct ecm_tracker_instance *ti, ecm_tracker_sender_state_t *src_state, 814 ecm_tracker_sender_state_t *dest_state, ecm_tracker_connection_state_t *state, ecm_db_timer_group_t *tg) 815{ 816 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 817 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 818 spin_lock_bh(&utii->lock); 819 *src_state = utii->sender_state[ECM_TRACKER_SENDER_TYPE_SRC]; 820 *dest_state = utii->sender_state[ECM_TRACKER_SENDER_TYPE_DEST]; 821 *tg = utii->timer_group; 822 spin_unlock_bh(&utii->lock); 823 *state = ecm_tracker_udp_connection_state_matrix[*src_state][*dest_state]; 824} 825 826#ifdef ECM_STATE_OUTPUT_ENABLE 827/* 828 * ecm_tracker_udp_state_text_get_callback() 829 * Return state 830 */ 831static int ecm_tracker_udp_state_text_get_callback(struct ecm_tracker_instance *ti, struct ecm_state_file_instance *sfi) 832{ 833 int result; 834 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)ti; 835#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 836 int32_t src_count; 837 int32_t src_bytes_total; 838 int32_t dest_count; 839 int32_t dest_bytes_total; 840 int32_t data_limit; 841#endif 842 ecm_db_timer_group_t timer_group; 843 ecm_tracker_sender_state_t sender_state[ECM_TRACKER_SENDER_MAX]; 844 ecm_tracker_connection_state_t connection_state; 845 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 846 847 if ((result = ecm_state_prefix_add(sfi, "tracker_udp"))) { 848 return result; 849 } 850 851 /* 852 * Capture state 853 */ 854 spin_lock_bh(&utii->lock); 855#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 856 src_count = utii->src_count; 857 src_bytes_total = utii->src_bytes_total; 858 dest_count = utii->dest_count; 859 dest_bytes_total = utii->dest_bytes_total; 860 data_limit = utii->data_limit; 861#endif 862 sender_state[ECM_TRACKER_SENDER_TYPE_SRC] = utii->sender_state[ECM_TRACKER_SENDER_TYPE_SRC]; 863 sender_state[ECM_TRACKER_SENDER_TYPE_DEST] = utii->sender_state[ECM_TRACKER_SENDER_TYPE_DEST]; 864 timer_group = utii->timer_group; 865 spin_unlock_bh(&utii->lock); 866 connection_state = ecm_tracker_udp_connection_state_matrix[sender_state[ECM_TRACKER_SENDER_TYPE_SRC]][sender_state[ECM_TRACKER_SENDER_TYPE_DEST]]; 867 868#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 869 if ((result = ecm_state_write(sfi, "src_count", "%d", src_count))) { 870 return result; 871 } 872 if ((result = ecm_state_write(sfi, "src_bytes_total", "%d", src_bytes_total))) { 873 return result; 874 } 875 if ((result = ecm_state_write(sfi, "dest_count", "%d", dest_count))) { 876 return result; 877 } 878 if ((result = ecm_state_write(sfi, "dest_bytes_total", "%d", dest_bytes_total))) { 879 return result; 880 } 881 if ((result = ecm_state_write(sfi, "data_limit", "%d", data_limit))) { 882 return result; 883 } 884#endif 885 886 connection_state = ecm_tracker_udp_connection_state_matrix[sender_state[ECM_TRACKER_SENDER_TYPE_SRC]][sender_state[ECM_TRACKER_SENDER_TYPE_DEST]]; 887 if ((result = ecm_state_write(sfi, "timer_group", "%d", ECM_DB_TIMER_GROUPS_CONNECTION_GENERIC_TIMEOUT))) { 888 return result; 889 } 890 if ((result = ecm_state_write(sfi, "src_sender_state", "%s", ecm_tracker_sender_state_to_string(sender_state[ECM_TRACKER_SENDER_TYPE_SRC])))) { 891 return result; 892 } 893 if ((result = ecm_state_write(sfi, "dest_sender_state", "%s", ecm_tracker_sender_state_to_string(sender_state[ECM_TRACKER_SENDER_TYPE_DEST])))) { 894 return result; 895 } 896 if ((result = ecm_state_write(sfi, "connection_state", "%s", ecm_tracker_connection_state_to_string(connection_state)))) { 897 return result; 898 } 899 900 return ecm_state_prefix_remove(sfi); 901} 902#endif 903 904/* 905 * ecm_tracker_udp_init() 906 * Initialise the two host addresses that define the two directions we track data for 907 */ 908void ecm_tracker_udp_init(struct ecm_tracker_udp_instance *uti, int32_t data_limit, int src_port, int dest_port) 909{ 910 struct ecm_tracker_udp_internal_instance *utii = (struct ecm_tracker_udp_internal_instance *)uti; 911 DEBUG_CHECK_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC, "%p: magic failed", utii); 912 DEBUG_TRACE("%p: init udp tracker\n", utii); 913 914 spin_lock_bh(&utii->lock); 915#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 916 utii->data_limit = data_limit; 917#endif 918 if ((src_port < 1024) || (dest_port < 1024)) { 919 /* 920 * Because UDP connections can be reaped we assign well known ports to the WKP timer group. 921 * The WKP group is not reaped thus preserving connections involving known services. 922 * NOTE: Classifiers are still free to change the group as they see fit. 923 */ 924 utii->timer_group = ECM_DB_TIMER_GROUPS_CONNECTION_UDP_WKP_TIMEOUT; 925 spin_unlock_bh(&utii->lock); 926 return; 927 } 928 utii->timer_group = ECM_DB_TIMER_GROUPS_CONNECTION_UDP_GENERIC_TIMEOUT; 929 spin_unlock_bh(&utii->lock); 930} 931EXPORT_SYMBOL(ecm_tracker_udp_init); 932 933/* 934 * ecm_tracker_udp_alloc() 935 */ 936struct ecm_tracker_udp_instance *ecm_tracker_udp_alloc(void) 937{ 938 struct ecm_tracker_udp_internal_instance *utii; 939 940 utii = (struct ecm_tracker_udp_internal_instance *)kzalloc(sizeof(struct ecm_tracker_udp_internal_instance), GFP_ATOMIC | __GFP_NOWARN); 941 if (!utii) { 942 DEBUG_WARN("Failed to allocate udp tracker instance\n"); 943 return NULL; 944 } 945 946 utii->udp_base.base.ref = ecm_tracker_udp_ref_callback; 947 utii->udp_base.base.deref = ecm_tracker_udp_deref_callback; 948 utii->udp_base.base.state_update = ecm_tracker_udp_state_update_callback; 949 utii->udp_base.base.state_get = ecm_tracker_udp_state_get_callback; 950#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE 951 utii->udp_base.base.datagram_count_get = ecm_tracker_udp_datagram_count_get_callback; 952 utii->udp_base.base.datagram_discard = ecm_tracker_udp_datagram_discard_callback; 953 utii->udp_base.base.datagram_read = ecm_tracker_udp_datagram_read_callback; 954 utii->udp_base.base.datagram_size_get = ecm_tracker_udp_datagram_size_get_callback; 955 utii->udp_base.base.datagram_add = ecm_tracker_udp_datagram_add_callback; 956 utii->udp_base.base.discard_all = ecm_tracker_udp_discard_all_callback; 957 utii->udp_base.base.data_total_get = ecm_tracker_udp_data_total_get_callback; 958 utii->udp_base.base.data_limit_get = ecm_tracker_udp_data_limit_get_callback; 959 utii->udp_base.base.data_limit_set = ecm_tracker_udp_data_limit_set_callback; 960 961 utii->udp_base.data_read = ecm_tracker_udp_data_read_callback; 962 utii->udp_base.data_size_get = ecm_tracker_udp_data_size_get_callback; 963 utii->udp_base.datagram_add = ecm_tracker_udp_datagram_add_checked_callback; 964#endif 965#ifdef ECM_STATE_OUTPUT_ENABLE 966 utii->udp_base.base.state_text_get = ecm_tracker_udp_state_text_get_callback; 967#endif 968 969 spin_lock_init(&utii->lock); 970 971 utii->refs = 1; 972 DEBUG_SET_MAGIC(utii, ECM_TRACKER_UDP_INSTANCE_MAGIC); 973 974 spin_lock_bh(&ecm_tracker_udp_lock); 975 ecm_tracker_udp_count++; 976 DEBUG_ASSERT(ecm_tracker_udp_count > 0, "%p: udp tracker count wrap\n", utii); 977 spin_unlock_bh(&ecm_tracker_udp_lock); 978 979 DEBUG_TRACE("UDP tracker created %p\n", utii); 980 return (struct ecm_tracker_udp_instance *)utii; 981} 982EXPORT_SYMBOL(ecm_tracker_udp_alloc); 983