em_meta.c (c7066f70d9610df0b9406cc635fc09e86136e714) em_meta.c (cc7ec456f82da7f89a5b376e613b3ac4311b3e9a)
1/*
2 * net/sched/em_meta.c Metadata ematch
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 59 unchanged lines hidden (view full) ---

68#include <linux/random.h>
69#include <linux/if_vlan.h>
70#include <linux/tc_ematch/tc_em_meta.h>
71#include <net/dst.h>
72#include <net/route.h>
73#include <net/pkt_cls.h>
74#include <net/sock.h>
75
1/*
2 * net/sched/em_meta.c Metadata ematch
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 59 unchanged lines hidden (view full) ---

68#include <linux/random.h>
69#include <linux/if_vlan.h>
70#include <linux/tc_ematch/tc_em_meta.h>
71#include <net/dst.h>
72#include <net/route.h>
73#include <net/pkt_cls.h>
74#include <net/sock.h>
75
76struct meta_obj
77{
76struct meta_obj {
78 unsigned long value;
79 unsigned int len;
80};
81
77 unsigned long value;
78 unsigned int len;
79};
80
82struct meta_value
83{
81struct meta_value {
84 struct tcf_meta_val hdr;
85 unsigned long val;
86 unsigned int len;
87};
88
82 struct tcf_meta_val hdr;
83 unsigned long val;
84 unsigned int len;
85};
86
89struct meta_match
90{
87struct meta_match {
91 struct meta_value lvalue;
92 struct meta_value rvalue;
93};
94
95static inline int meta_id(struct meta_value *v)
96{
97 return TCF_META_ID(v->hdr.kind);
98}

--- 151 unchanged lines hidden (view full) ---

250 * Routing
251 **************************************************************************/
252
253META_COLLECTOR(int_rtclassid)
254{
255 if (unlikely(skb_dst(skb) == NULL))
256 *err = -1;
257 else
88 struct meta_value lvalue;
89 struct meta_value rvalue;
90};
91
92static inline int meta_id(struct meta_value *v)
93{
94 return TCF_META_ID(v->hdr.kind);
95}

--- 151 unchanged lines hidden (view full) ---

247 * Routing
248 **************************************************************************/
249
250META_COLLECTOR(int_rtclassid)
251{
252 if (unlikely(skb_dst(skb) == NULL))
253 *err = -1;
254 else
258#ifdef CONFIG_IP_ROUTE_CLASSID
255#ifdef CONFIG_NET_CLS_ROUTE
259 dst->value = skb_dst(skb)->tclassid;
260#else
261 dst->value = 0;
262#endif
263}
264
265META_COLLECTOR(int_rtiif)
266{

--- 211 unchanged lines hidden (view full) ---

478 SKIP_NONLOCAL(skb);
479 dst->value = skb->sk->sk_write_pending;
480}
481
482/**************************************************************************
483 * Meta value collectors assignment table
484 **************************************************************************/
485
256 dst->value = skb_dst(skb)->tclassid;
257#else
258 dst->value = 0;
259#endif
260}
261
262META_COLLECTOR(int_rtiif)
263{

--- 211 unchanged lines hidden (view full) ---

475 SKIP_NONLOCAL(skb);
476 dst->value = skb->sk->sk_write_pending;
477}
478
479/**************************************************************************
480 * Meta value collectors assignment table
481 **************************************************************************/
482
486struct meta_ops
487{
483struct meta_ops {
488 void (*get)(struct sk_buff *, struct tcf_pkt_info *,
489 struct meta_value *, struct meta_obj *, int *);
490};
491
492#define META_ID(name) TCF_META_ID_##name
493#define META_FUNC(name) { .get = meta_##name }
494
495/* Meta value operations table listing all meta value collectors and
496 * assigns them to a type and meta id. */
484 void (*get)(struct sk_buff *, struct tcf_pkt_info *,
485 struct meta_value *, struct meta_obj *, int *);
486};
487
488#define META_ID(name) TCF_META_ID_##name
489#define META_FUNC(name) { .get = meta_##name }
490
491/* Meta value operations table listing all meta value collectors and
492 * assigns them to a type and meta id. */
497static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
493static struct meta_ops __meta_ops[TCF_META_TYPE_MAX + 1][TCF_META_ID_MAX + 1] = {
498 [TCF_META_TYPE_VAR] = {
499 [META_ID(DEV)] = META_FUNC(var_dev),
500 [META_ID(SK_BOUND_IF)] = META_FUNC(var_sk_bound_if),
501 },
502 [TCF_META_TYPE_INT] = {
503 [META_ID(RANDOM)] = META_FUNC(int_random),
504 [META_ID(LOADAVG_0)] = META_FUNC(int_loadavg_0),
505 [META_ID(LOADAVG_1)] = META_FUNC(int_loadavg_1),

--- 39 unchanged lines hidden (view full) ---

545 [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo),
546 [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off),
547 [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend),
548 [META_ID(VLAN_TAG)] = META_FUNC(int_vlan_tag),
549 [META_ID(RXHASH)] = META_FUNC(int_rxhash),
550 }
551};
552
494 [TCF_META_TYPE_VAR] = {
495 [META_ID(DEV)] = META_FUNC(var_dev),
496 [META_ID(SK_BOUND_IF)] = META_FUNC(var_sk_bound_if),
497 },
498 [TCF_META_TYPE_INT] = {
499 [META_ID(RANDOM)] = META_FUNC(int_random),
500 [META_ID(LOADAVG_0)] = META_FUNC(int_loadavg_0),
501 [META_ID(LOADAVG_1)] = META_FUNC(int_loadavg_1),

--- 39 unchanged lines hidden (view full) ---

541 [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo),
542 [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off),
543 [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend),
544 [META_ID(VLAN_TAG)] = META_FUNC(int_vlan_tag),
545 [META_ID(RXHASH)] = META_FUNC(int_rxhash),
546 }
547};
548
553static inline struct meta_ops * meta_ops(struct meta_value *val)
549static inline struct meta_ops *meta_ops(struct meta_value *val)
554{
555 return &__meta_ops[meta_type(val)][meta_id(val)];
556}
557
558/**************************************************************************
559 * Type specific operations for TCF_META_TYPE_VAR
560 **************************************************************************/
561

