예제 #1
0
파일: vrouterapi.py 프로젝트: sinofeng/vlcp
 def walker(walk, write):
     for key, parameters in parameter_dict.items():
         with suppress(WalkKeyNotRetrieved):
             value = walk(key)
             value = create_new(RouterPort, value, parameters['id'])
             subnet = walk(SubNet.default_key(parameters['subnet']))
             if subnet is None:
                 raise ValueError("Subnet " + parameters['subnet'] + " not exists")
             subnet_map = walk(SubNetMap.default_key(parameters['subnet']))
             router = walk(VRouter.default_key(parameters['router']))
             if router is None:
                 raise ValueError("Virtual router " + parameters['router'] + " not exists")
             if hasattr(subnet, 'router'):
                 # normal subnet can only have one router
                 _, (rid,) = VRouter._getIndices(subnet.router.getkey())
                 raise ValueError("Subnet %r is already in virtual router %r", parameters['subnet'], rid)
             if hasattr(subnet_map, 'routers'):
                 if router.create_weakreference() in subnet_map.routers.dataset():
                     raise ValueError("Subnet %r is already in virtual router %r", parameters['subnet'],
                                                                                   parameters['router'])
             if 'ip_address' in parameters:
                 if getattr(subnet, 'isexternal', False):
                     raise ValueError("Cannot specify IP address when add external subnet to virtual router")
                 # Check IP address in CIDR
                 nip = parse_ip4_address(parameters['ip_address'])
                 cidr, prefix = parse_ip4_network(subnet.cidr)
                 if not ip_in_network(nip, cidr, prefix):
                     raise ValueError("IP address " + parameters['ip_address'] + " not in subnet CIDR")
                 # Check IP not allocated
                 if str(nip) in subnet_map.allocated_ips:
                     raise ValueError("IP address " + parameters['ip_address'] + " has been used")
                 else:
                     # Save to allocated map
                     subnet_map.allocated_ips[str(nip)] = (value.create_weakreference(), router.create_weakreference())
                     write(subnet_map.getkey(), subnet_map)
             else:
                 # Use gateway
                 if not hasattr(subnet, 'gateway'):
                     raise ValueError("Subnet " + subnet.id + " does not have a gateway, IP address on router port must be specified explicitly")
             if not hasattr(subnet_map, 'routers'):
                 subnet_map.routers = DataObjectSet()
             subnet_map.routers.dataset().add(router.create_weakreference())
             if not hasattr(subnet_map, 'routerports'):
                 subnet_map.routerports = {}
             subnet_map.routerports[router.id] = value.create_weakreference()
             write(subnet_map.getkey(), subnet_map)
             if not getattr(subnet, 'isexternal', False):
                 subnet.router = value.create_weakreference()
                 write(subnet.getkey(), subnet)
             # Save port to router
             router.interfaces.dataset().add(value.create_weakreference())
             write(router.getkey(), router)
             value.router = router.create_reference()
             value.subnet = subnet.create_reference()
             for k, v in parameters.items():
                 if k not in ('router', 'subnet', 'id'):
                     setattr(value, k, v)
             write(key, value)
예제 #2
0
    def updatevirtualrouters(self, routers):
        "Update multiple virtual routers"
        idset = set()
        for router in routers:
            if 'id' not in router:
                raise ValueError(" must specify id")
            else:
                if router['id'] in idset:
                    raise ValueError(" id repeat " + router['id'])
                else:
                    idset.add(router['id'])

            # if routers updating ,, check format
            if 'routes' in router:
                for r in router['routes']:
                    ip_prefix = r[0]
                    nexthop = r[1]

                    if ip_prefix and nexthop:
                        ip_prefix = parse_ip4_network(ip_prefix)
                        nexthop = check_ip_address(nexthop)
                    else:
                        raise ValueError("routes format error " + r)

        routerkeys = [VRouter.default_key(r['id']) for r in routers]

        def updaterouter(keys, values):

            for i in range(0, len(routers)):
                if values[i]:
                    for k, v in routers[i].items():

                        if k == 'routes':
                            # update routers accord new static routes
                            values[i].routes = []
                            for pn in v:
                                values[i].routes.append(pn)
                        else:
                            setattr(values[i], k, v)
                else:
                    raise ValueError("router object not exists " +
                                     routers[i]['id'])

            return keys, values

        try:
            for m in callAPI(self.app_routine, 'objectdb', 'transact', {
                    'keys': routerkeys,
                    'updater': updaterouter
            }):
                yield m
        except:
            raise
        else:

            for m in self._dumpkeys(routerkeys):
                yield m
예제 #3
0
 def __init__(self, parent):
     HttpHandler.__init__(self, parent.scheduler, False, parent.vhostbind)
     self._parent = parent
     self._logger = parent._logger
     self._macbase = uint64.create(
         create_binary(mac_addr_bytes(self._parent.mactemplate), 8))
     cidrrange = parent.cidrrange
     try:
         subnet, mask = parse_ip4_network(cidrrange)
         if not (0 <= mask <= 24):
             raise ValueError
     except Exception:
         self._logger.warning(
             'Invalid CIDR range: %r. Using default 10.0.0.0/8', cidrrange)
         subnet = ip4_addr('10.0.0.0')
         mask = 8
     self.cidrrange_subnet = subnet
     self.cidrrange_mask = mask
     self.cidrrange_end = (1 << (24 - mask))
     self.pooltimeout = parent.pooltimeout
     self.iptimeout = parent.iptimeout
     self._reqid = 0
예제 #4
0
파일: dhcp.py 프로젝트: vtanrun/vlcp
def _create_dhcp_route(cidr, router):
    network, mask = parse_ip4_network(cidr)
    return dhcp_route(subnet = ip4_addr.tobytes(network), mask = mask, router = ip4_addr(router))
