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
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 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
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
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
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
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 _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 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
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)
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)
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
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)
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
def valid_ip_address(addr): if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr): return False return True
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 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
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