Lines Matching refs:rule
50 struct fib_rule *rule; in fib_default_rule_pref() local
55 rule = list_entry(pos->next, struct fib_rule, list); in fib_default_rule_pref()
56 if (rule->pref) in fib_default_rule_pref()
57 return rule->pref - 1; in fib_default_rule_pref()
64 static void notify_rule_change(int event, struct fib_rule *rule,
152 struct fib_rule *rule, *tmp; in fib_rules_cleanup_ops() local
154 list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) { in fib_rules_cleanup_ops()
155 list_del_rcu(&rule->list); in fib_rules_cleanup_ops()
157 ops->delete(rule); in fib_rules_cleanup_ops()
158 fib_rule_put(rule); in fib_rules_cleanup_ops()
175 static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, in fib_rule_match() argument
180 if (rule->iifindex && (rule->iifindex != fl->flowi_iif)) in fib_rule_match()
183 if (rule->oifindex && (rule->oifindex != fl->flowi_oif)) in fib_rule_match()
186 if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) in fib_rule_match()
189 if (rule->tun_id && (rule->tun_id != fl->flowi_tun_key.tun_id)) in fib_rule_match()
192 ret = ops->match(rule, fl, flags); in fib_rule_match()
194 return (rule->flags & FIB_RULE_INVERT) ? !ret : ret; in fib_rule_match()
200 struct fib_rule *rule; in fib_rules_lookup() local
205 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in fib_rules_lookup()
207 if (!fib_rule_match(rule, ops, fl, flags)) in fib_rules_lookup()
210 if (rule->action == FR_ACT_GOTO) { in fib_rules_lookup()
213 target = rcu_dereference(rule->ctarget); in fib_rules_lookup()
217 rule = target; in fib_rules_lookup()
220 } else if (rule->action == FR_ACT_NOP) in fib_rules_lookup()
223 err = ops->action(rule, fl, flags, arg); in fib_rules_lookup()
225 if (!err && ops->suppress && ops->suppress(rule, arg)) in fib_rules_lookup()
230 likely(atomic_inc_not_zero(&rule->refcnt))) { in fib_rules_lookup()
231 arg->rule = rule; in fib_rules_lookup()
273 struct fib_rule *rule, *r, *last = NULL; in fib_nl_newrule() local
294 rule = kzalloc(ops->rule_size, GFP_KERNEL); in fib_nl_newrule()
295 if (rule == NULL) { in fib_nl_newrule()
299 rule->fr_net = net; in fib_nl_newrule()
301 rule->pref = tb[FRA_PRIORITY] ? nla_get_u32(tb[FRA_PRIORITY]) in fib_nl_newrule()
307 rule->iifindex = -1; in fib_nl_newrule()
308 nla_strlcpy(rule->iifname, tb[FRA_IIFNAME], IFNAMSIZ); in fib_nl_newrule()
309 dev = __dev_get_by_name(net, rule->iifname); in fib_nl_newrule()
311 rule->iifindex = dev->ifindex; in fib_nl_newrule()
317 rule->oifindex = -1; in fib_nl_newrule()
318 nla_strlcpy(rule->oifname, tb[FRA_OIFNAME], IFNAMSIZ); in fib_nl_newrule()
319 dev = __dev_get_by_name(net, rule->oifname); in fib_nl_newrule()
321 rule->oifindex = dev->ifindex; in fib_nl_newrule()
325 rule->mark = nla_get_u32(tb[FRA_FWMARK]); in fib_nl_newrule()
326 if (rule->mark) in fib_nl_newrule()
330 rule->mark_mask = 0xFFFFFFFF; in fib_nl_newrule()
334 rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]); in fib_nl_newrule()
337 rule->tun_id = nla_get_be64(tb[FRA_TUN_ID]); in fib_nl_newrule()
339 rule->action = frh->action; in fib_nl_newrule()
340 rule->flags = frh->flags; in fib_nl_newrule()
341 rule->table = frh_get_table(frh, tb); in fib_nl_newrule()
343 rule->suppress_prefixlen = nla_get_u32(tb[FRA_SUPPRESS_PREFIXLEN]); in fib_nl_newrule()
345 rule->suppress_prefixlen = -1; in fib_nl_newrule()
348 rule->suppress_ifgroup = nla_get_u32(tb[FRA_SUPPRESS_IFGROUP]); in fib_nl_newrule()
350 rule->suppress_ifgroup = -1; in fib_nl_newrule()
354 if (rule->action != FR_ACT_GOTO) in fib_nl_newrule()
357 rule->target = nla_get_u32(tb[FRA_GOTO]); in fib_nl_newrule()
359 if (rule->target <= rule->pref) in fib_nl_newrule()
363 if (r->pref == rule->target) { in fib_nl_newrule()
364 RCU_INIT_POINTER(rule->ctarget, r); in fib_nl_newrule()
369 if (rcu_dereference_protected(rule->ctarget, 1) == NULL) in fib_nl_newrule()
371 } else if (rule->action == FR_ACT_GOTO) in fib_nl_newrule()
374 err = ops->configure(rule, skb, frh, tb); in fib_nl_newrule()
379 if (r->pref > rule->pref) in fib_nl_newrule()
384 fib_rule_get(rule); in fib_nl_newrule()
387 list_add_rcu(&rule->list, &last->list); in fib_nl_newrule()
389 list_add_rcu(&rule->list, &ops->rules_list); in fib_nl_newrule()
398 r->target == rule->pref && in fib_nl_newrule()
400 rcu_assign_pointer(r->ctarget, rule); in fib_nl_newrule()
407 if (rule->action == FR_ACT_GOTO) in fib_nl_newrule()
413 if (rule->tun_id) in fib_nl_newrule()
416 notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); in fib_nl_newrule()
422 kfree(rule); in fib_nl_newrule()
433 struct fib_rule *rule, *tmp; in fib_nl_delrule() local
454 list_for_each_entry(rule, &ops->rules_list, list) { in fib_nl_delrule()
455 if (frh->action && (frh->action != rule->action)) in fib_nl_delrule()
459 (frh_get_table(frh, tb) != rule->table)) in fib_nl_delrule()
463 (rule->pref != nla_get_u32(tb[FRA_PRIORITY]))) in fib_nl_delrule()
467 nla_strcmp(tb[FRA_IIFNAME], rule->iifname)) in fib_nl_delrule()
471 nla_strcmp(tb[FRA_OIFNAME], rule->oifname)) in fib_nl_delrule()
475 (rule->mark != nla_get_u32(tb[FRA_FWMARK]))) in fib_nl_delrule()
479 (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK]))) in fib_nl_delrule()
483 (rule->tun_id != nla_get_be64(tb[FRA_TUN_ID]))) in fib_nl_delrule()
486 if (!ops->compare(rule, frh, tb)) in fib_nl_delrule()
489 if (rule->flags & FIB_RULE_PERMANENT) { in fib_nl_delrule()
495 err = ops->delete(rule); in fib_nl_delrule()
500 if (rule->tun_id) in fib_nl_delrule()
503 list_del_rcu(&rule->list); in fib_nl_delrule()
505 if (rule->action == FR_ACT_GOTO) { in fib_nl_delrule()
507 if (rtnl_dereference(rule->ctarget) == NULL) in fib_nl_delrule()
519 if (rtnl_dereference(tmp->ctarget) == rule) { in fib_nl_delrule()
526 notify_rule_change(RTM_DELRULE, rule, ops, nlh, in fib_nl_delrule()
528 fib_rule_put(rule); in fib_nl_delrule()
541 struct fib_rule *rule) in fib_rule_nlmsg_size() argument
555 payload += ops->nlmsg_payload(rule); in fib_rule_nlmsg_size()
560 static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, in fib_nl_fill_rule() argument
573 frh->table = rule->table; in fib_nl_fill_rule()
574 if (nla_put_u32(skb, FRA_TABLE, rule->table)) in fib_nl_fill_rule()
576 if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen)) in fib_nl_fill_rule()
580 frh->action = rule->action; in fib_nl_fill_rule()
581 frh->flags = rule->flags; in fib_nl_fill_rule()
583 if (rule->action == FR_ACT_GOTO && in fib_nl_fill_rule()
584 rcu_access_pointer(rule->ctarget) == NULL) in fib_nl_fill_rule()
587 if (rule->iifname[0]) { in fib_nl_fill_rule()
588 if (nla_put_string(skb, FRA_IIFNAME, rule->iifname)) in fib_nl_fill_rule()
590 if (rule->iifindex == -1) in fib_nl_fill_rule()
594 if (rule->oifname[0]) { in fib_nl_fill_rule()
595 if (nla_put_string(skb, FRA_OIFNAME, rule->oifname)) in fib_nl_fill_rule()
597 if (rule->oifindex == -1) in fib_nl_fill_rule()
601 if ((rule->pref && in fib_nl_fill_rule()
602 nla_put_u32(skb, FRA_PRIORITY, rule->pref)) || in fib_nl_fill_rule()
603 (rule->mark && in fib_nl_fill_rule()
604 nla_put_u32(skb, FRA_FWMARK, rule->mark)) || in fib_nl_fill_rule()
605 ((rule->mark_mask || rule->mark) && in fib_nl_fill_rule()
606 nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) || in fib_nl_fill_rule()
607 (rule->target && in fib_nl_fill_rule()
608 nla_put_u32(skb, FRA_GOTO, rule->target)) || in fib_nl_fill_rule()
609 (rule->tun_id && in fib_nl_fill_rule()
610 nla_put_be64(skb, FRA_TUN_ID, rule->tun_id))) in fib_nl_fill_rule()
613 if (rule->suppress_ifgroup != -1) { in fib_nl_fill_rule()
614 if (nla_put_u32(skb, FRA_SUPPRESS_IFGROUP, rule->suppress_ifgroup)) in fib_nl_fill_rule()
618 if (ops->fill(rule, skb, frh) < 0) in fib_nl_fill_rule()
633 struct fib_rule *rule; in dump_rules() local
637 list_for_each_entry_rcu(rule, &ops->rules_list, list) { in dump_rules()
641 err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid, in dump_rules()
692 static void notify_rule_change(int event, struct fib_rule *rule, in notify_rule_change() argument
701 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); in notify_rule_change()
705 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); in notify_rule_change()
722 struct fib_rule *rule; in attach_rules() local
724 list_for_each_entry(rule, rules, list) { in attach_rules()
725 if (rule->iifindex == -1 && in attach_rules()
726 strcmp(dev->name, rule->iifname) == 0) in attach_rules()
727 rule->iifindex = dev->ifindex; in attach_rules()
728 if (rule->oifindex == -1 && in attach_rules()
729 strcmp(dev->name, rule->oifname) == 0) in attach_rules()
730 rule->oifindex = dev->ifindex; in attach_rules()
736 struct fib_rule *rule; in detach_rules() local
738 list_for_each_entry(rule, rules, list) { in detach_rules()
739 if (rule->iifindex == dev->ifindex) in detach_rules()
740 rule->iifindex = -1; in detach_rules()
741 if (rule->oifindex == dev->ifindex) in detach_rules()
742 rule->oifindex = -1; in detach_rules()