예제 #5
0
    def updateflow(self, connection, addvalues, removevalues, updatedvalues):
        try:
            allobjs = set(o for o in self._savedresult
                          if o is not None and not o.isdeleted())
            # Create DHCP entries
            lastlognetinfo = self._lastlognetinfo
            lastlogportinfo = self._lastlogportinfo
            lastserveraddresses = self._lastserveraddresses
            currentlognetinfo = dict(
                (n, id) for n, id in self._lastlognets if n in allobjs)
            currentlogportinfo = dict(
                (p,
                 (id, currentlognetinfo[p.network], p.ip_address,
                  p.mac_address,
                  getattr(p.subnet, 'dhcp_server', self._parent.serveraddress))
                 ) for p, id in self._lastlogports if p in allobjs
                and p.network in currentlognetinfo and hasattr(p, 'subnet'))
            currentserveraddresses = set(
                (v[4], self._parent.servermac, p.network.id, True)
                for p, v in currentlogportinfo.items())
            self._lastlognetinfo = currentlognetinfo
            self._lastlogportinfo = currentlogportinfo
            self._lastserveraddresses = currentserveraddresses
            dhcp_entries = {}
            t1 = self._parent.t1
            t2 = self._parent.t2
            for p in self._savedresult:
                if p is not None and not p.isdeleted() and p.isinstance(LogicalPort) and hasattr(p, 'subnet') \
                        and hasattr(p, 'ip_address') and hasattr(p, 'mac_address'):
                    if p.network in currentlognetinfo and p in currentlogportinfo:
                        try:
                            pid, _, ip_address, mac_address, server_address = currentlogportinfo[
                                p]
                            if getattr(p.subnet, 'dhcp_enabled', False):
                                continue
                            cidr = p.subnet.cidr
                            network, mask = parse_ip4_network(cidr)
                            # options from default settings
                            entries = {
                                d.OPTION_LEASE_TIME:
                                (lambda x: d.DHCPTIME_INFINITE
                                 if x is None else x)(self._parent.leasetime)
                            }
                            # options from network
                            if hasattr(p.network, 'dns_nameservers'):
                                entries[
                                    d.
                                    OPTION_DNSSERVER] = p.network.dns_nameservers
                            if hasattr(p.network, 'domain_name'):
                                entries[
                                    d.
                                    OPTION_DOMAINNAME] = p.network.domain_name
                            if hasattr(p.network, 'mtu'):
                                entries[d.OPTION_MTU] = p.network.mtu
                            if hasattr(p.network, 'ntp_servers'):
                                entries[
                                    d.OPTION_NTPSERVER] = p.network.ntp_servers
                            if hasattr(p.network, 'lease_time'):
                                entries[
                                    d.OPTION_LEASE_TIME] = p.network.lease_time
                            if hasattr(p.network, 'extra_dhcp_options'):
                                entries.update(p.network.extra_dhcp_options)
                            options = d.create_dhcp_options(
                                entries, True, True)
                            # options from subnet
                            entries = {
                                d.OPTION_NETMASK:
                                ip4_addr.formatter(get_netmask(mask)),
                                d.OPTION_BROADCAST:
                                ip4_addr.formatter(get_broadcast(
                                    network, mask))
                            }
                            if hasattr(p.subnet, 'gateway'):
                                entries[d.OPTION_ROUTER] = p.subnet.gateway
                            if hasattr(p.subnet, 'dns_nameservers'):
                                entries[
                                    d.
                                    OPTION_DNSSERVER] = p.subnet.dns_nameservers
                            if hasattr(p.subnet, 'domain_name'):
                                entries[
                                    d.OPTION_DOMAINNAME] = p.subnet.domain_name
                            if hasattr(p.subnet, 'mtu'):
                                entries[d.OPTION_MTU] = p.subnet.mtu
                            if hasattr(p.subnet, 'ntp_servers'):
                                entries[
                                    d.OPTION_NTPSERVER] = p.subnet.ntp_servers
                            if hasattr(p.subnet, 'lease_time'):
                                entries[
                                    d.OPTION_LEASE_TIME] = p.subnet.lease_time
                            # Routes is special
                            if hasattr(p.subnet, 'host_routes'):
                                routes = list(p.subnet.host_routes)
                                if routes and not any(
                                        parse_ip4_network(r[0]) == (0, 0)
                                        for r in routes):
                                    routes.append(
                                        ['0.0.0.0/0', p.subnet.gateway])
                                entries[d.OPTION_CLASSLESSROUTE] = routes
                            # TODO: add extra routes from routers
                            if hasattr(p.subnet, 'extra_dhcp_options'):
                                entries.update(p.subnet.extra_dhcp_options)
                            options.update(
                                d.create_dhcp_options(entries, True, True))
                            entries = {}
                            if hasattr(p, 'hostname'):
                                entries[d.OPTION_HOSTNAME] = p.hostname
                            if hasattr(p, 'extra_dhcp_options'):
                                entries.update(p.extra_dhcp_options)
                            options.update(
                                d.create_dhcp_options(entries, True, True))
                            entries = {
                                d.OPTION_SERVER_IDENTIFIER: server_address
                            }
                            options.update(
                                d.create_dhcp_options(entries, True, True))
                            options = dict((k, v) for k, v in options.items()
                                           if v is not None)
                            if d.OPTION_LEASE_TIME not in options:
                                options[
                                    d.
                                    OPTION_LEASE_TIME] = d.create_option_from_value(
                                        d.OPTION_LEASE_TIME,
                                        d.DHCPTIME_INFINITE)
                            if options[
                                    d.
                                    OPTION_LEASE_TIME].value != d.DHCPTIME_INFINITE:
                                leasetime = options[d.OPTION_LEASE_TIME].value
                                if d.OPTION_T1 not in options and t1 is not None and t1 < leasetime:
                                    options[
                                        d.
                                        OPTION_T1] = d.create_option_from_value(
                                            d.OPTION_T1, t1)
                                if d.OPTION_T2 not in options and t2 is not None and t2 < leasetime:
                                    options[
                                        d.
                                        OPTION_T1] = d.create_option_from_value(
                                            d.OPTION_T1, t2)
                            dhcp_entries[pid] = (mac_addr(mac_address),
                                                 ip4_addr(ip_address),
                                                 ip4_addr(server_address),
                                                 options)
                        except Exception:
                            self._logger.warning(
                                "Failed to create DHCP options for port id=%r. Will disable DHCP on this port",
                                p.id,
                                exc_info=True)
            self._dhcpentries = dhcp_entries
            # Create flows
            # For every logical port, create two flows
            ofdef = connection.openflowdef
            vhost = connection.protocol.vhost
            l3 = self._parent._gettableindex('l3input', vhost)
            cmds = []
            if connection.protocol.disablenxext:

                def match_network(nid):
                    return [
                        ofdef.create_oxm(ofdef.OXM_OF_METADATA_W,
                                         ((nid & 0xffff) << 32) |
                                         (0xffff << 16),
                                         b'\x00\x00\xff\xff\x40\x00\x00\x00')
                    ]
            else:

                def match_network(nid):
                    return [
                        ofdef.create_oxm(ofdef.NXM_NX_REG5, nid),
                        ofdef.create_oxm(ofdef.NXM_NX_REG7_W, 0x4000, 0x4000)
                    ]

            def _delete_flows(nid):
                return ofdef.ofp_flow_mod(
                    cookie=0x1,
                    cookie_mask=0xffffffffffffffff,
                    table_id=l3,
                    command=ofdef.OFPFC_DELETE,
                    priority=ofdef.OFP_DEFAULT_PRIORITY,
                    buffer_id=ofdef.OFP_NO_BUFFER,
                    out_port=ofdef.OFPP_ANY,
                    out_group=ofdef.OFPG_ANY,
                    match=ofdef.ofp_match_oxm(oxm_fields=match_network(nid) + [
                        ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE,
                                         ofdef.ETHERTYPE_IP),
                        ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO,
                                         ofdef.IPPROTO_UDP),
                        ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                    ]))

            def _delete_flows2(nid, serveraddr):
                return ofdef.ofp_flow_mod(
                    cookie=0x1,
                    cookie_mask=0xffffffffffffffff,
                    table_id=l3,
                    command=ofdef.OFPFC_DELETE,
                    priority=ofdef.OFP_DEFAULT_PRIORITY,
                    buffer_id=ofdef.OFP_NO_BUFFER,
                    out_port=ofdef.OFPP_ANY,
                    out_group=ofdef.OFPG_ANY,
                    match=ofdef.ofp_match_oxm(oxm_fields=match_network(nid) + [
                        ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE,
                                         ofdef.ETHERTYPE_IP),
                        ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO,
                                         ofdef.IPPROTO_UDP),
                        ofdef.create_oxm(ofdef.OXM_OF_IPV4_DST,
                                         ip4_addr_bytes(serveraddr)),
                        ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                    ]))

            def _create_flows(nid):
                return ofdef.ofp_flow_mod(
                    cookie=0x1,
                    cookie_mask=0xffffffffffffffff,
                    table_id=l3,
                    command=ofdef.OFPFC_ADD,
                    priority=ofdef.OFP_DEFAULT_PRIORITY,
                    buffer_id=ofdef.OFP_NO_BUFFER,
                    out_port=ofdef.OFPP_ANY,
                    out_group=ofdef.OFPG_ANY,
                    match=ofdef.ofp_match_oxm(oxm_fields=match_network(nid) + [
                        ofdef.create_oxm(ofdef.OXM_OF_ETH_DST_W,
                                         b'\x01\x00\x00\x00\x00\x00',
                                         b'\x01\x00\x00\x00\x00\x00'),
                        ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE,
                                         ofdef.ETHERTYPE_IP),
                        ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO,
                                         ofdef.IPPROTO_UDP),
                        ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                    ]),
                    instructions=[
                        ofdef.ofp_instruction_actions(actions=[
                            ofdef.ofp_action_output(
                                port=ofdef.OFPP_CONTROLLER,
                                max_len=ofdef.OFPCML_NO_BUFFER)
                        ])
                    ])

            def _create_flows2(nid, serveraddr):
                return ofdef.ofp_flow_mod(
                    cookie=0x1,
                    cookie_mask=0xffffffffffffffff,
                    table_id=l3,
                    command=ofdef.OFPFC_ADD,
                    priority=ofdef.OFP_DEFAULT_PRIORITY,
                    buffer_id=ofdef.OFP_NO_BUFFER,
                    out_port=ofdef.OFPP_ANY,
                    out_group=ofdef.OFPG_ANY,
                    match=ofdef.ofp_match_oxm(oxm_fields=match_network(nid) + [
                        ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE,
                                         ofdef.ETHERTYPE_IP),
                        ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO,
                                         ofdef.IPPROTO_UDP),
                        ofdef.create_oxm(ofdef.OXM_OF_IPV4_DST,
                                         ip4_addr_bytes(serveraddr)),
                        ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                    ]),
                    instructions=[
                        ofdef.ofp_instruction_actions(actions=[
                            ofdef.ofp_action_output(
                                port=ofdef.OFPP_CONTROLLER,
                                max_len=ofdef.OFPCML_NO_BUFFER)
                        ])
                    ])

            for n in removevalues:
                if n in lastlognetinfo:
                    nid = lastlognetinfo[n]
                    cmds.append(_delete_flows(nid))
            lastnetdict = {n.id: n for n in lastlognetinfo}
            for serveraddr in lastserveraddresses:
                if serveraddr not in currentserveraddresses:
                    addr, _, networkid, _ = serveraddr
                    if networkid in lastnetdict:
                        n = lastnetdict[networkid]
                        nid = lastlognetinfo[n]
                        cmds.append(_delete_flows2(nid, addr))
            for m in self.execute_commands(connection, cmds):
                yield m

            # Remove old ARP entries; Add new ARP entries
            remove_arps = lastserveraddresses.difference(
                currentserveraddresses)
            if remove_arps:
                for m in callAPI(self, 'arpresponder', 'removeproxyarp', {
                        'connection': connection,
                        'arpentries': remove_arps
                }):
                    yield m
            add_arps = currentserveraddresses.difference(lastserveraddresses)
            if add_arps:
                for m in callAPI(self, 'arpresponder', 'createproxyarp', {
                        'connection': connection,
                        'arpentries': add_arps
                }):
                    yield m
            del cmds[:]
            for n in addvalues:
                if n in currentlognetinfo:
                    nid = currentlognetinfo[n]
                    cmds.append(_create_flows(nid))
            currnetdict = {n.id: n for n in currentlognetinfo}
            for serveraddr in currentserveraddresses:
                if serveraddr not in lastserveraddresses:
                    addr, _, networkid, _ = serveraddr
                    if networkid in currnetdict:
                        n = currnetdict[networkid]
                        nid = currentlognetinfo[n]
                        cmds.append(_create_flows2(nid, addr))
            for m in self.execute_commands(connection, cmds):
                yield m
        except Exception:
            self._logger.warning(
                "Unexpected exception in DHCPUpdater. Will ignore and continue.",
                exc_info=True)
