Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * net/sched/em_meta.c	Metadata ematch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Authors:	Thomas Graf <tgraf@suug.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * ==========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * 	The metadata ematch compares two meta objects where each object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * 	represents either a meta value stored in the kernel or a static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * 	value provided by userspace. The objects are not provided by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * 	userspace itself but rather a definition providing the information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * 	to build them. Every object is of a certain type which must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * 	equal to the object it is being compared to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * 	The definition of a objects conists of the type (meta type), a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * 	identifier (meta id) and additional type specific information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * 	The meta id is either TCF_META_TYPE_VALUE for values provided by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * 	userspace or a index to the meta operations table consisting of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * 	function pointers to type specific meta data collectors returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * 	the value of the requested meta value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  * 	         lvalue                                   rvalue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * 	      +-----------+                           +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * 	      | type: INT |                           | type: INT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * 	 def  | id: DEV   |                           | id: VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  * 	      | data:     |                           | data: 3   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  * 	      +-----------+                           +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  * 	            |                                       |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * 	            ---> meta_ops[INT][DEV](...)            |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  *	                      |                             |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  * 	            -----------                             |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  * 	            V                                       V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  * 	      +-----------+                           +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  * 	      | type: INT |                           | type: INT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  * 	 obj  | id: DEV |                             | id: VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * 	      | data: 2   |<--data got filled out     | data: 3   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * 	      +-----------+                           +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  * 	            |                                         |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  * 	            --------------> 2  equals 3 <--------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  * 	This is a simplified schema, the complexity varies depending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  * 	on the meta type. Obviously, the length of the data must also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  * 	be provided for non-numeric types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  * 	Additionally, type dependent modifiers such as shift operators
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  * 	or mask may be applied to extend the functionaliy. As of now,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  * 	the variable length type supports shifting the byte string to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  * 	the right, eating up any number of octets and thus supporting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  * 	wildcard interface name comparisons such as "ppp%" matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  * 	ppp0..9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53)  * 	NOTE: Certain meta values depend on other subsystems and are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * 	      only available if that subsystem is enabled in the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <linux/sched/loadavg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #include <linux/tc_ematch/tc_em_meta.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #include <net/dst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #include <net/route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #include <net/pkt_cls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) struct meta_obj {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	unsigned long		value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	unsigned int		len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) struct meta_value {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	struct tcf_meta_val	hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	unsigned long		val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	unsigned int		len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) struct meta_match {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	struct meta_value	lvalue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	struct meta_value	rvalue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static inline int meta_id(struct meta_value *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	return TCF_META_ID(v->hdr.kind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static inline int meta_type(struct meta_value *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	return TCF_META_TYPE(v->hdr.kind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define META_COLLECTOR(FUNC) static void meta_##FUNC(struct sk_buff *skb, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	struct tcf_pkt_info *info, struct meta_value *v, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct meta_obj *dst, int *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  * System status & misc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) META_COLLECTOR(int_random)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	get_random_bytes(&dst->value, sizeof(dst->value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) static inline unsigned long fixed_loadavg(int load)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	int rnd_load = load + (FIXED_1/200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	int rnd_frac = ((rnd_load & (FIXED_1-1)) * 100) >> FSHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	return ((rnd_load >> FSHIFT) * 100) + rnd_frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) META_COLLECTOR(int_loadavg_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	dst->value = fixed_loadavg(avenrun[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) META_COLLECTOR(int_loadavg_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	dst->value = fixed_loadavg(avenrun[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) META_COLLECTOR(int_loadavg_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	dst->value = fixed_loadavg(avenrun[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  * Device names & indices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static inline int int_dev(struct net_device *dev, struct meta_obj *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	if (unlikely(dev == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	dst->value = dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) static inline int var_dev(struct net_device *dev, struct meta_obj *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	if (unlikely(dev == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	dst->value = (unsigned long) dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	dst->len = strlen(dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) META_COLLECTOR(int_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	*err = int_dev(skb->dev, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) META_COLLECTOR(var_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	*err = var_dev(skb->dev, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * vlan tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) META_COLLECTOR(int_vlan_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	unsigned short tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	if (skb_vlan_tag_present(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		dst->value = skb_vlan_tag_get(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	else if (!__vlan_get_tag(skb, &tag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		dst->value = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)  * skb attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) META_COLLECTOR(int_priority)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	dst->value = skb->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) META_COLLECTOR(int_protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	/* Let userspace take care of the byte ordering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	dst->value = skb_protocol(skb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) META_COLLECTOR(int_pkttype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	dst->value = skb->pkt_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) META_COLLECTOR(int_pktlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	dst->value = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) META_COLLECTOR(int_datalen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	dst->value = skb->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) META_COLLECTOR(int_maclen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	dst->value = skb->mac_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) META_COLLECTOR(int_rxhash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	dst->value = skb_get_hash(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)  * Netfilter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) META_COLLECTOR(int_mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	dst->value = skb->mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236)  * Traffic Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) META_COLLECTOR(int_tcindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	dst->value = skb->tc_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  * Routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) META_COLLECTOR(int_rtclassid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	if (unlikely(skb_dst(skb) == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) #ifdef CONFIG_IP_ROUTE_CLASSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		dst->value = skb_dst(skb)->tclassid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		dst->value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) META_COLLECTOR(int_rtiif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	if (unlikely(skb_rtable(skb) == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		dst->value = inet_iif(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269)  * Socket Attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) #define skip_nonlocal(skb) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	(unlikely(skb->sk == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) META_COLLECTOR(int_sk_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	if (skip_nonlocal(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	dst->value = skb->sk->sk_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) META_COLLECTOR(int_sk_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	if (skip_nonlocal(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	dst->value = skb->sk->sk_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) META_COLLECTOR(int_sk_reuse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	if (skip_nonlocal(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	dst->value = skb->sk->sk_reuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) META_COLLECTOR(int_sk_bound_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	if (skip_nonlocal(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	/* No error if bound_dev_if is 0, legal userspace check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	dst->value = skb->sk->sk_bound_dev_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) META_COLLECTOR(var_sk_bound_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	if (skip_nonlocal(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	if (skb->sk->sk_bound_dev_if == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		dst->value = (unsigned long) "any";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		dst->len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		dev = dev_get_by_index_rcu(sock_net(skb->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 					   skb->sk->sk_bound_dev_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		*err = var_dev(dev, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) META_COLLECTOR(int_sk_refcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	if (skip_nonlocal(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	dst->value = refcount_read(&skb->sk->sk_refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) META_COLLECTOR(int_sk_rcvbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	dst->value = sk->sk_rcvbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) META_COLLECTOR(int_sk_shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	dst->value = sk->sk_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) META_COLLECTOR(int_sk_proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	dst->value = sk->sk_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) META_COLLECTOR(int_sk_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	dst->value = sk->sk_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) META_COLLECTOR(int_sk_rmem_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	dst->value = sk_rmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) META_COLLECTOR(int_sk_wmem_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	dst->value = sk_wmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) META_COLLECTOR(int_sk_omem_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	dst->value = atomic_read(&sk->sk_omem_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) META_COLLECTOR(int_sk_rcv_qlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	dst->value = sk->sk_receive_queue.qlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) META_COLLECTOR(int_sk_snd_qlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	dst->value = sk->sk_write_queue.qlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) META_COLLECTOR(int_sk_wmem_queued)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	dst->value = READ_ONCE(sk->sk_wmem_queued);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) META_COLLECTOR(int_sk_fwd_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	dst->value = sk->sk_forward_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) META_COLLECTOR(int_sk_sndbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	dst->value = sk->sk_sndbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) META_COLLECTOR(int_sk_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	dst->value = (__force int) sk->sk_allocation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) META_COLLECTOR(int_sk_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	if (skip_nonlocal(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	dst->value = skb->sk->sk_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) META_COLLECTOR(int_sk_lingertime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	dst->value = sk->sk_lingertime / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) META_COLLECTOR(int_sk_err_qlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	dst->value = sk->sk_error_queue.qlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) META_COLLECTOR(int_sk_ack_bl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	dst->value = READ_ONCE(sk->sk_ack_backlog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) META_COLLECTOR(int_sk_max_ack_bl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	dst->value = READ_ONCE(sk->sk_max_ack_backlog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) META_COLLECTOR(int_sk_prio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	dst->value = sk->sk_priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) META_COLLECTOR(int_sk_rcvlowat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	dst->value = READ_ONCE(sk->sk_rcvlowat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) META_COLLECTOR(int_sk_rcvtimeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	dst->value = sk->sk_rcvtimeo / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) META_COLLECTOR(int_sk_sndtimeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	dst->value = sk->sk_sndtimeo / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) META_COLLECTOR(int_sk_sendmsg_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	dst->value = sk->sk_frag.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) META_COLLECTOR(int_sk_write_pend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	const struct sock *sk = skb_to_full_sk(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		*err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	dst->value = sk->sk_write_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)  * Meta value collectors assignment table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) struct meta_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	void		(*get)(struct sk_buff *, struct tcf_pkt_info *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 			       struct meta_value *, struct meta_obj *, int *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) #define META_ID(name) TCF_META_ID_##name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) #define META_FUNC(name) { .get = meta_##name }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) /* Meta value operations table listing all meta value collectors and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617)  * assigns them to a type and meta id. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) static struct meta_ops __meta_ops[TCF_META_TYPE_MAX + 1][TCF_META_ID_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	[TCF_META_TYPE_VAR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		[META_ID(DEV)]			= META_FUNC(var_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		[META_ID(SK_BOUND_IF)] 		= META_FUNC(var_sk_bound_if),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	[TCF_META_TYPE_INT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		[META_ID(RANDOM)]		= META_FUNC(int_random),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		[META_ID(LOADAVG_0)]		= META_FUNC(int_loadavg_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		[META_ID(LOADAVG_1)]		= META_FUNC(int_loadavg_1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		[META_ID(LOADAVG_2)]		= META_FUNC(int_loadavg_2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		[META_ID(DEV)]			= META_FUNC(int_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		[META_ID(PRIORITY)]		= META_FUNC(int_priority),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		[META_ID(PROTOCOL)]		= META_FUNC(int_protocol),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		[META_ID(PKTTYPE)]		= META_FUNC(int_pkttype),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		[META_ID(PKTLEN)]		= META_FUNC(int_pktlen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		[META_ID(DATALEN)]		= META_FUNC(int_datalen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		[META_ID(MACLEN)]		= META_FUNC(int_maclen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		[META_ID(NFMARK)]		= META_FUNC(int_mark),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		[META_ID(TCINDEX)]		= META_FUNC(int_tcindex),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		[META_ID(RTCLASSID)]		= META_FUNC(int_rtclassid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		[META_ID(RTIIF)]		= META_FUNC(int_rtiif),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		[META_ID(SK_FAMILY)]		= META_FUNC(int_sk_family),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		[META_ID(SK_STATE)]		= META_FUNC(int_sk_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		[META_ID(SK_REUSE)]		= META_FUNC(int_sk_reuse),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		[META_ID(SK_BOUND_IF)]		= META_FUNC(int_sk_bound_if),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		[META_ID(SK_REFCNT)]		= META_FUNC(int_sk_refcnt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		[META_ID(SK_RCVBUF)]		= META_FUNC(int_sk_rcvbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		[META_ID(SK_SNDBUF)]		= META_FUNC(int_sk_sndbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		[META_ID(SK_SHUTDOWN)]		= META_FUNC(int_sk_shutdown),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		[META_ID(SK_PROTO)]		= META_FUNC(int_sk_proto),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		[META_ID(SK_TYPE)]		= META_FUNC(int_sk_type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		[META_ID(SK_RMEM_ALLOC)]	= META_FUNC(int_sk_rmem_alloc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		[META_ID(SK_WMEM_ALLOC)]	= META_FUNC(int_sk_wmem_alloc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		[META_ID(SK_OMEM_ALLOC)]	= META_FUNC(int_sk_omem_alloc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		[META_ID(SK_WMEM_QUEUED)]	= META_FUNC(int_sk_wmem_queued),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		[META_ID(SK_RCV_QLEN)]		= META_FUNC(int_sk_rcv_qlen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		[META_ID(SK_SND_QLEN)]		= META_FUNC(int_sk_snd_qlen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		[META_ID(SK_ERR_QLEN)]		= META_FUNC(int_sk_err_qlen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		[META_ID(SK_FORWARD_ALLOCS)]	= META_FUNC(int_sk_fwd_alloc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		[META_ID(SK_ALLOCS)]		= META_FUNC(int_sk_alloc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		[META_ID(SK_HASH)]		= META_FUNC(int_sk_hash),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		[META_ID(SK_LINGERTIME)]	= META_FUNC(int_sk_lingertime),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		[META_ID(SK_ACK_BACKLOG)]	= META_FUNC(int_sk_ack_bl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		[META_ID(SK_MAX_ACK_BACKLOG)]	= META_FUNC(int_sk_max_ack_bl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		[META_ID(SK_PRIO)]		= META_FUNC(int_sk_prio),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		[META_ID(SK_RCVLOWAT)]		= META_FUNC(int_sk_rcvlowat),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		[META_ID(SK_RCVTIMEO)]		= META_FUNC(int_sk_rcvtimeo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		[META_ID(SK_SNDTIMEO)]		= META_FUNC(int_sk_sndtimeo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		[META_ID(SK_SENDMSG_OFF)]	= META_FUNC(int_sk_sendmsg_off),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		[META_ID(SK_WRITE_PENDING)]	= META_FUNC(int_sk_write_pend),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		[META_ID(VLAN_TAG)]		= META_FUNC(int_vlan_tag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		[META_ID(RXHASH)]		= META_FUNC(int_rxhash),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) static inline struct meta_ops *meta_ops(struct meta_value *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	return &__meta_ops[meta_type(val)][meta_id(val)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679)  * Type specific operations for TCF_META_TYPE_VAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) static int meta_var_compare(struct meta_obj *a, struct meta_obj *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	int r = a->len - b->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	if (r == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		r = memcmp((void *) a->value, (void *) b->value, a->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) static int meta_var_change(struct meta_value *dst, struct nlattr *nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	int len = nla_len(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	dst->val = (unsigned long)kmemdup(nla_data(nla), len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	if (dst->val == 0UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	dst->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) static void meta_var_destroy(struct meta_value *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	kfree((void *) v->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) static void meta_var_apply_extras(struct meta_value *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 				  struct meta_obj *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	int shift = v->hdr.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	if (shift && shift < dst->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		dst->len -= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) static int meta_var_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (v->val && v->len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	    nla_put(skb, tlv, v->len, (void *) v->val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729)  * Type specific operations for TCF_META_TYPE_INT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) static int meta_int_compare(struct meta_obj *a, struct meta_obj *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	/* Let gcc optimize it, the unlikely is not really based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	 * some numbers but jump free code for mismatches seems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	 * more logical. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	if (unlikely(a->value == b->value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	else if (a->value < b->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) static int meta_int_change(struct meta_value *dst, struct nlattr *nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	if (nla_len(nla) >= sizeof(unsigned long)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		dst->val = *(unsigned long *) nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		dst->len = sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	} else if (nla_len(nla) == sizeof(u32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		dst->val = nla_get_u32(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		dst->len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) static void meta_int_apply_extras(struct meta_value *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 				  struct meta_obj *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	if (v->hdr.shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		dst->value >>= v->hdr.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (v->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		dst->value &= v->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	if (v->len == sizeof(unsigned long)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		if (nla_put(skb, tlv, sizeof(unsigned long), &v->val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	} else if (v->len == sizeof(u32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		if (nla_put_u32(skb, tlv, v->val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786)  * Type specific operations table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) struct meta_type_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	void	(*destroy)(struct meta_value *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	int	(*compare)(struct meta_obj *, struct meta_obj *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	int	(*change)(struct meta_value *, struct nlattr *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	void	(*apply_extras)(struct meta_value *, struct meta_obj *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	int	(*dump)(struct sk_buff *, struct meta_value *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) static const struct meta_type_ops __meta_type_ops[TCF_META_TYPE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	[TCF_META_TYPE_VAR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		.destroy = meta_var_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		.compare = meta_var_compare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		.change = meta_var_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		.apply_extras = meta_var_apply_extras,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		.dump = meta_var_dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	[TCF_META_TYPE_INT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		.compare = meta_int_compare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		.change = meta_int_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		.apply_extras = meta_int_apply_extras,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		.dump = meta_int_dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) static inline const struct meta_type_ops *meta_type_ops(struct meta_value *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	return &__meta_type_ops[meta_type(v)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819)  * Core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) static int meta_get(struct sk_buff *skb, struct tcf_pkt_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		    struct meta_value *v, struct meta_obj *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (meta_id(v) == TCF_META_ID_VALUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		dst->value = v->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		dst->len = v->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	meta_ops(v)->get(skb, info, v, dst, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	if (meta_type_ops(v)->apply_extras)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		meta_type_ops(v)->apply_extras(v, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) static int em_meta_match(struct sk_buff *skb, struct tcf_ematch *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			 struct tcf_pkt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	struct meta_match *meta = (struct meta_match *) m->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	struct meta_obj l_value, r_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	if (meta_get(skb, info, &meta->lvalue, &l_value) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	    meta_get(skb, info, &meta->rvalue, &r_value) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	r = meta_type_ops(&meta->lvalue)->compare(&l_value, &r_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	switch (meta->lvalue.hdr.op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	case TCF_EM_OPND_EQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		return !r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	case TCF_EM_OPND_LT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		return r < 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	case TCF_EM_OPND_GT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		return r > 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) static void meta_delete(struct meta_match *meta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	if (meta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		const struct meta_type_ops *ops = meta_type_ops(&meta->lvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		if (ops && ops->destroy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			ops->destroy(&meta->lvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			ops->destroy(&meta->rvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	kfree(meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) static inline int meta_change_data(struct meta_value *dst, struct nlattr *nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	if (nla) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		if (nla_len(nla) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		return meta_type_ops(dst)->change(dst, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) static inline int meta_is_supported(struct meta_value *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	return !meta_id(val) || meta_ops(val)->get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) static const struct nla_policy meta_policy[TCA_EM_META_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	[TCA_EM_META_HDR]	= { .len = sizeof(struct tcf_meta_hdr) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) static int em_meta_change(struct net *net, void *data, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			  struct tcf_ematch *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	struct nlattr *tb[TCA_EM_META_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	struct tcf_meta_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	struct meta_match *meta = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	err = nla_parse_deprecated(tb, TCA_EM_META_MAX, data, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 				   meta_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	if (tb[TCA_EM_META_HDR] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	hdr = nla_data(tb[TCA_EM_META_HDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if (TCF_META_TYPE(hdr->left.kind) != TCF_META_TYPE(hdr->right.kind) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	    TCF_META_TYPE(hdr->left.kind) > TCF_META_TYPE_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	    TCF_META_ID(hdr->left.kind) > TCF_META_ID_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	    TCF_META_ID(hdr->right.kind) > TCF_META_ID_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	meta = kzalloc(sizeof(*meta), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	if (meta == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	memcpy(&meta->lvalue.hdr, &hdr->left, sizeof(hdr->left));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	memcpy(&meta->rvalue.hdr, &hdr->right, sizeof(hdr->right));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	if (!meta_is_supported(&meta->lvalue) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	    !meta_is_supported(&meta->rvalue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	if (meta_change_data(&meta->lvalue, tb[TCA_EM_META_LVALUE]) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	    meta_change_data(&meta->rvalue, tb[TCA_EM_META_RVALUE]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	m->datalen = sizeof(*meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	m->data = (unsigned long) meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) errout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	if (err && meta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		meta_delete(meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) static void em_meta_destroy(struct tcf_ematch *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	if (m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		meta_delete((struct meta_match *) m->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) static int em_meta_dump(struct sk_buff *skb, struct tcf_ematch *em)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	struct meta_match *meta = (struct meta_match *) em->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	struct tcf_meta_hdr hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	const struct meta_type_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	memset(&hdr, 0, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	memcpy(&hdr.left, &meta->lvalue.hdr, sizeof(hdr.left));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	memcpy(&hdr.right, &meta->rvalue.hdr, sizeof(hdr.right));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	if (nla_put(skb, TCA_EM_META_HDR, sizeof(hdr), &hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	ops = meta_type_ops(&meta->lvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	if (ops->dump(skb, &meta->lvalue, TCA_EM_META_LVALUE) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	    ops->dump(skb, &meta->rvalue, TCA_EM_META_RVALUE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) static struct tcf_ematch_ops em_meta_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	.kind	  = TCF_EM_META,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	.change	  = em_meta_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	.match	  = em_meta_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	.destroy  = em_meta_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	.dump	  = em_meta_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	.owner	  = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	.link	  = LIST_HEAD_INIT(em_meta_ops.link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) static int __init init_em_meta(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	return tcf_em_register(&em_meta_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static void __exit exit_em_meta(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	tcf_em_unregister(&em_meta_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) module_init(init_em_meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) module_exit(exit_em_meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) MODULE_ALIAS_TCF_EMATCH(TCF_EM_META);