Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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