Exemple #1
0
def check_ip_address(ipaddress):
    try:
        ip4_addr(ipaddress)
    except Exception:
        raise ValueError(" ip address illegal " + ipaddress)

    return ipaddress
Exemple #2
0
def parser_ip_address(ipaddress):
    try:
        ip4_addr(ipaddress)
    except Exception:
        raise ValueError(" ip address illegal " + ipaddress)

    return ipaddress
Exemple #3
0
            def packet_out_free_arp(logicalport, logicalnet, logicalnetid,
                                    phyportid):
                egress = self._parent._gettableindex(
                    "egress", self._connection.protocol.vhost)
                arp_request_packet = arp_packet_l4(
                    dl_src=mac_addr(logicalport.mac_address),
                    dl_dst=mac_addr("FF:FF:FF:FF:FF:FF"),
                    arp_op=ofdef.ARPOP_REQUEST,
                    arp_sha=mac_addr(logicalport.mac_address),
                    arp_spa=ip4_addr(logicalport.ip_address),
                    arp_tpa=ip4_addr(logicalport.ip_address))

                return ofdef.ofp_packet_out(
                    buffer_id=ofdef.OFP_NO_BUFFER,
                    in_port=ofdef.OFPP_CONTROLLER,
                    actions=[
                        ofdef.ofp_action_set_field(field=ofdef.create_oxm(
                            ofdef.NXM_NX_REG4, logicalnetid)),
                        ofdef.ofp_action_set_field(field=ofdef.create_oxm(
                            ofdef.NXM_NX_REG5, logicalnetid)),
                        ofdef.ofp_action_set_field(field=ofdef.create_oxm(
                            ofdef.NXM_NX_REG6, phyportid)),
                        ofdef.ofp_action_set_field(
                            field=ofdef.create_oxm(ofdef.NXM_NX_REG7, 0x4000)),
                        ofdef.nx_action_resubmit(table=egress)
                    ],
                    data=arp_request_packet._tobytes())
Exemple #4
0
def check_ip_address(ipaddress):
    try:
        ip = ip4_addr(ipaddress)
    except Exception:
        raise ValueError("Invalid IP address " + ipaddress)

    return ip
Exemple #5
0
 def generate_route(r):
     r_g = {'Destination': r[0]}
     if ip4_addr(r[1]) == 0:
         r_g['RouteType'] = 1
     else:
         r_g['RouteType'] = 0
         r_g['NextHop'] = r[1]
Exemple #6
0
        def delete_interface(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(routerportkeys):]
            rpobjs = values[-len(routerportkeys):]

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

            for interface in delete_interfaces:
                r = rdict.get(VRouter.default_key(interface["router"]), None)
                sn = sndict.get(SubNet.default_key(interface["subnet"]), None)
                snm = snmdict.get(SubNetMap.default_key(interface["subnet"]),
                                  None)
                rp = rpdict.get(
                    RouterPort.default_key(interface["routerport"]), None)

                if r and sn and snm and rp:
                    # has not attr ip_address, means router port use subnet gateway as ip_address
                    if hasattr(rp, 'ip_address'):
                        # it means have allocated ip address in subnetmap, delete it
                        ipaddress = ip4_addr(rp.ip_address)
                        del snm.allocated_ips[str(ipaddress)]

                    # one subnet only have one router , so del this attr
                    if hasattr(sn, 'router'):
                        delattr(sn, 'router')

                    if rp.create_weakreference() in r.interfaces.dataset():
                        r.interfaces.dataset().discard(
                            rp.create_weakreference())
                    else:
                        raise ValueError("router " + interface["router"] +
                                         " have no router port " +
                                         interface["routerport"])
                else:
                    raise ValueError("route " + interface["router"] +
                                     " subnet " + interface["subnet"] +
                                     " routerport " + interface["routerport"] +
                                     " not existed!")

            return keys, robjs + snobjs + snmobjs + [None
                                                     ] * len(routerportkeys)
Exemple #7
0
def parse_ip4_network( network ):

    ip,f,prefix = network.rpartition('/')
    if not f or not prefix:
        raise ValueError('invalid cidr ' + network)
    if not 0 <= int(prefix) <= 32:
        raise ValueError("invalid prefix " + prefix)

    netmask = get_netmask(prefix)

    value = ip4_addr(ip)
    return value & netmask,int(prefix)
