diff mbox

[net-next,3/6] net: bridge: break if __br_mdb_del fails

Message ID 20170517212709.6473-4-vivien.didelot@savoirfairelinux.com
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

Vivien Didelot May 17, 2017, 9:27 p.m. UTC
Be symmetric with br_mdb_add and break if __br_mdb_del returns an error.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/bridge/br_mdb.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Comments

Nikolay Aleksandrov May 18, 2017, 1:45 p.m. UTC | #1
On 5/18/17 12:27 AM, Vivien Didelot wrote:
> Be symmetric with br_mdb_add and break if __br_mdb_del returns an error.
> 
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
> ---
>   net/bridge/br_mdb.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
> index d20a01622b20..24eeeefb4179 100644
> --- a/net/bridge/br_mdb.c
> +++ b/net/bridge/br_mdb.c
> @@ -688,8 +688,9 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
>   		list_for_each_entry(v, &vg->vlan_list, vlist) {
>   			entry->vid = v->vid;
>   			err = __br_mdb_del(br, entry);
> -			if (!err)
> -				__br_mdb_notify(dev, p, entry, RTM_DELMDB);
> +			if (err)
> +				break;
> +			__br_mdb_notify(dev, p, entry, RTM_DELMDB);
>   		}
>   	} else {
>   		err = __br_mdb_del(br, entry);
> 

This can potentially break user-space scripts that rely on the best-effort
behaviour, this is the normal "delete without vid & enabled vlan filtering".
You can check the fdb delete code which does the same, this was intentional.

You can add an mdb entry without a vid to all vlans, add a vlan and then try
to remove it from all vlans where it is present - with this patch obviously
that will fail at the new vlan.
Vivien Didelot May 18, 2017, 3:08 p.m. UTC | #2
Hi Nikolay,

Nikolay Aleksandrov <nikolay@cumulusnetworks.com> writes:

>>   			err = __br_mdb_del(br, entry);
>> -			if (!err)
>> -				__br_mdb_notify(dev, p, entry, RTM_DELMDB);
>> +			if (err)
>> +				break;
>> +			__br_mdb_notify(dev, p, entry, RTM_DELMDB);
>>   		}
>>   	} else {
>>   		err = __br_mdb_del(br, entry);
>> 
>
> This can potentially break user-space scripts that rely on the best-effort
> behaviour, this is the normal "delete without vid & enabled vlan filtering".
> You can check the fdb delete code which does the same, this was intentional.
>
> You can add an mdb entry without a vid to all vlans, add a vlan and then try
> to remove it from all vlans where it is present - with this patch obviously
> that will fail at the new vlan.

OK good to know. That intention wasn't obvious. I can make __br_mdb_del
return void instead? What about the rest of the patchset if I do so?

Thanks,

        Vivien
Nikolay Aleksandrov May 18, 2017, 3:25 p.m. UTC | #3
On 5/18/17 6:08 PM, Vivien Didelot wrote:
> Hi Nikolay,
> 
> Nikolay Aleksandrov <nikolay@cumulusnetworks.com> writes:
> 
>>>    			err = __br_mdb_del(br, entry);
>>> -			if (!err)
>>> -				__br_mdb_notify(dev, p, entry, RTM_DELMDB);
>>> +			if (err)
>>> +				break;
>>> +			__br_mdb_notify(dev, p, entry, RTM_DELMDB);
>>>    		}
>>>    	} else {
>>>    		err = __br_mdb_del(br, entry);
>>>
>>
>> This can potentially break user-space scripts that rely on the best-effort
>> behaviour, this is the normal "delete without vid & enabled vlan filtering".
>> You can check the fdb delete code which does the same, this was intentional.
>>
>> You can add an mdb entry without a vid to all vlans, add a vlan and then try
>> to remove it from all vlans where it is present - with this patch obviously
>> that will fail at the new vlan.
> 
> OK good to know. That intention wasn't obvious. I can make __br_mdb_del
> return void instead? What about the rest of the patchset if I do so?
> 
> Thanks,
> 
>          Vivien
> 

If you make it return void we will not be able to return proper error value
when doing a single operation (the else case). About the rest I see only some
minor style issues, I'll comment on the respective patches. Another minor nit is 
using switch() instead of if/else for the message types but that is really up to 
you, I don't mind either way. :-)

Cheers,
  Nik
Vivien Didelot May 18, 2017, 3:45 p.m. UTC | #4
Hi Nikolay,

Nikolay Aleksandrov <nikolay@cumulusnetworks.com> writes:

>> OK good to know. That intention wasn't obvious. I can make __br_mdb_del
>> return void instead? What about the rest of the patchset if I do so?
>
> If you make it return void we will not be able to return proper error value
> when doing a single operation (the else case). About the rest I see only some
> minor style issues, I'll comment on the respective patches. Another minor nit is 
> using switch() instead of if/else for the message types but that is really up to 
> you, I don't mind either way. :-)

Ho OK I understand better the batch vs single delete operation now.
__br_mdb_do hardly makes sense now, because we don't know which case we
are handling... But factorizing br_mdb_do still makes sense. I'll come
up with something.

Thanks,

        Vivien
diff mbox

Patch

diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index d20a01622b20..24eeeefb4179 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -688,8 +688,9 @@  static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
 		list_for_each_entry(v, &vg->vlan_list, vlist) {
 			entry->vid = v->vid;
 			err = __br_mdb_del(br, entry);
-			if (!err)
-				__br_mdb_notify(dev, p, entry, RTM_DELMDB);
+			if (err)
+				break;
+			__br_mdb_notify(dev, p, entry, RTM_DELMDB);
 		}
 	} else {
 		err = __br_mdb_del(br, entry);