Ejemplo n.º 1
0
    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()
        self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml')
        self.table = FakeOFTable(self.NUM_TABLES)
        dp = self.update_config(self.CONFIG)
        self.valve = valve_factory(dp)(dp, 'test_valve')

        # establish connection to datapath
        ofmsgs = self.valve.datapath_connect(self.DP_ID,
                                             range(1, self.NUM_PORTS + 1))
        self.table.apply_ofmsgs(ofmsgs)

        # learn some mac addresses
        self.rcv_packet(1, 0x100, {
            'eth_src': self.P1_V100_MAC,
            'eth_dst': self.UNKNOWN_MAC
        })
        self.rcv_packet(2, 0x200, {
            'eth_src': self.P2_V200_MAC,
            'eth_dst': self.P3_V200_MAC,
            'vid': 0x200
        })
        self.rcv_packet(3, 0x200, {
            'eth_src': self.P3_V200_MAC,
            'eth_dst': self.P2_V200_MAC,
            'vid': 0x200
        })
Ejemplo n.º 2
0
    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()
        self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml')
        self.table = FakeOFTable(self.NUM_TABLES)
        dp = self.update_config(self.CONFIG)
        self.valve = valve_factory(dp)(dp, 'test_valve')

        # establish connection to datapath
        ofmsgs = self.valve.datapath_connect(
            self.DP_ID,
            range(1, self.NUM_PORTS + 1)
            )
        self.table.apply_ofmsgs(ofmsgs)

        # learn some mac addresses
        self.rcv_packet(1, 0x100, {
            'eth_src': self.P1_V100_MAC,
            'eth_dst': self.UNKNOWN_MAC
            })
        self.rcv_packet(2, 0x200, {
            'eth_src': self.P2_V200_MAC,
            'eth_dst': self.P3_V200_MAC,
            'vid': 0x200
            })
        self.rcv_packet(3, 0x200, {
            'eth_src': self.P3_V200_MAC,
            'eth_dst': self.P2_V200_MAC,
            'vid': 0x200
            })
Ejemplo n.º 3
0
def check_config(conf_files, debug_level, check_output_file):
    """Return True and successful config dict, if all config can be parsed."""
    logname = os.devnull
    logger = logging.getLogger('%s.config' % logname)
    logger_handler = logging.StreamHandler(stream=sys.stderr)
    logger.addHandler(logger_handler)
    logger.propagate = 0
    logger.setLevel(debug_level)
    check_output = []

    for conf_file in conf_files:
        check_result = False

        try:
            _, dps = dp_parser(conf_file, logname)
            if dps is not None:
                dps_conf = [(valve.valve_factory(dp), dp.to_conf())
                            for dp in dps]
                check_output.extend([conf for _, conf in dps_conf])
                check_result = True
                continue
        except InvalidConfigError as config_err:
            check_output = [config_err]
        break

    pprint.pprint(check_output, stream=check_output_file)
    return check_result
Ejemplo n.º 4
0
def check_config(conf_files, debug_level, check_output_file):
    """Return True and successful config dict, if all config can be parsed."""
    logname = os.devnull
    logger = logging.getLogger('%s.config' % logname)
    logger_handler = logging.StreamHandler(stream=sys.stderr)
    logger.addHandler(logger_handler)
    logger.propagate = 0
    logger.setLevel(debug_level)
    check_output = ''
    check_result = False

    for conf_file in conf_files:
        try:
            _, dps = dp_parser(conf_file, logname)
            for dp in dps:
                valve_dp = valve.valve_factory(dp)
                if valve_dp is None:
                    check_result = False
                    break
                check_output = dp.to_conf()
                check_result = True
        except InvalidConfigError as config_err:
            check_output = config_err
    check_output_file.write(str(check_output))
    return check_result
Ejemplo n.º 5
0
def check_config(conf_files, debug_level, check_output_file):
    """Return True and successful config dict, if all config can be parsed."""
    logname = os.devnull
    logger = logging.getLogger('%s.config' % logname)
    logger_handler = logging.StreamHandler(stream=sys.stderr)
    logger.addHandler(logger_handler)
    logger.propagate = 0
    logger.setLevel(debug_level)
    check_output = []

    if conf_files:
        for conf_file in conf_files:
            check_result = False

            try:
                _, dps = dp_parser(conf_file, logname)
                if dps is not None:
                    dps_conf = [(valve.valve_factory(dp), dp.to_conf()) for dp in dps]
                    check_output.extend([conf for _, conf in dps_conf])
                    check_result = True
                    continue
            except InvalidConfigError as config_err:
                check_output = [config_err]
            break
    else:
        check_result = False
        check_output = ['no files specified']

    pprint.pprint(check_output, stream=check_output_file)
    return check_result