Exemple #8
0
def parse_ip4_network( network ):

    ip,f,prefix = network.rpartition('/')
    if not f:
        raise ValueError('invalid cidr ' + prefix)
    if not 0 <= int(prefix) <= 32:
        raise ValueError("invalid prefix " + prefix)

    netmask = get_netmask(prefix)

    value = ip4_addr(ip)
    return value & netmask,int(prefix)
Exemple #9
0
        def removerouterinterface(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(subnetmapkeys) + len(subnetmapkeys)]

            rportkeys = keys[len(routerkeys) + len(subnetkeys) + len(subnetmapkeys):]
            rportobjs = values[len(routerkeys) + len(subnetkeys) + len(subnetmapkeys):]

            # we get (routerkeys,routerobjs) on begin to get (router , subnet) attr
            # this is second get (routerkeys,routerobjs) , if (router,subnet) is different from last, Nothing can do!
            if [r.router.getkey() for r in routerportobjs] !=\
                    [r.router.getkey() if r is not None else None for r in rportobjs] and\
                [r.subnet.getkey() for r in routerportobjs] !=\
                    [r.subnet.getkey() if r is not None else None for r in  rportobjs]:
                raise ValueError(" conflict error, try again!")
 
            rdict = dict(zip(rkeys,robjs))
            sndict = dict(zip(snkeys,zip(snobjs,snmobjs)))

            rportdict = dict(zip(rportkeys,rportobjs))
            

            for interface in deleteinterfaces:
                routerobj = rdict[VRouter.default_key(interface['router'])]
                subnetobj,subnetmapobj = sndict[SubNet.default_key(interface['subnet'])]
                rportobj = rportdict[RouterPort.default_key(interface['id'])]

                if routerobj and subnetobj and subnetmapobj:

                    # has not attr ip_address, means router port use subnet gateway as ip_address
                    if hasattr(rportobj,'ip_address'):
                        # it means have allocated ip address in subnetmap, delete it
                        ipaddress = ip4_addr(rportobj.ip_address)
                        del subnetmapobj.allocated_ips[str(ipaddress)]

                    # one subnet only have one router , so del this attr
                    if hasattr(subnetobj,'router'):
                        delattr(subnetobj,'router')

                    routerobj.interfaces.dataset().discard(rportobj.create_weakreference())
                else:
                    raise ValueError(" interface router " + interface['router']\
                                     + "or subnet " + interface['subnet'] + "not existed")

            return keys,robjs + snobjs + snmobjs + [None] * len(routerportkeys)
    async def ipam_releaseaddress(self, env, params):
        poolid = params['PoolID']
        address = params['Address']
        address = ip4_addr.formatter(ip4_addr(address))

        def _updater(keys, values, timestamp):
            pool = values[0]
            if pool is None:
                return ((), ())
            self._remove_staled_ips(pool, timestamp)
            if address in pool.reserved_ips:
                del pool.reserved_ips[address]
            return ((keys[0], ), (pool, ))

        await call_api(
            self, 'objectdb', 'transact', {
                'keys': (IPAMReserve.default_key(poolid), ),
                'updater': _updater,
                'withtime': True
            })
        env.outputjson({})
Exemple #11
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
Exemple #12
0
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))
Exemple #13
0
                      prepack = _prepack_dhcp_option,
                      padding = 1
                      )

dhcp_option_single_byte = nstruct(name = 'dhcp_option_single_byte',
                                  base = dhcp_option,
                                  criteria = lambda x: x.tag in (OPTION_PAD, OPTION_END),
                                  init = packvalue(OPTION_PAD, 'tag'))

dhcp_option_address = nstruct((ip4_addr, 'value'),
                                 name = 'dhcp_option_address',
                                 base = dhcp_option,
                                 criteria = lambda x: x.tag in (OPTION_NETMASK, OPTION_REQUESTED_IP, OPTION_SERVER_IDENTIFIER, OPTION_BROADCAST),
                                 init = packvalue(OPTION_NETMASK, 'tag'))

dhcp_option_address._parse_from_value = lambda x: ip4_addr(x)

dhcp_time_value = enum('dhcp_time_value', globals(), uint32,
                       DHCPTIME_INFINITE = 0xffffffff
                  )

