Esempio n. 1
0
    def check_config(self):
        super(Port, self).check_config()
        test_config_condition(not (isinstance(self.number, int) and self.number > 0 and (
            not valve_of.ignore_port(self.number))), ('Port number invalid: %s' % self.number))
        test_config_condition(
            self.hairpin and self.hairpin_unicast,
            'Cannot have both hairpin and hairpin_unicast enabled')
        if self.dot1x:
            test_config_condition(self.number > 65535, (
                '802.1x not supported on ports > 65535'))
        if self.dot1x_acl:
            test_config_condition(not self.dot1x, (
                '802.1x_ACL requires dot1x to be enabled also'))
        if self.mirror:
            test_config_condition(self.tagged_vlans or self.native_vlan, (
                'mirror port %s cannot have any VLANs assigned' % self))
        if self.stack:
            self._check_conf_types(self.stack, self.stack_defaults_types)
            for stack_config in list(self.stack_defaults_types.keys()):
                test_config_condition(stack_config not in self.stack, (
                    'stack %s must be defined' % stack_config))
            # LLDP always enabled for stack ports.
            self.receive_lldp = True
            if not self.lldp_beacon_enabled():
                self.lldp_beacon.update({'enable': True})

        if self.lldp_beacon:
            self._check_conf_types(
                self.lldp_beacon, self.lldp_beacon_defaults_types)
            self.lldp_beacon = self._set_unknown_conf(
                self.lldp_beacon, self.lldp_beacon_defaults_types)
            if self.lldp_beacon_enabled():
                if self.lldp_beacon['port_descr'] is None:
                    self.lldp_beacon['port_descr'] = self.description

                org_tlvs = []
                for org_tlv in self.lldp_beacon['org_tlvs']:
                    self._check_conf_types(org_tlv, self.lldp_org_tlv_defaults_types)
                    test_config_condition(len(org_tlv) != len(self.lldp_org_tlv_defaults_types), (
                        'missing org_tlv config'))
                    if not isinstance(org_tlv['info'], bytearray):
                        try:
                            org_tlv['info'] = bytearray.fromhex(
                                org_tlv['info']) # pytype: disable=missing-parameter
                        except ValueError:
                            org_tlv['info'] = org_tlv['info'].encode('utf-8')
                    if not isinstance(org_tlv['oui'], bytearray):
                        org_tlv['oui'] = bytearray.fromhex(
                            '%6.6x' % org_tlv['oui']) # pytype: disable=missing-parameter
                    org_tlvs.append(org_tlv)
                self.lldp_beacon['org_tlvs'] = org_tlvs
        if self.acl_in and self.acls_in:
            raise InvalidConfigError('found both acl_in and acls_in, use only acls_in')
        if self.acl_in and not isinstance(self.acl_in, list):
            self.acls_in = [self.acl_in,]
            self.acl_in = None
        if self.acls_in:
            for acl in self.acls_in:
                test_config_condition(not isinstance(acl, (int, str)),
                                      'ACL names must be int or str')
Esempio n. 2
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
        flowmods = valve.port_status_handler(port_no, reason, port_status)
        self._send_flow_msgs(dp_id, flowmods)
        # pylint: disable=no-member
        self.metrics.port_status.labels(dp_id=hex(dp_id),
                                        port=port_no).set(port_status)
Esempio n. 3
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)
Esempio n. 4
0
 def port_no_valid(self, port_no):
     """Return True if supplied port number valid on this datapath."""
     if valve_of.ignore_port(port_no):
         return False
     if port_no not in self.dp.ports:
         self.logger.info('port %u unknown' % port_no)
         return False
     return True
