Add support for Black Hole Detection

Change-Id: Ibb56674a453ede3661083838aaeef7bb2d1ae566
This commit is contained in:
Volodymyr Samotiy 2016-07-21 17:04:31 +03:00
parent 27c192c61e
commit d0f40b1445
14 changed files with 2898 additions and 20 deletions

View File

@ -91,6 +91,11 @@ A command line application that can be used to configure BroadView BST.
A command line application that can be used to configure BroadView PacketTrace.
### bv-bhdctl.py
A command line application that can be used to configure BroadView's Black
Hole Detection feature.
### bv-ctl.py
A command line application that can be used to issue general BroadView
@ -266,6 +271,52 @@ The class PTParser (found in pt/pt_parser.py) accepts the JSON payload
that is sent by a BroadView agent for PacketTrace, and converts this
payload into Python objects. It provides an API for accessing these objects.
## Black Hole Detection Configuration and Reports
The bhd.py file in config contains various configuration and data gathering
classes.
The following briefly summarizes these classes. For example usage, see the
unit test code in bhd.py, or the bv-bhdctl.py application.
### BlackHoleDetectionEnable
This class can be used to enable (or disable) black hole detection.
### ConfigureBlackHole
This class configures the Black Hole Detection functionality on the switch.
### CancelBlackHole
This class nullifies the configuration made by the ConfigureBlackHole class.
### GetBlackHoleDetectionEnable
This class can be used to determine of black hole detection is enabled or not.
### GetBlackHole
This class is used to get the current configuration of black hole detection
on the agent.
### GetBlackHoleEventReport
This class is used to get a black hole event report. It is only valid if the
agent sampling mode is configured on the agent.
### GetSFlowSamplingStatus
This class is used to get current sFlow sampling status of Black Holed
traffic.
## BHDParser Object
The class BHDParser (found in bhd/bhd_parser.py) accepts the JSON payload
that is sent by a BroadView agent for Black Hole Detection, and converts this
payload into Python objects. It provides an API for accessing the data that
is contained in these objects.
## Unit tests
To ensure that broadview-lib is decoupled from any (and all) OpenStack

View File

View File

@ -0,0 +1,56 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class AgentSamplingParams():
def __init__(self):
self._waterMark = 0
self._samplePeriodicity = 0
self._sampleCount = 0
def getWaterMark(self):
return self._waterMark
def getSamplePeriodicity(self):
return self._samplePeriodicity
def getSampleCount(self):
return self._sampleCount
def __repr__(self):
return "agent-sampling-params"
def parse(self, data):
ret = True
if "sampling-params" in data:
p = data["sampling-params"]
else:
ret = False
if ret:
if "water-mark" in p:
self._waterMark = p["water-mark"]
else:
ret = False
if "sample-periodicity" in p:
self._samplePeriodicity = p["sample-periodicity"]
else:
ret = False
if "sample-count" in p:
self._sampleCount = p["sample-count"]
else:
ret = False
return ret

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import agent_sampling_params
import sflow_sampling_params
class BlackHole():
AgentSampling = 1
SFlowSampling = 2
def __init__(self):
self._portList = []
self._samplingMethod = None
self._samplingParams = None
def getSamplingMethod(self):
return self._samplingMethod
def getPortList(self):
return self._portList
def getSamplingParams(self):
return self._samplingParams
def __repr__(self):
return "get-black-hole"
def parse(self, data):
ret = True
if "sampling-method" in data:
if data["sampling-method"] == "sflow":
self._samplingMethod = BlackHole.SFlowSampling
self._samplingParams = sflow_sampling_params.SFlowSamplingParams()
elif data["sampling-method"] == "agent":
self._samplingMethod = BlackHole.AgentSampling
self._samplingParams = agent_sampling_params.AgentSamplingParams()
else:
ret = False
else:
ret = False
if ret:
if not "port-list" in data:
ret = False
else:
self._portList = data["port-list"]
if ret:
ret = self._samplingParams.parse(data)
return ret

View File

@ -0,0 +1,60 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class BlackHoleEventReport():
def __init__(self):
self._ingressPort = None
self._egressPortList = []
self._blackHoledPacketCount = 0
self._samplePacket = None
def getIngressPort(self):
return self._ingressPort
def getEgressPortList(self):
return self._egressPortList
def getBlackHoledPacketCount(self):
return self._blackHoledPacketCount
def getSamplePacket(self):
return self._samplePacket
def __repr__(self):
return "get-black-hole-event-report"
def parse(self, data):
ret = True
if "ingress-port" in data:
self._ingressPort = data["ingress-port"]
else:
ret = False
if "egress-port-list" in data:
self._egressPortList = data["egress-port-list"]
else:
ret = False
if "black-holed-packet-count" in data:
self._blackHoledPacketCount = data["black-holed-packet-count"]
else:
ret = False
if "sample-packet" in data:
self._samplePacket = data["sample-packet"]
else:
ret = False
return ret

