10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
40d163575Sopenharmony_ci *
50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
60d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
70d163575Sopenharmony_ci *
80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
90d163575Sopenharmony_ci *    conditions and the following disclaimer.
100d163575Sopenharmony_ci *
110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
120d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
130d163575Sopenharmony_ci *    provided with the distribution.
140d163575Sopenharmony_ci *
150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
160d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
170d163575Sopenharmony_ci *    permission.
180d163575Sopenharmony_ci *
190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
300d163575Sopenharmony_ci */
310d163575Sopenharmony_ci
320d163575Sopenharmony_ci#include <lwip/sys.h>
330d163575Sopenharmony_ci#include <lwip/netif.h>
340d163575Sopenharmony_ci#include <lwip/snmp.h>
350d163575Sopenharmony_ci#include <lwip/etharp.h>
360d163575Sopenharmony_ci#include <lwip/sockets.h>
370d163575Sopenharmony_ci#include <lwip/ethip6.h>
380d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER
390d163575Sopenharmony_ci#include <lwip/tcpip.h>
400d163575Sopenharmony_ci#endif
410d163575Sopenharmony_ci
420d163575Sopenharmony_ci#define LWIP_NETIF_HOSTNAME_DEFAULT         "default"
430d163575Sopenharmony_ci#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS     100000000 // 100Mbps
440d163575Sopenharmony_ci
450d163575Sopenharmony_ci#define link_rx_drop cachehit
460d163575Sopenharmony_ci#define link_rx_overrun cachehit
470d163575Sopenharmony_ci
480d163575Sopenharmony_ci#define LWIP_STATIC static
490d163575Sopenharmony_ci
500d163575Sopenharmony_ci#ifndef LWIP_NETIF_IFINDEX_MAX_EX
510d163575Sopenharmony_ci#define LWIP_NETIF_IFINDEX_MAX_EX 255
520d163575Sopenharmony_ci#endif
530d163575Sopenharmony_ci
540d163575Sopenharmony_ciLWIP_STATIC void
550d163575Sopenharmony_cidriverif_init_ifname(struct netif *netif)
560d163575Sopenharmony_ci{
570d163575Sopenharmony_ci    struct netif *tmpnetif = NULL;
580d163575Sopenharmony_ci    const char *prefix = (netif->link_layer_type == WIFI_DRIVER_IF) ? "wlan" : "eth";
590d163575Sopenharmony_ci
600d163575Sopenharmony_ci    netif->name[0] = prefix[0];
610d163575Sopenharmony_ci    netif->name[1] = prefix[1];
620d163575Sopenharmony_ci
630d163575Sopenharmony_ci    for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) {
640d163575Sopenharmony_ci        if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1,
650d163575Sopenharmony_ci                       "%s%d", prefix, i) < 0) {
660d163575Sopenharmony_ci            break;
670d163575Sopenharmony_ci        }
680d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER
690d163575Sopenharmony_ci        NETIF_FOREACH(tmpnetif, get_net_group_from_netif(netif)) {
700d163575Sopenharmony_ci#else
710d163575Sopenharmony_ci        NETIF_FOREACH(tmpnetif) {
720d163575Sopenharmony_ci#endif
730d163575Sopenharmony_ci            if (strcmp(tmpnetif->full_name, netif->full_name) == 0) {
740d163575Sopenharmony_ci                break;
750d163575Sopenharmony_ci            }
760d163575Sopenharmony_ci        }
770d163575Sopenharmony_ci        if (tmpnetif == NULL) {
780d163575Sopenharmony_ci            return;
790d163575Sopenharmony_ci        }
800d163575Sopenharmony_ci    }
810d163575Sopenharmony_ci    netif->full_name[0] = '\0';
820d163575Sopenharmony_ci}
830d163575Sopenharmony_ci
840d163575Sopenharmony_ci/*
850d163575Sopenharmony_ci * This function should do the actual transmission of the packet. The packet is
860d163575Sopenharmony_ci * contained in the pbuf that is passed to the function. This pbuf
870d163575Sopenharmony_ci * might be chained.
880d163575Sopenharmony_ci *
890d163575Sopenharmony_ci * @param netif the lwip network interface structure for this driverif
900d163575Sopenharmony_ci * @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type)
910d163575Sopenharmony_ci * @return ERR_OK if the packet could be sent
920d163575Sopenharmony_ci *         an err_t value if the packet couldn't be sent
930d163575Sopenharmony_ci *
940d163575Sopenharmony_ci * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
950d163575Sopenharmony_ci *       strange results. You might consider waiting for space in the DMA queue
960d163575Sopenharmony_ci *       to become available since the stack doesn't retry to send a packet
970d163575Sopenharmony_ci *       dropped because of memory failure (except for the TCP timers).
980d163575Sopenharmony_ci */
990d163575Sopenharmony_ci
1000d163575Sopenharmony_ciLWIP_STATIC err_t
1010d163575Sopenharmony_cidriverif_output(struct netif *netif, struct pbuf *p)
1020d163575Sopenharmony_ci{
1030d163575Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_output : going to send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \
1040d163575Sopenharmony_ci    (void *)p, p->tot_len, (void *)netif));
1050d163575Sopenharmony_ci
1060d163575Sopenharmony_ci#if PF_PKT_SUPPORT
1070d163575Sopenharmony_ci    if (all_pkt_raw_pcbs != NULL) {
1080d163575Sopenharmony_ci        p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST));
1090d163575Sopenharmony_ci        p->flags |= PBUF_FLAG_OUTGOING;
1100d163575Sopenharmony_ci        (void)raw_pkt_input(p, netif, NULL);
1110d163575Sopenharmony_ci    }
1120d163575Sopenharmony_ci#endif
1130d163575Sopenharmony_ci
1140d163575Sopenharmony_ci#if ETH_PAD_SIZE
1150d163575Sopenharmony_ci    (void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
1160d163575Sopenharmony_ci#endif
1170d163575Sopenharmony_ci
1180d163575Sopenharmony_ci    netif->drv_send(netif, p);
1190d163575Sopenharmony_ci
1200d163575Sopenharmony_ci#if ETH_PAD_SIZE
1210d163575Sopenharmony_ci    (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
1220d163575Sopenharmony_ci#endif
1230d163575Sopenharmony_ci    MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
1240d163575Sopenharmony_ci    LINK_STATS_INC(link.xmit);
1250d163575Sopenharmony_ci
1260d163575Sopenharmony_ci    return ERR_OK;
1270d163575Sopenharmony_ci}
1280d163575Sopenharmony_ci
1290d163575Sopenharmony_ci/*
1300d163575Sopenharmony_ci * This function should be called by network driver to pass the input packet to LwIP.
1310d163575Sopenharmony_ci * Before calling this API, driver has to keep the packet in pbuf structure. Driver has to
1320d163575Sopenharmony_ci * call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver
1330d163575Sopenharmony_ci * has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread.
1340d163575Sopenharmony_ci * Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to
1350d163575Sopenharmony_ci * free the pbuf.
1360d163575Sopenharmony_ci *
1370d163575Sopenharmony_ci * @param netif the lwip network interface structure for this driverif
1380d163575Sopenharmony_ci * @param p packet in pbuf structure format
1390d163575Sopenharmony_ci */
1400d163575Sopenharmony_civoid
1410d163575Sopenharmony_cidriverif_input(struct netif *netif, struct pbuf *p)
1420d163575Sopenharmony_ci{
1430d163575Sopenharmony_ci#if PF_PKT_SUPPORT
1440d163575Sopenharmony_ci#if  (DRIVERIF_DEBUG & LWIP_DBG_OFF)
1450d163575Sopenharmony_ci    u16_t ethhdr_type;
1460d163575Sopenharmony_ci    struct eth_hdr* ethhdr = NULL;
1470d163575Sopenharmony_ci#endif
1480d163575Sopenharmony_ci#else
1490d163575Sopenharmony_ci    u16_t ethhdr_type;
1500d163575Sopenharmony_ci    struct eth_hdr *ethhdr = NULL;
1510d163575Sopenharmony_ci#endif
1520d163575Sopenharmony_ci    err_t ret = ERR_VAL;
1530d163575Sopenharmony_ci
1540d163575Sopenharmony_ci    LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return);
1550d163575Sopenharmony_ci
1560d163575Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \
1570d163575Sopenharmony_ci                               packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len));
1580d163575Sopenharmony_ci
1590d163575Sopenharmony_ci    /* points to packet payload, which starts with an Ethernet header */
1600d163575Sopenharmony_ci    MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
1610d163575Sopenharmony_ci    if (p->len < SIZEOF_ETH_HDR) {
1620d163575Sopenharmony_ci        (void)pbuf_free(p);
1630d163575Sopenharmony_ci        LINK_STATS_INC(link.drop);
1640d163575Sopenharmony_ci        LINK_STATS_INC(link.link_rx_drop);
1650d163575Sopenharmony_ci        return;
1660d163575Sopenharmony_ci    }
1670d163575Sopenharmony_ci
1680d163575Sopenharmony_ci#if PF_PKT_SUPPORT
1690d163575Sopenharmony_ci#if  (DRIVERIF_DEBUG & LWIP_DBG_OFF)
1700d163575Sopenharmony_ci    ethhdr = (struct eth_hdr *)p->payload;
1710d163575Sopenharmony_ci    ethhdr_type = ntohs(ethhdr->type);
1720d163575Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", ethhdr_type, netif->input));
1730d163575Sopenharmony_ci#endif
1740d163575Sopenharmony_ci
1750d163575Sopenharmony_ci    /* full packet send to tcpip_thread to process */
1760d163575Sopenharmony_ci    if (netif->input) {
1770d163575Sopenharmony_ci        ret = netif->input(p, netif);
1780d163575Sopenharmony_ci    }
1790d163575Sopenharmony_ci    if (ret != ERR_OK) {
1800d163575Sopenharmony_ci        LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
1810d163575Sopenharmony_ci        (void)pbuf_free(p);
1820d163575Sopenharmony_ci        LINK_STATS_INC(link.drop);
1830d163575Sopenharmony_ci        LINK_STATS_INC(link.link_rx_drop);
1840d163575Sopenharmony_ci        if (ret == ERR_MEM) {
1850d163575Sopenharmony_ci            LINK_STATS_INC(link.link_rx_overrun);
1860d163575Sopenharmony_ci        }
1870d163575Sopenharmony_ci    } else {
1880d163575Sopenharmony_ci        LINK_STATS_INC(link.recv);
1890d163575Sopenharmony_ci    }
1900d163575Sopenharmony_ci
1910d163575Sopenharmony_ci#else
1920d163575Sopenharmony_ci    ethhdr = (struct eth_hdr *)p->payload;
1930d163575Sopenharmony_ci    ethhdr_type = ntohs(ethhdr->type);
1940d163575Sopenharmony_ci
1950d163575Sopenharmony_ci    switch (ethhdr_type) {
1960d163575Sopenharmony_ci        /* IP or ARP packet? */
1970d163575Sopenharmony_ci        case ETHTYPE_IP:
1980d163575Sopenharmony_ci        case ETHTYPE_IPV6:
1990d163575Sopenharmony_ci        case ETHTYPE_ARP:
2000d163575Sopenharmony_ci#if ETHARP_SUPPORT_VLAN
2010d163575Sopenharmony_ci        case ETHTYPE_VLAN:
2020d163575Sopenharmony_ci#endif /* ETHARP_SUPPORT_VLAN */
2030d163575Sopenharmony_ci            LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdr_type));
2040d163575Sopenharmony_ci            /* full packet send to tcpip_thread to process */
2050d163575Sopenharmony_ci            if (netif->input != NULL) {
2060d163575Sopenharmony_ci                ret = netif->input(p, netif);
2070d163575Sopenharmony_ci            }
2080d163575Sopenharmony_ci
2090d163575Sopenharmony_ci            if (ret != ERR_OK) {
2100d163575Sopenharmony_ci                LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
2110d163575Sopenharmony_ci                (void)pbuf_free(p);
2120d163575Sopenharmony_ci                LINK_STATS_INC(link.drop);
2130d163575Sopenharmony_ci                LINK_STATS_INC(link.link_rx_drop);
2140d163575Sopenharmony_ci                if (ret == ERR_MEM) {
2150d163575Sopenharmony_ci                    MIB2_STATS_NETIF_INC(netif, ifinoverruns);
2160d163575Sopenharmony_ci                    LINK_STATS_INC(link.link_rx_overrun);
2170d163575Sopenharmony_ci                }
2180d163575Sopenharmony_ci            } else {
2190d163575Sopenharmony_ci                LINK_STATS_INC(link.recv);
2200d163575Sopenharmony_ci            }
2210d163575Sopenharmony_ci            break;
2220d163575Sopenharmony_ci
2230d163575Sopenharmony_ci        default:
2240d163575Sopenharmony_ci            LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", ethhdr_type));
2250d163575Sopenharmony_ci            (void)pbuf_free(p);
2260d163575Sopenharmony_ci            LINK_STATS_INC(link.drop);
2270d163575Sopenharmony_ci            LINK_STATS_INC(link.link_rx_drop);
2280d163575Sopenharmony_ci            break;
2290d163575Sopenharmony_ci    }
2300d163575Sopenharmony_ci#endif
2310d163575Sopenharmony_ci
2320d163575Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n"));
2330d163575Sopenharmony_ci}
2340d163575Sopenharmony_ci
2350d163575Sopenharmony_ci/*
2360d163575Sopenharmony_ci * Should be called at the beginning of the program to set up the
2370d163575Sopenharmony_ci * network interface. It calls the function low_level_init() to do the
2380d163575Sopenharmony_ci * actual setup of the hardware.
2390d163575Sopenharmony_ci *
2400d163575Sopenharmony_ci * This function should be passed as a parameter to netif_add().
2410d163575Sopenharmony_ci *
2420d163575Sopenharmony_ci * @param netif the lwip network interface structure for this driverif
2430d163575Sopenharmony_ci * @return ERR_OK if the loopif is initialized
2440d163575Sopenharmony_ci *         ERR_MEM on Allocation Failure
2450d163575Sopenharmony_ci *         any other err_t on error
2460d163575Sopenharmony_ci */
2470d163575Sopenharmony_cierr_t
2480d163575Sopenharmony_cidriverif_init(struct netif *netif)
2490d163575Sopenharmony_ci{
2500d163575Sopenharmony_ci    u16_t link_layer_type;
2510d163575Sopenharmony_ci
2520d163575Sopenharmony_ci    if (netif == NULL) {
2530d163575Sopenharmony_ci        return ERR_IF;
2540d163575Sopenharmony_ci    }
2550d163575Sopenharmony_ci    link_layer_type = netif->link_layer_type;
2560d163575Sopenharmony_ci    LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \
2570d163575Sopenharmony_ci    ((link_layer_type == ETHERNET_DRIVER_IF) || (link_layer_type == WIFI_DRIVER_IF)), \
2580d163575Sopenharmony_ci    return ERR_IF);
2590d163575Sopenharmony_ci
2600d163575Sopenharmony_ci    LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \
2610d163575Sopenharmony_ci    (netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF);
2620d163575Sopenharmony_ci
2630d163575Sopenharmony_ci    LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF);
2640d163575Sopenharmony_ci
2650d163575Sopenharmony_ci#if LWIP_NETIF_PROMISC
2660d163575Sopenharmony_ci    LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF);
2670d163575Sopenharmony_ci#endif
2680d163575Sopenharmony_ci
2690d163575Sopenharmony_ci#if LWIP_NETIF_HOSTNAME
2700d163575Sopenharmony_ci    /* Initialize interface hostname */
2710d163575Sopenharmony_ci    netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT;
2720d163575Sopenharmony_ci#endif /* LWIP_NETIF_HOSTNAME */
2730d163575Sopenharmony_ci
2740d163575Sopenharmony_ci    /*
2750d163575Sopenharmony_ci     * Initialize the snmp variables and counters inside the struct netif.
2760d163575Sopenharmony_ci     * The last argument should be replaced with your link speed, in units
2770d163575Sopenharmony_ci     * of bits per second.
2780d163575Sopenharmony_ci     */
2790d163575Sopenharmony_ci    NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
2800d163575Sopenharmony_ci
2810d163575Sopenharmony_ci    netif->output = etharp_output;
2820d163575Sopenharmony_ci    netif->linkoutput = driverif_output;
2830d163575Sopenharmony_ci
2840d163575Sopenharmony_ci    /* init the netif's full name */
2850d163575Sopenharmony_ci    driverif_init_ifname(netif);
2860d163575Sopenharmony_ci
2870d163575Sopenharmony_ci    /* maximum transfer unit */
2880d163575Sopenharmony_ci    netif->mtu = IP_FRAG_MAX_MTU;
2890d163575Sopenharmony_ci
2900d163575Sopenharmony_ci    /* device capabilities */
2910d163575Sopenharmony_ci    /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
2920d163575Sopenharmony_ci    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
2930d163575Sopenharmony_ci                   #if DRIVER_STATUS_CHECK
2940d163575Sopenharmony_ci                   NETIF_FLAG_DRIVER_RDY |
2950d163575Sopenharmony_ci                   #endif
2960d163575Sopenharmony_ci                   #if LWIP_IGMP
2970d163575Sopenharmony_ci                   NETIF_FLAG_IGMP |
2980d163575Sopenharmony_ci                   #endif
2990d163575Sopenharmony_ci
3000d163575Sopenharmony_ci                   /**
3010d163575Sopenharmony_ci                   @page RFC-2710 RFC-2710
3020d163575Sopenharmony_ci                   @par Compliant Sections
3030d163575Sopenharmony_ci                   Section 5. Node State Transition Diagram
3040d163575Sopenharmony_ci                   @par Behavior Description
3050d163575Sopenharmony_ci                   MLD messages are sent for multicast addresses whose scope is 2
3060d163575Sopenharmony_ci                   (link-local), including Solicited-Node multicast addresses.\n
3070d163575Sopenharmony_ci                   Behavior:Stack will send MLD6 report /Done to solicited node multicast address
3080d163575Sopenharmony_ci                   if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
3090d163575Sopenharmony_ci                   */
3100d163575Sopenharmony_ci                   /* Enable sending MLD report /done for solicited address during neighbour discovery */
3110d163575Sopenharmony_ci                   #if LWIP_IPV6 && LWIP_IPV6_MLD
3120d163575Sopenharmony_ci                   #if LWIP_MLD6_ENABLE_MLD_ON_DAD
3130d163575Sopenharmony_ci                   NETIF_FLAG_MLD6 |
3140d163575Sopenharmony_ci                   #endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */
3150d163575Sopenharmony_ci                   #endif
3160d163575Sopenharmony_ci                   NETIF_FLAG_LINK_UP;
3170d163575Sopenharmony_ci
3180d163575Sopenharmony_ci#if DRIVER_STATUS_CHECK
3190d163575Sopenharmony_ci    netif->waketime = -1;
3200d163575Sopenharmony_ci#endif /* DRIVER_STATUS_CHECK */
3210d163575Sopenharmony_ci    LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif));
3220d163575Sopenharmony_ci    return ERR_OK;
3230d163575Sopenharmony_ci}
3240d163575Sopenharmony_ci
3250d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER
3260d163575Sopenharmony_cistatic err_t netif_veth_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr)
3270d163575Sopenharmony_ci{
3280d163575Sopenharmony_ci    LWIP_UNUSED_ARG(addr);
3290d163575Sopenharmony_ci    return netif_loop_output(netif->peer, p);
3300d163575Sopenharmony_ci}
3310d163575Sopenharmony_ci
3320d163575Sopenharmony_cistatic void veth_init_fullname(struct netif *netif)
3330d163575Sopenharmony_ci{
3340d163575Sopenharmony_ci    struct netif *tmpnetif = NULL;
3350d163575Sopenharmony_ci
3360d163575Sopenharmony_ci    for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) {
3370d163575Sopenharmony_ci        if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1,
3380d163575Sopenharmony_ci                       "%s%d", "veth", i) < 0) {
3390d163575Sopenharmony_ci            break;
3400d163575Sopenharmony_ci        }
3410d163575Sopenharmony_ci        NETIF_FOREACH(tmpnetif, get_net_group_from_netif(netif)) {
3420d163575Sopenharmony_ci            if (strcmp(tmpnetif->full_name, netif->full_name) == 0) {
3430d163575Sopenharmony_ci                break;
3440d163575Sopenharmony_ci            }
3450d163575Sopenharmony_ci        }
3460d163575Sopenharmony_ci        if (tmpnetif == NULL) {
3470d163575Sopenharmony_ci            return;
3480d163575Sopenharmony_ci        }
3490d163575Sopenharmony_ci    }
3500d163575Sopenharmony_ci    netif->full_name[0] = '\0';
3510d163575Sopenharmony_ci}
3520d163575Sopenharmony_ci
3530d163575Sopenharmony_cistatic err_t netif_vethif_init(struct netif *netif)
3540d163575Sopenharmony_ci{
3550d163575Sopenharmony_ci    LWIP_ASSERT("netif_vethif_init: invalid netif", netif != NULL);
3560d163575Sopenharmony_ci
3570d163575Sopenharmony_ci    /* initialize the snmp variables and counters inside the struct netif
3580d163575Sopenharmony_ci     * ifSpeed: no assumption can be made!
3590d163575Sopenharmony_ci     */
3600d163575Sopenharmony_ci    MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
3610d163575Sopenharmony_ci    netif->link_layer_type = VETH_DRIVER_IF;
3620d163575Sopenharmony_ci
3630d163575Sopenharmony_ci    netif->name[0] = 'v';
3640d163575Sopenharmony_ci    netif->name[1] = 'e';
3650d163575Sopenharmony_ci
3660d163575Sopenharmony_ci    veth_init_fullname(netif);
3670d163575Sopenharmony_ci    netif->output = netif_veth_output;
3680d163575Sopenharmony_ci
3690d163575Sopenharmony_ci    netif_set_flags(netif, NETIF_FLAG_IGMP);
3700d163575Sopenharmony_ci    NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_DISABLE_ALL);
3710d163575Sopenharmony_ci    return ERR_OK;
3720d163575Sopenharmony_ci}
3730d163575Sopenharmony_ci
3740d163575Sopenharmony_civoid veth_init(struct netif *netif, struct net_group *group)
3750d163575Sopenharmony_ci{
3760d163575Sopenharmony_ci    netif_add_noaddr(netif, group, NULL, netif_vethif_init, tcpip_input);
3770d163575Sopenharmony_ci    netif_set_link_up(netif);
3780d163575Sopenharmony_ci    netif_set_up(netif);
3790d163575Sopenharmony_ci}
3800d163575Sopenharmony_ci#endif
381