summaryrefslogtreecommitdiffstats
path: root/kernel/include/net/fib_rules.h
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/include/net/fib_rules.h')
-rw-r--r--kernel/include/net/fib_rules.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/kernel/include/net/fib_rules.h b/kernel/include/net/fib_rules.h
new file mode 100644
index 000000000..6d67383a5
--- /dev/null
+++ b/kernel/include/net/fib_rules.h
@@ -0,0 +1,120 @@
+#ifndef __NET_FIB_RULES_H
+#define __NET_FIB_RULES_H
+
+#include <linux/types.h>
+#include <linux/slab.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;
+ int iifindex;
+ int oifindex;
+ u32 mark;
+ u32 mark_mask;
+ u32 flags;
+ u32 table;
+ u8 action;
+ /* 3 bytes hole, try to use */
+ u32 target;
+ struct fib_rule __rcu *ctarget;
+ struct net *fr_net;
+
+ atomic_t refcnt;
+ u32 pref;
+ int suppress_ifgroup;
+ int suppress_prefixlen;
+ char iifname[IFNAMSIZ];
+ char oifname[IFNAMSIZ];
+ struct rcu_head rcu;
+};
+
+struct fib_lookup_arg {
+ void *lookup_ptr;
+ void *result;
+ struct fib_rule *rule;
+ int flags;
+#define FIB_LOOKUP_NOREF 1
+};
+
+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 *);
+ bool (*suppress)(struct fib_rule *,
+ struct fib_lookup_arg *);
+ int (*match)(struct fib_rule *,
+ struct flowi *, int);
+ int (*configure)(struct fib_rule *,
+ struct sk_buff *,
+ struct fib_rule_hdr *,
+ struct nlattr **);
+ int (*delete)(struct fib_rule *);
+ int (*compare)(struct fib_rule *,
+ struct fib_rule_hdr *,
+ struct nlattr **);
+ int (*fill)(struct fib_rule *, struct sk_buff *,
+ struct fib_rule_hdr *);
+ u32 (*default_pref)(struct fib_rules_ops *ops);
+ 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)(struct fib_rules_ops *ops);
+
+ int nlgroup;
+ const struct nla_policy *policy;
+ struct list_head rules_list;
+ struct module *owner;
+ struct net *fro_net;
+ struct rcu_head rcu;
+};
+
+#define FRA_GENERIC_POLICY \
+ [FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
+ [FRA_OIFNAME] = { .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_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
+ [FRA_SUPPRESS_IFGROUP] = { .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(struct fib_rule *rule)
+{
+ if (atomic_dec_and_test(&rule->refcnt))
+ kfree_rcu(rule, 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;
+}
+
+struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *,
+ struct net *);
+void fib_rules_unregister(struct fib_rules_ops *);
+
+int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags,
+ struct fib_lookup_arg *);
+int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
+ u32 flags);
+u32 fib_default_rule_pref(struct fib_rules_ops *ops);
+#endif