1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * net/sched/em_u32.c U32 Ematch 4 * 5 * Authors: Thomas Graf <tgraf@suug.ch> 6 * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 7 * 8 * Based on net/sched/cls_u32.c 9 */ 10 11 #include <linux/module.h> 12 #include <linux/types.h> 13 #include <linux/kernel.h> 14 #include <linux/skbuff.h> 15 #include <net/pkt_cls.h> 16 17 static int em_u32_match(struct sk_buff *skb, struct tcf_ematch *em, 18 struct tcf_pkt_info *info) 19 { 20 struct tc_u32_key *key = (struct tc_u32_key *) em->data; 21 const unsigned char *ptr = skb_network_header(skb); 22 23 if (info) { 24 if (info->ptr) 25 ptr = info->ptr; 26 ptr += (info->nexthdr & key->offmask); 27 } 28 29 ptr += key->off; 30 31 if (!tcf_valid_offset(skb, ptr, sizeof(u32))) 32 return 0; 33 34 return !(((*(__be32 *) ptr) ^ key->val) & key->mask); 35 } 36 37 static struct tcf_ematch_ops em_u32_ops = { 38 .kind = TCF_EM_U32, 39 .datalen = sizeof(struct tc_u32_key), 40 .match = em_u32_match, 41 .owner = THIS_MODULE, 42 .link = LIST_HEAD_INIT(em_u32_ops.link) 43 }; 44 45 static int __init init_em_u32(void) 46 { 47 return tcf_em_register(&em_u32_ops); 48 } 49 50 static void __exit exit_em_u32(void) 51 { 52 tcf_em_unregister(&em_u32_ops); 53 } 54 55 MODULE_LICENSE("GPL"); 56 57 module_init(init_em_u32); 58 module_exit(exit_em_u32); 59 60 MODULE_ALIAS_TCF_EMATCH(TCF_EM_U32); 61