예제 #6
0
        def _updater(keys, values, timestamp):
            pool = values[0]
            if pool is None:
                raise ValueError('PoolID %r does not exist' % (poolid, ))
            self._remove_staled_ips(pool, timestamp)
            if len(values) > 1:
                subnetmap = values[1]
                if not hasattr(
                        pool,
                        'subnetmap') or pool.subnetmap.getkey() != keys[1]:
                    raise RetryUpdateException
                subnet = values[2]
            else:
                subnetmap = None
                if hasattr(pool, 'subnetmap'):
                    raise RetryUpdateException
            if address:
                # check ip_address in cidr
                if address in pool.reserved_ips:
                    raise ValueError("IP address " + address +
                                     " has been reserved")
                if pool.subpool:
                    cidr = pool.subpool
                else:
                    cidr = pool.pool
                network, mask = parse_ip4_network(cidr)
                addr_num = ip4_addr(address)
                if not ip_in_network(addr_num, network, mask):
                    raise ValueError('IP address ' + address +
                                     " is not in the network CIDR")
                if subnetmap is not None:
                    start = ip4_addr(subnet.allocated_start)
                    end = ip4_addr(subnet.allocated_end)
                    try:
                        assert start <= addr_num <= end
                        if hasattr(subnet, 'gateway'):
                            assert addr_num != ip4_addr(subnet.gateway)
                    except Exception:
                        raise ValueError("specified IP address " + address +
                                         " is not valid")

                    if str(addr_num) in subnetmap.allocated_ips:
                        raise ValueError("IP address " + address +
                                         " has been used")
                new_address = address
            else:
                # allocated ip_address from cidr
                gateway = None
                cidr = pool.pool
                if pool.subpool:
                    cidr = pool.subpool
                network, prefix = parse_ip4_network(cidr)
                start = network_first(network, prefix)
                end = network_last(network, prefix)
                if subnetmap is not None:
                    start = max(start, ip4_addr(subnet.allocated_start))
                    end = min(end, ip4_addr(subnet.allocated_end))
                    if hasattr(subnet, "gateway"):
                        gateway = ip4_addr(subnet.gateway)
                for ip_address in range(start, end):
                    new_address = ip4_addr.formatter(ip_address)
                    if ip_address != gateway and \
                        (subnetmap is None or str(ip_address) not in subnetmap.allocated_ips) and \
                        new_address not in pool.reserved_ips:
                        break
                else:
                    raise ValueError("No available IP address can be used")
            pool.reserved_ips[
                new_address] = timestamp + self.iptimeout * 1000000
            _, mask = parse_ip4_network(pool.pool)
            rets[:] = [new_address + '/' + str(mask)]
            return ((keys[0], ), (pool, ))
