1/* 2 ************************************************************************** 3 * Copyright (c) 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/* 18 * Parental Controls Classifier. 19 * While not implementing parental controls feature itself. 20 * This module provides an interface for customer parental controls systems to interract with the ECM. 21 * This ensures that acceleration will not interfere with parental controls logics, especially DPI. 22 */ 23 24#include <linux/version.h> 25#include <linux/types.h> 26#include <linux/ip.h> 27#include <linux/tcp.h> 28#include <linux/module.h> 29#include <linux/skbuff.h> 30#include <linux/icmp.h> 31#include <linux/debugfs.h> 32#include <linux/kthread.h> 33#include <linux/pkt_sched.h> 34#include <linux/string.h> 35#include <linux/ctype.h> 36#include <net/route.h> 37#include <net/ip.h> 38#include <net/tcp.h> 39#include <asm/unaligned.h> 40#include <asm/uaccess.h> /* for put_user */ 41#include <net/ipv6.h> 42#include <linux/inet.h> 43#include <linux/in.h> 44#include <linux/udp.h> 45#include <linux/tcp.h> 46 47#include <linux/netfilter_ipv4.h> 48#include <linux/netfilter_bridge.h> 49#include <net/netfilter/nf_conntrack.h> 50#include <net/netfilter/nf_conntrack_helper.h> 51#include <net/netfilter/nf_conntrack_l4proto.h> 52#include <net/netfilter/nf_conntrack_l3proto.h> 53#include <net/netfilter/nf_conntrack_core.h> 54#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 55#include <net/netfilter/ipv4/nf_defrag_ipv4.h> 56 57/* 58 * Debug output levels 59 * 0 = OFF 60 * 1 = ASSERTS / ERRORS 61 * 2 = 1 + WARN 62 * 3 = 2 + INFO 63 * 4 = 3 + TRACE 64 */ 65#define DEBUG_LEVEL ECM_CLASSIFIER_PCC_DEBUG_LEVEL 66 67#include "ecm_types.h" 68#include "ecm_db_types.h" 69#include "ecm_state.h" 70#include "ecm_tracker.h" 71#include "ecm_classifier.h" 72#include "ecm_front_end_types.h" 73#include "ecm_tracker_datagram.h" 74#include "ecm_tracker_udp.h" 75#include "ecm_tracker_tcp.h" 76#include "ecm_db.h" 77#include "ecm_classifier_pcc.h" 78#include "ecm_classifier_pcc_public.h" 79 80/* 81 * Magic numbers 82 */ 83#define ECM_CLASSIFIER_PCC_INSTANCE_MAGIC 0x2351 84 85/* 86 * struct ecm_classifier_pcc_instance 87 * State per connection for PCC classifier 88 */ 89struct ecm_classifier_pcc_instance { 90 struct ecm_classifier_instance base; /* Base type */ 91 92 ecm_classifier_pcc_result_t accel_permit_state; /* Permission state for acceleration */ 93 uint32_t ci_serial; /* RO: Serial of the connection */ 94 long process_jiffies_last; /* Rate limiting the calls to the registrant */ 95 uint32_t reg_calls_to; /* #calls to registrant */ 96 uint32_t reg_calls_from; /* #calls from registrant */ 97 98 struct ecm_classifier_process_response process_response; 99 /* Last process response computed */ 100 int refs; /* Integer to trap we never go negative */ 101#if (DEBUG_LEVEL > 0) 102 uint16_t magic; 103#endif 104}; 105 106static DEFINE_SPINLOCK(ecm_classifier_pcc_lock); /* Concurrency control SMP access */ 107static int ecm_classifier_pcc_count = 0; /* Tracks number of instances allocated */ 108static struct ecm_classifier_pcc_registrant *ecm_classifier_registrant = NULL; 109 /* Singleton Parent Controls code */ 110 111/* 112 * Operational control 113 */ 114static bool ecm_classifier_pcc_enabled = false; /* Enable / disable state of the classifier function */ 115 116/* 117 * Debugfs dentry object. 118 */ 119static struct dentry *ecm_classifier_pcc_dentry; 120 121/* 122 * ecm_classifier_pcc_register() 123 * Register a new PCC module. 124 * 125 */ 126int ecm_classifier_pcc_register(struct ecm_classifier_pcc_registrant *r) 127{ 128 /* 129 * Hold the module of the registrant 130 */ 131 if (!try_module_get(r->this_module)) { 132 return -ESHUTDOWN; 133 } 134 135 /* 136 * Hold the registrant we have been given for our purposes. 137 */ 138 r->ref(r); 139 140 spin_lock_bh(&ecm_classifier_pcc_lock); 141 if (ecm_classifier_registrant) { 142 spin_unlock_bh(&ecm_classifier_pcc_lock); 143 DEBUG_WARN("Registrant already\n"); 144 module_put(r->this_module); 145 r->deref(r); 146 return -EALREADY; 147 } 148 ecm_classifier_registrant = r; 149 ecm_classifier_pcc_enabled = true; 150 spin_unlock_bh(&ecm_classifier_pcc_lock); 151 152 /* 153 * Flag a re-generation of all connections is needed 154 */ 155 ecm_db_regeneration_needed(); 156 return 0; 157} 158EXPORT_SYMBOL(ecm_classifier_pcc_register); 159 160/* 161 * ecm_classifier_pcc_unregister_begin() 162 * Begin unregistration process 163 */ 164void ecm_classifier_pcc_unregister_begin(struct ecm_classifier_pcc_registrant *r) 165{ 166 struct ecm_classifier_pcc_registrant *reg; 167 168 spin_lock_bh(&ecm_classifier_pcc_lock); 169 reg = ecm_classifier_registrant; 170 if (!reg) { 171 spin_unlock_bh(&ecm_classifier_pcc_lock); 172 DEBUG_WARN("No Registrant\n"); 173 return; 174 } 175 if (reg != r) { 176 spin_unlock_bh(&ecm_classifier_pcc_lock); 177 DEBUG_WARN("Unexpected registrant, given: %p, expecting: %p\n", r, reg); 178 return; 179 } 180 181 ecm_classifier_registrant = NULL; 182 ecm_classifier_pcc_enabled = false; 183 spin_unlock_bh(&ecm_classifier_pcc_lock); 184 185 /* 186 * Release our ref upon the registrant that we took when it was registered 187 */ 188 reg->deref(reg); 189 module_put(reg->this_module); 190 191 /* 192 * Flag a re-generation of all connections is needed 193 */ 194 ecm_db_regeneration_needed(); 195} 196EXPORT_SYMBOL(ecm_classifier_pcc_unregister_begin); 197 198/* 199 * ecm_classifier_pcc_permit_accel_v4() 200 * Permit acceleration. 201 * 202 * Big endian parameters apart from protocol 203 */ 204void ecm_classifier_pcc_permit_accel_v4(uint8_t *src_mac, __be32 src_ip, int src_port, uint8_t *dest_mac, __be32 dest_ip, int dest_port, int protocol) 205{ 206 ip_addr_t ecm_src_ip; 207 ip_addr_t ecm_dest_ip; 208 struct ecm_db_connection_instance *ci; 209 struct ecm_classifier_instance *classi; 210 struct ecm_classifier_pcc_instance *pcci; 211 212 /* 213 * Look up ECM connection from the given tuple 214 */ 215 src_port = ntohs(src_port); 216 dest_port = ntohs(dest_port); 217 ECM_NIN4_ADDR_TO_IP_ADDR(ecm_src_ip, src_ip); 218 ECM_NIN4_ADDR_TO_IP_ADDR(ecm_dest_ip, dest_ip); 219 220 { 221 char src_ip_str[40]; 222 char dest_ip_str[40]; 223 224 ecm_ip_addr_to_string(src_ip_str, ecm_src_ip); 225 ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip); 226 227 DEBUG_INFO("Permit Accel v4, lookup connection using \n" 228 "Protocol: %d\n" 229 "src: %s:%d\n" 230 "dest: %s:%d\n", 231 protocol, 232 src_ip_str, src_port, 233 dest_ip_str, dest_port); 234 } 235 236 ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port); 237 if (!ci) { 238 DEBUG_TRACE("Not found\n"); 239 return; 240 } 241 242 /* 243 * Get the PCC classifier 244 */ 245 classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC); 246 if (!classi) { 247 DEBUG_TRACE("No PCC classi\n"); 248 ecm_db_connection_deref(ci); 249 return; 250 } 251 pcci = (struct ecm_classifier_pcc_instance *)classi; 252 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 253 254 /* 255 * Set the permitted accel state to PERMITTED 256 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too). 257 */ 258 spin_lock_bh(&ecm_classifier_pcc_lock); 259 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_PERMITTED; 260 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES; 261 pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE; 262 pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL; 263 pcci->reg_calls_from++; 264 spin_unlock_bh(&ecm_classifier_pcc_lock); 265 266 classi->deref(classi); 267 ecm_db_connection_deref(ci); 268} 269EXPORT_SYMBOL(ecm_classifier_pcc_permit_accel_v4); 270 271/* 272 * ecm_classifier_pcc_permit_accel_v6() 273 * Permit acceleration 274 * 275 * Big endian parameters apart from protocol. 276 * 277 * NOTE: If IPv6 is not supported in ECM this function must still exist as a stub to avoid compilation problems for registrants. 278 */ 279void ecm_classifier_pcc_permit_accel_v6(uint8_t *src_mac, struct in6_addr *src_ip, int src_port, uint8_t *dest_mac, struct in6_addr *dest_ip, int dest_port, int protocol) 280{ 281#ifdef ECM_IPV6_ENABLE 282 struct in6_addr in6; 283 ip_addr_t ecm_src_ip; 284 ip_addr_t ecm_dest_ip; 285 struct ecm_db_connection_instance *ci; 286 struct ecm_classifier_instance *classi; 287 struct ecm_classifier_pcc_instance *pcci; 288 289 /* 290 * Look up ECM connection from the given tuple 291 */ 292 src_port = ntohs(src_port); 293 dest_port = ntohs(dest_port); 294 in6 = *src_ip; 295 ECM_NIN6_ADDR_TO_IP_ADDR(ecm_src_ip, in6); 296 in6 = *dest_ip; 297 ECM_NIN6_ADDR_TO_IP_ADDR(ecm_dest_ip, in6); 298 299 { 300 char src_ip_str[40]; 301 char dest_ip_str[40]; 302 303 ecm_ip_addr_to_string(src_ip_str, ecm_src_ip); 304 ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip); 305 306 DEBUG_INFO("Permit Accel v6, lookup connection using \n" 307 "Protocol: %d\n" 308 "src: %s:%d\n" 309 "dest: %s:%d\n", 310 protocol, 311 src_ip_str, src_port, 312 dest_ip_str, dest_port); 313 } 314 315 ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port); 316 if (!ci) { 317 DEBUG_TRACE("Not found\n"); 318 return; 319 } 320 321 /* 322 * Get the PCC classifier 323 */ 324 classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC); 325 if (!classi) { 326 DEBUG_TRACE("No PCC classi\n"); 327 ecm_db_connection_deref(ci); 328 return; 329 } 330 pcci = (struct ecm_classifier_pcc_instance *)classi; 331 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 332 333 /* 334 * Set the permitted accel state to PERMITTED 335 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too). 336 */ 337 spin_lock_bh(&ecm_classifier_pcc_lock); 338 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_PERMITTED; 339 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES; 340 pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE; 341 pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL; 342 pcci->reg_calls_from++; 343 spin_unlock_bh(&ecm_classifier_pcc_lock); 344 345 classi->deref(classi); 346 ecm_db_connection_deref(ci); 347#endif 348} 349EXPORT_SYMBOL(ecm_classifier_pcc_permit_accel_v6); 350 351/* 352 * ecm_classifier_pcc_deny_accel_v4() 353 * Deny acceleration 354 */ 355void ecm_classifier_pcc_deny_accel_v4(uint8_t *src_mac, __be32 src_ip, int src_port, uint8_t *dest_mac, __be32 dest_ip, int dest_port, int protocol) 356{ 357 ip_addr_t ecm_src_ip; 358 ip_addr_t ecm_dest_ip; 359 struct ecm_db_connection_instance *ci; 360 struct ecm_classifier_instance *classi; 361 struct ecm_classifier_pcc_instance *pcci; 362 struct ecm_front_end_connection_instance *feci; 363 364 /* 365 * Look up ECM connection from the given tuple 366 */ 367 src_port = ntohs(src_port); 368 dest_port = ntohs(dest_port); 369 ECM_NIN4_ADDR_TO_IP_ADDR(ecm_src_ip, src_ip); 370 ECM_NIN4_ADDR_TO_IP_ADDR(ecm_dest_ip, dest_ip); 371 372 { 373 char src_ip_str[40]; 374 char dest_ip_str[40]; 375 376 ecm_ip_addr_to_string(src_ip_str, ecm_src_ip); 377 ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip); 378 379 DEBUG_INFO("Deny Accel v4, lookup connection using \n" 380 "Protocol: %d\n" 381 "src: %s:%d\n" 382 "dest: %s:%d\n", 383 protocol, 384 src_ip_str, src_port, 385 dest_ip_str, dest_port); 386 } 387 388 ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port); 389 if (!ci) { 390 DEBUG_TRACE("Not found\n"); 391 return; 392 } 393 394 /* 395 * Get the PCC classifier 396 */ 397 classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC); 398 if (!classi) { 399 DEBUG_TRACE("No PCC classi\n"); 400 ecm_db_connection_deref(ci); 401 return; 402 } 403 pcci = (struct ecm_classifier_pcc_instance *)classi; 404 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 405 406 /* 407 * Set the permitted accel state to DENIED 408 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too). 409 */ 410 spin_lock_bh(&ecm_classifier_pcc_lock); 411 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED; 412 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES; 413 pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE; 414 pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO; 415 pcci->reg_calls_from++; 416 spin_unlock_bh(&ecm_classifier_pcc_lock); 417 418 /* 419 * Get the front end and issue a deceleration 420 * If the connection is not accelerated anyway this will have no effect 421 */ 422 feci = ecm_db_connection_front_end_get_and_ref(ci); 423 feci->decelerate(feci); 424 feci->deref(feci); 425 426 classi->deref(classi); 427 ecm_db_connection_deref(ci); 428} 429EXPORT_SYMBOL(ecm_classifier_pcc_deny_accel_v4); 430 431/* 432 * ecm_classifier_pcc_deny_accel_v6() 433 * Deny acceleration 434 * 435 * NOTE: If IPv6 is not supported in ECM this function must still exist as a stub to avoid compilation problems for registrants. 436 */ 437void ecm_classifier_pcc_deny_accel_v6(uint8_t *src_mac, struct in6_addr *src_ip, int src_port, uint8_t *dest_mac, struct in6_addr *dest_ip, int dest_port, int protocol) 438{ 439#ifdef ECM_IPV6_ENABLE 440 struct in6_addr in6; 441 ip_addr_t ecm_src_ip; 442 ip_addr_t ecm_dest_ip; 443 struct ecm_db_connection_instance *ci; 444 struct ecm_classifier_instance *classi; 445 struct ecm_classifier_pcc_instance *pcci; 446 struct ecm_front_end_connection_instance *feci; 447 448 /* 449 * Look up ECM connection from the given tuple 450 */ 451 src_port = ntohs(src_port); 452 dest_port = ntohs(dest_port); 453 in6 = *src_ip; 454 ECM_NIN6_ADDR_TO_IP_ADDR(ecm_src_ip, in6); 455 in6 = *dest_ip; 456 ECM_NIN6_ADDR_TO_IP_ADDR(ecm_dest_ip, in6); 457 458 { 459 char src_ip_str[40]; 460 char dest_ip_str[40]; 461 462 ecm_ip_addr_to_string(src_ip_str, ecm_src_ip); 463 ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip); 464 465 DEBUG_INFO("Deny Accel v6, lookup connection using \n" 466 "Protocol: %d\n" 467 "src: %s:%d\n" 468 "dest: %s:%d\n", 469 protocol, 470 src_ip_str, src_port, 471 dest_ip_str, dest_port); 472 } 473 474 ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port); 475 if (!ci) { 476 DEBUG_TRACE("Not found\n"); 477 return; 478 } 479 480 /* 481 * Get the PCC classifier 482 */ 483 classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC); 484 if (!classi) { 485 DEBUG_TRACE("No PCC classi\n"); 486 ecm_db_connection_deref(ci); 487 return; 488 } 489 pcci = (struct ecm_classifier_pcc_instance *)classi; 490 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 491 492 /* 493 * Set the permitted accel state to DENIED 494 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too). 495 */ 496 spin_lock_bh(&ecm_classifier_pcc_lock); 497 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED; 498 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES; 499 pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE; 500 pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO; 501 pcci->reg_calls_from++; 502 spin_unlock_bh(&ecm_classifier_pcc_lock); 503 504 /* 505 * Get the front end and issue a deceleration 506 * If the connection is not accelerated anyway this will have no effect 507 */ 508 feci = ecm_db_connection_front_end_get_and_ref(ci); 509 feci->decelerate(feci); 510 feci->deref(feci); 511 512 classi->deref(classi); 513 ecm_db_connection_deref(ci); 514#endif 515} 516EXPORT_SYMBOL(ecm_classifier_pcc_deny_accel_v6); 517 518/* 519 * ecm_classifier_pcc_unregister_force() 520 * Unregister the registrant, if any 521 */ 522static void ecm_classifier_pcc_unregister_force(struct ecm_classifier_pcc_instance *pcci) 523{ 524 struct ecm_classifier_pcc_registrant *reg; 525 526 spin_lock_bh(&ecm_classifier_pcc_lock); 527 reg = ecm_classifier_registrant; 528 if (!reg) { 529 spin_unlock_bh(&ecm_classifier_pcc_lock); 530 return; 531 } 532 ecm_classifier_registrant = NULL; 533 ecm_classifier_pcc_enabled = false; 534 spin_unlock_bh(&ecm_classifier_pcc_lock); 535 536 /* 537 * Release our ref upon the registrant that we took when it was registered 538 */ 539 DEBUG_INFO("Force unregistration of: %p\n", reg); 540 reg->deref(reg); 541 542 /* 543 * Release hold on registrant module 544 */ 545 module_put(reg->this_module); 546 547 /* 548 * Flag a re-generation of all connections is needed 549 */ 550 ecm_db_regeneration_needed(); 551} 552 553/* 554 * _ecm_classifier_pcc_ref() 555 * Ref 556 */ 557static void _ecm_classifier_pcc_ref(struct ecm_classifier_pcc_instance *pcci) 558{ 559 pcci->refs++; 560 DEBUG_TRACE("%p: pcci ref %d\n", pcci, pcci->refs); 561 DEBUG_ASSERT(pcci->refs > 0, "%p: ref wrap\n", pcci); 562} 563 564/* 565 * ecm_classifier_pcc_ref() 566 * Ref 567 */ 568static void ecm_classifier_pcc_ref(struct ecm_classifier_instance *ci) 569{ 570 struct ecm_classifier_pcc_instance *pcci; 571 pcci = (struct ecm_classifier_pcc_instance *)ci; 572 573 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 574 spin_lock_bh(&ecm_classifier_pcc_lock); 575 _ecm_classifier_pcc_ref(pcci); 576 spin_unlock_bh(&ecm_classifier_pcc_lock); 577} 578 579/* 580 * ecm_classifier_pcc_deref() 581 * Deref 582 */ 583static int ecm_classifier_pcc_deref(struct ecm_classifier_instance *ci) 584{ 585 struct ecm_classifier_pcc_instance *pcci; 586 pcci = (struct ecm_classifier_pcc_instance *)ci; 587 588 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 589 spin_lock_bh(&ecm_classifier_pcc_lock); 590 pcci->refs--; 591 DEBUG_ASSERT(pcci->refs >= 0, "%p: refs wrapped\n", pcci); 592 DEBUG_TRACE("%p: Parental Controls classifier deref %d\n", pcci, pcci->refs); 593 if (pcci->refs) { 594 int refs = pcci->refs; 595 spin_unlock_bh(&ecm_classifier_pcc_lock); 596 return refs; 597 } 598 599 /* 600 * Object to be destroyed 601 */ 602 ecm_classifier_pcc_count--; 603 DEBUG_ASSERT(ecm_classifier_pcc_count >= 0, "%p: ecm_classifier_pcc_count wrap\n", pcci); 604 605 spin_unlock_bh(&ecm_classifier_pcc_lock); 606 607 /* 608 * Final 609 */ 610 DEBUG_INFO("%p: Final Parental Controls classifier instance\n", pcci); 611 kfree(pcci); 612 613 return 0; 614} 615 616/* 617 * ecm_classifier_pcc_process() 618 * Process new packet 619 * 620 * NOTE: This function would only ever be called if all other classifiers have failed. 621 */ 622static void ecm_classifier_pcc_process(struct ecm_classifier_instance *aci, ecm_tracker_sender_type_t sender, 623 struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb, 624 struct ecm_classifier_process_response *process_response) 625{ 626 struct ecm_classifier_pcc_instance *pcci = (struct ecm_classifier_pcc_instance *)aci; 627 ecm_classifier_pcc_result_t accel_permit_state; 628 ecm_classifier_pcc_result_t reg_result; 629 struct ecm_db_connection_instance *ci; 630 long jiffies_now; 631 int ip_version; 632 uint8_t src_mac[ETH_ALEN]; 633 uint8_t dest_mac[ETH_ALEN]; 634 int protocol; 635 int src_port; 636 int dst_port; 637 ip_addr_t src_ip; 638 ip_addr_t dst_ip; 639 struct ecm_classifier_pcc_registrant *registrant; 640 641 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: invalid state magic\n", pcci); 642 643 /* 644 * Get connection 645 */ 646 ci = ecm_db_connection_serial_find_and_ref(pcci->ci_serial); 647 if (!ci) { 648 /* 649 * Connection has gone from under us 650 */ 651 spin_lock_bh(&ecm_classifier_pcc_lock); 652 goto not_relevant; 653 } 654 655 /* 656 * Early detection of DNS server port 657 */ 658 dst_port = ecm_db_connection_to_port_get(ci); 659 660 spin_lock_bh(&ecm_classifier_pcc_lock); 661 662 /* 663 * Not relevant to the connection if not enabled. 664 */ 665 if (unlikely(!ecm_classifier_pcc_enabled)) { 666 /* 667 * Not relevant. 668 */ 669 goto not_relevant; 670 } 671 672 /* 673 * What is our acceleration permit state? 674 * If it is something other than ECM_CLASSIFIER_PCC_RESULT_NOT_YET then we have a definitive result already. 675 */ 676 accel_permit_state = pcci->accel_permit_state; 677 if (accel_permit_state != ECM_CLASSIFIER_PCC_RESULT_NOT_YET) { 678 *process_response = pcci->process_response; 679 spin_unlock_bh(&ecm_classifier_pcc_lock); 680 ecm_db_connection_deref(ci); 681 return; 682 } 683 684 /* 685 * If the destination port is to DNS server then we implicitly deny acceleration 686 */ 687 if (dst_port == 53) { 688 /* 689 * By setting the permit state to DENIED we will always deny from this point on 690 */ 691 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED; 692 goto deny_accel; 693 } 694 695 /* 696 * We need to call to the registrant BUT we cannot do this at a rate that exceeds 1/sec 697 * NOTE: Not worried about wrap around, it's only one second. 698 */ 699 jiffies_now = jiffies; 700 if ((jiffies_now - pcci->process_jiffies_last) < HZ) { 701 /* 702 * We cannot permit acceleration just yet 703 * Deny accel but don't change the permit state - we try again later 704 */ 705 goto deny_accel; 706 } 707 pcci->process_jiffies_last = jiffies_now; 708 709 /* 710 * We have to call out to our registrant to see if we can get permission to accelerate. 711 * Get our registrant 712 */ 713 registrant = ecm_classifier_registrant; 714 registrant->ref(registrant); 715 716 /* 717 * Bump reg calls made to the registrant. 718 */ 719 pcci->reg_calls_to++; 720 721 spin_unlock_bh(&ecm_classifier_pcc_lock); 722 723 /* 724 * See if we can hold the registrant module - it may be unloading. 725 */ 726 if (!try_module_get(registrant->this_module)) { 727 /* 728 * Module is unloading. 729 */ 730 registrant->deref(registrant); 731 732 /* 733 * Force unregistration 734 */ 735 ecm_classifier_pcc_unregister_force(pcci); 736 737 /* 738 * We are implicitly "not relevant". 739 */ 740 spin_lock_bh(&ecm_classifier_pcc_lock); 741 goto not_relevant; 742 } 743 744 /* 745 * Ask the registrant if we may accelerate (big endian) 746 */ 747 ip_version = ecm_db_connection_ip_version_get(ci); 748 protocol = ecm_db_connection_protocol_get(ci); 749 ecm_db_connection_from_address_get(ci, src_ip); 750 src_port = htons(ecm_db_connection_from_port_get(ci)); 751 dst_port = htons(dst_port); 752 ecm_db_connection_to_address_get(ci, dst_ip); 753 ecm_db_connection_from_node_address_get(ci, src_mac); 754 ecm_db_connection_to_node_address_get(ci, dest_mac); 755 756 /* 757 * Default is permitted in case ip_version is unsupported here 758 */ 759 reg_result = ECM_CLASSIFIER_PCC_RESULT_PERMITTED; 760 if (ip_version == 4) { 761 __be32 src_ip4; 762 __be32 dest_ip4; 763 764 ECM_IP_ADDR_TO_NIN4_ADDR(src_ip4, src_ip); 765 ECM_IP_ADDR_TO_NIN4_ADDR(dest_ip4, dst_ip); 766 reg_result = registrant->okay_to_accel_v4(registrant, src_mac, src_ip4, src_port, dest_mac, dest_ip4, dst_port, protocol); 767 } 768#ifdef ECM_IPV6_ENABLE 769 if (ip_version == 6) { 770 struct in6_addr src_ip6; 771 struct in6_addr dest_ip6; 772 ECM_IP_ADDR_TO_NIN6_ADDR(src_ip6, src_ip); 773 ECM_IP_ADDR_TO_NIN6_ADDR(dest_ip6, dst_ip); 774 reg_result = registrant->okay_to_accel_v6(registrant, src_mac, &src_ip6, src_port, dest_mac, &dest_ip6, dst_port, protocol); 775 } 776#endif 777 778 /* 779 * Release the ref taken for this call 780 */ 781 registrant->deref(registrant); 782 783 /* 784 * Release the module ref taken. 785 */ 786 module_put(registrant->this_module); 787 788 /* 789 * Handle the result 790 */ 791 switch (reg_result) { 792 case ECM_CLASSIFIER_PCC_RESULT_NOT_YET: 793 /* 794 * Deny accel but don't change the permit state - we try again later 795 */ 796 spin_lock_bh(&ecm_classifier_pcc_lock); 797 goto deny_accel; 798 case ECM_CLASSIFIER_PCC_RESULT_DENIED: 799 /* 800 * Deny accel and set the permit state to denied - this connection is denied from this point on. 801 */ 802 spin_lock_bh(&ecm_classifier_pcc_lock); 803 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED; 804 goto deny_accel; 805 case ECM_CLASSIFIER_PCC_RESULT_PERMITTED: 806 break; 807 default: 808 DEBUG_ASSERT(false, "Unhandled result: %d\n", reg_result); 809 } 810 811 /* 812 * Acceleration is permitted 813 */ 814 spin_lock_bh(&ecm_classifier_pcc_lock); 815 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_PERMITTED; 816 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES; 817 pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE; 818 pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL; 819 *process_response = pcci->process_response; 820 spin_unlock_bh(&ecm_classifier_pcc_lock); 821 ecm_db_connection_deref(ci); 822 823 return; 824 825not_relevant: 826 827 /* 828 * ecm_classifier_pcc_lock MUST be held 829 */ 830 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_NO; 831 pcci->process_response.process_actions = 0; 832 *process_response = pcci->process_response; 833 spin_unlock_bh(&ecm_classifier_pcc_lock); 834 ecm_db_connection_deref(ci); 835 return; 836 837deny_accel: 838 839 /* 840 * ecm_classifier_pcc_lock MUST be held 841 */ 842 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES; 843 pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE; 844 pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO; 845 *process_response = pcci->process_response; 846 spin_unlock_bh(&ecm_classifier_pcc_lock); 847 ecm_db_connection_deref(ci); 848 return; 849 850} 851 852/* 853 * ecm_classifier_pcc_type_get() 854 * Get type of classifier this is 855 */ 856static ecm_classifier_type_t ecm_classifier_pcc_type_get(struct ecm_classifier_instance *aci) 857{ 858 struct ecm_classifier_pcc_instance *pcci; 859 pcci = (struct ecm_classifier_pcc_instance *)aci; 860 861 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 862 return ECM_CLASSIFIER_TYPE_PCC; 863} 864 865/* 866 * ecm_classifier_pcc_reclassify_allowed() 867 * Get whether reclassification is allowed 868 */ 869static bool ecm_classifier_pcc_reclassify_allowed(struct ecm_classifier_instance *aci) 870{ 871 struct ecm_classifier_pcc_instance *pcci; 872 pcci = (struct ecm_classifier_pcc_instance *)aci; 873 874 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 875 return true; 876} 877 878/* 879 * ecm_classifier_pcc_reclassify() 880 * Reclassify 881 */ 882static void ecm_classifier_pcc_reclassify(struct ecm_classifier_instance *aci) 883{ 884 struct ecm_classifier_pcc_instance *pcci; 885 pcci = (struct ecm_classifier_pcc_instance *)aci; 886 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 887 888 /* 889 * Connection needs to be reset to 'as new' 890 * NOTE: Implicitly the connection would have been decelerated now so we don't need to worry about that. 891 */ 892 spin_lock_bh(&ecm_classifier_pcc_lock); 893 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_NOT_YET; 894 895 /* 896 * Reset jiffies for rate limiting registrant calls 897 */ 898 pcci->process_jiffies_last = jiffies; 899 900 spin_unlock_bh(&ecm_classifier_pcc_lock); 901} 902 903/* 904 * ecm_classifier_pcc_last_process_response_get() 905 * Get result code returned by the last process call 906 */ 907static void ecm_classifier_pcc_last_process_response_get(struct ecm_classifier_instance *aci, 908 struct ecm_classifier_process_response *process_response) 909{ 910 struct ecm_classifier_pcc_instance *pcci; 911 pcci = (struct ecm_classifier_pcc_instance *)aci; 912 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 913 914 spin_lock_bh(&ecm_classifier_pcc_lock); 915 *process_response = pcci->process_response; 916 spin_unlock_bh(&ecm_classifier_pcc_lock); 917} 918 919/* 920 * ecm_classifier_pcc_sync_to_v4() 921 * Front end is pushing accel engine state to us 922 */ 923static void ecm_classifier_pcc_sync_to_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync) 924{ 925 struct ecm_classifier_pcc_instance *pcci __attribute__((unused)); 926 927 pcci = (struct ecm_classifier_pcc_instance *)aci; 928 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 929} 930 931/* 932 * ecm_classifier_pcc_sync_from_v4() 933 * Front end is retrieving accel engine state from us 934 */ 935static void ecm_classifier_pcc_sync_from_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc) 936{ 937 struct ecm_classifier_pcc_instance *pcci __attribute__((unused)); 938 939 pcci = (struct ecm_classifier_pcc_instance *)aci; 940 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 941} 942 943/* 944 * ecm_classifier_pcc_sync_to_v6() 945 * Front end is pushing accel engine state to us 946 */ 947static void ecm_classifier_pcc_sync_to_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync) 948{ 949 struct ecm_classifier_pcc_instance *pcci __attribute__((unused)); 950 951 pcci = (struct ecm_classifier_pcc_instance *)aci; 952 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 953} 954 955/* 956 * ecm_classifier_pcc_sync_from_v6() 957 * Front end is retrieving accel engine state from us 958 */ 959static void ecm_classifier_pcc_sync_from_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc) 960{ 961 struct ecm_classifier_pcc_instance *pcci __attribute__((unused)); 962 963 pcci = (struct ecm_classifier_pcc_instance *)aci; 964 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 965} 966 967#ifdef ECM_STATE_OUTPUT_ENABLE 968/* 969 * ecm_classifier_pcc_state_get() 970 * Return state 971 */ 972static int ecm_classifier_pcc_state_get(struct ecm_classifier_instance *ci, struct ecm_state_file_instance *sfi) 973{ 974 int result; 975 struct ecm_classifier_pcc_instance *pcci; 976 struct ecm_classifier_process_response process_response; 977 ecm_classifier_pcc_result_t accel_permit_state; 978 uint32_t reg_calls_to; 979 uint32_t reg_calls_from; 980 981 pcci = (struct ecm_classifier_pcc_instance *)ci; 982 DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci); 983 984 if ((result = ecm_state_prefix_add(sfi, "pcc"))) { 985 return result; 986 } 987 988 spin_lock_bh(&ecm_classifier_pcc_lock); 989 accel_permit_state = pcci->accel_permit_state; 990 process_response = pcci->process_response; 991 reg_calls_to = pcci->reg_calls_to; 992 reg_calls_from = pcci->reg_calls_from; 993 spin_unlock_bh(&ecm_classifier_pcc_lock); 994 995 996 if ((result = ecm_state_write(sfi, "accel_permit_state", "%d", accel_permit_state))) { 997 return result; 998 } 999 if ((result = ecm_state_write(sfi, "reg_calls_to", "%d", reg_calls_to))) { 1000 return result; 1001 } 1002 if ((result = ecm_state_write(sfi, "reg_calls_from", "%d", reg_calls_from))) { 1003 return result; 1004 } 1005 1006 /* 1007 * Output our last process response 1008 */ 1009 if ((result = ecm_classifier_process_response_state_get(sfi, &process_response))) { 1010 return result; 1011 } 1012 1013 if ((result = ecm_state_prefix_remove(sfi))) { 1014 return result; 1015 } 1016 1017 return ecm_state_prefix_remove(sfi); 1018} 1019#endif 1020 1021/* 1022 * ecm_classifier_pcc_instance_alloc() 1023 * Allocate an instance of the Parental Controls classifier 1024 */ 1025struct ecm_classifier_pcc_instance *ecm_classifier_pcc_instance_alloc(struct ecm_db_connection_instance *ci) 1026{ 1027 struct ecm_classifier_pcc_instance *pcci; 1028 struct ecm_classifier_instance *cdi; 1029 1030 /* 1031 * Allocate the instance 1032 */ 1033 pcci = (struct ecm_classifier_pcc_instance *)kzalloc(sizeof(struct ecm_classifier_pcc_instance), GFP_ATOMIC | __GFP_NOWARN); 1034 if (!pcci) { 1035 DEBUG_WARN("Failed to allocate Parental Controls Classifier instance\n"); 1036 return NULL; 1037 } 1038 1039 DEBUG_SET_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC); 1040 pcci->refs = 1; 1041 pcci->ci_serial = ecm_db_connection_serial_get(ci); 1042 1043 /* 1044 * We are relevant to the connection at this time 1045 */ 1046 pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES; 1047 1048 /* 1049 * Don't know yet whether we are allowed to accelerate - need to query the registrant 1050 */ 1051 pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_NOT_YET; 1052 1053 /* 1054 * Reset jiffies for rate limiting registrant calls 1055 */ 1056 pcci->process_jiffies_last = jiffies; 1057 1058 /* 1059 * Methods generic to all classifiers. 1060 */ 1061 cdi = (struct ecm_classifier_instance *)pcci; 1062 cdi->process = ecm_classifier_pcc_process; 1063 cdi->sync_from_v4 = ecm_classifier_pcc_sync_from_v4; 1064 cdi->sync_to_v4 = ecm_classifier_pcc_sync_to_v4; 1065 cdi->sync_from_v6 = ecm_classifier_pcc_sync_from_v6; 1066 cdi->sync_to_v6 = ecm_classifier_pcc_sync_to_v6; 1067 cdi->type_get = ecm_classifier_pcc_type_get; 1068 cdi->reclassify_allowed = ecm_classifier_pcc_reclassify_allowed; 1069 cdi->reclassify = ecm_classifier_pcc_reclassify; 1070 cdi->last_process_response_get = ecm_classifier_pcc_last_process_response_get; 1071#ifdef ECM_STATE_OUTPUT_ENABLE 1072 cdi->state_get = ecm_classifier_pcc_state_get; 1073#endif 1074 cdi->ref = ecm_classifier_pcc_ref; 1075 cdi->deref = ecm_classifier_pcc_deref; 1076 1077 /* 1078 * Increment stats 1079 */ 1080 spin_lock_bh(&ecm_classifier_pcc_lock); 1081 ecm_classifier_pcc_count++; 1082 DEBUG_ASSERT(ecm_classifier_pcc_count > 0, "%p: ecm_classifier_pcc_count wrap\n", pcci); 1083 spin_unlock_bh(&ecm_classifier_pcc_lock); 1084 1085 DEBUG_INFO("Parental Controls classifier instance alloc: %p\n", pcci); 1086 return pcci; 1087} 1088EXPORT_SYMBOL(ecm_classifier_pcc_instance_alloc); 1089 1090/* 1091 * ecm_classifier_pcc_init() 1092 */ 1093int ecm_classifier_pcc_init(struct dentry *dentry) 1094{ 1095 DEBUG_INFO("Parental Controls classifier Module init\n"); 1096 1097 ecm_classifier_pcc_dentry = debugfs_create_dir("ecm_classifier_pcc", dentry); 1098 if (!ecm_classifier_pcc_dentry) { 1099 DEBUG_ERROR("Failed to create ecm pcc directory in debugfs\n"); 1100 return -1; 1101 } 1102 1103 if (!debugfs_create_u32("enabled", S_IRUGO, ecm_classifier_pcc_dentry, 1104 (u32 *)&ecm_classifier_pcc_enabled)) { 1105 DEBUG_ERROR("Failed to create pcc enabled file in debugfs\n"); 1106 debugfs_remove_recursive(ecm_classifier_pcc_dentry); 1107 return -1; 1108 } 1109 1110 return 0; 1111} 1112EXPORT_SYMBOL(ecm_classifier_pcc_init); 1113 1114/* 1115 * ecm_classifier_pcc_exit() 1116 */ 1117void ecm_classifier_pcc_exit(void) 1118{ 1119 DEBUG_INFO("Parental Controls classifier Module exit\n"); 1120 1121 /* 1122 * Remove the debugfs files recursively. 1123 */ 1124 if (ecm_classifier_pcc_dentry) { 1125 debugfs_remove_recursive(ecm_classifier_pcc_dentry); 1126 } 1127 1128} 1129EXPORT_SYMBOL(ecm_classifier_pcc_exit); 1130