[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RFC PATCH v2 3/5] tools/hotplug/Linux: Add bridge VLAN support
On Wed, May 8, 2024 at 6:55 PM Leigh Brown <leigh@xxxxxxxxxxxxx> wrote: > > Update add_to_bridge shell function to read the vlan parameter > from xenstore and set the bridge VLAN configuration for the VID. > > Add additional helper functions to parse the vlan specification, > which consists of one or more of the follow: > > a) single VLAN (e.g. 10). > b) contiguous range of VLANs (e.g. 10-15). > c) discontiguous range with base, increment and count > (e.g. 100+10x9 which gives VLAN IDs 100, 110, ... 190). > > A single VLAN can be suffixed with "p" to indicate the PVID, or > "u" to indicate untagged. A range of VLANs can be suffixed with > "u" to indicate untagged. A complex example would be: > > vlan=1p/10-15/20-25u > > This capability only works when using the iproute2 bridge command, > so a warning is issued if the vlan parameter is set and the bridge > command is not available, as it will be ignored. > > Signed-off-by: Leigh Brown <leigh@xxxxxxxxxxxxx> > --- > tools/hotplug/Linux/xen-network-common.sh | 111 ++++++++++++++++++++++ > 1 file changed, 111 insertions(+) > > diff --git a/tools/hotplug/Linux/xen-network-common.sh > b/tools/hotplug/Linux/xen-network-common.sh > index 42fa704e8d..d9fb4f7355 100644 > --- a/tools/hotplug/Linux/xen-network-common.sh > +++ b/tools/hotplug/Linux/xen-network-common.sh > @@ -121,10 +121,113 @@ create_bridge () { > fi > } > > +_vif_vlan_add() { > + # References vlans, pvid and error variables from the calling function > + local -i vid=$1 > + local flag=${2:-} > + > + if (( vid < 1 || vid > 4094 )) ;then > + error="vlan id $vid not between 1 and 4094" > + return > + fi > + if [[ -n "${vlans[$vid]}" ]] ;then > + error="vlan id $vid specified more than once" > + return You could do `fatal "vlan id $vid specified more than once"` and just terminate the script at this point. It would simplify your later code if you use fatal more. > + fi > + case $flag in > + p) if (( pvid != 0 )) ;then > + error="more than one pvid specified ($vid and $pvid)" > + return > + fi > + pvid=$vid > + vlans[$vid]=p ;; > + u) vlans[$vid]=u ;; > + *) vlans[$vid]=t ;; > + esac > +} > + > +_vif_vlan_parse_term() { > + # References error variable from the calling function > + local vid incr last term=${1:-} > + > + if [[ $term =~ ^([0-9]+)([pu])?$ ]] ;then I like that you split the different cases into multiple REs. > + _vif_vlan_add ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} > + elif [[ $term =~ ^([0-9]+)-([0-9]+)(u)?$ ]] ;then > + vid=${BASH_REMATCH[1]} > + last=${BASH_REMATCH[2]} > + if (( last >= vid )) ;then > + for (( ; vid<=last; vid++ )) ;do > + _vif_vlan_add $vid ${BASH_REMATCH[3]} > + done > + else > + error="invalid vlan id range: $term" > + fi > + elif [[ $term =~ ^([0-9]+)\+([0-9]+)x([0-9]+)(u)?$ ]] ;then > + vid=${BASH_REMATCH[1]} > + incr=${BASH_REMATCH[2]} > + for (( j=${BASH_REMATCH[3]}; j>0; --j, vid+=incr )) > + do > + _vif_vlan_add $vid ${BASH_REMATCH[4]} > + done > + else > + error="invalid vlan specification: $term" > + fi > +} > + > +_vif_vlan_validate_pvid() { > + # References vlans and pvid variables from the calling function > + if (( pvid == 0 )) ;then > + if (( ${#vlans[@]} == 1 )) ;then > + vlans[${!vlans[*]}]=p > + else > + error="pvid required for multiple vlan ids" > + fi > + fi > +} > + > +_vif_vlan_setup() { > + # References vlans and dev variable from the calling function > + local vid cmd > + > + bridge vlan del dev "$dev" vid 1 > + for vid in ${!vlans[@]} ;do > + cmd="bridge vlan add dev '$dev' vid $vid" > + case ${vlans[$vid]} in > + p) cmd="$cmd pvid untagged" ;; > + u) cmd="$cmd untagged" ;; > + t) ;; > + esac > + eval "$cmd" > + done > +} > + > +_vif_vlan_membership() { > + # The vlans, pvid, dev and error variables are used by sub-functions > + local -A vlans=() > + local -a terms=() > + local -i i pvid=0 > + local dev=$1 error="" > + > + # Split the vlan specification string into its terms > + readarray -d / -t terms <<<$2 > + for (( i=0; i<${#terms[@]}; ++i )) ;do > + _vif_vlan_parse_term ${terms[$i]%%[[:space:]]} > + [[ -n "$error" ]] && break > + done > + > + [[ -z "$error" ]] && _vif_vlan_validate_pvid > + [[ -z "$error" ]] && _vif_vlan_setup > + [[ -z "$error" ]] && return 0 > + > + log error "$error" > + return 1 > +} > + > # Usage: add_to_bridge bridge dev > add_to_bridge () { > local bridge=$1 > local dev=$2 > + local vlan=$(xenstore_read_default "$XENBUS_PATH/vlan" "") > > # Don't add $dev to $bridge if it's already on the bridge. > if [ ! -e "/sys/class/net/${bridge}/brif/${dev}" ]; then > @@ -134,6 +237,14 @@ add_to_bridge () { > else > ip link set ${dev} master ${bridge} > fi > + if [ -n "${vlan}" ] ;then > + if which bridge >&/dev/null; then > + log debug "configuring VLANs for ${dev} on ${bridge}" > + _vif_vlan_membership "${dev}" "${vlan}" > + else > + log warning "bridge command not available, ignoring vlan > config" Do you think this should be fatal? It seems to me that setting up the connection but not applying the vlans could be a security issue. This file before your patch was very close to posix sh. Afterwards, it definitely needs bash. vif-bridge is /bin/bash, so it is fine. Regards, Jason
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |