def alloc_port(src_ip, src_port, dst_ip, dst_port, switch, switch_port):
    """
    Allocate a temporary EIP:port for this flow
    """
    handler = DBHandler()
    if src_port == 0:
        return
    nat_rule = handler.get(int_ip=src_ip)
    if nat_rule:
        eip = nat_rule[0].get('ext_ip')
        for port in range(1, 65536):
            if port not in used_ports.get(eip).keys():
                #get unused flow ID
                for flowid in range(0, 999):
                    if flowid not in used_flowid:
                        used_flowid.append(flowid)
                        break
                else:
                    return 'ERROR'
                used_ports.get(eip)[port] = (src_ip, src_port, dst_ip, dst_port, flowid)
                #set SNAT flow
                egress_flow = [src_ip, src_port, dst_ip, dst_port]
                of_handler.set_snat(egress_flow, eip, port, 1000 + flowid, switch)
                #set DNAT flow
                ingress_flow = [dst_ip, dst_port, eip, port]
                of_handler.set_dnat(ingress_flow, src_ip, src_port, 2000 + flowid, switch, switch_port)
                #set ROUTE flow
                of_handler.set_route(ingress_flow, int(switch) + 1, 3000 + flowid, GWID)
                return json.dumps([eip, port])
    return 'ERROR'
def get_nat():
    """
    return all NAT rules
    """
    handler = DBHandler()
    ret = handler.get()
    if ret:
        return json.dumps(ret)
    else:
        return ''
def unbind_eip(bindings):
    """
    Delete NAT rules for each internal IP to EIP
    """
    global used_ports
    handler = DBHandler()
    for int_ip in bindings['int_ip']:
        handler.add(int_ip)
    if not len(handler.get(ext_ip=bindings['ext_ip'])):
        used_ports.pop(bindings['ext_ip'])
def expire_port(src_ip, src_port, dst_ip, dst_port, switch, switch_port):
    """
    Expire a temporary EIP:port for this flow
    """
    handler = DBHandler()
    nat_rule = handler.get(int_ip=src_ip)
    if nat_rule:
        eip = nat_rule[0].get('ext_ip')
        for port in used_ports.get(eip):
            if used_ports.get(eip).get(port)[:4] == (src_ip, src_port, dst_ip, dst_port):
                flow = used_ports.get(eip).pop(port)
                flowid = flow.pop(4)
                #set flowid unused
                used_flowid.remove(flowid)
                #rm ROUTE flow
                ingress_flow = [dst_ip, dst_port, eip, src_port]
                of_handler.set_route(ingress_flow, switch + 1, flowid, GWID, method='DELETE')
    return 'OK'