Skip to content

Commit

Permalink
[vlanmgr]: Update VLAN removal code to work with 5.10 kernel and newe…
Browse files Browse the repository at this point in the history
…r iproute2 versions (sonic-net#1970)

* Update VLAN removal code to work with 5.10 kernel and newer iproute2 versions

There is an issue discovered by Alexander Allen where VLAN member
removal from a VLAN doesn't fully happen on a 5.10 kernel. The reason
for this is that there is a change in the output of the `bridge vlan
show` command between the 4.19 kernel and the 5.10 kernel. To add to
this, the output is different depending on whether iproute2 4.20 or
iproute2 5.10 is installed. These output changes cause only some of the
VLAN member removal code to run; specifically, the interface will not be
the member of a VLAN anymore, but it will still be part of the bridge.

Therefore, update the code that parses the output of `bridge vlan show`
to handle iproute2 4.20 with 4.19 kernel, iproute2 4.20 with 5.10
kernel, and iproute2 5.10 with 5.10 kernel. This should cover all
possible combinations we'll have until all containers are on Bullseye.

Signed-off-by: Saikrishna Arcot <[email protected]>

* Store the exit code of the bridge vlan show command.

Signed-off-by: Saikrishna Arcot <[email protected]>

* Add missing space.

Signed-off-by: Saikrishna Arcot <[email protected]>
  • Loading branch information
saiarcot895 authored Oct 28, 2021
1 parent 41fb26c commit 9ef2ba4
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions cfgmgr/vlanmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,19 +237,27 @@ bool VlanMgr::removeHostVlanMember(int vlan_id, const string &port_alias)

// The command should be generated as:
// /bin/bash -c '/sbin/bridge vlan del vid {{vlan_id}} dev {{port_alias}} &&
// ( /sbin/bridge vlan show dev {{port_alias}} | /bin/grep -q None;
// ret=$?; if [ $ret -eq 0 ]; then
// ( vlanShow=$(/sbin/bridge vlan show dev {{port_alias}});
// ret=$?;
// if [ $ret -eq 0 ]; then
// if (! echo "$vlanShow" | grep -q {{port_alias}})
// || (echo "$vlanShow" | grep -q None$)
// || (echo "$vlanShow" | grep -q {{port_alias}}$); then
// /sbin/ip link set {{port_alias}} nomaster;
// elif [ $ret -eq 1 ]; then exit 0;
// fi;
// else exit $ret; fi )'

// When port is not member of any VLAN, it shall be detached from Dot1Q bridge!
ostringstream cmds, inner;
inner << BRIDGE_CMD " vlan del vid " + std::to_string(vlan_id) + " dev " << shellquote(port_alias) << " && ( "
BRIDGE_CMD " vlan show dev " << shellquote(port_alias) << " | "
GREP_CMD " -q None; ret=$?; if [ $ret -eq 0 ]; then "
"vlanShow=$(" BRIDGE_CMD " vlan show dev " << shellquote(port_alias) << "); "
"ret=$?; "
"if [ $ret -eq 0 ]; then "
"if (! echo \"$vlanShow\" | " GREP_CMD " -q " << shellquote(port_alias) << ") "
" || (echo \"$vlanShow\" | " GREP_CMD " -q None$) "
" || (echo \"$vlanShow\" | " GREP_CMD " -q " << shellquote(port_alias) << "$); then "
IP_CMD " link set " << shellquote(port_alias) << " nomaster; "
"elif [ $ret -eq 1 ]; then exit 0; "
"fi; "
"else exit $ret; fi )";
cmds << BASH_CMD " -c " << shellquote(inner.str());

Expand Down

0 comments on commit 9ef2ba4

Please sign in to comment.