Re: [patch net-next v2 2/4] net: sched: introduce per-egress action device callbacks
Sun, Nov 19, 2017 at 08:37:49PM CET, manish.cho...@cavium.com wrote: >> -Original Message- >> From: netdev-ow...@vger.kernel.org [mailto:netdev-ow...@vger.kernel.org] >> On Behalf Of Jiri Pirko >> Sent: Wednesday, October 11, 2017 1:11 PM >> To: netdev@vger.kernel.org >> Cc: da...@davemloft.net; j...@mojatatu.com; xiyou.wangc...@gmail.com; >> sae...@mellanox.com; mat...@mellanox.com; leo...@mellanox.com; >> ml...@mellanox.com; david.lai...@aculab.com; gerlitz...@gmail.com >> Subject: [patch net-next v2 2/4] net: sched: introduce per-egress action >> device >> callbacks >> >> From: Jiri Pirko <j...@mellanox.com> >> >> Introduce infrastructure that allows drivers to register callbacks that are >> called >> whenever tc would offload inserted rule and specified device acts as tc >> action >> egress device. >> >> Signed-off-by: Jiri Pirko <j...@mellanox.com> >> --- >> v1->v2: >> - take rtnl for register/unregister >> --- >> include/net/act_api.h | 34 >> include/net/pkt_cls.h | 2 + >> net/sched/act_api.c | 220 >> ++ >> net/sched/cls_api.c | 30 +++ >> 4 files changed, 286 insertions(+) >> >> diff --git a/include/net/act_api.h b/include/net/act_api.h index >> 900168a..f5e8c90 100644 >> --- a/include/net/act_api.h >> +++ b/include/net/act_api.h >> @@ -174,4 +174,38 @@ static inline void tcf_action_stats_update(struct >> tc_action *a, u64 bytes, #endif } >> >> +typedef int tc_setup_cb_t(enum tc_setup_type type, >> + void *type_data, void *cb_priv); >> + >> +#ifdef CONFIG_NET_CLS_ACT >> +int tc_setup_cb_egdev_register(const struct net_device *dev, >> + tc_setup_cb_t *cb, void *cb_priv); void >> +tc_setup_cb_egdev_unregister(const struct net_device *dev, >> + tc_setup_cb_t *cb, void *cb_priv); int >> +tc_setup_cb_egdev_call(const struct net_device *dev, >> + enum tc_setup_type type, void *type_data, >> + bool err_stop); >> +#else >> +static inline >> +int tc_setup_cb_egdev_register(const struct net_device *dev, >> + tc_setup_cb_t *cb, void *cb_priv) { >> +return 0; >> +} >> + >> +static inline >> +void tc_setup_cb_egdev_unregister(const struct net_device *dev, >> + tc_setup_cb_t *cb, void *cb_priv) { } >> + >> +static inline >> +int tc_setup_cb_egdev_call(const struct net_device *dev, >> + enum tc_setup_type type, void *type_data, >> + bool err_stop) >> +{ >> +return 0; >> +} >> +#endif >> + >> #endif >> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index >> e80edd8..6f8149c 100644 >> --- a/include/net/pkt_cls.h >> +++ b/include/net/pkt_cls.h >> @@ -206,6 +206,8 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts >> *exts); int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts >> *exts); int >> tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts, >> struct net_device **hw_dev); >> +int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type, >> + void *type_data, bool err_stop); >> >> /** >> * struct tcf_pkt_info - packet information diff --git a/net/sched/act_api.c >> b/net/sched/act_api.c index da6fa82..ac97db9 100644 >> --- a/net/sched/act_api.c >> +++ b/net/sched/act_api.c >> @@ -21,6 +21,8 @@ >> #include >> #include >> #include >> +#include >> +#include >> #include >> #include >> #include >> @@ -1249,8 +1251,226 @@ static int tc_dump_action(struct sk_buff *skb, >> struct netlink_callback *cb) >> return skb->len; >> } >> >> +struct tcf_action_net { >> +struct rhashtable egdev_ht; >> +}; >> + >> +static unsigned int tcf_action_net_id; >> + >> +struct tcf_action_egdev_cb { >> +struct list_head list; >> +tc_setup_cb_t *cb; >> +void *cb_priv; >> +}; >> + >> +struct tcf_action_egdev { >> +struct rhash_head ht_node; >> +const struct net_device *dev; >> +unsigned int refcnt; >> +struct list_head cb_list; >> +}; >> + >> +static const struct rhashtable_params tcf_action_egdev_ht_params = { >> +.key_offse
RE: [patch net-next v2 2/4] net: sched: introduce per-egress action device callbacks
> -Original Message- > From: netdev-ow...@vger.kernel.org [mailto:netdev-ow...@vger.kernel.org] > On Behalf Of Jiri Pirko > Sent: Wednesday, October 11, 2017 1:11 PM > To: netdev@vger.kernel.org > Cc: da...@davemloft.net; j...@mojatatu.com; xiyou.wangc...@gmail.com; > sae...@mellanox.com; mat...@mellanox.com; leo...@mellanox.com; > ml...@mellanox.com; david.lai...@aculab.com; gerlitz...@gmail.com > Subject: [patch net-next v2 2/4] net: sched: introduce per-egress action > device > callbacks > > From: Jiri Pirko <j...@mellanox.com> > > Introduce infrastructure that allows drivers to register callbacks that are > called > whenever tc would offload inserted rule and specified device acts as tc action > egress device. > > Signed-off-by: Jiri Pirko <j...@mellanox.com> > --- > v1->v2: > - take rtnl for register/unregister > --- > include/net/act_api.h | 34 > include/net/pkt_cls.h | 2 + > net/sched/act_api.c | 220 > ++ > net/sched/cls_api.c | 30 +++ > 4 files changed, 286 insertions(+) > > diff --git a/include/net/act_api.h b/include/net/act_api.h index > 900168a..f5e8c90 100644 > --- a/include/net/act_api.h > +++ b/include/net/act_api.h > @@ -174,4 +174,38 @@ static inline void tcf_action_stats_update(struct > tc_action *a, u64 bytes, #endif } > > +typedef int tc_setup_cb_t(enum tc_setup_type type, > + void *type_data, void *cb_priv); > + > +#ifdef CONFIG_NET_CLS_ACT > +int tc_setup_cb_egdev_register(const struct net_device *dev, > +tc_setup_cb_t *cb, void *cb_priv); void > +tc_setup_cb_egdev_unregister(const struct net_device *dev, > + tc_setup_cb_t *cb, void *cb_priv); int > +tc_setup_cb_egdev_call(const struct net_device *dev, > +enum tc_setup_type type, void *type_data, > +bool err_stop); > +#else > +static inline > +int tc_setup_cb_egdev_register(const struct net_device *dev, > +tc_setup_cb_t *cb, void *cb_priv) { > + return 0; > +} > + > +static inline > +void tc_setup_cb_egdev_unregister(const struct net_device *dev, > + tc_setup_cb_t *cb, void *cb_priv) { } > + > +static inline > +int tc_setup_cb_egdev_call(const struct net_device *dev, > +enum tc_setup_type type, void *type_data, > +bool err_stop) > +{ > + return 0; > +} > +#endif > + > #endif > diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index > e80edd8..6f8149c 100644 > --- a/include/net/pkt_cls.h > +++ b/include/net/pkt_cls.h > @@ -206,6 +206,8 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts > *exts); int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts); > int > tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts, >struct net_device **hw_dev); > +int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type, > +void *type_data, bool err_stop); > > /** > * struct tcf_pkt_info - packet information diff --git a/net/sched/act_api.c > b/net/sched/act_api.c index da6fa82..ac97db9 100644 > --- a/net/sched/act_api.c > +++ b/net/sched/act_api.c > @@ -21,6 +21,8 @@ > #include > #include > #include > +#include > +#include > #include > #include > #include > @@ -1249,8 +1251,226 @@ static int tc_dump_action(struct sk_buff *skb, > struct netlink_callback *cb) > return skb->len; > } > > +struct tcf_action_net { > + struct rhashtable egdev_ht; > +}; > + > +static unsigned int tcf_action_net_id; > + > +struct tcf_action_egdev_cb { > + struct list_head list; > + tc_setup_cb_t *cb; > + void *cb_priv; > +}; > + > +struct tcf_action_egdev { > + struct rhash_head ht_node; > + const struct net_device *dev; > + unsigned int refcnt; > + struct list_head cb_list; > +}; > + > +static const struct rhashtable_params tcf_action_egdev_ht_params = { > + .key_offset = offsetof(struct tcf_action_egdev, dev), > + .head_offset = offsetof(struct tcf_action_egdev, ht_node), > + .key_len = sizeof(const struct net_device *), }; > + > +static struct tcf_action_egdev * > +tcf_action_egdev_lookup(const struct net_device *dev) { > + struct net *net = dev_net(dev); > + struct tcf_action_net *tan = net_generic(net, tcf_action_net_id); > + > + return rhashtable_lookup_fast(>egdev_ht, , > + tcf_action_egdev_ht_params); > +} &g
[patch net-next v2 2/4] net: sched: introduce per-egress action device callbacks
From: Jiri PirkoIntroduce infrastructure that allows drivers to register callbacks that are called whenever tc would offload inserted rule and specified device acts as tc action egress device. Signed-off-by: Jiri Pirko --- v1->v2: - take rtnl for register/unregister --- include/net/act_api.h | 34 include/net/pkt_cls.h | 2 + net/sched/act_api.c | 220 ++ net/sched/cls_api.c | 30 +++ 4 files changed, 286 insertions(+) diff --git a/include/net/act_api.h b/include/net/act_api.h index 900168a..f5e8c90 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -174,4 +174,38 @@ static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes, #endif } +typedef int tc_setup_cb_t(enum tc_setup_type type, + void *type_data, void *cb_priv); + +#ifdef CONFIG_NET_CLS_ACT +int tc_setup_cb_egdev_register(const struct net_device *dev, + tc_setup_cb_t *cb, void *cb_priv); +void tc_setup_cb_egdev_unregister(const struct net_device *dev, + tc_setup_cb_t *cb, void *cb_priv); +int tc_setup_cb_egdev_call(const struct net_device *dev, + enum tc_setup_type type, void *type_data, + bool err_stop); +#else +static inline +int tc_setup_cb_egdev_register(const struct net_device *dev, + tc_setup_cb_t *cb, void *cb_priv) +{ + return 0; +} + +static inline +void tc_setup_cb_egdev_unregister(const struct net_device *dev, + tc_setup_cb_t *cb, void *cb_priv) +{ +} + +static inline +int tc_setup_cb_egdev_call(const struct net_device *dev, + enum tc_setup_type type, void *type_data, + bool err_stop) +{ + return 0; +} +#endif + #endif diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index e80edd8..6f8149c 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -206,6 +206,8 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts); int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts); int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts, struct net_device **hw_dev); +int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type, + void *type_data, bool err_stop); /** * struct tcf_pkt_info - packet information diff --git a/net/sched/act_api.c b/net/sched/act_api.c index da6fa82..ac97db9 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -1249,8 +1251,226 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } +struct tcf_action_net { + struct rhashtable egdev_ht; +}; + +static unsigned int tcf_action_net_id; + +struct tcf_action_egdev_cb { + struct list_head list; + tc_setup_cb_t *cb; + void *cb_priv; +}; + +struct tcf_action_egdev { + struct rhash_head ht_node; + const struct net_device *dev; + unsigned int refcnt; + struct list_head cb_list; +}; + +static const struct rhashtable_params tcf_action_egdev_ht_params = { + .key_offset = offsetof(struct tcf_action_egdev, dev), + .head_offset = offsetof(struct tcf_action_egdev, ht_node), + .key_len = sizeof(const struct net_device *), +}; + +static struct tcf_action_egdev * +tcf_action_egdev_lookup(const struct net_device *dev) +{ + struct net *net = dev_net(dev); + struct tcf_action_net *tan = net_generic(net, tcf_action_net_id); + + return rhashtable_lookup_fast(>egdev_ht, , + tcf_action_egdev_ht_params); +} + +static struct tcf_action_egdev * +tcf_action_egdev_get(const struct net_device *dev) +{ + struct tcf_action_egdev *egdev; + struct tcf_action_net *tan; + + egdev = tcf_action_egdev_lookup(dev); + if (egdev) + goto inc_ref; + + egdev = kzalloc(sizeof(*egdev), GFP_KERNEL); + if (!egdev) + return NULL; + INIT_LIST_HEAD(>cb_list); + tan = net_generic(dev_net(dev), tcf_action_net_id); + rhashtable_insert_fast(>egdev_ht, >ht_node, + tcf_action_egdev_ht_params); + +inc_ref: + egdev->refcnt++; + return egdev; +} + +static void tcf_action_egdev_put(struct tcf_action_egdev *egdev) +{ + struct tcf_action_net *tan; + + if (--egdev->refcnt) + return; + tan = net_generic(dev_net(egdev->dev), tcf_action_net_id); + rhashtable_remove_fast(>egdev_ht, >ht_node, + tcf_action_egdev_ht_params); + kfree(egdev); +} + +static struct tcf_action_egdev_cb * +tcf_action_egdev_cb_lookup(struct tcf_action_egdev *egdev, +