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 <asm/unaligned.h>
 18 #include <net/pkt_cls.h>
 19 
 20 static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
 21 {
 22         return unlikely(cmp->flags & TCF_EM_CMP_TRANS);
 23 }
 24 
 25 static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
 26                         struct tcf_pkt_info *info)
 27 {
 28         struct tcf_em_cmp *cmp = (struct tcf_em_cmp *) em->data;
 29         unsigned char *ptr = tcf_get_base_ptr(skb, cmp->layer) + cmp->off;
 30         u32 val = 0;
 31 
 32         if (!tcf_valid_offset(skb, ptr, cmp->align))
 33                 return 0;
 34 
 35         switch (cmp->align) {
 36                 case TCF_EM_ALIGN_U8:
 37                         val = *ptr;
 38                         break;
 39 
 40                 case TCF_EM_ALIGN_U16:
 41                         val = get_unaligned_be16(ptr);
 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 = get_unaligned_be32(ptr);
 51 
 52                         if (cmp_needs_transformation(cmp))
 53                                 val = be32_to_cpu(val);
 54                         break;
 55 
 56                 default:
 57                         return 0;
 58         }
 59 
 60         if (cmp->mask)
 61                 val &= cmp->mask;
 62 
 63         switch (cmp->opnd) {
 64                 case TCF_EM_OPND_EQ:
 65                         return val == cmp->val;
 66                 case TCF_EM_OPND_LT:
 67                         return val < cmp->val;
 68                 case TCF_EM_OPND_GT:
 69                         return val > cmp->val;
 70         }
 71 
 72         return 0;
 73 }
 74 
 75 static struct tcf_ematch_ops em_cmp_ops = {
 76         .kind     = TCF_EM_CMP,
 77         .datalen  = sizeof(struct tcf_em_cmp),
 78         .match    = em_cmp_match,
 79         .owner    = THIS_MODULE,
 80         .link     = LIST_HEAD_INIT(em_cmp_ops.link)
 81 };
 82 
 83 static int __init init_em_cmp(void)
 84 {
 85         return tcf_em_register(&em_cmp_ops);
 86 }
 87 
 88 static void __exit exit_em_cmp(void)
 89 {
 90         tcf_em_unregister(&em_cmp_ops);
 91 }
 92 
 93 MODULE_LICENSE("GPL");
 94 
 95 module_init(init_em_cmp);
 96 module_exit(exit_em_cmp);
 97 
 98 MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);
 99 
  This page was automatically generated by the LXR engine.