18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * net/sched/em_u32.c U32 Ematch 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Authors: Thomas Graf <tgraf@suug.ch> 68c2ecf20Sopenharmony_ci * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Based on net/sched/cls_u32.c 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/types.h> 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 158c2ecf20Sopenharmony_ci#include <net/pkt_cls.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic int em_u32_match(struct sk_buff *skb, struct tcf_ematch *em, 188c2ecf20Sopenharmony_ci struct tcf_pkt_info *info) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci struct tc_u32_key *key = (struct tc_u32_key *) em->data; 218c2ecf20Sopenharmony_ci const unsigned char *ptr = skb_network_header(skb); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci if (info) { 248c2ecf20Sopenharmony_ci if (info->ptr) 258c2ecf20Sopenharmony_ci ptr = info->ptr; 268c2ecf20Sopenharmony_ci ptr += (info->nexthdr & key->offmask); 278c2ecf20Sopenharmony_ci } 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci ptr += key->off; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci if (!tcf_valid_offset(skb, ptr, sizeof(u32))) 328c2ecf20Sopenharmony_ci return 0; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci return !(((*(__be32 *) ptr) ^ key->val) & key->mask); 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic struct tcf_ematch_ops em_u32_ops = { 388c2ecf20Sopenharmony_ci .kind = TCF_EM_U32, 398c2ecf20Sopenharmony_ci .datalen = sizeof(struct tc_u32_key), 408c2ecf20Sopenharmony_ci .match = em_u32_match, 418c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 428c2ecf20Sopenharmony_ci .link = LIST_HEAD_INIT(em_u32_ops.link) 438c2ecf20Sopenharmony_ci}; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic int __init init_em_u32(void) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci return tcf_em_register(&em_u32_ops); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic void __exit exit_em_u32(void) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci tcf_em_unregister(&em_u32_ops); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cimodule_init(init_em_u32); 588c2ecf20Sopenharmony_cimodule_exit(exit_em_u32); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ciMODULE_ALIAS_TCF_EMATCH(TCF_EM_U32); 61