Merge pull request #2936 from enkiller/net

[components][net] 1.网卡可卸载 2.dhcpd 服务可停止
This commit is contained in:
Bernard Xiong 2019-08-11 14:33:47 +08:00 committed by GitHub
commit b86333f5a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 217 additions and 14 deletions

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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)
{

View File

@ -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);
}
}

View File

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

View File

@ -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();
}

View File

@ -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);

View File

@ -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
*