dhcp_option_time = nstruct((dhcp_time_value, 'value'),
                             name = 'dhcp_option_time',
                             base = dhcp_option,
                             criteria = lambda x: x.tag in (OPTION_TIME_OFFSET, OPTION_LEASE_TIME, OPTION_T1, OPTION_T2),
                             init = packvalue(OPTION_LEASE_TIME, 'tag')
                             )

dhcp_option_time._parse_from_value = lambda x: int(x) if x is not None and x != 'infinity' else DHCPTIME_INFINITE

dhcp_option_servers = nstruct((ip4_addr[0], 'value'),
Exemple #14
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)
Exemple #15
0
def _get_ip(ip):
    try:
        return ip4_addr(ip)
    except Exception:
        return None
Exemple #16
0
    def createendpoint(self, env, params):
        lognet_id = 'docker-' + params['NetworkID'] + '-lognet'
        subnet_id = 'docker-' + params['NetworkID'] + '-subnet'
        logport_id = 'docker-' + params['EndpointID']
        logport_params = {}
        if 'Options' in params:
            logport_params.update(params['Options'])
        logport_params['id'] = logport_id
        logport_params['logicalnetwork'] = lognet_id
        logport_params['subnet'] = subnet_id
        mac_address = None
        if 'Interface' in params:
            interface = params['Interface']
            if 'Address' in interface and interface['Address']:
                ip, f, prefix = interface['Address'].partition('/')
                logport_params['ip_address'] = ip
            else:
                ip = None
            if 'MacAddress' in interface and interface['MacAddress']:
                logport_params['mac_address'] = interface['MacAddress']
                mac_address = interface['MacAddress']
        if mac_address is None:
            # Generate a MAC address
            if ip:
                # Generate MAC address based on IP address
                mac_num = self._macbase
                mac_num ^= ((hash(subnet_id) & 0xffffffff) << 8)
                mac_num ^= ip4_addr(ip)
            else:
                # Generate MAC address based on Port ID and random number
                mac_num = self._macbase
                mac_num ^= ((hash(logport_id) & 0xffffffff) << 8)
                mac_num ^= randint(0, 0xffffffff)
            mac_address = mac_addr_bytes.formatter(create_binary(mac_num, 6))
            logport_params['mac_address'] = mac_address
        try:
            for m in callAPI(self, 'viperflow', 'createlogicalport',
                             logport_params):
                yield m
        except Exception as exc:
            # There is an issue that docker daemon may not delete an endpoint correctly
            # If autoremoveports is enabled, we remove the logical port automatically
            # Note that created veth and Openvswitch ports are not cleared because they
            # may not on this server, so you must clean them yourself with vlcp_docker.cleanup
            if self._parent.autoremoveports:
                for m in callAPI(self, 'viperflow', 'listlogicalports', {
                        'logicalnetwork': lognet_id,
                        'ip_address': ip
                }):
                    yield m
                if self.retvalue:
                    if self.retvalue[0]['id'].startswith('docker-'):
                        dup_pid = self.retvalue[0]['id']
                        self._logger.warning(
                            'Duplicated ports detected: %s (%s). Will remove it.',
                            dup_pid, self.retvalue[0]['ip_address'])
                        for m in callAPI(self, 'viperflow',
                                         'deletelogicalport', {'id': dup_pid}):
                            yield m
                        # Retry create logical port
                        for m in callAPI(self, 'viperflow',
                                         'createlogicalport', logport_params):
                            yield m
                    else:
                        self._logger.warning(
                            'Duplicated with a non-docker port')
                        raise exc
                else:
                    raise exc
            else:
                raise exc
        ip_address = self.retvalue[0]['ip_address']
        subnet_cidr = self.retvalue[0]['subnet']['cidr']
        mtu = self.retvalue[0]['network'].get('mtu', self._parent.mtu)
        _, _, prefix = subnet_cidr.partition('/')
        if 'docker_ipam_poolid' in self.retvalue[0]['subnet']:
            docker_ipam_poolid = self.retvalue[0]['subnet'][
                'docker_ipam_poolid']

            def _remove_ip_reservation():
                try:
                    # The reservation is completed, remove the temporary reservation
                    def _ipam_updater(keys, values, timestamp):
                        pool = values[0]
                        self._remove_staled_ips(pool, timestamp)
                        if ip_address in pool.reserved_ips:
                            del pool.reserved_ips[ip_address]
                        return ((keys[0], ), (pool, ))

                    for m in callAPI(
                            self, 'objectdb', 'transact',
                        {
                            'keys':
                            (IPAMReserve.default_key(docker_ipam_poolid), ),
                            'updater': _ipam_updater,
                            'withtime': True
                        }):
                        yield m
                except Exception:
                    self._logger.warning(
                        'Unexpected exception while removing reservation of IP address %r, will ignore and continue',
                        ip_address,
                        exc_info=True)

            self.subroutine(_remove_ip_reservation())
        port_created = False
        try:
            for m in self._parent.taskpool.runTask(
                    self,
                    lambda: _create_veth(self._parent.ipcommand, self._parent.
                                         vethprefix, mac_address, mtu)):
                yield m
            port_created = True
            device_name, _ = self.retvalue
            info = DockerInfo.create_instance(logport_id)
            info.docker_port = device_name

            @updater
            def _updater(dockerinfo):
                dockerinfo = set_new(dockerinfo, info)
                return (dockerinfo, )

            for m in callAPI(self, 'objectdb', 'transact', {
                    'keys': (info.getkey(), ),
                    'updater': _updater
            }):
                yield m
            for m in self._parent.taskpool.runTask(
                    self,
                    lambda: _plug_ovs(self._parent.ovscommand, self._parent.
                                      ovsbridge, device_name, logport_id)):
                yield m
            result = {'Interface': {'MacAddress': mac_address}}
            if 'Address' not in interface:
                result['Interface']['Address'] = ip_address + '/' + prefix
            env.outputjson(result)
        except Exception as exc:
            try:
                if port_created:
                    for m in self._parent.taskpool.runTask(
                            self, lambda: _delete_veth(self._parent.ipcommand,
                                                       device_name)):
                        yield m
            except Exception:
                pass
            try:
                for m in callAPI(self, 'viperflow', 'deletelogicalport',
                                 {'id': logport_id}):
                    yield m
            except Exception:
                pass
            raise exc
