Lines Matching full:rule

38 bool fib_rule_matchall(const struct fib_rule *rule)  in fib_rule_matchall()  argument
40 if (READ_ONCE(rule->iifindex) || READ_ONCE(rule->oifindex) || in fib_rule_matchall()
41 rule->mark || rule->tun_id || rule->flags) in fib_rule_matchall()
43 if (rule->suppress_ifgroup != -1 || rule->suppress_prefixlen != -1) in fib_rule_matchall()
45 if (!uid_eq(rule->uid_range.start, fib_kuid_range_unset.start) || in fib_rule_matchall()
46 !uid_eq(rule->uid_range.end, fib_kuid_range_unset.end)) in fib_rule_matchall()
48 if (fib_rule_port_range_set(&rule->sport_range)) in fib_rule_matchall()
50 if (fib_rule_port_range_set(&rule->dport_range)) in fib_rule_matchall()
86 struct fib_rule *rule; in fib_default_rule_pref() local
91 rule = list_entry(pos->next, struct fib_rule, list); in fib_default_rule_pref()
92 if (rule->pref) in fib_default_rule_pref()
93 return rule->pref - 1; in fib_default_rule_pref()
100 static void notify_rule_change(int event, struct fib_rule *rule,
189 struct fib_rule *rule, *tmp; in fib_rules_cleanup_ops() local
191 list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) { in fib_rules_cleanup_ops()
192 list_del_rcu(&rule->list); in fib_rules_cleanup_ops()
194 ops->delete(rule); in fib_rules_cleanup_ops()
195 fib_rule_put(rule); in fib_rules_cleanup_ops()
260 static bool fib_rule_iif_match(const struct fib_rule *rule, int iifindex, in fib_rule_iif_match() argument
263 u8 iif_is_l3_master = READ_ONCE(rule->iif_is_l3_master); in fib_rule_iif_match()
269 static bool fib_rule_oif_match(const struct fib_rule *rule, int oifindex, in fib_rule_oif_match() argument
272 u8 oif_is_l3_master = READ_ONCE(rule->oif_is_l3_master); in fib_rule_oif_match()
278 static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, in fib_rule_match() argument
284 iifindex = READ_ONCE(rule->iifindex); in fib_rule_match()
285 if (iifindex && !fib_rule_iif_match(rule, iifindex, fl)) in fib_rule_match()
288 oifindex = READ_ONCE(rule->oifindex); in fib_rule_match()
289 if (oifindex && !fib_rule_oif_match(rule, oifindex, fl)) in fib_rule_match()
292 if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) in fib_rule_match()
295 if (rule->tun_id && (rule->tun_id != fl->flowi_tun_key.tun_id)) in fib_rule_match()
298 if (rule->l3mdev && !l3mdev_fib_rule_match(rule->fr_net, fl, arg)) in fib_rule_match()
301 if (uid_lt(fl->flowi_uid, rule->uid_range.start) || in fib_rule_match()
302 uid_gt(fl->flowi_uid, rule->uid_range.end)) in fib_rule_match()
308 rule, fl, flags); in fib_rule_match()
310 return (rule->flags & FIB_RULE_INVERT) ? !ret : ret; in fib_rule_match()
316 struct fib_rule *rule; in fib_rules_lookup() local
321 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in fib_rules_lookup()
323 if (!fib_rule_match(rule, ops, fl, flags, arg)) in fib_rules_lookup()
326 if (rule->action == FR_ACT_GOTO) { in fib_rules_lookup()
329 target = rcu_dereference(rule->ctarget); in fib_rules_lookup()
333 rule = target; in fib_rules_lookup()
336 } else if (rule->action == FR_ACT_NOP) in fib_rules_lookup()
342 rule, fl, flags, arg); in fib_rules_lookup()
347 rule, flags, arg)) in fib_rules_lookup()
352 likely(refcount_inc_not_zero(&rule->refcnt))) { in fib_rules_lookup()
353 arg->rule = rule; in fib_rules_lookup()
370 struct fib_rule *rule, int family, in call_fib_rule_notifier() argument
376 .rule = rule, in call_fib_rule_notifier()
384 struct fib_rule *rule, in call_fib_rule_notifiers() argument
391 .rule = rule, in call_fib_rule_notifiers()
406 struct fib_rule *rule; in fib_rules_dump() local
412 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in fib_rules_dump()
414 rule, family, extack); in fib_rules_dump()
443 struct fib_rule *rule, in rule_find()
449 if (rule->action && r->action != rule->action) in rule_find()
452 if (rule->table && r->table != rule->table) in rule_find()
455 if (user_priority && r->pref != rule->pref) in rule_find()
458 if (rule->iifname[0] && in rule_find()
459 memcmp(r->iifname, rule->iifname, IFNAMSIZ)) in rule_find()
462 if (rule->oifname[0] && in rule_find()
463 memcmp(r->oifname, rule->oifname, IFNAMSIZ)) in rule_find()
466 if (rule->mark && r->mark != rule->mark) in rule_find()
469 if (rule->suppress_ifgroup != -1 && in rule_find()
470 r->suppress_ifgroup != rule->suppress_ifgroup) in rule_find()
473 if (rule->suppress_prefixlen != -1 && in rule_find()
474 r->suppress_prefixlen != rule->suppress_prefixlen) in rule_find()
477 if (rule->mark_mask && r->mark_mask != rule->mark_mask) in rule_find()
480 if (rule->tun_id && r->tun_id != rule->tun_id) in rule_find()
483 if (rule->l3mdev && r->l3mdev != rule->l3mdev) in rule_find()
486 if (uid_range_set(&rule->uid_range) && in rule_find()
487 (!uid_eq(r->uid_range.start, rule->uid_range.start) || in rule_find()
488 !uid_eq(r->uid_range.end, rule->uid_range.end))) in rule_find()
491 if (rule->ip_proto && r->ip_proto != rule->ip_proto) in rule_find()
494 if (rule->proto && r->proto != rule->proto) in rule_find()
497 if (fib_rule_port_range_set(&rule->sport_range) && in rule_find()
499 &rule->sport_range)) in rule_find()
502 if (rule->sport_mask && r->sport_mask != rule->sport_mask) in rule_find()
505 if (fib_rule_port_range_set(&rule->dport_range) && in rule_find()
507 &rule->dport_range)) in rule_find()
510 if (rule->dport_mask && r->dport_mask != rule->dport_mask) in rule_find()
573 struct fib_rule **rule, in fib_nl2rule() argument
729 *rule = nlrule; in fib_nl2rule()
777 struct nlattr **tb, struct fib_rule *rule) in rule_exists() argument
782 if (r->action != rule->action) in rule_exists()
785 if (r->table != rule->table) in rule_exists()
788 if (r->pref != rule->pref) in rule_exists()
791 if (memcmp(r->iifname, rule->iifname, IFNAMSIZ)) in rule_exists()
794 if (memcmp(r->oifname, rule->oifname, IFNAMSIZ)) in rule_exists()
797 if (r->mark != rule->mark) in rule_exists()
800 if (r->suppress_ifgroup != rule->suppress_ifgroup) in rule_exists()
803 if (r->suppress_prefixlen != rule->suppress_prefixlen) in rule_exists()
806 if (r->mark_mask != rule->mark_mask) in rule_exists()
809 if (r->tun_id != rule->tun_id) in rule_exists()
812 if (r->l3mdev != rule->l3mdev) in rule_exists()
815 if (!uid_eq(r->uid_range.start, rule->uid_range.start) || in rule_exists()
816 !uid_eq(r->uid_range.end, rule->uid_range.end)) in rule_exists()
819 if (r->ip_proto != rule->ip_proto) in rule_exists()
822 if (r->proto != rule->proto) in rule_exists()
826 &rule->sport_range)) in rule_exists()
829 if (r->sport_mask != rule->sport_mask) in rule_exists()
833 &rule->dport_range)) in rule_exists()
836 if (r->dport_mask != rule->dport_mask) in rule_exists()
876 struct fib_rule *rule = NULL, *r, *last = NULL; in fib_newrule() local
891 NL_SET_ERR_MSG(extack, "Rule family not supported"); in fib_newrule()
902 err = fib_nl2rule(net, nlh, extack, ops, tb, &rule, &user_priority); in fib_newrule()
909 err = fib_nl2rule_rtnl(rule, ops, tb, extack); in fib_newrule()
914 rule_exists(ops, frh, tb, rule)) { in fib_newrule()
919 err = ops->configure(rule, skb, frh, tb, extack); in fib_newrule()
923 err = call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops, in fib_newrule()
929 if (r->pref == rule->target) { in fib_newrule()
930 RCU_INIT_POINTER(rule->ctarget, r); in fib_newrule()
935 if (rcu_dereference_protected(rule->ctarget, 1) == NULL) in fib_newrule()
939 if (r->pref > rule->pref) in fib_newrule()
945 list_add_rcu(&rule->list, &last->list); in fib_newrule()
947 list_add_rcu(&rule->list, &ops->rules_list); in fib_newrule()
952 * any of them are pointing to this new rule. in fib_newrule()
956 r->target == rule->pref && in fib_newrule()
958 rcu_assign_pointer(r->ctarget, rule); in fib_newrule()
965 if (rule->action == FR_ACT_GOTO) in fib_newrule()
971 if (rule->tun_id) in fib_newrule()
974 fib_rule_get(rule); in fib_newrule()
979 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); in fib_newrule()
980 fib_rule_put(rule); in fib_newrule()
988 kfree(rule); in fib_newrule()
1004 struct fib_rule *rule = NULL, *nlrule = NULL; in fib_delrule() local
1019 NL_SET_ERR_MSG(extack, "Rule family not supported"); in fib_delrule()
1041 rule = rule_find(ops, frh, tb, nlrule, user_priority); in fib_delrule()
1042 if (!rule) { in fib_delrule()
1047 if (rule->flags & FIB_RULE_PERMANENT) { in fib_delrule()
1053 err = ops->delete(rule); in fib_delrule()
1058 if (rule->tun_id) in fib_delrule()
1061 list_del_rcu(&rule->list); in fib_delrule()
1063 if (rule->action == FR_ACT_GOTO) { in fib_delrule()
1065 if (rtnl_dereference(rule->ctarget) == NULL) in fib_delrule()
1070 * Check if this rule is a target to any of them. If so, in fib_delrule()
1074 * current if it is goto rule, have actually been added. in fib_delrule()
1079 n = list_next_entry(rule, list); in fib_delrule()
1080 if (&n->list == &ops->rules_list || n->pref != rule->pref) in fib_delrule()
1083 if (rtnl_dereference(r->ctarget) != rule) in fib_delrule()
1091 call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL, rule, ops, NULL); in fib_delrule()
1096 notify_rule_change(RTM_DELRULE, rule, ops, nlh, NETLINK_CB(skb).portid); in fib_delrule()
1097 fib_rule_put(rule); in fib_delrule()
1120 struct fib_rule *rule) in fib_rule_nlmsg_size() argument
1141 payload += ops->nlmsg_payload(rule); in fib_rule_nlmsg_size()
1146 static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, in fib_nl_fill_rule() argument
1159 frh->table = rule->table < 256 ? rule->table : RT_TABLE_COMPAT; in fib_nl_fill_rule()
1160 if (nla_put_u32(skb, FRA_TABLE, rule->table)) in fib_nl_fill_rule()
1162 if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen)) in fib_nl_fill_rule()
1166 frh->action = rule->action; in fib_nl_fill_rule()
1167 frh->flags = rule->flags; in fib_nl_fill_rule()
1169 if (nla_put_u8(skb, FRA_PROTOCOL, rule->proto)) in fib_nl_fill_rule()
1172 if (rule->action == FR_ACT_GOTO && in fib_nl_fill_rule()
1173 rcu_access_pointer(rule->ctarget) == NULL) in fib_nl_fill_rule()
1176 if (rule->iifname[0]) { in fib_nl_fill_rule()
1177 if (nla_put_string(skb, FRA_IIFNAME, rule->iifname)) in fib_nl_fill_rule()
1179 if (READ_ONCE(rule->iifindex) == -1) in fib_nl_fill_rule()
1183 if (rule->oifname[0]) { in fib_nl_fill_rule()
1184 if (nla_put_string(skb, FRA_OIFNAME, rule->oifname)) in fib_nl_fill_rule()
1186 if (READ_ONCE(rule->oifindex) == -1) in fib_nl_fill_rule()
1190 if ((rule->pref && in fib_nl_fill_rule()
1191 nla_put_u32(skb, FRA_PRIORITY, rule->pref)) || in fib_nl_fill_rule()
1192 (rule->mark && in fib_nl_fill_rule()
1193 nla_put_u32(skb, FRA_FWMARK, rule->mark)) || in fib_nl_fill_rule()
1194 ((rule->mark_mask || rule->mark) && in fib_nl_fill_rule()
1195 nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) || in fib_nl_fill_rule()
1196 (rule->target && in fib_nl_fill_rule()
1197 nla_put_u32(skb, FRA_GOTO, rule->target)) || in fib_nl_fill_rule()
1198 (rule->tun_id && in fib_nl_fill_rule()
1199 nla_put_be64(skb, FRA_TUN_ID, rule->tun_id, FRA_PAD)) || in fib_nl_fill_rule()
1200 (rule->l3mdev && in fib_nl_fill_rule()
1201 nla_put_u8(skb, FRA_L3MDEV, rule->l3mdev)) || in fib_nl_fill_rule()
1202 (uid_range_set(&rule->uid_range) && in fib_nl_fill_rule()
1203 nla_put_uid_range(skb, &rule->uid_range)) || in fib_nl_fill_rule()
1204 (fib_rule_port_range_set(&rule->sport_range) && in fib_nl_fill_rule()
1205 nla_put_port_range(skb, FRA_SPORT_RANGE, &rule->sport_range)) || in fib_nl_fill_rule()
1206 (rule->sport_mask && nla_put_u16(skb, FRA_SPORT_MASK, in fib_nl_fill_rule()
1207 rule->sport_mask)) || in fib_nl_fill_rule()
1208 (fib_rule_port_range_set(&rule->dport_range) && in fib_nl_fill_rule()
1209 nla_put_port_range(skb, FRA_DPORT_RANGE, &rule->dport_range)) || in fib_nl_fill_rule()
1210 (rule->dport_mask && nla_put_u16(skb, FRA_DPORT_MASK, in fib_nl_fill_rule()
1211 rule->dport_mask)) || in fib_nl_fill_rule()
1212 (rule->ip_proto && nla_put_u8(skb, FRA_IP_PROTO, rule->ip_proto))) in fib_nl_fill_rule()
1215 if (rule->suppress_ifgroup != -1) { in fib_nl_fill_rule()
1216 if (nla_put_u32(skb, FRA_SUPPRESS_IFGROUP, rule->suppress_ifgroup)) in fib_nl_fill_rule()
1220 if (ops->fill(rule, skb, frh) < 0) in fib_nl_fill_rule()
1235 struct fib_rule *rule; in dump_rules() local
1239 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in dump_rules()
1243 err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid, in dump_rules()
1264 NL_SET_ERR_MSG(extack, "Invalid header for fib rule dump request"); in fib_valid_dumprule_req()
1272 "Invalid values in header for fib rule dump request"); in fib_valid_dumprule_req()
1277 NL_SET_ERR_MSG(extack, "Invalid data after header in fib rule dump request"); in fib_valid_dumprule_req()
1328 static void notify_rule_change(int event, struct fib_rule *rule, in notify_rule_change() argument
1337 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); in notify_rule_change()
1341 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); in notify_rule_change()
1357 struct fib_rule *rule; in attach_rules() local
1359 list_for_each_entry(rule, rules, list) { in attach_rules()
1360 if (rule->iifindex == -1 && in attach_rules()
1361 strcmp(dev->name, rule->iifname) == 0) { in attach_rules()
1362 WRITE_ONCE(rule->iifindex, dev->ifindex); in attach_rules()
1363 WRITE_ONCE(rule->iif_is_l3_master, in attach_rules()
1366 if (rule->oifindex == -1 && in attach_rules()
1367 strcmp(dev->name, rule->oifname) == 0) { in attach_rules()
1368 WRITE_ONCE(rule->oifindex, dev->ifindex); in attach_rules()
1369 WRITE_ONCE(rule->oif_is_l3_master, in attach_rules()
1377 struct fib_rule *rule; in detach_rules() local
1379 list_for_each_entry(rule, rules, list) { in detach_rules()
1380 if (rule->iifindex == dev->ifindex) { in detach_rules()
1381 WRITE_ONCE(rule->iifindex, -1); in detach_rules()
1382 WRITE_ONCE(rule->iif_is_l3_master, false); in detach_rules()
1384 if (rule->oifindex == dev->ifindex) { in detach_rules()
1385 WRITE_ONCE(rule->oifindex, -1); in detach_rules()
1386 WRITE_ONCE(rule->oif_is_l3_master, false); in detach_rules()