View File

@ -0,0 +1,88 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class SFlowSamplingParams():
def __init__(self):
self._vlanId = 0
self._dstIP = None
self._srcUDPPort = 0
self._dstUDPPort = 0
self._mirrorPort = None
self._samplePoolSize = 0
def getVLANId(self):
return self._vlanId
def getDstIP(self):
return self._dstIP
def getSrcUDPPort(self):
return self._srcUDPPort
def getDstUDPPort(self):
return self._dstUDPPort
def getMirrorPort(self):
return self._mirrorPort
def getSamplePoolSize(self):
return self._samplePoolSize
def __repr__(self):
return "sflow-sampling-params"
def parse(self, data):
ret = True
if "sampling-params" in data:
p = data["sampling-params"]
else:
ret = False
if ret:
if "mirror-port" in p:
self._mirrorPort = p["mirror-port"]
else:
ret = False
if "sample-pool-size" in p:
self._samplePoolSize = p["sample-pool-size"]
else:
ret = False
if "encapsulation-params" in p:
# embedded object, note we are changing p here
p = p["encapsulation-params"]
else:
ret = False
if "vlan-id" in p:
self._vlanId = p["vlan-id"]
else:
ret = False
if "destination-ip" in p:
self._dstIP = p["destination-ip"]
else:
ret = False
if "source-udp-port" in p:
self._srcUDPPort = p["source-udp-port"]
else:
ret = False
if "destination-udp-port" in p:
self._dstUDPPort = p["destination-udp-port"]
else:
ret = False
return ret

View File

@ -0,0 +1,80 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class SFlowSamplingStatusEntry():
def __init__(self):
self._port = None
self._sflowSamplingEnabled = False
self._sampledPacketCount = 0
self._blackHoledPacketCount = 0
def getSFlowSamplingEnabled(self):
return self._sflowSamplingEnabled
def getPort(self):
return self._port
def getSampledPacketCount(self):
return self._sampledPacketCount
def getBlackHoledPacketCount(self):
return self._blackHoledPacketCount
class SFlowSamplingStatus():
def __init__(self):
self.__table = []
def __iter__(self):
self.__n = 0
return self
def next(self):
if self.__n >= len(self.__table):
raise StopIteration
else:
n = self.__n
self.__n += 1
return self.__table[n]
def __repr__(self):
return "sflow-sampling-status"
def parse(self, data):
ret = True
if not "data" in data:
ret = False
else:
for y in data["data"]:
val = SFlowSamplingStatusEntry()
if not "port" in y:
ret = False
break
val._port = y["port"]
if not "sflow-sampling-enabled" in y:
ret = False
break
val._sflowSamplingEnabled = y["sflow-sampling-enabled"] == 1
if not "sampled-packet-count" in y:
ret = False
break
val._sampledPacketCount = y["sampled-packet-count"]
if not "black-holed-packet-count" in y:
ret = False
break
val._blackHoledPacketCount = y["black-holed-packet-count"]
self.__table.append(val)
return ret

533
broadview_lib/config/bhd.py Normal file
View File

