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