def __init__(self, data): self.dps = [] self.links = {} link_re = re.compile('(\S+)\s+(\d+)\s+(\S+)\s+(\d+)') # Read link information lines = data.splitlines() if not len(lines): return dpline = lines[0] for k in dpline.split(): dp = create_datapathid_from_host(create_eaddr(k).hb_long()) self.dps.append(dp) for line in lines[1:]: r = link_re.match(line) if r is not None: dp1 = create_datapathid_from_host(create_eaddr(r.group(1)).hb_long()) port1 = int(r.group(2)) dp2 = create_datapathid_from_host(create_eaddr(r.group(3)).hb_long()) port2 = int(r.group(4)) if dp1 not in self.dps: self.dps.append[dp1] if dp2 not in self.dps: self.dps.append[dp2] if dp1 not in self.links: self.links[dp1] = {} if dp2 not in self.links: self.links[dp2] = {} self.links[dp1][dp2] = (port1, port2) self.links[dp2][dp1] = (port2, port1)
def add_rule(self, dstip, src, dst, comand, srcip=None): "find inport" src = netinet.create_datapathid_from_host(src) dst = netinet.create_datapathid_from_host(dst) in_ports = [] if src.as_host() == 0: ports = self.dp_stats[dst.as_host()]['ports'] for port in ports: if not self.pytop.is_internal(dst, port): in_ports.append(port) else: alinks = self.pytop.get_outlinks(src, dst) for link in alinks: in_ports.append(link.dst) # #test for inport in in_ports: flow = {} flow[core.NW_DST] = dstip flow[core.IN_PORT] = inport if srcip != None: flow[core.NW_SRC] = srcip #If no forward actions are present, the packet is dropped actions = [] self.delete_datapath_flow(dst.as_host(), flow) self.install_datapath_flow(dst.as_host(), flow, 0, FIREWALL_TIMEOUT, actions, None, FIREWALL_PRIORITY, None, None)
def add_rule(self,dstip,src,dst,comand,srcip = None): "find inport" src = netinet.create_datapathid_from_host(src) dst = netinet.create_datapathid_from_host(dst) in_ports = [] if src.as_host() == 0: ports = self.dp_stats[dst.as_host()]['ports'] for port in ports: if not self.pytop.is_internal(dst,port): in_ports.append(port) else: alinks = self.pytop.get_outlinks(src,dst) for link in alinks: in_ports.append(link.dst) # #test for inport in in_ports: flow ={} flow[core.NW_DST] = dstip flow[core.IN_PORT] = inport if srcip != None: flow[core.NW_SRC] = srcip #If no forward actions are present, the packet is dropped actions = [] self.delete_datapath_flow(dst.as_host(),flow) self.install_datapath_flow(dst.as_host(),flow,0,FIREWALL_TIMEOUT,actions,None,FIREWALL_PRIORITY,None,None)
def post_link_event(self, linktuple, action): e = Link_event( create_datapathid_from_host(linktuple[0]), create_datapathid_from_host(linktuple[2]), linktuple[1], linktuple[3], action, ) self.post(e)
def add_link(self, linktuple): self.post_link_event(linktuple, Link_event.ADD) src_dpid = create_datapathid_from_host(linktuple[0]) src_port = linktuple[1] dst_dpid = create_datapathid_from_host(linktuple[2]) dst_port = linktuple[3] self._bindings.add_link(src_dpid,src_port,dst_dpid,dst_port) self._user_event_log.log("discovery",LogLevel.ALERT, "Added network link between {sl} and {dl}", set_src_loc = (src_dpid,src_port), set_dst_loc = (dst_dpid,dst_port))
def add_link(self, linktuple): self.post_link_event(linktuple, Link_event.ADD) src_dpid = create_datapathid_from_host(linktuple[0]) src_port = linktuple[1] dst_dpid = create_datapathid_from_host(linktuple[2]) dst_port = linktuple[3] self._bindings.add_link(src_dpid,src_port,dst_dpid,dst_port) self._user_event_log.log("discovery",LogLevel.ALERT, "Added network link between {sl} and {dl}", set_src_loc = (src_dpid,src_port), set_dst_loc = (dst_dpid,dst_port))
def post_host_event(self, ht, action): if action == 'ADD': #print 'Adding' #------------------------------------------------dp_id--inport--dl_addr-nw_addr-hostname,netid,tim,tim lhe = Lldp_host_event(create_datapathid_from_host(ht[0]), ht[1], ht[2], ht[3], 0, 0 , 0, 0) else: #print 'Deleting' #------------------------------------------------dp_id--inport--dl_addr-nw_addr-hostname,netid,enabled_fields lhe = Lldp_host_event(create_datapathid_from_host(ht[0]), ht[1], ht[2], ht[3], 0, 0 ,0) self.post(lhe)
def post_next_verify(self): change = None while len(self.current_session.changes_to_verify) > 0: curr_change = self.current_session.changes_to_verify.pop(0) if curr_change.status != "FAILED": change = curr_change break if change == None: return if (change.element == "flow"): source_port_info = change.parameters["source"] destination_port_info = change.parameters["destination"] request = { #'out_port': int(destination_port_info["port"]), 'match': { 'in_port': int(source_port_info["port"]), 'dl_vlan': int(source_port_info["vlan_range"]) } } dpid = netinet.create_datapathid_from_host(change.switch) logger.debug("Fetching %d.%d from %d" % (int(source_port_info["port"]), int(source_port_info["vlan_range"]), change.switch)) change.ff = self.ffa.fetch(dpid, request, lambda: self.flow_result_cb(change)) return
def handle_flow_stats_in(self, event): """ Extract 'action' from the matching flow entry in order to see find the next hop """ if c_ntohl(event.xid) == self.pending_query_xid: # See action(s) for this entry if len(event.flows) != 1: log.debug("matched to more than one flow entry! this should not happen") ports = [] for action in event.flows[0]['actions']: if action['type'] == 0: ports.append(action['port']) #elif ADD other action types here dpid = netinet.create_datapathid_from_host(event.datapath_id) next_dpid = self.get_remote_dpid_for_port(dpid, ports[0]) if(next_dpid): log.debug("Got FlowTracer stats reply from %s", dpid ) log.debug("Querying %s", next_dpid) self.pending_query_xid = self.send_flow_stats_request(next_dpid, \ self.match) else: log.debug("TRACE END") # Add last port (to host) self.current_path.append(str(ports[0])) print self.current_path # Send complete path to GUI self.send_to_gui("highlight", self.current_path) # Reset path self.current_path = [] return CONTINUE
def register_location(name, dpid, port, port_name): if isinstance(dpid, basestring): d = __instance__.get_switch(dpid) d.addCallback(register_location2, name, dpid, port, port_name) return d if not isinstance(dpid, netinet.datapathid): dpid = netinet.create_datapathid_from_host(dpid) return __instance__.add_location(LocationInfo(name, dpid, port, port_name))
def delete_links(self, deleteme): for linktuple in deleteme: del self.adjacency_list[linktuple] src_dpid = create_datapathid_from_host(linktuple[0]) src_port = linktuple[1] dst_dpid = create_datapathid_from_host(linktuple[2]) dst_port = linktuple[3] try: self._bindings.remove_link(src_dpid,src_port,dst_dpid,dst_port) self._user_event_log.log("discovery",LogLevel.ALERT, "Removed network link between {sl} and {dl}", set_src_loc = (src_dpid,src_port), set_dst_loc = (dst_dpid,dst_port)) except Exception, e: lg.error('Error removing links from binding storage') self.post_link_event(linktuple, Link_event.REMOVE)
def delete_links(self, deleteme): for linktuple in deleteme: del self.adjacency_list[linktuple] src_dpid = create_datapathid_from_host(linktuple[0]) src_port = linktuple[1] dst_dpid = create_datapathid_from_host(linktuple[2]) dst_port = linktuple[3] try: self._bindings.remove_link(src_dpid,src_port,dst_dpid,dst_port) self._user_event_log.log("discovery",LogLevel.ALERT, "Removed network link between {sl} and {dl}", set_src_loc = (src_dpid,src_port), set_dst_loc = (dst_dpid,dst_port)) except Exception, e: lg.error('Error removing links from binding storage') self.post_link_event(linktuple, Link_event.REMOVE)
def register_host(name, dpid=None, port=None, dladdr=None, is_router=False, is_gateway=False, nwaddr=None): ninfos = [] if dpid != None or port != None: if not isinstance(dpid, netinet.datapathid): dpid = netinet.create_datapathid_from_host(dpid) ninfos.append(NetInfo(dpid, port)) if dladdr != None: if not isinstance(dladdr, netinet.ethernetaddr): dladdr = netinet.create_eaddr(dladdr) ninfos.append(NetInfo(None, None, dladdr, None, is_router, is_gateway)) if nwaddr != None: ninfos.append(NetInfo(None, None, None, nwaddr)) return __instance__.add_host(HostInfo(name, netinfos=ninfos))
def render_GET(self, request): reset = False for a in request.args: if a in self.args: if not reset: self.dpsrc = self.inport = self.dlsrc = self.dldst = self.nwsrc = self.nwdst = '' reset = True setattr(self, a, request.args[a][-1]) mako_args = { 'dpsrc' : self.dpsrc, 'inport' : self.inport, 'dlsrc' : self.dlsrc, 'dldst' : self.dldst, 'nwsrc' : self.nwsrc, 'nwdst' : self.nwdst } retrieve = False for v in mako_args.values(): if v != '': retrieve = True break mako_args['policy'] = self.policy mako_args['names'] = None if not retrieve: return self.render_tmpl(request, "policydebug.mako", args=mako_args) try: if self.dpsrc == '': dpsrc = create_datapathid_from_host(0) else: dpsrc = create_datapathid_from_host(long(self.dpsrc)) if dpsrc == None: mako_args["name_err"] = "Invalid dpsrc." return self.render_tmpl(request, "policydebug.mako", args=mako_args) except ValueError, e: mako_args["name_err"] = "Invalid dpsrc." return self.render_tmpl(request, "policydebug.mako", args=mako_args)
def start(self, dpid_list, dm): self.d = defer.Deferred() if len(dpid_list) == 0: self.d.callback({}) return self.d self.data = {} dpid_list = list(set(dpid_list)) self.p_count = len(dpid_list) self.cb_count = 0 for id in dpid_list: d = dm.search_principals(Directory.SWITCH_PRINCIPAL, {'dpid': create_datapathid_from_host(id)}) d.addCallback(self._search_callback, id) d.addErrback(self._eb) return self.d
def start(self, dpid_list, dm): self.d = defer.Deferred() if len(dpid_list) == 0: self.d.callback({}) return self.d self.data = {} dpid_list = list(set(dpid_list)) self.p_count = len(dpid_list) self.cb_count = 0 for id in dpid_list: d = dm.search_principals(Directory.SWITCH_PRINCIPAL, {'dpid': create_datapathid_from_host(id) }) d.addCallback(self._search_callback, id) d.addErrback(self._eb) return self.d
def get_policy_names(self, request, data): try: content = web_arg_utils.flatten_args(request.args) keys = ['inport', 'dpsrc', 'dlsrc', 'dldst', 'nwsrc', 'nwdst'] for key in keys: if not content.has_key(key): return webservice.badRequest(request, "Must include '%s' argument." % key) try: dp = create_datapathid_from_host(long(content['dpsrc'])) if dp == None: return webservice.badRequest(request, "Invalid datapath ID.") except ValueError, e: return webservice.badRequest(request, "Invalid datapath.") try: port = int(content['inport']) except ValueError, e: return webservice.badRequest(request, "Invalid inport.")
def get_policy_names(self, request, data): try: content = web_arg_utils.flatten_args(request.args) keys = ['inport', 'dpsrc', 'dlsrc', 'dldst', 'nwsrc', 'nwdst'] for key in keys: if not content.has_key(key): return webservice.badRequest( request, "Must include '%s' argument." % key) try: dp = create_datapathid_from_host(long(content['dpsrc'])) if dp == None: return webservice.badRequest(request, "Invalid datapath ID.") except ValueError, e: return webservice.badRequest(request, "Invalid datapath.") try: port = int(content['inport']) except ValueError, e: return webservice.badRequest(request, "Invalid inport.")
def __init__(self, data): self.clients = {} self.servers = {} loc_re = re.compile('(\S+)\s+(\S+)\s+(\d+)') lines = data.splitlines() for line in lines: if line.startswith('#Servers:'): configType = 'Servers' continue elif line.startswith('#Clients:'): configType = 'Clients' continue r = loc_re.match(line) if r is not None: host = create_eaddr(r.group(1)) dpid = create_datapathid_from_host(create_eaddr(r.group(2)).hb_long()) port = int(r.group(3)) if configType == 'Servers': self.servers[host] = (dpid, port) elif configType == 'Clients': self.clients[host] = (dpid, port)
def handle_flow_stats_in(self, event): """ Extract 'action' from the matching flow entry in order to see find the next hop """ if c_ntohl(event.xid) == self.pending_query_xid: # See action(s) for this entry if len(event.flows) != 1: log.debug( "matched to more than one flow entry! this should not happen" ) ports = [] for action in event.flows[0]['actions']: if action['type'] == 0: ports.append(action['port']) #elif ADD other action types here dpid = netinet.create_datapathid_from_host(event.datapath_id) next_dpid = self.get_remote_dpid_for_port(dpid, ports[0]) if (next_dpid): log.debug("Got FlowTracer stats reply from %s", dpid) log.debug("Querying %s", next_dpid) self.pending_query_xid = self.send_flow_stats_request(next_dpid, \ self.match) else: log.debug("TRACE END") # Add last port (to host) self.current_path.append(str(ports[0])) print self.current_path # Send complete path to GUI self.send_to_gui("highlight", self.current_path) # Reset path self.current_path = [] return CONTINUE
def forward_packet(self, dpid, inport, packet, buf, bufid): packet_src = convert_to_eaddr(packet.src) packet_dst = convert_to_eaddr(packet.dst) ip_packet = packet.find('ipv4') udp_packet = packet.find('udp') tcp_packet = packet.find('tcp') #log.info('Forwarding packet') # Process only UDP and TCP packets if udp_packet: packet_srcport = udp_packet.srcport packet_dstport = udp_packet.dstport elif tcp_packet: packet_srcport = tcp_packet.srcport packet_dstport = tcp_packet.dstport else: log.warning('only UDP or TCP packets are allowed.') return # Allow packets coming from reverse direction. # Flip align packet info if it is coming from reverse direction if packet_src in self.sloc.clients.keys(): log.warning('Packet reverse direction. Packet received from client.') return if (packet_src, packet_dst, packet_srcport, packet_dstport) in self.flow_table: dps = self.flow_table[(packet_src, packet_dst, packet_srcport, packet_dstport)] # Copy dps dps = dps[:] elif self.sloc.servers[packet_src][0] == create_datapathid_from_host(dpid): #Find max/min load on the nodes then assign aggregate with the minimum load dps = self.get_path(packet_src, self.aggr_sw[self.next_sw_idx], packet_dst) self.flow_table[(packet_src, packet_dst, packet_srcport, packet_dstport)] = dps self.aggr_sw_counter[self.aggr_sw[self.next_sw_idx]] += 1 sorted_node = sorted(self.aggr_sw_counter.items(), key = itemgetter(1)) min_node = sorted_node[0] self.next_sw_idx = self.aggr_sw.index(min_node[0]) else: print 'Packet can only initiate connection from end-points' return # Skip switches that has the flow installed already for dp in dps[:]: if dp[0] == create_datapathid_from_host(dpid): break else: dps.remove(dp) # Install flow rules for dp in dps: flow = extract_flow(packet) flow[core.NW_TOS] = ip_packet.tos actions = [[openflow.OFPAT_OUTPUT, [0, dp[2]]]] # Install flow rule and forward the packet if dp[0] == create_datapathid_from_host(dpid): flow[core.IN_PORT] = inport self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions, bufid, openflow.OFP_DEFAULT_PRIORITY, inport, buf) # Install rest of flow rules else: flow[core.IN_PORT] = dp[1] self.install_datapath_flow(dp[0].as_host(), flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions, None, openflow.OFP_DEFAULT_PRIORITY, dp[1], None) #Install reverse path rev_flow = self.build_reverse_flow(flow) rev_flow[core.IN_PORT] = dp[2] rev_actions = [[openflow.OFPAT_OUTPUT, [0, dp[1]]]] self.install_datapath_flow(dp[0].as_host(), rev_flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, rev_actions, None, openflow.OFP_DEFAULT_PRIORITY, dp[2], None)
def handle_flow_in(self, event): if not event.active: return CONTINUE indatapath = netinet.create_datapathid_from_host(event.datapath_id) route = pyrouting.Route() sloc = event.route_source if sloc == None: sloc = event.source['location'] route.id.src = netinet.create_datapathid_from_host(sloc & DP_MASK) inport = (sloc >> 48) & PORT_MASK if len(event.route_destinations) > 0: dstlist = event.route_destinations else: dstlist = event.destinations checked = False for dst in dstlist: if isinstance(dst, dict): if not dst['allowed']: continue dloc = dst['connector']['location'] else: dloc = dst if dloc == 0: continue route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) if self.routing.get_route(route): checked = True outport = (dloc >> 48) & PORT_MASK if self.routing.check_route(route, inport, outport): log.msg('Found route %s.' % hex(route.id.src.as_host())+':'+str(inport)+' to '+hex(route.id.dst.as_host())+':'+str(outport)) actions = [self.make_action_array([[openflow.OFPAT_SET_DL_SRC, event.flow.dl_src]])] for i in xrange(route.path.size()): actions.append("") self.routing.setup_route(event.flow, route, inport, outport, FLOW_TIMEOUT, actions, True) if indatapath == route.id.src or pyrouting.dp_on_route(indatapath, route): self.routing.send_packet(indatapath, inport, openflow.OFPP_TABLE, event.buffer_id, event.buf, "", False, event.flow) else: log.err("Packet not on route - dropping.") return CONTINUE else: log.msg("Invalid route between %s." % hex(route.id.src.as_host())+':'+str(inport)+' to '+hex(route.id.dst.as_host())+':'+str(outport)) else: log.msg("No route between %s and %s." % (hex(route.id.src.as_host()), hex(route.id.dst.as_host()))) if not checked: log.msg('Broadcasting packet') if event.flow.dl_dst.is_broadcast(): self.routing.setup_flow(event.flow, indatapath, openflow.OFPP_FLOOD, event.buffer_id, event.buf, BROADCAST_TIMEOUT, "", event.flow.dl_type == htons(ethernet.IP_TYPE)) else: inport = ntohs(event.flow.in_port) self.routing.send_packet(indatapath, inport, openflow.OFPP_FLOOD, event.buffer_id, event.buf, "", event.flow.dl_type == htons(ethernet.IP_TYPE), event.flow) else: log.msg("Dropping packet") return CONTINUE
def forward_packet(self, dpid, inport, packet, buf, bufid): packet_src = convert_to_eaddr(packet.src) packet_dst = convert_to_eaddr(packet.dst) ip_packet = packet.find('ipv4') udp_packet = packet.find('udp') tcp_packet = packet.find('tcp') #log.info('Forwarding packet') # Process only UDP and TCP packets if udp_packet: packet_srcport = udp_packet.srcport packet_dstport = udp_packet.dstport elif tcp_packet: packet_srcport = tcp_packet.srcport packet_dstport = tcp_packet.dstport else: log.warning('only UDP or TCP packets are allowed.') return if packet_src in self.sloc.clients.keys(): #print 'Return path packet' return if (packet_src, packet_dst, packet_srcport, packet_dstport) in self.flow_table: dps = self.flow_table[(packet_src, packet_dst, packet_srcport, packet_dstport)] dps = dps[:] else: #print packet.src, packet_srcport, packet.dst, packet_dstport, self.next_sw_idx dps = self.get_path(packet_src, self.aggr_sw[self.next_sw_idx], packet_dst) self.flow_table[(packet_src, packet_dst, packet_srcport, packet_dstport)] = dps self.next_sw_idx = (self.next_sw_idx+1)%len(self.aggr_sw) #print 'Installing new path' # Skip switches that has the flow installed already for dp in dps[:]: if dp[0] == create_datapathid_from_host(dpid): break else: dps.remove(dp) # Install flow rules for dp in dps: flow = extract_flow(packet) #del flow[core.DL_TYPE] #del flow[NW_PROTO] actions = [[openflow.OFPAT_OUTPUT, [0, dp[2]]]] # Install flow rule and forward the packet if dp[0] == create_datapathid_from_host(dpid): flow[core.IN_PORT] = inport self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions, bufid, openflow.OFP_DEFAULT_PRIORITY, inport, buf) # Install rest of flow rules else: flow[core.IN_PORT] = dp[1] self.install_datapath_flow(dp[0].as_host(), flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions, None, openflow.OFP_DEFAULT_PRIORITY, dp[1], None) #Install reverse path rev_flow = self.build_reverse_flow(flow) rev_flow[core.IN_PORT] = dp[2] rev_actions = [[openflow.OFPAT_OUTPUT, [0, dp[1]]]] self.install_datapath_flow(dp[0].as_host(), rev_flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, rev_actions, None, openflow.OFP_DEFAULT_PRIORITY, dp[2], None)
def post_link_event(self, linktuple, action): e = Link_event(create_datapathid_from_host(linktuple[0]), create_datapathid_from_host(linktuple[2]), linktuple[1], linktuple[3], action) self.post(e)
def forward_packet(self, dpid, inport, packet, buf, bufid): packet_src = convert_to_eaddr(packet.src) packet_dst = convert_to_eaddr(packet.dst) ip_packet = packet.find('ipv4') udp_packet = packet.find('udp') tcp_packet = packet.find('tcp') #log.info('Forwarding packet') # Process only UDP and TCP packets if udp_packet: packet_srcport = udp_packet.srcport packet_dstport = udp_packet.dstport elif tcp_packet: packet_srcport = tcp_packet.srcport packet_dstport = tcp_packet.dstport else: log.warning('only UDP or TCP packets are allowed.') return if packet_src in self.sloc.clients.keys(): #print 'Return path packet' return if (packet_src, packet_dst, packet_srcport, packet_dstport) in self.flow_table: dps = self.flow_table[(packet_src, packet_dst, packet_srcport, packet_dstport)] dps = dps[:] else: #print packet.src, packet_srcport, packet.dst, packet_dstport, self.next_sw_idx dps = self.get_path(packet_src, self.aggr_sw[self.next_sw_idx], packet_dst) self.flow_table[(packet_src, packet_dst, packet_srcport, packet_dstport)] = dps self.next_sw_idx = (self.next_sw_idx + 1) % len(self.aggr_sw) #print 'Installing new path' # Skip switches that has the flow installed already for dp in dps[:]: if dp[0] == create_datapathid_from_host(dpid): break else: dps.remove(dp) # Install flow rules for dp in dps: flow = extract_flow(packet) #del flow[core.DL_TYPE] #del flow[NW_PROTO] actions = [[openflow.OFPAT_OUTPUT, [0, dp[2]]]] # Install flow rule and forward the packet if dp[0] == create_datapathid_from_host(dpid): flow[core.IN_PORT] = inport self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions, bufid, openflow.OFP_DEFAULT_PRIORITY, inport, buf) # Install rest of flow rules else: flow[core.IN_PORT] = dp[1] self.install_datapath_flow(dp[0].as_host(), flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions, None, openflow.OFP_DEFAULT_PRIORITY, dp[1], None) #Install reverse path rev_flow = self.build_reverse_flow(flow) rev_flow[core.IN_PORT] = dp[2] rev_actions = [[openflow.OFPAT_OUTPUT, [0, dp[1]]]] self.install_datapath_flow(dp[0].as_host(), rev_flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, rev_actions, None, openflow.OFP_DEFAULT_PRIORITY, dp[2], None)
def handle_flow_in(self, event): if not event.active: return CONTINUE indatapath = netinet.create_datapathid_from_host(event.datapath_id) route = pyrouting.Route() sloc = event.route_source if sloc == None: sloc = event.src_location['sw']['dp'] route.id.src = netinet.create_datapathid_from_host(sloc) inport = event.src_location['port'] sloc = sloc | (inport << 48) else: route.id.src = netinet.create_datapathid_from_host(sloc & DP_MASK) inport = (sloc >> 48) & PORT_MASK if len(event.route_destinations) > 0: dstlist = event.route_destinations else: dstlist = event.dst_locations checked = False for dst in dstlist: if isinstance(dst, dict): if not dst['allowed']: continue dloc = dst['authed_location']['sw']['dp'] route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = dst['authed_location']['port'] dloc = dloc | (outport << 48) else: dloc = dst route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = (dloc >> 48) & PORT_MASK if dloc == 0: continue if self.routing.get_route(route): checked = True if self.routing.check_route(route, inport, outport): log.debug('Found route %s.' % hex(route.id.src.as_host())+\ ':'+str(inport)+' to '+hex(route.id.dst.as_host())+\ ':'+str(outport)) if route.id.src == route.id.dst: firstoutport = outport else: firstoutport = route.path[0].outport p = [] if route.id.src == route.id.dst: p.append(str(inport)) p.append(str(indatapath)) p.append(str(firstoutport)) else: s2s_links = len(route.path) p.append(str(inport)) p.append(str(indatapath)) for i in range(0,s2s_links): p.append(str(route.path[i].dst)) p.append(str(outport)) self.routing.setup_route(event.flow, route, inport, \ outport, FLOW_TIMEOUT, [], True) # Send Barriers pending_route = [] #log.debug("Sending BARRIER to switches:") # Add barrier xids for dpid in p[1:len(p)-1]: log.debug("Sending barrier to %s", dpid) pending_route.append(self.send_barrier(int(dpid,16))) # Add packetout info pending_route.append([indatapath, inport, event]) # Store new pending_route (waiting for barrier replies) self.pending_routes.append(pending_route) # send path to be highlighted to GUI self.send_to_gui("highlight",p) # Send packet out (do it after receiving barrier(s)) if indatapath == route.id.src or \ pyrouting.dp_on_route(indatapath, route): pass #self.routing.send_packet(indatapath, inport, \ # openflow.OFPP_TABLE,event.buffer_id,event.buf,"", \ # False, event.flow) else: log.debug("Packet not on route - dropping.") return CONTINUE else: log.debug("Invalid route between %s." \ % hex(route.id.src.as_host())+':'+str(inport)+' to '+\ hex(route.id.dst.as_host())+':'+str(outport)) else: log.debug("No route between %s and %s." % \ (hex(route.id.src.as_host()), hex(route.id.dst.as_host()))) if not checked: if event.flow.dl_dst.is_broadcast(): log.debug("Setting up FLOOD flow on %s", str(indatapath)) self.routing.setup_flow(event.flow, indatapath, \ openflow.OFPP_FLOOD, event.buffer_id, event.buf, \ BROADCAST_TIMEOUT, "", \ event.flow.dl_type == htons(ethernet.IP_TYPE)) else: inport = ntohs(event.flow.in_port) log.debug("Flooding") self.routing.send_packet(indatapath, inport, \ openflow.OFPP_FLOOD, \ event.buffer_id, event.buf, "", \ event.flow.dl_type == htons(ethernet.IP_TYPE),\ event.flow) else: log.debug("Dropping packet") return CONTINUE
def handle_flow_in(self, event): if not event.active: return CONTINUE indatapath = netinet.create_datapathid_from_host(event.datapath_id) route = pyrouting.Route() sloc = event.route_source if sloc == None: sloc = event.src_location['sw']['dp'] route.id.src = netinet.create_datapathid_from_host(sloc) inport = event.src_location['port'] sloc = sloc | (inport << 48) else: route.id.src = netinet.create_datapathid_from_host(sloc & DP_MASK) inport = (sloc >> 48) & PORT_MASK if len(event.route_destinations) > 0: dstlist = event.route_destinations else: dstlist = event.dst_locations checked = False for dst in dstlist: if isinstance(dst, dict): if not dst['allowed']: continue dloc = dst['authed_location']['sw']['dp'] route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = dst['authed_location']['port'] dloc = dloc | (outport << 48) else: dloc = dst route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = (dloc >> 48) & PORT_MASK if dloc == 0: continue if self.routing.get_route(route): checked = True if self.routing.check_route(route, inport, outport): log.err('Found route %s.' % hex(route.id.src.as_host())+':'+str(inport)+' to '+hex(route.id.dst.as_host())+':'+str(outport)) self.routing.setup_route(event.flow, route, inport, outport, FLOW_TIMEOUT, [], True) if indatapath == route.id.src or pyrouting.dp_on_route(indatapath, route): self.routing.send_packet(indatapath, inport, openflow.OFPP_TABLE, event.buffer_id, event.buf, "", False, event.flow) else: log.err("Packet not on route - dropping.") return CONTINUE else: log.err("Invalid route between %s." % hex(route.id.src.as_host())+':'+str(inport)+' to '+hex(route.id.dst.as_host())+':'+str(outport)) else: log.err("No route between %s and %s." % (hex(route.id.src.as_host()), hex(route.id.dst.as_host()))) if not checked: log.err('Broadcasting packet') if event.flow.dl_dst.is_broadcast(): self.routing.setup_flow(event.flow, indatapath, openflow.OFPP_FLOOD, event.buffer_id, event.buf, BROADCAST_TIMEOUT, "", event.flow.dl_type == htons(ethernet.IP_TYPE)) else: inport = ntohs(event.flow.in_port) self.routing.send_packet(indatapath, inport, openflow.OFPP_FLOOD, event.buffer_id, event.buf, "", event.flow.dl_type == htons(ethernet.IP_TYPE), event.flow) else: log.err("Dropping packet") return CONTINUE
def handle_flow_in(self, event): if not event.active: return CONTINUE indatapath = netinet.create_datapathid_from_host(event.datapath_id) route = pyrouting.Route() sloc = event.route_source if sloc == None: sloc = event.src_location['sw']['dp'] route.id.src = netinet.create_datapathid_from_host(sloc) inport = event.src_location['port'] sloc = sloc | (inport << 48) else: route.id.src = netinet.create_datapathid_from_host(sloc & DP_MASK) inport = (sloc >> 48) & PORT_MASK if len(event.route_destinations) > 0: dstlist = event.route_destinations else: dstlist = event.dst_locations checked = False for dst in dstlist: if isinstance(dst, dict): if not dst['allowed']: continue dloc = dst['authed_location']['sw']['dp'] route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = dst['authed_location']['port'] dloc = dloc | (outport << 48) else: dloc = dst route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = (dloc >> 48) & PORT_MASK if dloc == 0: continue if self.routing.get_route(route): checked = True if self.routing.check_route(route, inport, outport): log.debug('Found route %s.' % hex(route.id.src.as_host())+\ ':'+str(inport)+' to '+hex(route.id.dst.as_host())+\ ':'+str(outport)) if route.id.src == route.id.dst: firstoutport = outport else: firstoutport = route.path[0].outport p = [] if route.id.src == route.id.dst: p.append(str(inport)) p.append(str(indatapath)) p.append(str(firstoutport)) else: s2s_links = len(route.path) p.append(str(inport)) p.append(str(indatapath)) for i in range(0, s2s_links): p.append(str(route.path[i].dst)) p.append(str(outport)) #print 'unicast' #print type(event.flow) #print dir(event.flow) #print str(event.flow)#.to_string() self.routing.setup_route(event.flow, route, inport, \ outport, FLOW_TIMEOUT, [], True) # Send Barriers pending_route = [] #log.debug("Sending BARRIER to switches:") # Add barrier xids for dpid in p[1:len(p) - 1]: log.debug("Sending barrier to %s", dpid) pending_route.append(self.send_barrier(int(dpid, 16))) # Add packetout info pending_route.append([indatapath, inport, event]) # Store new pending_route (waiting for barrier replies) self.pending_routes.append(pending_route) # send path to be highlighted to GUI #self.send_to_gui("highlight",p) # Send packet out (do it after receiving barrier(s)) if indatapath == route.id.src or \ pyrouting.dp_on_route(indatapath, route): #pass self.routing.send_packet(indatapath, inport, \ openflow.OFPP_TABLE,event.buffer_id,event.buf,"", \ False, event.flow) else: log.debug("Packet not on route - dropping.") return CONTINUE else: log.debug("Invalid route between %s." \ % hex(route.id.src.as_host())+':'+str(inport)+' to '+\ hex(route.id.dst.as_host())+':'+str(outport)) else: log.debug("No route between %s and %s." % \ (hex(route.id.src.as_host()), hex(route.id.dst.as_host()))) if not checked: #just broadcast to external port #black food eth = ethernet(event.buf) if eth.type != ethernet.IP_TYPE and\ eth.type != ethernet.ARP_TYPE and\ eth.type != ethernet.PAE_TYPE and\ eth.type != ethernet.VLAN_TYPE: return CONTINUE for d in self.dp_stats: for port in self.dp_stats[d]['ports']: if not self.pytop.is_internal(\ netinet.create_datapathid_from_host(d),port): self.send_openflow_packet(d, event.buf, port) return STOP if event.flow.dl_dst.is_broadcast(): log.debug("Setting up FLOOD flow on %s", str(indatapath)) self.routing.setup_flow(event.flow, indatapath, \ openflow.OFPP_FLOOD, event.buffer_id, event.buf, \ BROADCAST_TIMEOUT, "", \ event.flow.dl_type == htons(ethernet.IP_TYPE)) else: inport = ntohs(event.flow.in_port) log.debug("Flooding") #print 'flooding ' self.routing.send_packet(indatapath, inport, \ openflow.OFPP_FLOOD, \ event.buffer_id, event.buf, "", \ event.flow.dl_type == htons(ethernet.IP_TYPE),\ event.flow) else: log.debug("Dropping packet") return STOP
def register_switch(name, dpid): if not isinstance(dpid, netinet.datapathid): dpid = netinet.create_datapathid_from_host(dpid) return __instance__.add_switch(SwitchInfo(name, dpid))
def handle_flow_in(self, event): if not event.active: return CONTINUE indatapath = netinet.create_datapathid_from_host(event.datapath_id) route = pyrouting.Route() sloc = event.route_source if sloc == None: sloc = event.src_location['sw']['dp'] route.id.src = netinet.create_datapathid_from_host(sloc) inport = event.src_location['port'] sloc = sloc | (inport << 48) else: route.id.src = netinet.create_datapathid_from_host(sloc & DP_MASK) inport = (sloc >> 48) & PORT_MASK if len(event.route_destinations) > 0: dstlist = event.route_destinations else: dstlist = event.dst_locations checked = False for dst in dstlist: if isinstance(dst, dict): if not dst['allowed']: continue dloc = dst['authed_location']['sw']['dp'] route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = dst['authed_location']['port'] dloc = dloc | (outport << 48) else: dloc = dst route.id.dst = netinet.create_datapathid_from_host(dloc & DP_MASK) outport = (dloc >> 48) & PORT_MASK if dloc == 0: continue if self.routing.get_route(route): checked = True if self.routing.check_route(route, inport, outport): log.err('Found route %s.' % hex(route.id.src.as_host()) + ':' + str(inport) + ' to ' + hex(route.id.dst.as_host()) + ':' + str(outport)) self.routing.setup_route(event.flow, route, inport, outport, FLOW_TIMEOUT, [], True) if indatapath == route.id.src or pyrouting.dp_on_route( indatapath, route): self.routing.send_packet(indatapath, inport, openflow.OFPP_TABLE, event.buffer_id, event.buf, "", False, event.flow) else: log.err("Packet not on route - dropping.") return CONTINUE else: log.err("Invalid route between %s." % hex(route.id.src.as_host()) + ':' + str(inport) + ' to ' + hex(route.id.dst.as_host()) + ':' + str(outport)) else: log.err( "No route between %s and %s." % (hex(route.id.src.as_host()), hex(route.id.dst.as_host()))) if not checked: log.err('Broadcasting packet') if event.flow.dl_dst.is_broadcast(): self.routing.setup_flow( event.flow, indatapath, openflow.OFPP_FLOOD, event.buffer_id, event.buf, BROADCAST_TIMEOUT, "", event.flow.dl_type == htons(ethernet.IP_TYPE)) else: inport = ntohs(event.flow.in_port) self.routing.send_packet( indatapath, inport, openflow.OFPP_FLOOD, event.buffer_id, event.buf, "", event.flow.dl_type == htons(ethernet.IP_TYPE), event.flow) else: log.err("Dropping packet") return CONTINUE