SylixOS 网络协议栈,数据结构浅析
结构体定义
struct netif {
#if !LWIP_SINGLE_NETIF/** pointer to next in linked list */struct netif *next;
#endif#if LWIP_IPV4/** IP address configuration in network byte order */ip_addr_t ip_addr;ip_addr_t netmask;ip_addr_t gw;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6/** Array of IPv6 addresses for this netif. */ip_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES];/** The state of each IPv6 address (Tentative, Preferred, etc).* @see ip6_addr.h */u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES];
#if LWIP_IPV6_ADDRESS_LIFETIMES/** Remaining valid and preferred lifetime of each IPv6 address, in seconds.* For valid lifetimes, the special value of IP6_ADDR_LIFE_STATIC (0)* indicates the address is static and has no lifetimes. */u32_t ip6_addr_valid_life[LWIP_IPV6_NUM_ADDRESSES];u32_t ip6_addr_pref_life[LWIP_IPV6_NUM_ADDRESSES];
#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
#ifdef SYLIXOS /* SylixOS Add default gateway */ip_addr_t ip6_gw; /* ipv6 default gateway */
#endif /* SYLIXOS */
#endif /* LWIP_IPV6 *//** This function is called by the network device driver* to pass a packet up the TCP/IP stack. */netif_input_fn input;
#if LWIP_IPV4/** This function is called by the IP module when it wants* to send a packet on the interface. This function typically* first resolves the hardware address, then sends the packet.* For ethernet physical layer, this is usually etharp_output() */netif_output_fn output;
#endif /* LWIP_IPV4 *//** This function is called by ethernet_output() when it wants* to send a packet on the interface. This function outputs* the pbuf as-is on the link medium. */netif_linkoutput_fn linkoutput;
#if LWIP_IPV6/** This function is called by the IPv6 module when it wants* to send a packet on the interface. This function typically* first resolves the hardware address, then sends the packet.* For ethernet physical layer, this is usually ethip6_output() */netif_output_ip6_fn output_ip6;
#endif /* LWIP_IPV6 */
#if LWIP_NETIF_STATUS_CALLBACK/** This function is called when the netif state is set to up or down*/netif_status_callback_fn status_callback;
#endif /* LWIP_NETIF_STATUS_CALLBACK */
#if LWIP_NETIF_LINK_CALLBACK/** This function is called when the netif link is set to up or down*/netif_status_callback_fn link_callback;
#endif /* LWIP_NETIF_LINK_CALLBACK */
#if LWIP_NETIF_REMOVE_CALLBACK/** This function is called when the netif has been removed */netif_status_callback_fn remove_callback;
#endif /* LWIP_NETIF_REMOVE_CALLBACK *//** This field can be set by the device driver and could point* to state information for the device. */void *state;
#ifdef netif_get_client_datavoid* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX + LWIP_NUM_NETIF_CLIENT_DATA];
#endif
#if LWIP_NETIF_HOSTNAME/* the hostname for this netif, NULL is a valid value */const char* hostname;
#endif /* LWIP_NETIF_HOSTNAME */
#if LWIP_CHECKSUM_CTRL_PER_NETIFu16_t chksum_flags;
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*//** maximum transfer unit (in bytes) */u16_t mtu;
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES/** maximum transfer unit (in bytes), updated by RA */u16_t mtu6;
#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES *//** link level hardware address of this interface */u8_t hwaddr[NETIF_MAX_HWADDR_LEN];/** number of bytes used in hwaddr */u8_t hwaddr_len;/** flags (@see @ref netif_flags) */u8_t flags;/** descriptive abbreviation */char name[2];/** number of this interface. Used for @ref if_api and @ref netifapi_netif,* as well as for IPv6 zones */u8_t num;
#if LWIP_IPV6_AUTOCONFIG/** is this netif enabled for IPv6 autoconfiguration */u8_t ip6_autoconfig_enabled;
#endif /* LWIP_IPV6_AUTOCONFIG */
#if LWIP_IPV6_SEND_ROUTER_SOLICIT/** Number of Router Solicitation messages that remain to be sent. */u8_t rs_count;
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
#if MIB2_STATS/** link type (from "snmp_ifType" enum from snmp_mib2.h) */
#ifdef SYLIXOS /* SylixOS Need u16_t link type */u16_t link_type;
#else /* SYLIXOS */u8_t link_type;
#endif /* !SYLIXOS *//** (estimate) link speed */u32_t link_speed;/** timestamp at last change made (up/down) */u32_t ts;/** counters */struct stats_mib2_netif_ctrs mib2_counters;
#endif /* MIB2_STATS */
#if LWIP_IPV4 && LWIP_IGMP/** This function could be called to add or delete an entry in the multicastfilter table of the ethernet MAC.*/netif_igmp_mac_filter_fn igmp_mac_filter;
#endif /* LWIP_IPV4 && LWIP_IGMP */
#if LWIP_IPV6 && LWIP_IPV6_MLD/** This function could be called to add or delete an entry in the IPv6 multicastfilter table of the ethernet MAC. */netif_mld_mac_filter_fn mld_mac_filter;
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
#if LWIP_NETIF_USE_HINTSstruct netif_hint *hints;
#endif /* LWIP_NETIF_USE_HINTS */
#if ENABLE_LOOPBACK/* List of packets to be queued for ourselves. */struct pbuf *loop_first;struct pbuf *loop_last;
#if LWIP_NETIF_LOOPBACK_MULTITHREADING /* SylixOS Add this to fixed loop event lost bug */u8_t loop_schedule;
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
#if LWIP_LOOPBACK_MAX_PBUFSu16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
#endif /* ENABLE_LOOPBACK */#ifdef SYLIXOS /* SylixOS Add */int (*ioctl)(struct netif *, int, void *);void (*up)(struct netif *); /* make net device up */void (*down)(struct netif *); /* make net device down *//* SylixOS firewall */void *inner_fw_stat;int (*inner_fw)(struct netif *, struct pbuf *p); /* inner firewall: net packet filter hook */int (*outer_fw)(void *, struct pbuf *p); /* outer firewall (first arg is netdev *) *//* SylixOS QoS hook (return 7 is highest prio, 0 is lowest prio) */void *inner_qos_stat;u8_t (*inner_qos)(struct netif *, struct pbuf *p, u8_t ipver, u8_t prio, u16_t iphdr_offset, u8_t *dont_drop);u8_t (*outer_qos)(void *, struct pbuf *p, u8_t ipver, u8_t prio, u16_t iphdr_offset, u8_t *dont_drop);/* SylixOS externed flags */int flags2;
#define NETIF_FLAG2_DHCP 0x01
#define NETIF_FLAG2_DHCP6 0x08
#define NETIF_FLAG2_PROMISC 0x02
#define NETIF_FLAG2_ALLMULTI 0x04
#define NETIF_FLAG2_RESTATE 0x10 /* Need to quickly reset the state of the network interface */int priv_flags;void *ext_eth; /* net bridge or bonding or ... eth node */void *ext_ctl; /* net bridge or bonding or ... ctl block */struct netif *ext_inp; /* net bridge or bonding netif */void *flowctl; /* net flow ctl */u32_t sec_region; /* net security region */u16_t vlanid; /* include tag & pri */int metric; /* netif metric (NOT support now) *//* SylixOS TCP optimization parameters */u8_t tcp_ack_freq; /* TCP ACK Delay frequecy */u32_t tcp_wnd; /* TCP rcv_wnd *//* SylixOS mip externed */struct netif *mipif;struct netif *masterif;/* NAT mode */
#define NETIF_NAT_NONE 0
#define NETIF_NAT_AP 1
#define NETIF_NAT_LOCAL 2u8_t nat_mode;/* ARPHRD_xxx */u16_t ar_hrd;
#if PPP_SUPPORTu32_t ppp_ref; /* PPP reference count */
#endif
#if LW_CFG_LWIP_DNS_SWITCH > 0ip_addr_t dns_save[DNS_MAX_SERVERS];
#endif /* LW_CFG_LWIP_DNS_SWITCH */
#if LWIP_IPV6u8_t ip6_addr_is_autocfg[LWIP_IPV6_NUM_ADDRESSES];
#endif
#endif /* SYLIXOS */
};
结构体成员解析
这里定义了一个名为 netif
的结构体,它是 LwIP
网络栈中的一个重要组成部分,用于描述网络接口的状态和功能。LwIP 是一个轻量级的 TCP/IP 协议栈,广泛应用于嵌入式系统中。结构体 netif 包含了大量的字段,每个字段都有特定的功能和用途。
下面是对结构体 netif 中各个字段的解释:
- 链表相关字段
struct netif *next
:指向下一个 netif 结构的指针,用于构建链表。这样可以方便地管理多个网络接口。
- IPv4 相关字段
ip_addr_t ip_addr
:网络接口的 IP 地址。ip_addr_t netmask
:子网掩码。ip_addr_t gw
:默认网关地址。
- IPv6 相关字段
ip_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]
:IPv6 地址数组,存储网络接口上的所有 IPv6 地址。u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]
:IPv6 地址状态,表示每个地址的状态(例如 Tentative、Preferred 等)。u32_t ip6_addr_valid_life[LWIP_IPV6_NUM_ADDRESSES]
:IPv6 地址的有效寿命(单位:秒)。u32_t ip6_addr_pref_life[LWIP_IPV6_NUM_ADDRESSES]
:IPv6 地址的首选寿命(单位:秒)。ip_addr_t ip6_gw
:IPv6 默认网关地址(SylixOS 特定)。
- 输入输出函数指针
netif_input_fn input
:接收数据包的回调函数,当网络设备驱动程序接收到一个数据包时,会调用这个函数将数据包传递给 LwIP 栈进行处理。
netif_output_fn output
:发送 IPv4 数据包的回调函数,当 LwIP 栈需要发送一个 IPv4 数据包时,会调用这个函数。
netif_linkoutput_fn linkoutput
:发送数据帧的回调函数,用于直接发送链路层数据帧。
netif_output_ip6_fn output_ip6
:发送 IPv6 数据包的回调函数,当 LwIP 栈需要发送一个 IPv6 数据包时,会调用这个函数。 - 状态回调函数指针
netif_status_callback_fn status_callback
:当网络接口状态(UP/DOWN)改变时调用的回调函数。netif_status_callback_fn link_callback
:当网络链接状态(UP/DOWN)改变时调用的回调函数。netif_status_callback_fn remove_callback
:当网络接口被移除时调用的回调函数。
- 其他字段
void *state
:设备驱动状态信息的指针,可以存储设备特有的状态信息。void* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX + LWIP_NUM_NETIF_CLIENT_DATA]
:客户端数据数组,用于存储客户端模块的数据。const char* hostname
:网络接口的主机名。u16_t chksum_flags
:校验和标志,用于指示哪些校验和应该由网络接口硬件计算。u16_t mtu
:最大传输单元(MTU),表示该网络接口支持的最大数据包大小。u16_t mtu6
:IPv6 最大传输单元(MTU),用于存储通过路由器通告(RA)更新的 MTU 值。u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
:硬件地址,存储网络接口的物理地址(MAC 地址)。u8_t hwaddr_len
:硬件地址长度,表示实际使用的硬件地址字节数。u8_t flags
:标志位,表示网络接口的各种状态标志(如 UP、DOWN、LINK_UP 等)。char name[2]
:接口名称,通常用于标识网络接口的类型(如 “en” 表示以太网)。u8_t num
:接口编号,用于标识网络接口的唯一性。u8_t ip6_autoconfig_enabled
:是否启用 IPv6 自动配置。u8_t rs_count
:剩余的路由器请求消息数量,用于跟踪发送的路由器请求(Router Solicitation)次数。
- 多播过滤函数指针
netif_igmp_mac_filter_fn igmp_mac_filter
:IPv4 多播过滤函数,用于添加或删除以太网 MAC 多播过滤表项。netif_mld_mac_filter_fn mld_mac_filter
:IPv6 多播过滤函数,用于添加或删除 IPv6 多播过滤表项。
- SylixOS 特定扩展字段
int (*ioctl)(struct netif *, int, void *)
:设备控制命令函数,用于执行设备相关的控制操作。void (*up)(struct netif *)
:使接口上线的函数。void (*down)(struct netif *)
:使接口下线的函数。void *inner_fw_stat
:内部防火墙状态。int (*inner_fw)(struct netif *, struct pbuf *p)
:内部防火墙过滤函数,用于过滤传入的数据包。int (*outer_fw)(void *, struct pbuf *p)
:外部防火墙过滤函数,用于过滤传出的数据包。void *inner_qos_stat
:内部 QoS 状态。u8_t (*inner_qos)(struct netif *, struct pbuf *p, u8_t ipver, u8_t prio, u16_t iphdr_offset, u8_t *dont_drop)
:内部 QoS 调度函数,用于设置数据包的优先级。u8_t (*outer_qos)(void *, struct pbuf *p, u8_t ipver, u8_t prio, u16_t iphdr_offset, u8_t *dont_drop)
:外部 QoS 调度函数,用于设置数据包的优先级。int flags2
:额外标志,用于标记网络接口的其他状态。int priv_flags
:私有标志,用于存储私有标志位。void *ext_eth
:外部以太网节点,用于桥接或绑定多个网络接口。void *ext_ctl
:外部控制块,用于存储外部控制信息。struct netif *ext_inp
:外部网络接口,用于桥接或绑定时的输入接口。void *flowctl
:流控,用于流量控制机制。u32_t sec_region
:安全区域,用于标识网络接口的安全区域。u16_t vlanid
:VLAN ID,用于标识虚拟局域网。int metric
:接口度量,用于路由选择时的权重。u8_t tcp_ack_freq
:TCP ACK 延迟频率,用于优化 TCP 的 ACK 发送策略。u32_t tcp_wnd
:TCP 接收窗口大小,用于设置 TCP 的接收窗口大小。struct netif *mipif
:移动 IP 接口,用于移动 IP 的相关操作。struct netif *masterif
:主接口,用于指定桥接或绑定的主接口。u8_t nat_mode
:NAT 模式,用于标识 NAT 操作模式。u16_t ar_hrd
:ARP 硬件类型,用于 ARP 请求时的硬件类型。u32_t ppp_ref
:PPP 引用计数,用于跟踪 PPP 连接的数量。ip_addr_t dns_save[DNS_MAX_SERVERS]
:保存的 DNS 服务器地址,用于存储 DNS 服务器地址。u8_t ip6_addr_is_autocfg[LWIP_IPV6_NUM_ADDRESSES]
:IPv6 地址是否自动配置,用于标记 IPv6 地址是否通过自动配置获得。
总结
netif
结构体是 LwIP 网络栈中的核心组件之一,它用于描述网络接口的各种属性和状态,并提供了与网络接口相关的各种操作函数。通过正确配置和使用 netif 结构体,可以在 LwIP 中实现对不同网络接口的支持和管理。这些字段覆盖了网络接口的基础配置、IPv4/IPv6 地址管理、输入输出操作、状态变更通知等功能,使得 LwIP 能够灵活地适配不同的网络环境和设备。