예제 #7
0
    def ipam_requestpool(self, env, params):
        if params['AddressSpace'] != _GLOBAL_SPACE:
            raise ValueError(
                'Unsupported address space: must use this IPAM driver together with network driver'
            )
        if params['V6']:
            raise ValueError('IPv6 is not supported')
        new_pool = IPAMReserve.create_instance(uuid1().hex)
        new_pool.pool = params['Pool']
        if new_pool.pool:
            subnet, mask = parse_ip4_network(new_pool.pool)
            new_pool.pool = ip4_addr.formatter(subnet) + '/' + str(mask)
        new_pool.subpool = params['SubPool']
        if new_pool.subpool:
            subnet, mask = parse_ip4_network(new_pool.subpool)
            new_pool.subpool = ip4_addr.formatter(subnet) + '/' + str(mask)
        new_pool.options = params['Options']
        if new_pool.pool:
            l = Lock(('dockerplugin_ipam_request_pool', new_pool.pool),
                     self.scheduler)
            for m in l.lock(self):
                yield m
        else:
            l = None
        try:
            while True:
                fail = 0
                rets = []

                def _updater(keys, values, timestamp):
                    reservepool = values[0]
                    reserve_new_pool = set_new(values[1], new_pool)
                    remove_keys = self._remove_staled_pools(
                        reservepool, timestamp)
                    used_cidrs = set(
                        cidr
                        for _, (cidr, _) in reservepool.reserved_pools.items())
                    if not reserve_new_pool.pool:
                        # pool is not specified
                        for _ in range(0, self.cidrrange_end):
                            reservepool.nextalloc += 1
                            if reservepool.nextalloc >= self.cidrrange_end:
                                reservepool.nextalloc = 0
                            new_subnet = self.cidrrange_subnet | (
                                reservepool.nextalloc << 8)
                            new_cidr = ip4_addr.formatter(new_subnet) + '/24'
                            if new_cidr not in used_cidrs:
                                break
                        reserve_new_pool.pool = new_cidr
                        reserve_new_pool.subpool = ''
                    rets[:] = [reserve_new_pool.pool]
                    if reserve_new_pool.pool in used_cidrs:
                        # We must wait until this CIDR is released
                        raise IPAMUsingException
                    reservepool.reserved_pools[reserve_new_pool.id] = \
                                                       [reserve_new_pool.pool,
                                                       timestamp + self.pooltimeout * 1000000]
                    marker = IPAMReserveMarker.create_instance(
                        reserve_new_pool.pool)
                    if marker.getkey() in remove_keys:
                        remove_keys.remove(marker.getkey())
                        return (tuple(keys[0:2]) + tuple(remove_keys),
                                (reservepool, reserve_new_pool) +
                                (None, ) * len(remove_keys))
                    else:
                        return (tuple(keys[0:2]) + (marker.getkey(), ) +
                                tuple(remove_keys),
                                (reservepool, reserve_new_pool, marker) +
                                (None, ) * len(remove_keys))

                try:
                    for m in callAPI(
                            self, 'objectdb', 'transact',
                        {
                            'keys':
                            (IPAMPoolReserve.default_key(), new_pool.getkey()),
                            'updater':
                            _updater,
                            'withtime':
                            True
                        }):
                        yield m
                except IPAMUsingException:
                    # Wait for the CIDR to be released
                    self._reqid += 1
                    fail += 1
                    reqid = ('dockerplugin_ipam', self._reqid)
                    marker_key = IPAMReserveMarker.default_key(rets[0])
                    for m in callAPI(self, 'objectdb', 'get', {
                            'key': marker_key,
                            'requestid': reqid,
                            'nostale': True
                    }):
                        yield m
                    retvalue = self.retvalue
                    with watch_context([marker_key], [retvalue], reqid, self):
                        if retvalue is not None and not retvalue.isdeleted():
                            for m in self.executeWithTimeout(
                                    self.pooltimeout,
                                    retvalue.waitif(self,
                                                    lambda x: x.isdeleted())):
                                yield m
                else:
                    env.outputjson({
                        'PoolID': new_pool.id,
                        'Pool': rets[0],
                        'Data': {}
                    })
                    break
        finally:
            if l is not None:
                l.unlock()
