linux/include/net/act_api.h
<<
>>
Prefs
   1#ifndef __NET_ACT_API_H
   2#define __NET_ACT_API_H
   3
   4/*
   5 * Public action API for classifiers/qdiscs
   6*/
   7
   8#include <net/sch_generic.h>
   9#include <net/pkt_sched.h>
  10#include <net/net_namespace.h>
  11#include <net/netns/generic.h>
  12
  13
  14struct tcf_hashinfo {
  15        struct hlist_head       *htab;
  16        unsigned int            hmask;
  17        spinlock_t              lock;
  18        u32                     index;
  19};
  20
  21struct tc_action_ops;
  22
  23struct tc_action {
  24        const struct tc_action_ops      *ops;
  25        __u32                           type; /* for backward compat(TCA_OLD_COMPAT) */
  26        __u32                           order;
  27        struct list_head                list;
  28        struct tcf_hashinfo             *hinfo;
  29
  30        struct hlist_node               tcfa_head;
  31        u32                             tcfa_index;
  32        int                             tcfa_refcnt;
  33        int                             tcfa_bindcnt;
  34        u32                             tcfa_capab;
  35        int                             tcfa_action;
  36        struct tcf_t                    tcfa_tm;
  37        struct gnet_stats_basic_packed  tcfa_bstats;
  38        struct gnet_stats_queue         tcfa_qstats;
  39        struct gnet_stats_rate_est64    tcfa_rate_est;
  40        spinlock_t                      tcfa_lock;
  41        struct rcu_head                 tcfa_rcu;
  42        struct gnet_stats_basic_cpu __percpu *cpu_bstats;
  43        struct gnet_stats_queue __percpu *cpu_qstats;
  44};
  45#define tcf_act         common.tcfa_act
  46#define tcf_head        common.tcfa_head
  47#define tcf_index       common.tcfa_index
  48#define tcf_refcnt      common.tcfa_refcnt
  49#define tcf_bindcnt     common.tcfa_bindcnt
  50#define tcf_capab       common.tcfa_capab
  51#define tcf_action      common.tcfa_action
  52#define tcf_tm          common.tcfa_tm
  53#define tcf_bstats      common.tcfa_bstats
  54#define tcf_qstats      common.tcfa_qstats
  55#define tcf_rate_est    common.tcfa_rate_est
  56#define tcf_lock        common.tcfa_lock
  57#define tcf_rcu         common.tcfa_rcu
  58
  59static inline unsigned int tcf_hash(u32 index, unsigned int hmask)
  60{
  61        return index & hmask;
  62}
  63
  64static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask)
  65{
  66        int i;
  67
  68        spin_lock_init(&hf->lock);
  69        hf->index = 0;
  70        hf->hmask = mask;
  71        hf->htab = kzalloc((mask + 1) * sizeof(struct hlist_head),
  72                           GFP_KERNEL);
  73        if (!hf->htab)
  74                return -ENOMEM;
  75        for (i = 0; i < mask + 1; i++)
  76                INIT_HLIST_HEAD(&hf->htab[i]);
  77        return 0;
  78}
  79
  80/* Update lastuse only if needed, to avoid dirtying a cache line.
  81 * We use a temp variable to avoid fetching jiffies twice.
  82 */
  83static inline void tcf_lastuse_update(struct tcf_t *tm)
  84{
  85        unsigned long now = jiffies;
  86
  87        if (tm->lastuse != now)
  88                tm->lastuse = now;
  89        if (unlikely(!tm->firstuse))
  90                tm->firstuse = now;
  91}
  92
  93static inline void tcf_tm_dump(struct tcf_t *dtm, const struct tcf_t *stm)
  94{
  95        dtm->install = jiffies_to_clock_t(jiffies - stm->install);
  96        dtm->lastuse = jiffies_to_clock_t(jiffies - stm->lastuse);
  97        dtm->firstuse = jiffies_to_clock_t(jiffies - stm->firstuse);
  98        dtm->expires = jiffies_to_clock_t(stm->expires);
  99}
 100
 101#ifdef CONFIG_NET_CLS_ACT
 102
 103#define ACT_P_CREATED 1
 104#define ACT_P_DELETED 1
 105
 106struct tc_action_ops {
 107        struct list_head head;
 108        char    kind[IFNAMSIZ];
 109        __u32   type; /* TBD to match kind */
 110        size_t  size;
 111        struct module           *owner;
 112        int     (*act)(struct sk_buff *, const struct tc_action *,
 113                       struct tcf_result *);
 114        int     (*dump)(struct sk_buff *, struct tc_action *, int, int);
 115        void    (*cleanup)(struct tc_action *, int bind);
 116        int     (*lookup)(struct net *, struct tc_action **, u32);
 117        int     (*init)(struct net *net, struct nlattr *nla,
 118                        struct nlattr *est, struct tc_action **act, int ovr,
 119                        int bind);
 120        int     (*walk)(struct net *, struct sk_buff *,
 121                        struct netlink_callback *, int, const struct tc_action_ops *);
 122        void    (*stats_update)(struct tc_action *, u64, u32, u64);
 123};
 124
 125struct tc_action_net {
 126        struct tcf_hashinfo *hinfo;
 127        const struct tc_action_ops *ops;
 128};
 129
 130static inline
 131int tc_action_net_init(struct tc_action_net *tn,
 132                       const struct tc_action_ops *ops, unsigned int mask)
 133{
 134        int err = 0;
 135
 136        tn->hinfo = kmalloc(sizeof(*tn->hinfo), GFP_KERNEL);
 137        if (!tn->hinfo)
 138                return -ENOMEM;
 139        tn->ops = ops;
 140        err = tcf_hashinfo_init(tn->hinfo, mask);
 141        if (err)
 142                kfree(tn->hinfo);
 143        return err;
 144}
 145
 146void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
 147                          struct tcf_hashinfo *hinfo);
 148
 149static inline void tc_action_net_exit(struct tc_action_net *tn)
 150{
 151        tcf_hashinfo_destroy(tn->ops, tn->hinfo);
 152        kfree(tn->hinfo);
 153}
 154
 155int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
 156                       struct netlink_callback *cb, int type,
 157                       const struct tc_action_ops *ops);
 158int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
 159u32 tcf_hash_new_index(struct tc_action_net *tn);
 160bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
 161                    int bind);
 162int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
 163                    struct tc_action **a, const struct tc_action_ops *ops, int bind,
 164                    bool cpustats);
 165void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est);
 166void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a);
 167
 168int __tcf_hash_release(struct tc_action *a, bool bind, bool strict);
 169
 170static inline int tcf_hash_release(struct tc_action *a, bool bind)
 171{
 172        return __tcf_hash_release(a, bind, false);
 173}
 174
 175int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);
 176int tcf_unregister_action(struct tc_action_ops *a,
 177                          struct pernet_operations *ops);
 178int tcf_action_destroy(struct list_head *actions, int bind);
 179int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
 180                    int nr_actions, struct tcf_result *res);
 181int tcf_action_init(struct net *net, struct nlattr *nla,
 182                                  struct nlattr *est, char *n, int ovr,
 183                                  int bind, struct list_head *);
 184struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
 185                                    struct nlattr *est, char *n, int ovr,
 186                                    int bind);
 187int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
 188int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 189int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
 190int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
 191
 192#endif /* CONFIG_NET_CLS_ACT */
 193
 194static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
 195                                           u64 packets, u64 lastuse)
 196{
 197#ifdef CONFIG_NET_CLS_ACT
 198        if (!a->ops->stats_update)
 199                return;
 200
 201        a->ops->stats_update(a, bytes, packets, lastuse);
 202#endif
 203}
 204
 205#endif
 206