Lines Matching refs:ops
44 int fib_default_rule_add(struct fib_rules_ops *ops, in fib_default_rule_add() argument
49 r = kzalloc(ops->rule_size, GFP_KERNEL); in fib_default_rule_add()
59 r->fr_net = ops->fro_net; in fib_default_rule_add()
67 list_add_tail(&r->list, &ops->rules_list); in fib_default_rule_add()
72 static u32 fib_default_rule_pref(struct fib_rules_ops *ops) in fib_default_rule_pref() argument
77 if (!list_empty(&ops->rules_list)) { in fib_default_rule_pref()
78 pos = ops->rules_list.next; in fib_default_rule_pref()
79 if (pos->next != &ops->rules_list) { in fib_default_rule_pref()
90 struct fib_rules_ops *ops, struct nlmsghdr *nlh,
95 struct fib_rules_ops *ops; in lookup_rules_ops() local
98 list_for_each_entry_rcu(ops, &net->rules_ops, list) { in lookup_rules_ops()
99 if (ops->family == family) { in lookup_rules_ops()
100 if (!try_module_get(ops->owner)) in lookup_rules_ops()
101 ops = NULL; in lookup_rules_ops()
103 return ops; in lookup_rules_ops()
111 static void rules_ops_put(struct fib_rules_ops *ops) in rules_ops_put() argument
113 if (ops) in rules_ops_put()
114 module_put(ops->owner); in rules_ops_put()
117 static void flush_route_cache(struct fib_rules_ops *ops) in flush_route_cache() argument
119 if (ops->flush_cache) in flush_route_cache()
120 ops->flush_cache(ops); in flush_route_cache()
123 static int __fib_rules_register(struct fib_rules_ops *ops) in __fib_rules_register() argument
129 net = ops->fro_net; in __fib_rules_register()
131 if (ops->rule_size < sizeof(struct fib_rule)) in __fib_rules_register()
134 if (ops->match == NULL || ops->configure == NULL || in __fib_rules_register()
135 ops->compare == NULL || ops->fill == NULL || in __fib_rules_register()
136 ops->action == NULL) in __fib_rules_register()
141 if (ops->family == o->family) in __fib_rules_register()
144 list_add_tail_rcu(&ops->list, &net->rules_ops); in __fib_rules_register()
155 struct fib_rules_ops *ops; in fib_rules_register() local
158 ops = kmemdup(tmpl, sizeof(*ops), GFP_KERNEL); in fib_rules_register()
159 if (ops == NULL) in fib_rules_register()
162 INIT_LIST_HEAD(&ops->rules_list); in fib_rules_register()
163 ops->fro_net = net; in fib_rules_register()
165 err = __fib_rules_register(ops); in fib_rules_register()
167 kfree(ops); in fib_rules_register()
168 ops = ERR_PTR(err); in fib_rules_register()
171 return ops; in fib_rules_register()
175 static void fib_rules_cleanup_ops(struct fib_rules_ops *ops) in fib_rules_cleanup_ops() argument
179 list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) { in fib_rules_cleanup_ops()
181 if (ops->delete) in fib_rules_cleanup_ops()
182 ops->delete(rule); in fib_rules_cleanup_ops()
187 void fib_rules_unregister(struct fib_rules_ops *ops) in fib_rules_unregister() argument
189 struct net *net = ops->fro_net; in fib_rules_unregister()
192 list_del_rcu(&ops->list); in fib_rules_unregister()
195 fib_rules_cleanup_ops(ops); in fib_rules_unregister()
196 kfree_rcu(ops, rcu); in fib_rules_unregister()
248 static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, in fib_rule_match() argument
273 ret = ops->match(rule, fl, flags); in fib_rule_match()
278 int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, in fib_rules_lookup() argument
286 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in fib_rules_lookup()
288 if (!fib_rule_match(rule, ops, fl, flags, arg)) in fib_rules_lookup()
304 err = ops->action(rule, fl, flags, arg); in fib_rules_lookup()
306 if (!err && ops->suppress && ops->suppress(rule, arg)) in fib_rules_lookup()
342 struct fib_rules_ops *ops, in call_fib_rule_notifiers() argument
346 .info.family = ops->family, in call_fib_rule_notifiers()
351 ops->fib_rules_seq++; in call_fib_rule_notifiers()
358 struct fib_rules_ops *ops; in fib_rules_dump() local
361 ops = lookup_rules_ops(net, family); in fib_rules_dump()
362 if (!ops) in fib_rules_dump()
364 list_for_each_entry_rcu(rule, &ops->rules_list, list) in fib_rules_dump()
367 rules_ops_put(ops); in fib_rules_dump()
376 struct fib_rules_ops *ops; in fib_rules_seq_read() local
380 ops = lookup_rules_ops(net, family); in fib_rules_seq_read()
381 if (!ops) in fib_rules_seq_read()
383 fib_rules_seq = ops->fib_rules_seq; in fib_rules_seq_read()
384 rules_ops_put(ops); in fib_rules_seq_read()
390 static struct fib_rule *rule_find(struct fib_rules_ops *ops, in rule_find() argument
398 list_for_each_entry(r, &ops->rules_list, list) { in rule_find()
460 if (!ops->compare(r, frh, tb)) in rule_find()
491 struct fib_rules_ops *ops, in fib_nl2rule() argument
503 frh->src_len > (ops->addr_size * 8) || in fib_nl2rule()
504 nla_len(tb[FRA_SRC]) != ops->addr_size) { in fib_nl2rule()
511 frh->dst_len > (ops->addr_size * 8) || in fib_nl2rule()
512 nla_len(tb[FRA_DST]) != ops->addr_size) { in fib_nl2rule()
517 nlrule = kzalloc(ops->rule_size, GFP_KERNEL); in fib_nl2rule()
529 nlrule->pref = fib_default_rule_pref(ops); in fib_nl2rule()
659 static int rule_exists(struct fib_rules_ops *ops, struct fib_rule_hdr *frh, in rule_exists() argument
664 list_for_each_entry(r, &ops->rules_list, list) { in rule_exists()
719 if (!ops->compare(r, frh, tb)) in rule_exists()
731 struct fib_rules_ops *ops = NULL; in fib_nl_newrule() local
742 ops = lookup_rules_ops(net, frh->family); in fib_nl_newrule()
743 if (!ops) { in fib_nl_newrule()
749 err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, extack); in fib_nl_newrule()
755 err = fib_nl2rule(skb, nlh, extack, ops, tb, &rule, &user_priority); in fib_nl_newrule()
760 rule_exists(ops, frh, tb, rule)) { in fib_nl_newrule()
765 err = ops->configure(rule, skb, frh, tb, extack); in fib_nl_newrule()
769 err = call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops, in fib_nl_newrule()
774 list_for_each_entry(r, &ops->rules_list, list) { in fib_nl_newrule()
784 list_for_each_entry(r, &ops->rules_list, list) { in fib_nl_newrule()
793 list_add_rcu(&rule->list, &ops->rules_list); in fib_nl_newrule()
795 if (ops->unresolved_rules) { in fib_nl_newrule()
800 list_for_each_entry(r, &ops->rules_list, list) { in fib_nl_newrule()
805 if (--ops->unresolved_rules == 0) in fib_nl_newrule()
812 ops->nr_goto_rules++; in fib_nl_newrule()
815 ops->unresolved_rules++; in fib_nl_newrule()
820 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); in fib_nl_newrule()
821 flush_route_cache(ops); in fib_nl_newrule()
822 rules_ops_put(ops); in fib_nl_newrule()
828 rules_ops_put(ops); in fib_nl_newrule()
838 struct fib_rules_ops *ops = NULL; in fib_nl_delrule() local
849 ops = lookup_rules_ops(net, frh->family); in fib_nl_delrule()
850 if (ops == NULL) { in fib_nl_delrule()
856 err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, extack); in fib_nl_delrule()
862 err = fib_nl2rule(skb, nlh, extack, ops, tb, &nlrule, &user_priority); in fib_nl_delrule()
866 rule = rule_find(ops, frh, tb, nlrule, user_priority); in fib_nl_delrule()
877 if (ops->delete) { in fib_nl_delrule()
878 err = ops->delete(rule); in fib_nl_delrule()
889 ops->nr_goto_rules--; in fib_nl_delrule()
891 ops->unresolved_rules--; in fib_nl_delrule()
901 if (ops->nr_goto_rules > 0) { in fib_nl_delrule()
905 if (&n->list == &ops->rules_list || n->pref != rule->pref) in fib_nl_delrule()
907 list_for_each_entry(r, &ops->rules_list, list) { in fib_nl_delrule()
912 ops->unresolved_rules++; in fib_nl_delrule()
916 call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL, rule, ops, in fib_nl_delrule()
918 notify_rule_change(RTM_DELRULE, rule, ops, nlh, in fib_nl_delrule()
921 flush_route_cache(ops); in fib_nl_delrule()
922 rules_ops_put(ops); in fib_nl_delrule()
928 rules_ops_put(ops); in fib_nl_delrule()
933 static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops, in fib_rule_nlmsg_size() argument
952 if (ops->nlmsg_payload) in fib_rule_nlmsg_size()
953 payload += ops->nlmsg_payload(rule); in fib_rule_nlmsg_size()
960 struct fib_rules_ops *ops) in fib_nl_fill_rule() argument
970 frh->family = ops->family; in fib_nl_fill_rule()
1028 if (ops->fill(rule, skb, frh) < 0) in fib_nl_fill_rule()
1040 struct fib_rules_ops *ops) in dump_rules() argument
1047 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in dump_rules()
1053 NLM_F_MULTI, ops); in dump_rules()
1061 rules_ops_put(ops); in dump_rules()
1069 struct fib_rules_ops *ops; in fib_nl_dumprule() local
1075 ops = lookup_rules_ops(net, family); in fib_nl_dumprule()
1076 if (ops == NULL) in fib_nl_dumprule()
1079 dump_rules(skb, cb, ops); in fib_nl_dumprule()
1085 list_for_each_entry_rcu(ops, &net->rules_ops, list) { in fib_nl_dumprule()
1086 if (idx < cb->args[0] || !try_module_get(ops->owner)) in fib_nl_dumprule()
1089 if (dump_rules(skb, cb, ops) < 0) in fib_nl_dumprule()
1103 struct fib_rules_ops *ops, struct nlmsghdr *nlh, in notify_rule_change() argument
1110 net = ops->fro_net; in notify_rule_change()
1111 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); in notify_rule_change()
1115 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); in notify_rule_change()
1123 rtnl_notify(skb, net, pid, ops->nlgroup, nlh, GFP_KERNEL); in notify_rule_change()
1127 rtnl_set_sk_err(net, ops->nlgroup, err); in notify_rule_change()
1162 struct fib_rules_ops *ops; in fib_rules_event() local
1168 list_for_each_entry(ops, &net->rules_ops, list) in fib_rules_event()
1169 attach_rules(&ops->rules_list, dev); in fib_rules_event()
1173 list_for_each_entry(ops, &net->rules_ops, list) { in fib_rules_event()
1174 detach_rules(&ops->rules_list, dev); in fib_rules_event()
1175 attach_rules(&ops->rules_list, dev); in fib_rules_event()
1180 list_for_each_entry(ops, &net->rules_ops, list) in fib_rules_event()
1181 detach_rules(&ops->rules_list, dev); in fib_rules_event()