1/* 2 * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This software has been sponsored by Sophos Astaro <http://www.sophos.com> 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/module.h> 14#include <linux/netlink.h> 15#include <linux/netfilter.h> 16#include <linux/netfilter/nfnetlink.h> 17#include <linux/netfilter/nf_tables.h> 18#include <linux/netfilter/nf_tables_compat.h> 19#include <linux/netfilter/x_tables.h> 20#include <linux/netfilter_ipv4/ip_tables.h> 21#include <linux/netfilter_ipv6/ip6_tables.h> 22#include <linux/netfilter_bridge/ebtables.h> 23#include <linux/netfilter_arp/arp_tables.h> 24#include <net/netfilter/nf_tables.h> 25 26static int nft_compat_chain_validate_dependency(const char *tablename, 27 const struct nft_chain *chain) 28{ 29 const struct nft_base_chain *basechain; 30 31 if (!tablename || !(chain->flags & NFT_BASE_CHAIN)) 32 return 0; 33 34 basechain = nft_base_chain(chain); 35 if (strcmp(tablename, "nat") == 0 && 36 basechain->type->type != NFT_CHAIN_T_NAT) 37 return -EINVAL; 38 39 return 0; 40} 41 42union nft_entry { 43 struct ipt_entry e4; 44 struct ip6t_entry e6; 45 struct ebt_entry ebt; 46 struct arpt_entry arp; 47}; 48 49static inline void 50nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info) 51{ 52 par->target = xt; 53 par->targinfo = xt_info; 54 par->hotdrop = false; 55} 56 57static void nft_target_eval_xt(const struct nft_expr *expr, 58 struct nft_regs *regs, 59 const struct nft_pktinfo *pkt) 60{ 61 void *info = nft_expr_priv(expr); 62 struct xt_target *target = expr->ops->data; 63 struct sk_buff *skb = pkt->skb; 64 int ret; 65 66 nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info); 67 68 ret = target->target(skb, &pkt->xt); 69 70 if (pkt->xt.hotdrop) 71 ret = NF_DROP; 72 73 switch (ret) { 74 case XT_CONTINUE: 75 regs->verdict.code = NFT_CONTINUE; 76 break; 77 default: 78 regs->verdict.code = ret; 79 break; 80 } 81} 82 83static void nft_target_eval_bridge(const struct nft_expr *expr, 84 struct nft_regs *regs, 85 const struct nft_pktinfo *pkt) 86{ 87 void *info = nft_expr_priv(expr); 88 struct xt_target *target = expr->ops->data; 89 struct sk_buff *skb = pkt->skb; 90 int ret; 91 92 nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info); 93 94 ret = target->target(skb, &pkt->xt); 95 96 if (pkt->xt.hotdrop) 97 ret = NF_DROP; 98 99 switch (ret) { 100 case EBT_ACCEPT: 101 regs->verdict.code = NF_ACCEPT; 102 break; 103 case EBT_DROP: 104 regs->verdict.code = NF_DROP; 105 break; 106 case EBT_CONTINUE: 107 regs->verdict.code = NFT_CONTINUE; 108 break; 109 case EBT_RETURN: 110 regs->verdict.code = NFT_RETURN; 111 break; 112 default: 113 regs->verdict.code = ret; 114 break; 115 } 116} 117 118static const struct nla_policy nft_target_policy[NFTA_TARGET_MAX + 1] = { 119 [NFTA_TARGET_NAME] = { .type = NLA_NUL_STRING }, 120 [NFTA_TARGET_REV] = { .type = NLA_U32 }, 121 [NFTA_TARGET_INFO] = { .type = NLA_BINARY }, 122}; 123 124static void 125nft_target_set_tgchk_param(struct xt_tgchk_param *par, 126 const struct nft_ctx *ctx, 127 struct xt_target *target, void *info, 128 union nft_entry *entry, u16 proto, bool inv) 129{ 130 par->net = ctx->net; 131 par->table = ctx->table->name; 132 switch (ctx->afi->family) { 133 case AF_INET: 134 entry->e4.ip.proto = proto; 135 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; 136 break; 137 case AF_INET6: 138 if (proto) 139 entry->e6.ipv6.flags |= IP6T_F_PROTO; 140 141 entry->e6.ipv6.proto = proto; 142 entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; 143 break; 144 case NFPROTO_BRIDGE: 145 entry->ebt.ethproto = (__force __be16)proto; 146 entry->ebt.invflags = inv ? EBT_IPROTO : 0; 147 break; 148 case NFPROTO_ARP: 149 break; 150 } 151 par->entryinfo = entry; 152 par->target = target; 153 par->targinfo = info; 154 if (ctx->chain->flags & NFT_BASE_CHAIN) { 155 const struct nft_base_chain *basechain = 156 nft_base_chain(ctx->chain); 157 const struct nf_hook_ops *ops = &basechain->ops[0]; 158 159 par->hook_mask = 1 << ops->hooknum; 160 } else { 161 par->hook_mask = 0; 162 } 163 par->family = ctx->afi->family; 164} 165 166static void target_compat_from_user(struct xt_target *t, void *in, void *out) 167{ 168 int pad; 169 170 memcpy(out, in, t->targetsize); 171 pad = XT_ALIGN(t->targetsize) - t->targetsize; 172 if (pad > 0) 173 memset(out + t->targetsize, 0, pad); 174} 175 176static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] = { 177 [NFTA_RULE_COMPAT_PROTO] = { .type = NLA_U32 }, 178 [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, 179}; 180 181static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) 182{ 183 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; 184 u32 flags; 185 int err; 186 187 err = nla_parse_nested(tb, NFTA_RULE_COMPAT_MAX, attr, 188 nft_rule_compat_policy); 189 if (err < 0) 190 return err; 191 192 if (!tb[NFTA_RULE_COMPAT_PROTO] || !tb[NFTA_RULE_COMPAT_FLAGS]) 193 return -EINVAL; 194 195 flags = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_FLAGS])); 196 if (flags & ~NFT_RULE_COMPAT_F_MASK) 197 return -EINVAL; 198 if (flags & NFT_RULE_COMPAT_F_INV) 199 *inv = true; 200 201 *proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO])); 202 return 0; 203} 204 205static int 206nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, 207 const struct nlattr * const tb[]) 208{ 209 void *info = nft_expr_priv(expr); 210 struct xt_target *target = expr->ops->data; 211 struct xt_tgchk_param par; 212 size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); 213 u16 proto = 0; 214 bool inv = false; 215 union nft_entry e = {}; 216 int ret; 217 218 ret = nft_compat_chain_validate_dependency(target->table, ctx->chain); 219 if (ret < 0) 220 goto err; 221 222 target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info); 223 224 if (ctx->nla[NFTA_RULE_COMPAT]) { 225 ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); 226 if (ret < 0) 227 goto err; 228 } 229 230 nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); 231 232 ret = xt_check_target(&par, size, proto, inv); 233 if (ret < 0) 234 goto err; 235 236 /* The standard target cannot be used */ 237 if (target->target == NULL) { 238 ret = -EINVAL; 239 goto err; 240 } 241 242 return 0; 243err: 244 module_put(target->me); 245 return ret; 246} 247 248static void 249nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) 250{ 251 struct xt_target *target = expr->ops->data; 252 void *info = nft_expr_priv(expr); 253 struct xt_tgdtor_param par; 254 255 par.net = ctx->net; 256 par.target = target; 257 par.targinfo = info; 258 par.family = ctx->afi->family; 259 if (par.target->destroy != NULL) 260 par.target->destroy(&par); 261 262 module_put(target->me); 263} 264 265static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr) 266{ 267 const struct xt_target *target = expr->ops->data; 268 void *info = nft_expr_priv(expr); 269 270 if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) || 271 nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) || 272 nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(target->targetsize), info)) 273 goto nla_put_failure; 274 275 return 0; 276 277nla_put_failure: 278 return -1; 279} 280 281static int nft_target_validate(const struct nft_ctx *ctx, 282 const struct nft_expr *expr, 283 const struct nft_data **data) 284{ 285 struct xt_target *target = expr->ops->data; 286 unsigned int hook_mask = 0; 287 int ret; 288 289 if (ctx->chain->flags & NFT_BASE_CHAIN) { 290 const struct nft_base_chain *basechain = 291 nft_base_chain(ctx->chain); 292 const struct nf_hook_ops *ops = &basechain->ops[0]; 293 294 hook_mask = 1 << ops->hooknum; 295 if (!(hook_mask & target->hooks)) 296 return -EINVAL; 297 298 ret = nft_compat_chain_validate_dependency(target->table, 299 ctx->chain); 300 if (ret < 0) 301 return ret; 302 } 303 return 0; 304} 305 306static void nft_match_eval(const struct nft_expr *expr, 307 struct nft_regs *regs, 308 const struct nft_pktinfo *pkt) 309{ 310 void *info = nft_expr_priv(expr); 311 struct xt_match *match = expr->ops->data; 312 struct sk_buff *skb = pkt->skb; 313 bool ret; 314 315 nft_compat_set_par((struct xt_action_param *)&pkt->xt, match, info); 316 317 ret = match->match(skb, (struct xt_action_param *)&pkt->xt); 318 319 if (pkt->xt.hotdrop) { 320 regs->verdict.code = NF_DROP; 321 return; 322 } 323 324 switch (ret ? 1 : 0) { 325 case 1: 326 regs->verdict.code = NFT_CONTINUE; 327 break; 328 case 0: 329 regs->verdict.code = NFT_BREAK; 330 break; 331 } 332} 333 334static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = { 335 [NFTA_MATCH_NAME] = { .type = NLA_NUL_STRING }, 336 [NFTA_MATCH_REV] = { .type = NLA_U32 }, 337 [NFTA_MATCH_INFO] = { .type = NLA_BINARY }, 338}; 339 340/* struct xt_mtchk_param and xt_tgchk_param look very similar */ 341static void 342nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, 343 struct xt_match *match, void *info, 344 union nft_entry *entry, u16 proto, bool inv) 345{ 346 par->net = ctx->net; 347 par->table = ctx->table->name; 348 switch (ctx->afi->family) { 349 case AF_INET: 350 entry->e4.ip.proto = proto; 351 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; 352 break; 353 case AF_INET6: 354 if (proto) 355 entry->e6.ipv6.flags |= IP6T_F_PROTO; 356 357 entry->e6.ipv6.proto = proto; 358 entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; 359 break; 360 case NFPROTO_BRIDGE: 361 entry->ebt.ethproto = (__force __be16)proto; 362 entry->ebt.invflags = inv ? EBT_IPROTO : 0; 363 break; 364 case NFPROTO_ARP: 365 break; 366 } 367 par->entryinfo = entry; 368 par->match = match; 369 par->matchinfo = info; 370 if (ctx->chain->flags & NFT_BASE_CHAIN) { 371 const struct nft_base_chain *basechain = 372 nft_base_chain(ctx->chain); 373 const struct nf_hook_ops *ops = &basechain->ops[0]; 374 375 par->hook_mask = 1 << ops->hooknum; 376 } else { 377 par->hook_mask = 0; 378 } 379 par->family = ctx->afi->family; 380} 381 382static void match_compat_from_user(struct xt_match *m, void *in, void *out) 383{ 384 int pad; 385 386 memcpy(out, in, m->matchsize); 387 pad = XT_ALIGN(m->matchsize) - m->matchsize; 388 if (pad > 0) 389 memset(out + m->matchsize, 0, pad); 390} 391 392static int 393nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, 394 const struct nlattr * const tb[]) 395{ 396 void *info = nft_expr_priv(expr); 397 struct xt_match *match = expr->ops->data; 398 struct xt_mtchk_param par; 399 size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO])); 400 u16 proto = 0; 401 bool inv = false; 402 union nft_entry e = {}; 403 int ret; 404 405 ret = nft_compat_chain_validate_dependency(match->table, ctx->chain); 406 if (ret < 0) 407 goto err; 408 409 match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info); 410 411 if (ctx->nla[NFTA_RULE_COMPAT]) { 412 ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv); 413 if (ret < 0) 414 goto err; 415 } 416 417 nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); 418 419 ret = xt_check_match(&par, size, proto, inv); 420 if (ret < 0) 421 goto err; 422 423 return 0; 424err: 425 module_put(match->me); 426 return ret; 427} 428 429static void 430nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) 431{ 432 struct xt_match *match = expr->ops->data; 433 void *info = nft_expr_priv(expr); 434 struct xt_mtdtor_param par; 435 436 par.net = ctx->net; 437 par.match = match; 438 par.matchinfo = info; 439 par.family = ctx->afi->family; 440 if (par.match->destroy != NULL) 441 par.match->destroy(&par); 442 443 module_put(match->me); 444} 445 446static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr) 447{ 448 void *info = nft_expr_priv(expr); 449 struct xt_match *match = expr->ops->data; 450 451 if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) || 452 nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) || 453 nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(match->matchsize), info)) 454 goto nla_put_failure; 455 456 return 0; 457 458nla_put_failure: 459 return -1; 460} 461 462static int nft_match_validate(const struct nft_ctx *ctx, 463 const struct nft_expr *expr, 464 const struct nft_data **data) 465{ 466 struct xt_match *match = expr->ops->data; 467 unsigned int hook_mask = 0; 468 int ret; 469 470 if (ctx->chain->flags & NFT_BASE_CHAIN) { 471 const struct nft_base_chain *basechain = 472 nft_base_chain(ctx->chain); 473 const struct nf_hook_ops *ops = &basechain->ops[0]; 474 475 hook_mask = 1 << ops->hooknum; 476 if (!(hook_mask & match->hooks)) 477 return -EINVAL; 478 479 ret = nft_compat_chain_validate_dependency(match->table, 480 ctx->chain); 481 if (ret < 0) 482 return ret; 483 } 484 return 0; 485} 486 487static int 488nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, 489 int event, u16 family, const char *name, 490 int rev, int target) 491{ 492 struct nlmsghdr *nlh; 493 struct nfgenmsg *nfmsg; 494 unsigned int flags = portid ? NLM_F_MULTI : 0; 495 496 event |= NFNL_SUBSYS_NFT_COMPAT << 8; 497 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); 498 if (nlh == NULL) 499 goto nlmsg_failure; 500 501 nfmsg = nlmsg_data(nlh); 502 nfmsg->nfgen_family = family; 503 nfmsg->version = NFNETLINK_V0; 504 nfmsg->res_id = 0; 505 506 if (nla_put_string(skb, NFTA_COMPAT_NAME, name) || 507 nla_put_be32(skb, NFTA_COMPAT_REV, htonl(rev)) || 508 nla_put_be32(skb, NFTA_COMPAT_TYPE, htonl(target))) 509 goto nla_put_failure; 510 511 nlmsg_end(skb, nlh); 512 return skb->len; 513 514nlmsg_failure: 515nla_put_failure: 516 nlmsg_cancel(skb, nlh); 517 return -1; 518} 519 520static int 521nfnl_compat_get(struct sock *nfnl, struct sk_buff *skb, 522 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 523{ 524 int ret = 0, target; 525 struct nfgenmsg *nfmsg; 526 const char *fmt; 527 const char *name; 528 u32 rev; 529 struct sk_buff *skb2; 530 531 if (tb[NFTA_COMPAT_NAME] == NULL || 532 tb[NFTA_COMPAT_REV] == NULL || 533 tb[NFTA_COMPAT_TYPE] == NULL) 534 return -EINVAL; 535 536 name = nla_data(tb[NFTA_COMPAT_NAME]); 537 rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV])); 538 target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE])); 539 540 nfmsg = nlmsg_data(nlh); 541 542 switch(nfmsg->nfgen_family) { 543 case AF_INET: 544 fmt = "ipt_%s"; 545 break; 546 case AF_INET6: 547 fmt = "ip6t_%s"; 548 break; 549 case NFPROTO_BRIDGE: 550 fmt = "ebt_%s"; 551 break; 552 case NFPROTO_ARP: 553 fmt = "arpt_%s"; 554 break; 555 default: 556 pr_err("nft_compat: unsupported protocol %d\n", 557 nfmsg->nfgen_family); 558 return -EINVAL; 559 } 560 561 try_then_request_module(xt_find_revision(nfmsg->nfgen_family, name, 562 rev, target, &ret), 563 fmt, name); 564 565 if (ret < 0) 566 return ret; 567 568 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 569 if (skb2 == NULL) 570 return -ENOMEM; 571 572 /* include the best revision for this extension in the message */ 573 if (nfnl_compat_fill_info(skb2, NETLINK_CB(skb).portid, 574 nlh->nlmsg_seq, 575 NFNL_MSG_TYPE(nlh->nlmsg_type), 576 NFNL_MSG_COMPAT_GET, 577 nfmsg->nfgen_family, 578 name, ret, target) <= 0) { 579 kfree_skb(skb2); 580 return -ENOSPC; 581 } 582 583 ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid, 584 MSG_DONTWAIT); 585 if (ret > 0) 586 ret = 0; 587 588 return ret == -EAGAIN ? -ENOBUFS : ret; 589} 590 591static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = { 592 [NFTA_COMPAT_NAME] = { .type = NLA_NUL_STRING, 593 .len = NFT_COMPAT_NAME_MAX-1 }, 594 [NFTA_COMPAT_REV] = { .type = NLA_U32 }, 595 [NFTA_COMPAT_TYPE] = { .type = NLA_U32 }, 596}; 597 598static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = { 599 [NFNL_MSG_COMPAT_GET] = { .call = nfnl_compat_get, 600 .attr_count = NFTA_COMPAT_MAX, 601 .policy = nfnl_compat_policy_get }, 602}; 603 604static const struct nfnetlink_subsystem nfnl_compat_subsys = { 605 .name = "nft-compat", 606 .subsys_id = NFNL_SUBSYS_NFT_COMPAT, 607 .cb_count = NFNL_MSG_COMPAT_MAX, 608 .cb = nfnl_nft_compat_cb, 609}; 610 611static LIST_HEAD(nft_match_list); 612 613struct nft_xt { 614 struct list_head head; 615 struct nft_expr_ops ops; 616}; 617 618static struct nft_expr_type nft_match_type; 619 620static bool nft_match_cmp(const struct xt_match *match, 621 const char *name, u32 rev, u32 family) 622{ 623 return strcmp(match->name, name) == 0 && match->revision == rev && 624 (match->family == NFPROTO_UNSPEC || match->family == family); 625} 626 627static const struct nft_expr_ops * 628nft_match_select_ops(const struct nft_ctx *ctx, 629 const struct nlattr * const tb[]) 630{ 631 struct nft_xt *nft_match; 632 struct xt_match *match; 633 char *mt_name; 634 u32 rev, family; 635 636 if (tb[NFTA_MATCH_NAME] == NULL || 637 tb[NFTA_MATCH_REV] == NULL || 638 tb[NFTA_MATCH_INFO] == NULL) 639 return ERR_PTR(-EINVAL); 640 641 mt_name = nla_data(tb[NFTA_MATCH_NAME]); 642 rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV])); 643 family = ctx->afi->family; 644 645 /* Re-use the existing match if it's already loaded. */ 646 list_for_each_entry(nft_match, &nft_match_list, head) { 647 struct xt_match *match = nft_match->ops.data; 648 649 if (nft_match_cmp(match, mt_name, rev, family)) { 650 if (!try_module_get(match->me)) 651 return ERR_PTR(-ENOENT); 652 653 return &nft_match->ops; 654 } 655 } 656 657 match = xt_request_find_match(family, mt_name, rev); 658 if (IS_ERR(match)) 659 return ERR_PTR(-ENOENT); 660 661 /* This is the first time we use this match, allocate operations */ 662 nft_match = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); 663 if (nft_match == NULL) 664 return ERR_PTR(-ENOMEM); 665 666 nft_match->ops.type = &nft_match_type; 667 nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize)); 668 nft_match->ops.eval = nft_match_eval; 669 nft_match->ops.init = nft_match_init; 670 nft_match->ops.destroy = nft_match_destroy; 671 nft_match->ops.dump = nft_match_dump; 672 nft_match->ops.validate = nft_match_validate; 673 nft_match->ops.data = match; 674 675 list_add(&nft_match->head, &nft_match_list); 676 677 return &nft_match->ops; 678} 679 680static void nft_match_release(void) 681{ 682 struct nft_xt *nft_match, *tmp; 683 684 list_for_each_entry_safe(nft_match, tmp, &nft_match_list, head) 685 kfree(nft_match); 686} 687 688static struct nft_expr_type nft_match_type __read_mostly = { 689 .name = "match", 690 .select_ops = nft_match_select_ops, 691 .policy = nft_match_policy, 692 .maxattr = NFTA_MATCH_MAX, 693 .owner = THIS_MODULE, 694}; 695 696static LIST_HEAD(nft_target_list); 697 698static struct nft_expr_type nft_target_type; 699 700static bool nft_target_cmp(const struct xt_target *tg, 701 const char *name, u32 rev, u32 family) 702{ 703 return strcmp(tg->name, name) == 0 && tg->revision == rev && 704 (tg->family == NFPROTO_UNSPEC || tg->family == family); 705} 706 707static const struct nft_expr_ops * 708nft_target_select_ops(const struct nft_ctx *ctx, 709 const struct nlattr * const tb[]) 710{ 711 struct nft_xt *nft_target; 712 struct xt_target *target; 713 char *tg_name; 714 u32 rev, family; 715 716 if (tb[NFTA_TARGET_NAME] == NULL || 717 tb[NFTA_TARGET_REV] == NULL || 718 tb[NFTA_TARGET_INFO] == NULL) 719 return ERR_PTR(-EINVAL); 720 721 tg_name = nla_data(tb[NFTA_TARGET_NAME]); 722 rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV])); 723 family = ctx->afi->family; 724 725 /* Re-use the existing target if it's already loaded. */ 726 list_for_each_entry(nft_target, &nft_target_list, head) { 727 struct xt_target *target = nft_target->ops.data; 728 729 if (nft_target_cmp(target, tg_name, rev, family)) { 730 if (!try_module_get(target->me)) 731 return ERR_PTR(-ENOENT); 732 733 return &nft_target->ops; 734 } 735 } 736 737 target = xt_request_find_target(family, tg_name, rev); 738 if (IS_ERR(target)) 739 return ERR_PTR(-ENOENT); 740 741 /* This is the first time we use this target, allocate operations */ 742 nft_target = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); 743 if (nft_target == NULL) 744 return ERR_PTR(-ENOMEM); 745 746 nft_target->ops.type = &nft_target_type; 747 nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize)); 748 nft_target->ops.init = nft_target_init; 749 nft_target->ops.destroy = nft_target_destroy; 750 nft_target->ops.dump = nft_target_dump; 751 nft_target->ops.validate = nft_target_validate; 752 nft_target->ops.data = target; 753 754 if (family == NFPROTO_BRIDGE) 755 nft_target->ops.eval = nft_target_eval_bridge; 756 else 757 nft_target->ops.eval = nft_target_eval_xt; 758 759 list_add(&nft_target->head, &nft_target_list); 760 761 return &nft_target->ops; 762} 763 764static void nft_target_release(void) 765{ 766 struct nft_xt *nft_target, *tmp; 767 768 list_for_each_entry_safe(nft_target, tmp, &nft_target_list, head) 769 kfree(nft_target); 770} 771 772static struct nft_expr_type nft_target_type __read_mostly = { 773 .name = "target", 774 .select_ops = nft_target_select_ops, 775 .policy = nft_target_policy, 776 .maxattr = NFTA_TARGET_MAX, 777 .owner = THIS_MODULE, 778}; 779 780static int __init nft_compat_module_init(void) 781{ 782 int ret; 783 784 ret = nft_register_expr(&nft_match_type); 785 if (ret < 0) 786 return ret; 787 788 ret = nft_register_expr(&nft_target_type); 789 if (ret < 0) 790 goto err_match; 791 792 ret = nfnetlink_subsys_register(&nfnl_compat_subsys); 793 if (ret < 0) { 794 pr_err("nft_compat: cannot register with nfnetlink.\n"); 795 goto err_target; 796 } 797 798 pr_info("nf_tables_compat: (c) 2012 Pablo Neira Ayuso <pablo@netfilter.org>\n"); 799 800 return ret; 801 802err_target: 803 nft_unregister_expr(&nft_target_type); 804err_match: 805 nft_unregister_expr(&nft_match_type); 806 return ret; 807} 808 809static void __exit nft_compat_module_exit(void) 810{ 811 nfnetlink_subsys_unregister(&nfnl_compat_subsys); 812 nft_unregister_expr(&nft_target_type); 813 nft_unregister_expr(&nft_match_type); 814 nft_match_release(); 815 nft_target_release(); 816} 817 818MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT); 819 820module_init(nft_compat_module_init); 821module_exit(nft_compat_module_exit); 822 823MODULE_LICENSE("GPL"); 824MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); 825MODULE_ALIAS_NFT_EXPR("match"); 826MODULE_ALIAS_NFT_EXPR("target"); 827