Пример #1
0
    def test_add_remove_member(self):
        members = []
        # we need to filter out VLAN interfaces identified by a dot (.)
        # in their name - just in case!
        for tmp in Section.interfaces("ethernet"):
            if not '.' in tmp:
                members.append(tmp)

        for intf in self._interfaces:
            for member in members:
                # We can not enslave an interface when there is an address
                # assigned - take care here - or find them dynamically if a user
                # runs vyos-smoketest on his production device?
                self.session.set(self._base_path +
                                 [intf, 'member', 'interface', member])

        self.session.commit()

        # check validate() - we can only add existing interfaces
        self.session.set(self._base_path +
                         [intf, 'member', 'interface', 'eth99'])
        with self.assertRaises(ConfigSessionError):
            self.session.commit()

        # check if member deletion works as expected
        self.session.delete(self._base_path + [intf, 'member'])
        self.session.commit()
    def test_add_remove_member(self):
        members = []
        # we need to filter out VLAN interfaces identified by a dot (.)
        # in their name - just in case!
        for tmp in Section.interfaces("ethernet"):
            if not '.' in tmp:
                members.append(tmp)

        for intf in self._interfaces:
            cost = 1000
            priority = 10

            self.session.set(self._base_path + [intf, 'stp'])

            # assign members to bridge interface
            for member in members:
                self.session.set(self._base_path +
                                 [intf, 'member', 'interface', member])
                self.session.set(
                    self._base_path +
                    [intf, 'member', 'interface', member, 'cost',
                     str(cost)])
                self.session.set(self._base_path + [
                    intf, 'member', 'interface', member, 'priority',
                    str(priority)
                ])
                cost += 1
                priority += 1

        self.session.commit()

        for intf in self._interfaces:
            self.session.delete(self._base_path + [intf, 'member'])

        self.session.commit()
Пример #3
0
    def setUp(self):
        super().setUp()

        self._base_path = ['interfaces', 'ethernet']
        self._test_mtu = True
        self._interfaces = []

        # we need to filter out VLAN interfaces identified by a dot (.)
        # in their name - just in case!
        for tmp in Section.interfaces("ethernet"):
            if not '.' in tmp:
                self._interfaces.append(tmp)
    def setUp(self):
         super().setUp()
         self._base_path = ['interfaces', 'macsec']
         self._options = {
             'macsec0': ['source-interface eth0',
                         'security cipher gcm-aes-128']
         }

         # if we have a physical eth1 interface, add a second macsec instance
         if 'eth1' in Section.interfaces("ethernet"):
             macsec = { 'macsec1': ['source-interface eth1', 'security cipher gcm-aes-128'] }
             self._options.update(macsec)

         self._interfaces = list(self._options)
Пример #5
0
def apply(wwan):
    if wwan['deleted']:
        # bail out early
        return None

    if not wwan['disable']:
        # "dial" WWAN connection
        intf = wwan['intf']
        call(f'systemctl start ppp@{intf}.service')

        # re-add ourselves to any bridge we might have fallen out of
        # FIXME: wwan isn't under vyos.ifconfig so we can't call
        # Interfaces.add_to_bridge() so STP settings won't get applied
        if wwan['is_bridge_member'] in Section.interfaces('bridge'):
            BridgeIf(wwan['is_bridge_member'], create=False).add_port(wwan['intf'])

    return None
