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