Esempio n. 5
0
    def check_config(self):
        super(Port, self).check_config()
        test_config_condition(
            not (isinstance(self.number, int) and self.number > 0 and
                 (not valve_of.ignore_port(self.number))),
            ('Port number invalid: %s' % self.number))
        if self.mirror:
            test_config_condition(
                self.tagged_vlans or self.native_vlan,
                ('mirror port %s cannot have any VLANs assigned' % self))
        if self.stack:
            self._check_conf_types(self.stack, self.stack_defaults_types)
            for stack_config in list(self.stack_defaults_types.keys()):
                test_config_condition(
                    stack_config not in self.stack,
                    ('stack %s must be defined' % stack_config))
        if self.lldp_beacon:
            self._check_conf_types(self.lldp_beacon,
                                   self.lldp_beacon_defaults_types)
            self.lldp_beacon = self._set_unknown_conf(
                self.lldp_beacon, self.lldp_beacon_defaults_types)
            if self.lldp_beacon_enabled():
                if self.lldp_beacon['port_descr'] is None:
                    self.lldp_beacon['port_descr'] = self.description

                org_tlvs = []
                for org_tlv in self.lldp_beacon['org_tlvs']:
                    self._check_conf_types(org_tlv,
                                           self.lldp_org_tlv_defaults_types)
                    test_config_condition(
                        len(org_tlv) != len(self.lldp_org_tlv_defaults_types),
                        ('missing org_tlv config'))
                    if not isinstance(org_tlv['info'], bytearray):
                        try:
                            org_tlv['info'] = bytearray.fromhex(
                                org_tlv['info'])  # pytype: disable=missing-parameter
                        except ValueError:
                            org_tlv['info'] = org_tlv['info'].encode('utf-8')
                    if not isinstance(org_tlv['oui'], bytearray):
                        org_tlv['oui'] = bytearray.fromhex(
                            '%6.6x' % org_tlv['oui'])  # pytype: disable=missing-parameter
                    org_tlvs.append(org_tlv)
                self.lldp_beacon['org_tlvs'] = org_tlvs
        if self.acl_in and self.acls_in:
            raise InvalidConfigError(
                'found both acl_in and acls_in, use only acls_in')
        if self.acl_in and not isinstance(self.acl_in, list):
            self.acls_in = [
                self.acl_in,
            ]
            self.acl_in = None
        if self.acls_in:
            for acl in self.acls_in:
                test_config_condition(not isinstance(acl, (int, str)),
                                      'acl names must be int or')
Esempio n. 6
0
    def _datapath_connect(self, ryu_event):
        """Handle any/all re/connection of a datapath.

        Args:
            ryu_event (ryu.controller.ofp_event.Event)
        """
        now = time.time()
        valve, ryu_dp, _ = self._get_valve(ryu_event)
        if valve is None:
            return
        discovered_up_ports = [
            port.port_no for port in list(ryu_dp.ports.values())
            if valve_of.port_status_from_state(port.state) and not valve_of.ignore_port(port.port_no)]
        self._send_flow_msgs(valve, valve.datapath_connect(now, discovered_up_ports))
Esempio n. 7
0
    def _datapath_connect(self, ryu_event):
        """Handle any/all re/connection of a datapath.

        Args:
            ryu_event (ryu.controller.ofp_event.Event)
        """
        now = time.time()
        valve, ryu_dp, _ = self._get_valve(ryu_event)
        if valve is None:
            return
        discovered_up_ports = [
            port.port_no for port in list(ryu_dp.ports.values())
            if (valve_of.port_status_from_state(port.state) and
                not valve_of.ignore_port(port.port_no))]
        self._send_flow_msgs(valve, valve.datapath_connect(now, discovered_up_ports))
Esempio n. 8
0
    def _datapath_connect(self, ryu_dp):
        """Handle any/all re/connection of a datapath.

        Args:
            ryu_dp (ryu.controller.controller.Datapath): datapath.
        """
        dp_id = ryu_dp.id
        valve = self._get_valve(ryu_dp, '_datapath_connect')
        if valve is None:
            return
        discovered_ports = [
            port for port in list(ryu_dp.ports.values())
            if not valve_of.ignore_port(port.port_no)
        ]
        flowmods = valve.datapath_connect(discovered_ports)
        self._send_flow_msgs(dp_id, flowmods)
Esempio n. 9
0
File: port.py Progetto: nfz1/faucet
    def check_config(self):
        super(Port, self).check_config()
        assert isinstance(self.number, int) and self.number > 0 and not ignore_port(self.number), (
            'Port number invalid: %s' % self.number)
        if self.mirror:
            assert not self.tagged_vlans and not self.native_vlan, (
                'mirror port %s cannot have any VLANs assigned' % self)
        if self.stack:
            self._check_conf_types(self.stack, self.stack_defaults_types)
            for stack_config in list(self.stack_defaults_types.keys()):
                assert stack_config in self.stack, 'stack %s must be defined' % stack_config
        if self.lldp_beacon:
            self._check_conf_types(
                self.lldp_beacon, self.lldp_beacon_defaults_types)
            self.lldp_beacon = self._set_unknown_conf(
                self.lldp_beacon, self.lldp_beacon_defaults_types)
            if self.lldp_beacon_enabled():
                assert self.native_vlan, 'native_vlan must be defined for LLDP beacon'
                if self.lldp_beacon['port_descr'] is None:
                    self.lldp_beacon['port_descr'] = self.description

                org_tlvs = []
                for org_tlv in self.lldp_beacon['org_tlvs']:
                    self._check_conf_types(org_tlv, self.lldp_org_tlv_defaults_types)
                    assert len(org_tlv) == len(self.lldp_org_tlv_defaults_types), (
                        'missing org_tlv config')
                    try:
                        org_tlv['info'] = bytearray.fromhex(org_tlv['info'])
                    except ValueError:
                        org_tlv['info'] = org_tlv['info'].encode('utf-8')
                    org_tlv['oui'] = bytearray.fromhex('%6.6x' % org_tlv['oui'])
                    org_tlvs.append(org_tlv)
                self.lldp_beacon['org_tlvs'] = org_tlvs
        if self.acl_in and self.acls_in:
            assert False, 'found both acl_in and acls_in, use only acls_in'
        if self.acl_in and not isinstance(self.acl_in, list):
            self.acls_in = [self.acl_in,]
            self.acl_in = None
        if self.acls_in:
            for acl in self.acls_in:
                assert isinstance(acl, (int, str)), 'acl names must be int or'
