SDN流量调度

  • 拓扑:标准的两地三平面网络

  • 流量调度:对指定的数据流(包括上行流量和下行流量)在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    
    
  • 实现过程

  1. 首先选择一个总行,拿到总行的详细信息(要下发的网段)
  2. 选择要切换的线路
  3. 选择添加的分行(分行里会有多个router,每个router也会包含要下发的网段)
  4. 并根据原线路选择上行线路和下行线路,上行线路是ipv4的类型,下行线路是flowspec的类型
  5. 下发策略:
    分行:你到总行网段的下一跳信息和优先级
    总行:你到分行网段的下一跳信息和优先级
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值