linux/include/net/pkt_cls.h
<<
>>
Prefs
   1#ifndef __NET_PKT_CLS_H
   2#define __NET_PKT_CLS_H
   3
   4#include <linux/pkt_cls.h>
   5#include <net/sch_generic.h>
   6#include <net/act_api.h>
   7
   8/* Basic packet classifier frontend definitions. */
   9
  10struct tcf_walker {
  11        int     stop;
  12        int     skip;
  13        int     count;
  14        int     (*fn)(struct tcf_proto *, unsigned long node, struct tcf_walker *);
  15};
  16
  17int register_tcf_proto_ops(struct tcf_proto_ops *ops);
  18int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
  19
  20static inline unsigned long
  21__cls_set_class(unsigned long *clp, unsigned long cl)
  22{
  23        return xchg(clp, cl);
  24}
  25
  26static inline unsigned long
  27cls_set_class(struct tcf_proto *tp, unsigned long *clp, 
  28        unsigned long cl)
  29{
  30        unsigned long old_cl;
  31        
  32        tcf_tree_lock(tp);
  33        old_cl = __cls_set_class(clp, cl);
  34        tcf_tree_unlock(tp);
  35 
  36        return old_cl;
  37}
  38
  39static inline void
  40tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
  41{
  42        unsigned long cl;
  43
  44        cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid);
  45        cl = cls_set_class(tp, &r->class, cl);
  46        if (cl)
  47                tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
  48}
  49
  50static inline void
  51tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
  52{
  53        unsigned long cl;
  54
  55        if ((cl = __cls_set_class(&r->class, 0)) != 0)
  56                tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
  57}
  58
  59struct tcf_exts {
  60#ifdef CONFIG_NET_CLS_ACT
  61        __u32   type; /* for backward compat(TCA_OLD_COMPAT) */
  62        struct list_head actions;
  63#endif
  64        /* Map to export classifier specific extension TLV types to the
  65         * generic extensions API. Unsupported extensions must be set to 0.
  66         */
  67        int action;
  68        int police;
  69};
  70
  71static inline void tcf_exts_init(struct tcf_exts *exts, int action, int police)
  72{
  73#ifdef CONFIG_NET_CLS_ACT
  74        exts->type = 0;
  75        INIT_LIST_HEAD(&exts->actions);
  76#endif
  77        exts->action = action;
  78        exts->police = police;
  79}
  80
  81/**
  82 * tcf_exts_is_predicative - check if a predicative extension is present
  83 * @exts: tc filter extensions handle
  84 *
  85 * Returns 1 if a predicative extension is present, i.e. an extension which
  86 * might cause further actions and thus overrule the regular tcf_result.
  87 */
  88static inline int
  89tcf_exts_is_predicative(struct tcf_exts *exts)
  90{
  91#ifdef CONFIG_NET_CLS_ACT
  92        return !list_empty(&exts->actions);
  93#else
  94        return 0;
  95#endif
  96}
  97
  98/**
  99 * tcf_exts_is_available - check if at least one extension is present
 100 * @exts: tc filter extensions handle
 101 *
 102 * Returns 1 if at least one extension is present.
 103 */
 104static inline int
 105tcf_exts_is_available(struct tcf_exts *exts)
 106{
 107        /* All non-predicative extensions must be added here. */
 108        return tcf_exts_is_predicative(exts);
 109}
 110
 111/**
 112 * tcf_exts_exec - execute tc filter extensions
 113 * @skb: socket buffer
 114 * @exts: tc filter extensions handle
 115 * @res: desired result
 116 *
 117 * Executes all configured extensions. Returns 0 on a normal execution,
 118 * a negative number if the filter must be considered unmatched or
 119 * a positive action code (TC_ACT_*) which must be returned to the
 120 * underlying layer.
 121 */
 122static inline int
 123tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
 124               struct tcf_result *res)
 125{
 126#ifdef CONFIG_NET_CLS_ACT
 127        if (!list_empty(&exts->actions))
 128                return tcf_action_exec(skb, &exts->actions, res);
 129#endif
 130        return 0;
 131}
 132
 133int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
 134                      struct nlattr **tb, struct nlattr *rate_tlv,
 135                      struct tcf_exts *exts, bool ovr);
 136void tcf_exts_destroy(struct tcf_exts *exts);
 137void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
 138                     struct tcf_exts *src);
 139int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
 140int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
 141
 142/**
 143 * struct tcf_pkt_info - packet information
 144 */
 145struct tcf_pkt_info {
 146        unsigned char *         ptr;
 147        int                     nexthdr;
 148};
 149
 150#ifdef CONFIG_NET_EMATCH
 151
 152struct tcf_ematch_ops;
 153
 154/**
 155 * struct tcf_ematch - extended match (ematch)
 156 * 
 157 * @matchid: identifier to allow userspace to reidentify a match
 158 * @flags: flags specifying attributes and the relation to other matches
 159 * @ops: the operations lookup table of the corresponding ematch module
 160 * @datalen: length of the ematch specific configuration data
 161 * @data: ematch specific data
 162 */
 163struct tcf_ematch {
 164        struct tcf_ematch_ops * ops;
 165        unsigned long           data;
 166        unsigned int            datalen;
 167        u16                     matchid;
 168        u16                     flags;
 169        struct net              *net;
 170};
 171
 172static inline int tcf_em_is_container(struct tcf_ematch *em)
 173{
 174        return !em->ops;
 175}
 176
 177static inline int tcf_em_is_simple(struct tcf_ematch *em)
 178{
 179        return em->flags & TCF_EM_SIMPLE;
 180}
 181
 182static inline int tcf_em_is_inverted(struct tcf_ematch *em)
 183{
 184        return em->flags & TCF_EM_INVERT;
 185}
 186
 187static inline int tcf_em_last_match(struct tcf_ematch *em)
 188{
 189        return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END;
 190}
 191
 192static inline int tcf_em_early_end(struct tcf_ematch *em, int result)
 193{
 194        if (tcf_em_last_match(em))
 195                return 1;
 196
 197        if (result == 0 && em->flags & TCF_EM_REL_AND)
 198                return 1;
 199
 200        if (result != 0 && em->flags & TCF_EM_REL_OR)
 201                return 1;
 202
 203        return 0;
 204}
 205        
 206/**
 207 * struct tcf_ematch_tree - ematch tree handle
 208 *
 209 * @hdr: ematch tree header supplied by userspace
 210 * @matches: array of ematches
 211 */
 212struct tcf_ematch_tree {
 213        struct tcf_ematch_tree_hdr hdr;
 214        struct tcf_ematch *     matches;
 215        
 216};
 217
 218/**
 219 * struct tcf_ematch_ops - ematch module operations
 220 * 
 221 * @kind: identifier (kind) of this ematch module
 222 * @datalen: length of expected configuration data (optional)
 223 * @change: called during validation (optional)
 224 * @match: called during ematch tree evaluation, must return 1/0
 225 * @destroy: called during destroyage (optional)
 226 * @dump: called during dumping process (optional)
 227 * @owner: owner, must be set to THIS_MODULE
 228 * @link: link to previous/next ematch module (internal use)
 229 */
 230struct tcf_ematch_ops {
 231        int                     kind;
 232        int                     datalen;
 233        int                     (*change)(struct net *net, void *,
 234                                          int, struct tcf_ematch *);
 235        int                     (*match)(struct sk_buff *, struct tcf_ematch *,
 236                                         struct tcf_pkt_info *);
 237        void                    (*destroy)(struct tcf_ematch *);
 238        int                     (*dump)(struct sk_buff *, struct tcf_ematch *);
 239        struct module           *owner;
 240        struct list_head        link;
 241};
 242
 243int tcf_em_register(struct tcf_ematch_ops *);
 244void tcf_em_unregister(struct tcf_ematch_ops *);
 245int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
 246                         struct tcf_ematch_tree *);
 247void tcf_em_tree_destroy(struct tcf_ematch_tree *);
 248int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
 249int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
 250                        struct tcf_pkt_info *);
 251
 252/**
 253 * tcf_em_tree_change - replace ematch tree of a running classifier
 254 *
 255 * @tp: classifier kind handle
 256 * @dst: destination ematch tree variable
 257 * @src: source ematch tree (temporary tree from tcf_em_tree_validate)
 258 *
 259 * This functions replaces the ematch tree in @dst with the ematch
 260 * tree in @src. The classifier in charge of the ematch tree may be
 261 * running.
 262 */
 263static inline void tcf_em_tree_change(struct tcf_proto *tp,
 264                                      struct tcf_ematch_tree *dst,
 265                                      struct tcf_ematch_tree *src)
 266{
 267        tcf_tree_lock(tp);
 268        memcpy(dst, src, sizeof(*dst));
 269        tcf_tree_unlock(tp);
 270}
 271
 272/**
 273 * tcf_em_tree_match - evaulate an ematch tree
 274 *
 275 * @skb: socket buffer of the packet in question
 276 * @tree: ematch tree to be used for evaluation
 277 * @info: packet information examined by classifier
 278 *
 279 * This function matches @skb against the ematch tree in @tree by going
 280 * through all ematches respecting their logic relations returning
 281 * as soon as the result is obvious.
 282 *
 283 * Returns 1 if the ematch tree as-one matches, no ematches are configured
 284 * or ematch is not enabled in the kernel, otherwise 0 is returned.
 285 */
 286static inline int tcf_em_tree_match(struct sk_buff *skb,
 287                                    struct tcf_ematch_tree *tree,
 288                                    struct tcf_pkt_info *info)
 289{
 290        if (tree->hdr.nmatches)
 291                return __tcf_em_tree_match(skb, tree, info);
 292        else
 293                return 1;
 294}
 295
 296#define MODULE_ALIAS_TCF_EMATCH(kind)   MODULE_ALIAS("ematch-kind-" __stringify(kind))
 297
 298#else /* CONFIG_NET_EMATCH */
 299
 300struct tcf_ematch_tree {
 301};
 302
 303#define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
 304#define tcf_em_tree_destroy(t) do { (void)(t); } while(0)
 305#define tcf_em_tree_dump(skb, t, tlv) (0)
 306#define tcf_em_tree_change(tp, dst, src) do { } while(0)
 307#define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
 308
 309#endif /* CONFIG_NET_EMATCH */
 310
 311static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
 312{
 313        switch (layer) {
 314                case TCF_LAYER_LINK:
 315                        return skb->data;
 316                case TCF_LAYER_NETWORK:
 317                        return skb_network_header(skb);
 318                case TCF_LAYER_TRANSPORT:
 319                        return skb_transport_header(skb);
 320        }
 321
 322        return NULL;
 323}
 324
 325static inline int tcf_valid_offset(const struct sk_buff *skb,
 326                                   const unsigned char *ptr, const int len)
 327{
 328        return likely((ptr + len) <= skb_tail_pointer(skb) &&
 329                      ptr >= skb->head &&
 330                      (ptr <= (ptr + len)));
 331}
 332
 333#ifdef CONFIG_NET_CLS_IND
 334#include <net/net_namespace.h>
 335
 336static inline int
 337tcf_change_indev(struct net *net, struct nlattr *indev_tlv)
 338{
 339        char indev[IFNAMSIZ];
 340        struct net_device *dev;
 341
 342        if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
 343                return -EINVAL;
 344        dev = __dev_get_by_name(net, indev);
 345        if (!dev)
 346                return -ENODEV;
 347        return dev->ifindex;
 348}
 349
 350static inline bool
 351tcf_match_indev(struct sk_buff *skb, int ifindex)
 352{
 353        if (!ifindex)
 354                return true;
 355        if  (!skb->skb_iif)
 356                return false;
 357        return ifindex == skb->skb_iif;
 358}
 359#endif /* CONFIG_NET_CLS_IND */
 360
 361#endif
 362