Esempio n. 10
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)
Esempio n. 11
0
 def check_config(self):
     super(Port, self).check_config()
     assert isinstance(self.number, int) and self.number > 0 and not ignore_port(self.number), (
         'Port number invalid: %s' % self.number)
Esempio n. 12
0
 def port_up_valid(port):
     """Return True if port is up and in valid range."""
     return valve_of.port_status_from_state(
         port.state) and not valve_of.ignore_port(port.port_no)
Esempio n. 13
0
File: dp.py Progetto: vmastar/faucet
 def port_no_valid(self, port_no):
     """Return True if supplied port number valid on this datapath."""
     return not valve_of.ignore_port(port_no) and port_no in self.ports
Esempio n. 14
0
 def port_up_valid(port):
     """Return True if port is up and in valid range."""
     return port.state == 0 and not valve_of.ignore_port(port.port_no)
Esempio n. 15
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
        # Drop any packet we didn't specifically ask for
        if msg.reason != valve_of.ofp.OFPR_ACTION:
            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)
        if not valve_packet.mac_addr_is_unicast(pkt_meta.eth_src):
            self.logger.info(
                'packet with non-unicast eth_src %s port %u from %s',
                pkt_meta.eth_src, in_port, dpid_log(dp_id))
            return
        if valve.dp.stack is not None:
            if (not pkt_meta.port.stack
                    and pkt_meta.vlan not in pkt_meta.port.tagged_vlans
                    and pkt_meta.vlan != pkt_meta.port.native_vlan):
                self.logger.warning((
                    'packet from non-stack port number %u is not member of VLAN %u'
                    % (pkt_meta.port.number, pkt_meta.vlan.vid)))
                return
        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)
Esempio n. 16
0
 def port_no_valid(self, port_no):
     """Return True if supplied port number valid on this datapath."""
     return not valve_of.ignore_port(port_no) and port_no in self.ports