예제 #8
0
파일: dhcp.py 프로젝트: hubo1016/vlcp
def _create_dhcp_route(cidr, router):
    network, mask = parse_ip4_network(cidr)
    return dhcp_route(subnet = ip4_addr.tobytes(network), mask = mask, router = ip4_addr(router))
예제 #9
0
        def addrouterinterface(keys, values):

            rkeys = keys[0:len(routerkeys)]
            robjs = values[0:len(routerkeys)]

            snkeys = keys[len(routerkeys):len(routerkeys) + len(subnetkeys)]
            snobjs = values[len(routerkeys):len(routerkeys) + len(subnetkeys)]

            snmkeys = keys[len(routerkeys) + len(subnetkeys):len(routerkeys) +
                           len(subnetkeys) + len(subnetmapkeys)]
            snmobjs = values[len(routerkeys) +
                             len(subnetkeys):len(routerkeys) +
                             len(subnetkeys) + len(subnetmapkeys)]

            rpkeys = keys[len(routerkeys) + len(subnetkeys) +
                          len(subnetmapkeys):]
            rpobjs = values[len(routerkeys) + len(subnetkeys) +
                            len(subnetmapkeys):]

            rdict = dict(zip(rkeys, robjs))
            sndict = dict(zip(snkeys, zip(snobjs, snmobjs)))
            rpdict = dict(zip(rpkeys, rpobjs))

            for i, interface in enumerate(newinterfaces):
                routerport = interface['id']
                router = interface['router']
                subnet = interface['subnet']

                routerobj = rdict.get(VRouter.default_key(router))
                subnetobj, subnetmapobj = sndict.get(
                    SubNet.default_key(subnet))
                newrouterport = newrouterportdict.get(
                    RouterPort.default_key(routerport))
                routerport = rpdict.get(RouterPort.default_key(routerport))

                if routerobj and subnetobj and subnetmapobj:

                    # now subnet only have one router ,,so check it
                    if not hasattr(subnetobj, 'router'):

                        # new router port special ip address , we check it in subnetmap
                        if hasattr(newrouterport, "ip_address"):
                            ipaddress = ip4_addr(newrouterport.ip_address)

                            n, p = parse_ip4_network(subnetobj.cidr)

                            if not ip_in_network(ipaddress, n, p):
                                raise ValueError(
                                    " special ip address not in subnet cidr")

                            if str(ipaddress
                                   ) not in subnetmapobj.allocated_ips:
                                subnetmapobj.allocated_ips[str(
                                    ipaddress
                                )] = newrouterport.create_weakreference()
                            else:
                                raise ValueError(
                                    " ip address have used in subnet " +
                                    newrouterport.ip_address)
                        else:
                            # not have special ip address, special gateway to this only router port
                            # gateway in subnet existed be sure

                            #
                            # when this case , special subnet gateway as ip_address
                            # but we do not set ip_address attr ,  when subnet gateway change ,
                            # we do not need to change router port attr

                            #setattr(newrouterport,"ip_address",subnetobj.gateway)

                            # it may be subnet not have gateway, checkout it
                            if not hasattr(subnetobj, "gateway"):
                                raise ValueError(
                                    " interface not special ip_address and subnet has no gateway"
                                )

                        #routerport = set_new(routerport,newrouterport)
                        values[len(routerkeys) + len(subnetkeys) +
                               len(subnetmapkeys) + i] = set_new(
                                   values[len(routerkeys) + len(subnetkeys) +
                                          len(subnetmapkeys) + i],
                                   routerportobjects[i])
                        subnetobj.router = newrouterport.create_weakreference()
                        routerobj.interfaces.dataset().add(
                            newrouterport.create_weakreference())
                    else:
                        raise ValueError(" subnet " + subnet +
                                         " have router port " +
                                         subnetobj.router.getkey())
                else:
                    raise ValueError(" routerobj " + router + "or subnetobj " +
                                     subnet + " not existed ")

            return keys, values
