Esempio n. 1
0
    def start(self):
        if ip.valid_ipv6(self._address):
            server = hub.listen((self._address, self._port),
                                family=socket.AF_INET6)
        else:
            server = hub.listen((self._address, self._port))
        key = self.CONF.ovsdb.mngr_privkey or self.CONF.ctl_privkey
        cert = self.CONF.ovsdb.mngr_cert or self.CONF.ctl_cert

        if key is not None and cert is not None:
            ssl_kwargs = dict(keyfile=key, certfile=cert, server_side=True)

            if self.CONF.ca_certs is not None:
                ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED
                ssl_kwargs['ca_certs'] = self.CONF.ca_certs

            server = ssl.wrap_socket(server, **ssl_kwargs)

        self._server = server

        if ip.valid_ipv6(self._address):
            self.logger.info('Listening on [%s]:%s for clients', self._address,
                             self._port)
        else:
            self.logger.info('Listening on %s:%s for clients', self._address,
                             self._port)
        t = hub.spawn(self._accept, self._server)
        super(OVSDB, self).start()
        return t
Esempio n. 2
0
def _split_addr(addr):
    """
    Splits a str of IP address and port pair into (host, port).

    Example::

        >>> _split_addr('127.0.0.1:6653')
        ('127.0.0.1', 6653)
        >>> _split_addr('[::1]:6653')
        ('::1', 6653)

    Raises ValueError if invalid format.

    :param addr: A pair of IP address and port.
    :return: IP address and port
    """
    e = ValueError('Invalid IP address and port pair: "%s"' % addr)
    pair = addr.rsplit(':', 1)
    if len(pair) != 2:
        raise e

    addr, port = pair
    if addr.startswith('[') and addr.endswith(']'):
        addr = addr.lstrip('[').rstrip(']')
        if not ip.valid_ipv6(addr):
            raise e
    elif not ip.valid_ipv4(addr):
        raise e

    return addr, int(port, 0)
def ip_address_add(session, ifname, ifaddr):
    """
    Adds an IP address to interface record identified with the given "ifname".

    The arguments are similar to "ip address add" command of iproute2.

    :param session: Session instance connecting to database.
    :param ifname: Name of interface.
    :param ifaddr: IPv4 or IPv6 address.
    :return: Instance of record or "None" if failed.
    """
    def _append_inet_addr(intf_inet, addr):
        addr_list = intf_inet.split(',')
        if addr in addr_list:
            LOG.debug('Interface "%s" has already "ifaddr": %s', intf.ifname,
                      addr)
            return intf_inet
        else:
            addr_list.append(addr)
            return ','.join(addr_list)

    intf = ip_link_show(session, ifname=ifname)
    if not intf:
        LOG.debug('Interface "%s" does not exist', ifname)
        return None

    if ip.valid_ipv4(ifaddr):
        intf.inet = _append_inet_addr(intf.inet, ifaddr)
    elif ip.valid_ipv6(ifaddr):
        intf.inet6 = _append_inet_addr(intf.inet6, ifaddr)
    else:
        LOG.debug('Invalid IP address for "ifaddr": %s', ifaddr)
        return None

    return intf
Esempio n. 4
0
        def __init__(self,
                     listen_info,
                     handle=None,
                     backlog=None,
                     spawn='default',
                     **ssl_args):
            assert backlog is None
            assert spawn == 'default'

            if ip.valid_ipv6(listen_info[0]):
                self.server = eventlet.listen(listen_info,
                                              family=socket.AF_INET6)
            elif os.path.isdir(os.path.dirname(listen_info[0])):
                # Case for Unix domain socket
                self.server = eventlet.listen(listen_info[0],
                                              family=socket.AF_UNIX)
            else:
                self.server = eventlet.listen(listen_info)

            if ssl_args:

                def wrap_and_handle(sock, addr):
                    ssl_args.setdefault('server_side', True)
                    handle(ssl.wrap_socket(sock, **ssl_args), addr)

                self.handle = wrap_and_handle
            else:
                self.handle = handle
