def __init__(self, *args, **kwargs): super(Ryu, self).__init__(*args, **kwargs) #--- register for configuration options SciPass_opts = [ cfg.StrOpt('SciPassConfig', default='/etc/SciPass/SciPass.xml', help='where to find the SciPass config file'), cfg.BoolOpt('readState', default=False, help='Read previous state or not') ] self.CONF.register_opts(SciPass_opts, group='SciPass') self.logger.error("Starting SciPass") self.datapaths = {} self.isactive = 1 self.statsInterval = 5 self.balanceInterval = 15 self.bal = None self.stats = {} self.stats_thread = hub.spawn(self._stats_loop) self.balance_thread = hub.spawn(self._balance_loop) self.ports = defaultdict(dict) self.prefix_bytes = defaultdict(lambda: defaultdict(dict)) self.lastStatsTime = {} self.flowmods = {} api = SciPass(logger=self.logger, config=self.CONF.SciPass.SciPassConfig, readState=self.CONF.SciPass.readState) api.registerForwardingStateChangeHandler( self.changeSwitchForwardingState) self.api = api wsgi = kwargs['wsgi'] wsgi.register(SciPassRest, {'api': self.api})
from ryu.lib.packet import lldp, ether_types from ryu.ofproto.ether import ETH_TYPE_LLDP from ryu.ofproto.ether import ETH_TYPE_CFM from ryu.ofproto import nx_match from ryu.ofproto import ofproto_v1_0 from ryu.ofproto import ofproto_v1_2 from ryu.ofproto import ofproto_v1_3 from ryu.ofproto import ofproto_v1_4 LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.register_cli_opts([ cfg.BoolOpt('observe-links', default=False, help='observe link discovery events.'), cfg.BoolOpt('install-lldp-flow', default=True, help='link discovery: explicitly install flow entry ' 'to send lldp packet to controller'), cfg.BoolOpt('explicit-drop', default=True, help='link discovery: explicitly drop lldp packet in') ]) class Port(object): # This is data class passed by EventPortXXX def __init__(self, dpid, ofproto, ofpport): super(Port, self).__init__()
LOG = logging.getLogger('dragon_knight') CONF = cfg.CONF CONF.set_override('observe_links', True) CONF.register_cli_opts([ cfg.ListOpt('app-lists', default=[], help='application module name to run'), cfg.MultiStrOpt('app', positional=True, default=[], help='application module name to run'), cfg.StrOpt('pid-file', default=None, help='pid file name'), cfg.BoolOpt('enable-debugger', default=False, help='don\'t overwrite Python standard threading library' '(use only for debugging)') ]) def main(args=None, prog=None): try: CONF(args=args, prog=prog, project='ryu', version='ryu-manager {}'.format(version), default_config_files=['/usr/local/etc/ryu/ryu.conf']) except cfg.ConfigFilesNotFoundError: CONF(args=args, prog=prog, project='ryu',
class ForwardingModule(app_manager.RyuApp): """ Generic forwarding module. Wont listen to Packet in messages but other modules will trigger when they need forwarding Table 2 -> Used by Forwarding module Table 2 entries: SRC_MAC:DST_MAC:IN_PORT -> OUT_PORT (n vice versa x times) to enable basic forwarding Proto ARP: Controller NO_MATCH: Discard -> TODO: communication error on Controller reboot """ _CONTEXTS = { 'switches': switches.Switches, 'dpset': dpset.DPSet, 'db': DatabaseModule } OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] opts = [ cfg.IntOpt('table', default=2, help='Table to use for forwarding'), cfg.IntOpt('cookie_arp', default=101, help='FLow mod cookie to use for Controller event on arp'), cfg.IntOpt('priority', default=1, help='Priority to use to add the forwarding rules'), cfg.BoolOpt( 'caching', default='true', help='Disables or enables caching of shortest paths and of paths') ] def __init__(self, *args, **kwargs): super(ForwardingModule, self).__init__(*args, **kwargs) CONF.register_opts(self.opts, group='forwarding') self.switches = kwargs['switches'] self.dpset = kwargs['dpset'] self.ofHelper = ofprotoHelper.ofProtoHelperGeneric() self.installed_paths = [] self.shortestPathCache = [] if CONF.forwarding.caching: self.logger.info('Caching enabled') @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): """ Loads ARP action to send arp packets to controller :param ev: :return: """ datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch() actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] self.ofHelper.add_flow(datapath, 0, match, actions, CONF.forwarding.table, CONF.forwarding.cookie_arp) def _add_forwarding_rule(self, datapath, src_ip, dst_ip, out_port): parser = datapath.ofproto_parser match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=src_ip, ipv4_dst=dst_ip) actions = [parser.OFPActionOutput(out_port)] self.ofHelper.add_flow(datapath, CONF.forwarding.priority, match, actions, CONF.forwarding.table) def _apply_forwarding_path(self, path): """ :param path: Path to apply :type path: Path :return: """ if CONF.forwarding.caching: if (path.src_ip, path.dst_ip) not in self.installed_paths: for rule in path.fw: if isinstance(rule['src'], int): self._add_forwarding_rule( self.switches.dps[rule['src']], path.src_ip, path.dst_ip, rule['port']) self.installed_paths.append((path.src_ip, path.dst_ip)) else: for rule in path.fw: if isinstance(rule['src'], int): self._add_forwarding_rule(self.switches.dps[rule['src']], path.src_ip, path.dst_ip, rule['port']) if CONF.forwarding.caching: if (path.dst_ip, path.src_ip) not in self.installed_paths: for rule in path.bw: if isinstance(rule['src'], int): self._add_forwarding_rule( self.switches.dps[rule['src']], path.dst_ip, path.src_ip, rule['port']) self.installed_paths.append((path.dst_ip, path.src_ip)) else: for rule in path.bw: if isinstance(rule['src'], int): self._add_forwarding_rule(self.switches.dps[rule['src']], path.dst_ip, path.src_ip, rule['port']) def _get_topology(self): """ Returns a networkx DiGraph Object :return: """ switches = [dp for dp in self.switches.dps] links = [(link.src.dpid, link.dst.dpid, { 'port': link.src.port_no }) for link in self.switches.links] g = nx.DiGraph() g.add_nodes_from(switches) g.add_edges_from(links) for mac, host in self.switches.hosts.iteritems(): g.add_node(host.ipv4[0]) g.add_edge(host.ipv4[0], host.port.dpid) g.add_edge(host.port.dpid, host.ipv4[0], port=host.port.port_no) return g def _get_shortest_path(self, src_ip, dst_ip): if CONF.forwarding.caching: pathcache = dict(self.shortestPathCache) if src_ip + '_' + dst_ip in pathcache: return pathcache[src_ip + '_' + dst_ip] g = self._get_topology() try: nxPath = nx.shortest_path(g, src_ip, dst_ip) except nx.NodeNotFound: return None path = Path(src_ip, dst_ip) for i in range(0, len(nxPath) - 1): edged = g.get_edge_data(nxPath[i], nxPath[i + 1]) path.fw.append({ 'src': nxPath[i], 'dst': nxPath[i + 1], 'port': edged['port'] if 'port' in edged else '' }) edged = g.get_edge_data(nxPath[i + 1], nxPath[i]) path.bw.append({ 'src': nxPath[i + 1], 'dst': nxPath[i], 'port': edged['port'] if 'port' in edged else '' }) if CONF.forwarding.caching: self.shortestPathCache.append((src_ip + '_' + dst_ip, path)) return path def _get_hop_out_port(self, dst_ip, datapath, path): """ :param dst_ip: :param datapath: :type datapath: Datapath :param path: :type path: Path :return: """ if dst_ip == path.dst_ip: for hop in path.fw: if hop['src'] == datapath.id: for port in self.switches.ports: # type: Port if port.dpid == datapath.id and port.port_no == hop[ 'port']: return port if dst_ip == path.src_ip: for hop in path.bw: if hop['src'] == datapath.id: for port in self.switches.ports: # type: Port if port.dpid == datapath.id and port.port_no == hop[ 'port']: return port return None @set_ev_cls(EventTopologyRequest, None) def getTopology(self, ev): topology = self._get_topology() reply = EventTopologyReply(topology, ev.src) self.reply_to_request(ev, reply) @set_ev_cls(EventShortestPathRequest, None) def requestShortestPath(self, ev): path = self._get_shortest_path(ev.src_ip, ev.dst_ip) if path: self._apply_forwarding_path(path) reply = EventShortestPathReply(path=path, dst=ev.src) else: reply = EventShortestPathReply(path=None, dst=ev.src) self.reply_to_request(ev, reply) @set_ev_cls(EventForwardingPipeline, None) def forwardingRequest(self, ev): """ :param ev: :type ev: EventForwardingPipeline :return: """ datapath = ev.datapath match = ev.match pkt = packet.Packet(ev.data) eth = pkt.get_protocols( ethernet.ethernet)[0] # type: ethernet.ethernet self.logger.debug('EventForwarding requested on ' + str(eth)) if eth.ethertype == ether_types.ETH_TYPE_ARP: # This part is responsible for handling ARP's, # ARP are only received and sent on access port to eliminate forwarding loops arpp = pkt.get_protocols(arp.arp)[0] if arpp.opcode in [arp.ARP_REQUEST, arp.ARP_REPLY]: self.logger.debug('we are looking for %s:%s from %s:%s', arpp.dst_ip, arpp.dst_mac, arpp.src_ip, arpp.src_mac) host = [ x for key, x in self.switches.hosts.iteritems() if x.ipv4[0] == arpp.dst_ip ] if host: host = host[0] self.ofHelper.do_packet_out( ev.data, self.switches.dps[host.port.dpid], host.port) else: nonAccessPorts = [] for link, ts in self.switches.links.iteritems(): nonAccessPorts.extend((link.src, link.dst)) accessPorts = [ port for port, portdata in self.switches.ports.iteritems() if port not in nonAccessPorts ] # Send packet out to all access ports instead of flood to prevent broadcast loops for port in accessPorts: self.ofHelper.do_packet_out( ev.data, self.switches.dps[port.dpid], port) elif eth.ethertype == ether_types.ETH_TYPE_IP: # gets the shortest path between two nodes and installs. ip = pkt.get_protocols(ipv4.ipv4)[0] # type: ipv4.ipv4 self.logger.debug('Eventforwarding on IP packet ' + str(ip)) path = self._get_shortest_path(ip.src, ip.dst) if path: self._apply_forwarding_path(path) if ev.doPktOut: out_port = self._get_hop_out_port(ip.dst, ev.datapath, path) if out_port: self.logger.debug( 'Doing a Packet out on forwarding request') self.ofHelper.do_packet_out(ev.data, ev.datapath, out_port) else: self.logger.error('Failed to retrieve next hop port')
PRIORITY_DEFAULT_ROUTING = 1 PRIORITY_ADDRESSED_DEFAULT_ROUTING = 2 PRIORITY_MAC_LEARNING = 3 PRIORITY_STATIC_ROUTING = 3 PRIORITY_ADDRESSED_STATIC_ROUTING = 4 PRIORITY_IMPLICIT_ROUTING = 5 PRIORITY_L2_SWITCHING = 6 PRIORITY_IP_HANDLING = 7 PRIORITY_PENALTYBOX = 8 PRIORITY_TYPE_ROUTE = 'priority_route' CONF = cfg.CONF plexus_configuration_group = 'plexus' plexus_backdoor_opt = cfg.BoolOpt('backdoor_enable', default = True, help = 'Enable backdoor REPL for inspecting state of python runtime') plexus_backdoor_port_opt = cfg.IntOpt('backdoor_listen_port', default = 3000, help='Port on which the backdoor REPL should listen, on the local interface') CONF.register_opt(plexus_backdoor_opt, group = plexus_configuration_group) CONF.register_opt(plexus_backdoor_port_opt, group = plexus_configuration_group) switchboard_configuration_group = 'switchboard' switchboard_stateurl_opt = cfg.StrOpt('state_url', default = 'https://switchboard.oit.duke.edu/sdn_callback/restore_state', help = 'URL for accessing SwitchBoard knowledge base') switchboard_username_opt = cfg.StrOpt('username', default = 'username', help='Username for accessing SwitchBoard knowledge base') switchboard_password_opt = cfg.StrOpt('password',
from __future__ import print_function from ryu import cfg import inspect import platform import logging import logging.config import logging.handlers import os import sys import ConfigParser CONF = cfg.CONF CONF.register_cli_opts([ cfg.IntOpt('default-log-level', default=None, help='default log level'), cfg.BoolOpt('verbose', default=False, help='show debug output'), cfg.BoolOpt('use-stderr', default=True, help='log to standard error'), cfg.BoolOpt('use-syslog', default=False, help='output to syslog'), cfg.StrOpt('log-dir', default=None, help='log file directory'), cfg.StrOpt('log-file', default=None, help='log file name'), cfg.StrOpt('log-file-mode', default='0644', help='default log file permission'), cfg.StrOpt('log-config-file', default=None, help='Path to a logging config file to use') ]) _EARLY_LOG_HANDLER = None
import ryu.lib.packet.ipv4 import ryu.lib.packet.udp import sys # For getting command line arguments and passing to Ryu import eventlet from eventlet import backdoor # For telnet python access from ryu.ofproto import ofproto_v1_0 # This code is OpenFlow 1.0 specific # Will use this to track the VLAN info associated with each switch SwitchVLAN = namedtuple("SwitchVLAN", ['vid2local', 'port2vid', 'taggedPorts']) if __name__ == "__main__": # Stuff to set additional command line options from ryu import cfg CONF = cfg.CONF CONF.register_cli_opts([ cfg.StrOpt('netfile', default=None, help='network json file'), cfg.BoolOpt('notelnet', default=False, help='Telnet based debugger.') ]) class MultipleSwitchVLANlrn(app_manager.RyuApp): """ Outline of a Ryu application that performs a number of tasks and responds to various events. """ OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] def __init__(self, *args, **kwargs): """ Define member variables here. I do this here so that we can look at them via the telnet python command line. I use the standard Python deque data structure with a finite length so that I only keep the latest few events of a given type. """
import os import collections from docker import client from docker import tls from ryu import cfg docker_opts = [ cfg.BoolOpt('api_insecure', default=False, help='If set, ignore any SSL validation issues'), cfg.StrOpt('ca_file', help='Location of CA certificates file for ' 'securing docker api requests (tlscacert).'), cfg.StrOpt('cert_file', help='Location of TLS certificate file for ' 'securing docker api requests (tlscert).'), cfg.StrOpt('key_file', help='Location of TLS private key file for ' 'securing docker api requests (tlskey).'), ] CONF = cfg.CONF CONF.register_opts(docker_opts, 'docker') DOCKER_PLUGIN = 'daolinet' DEFAULT_TIMEOUT_SECONDS = 120 DEFAULT_DOCKER_API_VERSION = '1.19' class DockerHTTPClient(client.Client):
default=3, help='tester sw receiving port 2 ' '(default: 3)'), cfg.StrOpt('dir', default='ryu/tests/switch/of13', help='test files directory'), cfg.StrOpt('target-version', default='openflow13', help='target sw OFP version [openflow13|openflow14] ' '(default: openflow13)'), cfg.StrOpt('tester-version', default='openflow13', help='tester sw OFP version [openflow13|openflow14] ' '(default: openflow13)') ], group='test-switch') CONF.register_cli_opts( [ # refmon cfg.StrOpt('config', default=None, help='path of config file'), cfg.StrOpt('flowmodlog', default=None, help='path of flowmod log file'), cfg.StrOpt('input', default=None, help='path of input file'), cfg.StrOpt('log', default=None, help='path of log file'), cfg.BoolOpt('always_ready', default=False, help='assume all switches are up and registered with Ryu'), ], group='refmon')
from ryu.topology import switches #"ryu.app.simple_switch_13_rest" #"ryu.app.domain_controller" CONF = cfg.CONF CONF.register_cli_opts([ cfg.ListOpt('app-lists', default=["ryu.app.domain_controller"], help='application module name to run'), cfg.MultiStrOpt('app', positional=True, default=[], help='application module name to run'), cfg.StrOpt('pid-file', default=None, help='pid file name'), cfg.BoolOpt('enable-debugger', default=False, help='don\'t overwrite Python standard threading library' '(use only for debugging)'), cfg.IntOpt("domain_id", default=1, help="id of domain controller"), cfg.StrOpt("domain_wsgi_ip", default="10.108.90.202", help="port no of domain\'s wsgi"), cfg.IntOpt("domain_port", default=8080, help="domain_port of super controller"), cfg.StrOpt("super_wsgi_ip", default="10.108.90.200", help="port no of super\'s wsgi"), cfg.IntOpt("super_wsgi_port", default=8080, help="super_port of super controller"), cfg.BoolOpt('super_exist',
import ShortestPathBridgeNet_NP as spbN_NP from ryu.base import app_manager from ryu.controller import ofp_event from ryu.controller.handler import set_ev_cls from ryu.cmd import manager # For directly starting Ryu import sys # For getting command line arguments and passing to Ryu import eventlet from eventlet import backdoor # For telnet python access from ryu.ofproto import ofproto_v1_0 # This code is OpenFlow 1.0 specific if __name__ == "__main__": # Stuff to set additional command line options from ryu import cfg CONF = cfg.CONF CONF.register_cli_opts([ cfg.StrOpt('netfile', default=None, help='network json file'), cfg.BoolOpt('widest_paths', default=False, help='Use widest path.'), cfg.BoolOpt('notelnet', default=False, help='Telnet based debugger.') ]) class L2DestForwardStatic(app_manager.RyuApp): """ Waits for OpenFlow switches to connect and then fills their forwarding tables based on the network topology json file from the command line. """ OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] def __init__(self, *args, **kwargs): """ Compute the forwarding tables based on the network description file, and whether shortest or widest paths should be used.