@ -0,0 +1,533 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from agentapi import AgentAPI
from broadview_lib.bhd.bhd_parser import BHDParser
from broadview_lib.config.broadviewconfig import BroadViewBSTSwitches
import unittest
class BlackHoleDetectionEnable(AgentAPI):
def __init__(self, host, port):
super(BlackHoleDetectionEnable, self).__init__()
self.setFeature("black-hole-detection")
self.setHttpMethod("POST")
self.setHost(host)
self.setPort(port)
self.__black_hole_detection_enable = False
self.__asic_id = "1"
def setEnable(self, val):
self.__black_hole_detection_enable = val
def setASIC(self, val):
self.__asic_id = val
def send(self, timeout=30):
status, json = self._send(self.toDict(), timeout)
return status
def toDict(self):
ret = {}
params = {}
params["enable"] = 1 if self.__black_hole_detection_enable else 0
ret["asic-id"] = self.__asic_id
ret["params"] = params
ret["method"] = "black-hole-detection-enable"
return ret
class ConfigureBlackHole(AgentAPI):
def __init__(self, host, port):
super(ConfigureBlackHole, self).__init__()
self.setFeature("black-hole-detection")
self.setHttpMethod("POST")
self.setHost(host)
self.setPort(port)
self.__port_list = []
self.__sampling_method = "agent"
self.__water_mark = 200
self.__sample_periodicity = 15
self.__sample_count = 10
self.__vlan_id = 1
self.__destination_ip = None
self.__source_udp_port = None
self.__destination_udp_port = None
self.__mirror_port = None
self.__sample_pool_size = None
self.__asic_id = "1"
def setPortList(self, val):
self.__port_list = val
def setSamplingMethod(self, val):
self.__sampling_method = val
def setWaterMark(self, val):
self.__water_mark = val
def setSamplePeriodicity(self, val):
self.__sample_periodicity = val
def setSampleCount(self, val):
self.__sample_count = val
def setVLANId(self, val):
self.__vlan_id = val
def setDestinationIP(self, val):
self.__destination_ip = val
def setSourceUDPPort(self, val):
self.__source_udp_port = val
def setDestinationUDPPort(self, val):
self.__destination_udp_port = val
def setMirrorPort(self, val):
self.__mirror_port = val
def setSamplePoolSize(self, val):
self.__sample_pool_size = val
def setASIC(self, val):
self.__asic_id = val
def send(self, timeout=30):
status, json = self._send(self.toDict(), timeout)
return status
def toDict(self):
ret = {}
params = {}
params["port-list"] = self.__port_list
params["sampling-method"] = self.__sampling_method
params["sampling-params"] = {}
if self.__sampling_method == "agent":
params["sampling-params"]["water-mark"] = self.__water_mark
params["sampling-params"]["sample-periodicity"] = self.__sample_periodicity
params["sampling-params"]["sample-count"] = self.__sample_count
else:
params["sampling-params"]["encapsulation-params"] = {}
params["sampling-params"]["encapsulation-params"]["vlan-id"] = self.__vlan_id
params["sampling-params"]["encapsulation-params"]["destination-ip"] = self.__destination_ip
params["sampling-params"]["encapsulation-params"]["source-udp-port"] = self.__source_udp_port
params["sampling-params"]["encapsulation-params"]["destination-udp-port"] = self.__destination_udp_port
params["sampling-params"]["mirror-port"] = self.__mirror_port
params["sampling-params"]["sample-pool-size"] = self.__sample_pool_size
ret["asic-id"] = self.__asic_id
ret["params"] = params
ret["method"] = "configure-black-hole"
return ret
class CancelBlackHole(AgentAPI):
def __init__(self, host, port):
super(CancelBlackHole, self).__init__()
self.setFeature("black-hole-detection")
self.setHttpMethod("POST")
self.setHost(host)
self.setPort(port)
self.__id = 0
self.__asic_id = "1"
def setId(self, val):
self.__id = val
def setASIC(self, val):
self.__asic_id = val
def send(self, timeout=30):
status, json = self._send(self.toDict(), timeout)
return status
def toDict(self):
ret = {}
params = {}
params["id"] = self.__id
ret["asic-id"] = self.__asic_id
ret["params"] = params
ret["method"] = "cancel-black-hole"
return ret
'''
Status/Reporting Requests
'''
class GetBlackHoleDetectionEnable(AgentAPI):
def __init__(self, host, port):
super(GetBlackHoleDetectionEnable, self).__init__()
self.setFeature("black-hole-detection")
self.setHttpMethod("POST")
self.setHost(host)
self.setPort(port)
self.__enable = False
self.__asic_id = "1"
self.__json = None
def getEnable(self):
return self.__bhd_enable
def getASIC(self):
return self.__asic_id
def setASIC(self, val):
self.__asic_id = val
def getJSON(self):
return self.__json
def send(self, timeout=30):
status, json = self._send(self.toDict(), timeout)
if status == 200:
self.__version = json["version"]
res = json["result"]
self.__json = res
self.__enable = res["enable"] == 1
return status
def toDict(self):
ret = {}
params = {}
params["enable"] = 1 if self.__enable == True else 0
ret["asic-id"] = self.__asic_id
ret["params"] = params
ret["method"] = "get-black-hole-detection-enable"
return ret
class GetBlackHole(AgentAPI):
def __init__(self, host, port):
super(GetBlackHole, self).__init__()
self.setFeature("black-hole-detection")
self.setHttpMethod("POST")
self.setHost(host)
self.setPort(port)
self.__asic_id = "1"
self.__json = None
def getASIC(self):
return self.__asic_id
def setASIC(self, val):
self.__asic_id = val
def getJSON(self):
return self.__json
def send(self, timeout=30):
status, json = self._send(self.toDict(), timeout)
rep = None
if status == 200:
self.__json = json["result"]
rep = PTParser()
rep.process(json)
return status, rep
def toDict(self):
ret = {}
params = {}
ret["asic-id"] = self.__asic_id
ret["params"] = params
ret["method"] = "get-black-hole"
return ret
class GetSFlowSamplingStatus(AgentAPI):
def __init__(self, host, port):
super(GetSFlowSamplingStatus, self).__init__()
self.setFeature("black-hole-detection")
self.setHttpMethod("POST")
self.setHost(host)
self.setPort(port)
self.__port_list = []
self.__asic_id = "1"
self.__json = None
def getASIC(self):
return self.__asic_id
def setASIC(self, val):
self.__asic_id = val
def setPortList(self, val):
self.__port_list = val
def getJSON(self):
return self.__json
def send(self, timeout=30):
status, json = self._send(self.toDict(), timeout)
rep = None
if status == 200:
self.__json = json["report"]
rep = PTParser()
rep.process(json)
return status, rep
def toDict(self):
ret = {}
params = {}
params["port-list"] = self.__port_list
ret["asic-id"] = self.__asic_id
ret["params"] = params
ret["method"] = "get-sflow-sampling-status"
return ret
class TestBHDAPIParams(unittest.TestCase):
def setUp(self):
pass
def test_BlackHoleDetectionEnable(self):
sw = BroadViewBSTSwitches()
if len(sw):
for x in sw:
host = x["ip"]
port = x["port"]
break
else:
host = "192.168.3.1"
port = 8080
x = BlackHoleDetectionEnable(host, port)
d = x.toDict()
self.assertTrue("asic-id" in d)
self.assertTrue("params" in d)
self.assertTrue("method" in d)
self.assertTrue(x.getFeature() == "black-hole-detection")
self.assertTrue(x.getHttpMethod() == "POST")
self.assertTrue(x.getHost() == host)
self.assertTrue(x.getPort() == port)
self.assertTrue(d["asic-id"] == "1")
self.assertTrue(d["method"] == "black-hole-detection-enable")
params = d["params"]
self.assertEqual(params["enable"], False)
x.setEnable(True)
d = x.toDict()
params = d["params"]
self.assertEqual(params["enable"], True)
x.setEnable(False)
d = x.toDict()
params = d["params"]
self.assertEqual(params["enable"], False)
def test_ConfigureBlackHole(self):
sw = BroadViewBSTSwitches()
if len(sw):
for x in sw:
host = x["ip"]
port = x["port"]
break
else:
host = "192.168.3.1"
port = 8080
x = ConfigureBlackHole(host, port)
d = x.toDict()
self.assertTrue("asic-id" in d)
self.assertTrue("params" in d)
self.assertTrue("method" in d)
self.assertTrue(x.getFeature() == "black-hole-detection")
self.assertTrue(x.getHttpMethod() == "POST")
self.assertTrue(x.getHost() == host)
self.assertTrue(x.getPort() == port)
params = d["params"]
samplingParams = params["sampling-params"]
self.assertTrue(d["asic-id"] == "1")
self.assertEqual(len(params["port-list"]), 0)
self.assertEqual(params["sampling-method"], "agent")
self.assertTrue(samplingParams["water-mark"] == 200)
self.assertTrue(samplingParams["sample-periodicity"] == 15)
self.assertTrue(samplingParams["sample-count"] == 10)
x.setSamplingMethod("agent")
x.setPortList(["1","5","6","10-15"])
x.setWaterMark(500)
x.setSamplePeriodicity(25)
x.setSampleCount(50)
x.setVLANId(4000)
x.setDestinationIP("10.0.0.4")
x.setSourceUDPPort(1234)
x.setDestinationUDPPort(5678)
x.setMirrorPort(8)
x.setSamplePoolSize(5)
d = x.toDict()
params = d["params"]
samplingParams = params["sampling-params"]
self.assertEqual(params["sampling-method"], "agent")
self.assertTrue("port-list" in params)
self.assertTrue("water-mark" in samplingParams)
self.assertTrue("sample-periodicity" in samplingParams)
self.assertTrue("sample-count" in samplingParams)
self.assertTrue(not "vlan-id" in samplingParams)
self.assertTrue(not "destination-ip" in samplingParams)
self.assertTrue(not "source-udp-port" in samplingParams)
self.assertTrue(not "destination-udp-port" in samplingParams)
self.assertTrue(not "mirror-port" in samplingParams)
self.assertTrue(not "sample-pool-size" in samplingParams)
self.assertTrue(samplingParams["water-mark"] == 500)
self.assertTrue(samplingParams["sample-periodicity"] == 25)
self.assertTrue(samplingParams["sample-count"] == 50)
self.assertTrue(len(params["port-list"]) == 4)
self.assertTrue("1" in params["port-list"])
self.assertTrue("5" in params["port-list"])
self.assertTrue("6" in params["port-list"])
self.assertTrue("10-15" in params["port-list"])
x.setSamplingMethod("sflow")
d = x.toDict()
params = d["params"]
samplingParams = params["sampling-params"]
encapsulationParams = samplingParams["encapsulation-params"]
self.assertEqual(params["sampling-method"], "sflow")
self.assertTrue("port-list" in params)
self.assertTrue(not "water-mark" in samplingParams)
self.assertTrue(not "sample-periodicity" in samplingParams)
self.assertTrue(not "sample-count" in samplingParams)
self.assertTrue("vlan-id" in encapsulationParams)
self.assertTrue("destination-ip" in encapsulationParams)
self.assertTrue("source-udp-port" in encapsulationParams)
self.assertTrue("destination-udp-port" in encapsulationParams)
self.assertTrue("mirror-port" in samplingParams)
self.assertTrue("sample-pool-size" in samplingParams)
self.assertTrue(encapsulationParams["vlan-id"] == 4000)
self.assertTrue(encapsulationParams["destination-ip"] == "10.0.0.4")
self.assertTrue(encapsulationParams["source-udp-port"] == 1234)
self.assertTrue(encapsulationParams["destination-udp-port"] == 5678)
self.assertTrue(samplingParams["mirror-port"] == 8)
self.assertTrue(samplingParams["sample-pool-size"] == 5)
self.assertTrue(len(params["port-list"]) == 4)
self.assertTrue("1" in params["port-list"])
self.assertTrue("5" in params["port-list"])
self.assertTrue("6" in params["port-list"])
self.assertTrue("10-15" in params["port-list"])
def test_CancelBlackHole(self):
sw = BroadViewBSTSwitches()
if len(sw):
for x in sw:
host = x["ip"]
port = x["port"]
break
else:
host = "192.168.3.1"
port = 8080
x = CancelBlackHole(host, port)
d = x.toDict()
self.assertTrue("asic-id" in d)
self.assertTrue("params" in d)
self.assertTrue("method" in d)
self.assertTrue(x.getFeature() == "black-hole-detection")
self.assertTrue(x.getHttpMethod() == "POST")
self.assertTrue(x.getHost() == host)
self.assertTrue(x.getPort() == port)
self.assertTrue(d["asic-id"] == "1")
self.assertTrue(d["method"] == "cancel-black-hole")
def test_GetBlackHoleDetectionEnable(self):
sw = BroadViewBSTSwitches()
if len(sw):
for x in sw:
host = x["ip"]
port = x["port"]
break
else:
host = "192.168.3.1"
port = 8080
x = GetBlackHoleDetectionEnable(host, port)
d = x.toDict()
self.assertTrue("asic-id" in d)
self.assertTrue("params" in d)
self.assertTrue("method" in d)
self.assertTrue(x.getFeature() == "black-hole-detection")
self.assertTrue(x.getHttpMethod() == "POST")
self.assertTrue(x.getHost() == host)
self.assertTrue(x.getPort() == port)
self.assertTrue(d["asic-id"] == "1")
self.assertTrue(d["method"] == "get-black-hole-detection-enable")
def test_GetBlackHole(self):
sw = BroadViewBSTSwitches()
if len(sw):
for x in sw:
host = x["ip"]
port = x["port"]
break
else:
host = "192.168.3.1"
port = 8080
x = GetBlackHole(host, port)
d = x.toDict()
self.assertTrue("asic-id" in d)
self.assertTrue("params" in d)
self.assertTrue("method" in d)
self.assertTrue(x.getFeature() == "black-hole-detection")
self.assertTrue(x.getHttpMethod() == "POST")
self.assertTrue(x.getHost() == host)
self.assertTrue(x.getPort() == port)
self.assertTrue(d["asic-id"] == "1")
self.assertTrue(d["method"] == "get-black-hole")
def test_GetSFlowSamplingStatus(self):
sw = BroadViewBSTSwitches()
if len(sw):
for x in sw:
host = x["ip"]
port = x["port"]
break
else:
host = "192.168.3.1"
port = 8080
x = GetSFlowSamplingStatus(host, port)
d = x.toDict()
self.assertTrue("asic-id" in d)
self.assertTrue("params" in d)
self.assertTrue("method" in d)
self.assertTrue(x.getFeature() == "black-hole-detection")
self.assertTrue(x.getHttpMethod() == "POST")
self.assertTrue(x.getHost() == host)
self.assertTrue(x.getPort() == port)
self.assertTrue(d["asic-id"] == "1")
self.assertTrue(d["method"] == "get-sflow-sampling-status")
params = d["params"]
self.assertTrue("port-list" in params)
self.assertTrue(len(params["port-list"]) == 0)
x.setPortList(["1", "11", "3", "4-10"])
d = x.toDict()
params = d["params"]
self.assertTrue("1" in params["port-list"])
self.assertTrue("11" in params["port-list"])
self.assertTrue("3" in params["port-list"])
self.assertTrue("4-10" in params["port-list"])
self.assertTrue(len(params["port-list"]) == 4)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,29 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
host=10.14.244.128
port=8082
echo "********** get-system-feature **********"
python bv-ctl.py get-system-feature timeout:30 host:$host port:$port
echo "********** get-switch-properties **********"
python bv-ctl.py get-switch-properties timeout:30 host:$host port:$port
python bv-bhdctl.py configure sampling-method:agent sample-count:100 sample-periodicity:45 port-list:1,2,3,4 water-mark:45 timeout:30 host:$host port:$port
python bv-bhdctl.py configure sampling-method:sflow vlan-id:1 dst-ip:10.0.0.4 src-udp-port:4567 dst-udp-port:1234 mirror-port:3 sample-pool-size:100 timeout:30 host:$host port:$port
python bv-bhdctl.py get-detection-enable timeout:30 host:$host port:$port
python bv-bhdctl.py get timeout:30 host:$host port:$port
python bv-bhdctl.py get-sflow-sampling-status port-list:1,2,3,4 timeout:30 host:$host port:$port
python bv-bhdctl.py cancel timeout:30 host:$host port:$port
python bv-bhdctl.py detection-enable enable:true timeout:30 host:$host port:$port

