Просмотр исходного кода

[components][net] 1.网卡可卸载 2.dhcpd 服务可停止

tangyuxin 5 лет назад
Родитель
Сommit
16304f14a8

+ 1 - 0
components/net/lwip-2.0.2/src/include/netif/ethernetif.h

@@ -41,6 +41,7 @@ extern "C" {
     rt_err_t eth_device_init(struct eth_device * dev, const char *name);
     rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flag);
     rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up);
+    void eth_device_deinit(struct eth_device *dev);
 
     int eth_system_device_init(void);
 

+ 32 - 0
components/net/lwip-2.0.2/src/netif/ethernetif.c

@@ -333,6 +333,19 @@ static int netdev_add(struct netif *lwip_netif)
     return result;
 }
 
+static void netdev_del(struct netif *lwip_netif)
+{
+    char name[LWIP_NETIF_NAME_LEN + 1];
+    struct netdev *netdev;
+
+    RT_ASSERT(lwip_netif);
+
+    rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
+    netdev = netdev_get_by_name(name);
+    netdev_unregister(netdev);
+    rt_free(netdev);
+}
+
 /* synchronize lwIP network interface device and network interface device flags */
 static int netdev_flags_sync(struct netif *lwip_netif)
 {
@@ -538,6 +551,25 @@ rt_err_t eth_device_init(struct eth_device * dev, const char *name)
     return eth_device_init_with_flag(dev, name, flags);
 }
 
+void eth_device_deinit(struct eth_device *dev)
+{
+    struct netif* netif = dev->netif;
+
+#if LWIP_DHCP
+    dhcp_stop(netif);
+    dhcp_cleanup(netif);
+#endif
+    netif_set_down(netif);
+    netif_remove(netif);
+#ifdef RT_USING_NETDEV
+    netdev_del(netif);
+#endif
+    rt_device_close(&(dev->parent));
+    rt_device_unregister(&(dev->parent));
+    rt_sem_detach(&(dev->tx_ack));
+    rt_free(netif);
+}
+
 #ifndef LWIP_NO_RX_THREAD
 rt_err_t eth_device_ready(struct eth_device* dev)
 {

+ 1 - 0
components/net/lwip-2.1.0/src/include/netif/ethernetif.h

@@ -41,6 +41,7 @@ extern "C" {
     rt_err_t eth_device_init(struct eth_device * dev, const char *name);
     rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flag);
     rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up);
+    void eth_device_deinit(struct eth_device *dev);
 
     int eth_system_device_init(void);
 

+ 32 - 0
components/net/lwip-2.1.0/src/netif/ethernetif.c

@@ -334,6 +334,19 @@ static int netdev_add(struct netif *lwip_netif)
     return result;
 }
 
+static void netdev_del(struct netif *lwip_netif)
+{
+    char name[LWIP_NETIF_NAME_LEN + 1];
+    struct netdev *netdev;
+
+    RT_ASSERT(lwip_netif);
+
+    rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
+    netdev = netdev_get_by_name(name);
+    netdev_unregister(netdev);
+    rt_free(netdev);
+}
+
 /* synchronize lwIP network interface device and network interface device flags */
 static int netdev_flags_sync(struct netif *lwip_netif)
 {
@@ -543,6 +556,25 @@ rt_err_t eth_device_init(struct eth_device * dev, const char *name)
     return eth_device_init_with_flag(dev, name, flags);
 }
 
