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
Beispiel #2
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)
Beispiel #3
0
def create_rt_extended_community(value, subtype=2):
    """
    Creates an instance of the BGP Route Target Community (if "subtype=2")
    or Route Origin Community ("subtype=3").

    :param value: String of Route Target or Route Origin value.
    :param subtype: Subtype of Extended Community.
    :return: An instance of Route Target or Route Origin Community.
    """
    global_admin, local_admin = value.split(':')
    local_admin = int(local_admin)
    if global_admin.isdigit() and 0 <= int(global_admin) <= 0xffff:
        ext_com = BGPTwoOctetAsSpecificExtendedCommunity(
            subtype=subtype,
            as_number=int(global_admin),
            local_administrator=local_admin)
    elif global_admin.isdigit() and 0xffff < int(global_admin) <= 0xffffffff:
        ext_com = BGPFourOctetAsSpecificExtendedCommunity(
            subtype=subtype,
            as_number=int(global_admin),
            local_administrator=local_admin)
    elif ip.valid_ipv4(global_admin):
        ext_com = BGPIPv4AddressSpecificExtendedCommunity(
            subtype=subtype,
            ipv4_address=global_admin,
            local_administrator=local_admin)
    else:
        raise ValueError(
            'Invalid Route Target or Route Origin value: %s' % value)

    return ext_com
Beispiel #4
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)
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
Beispiel #6
0
def create_rt_extended_community(value, subtype=2):
    """
    Creates an instance of the BGP Route Target Community (if "subtype=2")
    or Route Origin Community ("subtype=3").

    :param value: String of Route Target or Route Origin value.
    :param subtype: Subtype of Extended Community.
    :return: An instance of Route Target or Route Origin Community.
    """
    global_admin, local_admin = value.split(':')
    local_admin = int(local_admin)
    if global_admin.isdigit() and 0 <= int(global_admin) <= 0xffff:
        ext_com = BGPTwoOctetAsSpecificExtendedCommunity(
            subtype=subtype,
            as_number=int(global_admin),
            local_administrator=local_admin)
    elif global_admin.isdigit() and 0xffff < int(global_admin) <= 0xffffffff:
        ext_com = BGPFourOctetAsSpecificExtendedCommunity(
            subtype=subtype,
            as_number=int(global_admin),
            local_administrator=local_admin)
    elif ip.valid_ipv4(global_admin):
        ext_com = BGPIPv4AddressSpecificExtendedCommunity(
            subtype=subtype,
            ipv4_address=global_admin,
            local_administrator=local_admin)
    else:
        raise ValueError('Invalid Route Target or Route Origin value: %s' %
                         value)

    return ext_com
Beispiel #7
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)
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)
    def _connect_tcp(self, peer_addr, conn_handler, time_out=None,
                     bind_address=None, password=None):
        """Creates a TCP connection to given peer address.

        Tries to create a socket for `timeout` number of seconds. If
        successful, uses the socket instance to start `client_factory`.
        The socket is bound to `bind_address` if specified.
        """
        LOG.debug('Connect TCP called for %s:%s', peer_addr[0], peer_addr[1])
        if ip.valid_ipv4(peer_addr[0]):
            family = socket.AF_INET
        else:
            family = socket.AF_INET6
        with Timeout(time_out, socket.error):
            sock = socket.socket(family)
            if bind_address:
                sock.bind(bind_address)
            if password:
                sockopt.set_tcp_md5sig(sock, peer_addr[0], password)
            sock.connect(peer_addr)
            # socket.error exception is raised in case of timeout and
            # the following code is executed only when the connection
            # is established.

        # Connection name for pro-active connection is made up of
        # local end address + remote end address
        local = self.get_localname(sock)[0]
        remote = self.get_remotename(sock)[0]
        conn_name = ('L: ' + local + ', R: ' + remote)
        self._asso_socket_map[conn_name] = sock
        # If connection is established, we call connection handler
        # in a new thread.
        self._spawn(conn_name, conn_handler, sock)
        return sock
