1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * net/ipv6/fib6_rules.c IPv6 Routing Policy Rules 4 * 5 * Copyright (C)2003-2006 Helsinki University of Technology 6 * Copyright (C)2003-2006 USAGI/WIDE Project 7 * 8 * Authors 9 * Thomas Graf <tgraf@suug.ch> 10 * Ville Nuorvala <vnuorval@tcs.hut.fi> 11 */ 12 13 #include <linux/netdevice.h> 14 #include <linux/notifier.h> 15 #include <linux/export.h> 16 #include <linux/indirect_call_wrapper.h> 17 18 #include <net/fib_rules.h> 19 #include <net/inet_dscp.h> 20 #include <net/ipv6.h> 21 #include <net/addrconf.h> 22 #include <net/ip6_route.h> 23 #include <net/netlink.h> 24 25 struct fib6_rule { 26 struct fib_rule common; 27 struct rt6key src; 28 struct rt6key dst; 29 __be32 flowlabel; 30 __be32 flowlabel_mask; 31 dscp_t dscp; 32 dscp_t dscp_mask; 33 u8 dscp_full:1; /* DSCP or TOS selector */ 34 }; 35 36 static bool fib6_rule_matchall(const struct fib_rule *rule) 37 { 38 struct fib6_rule *r = container_of(rule, struct fib6_rule, common); 39 40 if (r->dst.plen || r->src.plen || r->dscp || r->flowlabel_mask) 41 return false; 42 return fib_rule_matchall(rule); 43 } 44 45 bool fib6_rule_default(const struct fib_rule *rule) 46 { 47 if (!fib6_rule_matchall(rule) || rule->action != FR_ACT_TO_TBL || 48 rule->l3mdev) 49 return false; 50 if (rule->table != RT6_TABLE_LOCAL && rule->table != RT6_TABLE_MAIN) 51 return false; 52 return true; 53 } 54 EXPORT_SYMBOL_GPL(fib6_rule_default); 55 56 int fib6_rules_dump(struct net *net, struct notifier_block *nb, 57 struct netlink_ext_ack *extack) 58 { 59 return fib_rules_dump(net, nb, AF_INET6, extack); 60 } 61 62 unsigned int fib6_rules_seq_read(const struct net *net) 63 { 64 return fib_rules_seq_read(net, AF_INET6); 65 } 66 67 /* called with rcu lock held; no reference taken on fib6_info */ 68 int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6, 69 struct fib6_result *res, int flags) 70 { 71 int err; 72 73 if (net->ipv6.fib6_has_custom_rules) { 74 struct fib_lookup_arg arg = { 75 .lookup_ptr = fib6_table_lookup, 76 .lookup_data = &oif, 77 .result = res, 78 .flags = FIB_LOOKUP_NOREF, 79 }; 80 81 l3mdev_update_flow(net, flowi6_to_flowi(fl6)); 82 83 err = fib_rules_lookup(net->ipv6.fib6_rules_ops, 84 flowi6_to_flowi(fl6), flags, &arg); 85 } else { 86 err = fib6_table_lookup(net, net->ipv6.fib6_local_tbl, oif, 87 fl6, res, flags); 88 if (err || res->f6i == net->ipv6.fib6_null_entry) 89 err = fib6_table_lookup(net, net->ipv6.fib6_main_tbl, 90 oif, fl6, res, flags); 91 } 92 93 return err; 94 } 95 #if IS_MODULE(CONFIG_NFT_FIB_IPV6) 96 EXPORT_SYMBOL_GPL(fib6_lookup); 97 #endif 98 99 struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, 100 const struct sk_buff *skb, 101 int flags, pol_lookup_t lookup) 102 { 103 if (net->ipv6.fib6_has_custom_rules) { 104 struct fib6_result res = {}; 105 struct fib_lookup_arg arg = { 106 .lookup_ptr = lookup, 107 .lookup_data = skb, 108 .result = &res, 109 .flags = FIB_LOOKUP_NOREF, 110 }; 111 112 /* update flow if oif or iif point to device enslaved to l3mdev */ 113 l3mdev_update_flow(net, flowi6_to_flowi(fl6)); 114 115 fib_rules_lookup(net->ipv6.fib6_rules_ops, 116 flowi6_to_flowi(fl6), flags, &arg); 117 118 if (res.rt6) 119 return &res.rt6->dst; 120 } else { 121 struct rt6_info *rt; 122 123 rt = pol_lookup_func(lookup, 124 net, net->ipv6.fib6_local_tbl, fl6, skb, flags); 125 if (rt != net->ipv6.ip6_null_entry && rt->dst.error != -EAGAIN) 126 return &rt->dst; 127 ip6_rt_put_flags(rt, flags); 128 rt = pol_lookup_func(lookup, 129 net, net->ipv6.fib6_main_tbl, fl6, skb, flags); 130 if (rt->dst.error != -EAGAIN) 131 return &rt->dst; 132 ip6_rt_put_flags(rt, flags); 133 } 134 135 if (!(flags & RT6_LOOKUP_F_DST_NOREF)) 136 dst_hold(&net->ipv6.ip6_null_entry->dst); 137 return &net->ipv6.ip6_null_entry->dst; 138 } 139 140 static int fib6_rule_saddr(struct net *net, struct fib_rule *rule, int flags, 141 struct flowi6 *flp6, const struct net_device *dev) 142 { 143 struct fib6_rule *r = (struct fib6_rule *)rule; 144 145 /* If we need to find a source address for this traffic, 146 * we check the result if it meets requirement of the rule. 147 */ 148 if ((rule->flags & FIB_RULE_FIND_SADDR) && 149 r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { 150 struct in6_addr saddr; 151 152 if (ipv6_dev_get_saddr(net, dev, &flp6->daddr, 153 rt6_flags2srcprefs(flags), &saddr)) 154 return -EAGAIN; 155 156 if (!ipv6_prefix_equal(&saddr, &r->src.addr, r->src.plen)) 157 return -EAGAIN; 158 159 flp6->saddr = saddr; 160 } 161 162 return 0; 163 } 164 165 static int fib6_rule_action_alt(struct fib_rule *rule, struct flowi *flp, 166 int flags, struct fib_lookup_arg *arg) 167 { 168 struct fib6_result *res = arg->result; 169 struct flowi6 *flp6 = &flp->u.ip6; 170 struct net *net = rule->fr_net; 171 struct fib6_table *table; 172 int err, *oif; 173 u32 tb_id; 174 175 switch (rule->action) { 176 case FR_ACT_TO_TBL: 177 break; 178 case FR_ACT_UNREACHABLE: 179 return -ENETUNREACH; 180 case FR_ACT_PROHIBIT: 181 return -EACCES; 182 case FR_ACT_BLACKHOLE: 183 default: 184 return -EINVAL; 185 } 186 187 tb_id = fib_rule_get_table(rule, arg); 188 table = fib6_get_table(net, tb_id); 189 if (!table) 190 return -EAGAIN; 191 192 oif = (int *)arg->lookup_data; 193 err = fib6_table_lookup(net, table, *oif, flp6, res, flags); 194 if (!err && res->f6i != net->ipv6.fib6_null_entry) 195 err = fib6_rule_saddr(net, rule, flags, flp6, 196 res->nh->fib_nh_dev); 197 else 198 err = -EAGAIN; 199 200 return err; 201 } 202 203 static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp, 204 int flags, struct fib_lookup_arg *arg) 205 { 206 struct fib6_result *res = arg->result; 207 struct flowi6 *flp6 = &flp->u.ip6; 208 struct rt6_info *rt = NULL; 209 struct fib6_table *table; 210 struct net *net = rule->fr_net; 211 pol_lookup_t lookup = arg->lookup_ptr; 212 int err = 0; 213 u32 tb_id; 214 215 switch (rule->action) { 216 case FR_ACT_TO_TBL: 217 break; 218 case FR_ACT_UNREACHABLE: 219 err = -ENETUNREACH; 220 rt = net->ipv6.ip6_null_entry; 221 goto discard_pkt; 222 default: 223 case FR_ACT_BLACKHOLE: 224 err = -EINVAL; 225 rt = net->ipv6.ip6_blk_hole_entry; 226 goto discard_pkt; 227 case FR_ACT_PROHIBIT: 228 err = -EACCES; 229 rt = net->ipv6.ip6_prohibit_entry; 230 goto discard_pkt; 231 } 232 233 tb_id = fib_rule_get_table(rule, arg); 234 table = fib6_get_table(net, tb_id); 235 if (!table) { 236 err = -EAGAIN; 237 goto out; 238 } 239 240 rt = pol_lookup_func(lookup, 241 net, table, flp6, arg->lookup_data, flags); 242 if (rt != net->ipv6.ip6_null_entry) { 243 struct inet6_dev *idev = ip6_dst_idev(&rt->dst); 244 245 if (!idev) 246 goto again; 247 err = fib6_rule_saddr(net, rule, flags, flp6, 248 idev->dev); 249 250 if (err == -EAGAIN) 251 goto again; 252 253 err = rt->dst.error; 254 if (err != -EAGAIN) 255 goto out; 256 } 257 again: 258 ip6_rt_put_flags(rt, flags); 259 err = -EAGAIN; 260 rt = NULL; 261 goto out; 262 263 discard_pkt: 264 if (!(flags & RT6_LOOKUP_F_DST_NOREF)) 265 dst_hold(&rt->dst); 266 out: 267 res->rt6 = rt; 268 return err; 269 } 270 271 INDIRECT_CALLABLE_SCOPE int fib6_rule_action(struct fib_rule *rule, 272 struct flowi *flp, int flags, 273 struct fib_lookup_arg *arg) 274 { 275 if (arg->lookup_ptr == fib6_table_lookup) 276 return fib6_rule_action_alt(rule, flp, flags, arg); 277 278 return __fib6_rule_action(rule, flp, flags, arg); 279 } 280 281 INDIRECT_CALLABLE_SCOPE bool fib6_rule_suppress(struct fib_rule *rule, 282 int flags, 283 struct fib_lookup_arg *arg) 284 { 285 struct fib6_result *res = arg->result; 286 struct rt6_info *rt = res->rt6; 287 struct net_device *dev = NULL; 288 289 if (!rt) 290 return false; 291 292 if (rt->rt6i_idev) 293 dev = rt->rt6i_idev->dev; 294 295 /* do not accept result if the route does 296 * not meet the required prefix length 297 */ 298 if (rt->rt6i_dst.plen <= rule->suppress_prefixlen) 299 goto suppress_route; 300 301 /* do not accept result if the route uses a device 302 * belonging to a forbidden interface group 303 */ 304 if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup) 305 goto suppress_route; 306 307 return false; 308 309 suppress_route: 310 ip6_rt_put_flags(rt, flags); 311 return true; 312 } 313 314 INDIRECT_CALLABLE_SCOPE int fib6_rule_match(struct fib_rule *rule, 315 struct flowi *fl, int flags) 316 { 317 struct fib6_rule *r = (struct fib6_rule *) rule; 318 struct flowi6 *fl6 = &fl->u.ip6; 319 320 if (r->dst.plen && 321 !ipv6_prefix_equal(&fl6->daddr, &r->dst.addr, r->dst.plen)) 322 return 0; 323 324 /* 325 * If FIB_RULE_FIND_SADDR is set and we do not have a 326 * source address for the traffic, we defer check for 327 * source address. 328 */ 329 if (r->src.plen) { 330 if (flags & RT6_LOOKUP_F_HAS_SADDR) { 331 if (!ipv6_prefix_equal(&fl6->saddr, &r->src.addr, 332 r->src.plen)) 333 return 0; 334 } else if (!(r->common.flags & FIB_RULE_FIND_SADDR)) 335 return 0; 336 } 337 338 if ((r->dscp ^ ip6_dscp(fl6->flowlabel)) & r->dscp_mask) 339 return 0; 340 341 if ((r->flowlabel ^ flowi6_get_flowlabel(fl6)) & r->flowlabel_mask) 342 return 0; 343 344 if (rule->ip_proto && (rule->ip_proto != fl6->flowi6_proto)) 345 return 0; 346 347 if (!fib_rule_port_match(&rule->sport_range, rule->sport_mask, 348 fl6->fl6_sport)) 349 return 0; 350 351 if (!fib_rule_port_match(&rule->dport_range, rule->dport_mask, 352 fl6->fl6_dport)) 353 return 0; 354 355 return 1; 356 } 357 358 static int fib6_nl2rule_dscp(const struct nlattr *nla, struct fib6_rule *rule6, 359 struct netlink_ext_ack *extack) 360 { 361 if (rule6->dscp) { 362 NL_SET_ERR_MSG(extack, "Cannot specify both TOS and DSCP"); 363 return -EINVAL; 364 } 365 366 rule6->dscp = inet_dsfield_to_dscp(nla_get_u8(nla) << 2); 367 rule6->dscp_mask = inet_dsfield_to_dscp(INET_DSCP_MASK); 368 rule6->dscp_full = true; 369 370 return 0; 371 } 372 373 static int fib6_nl2rule_dscp_mask(const struct nlattr *nla, 374 struct fib6_rule *rule6, 375 struct netlink_ext_ack *extack) 376 { 377 dscp_t dscp_mask; 378 379 if (!rule6->dscp_full) { 380 NL_SET_ERR_MSG_ATTR(extack, nla, 381 "Cannot specify DSCP mask without DSCP value"); 382 return -EINVAL; 383 } 384 385 dscp_mask = inet_dsfield_to_dscp(nla_get_u8(nla) << 2); 386 if (rule6->dscp & ~dscp_mask) { 387 NL_SET_ERR_MSG_ATTR(extack, nla, "Invalid DSCP mask"); 388 return -EINVAL; 389 } 390 391 rule6->dscp_mask = dscp_mask; 392 393 return 0; 394 } 395 396 static int fib6_nl2rule_flowlabel(struct nlattr **tb, struct fib6_rule *rule6, 397 struct netlink_ext_ack *extack) 398 { 399 __be32 flowlabel, flowlabel_mask; 400 401 if (NL_REQ_ATTR_CHECK(extack, NULL, tb, FRA_FLOWLABEL) || 402 NL_REQ_ATTR_CHECK(extack, NULL, tb, FRA_FLOWLABEL_MASK)) 403 return -EINVAL; 404 405 flowlabel = nla_get_be32(tb[FRA_FLOWLABEL]); 406 flowlabel_mask = nla_get_be32(tb[FRA_FLOWLABEL_MASK]); 407 408 if (flowlabel_mask & ~IPV6_FLOWLABEL_MASK) { 409 NL_SET_ERR_MSG_ATTR(extack, tb[FRA_FLOWLABEL_MASK], 410 "Invalid flow label mask"); 411 return -EINVAL; 412 } 413 414 if (flowlabel & ~flowlabel_mask) { 415 NL_SET_ERR_MSG(extack, "Flow label and mask do not match"); 416 return -EINVAL; 417 } 418 419 rule6->flowlabel = flowlabel; 420 rule6->flowlabel_mask = flowlabel_mask; 421 422 return 0; 423 } 424 425 static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, 426 struct fib_rule_hdr *frh, 427 struct nlattr **tb, 428 struct netlink_ext_ack *extack) 429 { 430 struct fib6_rule *rule6 = (struct fib6_rule *)rule; 431 struct net *net = rule->fr_net; 432 int err = -EINVAL; 433 434 if (!inet_validate_dscp(frh->tos)) { 435 NL_SET_ERR_MSG(extack, 436 "Invalid dsfield (tos): ECN bits must be 0"); 437 goto errout; 438 } 439 rule6->dscp = inet_dsfield_to_dscp(frh->tos); 440 rule6->dscp_mask = frh->tos ? inet_dsfield_to_dscp(INET_DSCP_MASK) : 0; 441 442 if (tb[FRA_DSCP] && fib6_nl2rule_dscp(tb[FRA_DSCP], rule6, extack) < 0) 443 goto errout; 444 445 if (tb[FRA_DSCP_MASK] && 446 fib6_nl2rule_dscp_mask(tb[FRA_DSCP_MASK], rule6, extack) < 0) 447 goto errout; 448 449 if ((tb[FRA_FLOWLABEL] || tb[FRA_FLOWLABEL_MASK]) && 450 fib6_nl2rule_flowlabel(tb, rule6, extack) < 0) 451 goto errout; 452 453 if (rule->action == FR_ACT_TO_TBL && !rule->l3mdev) { 454 if (rule->table == RT6_TABLE_UNSPEC) { 455 NL_SET_ERR_MSG(extack, "Invalid table"); 456 goto errout; 457 } 458 459 if (fib6_new_table(net, rule->table) == NULL) { 460 err = -ENOBUFS; 461 goto errout; 462 } 463 } 464 465 if (frh->src_len) 466 rule6->src.addr = nla_get_in6_addr(tb[FRA_SRC]); 467 468 if (frh->dst_len) 469 rule6->dst.addr = nla_get_in6_addr(tb[FRA_DST]); 470 471 rule6->src.plen = frh->src_len; 472 rule6->dst.plen = frh->dst_len; 473 474 if (fib_rule_requires_fldissect(rule)) 475 net->ipv6.fib6_rules_require_fldissect++; 476 477 net->ipv6.fib6_has_custom_rules = true; 478 err = 0; 479 errout: 480 return err; 481 } 482 483 static int fib6_rule_delete(struct fib_rule *rule) 484 { 485 struct net *net = rule->fr_net; 486 487 if (net->ipv6.fib6_rules_require_fldissect && 488 fib_rule_requires_fldissect(rule)) 489 net->ipv6.fib6_rules_require_fldissect--; 490 491 return 0; 492 } 493 494 static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, 495 struct nlattr **tb) 496 { 497 struct fib6_rule *rule6 = (struct fib6_rule *) rule; 498 499 if (frh->src_len && (rule6->src.plen != frh->src_len)) 500 return 0; 501 502 if (frh->dst_len && (rule6->dst.plen != frh->dst_len)) 503 return 0; 504 505 if (frh->tos && 506 (rule6->dscp_full || 507 inet_dscp_to_dsfield(rule6->dscp) != frh->tos)) 508 return 0; 509 510 if (tb[FRA_DSCP]) { 511 dscp_t dscp; 512 513 dscp = inet_dsfield_to_dscp(nla_get_u8(tb[FRA_DSCP]) << 2); 514 if (!rule6->dscp_full || rule6->dscp != dscp) 515 return 0; 516 } 517 518 if (tb[FRA_DSCP_MASK]) { 519 dscp_t dscp_mask; 520 521 dscp_mask = inet_dsfield_to_dscp(nla_get_u8(tb[FRA_DSCP_MASK]) << 2); 522 if (!rule6->dscp_full || rule6->dscp_mask != dscp_mask) 523 return 0; 524 } 525 526 if (tb[FRA_FLOWLABEL] && 527 nla_get_be32(tb[FRA_FLOWLABEL]) != rule6->flowlabel) 528 return 0; 529 530 if (tb[FRA_FLOWLABEL_MASK] && 531 nla_get_be32(tb[FRA_FLOWLABEL_MASK]) != rule6->flowlabel_mask) 532 return 0; 533 534 if (frh->src_len && 535 nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr))) 536 return 0; 537 538 if (frh->dst_len && 539 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) 540 return 0; 541 542 return 1; 543 } 544 545 static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb, 546 struct fib_rule_hdr *frh) 547 { 548 struct fib6_rule *rule6 = (struct fib6_rule *) rule; 549 550 frh->dst_len = rule6->dst.plen; 551 frh->src_len = rule6->src.plen; 552 553 if (rule6->dscp_full) { 554 frh->tos = 0; 555 if (nla_put_u8(skb, FRA_DSCP, 556 inet_dscp_to_dsfield(rule6->dscp) >> 2) || 557 nla_put_u8(skb, FRA_DSCP_MASK, 558 inet_dscp_to_dsfield(rule6->dscp_mask) >> 2)) 559 goto nla_put_failure; 560 } else { 561 frh->tos = inet_dscp_to_dsfield(rule6->dscp); 562 } 563 564 if (rule6->flowlabel_mask && 565 (nla_put_be32(skb, FRA_FLOWLABEL, rule6->flowlabel) || 566 nla_put_be32(skb, FRA_FLOWLABEL_MASK, rule6->flowlabel_mask))) 567 goto nla_put_failure; 568 569 if ((rule6->dst.plen && 570 nla_put_in6_addr(skb, FRA_DST, &rule6->dst.addr)) || 571 (rule6->src.plen && 572 nla_put_in6_addr(skb, FRA_SRC, &rule6->src.addr))) 573 goto nla_put_failure; 574 return 0; 575 576 nla_put_failure: 577 return -ENOBUFS; 578 } 579 580 static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) 581 { 582 return nla_total_size(16) /* dst */ 583 + nla_total_size(16) /* src */ 584 + nla_total_size(1) /* dscp */ 585 + nla_total_size(1) /* dscp mask */ 586 + nla_total_size(4) /* flowlabel */ 587 + nla_total_size(4); /* flowlabel mask */ 588 } 589 590 static void fib6_rule_flush_cache(struct fib_rules_ops *ops) 591 { 592 rt_genid_bump_ipv6(ops->fro_net); 593 } 594 595 static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = { 596 .family = AF_INET6, 597 .rule_size = sizeof(struct fib6_rule), 598 .addr_size = sizeof(struct in6_addr), 599 .action = fib6_rule_action, 600 .match = fib6_rule_match, 601 .suppress = fib6_rule_suppress, 602 .configure = fib6_rule_configure, 603 .delete = fib6_rule_delete, 604 .compare = fib6_rule_compare, 605 .fill = fib6_rule_fill, 606 .nlmsg_payload = fib6_rule_nlmsg_payload, 607 .flush_cache = fib6_rule_flush_cache, 608 .nlgroup = RTNLGRP_IPV6_RULE, 609 .owner = THIS_MODULE, 610 .fro_net = &init_net, 611 }; 612 613 static int __net_init fib6_rules_net_init(struct net *net) 614 { 615 struct fib_rules_ops *ops; 616 int err; 617 618 ops = fib_rules_register(&fib6_rules_ops_template, net); 619 if (IS_ERR(ops)) 620 return PTR_ERR(ops); 621 622 err = fib_default_rule_add(ops, 0, RT6_TABLE_LOCAL); 623 if (err) 624 goto out_fib6_rules_ops; 625 626 err = fib_default_rule_add(ops, 0x7FFE, RT6_TABLE_MAIN); 627 if (err) 628 goto out_fib6_rules_ops; 629 630 net->ipv6.fib6_rules_ops = ops; 631 net->ipv6.fib6_rules_require_fldissect = 0; 632 out: 633 return err; 634 635 out_fib6_rules_ops: 636 fib_rules_unregister(ops); 637 goto out; 638 } 639 640 static void __net_exit fib6_rules_net_exit_batch(struct list_head *net_list) 641 { 642 struct net *net; 643 644 rtnl_lock(); 645 list_for_each_entry(net, net_list, exit_list) { 646 fib_rules_unregister(net->ipv6.fib6_rules_ops); 647 cond_resched(); 648 } 649 rtnl_unlock(); 650 } 651 652 static struct pernet_operations fib6_rules_net_ops = { 653 .init = fib6_rules_net_init, 654 .exit_batch = fib6_rules_net_exit_batch, 655 }; 656 657 int __init fib6_rules_init(void) 658 { 659 return register_pernet_subsys(&fib6_rules_net_ops); 660 } 661 662 663 void fib6_rules_cleanup(void) 664 { 665 unregister_pernet_subsys(&fib6_rules_net_ops); 666 } 667