1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * net/core/fib_rules.c Generic Routing Rules 4 * 5 * Authors: Thomas Graf <tgraf@suug.ch> 6 */ 7 8 #include <linux/types.h> 9 #include <linux/kernel.h> 10 #include <linux/slab.h> 11 #include <linux/list.h> 12 #include <linux/module.h> 13 #include <net/net_namespace.h> 14 #include <net/sock.h> 15 #include <net/fib_rules.h> 16 #include <net/ip_tunnels.h> 17 #include <linux/indirect_call_wrapper.h> 18 19 #if defined(CONFIG_IPV6) && defined(CONFIG_IPV6_MULTIPLE_TABLES) 20 #ifdef CONFIG_IP_MULTIPLE_TABLES 21 #define INDIRECT_CALL_MT(f, f2, f1, ...) \ 22 INDIRECT_CALL_INET(f, f2, f1, __VA_ARGS__) 23 #else 24 #define INDIRECT_CALL_MT(f, f2, f1, ...) INDIRECT_CALL_1(f, f2, __VA_ARGS__) 25 #endif 26 #elif defined(CONFIG_IP_MULTIPLE_TABLES) 27 #define INDIRECT_CALL_MT(f, f2, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__) 28 #else 29 #define INDIRECT_CALL_MT(f, f2, f1, ...) f(__VA_ARGS__) 30 #endif 31 32 static const struct fib_kuid_range fib_kuid_range_unset = { 33 KUIDT_INIT(0), 34 KUIDT_INIT(~0), 35 }; 36 37 bool fib_rule_matchall(const struct fib_rule *rule) 38 { 39 if (rule->iifindex || rule->oifindex || rule->mark || rule->tun_id || 40 rule->flags) 41 return false; 42 if (rule->suppress_ifgroup != -1 || rule->suppress_prefixlen != -1) 43 return false; 44 if (!uid_eq(rule->uid_range.start, fib_kuid_range_unset.start) || 45 !uid_eq(rule->uid_range.end, fib_kuid_range_unset.end)) 46 return false; 47 if (fib_rule_port_range_set(&rule->sport_range)) 48 return false; 49 if (fib_rule_port_range_set(&rule->dport_range)) 50 return false; 51 return true; 52 } 53 EXPORT_SYMBOL_GPL(fib_rule_matchall); 54 55 int fib_default_rule_add(struct fib_rules_ops *ops, 56 u32 pref, u32 table) 57 { 58 struct fib_rule *r; 59 60 r = kzalloc(ops->rule_size, GFP_KERNEL_ACCOUNT); 61 if (r == NULL) 62 return -ENOMEM; 63 64 refcount_set(&r->refcnt, 1); 65 r->action = FR_ACT_TO_TBL; 66 r->pref = pref; 67 r->table = table; 68 r->proto = RTPROT_KERNEL; 69 r->fr_net = ops->fro_net; 70 r->uid_range = fib_kuid_range_unset; 71 72 r->suppress_prefixlen = -1; 73 r->suppress_ifgroup = -1; 74 75 /* The lock is not required here, the list in unreacheable 76 * at the moment this function is called */ 77 list_add_tail(&r->list, &ops->rules_list); 78 return 0; 79 } 80 EXPORT_SYMBOL(fib_default_rule_add); 81 82 static u32 fib_default_rule_pref(struct fib_rules_ops *ops) 83 { 84 struct list_head *pos; 85 struct fib_rule *rule; 86 87 if (!list_empty(&ops->rules_list)) { 88 pos = ops->rules_list.next; 89 if (pos->next != &ops->rules_list) { 90 rule = list_entry(pos->next, struct fib_rule, list); 91 if (rule->pref) 92 return rule->pref - 1; 93 } 94 } 95 96 return 0; 97 } 98 99 static void notify_rule_change(int event, struct fib_rule *rule, 100 struct fib_rules_ops *ops, struct nlmsghdr *nlh, 101 u32 pid); 102 103 static struct fib_rules_ops *lookup_rules_ops(struct net *net, int family) 104 { 105 struct fib_rules_ops *ops; 106 107 rcu_read_lock(); 108 list_for_each_entry_rcu(ops, &net->rules_ops, list) { 109 if (ops->family == family) { 110 if (!try_module_get(ops->owner)) 111 ops = NULL; 112 rcu_read_unlock(); 113 return ops; 114 } 115 } 116 rcu_read_unlock(); 117 118 return NULL; 119 } 120 121 static void rules_ops_put(struct fib_rules_ops *ops) 122 { 123 if (ops) 124 module_put(ops->owner); 125 } 126 127 static void flush_route_cache(struct fib_rules_ops *ops) 128 { 129 if (ops->flush_cache) 130 ops->flush_cache(ops); 131 } 132 133 static int __fib_rules_register(struct fib_rules_ops *ops) 134 { 135 int err = -EEXIST; 136 struct fib_rules_ops *o; 137 struct net *net; 138 139 net = ops->fro_net; 140 141 if (ops->rule_size < sizeof(struct fib_rule)) 142 return -EINVAL; 143 144 if (ops->match == NULL || ops->configure == NULL || 145 ops->compare == NULL || ops->fill == NULL || 146 ops->action == NULL) 147 return -EINVAL; 148 149 spin_lock(&net->rules_mod_lock); 150 list_for_each_entry(o, &net->rules_ops, list) 151 if (ops->family == o->family) 152 goto errout; 153 154 list_add_tail_rcu(&ops->list, &net->rules_ops); 155 err = 0; 156 errout: 157 spin_unlock(&net->rules_mod_lock); 158 159 return err; 160 } 161 162 struct fib_rules_ops * 163 fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net) 164 { 165 struct fib_rules_ops *ops; 166 int err; 167 168 ops = kmemdup(tmpl, sizeof(*ops), GFP_KERNEL); 169 if (ops == NULL) 170 return ERR_PTR(-ENOMEM); 171 172 INIT_LIST_HEAD(&ops->rules_list); 173 ops->fro_net = net; 174 175 err = __fib_rules_register(ops); 176 if (err) { 177 kfree(ops); 178 ops = ERR_PTR(err); 179 } 180 181 return ops; 182 } 183 EXPORT_SYMBOL_GPL(fib_rules_register); 184 185 static void fib_rules_cleanup_ops(struct fib_rules_ops *ops) 186 { 187 struct fib_rule *rule, *tmp; 188 189 list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) { 190 list_del_rcu(&rule->list); 191 if (ops->delete) 192 ops->delete(rule); 193 fib_rule_put(rule); 194 } 195 } 196 197 void fib_rules_unregister(struct fib_rules_ops *ops) 198 { 199 struct net *net = ops->fro_net; 200 201 spin_lock(&net->rules_mod_lock); 202 list_del_rcu(&ops->list); 203 spin_unlock(&net->rules_mod_lock); 204 205 fib_rules_cleanup_ops(ops); 206 kfree_rcu(ops, rcu); 207 } 208 EXPORT_SYMBOL_GPL(fib_rules_unregister); 209 210 static int uid_range_set(struct fib_kuid_range *range) 211 { 212 return uid_valid(range->start) && uid_valid(range->end); 213 } 214 215 static struct fib_kuid_range nla_get_kuid_range(struct nlattr **tb) 216 { 217 struct fib_rule_uid_range *in; 218 struct fib_kuid_range out; 219 220 in = (struct fib_rule_uid_range *)nla_data(tb[FRA_UID_RANGE]); 221 222 out.start = make_kuid(current_user_ns(), in->start); 223 out.end = make_kuid(current_user_ns(), in->end); 224 225 return out; 226 } 227 228 static int nla_put_uid_range(struct sk_buff *skb, struct fib_kuid_range *range) 229 { 230 struct fib_rule_uid_range out = { 231 from_kuid_munged(current_user_ns(), range->start), 232 from_kuid_munged(current_user_ns(), range->end) 233 }; 234 235 return nla_put(skb, FRA_UID_RANGE, sizeof(out), &out); 236 } 237 238 static int nla_get_port_range(struct nlattr *pattr, 239 struct fib_rule_port_range *port_range) 240 { 241 const struct fib_rule_port_range *pr = nla_data(pattr); 242 243 if (!fib_rule_port_range_valid(pr)) 244 return -EINVAL; 245 246 port_range->start = pr->start; 247 port_range->end = pr->end; 248 249 return 0; 250 } 251 252 static int nla_put_port_range(struct sk_buff *skb, int attrtype, 253 struct fib_rule_port_range *range) 254 { 255 return nla_put(skb, attrtype, sizeof(*range), range); 256 } 257 258 static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, 259 struct flowi *fl, int flags, 260 struct fib_lookup_arg *arg) 261 { 262 int ret = 0; 263 264 if (rule->iifindex && (rule->iifindex != fl->flowi_iif)) 265 goto out; 266 267 if (rule->oifindex && (rule->oifindex != fl->flowi_oif)) 268 goto out; 269 270 if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) 271 goto out; 272 273 if (rule->tun_id && (rule->tun_id != fl->flowi_tun_key.tun_id)) 274 goto out; 275 276 if (rule->l3mdev && !l3mdev_fib_rule_match(rule->fr_net, fl, arg)) 277 goto out; 278 279 if (uid_lt(fl->flowi_uid, rule->uid_range.start) || 280 uid_gt(fl->flowi_uid, rule->uid_range.end)) 281 goto out; 282 283 ret = INDIRECT_CALL_MT(ops->match, 284 fib6_rule_match, 285 fib4_rule_match, 286 rule, fl, flags); 287 out: 288 return (rule->flags & FIB_RULE_INVERT) ? !ret : ret; 289 } 290 291 int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, 292 int flags, struct fib_lookup_arg *arg) 293 { 294 struct fib_rule *rule; 295 int err; 296 297 rcu_read_lock(); 298 299 list_for_each_entry_rcu(rule, &ops->rules_list, list) { 300 jumped: 301 if (!fib_rule_match(rule, ops, fl, flags, arg)) 302 continue; 303 304 if (rule->action == FR_ACT_GOTO) { 305 struct fib_rule *target; 306 307 target = rcu_dereference(rule->ctarget); 308 if (target == NULL) { 309 continue; 310 } else { 311 rule = target; 312 goto jumped; 313 } 314 } else if (rule->action == FR_ACT_NOP) 315 continue; 316 else 317 err = INDIRECT_CALL_MT(ops->action, 318 fib6_rule_action, 319 fib4_rule_action, 320 rule, fl, flags, arg); 321 322 if (!err && ops->suppress && INDIRECT_CALL_MT(ops->suppress, 323 fib6_rule_suppress, 324 fib4_rule_suppress, 325 rule, flags, arg)) 326 continue; 327 328 if (err != -EAGAIN) { 329 if ((arg->flags & FIB_LOOKUP_NOREF) || 330 likely(refcount_inc_not_zero(&rule->refcnt))) { 331 arg->rule = rule; 332 goto out; 333 } 334 break; 335 } 336 } 337 338 err = -ESRCH; 339 out: 340 rcu_read_unlock(); 341 342 return err; 343 } 344 EXPORT_SYMBOL_GPL(fib_rules_lookup); 345 346 static int call_fib_rule_notifier(struct notifier_block *nb, 347 enum fib_event_type event_type, 348 struct fib_rule *rule, int family, 349 struct netlink_ext_ack *extack) 350 { 351 struct fib_rule_notifier_info info = { 352 .info.family = family, 353 .info.extack = extack, 354 .rule = rule, 355 }; 356 357 return call_fib_notifier(nb, event_type, &info.info); 358 } 359 360 static int call_fib_rule_notifiers(struct net *net, 361 enum fib_event_type event_type, 362 struct fib_rule *rule, 363 struct fib_rules_ops *ops, 364 struct netlink_ext_ack *extack) 365 { 366 struct fib_rule_notifier_info info = { 367 .info.family = ops->family, 368 .info.extack = extack, 369 .rule = rule, 370 }; 371 372 ops->fib_rules_seq++; 373 return call_fib_notifiers(net, event_type, &info.info); 374 } 375 376 /* Called with rcu_read_lock() */ 377 int fib_rules_dump(struct net *net, struct notifier_block *nb, int family, 378 struct netlink_ext_ack *extack) 379 { 380 struct fib_rules_ops *ops; 381 struct fib_rule *rule; 382 int err = 0; 383 384 ops = lookup_rules_ops(net, family); 385 if (!ops) 386 return -EAFNOSUPPORT; 387 list_for_each_entry_rcu(rule, &ops->rules_list, list) { 388 err = call_fib_rule_notifier(nb, FIB_EVENT_RULE_ADD, 389 rule, family, extack); 390 if (err) 391 break; 392 } 393 rules_ops_put(ops); 394 395 return err; 396 } 397 EXPORT_SYMBOL_GPL(fib_rules_dump); 398 399 unsigned int fib_rules_seq_read(struct net *net, int family) 400 { 401 unsigned int fib_rules_seq; 402 struct fib_rules_ops *ops; 403 404 ASSERT_RTNL(); 405 406 ops = lookup_rules_ops(net, family); 407 if (!ops) 408 return 0; 409 fib_rules_seq = ops->fib_rules_seq; 410 rules_ops_put(ops); 411 412 return fib_rules_seq; 413 } 414 EXPORT_SYMBOL_GPL(fib_rules_seq_read); 415 416 static struct fib_rule *rule_find(struct fib_rules_ops *ops, 417 struct fib_rule_hdr *frh, 418 struct nlattr **tb, 419 struct fib_rule *rule, 420 bool user_priority) 421 { 422 struct fib_rule *r; 423 424 list_for_each_entry(r, &ops->rules_list, list) { 425 if (rule->action && r->action != rule->action) 426 continue; 427 428 if (rule->table && r->table != rule->table) 429 continue; 430 431 if (user_priority && r->pref != rule->pref) 432 continue; 433 434 if (rule->iifname[0] && 435 memcmp(r->iifname, rule->iifname, IFNAMSIZ)) 436 continue; 437 438 if (rule->oifname[0] && 439 memcmp(r->oifname, rule->oifname, IFNAMSIZ)) 440 continue; 441 442 if (rule->mark && r->mark != rule->mark) 443 continue; 444 445 if (rule->suppress_ifgroup != -1 && 446 r->suppress_ifgroup != rule->suppress_ifgroup) 447 continue; 448 449 if (rule->suppress_prefixlen != -1 && 450 r->suppress_prefixlen != rule->suppress_prefixlen) 451 continue; 452 453 if (rule->mark_mask && r->mark_mask != rule->mark_mask) 454 continue; 455 456 if (rule->tun_id && r->tun_id != rule->tun_id) 457 continue; 458 459 if (r->fr_net != rule->fr_net) 460 continue; 461 462 if (rule->l3mdev && r->l3mdev != rule->l3mdev) 463 continue; 464 465 if (uid_range_set(&rule->uid_range) && 466 (!uid_eq(r->uid_range.start, rule->uid_range.start) || 467 !uid_eq(r->uid_range.end, rule->uid_range.end))) 468 continue; 469 470 if (rule->ip_proto && r->ip_proto != rule->ip_proto) 471 continue; 472 473 if (rule->proto && r->proto != rule->proto) 474 continue; 475 476 if (fib_rule_port_range_set(&rule->sport_range) && 477 !fib_rule_port_range_compare(&r->sport_range, 478 &rule->sport_range)) 479 continue; 480 481 if (fib_rule_port_range_set(&rule->dport_range) && 482 !fib_rule_port_range_compare(&r->dport_range, 483 &rule->dport_range)) 484 continue; 485 486 if (!ops->compare(r, frh, tb)) 487 continue; 488 return r; 489 } 490 491 return NULL; 492 } 493 494 #ifdef CONFIG_NET_L3_MASTER_DEV 495 static int fib_nl2rule_l3mdev(struct nlattr *nla, struct fib_rule *nlrule, 496 struct netlink_ext_ack *extack) 497 { 498 nlrule->l3mdev = nla_get_u8(nla); 499 if (nlrule->l3mdev != 1) { 500 NL_SET_ERR_MSG(extack, "Invalid l3mdev attribute"); 501 return -1; 502 } 503 504 return 0; 505 } 506 #else 507 static int fib_nl2rule_l3mdev(struct nlattr *nla, struct fib_rule *nlrule, 508 struct netlink_ext_ack *extack) 509 { 510 NL_SET_ERR_MSG(extack, "l3mdev support is not enabled in kernel"); 511 return -1; 512 } 513 #endif 514 515 static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh, 516 struct netlink_ext_ack *extack, 517 struct fib_rules_ops *ops, 518 struct nlattr *tb[], 519 struct fib_rule **rule, 520 bool *user_priority) 521 { 522 struct net *net = sock_net(skb->sk); 523 struct fib_rule_hdr *frh = nlmsg_data(nlh); 524 struct fib_rule *nlrule = NULL; 525 int err = -EINVAL; 526 527 if (frh->src_len) 528 if (!tb[FRA_SRC] || 529 frh->src_len > (ops->addr_size * 8) || 530 nla_len(tb[FRA_SRC]) != ops->addr_size) { 531 NL_SET_ERR_MSG(extack, "Invalid source address"); 532 goto errout; 533 } 534 535 if (frh->dst_len) 536 if (!tb[FRA_DST] || 537 frh->dst_len > (ops->addr_size * 8) || 538 nla_len(tb[FRA_DST]) != ops->addr_size) { 539 NL_SET_ERR_MSG(extack, "Invalid dst address"); 540 goto errout; 541 } 542 543 nlrule = kzalloc(ops->rule_size, GFP_KERNEL_ACCOUNT); 544 if (!nlrule) { 545 err = -ENOMEM; 546 goto errout; 547 } 548 refcount_set(&nlrule->refcnt, 1); 549 nlrule->fr_net = net; 550 551 if (tb[FRA_PRIORITY]) { 552 nlrule->pref = nla_get_u32(tb[FRA_PRIORITY]); 553 *user_priority = true; 554 } else { 555 nlrule->pref = fib_default_rule_pref(ops); 556 } 557 558 nlrule->proto = tb[FRA_PROTOCOL] ? 559 nla_get_u8(tb[FRA_PROTOCOL]) : RTPROT_UNSPEC; 560 561 if (tb[FRA_IIFNAME]) { 562 struct net_device *dev; 563 564 nlrule->iifindex = -1; 565 nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ); 566 dev = __dev_get_by_name(net, nlrule->iifname); 567 if (dev) 568 nlrule->iifindex = dev->ifindex; 569 } 570 571 if (tb[FRA_OIFNAME]) { 572 struct net_device *dev; 573 574 nlrule->oifindex = -1; 575 nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ); 576 dev = __dev_get_by_name(net, nlrule->oifname); 577 if (dev) 578 nlrule->oifindex = dev->ifindex; 579 } 580 581 if (tb[FRA_FWMARK]) { 582 nlrule->mark = nla_get_u32(tb[FRA_FWMARK]); 583 if (nlrule->mark) 584 /* compatibility: if the mark value is non-zero all bits 585 * are compared unless a mask is explicitly specified. 586 */ 587 nlrule->mark_mask = 0xFFFFFFFF; 588 } 589 590 if (tb[FRA_FWMASK]) 591 nlrule->mark_mask = nla_get_u32(tb[FRA_FWMASK]); 592 593 if (tb[FRA_TUN_ID]) 594 nlrule->tun_id = nla_get_be64(tb[FRA_TUN_ID]); 595 596 if (tb[FRA_L3MDEV] && 597 fib_nl2rule_l3mdev(tb[FRA_L3MDEV], nlrule, extack) < 0) 598 goto errout_free; 599 600 nlrule->action = frh->action; 601 nlrule->flags = frh->flags; 602 nlrule->table = frh_get_table(frh, tb); 603 if (tb[FRA_SUPPRESS_PREFIXLEN]) 604 nlrule->suppress_prefixlen = nla_get_u32(tb[FRA_SUPPRESS_PREFIXLEN]); 605 else 606 nlrule->suppress_prefixlen = -1; 607 608 if (tb[FRA_SUPPRESS_IFGROUP]) 609 nlrule->suppress_ifgroup = nla_get_u32(tb[FRA_SUPPRESS_IFGROUP]); 610 else 611 nlrule->suppress_ifgroup = -1; 612 613 if (tb[FRA_GOTO]) { 614 if (nlrule->action != FR_ACT_GOTO) { 615 NL_SET_ERR_MSG(extack, "Unexpected goto"); 616 goto errout_free; 617 } 618 619 nlrule->target = nla_get_u32(tb[FRA_GOTO]); 620 /* Backward jumps are prohibited to avoid endless loops */ 621 if (nlrule->target <= nlrule->pref) { 622 NL_SET_ERR_MSG(extack, "Backward goto not supported"); 623 goto errout_free; 624 } 625 } else if (nlrule->action == FR_ACT_GOTO) { 626 NL_SET_ERR_MSG(extack, "Missing goto target for action goto"); 627 goto errout_free; 628 } 629 630 if (nlrule->l3mdev && nlrule->table) { 631 NL_SET_ERR_MSG(extack, "l3mdev and table are mutually exclusive"); 632 goto errout_free; 633 } 634 635 if (tb[FRA_UID_RANGE]) { 636 if (current_user_ns() != net->user_ns) { 637 err = -EPERM; 638 NL_SET_ERR_MSG(extack, "No permission to set uid"); 639 goto errout_free; 640 } 641 642 nlrule->uid_range = nla_get_kuid_range(tb); 643 644 if (!uid_range_set(&nlrule->uid_range) || 645 !uid_lte(nlrule->uid_range.start, nlrule->uid_range.end)) { 646 NL_SET_ERR_MSG(extack, "Invalid uid range"); 647 goto errout_free; 648 } 649 } else { 650 nlrule->uid_range = fib_kuid_range_unset; 651 } 652 653 if (tb[FRA_IP_PROTO]) 654 nlrule->ip_proto = nla_get_u8(tb[FRA_IP_PROTO]); 655 656 if (tb[FRA_SPORT_RANGE]) { 657 err = nla_get_port_range(tb[FRA_SPORT_RANGE], 658 &nlrule->sport_range); 659 if (err) { 660 NL_SET_ERR_MSG(extack, "Invalid sport range"); 661 goto errout_free; 662 } 663 } 664 665 if (tb[FRA_DPORT_RANGE]) { 666 err = nla_get_port_range(tb[FRA_DPORT_RANGE], 667 &nlrule->dport_range); 668 if (err) { 669 NL_SET_ERR_MSG(extack, "Invalid dport range"); 670 goto errout_free; 671 } 672 } 673 674 *rule = nlrule; 675 676 return 0; 677 678 errout_free: 679 kfree(nlrule); 680 errout: 681 return err; 682 } 683 684 static int rule_exists(struct fib_rules_ops *ops, struct fib_rule_hdr *frh, 685 struct nlattr **tb, struct fib_rule *rule) 686 { 687 struct fib_rule *r; 688 689 list_for_each_entry(r, &ops->rules_list, list) { 690 if (r->action != rule->action) 691 continue; 692 693 if (r->table != rule->table) 694 continue; 695 696 if (r->pref != rule->pref) 697 continue; 698 699 if (memcmp(r->iifname, rule->iifname, IFNAMSIZ)) 700 continue; 701 702 if (memcmp(r->oifname, rule->oifname, IFNAMSIZ)) 703 continue; 704 705 if (r->mark != rule->mark) 706 continue; 707 708 if (r->suppress_ifgroup != rule->suppress_ifgroup) 709 continue; 710 711 if (r->suppress_prefixlen != rule->suppress_prefixlen) 712 continue; 713 714 if (r->mark_mask != rule->mark_mask) 715 continue; 716 717 if (r->tun_id != rule->tun_id) 718 continue; 719 720 if (r->fr_net != rule->fr_net) 721 continue; 722 723 if (r->l3mdev != rule->l3mdev) 724 continue; 725 726 if (!uid_eq(r->uid_range.start, rule->uid_range.start) || 727 !uid_eq(r->uid_range.end, rule->uid_range.end)) 728 continue; 729 730 if (r->ip_proto != rule->ip_proto) 731 continue; 732 733 if (r->proto != rule->proto) 734 continue; 735 736 if (!fib_rule_port_range_compare(&r->sport_range, 737 &rule->sport_range)) 738 continue; 739 740 if (!fib_rule_port_range_compare(&r->dport_range, 741 &rule->dport_range)) 742 continue; 743 744 if (!ops->compare(r, frh, tb)) 745 continue; 746 return 1; 747 } 748 return 0; 749 } 750 751 static const struct nla_policy fib_rule_policy[FRA_MAX + 1] = { 752 [FRA_UNSPEC] = { .strict_start_type = FRA_DPORT_RANGE + 1 }, 753 [FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, 754 [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, 755 [FRA_PRIORITY] = { .type = NLA_U32 }, 756 [FRA_FWMARK] = { .type = NLA_U32 }, 757 [FRA_FLOW] = { .type = NLA_U32 }, 758 [FRA_TUN_ID] = { .type = NLA_U64 }, 759 [FRA_FWMASK] = { .type = NLA_U32 }, 760 [FRA_TABLE] = { .type = NLA_U32 }, 761 [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, 762 [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, 763 [FRA_GOTO] = { .type = NLA_U32 }, 764 [FRA_L3MDEV] = { .type = NLA_U8 }, 765 [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) }, 766 [FRA_PROTOCOL] = { .type = NLA_U8 }, 767 [FRA_IP_PROTO] = { .type = NLA_U8 }, 768 [FRA_SPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }, 769 [FRA_DPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) } 770 }; 771 772 int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, 773 struct netlink_ext_ack *extack) 774 { 775 struct net *net = sock_net(skb->sk); 776 struct fib_rule_hdr *frh = nlmsg_data(nlh); 777 struct fib_rules_ops *ops = NULL; 778 struct fib_rule *rule = NULL, *r, *last = NULL; 779 struct nlattr *tb[FRA_MAX + 1]; 780 int err = -EINVAL, unresolved = 0; 781 bool user_priority = false; 782 783 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) { 784 NL_SET_ERR_MSG(extack, "Invalid msg length"); 785 goto errout; 786 } 787 788 ops = lookup_rules_ops(net, frh->family); 789 if (!ops) { 790 err = -EAFNOSUPPORT; 791 NL_SET_ERR_MSG(extack, "Rule family not supported"); 792 goto errout; 793 } 794 795 err = nlmsg_parse_deprecated(nlh, sizeof(*frh), tb, FRA_MAX, 796 fib_rule_policy, extack); 797 if (err < 0) { 798 NL_SET_ERR_MSG(extack, "Error parsing msg"); 799 goto errout; 800 } 801 802 err = fib_nl2rule(skb, nlh, extack, ops, tb, &rule, &user_priority); 803 if (err) 804 goto errout; 805 806 if ((nlh->nlmsg_flags & NLM_F_EXCL) && 807 rule_exists(ops, frh, tb, rule)) { 808 err = -EEXIST; 809 goto errout_free; 810 } 811 812 err = ops->configure(rule, skb, frh, tb, extack); 813 if (err < 0) 814 goto errout_free; 815 816 err = call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops, 817 extack); 818 if (err < 0) 819 goto errout_free; 820 821 list_for_each_entry(r, &ops->rules_list, list) { 822 if (r->pref == rule->target) { 823 RCU_INIT_POINTER(rule->ctarget, r); 824 break; 825 } 826 } 827 828 if (rcu_dereference_protected(rule->ctarget, 1) == NULL) 829 unresolved = 1; 830 831 list_for_each_entry(r, &ops->rules_list, list) { 832 if (r->pref > rule->pref) 833 break; 834 last = r; 835 } 836 837 if (last) 838 list_add_rcu(&rule->list, &last->list); 839 else 840 list_add_rcu(&rule->list, &ops->rules_list); 841 842 if (ops->unresolved_rules) { 843 /* 844 * There are unresolved goto rules in the list, check if 845 * any of them are pointing to this new rule. 846 */ 847 list_for_each_entry(r, &ops->rules_list, list) { 848 if (r->action == FR_ACT_GOTO && 849 r->target == rule->pref && 850 rtnl_dereference(r->ctarget) == NULL) { 851 rcu_assign_pointer(r->ctarget, rule); 852 if (--ops->unresolved_rules == 0) 853 break; 854 } 855 } 856 } 857 858 if (rule->action == FR_ACT_GOTO) 859 ops->nr_goto_rules++; 860 861 if (unresolved) 862 ops->unresolved_rules++; 863 864 if (rule->tun_id) 865 ip_tunnel_need_metadata(); 866 867 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); 868 flush_route_cache(ops); 869 rules_ops_put(ops); 870 return 0; 871 872 errout_free: 873 kfree(rule); 874 errout: 875 rules_ops_put(ops); 876 return err; 877 } 878 EXPORT_SYMBOL_GPL(fib_nl_newrule); 879 880 int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, 881 struct netlink_ext_ack *extack) 882 { 883 struct net *net = sock_net(skb->sk); 884 struct fib_rule_hdr *frh = nlmsg_data(nlh); 885 struct fib_rules_ops *ops = NULL; 886 struct fib_rule *rule = NULL, *r, *nlrule = NULL; 887 struct nlattr *tb[FRA_MAX+1]; 888 int err = -EINVAL; 889 bool user_priority = false; 890 891 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) { 892 NL_SET_ERR_MSG(extack, "Invalid msg length"); 893 goto errout; 894 } 895 896 ops = lookup_rules_ops(net, frh->family); 897 if (ops == NULL) { 898 err = -EAFNOSUPPORT; 899 NL_SET_ERR_MSG(extack, "Rule family not supported"); 900 goto errout; 901 } 902 903 err = nlmsg_parse_deprecated(nlh, sizeof(*frh), tb, FRA_MAX, 904 fib_rule_policy, extack); 905 if (err < 0) { 906 NL_SET_ERR_MSG(extack, "Error parsing msg"); 907 goto errout; 908 } 909 910 err = fib_nl2rule(skb, nlh, extack, ops, tb, &nlrule, &user_priority); 911 if (err) 912 goto errout; 913 914 rule = rule_find(ops, frh, tb, nlrule, user_priority); 915 if (!rule) { 916 err = -ENOENT; 917 goto errout; 918 } 919 920 if (rule->flags & FIB_RULE_PERMANENT) { 921 err = -EPERM; 922 goto errout; 923 } 924 925 if (ops->delete) { 926 err = ops->delete(rule); 927 if (err) 928 goto errout; 929 } 930 931 if (rule->tun_id) 932 ip_tunnel_unneed_metadata(); 933 934 list_del_rcu(&rule->list); 935 936 if (rule->action == FR_ACT_GOTO) { 937 ops->nr_goto_rules--; 938 if (rtnl_dereference(rule->ctarget) == NULL) 939 ops->unresolved_rules--; 940 } 941 942 /* 943 * Check if this rule is a target to any of them. If so, 944 * adjust to the next one with the same preference or 945 * disable them. As this operation is eventually very 946 * expensive, it is only performed if goto rules, except 947 * current if it is goto rule, have actually been added. 948 */ 949 if (ops->nr_goto_rules > 0) { 950 struct fib_rule *n; 951 952 n = list_next_entry(rule, list); 953 if (&n->list == &ops->rules_list || n->pref != rule->pref) 954 n = NULL; 955 list_for_each_entry(r, &ops->rules_list, list) { 956 if (rtnl_dereference(r->ctarget) != rule) 957 continue; 958 rcu_assign_pointer(r->ctarget, n); 959 if (!n) 960 ops->unresolved_rules++; 961 } 962 } 963 964 call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL, rule, ops, 965 NULL); 966 notify_rule_change(RTM_DELRULE, rule, ops, nlh, 967 NETLINK_CB(skb).portid); 968 fib_rule_put(rule); 969 flush_route_cache(ops); 970 rules_ops_put(ops); 971 kfree(nlrule); 972 return 0; 973 974 errout: 975 kfree(nlrule); 976 rules_ops_put(ops); 977 return err; 978 } 979 EXPORT_SYMBOL_GPL(fib_nl_delrule); 980 981 static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops, 982 struct fib_rule *rule) 983 { 984 size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr)) 985 + nla_total_size(IFNAMSIZ) /* FRA_IIFNAME */ 986 + nla_total_size(IFNAMSIZ) /* FRA_OIFNAME */ 987 + nla_total_size(4) /* FRA_PRIORITY */ 988 + nla_total_size(4) /* FRA_TABLE */ 989 + nla_total_size(4) /* FRA_SUPPRESS_PREFIXLEN */ 990 + nla_total_size(4) /* FRA_SUPPRESS_IFGROUP */ 991 + nla_total_size(4) /* FRA_FWMARK */ 992 + nla_total_size(4) /* FRA_FWMASK */ 993 + nla_total_size_64bit(8) /* FRA_TUN_ID */ 994 + nla_total_size(sizeof(struct fib_kuid_range)) 995 + nla_total_size(1) /* FRA_PROTOCOL */ 996 + nla_total_size(1) /* FRA_IP_PROTO */ 997 + nla_total_size(sizeof(struct fib_rule_port_range)) /* FRA_SPORT_RANGE */ 998 + nla_total_size(sizeof(struct fib_rule_port_range)); /* FRA_DPORT_RANGE */ 999 1000 if (ops->nlmsg_payload) 1001 payload += ops->nlmsg_payload(rule); 1002 1003 return payload; 1004 } 1005 1006 static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, 1007 u32 pid, u32 seq, int type, int flags, 1008 struct fib_rules_ops *ops) 1009 { 1010 struct nlmsghdr *nlh; 1011 struct fib_rule_hdr *frh; 1012 1013 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags); 1014 if (nlh == NULL) 1015 return -EMSGSIZE; 1016 1017 frh = nlmsg_data(nlh); 1018 frh->family = ops->family; 1019 frh->table = rule->table < 256 ? rule->table : RT_TABLE_COMPAT; 1020 if (nla_put_u32(skb, FRA_TABLE, rule->table)) 1021 goto nla_put_failure; 1022 if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen)) 1023 goto nla_put_failure; 1024 frh->res1 = 0; 1025 frh->res2 = 0; 1026 frh->action = rule->action; 1027 frh->flags = rule->flags; 1028 1029 if (nla_put_u8(skb, FRA_PROTOCOL, rule->proto)) 1030 goto nla_put_failure; 1031 1032 if (rule->action == FR_ACT_GOTO && 1033 rcu_access_pointer(rule->ctarget) == NULL) 1034 frh->flags |= FIB_RULE_UNRESOLVED; 1035 1036 if (rule->iifname[0]) { 1037 if (nla_put_string(skb, FRA_IIFNAME, rule->iifname)) 1038 goto nla_put_failure; 1039 if (rule->iifindex == -1) 1040 frh->flags |= FIB_RULE_IIF_DETACHED; 1041 } 1042 1043 if (rule->oifname[0]) { 1044 if (nla_put_string(skb, FRA_OIFNAME, rule->oifname)) 1045 goto nla_put_failure; 1046 if (rule->oifindex == -1) 1047 frh->flags |= FIB_RULE_OIF_DETACHED; 1048 } 1049 1050 if ((rule->pref && 1051 nla_put_u32(skb, FRA_PRIORITY, rule->pref)) || 1052 (rule->mark && 1053 nla_put_u32(skb, FRA_FWMARK, rule->mark)) || 1054 ((rule->mark_mask || rule->mark) && 1055 nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) || 1056 (rule->target && 1057 nla_put_u32(skb, FRA_GOTO, rule->target)) || 1058 (rule->tun_id && 1059 nla_put_be64(skb, FRA_TUN_ID, rule->tun_id, FRA_PAD)) || 1060 (rule->l3mdev && 1061 nla_put_u8(skb, FRA_L3MDEV, rule->l3mdev)) || 1062 (uid_range_set(&rule->uid_range) && 1063 nla_put_uid_range(skb, &rule->uid_range)) || 1064 (fib_rule_port_range_set(&rule->sport_range) && 1065 nla_put_port_range(skb, FRA_SPORT_RANGE, &rule->sport_range)) || 1066 (fib_rule_port_range_set(&rule->dport_range) && 1067 nla_put_port_range(skb, FRA_DPORT_RANGE, &rule->dport_range)) || 1068 (rule->ip_proto && nla_put_u8(skb, FRA_IP_PROTO, rule->ip_proto))) 1069 goto nla_put_failure; 1070 1071 if (rule->suppress_ifgroup != -1) { 1072 if (nla_put_u32(skb, FRA_SUPPRESS_IFGROUP, rule->suppress_ifgroup)) 1073 goto nla_put_failure; 1074 } 1075 1076 if (ops->fill(rule, skb, frh) < 0) 1077 goto nla_put_failure; 1078 1079 nlmsg_end(skb, nlh); 1080 return 0; 1081 1082 nla_put_failure: 1083 nlmsg_cancel(skb, nlh); 1084 return -EMSGSIZE; 1085 } 1086 1087 static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb, 1088 struct fib_rules_ops *ops) 1089 { 1090 int idx = 0; 1091 struct fib_rule *rule; 1092 int err = 0; 1093 1094 rcu_read_lock(); 1095 list_for_each_entry_rcu(rule, &ops->rules_list, list) { 1096 if (idx < cb->args[1]) 1097 goto skip; 1098 1099 err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid, 1100 cb->nlh->nlmsg_seq, RTM_NEWRULE, 1101 NLM_F_MULTI, ops); 1102 if (err) 1103 break; 1104 skip: 1105 idx++; 1106 } 1107 rcu_read_unlock(); 1108 cb->args[1] = idx; 1109 rules_ops_put(ops); 1110 1111 return err; 1112 } 1113 1114 static int fib_valid_dumprule_req(const struct nlmsghdr *nlh, 1115 struct netlink_ext_ack *extack) 1116 { 1117 struct fib_rule_hdr *frh; 1118 1119 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) { 1120 NL_SET_ERR_MSG(extack, "Invalid header for fib rule dump request"); 1121 return -EINVAL; 1122 } 1123 1124 frh = nlmsg_data(nlh); 1125 if (frh->dst_len || frh->src_len || frh->tos || frh->table || 1126 frh->res1 || frh->res2 || frh->action || frh->flags) { 1127 NL_SET_ERR_MSG(extack, 1128 "Invalid values in header for fib rule dump request"); 1129 return -EINVAL; 1130 } 1131 1132 if (nlmsg_attrlen(nlh, sizeof(*frh))) { 1133 NL_SET_ERR_MSG(extack, "Invalid data after header in fib rule dump request"); 1134 return -EINVAL; 1135 } 1136 1137 return 0; 1138 } 1139 1140 static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb) 1141 { 1142 const struct nlmsghdr *nlh = cb->nlh; 1143 struct net *net = sock_net(skb->sk); 1144 struct fib_rules_ops *ops; 1145 int err, idx = 0, family; 1146 1147 if (cb->strict_check) { 1148 err = fib_valid_dumprule_req(nlh, cb->extack); 1149 1150 if (err < 0) 1151 return err; 1152 } 1153 1154 family = rtnl_msg_family(nlh); 1155 if (family != AF_UNSPEC) { 1156 /* Protocol specific dump request */ 1157 ops = lookup_rules_ops(net, family); 1158 if (ops == NULL) 1159 return -EAFNOSUPPORT; 1160 1161 return dump_rules(skb, cb, ops); 1162 } 1163 1164 err = 0; 1165 rcu_read_lock(); 1166 list_for_each_entry_rcu(ops, &net->rules_ops, list) { 1167 if (idx < cb->args[0] || !try_module_get(ops->owner)) 1168 goto skip; 1169 1170 err = dump_rules(skb, cb, ops); 1171 if (err < 0) 1172 break; 1173 1174 cb->args[1] = 0; 1175 skip: 1176 idx++; 1177 } 1178 rcu_read_unlock(); 1179 cb->args[0] = idx; 1180 1181 return err; 1182 } 1183 1184 static void notify_rule_change(int event, struct fib_rule *rule, 1185 struct fib_rules_ops *ops, struct nlmsghdr *nlh, 1186 u32 pid) 1187 { 1188 struct net *net; 1189 struct sk_buff *skb; 1190 int err = -ENOMEM; 1191 1192 net = ops->fro_net; 1193 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); 1194 if (skb == NULL) 1195 goto errout; 1196 1197 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); 1198 if (err < 0) { 1199 /* -EMSGSIZE implies BUG in fib_rule_nlmsg_size() */ 1200 WARN_ON(err == -EMSGSIZE); 1201 kfree_skb(skb); 1202 goto errout; 1203 } 1204 1205 rtnl_notify(skb, net, pid, ops->nlgroup, nlh, GFP_KERNEL); 1206 return; 1207 errout: 1208 if (err < 0) 1209 rtnl_set_sk_err(net, ops->nlgroup, err); 1210 } 1211 1212 static void attach_rules(struct list_head *rules, struct net_device *dev) 1213 { 1214 struct fib_rule *rule; 1215 1216 list_for_each_entry(rule, rules, list) { 1217 if (rule->iifindex == -1 && 1218 strcmp(dev->name, rule->iifname) == 0) 1219 rule->iifindex = dev->ifindex; 1220 if (rule->oifindex == -1 && 1221 strcmp(dev->name, rule->oifname) == 0) 1222 rule->oifindex = dev->ifindex; 1223 } 1224 } 1225 1226 static void detach_rules(struct list_head *rules, struct net_device *dev) 1227 { 1228 struct fib_rule *rule; 1229 1230 list_for_each_entry(rule, rules, list) { 1231 if (rule->iifindex == dev->ifindex) 1232 rule->iifindex = -1; 1233 if (rule->oifindex == dev->ifindex) 1234 rule->oifindex = -1; 1235 } 1236 } 1237 1238 1239 static int fib_rules_event(struct notifier_block *this, unsigned long event, 1240 void *ptr) 1241 { 1242 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 1243 struct net *net = dev_net(dev); 1244 struct fib_rules_ops *ops; 1245 1246 ASSERT_RTNL(); 1247 1248 switch (event) { 1249 case NETDEV_REGISTER: 1250 list_for_each_entry(ops, &net->rules_ops, list) 1251 attach_rules(&ops->rules_list, dev); 1252 break; 1253 1254 case NETDEV_CHANGENAME: 1255 list_for_each_entry(ops, &net->rules_ops, list) { 1256 detach_rules(&ops->rules_list, dev); 1257 attach_rules(&ops->rules_list, dev); 1258 } 1259 break; 1260 1261 case NETDEV_UNREGISTER: 1262 list_for_each_entry(ops, &net->rules_ops, list) 1263 detach_rules(&ops->rules_list, dev); 1264 break; 1265 } 1266 1267 return NOTIFY_DONE; 1268 } 1269 1270 static struct notifier_block fib_rules_notifier = { 1271 .notifier_call = fib_rules_event, 1272 }; 1273 1274 static int __net_init fib_rules_net_init(struct net *net) 1275 { 1276 INIT_LIST_HEAD(&net->rules_ops); 1277 spin_lock_init(&net->rules_mod_lock); 1278 return 0; 1279 } 1280 1281 static void __net_exit fib_rules_net_exit(struct net *net) 1282 { 1283 WARN_ON_ONCE(!list_empty(&net->rules_ops)); 1284 } 1285 1286 static struct pernet_operations fib_rules_net_ops = { 1287 .init = fib_rules_net_init, 1288 .exit = fib_rules_net_exit, 1289 }; 1290 1291 static int __init fib_rules_init(void) 1292 { 1293 int err; 1294 rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL, 0); 1295 rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL, 0); 1296 rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule, 1297 RTNL_FLAG_DUMP_UNLOCKED); 1298 1299 err = register_pernet_subsys(&fib_rules_net_ops); 1300 if (err < 0) 1301 goto fail; 1302 1303 err = register_netdevice_notifier(&fib_rules_notifier); 1304 if (err < 0) 1305 goto fail_unregister; 1306 1307 return 0; 1308 1309 fail_unregister: 1310 unregister_pernet_subsys(&fib_rules_net_ops); 1311 fail: 1312 rtnl_unregister(PF_UNSPEC, RTM_NEWRULE); 1313 rtnl_unregister(PF_UNSPEC, RTM_DELRULE); 1314 rtnl_unregister(PF_UNSPEC, RTM_GETRULE); 1315 return err; 1316 } 1317 1318 subsys_initcall(fib_rules_init); 1319
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.