def validate_route_target(cls, route_target_name, global_asn=None): ok, result = cls._parse_route_target_name(route_target_name) if not ok: return False, result, None asn, target = result if not global_asn: try: global_asn = cls.server.global_autonomous_system except VncError as e: return False, (400, str(e)), None if type(asn) == int: ok, result = cls.server.get_resource_class( 'global_system_config').check_asn_range(asn) if not ok: return ok, result, None ret_val = "target:" + str(asn) + ":" + str(target) # If the ASN of Route Target matches Global ASN, we need to check # for its target range. The target should not clash with contrail # RT target reserved space as detailed below if asn == global_asn: global_4byte_flag = cls.server.enable_4byte_as if global_4byte_flag: # Case when 4 byte ASN flag is set # Target should be # 1. 1 <= target < _BGP_RTGT_MIN_ID_TYPE1_2 # 2. _BGP_RTGT_MAX_ID_TYPE1_2 < target <= 0xFFFF # This is because contrail allocates RT targets in the range of # 8000-32768 if ((1 <= target < get_bgp_rtgt_min_id(asn)) or (get_bgp_rtgt_max_id(asn) < target <= 0xFFFF)): return True, True, ret_val else: return True, False, ret_val else: # Case when 2 byte ASN flag is set # Target should be: # 1. 1 <= target < _BGP_RTGT_MIN_ID_TYPE0 # 2. _BGP_RTGT_MAX_ID_TYPE0 < target <= 0xFFFFFFFF if ((1 <= target < get_bgp_rtgt_min_id(asn)) or (get_bgp_rtgt_max_id(asn) < target <= 0xFFFFFFFF)): return True, True, ret_val else: return True, False, ret_val return True, True, ret_val
def _check_route_targets(cls, obj_dict): rt_dict = obj_dict.get('configured_route_target_list') if not rt_dict: return True, '' route_target_list = rt_dict.get('route_target') if not route_target_list: return True, '' global_asn = cls.server.global_autonomous_system for idx, rt in enumerate(route_target_list): ok, result, new_rt = cls.server.get_resource_class( 'route_target').validate_route_target(rt) if not ok: return False, result user_defined_rt = result if not user_defined_rt: return (False, "Configured route target must use ASN that is " "different from global ASN or route target value must" " be less than %d and greater than %d" % (get_bgp_rtgt_min_id(global_asn), get_bgp_rtgt_max_id(global_asn))) if new_rt: route_target_list[idx] = new_rt return (True, '')
def test_route_target_is_in_system_range(self): # RT name, global ASN, expected result tested_values = [ ('target:1:1', 42, True), ('target:42:1', 42, True), # We now allow suffix 'L' for an ASN ('target:40L:10', 42, True), # Don't allow target value to be greater than 0xFFFF # when ASN is appended with 'L' ('target:40L:70000', 42, False), # Test with same ASN as global ASN(42). But target value # being greater than get_bgp_rtgt_min_id ('target:42:%d' % (get_bgp_rtgt_min_id(42) + 1000), 42, False), # Test with same ASN as global ASN(42). But target value # being greater than get_bgp_rtgt_max_id ('target:42:%d' % (get_bgp_rtgt_max_id(42) + 1000), 42, True), # Test with ASN different from global ASN(42). # Target value can be either greater than get_bgp_rtgt_max_id # or greater than get_bgp_rtgt_max_id ('target:40:%d' % (get_bgp_rtgt_min_id(42) + 1000), 42, True), ('target:40:%d' % (get_bgp_rtgt_max_id(42) + 1000), 42, True) ] for rt_name, global_asn, expected_result in tested_values: ok, result, _ = RouteTargetServer.validate_route_target( rt_name, global_asn) if not ok: self.assertEqual( ok, expected_result, "For rt_name: %s, expected result is %s" % (rt_name, expected_result)) else: self.assertEqual( result, expected_result, "Route target: %s and global ASN: %d" % (rt_name, global_asn))