+void eth_device_deinit(struct eth_device *dev)
+{
+    struct netif* netif = dev->netif;
+
+#if LWIP_DHCP
+    dhcp_stop(netif);
+    dhcp_cleanup(netif);
+#endif
+    netif_set_down(netif);
+    netif_remove(netif);
+#ifdef RT_USING_NETDEV
+    netdev_del(netif);
+#endif
+    rt_device_close(&(dev->parent));
+    rt_device_unregister(&(dev->parent));
+    rt_sem_detach(&(dev->tx_ack));
+    rt_free(netif);
+}
+
 #ifndef LWIP_NO_RX_THREAD
 rt_err_t eth_device_ready(struct eth_device* dev)
 {

+ 8 - 2
components/net/lwip_dhcpd/dhcp_server.c

@@ -279,6 +279,7 @@ static void dhcpd_thread_entry(void *parameter)
     {
         /* bind failed. */
         DEBUG_PRINTF("bind server address failed, errno=%d\n", errno);
+        closesocket(sock);
         rt_free(recv_data);
         return;
     }
@@ -290,7 +291,13 @@ static void dhcpd_thread_entry(void *parameter)
     {
         bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0,
                               (struct sockaddr *)&client_addr, &addr_len);
-        if (bytes_read < DHCP_MSG_LEN)
+        if (bytes_read <= 0)
+        {
+            closesocket(sock);
+            rt_free(recv_data);
+            return;
+        }
+        else if (bytes_read < DHCP_MSG_LEN)
         {
             DEBUG_PRINTF("packet too short, wait for next!\n");
             continue;
@@ -546,4 +553,3 @@ void dhcpd_start(const char *netif_name)
         rt_thread_startup(thread);
     }
 }
-

+ 1 - 0
components/net/lwip_dhcpd/dhcp_server.h

@@ -44,6 +44,7 @@ extern "C" {
 #endif
 
 void dhcpd_start(const char *netif_name);
+void dhcpd_stop(const char *netif_name);
 
 #ifdef __cplusplus
 }

+ 80 - 2
components/net/lwip_dhcpd/dhcp_server_raw.c

@@ -666,6 +666,7 @@ dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end)
     return ERR_OK;
 }
 
+extern void set_if(const char *netif_name, const char *ip_addr, const char *gw_addr, const char *nm_addr);
 
 void dhcpd_start(const char *netif_name)
 {
@@ -701,8 +702,6 @@ void dhcpd_start(const char *netif_name)
 
     if (1)
     {
-        extern void set_if(const char *netif_name, const char *ip_addr, const char *gw_addr, const char *nm_addr);
-
         dhcp_stop(netif);
 
         set_if(netif_name, DHCPD_SERVER_IP, "0.0.0.0", "255.255.255.0");
@@ -750,4 +749,83 @@ _exit:
     return;
 }
 
+void dhcpd_stop(const char *netif_name)
+{
+    struct dhcp_server *dhcp_server, *server_node;
+    struct netif *netif = netif_list;
+    struct dhcp_client_node *node, *next;
+
+    DEBUG_PRINTF("%s: %s\r\n", __FUNCTION__, netif_name);
+
+    LWIP_NETIF_LOCK();
+    if (strlen(netif_name) > sizeof(netif->name))
+    {
+        DEBUG_PRINTF("network interface name too long!\r\n");
+        goto _exit;
+    }
+
+    while (netif != RT_NULL)
+    {
+        if (strncmp(netif_name, netif->name, sizeof(netif->name)) == 0)
+            break;
+
+        netif = netif->next;
+        if (netif == RT_NULL)
+        {
+            DEBUG_PRINTF("network interface: %s not found!\r\n", netif_name);
+            break;
+        }
+    }
+
+    if (netif == RT_NULL)
+    {
+        goto _exit;
+    }
 
+    /* If this netif alreday use the dhcp server. */
+    for (dhcp_server = lw_dhcp_server; dhcp_server != NULL; dhcp_server = dhcp_server->next)
+    {
+        if (dhcp_server->netif == netif)
+        {
+            break;
+        }
+    }
+    if (dhcp_server == RT_NULL)
+    {
+        goto _exit;
+    }
+
+    /* remove dhcp server */
+    if (dhcp_server == lw_dhcp_server)
+    {
+        lw_dhcp_server = lw_dhcp_server->next;
+    }
+    else
+    {
+        server_node = lw_dhcp_server;
+        while (server_node->next && server_node->next != dhcp_server)
+        {
+            server_node = server_node->next;
+        }
+        if (server_node->next != RT_NULL)
+        {
+            server_node->next = server_node->next->next;
+        }
+    }
+
+    udp_disconnect(dhcp_server->pcb);
+    udp_remove(dhcp_server->pcb);
+
+    /* remove all client node */
+    for (node = dhcp_server->node_list; node != NULL; node = next)
+    {
+        next = node->next;
+        mem_free(node);
+    }
+
+    mem_free(dhcp_server);
+    set_if(netif_name, "0.0.0.0", "0.0.0.0", "0.0.0.0");
+
+_exit:
+    LWIP_NETIF_UNLOCK();
+}

+ 31 - 10
components/net/netdev/src/netdev.c

@@ -99,7 +99,7 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data)
 
     rt_hw_interrupt_enable(level);
 