Пример #6
0
    def add_to_bridge(self, br):
        """
        Adds the interface to the bridge with the passed port config.

        Returns False if bridge doesn't exist.
        """

        # check if the bridge exists (on boot it doesn't)
        if br not in Section.interfaces('bridge'):
            return False

        self.flush_addrs()
        # add interface to bridge - use Section.klass to get BridgeIf class
        Section.klass(br)(br, create=False).add_port(self.ifname)

        # TODO: port config (STP)

        return True
    def setUp(self):
        super().setUp()

        self._base_path = ['interfaces', 'ethernet']
        self._test_ip = True
        self._test_mtu = True
        self._test_vlan = True
        self._test_qinq = True
        self._test_ipv6 = True
        self._interfaces = []

        # we need to filter out VLAN interfaces identified by a dot (.)
        # in their name - just in case!
        if 'TEST_ETH' in os.environ:
            tmp = os.environ['TEST_ETH'].split()
            self._interfaces = tmp
        else:
            for tmp in Section.interfaces("ethernet"):
                if not '.' in tmp:
                    self._interfaces.append(tmp)

        def test_dhcp_disable(self):
            """
            When interface is configured as admin down, it must be admin down even
            """
            for interface in self._interfaces:
                self.session.set(self._base_path + [interface, 'disable'])
                for option in self._options.get(interface, []):
                    self.session.set(self._base_path + [interface] +
                                     option.split())

                # Also enable DHCP (ISC DHCP always places interface in admin up
                # state so we check that we do not start DHCP client.
                # https://phabricator.vyos.net/T2767
                self.session.set(self._base_path +
                                 [interface, 'address', 'dhcp'])

            self.session.commit()

            # Validate interface state
            for interface in self._interfaces:
                with open(f'/sys/class/net/{interface}/flags', 'r') as f:
                    flags = f.read()
                self.assertEqual(int(flags, 16) & 1, 0)
    def setUp(self):
        super().setUp()

        self._test_ipv6 = True

        self._base_path = ['interfaces', 'bridge']
        self._interfaces = ['br0']

        self._members = []
        # we need to filter out VLAN interfaces identified by a dot (.)
        # in their name - just in case!
        if 'TEST_ETH' in os.environ:
            self._members = os.environ['TEST_ETH'].split()
        else:
            for tmp in Section.interfaces("ethernet"):
                if not '.' in tmp:
                    self._members.append(tmp)

        self._options['br0'] = []
        for member in self._members:
            self._options['br0'].append(f'member interface {member}')
Пример #9
0
def _sflow_default_agentip(config):
    # check if any of BGP, OSPF, OSPFv3 protocols are configured and use router-id from there
    if config.exists('protocols bgp'):
        bgp_router_id = config.return_value("protocols bgp {} parameters router-id".format(config.list_nodes('protocols bgp')[0]))
        if bgp_router_id:
            return bgp_router_id
    if config.return_value('protocols ospf parameters router-id'):
        return config.return_value('protocols ospf parameters router-id')
    if config.return_value('protocols ospfv3 parameters router-id'):
        return config.return_value('protocols ospfv3 parameters router-id')

    # if router-id was not found, use first available ip of any interface
    for iface in Section.interfaces():
        for address in Interface(iface).get_addr():
            # return an IP, if this is not loopback
            regex_filter = re.compile('^(?!(127)|(::1)|(fe80))(?P<ipaddr>[a-f\d\.:]+)/\d+$')
            if regex_filter.search(address):
                return regex_filter.search(address).group('ipaddr')

    # return nothing by default
    return None
Пример #10
0
def matching(feature):
    for section in Section.feature(feature):
        for intf in Section.interfaces(section):
            yield intf
Пример #11
0
                   action="store_true",
                   help="List all broadcast interfaces")
group.add_argument("-br",
                   "--bridgeable",
                   action="store_true",
                   help="List all bridgeable interfaces")
group.add_argument("-bo",
                   "--bondable",
                   action="store_true",
                   help="List all bondable interfaces")

args = parser.parse_args()

if args.type:
    try:
        interfaces = Section.interfaces(args.type)
        print(" ".join(interfaces))
    except ValueError as e:
        print(e, file=sys.stderr)
        print("")

elif args.broadcast:
    print(" ".join(matching("broadcast")))

elif args.bridgeable:
    print(" ".join(matching("bridgeable")))

elif args.bondable:
    # we need to filter out VLAN interfaces identified by a dot (.) in their name
    print(" ".join([intf for intf in matching("bondable") if '.' not in intf]))
