-
拓扑:标准的两地三平面网络
-
流量调度:对指定的数据流(包括上行流量和下行流量)在OA平面与TRS平面之间进行调度
上行流量为客户端到服务器端的流量、下行流量为服务器端到客户端的流量
-
下一跳信息
根据SNMP的mib=1, 3, 6, 1, 4, 1, 9, 9, 187, 1, 2, 5, 1, 11, 1, 4拿到邻居的AS和IP,并用IP作为下一跳,来验证下一跳是否可达from multiprocessing.pool import ThreadPool class Pool(): def __init__(self): self._process_count = 10 #指定处理的进程数 self._pool = ThreadPool(processes=self._process_count) def task(self, funcs=None): funcs(self._pool) self._pool.close() # 关闭pool self._pool.join() # 主进程阻塞,等待子进程退出 class Snmp(): def __init__(self): pool = Pool() def set_ip_comm(self, ip_comm): self.ip_comm = ip_comm def nexthop(self, pool): for ip in self.ip_comm: pool.apply_async(snmp_query, args=(ip, ), callback=self._callback(ip)) # apply_async这个方法是非阻塞的执行,apply是阻塞方式 # 第一个参数:要执行的方法 # 第二个参数:方法的参数,注意是元组,末尾要加, # 第三个参数:返回值 def snmp_query(self, ip): pass # 这里面根据mib采回对应信息 def get_nexthops(self): return self._pool.task(self.nexthop) # 这里比较乱,是pool去执行nexthop这个方法,执行完毕后关闭pool if __name__ == '__main__': snmp = Snmp() snmp.set_ip_comm([{"ip": "1.1.1.1", "community": "cisco"}, {"ip": "2.2.2.2", "community": "cisco"}]) snmp.get_nexthops()
-
此处介绍2种采集方法
1.通过pysnmp引入cmdgen重写GetRequest等方法
from pysnmp.entity.rfc3413.oneliner import cmdgen class Walk(self, ip,community): def __init__(self,community,ip,port=161,timeout=1,retries=3): self.cmd = cmdgen.CommunityData('my-agent',community,1) self.target = cmdgen.UdpTransportTarget((ip,161),timeout,retries) self.ip def GetRequest(self,*oid): try: result= {'errorIndication':None,'errorStatus':None,'value':None, 'ip': self.ip} errorIndication, errorStatus, errorIndex, varBindTable = cmdgen.CommandGenerator().getCmd(self.cmd,self.target,*oid) if errorIndication: result['errorIndication'] = errorIndication return result else: if errorStatus: result['errorStatus'] = '%s at %s\n' % (errorStatus.prettyPrint(),varBindTable[-1][int(errorIndex)-1]) return result else: Tables = [] # GetRequest只获取一个 for oid,val in varBindTable: oid = list(oid) Tables .append([oid,str(val)]) # GetBulkRequest获取多个,所以有2层for循环 for varBindTableRow in varBindTable: for oid, val in varBindTableRow: oid = list(oid) Tables .append([oid,str(val)]) result['TableItems'] = Tables except Exception, e: print e return result Tables = [[[1, 3, 6, 1, 2, 1, 1, 1, 0], 'Cisco IOS Software, CSR1000V Software (X86_64_LINUX_IOSD-UNIVERSALK9-M)']], 'errorStatus': None, 'value': None, 'errorIndication': None} 看到errorStatus和errorIndication证明数据正常采回,没有发现问题
2.根据hlapi 包采集
from pysnmp.hlapi import bulkCmd, getCmd, SnmpEngine, CommunityData, UdpTransportTarget, ContextData, ObjectType, ObjectIdentity, UsmUserData def next_cmd(self, oid, lexicographicMode=False, max_calls=0): # 参数说明:lexicographicMode默认为TRUE,会取回oid后的所有oid信息,手动将lexicographicMode改成False就只针对传递的oid采集,max_calls代表对采集信息的数量限制,默认不限制 self.snmp_ret = nextCmd(SnmpEngine(), CommunityData(self.community), UdpTransportTarget( (self.ip, self.port)), ContextData(), ObjectType(ObjectIdentity(oid)), maxCalls=max_calls, lexicographicMode=lexicographicMode) return self._to_result(oid) def _to_result(self, oid): result= {'errorIndication':None,'errorStatus':None,'value':None, 'ip': self.ip} errorIndication, errorStatus, errorIndex, varBindTable = cmdgen.CommandGenerator().getCmd(self.cmd,self.target,*oid) if errorIndication: result['errorIndication'] = errorIndication return result else: if errorStatus: result['errorStatus'] = '%s at %s\n' % (errorStatus.prettyPrint(),varBindTable[-1][int(errorIndex)-1]) return result else: Tables = [] # GetRequest只获取一个 for oid,val in varBindTable: oid = list(oid) Tables .append([oid,str(val)]) result['TableItems'] = Tables except Exception, e: print e return result
-
实现过程
- 首先选择一个总行,拿到总行的详细信息(要下发的网段)
- 选择要切换的线路
- 选择添加的分行(分行里会有多个router,每个router也会包含要下发的网段)
- 并根据原线路选择上行线路和下行线路,上行线路是ipv4的类型,下行线路是flowspec的类型
- 下发策略:
分行:你到总行网段的下一跳信息和优先级
总行:你到分行网段的下一跳信息和优先级