73417f617a
The results of FIB rules lookups are cached in the routing cache except for IPv6 as no such cache exists. So far, it was the responsibility of the user to flush the cache after modifying any rules. This lead to many false bug reports due to misunderstanding of this concept. This patch automatically flushes the route cache after inserting or deleting a rule. Thanks to Muli Ben-Yehuda <muli@il.ibm.com> for catching a bug in the previous patch. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
110 lines
2.5 KiB
C
110 lines
2.5 KiB
C
#ifndef __NET_FIB_RULES_H
|
|
#define __NET_FIB_RULES_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/fib_rules.h>
|
|
#include <net/flow.h>
|
|
#include <net/rtnetlink.h>
|
|
|
|
struct fib_rule
|
|
{
|
|
struct list_head list;
|
|
atomic_t refcnt;
|
|
int ifindex;
|
|
char ifname[IFNAMSIZ];
|
|
u32 mark;
|
|
u32 mark_mask;
|
|
u32 pref;
|
|
u32 flags;
|
|
u32 table;
|
|
u8 action;
|
|
u32 target;
|
|
struct fib_rule * ctarget;
|
|
struct rcu_head rcu;
|
|
};
|
|
|
|
struct fib_lookup_arg
|
|
{
|
|
void *lookup_ptr;
|
|
void *result;
|
|
struct fib_rule *rule;
|
|
};
|
|
|
|
struct fib_rules_ops
|
|
{
|
|
int family;
|
|
struct list_head list;
|
|
int rule_size;
|
|
int addr_size;
|
|
int unresolved_rules;
|
|
int nr_goto_rules;
|
|
|
|
int (*action)(struct fib_rule *,
|
|
struct flowi *, int,
|
|
struct fib_lookup_arg *);
|
|
int (*match)(struct fib_rule *,
|
|
struct flowi *, int);
|
|
int (*configure)(struct fib_rule *,
|
|
struct sk_buff *,
|
|
struct nlmsghdr *,
|
|
struct fib_rule_hdr *,
|
|
struct nlattr **);
|
|
int (*compare)(struct fib_rule *,
|
|
struct fib_rule_hdr *,
|
|
struct nlattr **);
|
|
int (*fill)(struct fib_rule *, struct sk_buff *,
|
|
struct nlmsghdr *,
|
|
struct fib_rule_hdr *);
|
|
u32 (*default_pref)(void);
|
|
size_t (*nlmsg_payload)(struct fib_rule *);
|
|
|
|
/* Called after modifications to the rules set, must flush
|
|
* the route cache if one exists. */
|
|
void (*flush_cache)(void);
|
|
|
|
int nlgroup;
|
|
struct nla_policy *policy;
|
|
struct list_head *rules_list;
|
|
struct module *owner;
|
|
};
|
|
|
|
#define FRA_GENERIC_POLICY \
|
|
[FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
|
|
[FRA_PRIORITY] = { .type = NLA_U32 }, \
|
|
[FRA_FWMARK] = { .type = NLA_U32 }, \
|
|
[FRA_FWMASK] = { .type = NLA_U32 }, \
|
|
[FRA_TABLE] = { .type = NLA_U32 }, \
|
|
[FRA_GOTO] = { .type = NLA_U32 }
|
|
|
|
static inline void fib_rule_get(struct fib_rule *rule)
|
|
{
|
|
atomic_inc(&rule->refcnt);
|
|
}
|
|
|
|
static inline void fib_rule_put_rcu(struct rcu_head *head)
|
|
{
|
|
struct fib_rule *rule = container_of(head, struct fib_rule, rcu);
|
|
kfree(rule);
|
|
}
|
|
|
|
static inline void fib_rule_put(struct fib_rule *rule)
|
|
{
|
|
if (atomic_dec_and_test(&rule->refcnt))
|
|
call_rcu(&rule->rcu, fib_rule_put_rcu);
|
|
}
|
|
|
|
static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
|
|
{
|
|
if (nla[FRA_TABLE])
|
|
return nla_get_u32(nla[FRA_TABLE]);
|
|
return frh->table;
|
|
}
|
|
|
|
extern int fib_rules_register(struct fib_rules_ops *);
|
|
extern int fib_rules_unregister(struct fib_rules_ops *);
|
|
|
|
extern int fib_rules_lookup(struct fib_rules_ops *,
|
|
struct flowi *, int flags,
|
|
struct fib_lookup_arg *);
|
|
#endif
|