Exemple #17
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, ))
Exemple #18
0
    def ipam_requestaddress(self, env, params):
        poolid = params['PoolID']
        address = params['Address']
        if address:
            address = ip4_addr.formatter(ip4_addr(address))
        reserve_key = IPAMReserve.default_key(poolid)
        rets = []

        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, ))

        while True:
            # First get the current data, to determine that whether the pool has already
            # been connected to a network
            self._reqid += 1
            reqid = ('dockerplugin_ipam', self._reqid)
            for m in callAPI(self, 'objectdb', 'get', {
                    'key': reserve_key,
                    'requestid': reqid,
                    'nostale': True
            }):
                yield m
            reserve_pool = self.retvalue
            with watch_context([reserve_key], [reserve_pool], reqid, self):
                if reserve_pool is None or reserve_pool.isdeleted():
                    raise ValueError('PoolID %r does not exist' % (poolid, ))
                if hasattr(reserve_pool, 'subnetmap'):
                    # Retrieve both the reserve pool and the subnet map
                    keys = (reserve_key, reserve_pool.subnetmap.getkey(),
                            SubNet.default_key(reserve_pool.subnetmap.id))
                else:
                    keys = (reserve_key, )
                try:
                    for m in callAPI(self, 'objectdb', 'transact', {
                            'keys': keys,
                            'updater': _updater,
                            'withtime': True
                    }):
                        yield m
                except RetryUpdateException:
                    continue
                else:
                    env.outputjson({'Address': rets[0], 'Data': {}})
                    break
Exemple #19
0
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))
Exemple #20
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 = 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)
Exemple #21
0
def parse_ip4_address(address):
    return ip4_addr(address)