Esempio n. 5
0
def register_switch_address(addr, interval=None):
    """
    Registers a new address to initiate connection to switch.

    Registers a new IP address and port pair of switch to let
    ryu.controller.controller.OpenFlowController to try to initiate
    connection to switch.

    :param addr: A tuple of (host, port) pair of switch.
    :param interval: Interval in seconds to try to connect to switch
    """
    assert len(addr) == 2
    assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0])
    ofp_handler = app_manager.lookup_service_brick(ofp_event.NAME)
    _TMP_ADDRESSES[addr] = interval

    def _retry_loop():
        # Delays registration if ofp_handler is not started yet
        while True:
            if ofp_handler.controller is not None:
                for a, i in _TMP_ADDRESSES.items():
                    ofp_handler.controller.spawn_client_loop(a, i)
                    hub.sleep(1)
                break
            hub.sleep(1)

    hub.spawn(_retry_loop)
Esempio n. 6
0
def validate_bgp_server_hosts(hosts):
    for host in hosts:
        if not ip.valid_ipv4(host) and not ip.valid_ipv6(host):
            raise ConfigTypeError(desc=('Invalid bgp sever hosts '
                                        'configuration value %s' % hosts))

    return hosts
Esempio n. 7
0
def create_connection(address):
    """
    Wrapper for socket.create_connection() function.

    If *address* (a 2-tuple ``(host, port)``) contains a valid IPv4/v6
    address, passes *address* to socket.create_connection().
    If *host* is valid path to Unix Domain socket, tries to connect to
    the server listening on the given socket.

    :param address: IP address or path to Unix Domain socket.
    :return: Socket instance.
    """
    host, _port = address

    if ip.valid_ipv4(host) or ip.valid_ipv6(host):
        return socket.create_connection(address)
    elif os.path.exists(host):
        sock = None
        try:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            sock.connect(host)
        except socket.error as e:
            if sock is not None:
                sock.close()
            raise e
        return sock
    else:
        raise ValueError('Invalid IP address or Unix Socket: %s' % host)
Esempio n. 8
0
def create_connection(address):
    """
    Wrapper for socket.create_connection() function.

    If *address* (a 2-tuple ``(host, port)``) contains a valid IPv4/v6
    address, passes *address* to socket.create_connection().
    If *host* is valid path to Unix Domain socket, tries to connect to
    the server listening on the given socket.

    :param address: IP address or path to Unix Domain socket.
    :return: Socket instance.
    """
    host, _port = address

    if ip.valid_ipv4(host) or ip.valid_ipv6(host):
        return socket.create_connection(address)
    elif os.path.exists(host):
        sock = None
        try:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            sock.connect(host)
        except socket.error as e:
            if sock is not None:
                sock.close()
            raise e
        return sock
    else:
        raise ValueError('Invalid IP address or Unix Socket: %s' % host)
Esempio n. 9
0
def _split_addr(addr):
    """
    Splits a str of IP address and port pair into (host, port).
    将字符串的IP 地址及端口,解析为(host,IP)格式

    Example::

        >>> _split_addr('127.0.0.1:6653')
        ('127.0.0.1', 6653)
        >>> _split_addr('[::1]:6653')
        ('::1', 6653)

    Raises ValueError if invalid format.
    非法格式触发ValueError类型错误

    :param addr: A pair of IP address and port.
    :return: IP address and port
    """
    e = ValueError('Invalid IP address and port pair: "%s"' % addr)
    pair = addr.rsplit(':', 1)
    if len(pair) != 2:
        raise e

    addr, port = pair
    if addr.startswith('[') and addr.endswith(']'):
        addr = addr.lstrip('[').rstrip(']')
        if not ip.valid_ipv6(addr):
            raise e
    elif not ip.valid_ipv4(addr):
        raise e

    return addr, int(port, 0)
