Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
 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)) 
Exemple #6
0
 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)) 
Exemple #7
0
    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)
Exemple #8
0
    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
Exemple #10
0
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)
Exemple #12
0
    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)
Exemple #13
0
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))
Exemple #14
0
    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)
Exemple #15
0
    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
Exemple #16
0
 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
Exemple #17
0
 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.")
Exemple #18
0
 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.")
Exemple #19
0
    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)
Exemple #20
0
    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
Exemple #21
0
    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)
Exemple #22
0
    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
Exemple #23
0
    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)
Exemple #24
0
 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)
Exemple #25
0
    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
Exemple #28
0
    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
Exemple #29
0
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))
Exemple #30
0
    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