1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * net/core/fib_rules.c Generic Routing Rules
4 *
5 * Authors: Thomas Graf <tgraf@suug.ch>
6 */
7
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11 #include <linux/list.h>
12 #include <linux/module.h>
13 #include <net/net_namespace.h>
14 #include <net/inet_dscp.h>
15 #include <net/sock.h>
16 #include <net/fib_rules.h>
17 #include <net/ip_tunnels.h>
18 #include <linux/indirect_call_wrapper.h>
19
20 #if defined(CONFIG_IPV6) && defined(CONFIG_IPV6_MULTIPLE_TABLES)
21 #ifdef CONFIG_IP_MULTIPLE_TABLES
22 #define INDIRECT_CALL_MT(f, f2, f1, ...) \
23 INDIRECT_CALL_INET(f, f2, f1, __VA_ARGS__)
24 #else
25 #define INDIRECT_CALL_MT(f, f2, f1, ...) INDIRECT_CALL_1(f, f2, __VA_ARGS__)
26 #endif
27 #elif defined(CONFIG_IP_MULTIPLE_TABLES)
28 #define INDIRECT_CALL_MT(f, f2, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__)
29 #else
30 #define INDIRECT_CALL_MT(f, f2, f1, ...) f(__VA_ARGS__)
31 #endif
32
33 static const struct fib_kuid_range fib_kuid_range_unset = {
34 KUIDT_INIT(0),
35 KUIDT_INIT(~0),
36 };
37
fib_rule_matchall(const struct fib_rule * rule)38 bool fib_rule_matchall(const struct fib_rule *rule)
39 {
40 if (READ_ONCE(rule->iifindex) || READ_ONCE(rule->oifindex) ||
41 rule->mark || rule->tun_id || rule->flags)
42 return false;
43 if (rule->suppress_ifgroup != -1 || rule->suppress_prefixlen != -1)
44 return false;
45 if (!uid_eq(rule->uid_range.start, fib_kuid_range_unset.start) ||
46 !uid_eq(rule->uid_range.end, fib_kuid_range_unset.end))
47 return false;
48 if (fib_rule_port_range_set(&rule->sport_range))
49 return false;
50 if (fib_rule_port_range_set(&rule->dport_range))
51 return false;
52 return true;
53 }
54
fib_default_rule_add(struct fib_rules_ops * ops,u32 pref,u32 table)55 int fib_default_rule_add(struct fib_rules_ops *ops,
56 u32 pref, u32 table)
57 {
58 struct fib_rule *r;
59
60 r = kzalloc(ops->rule_size, GFP_KERNEL_ACCOUNT);
61 if (r == NULL)
62 return -ENOMEM;
63
64 refcount_set(&r->refcnt, 1);
65 r->action = FR_ACT_TO_TBL;
66 r->pref = pref;
67 r->table = table;
68 r->proto = RTPROT_KERNEL;
69 r->fr_net = ops->fro_net;
70 r->uid_range = fib_kuid_range_unset;
71
72 r->suppress_prefixlen = -1;
73 r->suppress_ifgroup = -1;
74
75 /* The lock is not required here, the list in unreachable
76 * at the moment this function is called */
77 list_add_tail(&r->list, &ops->rules_list);
78 return 0;
79 }
80
fib_default_rule_pref(struct fib_rules_ops * ops)81 static u32 fib_default_rule_pref(struct fib_rules_ops *ops)
82 {
83 struct list_head *pos;
84 struct fib_rule *rule;
85
86 if (!list_empty(&ops->rules_list)) {
87 pos = ops->rules_list.next;
88 if (pos->next != &ops->rules_list) {
89 rule = list_entry(pos->next, struct fib_rule, list);
90 if (rule->pref)
91 return rule->pref - 1;
92 }
93 }
94
95 return 0;
96 }
97
98 static void notify_rule_change(int event, struct fib_rule *rule,
99 struct fib_rules_ops *ops, struct nlmsghdr *nlh,
100 u32 pid);
101
lookup_rules_ops(const struct net * net,int family)102 static struct fib_rules_ops *lookup_rules_ops(const struct net *net,
103 int family)
104 {
105 struct fib_rules_ops *ops;
106
107 rcu_read_lock();
108 list_for_each_entry_rcu(ops, &net->rules_ops, list) {
109 if (ops->family == family) {
110 if (!try_module_get(ops->owner))
111 ops = NULL;
112 rcu_read_unlock();
113 return ops;
114 }
115 }
116 rcu_read_unlock();
117
118 return NULL;
119 }
120
rules_ops_put(struct fib_rules_ops * ops)121 static void rules_ops_put(struct fib_rules_ops *ops)
122 {
123 if (ops)
124 module_put(ops->owner);
125 }
126
flush_route_cache(struct fib_rules_ops * ops)127 static void flush_route_cache(struct fib_rules_ops *ops)
128 {
129 if (ops->flush_cache)
130 ops->flush_cache(ops);
131 }
132
__fib_rules_register(struct fib_rules_ops * ops)133 static int __fib_rules_register(struct fib_rules_ops *ops)
134 {
135 int err = -EEXIST;
136 struct fib_rules_ops *o;
137 struct net *net;
138
139 net = ops->fro_net;
140
141 if (ops->rule_size < sizeof(struct fib_rule))
142 return -EINVAL;
143
144 if (ops->match == NULL || ops->configure == NULL ||
145 ops->compare == NULL || ops->fill == NULL ||
146 ops->action == NULL)
147 return -EINVAL;
148
149 spin_lock(&net->rules_mod_lock);
150 list_for_each_entry(o, &net->rules_ops, list)
151 if (ops->family == o->family)
152 goto errout;
153
154 list_add_tail_rcu(&ops->list, &net->rules_ops);
155 err = 0;
156 errout:
157 spin_unlock(&net->rules_mod_lock);
158
159 return err;
160 }
161
162 struct fib_rules_ops *
fib_rules_register(const struct fib_rules_ops * tmpl,struct net * net)163 fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net)
164 {
165 struct fib_rules_ops *ops;
166 int err;
167
168 ops = kmemdup(tmpl, sizeof(*ops), GFP_KERNEL);
169 if (ops == NULL)
170 return ERR_PTR(-ENOMEM);
171
172 INIT_LIST_HEAD(&ops->rules_list);
173 mutex_init(&ops->lock);
174 ops->fro_net = net;
175
176 err = __fib_rules_register(ops);
177 if (err) {
178 kfree(ops);
179 ops = ERR_PTR(err);
180 }
181
182 return ops;
183 }
184
fib_rules_cleanup_ops(struct fib_rules_ops * ops)185 static void fib_rules_cleanup_ops(struct fib_rules_ops *ops)
186 {
187 struct fib_rule *rule, *tmp;
188
189 list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) {
190 list_del_rcu(&rule->list);
191 if (ops->delete)
192 ops->delete(rule);
193 fib_rule_put(rule);
194 }
195 }
196
fib_rules_unregister(struct fib_rules_ops * ops)197 void fib_rules_unregister(struct fib_rules_ops *ops)
198 {
199 struct net *net = ops->fro_net;
200
201 spin_lock(&net->rules_mod_lock);
202 list_del_rcu(&ops->list);
203 spin_unlock(&net->rules_mod_lock);
204
205 fib_rules_cleanup_ops(ops);
206 mutex_destroy(&ops->lock);
207 kfree_rcu(ops, rcu);
208 }
209
uid_range_set(struct fib_kuid_range * range)210 static int uid_range_set(struct fib_kuid_range *range)
211 {
212 return uid_valid(range->start) && uid_valid(range->end);
213 }
214
nla_get_kuid_range(struct nlattr ** tb)215 static struct fib_kuid_range nla_get_kuid_range(struct nlattr **tb)
216 {
217 struct fib_rule_uid_range *in;
218 struct fib_kuid_range out;
219
220 in = (struct fib_rule_uid_range *)nla_data(tb[FRA_UID_RANGE]);
221
222 out.start = make_kuid(current_user_ns(), in->start);
223 out.end = make_kuid(current_user_ns(), in->end);
224
225 return out;
226 }
227
nla_put_uid_range(struct sk_buff * skb,struct fib_kuid_range * range)228 static int nla_put_uid_range(struct sk_buff *skb, struct fib_kuid_range *range)
229 {
230 struct fib_rule_uid_range out = {
231 from_kuid_munged(current_user_ns(), range->start),
232 from_kuid_munged(current_user_ns(), range->end)
233 };
234
235 return nla_put(skb, FRA_UID_RANGE, sizeof(out), &out);
236 }
237
nla_get_port_range(struct nlattr * pattr,struct fib_rule_port_range * port_range)238 static int nla_get_port_range(struct nlattr *pattr,
239 struct fib_rule_port_range *port_range)
240 {
241 const struct fib_rule_port_range *pr = nla_data(pattr);
242
243 if (!fib_rule_port_range_valid(pr))
244 return -EINVAL;
245
246 port_range->start = pr->start;
247 port_range->end = pr->end;
248
249 return 0;
250 }
251
nla_put_port_range(struct sk_buff * skb,int attrtype,struct fib_rule_port_range * range)252 static int nla_put_port_range(struct sk_buff *skb, int attrtype,
253 struct fib_rule_port_range *range)
254 {
255 return nla_put(skb, attrtype, sizeof(*range), range);
256 }
257
fib_rule_iif_match(const struct fib_rule * rule,int iifindex,const struct flowi * fl)258 static bool fib_rule_iif_match(const struct fib_rule *rule, int iifindex,
259 const struct flowi *fl)
260 {
261 u8 iif_is_l3_master = READ_ONCE(rule->iif_is_l3_master);
262
263 return iif_is_l3_master ? l3mdev_fib_rule_iif_match(fl, iifindex) :
264 fl->flowi_iif == iifindex;
265 }
266
fib_rule_oif_match(const struct fib_rule * rule,int oifindex,const struct flowi * fl)267 static bool fib_rule_oif_match(const struct fib_rule *rule, int oifindex,
268 const struct flowi *fl)
269 {
270 u8 oif_is_l3_master = READ_ONCE(rule->oif_is_l3_master);
271
272 return oif_is_l3_master ? l3mdev_fib_rule_oif_match(fl, oifindex) :
273 fl->flowi_oif == oifindex;
274 }
275
fib_rule_match(struct fib_rule * rule,struct fib_rules_ops * ops,struct flowi * fl,int flags,struct fib_lookup_arg * arg)276 static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
277 struct flowi *fl, int flags,
278 struct fib_lookup_arg *arg)
279 {
280 int iifindex, oifindex, ret = 0;
281
282 iifindex = READ_ONCE(rule->iifindex);
283 if (iifindex && !fib_rule_iif_match(rule, iifindex, fl))
284 goto out;
285
286 oifindex = READ_ONCE(rule->oifindex);
287 if (oifindex && !fib_rule_oif_match(rule, oifindex, fl))
288 goto out;
289
290 if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask)
291 goto out;
292
293 if (rule->tun_id && (rule->tun_id != fl->flowi_tun_key.tun_id))
294 goto out;
295
296 if (rule->l3mdev && !l3mdev_fib_rule_match(rule->fr_net, fl, arg))
297 goto out;
298
299 if (uid_lt(fl->flowi_uid, rule->uid_range.start) ||
300 uid_gt(fl->flowi_uid, rule->uid_range.end))
301 goto out;
302
303 ret = INDIRECT_CALL_MT(ops->match,
304 fib6_rule_match,
305 fib4_rule_match,
306 rule, fl, flags);
307 out:
308 return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
309 }
310
fib_rules_lookup(struct fib_rules_ops * ops,struct flowi * fl,int flags,struct fib_lookup_arg * arg)311 int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
312 int flags, struct fib_lookup_arg *arg)
313 {
314 struct fib_rule *rule;
315 int err;
316
317 rcu_read_lock();
318
319 list_for_each_entry_rcu(rule, &ops->rules_list, list) {
320 jumped:
321 if (!fib_rule_match(rule, ops, fl, flags, arg))
322 continue;
323
324 if (rule->action == FR_ACT_GOTO) {
325 struct fib_rule *target;
326
327 target = rcu_dereference(rule->ctarget);
328 if (target == NULL) {
329 continue;
330 } else {
331 rule = target;
332 goto jumped;
333 }
334 } else if (rule->action == FR_ACT_NOP)
335 continue;
336 else
337 err = INDIRECT_CALL_MT(ops->action,
338 fib6_rule_action,
339 fib4_rule_action,
340 rule, fl, flags, arg);
341
342 if (!err && ops->suppress && INDIRECT_CALL_MT(ops->suppress,
343 fib6_rule_suppress,
344 fib4_rule_suppress,
345 rule, flags, arg))
346 continue;
347
348 if (err != -EAGAIN) {
349 if ((arg->flags & FIB_LOOKUP_NOREF) ||
350 likely(fib_rule_get_safe(rule))) {
351 arg->rule = rule;
352 goto out;
353 }
354 break;
355 }
356 }
357
358 err = -ESRCH;
359 out:
360 rcu_read_unlock();
361
362 return err;
363 }
364
call_fib_rule_notifier(struct notifier_block * nb,enum fib_event_type event_type,struct fib_rule * rule,int family,struct netlink_ext_ack * extack)365 static int call_fib_rule_notifier(struct notifier_block *nb,
366 enum fib_event_type event_type,
367 struct fib_rule *rule, int family,
368 struct netlink_ext_ack *extack)
369 {
370 struct fib_rule_notifier_info info = {
371 .info.family = family,
372 .info.extack = extack,
373 .rule = rule,
374 };
375
376 return call_fib_notifier(nb, event_type, &info.info);
377 }
378
call_fib_rule_notifiers(struct net * net,enum fib_event_type event_type,struct fib_rule * rule,struct fib_rules_ops * ops,struct netlink_ext_ack * extack)379 static int call_fib_rule_notifiers(struct net *net,
380 enum fib_event_type event_type,
381 struct fib_rule *rule,
382 struct fib_rules_ops *ops,
383 struct netlink_ext_ack *extack)
384 {
385 struct fib_rule_notifier_info info = {
386 .info.family = ops->family,
387 .info.extack = extack,
388 .rule = rule,
389 };
390
391 lockdep_assert_held(&ops->lock);
392
393 /* Paired with READ_ONCE() in fib_rules_seq() */
394 WRITE_ONCE(ops->fib_rules_seq, ops->fib_rules_seq + 1);
395 return call_fib_notifiers(net, event_type, &info.info);
396 }
397
398 /* Called with rcu_read_lock() */
fib_rules_dump(struct net * net,struct notifier_block * nb,int family,struct netlink_ext_ack * extack)399 int fib_rules_dump(struct net *net, struct notifier_block *nb, int family,
400 struct netlink_ext_ack *extack)
401 {
402 struct fib_rules_ops *ops;
403 struct fib_rule *rule;
404 int err = 0;
405
406 ops = lookup_rules_ops(net, family);
407 if (!ops)
408 return -EAFNOSUPPORT;
409 list_for_each_entry_rcu(rule, &ops->rules_list, list) {
410 if (!fib_rule_get_safe(rule))
411 continue;
412
413 err = call_fib_rule_notifier(nb, FIB_EVENT_RULE_ADD,
414 rule, family, extack);
415 fib_rule_put(rule);
416 if (err)
417 break;
418 }
419 rules_ops_put(ops);
420
421 return err;
422 }
423
fib_rules_seq_read(const struct net * net,int family)424 unsigned int fib_rules_seq_read(const struct net *net, int family)
425 {
426 unsigned int fib_rules_seq;
427 struct fib_rules_ops *ops;
428
429 ops = lookup_rules_ops(net, family);
430 if (!ops)
431 return 0;
432 /* Paired with WRITE_ONCE() in call_fib_rule_notifiers() */
433 fib_rules_seq = READ_ONCE(ops->fib_rules_seq);
434 rules_ops_put(ops);
435
436 return fib_rules_seq;
437 }
438
rule_find(struct fib_rules_ops * ops,struct fib_rule_hdr * frh,struct nlattr ** tb,struct fib_rule * rule,bool user_priority)439 static struct fib_rule *rule_find(struct fib_rules_ops *ops,
440 struct fib_rule_hdr *frh,
441 struct nlattr **tb,
442 struct fib_rule *rule,
443 bool user_priority)
444 {
445 struct fib_rule *r;
446
447 list_for_each_entry(r, &ops->rules_list, list) {
448 if (rule->action && r->action != rule->action)
449 continue;
450
451 if (rule->table && r->table != rule->table)
452 continue;
453
454 if (user_priority && r->pref != rule->pref)
455 continue;
456
457 if (rule->iifname[0] &&
458 memcmp(r->iifname, rule->iifname, IFNAMSIZ))
459 continue;
460
461 if (rule->oifname[0] &&
462 memcmp(r->oifname, rule->oifname, IFNAMSIZ))
463 continue;
464
465 if (rule->mark && r->mark != rule->mark)
466 continue;
467
468 if (rule->suppress_ifgroup != -1 &&
469 r->suppress_ifgroup != rule->suppress_ifgroup)
470 continue;
471
472 if (rule->suppress_prefixlen != -1 &&
473 r->suppress_prefixlen != rule->suppress_prefixlen)
474 continue;
475
476 if (rule->mark_mask && r->mark_mask != rule->mark_mask)
477 continue;
478
479 if (rule->tun_id && r->tun_id != rule->tun_id)
480 continue;
481
482 if (rule->l3mdev && r->l3mdev != rule->l3mdev)
483 continue;
484
485 if (uid_range_set(&rule->uid_range) &&
486 (!uid_eq(r->uid_range.start, rule->uid_range.start) ||
487 !uid_eq(r->uid_range.end, rule->uid_range.end)))
488 continue;
489
490 if (rule->ip_proto && r->ip_proto != rule->ip_proto)
491 continue;
492
493 if (rule->proto && r->proto != rule->proto)
494 continue;
495
496 if (fib_rule_port_range_set(&rule->sport_range) &&
497 !fib_rule_port_range_compare(&r->sport_range,
498 &rule->sport_range))
499 continue;
500
501 if (rule->sport_mask && r->sport_mask != rule->sport_mask)
502 continue;
503
504 if (fib_rule_port_range_set(&rule->dport_range) &&
505 !fib_rule_port_range_compare(&r->dport_range,
506 &rule->dport_range))
507 continue;
508
509 if (rule->dport_mask && r->dport_mask != rule->dport_mask)
510 continue;
511
512 if (!ops->compare(r, frh, tb))
513 continue;
514 return r;
515 }
516
517 return NULL;
518 }
519
520 #ifdef CONFIG_NET_L3_MASTER_DEV
fib_nl2rule_l3mdev(struct nlattr * nla,struct fib_rule * nlrule,struct netlink_ext_ack * extack)521 static int fib_nl2rule_l3mdev(struct nlattr *nla, struct fib_rule *nlrule,
522 struct netlink_ext_ack *extack)
523 {
524 nlrule->l3mdev = nla_get_u8(nla);
525 if (nlrule->l3mdev != 1) {
526 NL_SET_ERR_MSG(extack, "Invalid l3mdev attribute");
527 return -1;
528 }
529
530 return 0;
531 }
532 #else
fib_nl2rule_l3mdev(struct nlattr * nla,struct fib_rule * nlrule,struct netlink_ext_ack * extack)533 static int fib_nl2rule_l3mdev(struct nlattr *nla, struct fib_rule *nlrule,
534 struct netlink_ext_ack *extack)
535 {
536 NL_SET_ERR_MSG(extack, "l3mdev support is not enabled in kernel");
537 return -1;
538 }
539 #endif
540
fib_nl2rule_port_mask(const struct nlattr * mask_attr,const struct fib_rule_port_range * range,u16 * port_mask,struct netlink_ext_ack * extack)541 static int fib_nl2rule_port_mask(const struct nlattr *mask_attr,
542 const struct fib_rule_port_range *range,
543 u16 *port_mask,
544 struct netlink_ext_ack *extack)
545 {
546 if (!fib_rule_port_range_valid(range)) {
547 NL_SET_ERR_MSG_ATTR(extack, mask_attr,
548 "Cannot specify port mask without port value");
549 return -EINVAL;
550 }
551
552 if (fib_rule_port_is_range(range)) {
553 NL_SET_ERR_MSG_ATTR(extack, mask_attr,
554 "Cannot specify port mask for port range");
555 return -EINVAL;
556 }
557
558 if (range->start & ~nla_get_u16(mask_attr)) {
559 NL_SET_ERR_MSG_ATTR(extack, mask_attr, "Invalid port mask");
560 return -EINVAL;
561 }
562
563 *port_mask = nla_get_u16(mask_attr);
564
565 return 0;
566 }
567
fib_nl2rule(struct net * net,struct nlmsghdr * nlh,struct netlink_ext_ack * extack,struct fib_rules_ops * ops,struct nlattr * tb[],struct fib_rule ** rule,bool * user_priority)568 static int fib_nl2rule(struct net *net, struct nlmsghdr *nlh,
569 struct netlink_ext_ack *extack,
570 struct fib_rules_ops *ops,
571 struct nlattr *tb[],
572 struct fib_rule **rule,
573 bool *user_priority)
574 {
575 struct fib_rule_hdr *frh = nlmsg_data(nlh);
576 struct fib_rule *nlrule = NULL;
577 int err = -EINVAL;
578
579 if (frh->src_len)
580 if (!tb[FRA_SRC] ||
581 frh->src_len > (ops->addr_size * 8) ||
582 nla_len(tb[FRA_SRC]) != ops->addr_size) {
583 NL_SET_ERR_MSG(extack, "Invalid source address");
584 goto errout;
585 }
586
587 if (frh->dst_len)
588 if (!tb[FRA_DST] ||
589 frh->dst_len > (ops->addr_size * 8) ||
590 nla_len(tb[FRA_DST]) != ops->addr_size) {
591 NL_SET_ERR_MSG(extack, "Invalid dst address");
592 goto errout;
593 }
594
595 nlrule = kzalloc(ops->rule_size, GFP_KERNEL_ACCOUNT);
596 if (!nlrule) {
597 err = -ENOMEM;
598 goto errout;
599 }
600 refcount_set(&nlrule->refcnt, 1);
601 nlrule->fr_net = net;
602
603 if (tb[FRA_PRIORITY]) {
604 nlrule->pref = nla_get_u32(tb[FRA_PRIORITY]);
605 *user_priority = true;
606 }
607
608 nlrule->proto = nla_get_u8_default(tb[FRA_PROTOCOL], RTPROT_UNSPEC);
609
610 if (tb[FRA_IIFNAME]) {
611 nlrule->iifindex = -1;
612 nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
613 }
614
615 if (tb[FRA_OIFNAME]) {
616 nlrule->oifindex = -1;
617 nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
618 }
619
620 if (tb[FRA_FWMARK]) {
621 nlrule->mark = nla_get_u32(tb[FRA_FWMARK]);
622 if (nlrule->mark)
623 /* compatibility: if the mark value is non-zero all bits
624 * are compared unless a mask is explicitly specified.
625 */
626 nlrule->mark_mask = 0xFFFFFFFF;
627 }
628
629 if (tb[FRA_FWMASK])
630 nlrule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
631
632 if (tb[FRA_TUN_ID])
633 nlrule->tun_id = nla_get_be64(tb[FRA_TUN_ID]);
634
635 if (tb[FRA_L3MDEV] &&
636 fib_nl2rule_l3mdev(tb[FRA_L3MDEV], nlrule, extack) < 0)
637 goto errout_free;
638
639 nlrule->action = frh->action;
640 nlrule->flags = frh->flags;
641 nlrule->table = frh_get_table(frh, tb);
642 if (tb[FRA_SUPPRESS_PREFIXLEN])
643 nlrule->suppress_prefixlen = nla_get_u32(tb[FRA_SUPPRESS_PREFIXLEN]);
644 else
645 nlrule->suppress_prefixlen = -1;
646
647 if (tb[FRA_SUPPRESS_IFGROUP])
648 nlrule->suppress_ifgroup = nla_get_u32(tb[FRA_SUPPRESS_IFGROUP]);
649 else
650 nlrule->suppress_ifgroup = -1;
651
652 if (tb[FRA_GOTO]) {
653 if (nlrule->action != FR_ACT_GOTO) {
654 NL_SET_ERR_MSG(extack, "Unexpected goto");
655 goto errout_free;
656 }
657
658 nlrule->target = nla_get_u32(tb[FRA_GOTO]);
659 } else if (nlrule->action == FR_ACT_GOTO) {
660 NL_SET_ERR_MSG(extack, "Missing goto target for action goto");
661 goto errout_free;
662 }
663
664 if (nlrule->l3mdev && nlrule->table) {
665 NL_SET_ERR_MSG(extack, "l3mdev and table are mutually exclusive");
666 goto errout_free;
667 }
668
669 if (tb[FRA_UID_RANGE]) {
670 if (current_user_ns() != net->user_ns) {
671 err = -EPERM;
672 NL_SET_ERR_MSG(extack, "No permission to set uid");
673 goto errout_free;
674 }
675
676 nlrule->uid_range = nla_get_kuid_range(tb);
677
678 if (!uid_range_set(&nlrule->uid_range) ||
679 !uid_lte(nlrule->uid_range.start, nlrule->uid_range.end)) {
680 NL_SET_ERR_MSG(extack, "Invalid uid range");
681 goto errout_free;
682 }
683 } else {
684 nlrule->uid_range = fib_kuid_range_unset;
685 }
686
687 if (tb[FRA_IP_PROTO])
688 nlrule->ip_proto = nla_get_u8(tb[FRA_IP_PROTO]);
689
690 if (tb[FRA_SPORT_RANGE]) {
691 err = nla_get_port_range(tb[FRA_SPORT_RANGE],
692 &nlrule->sport_range);
693 if (err) {
694 NL_SET_ERR_MSG(extack, "Invalid sport range");
695 goto errout_free;
696 }
697 if (!fib_rule_port_is_range(&nlrule->sport_range))
698 nlrule->sport_mask = U16_MAX;
699 }
700
701 if (tb[FRA_SPORT_MASK]) {
702 err = fib_nl2rule_port_mask(tb[FRA_SPORT_MASK],
703 &nlrule->sport_range,
704 &nlrule->sport_mask, extack);
705 if (err)
706 goto errout_free;
707 }
708
709 if (tb[FRA_DPORT_RANGE]) {
710 err = nla_get_port_range(tb[FRA_DPORT_RANGE],
711 &nlrule->dport_range);
712 if (err) {
713 NL_SET_ERR_MSG(extack, "Invalid dport range");
714 goto errout_free;
715 }
716 if (!fib_rule_port_is_range(&nlrule->dport_range))
717 nlrule->dport_mask = U16_MAX;
718 }
719
720 if (tb[FRA_DPORT_MASK]) {
721 err = fib_nl2rule_port_mask(tb[FRA_DPORT_MASK],
722 &nlrule->dport_range,
723 &nlrule->dport_mask, extack);
724 if (err)
725 goto errout_free;
726 }
727
728 *rule = nlrule;
729
730 return 0;
731
732 errout_free:
733 kfree(nlrule);
734 errout:
735 return err;
736 }
737
fib_nl2rule_locked(struct fib_rule * nlrule,struct fib_rules_ops * ops,struct nlattr * tb[],struct netlink_ext_ack * extack)738 static int fib_nl2rule_locked(struct fib_rule *nlrule,
739 struct fib_rules_ops *ops,
740 struct nlattr *tb[],
741 struct netlink_ext_ack *extack)
742 {
743 if (!tb[FRA_PRIORITY])
744 nlrule->pref = fib_default_rule_pref(ops);
745
746 /* Backward jumps are prohibited to avoid endless loops */
747 if (tb[FRA_GOTO] && nlrule->target <= nlrule->pref) {
748 NL_SET_ERR_MSG(extack, "Backward goto not supported");
749 return -EINVAL;
750 }
751
752 rcu_read_lock();
753
754 if (tb[FRA_IIFNAME]) {
755 struct net_device *dev;
756
757 dev = dev_get_by_name_rcu(nlrule->fr_net, nlrule->iifname);
758 if (dev) {
759 nlrule->iifindex = READ_ONCE(dev->ifindex);
760 nlrule->iif_is_l3_master = netif_is_l3_master(dev);
761 }
762 }
763
764 if (tb[FRA_OIFNAME]) {
765 struct net_device *dev;
766
767 dev = dev_get_by_name_rcu(nlrule->fr_net, nlrule->oifname);
768 if (dev) {
769 nlrule->oifindex = READ_ONCE(dev->ifindex);
770 nlrule->oif_is_l3_master = netif_is_l3_master(dev);
771 }
772 }
773
774 rcu_read_unlock();
775
776 return 0;
777 }
778
rule_exists(struct fib_rules_ops * ops,struct fib_rule_hdr * frh,struct nlattr ** tb,struct fib_rule * rule)779 static int rule_exists(struct fib_rules_ops *ops, struct fib_rule_hdr *frh,
780 struct nlattr **tb, struct fib_rule *rule)
781 {
782 struct fib_rule *r;
783
784 list_for_each_entry(r, &ops->rules_list, list) {
785 if (r->action != rule->action)
786 continue;
787
788 if (r->table != rule->table)
789 continue;
790
791 if (r->pref != rule->pref)
792 continue;
793
794 if (memcmp(r->iifname, rule->iifname, IFNAMSIZ))
795 continue;
796
797 if (memcmp(r->oifname, rule->oifname, IFNAMSIZ))
798 continue;
799
800 if (r->mark != rule->mark)
801 continue;
802
803 if (r->suppress_ifgroup != rule->suppress_ifgroup)
804 continue;
805
806 if (r->suppress_prefixlen != rule->suppress_prefixlen)
807 continue;
808
809 if (r->mark_mask != rule->mark_mask)
810 continue;
811
812 if (r->tun_id != rule->tun_id)
813 continue;
814
815 if (r->l3mdev != rule->l3mdev)
816 continue;
817
818 if (!uid_eq(r->uid_range.start, rule->uid_range.start) ||
819 !uid_eq(r->uid_range.end, rule->uid_range.end))
820 continue;
821
822 if (r->ip_proto != rule->ip_proto)
823 continue;
824
825 if (r->proto != rule->proto)
826 continue;
827
828 if (!fib_rule_port_range_compare(&r->sport_range,
829 &rule->sport_range))
830 continue;
831
832 if (r->sport_mask != rule->sport_mask)
833 continue;
834
835 if (!fib_rule_port_range_compare(&r->dport_range,
836 &rule->dport_range))
837 continue;
838
839 if (r->dport_mask != rule->dport_mask)
840 continue;
841
842 if (!ops->compare(r, frh, tb))
843 continue;
844 return 1;
845 }
846 return 0;
847 }
848
849 static const struct nla_policy fib_rule_policy[FRA_MAX + 1] = {
850 [FRA_UNSPEC] = { .strict_start_type = FRA_DPORT_RANGE + 1 },
851 [FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
852 [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
853 [FRA_PRIORITY] = { .type = NLA_U32 },
854 [FRA_FWMARK] = { .type = NLA_U32 },
855 [FRA_FLOW] = { .type = NLA_U32 },
856 [FRA_TUN_ID] = { .type = NLA_U64 },
857 [FRA_FWMASK] = { .type = NLA_U32 },
858 [FRA_TABLE] = { .type = NLA_U32 },
859 [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 },
860 [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 },
861 [FRA_GOTO] = { .type = NLA_U32 },
862 [FRA_L3MDEV] = { .type = NLA_U8 },
863 [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) },
864 [FRA_PROTOCOL] = { .type = NLA_U8 },
865 [FRA_IP_PROTO] = { .type = NLA_U8 },
866 [FRA_SPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) },
867 [FRA_DPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) },
868 [FRA_DSCP] = NLA_POLICY_MAX(NLA_U8, INET_DSCP_MASK >> 2),
869 [FRA_FLOWLABEL] = { .type = NLA_BE32 },
870 [FRA_FLOWLABEL_MASK] = { .type = NLA_BE32 },
871 [FRA_SPORT_MASK] = { .type = NLA_U16 },
872 [FRA_DPORT_MASK] = { .type = NLA_U16 },
873 [FRA_DSCP_MASK] = NLA_POLICY_MASK(NLA_U8, INET_DSCP_MASK >> 2),
874 };
875
fib_newrule(struct net * net,struct sk_buff * skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack,bool rtnl_held)876 int fib_newrule(struct net *net, struct sk_buff *skb, struct nlmsghdr *nlh,
877 struct netlink_ext_ack *extack, bool rtnl_held)
878 {
879 struct fib_rule *rule = NULL, *r, *last = NULL;
880 int err = -EINVAL, unresolved = 0;
881 struct fib_rules_ops *ops = NULL;
882 struct nlattr *tb[FRA_MAX + 1];
883 bool user_priority = false;
884 struct fib_rule_hdr *frh;
885 bool unlock_rtnl = false;
886
887 frh = nlmsg_payload(nlh, sizeof(*frh));
888 if (!frh) {
889 NL_SET_ERR_MSG(extack, "Invalid msg length");
890 goto errout;
891 }
892
893 ops = lookup_rules_ops(net, frh->family);
894 if (!ops) {
895 err = -EAFNOSUPPORT;
896 NL_SET_ERR_MSG(extack, "Rule family not supported");
897 goto errout;
898 }
899
900 err = nlmsg_parse_deprecated(nlh, sizeof(*frh), tb, FRA_MAX,
901 fib_rule_policy, extack);
902 if (err < 0) {
903 NL_SET_ERR_MSG(extack, "Error parsing msg");
904 goto errout;
905 }
906
907 err = fib_nl2rule(net, nlh, extack, ops, tb, &rule, &user_priority);
908 if (err)
909 goto errout;
910
911 if (!rtnl_held && ops->need_rtnl && ops->need_rtnl(net)) {
912 unlock_rtnl = true;
913 rtnl_net_lock(net);
914 }
915 mutex_lock(&ops->lock);
916
917 err = fib_nl2rule_locked(rule, ops, tb, extack);
918 if (err)
919 goto errout_free;
920
921 if ((nlh->nlmsg_flags & NLM_F_EXCL) &&
922 rule_exists(ops, frh, tb, rule)) {
923 err = -EEXIST;
924 goto errout_free;
925 }
926
927 err = ops->configure(rule, skb, frh, tb, extack);
928 if (err < 0)
929 goto errout_free;
930
931 err = call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops,
932 extack);
933 if (err < 0)
934 goto errout_free;
935
936 list_for_each_entry(r, &ops->rules_list, list) {
937 if (r->pref == rule->target) {
938 RCU_INIT_POINTER(rule->ctarget, r);
939 break;
940 }
941 }
942
943 if (rcu_dereference_protected(rule->ctarget, 1) == NULL)
944 unresolved = 1;
945
946 list_for_each_entry(r, &ops->rules_list, list) {
947 if (r->pref > rule->pref)
948 break;
949 last = r;
950 }
951
952 if (last)
953 list_add_rcu(&rule->list, &last->list);
954 else
955 list_add_rcu(&rule->list, &ops->rules_list);
956
957 if (ops->unresolved_rules) {
958 /*
959 * There are unresolved goto rules in the list, check if
960 * any of them are pointing to this new rule.
961 */
962 list_for_each_entry(r, &ops->rules_list, list) {
963 if (r->action == FR_ACT_GOTO &&
964 r->target == rule->pref &&
965 !rcu_access_pointer(r->ctarget)) {
966 rcu_assign_pointer(r->ctarget, rule);
967 if (--ops->unresolved_rules == 0)
968 break;
969 }
970 }
971 }
972
973 if (rule->action == FR_ACT_GOTO)
974 ops->nr_goto_rules++;
975
976 if (unresolved)
977 ops->unresolved_rules++;
978
979 if (rule->tun_id)
980 ip_tunnel_need_metadata();
981
982 fib_rule_get(rule);
983
984 mutex_unlock(&ops->lock);
985 if (unlock_rtnl)
986 rtnl_net_unlock(net);
987
988 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid);
989 fib_rule_put(rule);
990 flush_route_cache(ops);
991 rules_ops_put(ops);
992 return 0;
993
994 errout_free:
995 mutex_unlock(&ops->lock);
996 if (unlock_rtnl)
997 rtnl_net_unlock(net);
998 kfree(rule);
999 errout:
1000 rules_ops_put(ops);
1001 return err;
1002 }
1003 EXPORT_SYMBOL_GPL(fib_newrule);
1004
fib_nl_newrule(struct sk_buff * skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack)1005 static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
1006 struct netlink_ext_ack *extack)
1007 {
1008 return fib_newrule(sock_net(skb->sk), skb, nlh, extack, false);
1009 }
1010
fib_delrule(struct net * net,struct sk_buff * skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack,bool rtnl_held)1011 int fib_delrule(struct net *net, struct sk_buff *skb, struct nlmsghdr *nlh,
1012 struct netlink_ext_ack *extack, bool rtnl_held)
1013 {
1014 struct fib_rule *rule = NULL, *nlrule = NULL;
1015 struct fib_rules_ops *ops = NULL;
1016 struct nlattr *tb[FRA_MAX+1];
1017 bool user_priority = false;
1018 struct fib_rule_hdr *frh;
1019 int err = -EINVAL;
1020
1021 frh = nlmsg_payload(nlh, sizeof(*frh));
1022 if (!frh) {
1023 NL_SET_ERR_MSG(extack, "Invalid msg length");
1024 goto errout;
1025 }
1026
1027 ops = lookup_rules_ops(net, frh->family);
1028 if (ops == NULL) {
1029 err = -EAFNOSUPPORT;
1030 NL_SET_ERR_MSG(extack, "Rule family not supported");
1031 goto errout;
1032 }
1033
1034 err = nlmsg_parse_deprecated(nlh, sizeof(*frh), tb, FRA_MAX,
1035 fib_rule_policy, extack);
1036 if (err < 0) {
1037 NL_SET_ERR_MSG(extack, "Error parsing msg");
1038 goto errout;
1039 }
1040
1041 err = fib_nl2rule(net, nlh, extack, ops, tb, &nlrule, &user_priority);
1042 if (err)
1043 goto errout;
1044
1045 mutex_lock(&ops->lock);
1046
1047 err = fib_nl2rule_locked(nlrule, ops, tb, extack);
1048 if (err)
1049 goto errout_free;
1050
1051 rule = rule_find(ops, frh, tb, nlrule, user_priority);
1052 if (!rule) {
1053 err = -ENOENT;
1054 goto errout_free;
1055 }
1056
1057 if (rule->flags & FIB_RULE_PERMANENT) {
1058 err = -EPERM;
1059 goto errout_free;
1060 }
1061
1062 if (ops->delete)
1063 ops->delete(rule);
1064
1065 if (rule->tun_id)
1066 ip_tunnel_unneed_metadata();
1067
1068 list_del_rcu(&rule->list);
1069
1070 if (rule->action == FR_ACT_GOTO) {
1071 ops->nr_goto_rules--;
1072 if (!rcu_access_pointer(rule->ctarget))
1073 ops->unresolved_rules--;
1074 }
1075
1076 /*
1077 * Check if this rule is a target to any of them. If so,
1078 * adjust to the next one with the same preference or
1079 * disable them. As this operation is eventually very
1080 * expensive, it is only performed if goto rules, except
1081 * current if it is goto rule, have actually been added.
1082 */
1083 if (ops->nr_goto_rules > 0) {
1084 struct fib_rule *n, *r;
1085
1086 n = list_next_entry(rule, list);
1087 if (&n->list == &ops->rules_list || n->pref != rule->pref)
1088 n = NULL;
1089 list_for_each_entry(r, &ops->rules_list, list) {
1090 if (rcu_access_pointer(r->ctarget) != rule)
1091 continue;
1092 rcu_assign_pointer(r->ctarget, n);
1093 if (!n)
1094 ops->unresolved_rules++;
1095 }
1096 }
1097
1098 call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL, rule, ops, NULL);
1099
1100 mutex_unlock(&ops->lock);
1101
1102 notify_rule_change(RTM_DELRULE, rule, ops, nlh, NETLINK_CB(skb).portid);
1103 fib_rule_put(rule);
1104 flush_route_cache(ops);
1105 rules_ops_put(ops);
1106 kfree(nlrule);
1107 return 0;
1108
1109 errout_free:
1110 mutex_unlock(&ops->lock);
1111 kfree(nlrule);
1112 errout:
1113 rules_ops_put(ops);
1114 return err;
1115 }
1116 EXPORT_SYMBOL_GPL(fib_delrule);
1117
fib_nl_delrule(struct sk_buff * skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack)1118 static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
1119 struct netlink_ext_ack *extack)
1120 {
1121 return fib_delrule(sock_net(skb->sk), skb, nlh, extack, false);
1122 }
1123
fib_rule_nlmsg_size(struct fib_rules_ops * ops,struct fib_rule * rule)1124 static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
1125 struct fib_rule *rule)
1126 {
1127 size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr))
1128 + nla_total_size(IFNAMSIZ) /* FRA_IIFNAME */
1129 + nla_total_size(IFNAMSIZ) /* FRA_OIFNAME */
1130 + nla_total_size(4) /* FRA_PRIORITY */
1131 + nla_total_size(4) /* FRA_TABLE */
1132 + nla_total_size(4) /* FRA_SUPPRESS_PREFIXLEN */
1133 + nla_total_size(4) /* FRA_SUPPRESS_IFGROUP */
1134 + nla_total_size(4) /* FRA_FWMARK */
1135 + nla_total_size(4) /* FRA_FWMASK */
1136 + nla_total_size_64bit(8) /* FRA_TUN_ID */
1137 + nla_total_size(sizeof(struct fib_kuid_range))
1138 + nla_total_size(1) /* FRA_PROTOCOL */
1139 + nla_total_size(1) /* FRA_IP_PROTO */
1140 + nla_total_size(sizeof(struct fib_rule_port_range)) /* FRA_SPORT_RANGE */
1141 + nla_total_size(sizeof(struct fib_rule_port_range)) /* FRA_DPORT_RANGE */
1142 + nla_total_size(2) /* FRA_SPORT_MASK */
1143 + nla_total_size(2); /* FRA_DPORT_MASK */
1144
1145 if (ops->nlmsg_payload)
1146 payload += ops->nlmsg_payload(rule);
1147
1148 return payload;
1149 }
1150
fib_nl_fill_rule(struct sk_buff * skb,struct fib_rule * rule,u32 pid,u32 seq,int type,int flags,struct fib_rules_ops * ops)1151 static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
1152 u32 pid, u32 seq, int type, int flags,
1153 struct fib_rules_ops *ops)
1154 {
1155 struct nlmsghdr *nlh;
1156 struct fib_rule_hdr *frh;
1157
1158 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags);
1159 if (nlh == NULL)
1160 return -EMSGSIZE;
1161
1162 frh = nlmsg_data(nlh);
1163 frh->family = ops->family;
1164 frh->table = rule->table < 256 ? rule->table : RT_TABLE_COMPAT;
1165 if (nla_put_u32(skb, FRA_TABLE, rule->table))
1166 goto nla_put_failure;
1167 if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen))
1168 goto nla_put_failure;
1169 frh->res1 = 0;
1170 frh->res2 = 0;
1171 frh->action = rule->action;
1172 frh->flags = rule->flags;
1173
1174 if (nla_put_u8(skb, FRA_PROTOCOL, rule->proto))
1175 goto nla_put_failure;
1176
1177 if (rule->action == FR_ACT_GOTO &&
1178 rcu_access_pointer(rule->ctarget) == NULL)
1179 frh->flags |= FIB_RULE_UNRESOLVED;
1180
1181 if (rule->iifname[0]) {
1182 if (nla_put_string(skb, FRA_IIFNAME, rule->iifname))
1183 goto nla_put_failure;
1184 if (READ_ONCE(rule->iifindex) == -1)
1185 frh->flags |= FIB_RULE_IIF_DETACHED;
1186 }
1187
1188 if (rule->oifname[0]) {
1189 if (nla_put_string(skb, FRA_OIFNAME, rule->oifname))
1190 goto nla_put_failure;
1191 if (READ_ONCE(rule->oifindex) == -1)
1192 frh->flags |= FIB_RULE_OIF_DETACHED;
1193 }
1194
1195 if ((rule->pref &&
1196 nla_put_u32(skb, FRA_PRIORITY, rule->pref)) ||
1197 (rule->mark &&
1198 nla_put_u32(skb, FRA_FWMARK, rule->mark)) ||
1199 ((rule->mark_mask || rule->mark) &&
1200 nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) ||
1201 (rule->target &&
1202 nla_put_u32(skb, FRA_GOTO, rule->target)) ||
1203 (rule->tun_id &&
1204 nla_put_be64(skb, FRA_TUN_ID, rule->tun_id, FRA_PAD)) ||
1205 (rule->l3mdev &&
1206 nla_put_u8(skb, FRA_L3MDEV, rule->l3mdev)) ||
1207 (uid_range_set(&rule->uid_range) &&
1208 nla_put_uid_range(skb, &rule->uid_range)) ||
1209 (fib_rule_port_range_set(&rule->sport_range) &&
1210 nla_put_port_range(skb, FRA_SPORT_RANGE, &rule->sport_range)) ||
1211 (rule->sport_mask && nla_put_u16(skb, FRA_SPORT_MASK,
1212 rule->sport_mask)) ||
1213 (fib_rule_port_range_set(&rule->dport_range) &&
1214 nla_put_port_range(skb, FRA_DPORT_RANGE, &rule->dport_range)) ||
1215 (rule->dport_mask && nla_put_u16(skb, FRA_DPORT_MASK,
1216 rule->dport_mask)) ||
1217 (rule->ip_proto && nla_put_u8(skb, FRA_IP_PROTO, rule->ip_proto)))
1218 goto nla_put_failure;
1219
1220 if (rule->suppress_ifgroup != -1) {
1221 if (nla_put_u32(skb, FRA_SUPPRESS_IFGROUP, rule->suppress_ifgroup))
1222 goto nla_put_failure;
1223 }
1224
1225 if (ops->fill(rule, skb, frh) < 0)
1226 goto nla_put_failure;
1227
1228 nlmsg_end(skb, nlh);
1229 return 0;
1230
1231 nla_put_failure:
1232 nlmsg_cancel(skb, nlh);
1233 return -EMSGSIZE;
1234 }
1235
dump_rules(struct sk_buff * skb,struct netlink_callback * cb,struct fib_rules_ops * ops)1236 static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
1237 struct fib_rules_ops *ops)
1238 {
1239 int idx = 0;
1240 struct fib_rule *rule;
1241 int err = 0;
1242
1243 rcu_read_lock();
1244 list_for_each_entry_rcu(rule, &ops->rules_list, list) {
1245 if (idx < cb->args[1])
1246 goto skip;
1247
1248 err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid,
1249 cb->nlh->nlmsg_seq, RTM_NEWRULE,
1250 NLM_F_MULTI, ops);
1251 if (err)
1252 break;
1253 skip:
1254 idx++;
1255 }
1256 rcu_read_unlock();
1257 cb->args[1] = idx;
1258 rules_ops_put(ops);
1259
1260 return err;
1261 }
1262
fib_valid_dumprule_req(const struct nlmsghdr * nlh,struct netlink_ext_ack * extack)1263 static int fib_valid_dumprule_req(const struct nlmsghdr *nlh,
1264 struct netlink_ext_ack *extack)
1265 {
1266 struct fib_rule_hdr *frh;
1267
1268 frh = nlmsg_payload(nlh, sizeof(*frh));
1269 if (!frh) {
1270 NL_SET_ERR_MSG(extack, "Invalid header for fib rule dump request");
1271 return -EINVAL;
1272 }
1273
1274 if (frh->dst_len || frh->src_len || frh->tos || frh->table ||
1275 frh->res1 || frh->res2 || frh->action || frh->flags) {
1276 NL_SET_ERR_MSG(extack,
1277 "Invalid values in header for fib rule dump request");
1278 return -EINVAL;
1279 }
1280
1281 if (nlmsg_attrlen(nlh, sizeof(*frh))) {
1282 NL_SET_ERR_MSG(extack, "Invalid data after header in fib rule dump request");
1283 return -EINVAL;
1284 }
1285
1286 return 0;
1287 }
1288
fib_nl_dumprule(struct sk_buff * skb,struct netlink_callback * cb)1289 static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
1290 {
1291 const struct nlmsghdr *nlh = cb->nlh;
1292 struct net *net = sock_net(skb->sk);
1293 struct fib_rules_ops *ops;
1294 int err, idx = 0, family;
1295
1296 if (cb->strict_check) {
1297 err = fib_valid_dumprule_req(nlh, cb->extack);
1298
1299 if (err < 0)
1300 return err;
1301 }
1302
1303 family = rtnl_msg_family(nlh);
1304 if (family != AF_UNSPEC) {
1305 /* Protocol specific dump request */
1306 ops = lookup_rules_ops(net, family);
1307 if (ops == NULL)
1308 return -EAFNOSUPPORT;
1309
1310 return dump_rules(skb, cb, ops);
1311 }
1312
1313 err = 0;
1314 rcu_read_lock();
1315 list_for_each_entry_rcu(ops, &net->rules_ops, list) {
1316 if (idx < cb->args[0] || !try_module_get(ops->owner))
1317 goto skip;
1318
1319 err = dump_rules(skb, cb, ops);
1320 if (err < 0)
1321 break;
1322
1323 cb->args[1] = 0;
1324 skip:
1325 idx++;
1326 }
1327 rcu_read_unlock();
1328 cb->args[0] = idx;
1329
1330 return err;
1331 }
1332
notify_rule_change(int event,struct fib_rule * rule,struct fib_rules_ops * ops,struct nlmsghdr * nlh,u32 pid)1333 static void notify_rule_change(int event, struct fib_rule *rule,
1334 struct fib_rules_ops *ops, struct nlmsghdr *nlh,
1335 u32 pid)
1336 {
1337 struct net *net;
1338 struct sk_buff *skb;
1339 int err = -ENOMEM;
1340
1341 net = ops->fro_net;
1342 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL);
1343 if (skb == NULL)
1344 goto errout;
1345
1346 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
1347 if (err < 0) {
1348 /* -EMSGSIZE implies BUG in fib_rule_nlmsg_size() */
1349 WARN_ON(err == -EMSGSIZE);
1350 kfree_skb(skb);
1351 goto errout;
1352 }
1353
1354 rtnl_notify(skb, net, pid, ops->nlgroup, nlh, GFP_KERNEL);
1355 return;
1356 errout:
1357 rtnl_set_sk_err(net, ops->nlgroup, err);
1358 }
1359
attach_rules(struct list_head * rules,struct net_device * dev)1360 static void attach_rules(struct list_head *rules, struct net_device *dev)
1361 {
1362 struct fib_rule *rule;
1363
1364 list_for_each_entry(rule, rules, list) {
1365 if (rule->iifindex == -1 &&
1366 strcmp(dev->name, rule->iifname) == 0) {
1367 WRITE_ONCE(rule->iifindex, dev->ifindex);
1368 WRITE_ONCE(rule->iif_is_l3_master,
1369 netif_is_l3_master(dev));
1370 }
1371 if (rule->oifindex == -1 &&
1372 strcmp(dev->name, rule->oifname) == 0) {
1373 WRITE_ONCE(rule->oifindex, dev->ifindex);
1374 WRITE_ONCE(rule->oif_is_l3_master,
1375 netif_is_l3_master(dev));
1376 }
1377 }
1378 }
1379
detach_rules(struct list_head * rules,struct net_device * dev)1380 static void detach_rules(struct list_head *rules, struct net_device *dev)
1381 {
1382 struct fib_rule *rule;
1383
1384 list_for_each_entry(rule, rules, list) {
1385 if (rule->iifindex == dev->ifindex) {
1386 WRITE_ONCE(rule->iifindex, -1);
1387 WRITE_ONCE(rule->iif_is_l3_master, false);
1388 }
1389 if (rule->oifindex == dev->ifindex) {
1390 WRITE_ONCE(rule->oifindex, -1);
1391 WRITE_ONCE(rule->oif_is_l3_master, false);
1392 }
1393 }
1394 }
1395
1396
fib_rules_event(struct notifier_block * this,unsigned long event,void * ptr)1397 static int fib_rules_event(struct notifier_block *this, unsigned long event,
1398 void *ptr)
1399 {
1400 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1401 struct net *net = dev_net(dev);
1402 struct fib_rules_ops *ops;
1403
1404 switch (event) {
1405 case NETDEV_REGISTER:
1406 list_for_each_entry(ops, &net->rules_ops, list) {
1407 mutex_lock(&ops->lock);
1408 attach_rules(&ops->rules_list, dev);
1409 mutex_unlock(&ops->lock);
1410 }
1411 break;
1412
1413 case NETDEV_CHANGENAME:
1414 list_for_each_entry(ops, &net->rules_ops, list) {
1415 mutex_lock(&ops->lock);
1416 detach_rules(&ops->rules_list, dev);
1417 attach_rules(&ops->rules_list, dev);
1418 mutex_unlock(&ops->lock);
1419 }
1420 break;
1421
1422 case NETDEV_UNREGISTER:
1423 list_for_each_entry(ops, &net->rules_ops, list) {
1424 mutex_lock(&ops->lock);
1425 detach_rules(&ops->rules_list, dev);
1426 mutex_unlock(&ops->lock);
1427 }
1428 break;
1429 }
1430
1431 return NOTIFY_DONE;
1432 }
1433
1434 static struct notifier_block fib_rules_notifier = {
1435 .notifier_call = fib_rules_event,
1436 };
1437
fib_rules_net_init(struct net * net)1438 static int __net_init fib_rules_net_init(struct net *net)
1439 {
1440 INIT_LIST_HEAD(&net->rules_ops);
1441 spin_lock_init(&net->rules_mod_lock);
1442 return 0;
1443 }
1444
fib_rules_net_exit(struct net * net)1445 static void __net_exit fib_rules_net_exit(struct net *net)
1446 {
1447 WARN_ON_ONCE(!list_empty(&net->rules_ops));
1448 }
1449
1450 static struct pernet_operations fib_rules_net_ops = {
1451 .init = fib_rules_net_init,
1452 .exit = fib_rules_net_exit,
1453 };
1454
1455 static const struct rtnl_msg_handler fib_rules_rtnl_msg_handlers[] __initconst = {
1456 {.msgtype = RTM_NEWRULE, .doit = fib_nl_newrule,
1457 .flags = RTNL_FLAG_DOIT_PERNET},
1458 {.msgtype = RTM_DELRULE, .doit = fib_nl_delrule,
1459 .flags = RTNL_FLAG_DOIT_PERNET},
1460 {.msgtype = RTM_GETRULE, .dumpit = fib_nl_dumprule,
1461 .flags = RTNL_FLAG_DUMP_UNLOCKED},
1462 };
1463
fib_rules_init(void)1464 static int __init fib_rules_init(void)
1465 {
1466 int err;
1467
1468 rtnl_register_many(fib_rules_rtnl_msg_handlers);
1469
1470 err = register_pernet_subsys(&fib_rules_net_ops);
1471 if (err < 0)
1472 goto fail;
1473
1474 err = register_netdevice_notifier(&fib_rules_notifier);
1475 if (err < 0)
1476 goto fail_unregister;
1477
1478 return 0;
1479
1480 fail_unregister:
1481 unregister_pernet_subsys(&fib_rules_net_ops);
1482 fail:
1483 rtnl_unregister_many(fib_rules_rtnl_msg_handlers);
1484 return err;
1485 }
1486
1487 subsys_initcall(fib_rules_init);
1488