View File

@ -0,0 +1,379 @@
#!/usr/bin/python
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from broadview_lib.config.bhd import *
import sys
import json
class BHDCommand():
def __init__(self):
self._timeout = 30
self.__cmds = {
"detection-enable" : self.handleDetectionEnable,
"configure" : self.handleConfigure,
"cancel" : self.handleCancel,
"get-detection-enable" : self.handleGetDetectionEnable,
"get" : self.handleGet,
"get-sflow-sampling-status" : self.handleGetSFlowSamplingStatus,
"help": self.handleHelp,
}
self.__help = {
"detection-enable" : self.helpDetectionEnable,
"configure" : self.helpConfigure,
"cancel" : self.helpCancel,
"get-detection-enable" : self.helpGetDetectionEnable,
"get" : self.helpGet,
"get-sflow-sampling-status" : self.helpGetSFlowSamplingStatus,
}
def getTimeout(self, args):
timeout = 30
usage = False
for x in args:
if "timeout:" in x:
v = x.split(":")
if len(v) == 2:
timeout = int(v[1])
else:
print "invalid timeout"
usage = True
return usage, timeout
def getASICHostPort(self, args):
usage = False
asic = "1"
port = 8080
host = None
for x in args:
if "asic-id:" in x:
v = x.split(":")
if len(v) == 2:
asic = v[1]
else:
print "invalid asic-id"
usage = True
if "host:" in x:
v = x.split(":")
if len(v) == 2:
host = v[1]
else:
print "invalid host"
usage = True
if "port:" in x:
v = x.split(":")
if len(v) == 2:
port = int(v[1])
else:
print "invalid port"
usage = True
if host == None:
# host is required
print "missing host"
usage = True
return usage, asic, host, port
def usage(self):
print "usage: %s cmd host:ipv4 [timeout:seconds] [port:port] [asic-id:id] [args]" % (sys.argv[0])
print
print "Commands:"
print
for key, val in self.__help.iteritems():
print
val(key)
def handleHelp(self, args):
usage = True
if len(args):
cmd = args[0]
if cmd in self.__help:
self.__help[cmd](cmd)
usage = None
return usage, None
def handleUnimplemented(self, args):
usage = True
ret = None
return usage, ret
def helpUnimplemented(self, name):
print name
print
print "The {} command is currently not supported and may become deprecated".format(name)
def helpDetectionEnable(self, name):
print name, "[args]"
print
print "args:"
print
print " enable:[true|false]"
def handleDetectionEnable(self, args):
usage = False
usage, asic, host, port = self.getASICHostPort(args)
usage, self._timeout = self.getTimeout(args)
if not usage:
x = BlackHoleDetectionEnable(host, port)
x.setASIC(asic)
for arg in args:
if "enable:" in arg:
v = arg.split(":")
if len(v) == 2:
if v[1] == "true":
x.setEnable(True)
elif v[1] == "false":
x.setEnable(False)
else:
print "invalid enable argument"
self.helpDetectionEnable("detection-enable")
else:
print "invalid enable: bad argument count"
status = x.send(timeout=self._timeout)
if status != 200:
print "failure: %d" % (status)
ret = None
return usage, ret
def handleConfigure(self, args):
usage = False
usage, asic, host, port = self.getASICHostPort(args)
if not usage:
x = ConfigurePacketTraceDropReason(host, port)
for arg in args:
if "sampling-method:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setSamplingMethod(v[1])
else:
print "invalid sampling-method: bad argument count"
usage = True
elif "port-list:" in arg:
v = arg.split(":")
if len(v) == 2:
v2 = v[1].split(",")
port_list = []
for y in v2:
port_list.append(x)
x.setPortList(port_list)
else:
print "invalid port-list: bad argument count"
usage = True
elif "water-mark:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setWaterMark(int(v[1]))
else:
print "invalid water-mark: bad argument count"
usage = True
elif "sample-periodicity:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setSamplePeriodicity(int(v[1]))
else:
print "invalid sample-periodicity: bad argument count"
usage = True
elif "sample-count:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setSampleCount(int(v[1]))
else:
print "invalid sample-count: bad argument count"
usage = True
elif "dst-ip:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setDestinationIP(v[1])
else:
print "invalid dst-ip: bad argument count"
usage = True
elif "src-udp-port:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setSourceUDPPort(int(v[1]))
else:
print "invalid src-udp-port: bad argument count"
usage = True
elif "dst-udp-port:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setDestinationUDPPort(int(v[1]))
else:
print "invalid dst-udp-port: bad argument count"
usage = True
elif "mirror-port:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setMirrorPort(int(v[1]))
else:
print "invalid mirror-port: bad argument count"
usage = True
elif "sample-pool-size:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setSamplePoolSize(int(v[1]))
else:
print "invalid sample-pool-size: bad argument count"
usage = True
elif "vlan-id:" in arg:
v = arg.split(":")
if len(v) == 2:
x.setVLANId(int(v[1]))
else:
print "invalid vlan-id: bad argument count"
usage = True
x.setASIC(asic)
status = x.send(self._timeout)
if status != 200:
print "failure: %d" % (status)
ret = None
return usage, ret
def helpConfigure(self, name):
print name, "[args]"
print
print "args:"
print
print " sampling-method:[agent|sflow]"
print " water-mark:integer"
print " port-list:port[,port][,port]...[,port]"
print " sample-periodicity:[integer]"
print " sample-count:n"
print " vlan-id:id"
print " dst-ip:ipv4"
print " src-udp-port:integer"
print " dst-udp-port:integer"
print " mirror-port:integer"
print " sample-pool-size:integer"
def handleCancel(self, args):
usage = False
usage, asic, host, port = self.getASICHostPort(args)
if not usage:
x = CancelPacketTraceProfile(host, port)
x.setASIC(asic)
status = x.send(self._timeout)
if status != 200:
print "failure: %d" % (status)
ret = None
return usage, ret
def helpCancel(self, name):
print name
def handleGetDetectionEnable(self, args):
usage = False
usage, asic, host, port = self.getASICHostPort(args)
if not usage:
x = GetBlackHoleDetectionEnable(host, port)
x.setASIC(asic)
status = x.send(self._timeout)
if status == 200:
ret = json.dumps(x.getJSON())
print ret
else:
print "failure: %d" % (status)
ret = None
return usage, ret
def helpGetDetectionEnable(self, name):
print name
def handleGet(self, args):
usage = False
usage, asic, host, port = self.getASICHostPort(args)
if not usage:
x = GetBlackHole(host, port)
x.setASIC(asic)
status = x.send(self._timeout)
if status == 200:
ret = json.dumps(x.getJSON())
print ret
else:
print "failure: %d" % (status)
ret = None
return usage, ret
def helpGet(self, name):
print name
def handleGetSFlowSamplingStatus(self, args):
usage = False
usage, asic, host, port = self.getASICHostPort(args)
if not usage:
x = GetSFlowSamplingStatus(host, port)
for arg in args:
if "port-list:" in arg:
v = arg.split(":")
if len(v) == 2:
v2 = v[1].split(",")
port_list = []
for y in v2:
port_list.append(x)
x.setPortList(port_list)
else:
print "invalid port-list: bad argument count"
usage = True
x.setASIC(asic)
status = x.send(self._timeout)
if status == 200:
ret = json.dumps(x.getJSON())
print ret
else:
print "failure: %d" % (status)
ret = None
return usage, ret
def helpGetSFlowSamplingStatus(self, name):
print name, "[args]"
print
print "args:"
print
print " port-list:port[,port][,port]...[,port]"
def isCmd(self, cmd):
return cmd in self.__cmds
def handle(self, args):
usage = True
ret = {}
status = False
if len(args):
cmd = args.pop(0)
if self.isCmd(cmd):
usage, ret = self.__cmds[cmd](args)
return usage, ret
def main(argv):
x = BHDCommand()
usage, ret = x.handle(argv)
if usage:
x.usage()
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -0,0 +1,22 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
host=10.14.244.128
port=8082
echo "********** get-system-feature **********"
python bv-ctl.py get-system-feature timeout:30 host:$host port:$port
echo "********** get-switch-properties **********"
python bv-ctl.py get-switch-properties timeout:30 host:$host port:$port