--- 82 unchanged lines hidden (view full) ---

644 if (v->val)
645 dst->value &= v->val;
646}
647
648static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
649{
650 if (v->len == sizeof(unsigned long))
651 NLA_PUT(skb, tlv, sizeof(unsigned long), &v->val);
550{
551 return &__meta_ops[meta_type(val)][meta_id(val)];
552}
553
554/**************************************************************************
555 * Type specific operations for TCF_META_TYPE_VAR
556 **************************************************************************/
557

--- 82 unchanged lines hidden (view full) ---

640 if (v->val)
641 dst->value &= v->val;
642}
643
644static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
645{
646 if (v->len == sizeof(unsigned long))
647 NLA_PUT(skb, tlv, sizeof(unsigned long), &v->val);
652 else if (v->len == sizeof(u32)) {
648 else if (v->len == sizeof(u32))
653 NLA_PUT_U32(skb, tlv, v->val);
649 NLA_PUT_U32(skb, tlv, v->val);
654 }
655
656 return 0;
657
658nla_put_failure:
659 return -1;
660}
661
662/**************************************************************************
663 * Type specific operations table
664 **************************************************************************/
665
650
651 return 0;
652
653nla_put_failure:
654 return -1;
655}
656
657/**************************************************************************
658 * Type specific operations table
659 **************************************************************************/
660
666struct meta_type_ops
667{
661struct meta_type_ops {
668 void (*destroy)(struct meta_value *);
669 int (*compare)(struct meta_obj *, struct meta_obj *);
670 int (*change)(struct meta_value *, struct nlattr *);
671 void (*apply_extras)(struct meta_value *, struct meta_obj *);
672 int (*dump)(struct sk_buff *, struct meta_value *, int);
673};
674
662 void (*destroy)(struct meta_value *);
663 int (*compare)(struct meta_obj *, struct meta_obj *);
664 int (*change)(struct meta_value *, struct nlattr *);
665 void (*apply_extras)(struct meta_value *, struct meta_obj *);
666 int (*dump)(struct sk_buff *, struct meta_value *, int);
667};
668
675static struct meta_type_ops __meta_type_ops[TCF_META_TYPE_MAX+1] = {
669static struct meta_type_ops __meta_type_ops[TCF_META_TYPE_MAX + 1] = {
676 [TCF_META_TYPE_VAR] = {
677 .destroy = meta_var_destroy,
678 .compare = meta_var_compare,
679 .change = meta_var_change,
680 .apply_extras = meta_var_apply_extras,
681 .dump = meta_var_dump
682 },
683 [TCF_META_TYPE_INT] = {
684 .compare = meta_int_compare,
685 .change = meta_int_change,
686 .apply_extras = meta_int_apply_extras,
687 .dump = meta_int_dump
688 }
689};
690
670 [TCF_META_TYPE_VAR] = {
671 .destroy = meta_var_destroy,
672 .compare = meta_var_compare,
673 .change = meta_var_change,
674 .apply_extras = meta_var_apply_extras,
675 .dump = meta_var_dump
676 },
677 [TCF_META_TYPE_INT] = {
678 .compare = meta_int_compare,
679 .change = meta_int_change,
680 .apply_extras = meta_int_apply_extras,
681 .dump = meta_int_dump
682 }
683};
684
691static inline struct meta_type_ops * meta_type_ops(struct meta_value *v)
685static inline struct meta_type_ops *meta_type_ops(struct meta_value *v)
692{
693 return &__meta_type_ops[meta_type(v)];
694}
695
696/**************************************************************************
697 * Core
698 **************************************************************************/
699

