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