def _handler_datapath_up(self, ryu_dp): """Handle DP up. Args: ryu_dp (ryu.controller.controller.Datapath): datapath. """ dp_id = ryu_dp.id if dp_id in self.watchers: self.logger.info('%s up', dpid_log(dp_id)) for watchers in list(self.watchers[dp_id].values()): is_active = True for watcher in watchers: watcher.report_dp_status(1) watcher.start(ryu_dp, is_active) if is_active: self.logger.info( '%s %s watcher starting', dpid_log(dp_id), watcher.conf.type ) is_active = False ryu_dp.send_msg(valve_of.faucet_config(datapath=ryu_dp)) ryu_dp.send_msg(valve_of.gauge_async(datapath=ryu_dp)) else: self.logger.info('%s up, unknown', dpid_log(dp_id))
def load_configs(self, new_config_file, delete_dp=None): """Load/apply new config to all Valves.""" new_dps = self.parse_configs(new_config_file) if new_dps is not None: deleted_dpids = (set(list(self.valves.keys())) - set([dp.dp_id for dp in new_dps])) for new_dp in new_dps: dp_id = new_dp.dp_id if dp_id in self.valves: self.logger.info('Reconfiguring existing datapath %s', dpid_log(dp_id)) valve = self.valves[dp_id] ofmsgs = valve.reload_config(new_dp) if ofmsgs: self.send_flows_to_dp_by_id(new_dp.dp_id, ofmsgs) else: self.logger.info('Add new datapath %s', dpid_log(new_dp.dp_id)) valve = self.new_valve(new_dp) if valve is None: continue valve.update_config_metrics() self.valves[dp_id] = valve if delete_dp is not None: for deleted_dp in deleted_dpids: delete_dp(deleted_dp) del self.valves[deleted_dp] self.bgp.reset(self.valves)
def handler_connect_or_disconnect(self, ryu_event): """Handle connection or disconnection of a datapath. Args: ryu_event (ryu.controller.dpset.EventDP): trigger. """ ryu_dp = ryu_event.dp dp_id = ryu_dp.id # Datapath down message if not ryu_event.enter: if dp_id in self.valves: # pylint: disable=no-member self.metrics.of_dp_disconnections.labels(dpid=hex(dp_id)).inc() self.logger.debug('%s disconnected', dpid_log(dp_id)) self.valves[dp_id].datapath_disconnect(dp_id) else: self.logger.error('handler_connect_or_disconnect: unknown %s', dpid_log(dp_id)) return # pylint: disable=no-member self.metrics.of_dp_connections.labels(dpid=hex(dp_id)).inc() self.logger.debug('%s connected', dpid_log(dp_id)) self.handler_datapath(ryu_dp)
def _send_flow_msgs(self, dp_id, flow_msgs, ryu_dp=None): """Send OpenFlow messages to a connected datapath. Args: dp_id (int): datapath ID. flow_msgs (list): OpenFlow messages to send. ryu_dp: Override datapath from DPSet. """ if ryu_dp is None: ryu_dp = self.dpset.get(dp_id) if not ryu_dp: self.logger.error('send_flow_msgs: %s not up', dpid_log(dp_id)) return if dp_id not in self.valves: self.logger.error('send_flow_msgs: unknown %s', dpid_log(dp_id)) return valve = self.valves[dp_id] reordered_flow_msgs = valve_of.valve_flowreorder(flow_msgs) valve.ofchannel_log(reordered_flow_msgs) for flow_msg in reordered_flow_msgs: # pylint: disable=no-member self.metrics.of_flowmsgs_sent.labels(dp_id=hex(dp_id)).inc() flow_msg.datapath = ryu_dp ryu_dp.send_msg(flow_msg)
def _apply_configs(self, new_dps, now, delete_dp): self.update_config_applied(reset=True) if new_dps is None: return False deleted_dpids = {v for v in self.valves} - {dp.dp_id for dp in new_dps} sent = {} for new_dp in new_dps: dp_id = new_dp.dp_id if dp_id in self.valves: self.logger.info('Reconfiguring existing datapath %s', dpid_log(dp_id)) valve = self.valves[dp_id] ofmsgs = valve.reload_config(now, new_dp) self.send_flows_to_dp_by_id(valve, ofmsgs) sent[dp_id] = True else: self.logger.info('Add new datapath %s', dpid_log(new_dp.dp_id)) valve = self.new_valve(new_dp) if valve is None: continue self._notify({'CONFIG_CHANGE': {'restart_type': 'new'}}, dp=new_dp) valve.update_config_metrics() self.valves[dp_id] = valve if delete_dp is not None: for deleted_dp in deleted_dpids: delete_dp(deleted_dp) del self.valves[deleted_dp] self.bgp.reset(self.valves) self.dot1x.reset(self.valves) self.update_config_applied(sent) return True
def load_configs(self, now, new_config_file, delete_dp=None): """Load/apply new config to all Valves.""" new_dps = self.parse_configs(new_config_file) self.update_config_applied(reset=True) if new_dps is None: return False deleted_dpids = ( set(self.valves.keys()) - set([dp.dp_id for dp in new_dps])) sent = {} for new_dp in new_dps: dp_id = new_dp.dp_id if dp_id in self.valves: self.logger.info('Reconfiguring existing datapath %s', dpid_log(dp_id)) valve = self.valves[dp_id] ofmsgs = valve.reload_config(now, new_dp) self.send_flows_to_dp_by_id(valve, ofmsgs) sent[dp_id] = True else: self.logger.info('Add new datapath %s', dpid_log(new_dp.dp_id)) valve = self.new_valve(new_dp) if valve is None: continue valve.update_config_metrics() self.valves[dp_id] = valve if delete_dp is not None: for deleted_dp in deleted_dpids: delete_dp(deleted_dp) del self.valves[deleted_dp] self.bgp.reset(self.valves) self.dot1x.reset(self.valves) self.update_config_applied(sent) return True
def packet_in_handler(self, ryu_event): """Handle a packet in event from the dataplane. Args: ryu_event (ryu.controller.event.EventReplyBase): packet in message. """ msg = ryu_event.msg ryu_dp = msg.datapath dp_id = ryu_dp.id valve = self._get_valve(ryu_dp, 'packet_in_handler', msg) if valve is None: return if not valve.dp.running: return if valve.dp.cookie != msg.cookie: return in_port = msg.match['in_port'] if valve_of.ignore_port(in_port): return # Truncate packet in data (OVS > 2.5 does not honor max_len) msg.data = msg.data[:valve_of.MAX_PACKET_IN_BYTES] # eth/VLAN header only pkt, eth_pkt, vlan_vid, eth_type = valve_packet.parse_packet_in_pkt( msg.data, max_len=valve_packet.ETH_VLAN_HEADER_SIZE) if vlan_vid is None: self.logger.info('packet without VLAN header from %s port %s', dpid_log(dp_id), in_port) return if pkt is None: self.logger.info('unparseable packet from %s port %s', dpid_log(dp_id), in_port) return if vlan_vid not in valve.dp.vlans: self.logger.info('packet for unknown VLAN %u from %s', vlan_vid, dpid_log(dp_id)) return if in_port not in valve.dp.ports: self.logger.info('packet for unknown port %u from %s', in_port, dpid_log(dp_id)) return pkt_meta = valve.parse_rcv_packet(in_port, vlan_vid, eth_type, msg.data, msg.total_len, pkt, eth_pkt) other_valves = [ other_valve for other_valve in list(self.valves.values()) if valve != other_valve ] self.metrics.of_packet_ins.labels( # pylint: disable=no-member **valve.base_prom_labels).inc() packet_in_start = time.time() flowmods = valve.rcv_packet(other_valves, pkt_meta) packet_in_stop = time.time() self.metrics.faucet_packet_in_secs.labels( # pylint: disable=no-member **valve.base_prom_labels).observe(packet_in_stop - packet_in_start) self._send_flow_msgs(dp_id, flowmods) valve.update_metrics(self.metrics)
def _load_config(self): """Load Gauge config.""" new_confs = watcher_parser(self.config_file, self.logname, self.prom_client) new_watchers = {} for conf in new_confs: watcher = watcher_factory(conf)(conf, self.logname, self.prom_client) watcher_dpid = watcher.dp.dp_id ryu_dp = self.dpset.get(watcher_dpid) watcher_type = watcher.conf.type watcher_msg = '%s %s watcher' % (dpid_log(watcher_dpid), watcher_type) if watcher_dpid not in new_watchers: new_watchers[watcher_dpid] = {} if watcher_type not in new_watchers[watcher_dpid]: # remove old watchers for this stat if (watcher_dpid in self.watchers and watcher_type in self.watchers[watcher_dpid]): old_watchers = self.watchers[watcher_dpid][watcher_type] for old_watcher in old_watchers: if old_watcher.running(): self.logger.info('%s stopped', watcher_msg) old_watcher.stop() del self.watchers[watcher_dpid][watcher_type] # start new watcher new_watchers[watcher_dpid][watcher_type] = [watcher] if ryu_dp is None: watcher.report_dp_status(0) self.logger.info('%s added but DP currently down', watcher_msg) else: watcher.report_dp_status(1) watcher.start(ryu_dp, True) self.logger.info('%s started', watcher_msg) else: new_watchers[watcher_dpid][watcher_type].append(watcher) watcher.start(ryu_dp, False) for watcher_dpid, leftover_watchers in list(self.watchers.items()): for watcher_type, watcher in list(leftover_watchers.items()): watcher.report_dp_status(0) if watcher.running(): self.logger.info( '%s %s deconfigured', dpid_log(watcher_dpid), watcher_type) watcher.stop() self.watchers = new_watchers self.logger.info('config complete')
def port_status_handler(self, ryu_event): """Handle a port status change event. Args: ryu_event (ryu.controller.ofp_event.EventOFPPortStatus): trigger. """ msg = ryu_event.msg ryu_dp = msg.datapath dp_id = ryu_dp.id ofp = msg.datapath.ofproto reason = msg.reason port_no = msg.desc.port_no if dp_id not in self.valves: self.logger.error('port_status_handler: unknown %s', dpid_log(dp_id)) return valve = self.valves[dp_id] flowmods = [] if reason == ofp.OFPPR_ADD: flowmods = valve.port_add(dp_id, port_no) elif reason == ofp.OFPPR_DELETE: flowmods = valve.port_delete(dp_id, port_no) elif reason == ofp.OFPPR_MODIFY: port_down = msg.desc.state & ofp.OFPPS_LINK_DOWN if port_down: flowmods = valve.port_delete(dp_id, port_no) else: flowmods = valve.port_add(dp_id, port_no) else: self.logger.warning('Unhandled port status %s for port %u', reason, port_no) self._send_flow_msgs(ryu_dp, flowmods)
def _handler_datapath_down(self, ryu_dp): """Handle DP down. Args: ryu_dp (ryu.controller.controller.Datapath): datapath. """ dp_id = ryu_dp.id if dp_id in self.watchers: self.logger.info('%s down', dpid_log(dp_id)) for watcher in list(self.watchers[dp_id].values()): watcher.report_dp_status(0) self.logger.info('%s %s watcher stopping', dpid_log(dp_id), watcher.conf.type) watcher.stop() else: self.logger.info('%s down, unknown', dpid_log(dp_id))
def _handler_datapath_down(self, ryu_dp): """Handle DP down. Args: ryu_dp (ryu.controller.controller.Datapath): datapath. """ dp_id = ryu_dp.id if dp_id in self.watchers: self.logger.info('%s down', dpid_log(dp_id)) self.prom_client.dp_status.labels(dp_id=hex(dp_id)).set(0) # pylint: disable=no-member for watcher in list(self.watchers[dp_id].values()): self.logger.info('%s %s watcher stopping', dpid_log(dp_id), watcher.conf.type) watcher.stop() else: self.logger.info('%s down, unknown', dpid_log(dp_id))
def port_status_handler(self, ryu_event): """Handle a port status change event. Args: ryu_event (ryu.controller.ofp_event.EventOFPPortStatus): trigger. """ msg = ryu_event.msg ryu_dp = msg.datapath dp_id = ryu_dp.id valve = self._get_valve(ryu_dp, 'port_status_handler', msg) if valve is None: return if not valve.dp.running: return port_no = msg.desc.port_no if valve_of.ignore_port(port_no): return ofp = msg.datapath.ofproto reason = msg.reason port_down = msg.desc.state & ofp.OFPPS_LINK_DOWN port_status = not port_down self.logger.info('%s port state %u (reason %u)' % (dpid_log(dp_id), msg.desc.state, reason)) flowmods = valve.port_status_handler(port_no, reason, port_status) self._send_flow_msgs(dp_id, flowmods) port_labels = dict(valve.base_prom_labels, port=port_no) self.metrics.port_status.labels( # pylint: disable=no-member **port_labels).set(port_status)
def connect_or_disconnect_handler(self, ryu_event): """Handle connection or disconnection of a datapath. Args: ryu_event (ryu.controller.dpset.EventDP): trigger. """ ryu_dp = ryu_event.dp dp_id = ryu_dp.id valve = self._get_valve(ryu_dp, 'handler_connect_or_disconnect') if valve is None: return if ryu_event.enter: self.logger.info('%s connected', dpid_log(dp_id)) self._datapath_connect(ryu_dp) else: self.logger.info('%s disconnected', dpid_log(dp_id)) self._datapath_disconnect(ryu_dp)
def _apply_configs_existing(self, dp_id, new_dp): logging.info('Reconfiguring existing datapath %s', dpid_log(dp_id)) valve = self.valves[dp_id] cold_start, flowmods = valve.reload_config(new_dp) if flowmods: if cold_start: self.metrics.faucet_config_reload_cold.labels( # pylint: disable=no-member **valve.base_prom_labels).inc() self.logger.info('Cold starting %s', dpid_log(dp_id)) else: self.metrics.faucet_config_reload_warm.labels( # pylint: disable=no-member **valve.base_prom_labels).inc() self.logger.info('Warm starting %s', dpid_log(dp_id)) self._send_flow_msgs(new_dp.dp_id, flowmods) return valve self.logger.info('No changes to datapath %s', dpid_log(dp_id)) return None
def handler_connect_or_disconnect(self, ryu_event): ryu_dp = ryu_event.dp dp_id = ryu_dp.id if dp_id not in self.watchers: self.logger.info('no watcher configured for %s', dpid_log(dp_id)) return if ryu_event.enter: # DP is connecting self.logger.info('%s up', dpid_log(dp_id)) for watcher in list(self.watchers[dp_id].values()): watcher.start(ryu_dp) else: # DP is disconnecting if ryu_dp.id in self.watchers: for watcher in list(self.watchers[dp_id].values()): watcher.stop() del self.watchers[dp_id] self.logger.info('%s down', dpid_log(dp_id))
def _update_watcher(self, dp_id, name, msg): """Call watcher with event data.""" rcv_time = time.time() if dp_id in self.watchers and name in self.watchers[dp_id]: for watcher in self.watchers[dp_id][name]: watcher.update(rcv_time, dp_id, msg) else: self.logger.info('%s event, unknown', dpid_log(dp_id))
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
def handler_reconnect(self, ryu_event): """Handle reconnection of a datapath. Args: ryu_event (ryu.controller.dpset.EventDPReconnected): trigger. """ ryu_dp = ryu_event.dp self.logger.debug('%s reconnected', dpid_log(ryu_dp.id)) self.handler_datapath(ryu_dp)
def _stop_watchers(self, dp_id, watchers): """Stop watchers for DP.""" for watchers_by_name in list(watchers.values()): for watcher in watchers_by_name: watcher.report_dp_status(0) if watcher.is_active(): self.logger.info( '%s %s watcher stopping', dpid_log(dp_id), watcher.conf.type) watcher.stop()
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)
def _load_config(self): """Load Gauge config.""" self.config_file = os.getenv('GAUGE_CONFIG', self.config_file) new_confs = watcher_parser(self.config_file, self.logname, self.prom_client) new_watchers = {} for conf in new_confs: watcher = watcher_factory(conf)(conf, self.logname, self.prom_client) watcher_dpid = watcher.dp.dp_id ryu_dp = self.dpset.get(watcher_dpid) watcher_type = watcher.conf.type watcher_msg = '%s %s watcher' % (dpid_log(watcher_dpid), watcher_type) if watcher_dpid not in new_watchers: new_watchers[watcher_dpid] = {} if (watcher_dpid in self.watchers and watcher_type in self.watchers[watcher_dpid]): old_watcher = self.watchers[watcher_dpid][watcher_type] if old_watcher.running(): self.logger.info('%s stopped', watcher_msg) old_watcher.stop() del self.watchers[watcher_dpid][watcher_type] new_watchers[watcher_dpid][watcher_type] = watcher if ryu_dp is None: self.logger.info('%s added but DP currently down', watcher_msg) else: new_watchers[watcher_dpid][watcher_type].start(ryu_dp) self.logger.info('%s started', watcher_msg) for watcher_dpid, leftover_watchers in list(self.watchers.items()): for watcher_type, watcher in list(leftover_watchers.items()): if watcher.running(): self.logger.info('%s %s deconfigured', dpid_log(watcher_dpid), watcher_type) watcher.stop() self.watchers = new_watchers self.logger.info('config complete')
def _stat_port_name(self, msg, stat, dp_id): if stat.port_no == msg.datapath.ofproto.OFPP_CONTROLLER: return 'CONTROLLER' elif stat.port_no == msg.datapath.ofproto.OFPP_LOCAL: return 'LOCAL' elif stat.port_no in self.dp.ports: return self.dp.ports[stat.port_no].name self.logger.info('%s stats for unknown port %u', dpid_log(dp_id), stat.port_no) return None
def _start_watchers(self, ryu_dp, dp_id, watchers): """Start watchers for DP if active.""" for watchers_by_name in list(watchers.values()): for i, watcher in enumerate(watchers_by_name): is_active = i == 0 watcher.report_dp_status(1) watcher.start(ryu_dp, is_active) if is_active: self.logger.info( '%s %s watcher starting', dpid_log(dp_id), watcher.conf.type)
def _datapath_disconnect(self, ryu_event): """Handle DP down. Args: ryu_event (ryu.controller.event.EventReplyBase): DP event. """ watchers, ryu_dp, _ = self._get_watchers(ryu_event) if watchers is None: return self.logger.info('%s down', dpid_log(ryu_dp.id)) self._stop_watchers(watchers)
def ofchannel_log(self, ofmsgs): """Log OpenFlow messages in text format to debugging log.""" if (self.dp is not None and self.dp.ofchannel_log is not None): if self.ofchannel_logger is None: self.ofchannel_logger = valve_util.get_logger( self.dp.ofchannel_log, self.dp.ofchannel_log, logging.DEBUG, 0) for i, ofmsg in enumerate(ofmsgs, start=1): log_prefix = '%u/%u %s' % (i, len(ofmsgs), valve_util.dpid_log(self.dp.dp_id)) self.ofchannel_logger.debug('%s %s', log_prefix, ofmsg)
def _stat_port_name(self, msg, stat, dp_id): """Return port name as string based on port number.""" if stat.port_no == msg.datapath.ofproto.OFPP_CONTROLLER: return 'CONTROLLER' elif stat.port_no == msg.datapath.ofproto.OFPP_LOCAL: return 'LOCAL' elif stat.port_no in self.dp.ports: return self.dp.ports[stat.port_no].name self.logger.debug('%s stats for unknown port %u', dpid_log(dp_id), stat.port_no) return str(stat.port_no)
def _handler_datapath_down(self, ryu_dp): """Handle DP down. Args: ryu_dp (ryu.controller.controller.Datapath): datapath. """ watchers = self._get_watchers(ryu_dp, '_handler_datapath_down') if watchers is None: return self.logger.info('%s down', dpid_log(ryu_dp.id)) self._stop_watchers(ryu_dp.id, watchers)
def _send_flow_msgs(self, dp_id, flow_msgs, ryu_dp=None): """Send OpenFlow messages to a connected datapath. Args: dp_id (int): datapath ID. flow_msgs (list): OpenFlow messages to send. ryu_dp: Override datapath from DPSet. """ if ryu_dp is None: ryu_dp = self.dpset.get(dp_id) if not ryu_dp: self.logger.error('send_flow_msgs: %s not up', dpid_log(dp_id)) return if dp_id not in self.valves_manager.valves: self.logger.error('send_flow_msgs: unknown %s', dpid_log(dp_id)) return valve = self.valves_manager.valves[dp_id] valve.send_flows(ryu_dp, flow_msgs)
def packet_in_handler(self, ryu_event): """Handle a packet in event from the dataplane. Args: ryu_event (ryu.controller.event.EventReplyBase): packet in message. """ msg = ryu_event.msg ryu_dp = msg.datapath dp_id = ryu_dp.id valve = self._get_valve(ryu_dp, 'packet_in_handler', msg) if valve is None: return if not valve.dp.running: return in_port = msg.match['in_port'] if valve_of.ignore_port(in_port): return # eth/VLAN header only pkt, eth_pkt, vlan_vid, eth_type = valve_packet.parse_packet_in_pkt( msg.data, max_len=valve_packet.ETH_VLAN_HEADER_SIZE) if pkt is None or vlan_vid is None: self.logger.info('unparseable packet from %s port %s', dpid_log(dp_id), in_port) return if vlan_vid not in valve.dp.vlans: self.logger.info('packet for unknown VLAN %u from %s', vlan_vid, dpid_log(dp_id)) return pkt_meta = valve.parse_rcv_packet(in_port, vlan_vid, eth_type, msg.data, pkt, eth_pkt) other_valves = [ other_valve for other_valve in list(self.valves.values()) if valve != other_valve ] # pylint: disable=no-member self.metrics.of_packet_ins.labels(dp_id=hex(dp_id)).inc() flowmods = valve.rcv_packet(other_valves, pkt_meta) self._send_flow_msgs(dp_id, flowmods) valve.update_metrics(self.metrics)
def verify_lldp(self, port, now, valve, other_valves, remote_dp_id, remote_dp_name, remote_port_id, remote_port_state): """ Verify correct LLDP cabling, then update port to next state Args: port (Port): Port that received the LLDP now (float): Current time other_valves (list): Other valves in the topology remote_dp_id (int): Received LLDP remote DP ID remote_dp_name (str): Received LLDP remote DP name remote_port_id (int): Recevied LLDP port ID remote_port_state (int): Received LLDP port state Returns: dict: Ofmsgs by valve """ if not port.stack: return {} remote_dp = port.stack['dp'] remote_port = port.stack['port'] stack_correct = True self._inc_var('stack_probes_received') if (remote_dp_id != remote_dp.dp_id or remote_dp_name != remote_dp.name or remote_port_id != remote_port.number): self.logger.error( 'Stack %s cabling incorrect, expected %s:%s:%u, actual %s:%s:%u' % (port, valve_util.dpid_log(remote_dp.dp_id), remote_dp.name, remote_port.number, valve_util.dpid_log(remote_dp_id), remote_dp_name, remote_port_id)) stack_correct = False self._inc_var('stack_cabling_errors') port.dyn_stack_probe_info = { 'last_seen_lldp_time': now, 'stack_correct': stack_correct, 'remote_dp_id': remote_dp_id, 'remote_dp_name': remote_dp_name, 'remote_port_id': remote_port_id, 'remote_port_state': remote_port_state } return self.update_stack_link_state([port], now, valve, other_valves)
def _datapath_connect(self, ryu_event): """Handle DP up. Args: ryu_event (ryu.controller.event.EventReplyBase): DP event. """ watchers, ryu_dp, _ = self._get_watchers(ryu_event) if watchers is None: return self.logger.info('%s up', dpid_log(ryu_dp.id)) ryu_dp.send_msg(valve_of.faucet_config(datapath=ryu_dp)) ryu_dp.send_msg(valve_of.faucet_async(datapath=ryu_dp, packet_in=False)) self._start_watchers(ryu_dp, watchers, time.time())
def update(self, rcv_time, dp_id, msg): rcv_time_str = _rcv_time(rcv_time) reason = msg.reason port_no = msg.desc.port_no ofp = msg.datapath.ofproto log_msg = 'port %s unknown state %s' % (port_no, reason) if reason == ofp.OFPPR_ADD: log_msg = 'port %s added' % port_no elif reason == ofp.OFPPR_DELETE: log_msg = 'port %s deleted' % port_no elif reason == ofp.OFPPR_MODIFY: link_down = (msg.desc.state & ofp.OFPPS_LINK_DOWN) if link_down: log_msg = 'port %s down' % port_no else: log_msg = 'port %s up' % port_no log_msg = '%s %s' % (dpid_log(dp_id), log_msg) self.logger.info(log_msg) if self.conf.file: with open(self.conf.file, 'a') as logfile: logfile.write('\t'.join((rcv_time_str, log_msg)) + '\n')
def _get_datapath_obj(self, datapath_objs, ryu_event): """Get datapath object to response to an event. Args: datapath_objs (dict): datapath objects indexed by DP ID. ryu_event (ryu.controller.event.Event): event. Returns: valve, ryu_dp, msg: Nones, or datapath object, Ryu datapath, and Ryu msg (if any). """ datapath_obj = None msg = None if hasattr(ryu_event, 'msg'): msg = ryu_event.msg ryu_dp = msg.datapath else: ryu_dp = ryu_event.dp dp_id = ryu_dp.id if dp_id in datapath_objs: datapath_obj = datapath_objs[dp_id] else: ryu_dp.close() self.logger.error('%s: unknown datapath %s', str(ryu_event), dpid_log(dp_id)) return (datapath_obj, ryu_dp, msg)
def _delete_deconfigured_dp(self, deleted_dpid): self.logger.info( 'Deleting de-configured %s', dpid_log(deleted_dpid)) ryu_dp = self.dpset.get(deleted_dpid) if ryu_dp is not None: ryu_dp.close()