Esempio n. 10
0
    def _send_ip_route_impl(self,
                            prefix,
                            nexthops=None,
                            safi=packet_safi.UNICAST,
                            flags=zebra.ZEBRA_FLAG_INTERNAL,
                            distance=None,
                            metric=None,
                            mtu=None,
                            tag=None,
                            is_withdraw=False):
        if ip.valid_ipv4(prefix):
            if is_withdraw:
                msg_cls = zebra.ZebraIPv4RouteDelete
            else:
                msg_cls = zebra.ZebraIPv4RouteAdd
        elif ip.valid_ipv6(prefix):
            if is_withdraw:
                msg_cls = zebra.ZebraIPv6RouteDelete
            else:
                msg_cls = zebra.ZebraIPv6RouteAdd
        else:
            raise ValueError('Invalid prefix: %s' % prefix)

        nexthop_list = []
        for nexthop in nexthops:
            if ip.valid_ipv4(nexthop):
                nexthop_list.append(zebra.NextHopIPv4(addr=nexthop))
            elif ip.valid_ipv6(nexthop):
                nexthop_list.append(zebra.NextHopIPv6(addr=nexthop))
            else:
                raise ValueError('Invalid nexthop: %s' % nexthop)

        msg = zebra.ZebraMessage(version=self.zserv_ver,
                                 body=msg_cls(route_type=self.route_type,
                                              flags=flags,
                                              message=0,
                                              safi=safi,
                                              prefix=prefix,
                                              nexthops=nexthop_list,
                                              distance=distance,
                                              metric=metric,
                                              mtu=mtu,
                                              tag=tag,
                                              instance=0))
        self.send_msg(msg)

        return msg
Esempio n. 11
0
def detect_address_family(host):
    if ip.valid_ipv4(host):
        return socket.AF_INET
    elif ip.valid_ipv6(host):
        return socket.AF_INET6
    elif os.path.isdir(os.path.dirname(host)):
        return socket.AF_UNIX
    else:
        return None
Esempio n. 12
0
    def _send_ip_route_impl(
            self, prefix, nexthops=None,
            safi=packet_safi.UNICAST, flags=zebra.ZEBRA_FLAG_INTERNAL,
            distance=None, metric=None, mtu=None, tag=None,
            is_withdraw=False):
        if ip.valid_ipv4(prefix):
            if is_withdraw:
                msg_cls = zebra.ZebraIPv4RouteDelete
            else:
                msg_cls = zebra.ZebraIPv4RouteAdd
        elif ip.valid_ipv6(prefix):
            if is_withdraw:
                msg_cls = zebra.ZebraIPv6RouteDelete
            else:
                msg_cls = zebra.ZebraIPv6RouteAdd
        else:
            raise ValueError('Invalid prefix: %s' % prefix)

        nexthop_list = []
        for nexthop in nexthops:
            if ip.valid_ipv4(nexthop):
                nexthop_list.append(zebra.NextHopIPv4(addr=nexthop))
            elif ip.valid_ipv6(nexthop):
                nexthop_list.append(zebra.NextHopIPv6(addr=nexthop))
            else:
                raise ValueError('Invalid nexthop: %s' % nexthop)

        msg = zebra.ZebraMessage(
            version=self.zserv_ver,
            body=msg_cls(
                route_type=self.route_type,
                flags=flags,
                message=0,
                safi=safi,
                prefix=prefix,
                nexthops=nexthop_list,
                distance=distance,
                metric=metric,
                mtu=mtu,
                tag=tag,
                instance=0))
        self.send_msg(msg)

        return msg
Esempio n. 13
0
    def serialize(self):
        # fixup
        if ip.valid_ipv4(self.peer_ip) and ip.valid_ipv4(self.local_ip):
            self.afi = self.AFI_IPv4
        elif ip.valid_ipv6(self.peer_ip) and ip.valid_ipv6(self.local_ip):
            self.afi = self.AFI_IPv6
        else:
            raise ValueError(
                'peer_ip and local_ip must be the same address family: '
                'peer_ip=%s, local_ip=%s' % (self.peer_ip, self.local_ip))

        buf = struct.pack(self._HEADER_FMT, self.peer_as, self.local_as,
                          self.if_index, self.afi)

        buf += ip.text_to_bin(self.peer_ip)
        buf += ip.text_to_bin(self.local_ip)

        buf += struct.pack(self._STATES_FMT, self.old_state, self.new_state)

        return buf
