net: sched: flower: handle concurrent filter insertion in fl_change
Check if user specified a handle and another filter with the same handle was inserted concurrently. Return EAGAIN to retry filter processing (in case it is an overwrite request). Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
259e60f967
commit
9a2d938998
|
@ -1542,6 +1542,15 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
|
||||||
/* user specifies a handle and it doesn't exist */
|
/* user specifies a handle and it doesn't exist */
|
||||||
err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
||||||
handle, GFP_ATOMIC);
|
handle, GFP_ATOMIC);
|
||||||
|
|
||||||
|
/* Filter with specified handle was concurrently
|
||||||
|
* inserted after initial check in cls_api. This is not
|
||||||
|
* necessarily an error if NLM_F_EXCL is not set in
|
||||||
|
* message flags. Returning EAGAIN will cause cls_api to
|
||||||
|
* try to update concurrently inserted rule.
|
||||||
|
*/
|
||||||
|
if (err == -ENOSPC)
|
||||||
|
err = -EAGAIN;
|
||||||
} else {
|
} else {
|
||||||
handle = 1;
|
handle = 1;
|
||||||
err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
||||||
|
|
Loading…
Reference in New Issue