diff --git a/srcs/include/pppoe_info.h b/srcs/include/pppoe_info.h
index 42b7d0d..d755ae2 100644
--- a/srcs/include/pppoe_info.h
+++ b/srcs/include/pppoe_info.h
@@ -82,6 +82,7 @@ typedef struct {
 typedef struct {
     unsigned int  userid;
     VXLAN_TAG     vxlan;
+    unsigned char mac_addr[6];
     USER_INFO     user_info;
     PPPOE_SESSION session;
 
@@ -89,6 +90,7 @@ typedef struct {
 
     UT_hash_handle hh_id;
     UT_hash_handle hh_vxlan;
+    UT_hash_handle hh_mac;
 } USER_INFO_CONTEXT, *PUSER_INFO_CONTEXT;
 
 int           pppoe_session_create(PUSER_INFO_CONTEXT pUser);
diff --git a/srcs/include/user_info.h b/srcs/include/user_info.h
index 1cd3cee..86c73c5 100644
--- a/srcs/include/user_info.h
+++ b/srcs/include/user_info.h
@@ -19,6 +19,8 @@ void               user_info_change_status(PUSER_INFO_CONTEXT pInfo, USER_STATUS
 PUSER_INFO_CONTEXT get_all_user_by_id();
 PUSER_INFO_CONTEXT get_all_user_by_tag();
 uv_rwlock_t       *get_user_lock();
+PUSER_INFO_CONTEXT get_user_by_tag(PVXLAN_TAG pTag);
+struct netif      *get_user_nic_by_mac(const unsigned char mac[6]);
 #ifdef __cplusplus
 }
 #endif
diff --git a/srcs/libs/mq/mq_data.c b/srcs/libs/mq/mq_data.c
index 1764fdc..2ea6a51 100644
--- a/srcs/libs/mq/mq_data.c
+++ b/srcs/libs/mq/mq_data.c
@@ -54,6 +54,7 @@ typedef struct {
 
 static PMQ_DATA_MSG create_mq_data_msg(PMQ_DATA_MSG *pMsg) {
     *pMsg = (PMQ_DATA_MSG)malloc(sizeof(MQ_DATA_MSG));
+    memset(*pMsg, 0, sizeof(MQ_DATA_MSG));
     return *pMsg;
 }
 
@@ -241,7 +242,6 @@ static void process_data_msg(void *UNUSED(pDataCh), zmq_msg_t *pMsg) {
             PMQ_DATA_ADD_USER p = NULL;
             dzlog_debug("Process: %s\n", pMqMsg->params);
             decode_add_user_msg(pMqMsg->params, &p);
-
             if (p) {
                 int m, n;
                 for (m = 0; m < p->infoCount; m++) {
diff --git a/srcs/lwip/src/arch_linux/netif/pcapif.c b/srcs/lwip/src/arch_linux/netif/pcapif.c
index 4c5e3ce..23425f5 100644
--- a/srcs/lwip/src/arch_linux/netif/pcapif.c
+++ b/srcs/lwip/src/arch_linux/netif/pcapif.c
@@ -51,14 +51,11 @@
 #include "lwip/vxlan.h"
 #include "user_info.h"
 #include "lwip/tcpip.h"
-#include "netif/pppoeif.h"
 #include "misc.h"
 
 #if defined(LWIP_UNIX_LINUX)
 #include <linux/if.h>
 #include <zmq.h>
-#include <uv/unix.h>
-#include <uv.h>
 
 /* Define those to better describe your network interface. */
 #define IFNAME0 'p'
@@ -178,9 +175,9 @@ static void low_level_init(struct netif *netif) {
 
 static err_t low_level_output(struct netif *netif, struct pbuf *p) {
     unsigned char      buf[1518]; /* max packet size including VLAN excluding CRC */
-    ssize_t            written = 0;
-    struct pcapif     *pcapif  = (struct pcapif *)netif->state;
-    PUSER_INFO_CONTEXT pUser   = (PUSER_INFO_CONTEXT)p->extra;
+    ssize_t            written;
+    struct pcapif     *pcapif = (struct pcapif *)netif->state;
+    PUSER_INFO_CONTEXT pUser  = (PUSER_INFO_CONTEXT)p->extra;
 
     if (p->tot_len > sizeof(buf)) {
         MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
@@ -308,10 +305,11 @@ static void link_callback(struct netif *state_netif) {
 #endif /* LWIP_NETIF_LINK_CALLBACK */
 
 static err_t netif_input_data(struct pbuf *p, struct netif *inp) {
-    err_t                err = ERR_OK;
-    struct netif        *netif;
-    struct pcapif       *pcapif = (struct pcapif *)inp->state;
-    const unsigned char *pBuf   = (const unsigned char *)p->payload;
+    err_t                 err;
+    struct netif         *netif;
+    struct pcapif        *pcapif = (struct pcapif *)inp->state;
+    const unsigned char  *pBuf   = (const unsigned char *)p->payload;
+    const struct eth_hdr *eth    = (const struct eth_hdr *)p->payload;
 
     if (pcapif->vxlan_support) {
         const struct vxlan_package *pkg = (const struct vxlan_package *)pBuf;
@@ -323,14 +321,13 @@ static err_t netif_input_data(struct pbuf *p, struct netif *inp) {
         tag.q1  = lwip_ntohs(pkg->qinq_head.out_priority_cfi_and_id);
         tag.q2  = lwip_ntohs(pkg->qinq_head.in_priority_cfi_and_id);
 
-        HASH_FIND(hh_vxlan, get_all_user_by_tag(), &tag, sizeof(VXLAN_TAG), pContext);
+        pContext = get_user_by_tag(&tag);
+        //HASH_FIND(hh_vxlan, get_all_user_by_tag(), &tag, sizeof(VXLAN_TAG), pContext);
 
         if (pContext && pContext->session.pppif) {
             vxlan_pkg_decode(p, &ebuf, &tag);
 
             if (ebuf == NULL) {
-                struct eth_hdr *eth = (struct eth_hdr *)ebuf->payload;
-
                 if (strlen(pContext->session.data.svrBaseMac) == 0) {
                     if (strlen(pContext->session.data.svrBaseMac) == 0) {
                         sprintf(pContext->session.data.svrBaseMac,
@@ -359,18 +356,16 @@ static err_t netif_input_data(struct pbuf *p, struct netif *inp) {
         return tcpip_input(p, inp);
     }
 
-    // 遍历用户网卡处理数据
-    NETIF_FOREACH(netif) {
+    // 用户网卡处理数据
+    netif = get_user_nic_by_mac(eth->dest.addr);
 
-        if (netif->hwaddr_len == 6 && memcmp(p->payload, netif->hwaddr, netif->hwaddr_len) == 0) {
-
-            if ((err = netif->input(p, netif)) != ERR_OK) {
-                LWIP_DEBUGF(NETIF_DEBUG, ("pppoeif_input: netif input error\n"));
-                pbuf_free(p);
-            }
-
-            return err;
+    if(netif) {
+        if ((err = netif->input(p, netif)) != ERR_OK) {
+            LWIP_DEBUGF(NETIF_DEBUG, ("pppoeif_input: netif input error\n"));
+            pbuf_free(p);
         }
+
+        return err;
     }
 
     // 无用户关联网卡数据直接送协议栈处理
@@ -386,7 +381,6 @@ struct netif *bind_pcap_if(const char *eth_name, const char *pkg_filter, int vxl
     unsigned char      mac[6];
     ip4_addr_t         ipaddr_t, netmask_t, gw_t;
     char               errBuf[PCAP_ERRBUF_SIZE];
-    char               buf[2048];
     unsigned int       ipaddr = 0, gw = 0, netmask = 0;
 
     struct pcapif *pcapif = (struct pcapif *)mem_malloc(sizeof(struct pcapif));
@@ -416,7 +410,6 @@ struct netif *bind_pcap_if(const char *eth_name, const char *pkg_filter, int vxl
     pcapif->pkg_filter = strdup(pkg_filter);
 
     memset(errBuf, 0, PCAP_ERRBUF_SIZE);
-    memset(buf, 0, 2048);
 
     pPcap = pcap_open_live(pcapif->eth_name, MAX_BYTES_PACKAGE, 1, -1, errBuf);
 
@@ -425,11 +418,11 @@ struct netif *bind_pcap_if(const char *eth_name, const char *pkg_filter, int vxl
     }
 
     dzlog_debug("Pcap netif used filter: \"%s\"\n", pcapif->pkg_filter);
-    if (pcap_compile(pPcap, &filter, buf, 1, netmask) == -1) {
-        dzlog_error("Set package fileter[%s] error: %s\n", buf, pcap_geterr(pPcap));
+    if (pcap_compile(pPcap, &filter, pcapif->pkg_filter, 1, netmask) == -1) {
+        dzlog_error("Set package fileter[%s] error: %s\n", pcapif->pkg_filter, pcap_geterr(pPcap));
     }
     if (pcap_setfilter(pPcap, &filter) == -1) {
-        dzlog_error("Set package fileter[%s] error: %s\n", buf, pcap_geterr(pPcap));
+        dzlog_error("Set package fileter[%s] error: %s\n", pcapif->pkg_filter, pcap_geterr(pPcap));
     }
 
     pcapif->pcap = pPcap;
diff --git a/srcs/user/user_info.c b/srcs/user/user_info.c
index eb5fbf0..2074dea 100644
--- a/srcs/user/user_info.c
+++ b/srcs/user/user_info.c
@@ -8,6 +8,7 @@
 
 static PUSER_INFO_CONTEXT g_pUserByIdList   = NULL;
 static PUSER_INFO_CONTEXT g_pUserByTagsList = NULL;
+static PUSER_INFO_CONTEXT g_pUserByMacList  = NULL;
 static uv_rwlock_t        g_userLock;
 
 static USER_PARAMS g_userInfo[] = {
@@ -57,6 +58,7 @@ int user_info_add(unsigned int userid, PUSER_PARAMS pInfo) {
         pList->vxlan.q2               = pInfo->q2;
         pList->user_info.pppoe_user   = strdup(pInfo->pppoe_user);
         pList->user_info.pppoe_passwd = strdup(pInfo->pppoe_passwd);
+        memcpy(pList->mac_addr, pInfo->mac_addr, 6);
         memcpy(pList->user_info.mac_addr, pInfo->mac_addr, 6);
 
         pList->session.status = STATUS_TASK_INIT;
@@ -64,19 +66,55 @@ int user_info_add(unsigned int userid, PUSER_PARAMS pInfo) {
         uv_rwlock_wrlock(&g_userLock);
         HASH_ADD(hh_id, g_pUserByIdList, userid, sizeof(unsigned int), pList);
         HASH_ADD(hh_vxlan, g_pUserByTagsList, vxlan, sizeof(VXLAN_TAG), pList);
+        HASH_ADD(hh_mac, g_pUserByMacList, mac_addr, 6, pList);
         uv_rwlock_wrunlock(&g_userLock);
 
-        dzlog_debug("Add user: id = %u, vni = %u, q1 = %u, q2 = %u ppp_user = %s\n",
+        dzlog_debug("Add user: id = %u, vni = %u, q1 = %u, q2 = %u, ppp_user = %s, mac = %02X:%02X:%02X:%02X:%02X:%02X\n",
                     userid,
                     pInfo->vni,
                     pInfo->q1,
                     pInfo->q2,
-                    pInfo->pppoe_user);
+                    pInfo->pppoe_user,
+                    pList->mac_addr[0],
+                    pList->mac_addr[1],
+                    pList->mac_addr[2],
+                    pList->mac_addr[3],
+                    pList->mac_addr[4],
+                    pList->mac_addr[5]);
     }
 
     return ERR_SUCCESS;
 }
 
+struct netif *get_user_nic_by_mac(const unsigned char mac[6]) {
+    PUSER_INFO_CONTEXT pUser;
+    uv_rwlock_rdlock(&g_userLock);
+    HASH_FIND(hh_mac, g_pUserByMacList, mac, 6, pUser);
+    uv_rwlock_rdunlock(&g_userLock);
+
+    if (pUser) {
+        return pUser->session.nicif;
+    }
+
+    return NULL;
+}
+
+PUSER_INFO_CONTEXT get_user_by_tag(PVXLAN_TAG pTag) {
+    if (pTag) {
+        PUSER_INFO_CONTEXT pUser;
+
+        uv_rwlock_rdlock(&g_userLock);
+        HASH_FIND(hh_vxlan, g_pUserByTagsList, pTag, sizeof(VXLAN_TAG), pUser);
+        uv_rwlock_rdunlock(&g_userLock);
+
+        if (pUser) {
+            return pUser;
+        }
+    }
+
+    return NULL;
+}
+
 void user_info_remove(unsigned int userid) {
     PUSER_INFO_CONTEXT pInfo;