Beispiel #10
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)
Beispiel #11
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
Beispiel #12
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
Beispiel #13
0
    def _set_password(self, address, password):
        if ip.valid_ipv4(address):
            family = socket.AF_INET
        else:
            family = socket.AF_INET6

        for sock in self.listen_sockets.values():
            if sock.family == family:
                sockopt.set_tcp_md5sig(sock, address, password)
Beispiel #14
0
    def _set_password(self, address, password):
        if ip.valid_ipv4(address):
            family = socket.AF_INET
        else:
            family = socket.AF_INET6

        for sock in self.listen_sockets.values():
            if sock.family == family:
                sockopt.set_tcp_md5sig(sock, address, password)
Beispiel #15
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
def is_valid_ipv4(ipv4):
    """Returns True if given is a valid ipv4 address.

    Given value should be a dot-decimal notation string.

    Samples:
        - valid address: 10.0.0.1, 192.168.0.1
        - invalid address: 11.0.0, 192:168:0:1, etc.
    """
    return ip.valid_ipv4(ipv4)
Beispiel #17
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
Beispiel #18
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
    def update_global_table(self, prefix, next_hop=None, is_withdraw=False):
        """Update a BGP route in the Global table for the given `prefix`
        with the given `next_hop`.

        If `is_withdraw` is False, which is the default, add a BGP route
        to the Global table.
        If `is_withdraw` is True, remove a BGP route from the Global table.
        """
        src_ver_num = 1
        peer = None
        # set mandatory path attributes
        origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP)
        aspath = BGPPathAttributeAsPath([[]])

        pathattrs = OrderedDict()
        pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin
        pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath

        net = netaddr.IPNetwork(prefix)
        addr = str(net.ip)
        masklen = net.prefixlen
        if ip.valid_ipv4(addr):
            _nlri = IPAddrPrefix(masklen, addr)
            if next_hop is None:
                next_hop = '0.0.0.0'
            p = Ipv4Path
        else:
            _nlri = IP6AddrPrefix(masklen, addr)
            if next_hop is None:
                next_hop = '::'
            p = Ipv6Path

        new_path = p(peer,
                     _nlri,
                     src_ver_num,
                     pattrs=pathattrs,
                     nexthop=next_hop,
                     is_withdraw=is_withdraw)

        # add to global table and propagates to neighbors
        self.learn_path(new_path)
Beispiel #20
0
    def update_global_table(self, prefix, next_hop=None, is_withdraw=False):
        """Update a BGP route in the Global table for the given `prefix`
        with the given `next_hop`.

        If `is_withdraw` is False, which is the default, add a BGP route
        to the Global table.
        If `is_withdraw` is True, remove a BGP route from the Global table.
        """
        src_ver_num = 1
        peer = None
        # set mandatory path attributes
        origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP)
        aspath = BGPPathAttributeAsPath([[]])

        pathattrs = OrderedDict()
        pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin
        pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath

        net = netaddr.IPNetwork(prefix)
        addr = str(net.ip)
        masklen = net.prefixlen
        if ip.valid_ipv4(addr):
            _nlri = IPAddrPrefix(masklen, addr)
            if next_hop is None:
                next_hop = '0.0.0.0'
            p = Ipv4Path
        else:
            _nlri = IP6AddrPrefix(masklen, addr)
            if next_hop is None:
                next_hop = '::'
            p = Ipv6Path

        new_path = p(peer, _nlri, src_ver_num,
                     pattrs=pathattrs, nexthop=next_hop,
                     is_withdraw=is_withdraw)

        # add to global table and propagates to neighbors
        self.learn_path(new_path)
Beispiel #21
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
Beispiel #22
0
def valid_ip_address(addr):
    if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
        return False
    return True
Beispiel #23
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
Beispiel #24
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
Beispiel #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
Beispiel #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
Beispiel #27
0
def valid_ip_address(addr):
    if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
        return False
    return True