From 52cb2e0bfeaba2f2206c6d9bc294f448f4df1098 Mon Sep 17 00:00:00 2001 From: Henning Stahlke Date: Thu, 3 Feb 2022 13:37:39 +0100 Subject: [PATCH] Add docker/ovs-snmp, a SNMP enabled open vSwitch image source. --- appliances/ovs-snmp.gns3a | 18 ++++++++ docker/ovs-snmp/Dockerfile | 15 +++++++ docker/ovs-snmp/README.rst | 67 ++++++++++++++++++++++++++++++ docker/ovs-snmp/boot.sh | 84 ++++++++++++++++++++++++++++++++++++++ docker/ovs-snmp/lldpd.conf | 22 ++++++++++ docker/ovs-snmp/rstp | 59 ++++++++++++++++++++++++++ docker/ovs-snmp/snmpd.conf | 23 +++++++++++ 7 files changed, 288 insertions(+) create mode 100644 appliances/ovs-snmp.gns3a create mode 100644 docker/ovs-snmp/Dockerfile create mode 100644 docker/ovs-snmp/README.rst create mode 100644 docker/ovs-snmp/boot.sh create mode 100644 docker/ovs-snmp/lldpd.conf create mode 100644 docker/ovs-snmp/rstp create mode 100644 docker/ovs-snmp/snmpd.conf diff --git a/appliances/ovs-snmp.gns3a b/appliances/ovs-snmp.gns3a new file mode 100644 index 0000000..2592022 --- /dev/null +++ b/appliances/ovs-snmp.gns3a @@ -0,0 +1,18 @@ +{ + "appliance_id": "bfafb392-bb2b-4078-8817-29c55273fff6", + "name": "Open vSwitch with SNMP", + "category": "multilayer_switch", + "description": "Customized Open vSwtich with SNMP support", + "vendor_name": "Open vSwitch", + "vendor_url": "http://openvswitch.org/", + "product_name": "Open vSwitch", + "registry_version": 3, + "status": "stable", + "maintainer": "GNS3 Team", + "maintainer_email": "developers@gns3.net", + "usage": "", + "docker": { + "adapters": 8, + "image": "gns3/ovs-snmp:latest" + } +} \ No newline at end of file diff --git a/docker/ovs-snmp/Dockerfile b/docker/ovs-snmp/Dockerfile new file mode 100644 index 0000000..80f2382 --- /dev/null +++ b/docker/ovs-snmp/Dockerfile @@ -0,0 +1,15 @@ +FROM alpine:latest +RUN apk add --no-cache nano openvswitch tcpdump net-snmp lldpd +RUN mkdir -p /run/openvswitch && mkdir -p /var/log/openvswitch +COPY snmpd.conf /etc/snmp/snmpd.conf +COPY lldpd.conf /etc/lldpd.d/lldpd.conf +COPY boot.sh /bin/boot.sh +RUN chmod a+x /bin/boot.sh + +COPY rstp /bin/rstp +RUN chmod a+x /bin/rstp + +VOLUME /etc/openvswitch/ +VOLUME /etc/lldpd.d/ + +CMD ["/bin/boot.sh"] diff --git a/docker/ovs-snmp/README.rst b/docker/ovs-snmp/README.rst new file mode 100644 index 0000000..363f824 --- /dev/null +++ b/docker/ovs-snmp/README.rst @@ -0,0 +1,67 @@ +Docker Open vSwitch with SNMP for GNS3 +-------------------------------------- +Inspired by gns3/openvswitch +This are sources for docker image for a configurable Open vSwitch with SNMP and LLDP support. + +By default, all ports will be added to br0. To have eth0 as dedicated mgmt. interface see below. + +Use case examples: +- SNMP enabled switch +- test NMS / SNMP topology detection + +Software +-------- +Based on alpine:latest with additional net-snmp and lldpd packets installed. + +SNMP agent will listen on all interfaces, read-only community is 'public' +LLDP agent is integrated with snmpd. + +Both agents can be switched on or off by the respective environment variables. + +Environment variables +--------------------- +Set the following variables to either 1 or 0 to start or not start the corresponding protocols / daemons: +LLDP, SNMP, RSTP default 1 + +Dedicated management interface +------------------------------ +If MANAGEMENT_INTERFACE=1 eth0 will not be added to br0 and needs to be configured +as usual. + +Number of bridges +----------------- +By default one bridge (br0) is created and all interfaces are added. +To create more bridges set NUM_BR=n (default n=1). +Configuration of those additional bridges needs to be done manually. + +RSTP +---- +By default RSTP will be enabled (RSTP=1). +Use RSTP_ROOT to set bridge priority. 1 for primary root, 2 for secondary root bridge. + +LLDP +---- +Use LLDP_CHASSIS_ID=someName to configure chassis id. + +LLDP_PID_TYPE={ifname | mac} configure the port id subtype e.g. what is used as port id. +For even more LLDP config, you can connect to a running container and edit /etc/lldpd.d/lldpd.conf +(the folder is added as docker volume for persistence). + +Helpers +------- +/bin/rstp is a wrapper for ovs-vsctl. +Usage: rstp command [bridge] + status show status + enable enable RSTP + disable disable RSTP and forward BPDU + primary configure bridge as primary root + secondary configure bridge as secondary root + +By default br0 will be used. + +Building the container +####################### + +.. code:: bash + + docker build -t gns3/ovs-snmp . diff --git a/docker/ovs-snmp/boot.sh b/docker/ovs-snmp/boot.sh new file mode 100644 index 0000000..cd0292d --- /dev/null +++ b/docker/ovs-snmp/boot.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# 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 3 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, see . + +# defaults +[ -z "$GNS3_MAX_ETHERNET" ] && GNS3_MAX_ETHERNET="eth0" +MAX_ETH=${GNS3_MAX_ETHERNET##*[[:alpha:]]} +echo $MAX_ETH +[ -z "$NUM_BR" ] && NUM_BR="1" +[ -z "$RSTP" ] && RSTP="1" +[ -z "$LLDP" ] && LLDP="1" +[ -z "$SNMP" ] && SNMP="1" + +MGMT_IF="br0"; [ "$MANAGEMENT_INTERFACE" == "1" ] && MGMT_IF="eth0" +VSWITCHD_OPTS="--log-file --pidfile" + + +if [ ! -f "/etc/openvswitch/conf.db" ]; then + ovsdb-tool create /etc/openvswitch/conf.db /usr/share/openvswitch/vswitch.ovsschema + + ovsdb-server --detach --remote=punix:/var/run/openvswitch/db.sock + ovs-vswitchd --detach $VSWITCHD_OPTS + ovs-vsctl --no-wait init + + x=0 + until [ $x -eq $NUM_BR ]; do + ovs-vsctl add-br br$x + ovs-vsctl set bridge br$x datapath_type=netdev + x=$((x+1)) + done + + x=0; [ "$MANAGEMENT_INTERFACE" == "1" ] && x=1 + + until [ $x -gt $MAX_ETH ]; do + ovs-vsctl add-port br0 eth$x + x=$((x+1)) + done +else + ovsdb-server --detach --remote=punix:/var/run/openvswitch/db.sock + ovs-vswitchd --detach $VSWITCHD_OPTS +fi + +x=0 +until [ $x -eq $NUM_BR ]; do + if [ "$RSTP" == "1" ]; then + rstp enable br$x + else + rstp disable br$x + fi + if [ $x -eq 0 ]; then + [ "$RSTP_ROOT" == "1" ] && rstp primary br$x + [ "$RSTP_ROOT" == "2" ] && rstp secondary br$x + fi + ip link set dev br$x up + x=$((x+1)) +done + +/sbin/udhcpc -R --timeout=1 --tryagain=1 -b -p /var/run/udhcpc.$MGMT_IF.pid -i $MGMT_IF + +[ "$LLDP" == "1" ] && /usr/sbin/lldpd -x +[ "$SNMP" == "1" ] && /usr/sbin/snmpd + +if [ -n "$LLDP_CHASSIS_ID" ]; then + lldpcli configure system chassisid $LLDP_CHASSIS_ID +fi + +if [ "$LLDP_PID_TYPE" == "ifname" ]; then + lldpcli configure lldp portidsubtype ifname +elif [ "$LLDP_PID_TYPE" == "mac" ]; then + lldpcli configure lldp portidsubtype macaddress +fi + +/bin/sh diff --git a/docker/ovs-snmp/lldpd.conf b/docker/ovs-snmp/lldpd.conf new file mode 100644 index 0000000..4236d74 --- /dev/null +++ b/docker/ovs-snmp/lldpd.conf @@ -0,0 +1,22 @@ +# +# lldpd configuration examples +# + +## timers +# configure lldp tx-interval 15 +# configure lldp tx-hold 3 + +## TLV 1 (subtype: locally assigned) +# configure system chassisid myChassisName + +## TLV 2 (uncomment only one of the following subtypes) +# configure lldp portidsubtype ifname +# configure lldp portidsubtype macaddress +# configure ports eth0 lldp portidsubtype local port0 description foo +# configure ports eth1 lldp portidsubtype local port1 + +## TLV 5 +# configure system hostname host + +## TLV 6 +# configure system description ovs-managed diff --git a/docker/ovs-snmp/rstp b/docker/ovs-snmp/rstp new file mode 100644 index 0000000..a351393 --- /dev/null +++ b/docker/ovs-snmp/rstp @@ -0,0 +1,59 @@ +#!/bin/sh +BR="br0" + +usage() { + echo "Usage $0 command [bridge]" + echo " status show status" + echo " enable enable RSTP" + echo " disable disable RSTP and forward BPDU" + echo " primary configure bridge as primary root" + echo " secondary configure bridge as secondary root" + exit 1 +} + +status() { + ovs-appctl rstp/show $1 +} + +rstp_enable() { + echo "Enabling RSTP on '$1'" + ovs-vsctl set bridge $1 rstp_enable=true + ovs-vsctl set bridge $1 other-config:forward-bpdu=false +} + +rstp_disable() { + echo "Disabling RSTP on '$1'" + ovs-vsctl set bridge $1 rstp_enable=false + ovs-vsctl set bridge $1 other-config:forward-bpdu=true +} + +rstp_setprio() { + echo "Setting RSTP bridge priority for '$1' to $2" + ovs-vsctl set bridge $1 other_config:rstp-priority=$2 +} + +[ $# -lt 1 ] && usage + +br="br0"; [ -n "$2" ] && br=$2 + +cmd=$1 +case $cmd in + enable) + rstp_enable $br + ;; + disable) + rstp_disable $br + ;; + primary) + rstp_setprio $br 24576 + ;; + secondary) + rstp_setprio $br 28672 + ;; + status) + status $br + ;; + *) + usage + ;; +esac diff --git a/docker/ovs-snmp/snmpd.conf b/docker/ovs-snmp/snmpd.conf new file mode 100644 index 0000000..3a1dd21 --- /dev/null +++ b/docker/ovs-snmp/snmpd.conf @@ -0,0 +1,23 @@ +# +# snmpd.conf +# minimal config allowing v1/v2c public read access +# for SNMPv2-MIB::system and LLDP +# + +# listen on all IPs, default port +agentAddress udp:161 + +# system +view publicview included .1.3.6.1.2.1.1 +# interfaces +view publicview included .1.3.6.1.2.1.2 +# LLDP +view publicview included .1.0.8802.1.1.2 + +view privateview included .1.3.6.1.2.1.1 + +rocommunity public default -V publicview +rwcommunity private default -V privateview + +master agentx +