Ejemplo n.º 6
0
    def __init__(self, *args, **kwargs):
        super(Faucet, self).__init__(*args, **kwargs)

        # There doesnt seem to be a sensible method of getting command line
        # options into ryu apps. Instead I am using the environment variable
        # FAUCET_CONFIG to allow this to be set, if it is not set it will
        # default to valve.yaml
        sysprefix = get_sys_prefix()
        self.config_file = os.getenv('FAUCET_CONFIG',
                                     sysprefix + '/etc/ryu/faucet/faucet.yaml')
        self.logfile = os.getenv('FAUCET_LOG',
                                 sysprefix + '/var/log/ryu/faucet/faucet.log')
        self.exc_logfile = os.getenv(
            'FAUCET_EXCEPTION_LOG',
            sysprefix + '/var/log/ryu/faucet/faucet_exception.log')

        # Set the signal handler for reloading config file
        signal.signal(signal.SIGHUP, self.signal_handler)

        # Create dpset object for querying Ryu's DPSet application
        self.dpset = kwargs['dpset']

        # Setup logging
        self.logger = get_logger(self.logname, self.logfile, logging.DEBUG, 0)
        # Set up separate logging for exceptions
        self.exc_logger = get_logger(self.exc_logname, self.exc_logfile,
                                     logging.DEBUG, 1)

        # TODO: metrics instance can be passed to Valves also,
        # for DP specific instrumentation.
        self.metrics = FaucetMetrics()
        prom_port = int(os.getenv('FAUCET_PROMETHEUS_PORT', '9244'))
        start_http_server(prom_port)

        # Set up a valve object for each datapath
        self.valves = {}
        self.config_hashes, valve_dps = dp_parser(self.config_file,
                                                  self.logname)
        for valve_dp in valve_dps:
            # pylint: disable=no-member
            valve_cl = valve_factory(valve_dp)
            if valve_cl is None:
                self.logger.error('Hardware type not supported for DP: %s',
                                  valve_dp.name)
            else:
                valve = valve_cl(valve_dp, self.logname)
                self.valves[valve_dp.dp_id] = valve
                valve.update_config_metrics(self.metrics)

        self.gateway_resolve_request_thread = hub.spawn(
            self.gateway_resolve_request)
        self.host_expire_request_thread = hub.spawn(self.host_expire_request)

        self.dp_bgp_speakers = {}
        self._reset_bgp()

        # Register to API
        api = kwargs['faucet_api']
        api._register(self)
        self.send_event_to_observers(EventFaucetAPIRegistered())
Ejemplo n.º 7
0
    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()
        self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml')
        self.table = FakeOFTable(7)
        with open(self.config_file, 'w') as f:
            f.write(self.CONFIG)
        _, dps = dp_parser(self.config_file, 'test_valve')
        self.valve = valve_factory(dps[0])(dps[0], 'test_valve')

        # establish connection to datapath
        ofmsgs = self.valve.datapath_connect(
            self.DP_ID,
            range(1, self.NUM_PORTS + 1)
            )
        self.table.apply_ofmsgs(ofmsgs)

        # learn some mac addresses
        self.rcv_packet(1, 100, {
            'eth_src': self.P1_V100_MAC,
            'eth_dst': self.UNKNOWN_MAC
            })
        self.rcv_packet(2, 200, {
            'eth_src': self.P2_V200_MAC,
            'eth_dst': self.P3_V200_MAC,
            'vid': 200
            })
        self.rcv_packet(3, 200, {
            'eth_src': self.P3_V200_MAC,
            'eth_dst': self.P2_V200_MAC,
            'vid': 200
            })
Ejemplo n.º 8
0
 def new_valve(self, new_dp):
     valve_cl = valve_factory(new_dp)
     if valve_cl is not None:
         return valve_cl(new_dp, self.logname, self.metrics, self.notifier)
     self.logger.error('%s hardware %s must be one of %s', new_dp.name,
                       new_dp.hardware,
                       sorted(list(SUPPORTED_HARDWARE.keys())))
     return None
Ejemplo n.º 9
0
 def _apply_configs_new(self, dp_id, new_dp):
     self.logger.info('Add new datapath %s', dpid_log(dp_id))
     valve_cl = valve_factory(new_dp)
     if valve_cl is not None:
         return valve_cl(new_dp, self.logname, self.notifier)
     self.logger.error('%s hardware %s must be one of %s', new_dp.name,
                       new_dp.hardware,
                       sorted(list(SUPPORTED_HARDWARE.keys())))
     return None
Ejemplo n.º 10
0
 def new_valve(self, new_dp):
     valve_cl = valve_factory(new_dp)
     if valve_cl is not None:
         return valve_cl(new_dp, self.logname, self.metrics, self.notifier, self.dot1x)
     self.logger.error(
         '%s hardware %s must be one of %s',
         new_dp.name,
         new_dp.hardware,
         sorted(list(SUPPORTED_HARDWARE.keys())))
     return None
Ejemplo n.º 11
0
 def setup_valve(self, config):
     self.tmpdir = tempfile.mkdtemp()
     self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml')
     self.table = FakeOFTable(self.NUM_TABLES)
     self.faucet_event_sock = None
     self.logger = None
     self.metrics = None
     self.notifier = faucet_experimental_event.FaucetExperimentalEventNotifier(
         self.faucet_event_sock, self.metrics, self.logger)
     dp = self.update_config(config)
     self.valve = valve_factory(dp)(dp, 'test_valve', self.notifier)
