/* * net/sched/cls_u32.c Ugly (or Universal) 32bit key Packet Classifier. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> * * The filters are packed to hash tables of key nodes * with a set of 32bit key/mask pairs at every node. * Nodes reference next level hash tables etc. * * This scheme is the best universal classifier I managed to * invent; it is not super-fast, but it is not slow (provided you * program it correctly), and general enough. And its relative * speed grows as the number of rules becomes larger. * * It seems that it represents the best middle point between * speed and manageability both by human and by machine. * * It is especially useful for link sharing combined with QoS; * pure RSVP doesn't need such a general approach and can use * much simpler (and faster) schemes, sort of cls_rsvp.c. * * JHS: We should remove the CONFIG_NET_CLS_IND from here * eventually when the meta match extension is made available * * nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro> */#include<linux/module.h>#include<linux/slab.h>#include<linux/types.h>#include<linux/kernel.h>#include<linux/string.h>#include<linux/errno.h>#include<linux/percpu.h>#include<linux/rtnetlink.h>#include<linux/skbuff.h>#include<linux/bitmap.h>#include<linux/netdevice.h>#include<linux/hash.h>#include<net/netlink.h>#include<net/act_api.h>#include<net/pkt_cls.h>#include<linux/netdevice.h>#include<linux/idr.h>structtc_u_knode{structtc_u_knode__rcu*next;u32handle;structtc_u_hnode__rcu*ht_up;structtcf_extsexts;#ifdef CONFIG_NET_CLS_INDintifindex;#endifu8fshift;structtcf_resultres;structtc_u_hnode__rcu*ht_down;#ifdef CONFIG_CLS_U32_PERFstructtc_u32_pcnt__percpu*pf;#endifu32flags;#ifdef CONFIG_CLS_U32_MARKu32val;u32mask;u32__percpu*pcpu_success;#endifstructtcf_proto*tp;union{structwork_structwork;structrcu_headrcu;};/* The 'sel' field MUST be the last field in structure to allow for * tc_u32_keys allocated at end of structure. */structtc_u32_selsel;};structtc_u_hnode{structtc_u_hnode__rcu*next;u32handle;u32prio;structtc_u_common*tp_c;intrefcnt;unsignedintdivisor;structidrhandle_idr;structrcu_headrcu;/* The 'ht' field MUST be the last field in structure to allow for * more entries allocated at end of structure. */structtc_u_knode__rcu*ht[1];};structtc_u_common{structtc_u_hnode__rcu*hlist;structtcf_block*block;