Пример #12
0
def verify(config):
    # Verify that configuration is valid
    # skip all checks if flow-accounting was removed
    if not config['flow-accounting-configured']:
        return True

    # check if at least one collector is enabled
    if not (config['sflow']['configured'] or config['netflow']['configured']
            or not config['disable-imt']):
        raise ConfigError(
            "You need to configure at least one sFlow or NetFlow protocol, or not set \"disable-imt\" for flow-accounting"
        )

    # Check if at least one interface is configured
    if not config['interfaces']:
        raise ConfigError(
            "You need to configure at least one interface for flow-accounting")

    # check that all configured interfaces exists in the system
    for iface in config['interfaces']:
        if not iface in Section.interfaces():
            # chnged from error to warning to allow adding dynamic interfaces and interface templates
            # raise ConfigError("The {} interface is not presented in the system".format(iface))
            print("Warning: the {} interface is not presented in the system".
                  format(iface))

    # check sFlow configuration
    if config['sflow']['configured']:
        # check if at least one sFlow collector is configured if sFlow configuration is presented
        if not config['sflow']['servers']:
            raise ConfigError(
                "You need to configure at least one sFlow server")

        # check that all sFlow collectors use the same IP protocol version
        sflow_collector_ipver = None
        for sflow_collector in config['sflow']['servers']:
            if sflow_collector_ipver:
                if sflow_collector_ipver != ip_address(
                        sflow_collector['address']).version:
                    raise ConfigError(
                        "All sFlow servers must use the same IP protocol")
            else:
                sflow_collector_ipver = ip_address(
                    sflow_collector['address']).version

        # check agent-id for sFlow: we should avoid mixing IPv4 agent-id with IPv6 collectors and vice-versa
        for sflow_collector in config['sflow']['servers']:
            if ip_address(sflow_collector['address']).version != ip_address(
                    config['sflow']['agent-address']).version:
                raise ConfigError(
                    "Different IP address versions cannot be mixed in \"sflow agent-address\" and \"sflow server\". You need to set manually the same IP version for \"agent-address\" as for all sFlow servers"
                )

        # check if configured sFlow agent-id exist in the system
        agent_id_presented = None
        for iface in Section.interfaces():
            for address in Interface(iface).get_addr():
                # check an IP, if this is not loopback
                regex_filter = re.compile(
                    '^(?!(127)|(::1)|(fe80))(?P<ipaddr>[a-f\d\.:]+)/\d+$')
                if regex_filter.search(address):
                    if regex_filter.search(address).group(
                            'ipaddr') == config['sflow']['agent-address']:
                        agent_id_presented = True
                        break
        if not agent_id_presented:
            raise ConfigError(
                "Your \"sflow agent-address\" does not exist in the system")

    # check NetFlow configuration
    if config['netflow']['configured']:
        # check if at least one NetFlow collector is configured if NetFlow configuration is presented
        if not config['netflow']['servers']:
            raise ConfigError(
                "You need to configure at least one NetFlow server")

        # check if configured netflow source-ip exist in the system
        if config['netflow']['source-ip']:
            source_ip_presented = None
            for iface in Interface.listing():
                for address in Interface(iface).get_addr():
                    # check an IP
                    regex_filter = re.compile(
                        '^(?!(127)|(::1)|(fe80))(?P<ipaddr>[a-f\d\.:]+)/\d+$')
                    if regex_filter.search(address):
                        if regex_filter.search(address).group(
                                'ipaddr') == config['netflow']['source-ip']:
                            source_ip_presented = True
                            break
            if not source_ip_presented:
                raise ConfigError(
                    "Your \"netflow source-ip\" does not exist in the system")

        # check if engine-id compatible with selected protocol version
        if config['netflow']['engine-id']:
            v5_filter = '^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]):(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$'
            v9v10_filter = '^(\d|[1-9]\d{1,8}|[1-3]\d{9}|4[01]\d{8}|42[0-8]\d{7}|429[0-3]\d{6}|4294[0-8]\d{5}|42949[0-5]\d{4}|429496[0-6]\d{3}|4294967[01]\d{2}|42949672[0-8]\d|429496729[0-5])$'
            if config['netflow']['version'] == '5':
                regex_filter = re.compile(v5_filter)
                if not regex_filter.search(config['netflow']['engine-id']):
                    raise ConfigError(
                        "You cannot use NetFlow engine-id {} together with NetFlow protocol version {}"
                        .format(config['netflow']['engine-id'],
                                config['netflow']['version']))
            else:
                regex_filter = re.compile(v9v10_filter)
                if not regex_filter.search(config['netflow']['engine-id']):
                    raise ConfigError(
                        "You cannot use NetFlow engine-id {} together with NetFlow protocol version {}"
                        .format(config['netflow']['engine-id'],
                                config['netflow']['version']))

    # return True if all checks were passed
    return True
