def GenerateObjects(self, node, parent, vpc_spec_obj): if not self.__supported: return vpcid = parent.VPCId isV4Stack = utils.IsV4Stack(parent.Stack) isV6Stack = utils.IsV6Stack(parent.Stack) self.__v4objs[node][vpcid] = [] self.__v6objs[node][vpcid] = [] self.__v4iter[node][vpcid] = None self.__v6iter[node][vpcid] = None nhg_spec = getattr(vpc_spec_obj, 'nexthop-group', None) if nhg_spec == None: self.__num_nhgs_per_vpc.append(0) return for nhg_spec_obj in nhg_spec: for c in range(nhg_spec_obj.count): obj = NexthopGroupObject(node, parent, nhg_spec_obj) self.Objs[node].update({obj.Id: obj}) if isV4Stack: self.__v4objs[node][vpcid].append(obj) if isV6Stack: self.__v6objs[node][vpcid].append(obj) if len(self.__v4objs[node][vpcid]): self.__v4iter[node][vpcid] = utils.rrobiniter( self.__v4objs[node][vpcid]) if len(self.__v6objs[node][vpcid]): self.__v6iter[node][vpcid] = utils.rrobiniter( self.__v6objs[node][vpcid]) self.__num_nhgs_per_vpc.append(nhg_spec_obj.count) return
def GenerateObjects(self, node, parent, vpc_spec_obj): if not self.__supported: return def __isNhFeatureSupported(nh_type): if nh_type == 'underlay' or nh_type == 'overlay': return utils.IsPipelineApulu() return not utils.IsPipelineApulu() vpcid = parent.VPCId isV4Stack = utils.IsV4Stack(parent.Stack) isV6Stack = utils.IsV6Stack(parent.Stack) self.__v4objs[node][vpcid] = [] self.__v6objs[node][vpcid] = [] self.__v4iter[node][vpcid] = None self.__v6iter[node][vpcid] = None if getattr(vpc_spec_obj, 'nexthop', None) == None: self.__num_nh_per_vpc.append(0) return for nh_spec_obj in vpc_spec_obj.nexthop: nh_type = getattr(nh_spec_obj, 'type', 'ip') if not __isNhFeatureSupported(nh_type): continue for c in range(nh_spec_obj.count): obj = NexthopObject(node, parent, nh_spec_obj) self.Objs[node].update({obj.NexthopId: obj}) if nh_type == "underlay": self.__underlay_objs[node].update({obj.NexthopId: obj}) if isV4Stack: self.__v4objs[node][vpcid].append(obj) if isV6Stack: self.__v6objs[node][vpcid].append(obj) if len(self.__v4objs[node][vpcid]): self.__v4iter[node][vpcid] = utils.rrobiniter( self.__v4objs[node][vpcid]) if len(self.__v6objs[node][vpcid]): self.__v6iter[node][vpcid] = utils.rrobiniter( self.__v6objs[node][vpcid]) self.__num_nh_per_vpc.append(nh_spec_obj.count) return
def GenerateObjects(self, node, parent, subnet_spec_obj): if getattr(subnet_spec_obj, 'rmap', None) == None: return isV4Stack = utils.IsV4Stack(parent.VPC.Stack) isV6Stack = utils.IsV6Stack(parent.VPC.Stack) for rmap_spec_obj in subnet_spec_obj.rmap: if utils.IsPipelineApulu(): if hasattr(rmap_spec_obj, 'tunneltype'): if rmap_spec_obj.tunneltype == "ipsec-tunnel": tunnelAllocator = ResmgrClient[ node].IpsecTunnelModeTunAllocator elif rmap_spec_obj.tunneltype == "ipsec-transport": tunnelAllocator = ResmgrClient[ node].IpsecTransportModeTunAllocator else: assert (0) elif getattr(rmap_spec_obj, 'dual-ecmp', None) == None: tunnelAllocator = ResmgrClient[node].UnderlayTunAllocator else: tunnelAllocator = ResmgrClient[ node].UnderlayECMPTunAllocator else: tunnelAllocator = ResmgrClient[node].RemoteMplsVnicTunAllocator l2 = getattr(rmap_spec_obj, "l2", False) c = 0 v6c = 0 v4c = 0 while c < rmap_spec_obj.count: if isV6Stack: self.GenerateObj(node, parent, rmap_spec_obj.__dict__, \ utils.IP_VERSION_6, v6c, False) v6c = v6c + 1 if c < rmap_spec_obj.count and isV4Stack: self.GenerateObj(node, parent, rmap_spec_obj.__dict__, \ utils.IP_VERSION_4, v4c, False) c = c + 1 v4c = v4c + 1 if l2: self.GenerateObj(node, parent, rmap_spec_obj.__dict__, \ utils.IP_VERSION_4, v4c, True) return
def GenerateObjects(self, node, parent, vnic_spec_obj): isV4Stack = utils.IsV4Stack(parent.SUBNET.VPC.Stack) isV6Stack = utils.IsV6Stack(parent.SUBNET.VPC.Stack) c = 0 v6c = 0 v4c = 0 hasLocalMap = hasattr(vnic_spec_obj, 'lmap') if hasLocalMap: #iota case lmap_spec = vnic_spec_obj.lmap[0] lmap_count = len(vnic_spec_obj.lmap) else: #Dol case lmap_spec = vnic_spec_obj lmap_count = vnic_spec_obj.ipcount while c < lmap_count: if isV6Stack: obj = LocalMappingObject(node, parent, lmap_spec, \ utils.IP_VERSION_6, v6c) self.Objs[node].update({obj.MappingId: obj}) self.__epip_objs[node].update({(obj.IP, obj.VNIC.SUBNET.VPC.UUID.GetUuid()): obj}) self.PopulateTagCache(obj) if c < lmap_count and hasLocalMap: lmap_spec = vnic_spec_obj.lmap[c] else: v6c = v6c + 1 if c < lmap_count and isV4Stack: obj = LocalMappingObject(node, parent, lmap_spec, \ utils.IP_VERSION_4, v4c) self.Objs[node].update({obj.MappingId: obj}) self.__epip_objs[node].update({(obj.IP, obj.VNIC.SUBNET.VPC.UUID.GetUuid()): obj}) self.PopulateTagCache(obj) c = c + 1 if c < lmap_count and hasLocalMap: lmap_spec = vnic_spec_obj.lmap[c] else: v4c = v4c + 1 return
def IsV6Stack(self): return utils.IsV6Stack(self.Stack)
def GenerateObjects(self, node, parent, vpc_spec_obj): vpcid = parent.VPCId isV4Stack = utils.IsV4Stack(parent.Stack) isV6Stack = utils.IsV6Stack(parent.Stack) self.__v4objs[node][vpcid] = dict() self.__v6objs[node][vpcid] = dict() self.__v4iter[node][vpcid] = None self.__v6iter[node][vpcid] = None if not utils.IsTagSupported(): return def __get_adjacent_routes(base, count): routes = [] c = 1 routes.append(ipaddress.ip_network(base)) while c < count: routes.append(utils.GetNextSubnet(routes[c - 1])) c += 1 return routes def __get_overlap(basepfx, base, count): # for overlap, add user specified base prefix with original prefixlen routes = __get_user_specified_routes([basepfx]) routes.extend(__get_adjacent_routes(base, count)) return routes def __get_first_subnet(ip, prefixlen): for ip in ip.subnets(new_prefix=prefixlen): return (ip) return def __add_v4tagtable(v4rules): obj = TagObject(node, utils.IP_VERSION_4, v4rules) self.__v4objs[node][vpcid].update({obj.TagTblId: obj}) self.Objs[node].update({obj.TagTblId: obj}) def __add_v6tagtable(v6rules): obj = TagObject(node, utils.IP_VERSION_6, v6rules) self.__v6objs[node][vpcid].update({obj.TagTblId: obj}) self.Objs[node].update({obj.TagTblId: obj}) def __get_user_specified_rules(rulesspec): rules = [] if rulesspec: for rule in rulesspec: prefixes = [] for prefix in rule.prefixes: prefixes.append( ipaddress.ip_network(prefix.replace('\\', '/'))) obj = TagRuleObject(prefixes, rule.tag, rule.priority) rules.append(obj) return rules def __add_user_specified_tagtable(tagtablespec, pfxtype): if isV4Stack: __add_v4tagtable( __get_user_specified_rules(tagtablespec.v4rules)) if isV6Stack: __add_v6tagtable( __get_user_specified_rules(tagtablespec.v6rules)) if not hasattr(vpc_spec_obj, 'tagtbl'): return for tagtbl_spec_obj in vpc_spec_obj.tagtbl: tagtbltype = tagtbl_spec_obj.type tagpfxtype = tagtbl_spec_obj.pfxtype if tagtbltype == "specific": __add_user_specified_tagtable(tagtbl_spec_obj, tagpfxtype) continue if self.__v6objs[node][vpcid]: self.__v6iter[node][vpcid] = utils.rrobiniter( self.__v6objs[node][vpcid].values()) if self.__v4objs[node][vpcid]: self.__v4iter[node][vpcid] = utils.rrobiniter( self.__v4objs[node][vpcid].values()) return
def GenerateObjects(self, node, parent, vpc_spec_obj): vpcpeerid = parent.GetVPCPeerId() if not self.__supported: return vpcid = parent.VPCId isV4Stack = utils.IsV4Stack(parent.Stack) isV6Stack = utils.IsV6Stack(parent.Stack) and self.__v6supported self.__v4objs[node][vpcid] = dict() self.__v6objs[node][vpcid] = dict() self.__v4iter[node][vpcid] = None self.__v6iter[node][vpcid] = None if utils.IsNatSupported(): if ResmgrClient[node].RemoteInternetNonNatTunAllocator == None and \ ResmgrClient[node].RemoteInternetNatTunAllocator == None: logger.info( "Skipping route creation as there are no Internet tunnels") return def __get_adjacent_routes(base, count): routes = OrderedDict() ipaddr = ipaddress.ip_network(base) af = ipaddr.version spec = routetbl_spec_obj priority = topo.DEFAULT_ROUTE_PRIORITY priorityType = getattr(spec, "priority", None) if priorityType: priority = __get_priority(priorityType, True) nh_type, nh_id, nhgid, vpcid, tunnelid, nat_type, service_nat_prefix, \ dnat_ip, classpriority, meteren = __get_route_attribs(spec, af) obj = RouteObject(node, ipaddr, priority, nh_type, nh_id, nhgid, \ vpcid, tunnelid, nat_type, service_nat_prefix, \ dnat_ip, classpriority, meteren) routes.update({obj.Id: obj}) c = 1 while c < count: ipaddr = utils.GetNextSubnet(ipaddr) if priorityType: priority = __get_priority(priorityType, False, priority) nh_type, nh_id, nhgid, vpcid, tunnelid, nat_type, service_nat_prefix, \ dnat_ip, classpriority, meteren = __get_route_attribs(spec, af) obj = RouteObject(node, ipaddr, priority, nh_type, nh_id, \ nhgid, vpcid, tunnelid, nat_type, \ service_nat_prefix, dnat_ip, classpriority, \ meteren) routes.update({obj.Id: obj}) c += 1 return routes def __get_overlap(basepfx, base, count): # for overlap, add user specified base prefix with original prefixlen routes = __get_user_specified_routes([basepfx]) routes = utils.MergeDicts(routes, __get_adjacent_routes(base, count)) return routes def __get_first_subnet(ip, prefixlen): for ip in ip.subnets(new_prefix=prefixlen): return (ip) return def __add_v4routetable(v4routes, spec): obj = RouteTableObject(node, parent, utils.IP_VERSION_4, v4routes, spec.routetype, tunobj, vpcpeerid, spec) self.__v4objs[node][vpcid].update({obj.RouteTblId: obj}) self.Objs[node].update({obj.RouteTblId: obj}) def __add_v6routetable(v6routes, spec): obj = RouteTableObject(node, parent, utils.IP_VERSION_6, v6routes, spec.routetype, tunobj, vpcpeerid, spec) self.__v6objs[node][vpcid].update({obj.RouteTblId: obj}) self.Objs[node].update({obj.RouteTblId: obj}) def __derive_nh_type_info(spec): routetype = spec.routetype if 'vpc_peer' in routetype: return 'vpcpeer' elif 'blackhole' in routetype: return 'blackhole' elif utils.IsPipelineArtemis(): # handle service tunnel case, return tep return "nh" elif utils.IsPipelineApulu(): if 'overlay-ecmp' in spec.teptype: return "nhg" else: return "tep" else: return "tep" def __internet_tunnel_get(nat, teptype=None): if teptype is not None: if "service" in teptype: if "remoteservice" == teptype: return ResmgrClient[node].RemoteSvcTunAllocator.rrnext( ) return ResmgrClient[node].SvcTunAllocator.rrnext() if "underlay" in teptype: if "underlay-ecmp" == teptype: return ResmgrClient[ node].UnderlayECMPTunAllocator.rrnext() return ResmgrClient[node].UnderlayTunAllocator.rrnext() if "overlay-ecmp" in teptype: # Fill NhGroup later return None if nat is False: return ResmgrClient[ node].RemoteInternetNonNatTunAllocator.rrnext() else: return ResmgrClient[node].RemoteInternetNatTunAllocator.rrnext( ) def __get_tunnel(spec): routetype = spec.routetype nat, teptype = __get_nat_teptype_from_spec(spec) tunobj = __internet_tunnel_get(nat, teptype) return tunobj def __get_nexthop(af): nh = None if af == utils.IP_VERSION_4: nh = NexthopClient.GetV4Nexthop(node, parent.VPCId) else: nh = NexthopClient.GetV6Nexthop(node, parent.VPCId) return nh def __get_route_attribs(spec, af=utils.IP_VERSION_4): nhid = 0 nhgid = 0 vpcid = 0 tunnelid = 0 nat_type = None service_nat_prefix = getattr(spec, 'servicenatprefix', None) classpriority = getattr(spec, 'classpriority', 0) meteren = getattr(spec, 'meteren', False) dnat_ip = getattr(spec, 'dnatip', None) natspec = getattr(spec, 'nat', None) if natspec: nat_type = getattr(natspec, 'type', None) nat_level = getattr(natspec, 'level', None) nh_type = __derive_nh_type_info(spec) if nh_type == "vpcpeer": vpcid = vpcpeerid elif nh_type == "tep": tunobj = __get_tunnel(spec) if utils.IsPipelineArtemis() and tunobj.IsSvc(): # service tunnel case nh_type = "nh" nexthop = __get_nexthop(af) nh_id = nexthop.NexthopId else: tunnelid = tunobj.Id elif nh_type == "nh": nexthop = __get_nexthop(af) if nexthop: nhid = nexthop.NexthopId elif nh_type == "nhg": nhgid = 1 # fill later return nh_type, nhid, nhgid, vpcid, tunnelid, nat_type, \ service_nat_prefix, dnat_ip, classpriority, meteren def __get_priority(priotype, firstVal=False, priority=0): if priotype == "increasing": if firstVal: return topo.MIN_ROUTE_PRIORITY return (priority - 1) elif priotype == "decreasing": if firstVal: return topo.MAX_ROUTE_PRIORITY return (priority + 1) elif priotype == "random": return (random.randint(topo.MAX_ROUTE_PRIORITY, topo.MIN_ROUTE_PRIORITY)) else: logger.error("Unknown priority type", priotype) return (random.randint(topo.MAX_ROUTE_PRIORITY, topo.MIN_ROUTE_PRIORITY)) def __get_user_specified_routes(routespec): routes = OrderedDict() spec = routetbl_spec_obj priorityType = getattr(spec, "priority", None) priority = topo.DEFAULT_ROUTE_PRIORITY if priorityType: priority = __get_priority(spec.priority, True) if routespec: for route in routespec: if priorityType: priority = __get_priority(spec.priority, False, priority) nh_type, nh_id, nhgid, vpcid, tunnelid, nat_type, \ service_nat_prefix, dnat_ip, classpriority, \ meteren = __get_route_attribs(spec) obj = RouteObject(node, ipaddress.ip_network(route.replace('\\', '/')),\ priority, nh_type, nh_id, nhgid, vpcid, tunnelid,\ nat_type, service_nat_prefix, dnat_ip,\ classpriority, meteren) routes.update({obj.Id: obj}) return routes def __add_user_specified_routetable(spec): if isV4Stack: __add_v4routetable(__get_user_specified_routes(spec.v4routes), spec) if isV6Stack: __add_v6routetable(__get_user_specified_routes(spec.v6routes), spec) def __get_valid_route_count_per_route_table(count): if count > Resmgr.MAX_ROUTES_PER_ROUTE_TBL: return Resmgr.MAX_ROUTES_PER_ROUTE_TBL return count def __get_nat_teptype_from_spec(routetbl_spec_obj): nat = False natSpec = getattr(routetbl_spec_obj, 'nat', None) if natSpec: level = getattr(natSpec, 'level') if level == 'tunnel' and not utils.IsPipelineApulu(): nat = True teptype = getattr(routetbl_spec_obj, 'teptype', None) return nat, teptype for routetbl_spec_obj in vpc_spec_obj.routetbl: if utils.IsReconfigInProgress(node): id = getattr(routetbl_spec_obj, 'id', None) if id: obj = self.GetRouteTableObject(node, id) if obj: obj.ObjUpdate(routetbl_spec_obj) else: for obj in list(self.Objs[node].values()): obj.ObjUpdate(routetbl_spec_obj) continue routetbltype = routetbl_spec_obj.type routetype = routetbl_spec_obj.routetype nat, teptype = __get_nat_teptype_from_spec(routetbl_spec_obj) tunobj = __internet_tunnel_get(nat, teptype) if routetbltype == "specific": __add_user_specified_routetable(routetbl_spec_obj) continue routetablecount = routetbl_spec_obj.count v4routecount = __get_valid_route_count_per_route_table( routetbl_spec_obj.nv4routes) v6routecount = __get_valid_route_count_per_route_table( routetbl_spec_obj.nv6routes) v4prefixlen = routetbl_spec_obj.v4prefixlen v6prefixlen = routetbl_spec_obj.v6prefixlen v4base = __get_first_subnet( ipaddress.ip_network( routetbl_spec_obj.v4base.replace('\\', '/')), v4prefixlen) v6base = __get_first_subnet( ipaddress.ip_network( routetbl_spec_obj.v6base.replace('\\', '/')), v6prefixlen) # get user specified routes if any for 'base' routetbltype user_specified_v4routes = __get_user_specified_routes( routetbl_spec_obj.v4routes) user_specified_v6routes = __get_user_specified_routes( routetbl_spec_obj.v6routes) v4routecount -= len(user_specified_v4routes) v6routecount -= len(user_specified_v6routes) if 'overlap' in routetype: v4routecount -= 1 v6routecount -= 1 for i in range(routetablecount): if 'adjacent' in routetype: if isV4Stack: routes = utils.MergeDicts(user_specified_v4routes, \ __get_adjacent_routes(v4base, v4routecount-1)) __add_v4routetable(routes, routetbl_spec_obj) v4base = utils.GetNextSubnet( routes.get(list(routes)[-1]).ipaddr) if isV6Stack: routes = utils.MergeDicts(user_specified_v6routes, \ __get_adjacent_routes(v6base, v6routecount-1)) __add_v6routetable(routes, routetbl_spec_obj) v6base = utils.GetNextSubnet( routes.get(list(routes)[-1]).ipaddr) elif 'overlap' in routetype: if isV4Stack: routes = utils.MergeDicts(user_specified_v4routes, \ __get_overlap(routetbl_spec_obj.v4base, v4base, v4routecount)) __add_v4routetable(routes, routetbl_spec_obj) v4base = utils.GetNextSubnet( routes.get(list(routes)[-1]).ipaddr) if isV6Stack: routes = utils.MergeDicts(user_specified_v6routes, \ __get_overlap(routetbl_spec_obj.v6base, v6base, v6routecount)) __add_v6routetable(routes, routetbl_spec_obj) v6base = utils.GetNextSubnet( routes.get(list(routes)[-1]).ipaddr) if self.__v6objs[node][vpcid]: self.__v6iter[node][vpcid] = utils.rrobiniter( self.__v6objs[node][vpcid].values()) if self.__v4objs[node][vpcid]: self.__v4iter[node][vpcid] = utils.rrobiniter( self.__v4objs[node][vpcid].values())
def GenerateObjects(self, node, parent, vpcspecobj): vpcid = parent.VPCId isV4Stack = utils.IsV4Stack(parent.Stack) isV6Stack = utils.IsV6Stack(parent.Stack) self.__v4objs[node][vpcid] = [] self.__v6objs[node][vpcid] = [] self.__v4iter[node][vpcid] = None self.__v6iter[node][vpcid] = None if getattr(vpcspecobj, 'meter', None) == None: self.__num_v4_meter_per_vpc.append(0) self.__num_v6_meter_per_vpc.append(0) return if not utils.IsMeteringSupported(): return def __add_specific_meter_prefixes(rulespec, af): prefixes = [] if af == utils.IP_VERSION_4: for r in rulespec.v4prefixes: base = ipaddress.ip_network(r.replace('\\', '/')) prefix = ipaddress.ip_network(base) prefixes.append(prefix) else: for r in rulespec.v6prefixes: base = ipaddress.ip_network(r.replace('\\', '/')) prefix = ipaddress.ip_network(base) prefixes.append(prefix) return prefixes def __add_meter_rules(rule_spec, af, metercount): rules = [] for rulespec in rule_spec: prefixes = [] if af == utils.IP_VERSION_4: pfx = ipaddress.ip_network(rulespec.v4base.replace('\\', '/')) else: pfx = ipaddress.ip_network(rulespec.v6base.replace('\\', '/')) totalhosts = ipaddress.ip_network(pfx).num_addresses * (metercount * rulespec.num_prefixes) new_pfx = str(pfx.network_address + totalhosts) + '/' + str(pfx.prefixlen) prefix = ipaddress.ip_network(new_pfx) prefixes.append(prefix) c = 1 while c < rulespec.num_prefixes: pfx = utils.GetNextSubnet(prefix) prefix = ipaddress.ip_network(pfx) prefixes.append(prefix) c += 1 prefixes.extend(__add_specific_meter_prefixes(rulespec, af)) obj = MeterRuleObject(rulespec.type, rulespec.priority, prefixes) rules.append(obj) return rules def __add_meter_rules_from_routetable(meterspec, af): base_priority = meterspec.base_priority rule_type = meterspec.rule_type rules = [] if af == utils.IP_VERSION_4: total_rt = route.client.GetRouteV4Tables(node, vpcid) else: total_rt = route.client.GetRouteV6Tables(node, vpcid) if total_rt != None: for rt_id, rt_obj in total_rt.items(): if rt_obj.RouteType != 'overlap': # one rule for all routes in one route table pfxs = list(rt_obj.routes.values()) prefixes = [] for pfx in pfxs: prefixes.append(pfx.ipaddr) ruleobj = MeterRuleObject(rule_type, base_priority, prefixes) base_priority += 1 rules.append(ruleobj) return rules for meter in vpcspecobj.meter: c = 0 v4_count = 0 v6_count = 0 if meter.auto_fill: if isV4Stack: rules = __add_meter_rules_from_routetable(meter, utils.IP_VERSION_4) obj = MeterObject(node, parent, utils.IP_VERSION_4, rules) self.__v4objs[node][vpcid].append(obj) self.Objs[node].update({obj.MeterId: obj}) v4_count += len(rules) if isV6Stack: rules = __add_meter_rules_from_routetable(meter, utils.IP_VERSION_6) obj = MeterObject(node, parent, utils.IP_VERSION_6, rules) self.__v6objs[node][vpcid].append(obj) self.Objs[node].update({obj.MeterId: obj}) v6_count += len(rules) else: while c < meter.count: if isV4Stack: rules = __add_meter_rules(meter.rule, utils.IP_VERSION_4, c) obj = MeterObject(node, parent, utils.IP_VERSION_4, rules) self.__v4objs[node][vpcid].append(obj) self.Objs[node].update({obj.MeterId: obj}) v4_count += len(rules) if isV6Stack: rules = __add_meter_rules(meter.rule, utils.IP_VERSION_6, c) obj = MeterObject(node, parent, utils.IP_VERSION_6, rules) self.__v6objs[node][vpcid].append(obj) self.Objs[node].update({obj.MeterId: obj}) v6_count += len(rules) c += 1 if len(self.__v4objs[node][vpcid]): self.__v4iter[node][vpcid] = utils.rrobiniter(self.__v4objs[node][vpcid]) if len(self.__v6objs[node][vpcid]): self.__v6iter[node][vpcid] = utils.rrobiniter(self.__v6objs[node][vpcid]) self.__num_v4_meter_per_vpc.append(v4_count) self.__num_v6_meter_per_vpc.append(v6_count) return