Esempio n. 14
0
    def serialize(self):
        # fixup
        if ip.valid_ipv4(self.peer_ip) and ip.valid_ipv4(self.local_ip):
            self.afi = self.AFI_IPv4
        elif ip.valid_ipv6(self.peer_ip) and ip.valid_ipv6(self.local_ip):
            self.afi = self.AFI_IPv6
        else:
            raise ValueError(
                'peer_ip and local_ip must be the same address family: '
                'peer_ip=%s, local_ip=%s' % (self.peer_ip, self.local_ip))

        buf = struct.pack(self._HEADER_FMT,
                          self.peer_as, self.local_as,
                          self.if_index, self.afi)

        buf += ip.text_to_bin(self.peer_ip)
        buf += ip.text_to_bin(self.local_ip)

        buf += self.bgp_message.serialize()

        return buf
Esempio n. 15
0
    def serialize(self):
        if ip.valid_ipv6(self.ip_addr):
            # Sets Peer IP Address family bit to IPv6
            self.type |= self.IP_ADDR_FAMILY_BIT
        ip_addr = ip.text_to_bin(self.ip_addr)

        if self.type & self.AS_NUMBER_SIZE_BIT or self.as_num > 0xffff:
            # Four octet AS number
            self.type |= self.AS_NUMBER_SIZE_BIT
            as_num = struct.pack('!I', self.as_num)
        else:
            # Two octet AS number
            as_num = struct.pack('!H', self.as_num)

        buf = struct.pack(self._HEADER_FMT, self.type,
                          addrconv.ipv4.text_to_bin(self.bgp_id))

        return buf + ip_addr + as_num
Esempio n. 16
0
    def serialize(self):
        if ip.valid_ipv6(self.ip_addr):
            # Sets Peer IP Address family bit to IPv6
            self.type |= self.IP_ADDR_FAMILY_BIT
        ip_addr = ip.text_to_bin(self.ip_addr)

        if self.type & self.AS_NUMBER_SIZE_BIT or self.as_num > 0xffff:
            # Four octet AS number
            self.type |= self.AS_NUMBER_SIZE_BIT
            as_num = struct.pack('!I', self.as_num)
        else:
            # Two octet AS number
            as_num = struct.pack('!H', self.as_num)

        buf = struct.pack(self._HEADER_FMT,
                          self.type,
                          addrconv.ipv4.text_to_bin(self.bgp_id))

        return buf + ip_addr + as_num
Esempio n. 17
0
    def _accept(self, server):
        if self.CONF.ovsdb.whitelist:

            def check(address):
                if address in self.CONF.ovsdb.whitelist:
                    return True

                self.logger.debug('Connection from non-whitelist client '
                                  '(%s:%s)' % address)
                return False

        else:

            def check(address):
                return True

        while self.is_active:
            try:
                # TODO(jkoelker) SSL Certificate Fingerprint check
                sock, client_address = server.accept()

            except:
                if self.is_active:
                    self.logger.exception('Error accepting connection')
                    continue

            if not check(client_address[0]):
                sock.shutdown(socket.SHUT_RDWR)
                sock.close()
                continue

            if ip.valid_ipv6(client_address[0]):
                self.logger.debug('New connection from [%s]:%s' %
                                  client_address[:2])
            else:
                self.logger.debug('New connection from %s:%s' %
                                  client_address[:2])
            t = hub.spawn(self._start_remote, sock, client_address)
            self.threads.append(t)
