Skip to content

Commit

Permalink
added some error handling routines
Browse files Browse the repository at this point in the history
  • Loading branch information
mikenowak committed Mar 26, 2018
1 parent d3e7db9 commit dedbe81
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 27 deletions.
2 changes: 1 addition & 1 deletion adv_agentx.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def SetValue(self, value):
value, ctypes.POINTER(ctypes.c_ubyte)), size)
self.value = value
except Exception as e:
print("Could not find a valid type")
print("ERROR: Unexpected error in SetValue(): %s" % format(e))

# set error
def SetError(self, error):
Expand Down
71 changes: 45 additions & 26 deletions birdagent.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ def __init__(self, cfgfile, birdcli, sscmd):
bgp_defaults = {
'bgpPeerIdentifier': SnmpIpAddress("0.0.0.0"),
'bgpPeerLocalAddr': SnmpIpAddress("0.0.0.0"),
'bgpPeerLocalPort': 0,
'bgpPeerRemotePort': 0,
'bgpPeerHoldTime': 0,
'bgpPeerHoldTimeConfigured': 0,
'bgpPeerKeepAlive': 0,
Expand Down Expand Up @@ -142,17 +144,22 @@ def combinedConfigLines(filename):
yield the whole bird configuration file line by line;
all include-statements are resolved/unrolled
"""
with open(filename, "r") as bird_conf:
for line in bird_conf:
line = line.strip()
match = BirdAgent._re_config_include.search(line)
if not match:
yield line
else:
for subconf in glob.glob(match.group(1)):
yield "# subconf: %s (from %s)" % (subconf, line)
for subline in BirdAgent.combinedConfigLines(subconf):
yield subline
try:
with open(filename, "r") as bird_conf:
for line in bird_conf:
line = line.strip()
match = BirdAgent._re_config_include.search(line)
if not match:
yield line
else:
for subconf in glob.glob(match.group(1)):
yield "# subconf: %s (from %s)" % (subconf, line)
for subline in BirdAgent.combinedConfigLines(subconf):
yield subline
except IOError:
print("ERROR: Unable to open %s" % filename)
except Exception as e:
print("ERROR: Unexpected error in combinedConfigLines(): %s" % format(e))

@staticmethod
def bgpKeys():
Expand Down Expand Up @@ -211,6 +218,7 @@ def getBGPState(self):

if self._re_config_proto_end.search(line):
proto = None

if "timeformat" not in cfg:
print("WARNING: timeformat not configured for this agent's use.")

Expand All @@ -224,6 +232,7 @@ def getBGPState(self):
print(
"ERROR: bird-CLI %s failed: %i" %
(self.birdcli, birdc.returncode))

for line in output.split("\n"):
match = self._re_birdcli_bgp_begin.search(line)
if match:
Expand Down Expand Up @@ -263,32 +272,42 @@ def getBGPState(self):
if self._re_birdcli_bgp_end.search(line):
bgp_proto = None

# use ss to query for tcp:179 connections
# use ss to query for source and destination ports of the bgp protocols
bgp_sessions = {}
ss = subprocess.Popen(self.sscmd, shell=True, stdout=subprocess.PIPE)
for line in ss.communicate()[0].decode('utf-8', 'ignore').split("\n"):
match = self._re_ss.search(line)
if not match:
continue
# key 4-tuples by remote ip: src-addr, src-port, dst-addr, dst-port
bgp_sessions[match.group(3)] = match.groups()
try:
ss = subprocess.Popen(self.sscmd, shell=True,
stdout=subprocess.PIPE)

# now match the tcp:179 4-tuples with bgp-state,
# and enrich state by local+remote ports
for line in ss.communicate()[0].decode('utf-8', 'ignore').split("\n"):
match = self._re_ss.search(line)
if not match:
continue
# key 4-tuples by remote ip: src-addr, src-port, dst-addr, dst-port
bgp_sessions[match.group(3)] = match.groups()
except subprocess.CalledProcessError as e:
print("ERROR: Error executing \"ss\" command: %s" % format(e))

# match the connection 4-tuples with bgp-state
for proto in list(state["bgp-peers"].keys()):
state["bgp-peers"][proto]["bgpPeerLocalPort"] = 0
state["bgp-peers"][proto]["bgpPeerRemotePort"] = 0

# Report on sessions that are have no active connections
if state["bgp-peers"][proto]["bgpPeerRemoteAddr"] not in bgp_sessions:
# print("INFO: proto %s has no bgp session."%proto)
print("INFO: Protocol \"%s\" has no active BGP session." % proto)
continue

# enrich the state by local+remote ports
srcip, srcport, dstip, dstport = bgp_sessions[state["bgp-peers"][
proto]["bgpPeerRemoteAddr"]]

# Check for mismatch between config and ss output
if srcip != state["bgp-peers"][proto]["bgpPeerLocalAddr"] or \
dstip != state["bgp-peers"][proto]["bgpPeerRemoteAddr"]:
print(
"WARNING: proto %s has invalid BGP session (%s / %s)" %
(proto, srcip, dstip))
"WARNING: Protocol \"%s\" has mismatch between the configuration file (local: %s, neighbourd %s) and the active BGP session (local: %s, neighbour: %s)" %
(proto, state["bgp-peers"][proto]["bgpPeerLocalAddr"], state["bgp-peers"][proto]["bgpPeerRemoteAddr"], srcip, dstip))
continue

# populate the ports [TOD/FIXME]
state["bgp-peers"][proto]["bgpPeerLocalPort"] = int(srcport)
state["bgp-peers"][proto]["bgpPeerRemotePort"] = int(dstport)

Expand Down

0 comments on commit dedbe81

Please sign in to comment.