]> git.ipfire.org Git - people/ms/mstpd.git/commitdiff
Add debian utils & mans
authordv1tas <dv1tas@fbe50366-0c72-4402-a84b-5d246361dba7>
Wed, 26 Jun 2013 14:46:17 +0000 (14:46 +0000)
committerdv1tas <dv1tas@fbe50366-0c72-4402-a84b-5d246361dba7>
Wed, 26 Jun 2013 14:46:17 +0000 (14:46 +0000)
Signed-off-by: Satish Ashok <sashok@cumulusnetworks.com>
git-svn-id: svn://svn.code.sf.net/p/mstpd/code/trunk@50 fbe50366-0c72-4402-a84b-5d246361dba7

Makefile
lib/bash_completion [new file with mode: 0644]
lib/ifupdown.sh [new file with mode: 0755]
lib/mstpctl-utils-interfaces.5 [new file with mode: 0644]
lib/mstpctl-utils.sh [new file with mode: 0644]
lib/mstpctl.8 [new file with mode: 0644]
lib/mstpctl_restart_config [new file with mode: 0755]

index b8dc68d97b9a70a3e142808f1d99406c674be176..12fda536683647f98fc206bc0e4bdcbfcda86ac2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,15 @@ install: all
        install -m 755 mstpd $(DESTDIR)/sbin/mstpd
        install -m 755 mstpctl $(DESTDIR)/sbin/mstpctl
        install -m 755 bridge-stp /sbin/bridge-stp
