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