ReactOS 0.4.16-dev-297-gc569aee
bridgeif.c
Go to the documentation of this file.
1
6/*
7 * Copyright (c) 2017 Simon Goldschmidt.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 * OF SUCH DAMAGE.
31 *
32 * This file is part of the lwIP TCP/IP stack.
33 *
34 * Author: Simon Goldschmidt <goldsimon@gmx.de>
35 *
36 */
37
82#include "netif/bridgeif.h"
83#include "lwip/netif.h"
84#include "lwip/sys.h"
85#include "lwip/etharp.h"
86#include "lwip/ethip6.h"
87#include "lwip/snmp.h"
88#include "lwip/timeouts.h"
89#include <string.h>
90
91#if LWIP_NUM_NETIF_CLIENT_DATA
92
93/* Define those to better describe your network interface. */
94#define IFNAME0 'b'
95#define IFNAME1 'r'
96
97struct bridgeif_private_s;
98typedef struct bridgeif_port_private_s {
99 struct bridgeif_private_s *bridge;
100 struct netif *port_netif;
101 u8_t port_num;
102} bridgeif_port_t;
103
104typedef struct bridgeif_fdb_static_entry_s {
105 u8_t used;
106 bridgeif_portmask_t dst_ports;
107 struct eth_addr addr;
108} bridgeif_fdb_static_entry_t;
109
110typedef struct bridgeif_private_s {
111 struct netif *netif;
112 struct eth_addr ethaddr;
113 u8_t max_ports;
114 u8_t num_ports;
115 bridgeif_port_t *ports;
116 u16_t max_fdbs_entries;
117 bridgeif_fdb_static_entry_t *fdbs;
118 u16_t max_fdbd_entries;
119 void *fdbd;
120} bridgeif_private_t;
121
122/* netif data index to get the bridge on input */
123static u8_t bridgeif_netif_client_id = 0xff;
124
134err_t
135bridgeif_fdb_add(struct netif *bridgeif, const struct eth_addr *addr, bridgeif_portmask_t ports)
136{
137 int i;
138 bridgeif_private_t *br;
140 LWIP_ASSERT("invalid netif", bridgeif != NULL);
141 br = (bridgeif_private_t *)bridgeif->state;
142 LWIP_ASSERT("invalid state", br != NULL);
143
145 for (i = 0; i < br->max_fdbs_entries; i++) {
146 if (!br->fdbs[i].used) {
148 if (!br->fdbs[i].used) {
149 br->fdbs[i].used = 1;
150 br->fdbs[i].dst_ports = ports;
151 memcpy(&br->fdbs[i].addr, addr, sizeof(struct eth_addr));
154 return ERR_OK;
155 }
157 }
158 }
160 return ERR_MEM;
161}
162
167err_t
168bridgeif_fdb_remove(struct netif *bridgeif, const struct eth_addr *addr)
169{
170 int i;
171 bridgeif_private_t *br;
173 LWIP_ASSERT("invalid netif", bridgeif != NULL);
174 br = (bridgeif_private_t *)bridgeif->state;
175 LWIP_ASSERT("invalid state", br != NULL);
176
178 for (i = 0; i < br->max_fdbs_entries; i++) {
179 if (br->fdbs[i].used && !memcmp(&br->fdbs[i].addr, addr, sizeof(struct eth_addr))) {
181 if (br->fdbs[i].used && !memcmp(&br->fdbs[i].addr, addr, sizeof(struct eth_addr))) {
182 memset(&br->fdbs[i], 0, sizeof(bridgeif_fdb_static_entry_t));
185 return ERR_OK;
186 }
188 }
189 }
191 return ERR_VAL;
192}
193
196bridgeif_find_dst_ports(bridgeif_private_t *br, struct eth_addr *dst_addr)
197{
198 int i;
201 /* first check for static entries */
202 for (i = 0; i < br->max_fdbs_entries; i++) {
203 if (br->fdbs[i].used) {
204 if (!memcmp(&br->fdbs[i].addr, dst_addr, sizeof(struct eth_addr))) {
205 bridgeif_portmask_t ret = br->fdbs[i].dst_ports;
207 return ret;
208 }
209 }
210 }
211 if (dst_addr->addr[0] & 1) {
212 /* no match found: flood remaining group address */
214 return BR_FLOOD;
215 }
217 /* no match found: check dynamic fdb for port or fall back to flooding */
218 return bridgeif_fdb_get_dst_ports(br->fdbd, dst_addr);
219}
220
225static int
226bridgeif_is_local_mac(bridgeif_private_t *br, struct eth_addr *addr)
227{
228 int i;
230 if (!memcmp(br->netif->hwaddr, addr, sizeof(struct eth_addr))) {
231 return 1;
232 }
234 for (i = 0; i < br->num_ports; i++) {
235 struct netif *portif = br->ports[i].port_netif;
236 if (portif != NULL) {
237 if (!memcmp(portif->hwaddr, addr, sizeof(struct eth_addr))) {
239 return 1;
240 }
241 }
242 }
244 return 0;
245}
246
247/* Output helper function */
248static err_t
249bridgeif_send_to_port(bridgeif_private_t *br, struct pbuf *p, u8_t dstport_idx)
250{
251 if (dstport_idx < BRIDGEIF_MAX_PORTS) {
252 /* possibly an external port */
253 if (dstport_idx < br->max_ports) {
254 struct netif *portif = br->ports[dstport_idx].port_netif;
255 if ((portif != NULL) && (portif->linkoutput != NULL)) {
256 /* prevent sending out to rx port */
257 if (netif_get_index(portif) != p->if_idx) {
258 if (netif_is_link_up(portif)) {
259 LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> flood(%p:%d) -> %d\n", (void *)p, p->if_idx, netif_get_index(portif)));
260 return portif->linkoutput(portif, p);
261 }
262 }
263 }
264 }
265 } else {
266 LWIP_ASSERT("invalid port index", dstport_idx == BRIDGEIF_MAX_PORTS);
267 }
268 return ERR_OK;
269}
270
273static err_t
274bridgeif_send_to_ports(bridgeif_private_t *br, struct pbuf *p, bridgeif_portmask_t dstports)
275{
276 err_t err, ret_err = ERR_OK;
277 u8_t i;
281 for (i = 0; i < BRIDGEIF_MAX_PORTS; i++, mask = (bridgeif_portmask_t)(mask << 1)) {
282 if (dstports & mask) {
283 err = bridgeif_send_to_port(br, p, i);
284 if (err != ERR_OK) {
285 ret_err = err;
286 }
287 }
288 }
290 return ret_err;
291}
292
297static err_t
298bridgeif_output(struct netif *netif, struct pbuf *p)
299{
300 err_t err;
301 bridgeif_private_t *br = (bridgeif_private_t *)netif->state;
302 struct eth_addr *dst = (struct eth_addr *)(p->payload);
303
304 bridgeif_portmask_t dstports = bridgeif_find_dst_ports(br, dst);
305 err = bridgeif_send_to_ports(br, p, dstports);
306
307 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
308 if (((u8_t *)p->payload)[0] & 1) {
309 /* broadcast or multicast packet*/
310 MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
311 } else {
312 /* unicast packet */
313 MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
314 }
315 /* increase ifoutdiscards or ifouterrors on error */
316
317 LINK_STATS_INC(link.xmit);
318
319 return err;
320}
321
325static err_t
326bridgeif_input(struct pbuf *p, struct netif *netif)
327{
328 u8_t rx_idx;
329 bridgeif_portmask_t dstports;
330 struct eth_addr *src, *dst;
331 bridgeif_private_t *br;
332 bridgeif_port_t *port;
333 if (p == NULL || netif == NULL) {
334 return ERR_VAL;
335 }
336 port = (bridgeif_port_t *)netif_get_client_data(netif, bridgeif_netif_client_id);
337 LWIP_ASSERT("port data not set", port != NULL);
338 if (port == NULL || port->bridge == NULL) {
339 return ERR_VAL;
340 }
341 br = (bridgeif_private_t *)port->bridge;
342 rx_idx = netif_get_index(netif);
343 /* store receive index in pbuf */
344 p->if_idx = rx_idx;
345
346 dst = (struct eth_addr *)p->payload;
347 src = (struct eth_addr *)(((u8_t *)p->payload) + sizeof(struct eth_addr));
348
349 if ((src->addr[0] & 1) == 0) {
350 /* update src for all non-group addresses */
351 bridgeif_fdb_update_src(br->fdbd, src, port->port_num);
352 }
353
354 if (dst->addr[0] & 1) {
355 /* group address -> flood + cpu? */
356 dstports = bridgeif_find_dst_ports(br, dst);
357 bridgeif_send_to_ports(br, p, dstports);
358 if (dstports & (1 << BRIDGEIF_MAX_PORTS)) {
359 /* we pass the reference to ->input or have to free it */
360 LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> input(%p)\n", (void *)p));
361 if (br->netif->input(p, br->netif) != ERR_OK) {
362 pbuf_free(p);
363 }
364 } else {
365 /* all references done */
366 pbuf_free(p);
367 }
368 /* always return ERR_OK here to prevent the caller freeing the pbuf */
369 return ERR_OK;
370 } else {
371 /* is this for one of the local ports? */
372 if (bridgeif_is_local_mac(br, dst)) {
373 /* yes, send to cpu port only */
374 LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> input(%p)\n", (void *)p));
375 return br->netif->input(p, br->netif);
376 }
377
378 /* get dst port */
379 dstports = bridgeif_find_dst_ports(br, dst);
380 bridgeif_send_to_ports(br, p, dstports);
381 /* no need to send to cpu, flooding is for external ports only */
382 /* by this, we consumed the pbuf */
383 pbuf_free(p);
384 /* always return ERR_OK here to prevent the caller freeing the pbuf */
385 return ERR_OK;
386 }
387}
388
389#if !BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
392static err_t
393bridgeif_tcpip_input(struct pbuf *p, struct netif *netif)
394{
395 return tcpip_inpkt(p, netif, bridgeif_input);
396}
397#endif /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */
398
412err_t
414{
415 bridgeif_initdata_t *init_data;
416 bridgeif_private_t *br;
417 size_t alloc_len_sizet;
418 mem_size_t alloc_len;
419
420 LWIP_ASSERT("netif != NULL", (netif != NULL));
421 LWIP_ASSERT("bridgeif needs an input callback", (netif->input != NULL));
422#if !BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
423 if (netif->input == tcpip_input) {
424 LWIP_DEBUGF(BRIDGEIF_DEBUG | LWIP_DBG_ON, ("bridgeif does not need tcpip_input, use netif_input/ethernet_input instead\n"));
425 }
426#endif
427
428 if (bridgeif_netif_client_id == 0xFF) {
429 bridgeif_netif_client_id = netif_alloc_client_data_id();
430 }
431
432 init_data = (bridgeif_initdata_t *)netif->state;
433 LWIP_ASSERT("init_data != NULL", (init_data != NULL));
434 LWIP_ASSERT("init_data->max_ports <= BRIDGEIF_MAX_PORTS",
435 init_data->max_ports <= BRIDGEIF_MAX_PORTS);
436
437 alloc_len_sizet = sizeof(bridgeif_private_t) + (init_data->max_ports * sizeof(bridgeif_port_t) + (init_data->max_fdb_static_entries * sizeof(bridgeif_fdb_static_entry_t)));
438 alloc_len = (mem_size_t)alloc_len_sizet;
439 LWIP_ASSERT("alloc_len == alloc_len_sizet", alloc_len == alloc_len_sizet);
440 LWIP_DEBUGF(BRIDGEIF_DEBUG, ("bridgeif_init: allocating %d bytes for private data\n", (int)alloc_len));
441 br = (bridgeif_private_t *)mem_calloc(1, alloc_len);
442 if (br == NULL) {
443 LWIP_DEBUGF(NETIF_DEBUG, ("bridgeif_init: out of memory\n"));
444 return ERR_MEM;
445 }
446 memcpy(&br->ethaddr, &init_data->ethaddr, sizeof(br->ethaddr));
447 br->netif = netif;
448
449 br->max_ports = init_data->max_ports;
450 br->ports = (bridgeif_port_t *)(br + 1);
451
452 br->max_fdbs_entries = init_data->max_fdb_static_entries;
453 br->fdbs = (bridgeif_fdb_static_entry_t *)(((u8_t *)(br + 1)) + (init_data->max_ports * sizeof(bridgeif_port_t)));
454
455 br->max_fdbd_entries = init_data->max_fdb_dynamic_entries;
456 br->fdbd = bridgeif_fdb_init(init_data->max_fdb_dynamic_entries);
457 if (br->fdbd == NULL) {
458 LWIP_DEBUGF(NETIF_DEBUG, ("bridgeif_init: out of memory in fdb_init\n"));
459 mem_free(br);
460 return ERR_MEM;
461 }
462
463#if LWIP_NETIF_HOSTNAME
464 /* Initialize interface hostname */
465 netif->hostname = "lwip";
466#endif /* LWIP_NETIF_HOSTNAME */
467
468 /*
469 * Initialize the snmp variables and counters inside the struct netif.
470 * The last argument should be replaced with your link speed, in units
471 * of bits per second.
472 */
473 MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 0);
474
475 netif->state = br;
476 netif->name[0] = IFNAME0;
477 netif->name[1] = IFNAME1;
478 /* We directly use etharp_output() here to save a function call.
479 * You can instead declare your own function an call etharp_output()
480 * from it if you have to do some checks before sending (e.g. if link
481 * is available...) */
482#if LWIP_IPV4
483 netif->output = etharp_output;
484#endif /* LWIP_IPV4 */
485#if LWIP_IPV6
486 netif->output_ip6 = ethip6_output;
487#endif /* LWIP_IPV6 */
488 netif->linkoutput = bridgeif_output;
489
490 /* set MAC hardware address length */
492
493 /* set MAC hardware address */
494 memcpy(netif->hwaddr, &br->ethaddr, ETH_HWADDR_LEN);
495
496 /* maximum transfer unit */
497 netif->mtu = 1500;
498
499 /* device capabilities */
500 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
502
503#if LWIP_IPV6 && LWIP_IPV6_MLD
504 /*
505 * For hardware/netifs that implement MAC filtering.
506 * All-nodes link-local is handled by default, so we must let the hardware know
507 * to allow multicast packets in.
508 * Should set mld_mac_filter previously. */
509 if (netif->mld_mac_filter != NULL) {
510 ip6_addr_t ip6_allnodes_ll;
511 ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
512 netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
513 }
514#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
515
516 return ERR_OK;
517}
518
523err_t
524bridgeif_add_port(struct netif *bridgeif, struct netif *portif)
525{
526 bridgeif_private_t *br;
527 bridgeif_port_t *port;
528
529 LWIP_ASSERT("bridgeif != NULL", bridgeif != NULL);
530 LWIP_ASSERT("bridgeif->state != NULL", bridgeif->state != NULL);
531 LWIP_ASSERT("portif != NULL", portif != NULL);
532
533 if (!(portif->flags & NETIF_FLAG_ETHARP) || !(portif->flags & NETIF_FLAG_ETHERNET)) {
534 /* can only add ETHERNET/ETHARP interfaces */
535 return ERR_VAL;
536 }
537
538 br = (bridgeif_private_t *)bridgeif->state;
539
540 if (br->num_ports >= br->max_ports) {
541 return ERR_VAL;
542 }
543 port = &br->ports[br->num_ports];
544 port->port_netif = portif;
545 port->port_num = br->num_ports;
546 port->bridge = br;
547 br->num_ports++;
548
549 /* let the port call us on input */
550#if BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT
551 portif->input = bridgeif_input;
552#else
553 portif->input = bridgeif_tcpip_input;
554#endif
555 /* store pointer to bridge in netif */
556 netif_set_client_data(portif, bridgeif_netif_client_id, port);
557 /* remove ETHARP flag to prevent sending report events on netif-up */
559
560 return ERR_OK;
561}
562
563#endif /* LWIP_NUM_NETIF_CLIENT_DATA */
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static int used
Definition: adh-main.c:39
#define BR_FLOOD
Definition: bridgeif.h:63
u8_t bridgeif_portmask_t
Definition: bridgeif.h:54
err_t bridgeif_init(struct netif *netif)
#define BRIDGEIF_READ_UNPROTECT(lev)
Definition: bridgeif.h:118
err_t bridgeif_add_port(struct netif *bridgeif, struct netif *portif)
#define BRIDGEIF_DECL_PROTECT(lev)
Definition: bridgeif.h:116
err_t bridgeif_fdb_remove(struct netif *bridgeif, const struct eth_addr *addr)
#define BRIDGEIF_READ_PROTECT(lev)
Definition: bridgeif.h:117
#define BRIDGEIF_WRITE_UNPROTECT(lev)
Definition: bridgeif.h:120
err_t bridgeif_fdb_add(struct netif *bridgeif, const struct eth_addr *addr, bridgeif_portmask_t ports)
#define BRIDGEIF_WRITE_PROTECT(lev)
Definition: bridgeif.h:119
const WCHAR * link
Definition: db.cpp:997
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
USHORT port
Definition: uri.c:228
void * mem_calloc(mem_size_t count, mem_size_t size)
Definition: mem.c:999
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
u16_t mem_size_t
Definition: mem.h:67
#define MIB2_STATS_NETIF_ADD(n, x, val)
Definition: snmp.h:140
#define MIB2_STATS_NETIF_INC(n, x)
Definition: snmp.h:139
#define MIB2_INIT_NETIF(netif, type, speed)
Definition: snmp.h:138
#define ERR_MEM
Definition: fontsub.h:52
GLenum src
Definition: glext.h:6340
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLenum dst
Definition: glext.h:6340
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void * bridgeif_fdb_init(u16_t max_fdb_entries)
Definition: bridgeif_fdb.c:195
bridgeif_portmask_t bridgeif_fdb_get_dst_ports(void *fdb_ptr, struct eth_addr *dst_addr)
Definition: bridgeif_fdb.c:128
void bridgeif_fdb_update_src(void *fdb_ptr, struct eth_addr *src_addr, u8_t port_idx)
Definition: bridgeif_fdb.c:76
#define BRIDGEIF_MAX_PORTS
Definition: bridgeif_opts.h:68
#define BRIDGEIF_DEBUG
Definition: bridgeif_opts.h:73
#define BRIDGEIF_FW_DEBUG
Definition: bridgeif_opts.h:83
uint8_t u8_t
Definition: arch.h:125
uint16_t u16_t
Definition: arch.h:127
#define LWIP_DBG_ON
Definition: debug.h:72
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
@ ERR_VAL
Definition: err.h:67
#define NETIF_DEBUG
Definition: opt.h:3336
err_t tcpip_input(struct pbuf *p, struct netif *inp)
Definition: tcpip.c:288
#define NETIF_FLAG_LINK_UP
Definition: netif.h:93
#define NETIF_FLAG_ETHERNET
Definition: netif.h:101
#define NETIF_FLAG_ETHARP
Definition: netif.h:97
#define NETIF_FLAG_MLD6
Definition: netif.h:107
#define NETIF_FLAG_IGMP
Definition: netif.h:104
#define NETIF_FLAG_BROADCAST
Definition: netif.h:87
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
if(dx< 0)
Definition: linetemp.h:194
#define ETH_HWADDR_LEN
Definition: ethernet.h:51
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define netif_is_link_up(netif)
Definition: netif.h:491
@ NETIF_ADD_MAC_FILTER
Definition: netif.h:163
#define netif_get_index(netif)
Definition: netif.h:578
#define netif_clear_flags(netif, clr_flags)
Definition: netif.h:471
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
#define LINK_STATS_INC(x)
Definition: stats.h:384
u16_t max_fdb_static_entries
Definition: bridgeif.h:80
struct eth_addr ethaddr
Definition: bridgeif.h:72
u16_t max_fdb_dynamic_entries
Definition: bridgeif.h:78
Definition: netif.h:269
u8_t flags
Definition: netif.h:354
char name[2]
Definition: netif.h:356
void * state
Definition: netif.h:332
netif_input_fn input
Definition: netif.h:297
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:350
u16_t mtu
Definition: netif.h:344
netif_linkoutput_fn linkoutput
Definition: netif.h:308
u8_t hwaddr_len
Definition: netif.h:352
Definition: pbuf.h:186
err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
Definition: tcpip.c:245
int ret