Esempio n. 17
0
 def check_config(self):
     super(Port, self).check_config()
     test_config_condition(not (isinstance(self.number, int) and self.number > 0 and (
         not valve_of.ignore_port(self.number))), ('Port number invalid: %s' % self.number))
     non_vlan_options = {'stack', 'mirror', 'coprocessor', 'output_only'}
     vlan_agnostic_options = {'enabled', 'number', 'name', 'description', 'max_lldp_lost'}
     vlan_port = self.tagged_vlans or self.native_vlan
     non_vlan_port_options = {option for option in non_vlan_options if getattr(self, option)}
     test_config_condition(
         vlan_port and non_vlan_port_options,
         'cannot have VLANs configured on non-VLAN ports: %s' % self)
     if self.output_only:
         test_config_condition(
             not non_vlan_port_options.issubset({'mirror', 'output_only'}),
             'output_only can only coexist with mirror option on same port %s' % self)
     elif self.mirror:
         test_config_condition(
             not non_vlan_port_options.issubset({'mirror', 'coprocessor'}),
             'coprocessor can only coexist with mirror option on same port %s' % self)
     else:
         test_config_condition(
             len(non_vlan_port_options) > 1,
             'cannot have multiple non-VLAN port options %s on same port: %s' % (
                 non_vlan_port_options, self))
     if non_vlan_port_options:
         for key, default_val in self.defaults.items():
             if key in vlan_agnostic_options or key in non_vlan_port_options:
                 continue
             if key.startswith('acl') and (self.stack or self.coprocessor):
                 continue
             val = getattr(self, key)
             test_config_condition(
                 val != default_val and val,
                 'Cannot have VLAN option %s: %s on non-VLAN port %s' % (key, val, self))
     test_config_condition(
         self.hairpin and self.hairpin_unicast,
         'Cannot have both hairpin and hairpin_unicast enabled')
     dot1x_features = {
         dot1x_feature for dot1x_feature, dot1x_config in self.defaults.items()
         if dot1x_feature.startswith('dot1x_') and dot1x_config}
     test_config_condition(
         dot1x_features and not self.dot1x,
         '802.1x features %s require port to have dot1x enabled' % dot1x_features)
     if self.dot1x:
         test_config_condition(self.number > 65535, (
             '802.1x not supported on ports > 65535'))
         if self.dot1x_mab:
             test_config_condition(self.dot1x_dyn_acl, (
                 '802.1x_MAB cannot be used with 802.1x_DYN_ACL'))
         if self.dot1x_dyn_acl:
             test_config_condition(self.dot1x_acl, (
                 '802.1x_DYN_ACL cannot be used with 802.1x_ACL'))
     if self.coprocessor:
         self._check_conf_types(self.coprocessor, self.coprocessor_defaults_types)
         test_config_condition(
             self.coprocessor.get('strategy', None) != 'vlan_vid',
             'coprocessor only supports vlan_vid strategy')
         self.coprocessor['vlan_vid_base'] = self.coprocessor.get('vlan_vid_base', 1000)
     if self.stack:
         self._check_conf_types(self.stack, self.stack_defaults_types)
         for stack_config in list(self.stack_defaults_types.keys()):
             test_config_condition(stack_config not in self.stack, (
                 'stack %s must be defined' % stack_config))
         # LLDP always enabled for stack ports.
         self.receive_lldp = True
         if not self.lldp_beacon_enabled():
             self.lldp_beacon.update({'enable': True})
     if self.lacp_resp_interval is not None:
         test_config_condition(
             self.lacp_resp_interval > 65535 or self.lacp_resp_interval < 0.3,
             ('interval must be at least 0.3 and less than 65536'))
     if self.lacp_port_priority is not None:
         test_config_condition(
             self.lacp_port_priority > 255 or self.lacp_port_priority < 0,
             ('lacp port priority must be at least 0 and less than 256'))
     if self.lldp_peer_mac:
         test_config_condition(not netaddr.valid_mac(self.lldp_peer_mac), (
             'invalid MAC address %s' % self.lldp_peer_mac))
     if self.lldp_beacon:
         self._check_conf_types(
             self.lldp_beacon, self.lldp_beacon_defaults_types)
         self.lldp_beacon = self._set_unknown_conf(
             self.lldp_beacon, self.lldp_beacon_defaults_types)
         if self.lldp_beacon_enabled():
             if self.lldp_beacon['port_descr'] is None:
                 self.lldp_beacon['port_descr'] = self.description
             org_tlvs = []
             for org_tlv in self.lldp_beacon['org_tlvs']:
                 self._check_conf_types(org_tlv, self.lldp_org_tlv_defaults_types)
                 test_config_condition(len(org_tlv) != len(self.lldp_org_tlv_defaults_types), (
                     'missing org_tlv config'))
                 if not isinstance(org_tlv['info'], bytearray):
                     try:
                         org_tlv['info'] = bytearray.fromhex(
                             org_tlv['info']) # pytype: disable=missing-parameter
                     except ValueError:
                         org_tlv['info'] = org_tlv['info'].encode('utf-8')
                 if not isinstance(org_tlv['oui'], bytearray):
                     org_tlv['oui'] = bytearray.fromhex(
                         '%6.6x' % org_tlv['oui']) # pytype: disable=missing-parameter
                 org_tlvs.append(org_tlv)
             self.lldp_beacon['org_tlvs'] = org_tlvs
     test_config_condition(
         self.acl_in and self.acls_in,
         'Found both acl_in and acls_in, use only acls_in')
     if self.acl_in and not isinstance(self.acl_in, list):
         self.acls_in = [self.acl_in]
         self.acl_in = None
     if self.acls_in:
         for acl in self.acls_in:
             test_config_condition(not isinstance(acl, (int, str)),
                                   'ACL names must be int or str')
     lacp_options = [self.lacp_selected, self.lacp_unselected, self.lacp_standby]
     test_config_condition(
         lacp_options.count(True) > 1,
         'Cannot force multiple LACP port selection states')
Esempio n. 18
0
 def port_up_valid(port):
     return port.state == 0 and not valve_of.ignore_port(port.port_no)