View File

@ -0,0 +1,39 @@
# (C) Copyright Broadcom Corporation 2016
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
host=10.14.244.128
port=8082
echo "********** get-system-feature **********"
python bv-ctl.py get-system-feature timeout:30 host:$host port:$port
echo "********** get-switch-properties **********"
python bv-ctl.py get-switch-properties timeout:30 host:$host port:$port
echo "********** pt cfg-feature **********"
python bv-ptctl.py cfg-feature timeout:30 host:$host port:$port enable
echo "********** pt get-feature **********"
python bv-ptctl.py get-feature timeout:30 host:$host port:$port
echo "********** pt cfg-feature **********"
python bv-ptctl.py cfg-feature timeout:30 host:$host port:$port disable
echo "********** pt get-feature **********"
python bv-ptctl.py get-feature timeout:30 host:$host port:$port
echo "********** pt cancel-profile **********"
python bv-ptctl.py cancel-profile timeout:30 host:$host port:$port
echo "********** pt cancel-lag-resolution **********"
python bv-ptctl.py cancel-lag-resolution timeout:30 host:$host port:$port
echo "********** pt cancel-ecmp-resolution **********"
python bv-ptctl.py cancel-ecmp-resolution timeout:30 host:$host port:$port
echo "********** pt get-profile **********"
python bv-ptctl.py get-profile drop-packet:1 collection-interval:45 timeout:30 host:$host port:$port