Esempio n. 18
0
        def __init__(self,
                     listen_info,
                     handle=None,
                     backlog=None,
                     spawn='default',
                     **ssl_args):
            assert backlog is None
            assert spawn == 'default'

            if ip.valid_ipv6(listen_info[0]):
                self.server = eventlet.listen(listen_info,
                                              family=socket.AF_INET6)
            elif os.path.isdir(os.path.dirname(listen_info[0])):
                # Case for Unix domain socket
                self.server = eventlet.listen(listen_info[0],
                                              family=socket.AF_UNIX)
            else:
                self.server = eventlet.listen(listen_info)

            if ssl_args:

                def wrap_and_handle(sock, addr):
                    ssl_args.setdefault('server_side', True)
                    if 'ssl_ctx' in ssl_args:
                        ctx = ssl_args.pop('ssl_ctx')
                        ctx.load_cert_chain(ssl_args.pop('certfile'),
                                            ssl_args.pop('keyfile'))
                        if 'cert_reqs' in ssl_args:
                            ctx.verify_mode = ssl_args.pop('cert_reqs')
                        if 'ca_certs' in ssl_args:
                            ctx.load_verify_locations(ssl_args.pop('ca_certs'))
                        handle(ctx.wrap_socket(sock, **ssl_args), addr)
                    else:
                        handle(ssl.wrap_socket(sock, **ssl_args), addr)

                self.handle = wrap_and_handle
            else:
                self.handle = handle
Esempio n. 19
0
        def __init__(self, listen_info, handle=None, backlog=None,
                     spawn='default', **ssl_args):
            assert backlog is None
            assert spawn == 'default'

            if ip.valid_ipv6(listen_info[0]):
                self.server = eventlet.listen(listen_info,
                                              family=socket.AF_INET6)
            elif os.path.isdir(os.path.dirname(listen_info[0])):
                # Case for Unix domain socket
                self.server = eventlet.listen(listen_info[0],
                                              family=socket.AF_UNIX)
            else:
                self.server = eventlet.listen(listen_info)

            if ssl_args:
                def wrap_and_handle(sock, addr):
                    ssl_args.setdefault('server_side', True)
                    handle(ssl.wrap_socket(sock, **ssl_args), addr)

                self.handle = wrap_and_handle
            else:
                self.handle = handle
Esempio n. 20
0
def ip_address_delete(session, ifname, ifaddr):
    """
    Deletes an IP address from interface record identified with the given
    "ifname".

    The arguments are similar to "ip address delete" command of iproute2.

    :param session: Session instance connecting to database.
    :param ifname: Name of interface.
    :param ifaddr: IPv4 or IPv6 address.
    :return: Instance of record or "None" if failed.
    """
    def _remove_inet_addr(intf_inet, addr):
        addr_list = intf_inet.split(',')
        if addr not in addr_list:
            LOG.debug(
                'Interface "%s" does not have "ifaddr": %s',
                intf.ifname, addr)
            return intf_inet
        else:
            addr_list.remove(addr)
            return ','.join(addr_list)

    intf = ip_link_show(session, ifname=ifname)
    if not intf:
        LOG.debug('Interface "%s" does not exist', ifname)
        return None

    if ip.valid_ipv4(ifaddr):
        intf.inet = _remove_inet_addr(intf.inet, ifaddr)
    elif ip.valid_ipv6(ifaddr):
        intf.inet6 = _remove_inet_addr(intf.inet6, ifaddr)
    else:
        LOG.debug('Invalid IP address for "ifaddr": %s', ifaddr)
        return None

    return intf
