diff options
| author | Vlad Buslov <vladbu@mellanox.com> | 2019-08-26 16:45:05 +0300 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-08-26 14:17:43 -0700 | 
| commit | 1444c175a37443d3f6d3db825df050741452c3c3 (patch) | |
| tree | d10f8fff01a65b1113b440b0e174458c16d87d75 /net/sched | |
| parent | 5a6ff4b13d598573fc954f672cd2a267b76a01ec (diff) | |
| download | linux-1444c175a37443d3f6d3db825df050741452c3c3.tar.bz2 | |
net: sched: copy tunnel info when setting flow_action entry->tunnel
In order to remove dependency on rtnl lock, modify tc_setup_flow_action()
to copy tunnel info, instead of just saving pointer to tunnel_key action
tunnel info. This is necessary to prevent concurrent action overwrite from
releasing tunnel info while it is being used by rtnl-unlocked driver.
Implement helper tcf_tunnel_info_copy() that is used to copy tunnel info
with all its options to dynamically allocated memory block. Modify
tc_cleanup_flow_action() to free dynamically allocated tunnel info.
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
| -rw-r--r-- | net/sched/cls_api.c | 9 | 
1 files changed, 8 insertions, 1 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index d988737693e4..671ca905dbb5 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -3279,6 +3279,9 @@ void tc_cleanup_flow_action(struct flow_action *flow_action)  			if (entry->dev)  				dev_put(entry->dev);  			break; +		case FLOW_ACTION_TUNNEL_ENCAP: +			kfree(entry->tunnel); +			break;  		default:  			break;  		} @@ -3355,7 +3358,11 @@ int tc_setup_flow_action(struct flow_action *flow_action,  			}  		} else if (is_tcf_tunnel_set(act)) {  			entry->id = FLOW_ACTION_TUNNEL_ENCAP; -			entry->tunnel = tcf_tunnel_info(act); +			entry->tunnel = tcf_tunnel_info_copy(act); +			if (!entry->tunnel) { +				err = -ENOMEM; +				goto err_out; +			}  		} else if (is_tcf_tunnel_release(act)) {  			entry->id = FLOW_ACTION_TUNNEL_DECAP;  		} else if (is_tcf_pedit(act)) {  |