示例#1
0
    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
示例#2
0
    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
示例#3
0
 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
示例#4
0
 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
示例#5
0
 def IsV6Stack(self):
     return utils.IsV6Stack(self.Stack)
示例#6
0
    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
示例#7
0
    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())
示例#8
0
    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