Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    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')
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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))
Ejemplo n.º 11
0
    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))
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
 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
Ejemplo n.º 15
0
    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))
Ejemplo n.º 16
0
 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))
Ejemplo n.º 17
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.º 18
0
    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)
Ejemplo n.º 19
0
 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()
Ejemplo n.º 20
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.º 21
0
    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')
Ejemplo n.º 22
0
 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
Ejemplo n.º 23
0
 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)
Ejemplo n.º 24
0
    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)
Ejemplo n.º 25
0
 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)
Ejemplo n.º 26
0
 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)
Ejemplo n.º 27
0
    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)
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
    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)
Ejemplo n.º 30
0
    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)
Ejemplo n.º 31
0
    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)
Ejemplo n.º 32
0
    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())
Ejemplo n.º 33
0
    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())
Ejemplo n.º 34
0
 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')
Ejemplo n.º 35
0
    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)
Ejemplo n.º 36
0
 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()