--- 8 unchanged lines hidden (view full) ---

708 return 0;
709 }
710
711 meta_ops(v)->get(skb, info, v, dst, &err);
712 if (err < 0)
713 return err;
714
715 if (meta_type_ops(v)->apply_extras)
686{
687 return &__meta_type_ops[meta_type(v)];
688}
689
690/**************************************************************************
691 * Core
692 **************************************************************************/
693

--- 8 unchanged lines hidden (view full) ---

702 return 0;
703 }
704
705 meta_ops(v)->get(skb, info, v, dst, &err);
706 if (err < 0)
707 return err;
708
709 if (meta_type_ops(v)->apply_extras)
716 meta_type_ops(v)->apply_extras(v, dst);
710 meta_type_ops(v)->apply_extras(v, dst);
717
718 return 0;
719}
720
721static int em_meta_match(struct sk_buff *skb, struct tcf_ematch *m,
722 struct tcf_pkt_info *info)
723{
724 int r;
725 struct meta_match *meta = (struct meta_match *) m->data;
726 struct meta_obj l_value, r_value;
727
728 if (meta_get(skb, info, &meta->lvalue, &l_value) < 0 ||
729 meta_get(skb, info, &meta->rvalue, &r_value) < 0)
730 return 0;
731
732 r = meta_type_ops(&meta->lvalue)->compare(&l_value, &r_value);
733
734 switch (meta->lvalue.hdr.op) {
711
712 return 0;
713}
714
715static int em_meta_match(struct sk_buff *skb, struct tcf_ematch *m,
716 struct tcf_pkt_info *info)
717{
718 int r;
719 struct meta_match *meta = (struct meta_match *) m->data;
720 struct meta_obj l_value, r_value;
721
722 if (meta_get(skb, info, &meta->lvalue, &l_value) < 0 ||
723 meta_get(skb, info, &meta->rvalue, &r_value) < 0)
724 return 0;
725
726 r = meta_type_ops(&meta->lvalue)->compare(&l_value, &r_value);
727
728 switch (meta->lvalue.hdr.op) {
735 case TCF_EM_OPND_EQ:
736 return !r;
737 case TCF_EM_OPND_LT:
738 return r < 0;
739 case TCF_EM_OPND_GT:
740 return r > 0;
729 case TCF_EM_OPND_EQ:
730 return !r;
731 case TCF_EM_OPND_LT:
732 return r < 0;
733 case TCF_EM_OPND_GT:
734 return r > 0;
741 }
742
743 return 0;
744}
745
746static void meta_delete(struct meta_match *meta)
747{
748 if (meta) {

--- 17 unchanged lines hidden (view full) ---

766 return meta_type_ops(dst)->change(dst, nla);
767 }
768
769 return 0;
770}
771
772static inline int meta_is_supported(struct meta_value *val)
773{
735 }
736
737 return 0;
738}
739
740static void meta_delete(struct meta_match *meta)
741{
742 if (meta) {

--- 17 unchanged lines hidden (view full) ---

760 return meta_type_ops(dst)->change(dst, nla);
761 }
762
763 return 0;
764}
765
766static inline int meta_is_supported(struct meta_value *val)
767{
774 return (!meta_id(val) || meta_ops(val)->get);
768 return !meta_id(val) || meta_ops(val)->get;
775}
776
777static const struct nla_policy meta_policy[TCA_EM_META_MAX + 1] = {
778 [TCA_EM_META_HDR] = { .len = sizeof(struct tcf_meta_hdr) },
779};
780
781static int em_meta_change(struct tcf_proto *tp, void *data, int len,
782 struct tcf_ematch *m)

--- 103 unchanged lines hidden ---
769}
770
771static const struct nla_policy meta_policy[TCA_EM_META_MAX + 1] = {
772 [TCA_EM_META_HDR] = { .len = sizeof(struct tcf_meta_hdr) },
773};
774
775static int em_meta_change(struct tcf_proto *tp, void *data, int len,
776 struct tcf_ematch *m)

--- 103 unchanged lines hidden ---