Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * net/sched/em_cmp.c   Simple packet data comparison ematch
  3  *
  4  *              This program is free software; you can redistribute it and/or
  5  *              modify it under the terms of the GNU General Public License
  6  *              as published by the Free Software Foundation; either version
  7  *              2 of the License, or (at your option) any later version.
  8  *
  9  * Authors:     Thomas Graf <tgraf@suug.ch>
 10  */
 11 
 12 #include <linux/module.h>
 13 #include <linux/types.h>
 14 #include <linux/kernel.h>
 15 #include <linux/skbuff.h>
 16 #include <linux/tc_ematch/tc_em_cmp.h>
 17 #include <net/pkt_cls.h>
 18 
 19 static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
 20 {
 21         return unlikely(cmp->flags & TCF_EM_CMP_TRANS);
 22 }
 23 
 24 static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
 25                         struct tcf_pkt_info *info)
 26 {
 27         struct tcf_em_cmp *cmp = (struct tcf_em_cmp *) em->data;
 28         unsigned char *ptr = tcf_get_base_ptr(skb, cmp->layer) + cmp->off;
 29         u32 val = 0;
 30 
 31         if (!tcf_valid_offset(skb, ptr, cmp->align))
 32                 return 0;
 33 
 34         switch (cmp->align) {
 35                 case TCF_EM_ALIGN_U8:
 36                         val = *ptr;
 37                         break;
 38 
 39                 case TCF_EM_ALIGN_U16:
 40                         val = *ptr << 8;
 41                         val |= *(ptr+1);
 42 
 43                         if (cmp_needs_transformation(cmp))
 44                                 val = be16_to_cpu(val);
 45                         break;
 46 
 47                 case TCF_EM_ALIGN_U32:
 48                         /* Worth checking boundries? The branching seems
 49                          * to get worse. Visit again. */
 50                         val = *ptr << 24;
 51                         val |= *(ptr+1) << 16;
 52                         val |= *(ptr+2) << 8;
 53                         val |= *(ptr+3);
 54 
 55                         if (cmp_needs_transformation(cmp))
 56                                 val = be32_to_cpu(val);
 57                         break;
 58 
 59                 default:
 60                         return 0;
 61         }
 62 
 63         if (cmp->mask)
 64                 val &= cmp->mask;
 65 
 66         switch (cmp->opnd) {
 67                 case TCF_EM_OPND_EQ:
 68                         return val == cmp->val;
 69                 case TCF_EM_OPND_LT:
 70                         return val < cmp->val;
 71                 case TCF_EM_OPND_GT:
 72                         return val > cmp->val;
 73         }
 74 
 75         return 0;
 76 }
 77 
 78 static struct tcf_ematch_ops em_cmp_ops = {
 79         .kind     = TCF_EM_CMP,
 80         .datalen  = sizeof(struct tcf_em_cmp),
 81         .match    = em_cmp_match,
 82         .owner    = THIS_MODULE,
 83         .link     = LIST_HEAD_INIT(em_cmp_ops.link)
 84 };
 85 
 86 static int __init init_em_cmp(void)
 87 {
 88         return tcf_em_register(&em_cmp_ops);
 89 }
 90 
 91 static void __exit exit_em_cmp(void)
 92 {
 93         tcf_em_unregister(&em_cmp_ops);
 94 }
 95 
 96 MODULE_LICENSE("GPL");
 97 
 98 module_init(init_em_cmp);
 99 module_exit(exit_em_cmp);
100 
101 MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);
102 
  This page was automatically generated by the LXR engine.