aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/pkt_cls.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/pkt_cls.h')
-rw-r--r--include/net/pkt_cls.h113
1 files changed, 92 insertions, 21 deletions
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 753ac9361154..87406252f0a3 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -29,6 +29,7 @@ struct tcf_block_ext_info {
29 enum tcf_block_binder_type binder_type; 29 enum tcf_block_binder_type binder_type;
30 tcf_chain_head_change_t *chain_head_change; 30 tcf_chain_head_change_t *chain_head_change;
31 void *chain_head_change_priv; 31 void *chain_head_change_priv;
32 u32 block_index;
32}; 33};
33 34
34struct tcf_block_cb; 35struct tcf_block_cb;
@@ -38,16 +39,25 @@ bool tcf_queue_work(struct work_struct *work);
38struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, 39struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
39 bool create); 40 bool create);
40void tcf_chain_put(struct tcf_chain *chain); 41void tcf_chain_put(struct tcf_chain *chain);
42void tcf_block_netif_keep_dst(struct tcf_block *block);
41int tcf_block_get(struct tcf_block **p_block, 43int tcf_block_get(struct tcf_block **p_block,
42 struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q); 44 struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
45 struct netlink_ext_ack *extack);
43int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, 46int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
44 struct tcf_block_ext_info *ei); 47 struct tcf_block_ext_info *ei,
48 struct netlink_ext_ack *extack);
45void tcf_block_put(struct tcf_block *block); 49void tcf_block_put(struct tcf_block *block);
46void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, 50void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
47 struct tcf_block_ext_info *ei); 51 struct tcf_block_ext_info *ei);
48 52
53static inline bool tcf_block_shared(struct tcf_block *block)
54{
55 return block->index;
56}
57
49static inline struct Qdisc *tcf_block_q(struct tcf_block *block) 58static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
50{ 59{
60 WARN_ON(tcf_block_shared(block));
51 return block->q; 61 return block->q;
52} 62}
53 63
@@ -77,14 +87,16 @@ int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
77#else 87#else
78static inline 88static inline
79int tcf_block_get(struct tcf_block **p_block, 89int tcf_block_get(struct tcf_block **p_block,
80 struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q) 90 struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
91 struct netlink_ext_ack *extack)
81{ 92{
82 return 0; 93 return 0;
83} 94}
84 95
85static inline 96static inline
86int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, 97int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
87 struct tcf_block_ext_info *ei) 98 struct tcf_block_ext_info *ei,
99 struct netlink_ext_ack *extack)
88{ 100{
89 return 0; 101 return 0;
90} 102}
@@ -364,7 +376,8 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
364 376
365int tcf_exts_validate(struct net *net, struct tcf_proto *tp, 377int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
366 struct nlattr **tb, struct nlattr *rate_tlv, 378 struct nlattr **tb, struct nlattr *rate_tlv,
367 struct tcf_exts *exts, bool ovr); 379 struct tcf_exts *exts, bool ovr,
380 struct netlink_ext_ack *extack);
368void tcf_exts_destroy(struct tcf_exts *exts); 381void tcf_exts_destroy(struct tcf_exts *exts);
369void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src); 382void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
370int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts); 383int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
@@ -544,13 +557,16 @@ static inline int tcf_valid_offset(const struct sk_buff *skb,
544#include <net/net_namespace.h> 557#include <net/net_namespace.h>
545 558
546static inline int 559static inline int
547tcf_change_indev(struct net *net, struct nlattr *indev_tlv) 560tcf_change_indev(struct net *net, struct nlattr *indev_tlv,
561 struct netlink_ext_ack *extack)
548{ 562{
549 char indev[IFNAMSIZ]; 563 char indev[IFNAMSIZ];
550 struct net_device *dev; 564 struct net_device *dev;
551 565
552 if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) 566 if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) {
567 NL_SET_ERR_MSG(extack, "Interface name too long");
553 return -EINVAL; 568 return -EINVAL;
569 }
554 dev = __dev_get_by_name(net, indev); 570 dev = __dev_get_by_name(net, indev);
555 if (!dev) 571 if (!dev)
556 return -ENODEV; 572 return -ENODEV;
@@ -586,17 +602,9 @@ struct tc_cls_common_offload {
586 u32 chain_index; 602 u32 chain_index;
587 __be16 protocol; 603 __be16 protocol;
588 u32 prio; 604 u32 prio;
605 struct netlink_ext_ack *extack;
589}; 606};
590 607
591static inline void
592tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
593 const struct tcf_proto *tp)
594{
595 cls_common->chain_index = tp->chain->index;
596 cls_common->protocol = tp->protocol;
597 cls_common->prio = tp->prio;
598}
599
600struct tc_cls_u32_knode { 608struct tc_cls_u32_knode {
601 struct tcf_exts *exts; 609 struct tcf_exts *exts;
602 struct tc_u32_sel *sel; 610 struct tc_u32_sel *sel;
@@ -637,6 +645,31 @@ static inline bool tc_can_offload(const struct net_device *dev)
637 return dev->features & NETIF_F_HW_TC; 645 return dev->features & NETIF_F_HW_TC;
638} 646}
639 647
648static inline bool tc_can_offload_extack(const struct net_device *dev,
649 struct netlink_ext_ack *extack)
650{
651 bool can = tc_can_offload(dev);
652
653 if (!can)
654 NL_SET_ERR_MSG(extack, "TC offload is disabled on net device");
655
656 return can;
657}
658
659static inline bool
660tc_cls_can_offload_and_chain0(const struct net_device *dev,
661 struct tc_cls_common_offload *common)
662{
663 if (!tc_can_offload_extack(dev, common->extack))
664 return false;
665 if (common->chain_index) {
666 NL_SET_ERR_MSG(common->extack,
667 "Driver supports only offload of chain 0");
668 return false;
669 }
670 return true;
671}
672
640static inline bool tc_skip_hw(u32 flags) 673static inline bool tc_skip_hw(u32 flags)
641{ 674{
642 return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false; 675 return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false;
@@ -664,6 +697,18 @@ static inline bool tc_in_hw(u32 flags)
664 return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false; 697 return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false;
665} 698}
666 699
700static inline void
701tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
702 const struct tcf_proto *tp, u32 flags,
703 struct netlink_ext_ack *extack)
704{
705 cls_common->chain_index = tp->chain->index;
706 cls_common->protocol = tp->protocol;
707 cls_common->prio = tp->prio;
708 if (tc_skip_sw(flags))
709 cls_common->extack = extack;
710}
711
667enum tc_fl_command { 712enum tc_fl_command {
668 TC_CLSFLOWER_REPLACE, 713 TC_CLSFLOWER_REPLACE,
669 TC_CLSFLOWER_DESTROY, 714 TC_CLSFLOWER_DESTROY,
@@ -706,7 +751,6 @@ struct tc_cls_bpf_offload {
706 struct bpf_prog *oldprog; 751 struct bpf_prog *oldprog;
707 const char *name; 752 const char *name;
708 bool exts_integrated; 753 bool exts_integrated;
709 u32 gen_flags;
710}; 754};
711 755
712struct tc_mqprio_qopt_offload { 756struct tc_mqprio_qopt_offload {
@@ -727,6 +771,11 @@ struct tc_cookie {
727 u32 len; 771 u32 len;
728}; 772};
729 773
774struct tc_qopt_offload_stats {
775 struct gnet_stats_basic_packed *bstats;
776 struct gnet_stats_queue *qstats;
777};
778
730enum tc_red_command { 779enum tc_red_command {
731 TC_RED_REPLACE, 780 TC_RED_REPLACE,
732 TC_RED_DESTROY, 781 TC_RED_DESTROY,
@@ -739,9 +788,6 @@ struct tc_red_qopt_offload_params {
739 u32 max; 788 u32 max;
740 u32 probability; 789 u32 probability;
741 bool is_ecn; 790 bool is_ecn;
742};
743struct tc_red_qopt_offload_stats {
744 struct gnet_stats_basic_packed *bstats;
745 struct gnet_stats_queue *qstats; 791 struct gnet_stats_queue *qstats;
746}; 792};
747 793
@@ -751,9 +797,34 @@ struct tc_red_qopt_offload {
751 u32 parent; 797 u32 parent;
752 union { 798 union {
753 struct tc_red_qopt_offload_params set; 799 struct tc_red_qopt_offload_params set;
754 struct tc_red_qopt_offload_stats stats; 800 struct tc_qopt_offload_stats stats;
755 struct red_stats *xstats; 801 struct red_stats *xstats;
756 }; 802 };
757}; 803};
758 804
805enum tc_prio_command {
806 TC_PRIO_REPLACE,
807 TC_PRIO_DESTROY,
808 TC_PRIO_STATS,
809};
810
811struct tc_prio_qopt_offload_params {
812 int bands;
813 u8 priomap[TC_PRIO_MAX + 1];
814 /* In case that a prio qdisc is offloaded and now is changed to a
815 * non-offloadedable config, it needs to update the backlog & qlen
816 * values to negate the HW backlog & qlen values (and only them).
817 */
818 struct gnet_stats_queue *qstats;
819};
820
821struct tc_prio_qopt_offload {
822 enum tc_prio_command command;
823 u32 handle;
824 u32 parent;
825 union {
826 struct tc_prio_qopt_offload_params replace_params;
827 struct tc_qopt_offload_stats stats;
828 };
829};
759#endif 830#endif