Esempio n. 21
0
def ip_route_add(session, destination, device=None, gateway='', source='',
                 ifindex=0, route_type=zebra.ZEBRA_ROUTE_KERNEL,
                 is_selected=True):
    """
    Adds a route record into Zebra protocol service database.

    The arguments are similar to "ip route add" command of iproute2.

    If "is_selected=True", disables the existing selected route for the
    given destination.

    :param session: Session instance connecting to database.
    :param destination: Destination prefix.
    :param device: Source device.
    :param gateway: Gateway IP address.
    :param source: Source IP address.
    :param ifindex: Index of source device.
    :param route_type: Route type of daemon (or kernel).
    :param is_selected: If select the given route as "in use" or not.
    :return: Instance of record or "None" if failed.
    """
    if device:
        intf = interface.ip_link_show(session, ifname=device)
        if not intf:
            LOG.debug('Interface "%s" does not exist', device)
            return None
        ifindex = ifindex or intf.ifindex

        route = ip_route_show(session, destination=destination, device=device)
        if route:
            LOG.debug(
                'Route to "%s" already exists on "%s" device',
                destination, device)
            return route

    dest_addr, dest_prefix_num = destination.split('/')
    dest_prefix_num = int(dest_prefix_num)
    if ip.valid_ipv4(dest_addr) and 0 <= dest_prefix_num <= 32:
        family = socket.AF_INET
    elif ip.valid_ipv6(dest_addr) and 0 <= dest_prefix_num <= 128:
        family = socket.AF_INET6
    else:
        LOG.debug('Invalid IP address for "prefix": %s', destination)
        return None
    safi = packet_safi.UNICAST

    if is_selected:
        old_routes = ip_route_show_all(
            session, destination=destination, is_selected=True)
        for old_route in old_routes:
            if old_route:
                LOG.debug('Set existing route to unselected: %s', old_route)
                old_route.is_selected = False

    new_route = Route(
        family=family,
        safi=safi,
        destination=destination,
        gateway=gateway,
        ifindex=ifindex,
        source=source,
        route_type=route_type,
        is_selected=is_selected)

    session.add(new_route)

    return new_route
Esempio n. 22
0
 def __init__(self, addr, timeout=None, **ssl_args):
     assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0])
     self.addr = addr
     self.timeout = timeout
     self.ssl_args = ssl_args
     self._is_active = True
Esempio n. 23
0
def valid_ip_address(addr):
    if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
        return False
    return True
Esempio n. 24
0
def valid_ip_address(addr):
    if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
        return False
    return True
Esempio n. 25
0
def ip_route_add(session,
                 destination,
                 device=None,
                 gateway='',
                 source='',
                 ifindex=0,
                 route_type=zebra.ZEBRA_ROUTE_KERNEL,
                 is_selected=True):
    """
    Adds a route record into Zebra protocol service database.

    The arguments are similar to "ip route add" command of iproute2.

    If "is_selected=True", disables the existing selected route for the
    given destination.

    :param session: Session instance connecting to database.
    :param destination: Destination prefix.
    :param device: Source device.
    :param gateway: Gateway IP address.
    :param source: Source IP address.
    :param ifindex: Index of source device.
    :param route_type: Route type of daemon (or kernel).
    :param is_selected: If select the given route as "in use" or not.
    :return: Instance of record or "None" if failed.
    """
    if device:
        intf = interface.ip_link_show(session, ifname=device)
        if not intf:
            LOG.debug('Interface "%s" does not exist', device)
            return None
        ifindex = ifindex or intf.ifindex

        route = ip_route_show(session, destination=destination, device=device)
        if route:
            LOG.debug('Route to "%s" already exists on "%s" device',
                      destination, device)
            return route

    dest_addr, dest_prefix_num = destination.split('/')
    dest_prefix_num = int(dest_prefix_num)
    if ip.valid_ipv4(dest_addr) and 0 <= dest_prefix_num <= 32:
        family = socket.AF_INET
    elif ip.valid_ipv6(dest_addr) and 0 <= dest_prefix_num <= 128:
        family = socket.AF_INET6
    else:
        LOG.debug('Invalid IP address for "prefix": %s', destination)
        return None
    safi = packet_safi.UNICAST

    if is_selected:
        old_routes = ip_route_show_all(session,
                                       destination=destination,
                                       is_selected=True)
        for old_route in old_routes:
            if old_route:
                LOG.debug('Set existing route to unselected: %s', old_route)
                old_route.is_selected = False

    new_route = Route(family=family,
                      safi=safi,
                      destination=destination,
                      gateway=gateway,
                      ifindex=ifindex,
                      source=source,
                      route_type=route_type,
                      is_selected=is_selected)

    session.add(new_route)

    return new_route
Esempio n. 26
0
 def __init__(self, addr, timeout=None, **ssl_args):
     assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0])
     self.addr = addr
     self.timeout = timeout
     self.ssl_args = ssl_args
     self._is_active = True
def is_valid_ipv6(ipv6):
    """Returns True if given `ipv6` is a valid IPv6 address
    """
    return ip.valid_ipv6(ipv6)