Lines Matching refs:rule
23 bool fib_rule_matchall(const struct fib_rule *rule) in fib_rule_matchall() argument
25 if (rule->iifindex || rule->oifindex || rule->mark || rule->tun_id || in fib_rule_matchall()
26 rule->flags) in fib_rule_matchall()
28 if (rule->suppress_ifgroup != -1 || rule->suppress_prefixlen != -1) in fib_rule_matchall()
30 if (!uid_eq(rule->uid_range.start, fib_kuid_range_unset.start) || in fib_rule_matchall()
31 !uid_eq(rule->uid_range.end, fib_kuid_range_unset.end)) in fib_rule_matchall()
33 if (fib_rule_port_range_set(&rule->sport_range)) in fib_rule_matchall()
35 if (fib_rule_port_range_set(&rule->dport_range)) in fib_rule_matchall()
72 struct fib_rule *rule; in fib_default_rule_pref() local
77 rule = list_entry(pos->next, struct fib_rule, list); in fib_default_rule_pref()
78 if (rule->pref) in fib_default_rule_pref()
79 return rule->pref - 1; in fib_default_rule_pref()
86 static void notify_rule_change(int event, struct fib_rule *rule,
174 struct fib_rule *rule, *tmp; in fib_rules_cleanup_ops() local
176 list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) { in fib_rules_cleanup_ops()
177 list_del_rcu(&rule->list); in fib_rules_cleanup_ops()
179 ops->delete(rule); in fib_rules_cleanup_ops()
180 fib_rule_put(rule); in fib_rules_cleanup_ops()
245 static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, in fib_rule_match() argument
251 if (rule->iifindex && (rule->iifindex != fl->flowi_iif)) in fib_rule_match()
254 if (rule->oifindex && (rule->oifindex != fl->flowi_oif)) in fib_rule_match()
257 if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) in fib_rule_match()
260 if (rule->tun_id && (rule->tun_id != fl->flowi_tun_key.tun_id)) in fib_rule_match()
263 if (rule->l3mdev && !l3mdev_fib_rule_match(rule->fr_net, fl, arg)) in fib_rule_match()
266 if (uid_lt(fl->flowi_uid, rule->uid_range.start) || in fib_rule_match()
267 uid_gt(fl->flowi_uid, rule->uid_range.end)) in fib_rule_match()
270 ret = ops->match(rule, fl, flags); in fib_rule_match()
272 return (rule->flags & FIB_RULE_INVERT) ? !ret : ret; in fib_rule_match()
278 struct fib_rule *rule; in fib_rules_lookup() local
283 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in fib_rules_lookup()
285 if (!fib_rule_match(rule, ops, fl, flags, arg)) in fib_rules_lookup()
288 if (rule->action == FR_ACT_GOTO) { in fib_rules_lookup()
291 target = rcu_dereference(rule->ctarget); in fib_rules_lookup()
295 rule = target; in fib_rules_lookup()
298 } else if (rule->action == FR_ACT_NOP) in fib_rules_lookup()
301 err = ops->action(rule, fl, flags, arg); in fib_rules_lookup()
303 if (!err && ops->suppress && ops->suppress(rule, arg)) in fib_rules_lookup()
308 likely(refcount_inc_not_zero(&rule->refcnt))) { in fib_rules_lookup()
309 arg->rule = rule; in fib_rules_lookup()
326 struct fib_rule *rule, int family) in call_fib_rule_notifier() argument
330 .rule = rule, in call_fib_rule_notifier()
338 struct fib_rule *rule, in call_fib_rule_notifiers() argument
345 .rule = rule, in call_fib_rule_notifiers()
356 struct fib_rule *rule; in fib_rules_dump() local
361 list_for_each_entry_rcu(rule, &ops->rules_list, list) in fib_rules_dump()
362 call_fib_rule_notifier(nb, net, FIB_EVENT_RULE_ADD, rule, in fib_rules_dump()
390 struct fib_rule *rule, in rule_find()
396 if (rule->action && r->action != rule->action) in rule_find()
399 if (rule->table && r->table != rule->table) in rule_find()
402 if (user_priority && r->pref != rule->pref) in rule_find()
405 if (rule->iifname[0] && in rule_find()
406 memcmp(r->iifname, rule->iifname, IFNAMSIZ)) in rule_find()
409 if (rule->oifname[0] && in rule_find()
410 memcmp(r->oifname, rule->oifname, IFNAMSIZ)) in rule_find()
413 if (rule->mark && r->mark != rule->mark) in rule_find()
416 if (rule->suppress_ifgroup != -1 && in rule_find()
417 r->suppress_ifgroup != rule->suppress_ifgroup) in rule_find()
420 if (rule->suppress_prefixlen != -1 && in rule_find()
421 r->suppress_prefixlen != rule->suppress_prefixlen) in rule_find()
424 if (rule->mark_mask && r->mark_mask != rule->mark_mask) in rule_find()
427 if (rule->tun_id && r->tun_id != rule->tun_id) in rule_find()
430 if (r->fr_net != rule->fr_net) in rule_find()
433 if (rule->l3mdev && r->l3mdev != rule->l3mdev) in rule_find()
436 if (uid_range_set(&rule->uid_range) && in rule_find()
437 (!uid_eq(r->uid_range.start, rule->uid_range.start) || in rule_find()
438 !uid_eq(r->uid_range.end, rule->uid_range.end))) in rule_find()
441 if (rule->ip_proto && r->ip_proto != rule->ip_proto) in rule_find()
444 if (rule->proto && r->proto != rule->proto) in rule_find()
447 if (fib_rule_port_range_set(&rule->sport_range) && in rule_find()
449 &rule->sport_range)) in rule_find()
452 if (fib_rule_port_range_set(&rule->dport_range) && in rule_find()
454 &rule->dport_range)) in rule_find()
490 struct fib_rule **rule, in fib_nl2rule() argument
646 *rule = nlrule; in fib_nl2rule()
657 struct nlattr **tb, struct fib_rule *rule) in rule_exists() argument
662 if (r->action != rule->action) in rule_exists()
665 if (r->table != rule->table) in rule_exists()
668 if (r->pref != rule->pref) in rule_exists()
671 if (memcmp(r->iifname, rule->iifname, IFNAMSIZ)) in rule_exists()
674 if (memcmp(r->oifname, rule->oifname, IFNAMSIZ)) in rule_exists()
677 if (r->mark != rule->mark) in rule_exists()
680 if (r->suppress_ifgroup != rule->suppress_ifgroup) in rule_exists()
683 if (r->suppress_prefixlen != rule->suppress_prefixlen) in rule_exists()
686 if (r->mark_mask != rule->mark_mask) in rule_exists()
689 if (r->tun_id != rule->tun_id) in rule_exists()
692 if (r->fr_net != rule->fr_net) in rule_exists()
695 if (r->l3mdev != rule->l3mdev) in rule_exists()
698 if (!uid_eq(r->uid_range.start, rule->uid_range.start) || in rule_exists()
699 !uid_eq(r->uid_range.end, rule->uid_range.end)) in rule_exists()
702 if (r->ip_proto != rule->ip_proto) in rule_exists()
705 if (r->proto != rule->proto) in rule_exists()
709 &rule->sport_range)) in rule_exists()
713 &rule->dport_range)) in rule_exists()
729 struct fib_rule *rule = NULL, *r, *last = NULL; in fib_nl_newrule() local
753 err = fib_nl2rule(skb, nlh, extack, ops, tb, &rule, &user_priority); in fib_nl_newrule()
758 rule_exists(ops, frh, tb, rule)) { in fib_nl_newrule()
763 err = ops->configure(rule, skb, frh, tb, extack); in fib_nl_newrule()
767 err = call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops, in fib_nl_newrule()
773 if (r->pref == rule->target) { in fib_nl_newrule()
774 RCU_INIT_POINTER(rule->ctarget, r); in fib_nl_newrule()
779 if (rcu_dereference_protected(rule->ctarget, 1) == NULL) in fib_nl_newrule()
783 if (r->pref > rule->pref) in fib_nl_newrule()
789 list_add_rcu(&rule->list, &last->list); in fib_nl_newrule()
791 list_add_rcu(&rule->list, &ops->rules_list); in fib_nl_newrule()
800 r->target == rule->pref && in fib_nl_newrule()
802 rcu_assign_pointer(r->ctarget, rule); in fib_nl_newrule()
809 if (rule->action == FR_ACT_GOTO) in fib_nl_newrule()
815 if (rule->tun_id) in fib_nl_newrule()
818 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); in fib_nl_newrule()
824 kfree(rule); in fib_nl_newrule()
837 struct fib_rule *rule = NULL, *r, *nlrule = NULL; in fib_nl_delrule() local
865 rule = rule_find(ops, frh, tb, nlrule, user_priority); in fib_nl_delrule()
866 if (!rule) { in fib_nl_delrule()
871 if (rule->flags & FIB_RULE_PERMANENT) { in fib_nl_delrule()
877 err = ops->delete(rule); in fib_nl_delrule()
882 if (rule->tun_id) in fib_nl_delrule()
885 list_del_rcu(&rule->list); in fib_nl_delrule()
887 if (rule->action == FR_ACT_GOTO) { in fib_nl_delrule()
889 if (rtnl_dereference(rule->ctarget) == NULL) in fib_nl_delrule()
903 n = list_next_entry(rule, list); in fib_nl_delrule()
904 if (&n->list == &ops->rules_list || n->pref != rule->pref) in fib_nl_delrule()
907 if (rtnl_dereference(r->ctarget) != rule) in fib_nl_delrule()
915 call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL, rule, ops, in fib_nl_delrule()
917 notify_rule_change(RTM_DELRULE, rule, ops, nlh, in fib_nl_delrule()
919 fib_rule_put(rule); in fib_nl_delrule()
933 struct fib_rule *rule) in fib_rule_nlmsg_size() argument
952 payload += ops->nlmsg_payload(rule); in fib_rule_nlmsg_size()
957 static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, in fib_nl_fill_rule() argument
970 frh->table = rule->table; in fib_nl_fill_rule()
971 if (nla_put_u32(skb, FRA_TABLE, rule->table)) in fib_nl_fill_rule()
973 if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen)) in fib_nl_fill_rule()
977 frh->action = rule->action; in fib_nl_fill_rule()
978 frh->flags = rule->flags; in fib_nl_fill_rule()
980 if (nla_put_u8(skb, FRA_PROTOCOL, rule->proto)) in fib_nl_fill_rule()
983 if (rule->action == FR_ACT_GOTO && in fib_nl_fill_rule()
984 rcu_access_pointer(rule->ctarget) == NULL) in fib_nl_fill_rule()
987 if (rule->iifname[0]) { in fib_nl_fill_rule()
988 if (nla_put_string(skb, FRA_IIFNAME, rule->iifname)) in fib_nl_fill_rule()
990 if (rule->iifindex == -1) in fib_nl_fill_rule()
994 if (rule->oifname[0]) { in fib_nl_fill_rule()
995 if (nla_put_string(skb, FRA_OIFNAME, rule->oifname)) in fib_nl_fill_rule()
997 if (rule->oifindex == -1) in fib_nl_fill_rule()
1001 if ((rule->pref && in fib_nl_fill_rule()
1002 nla_put_u32(skb, FRA_PRIORITY, rule->pref)) || in fib_nl_fill_rule()
1003 (rule->mark && in fib_nl_fill_rule()
1004 nla_put_u32(skb, FRA_FWMARK, rule->mark)) || in fib_nl_fill_rule()
1005 ((rule->mark_mask || rule->mark) && in fib_nl_fill_rule()
1006 nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) || in fib_nl_fill_rule()
1007 (rule->target && in fib_nl_fill_rule()
1008 nla_put_u32(skb, FRA_GOTO, rule->target)) || in fib_nl_fill_rule()
1009 (rule->tun_id && in fib_nl_fill_rule()
1010 nla_put_be64(skb, FRA_TUN_ID, rule->tun_id, FRA_PAD)) || in fib_nl_fill_rule()
1011 (rule->l3mdev && in fib_nl_fill_rule()
1012 nla_put_u8(skb, FRA_L3MDEV, rule->l3mdev)) || in fib_nl_fill_rule()
1013 (uid_range_set(&rule->uid_range) && in fib_nl_fill_rule()
1014 nla_put_uid_range(skb, &rule->uid_range)) || in fib_nl_fill_rule()
1015 (fib_rule_port_range_set(&rule->sport_range) && in fib_nl_fill_rule()
1016 nla_put_port_range(skb, FRA_SPORT_RANGE, &rule->sport_range)) || in fib_nl_fill_rule()
1017 (fib_rule_port_range_set(&rule->dport_range) && in fib_nl_fill_rule()
1018 nla_put_port_range(skb, FRA_DPORT_RANGE, &rule->dport_range)) || in fib_nl_fill_rule()
1019 (rule->ip_proto && nla_put_u8(skb, FRA_IP_PROTO, rule->ip_proto))) in fib_nl_fill_rule()
1022 if (rule->suppress_ifgroup != -1) { in fib_nl_fill_rule()
1023 if (nla_put_u32(skb, FRA_SUPPRESS_IFGROUP, rule->suppress_ifgroup)) in fib_nl_fill_rule()
1027 if (ops->fill(rule, skb, frh) < 0) in fib_nl_fill_rule()
1042 struct fib_rule *rule; in dump_rules() local
1046 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in dump_rules()
1050 err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid, in dump_rules()
1135 static void notify_rule_change(int event, struct fib_rule *rule, in notify_rule_change() argument
1144 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); in notify_rule_change()
1148 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); in notify_rule_change()
1165 struct fib_rule *rule; in attach_rules() local
1167 list_for_each_entry(rule, rules, list) { in attach_rules()
1168 if (rule->iifindex == -1 && in attach_rules()
1169 strcmp(dev->name, rule->iifname) == 0) in attach_rules()
1170 rule->iifindex = dev->ifindex; in attach_rules()
1171 if (rule->oifindex == -1 && in attach_rules()
1172 strcmp(dev->name, rule->oifname) == 0) in attach_rules()
1173 rule->oifindex = dev->ifindex; in attach_rules()
1179 struct fib_rule *rule; in detach_rules() local
1181 list_for_each_entry(rule, rules, list) { in detach_rules()
1182 if (rule->iifindex == dev->ifindex) in detach_rules()
1183 rule->iifindex = -1; in detach_rules()
1184 if (rule->oifindex == dev->ifindex) in detach_rules()
1185 rule->oifindex = -1; in detach_rules()