View File

@ -16,9 +16,9 @@ host=10.14.244.128
port=8082
echo "********** get-system-feature **********"
python bv-ctl.py get-system-feature timeout:30 host:$host port:$port
python bv-ctl.py get-system-feature timeout:30 host:$host port:$port
echo "********** get-switch-properties **********"
python bv-ctl.py get-switch-properties timeout:30 host:$host port:$port
python bv-ctl.py get-switch-properties timeout:30 host:$host port:$port
echo "********** bst cfg-feature **********"
python bv-bstctl.py cfg-feature timeout:30 host:$host port:$port enable send_async_reports
@ -58,21 +58,3 @@ echo "********** bst cfg-thresholds ingress-port-service-pool **********"
python bv-bstctl.py cfg-thresholds host:$host port:$port ingress-port-service-pool:"4":2:50505
echo "********** bst cfg-thresholds ingress-service-pool **********"
python bv-bstctl.py cfg-thresholds host:$host port:$port ingress-service-pool:2:56783
echo "********** pt cfg-feature **********"
python bv-ptctl.py cfg-feature timeout:30 host:$host port:$port enable
echo "********** pt get-feature **********"
python bv-ptctl.py get-feature timeout:30 host:$host port:$port
echo "********** pt cfg-feature **********"
python bv-ptctl.py cfg-feature timeout:30 host:$host port:$port disable
echo "********** pt get-feature **********"
python bv-ptctl.py get-feature timeout:30 host:$host port:$port
echo "********** pt cancel-profile **********"
python bv-ptctl.py cancel-profile timeout:30 host:$host port:$port
echo "********** pt cancel-lag-resolution **********"
python bv-ptctl.py cancel-lag-resolution timeout:30 host:$host port:$port
echo "********** pt cancel-ecmp-resolution **********"
python bv-ptctl.py cancel-ecmp-resolution timeout:30 host:$host port:$port
echo "********** pt get-profile **********"
python bv-ptctl.py get-profile drop-packet:1 collection-interval:45 timeout:30 host:$host port:$port