예제 #10
0
        def walker(walk, write, timestamp):
            with suppress(WalkKeyNotRetrieved):
                pool = walk(reserve_key)
                if pool is None:
                    raise ValueError('PoolID %r does not exist' % (poolid, ))
                self._remove_staled_ips(pool, timestamp)
                if hasattr(pool, 'subnetmap'):
                    subnetmap_key = pool.subnetmap.getkey()
                    subnet_key = SubNetMap._subnet.rightkey(subnetmap_key)
                    ensure_keys(walk, subnet_key, subnetmap_key)
                    subnetmap = walk(subnetmap_key)
                    subnet = walk(subnet_key)
                else:
                    subnetmap = None
                    subnet = None
                if address:
                    # check ip_address in cidr
                    if address in pool.reserved_ips:
                        raise ValueError("IP address " + address +
                                         " has been reserved")
                    if pool.subpool:
                        cidr = pool.subpool
                    else:
                        cidr = pool.pool
                    network, mask = parse_ip4_network(cidr)
                    addr_num = ip4_addr(address)
                    if not ip_in_network(addr_num, network, mask):
                        raise ValueError('IP address ' + address +
                                         " is not in the network CIDR")
                    if subnetmap is not None:
                        start = ip4_addr(subnet.allocated_start)
                        end = ip4_addr(subnet.allocated_end)
                        try:
                            assert start <= addr_num <= end
                            if hasattr(subnet, 'gateway'):
                                assert addr_num != ip4_addr(subnet.gateway)
                        except Exception:
                            raise ValueError("specified IP address " +
                                             address + " is not valid")

                        if str(addr_num) in subnetmap.allocated_ips:
                            raise ValueError("IP address " + address +
                                             " has been used")
                    new_address = address
                else:
                    # allocated ip_address from cidr
                    gateway = None
                    cidr = pool.pool
                    if pool.subpool:
                        cidr = pool.subpool
                    network, prefix = parse_ip4_network(cidr)
                    start = network_first(network, prefix)
                    end = network_last(network, prefix)
                    if subnetmap is not None:
                        start = max(start, ip4_addr(subnet.allocated_start))
                        end = min(end, ip4_addr(subnet.allocated_end))
                        if hasattr(subnet, "gateway"):
                            gateway = ip4_addr(subnet.gateway)
                    for ip_address in range(start, end):
                        new_address = ip4_addr.formatter(ip_address)
                        if ip_address != gateway and \
                            (subnetmap is None or str(ip_address) not in subnetmap.allocated_ips) and \
                            new_address not in pool.reserved_ips:
                            break
                    else:
                        raise ValueError("No available IP address can be used")
                pool.reserved_ips[
                    new_address] = timestamp + self.iptimeout * 1000000
                _, mask = parse_ip4_network(pool.pool)
                rets[:] = [new_address + '/' + str(mask)]
                write(pool.getkey(), pool)
