cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

em_cmp.c (1913B)


      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
     16static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
     17{
     18	return unlikely(cmp->flags & TCF_EM_CMP_TRANS);
     19}
     20
     21static 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 boundaries? 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
     72static 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
     80static int __init init_em_cmp(void)
     81{
     82	return tcf_em_register(&em_cmp_ops);
     83}
     84
     85static void __exit exit_em_cmp(void)
     86{
     87	tcf_em_unregister(&em_cmp_ops);
     88}
     89
     90MODULE_LICENSE("GPL");
     91
     92module_init(init_em_cmp);
     93module_exit(exit_em_cmp);
     94
     95MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);