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