1 /* L3/L4 protocol support for nf_conntrack. */ 2 3 /* (C) 1999-2001 Paul `Rusty' Russell 4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> 5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org> 6 * (C) 2006-2012 Patrick McHardy <kaber@trash.net> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/types.h> 14 #include <linux/netfilter.h> 15 #include <linux/module.h> 16 #include <linux/slab.h> 17 #include <linux/mutex.h> 18 #include <linux/vmalloc.h> 19 #include <linux/stddef.h> 20 #include <linux/err.h> 21 #include <linux/percpu.h> 22 #include <linux/notifier.h> 23 #include <linux/kernel.h> 24 #include <linux/netdevice.h> 25 26 #include <net/netfilter/nf_conntrack.h> 27 #include <net/netfilter/nf_conntrack_l3proto.h> 28 #include <net/netfilter/nf_conntrack_l4proto.h> 29 #include <net/netfilter/nf_conntrack_core.h> 30 31 static struct nf_conntrack_l4proto __rcu **nf_ct_protos[PF_MAX] __read_mostly; 32 struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX] __read_mostly; 33 EXPORT_SYMBOL_GPL(nf_ct_l3protos); 34 35 static DEFINE_MUTEX(nf_ct_proto_mutex); 36 37 #ifdef CONFIG_SYSCTL 38 static int 39 nf_ct_register_sysctl(struct net *net, 40 struct ctl_table_header **header, 41 const char *path, 42 struct ctl_table *table) 43 { 44 if (*header == NULL) { 45 *header = register_net_sysctl(net, path, table); 46 if (*header == NULL) 47 return -ENOMEM; 48 } 49 50 return 0; 51 } 52 53 static void 54 nf_ct_unregister_sysctl(struct ctl_table_header **header, 55 struct ctl_table **table, 56 unsigned int users) 57 { 58 if (users > 0) 59 return; 60 61 unregister_net_sysctl_table(*header); 62 kfree(*table); 63 *header = NULL; 64 *table = NULL; 65 } 66 #endif 67 68 struct nf_conntrack_l4proto * 69 __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto) 70 { 71 if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL)) 72 return &nf_conntrack_l4proto_generic; 73 74 return rcu_dereference(nf_ct_protos[l3proto][l4proto]); 75 } 76 EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find); 77 78 /* this is guaranteed to always return a valid protocol helper, since 79 * it falls back to generic_protocol */ 80 struct nf_conntrack_l3proto * 81 nf_ct_l3proto_find_get(u_int16_t l3proto) 82 { 83 struct nf_conntrack_l3proto *p; 84 85 rcu_read_lock(); 86 p = __nf_ct_l3proto_find(l3proto); 87 if (!try_module_get(p->me)) 88 p = &nf_conntrack_l3proto_generic; 89 rcu_read_unlock(); 90 91 return p; 92 } 93 EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get); 94 95 int 96 nf_ct_l3proto_try_module_get(unsigned short l3proto) 97 { 98 int ret; 99 struct nf_conntrack_l3proto *p; 100 101 retry: p = nf_ct_l3proto_find_get(l3proto); 102 if (p == &nf_conntrack_l3proto_generic) { 103 ret = request_module("nf_conntrack-%d", l3proto); 104 if (!ret) 105 goto retry; 106 107 return -EPROTOTYPE; 108 } 109 110 return 0; 111 } 112 EXPORT_SYMBOL_GPL(nf_ct_l3proto_try_module_get); 113 114 void nf_ct_l3proto_module_put(unsigned short l3proto) 115 { 116 struct nf_conntrack_l3proto *p; 117 118 /* rcu_read_lock not necessary since the caller holds a reference, but 119 * taken anyways to avoid lockdep warnings in __nf_ct_l3proto_find() 120 */ 121 rcu_read_lock(); 122 p = __nf_ct_l3proto_find(l3proto); 123 module_put(p->me); 124 rcu_read_unlock(); 125 } 126 EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put); 127 128 int nf_ct_netns_get(struct net *net, u8 nfproto) 129 { 130 const struct nf_conntrack_l3proto *l3proto; 131 int ret; 132 133 might_sleep(); 134 135 ret = nf_ct_l3proto_try_module_get(nfproto); 136 if (ret < 0) 137 return ret; 138 139 /* we already have a reference, can't fail */ 140 rcu_read_lock(); 141 l3proto = __nf_ct_l3proto_find(nfproto); 142 rcu_read_unlock(); 143 144 if (!l3proto->net_ns_get) 145 return 0; 146 147 ret = l3proto->net_ns_get(net); 148 if (ret < 0) 149 nf_ct_l3proto_module_put(nfproto); 150 151 return ret; 152 } 153 EXPORT_SYMBOL_GPL(nf_ct_netns_get); 154 155 void nf_ct_netns_put(struct net *net, u8 nfproto) 156 { 157 const struct nf_conntrack_l3proto *l3proto; 158 159 might_sleep(); 160 161 /* same as nf_conntrack_netns_get(), reference assumed */ 162 rcu_read_lock(); 163 l3proto = __nf_ct_l3proto_find(nfproto); 164 rcu_read_unlock(); 165 166 if (WARN_ON(!l3proto)) 167 return; 168 169 if (l3proto->net_ns_put) 170 l3proto->net_ns_put(net); 171 172 nf_ct_l3proto_module_put(nfproto); 173 } 174 EXPORT_SYMBOL_GPL(nf_ct_netns_put); 175 176 struct nf_conntrack_l4proto * 177 nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num) 178 { 179 struct nf_conntrack_l4proto *p; 180 181 rcu_read_lock(); 182 p = __nf_ct_l4proto_find(l3num, l4num); 183 if (!try_module_get(p->me)) 184 p = &nf_conntrack_l4proto_generic; 185 rcu_read_unlock(); 186 187 return p; 188 } 189 EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get); 190 191 void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p) 192 { 193 module_put(p->me); 194 } 195 EXPORT_SYMBOL_GPL(nf_ct_l4proto_put); 196 197 static int kill_l3proto(struct nf_conn *i, void *data) 198 { 199 return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto; 200 } 201 202 static int kill_l4proto(struct nf_conn *i, void *data) 203 { 204 struct nf_conntrack_l4proto *l4proto; 205 l4proto = (struct nf_conntrack_l4proto *)data; 206 return nf_ct_protonum(i) == l4proto->l4proto && 207 nf_ct_l3num(i) == l4proto->l3proto; 208 } 209 210 int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto) 211 { 212 int ret = 0; 213 struct nf_conntrack_l3proto *old; 214 215 if (proto->l3proto >= AF_MAX) 216 return -EBUSY; 217 218 if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size) 219 return -EINVAL; 220 221 mutex_lock(&nf_ct_proto_mutex); 222 old = rcu_dereference_protected(nf_ct_l3protos[proto->l3proto], 223 lockdep_is_held(&nf_ct_proto_mutex)); 224 if (old != &nf_conntrack_l3proto_generic) { 225 ret = -EBUSY; 226 goto out_unlock; 227 } 228 229 if (proto->nlattr_tuple_size) 230 proto->nla_size = 3 * proto->nlattr_tuple_size(); 231 232 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto); 233 234 out_unlock: 235 mutex_unlock(&nf_ct_proto_mutex); 236 return ret; 237 238 } 239 EXPORT_SYMBOL_GPL(nf_ct_l3proto_register); 240 241 #ifdef CONFIG_SYSCTL 242 extern unsigned int nf_conntrack_default_on; 243 244 int nf_ct_l3proto_pernet_register(struct net *net, 245 struct nf_conntrack_l3proto *proto) 246 { 247 if (nf_conntrack_default_on == 0) 248 return 0; 249 250 return proto->net_ns_get ? proto->net_ns_get(net) : 0; 251 } 252 EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_register); 253 #endif 254 255 void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto) 256 { 257 BUG_ON(proto->l3proto >= AF_MAX); 258 259 mutex_lock(&nf_ct_proto_mutex); 260 BUG_ON(rcu_dereference_protected(nf_ct_l3protos[proto->l3proto], 261 lockdep_is_held(&nf_ct_proto_mutex) 262 ) != proto); 263 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], 264 &nf_conntrack_l3proto_generic); 265 mutex_unlock(&nf_ct_proto_mutex); 266 267 synchronize_rcu(); 268 } 269 EXPORT_SYMBOL_GPL(nf_ct_l3proto_unregister); 270 271 void nf_ct_l3proto_pernet_unregister(struct net *net, 272 struct nf_conntrack_l3proto *proto) 273 { 274 /* 275 * nf_conntrack_default_on *might* have registered hooks. 276 * ->net_ns_put must cope with more puts() than get(), i.e. 277 * if nf_conntrack_default_on was 0 at time of 278 * nf_ct_l3proto_pernet_register invocation this net_ns_put() 279 * should be a noop. 280 */ 281 if (proto->net_ns_put) 282 proto->net_ns_put(net); 283 284 /* Remove all contrack entries for this protocol */ 285 nf_ct_iterate_cleanup(net, kill_l3proto, proto, 0, 0); 286 } 287 EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister); 288 289 static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, 290 struct nf_conntrack_l4proto *l4proto) 291 { 292 if (l4proto->get_net_proto) { 293 /* statically built-in protocols use static per-net */ 294 return l4proto->get_net_proto(net); 295 } else if (l4proto->net_id) { 296 /* ... and loadable protocols use dynamic per-net */ 297 return net_generic(net, *l4proto->net_id); 298 } 299 return NULL; 300 } 301 302 static 303 int nf_ct_l4proto_register_sysctl(struct net *net, 304 struct nf_proto_net *pn, 305 struct nf_conntrack_l4proto *l4proto) 306 { 307 int err = 0; 308 309 #ifdef CONFIG_SYSCTL 310 if (pn->ctl_table != NULL) { 311 err = nf_ct_register_sysctl(net, 312 &pn->ctl_table_header, 313 "net/netfilter", 314 pn->ctl_table); 315 if (err < 0) { 316 if (!pn->users) { 317 kfree(pn->ctl_table); 318 pn->ctl_table = NULL; 319 } 320 } 321 } 322 #endif /* CONFIG_SYSCTL */ 323 return err; 324 } 325 326 static 327 void nf_ct_l4proto_unregister_sysctl(struct net *net, 328 struct nf_proto_net *pn, 329 struct nf_conntrack_l4proto *l4proto) 330 { 331 #ifdef CONFIG_SYSCTL 332 if (pn->ctl_table_header != NULL) 333 nf_ct_unregister_sysctl(&pn->ctl_table_header, 334 &pn->ctl_table, 335 pn->users); 336 #endif /* CONFIG_SYSCTL */ 337 } 338 339 /* FIXME: Allow NULL functions and sub in pointers to generic for 340 them. --RR */ 341 int nf_ct_l4proto_register_one(struct nf_conntrack_l4proto *l4proto) 342 { 343 int ret = 0; 344 345 if (l4proto->l3proto >= PF_MAX) 346 return -EBUSY; 347 348 if ((l4proto->to_nlattr && !l4proto->nlattr_size) || 349 (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size)) 350 return -EINVAL; 351 352 mutex_lock(&nf_ct_proto_mutex); 353 if (!nf_ct_protos[l4proto->l3proto]) { 354 /* l3proto may be loaded latter. */ 355 struct nf_conntrack_l4proto __rcu **proto_array; 356 int i; 357 358 proto_array = kmalloc(MAX_NF_CT_PROTO * 359 sizeof(struct nf_conntrack_l4proto *), 360 GFP_KERNEL); 361 if (proto_array == NULL) { 362 ret = -ENOMEM; 363 goto out_unlock; 364 } 365 366 for (i = 0; i < MAX_NF_CT_PROTO; i++) 367 RCU_INIT_POINTER(proto_array[i], 368 &nf_conntrack_l4proto_generic); 369 370 /* Before making proto_array visible to lockless readers, 371 * we must make sure its content is committed to memory. 372 */ 373 smp_wmb(); 374 375 nf_ct_protos[l4proto->l3proto] = proto_array; 376 } else if (rcu_dereference_protected( 377 nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 378 lockdep_is_held(&nf_ct_proto_mutex) 379 ) != &nf_conntrack_l4proto_generic) { 380 ret = -EBUSY; 381 goto out_unlock; 382 } 383 384 l4proto->nla_size = 0; 385 if (l4proto->nlattr_size) 386 l4proto->nla_size += l4proto->nlattr_size(); 387 if (l4proto->nlattr_tuple_size) 388 l4proto->nla_size += 3 * l4proto->nlattr_tuple_size(); 389 390 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 391 l4proto); 392 out_unlock: 393 mutex_unlock(&nf_ct_proto_mutex); 394 return ret; 395 } 396 EXPORT_SYMBOL_GPL(nf_ct_l4proto_register_one); 397 398 int nf_ct_l4proto_pernet_register_one(struct net *net, 399 struct nf_conntrack_l4proto *l4proto) 400 { 401 int ret = 0; 402 struct nf_proto_net *pn = NULL; 403 404 if (l4proto->init_net) { 405 ret = l4proto->init_net(net, l4proto->l3proto); 406 if (ret < 0) 407 goto out; 408 } 409 410 pn = nf_ct_l4proto_net(net, l4proto); 411 if (pn == NULL) 412 goto out; 413 414 ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto); 415 if (ret < 0) 416 goto out; 417 418 pn->users++; 419 out: 420 return ret; 421 } 422 EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register_one); 423 424 void nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *l4proto) 425 { 426 BUG_ON(l4proto->l3proto >= PF_MAX); 427 428 mutex_lock(&nf_ct_proto_mutex); 429 BUG_ON(rcu_dereference_protected( 430 nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 431 lockdep_is_held(&nf_ct_proto_mutex) 432 ) != l4proto); 433 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 434 &nf_conntrack_l4proto_generic); 435 mutex_unlock(&nf_ct_proto_mutex); 436 437 synchronize_rcu(); 438 } 439 EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister_one); 440 441 void nf_ct_l4proto_pernet_unregister_one(struct net *net, 442 struct nf_conntrack_l4proto *l4proto) 443 { 444 struct nf_proto_net *pn = NULL; 445 446 pn = nf_ct_l4proto_net(net, l4proto); 447 if (pn == NULL) 448 return; 449 450 pn->users--; 451 nf_ct_l4proto_unregister_sysctl(net, pn, l4proto); 452 453 /* Remove all contrack entries for this protocol */ 454 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto, 0, 0); 455 } 456 EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister_one); 457 458 int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto[], 459 unsigned int num_proto) 460 { 461 int ret = -EINVAL, ver; 462 unsigned int i; 463 464 for (i = 0; i < num_proto; i++) { 465 ret = nf_ct_l4proto_register_one(l4proto[i]); 466 if (ret < 0) 467 break; 468 } 469 if (i != num_proto) { 470 ver = l4proto[i]->l3proto == PF_INET6 ? 6 : 4; 471 pr_err("nf_conntrack_ipv%d: can't register %s%d proto.\n", 472 ver, l4proto[i]->name, ver); 473 nf_ct_l4proto_unregister(l4proto, i); 474 } 475 return ret; 476 } 477 EXPORT_SYMBOL_GPL(nf_ct_l4proto_register); 478 479 int nf_ct_l4proto_pernet_register(struct net *net, 480 struct nf_conntrack_l4proto *l4proto[], 481 unsigned int num_proto) 482 { 483 int ret = -EINVAL; 484 unsigned int i; 485 486 for (i = 0; i < num_proto; i++) { 487 ret = nf_ct_l4proto_pernet_register_one(net, l4proto[i]); 488 if (ret < 0) 489 break; 490 } 491 if (i != num_proto) { 492 pr_err("nf_conntrack_%s%d: pernet registration failed\n", 493 l4proto[i]->name, 494 l4proto[i]->l3proto == PF_INET6 ? 6 : 4); 495 nf_ct_l4proto_pernet_unregister(net, l4proto, i); 496 } 497 return ret; 498 } 499 EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register); 500 501 void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto[], 502 unsigned int num_proto) 503 { 504 while (num_proto-- != 0) 505 nf_ct_l4proto_unregister_one(l4proto[num_proto]); 506 } 507 EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister); 508 509 void nf_ct_l4proto_pernet_unregister(struct net *net, 510 struct nf_conntrack_l4proto *l4proto[], 511 unsigned int num_proto) 512 { 513 while (num_proto-- != 0) 514 nf_ct_l4proto_pernet_unregister_one(net, l4proto[num_proto]); 515 } 516 EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister); 517 518 int nf_conntrack_proto_pernet_init(struct net *net) 519 { 520 int err; 521 struct nf_proto_net *pn = nf_ct_l4proto_net(net, 522 &nf_conntrack_l4proto_generic); 523 524 err = nf_conntrack_l4proto_generic.init_net(net, 525 nf_conntrack_l4proto_generic.l3proto); 526 if (err < 0) 527 return err; 528 err = nf_ct_l4proto_register_sysctl(net, 529 pn, 530 &nf_conntrack_l4proto_generic); 531 if (err < 0) 532 return err; 533 534 pn->users++; 535 return 0; 536 } 537 538 void nf_conntrack_proto_pernet_fini(struct net *net) 539 { 540 struct nf_proto_net *pn = nf_ct_l4proto_net(net, 541 &nf_conntrack_l4proto_generic); 542 543 pn->users--; 544 nf_ct_l4proto_unregister_sysctl(net, 545 pn, 546 &nf_conntrack_l4proto_generic); 547 } 548 549 int nf_conntrack_proto_init(void) 550 { 551 unsigned int i; 552 for (i = 0; i < AF_MAX; i++) 553 rcu_assign_pointer(nf_ct_l3protos[i], 554 &nf_conntrack_l3proto_generic); 555 return 0; 556 } 557 558 void nf_conntrack_proto_fini(void) 559 { 560 unsigned int i; 561 /* free l3proto protocol tables */ 562 for (i = 0; i < PF_MAX; i++) 563 kfree(nf_ct_protos[i]); 564 } 565