linux/include/net/fib_rules.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __NET_FIB_RULES_H
   3#define __NET_FIB_RULES_H
   4
   5#include <linux/types.h>
   6#include <linux/slab.h>
   7#include <linux/netdevice.h>
   8#include <linux/fib_rules.h>
   9#include <linux/refcount.h>
  10#include <net/flow.h>
  11#include <net/rtnetlink.h>
  12#include <net/fib_notifier.h>
  13#include <linux/indirect_call_wrapper.h>
  14
  15struct fib_kuid_range {
  16        kuid_t start;
  17        kuid_t end;
  18};
  19
  20struct fib_rule {
  21        struct list_head        list;
  22        int                     iifindex;
  23        int                     oifindex;
  24        u32                     mark;
  25        u32                     mark_mask;
  26        u32                     flags;
  27        u32                     table;
  28        u8                      action;
  29        u8                      l3mdev;
  30        u8                      proto;
  31        u8                      ip_proto;
  32        u32                     target;
  33        __be64                  tun_id;
  34        struct fib_rule __rcu   *ctarget;
  35        struct net              *fr_net;
  36
  37        refcount_t              refcnt;
  38        u32                     pref;
  39        int                     suppress_ifgroup;
  40        int                     suppress_prefixlen;
  41        char                    iifname[IFNAMSIZ];
  42        char                    oifname[IFNAMSIZ];
  43        struct fib_kuid_range   uid_range;
  44        struct fib_rule_port_range      sport_range;
  45        struct fib_rule_port_range      dport_range;
  46        struct rcu_head         rcu;
  47};
  48
  49struct fib_lookup_arg {
  50        void                    *lookup_ptr;
  51        const void              *lookup_data;
  52        void                    *result;
  53        struct fib_rule         *rule;
  54        u32                     table;
  55        int                     flags;
  56#define FIB_LOOKUP_NOREF                1
  57#define FIB_LOOKUP_IGNORE_LINKSTATE     2
  58};
  59
  60struct fib_rules_ops {
  61        int                     family;
  62        struct list_head        list;
  63        int                     rule_size;
  64        int                     addr_size;
  65        int                     unresolved_rules;
  66        int                     nr_goto_rules;
  67        unsigned int            fib_rules_seq;
  68
  69        int                     (*action)(struct fib_rule *,
  70                                          struct flowi *, int,
  71                                          struct fib_lookup_arg *);
  72        bool                    (*suppress)(struct fib_rule *,
  73                                            struct fib_lookup_arg *);
  74        int                     (*match)(struct fib_rule *,
  75                                         struct flowi *, int);
  76        int                     (*configure)(struct fib_rule *,
  77                                             struct sk_buff *,
  78                                             struct fib_rule_hdr *,
  79                                             struct nlattr **,
  80                                             struct netlink_ext_ack *);
  81        int                     (*delete)(struct fib_rule *);
  82        int                     (*compare)(struct fib_rule *,
  83                                           struct fib_rule_hdr *,
  84                                           struct nlattr **);
  85        int                     (*fill)(struct fib_rule *, struct sk_buff *,
  86                                        struct fib_rule_hdr *);
  87        size_t                  (*nlmsg_payload)(struct fib_rule *);
  88
  89        /* Called after modifications to the rules set, must flush
  90         * the route cache if one exists. */
  91        void                    (*flush_cache)(struct fib_rules_ops *ops);
  92
  93        int                     nlgroup;
  94        const struct nla_policy *policy;
  95        struct list_head        rules_list;
  96        struct module           *owner;
  97        struct net              *fro_net;
  98        struct rcu_head         rcu;
  99};
 100
 101struct fib_rule_notifier_info {
 102        struct fib_notifier_info info; /* must be first */
 103        struct fib_rule *rule;
 104};
 105
 106#define FRA_GENERIC_POLICY \
 107        [FRA_UNSPEC]    = { .strict_start_type = FRA_DPORT_RANGE + 1 }, \
 108        [FRA_IIFNAME]   = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
 109        [FRA_OIFNAME]   = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
 110        [FRA_PRIORITY]  = { .type = NLA_U32 }, \
 111        [FRA_FWMARK]    = { .type = NLA_U32 }, \
 112        [FRA_TUN_ID]    = { .type = NLA_U64 }, \
 113        [FRA_FWMASK]    = { .type = NLA_U32 }, \
 114        [FRA_TABLE]     = { .type = NLA_U32 }, \
 115        [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
 116        [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
 117        [FRA_GOTO]      = { .type = NLA_U32 }, \
 118        [FRA_L3MDEV]    = { .type = NLA_U8 }, \
 119        [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) }, \
 120        [FRA_PROTOCOL]  = { .type = NLA_U8 }, \
 121        [FRA_IP_PROTO]  = { .type = NLA_U8 }, \
 122        [FRA_SPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }, \
 123        [FRA_DPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }
 124
 125
 126static inline void fib_rule_get(struct fib_rule *rule)
 127{
 128        refcount_inc(&rule->refcnt);
 129}
 130
 131static inline void fib_rule_put(struct fib_rule *rule)
 132{
 133        if (refcount_dec_and_test(&rule->refcnt))
 134                kfree_rcu(rule, rcu);
 135}
 136
 137#ifdef CONFIG_NET_L3_MASTER_DEV
 138static inline u32 fib_rule_get_table(struct fib_rule *rule,
 139                                     struct fib_lookup_arg *arg)
 140{
 141        return rule->l3mdev ? arg->table : rule->table;
 142}
 143#else
 144static inline u32 fib_rule_get_table(struct fib_rule *rule,
 145                                     struct fib_lookup_arg *arg)
 146{
 147        return rule->table;
 148}
 149#endif
 150
 151static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
 152{
 153        if (nla[FRA_TABLE])
 154                return nla_get_u32(nla[FRA_TABLE]);
 155        return frh->table;
 156}
 157
 158static inline bool fib_rule_port_range_set(const struct fib_rule_port_range *range)
 159{
 160        return range->start != 0 && range->end != 0;
 161}
 162
 163static inline bool fib_rule_port_inrange(const struct fib_rule_port_range *a,
 164                                         __be16 port)
 165{
 166        return ntohs(port) >= a->start &&
 167                ntohs(port) <= a->end;
 168}
 169
 170static inline bool fib_rule_port_range_valid(const struct fib_rule_port_range *a)
 171{
 172        return a->start != 0 && a->end != 0 && a->end < 0xffff &&
 173                a->start <= a->end;
 174}
 175
 176static inline bool fib_rule_port_range_compare(struct fib_rule_port_range *a,
 177                                               struct fib_rule_port_range *b)
 178{
 179        return a->start == b->start &&
 180                a->end == b->end;
 181}
 182
 183static inline bool fib_rule_requires_fldissect(struct fib_rule *rule)
 184{
 185        return rule->iifindex != LOOPBACK_IFINDEX && (rule->ip_proto ||
 186                fib_rule_port_range_set(&rule->sport_range) ||
 187                fib_rule_port_range_set(&rule->dport_range));
 188}
 189
 190struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *,
 191                                         struct net *);
 192void fib_rules_unregister(struct fib_rules_ops *);
 193
 194int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags,
 195                     struct fib_lookup_arg *);
 196int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
 197                         u32 flags);
 198bool fib_rule_matchall(const struct fib_rule *rule);
 199int fib_rules_dump(struct net *net, struct notifier_block *nb, int family,
 200                   struct netlink_ext_ack *extack);
 201unsigned int fib_rules_seq_read(struct net *net, int family);
 202
 203int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
 204                   struct netlink_ext_ack *extack);
 205int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
 206                   struct netlink_ext_ack *extack);
 207
 208INDIRECT_CALLABLE_DECLARE(int fib6_rule_match(struct fib_rule *rule,
 209                                            struct flowi *fl, int flags));
 210INDIRECT_CALLABLE_DECLARE(int fib4_rule_match(struct fib_rule *rule,
 211                                            struct flowi *fl, int flags));
 212
 213INDIRECT_CALLABLE_DECLARE(int fib6_rule_action(struct fib_rule *rule,
 214                            struct flowi *flp, int flags,
 215                            struct fib_lookup_arg *arg));
 216INDIRECT_CALLABLE_DECLARE(int fib4_rule_action(struct fib_rule *rule,
 217                            struct flowi *flp, int flags,
 218                            struct fib_lookup_arg *arg));
 219
 220INDIRECT_CALLABLE_DECLARE(bool fib6_rule_suppress(struct fib_rule *rule,
 221                                                struct fib_lookup_arg *arg));
 222INDIRECT_CALLABLE_DECLARE(bool fib4_rule_suppress(struct fib_rule *rule,
 223                                                struct fib_lookup_arg *arg));
 224#endif
 225