root/net/sched/em_cmp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cmp_needs_transformation
  2. em_cmp_match
  3. init_em_cmp
  4. exit_em_cmp

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * net/sched/em_cmp.c   Simple packet data comparison ematch
   4  *
   5  * Authors:     Thomas Graf <tgraf@suug.ch>
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/types.h>
  10 #include <linux/kernel.h>
  11 #include <linux/skbuff.h>
  12 #include <linux/tc_ematch/tc_em_cmp.h>
  13 #include <asm/unaligned.h>
  14 #include <net/pkt_cls.h>
  15 
  16 static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
  17 {
  18         return unlikely(cmp->flags & TCF_EM_CMP_TRANS);
  19 }
  20 
  21 static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
  22                         struct tcf_pkt_info *info)
  23 {
  24         struct tcf_em_cmp *cmp = (struct tcf_em_cmp *) em->data;
  25         unsigned char *ptr = tcf_get_base_ptr(skb, cmp->layer) + cmp->off;
  26         u32 val = 0;
  27 
  28         if (!tcf_valid_offset(skb, ptr, cmp->align))
  29                 return 0;
  30 
  31         switch (cmp->align) {
  32         case TCF_EM_ALIGN_U8:
  33                 val = *ptr;
  34                 break;
  35 
  36         case TCF_EM_ALIGN_U16:
  37                 val = get_unaligned_be16(ptr);
  38 
  39                 if (cmp_needs_transformation(cmp))
  40                         val = be16_to_cpu(val);
  41                 break;
  42 
  43         case TCF_EM_ALIGN_U32:
  44                 /* Worth checking boundries? The branching seems
  45                  * to get worse. Visit again.
  46                  */
  47                 val = get_unaligned_be32(ptr);
  48 
  49                 if (cmp_needs_transformation(cmp))
  50                         val = be32_to_cpu(val);
  51                 break;
  52 
  53         default:
  54                 return 0;
  55         }
  56 
  57         if (cmp->mask)
  58                 val &= cmp->mask;
  59 
  60         switch (cmp->opnd) {
  61         case TCF_EM_OPND_EQ:
  62                 return val == cmp->val;
  63         case TCF_EM_OPND_LT:
  64                 return val < cmp->val;
  65         case TCF_EM_OPND_GT:
  66                 return val > cmp->val;
  67         }
  68 
  69         return 0;
  70 }
  71 
  72 static struct tcf_ematch_ops em_cmp_ops = {
  73         .kind     = TCF_EM_CMP,
  74         .datalen  = sizeof(struct tcf_em_cmp),
  75         .match    = em_cmp_match,
  76         .owner    = THIS_MODULE,
  77         .link     = LIST_HEAD_INIT(em_cmp_ops.link)
  78 };
  79 
  80 static int __init init_em_cmp(void)
  81 {
  82         return tcf_em_register(&em_cmp_ops);
  83 }
  84 
  85 static void __exit exit_em_cmp(void)
  86 {
  87         tcf_em_unregister(&em_cmp_ops);
  88 }
  89 
  90 MODULE_LICENSE("GPL");
  91 
  92 module_init(init_em_cmp);
  93 module_exit(exit_em_cmp);
  94 
  95 MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);

/* [<][>][^][v][top][bottom][index][help] */