1/* Connection tracking via netlink socket. Allows for user space 2 * protocol helpers and general trouble making from userspace. 3 * 4 * (C) 2001 by Jay Schulist <jschlst@samba.org> 5 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org> 6 * (C) 2003 by Patrick Mchardy <kaber@trash.net> 7 * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net> 8 * 9 * Initial connection tracking via netlink development funded and 10 * generally made possible by Network Robots, Inc. (www.networkrobots.com) 11 * 12 * Further development of this code funded by Astaro AG (http://www.astaro.com) 13 * 14 * This software may be used and distributed according to the terms 15 * of the GNU General Public License, incorporated herein by reference. 16 */ 17 18#include <linux/init.h> 19#include <linux/module.h> 20#include <linux/kernel.h> 21#include <linux/types.h> 22#include <linux/timer.h> 23#include <linux/skbuff.h> 24#include <linux/errno.h> 25#include <linux/netlink.h> 26#include <linux/spinlock.h> 27#include <linux/interrupt.h> 28#include <linux/notifier.h> 29 30#include <linux/netfilter.h> 31#include <net/netlink.h> 32#include <net/netfilter/nf_conntrack.h> 33#include <net/netfilter/nf_conntrack_core.h> 34#include <net/netfilter/nf_conntrack_expect.h> 35#include <net/netfilter/nf_conntrack_helper.h> 36#include <net/netfilter/nf_conntrack_l3proto.h> 37#include <net/netfilter/nf_conntrack_l4proto.h> 38#include <net/netfilter/nf_conntrack_tuple.h> 39#ifdef CONFIG_NF_NAT_NEEDED 40#include <net/netfilter/nf_nat_core.h> 41#include <net/netfilter/nf_nat_protocol.h> 42#endif 43 44#include <linux/netfilter/nfnetlink.h> 45#include <linux/netfilter/nfnetlink_conntrack.h> 46 47MODULE_LICENSE("GPL"); 48 49static char __initdata version[] = "0.93"; 50 51static inline int 52ctnetlink_dump_tuples_proto(struct sk_buff *skb, 53 const struct nf_conntrack_tuple *tuple, 54 struct nf_conntrack_l4proto *l4proto) 55{ 56 int ret = 0; 57 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); 58 59 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 60 61 if (likely(l4proto->tuple_to_nfattr)) 62 ret = l4proto->tuple_to_nfattr(skb, tuple); 63 64 NFA_NEST_END(skb, nest_parms); 65 66 return ret; 67 68nfattr_failure: 69 return -1; 70} 71 72static inline int 73ctnetlink_dump_tuples_ip(struct sk_buff *skb, 74 const struct nf_conntrack_tuple *tuple, 75 struct nf_conntrack_l3proto *l3proto) 76{ 77 int ret = 0; 78 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); 79 80 if (likely(l3proto->tuple_to_nfattr)) 81 ret = l3proto->tuple_to_nfattr(skb, tuple); 82 83 NFA_NEST_END(skb, nest_parms); 84 85 return ret; 86 87nfattr_failure: 88 return -1; 89} 90 91static inline int 92ctnetlink_dump_tuples(struct sk_buff *skb, 93 const struct nf_conntrack_tuple *tuple) 94{ 95 int ret; 96 struct nf_conntrack_l3proto *l3proto; 97 struct nf_conntrack_l4proto *l4proto; 98 99 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 100 ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto); 101 nf_ct_l3proto_put(l3proto); 102 103 if (unlikely(ret < 0)) 104 return ret; 105 106 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); 107 ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto); 108 nf_ct_l4proto_put(l4proto); 109 110 return ret; 111} 112 113static inline int 114ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct) 115{ 116 __be32 status = htonl((u_int32_t) ct->status); 117 NFA_PUT(skb, CTA_STATUS, sizeof(status), &status); 118 return 0; 119 120nfattr_failure: 121 return -1; 122} 123 124static inline int 125ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct) 126{ 127 long timeout_l = ct->timeout.expires - jiffies; 128 __be32 timeout; 129 130 if (timeout_l < 0) 131 timeout = 0; 132 else 133 timeout = htonl(timeout_l / HZ); 134 135 NFA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout); 136 return 0; 137 138nfattr_failure: 139 return -1; 140} 141 142static inline int 143ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) 144{ 145 struct nf_conntrack_l4proto *l4proto = nf_ct_l4proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 146 struct nfattr *nest_proto; 147 int ret; 148 149 if (!l4proto->to_nfattr) { 150 nf_ct_l4proto_put(l4proto); 151 return 0; 152 } 153 154 nest_proto = NFA_NEST(skb, CTA_PROTOINFO); 155 156 ret = l4proto->to_nfattr(skb, nest_proto, ct); 157 158 nf_ct_l4proto_put(l4proto); 159 160 NFA_NEST_END(skb, nest_proto); 161 162 return ret; 163 164nfattr_failure: 165 nf_ct_l4proto_put(l4proto); 166 return -1; 167} 168 169static inline int 170ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) 171{ 172 struct nfattr *nest_helper; 173 const struct nf_conn_help *help = nfct_help(ct); 174 struct nf_conntrack_helper *helper; 175 176 if (!help) 177 return 0; 178 179 rcu_read_lock(); 180 helper = rcu_dereference(help->helper); 181 if (!helper) 182 goto out; 183 184 nest_helper = NFA_NEST(skb, CTA_HELP); 185 NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name); 186 187 if (helper->to_nfattr) 188 helper->to_nfattr(skb, ct); 189 190 NFA_NEST_END(skb, nest_helper); 191out: 192 rcu_read_unlock(); 193 return 0; 194 195nfattr_failure: 196 rcu_read_unlock(); 197 return -1; 198} 199 200#ifdef CONFIG_NF_CT_ACCT 201static inline int 202ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, 203 enum ip_conntrack_dir dir) 204{ 205 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; 206 struct nfattr *nest_count = NFA_NEST(skb, type); 207 __be32 tmp; 208 209 tmp = htonl(ct->counters[dir].packets); 210 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); 211 212 tmp = htonl(ct->counters[dir].bytes); 213 NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp); 214 215 NFA_NEST_END(skb, nest_count); 216 217 return 0; 218 219nfattr_failure: 220 return -1; 221} 222#else 223#define ctnetlink_dump_counters(a, b, c) (0) 224#endif 225 226#ifdef CONFIG_NF_CONNTRACK_MARK 227static inline int 228ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) 229{ 230 __be32 mark = htonl(ct->mark); 231 232 NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark); 233 return 0; 234 235nfattr_failure: 236 return -1; 237} 238#else 239#define ctnetlink_dump_mark(a, b) (0) 240#endif 241 242static inline int 243ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct) 244{ 245 __be32 id = htonl(ct->id); 246 NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id); 247 return 0; 248 249nfattr_failure: 250 return -1; 251} 252 253static inline int 254ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct) 255{ 256 __be32 use = htonl(atomic_read(&ct->ct_general.use)); 257 258 NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); 259 return 0; 260 261nfattr_failure: 262 return -1; 263} 264 265#define tuple(ct, dir) (&(ct)->tuplehash[dir].tuple) 266 267static int 268ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, 269 int event, int nowait, 270 const struct nf_conn *ct) 271{ 272 struct nlmsghdr *nlh; 273 struct nfgenmsg *nfmsg; 274 struct nfattr *nest_parms; 275 unsigned char *b = skb_tail_pointer(skb); 276 277 event |= NFNL_SUBSYS_CTNETLINK << 8; 278 nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg)); 279 nfmsg = NLMSG_DATA(nlh); 280 281 nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; 282 nfmsg->nfgen_family = 283 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; 284 nfmsg->version = NFNETLINK_V0; 285 nfmsg->res_id = 0; 286 287 nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG); 288 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0) 289 goto nfattr_failure; 290 NFA_NEST_END(skb, nest_parms); 291 292 nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY); 293 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) 294 goto nfattr_failure; 295 NFA_NEST_END(skb, nest_parms); 296 297 if (ctnetlink_dump_status(skb, ct) < 0 || 298 ctnetlink_dump_timeout(skb, ct) < 0 || 299 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || 300 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0 || 301 ctnetlink_dump_protoinfo(skb, ct) < 0 || 302 ctnetlink_dump_helpinfo(skb, ct) < 0 || 303 ctnetlink_dump_mark(skb, ct) < 0 || 304 ctnetlink_dump_id(skb, ct) < 0 || 305 ctnetlink_dump_use(skb, ct) < 0) 306 goto nfattr_failure; 307 308 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 309 return skb->len; 310 311nlmsg_failure: 312nfattr_failure: 313 nlmsg_trim(skb, b); 314 return -1; 315} 316 317#ifdef CONFIG_NF_CONNTRACK_EVENTS 318static int ctnetlink_conntrack_event(struct notifier_block *this, 319 unsigned long events, void *ptr) 320{ 321 struct nlmsghdr *nlh; 322 struct nfgenmsg *nfmsg; 323 struct nfattr *nest_parms; 324 struct nf_conn *ct = (struct nf_conn *)ptr; 325 struct sk_buff *skb; 326 unsigned int type; 327 sk_buff_data_t b; 328 unsigned int flags = 0, group; 329 330 /* ignore our fake conntrack entry */ 331 if (ct == &nf_conntrack_untracked) 332 return NOTIFY_DONE; 333 334 if (events & IPCT_DESTROY) { 335 type = IPCTNL_MSG_CT_DELETE; 336 group = NFNLGRP_CONNTRACK_DESTROY; 337 } else if (events & (IPCT_NEW | IPCT_RELATED)) { 338 type = IPCTNL_MSG_CT_NEW; 339 flags = NLM_F_CREATE|NLM_F_EXCL; 340 group = NFNLGRP_CONNTRACK_NEW; 341 } else if (events & (IPCT_STATUS | IPCT_PROTOINFO)) { 342 type = IPCTNL_MSG_CT_NEW; 343 group = NFNLGRP_CONNTRACK_UPDATE; 344 } else 345 return NOTIFY_DONE; 346 347 if (!nfnetlink_has_listeners(group)) 348 return NOTIFY_DONE; 349 350 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 351 if (!skb) 352 return NOTIFY_DONE; 353 354 b = skb->tail; 355 356 type |= NFNL_SUBSYS_CTNETLINK << 8; 357 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); 358 nfmsg = NLMSG_DATA(nlh); 359 360 nlh->nlmsg_flags = flags; 361 nfmsg->nfgen_family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; 362 nfmsg->version = NFNETLINK_V0; 363 nfmsg->res_id = 0; 364 365 nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG); 366 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0) 367 goto nfattr_failure; 368 NFA_NEST_END(skb, nest_parms); 369 370 nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY); 371 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) 372 goto nfattr_failure; 373 NFA_NEST_END(skb, nest_parms); 374 375 if (events & IPCT_DESTROY) { 376 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || 377 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0) 378 goto nfattr_failure; 379 } else { 380 if (ctnetlink_dump_status(skb, ct) < 0) 381 goto nfattr_failure; 382 383 if (ctnetlink_dump_timeout(skb, ct) < 0) 384 goto nfattr_failure; 385 386 if (events & IPCT_PROTOINFO 387 && ctnetlink_dump_protoinfo(skb, ct) < 0) 388 goto nfattr_failure; 389 390 if ((events & IPCT_HELPER || nfct_help(ct)) 391 && ctnetlink_dump_helpinfo(skb, ct) < 0) 392 goto nfattr_failure; 393 394#ifdef CONFIG_NF_CONNTRACK_MARK 395 if ((events & IPCT_MARK || ct->mark) 396 && ctnetlink_dump_mark(skb, ct) < 0) 397 goto nfattr_failure; 398#endif 399 400 if (events & IPCT_COUNTER_FILLING && 401 (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || 402 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)) 403 goto nfattr_failure; 404 } 405 406 nlh->nlmsg_len = skb->tail - b; 407 nfnetlink_send(skb, 0, group, 0); 408 return NOTIFY_DONE; 409 410nlmsg_failure: 411nfattr_failure: 412 kfree_skb(skb); 413 return NOTIFY_DONE; 414} 415#endif /* CONFIG_NF_CONNTRACK_EVENTS */ 416 417static int ctnetlink_done(struct netlink_callback *cb) 418{ 419 if (cb->args[1]) 420 nf_ct_put((struct nf_conn *)cb->args[1]); 421 return 0; 422} 423 424#define L3PROTO(ct) ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num 425 426static int 427ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 428{ 429 struct nf_conn *ct, *last; 430 struct nf_conntrack_tuple_hash *h; 431 struct list_head *i; 432 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 433 u_int8_t l3proto = nfmsg->nfgen_family; 434 435 read_lock_bh(&nf_conntrack_lock); 436 last = (struct nf_conn *)cb->args[1]; 437 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { 438restart: 439 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) { 440 h = (struct nf_conntrack_tuple_hash *) i; 441 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) 442 continue; 443 ct = nf_ct_tuplehash_to_ctrack(h); 444 /* Dump entries of a given L3 protocol number. 445 * If it is not specified, ie. l3proto == 0, 446 * then dump everything. */ 447 if (l3proto && L3PROTO(ct) != l3proto) 448 continue; 449 if (cb->args[1]) { 450 if (ct != last) 451 continue; 452 cb->args[1] = 0; 453 } 454 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, 455 cb->nlh->nlmsg_seq, 456 IPCTNL_MSG_CT_NEW, 457 1, ct) < 0) { 458 nf_conntrack_get(&ct->ct_general); 459 cb->args[1] = (unsigned long)ct; 460 goto out; 461 } 462#ifdef CONFIG_NF_CT_ACCT 463 if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == 464 IPCTNL_MSG_CT_GET_CTRZERO) 465 memset(&ct->counters, 0, sizeof(ct->counters)); 466#endif 467 } 468 if (cb->args[1]) { 469 cb->args[1] = 0; 470 goto restart; 471 } 472 } 473out: 474 read_unlock_bh(&nf_conntrack_lock); 475 if (last) 476 nf_ct_put(last); 477 478 return skb->len; 479} 480 481static inline int 482ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple) 483{ 484 struct nfattr *tb[CTA_IP_MAX]; 485 struct nf_conntrack_l3proto *l3proto; 486 int ret = 0; 487 488 nfattr_parse_nested(tb, CTA_IP_MAX, attr); 489 490 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 491 492 if (likely(l3proto->nfattr_to_tuple)) 493 ret = l3proto->nfattr_to_tuple(tb, tuple); 494 495 nf_ct_l3proto_put(l3proto); 496 497 return ret; 498} 499 500static const size_t cta_min_proto[CTA_PROTO_MAX] = { 501 [CTA_PROTO_NUM-1] = sizeof(u_int8_t), 502}; 503 504static inline int 505ctnetlink_parse_tuple_proto(struct nfattr *attr, 506 struct nf_conntrack_tuple *tuple) 507{ 508 struct nfattr *tb[CTA_PROTO_MAX]; 509 struct nf_conntrack_l4proto *l4proto; 510 int ret = 0; 511 512 nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); 513 514 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) 515 return -EINVAL; 516 517 if (!tb[CTA_PROTO_NUM-1]) 518 return -EINVAL; 519 tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]); 520 521 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); 522 523 if (likely(l4proto->nfattr_to_tuple)) 524 ret = l4proto->nfattr_to_tuple(tb, tuple); 525 526 nf_ct_l4proto_put(l4proto); 527 528 return ret; 529} 530 531static inline int 532ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple, 533 enum ctattr_tuple type, u_int8_t l3num) 534{ 535 struct nfattr *tb[CTA_TUPLE_MAX]; 536 int err; 537 538 memset(tuple, 0, sizeof(*tuple)); 539 540 nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); 541 542 if (!tb[CTA_TUPLE_IP-1]) 543 return -EINVAL; 544 545 tuple->src.l3num = l3num; 546 547 err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP-1], tuple); 548 if (err < 0) 549 return err; 550 551 if (!tb[CTA_TUPLE_PROTO-1]) 552 return -EINVAL; 553 554 err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO-1], tuple); 555 if (err < 0) 556 return err; 557 558 /* orig and expect tuples get DIR_ORIGINAL */ 559 if (type == CTA_TUPLE_REPLY) 560 tuple->dst.dir = IP_CT_DIR_REPLY; 561 else 562 tuple->dst.dir = IP_CT_DIR_ORIGINAL; 563 564 return 0; 565} 566 567#ifdef CONFIG_NF_NAT_NEEDED 568static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = { 569 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t), 570 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t), 571}; 572 573static int nfnetlink_parse_nat_proto(struct nfattr *attr, 574 const struct nf_conn *ct, 575 struct nf_nat_range *range) 576{ 577 struct nfattr *tb[CTA_PROTONAT_MAX]; 578 struct nf_nat_protocol *npt; 579 580 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); 581 582 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) 583 return -EINVAL; 584 585 npt = nf_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 586 587 if (!npt->nfattr_to_range) { 588 nf_nat_proto_put(npt); 589 return 0; 590 } 591 592 /* nfattr_to_range returns 1 if it parsed, 0 if not, neg. on error */ 593 if (npt->nfattr_to_range(tb, range) > 0) 594 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; 595 596 nf_nat_proto_put(npt); 597 598 return 0; 599} 600 601static const size_t cta_min_nat[CTA_NAT_MAX] = { 602 [CTA_NAT_MINIP-1] = sizeof(u_int32_t), 603 [CTA_NAT_MAXIP-1] = sizeof(u_int32_t), 604}; 605 606static inline int 607nfnetlink_parse_nat(struct nfattr *nat, 608 const struct nf_conn *ct, struct nf_nat_range *range) 609{ 610 struct nfattr *tb[CTA_NAT_MAX]; 611 int err; 612 613 memset(range, 0, sizeof(*range)); 614 615 nfattr_parse_nested(tb, CTA_NAT_MAX, nat); 616 617 if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat)) 618 return -EINVAL; 619 620 if (tb[CTA_NAT_MINIP-1]) 621 range->min_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MINIP-1]); 622 623 if (!tb[CTA_NAT_MAXIP-1]) 624 range->max_ip = range->min_ip; 625 else 626 range->max_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MAXIP-1]); 627 628 if (range->min_ip) 629 range->flags |= IP_NAT_RANGE_MAP_IPS; 630 631 if (!tb[CTA_NAT_PROTO-1]) 632 return 0; 633 634 err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range); 635 if (err < 0) 636 return err; 637 638 return 0; 639} 640#endif 641 642static inline int 643ctnetlink_parse_help(struct nfattr *attr, char **helper_name) 644{ 645 struct nfattr *tb[CTA_HELP_MAX]; 646 647 nfattr_parse_nested(tb, CTA_HELP_MAX, attr); 648 649 if (!tb[CTA_HELP_NAME-1]) 650 return -EINVAL; 651 652 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]); 653 654 return 0; 655} 656 657static const size_t cta_min[CTA_MAX] = { 658 [CTA_STATUS-1] = sizeof(u_int32_t), 659 [CTA_TIMEOUT-1] = sizeof(u_int32_t), 660 [CTA_MARK-1] = sizeof(u_int32_t), 661 [CTA_USE-1] = sizeof(u_int32_t), 662 [CTA_ID-1] = sizeof(u_int32_t) 663}; 664 665static int 666ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 667 struct nlmsghdr *nlh, struct nfattr *cda[]) 668{ 669 struct nf_conntrack_tuple_hash *h; 670 struct nf_conntrack_tuple tuple; 671 struct nf_conn *ct; 672 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 673 u_int8_t u3 = nfmsg->nfgen_family; 674 int err = 0; 675 676 if (nfattr_bad_size(cda, CTA_MAX, cta_min)) 677 return -EINVAL; 678 679 if (cda[CTA_TUPLE_ORIG-1]) 680 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); 681 else if (cda[CTA_TUPLE_REPLY-1]) 682 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); 683 else { 684 /* Flush the whole table */ 685 nf_conntrack_flush(); 686 return 0; 687 } 688 689 if (err < 0) 690 return err; 691 692 h = nf_conntrack_find_get(&tuple, NULL); 693 if (!h) 694 return -ENOENT; 695 696 ct = nf_ct_tuplehash_to_ctrack(h); 697 698 if (cda[CTA_ID-1]) { 699 u_int32_t id = ntohl(*(__be32 *)NFA_DATA(cda[CTA_ID-1])); 700 if (ct->id != id) { 701 nf_ct_put(ct); 702 return -ENOENT; 703 } 704 } 705 if (del_timer(&ct->timeout)) 706 ct->timeout.function((unsigned long)ct); 707 708 nf_ct_put(ct); 709 710 return 0; 711} 712 713static int 714ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, 715 struct nlmsghdr *nlh, struct nfattr *cda[]) 716{ 717 struct nf_conntrack_tuple_hash *h; 718 struct nf_conntrack_tuple tuple; 719 struct nf_conn *ct; 720 struct sk_buff *skb2 = NULL; 721 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 722 u_int8_t u3 = nfmsg->nfgen_family; 723 int err = 0; 724 725 if (nlh->nlmsg_flags & NLM_F_DUMP) { 726#ifndef CONFIG_NF_CT_ACCT 727 if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) 728 return -ENOTSUPP; 729#endif 730 return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, 731 ctnetlink_done); 732 } 733 734 if (nfattr_bad_size(cda, CTA_MAX, cta_min)) 735 return -EINVAL; 736 737 if (cda[CTA_TUPLE_ORIG-1]) 738 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); 739 else if (cda[CTA_TUPLE_REPLY-1]) 740 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); 741 else 742 return -EINVAL; 743 744 if (err < 0) 745 return err; 746 747 h = nf_conntrack_find_get(&tuple, NULL); 748 if (!h) 749 return -ENOENT; 750 751 ct = nf_ct_tuplehash_to_ctrack(h); 752 753 err = -ENOMEM; 754 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 755 if (!skb2) { 756 nf_ct_put(ct); 757 return -ENOMEM; 758 } 759 760 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 761 IPCTNL_MSG_CT_NEW, 1, ct); 762 nf_ct_put(ct); 763 if (err <= 0) 764 goto free; 765 766 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); 767 if (err < 0) 768 goto out; 769 770 return 0; 771 772free: 773 kfree_skb(skb2); 774out: 775 return err; 776} 777 778static inline int 779ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[]) 780{ 781 unsigned long d; 782 unsigned int status = ntohl(*(__be32 *)NFA_DATA(cda[CTA_STATUS-1])); 783 d = ct->status ^ status; 784 785 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING)) 786 /* unchangeable */ 787 return -EINVAL; 788 789 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY)) 790 /* SEEN_REPLY bit can only be set */ 791 return -EINVAL; 792 793 794 if (d & IPS_ASSURED && !(status & IPS_ASSURED)) 795 /* ASSURED bit can only be set */ 796 return -EINVAL; 797 798 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) { 799#ifndef CONFIG_NF_NAT_NEEDED 800 return -EINVAL; 801#else 802 struct nf_nat_range range; 803 804 if (cda[CTA_NAT_DST-1]) { 805 if (nfnetlink_parse_nat(cda[CTA_NAT_DST-1], ct, 806 &range) < 0) 807 return -EINVAL; 808 if (nf_nat_initialized(ct, 809 HOOK2MANIP(NF_IP_PRE_ROUTING))) 810 return -EEXIST; 811 nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING); 812 } 813 if (cda[CTA_NAT_SRC-1]) { 814 if (nfnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct, 815 &range) < 0) 816 return -EINVAL; 817 if (nf_nat_initialized(ct, 818 HOOK2MANIP(NF_IP_POST_ROUTING))) 819 return -EEXIST; 820 nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING); 821 } 822#endif 823 } 824 825 /* Be careful here, modifying NAT bits can screw up things, 826 * so don't let users modify them directly if they don't pass 827 * nf_nat_range. */ 828 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK); 829 return 0; 830} 831 832 833static inline int 834ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) 835{ 836 struct nf_conntrack_helper *helper; 837 struct nf_conn_help *help = nfct_help(ct); 838 char *helpname; 839 int err; 840 841 /* don't change helper of sibling connections */ 842 if (ct->master) 843 return -EINVAL; 844 845 err = ctnetlink_parse_help(cda[CTA_HELP-1], &helpname); 846 if (err < 0) 847 return err; 848 849 if (!strcmp(helpname, "")) { 850 if (help && help->helper) { 851 /* we had a helper before ... */ 852 nf_ct_remove_expectations(ct); 853 rcu_assign_pointer(help->helper, NULL); 854 } 855 856 return 0; 857 } 858 859 if (!help) { 860 return -EBUSY; 861 } 862 863 helper = __nf_conntrack_helper_find_byname(helpname); 864 if (helper == NULL) 865 return -EINVAL; 866 867 if (help->helper == helper) 868 return 0; 869 870 if (help->helper) 871 return -EBUSY; 872 873 /* need to zero data of old helper */ 874 memset(&help->help, 0, sizeof(help->help)); 875 rcu_assign_pointer(help->helper, helper); 876 877 return 0; 878} 879 880static inline int 881ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[]) 882{ 883 u_int32_t timeout = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1])); 884 885 if (!del_timer(&ct->timeout)) 886 return -ETIME; 887 888 ct->timeout.expires = jiffies + timeout * HZ; 889 add_timer(&ct->timeout); 890 891 return 0; 892} 893 894static inline int 895ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[]) 896{ 897 struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1]; 898 struct nf_conntrack_l4proto *l4proto; 899 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; 900 u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; 901 int err = 0; 902 903 nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr); 904 905 l4proto = nf_ct_l4proto_find_get(l3num, npt); 906 907 if (l4proto->from_nfattr) 908 err = l4proto->from_nfattr(tb, ct); 909 nf_ct_l4proto_put(l4proto); 910 911 return err; 912} 913 914static int 915ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) 916{ 917 int err; 918 919 if (cda[CTA_HELP-1]) { 920 err = ctnetlink_change_helper(ct, cda); 921 if (err < 0) 922 return err; 923 } 924 925 if (cda[CTA_TIMEOUT-1]) { 926 err = ctnetlink_change_timeout(ct, cda); 927 if (err < 0) 928 return err; 929 } 930 931 if (cda[CTA_STATUS-1]) { 932 err = ctnetlink_change_status(ct, cda); 933 if (err < 0) 934 return err; 935 } 936 937 if (cda[CTA_PROTOINFO-1]) { 938 err = ctnetlink_change_protoinfo(ct, cda); 939 if (err < 0) 940 return err; 941 } 942 943#if defined(CONFIG_NF_CONNTRACK_MARK) 944 if (cda[CTA_MARK-1]) 945 ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); 946#endif 947 948 return 0; 949} 950 951static int 952ctnetlink_create_conntrack(struct nfattr *cda[], 953 struct nf_conntrack_tuple *otuple, 954 struct nf_conntrack_tuple *rtuple) 955{ 956 struct nf_conn *ct; 957 int err = -EINVAL; 958 struct nf_conn_help *help; 959 struct nf_conntrack_helper *helper = NULL; 960 961 ct = nf_conntrack_alloc(otuple, rtuple); 962 if (ct == NULL || IS_ERR(ct)) 963 return -ENOMEM; 964 965 if (!cda[CTA_TIMEOUT-1]) 966 goto err; 967 ct->timeout.expires = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1])); 968 969 ct->timeout.expires = jiffies + ct->timeout.expires * HZ; 970 ct->status |= IPS_CONFIRMED; 971 972 if (cda[CTA_STATUS-1]) { 973 err = ctnetlink_change_status(ct, cda); 974 if (err < 0) 975 goto err; 976 } 977 978 if (cda[CTA_PROTOINFO-1]) { 979 err = ctnetlink_change_protoinfo(ct, cda); 980 if (err < 0) 981 goto err; 982 } 983 984#if defined(CONFIG_NF_CONNTRACK_MARK) 985 if (cda[CTA_MARK-1]) 986 ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); 987#endif 988 989 help = nfct_help(ct); 990 if (help) { 991 helper = nf_ct_helper_find_get(rtuple); 992 /* not in hash table yet so not strictly necessary */ 993 rcu_assign_pointer(help->helper, helper); 994 } 995 996 add_timer(&ct->timeout); 997 nf_conntrack_hash_insert(ct); 998 999 if (helper) 1000 nf_ct_helper_put(helper); 1001 1002 return 0; 1003 1004err: 1005 nf_conntrack_free(ct); 1006 return err; 1007} 1008 1009static int 1010ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, 1011 struct nlmsghdr *nlh, struct nfattr *cda[]) 1012{ 1013 struct nf_conntrack_tuple otuple, rtuple; 1014 struct nf_conntrack_tuple_hash *h = NULL; 1015 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 1016 u_int8_t u3 = nfmsg->nfgen_family; 1017 int err = 0; 1018 1019 if (nfattr_bad_size(cda, CTA_MAX, cta_min)) 1020 return -EINVAL; 1021 1022 if (cda[CTA_TUPLE_ORIG-1]) { 1023 err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3); 1024 if (err < 0) 1025 return err; 1026 } 1027 1028 if (cda[CTA_TUPLE_REPLY-1]) { 1029 err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY, u3); 1030 if (err < 0) 1031 return err; 1032 } 1033 1034 write_lock_bh(&nf_conntrack_lock); 1035 if (cda[CTA_TUPLE_ORIG-1]) 1036 h = __nf_conntrack_find(&otuple, NULL); 1037 else if (cda[CTA_TUPLE_REPLY-1]) 1038 h = __nf_conntrack_find(&rtuple, NULL); 1039 1040 if (h == NULL) { 1041 write_unlock_bh(&nf_conntrack_lock); 1042 err = -ENOENT; 1043 if (nlh->nlmsg_flags & NLM_F_CREATE) 1044 err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); 1045 return err; 1046 } 1047 /* implicit 'else' */ 1048 1049 /* we only allow nat config for new conntracks */ 1050 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) { 1051 err = -EINVAL; 1052 goto out_unlock; 1053 } 1054 1055 /* We manipulate the conntrack inside the global conntrack table lock, 1056 * so there's no need to increase the refcount */ 1057 err = -EEXIST; 1058 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) 1059 err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda); 1060 1061out_unlock: 1062 write_unlock_bh(&nf_conntrack_lock); 1063 return err; 1064} 1065 1066/*********************************************************************** 1067 * EXPECT 1068 ***********************************************************************/ 1069 1070static inline int 1071ctnetlink_exp_dump_tuple(struct sk_buff *skb, 1072 const struct nf_conntrack_tuple *tuple, 1073 enum ctattr_expect type) 1074{ 1075 struct nfattr *nest_parms = NFA_NEST(skb, type); 1076 1077 if (ctnetlink_dump_tuples(skb, tuple) < 0) 1078 goto nfattr_failure; 1079 1080 NFA_NEST_END(skb, nest_parms); 1081 1082 return 0; 1083 1084nfattr_failure: 1085 return -1; 1086} 1087 1088static inline int 1089ctnetlink_exp_dump_mask(struct sk_buff *skb, 1090 const struct nf_conntrack_tuple *tuple, 1091 const struct nf_conntrack_tuple *mask) 1092{ 1093 int ret; 1094 struct nf_conntrack_l3proto *l3proto; 1095 struct nf_conntrack_l4proto *l4proto; 1096 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); 1097 1098 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 1099 ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto); 1100 nf_ct_l3proto_put(l3proto); 1101 1102 if (unlikely(ret < 0)) 1103 goto nfattr_failure; 1104 1105 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); 1106 ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto); 1107 nf_ct_l4proto_put(l4proto); 1108 if (unlikely(ret < 0)) 1109 goto nfattr_failure; 1110 1111 NFA_NEST_END(skb, nest_parms); 1112 1113 return 0; 1114 1115nfattr_failure: 1116 return -1; 1117} 1118 1119static inline int 1120ctnetlink_exp_dump_expect(struct sk_buff *skb, 1121 const struct nf_conntrack_expect *exp) 1122{ 1123 struct nf_conn *master = exp->master; 1124 __be32 timeout = htonl((exp->timeout.expires - jiffies) / HZ); 1125 __be32 id = htonl(exp->id); 1126 1127 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) 1128 goto nfattr_failure; 1129 if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0) 1130 goto nfattr_failure; 1131 if (ctnetlink_exp_dump_tuple(skb, 1132 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 1133 CTA_EXPECT_MASTER) < 0) 1134 goto nfattr_failure; 1135 1136 NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout); 1137 NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id); 1138 1139 return 0; 1140 1141nfattr_failure: 1142 return -1; 1143} 1144 1145static int 1146ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq, 1147 int event, 1148 int nowait, 1149 const struct nf_conntrack_expect *exp) 1150{ 1151 struct nlmsghdr *nlh; 1152 struct nfgenmsg *nfmsg; 1153 unsigned char *b = skb_tail_pointer(skb); 1154 1155 event |= NFNL_SUBSYS_CTNETLINK_EXP << 8; 1156 nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg)); 1157 nfmsg = NLMSG_DATA(nlh); 1158 1159 nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; 1160 nfmsg->nfgen_family = exp->tuple.src.l3num; 1161 nfmsg->version = NFNETLINK_V0; 1162 nfmsg->res_id = 0; 1163 1164 if (ctnetlink_exp_dump_expect(skb, exp) < 0) 1165 goto nfattr_failure; 1166 1167 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1168 return skb->len; 1169 1170nlmsg_failure: 1171nfattr_failure: 1172 nlmsg_trim(skb, b); 1173 return -1; 1174} 1175 1176#ifdef CONFIG_NF_CONNTRACK_EVENTS 1177static int ctnetlink_expect_event(struct notifier_block *this, 1178 unsigned long events, void *ptr) 1179{ 1180 struct nlmsghdr *nlh; 1181 struct nfgenmsg *nfmsg; 1182 struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr; 1183 struct sk_buff *skb; 1184 unsigned int type; 1185 sk_buff_data_t b; 1186 int flags = 0; 1187 1188 if (events & IPEXP_NEW) { 1189 type = IPCTNL_MSG_EXP_NEW; 1190 flags = NLM_F_CREATE|NLM_F_EXCL; 1191 } else 1192 return NOTIFY_DONE; 1193 1194 if (!nfnetlink_has_listeners(NFNLGRP_CONNTRACK_EXP_NEW)) 1195 return NOTIFY_DONE; 1196 1197 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 1198 if (!skb) 1199 return NOTIFY_DONE; 1200 1201 b = skb->tail; 1202 1203 type |= NFNL_SUBSYS_CTNETLINK_EXP << 8; 1204 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); 1205 nfmsg = NLMSG_DATA(nlh); 1206 1207 nlh->nlmsg_flags = flags; 1208 nfmsg->nfgen_family = exp->tuple.src.l3num; 1209 nfmsg->version = NFNETLINK_V0; 1210 nfmsg->res_id = 0; 1211 1212 if (ctnetlink_exp_dump_expect(skb, exp) < 0) 1213 goto nfattr_failure; 1214 1215 nlh->nlmsg_len = skb->tail - b; 1216 nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); 1217 return NOTIFY_DONE; 1218 1219nlmsg_failure: 1220nfattr_failure: 1221 kfree_skb(skb); 1222 return NOTIFY_DONE; 1223} 1224#endif 1225 1226static int 1227ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 1228{ 1229 struct nf_conntrack_expect *exp = NULL; 1230 struct list_head *i; 1231 u_int32_t *id = (u_int32_t *) &cb->args[0]; 1232 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 1233 u_int8_t l3proto = nfmsg->nfgen_family; 1234 1235 read_lock_bh(&nf_conntrack_lock); 1236 list_for_each_prev(i, &nf_conntrack_expect_list) { 1237 exp = (struct nf_conntrack_expect *) i; 1238 if (l3proto && exp->tuple.src.l3num != l3proto) 1239 continue; 1240 if (exp->id <= *id) 1241 continue; 1242 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid, 1243 cb->nlh->nlmsg_seq, 1244 IPCTNL_MSG_EXP_NEW, 1245 1, exp) < 0) 1246 goto out; 1247 *id = exp->id; 1248 } 1249out: 1250 read_unlock_bh(&nf_conntrack_lock); 1251 1252 return skb->len; 1253} 1254 1255static const size_t cta_min_exp[CTA_EXPECT_MAX] = { 1256 [CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t), 1257 [CTA_EXPECT_ID-1] = sizeof(u_int32_t) 1258}; 1259 1260static int 1261ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, 1262 struct nlmsghdr *nlh, struct nfattr *cda[]) 1263{ 1264 struct nf_conntrack_tuple tuple; 1265 struct nf_conntrack_expect *exp; 1266 struct sk_buff *skb2; 1267 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 1268 u_int8_t u3 = nfmsg->nfgen_family; 1269 int err = 0; 1270 1271 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) 1272 return -EINVAL; 1273 1274 if (nlh->nlmsg_flags & NLM_F_DUMP) { 1275 return netlink_dump_start(ctnl, skb, nlh, 1276 ctnetlink_exp_dump_table, 1277 ctnetlink_done); 1278 } 1279 1280 if (cda[CTA_EXPECT_MASTER-1]) 1281 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3); 1282 else 1283 return -EINVAL; 1284 1285 if (err < 0) 1286 return err; 1287 1288 exp = nf_conntrack_expect_find_get(&tuple); 1289 if (!exp) 1290 return -ENOENT; 1291 1292 if (cda[CTA_EXPECT_ID-1]) { 1293 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]); 1294 if (exp->id != ntohl(id)) { 1295 nf_conntrack_expect_put(exp); 1296 return -ENOENT; 1297 } 1298 } 1299 1300 err = -ENOMEM; 1301 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1302 if (!skb2) 1303 goto out; 1304 1305 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, 1306 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, 1307 1, exp); 1308 if (err <= 0) 1309 goto free; 1310 1311 nf_conntrack_expect_put(exp); 1312 1313 return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); 1314 1315free: 1316 kfree_skb(skb2); 1317out: 1318 nf_conntrack_expect_put(exp); 1319 return err; 1320} 1321 1322static int 1323ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, 1324 struct nlmsghdr *nlh, struct nfattr *cda[]) 1325{ 1326 struct nf_conntrack_expect *exp, *tmp; 1327 struct nf_conntrack_tuple tuple; 1328 struct nf_conntrack_helper *h; 1329 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 1330 u_int8_t u3 = nfmsg->nfgen_family; 1331 int err; 1332 1333 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) 1334 return -EINVAL; 1335 1336 if (cda[CTA_EXPECT_TUPLE-1]) { 1337 /* delete a single expect by tuple */ 1338 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); 1339 if (err < 0) 1340 return err; 1341 1342 /* bump usage count to 2 */ 1343 exp = nf_conntrack_expect_find_get(&tuple); 1344 if (!exp) 1345 return -ENOENT; 1346 1347 if (cda[CTA_EXPECT_ID-1]) { 1348 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]); 1349 if (exp->id != ntohl(id)) { 1350 nf_conntrack_expect_put(exp); 1351 return -ENOENT; 1352 } 1353 } 1354 1355 /* after list removal, usage count == 1 */ 1356 nf_conntrack_unexpect_related(exp); 1357 /* have to put what we 'get' above. 1358 * after this line usage count == 0 */ 1359 nf_conntrack_expect_put(exp); 1360 } else if (cda[CTA_EXPECT_HELP_NAME-1]) { 1361 char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]); 1362 1363 /* delete all expectations for this helper */ 1364 write_lock_bh(&nf_conntrack_lock); 1365 h = __nf_conntrack_helper_find_byname(name); 1366 if (!h) { 1367 write_unlock_bh(&nf_conntrack_lock); 1368 return -EINVAL; 1369 } 1370 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, 1371 list) { 1372 struct nf_conn_help *m_help = nfct_help(exp->master); 1373 if (m_help->helper == h 1374 && del_timer(&exp->timeout)) { 1375 nf_ct_unlink_expect(exp); 1376 nf_conntrack_expect_put(exp); 1377 } 1378 } 1379 write_unlock_bh(&nf_conntrack_lock); 1380 } else { 1381 /* This basically means we have to flush everything*/ 1382 write_lock_bh(&nf_conntrack_lock); 1383 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, 1384 list) { 1385 if (del_timer(&exp->timeout)) { 1386 nf_ct_unlink_expect(exp); 1387 nf_conntrack_expect_put(exp); 1388 } 1389 } 1390 write_unlock_bh(&nf_conntrack_lock); 1391 } 1392 1393 return 0; 1394} 1395static int 1396ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nfattr *cda[]) 1397{ 1398 return -EOPNOTSUPP; 1399} 1400 1401static int 1402ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3) 1403{ 1404 struct nf_conntrack_tuple tuple, mask, master_tuple; 1405 struct nf_conntrack_tuple_hash *h = NULL; 1406 struct nf_conntrack_expect *exp; 1407 struct nf_conn *ct; 1408 struct nf_conn_help *help; 1409 int err = 0; 1410 1411 /* caller guarantees that those three CTA_EXPECT_* exist */ 1412 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); 1413 if (err < 0) 1414 return err; 1415 err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3); 1416 if (err < 0) 1417 return err; 1418 err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3); 1419 if (err < 0) 1420 return err; 1421 1422 /* Look for master conntrack of this expectation */ 1423 h = nf_conntrack_find_get(&master_tuple, NULL); 1424 if (!h) 1425 return -ENOENT; 1426 ct = nf_ct_tuplehash_to_ctrack(h); 1427 help = nfct_help(ct); 1428 1429 if (!help || !help->helper) { 1430 /* such conntrack hasn't got any helper, abort */ 1431 err = -EINVAL; 1432 goto out; 1433 } 1434 1435 exp = nf_conntrack_expect_alloc(ct); 1436 if (!exp) { 1437 err = -ENOMEM; 1438 goto out; 1439 } 1440 1441 exp->expectfn = NULL; 1442 exp->flags = 0; 1443 exp->master = ct; 1444 exp->helper = NULL; 1445 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); 1446 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple)); 1447 1448 err = nf_conntrack_expect_related(exp); 1449 nf_conntrack_expect_put(exp); 1450 1451out: 1452 nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); 1453 return err; 1454} 1455 1456static int 1457ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, 1458 struct nlmsghdr *nlh, struct nfattr *cda[]) 1459{ 1460 struct nf_conntrack_tuple tuple; 1461 struct nf_conntrack_expect *exp; 1462 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 1463 u_int8_t u3 = nfmsg->nfgen_family; 1464 int err = 0; 1465 1466 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) 1467 return -EINVAL; 1468 1469 if (!cda[CTA_EXPECT_TUPLE-1] 1470 || !cda[CTA_EXPECT_MASK-1] 1471 || !cda[CTA_EXPECT_MASTER-1]) 1472 return -EINVAL; 1473 1474 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); 1475 if (err < 0) 1476 return err; 1477 1478 write_lock_bh(&nf_conntrack_lock); 1479 exp = __nf_conntrack_expect_find(&tuple); 1480 1481 if (!exp) { 1482 write_unlock_bh(&nf_conntrack_lock); 1483 err = -ENOENT; 1484 if (nlh->nlmsg_flags & NLM_F_CREATE) 1485 err = ctnetlink_create_expect(cda, u3); 1486 return err; 1487 } 1488 1489 err = -EEXIST; 1490 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) 1491 err = ctnetlink_change_expect(exp, cda); 1492 write_unlock_bh(&nf_conntrack_lock); 1493 1494 return err; 1495} 1496 1497#ifdef CONFIG_NF_CONNTRACK_EVENTS 1498static struct notifier_block ctnl_notifier = { 1499 .notifier_call = ctnetlink_conntrack_event, 1500}; 1501 1502static struct notifier_block ctnl_notifier_exp = { 1503 .notifier_call = ctnetlink_expect_event, 1504}; 1505#endif 1506 1507static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { 1508 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack, 1509 .attr_count = CTA_MAX, }, 1510 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack, 1511 .attr_count = CTA_MAX, }, 1512 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack, 1513 .attr_count = CTA_MAX, }, 1514 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack, 1515 .attr_count = CTA_MAX, }, 1516}; 1517 1518static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { 1519 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect, 1520 .attr_count = CTA_EXPECT_MAX, }, 1521 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect, 1522 .attr_count = CTA_EXPECT_MAX, }, 1523 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect, 1524 .attr_count = CTA_EXPECT_MAX, }, 1525}; 1526 1527static struct nfnetlink_subsystem ctnl_subsys = { 1528 .name = "conntrack", 1529 .subsys_id = NFNL_SUBSYS_CTNETLINK, 1530 .cb_count = IPCTNL_MSG_MAX, 1531 .cb = ctnl_cb, 1532}; 1533 1534static struct nfnetlink_subsystem ctnl_exp_subsys = { 1535 .name = "conntrack_expect", 1536 .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP, 1537 .cb_count = IPCTNL_MSG_EXP_MAX, 1538 .cb = ctnl_exp_cb, 1539}; 1540 1541MODULE_ALIAS("ip_conntrack_netlink"); 1542MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); 1543MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP); 1544 1545static int __init ctnetlink_init(void) 1546{ 1547 int ret; 1548 1549 printk("ctnetlink v%s: registering with nfnetlink.\n", version); 1550 ret = nfnetlink_subsys_register(&ctnl_subsys); 1551 if (ret < 0) { 1552 printk("ctnetlink_init: cannot register with nfnetlink.\n"); 1553 goto err_out; 1554 } 1555 1556 ret = nfnetlink_subsys_register(&ctnl_exp_subsys); 1557 if (ret < 0) { 1558 printk("ctnetlink_init: cannot register exp with nfnetlink.\n"); 1559 goto err_unreg_subsys; 1560 } 1561 1562#ifdef CONFIG_NF_CONNTRACK_EVENTS 1563 ret = nf_conntrack_register_notifier(&ctnl_notifier); 1564 if (ret < 0) { 1565 printk("ctnetlink_init: cannot register notifier.\n"); 1566 goto err_unreg_exp_subsys; 1567 } 1568 1569 ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp); 1570 if (ret < 0) { 1571 printk("ctnetlink_init: cannot expect register notifier.\n"); 1572 goto err_unreg_notifier; 1573 } 1574#endif 1575 1576 return 0; 1577 1578#ifdef CONFIG_NF_CONNTRACK_EVENTS 1579err_unreg_notifier: 1580 nf_conntrack_unregister_notifier(&ctnl_notifier); 1581err_unreg_exp_subsys: 1582 nfnetlink_subsys_unregister(&ctnl_exp_subsys); 1583#endif 1584err_unreg_subsys: 1585 nfnetlink_subsys_unregister(&ctnl_subsys); 1586err_out: 1587 return ret; 1588} 1589 1590static void __exit ctnetlink_exit(void) 1591{ 1592 printk("ctnetlink: unregistering from nfnetlink.\n"); 1593 1594#ifdef CONFIG_NF_CONNTRACK_EVENTS 1595 nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); 1596 nf_conntrack_unregister_notifier(&ctnl_notifier); 1597#endif 1598 1599 nfnetlink_subsys_unregister(&ctnl_exp_subsys); 1600 nfnetlink_subsys_unregister(&ctnl_subsys); 1601 return; 1602} 1603 1604module_init(ctnetlink_init); 1605module_exit(ctnetlink_exit); 1606