예제 #11
0
파일: dhcpserver.py 프로젝트: hubo1016/vlcp
 def updateflow(self, connection, addvalues, removevalues, updatedvalues):
     try:
         allobjs = set(o for o in self._savedresult if o is not None and not o.isdeleted())
         # Create DHCP entries
         lastlognetinfo = self._lastlognetinfo
         lastlogportinfo = self._lastlogportinfo
         lastserveraddresses = self._lastserveraddresses
         currentlognetinfo = dict((n, id) for n,id in self._lastlognets if n in allobjs)
         currentlogportinfo = dict((p, (id, currentlognetinfo[p.network], p.ip_address, p.mac_address, getattr(p.subnet, 'dhcp_server', self._parent.serveraddress)))
                                   for p,id in self._lastlogports
                                   if p in allobjs and p.network in currentlognetinfo and hasattr(p,'subnet'))
         currentserveraddresses = set((v[4], self._parent.servermac, p.network.id, True)
                                      for p,v in currentlogportinfo.items())
         self._lastlognetinfo = currentlognetinfo
         self._lastlogportinfo = currentlogportinfo
         self._lastserveraddresses = currentserveraddresses
         dhcp_entries = {}
         t1 = self._parent.t1
         t2 = self._parent.t2
         for p in self._savedresult:
             if p is not None and not p.isdeleted() and p.isinstance(LogicalPort) and hasattr(p, 'subnet') \
                     and hasattr(p, 'ip_address') and hasattr(p, 'mac_address'):
                 if p.network in currentlognetinfo and p in currentlogportinfo:
                     try:
                         pid, _, ip_address, mac_address, server_address = currentlogportinfo[p]
                         if getattr(p.subnet, 'dhcp_enabled', False):
                             continue
                         cidr = p.subnet.cidr
                         network, mask = parse_ip4_network(cidr)
                         # options from default settings
                         entries = {d.OPTION_LEASE_TIME: (lambda x: d.DHCPTIME_INFINITE if x is None else x)(self._parent.leasetime)
                                    }
                         # options from network
                         if hasattr(p.network, 'dns_nameservers'):
                             entries[d.OPTION_DNSSERVER] = p.network.dns_nameservers
                         if hasattr(p.network, 'domain_name'):
                             entries[d.OPTION_DOMAINNAME] = p.network.domain_name
                         if hasattr(p.network, 'mtu'):
                             entries[d.OPTION_MTU] = p.network.mtu
                         if hasattr(p.network, 'ntp_servers'):
                             entries[d.OPTION_NTPSERVER] = p.network.ntp_servers
                         if hasattr(p.network, 'lease_time'):
                             entries[d.OPTION_LEASE_TIME] = p.network.lease_time
                         if hasattr(p.network, 'extra_dhcp_options'):
                             entries.update(p.network.extra_dhcp_options)
                         options = d.create_dhcp_options(entries, True, True)
                         # options from subnet
                         entries = {d.OPTION_NETMASK : ip4_addr.formatter(get_netmask(mask)),
                                    d.OPTION_BROADCAST : ip4_addr.formatter(get_broadcast(network, mask))}
                         if hasattr(p.subnet, 'gateway'):
                             entries[d.OPTION_ROUTER] = p.subnet.gateway
                         if hasattr(p.subnet, 'dns_nameservers'):
                             entries[d.OPTION_DNSSERVER] = p.subnet.dns_nameservers
                         if hasattr(p.subnet, 'domain_name'):
                             entries[d.OPTION_DOMAINNAME] = p.subnet.domain_name
                         if hasattr(p.subnet, 'mtu'):
                             entries[d.OPTION_MTU] = p.subnet.mtu
                         if hasattr(p.subnet, 'ntp_servers'):
                             entries[d.OPTION_NTPSERVER] = p.subnet.ntp_servers
                         if hasattr(p.subnet, 'lease_time'):
                             entries[d.OPTION_LEASE_TIME] = p.subnet.lease_time
                         # Routes is special
                         if hasattr(p.subnet, 'host_routes'):
                             routes = list(p.subnet.host_routes)
                             if routes and not any(parse_ip4_network(r[0]) == (0,0) for r in routes):
                                 routes.append(['0.0.0.0/0', p.subnet.gateway])
                             entries[d.OPTION_CLASSLESSROUTE] = routes
                         # TODO: add extra routes from routers
                         if hasattr(p.subnet, 'extra_dhcp_options'):
                             entries.update(p.subnet.extra_dhcp_options)
                         options.update(d.create_dhcp_options(entries, True, True))
                         entries = {}
                         if hasattr(p, 'hostname'):
                             entries[d.OPTION_HOSTNAME] = p.hostname
                         if hasattr(p, 'extra_dhcp_options'):
                             entries.update(p.extra_dhcp_options)
                         options.update(d.create_dhcp_options(entries, True, True))
                         entries = {d.OPTION_SERVER_IDENTIFIER: server_address}
                         options.update(d.create_dhcp_options(entries, True, True))
                         options = dict((k,v) for k,v in options.items() if v is not None)
                         if d.OPTION_LEASE_TIME not in options:
                             options[d.OPTION_LEASE_TIME] = d.create_option_from_value(d.OPTION_LEASE_TIME, d.DHCPTIME_INFINITE)
                         if options[d.OPTION_LEASE_TIME].value != d.DHCPTIME_INFINITE:
                             leasetime = options[d.OPTION_LEASE_TIME].value
                             if d.OPTION_T1 not in options and t1 is not None and t1 < leasetime:
                                 options[d.OPTION_T1] = d.create_option_from_value(d.OPTION_T1, t1)
                             if d.OPTION_T2 not in options and t2 is not None and t2 < leasetime:
                                 options[d.OPTION_T1] = d.create_option_from_value(d.OPTION_T1, t2)
                         dhcp_entries[pid] = (mac_addr(mac_address), ip4_addr(ip_address),
                                             ip4_addr(server_address), options)
                     except Exception:
                         self._logger.warning("Failed to create DHCP options for port id=%r. Will disable DHCP on this port",
                                              p.id, exc_info = True)
         self._dhcpentries = dhcp_entries
         # Create flows
         # For every logical port, create two flows
         ofdef = connection.openflowdef
         vhost = connection.protocol.vhost
         l3 = self._parent._gettableindex('l3input', vhost)
         cmds = []
         if connection.protocol.disablenxext:
             def match_network(nid):
                 return [ofdef.create_oxm(ofdef.OXM_OF_METADATA_W, ((nid & 0xffff) << 32) | (0xffff << 16),
                                         b'\x00\x00\xff\xff\x40\x00\x00\x00')]
         else:
             def match_network(nid):
                 return [ofdef.create_oxm(ofdef.NXM_NX_REG5, nid),
                         ofdef.create_oxm(ofdef.NXM_NX_REG7_W, 0x4000, 0x4000)]
         def _delete_flows(nid):
             return ofdef.ofp_flow_mod(cookie = 0x1,
                                            cookie_mask = 0xffffffffffffffff,
                                            table_id = l3,
                                            command = ofdef.OFPFC_DELETE,
                                            priority = ofdef.OFP_DEFAULT_PRIORITY,
                                            buffer_id = ofdef.OFP_NO_BUFFER,
                                            out_port = ofdef.OFPP_ANY,
                                            out_group = ofdef.OFPG_ANY,
                                            match = ofdef.ofp_match_oxm(
                                                         oxm_fields = 
                                                             match_network(nid) +
                                                             [ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE, ofdef.ETHERTYPE_IP),
                                                             ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO, ofdef.IPPROTO_UDP),
                                                             ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                                                             ]
                                                     )
                                            )
         def _delete_flows2(nid, serveraddr):
             return ofdef.ofp_flow_mod(cookie = 0x1,
                                            cookie_mask = 0xffffffffffffffff,
                                            table_id = l3,
                                            command = ofdef.OFPFC_DELETE,
                                            priority = ofdef.OFP_DEFAULT_PRIORITY,
                                            buffer_id = ofdef.OFP_NO_BUFFER,
                                            out_port = ofdef.OFPP_ANY,
                                            out_group = ofdef.OFPG_ANY,
                                            match = ofdef.ofp_match_oxm(
                                                         oxm_fields = 
                                                             match_network(nid) +
                                                             [ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE, ofdef.ETHERTYPE_IP),
                                                             ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO, ofdef.IPPROTO_UDP),
                                                             ofdef.create_oxm(ofdef.OXM_OF_IPV4_DST,
                                                                              ip4_addr_bytes(serveraddr)),
                                                             ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                                                             ]
                                                     )
                                            )
         def _create_flows(nid):
             return ofdef.ofp_flow_mod(cookie = 0x1,
                                        cookie_mask = 0xffffffffffffffff,
                                        table_id = l3,
                                        command = ofdef.OFPFC_ADD,
                                        priority = ofdef.OFP_DEFAULT_PRIORITY,
                                        buffer_id = ofdef.OFP_NO_BUFFER,
                                        out_port = ofdef.OFPP_ANY,
                                        out_group = ofdef.OFPG_ANY,
                                        match = ofdef.ofp_match_oxm(
                                                     oxm_fields = 
                                                         match_network(nid) +
                                                         [ofdef.create_oxm(ofdef.OXM_OF_ETH_DST_W, b'\x01\x00\x00\x00\x00\x00', b'\x01\x00\x00\x00\x00\x00'),
                                                         ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE, ofdef.ETHERTYPE_IP),
                                                         ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO, ofdef.IPPROTO_UDP),
                                                         ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                                                         ]
                                                 ),
                                        instructions = [
                                             ofdef.ofp_instruction_actions(
                                                         actions = [
                                                             ofdef.ofp_action_output(port = ofdef.OFPP_CONTROLLER,
                                                                                     max_len = ofdef.OFPCML_NO_BUFFER
                                                                                     )
                                                         ]
                                                     )
                                                 ]
                                        )
         def _create_flows2(nid, serveraddr):
             return ofdef.ofp_flow_mod(cookie = 0x1,
                                        cookie_mask = 0xffffffffffffffff,
                                        table_id = l3,
                                        command = ofdef.OFPFC_ADD,
                                        priority = ofdef.OFP_DEFAULT_PRIORITY,
                                        buffer_id = ofdef.OFP_NO_BUFFER,
                                        out_port = ofdef.OFPP_ANY,
                                        out_group = ofdef.OFPG_ANY,
                                        match = ofdef.ofp_match_oxm(
                                                     oxm_fields = match_network(nid) +
                                                         [ofdef.create_oxm(ofdef.OXM_OF_ETH_TYPE, ofdef.ETHERTYPE_IP),
                                                         ofdef.create_oxm(ofdef.OXM_OF_IP_PROTO, ofdef.IPPROTO_UDP),
                                                         ofdef.create_oxm(ofdef.OXM_OF_IPV4_DST,
                                                                          ip4_addr_bytes(serveraddr)),
                                                         ofdef.create_oxm(ofdef.OXM_OF_UDP_DST, 67)
                                                         ]
                                                 ),
                                        instructions = [
                                             ofdef.ofp_instruction_actions(
                                                         actions = [
                                                             ofdef.ofp_action_output(port = ofdef.OFPP_CONTROLLER,
                                                                                     max_len = ofdef.OFPCML_NO_BUFFER
                                                                                     )
                                                         ]
                                                     )
                                                 ]
                                        )
         for n in removevalues:
             if n in lastlognetinfo:
                 nid = lastlognetinfo[n]
                 cmds.append(_delete_flows(nid))
         lastnetdict = dict((n.id,n) for n in lastlognetinfo)
         for serveraddr in lastserveraddresses:
             if serveraddr not in currentserveraddresses:
                 addr, _, networkid, _ = serveraddr
                 if networkid in lastnetdict:
                     n = lastnetdict[networkid]
                     nid = lastlognetinfo[n]
                     cmds.append(_delete_flows2(nid, addr))
         for m in self.execute_commands(connection, cmds):
             yield m
         
         # Remove old ARP entries; Add new ARP entries
         remove_arps = lastserveraddresses.difference(currentserveraddresses)
         if remove_arps:
             for m in callAPI(self, 'arpresponder', 'removeproxyarp', {'connection': connection,
                                                                       'arpentries': remove_arps}):
                 yield m
         add_arps = currentserveraddresses.difference(lastserveraddresses)
         if add_arps:
             for m in callAPI(self, 'arpresponder', 'createproxyarp', {'connection': connection,
                                                                       'arpentries': add_arps}):
                 yield m
         del cmds[:]
         for n in addvalues:
             if n in currentlognetinfo:
                 nid = currentlognetinfo[n]
                 cmds.append(_create_flows(nid))
         currnetdict = dict((n.id,n) for n in currentlognetinfo)
         for serveraddr in currentserveraddresses:
             if serveraddr not in lastserveraddresses:
                 addr, _, networkid, _ = serveraddr
                 if networkid in currnetdict:
                     n = currnetdict[networkid]
                     nid = currentlognetinfo[n]
                     cmds.append(_create_flows2(nid, addr))
         for m in self.execute_commands(connection, cmds):
             yield m
     except Exception:
         self._logger.warning("Unexpected exception in DHCPUpdater. Will ignore and continue.", exc_info = True)