+       -mkdir -pv $(DESTDIR)/lib/mstpctl-utils/
+       cp -rv lib/* $(DESTDIR)/lib/mstpctl-utils/
+       gzip -f $(DESTDIR)/lib/mstpctl-utils/mstpctl.8
+       gzip -f $(DESTDIR)/lib/mstpctl-utils/mstpctl-utils-interfaces.5
+       if [ -d $(DESTDIR)/etc/network/if-pre-up.d ] ; then ln -sf /lib/mstpctl-utils/ifupdown.sh $(DESTDIR)/etc/network/if-pre-up.d/mstpctl ; fi
+       if [ -d $(DESTDIR)/etc/network/if-pre-up.d ] ; then ln -sf /lib/mstpctl-utils/ifupdown.sh $(DESTDIR)/etc/network/if-post-down.d/mstpctl ; fi
+       if [ -d $(DESTDIR)/etc/bash_completion.d ] ; then ln -sf /lib/mstpctl-utils/bash_completion $(DESTDIR)/etc/bash_completion.d/mstpctl ; fi
+       ln -sf /lib/mstpctl-utils/mstpctl.8.gz $(DESTDIR)/usr/share/man/man8/mstpctl.8.gz
+       ln -sf /lib/mstpctl-utils/mstpctl-utils-interfaces.5.gz $(DESTDIR)/usr/share/man/man5/mstpctl-utils-interfaces.5.gz
 
 romfs: all
        $(ROMFSINST) /sbin/mstpd
diff --git a/lib/bash_completion b/lib/bash_completion
new file mode 100644 (file)
index 0000000..7db2f2a
--- /dev/null
@@ -0,0 +1,61 @@
+# bash completion for mstpctl                                -*- shell-script -*-
+
+_mstpctl()
+{
+    local cur prev words cword
+    _init_completion || return
+
+    local command=${words[1]}
+
+    case $cword in
+        1)
+            COMPREPLY=( $( compgen -W " addbridge createtree deletetree \
+                delbridge debuglevel portmcheck setmstconfid setvid2fid \
+                setfid2mstid setmaxage setfdelay setmaxhops setforcevers \
+                settxholdcount settreeprio setportpathcost setportadminedge \
+                setportautoedge setportp2p setportrestrrole setportrestrtcn \
+                setbpduguard settreeportprio settreeportcost showbridge \
+                showmstilist showmstconfid showvid2fid showfid2mstid showport \
+                showportdetail showtree showtreeport showall \
+                sethello setageing setportnetwork" -- "$cur" ) )
+            ;;
+        2)
+            case $command in
+                debuglevel|showall)
+                    ;;
+                *)
+                    COMPREPLY=( $( compgen -W "$( brctl show | \
+                        grep 'yes\|no' | awk '{print $1}')" -- "$cur" ) )
+            esac
+            ;;
+        3)
+            case $command in
+                showport|showportdetail|showtreeport|showportpathcode|\
+                setportadminedge|setportautoedge|setportp2p|\
+                setportrestrrole|setportrestrtcn|portmcheck|\
+                settreeportprio|settreeportcost|setportnetwork)
+                    COMPREPLY=( $( compgen -W "$(for x in \
+                        `ls /sys/class/net/${words[2]}/brif/`; do echo $x; \
+                        done)" -- "$cur" ) )
+                    ;;
+                setforcevers)
+                    COMPREPLY=( $( compgen -W 'mstp rstp stp' -- "$cur" ) )
+                    ;;
+            esac
+            ;;
+        4)
+            case $command in
+                setportadminedge|setportautoedge|\
+                setportrestrrole|setportrestrtcn|setbpduguard|setportnetwork)
+                    COMPREPLY=( $( compgen -W 'yes no' -- "$cur" ) )
+                    ;;
+                setportp2p)
+                    COMPREPLY=( $(compgen -W 'yes no auto' -- "$cur" ) )
+                    ;;
+            esac
+            ;;
+    esac
+} &&
+complete -F _mstpctl -o default mstpctl
+
+# ex: ts=4 sw=4 et filetype=sh
diff --git a/lib/ifupdown.sh b/lib/ifupdown.sh
new file mode 100755 (executable)
index 0000000..5fddb9a
--- /dev/null
@@ -0,0 +1,266 @@
+#!/bin/sh
+
+# Have a look at /usr/share/doc/bridge-utils/README.Debian if you want
+# more info about the way on wich a bridge is set up on Debian.
+# Author: Satish Ashok, <sashok@cumulusnetworks.com>
+
+if [ ! -x /sbin/mstpctl ]
+then
+  exit 0
+fi
+
+. /lib/mstpctl-utils/mstpctl-utils.sh
+
+case "$IF_MSTPCTL_PORTS" in
+    "")
+       exit 0
+       ;;
+    none)
+       INTERFACES=""
+       ;;
+    *)
+       INTERFACES="$IF_MSTPCTL_PORTS"
+       ;;
+esac
+
+
+# Previous work (create the interface)
+if [ "$MODE" = "start" ] && [ ! -d /sys/class/net/$IFACE ]; then
+  brctl addbr $IFACE || exit 1
+# Previous work (stop the interface)
+elif [ "$MODE" = "stop" ];  then
+  ifconfig $IFACE down || exit 1
+fi
+
+all_interfaces= &&
+unset all_interfaces &&
+mstpctl_parse_ports $INTERFACES | while read i
+do
+  for port in $i
+  do
+    # We attach and configure each port of the bridge
+    if [ "$MODE" = "start" ] && [ ! -d /sys/class/net/$IFACE/brif/$port ]; then
+      if [ -x /etc/network/if-pre-up.d/vlan ]; then
+        env IFACE=$port /etc/network/if-pre-up.d/vlan
+      fi
+      if [ "$IF_BRIDGE_HW" ]
+      then
+         ifconfig $port down; ifconfig $port hw ether $IF_BRIDGE_HW
+      fi
+      if [ -f /proc/sys/net/ipv6/conf/$port/disable_ipv6 ]
+      then
+        echo 1 > /proc/sys/net/ipv6/conf/$port/disable_ipv6
+      fi
+      brctl addif $IFACE $port && ifconfig $port 0.0.0.0 up
+    # We detach each port of the bridge
+    elif [ "$MODE" = "stop" ] && [ -d /sys/class/net/$IFACE/brif/$port ];  then
+      ifconfig $port down && brctl delif $IFACE $port && \
+        if [ -x /etc/network/if-post-down.d/vlan ]; then
+          env IFACE=$port /etc/network/if-post-down.d/vlan
+        fi
+      if [ -f /proc/sys/net/ipv6/conf/$port/disable_ipv6 ]
+      then
+        echo 0 > /proc/sys/net/ipv6/conf/$port/disable_ipv6
+      fi
+    fi
+  done
+done
+
+# We finish setting up the bridge
+if [ "$MODE" = "start" ] ; then
+
+  if [ "$IF_MSTPCTL_STP" ]
+  then
+    brctl stp $IFACE $IF_MSTPCTL_STP
+  fi
+
+  if [ "$IF_MSTPCTL_MAXAGE" ]
+  then
+    mstpctl setmaxage $IFACE $IF_MSTPCTL_MAXAGE
+  fi
+
+  if [ "$IF_MSTPCTL_FDELAY" ]
+  then
+    mstpctl setfdelay $IFACE $IF_MSTPCTL_FDELAY
+  fi
+
+  if [ "$IF_MSTPCTL_MAXHOPS" ]
+  then
+    mstpctl setmaxhops $IFACE $IF_MSTPCTL_MAXHOPS
+  fi
+
+  if [ "$IF_MSTPCTL_TXHOLDCOUNT" ]
+  then
+    mstpctl settxholdcount $IFACE $IF_MSTPCTL_TXHOLDCOUNT
+  fi
+
+  if [ "$IF_MSTPCTL_FORCEVERS" ]
+  then
+    mstpctl setforcevers $IFACE $IF_MSTPCTL_FORCEVERS
+  fi
+
+  if [ "$IF_MSTPCTL_TREEPRIO" ]
+  then
+    mstpctl settreeprio $IFACE 0 $IF_MSTPCTL_TREEPRIO
+  fi
+
+
+  if [ "$IF_MSTPCTL_PORTPATHCOST" ]
+  then
+    portpathcosts=$(echo "$IF_MSTPCTL_PORTPATHCOST" | tr '\n' ' ' | tr -s ' ')
+    for portpathcost in $portpathcosts
+    do
+       port=$(echo $portpathcost | cut -d '=' -f1)
+       pathcost=$(echo $portpathcost | cut -d '=' -f2)
+       if [ -n $port -a -n $pathcost ]
+       then
+          mstpctl setportpathcost $IFACE $port $pathcost
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_PORTADMINEDGE" ]
+  then
+    portadminedges=$(echo "$IF_MSTPCTL_PORTADMINEDGE" | tr '\n' ' ' | tr -s ' ')
+    for portadminedge in $portadminedges
+    do
+       port=$(echo $portadminedge | cut -d '=' -f1)
+       adminedge=$(echo $portadminedge | cut -d '=' -f2)
+       if [ -n $port -a -n $adminedge ]
+       then
+          mstpctl setportadminedge $IFACE $port $adminedge
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_PORTAUTOEDGE" ]
+  then
+    portautoedges=$(echo "$IF_MSTPCTL_PORTAUTOEDGE" | tr '\n' ' ' | tr -s ' ')
+    for portautoedge in $portautoedges
+    do
+       port=$(echo $portautoedge | cut -d '=' -f1)
+       autoedge=$(echo $portautoedge | cut -d '=' -f2)
+       if [ -n $port -a -n $autoedge ]
+       then
+          mstpctl setportautoedge $IFACE $port $autoedge
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_PORTP2P" ]
+  then
+    portp2ps=$(echo "$IF_MSTPCTL_PORTP2P" | tr '\n' ' ' | tr -s ' ')
+    for portp2p in $portp2ps
+    do
+       port=$(echo $portp2p | cut -d '=' -f1)
+       p2p=$(echo $portp2p | cut -d '=' -f2)
+       if [ -n $port -a -n $p2p ]
+       then
+          mstpctl setportp2p $IFACE $port $p2p
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_PORTRESTRROLE" ]
+  then
+    portrestrroles=$(echo "$IF_MSTPCTL_PORTRESTRROLE" | tr '\n' ' ' | tr -s ' ')
+    for portrestrrole in $portrestrroles
+    do
+       port=$(echo $portrestrrole | cut -d '=' -f1)
+       restrrole=$(echo $portrestrrole | cut -d '=' -f2)
+       if [ -n $port -a -n $restrrole ]
+       then
+          mstpctl setportrestrrole $IFACE $port $restrrole
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_PORTRESTRTCN" ]
+  then
+    portrestrtcns=$(echo "$IF_MSTPCTL_PORTRESTRTCN" | tr '\n' ' ' | tr -s ' ')
+    for portrestrtcn in $portrestrtcns
+    do
+       port=$(echo $portrestrtcn | cut -d '=' -f1)
+       restrtcn=$(echo $portrestrtcn | cut -d '=' -f2)
+       if [ -n $port -a -n $restrtcn ]
+       then
+          mstpctl setportrestrtcn $IFACE $port $restrtcn
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_BPDUGUARD" ]
+  then
+    portbpduguards=$(echo "$IF_MSTPCTL_BPDUGUARD" | tr '\n' ' ' | tr -s ' ')
+    for portbpduguard in $portbpduguards
+    do
+       port=$(echo $portbpduguard | cut -d '=' -f1)
+       bpduguard=$(echo $portbpduguard | cut -d '=' -f2)
+       if [ -n $port -a -n $bpduguard ]
+       then
+          mstpctl setbpduguard $IFACE $port $bpduguard
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_TREEPORTPRIO" ]
+  then
+    treeportprios=$(echo "$IF_MSTPCTL_TREEPORTPRIO" | tr '\n' ' ' | tr -s ' ')
+    for treeportprio in $treeportprios
+    do
+       treeport=$(echo $treeportprio | cut -d '=' -f1)
+       prio=$(echo $treeportprio | cut -d '=' -f2)
+       if [ -n $treeport -a -n $prio ]
+       then
+          mstpctl settreeportprio $IFACE $treeport 0 $prio
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_TREEPORTCOST" ]
+  then
+    treeportcosts=$(echo "$IF_MSTPCTL_TREEPORTCOST" | tr '\n' ' ' | tr -s ' ')
+    for treeportcost in $treeportcosts
+    do
+       treeport=$(echo $treeportcost | cut -d '=' -f1)
+       cost=$(echo $treeportcost | cut -d '=' -f2)
+       if [ -n $treeport -a -n $cost ]
+       then
+          mstpctl settreeportcost $IFACE $treeport 0 $cost
+       fi
+    done
+  fi
+
+  if [ "$IF_MSTPCTL_HELLO" ]
+  then
+    mstpctl sethello $IFACE $IF_MSTPCTL_HELLO
+  fi
+
+  if [ "$IF_MSTPCTL_AGEING" ]
+  then
+    mstpctl setageing $IFACE $IF_MSTPCTL_AGEING
+  fi
+
+  if [ "$IF_MSTPCTL_PORTNETWORK" ]
+  then
+    portnetworks=$(echo "$IF_MSTPCTL_PORTNETWORK" | tr '\n' ' ' | tr -s ' ')
+    for portnetwork in $portnetworks
+    do
+       port=$(echo $portnetwork | cut -d '=' -f1)
+       network=$(echo $portnetwork | cut -d '=' -f2)
+       if [ -n $port -a -n $network ]
+       then
+          mstpctl setportnetwork $IFACE $port $network
+       fi
+    done
+  fi
+
+  # We activate the bridge
+  ifconfig $IFACE 0.0.0.0 up
+
+# Finally we destroy the interface
+elif [ "$MODE" = "stop" ];  then
+
+  brctl delbr $IFACE
+
+fi
diff --git a/lib/mstpctl-utils-interfaces.5 b/lib/mstpctl-utils-interfaces.5
new file mode 100644 (file)
index 0000000..bafdbed
--- /dev/null
@@ -0,0 +1,167 @@
+.\" -*- nroff -*-
+.\" macros
+.de EX \" Begin Example
+.  IP
+.  ft CW
+.  nf
+.  ne \\$1
+..
+.de EE \" End Example
+.  ft P
+.  fi
+.  PP
+..
+.TH MSTPCTL-UTILS-INTERFACES 5 "April 29 2013" "mstpctl-utils" "File formats"
+.SH NAME
+mstpctl-utils-interfaces \- mstpctl-utils extensions for the
+.BR interfaces (5)
+file format
+.SH DESCRIPTION
+/etc/network/interfaces contains network interface configuration
+information for the
+.BR ifup (8)
+and
+.BR ifdown (8)
+commands.
+This manpage describes the mstpctl extensions to the standard
+.BR interfaces (5)
+file format.
+.P
+The main extension is the mstpctl_ports option, with it you describe that the
+interface is a bridge and what ports does it have. Spanning Tree protocol
+paramaters can also be specified.
+.P
+We'll see this with an example:
+.EX
+auto br0
+iface br0 inet static
+    address 12.0.0.3
+    netmask 255.255.255.0
+    mstpctl_ports swp1 swp2 swp3
+    mstpctl_stp on
+    mstpctl_maxage 20
+    mstpctl_fdelay 15
+    mstpctl_maxhops 20
+    mstpctl_txholdcount 6
+    mstpctl_forcevers rstp
+    mstpctl_portpathcost swp1=0 swp2=0
+    mstpctl_portadminedge swp1=no swp2=no
+    mstpctl_portautoedge swp1=yes swp2=yes
+    mstpctl_portp2p swp1=no swp2=no
+    mstpctl_portrestrrole swp1=no swp2=no
+    mstpctl_bpduguard swp1=no swp2=no
+    mstpctl_portrestrtcn swp1=no swp2=no
+    mstpctl_treeprio 32768
+    mstpctl_treeportprio swp3=128
+    mstpctl_hello 2
+    mstpctl_portnetwork swp1=no
+
+.EE
+.SH IFACE OPTIONS
+The below interface options for configuring STP parameters on an STP
+enabled bridge can be specified in /etc/network/interfaces.
+.TP
+.BI mstpctl_ports " interface specification"
+this option must exist to specify the bridge and the ports which need
+to be added to the bridge.
+.RS
+.EX
+mstpctl_ports swp1 swp4
+.EE
+.P
+Regular expressions can be used to select a number of interfaces
+.EX
+mstpctl_ports regex (eth|vif).*
+.EE
+This means to evaluate (as in
+.BR egrep (1))
+the expressions that
+follow after "regex" until either the end or a "noregex" statement
+is reached.
+.SS
+.TP
+.BI mstpctl_maxage " time"
+set max message age to \fItime\fP seconds, default is 20, can have a
+fractional part.
+.TP
+.BI mstpctl_fdelay " time"
+set bridge forward delay to \fItime\fP seconds, default is 15.
+.TP
+.BI mstpctl_maxhops " max_hops"
+set bridge maximum hops to \fImax_hops\fP, default is 15.
+.TP
+.BI mstpctl_forcevers " mstp|rstp|stp"
+sets the bridge's force STP version to either rstp/stp. mstp is
+not supported currently, default is rstp.
+.TP
+.BI mstpctl_txholdcount " tx_hold_count"
+set bridge transmit hold count to \fItx_hold_count\fP, default is 6.
+.TP
+.BI mstpctl_treeprio " priority"
+set bridge tree priority, \fIpriority\fP is between 0 and 65535,
+is a multiple of 4096 and default is 32768. Bridge priority affects
+bridge id, lowest priority bridge will be the root.
+.TP
+.BI mstpctl_portpathcost " port cost"
+set path cost for a port, default is 0, \fIport\fP is the name of
+the interface to which this setting applies.
+.TP
+.BI mstpctl_portadminedge " port yes|no"
+Enables/disables the initial edge state of the port <port>, default is no.
+.TP
+.BI mstpctl_portautoedge " port yes|no"
+Enables/disables the auto transition to/from edge state of the port <port>,
+default is no.
+.TP
+.BI mstpctl_portp2p " port yes|no"
+Enables/disables the point2point detection mode of the port <port>,
+default is no.
+.TP
+.BI mstpctl_portrestrrole " port yes|no"
+Enables/disables the port ability to take root role of the port <port>,
+default is no.
+.TP
+.BI mstpctl_portrestrtcn " port yes|no"
+Enables/disables the port ability to propagate received topology change
+notification of the port <port>, default is no.
+.TP
+.BI mstpctl_bpduguard " port yes|no"
+Enables/disables the bpduguard configuration of the port, default is no.
+.TP
+.BI mstpctl_treeportprio " port priority"
+sets the port <port>'s priority to <priority> for the MSTI instance.
+The priority value is a number between 0 and 240, is a multiple of 16,
+default is 128. Only MSTI 0 is supported currently.
+.TP
+.BI mstpctl_hello " time"
+set hello time to \fItime\fP seconds, default is 2.
+.TP
+.BI mstpctl_ageing " time"
+sets the ethernet (MAC) address ageing time, in seconds for the bridge
+when the running version is STP, but not RSTP/MSTP, default is 300s.
+.TP
+.BI mstpctl_portnetwork " port yes|no"
+Enables/disables the bridge assurance capability for a network port <port>,
+default is no.
+.TP
+.BI mstpctl_stp " state"
+turn spanning tree protocol on/off, \fIstate\fP values are no/yes,
+default is no.
+.RE
+.SH FILES
+.TP
+.I /etc/network/interfaces
+definitions of network interfaces
+See
+.BR interfaces (5)
+for more information.
+.RE
+.SH AUTHOR
+This manpage was written by Satish Ashok <sashok@cumulusnetworks.com>
+based on \fBbrctl-utils-interfaces\fP(5).
+.SH "SEE ALSO"
+.BR brctl (8),
+.BR interfaces (5),
+.BR ifup (8),
+.BR iwconfig (8),
+.BR run\-parts (8).
diff --git a/lib/mstpctl-utils.sh b/lib/mstpctl-utils.sh
new file mode 100644 (file)
index 0000000..78f1f82
--- /dev/null
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+mstpctl_parse_ports()
+{
+  while [ x"${1+set}" = xset ]
+  do
+    # For compatibility: the `all' option.
+    case $1 in
+      all)
+       shift &&
+       set regex eth.\* em.\* 'p[0-9].*' noregex "$@"
+       ;;
+    esac
+
+    # Primitive state machine...
+    case $1-`uname -s` in
+      regex-Linux)
+       all_interfaces=`sed -n 's%^[\ ]*\([^:]*\):.*$%\1%p' < /proc/net/dev`
+       shift
+       ;;
+      regex-*)
+       echo -n "$0 needs to be ported for your `uname -s` system.  " >&2
+       echo "Trying to continue nevertheless." >&2
+       shift
+       ;;
+      noregex-*)
+       all_interfaces=
+       unset all_interfaces
+       shift
+       ;;
+    esac
+
+    case ${all_interfaces+regex}-${1+set} in
+      regex-set)
+       # The following interface specification are to be parsed as regular
+       # expressions against all interfaces the system provides.
+       i=`egrep "^$1$" << EOAI
+$all_interfaces
+EOAI
+`
+       shift
+       ;;
+      *-set)
+       # Literal interfaces.
+       i=$1
+       shift
+       ;;
+      *)
+       # No interface specification is following.
+       i=
+       ;;
+    esac
+
+    echo $i
+  done
+}
diff --git a/lib/mstpctl.8 b/lib/mstpctl.8
new file mode 100644 (file)
index 0000000..9ccebef
--- /dev/null
@@ -0,0 +1,124 @@
+.\"
+.\"    This program is free software; you can redistribute it and/or modify
+.\"    it under the terms of the GNU General Public License as published by
+.\"    the Free Software Foundation; either version 2 of the License, or
+.\"    (at your option) any later version.
+.\"
+.\"    This program is distributed in the hope that it will be useful,
+.\"    but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\"    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\"    GNU General Public License for more details.
+.\"
+.\"    You should have received a copy of the GNU General Public License
+.\"    along with this program; if not, write to the Free Software
+.\"    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+.\"
+.\"
+.TH MSTPCTL 8 "April 29, 2013" "" ""
+.SH NAME
+mstpctl \- STP/RSTP/MSTP configuration
+.SH SYNOPSIS
+.BR "mstpctl [command]"
+.SH DESCRIPTION
+.B mstpctl
+is used to configure Spanning Tree and Rapid Spanning Tree
+configuration. Multiple Spanning Tree configuration is not supported
+currently. MSTPCTL is used for configuring STP parameters on bridges
+which have STP enabled. Currently, STP is disabled by default on the bridge.
+To enable STP, configure "brctl stp <bridge> on".
+
+.SH SPANNING TREE PROTOCOL CONFIGURATION
+
+.IR mstpctl(8)
+can be used for configuring certain spanning tree protocol
+parameters. For an explanation of these parameters, see the IEEE
+802.1D and 802.1Q specification .
+
+.B mstpctl setmaxage <bridge> <max_age>
+sets the bridge's 'maximum age' to <time> seconds.
+
+.B mstpctl setfdelay <bridge> <time>
+sets the bridge's 'bridge forward delay' to <time> seconds.
+
+.B mstpctl setmaxhops <bridge> <max_hops>
+sets the bridge's 'maximum hops' to <max_hops>.
+
+.B mstpctl setforcevers <bridge> {mstp|rstp|stp}
+sets the bridge's force STP version to either rstp/stp. mstp is
+not supported currently.
+
+.B mstpctl settxholdcount <bridge> <tx_hold_count>
+sets the bridge's 'bridge transmit hold count' to <tx_hold_count>.
+
+.B mstpctl settreeprio <bridge> <mstid> <priority>
+sets the bridge tree priority to <priority> for an MSTI instance.
+Only mstid value 0 is supported currently. The priority value is a number
+between 0 and 65535 and is a multiple of 4096. The bridge with the lowest
+priority will be elected 'root bridge'.
+
+.B mstpctl setportpathcost <bridge> <port> <cost>
+sets the port cost of the port <port> in bridge <bridge> to <cost>.
+
+.B mstpctl setportadminedge <bridge> <port> {yes|no}
+Enables/disables the initial edge state of the port <port> in bridge <bridge>.
+
+.B mstpctl setportautoedge <bridge> <port> {yes|no}
+Enables/disables the auto transition to/from edge state of the port <port> in
+bridge <bridge>.
+
+.B mstpctl setportp2p <bridge> <port> {yes|no|auto}
+Enables/disables the point2point detection mode of the port <port> in
+bridge <bridge>.
+
+.B mstpctl setportrestrrole <bridge> <port> {yes|no}
+Enables/disables the port ability to take root role of the port <port> in
+bridge <bridge>.
+
+.B mstpctl setportrestrtcn <bridge> <port> {yes|no}
+Enables/disables the port ability to propagate received topology change
+notification of the port <port> in bridge <bridge>.
+
+.B mstpctl setbpduguard <bridge> <port> {yes|no}
+Enables/disables the bpduguard configuration of the port in bridge <bridge>.
+
+.B mstpctl settreeportprio <bridge> <port> <mstid> <priority>
+sets the port <port>'s priority to <priority> for the MSTI instance.
+The priority value is a number between 0 and 240 and is a multiple of 16.
+
+.B mstpctl sethello <bridge> <time>
+sets the bridge's 'bridge hello time' to <time> seconds.
+
+.B mstpctl setageing <brname> <time>
+sets the ethernet (MAC) address ageing time, in seconds for the bridge
+when the running version is STP, but not RSTP/MSTP.
+
+.B mstpctl setportnetwork <bridge> <port> {yes|no}
+Enables/disables the bridge assurance capability for a network port <port> in
+bridge <bridge>.
+
+.SH SPANNING TREE PROTOCOL SHOW COMMANDS
+.B mstpctl showbridge <brname>
+will show information of the bridge.
+
+.B mstpctl showport <brname>
+will show information of the bridge ports.
+
+.B mstpctl showportdetail <brname>
+will show detailed information of the bridge ports.
+
+.B mstpctl showtree <brname> <mstid>
+will show tree information of the bridge in MSTI instance.
+
+.B mstpctl showtreeport <brname> <port> <mstid>
+will show per tree port information of the bridge port in MSTI instance.
+
+.B mstpctl showall
+will show detailed information of the bridge.
+
+.SH SEE ALSO
+.BR brctl(8)
+
+.SH AUTHOR
+The source code for mstpctl was written by Vitalii Demianets
+<vitas@nppfactor.kiev.ua>. This manpage was written by Satish Ashok
+<sashok@cumulusnetworks.com> based on \fBbrctl\fP(8).
diff --git a/lib/mstpctl_restart_config b/lib/mstpctl_restart_config
new file mode 100755 (executable)
index 0000000..d76a627
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+# mstpctl_restart_cfg_gen -
+# On MSTPD restart, readd the bridges which are configured currently.
+# Also, parse the interfaces files to replay MSTPCTL confguration
+# Author: Satish Ashok, <sashok@cumulusnetworks.com>
+#
+
+import os
+import glob
+
+mstpctl_br_cfg      = ['maxage', 'fdelay', 'maxhops', 'txholdcount', \
+                      'forcevers', 'hello', 'ageing']
+mstpctl_br_msti_cfg = ['treeprio']
+mstpctl_prt_cfg      = ['portpathcost', 'portadminedge', 'portautoedge', \
+                        'portp2p', 'portrestrrole', 'portrestrtcn', \
+                        'bpduguard', 'treeportprio', 'treeportcost',
+                        'portnetwork']
+
+#List of bridges which are present currently
+bridge_list = []
+
+# Form a list of bridge interfaces present and add the bridge in
+# mstpd using mstpctl to get mstpd know about the bridge and bridge ports.
+#
+def find_bridges():
+    global bridge_list
+    try:
+        dirList = os.listdir('/sys/class/net/')
+    except:
+        return None
+    for br_name in dirList:
+       # Verify if interface is a bridge
+        br_path = '/sys/class/net/' + br_name + '/bridge'
+        if os.path.exists(br_path) :
+           # Verify if bridge was in user_stp mode earlier
+            br_stp_file = br_path + '/' + 'stp_state'
+            f = open(br_stp_file)
+            stp_state = f.read()
+            if '2' in stp_state :
+                bridge_list.append(br_name)
+                os.system ("mstpctl addbridge " + br_name)
+            f.close()
+
+# Parse the interfaces file and extract all mstpctl configuration
+# present for bridge ports and replay the commands with the format
+# mstpctl set<command> so that mstpd gets the configuration.
+#
+def parse_config(filename):
+    f = open(filename)
+    intf = ''
+    for line in f:
+        str = line.strip().split(' ')
+        len_str = len(str)
+        if 2 > len_str :
+            continue
+        # Check if the source <file> keyword is present and extract the file
+        if str[0] == 'source' :
+            for sfile in glob.glob(str[1]):
+                parse_config(sfile)
+        if str[0] == 'iface' :
+            intf = str[1]
+        # Check if the interface is present in the bridge_list.
+        # This ensures that we replay configuration only for
+        # the bridges which are present currently.
+        if intf not in bridge_list :
+            continue
+        # Find if mstpctl_ keyword is present
+        if 'mstpctl_' in str[0] :
+            head, temp, mstp_cfg = str[0].partition('mstpctl_')
+            # Replay bridge configuration
+            if mstp_cfg in mstpctl_br_cfg :
+                os.system ("mstpctl set{0} {1} {2}".format(mstp_cfg,intf,str[1]))
+            # Replay Bridge CIST configuration, since MSTP not supported,
+            # hardcode MSTID to 0.
+            elif mstp_cfg in mstpctl_br_msti_cfg :
+                os.system ("mstpctl set{0} {1} 0 {2}".format(mstp_cfg,intf,str[1]))
+            # Replay Bridge port configuration
+            elif mstp_cfg in mstpctl_prt_cfg :
+                i = 1
+                # Find the list of ports present
+                while i < len_str :
+                    # Find the port and configuration
+                    port, temp1, prt_cfg = str[i].partition('=')
+                    # CIST Configuration - hardcode MSTID to 0.
+                    if mstp_cfg == 'treeportprio' or mstp_cfg == 'treeportcost' :
+                        os.system ("mstpctl set{0} {1} {2} 0 {3}"\
+                                    .format(mstp_cfg,intf, port, prt_cfg))
+                    else:
+                        os.system ("mstpctl set{0} {1} {2} {3}"\
+                                    .format(mstp_cfg,intf, port, prt_cfg))
+                    i = i + 1
+    f.close()
+    return
+
+find_bridges()
+parse_config('/etc/network/interfaces')