Ejemplo n.º 12
0
 def _load_configs(self, new_config_file):
     self.config_file = new_config_file
     self.config_hashes, new_dps = dp_parser(new_config_file, self.logname)
     if new_dps is None:
         self.logger.error('new config bad - rejecting')
         return
     deleted_valve_dpids = (set(list(self.valves.keys())) -
                            set([valve.dp_id for valve in new_dps]))
     for new_dp in new_dps:
         dp_id = new_dp.dp_id
         if dp_id in self.valves:
             valve = self.valves[dp_id]
             cold_start, flowmods = valve.reload_config(new_dp)
             # pylint: disable=no-member
             if flowmods:
                 self._send_flow_msgs(new_dp.dp_id, flowmods)
                 if cold_start:
                     self.metrics.faucet_config_reload_cold.labels(
                         dp_id=hex(dp_id)).inc()
                 else:
                     self.metrics.faucet_config_reload_warm.labels(
                         dp_id=hex(dp_id)).inc()
         else:
             # pylint: disable=no-member
             valve_cl = valve_factory(new_dp)
             if valve_cl is None:
                 self.logger.error('%s hardware %s must be one of %s',
                                   new_dp.name, new_dp.hardware,
                                   sorted(list(SUPPORTED_HARDWARE.keys())))
                 continue
             else:
                 valve = valve_cl(new_dp, self.logname)
                 self.valves[dp_id] = valve
             self.logger.info('Add new datapath %s', dpid_log(dp_id))
         self.metrics.reset_dpid(dp_id)
         valve.update_config_metrics(self.metrics)
     for deleted_valve_dpid in deleted_valve_dpids:
         self.logger.info('Deleting de-configured %s',
                          dpid_log(deleted_valve_dpid))
         del self.valves[deleted_valve_dpid]
         ryu_dp = self.dpset.get(deleted_valve_dpid)
         if ryu_dp is not None:
             ryu_dp.close()
     self._bgp.reset(self.valves, self.metrics)
Ejemplo n.º 13
0
 def _validate_faucet_config(self, config_dir):
     logname = os.devnull
     try:
         root_config = os.path.join(config_dir, self.default_config)
         _, _, dps, top_confs = dp_parser(root_config, logname)
         dps_conf = None
         valve_cls = None
         acls_conf = None
         if dps is not None:
             dps_conf = {dp.name: dp for dp in dps}
             valve_cls = [valve.valve_factory(dp) for dp in dps]
             acls_conf = top_confs.get('acls', {})
         if dps_conf:
             if not valve_cls:
                 raise InvalidConfigError('no valid DPs defined')
         else:
             dps_conf = {}
         return (dps_conf, acls_conf)
     except InvalidConfigError as err:
         raise _ServerError(f'Invalid config: {err}')  # pylint: disable=raise-missing-from
Ejemplo n.º 14
0
def check_config(conf_files):
    logname = '/dev/null'
    logger = logging.getLogger('%s.config' % logname)
    logger_handler = logging.StreamHandler(stream=sys.stderr)
    logger.addHandler(logger_handler)
    logger.propagate = 0
    logger.setLevel(logging.DEBUG)

    for conf_file in conf_files:
        parse_result = dp_parser(conf_file, logname)
        if parse_result is None:
            return False
        else:
            _, dps = parse_result
            for dp in dps:
                valve_dp = valve.valve_factory(dp)
                if valve_dp is None:
                    return False
                print((dp.to_conf()))
    return True
Ejemplo n.º 15
0
 def setup_valve(self, config):
     """Set up test DP with config."""
     self.tmpdir = tempfile.mkdtemp()
     self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml')
     self.faucet_event_sock = os.path.join(self.tmpdir, 'event.sock')
     self.logfile = os.path.join(self.tmpdir, 'faucet.log')
     self.table = FakeOFTable(self.NUM_TABLES)
     self.logger = valve_util.get_logger('faucet', self.logfile,
                                         logging.DEBUG, 0)
     self.registry = CollectorRegistry()
     # TODO: verify Prometheus variables
     self.metrics = faucet_metrics.FaucetMetrics(reg=self.registry)  # pylint: disable=unexpected-keyword-arg
     # TODO: verify events
     self.notifier = faucet_experimental_event.FaucetExperimentalEventNotifier(
         self.faucet_event_sock, self.metrics, self.logger)
     self.notifier.start()
     dp = self.update_config(config, self.DP)
     self.valve = valve_factory(dp)(dp, 'test_valve', self.notifier)
     self.valve.update_config_metrics(self.metrics)
     self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
     self.sock.connect(self.faucet_event_sock)
Ejemplo n.º 16
0
 def setup_valve(self, config):
     self.tmpdir = tempfile.mkdtemp()
     self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml')
     self.table = FakeOFTable(self.NUM_TABLES)
     dp = self.update_config(config)
     self.valve = valve_factory(dp)(dp, 'test_valve')