Exemple #22
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
Exemple #23
0
    def createendpoint(self, env, params):
        lognet_id = 'docker-' + params['NetworkID'] + '-lognet'
        subnet_id = 'docker-' + params['NetworkID'] + '-subnet'
        logport_id = 'docker-' + params['EndpointID']
        logport_params = {}
        if 'Options' in params:
            logport_params.update(params['Options'])
        logport_params['id'] = logport_id
        logport_params['logicalnetwork'] = lognet_id
        logport_params['subnet'] = subnet_id
        mac_address = None
        if 'Interface' in params:
            interface = params['Interface']
            if 'Address' in interface and interface['Address']:
                ip, f, prefix = interface['Address'].rpartition('/')
                logport_params['ip_address'] = ip
            else:
                ip = None
            if 'MacAddress' in interface and interface['MacAddress']:
                logport_params['mac_address'] = interface['MacAddress']
                mac_address = interface['MacAddress']
        if mac_address is None:
            # Generate a MAC address
            if ip:
                # Generate MAC address based on IP address
                mac_num = self._macbase
                mac_num ^= ((hash(subnet_id) & 0xffffffff) << 8)
                mac_num ^= ip4_addr(ip)
            else:
                # Generate MAC address based on Port ID and random number
                mac_num = self._macbase
                mac_num ^= ((hash(logport_id) & 0xffffffff) << 8)
                mac_num ^= randint(0, 0xffffffff)
            mac_address = mac_addr_bytes.formatter(create_binary(mac_num, 6))
            logport_params['mac_address'] = mac_address
        for m in callAPI(self, 'viperflow', 'createlogicalport',
                         logport_params):
            yield m
        ip_address = self.retvalue[0]['ip_address']
        subnet_cidr = self.retvalue[0]['subnet']['cidr']
        mtu = self.retvalue[0]['network'].get('mtu', self._parent.mtu)
        _, _, prefix = subnet_cidr.partition('/')
        port_created = False
        try:
            for m in self._parent.taskpool.runTask(
                    self,
                    lambda: _create_veth(self._parent.ipcommand, self._parent.
                                         vethprefix, mac_address, mtu)):
                yield m
            port_created = True
            device_name, _ = self.retvalue
            info = DockerInfo.create_instance(logport_id)
            info.docker_port = device_name

            @updater
            def _updater(dockerinfo):
                dockerinfo = set_new(dockerinfo, info)
                return (dockerinfo, )

            for m in callAPI(self, 'objectdb', 'transact', {
                    'keys': (info.getkey(), ),
                    'updater': _updater
            }):
                yield m
            for m in self._parent.taskpool.runTask(
                    self,
                    lambda: _plug_ovs(self._parent.ovscommand, self._parent.
                                      ovsbridge, device_name, logport_id)):
                yield m
            result = {'Interface': {'MacAddress': mac_address}}
            if 'Address' not in interface:
                result['Interface']['Address'] = ip_address + '/' + prefix
            env.outputjson(result)
        except Exception as exc:
            try:
                if port_created:
                    for m in self._parent.taskpool.runTask(
                            self, lambda: _delete_veth(self._parent.ipcommand,
                                                       device_name)):
                        yield m
            except Exception:
                pass
            try:
                for m in callAPI(self, 'viperflow', 'deletelogicalport',
                                 {'id': logport_id}):
                    yield m
            except Exception:
                pass
            raise exc
        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)
Exemple #25
0
                      prepack = _prepack_dhcp_option,
                      padding = 1
                      )

dhcp_option_single_byte = nstruct(name = 'dhcp_option_single_byte',
                                  base = dhcp_option,
                                  criteria = lambda x: x.tag in (OPTION_PAD, OPTION_END),
                                  init = packvalue(OPTION_PAD, 'tag'))

dhcp_option_address = nstruct((ip4_addr, 'value'),
                                 name = 'dhcp_option_address',
                                 base = dhcp_option,
                                 criteria = lambda x: x.tag in (OPTION_NETMASK, OPTION_REQUESTED_IP, OPTION_SERVER_IDENTIFIER, OPTION_BROADCAST),
                                 init = packvalue(OPTION_NETMASK, 'tag'))

dhcp_option_address._parse_from_value = lambda x: ip4_addr(x)

dhcp_time_value = enum('dhcp_time_value', globals(), uint32,
                       DHCPTIME_INFINITE = 0xffffffff
                  )

dhcp_option_time = nstruct((dhcp_time_value, 'value'),
                             name = 'dhcp_option_time',
                             base = dhcp_option,
                             criteria = lambda x: x.tag in (OPTION_TIME_OFFSET, OPTION_LEASE_TIME, OPTION_T1, OPTION_T2),
                             init = packvalue(OPTION_LEASE_TIME, 'tag')
                             )

dhcp_option_time._parse_from_value = lambda x: int(x) if x is not None and x != 'infinity' else DHCPTIME_INFINITE

dhcp_option_servers = nstruct((ip4_addr[0], 'value'),
Exemple #26
0
def parse_ip4_address(address):
    return ip4_addr(address)