Lines Matching refs:ops
25 int fib_default_rule_add(struct fib_rules_ops *ops, in fib_default_rule_add() argument
30 r = kzalloc(ops->rule_size, GFP_KERNEL); in fib_default_rule_add()
39 r->fr_net = hold_net(ops->fro_net); in fib_default_rule_add()
47 list_add_tail(&r->list, &ops->rules_list); in fib_default_rule_add()
52 u32 fib_default_rule_pref(struct fib_rules_ops *ops) in fib_default_rule_pref() argument
57 if (!list_empty(&ops->rules_list)) { in fib_default_rule_pref()
58 pos = ops->rules_list.next; in fib_default_rule_pref()
59 if (pos->next != &ops->rules_list) { in fib_default_rule_pref()
71 struct fib_rules_ops *ops, struct nlmsghdr *nlh,
76 struct fib_rules_ops *ops; in lookup_rules_ops() local
79 list_for_each_entry_rcu(ops, &net->rules_ops, list) { in lookup_rules_ops()
80 if (ops->family == family) { in lookup_rules_ops()
81 if (!try_module_get(ops->owner)) in lookup_rules_ops()
82 ops = NULL; in lookup_rules_ops()
84 return ops; in lookup_rules_ops()
92 static void rules_ops_put(struct fib_rules_ops *ops) in rules_ops_put() argument
94 if (ops) in rules_ops_put()
95 module_put(ops->owner); in rules_ops_put()
98 static void flush_route_cache(struct fib_rules_ops *ops) in flush_route_cache() argument
100 if (ops->flush_cache) in flush_route_cache()
101 ops->flush_cache(ops); in flush_route_cache()
104 static int __fib_rules_register(struct fib_rules_ops *ops) in __fib_rules_register() argument
110 net = ops->fro_net; in __fib_rules_register()
112 if (ops->rule_size < sizeof(struct fib_rule)) in __fib_rules_register()
115 if (ops->match == NULL || ops->configure == NULL || in __fib_rules_register()
116 ops->compare == NULL || ops->fill == NULL || in __fib_rules_register()
117 ops->action == NULL) in __fib_rules_register()
122 if (ops->family == o->family) in __fib_rules_register()
126 list_add_tail_rcu(&ops->list, &net->rules_ops); in __fib_rules_register()
137 struct fib_rules_ops *ops; in fib_rules_register() local
140 ops = kmemdup(tmpl, sizeof(*ops), GFP_KERNEL); in fib_rules_register()
141 if (ops == NULL) in fib_rules_register()
144 INIT_LIST_HEAD(&ops->rules_list); in fib_rules_register()
145 ops->fro_net = net; in fib_rules_register()
147 err = __fib_rules_register(ops); in fib_rules_register()
149 kfree(ops); in fib_rules_register()
150 ops = ERR_PTR(err); in fib_rules_register()
153 return ops; in fib_rules_register()
157 static void fib_rules_cleanup_ops(struct fib_rules_ops *ops) in fib_rules_cleanup_ops() argument
161 list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) { in fib_rules_cleanup_ops()
163 if (ops->delete) in fib_rules_cleanup_ops()
164 ops->delete(rule); in fib_rules_cleanup_ops()
171 struct fib_rules_ops *ops = container_of(head, struct fib_rules_ops, rcu); in fib_rules_put_rcu() local
172 struct net *net = ops->fro_net; in fib_rules_put_rcu()
175 kfree(ops); in fib_rules_put_rcu()
178 void fib_rules_unregister(struct fib_rules_ops *ops) in fib_rules_unregister() argument
180 struct net *net = ops->fro_net; in fib_rules_unregister()
183 list_del_rcu(&ops->list); in fib_rules_unregister()
184 fib_rules_cleanup_ops(ops); in fib_rules_unregister()
187 call_rcu(&ops->rcu, fib_rules_put_rcu); in fib_rules_unregister()
219 static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, in fib_rule_match() argument
237 ret = ops->match(rule, fl, flags); in fib_rule_match()
242 int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, in fib_rules_lookup() argument
250 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in fib_rules_lookup()
252 if (!fib_rule_match(rule, ops, fl, flags)) in fib_rules_lookup()
268 err = ops->action(rule, fl, flags, arg); in fib_rules_lookup()
270 if (!err && ops->suppress && ops->suppress(rule, arg)) in fib_rules_lookup()
292 struct fib_rules_ops *ops) in validate_rulemsg() argument
298 frh->src_len > (ops->addr_size * 8) || in validate_rulemsg()
299 nla_len(tb[FRA_SRC]) != ops->addr_size) in validate_rulemsg()
304 frh->dst_len > (ops->addr_size * 8) || in validate_rulemsg()
305 nla_len(tb[FRA_DST]) != ops->addr_size) in validate_rulemsg()
317 struct fib_rules_ops *ops = NULL; in fib_nl_newrule() local
325 ops = lookup_rules_ops(net, frh->family); in fib_nl_newrule()
326 if (ops == NULL) { in fib_nl_newrule()
331 err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy); in fib_nl_newrule()
335 err = validate_rulemsg(frh, tb, ops); in fib_nl_newrule()
339 rule = kzalloc(ops->rule_size, GFP_KERNEL); in fib_nl_newrule()
394 if (!tb[FRA_PRIORITY] && ops->default_pref) in fib_nl_newrule()
395 rule->pref = ops->default_pref(ops); in fib_nl_newrule()
407 list_for_each_entry(r, &ops->rules_list, list) { in fib_nl_newrule()
434 err = ops->configure(rule, skb, frh, tb); in fib_nl_newrule()
438 list_for_each_entry(r, &ops->rules_list, list) { in fib_nl_newrule()
449 list_add_rcu(&rule->list, &ops->rules_list); in fib_nl_newrule()
451 if (ops->unresolved_rules) { in fib_nl_newrule()
456 list_for_each_entry(r, &ops->rules_list, list) { in fib_nl_newrule()
461 if (--ops->unresolved_rules == 0) in fib_nl_newrule()
468 ops->nr_goto_rules++; in fib_nl_newrule()
471 ops->unresolved_rules++; in fib_nl_newrule()
473 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); in fib_nl_newrule()
474 flush_route_cache(ops); in fib_nl_newrule()
475 rules_ops_put(ops); in fib_nl_newrule()
482 rules_ops_put(ops); in fib_nl_newrule()
490 struct fib_rules_ops *ops = NULL; in fib_nl_delrule() local
499 ops = lookup_rules_ops(net, frh->family); in fib_nl_delrule()
500 if (ops == NULL) { in fib_nl_delrule()
505 err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy); in fib_nl_delrule()
509 err = validate_rulemsg(frh, tb, ops); in fib_nl_delrule()
521 list_for_each_entry(rule, &ops->rules_list, list) { in fib_nl_delrule()
554 if (!ops->compare(rule, frh, tb)) in fib_nl_delrule()
565 ops->nr_goto_rules--; in fib_nl_delrule()
567 ops->unresolved_rules--; in fib_nl_delrule()
576 if (ops->nr_goto_rules > 0) { in fib_nl_delrule()
577 list_for_each_entry(tmp, &ops->rules_list, list) { in fib_nl_delrule()
580 ops->unresolved_rules++; in fib_nl_delrule()
585 notify_rule_change(RTM_DELRULE, rule, ops, nlh, in fib_nl_delrule()
587 if (ops->delete) in fib_nl_delrule()
588 ops->delete(rule); in fib_nl_delrule()
590 flush_route_cache(ops); in fib_nl_delrule()
591 rules_ops_put(ops); in fib_nl_delrule()
597 rules_ops_put(ops); in fib_nl_delrule()
601 static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops, in fib_rule_nlmsg_size() argument
615 if (ops->nlmsg_payload) in fib_rule_nlmsg_size()
616 payload += ops->nlmsg_payload(rule); in fib_rule_nlmsg_size()
623 struct fib_rules_ops *ops) in fib_nl_fill_rule() argument
633 frh->family = ops->family; in fib_nl_fill_rule()
679 if (ops->fill(rule, skb, frh) < 0) in fib_nl_fill_rule()
690 struct fib_rules_ops *ops) in dump_rules() argument
697 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in dump_rules()
703 NLM_F_MULTI, ops); in dump_rules()
711 rules_ops_put(ops); in dump_rules()
719 struct fib_rules_ops *ops; in fib_nl_dumprule() local
725 ops = lookup_rules_ops(net, family); in fib_nl_dumprule()
726 if (ops == NULL) in fib_nl_dumprule()
729 dump_rules(skb, cb, ops); in fib_nl_dumprule()
735 list_for_each_entry_rcu(ops, &net->rules_ops, list) { in fib_nl_dumprule()
736 if (idx < cb->args[0] || !try_module_get(ops->owner)) in fib_nl_dumprule()
739 if (dump_rules(skb, cb, ops) < 0) in fib_nl_dumprule()
753 struct fib_rules_ops *ops, struct nlmsghdr *nlh, in notify_rule_change() argument
760 net = ops->fro_net; in notify_rule_change()
761 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); in notify_rule_change()
765 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); in notify_rule_change()
773 rtnl_notify(skb, net, pid, ops->nlgroup, nlh, GFP_KERNEL); in notify_rule_change()
777 rtnl_set_sk_err(net, ops->nlgroup, err); in notify_rule_change()
812 struct fib_rules_ops *ops; in fib_rules_event() local
818 list_for_each_entry(ops, &net->rules_ops, list) in fib_rules_event()
819 attach_rules(&ops->rules_list, dev); in fib_rules_event()
823 list_for_each_entry(ops, &net->rules_ops, list) { in fib_rules_event()
824 detach_rules(&ops->rules_list, dev); in fib_rules_event()
825 attach_rules(&ops->rules_list, dev); in fib_rules_event()
830 list_for_each_entry(ops, &net->rules_ops, list) in fib_rules_event()
831 detach_rules(&ops->rules_list, dev); in fib_rules_event()