• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2022-09-21
13  * Description: 网络
14  */
15 
16 #include <lwip/sys.h>
17 #include <lwip/netif.h>
18 #include <lwip/snmp.h>
19 #include <lwip/etharp.h>
20 #include <lwip/sockets.h>
21 #include <lwip/ethip6.h>
22 
23 #define LWIP_NETIF_HOSTNAME_DEFAULT         "default"
24 #define LINK_SPEED_OF_YOUR_NETIF_IN_BPS     100000000 // 100Mbps
25 
26 #define link_rx_drop cachehit
27 #define link_rx_overrun cachehit
28 
29 #define NETIF_NAME_PREFIX_MAX_LENGTH 10
30 #define NETIF_NAME_PREFIX_ETH "eth"
31 #define NETIF_NAME_PREFIX_WIFI "wlan"
32 #define NETIF_NAME_PREFIX_BT "bt"
33 
34 #ifndef LWIP_NETIF_IFINDEX_MAX_EX
35 #define LWIP_NETIF_IFINDEX_MAX_EX 255
36 #endif
37 
OsDriverifGetIfnamePrefix(struct netif * netif,char * prefix,int prefixLen)38 static void OsDriverifGetIfnamePrefix(struct netif *netif, char *prefix, int prefixLen)
39 {
40     if (prefix == NULL || netif == NULL) {
41         LWIP_ASSERT("invalid param", 0);
42         return;
43     }
44     switch (netif->link_layer_type) {
45         case ETHERNET_DRIVER_IF:
46             strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_ETH);
47             break;
48         case WIFI_DRIVER_IF:
49             strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_WIFI);
50             break;
51         case BT_PROXY_IF:
52             strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_BT);
53             break;
54         default:
55             LWIP_ASSERT("invalid link_layer_type", 0);
56             break;
57     }
58 }
59 
OsDriverifInitIfname(struct netif * netif)60 static void OsDriverifInitIfname(struct netif *netif)
61 {
62     struct netif *tmpNetif = NULL;
63     char prefix[NETIF_NAME_PREFIX_MAX_LENGTH] = {0};
64 
65     OsDriverifGetIfnamePrefix(netif, prefix, NETIF_NAME_PREFIX_MAX_LENGTH);
66     netif->name[0] = prefix[0];
67     netif->name[1] = prefix[1];
68 
69     if (netif->full_name[0] != '\0') {
70         LWIP_DEBUGF(DRIVERIF_DEBUG, ("netif already has fullname %s\n", netif->full_name));
71         return;
72     }
73     for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) {
74         if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1,
75             "%s%d", prefix, i) < 0) {
76             break;
77         }
78         NETIF_FOREACH(tmpNetif) {
79             if (strcmp(tmpNetif->full_name, netif->full_name) == 0) {
80                 break;
81             }
82         }
83         if (tmpNetif == NULL) {
84             LWIP_DEBUGF(DRIVERIF_DEBUG, ("set fullname success %s\n", netif->full_name));
85             return;
86         }
87     }
88     netif->full_name[0] = '\0';
89 }
90 
91 /*
92  * This function should do the actual transmission of the packet. The packet is
93  * contained in the pbuf that is passed to the function. This pbuf
94  * might be chained.
95  *
96  * @param netif the lwip network interface structure for this driverif
97  * @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type)
98  * @return ERR_OK if the packet could be sent
99  *         an err_t value if the packet couldn't be sent
100  *
101  * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
102  *       strange results. You might consider waiting for space in the DMA queue
103  *       to become availale since the stack doesn't retry to send a packet
104  *       dropped because of memory failure (except for the TCP timers).
105  */
106 
OsDriverifOutput(struct netif * netif,struct pbuf * p)107 static err_t OsDriverifOutput(struct netif *netif, struct pbuf *p)
108 {
109     LWIP_DEBUGF(DRIVERIF_DEBUG, ("OsDriverifOutput : send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \
110         (void *)p, p->tot_len, (void *)netif));
111 
112 #if PF_PKT_SUPPORT
113     if (all_pkt_raw_pcbs != NULL) {
114         p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST));
115         p->flags |= PBUF_FLAG_OUTGOING;
116         (void)raw_pkt_input(p, netif, NULL);
117     }
118 #endif
119 
120 #if ETH_PAD_SIZE
121     (void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
122 #endif
123 
124     netif->drv_send(netif, p);
125 
126 #if ETH_PAD_SIZE
127     (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
128 #endif
129     MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
130     LINK_STATS_INC(link.xmit);
131 
132     return ERR_OK;
133 }
134 
OsDriverifInputProc(struct netif * netif,struct pbuf * p)135 static void OsDriverifInputProc(struct netif *netif, struct pbuf *p)
136 {
137     err_t ret = ERR_VAL;
138     struct eth_hdr * ethhdr = (struct eth_hdr *)p->payload;
139     U16 ethhdrType = ntohs(ethhdr->type);
140 
141     switch (ethhdrType) {
142         /* IP or ARP packet? */
143         case ETHTYPE_IP:
144         case ETHTYPE_IPV6:
145         case ETHTYPE_ARP:
146 #if ETHARP_SUPPORT_VLAN
147         case ETHTYPE_VLAN:
148 #endif /* ETHARP_SUPPORT_VLAN */
149             LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdrType));
150             /* full packet send to tcpip_thread to process */
151             if (netif->input != NULL) {
152                 ret = netif->input(p, netif);
153             }
154 
155             if (ret != ERR_OK) {
156                 LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
157                 (void)pbuf_free(p);
158                 LINK_STATS_INC(link.drop);
159                 LINK_STATS_INC(link.link_rx_drop);
160                 if (ret == ERR_MEM) {
161                     MIB2_STATS_NETIF_INC(netif, ifinoverruns);
162                     LINK_STATS_INC(link.link_rx_overrun);
163                 }
164             } else {
165                 LINK_STATS_INC(link.recv);
166             }
167             break;
168 
169         default:
170             LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", \
171                 ethhdrType));
172             (void)pbuf_free(p);
173             LINK_STATS_INC(link.drop);
174             LINK_STATS_INC(link.link_rx_drop);
175             break;
176     }
177 }
178 
179 /*
180  * This function should be called by network driver to pass the input packet to LwIP.
181  * Before calling this API, driver has to keep the packet in pbuf structure. Driver has to
182  * call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver
183  * has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread.
184  * Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to
185  * free the pbuf.
186  *
187  * @param netif the lwip network interface structure for this driverif
188  * @param p packet in pbuf structure format
189  */
driverif_input(struct netif * netif,struct pbuf * p)190 void driverif_input(struct netif *netif, struct pbuf *p)
191 {
192 #if PF_PKT_SUPPORT
193 #if  (DRIVERIF_DEBUG & LWIP_DBG_OFF)
194     U16 ethhdrType;
195     struct eth_hdr* ethhdr = NULL;
196 #endif
197     err_t ret = ERR_VAL;
198 #endif
199 
200     LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return);
201 
202     LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \
203         packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len));
204 
205     /* points to packet payload, which starts with an Ethernet header */
206     MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
207     if (p->len < SIZEOF_ETH_HDR) {
208         (void)pbuf_free(p);
209         LINK_STATS_INC(link.drop);
210         LINK_STATS_INC(link.link_rx_drop);
211         return;
212     }
213 
214 #if PF_PKT_SUPPORT
215 #if  (DRIVERIF_DEBUG & LWIP_DBG_OFF)
216     ethhdr = (struct eth_hdr *)p->payload;
217     ethhdrType = ntohs(ethhdr->type);
218     LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", \
219         ethhdrType, netif->input));
220 #endif
221 
222     /* full packet send to tcpip_thread to process */
223     if (netif->input) {
224         ret = netif->input(p, netif);
225     }
226     if (ret != ERR_OK) {
227         LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
228         (void)pbuf_free(p);
229         LINK_STATS_INC(link.drop);
230         LINK_STATS_INC(link.link_rx_drop);
231         if (ret == ERR_MEM) {
232             LINK_STATS_INC(link.link_rx_overrun);
233         }
234     } else {
235         LINK_STATS_INC(link.recv);
236     }
237 
238 #else
239     OsDriverifInputProc(netif, p);
240 #endif
241 
242     LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n"));
243 }
244 
245 /*
246  * Should be called at the beginning of the program to set up the
247  * network interface. It calls the function low_level_init() to do the
248  * actual setup of the hardware.
249  *
250  * This function should be passed as a parameter to netif_add().
251  *
252  * @param netif the lwip network interface structure for this driverif
253  * @return ERR_OK if the loopif is initialized
254  *         ERR_MEM on Allocation Failure
255  *         any other err_t on error
256  */
driverif_init(struct netif * netif)257 err_t driverif_init(struct netif *netif)
258 {
259     U16 linkLayerType;
260 
261     if (netif == NULL) {
262         return ERR_IF;
263     }
264     linkLayerType = netif->link_layer_type;
265     LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \
266         ((linkLayerType == ETHERNET_DRIVER_IF) \
267         || (linkLayerType == WIFI_DRIVER_IF \
268         || linkLayerType == BT_PROXY_IF)), \
269             return ERR_IF);
270 
271     LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \
272     (netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF);
273 
274     LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF);
275 
276 #if LWIP_NETIF_PROMISC
277     LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF);
278 #endif
279 
280 #if LWIP_NETIF_HOSTNAME
281     /* Initialize interface hostname */
282     netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT;
283 #endif /* LWIP_NETIF_HOSTNAME */
284 
285     /*
286      * Initialize the snmp variables and counters inside the struct netif.
287      * The last argument should be replaced with your link speed, in units
288      * of bits per second.
289      */
290     NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
291 
292     netif->output = etharp_output;
293     netif->linkoutput = OsDriverifOutput;
294 
295     /* init the netif's full name */
296     OsDriverifInitIfname(netif);
297 
298     /* maximum transfer unit */
299     netif->mtu = IP_FRAG_MAX_MTU;
300 
301     /* device capabilities */
302     /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
303     netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
304 #if DRIVER_STATUS_CHECK
305         NETIF_FLAG_DRIVER_RDY |
306 #endif
307 #if LWIP_IGMP
308         NETIF_FLAG_IGMP |
309 #endif
310 
311         /**
312         @page RFC-2710 RFC-2710
313         @par Compliant Sections
314         Section 5. Node State Transition Diagram
315         @par Behavior Description
316         MLD messages are sent for multicast addresses whose scope is 2
317         (link-local), including Solicited-Node multicast addresses.\n
318         Behavior:Stack will send MLD6 report /Done to solicited node multicast address
319         if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
320         */
321         /* Enable sending MLD report /done for solicited address during neighbour discovery */
322 #if LWIP_IPV6 && LWIP_IPV6_MLD
323 #if LWIP_MLD6_ENABLE_MLD_ON_DAD
324         NETIF_FLAG_MLD6 |
325 #endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */
326 #endif
327         NETIF_FLAG_LINK_UP;
328 
329 #if DRIVER_STATUS_CHECK
330     netif->waketime = -1;
331 #endif /* DRIVER_STATUS_CHECK */
332     LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif));
333     return ERR_OK;
334 }
335