def validate_router_id(cluster_id): if not isinstance(cluster_id, str): raise ConfigTypeError(conf_name=CLUSTER_ID) if not is_valid_ipv4(cluster_id): raise ConfigValueError(desc='Invalid cluster id %s' % cluster_id) return cluster_id
def validate_rpc_host(ip): """ Validates the given ip for use as RPC server address. """ if not is_valid_ipv4(ip) and not is_valid_ipv6(ip): raise ApplicationException( desc='Invalid RPC ip address: %s' % ip) return ip
def is_valid_ip_addr(addr): # Note: Allows empty IP Address (means length=0). # e.g.) L2VPN MAC advertisement of Cisco NX-OS if not (addr is None or validation.is_valid_ipv4(addr) or validation.is_valid_ipv6(addr)): raise ConfigValueError(conf_name=IP_ADDR, conf_value=addr)
def ipv4_mapped_ipv6(ipv4): if not is_valid_ipv4(ipv4): raise ValueError('Invalid ipv4 address given %s.' % ipv4) ipv4n = socket.inet_pton(socket.AF_INET, ipv4) ipv6_hex = '00' * 10 + 'ff' * 2 + bytes2hex(ipv4n) ipv6n = hex2byte(ipv6_hex) ipv6 = socket.inet_ntop(socket.AF_INET6, ipv6n) return ipv6
def validate_router_id(router_id): if not router_id: raise MissingRequiredConf(conf_name=ROUTER_ID) if not isinstance(router_id, str): raise ConfigTypeError(conf_name=ROUTER_ID) if not is_valid_ipv4(router_id): raise ConfigValueError(desc='Invalid router id %s' % router_id) return router_id
def from_bytes(cls, recv_bytes, total_msg_len): # Validate OPEN message length. if len(recv_bytes) < 10: raise BadLen(Open.TYPE_CODE, len(recv_bytes) + cls.HEADER_SIZE) version, asnum, holdtime, bgpid, paramlen = \ struct.unpack_from('!BHH4sB', recv_bytes) if len(recv_bytes) != (10 + paramlen): # TODO(PH): Check what RFC says to do here. LOG.debug('Open message: too short.') offset = 10 # BGP implementation MUST reject Hold Time values of one or two # seconds. if holdtime <= 2: raise UnacceptableHoldTime() # BGP Identifier field MUST represents a valid unicast IP host address. bgpid = socket.inet_ntoa(bgpid) if not is_valid_ipv4(bgpid): raise BadBgpId() # Parse optional parameters. caps = OrderedDict() unrec_params = OrderedDict() while offset < len(recv_bytes): ptype, plen = struct.unpack_from('BB', recv_bytes, offset) offset += 2 value = recv_bytes[offset:offset + plen] offset += plen # Parse capabilities optional parameter. if ptype == CAP_OPT_PARA_TYPE: bgp_caps = capabilities.decode(value) # store decoded bgp capabilities by their capability-code for cap in bgp_caps: cap_code = cap.CODE if cap_code in caps: caps[cap_code].append(cap) else: caps[cap_code] = [cap] else: # Other unrecognized optional parameters. unrec_params[ptype] = value # Un-recognized capabilities are passed on, its up to application to # check if unrec-optional-paramters are a problem and send NOTIFICATION return cls(version, asnum, holdtime, bgpid, caps, unrec_params)
def add_to_vrf(self, route_dist, prefix, next_hop, route_family): """Adds `prefix` to VRF identified by `route_dist` with given `next_hop`. Returns assigned VPN label. """ from ryu.services.protocols.bgp.core import BgpCoreError assert route_dist and prefix and next_hop if route_family not in (VRF_RF_IPV4, VRF_RF_IPV6): raise ValueError('Given route_family %s is not supported.' % route_family) vrf_table = None table_id = (route_dist, route_family) if route_family == VRF_RF_IPV4: vrf_table = self._tables.get(table_id) if vrf_table is None: raise BgpCoreError(desc='VRF table for RD: %s does not ' 'exist.' % route_dist) if not is_valid_ipv4_prefix(prefix) or not is_valid_ipv4(next_hop): raise BgpCoreError(desc='Invalid Ipv4 prefix or nexthop.') ip, masklen = prefix.split('/') prefix = IPAddrPrefix(int(masklen), ip) elif route_family == VRF_RF_IPV6: vrf_table = self._tables.get(table_id) if vrf_table is None: raise BgpCoreError(desc='VRF table for RD: %s does not ' 'exist.' % route_dist) if not is_valid_ipv6_prefix(prefix) or not is_valid_ipv6(next_hop): raise BgpCoreError(desc='Invalid Ipv6 prefix or nexthop.') ip6, masklen = prefix.split('/') prefix = IP6AddrPrefix(int(masklen), ip6) return vrf_table.insert_vrf_path( prefix, next_hop=next_hop, gen_lbl=True )
def __init__(self, route_family, next_hop, nlri_list, reserved=None): if not (hasattr(route_family, 'afi') and hasattr(route_family, 'safi')): raise ValueError('Invalid parameter value for route_family %s.' % route_family) if not next_hop: raise ValueError('Invalid next_hop %s' % next_hop) # MpReachNlri attribute should have next-hop belonging to same # route-family if ((route_family == RF_IPv4_VPN and not is_valid_ipv4(next_hop)) or (route_family == RF_IPv6_VPN and not is_valid_ipv6(next_hop))): raise ValueError('Next hop should belong to %s route family' % route_family) if not nlri_list: nlri_list = [] RcgPathAttr.__init__(self) self._route_family = route_family self._next_hop = next_hop self._nlri_list = nlri_list self._reserved = reserved
def __init__(self, version, asnum, holdtime, bgpid, caps, unrec_params=None): # Validate arguments. if version < 1: raise ValueError('Invalid version number %s' % version) if not is_valid_old_asn(asnum): raise ValueError('Invalid AS number %s' % asnum) if holdtime <= 2: raise ValueError('Holdtime has to be greater than 2 sec.') if not caps: raise ValueError('Invalid capabilities.') if not is_valid_ipv4(bgpid): raise ValueError('Invalid bgp ID, should be valid IPv4, ' 'but given %s' % bgpid) BgpMessage.__init__(self) self._version = version self._holdtime = holdtime self._asnum = asnum self._bgpid = bgpid self._caps = caps self._unrec_params = unrec_params if not unrec_params: self._unrec_params = OrderedDict()
def is_valid_gw_ip_addr(addr): if not (validation.is_valid_ipv4(addr) or validation.is_valid_ipv6(addr)): raise ConfigValueError(conf_name=GW_IP_ADDR, conf_value=addr)
def is_valid_next_hop(next_hop): if not (validation.is_valid_ipv4(next_hop) or validation.is_valid_ipv6(next_hop)): raise ConfigValueError(conf_name=NEXT_HOP, conf_value=next_hop)
def is_valid_next_hop(next_hop_addr): return validation.is_valid_ipv4(next_hop_addr)
def test_is_valid_ipv4(self): ok_(validation.is_valid_ipv4('10.0.0.1'))
def __init__(self, ip_address): if not is_valid_ipv4(ip_address): raise ValueError('Invalid ipv4 address %s.' % ip_address) RcgPathAttr.__init__(self) self._ip_address = ip_address
def validate_rpc_ip(cls, ip): """Validates given ip for use as rpc host bind address. """ if not is_valid_ipv4(ip): raise ApplicationException(desc='Invalid rpc ip address.') return ip
def _validate_rpc_ip(rpc_server_ip): """Validates given ip for use as rpc host bind address. """ if not is_valid_ipv4(rpc_server_ip): raise NetworkControllerError(desc='Invalid rpc ip address.') return rpc_server_ip
def update_vrf_table(self, route_dist, prefix=None, next_hop=None, route_family=None, route_type=None, tunnel_type=None, is_withdraw=False, **kwargs): """Update a BGP route in the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is False, which is the default, add a BGP route to the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is True, remove a BGP route from the VRF table and the given `next_hop` is ignored. If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs` are required to construct EVPN NLRI and `prefix` is ignored. Returns assigned VPN label. """ from ryu.services.protocols.bgp.core import BgpCoreError assert route_dist if is_withdraw: gen_lbl = False next_hop = None else: gen_lbl = True if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)): raise BgpCoreError(desc='Invalid IPv4/IPv6 nexthop: %s' % next_hop) vrf_table = self._tables.get((route_dist, route_family)) if vrf_table is None: raise BgpCoreError( desc='VRF table does not exist: route_dist=%s, ' 'route_family=%s' % (route_dist, route_family)) if route_family == VRF_RF_IPV4: if not is_valid_ipv4_prefix(prefix): raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix) ip, masklen = prefix.split('/') prefix = IPAddrPrefix(int(masklen), ip) elif route_family == VRF_RF_IPV6: if not is_valid_ipv6_prefix(prefix): raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix) ip6, masklen = prefix.split('/') prefix = IP6AddrPrefix(int(masklen), ip6) elif route_family == VRF_RF_L2_EVPN: assert route_type if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME: # MPLS labels will be assigned automatically kwargs['mpls_labels'] = [] subclass = EvpnNLRI._lookup_type_name(route_type) kwargs['route_dist'] = route_dist esi = kwargs.get('esi', None) if esi is not None: # Note: Currently, we support arbitrary 9-octet ESI value only. kwargs['esi'] = EvpnArbitraryEsi(type_desc.Int9.from_user(esi)) if 'vni' in kwargs: # Disable to generate MPLS labels, because encapsulation type # is not MPLS. from ryu.services.protocols.bgp.api.prefix import ( TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE) assert tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE] gen_lbl = False prefix = subclass(**kwargs) else: raise BgpCoreError(desc='Unsupported route family %s' % route_family) # We do not check if we have a path to given prefix, we issue # withdrawal. Hence multiple withdrawals have not side effect. return vrf_table.insert_vrf_path(nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl, is_withdraw=is_withdraw, tunnel_type=tunnel_type)
def test_is_valid_ipv4(self): ok_(validation.is_valid_ipv4("10.0.0.1"))
def validate_local_address(ip_address): if not is_valid_ipv4(ip_address): raise ConfigValueError(desc='Invalid local ip_address: %s' % ip_address) return ip_address
def test_is_valid_ipv4_not_dot(self): eq_(False, validation.is_valid_ipv4("192:168:0:1"))
def update_vrf_table(self, route_dist, prefix=None, next_hop=None, route_family=None, route_type=None, tunnel_type=None, is_withdraw=False, redundancy_mode=None, pmsi_tunnel_type=None, **kwargs): """Update a BGP route in the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is False, which is the default, add a BGP route to the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is True, remove a BGP route from the VRF table and the given `next_hop` is ignored. If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs` are required to construct EVPN NLRI and `prefix` is ignored. ``redundancy_mode`` specifies a redundancy mode type. ` `pmsi_tunnel_type` specifies the type of the PMSI tunnel attribute used to encode the multicast tunnel identifier. This field is advertised only if route_type is EVPN_MULTICAST_ETAG_ROUTE. Returns assigned VPN label. """ from ryu.services.protocols.bgp.core import BgpCoreError assert route_dist if is_withdraw: gen_lbl = False next_hop = None else: gen_lbl = True if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)): raise BgpCoreError(desc='Invalid IPv4/IPv6 nexthop: %s' % next_hop) vrf_table = self._tables.get((route_dist, route_family)) if vrf_table is None: raise BgpCoreError( desc='VRF table does not exist: route_dist=%s, ' 'route_family=%s' % (route_dist, route_family)) vni = kwargs.get('vni', None) if route_family == VRF_RF_IPV4: if not is_valid_ipv4_prefix(prefix): raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix) ip, masklen = prefix.split('/') prefix = IPAddrPrefix(int(masklen), ip) elif route_family == VRF_RF_IPV6: if not is_valid_ipv6_prefix(prefix): raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix) ip6, masklen = prefix.split('/') prefix = IP6AddrPrefix(int(masklen), ip6) elif route_family == VRF_RF_L2_EVPN: assert route_type if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME: # MPLS labels will be assigned automatically kwargs['mpls_labels'] = [] if route_type == EvpnInclusiveMulticastEthernetTagNLRI.ROUTE_TYPE_NAME: # Inclusive Multicast Ethernet Tag Route does not have "vni", # omit "vni" from "kwargs" here. vni = kwargs.pop('vni', None) subclass = EvpnNLRI._lookup_type_name(route_type) kwargs['route_dist'] = route_dist esi = kwargs.get('esi', None) if esi is not None: if isinstance(esi, dict): esi_type = esi.get('type', 0) esi_class = EvpnEsi._lookup_type(esi_type) kwargs['esi'] = esi_class.from_jsondict(esi) else: # isinstance(esi, numbers.Integral) kwargs['esi'] = EvpnArbitraryEsi( type_desc.Int9.from_user(esi)) if vni is not None: # Disable to generate MPLS labels, # because encapsulation type is not MPLS. from ryu.services.protocols.bgp.api.prefix import ( TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE) assert tunnel_type in [ None, TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE ] gen_lbl = False prefix = subclass(**kwargs) else: raise BgpCoreError(desc='Unsupported route family %s' % route_family) # We do not check if we have a path to given prefix, we issue # withdrawal. Hence multiple withdrawals have not side effect. return vrf_table.insert_vrf_path(nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl, is_withdraw=is_withdraw, redundancy_mode=redundancy_mode, vni=vni, tunnel_type=tunnel_type, pmsi_tunnel_type=pmsi_tunnel_type)
def update_vrf_table(self, route_dist, prefix=None, next_hop=None, route_family=None, route_type=None, tunnel_type=None, is_withdraw=False, **kwargs): """Update a BGP route in the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is False, which is the default, add a BGP route to the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is True, remove a BGP route from the VRF table and the given `next_hop` is ignored. If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs` are required to construct EVPN NLRI and `prefix` is ignored. Returns assigned VPN label. """ from ryu.services.protocols.bgp.core import BgpCoreError assert route_dist if is_withdraw: gen_lbl = False next_hop = None else: gen_lbl = True if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)): raise BgpCoreError( desc='Invalid IPv4/IPv6 nexthop: %s' % next_hop) vrf_table = self._tables.get((route_dist, route_family)) if vrf_table is None: raise BgpCoreError( desc='VRF table does not exist: route_dist=%s, ' 'route_family=%s' % (route_dist, route_family)) if route_family == VRF_RF_IPV4: if not is_valid_ipv4_prefix(prefix): raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix) ip, masklen = prefix.split('/') prefix = IPAddrPrefix(int(masklen), ip) elif route_family == VRF_RF_IPV6: if not is_valid_ipv6_prefix(prefix): raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix) ip6, masklen = prefix.split('/') prefix = IP6AddrPrefix(int(masklen), ip6) elif route_family == VRF_RF_L2_EVPN: assert route_type if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME: # MPLS labels will be assigned automatically kwargs['mpls_labels'] = [] subclass = EvpnNLRI._lookup_type_name(route_type) kwargs['route_dist'] = route_dist esi = kwargs.get('esi', None) if esi is not None: # Note: Currently, we support arbitrary 9-octet ESI value only. kwargs['esi'] = EvpnArbitraryEsi(type_desc.Int9.from_user(esi)) if 'vni' in kwargs: # Disable to generate MPLS labels, because encapsulation type # is not MPLS. from ryu.services.protocols.bgp.api.prefix import ( TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE) assert tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE] gen_lbl = False prefix = subclass(**kwargs) else: raise BgpCoreError( desc='Unsupported route family %s' % route_family) # We do not check if we have a path to given prefix, we issue # withdrawal. Hence multiple withdrawals have not side effect. return vrf_table.insert_vrf_path( nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl, is_withdraw=is_withdraw, tunnel_type=tunnel_type)
def test_is_valid_ipv4_not_dot(self): eq_(False, validation.is_valid_ipv4('192:168:0:1'))
def update_vrf_table(self, route_dist, prefix=None, next_hop=None, route_family=None, route_type=None, tunnel_type=None, is_withdraw=False, redundancy_mode=None, pmsi_tunnel_type=None, **kwargs): """Update a BGP route in the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is False, which is the default, add a BGP route to the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is True, remove a BGP route from the VRF table and the given `next_hop` is ignored. If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs` are required to construct EVPN NLRI and `prefix` is ignored. ``redundancy_mode`` specifies a redundancy mode type. ` `pmsi_tunnel_type` specifies the type of the PMSI tunnel attribute used to encode the multicast tunnel identifier. This field is advertised only if route_type is EVPN_MULTICAST_ETAG_ROUTE. Returns assigned VPN label. """ from ryu.services.protocols.bgp.core import BgpCoreError assert route_dist if is_withdraw: gen_lbl = False next_hop = None else: gen_lbl = True if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)): raise BgpCoreError( desc='Invalid IPv4/IPv6 nexthop: %s' % next_hop) vrf_table = self._tables.get((route_dist, route_family)) if vrf_table is None: raise BgpCoreError( desc='VRF table does not exist: route_dist=%s, ' 'route_family=%s' % (route_dist, route_family)) vni = kwargs.get('vni', None) if route_family == VRF_RF_IPV4: if not is_valid_ipv4_prefix(prefix): raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix) ip, masklen = prefix.split('/') prefix = IPAddrPrefix(int(masklen), ip) elif route_family == VRF_RF_IPV6: if not is_valid_ipv6_prefix(prefix): raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix) ip6, masklen = prefix.split('/') prefix = IP6AddrPrefix(int(masklen), ip6) elif route_family == VRF_RF_L2_EVPN: assert route_type if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME: # MPLS labels will be assigned automatically kwargs['mpls_labels'] = [] subclass = EvpnNLRI._lookup_type_name(route_type) kwargs['route_dist'] = route_dist esi = kwargs.get('esi', None) if esi is not None: if isinstance(esi, dict): esi_type = esi.get('type', 0) esi_class = EvpnEsi._lookup_type(esi_type) kwargs['esi'] = esi_class.from_jsondict(esi) else: # isinstance(esi, numbers.Integral) kwargs['esi'] = EvpnArbitraryEsi( type_desc.Int9.from_user(esi)) if vni is not None: # Disable to generate MPLS labels, # because encapsulation type is not MPLS. from ryu.services.protocols.bgp.api.prefix import ( TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE) assert tunnel_type in [ None, TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE] gen_lbl = False prefix = subclass(**kwargs) else: raise BgpCoreError( desc='Unsupported route family %s' % route_family) # We do not check if we have a path to given prefix, we issue # withdrawal. Hence multiple withdrawals have not side effect. return vrf_table.insert_vrf_path( nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl, is_withdraw=is_withdraw, redundancy_mode=redundancy_mode, vni=vni, tunnel_type=tunnel_type, pmsi_tunnel_type=pmsi_tunnel_type)