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 net_rate_estimator __rcu *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        struct tc_cookie        *act_cookie;
  45};
  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        int     (*get_dev)(const struct tc_action *a, struct net *net,
 124                           struct net_device **mirred_dev);
 125};
 126
 127struct tc_action_net {
 128        struct tcf_hashinfo *hinfo;
 129        const struct tc_action_ops *ops;
 130};
 131
 132static inline
 133int tc_action_net_init(struct tc_action_net *tn,
 134                       const struct tc_action_ops *ops, unsigned int mask)
 135{
 136        int err = 0;
 137
 138        tn->hinfo = kmalloc(sizeof(*tn->hinfo), GFP_KERNEL);
 139        if (!tn->hinfo)
 140                return -ENOMEM;
 141        tn->ops = ops;
 142        err = tcf_hashinfo_init(tn->hinfo, mask);
 143        if (err)
 144                kfree(tn->hinfo);
 145        return err;
 146}
 147
 148void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
 149                          struct tcf_hashinfo *hinfo);
 150
 151static inline void tc_action_net_exit(struct tc_action_net *tn)
 152{
 153        tcf_hashinfo_destroy(tn->ops, tn->hinfo);
 154        kfree(tn->hinfo);
 155}
 156
 157int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
 158                       struct netlink_callback *cb, int type,
 159                       const struct tc_action_ops *ops);
 160int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
 161u32 tcf_hash_new_index(struct tc_action_net *tn);
 162bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
 163                    int bind);
 164int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
 165                    struct tc_action **a, const struct tc_action_ops *ops, int bind,
 166                    bool cpustats);
 167void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est);
 168void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a);
 169
 170int __tcf_hash_release(struct tc_action *a, bool bind, bool strict);
 171
 172static inline int tcf_hash_release(struct tc_action *a, bool bind)
 173{
 174        return __tcf_hash_release(a, bind, false);
 175}
 176
 177int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);
 178int tcf_unregister_action(struct tc_action_ops *a,
 179                          struct pernet_operations *ops);
 180int tcf_action_destroy(struct list_head *actions, int bind);
 181int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
 182                    int nr_actions, struct tcf_result *res);
 183int tcf_action_init(struct net *net, struct nlattr *nla,
 184                                  struct nlattr *est, char *n, int ovr,
 185                                  int bind, struct list_head *);
 186struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
 187                                    struct nlattr *est, char *n, int ovr,
 188                                    int bind);
 189int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
 190int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 191int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
 192int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
 193
 194#endif /* CONFIG_NET_CLS_ACT */
 195
 196static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
 197                                           u64 packets, u64 lastuse)
 198{
 199#ifdef CONFIG_NET_CLS_ACT
 200        if (!a->ops->stats_update)
 201                return;
 202
 203        a->ops->stats_update(a, bytes, packets, lastuse);
 204#endif
 205}
 206
 207#endif
 208