summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Buslov <vladbu@mellanox.com>2019-09-13 11:28:39 -0400
committerDavid S. Miller <davem@davemloft.net>2019-09-16 03:18:02 -0400
commit1158958a218bb55d1c358200d7f82808d11bf929 (patch)
tree3fca9616bf020edceb8c13f528846231eec134bc
parent28c9eb9042a954d4e9fbec91484bddce280f1beb (diff)
net: sched: extend flow_action_entry with destructor
Generalize flow_action_entry cleanup by extending the structure with pointer to destructor function. Set the destructor in tc_setup_flow_action(). Refactor tc_cleanup_flow_action() to call entry->destructor() instead of using switch that dispatches by entry->id and manually executes cleanup. This refactoring is necessary for following patches in this series that require destructor to use tc_action->ops callbacks that can't be easily obtained in tc_cleanup_flow_action(). Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/flow_offload.h6
-rw-r--r--net/sched/cls_api.c77
2 files changed, 50 insertions, 33 deletions
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index fc881875f856..86c567f531f3 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -154,8 +154,12 @@ enum flow_action_mangle_base {
154 FLOW_ACT_MANGLE_HDR_TYPE_UDP, 154 FLOW_ACT_MANGLE_HDR_TYPE_UDP,
155}; 155};
156 156
157typedef void (*action_destr)(void *priv);
158
157struct flow_action_entry { 159struct flow_action_entry {
158 enum flow_action_id id; 160 enum flow_action_id id;
161 action_destr destructor;
162 void *destructor_priv;
159 union { 163 union {
160 u32 chain_index; /* FLOW_ACTION_GOTO */ 164 u32 chain_index; /* FLOW_ACTION_GOTO */
161 struct net_device *dev; /* FLOW_ACTION_REDIRECT */ 165 struct net_device *dev; /* FLOW_ACTION_REDIRECT */
@@ -170,7 +174,7 @@ struct flow_action_entry {
170 u32 mask; 174 u32 mask;
171 u32 val; 175 u32 val;
172 } mangle; 176 } mangle;
173 const struct ip_tunnel_info *tunnel; /* FLOW_ACTION_TUNNEL_ENCAP */ 177 struct ip_tunnel_info *tunnel; /* FLOW_ACTION_TUNNEL_ENCAP */
174 u32 csum_flags; /* FLOW_ACTION_CSUM */ 178 u32 csum_flags; /* FLOW_ACTION_CSUM */
175 u32 mark; /* FLOW_ACTION_MARK */ 179 u32 mark; /* FLOW_ACTION_MARK */
176 u16 ptype; /* FLOW_ACTION_PTYPE */ 180 u16 ptype; /* FLOW_ACTION_PTYPE */
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 05c4fe1c3ca2..c668195379bd 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3282,25 +3282,48 @@ void tc_cleanup_flow_action(struct flow_action *flow_action)
3282 struct flow_action_entry *entry; 3282 struct flow_action_entry *entry;
3283 int i; 3283 int i;
3284 3284
3285 flow_action_for_each(i, entry, flow_action) { 3285 flow_action_for_each(i, entry, flow_action)
3286 switch (entry->id) { 3286 if (entry->destructor)
3287 case FLOW_ACTION_REDIRECT: 3287 entry->destructor(entry->destructor_priv);
3288 case FLOW_ACTION_MIRRED:
3289 case FLOW_ACTION_REDIRECT_INGRESS:
3290 case FLOW_ACTION_MIRRED_INGRESS:
3291 if (entry->dev)
3292 dev_put(entry->dev);
3293 break;
3294 case FLOW_ACTION_TUNNEL_ENCAP:
3295 kfree(entry->tunnel);
3296 break;
3297 default:
3298 break;
3299 }
3300 }
3301} 3288}
3302EXPORT_SYMBOL(tc_cleanup_flow_action); 3289EXPORT_SYMBOL(tc_cleanup_flow_action);
3303 3290
3291static void tcf_mirred_put_dev(void *priv)
3292{
3293 struct net_device *dev = priv;
3294
3295 dev_put(dev);
3296}
3297
3298static void tcf_mirred_get_dev(struct flow_action_entry *entry,
3299 const struct tc_action *act)
3300{
3301 entry->dev = tcf_mirred_dev(act);
3302 if (!entry->dev)
3303 return;
3304 dev_hold(entry->dev);
3305 entry->destructor = tcf_mirred_put_dev;
3306 entry->destructor_priv = entry->dev;
3307}
3308
3309static void tcf_tunnel_encap_put_tunnel(void *priv)
3310{
3311 struct ip_tunnel_info *tunnel = priv;
3312
3313 kfree(tunnel);
3314}
3315
3316static int tcf_tunnel_encap_get_tunnel(struct flow_action_entry *entry,
3317 const struct tc_action *act)
3318{
3319 entry->tunnel = tcf_tunnel_info_copy(act);
3320 if (!entry->tunnel)
3321 return -ENOMEM;
3322 entry->destructor = tcf_tunnel_encap_put_tunnel;
3323 entry->destructor_priv = entry->tunnel;
3324 return 0;
3325}
3326
3304int tc_setup_flow_action(struct flow_action *flow_action, 3327int tc_setup_flow_action(struct flow_action *flow_action,
3305 const struct tcf_exts *exts, bool rtnl_held) 3328 const struct tcf_exts *exts, bool rtnl_held)
3306{ 3329{
@@ -3329,24 +3352,16 @@ int tc_setup_flow_action(struct flow_action *flow_action,
3329 entry->chain_index = tcf_gact_goto_chain_index(act); 3352 entry->chain_index = tcf_gact_goto_chain_index(act);
3330 } else if (is_tcf_mirred_egress_redirect(act)) { 3353 } else if (is_tcf_mirred_egress_redirect(act)) {
3331 entry->id = FLOW_ACTION_REDIRECT; 3354 entry->id = FLOW_ACTION_REDIRECT;
3332 entry->dev = tcf_mirred_dev(act); 3355 tcf_mirred_get_dev(entry, act);
3333 if (entry->dev)
3334 dev_hold(entry->dev);
3335 } else if (is_tcf_mirred_egress_mirror(act)) { 3356 } else if (is_tcf_mirred_egress_mirror(act)) {
3336 entry->id = FLOW_ACTION_MIRRED; 3357 entry->id = FLOW_ACTION_MIRRED;
3337 entry->dev = tcf_mirred_dev(act); 3358 tcf_mirred_get_dev(entry, act);
3338 if (entry->dev)
3339 dev_hold(entry->dev);
3340 } else if (is_tcf_mirred_ingress_redirect(act)) { 3359 } else if (is_tcf_mirred_ingress_redirect(act)) {
3341 entry->id = FLOW_ACTION_REDIRECT_INGRESS; 3360 entry->id = FLOW_ACTION_REDIRECT_INGRESS;
3342 entry->dev = tcf_mirred_dev(act); 3361 tcf_mirred_get_dev(entry, act);
3343 if (entry->dev)
3344 dev_hold(entry->dev);
3345 } else if (is_tcf_mirred_ingress_mirror(act)) { 3362 } else if (is_tcf_mirred_ingress_mirror(act)) {
3346 entry->id = FLOW_ACTION_MIRRED_INGRESS; 3363 entry->id = FLOW_ACTION_MIRRED_INGRESS;
3347 entry->dev = tcf_mirred_dev(act); 3364 tcf_mirred_get_dev(entry, act);
3348 if (entry->dev)
3349 dev_hold(entry->dev);
3350 } else if (is_tcf_vlan(act)) { 3365 } else if (is_tcf_vlan(act)) {
3351 switch (tcf_vlan_action(act)) { 3366 switch (tcf_vlan_action(act)) {
3352 case TCA_VLAN_ACT_PUSH: 3367 case TCA_VLAN_ACT_PUSH:
@@ -3370,11 +3385,9 @@ int tc_setup_flow_action(struct flow_action *flow_action,
3370 } 3385 }
3371 } else if (is_tcf_tunnel_set(act)) { 3386 } else if (is_tcf_tunnel_set(act)) {
3372 entry->id = FLOW_ACTION_TUNNEL_ENCAP; 3387 entry->id = FLOW_ACTION_TUNNEL_ENCAP;
3373 entry->tunnel = tcf_tunnel_info_copy(act); 3388 err = tcf_tunnel_encap_get_tunnel(entry, act);
3374 if (!entry->tunnel) { 3389 if (err)
3375 err = -ENOMEM;
3376 goto err_out; 3390 goto err_out;
3377 }
3378 } else if (is_tcf_tunnel_release(act)) { 3391 } else if (is_tcf_tunnel_release(act)) {
3379 entry->id = FLOW_ACTION_TUNNEL_DECAP; 3392 entry->id = FLOW_ACTION_TUNNEL_DECAP;
3380 } else if (is_tcf_pedit(act)) { 3393 } else if (is_tcf_pedit(act)) {