-    return RT_EOK;    
+    return RT_EOK;
 }
 
 /**
@@ -118,7 +118,7 @@ int netdev_unregister(struct netdev *netdev)
     struct netdev *cur_netdev = RT_NULL;
 
     RT_ASSERT(netdev);
-    
+
     if (netdev_list == RT_NULL)
     {
         return -RT_ERROR;
@@ -129,18 +129,35 @@ int netdev_unregister(struct netdev *netdev)
     for (node = &(netdev_list->list); node; node = rt_slist_next(node))
     {
         cur_netdev = rt_slist_entry(node, struct netdev, list);
-        if (cur_netdev && (rt_memcmp(cur_netdev, netdev, sizeof(struct netdev)) == 0))
+        if (cur_netdev == netdev)
         {
-            rt_slist_remove(&(netdev_list->list), &(cur_netdev->list));
-            rt_hw_interrupt_enable(level);
-
-            return RT_EOK;
+            /* find this network interface device in network interface device list */
+            if (netdev_list == netdev && rt_slist_next(&netdev_list->list) == RT_NULL)
+            {
+                netdev_list = RT_NULL;
+            }
+            else
+            {
+                rt_slist_remove(&(netdev_list->list), &(cur_netdev->list));
+            }
+            if (netdev_default == netdev)
+            {
+                netdev_default = netdev_list;
+            }
+            break;
         }
     }
-
     rt_hw_interrupt_enable(level);
 
-    /* not find this network interface device in network interface device list */
+    if (cur_netdev == netdev)
+    {
+#ifdef RT_USING_SAL
+        extern int sal_netdev_cleanup(struct netdev *netdev);
+        sal_netdev_cleanup(netdev);
+#endif
+        rt_memset(netdev, 0, sizeof(*netdev));
+    }
+
     return -RT_ERROR;
 }
 
@@ -678,6 +695,10 @@ void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, con
 
     RT_ASSERT(dns_server);
 
+    if (netdev == RT_NULL)
+    {
+        return;
+    }
     /* check DNS servers is exist */
     for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
     {
@@ -687,7 +708,7 @@ void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, con
         }
     }
 
-    if (netdev && dns_num < NETDEV_DNS_SERVERS_NUM)
+    if (dns_num < NETDEV_DNS_SERVERS_NUM)
     {
         ip_addr_copy(netdev->dns_servers[dns_num], *dns_server);
 

+ 31 - 0
components/net/sal_socket/src/sal_socket.c

@@ -350,6 +350,37 @@ static void sal_unlock(void)
     rt_mutex_release(&sal_core_lock);
 }
 
+/**
+ * This function will clean the netdev.
+ *
+ * @note please don't invoke it on ISR.
+ */
+int sal_netdev_cleanup(struct netdev *netdev)
+{
+    int idx = 0, find_dev;
+
+    do
+    {
+        find_dev = 0;
+        sal_lock();
+        for (idx = 0; idx < socket_table.max_socket; idx++)
+        {
+            if (socket_table.sockets[idx] && socket_table.sockets[idx]->netdev == netdev)
+            {
+                find_dev = 1;
+                break;
+            }
+        }
+        sal_unlock();
+        if (find_dev)
+        {
+            rt_thread_mdelay(rt_tick_from_millisecond(100));
+        }
+    } while (find_dev);
+
+    return 0;
+}
+
 /**
  * This function will initialize sal socket object and set socket options
  *