Пример #13
0
def get_config():
    bridge = deepcopy(default_config_data)
    conf = Config()

    # determine tagNode instance
    if 'VYOS_TAGNODE_VALUE' not in os.environ:
        raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified')

    bridge['intf'] = os.environ['VYOS_TAGNODE_VALUE']

    # Check if bridge has been removed
    if not conf.exists('interfaces bridge ' + bridge['intf']):
        bridge['deleted'] = True
        return bridge

    # set new configuration level
    conf.set_level('interfaces bridge ' + bridge['intf'])

    # retrieve configured interface addresses
    if conf.exists('address'):
        bridge['address'] = conf.return_values('address')

    # Determine interface addresses (currently effective) - to determine which
    # address is no longer valid and needs to be removed
    eff_addr = conf.return_effective_values('address')
    bridge['address_remove'] = list_diff(eff_addr, bridge['address'])

    # retrieve aging - how long addresses are retained
    if conf.exists('aging'):
        bridge['aging'] = int(conf.return_value('aging'))

    # retrieve interface description
    if conf.exists('description'):
        bridge['description'] = conf.return_value('description')

    # get DHCP client identifier
    if conf.exists('dhcp-options client-id'):
        bridge['dhcp_client_id'] = conf.return_value('dhcp-options client-id')

    # DHCP client host name (overrides the system host name)
    if conf.exists('dhcp-options host-name'):
        bridge['dhcp_hostname'] = conf.return_value('dhcp-options host-name')

    # DHCP client vendor identifier
    if conf.exists('dhcp-options vendor-class-id'):
        bridge['dhcp_vendor_class_id'] = conf.return_value(
            'dhcp-options vendor-class-id')

    # DHCPv6 only acquire config parameters, no address
    if conf.exists('dhcpv6-options parameters-only'):
        bridge['dhcpv6_prm_only'] = True

    # DHCPv6 temporary IPv6 address
    if conf.exists('dhcpv6-options temporary'):
        bridge['dhcpv6_temporary'] = True

    # Disable this bridge interface
    if conf.exists('disable'):
        bridge['disable'] = True

    # Ignore link state changes
    if conf.exists('disable-link-detect'):
        bridge['disable_link_detect'] = 2

    # Forwarding delay
    if conf.exists('forwarding-delay'):
        bridge['forwarding_delay'] = int(conf.return_value('forwarding-delay'))

    # Hello packet advertisment interval
    if conf.exists('hello-time'):
        bridge['hello_time'] = int(conf.return_value('hello-time'))

    # Enable Internet Group Management Protocol (IGMP) querier
    if conf.exists('igmp querier'):
        bridge['igmp_querier'] = 1

    # ARP cache entry timeout in seconds
    if conf.exists('ip arp-cache-timeout'):
        bridge['arp_cache_tmo'] = int(
            conf.return_value('ip arp-cache-timeout'))

    # ARP filter configuration
    if conf.exists('ip disable-arp-filter'):
        bridge['ip_disable_arp_filter'] = 0

    # ARP enable accept
    if conf.exists('ip enable-arp-accept'):
        bridge['ip_enable_arp_accept'] = 1

    # ARP enable announce
    if conf.exists('ip enable-arp-announce'):
        bridge['ip_enable_arp_announce'] = 1

    # ARP enable ignore
    if conf.exists('ip enable-arp-ignore'):
        bridge['ip_enable_arp_ignore'] = 1

    # Enable acquisition of IPv6 address using stateless autoconfig (SLAAC)
    if conf.exists('ipv6 address autoconf'):
        bridge['ipv6_autoconf'] = 1

    # Get prefixes for IPv6 addressing based on MAC address (EUI-64)
    if conf.exists('ipv6 address eui64'):
        bridge['ipv6_eui64_prefix'] = conf.return_values('ipv6 address eui64')

    # Determine currently effective EUI64 addresses - to determine which
    # address is no longer valid and needs to be removed
    eff_addr = conf.return_effective_values('ipv6 address eui64')
    bridge['ipv6_eui64_prefix_remove'] = list_diff(eff_addr,
                                                   bridge['ipv6_eui64_prefix'])

    # Remove the default link-local address if set.
    if conf.exists('ipv6 address no-default-link-local'):
        bridge['ipv6_eui64_prefix_remove'].append('fe80::/64')
    else:
        # add the link-local by default to make IPv6 work
        bridge['ipv6_eui64_prefix'].append('fe80::/64')

    # Disable IPv6 forwarding on this interface
    if conf.exists('ipv6 disable-forwarding'):
        bridge['ipv6_forwarding'] = 0

    # IPv6 Duplicate Address Detection (DAD) tries
    if conf.exists('ipv6 dup-addr-detect-transmits'):
        bridge['ipv6_dup_addr_detect'] = int(
            conf.return_value('ipv6 dup-addr-detect-transmits'))

    # Media Access Control (MAC) address
    if conf.exists('mac'):
        bridge['mac'] = conf.return_value('mac')

    # Find out if MAC has changed - if so, we need to delete all IPv6 EUI64 addresses
    # before re-adding them
    if (bridge['mac']
            and bridge['intf'] in Section.interfaces(section='bridge') and
            bridge['mac'] != BridgeIf(bridge['intf'], create=False).get_mac()):
        bridge['ipv6_eui64_prefix_remove'] += bridge['ipv6_eui64_prefix']

    # to make IPv6 SLAAC and DHCPv6 work with forwarding=1,
    # accept_ra must be 2
    if bridge['ipv6_autoconf'] or 'dhcpv6' in bridge['address']:
        bridge['ipv6_accept_ra'] = 2

    # Interval at which neighbor bridges are removed
    if conf.exists('max-age'):
        bridge['max_age'] = int(conf.return_value('max-age'))

    # Determine bridge member interface (currently configured)
    for intf in conf.list_nodes('member interface'):
        # defaults are stored in util.py (they can't be here as all interface
        # scripts use the function)
        memberconf = get_bridge_member_config(conf, bridge['intf'], intf)
        if memberconf:
            memberconf['name'] = intf
            bridge['member'].append(memberconf)

    # Determine bridge member interface (currently effective) - to determine which
    # interfaces is no longer assigend to the bridge and thus can be removed
    eff_intf = conf.list_effective_nodes('member interface')
    act_intf = conf.list_nodes('member interface')
    bridge['member_remove'] = list_diff(eff_intf, act_intf)

    # Priority for this bridge
    if conf.exists('priority'):
        bridge['priority'] = int(conf.return_value('priority'))

    # Enable spanning tree protocol
    if conf.exists('stp'):
        bridge['stp'] = 1

    # retrieve VRF instance
    if conf.exists('vrf'):
        bridge['vrf'] = conf.return_value('vrf')

    return bridge
            if line.startswith("Common Name,"):
                dump = True
                continue
            if line.startswith("ROUTING TABLE"):
                dump = False
                continue
            if dump:
                # client entry in this file looks like
                # client1,172.18.202.10:47495,2957,2851,Sat Aug 17 00:07:11 2019
                # we are only interested in the client name 'client1'
                clients.append(line.split(',')[0])

    return clients

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--interface", type=str, help="List connected clients per interface")
    parser.add_argument("-a", "--all", action='store_true', help="List all connected OpenVPN clients")
    args = parser.parse_args()

    clients = []

    if args.interface:
        clients = get_client_from_interface(args.interface)
    elif args.all:
        for interface in Section.interfaces("openvpn"):
            clients += get_client_from_interface(interface)

    print(" ".join(clients))