/**
* @ingroup netif
* Add a network interface to the list of lwIP netifs.
*
* @param netif a pre-allocated netif structure
* @param ipaddr IP address for the new netif
* @param netmask network mask for the new netif
* @param gw default gateway IP address for the new netif
* @param state opaque data passed to the new netif
* @param init callback function that initializes the interface
* @param input callback function that is called to pass
* ingress packets up in the protocol layer stack.\n
* It is recommended to use a function that passes the input directly
* to the stack (netif_input(), NO_SYS=1 mode) or via sending a
* message to TCPIP thread (tcpip_input(), NO_SYS=0 mode).\n
* These functions use netif flags NETIF_FLAG_ETHARP and NETIF_FLAG_ETHERNET
* to decide whether to forward to ethernet_input() or ip_input().
* In other words, the functions only work when the netif
* driver is implemented correctly!\n
* Most members of struct netif should be be initialized by the
* netif init function = netif driver (init parameter of this function).\n
* IPv6: Don't forget to call netif_create_ip6_linklocal_address() after
* setting the MAC address in struct netif.hwaddr
* (IPv6 requires a link-local address).
*
* @return netif, or NULL if failed.
*/
struct netif *
netif_add(struct netif *netif,
#if LWIP_IPV4
const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
#endif /* LWIP_IPV4 */
void *state, netif_init_fn init, netif_input_fn input)
{
#if LWIP_IPV6
s8_t i;
#endif
#if LWIP_SINGLE_NETIF
if (netif_default != NULL) {
LWIP_ASSERT("single netif already set", 0);
return NULL;
}
#endif
LWIP_ASSERT("No init function given", init != NULL);
#if LWIP_IPV4
if (ipaddr == NULL) {
ipaddr = ip_2_ip4(IP4_ADDR_ANY);
}
if (netmask == NULL) {
netmask = ip_2_ip4(IP4_ADDR_ANY);
}
if (gw == NULL) {
gw = ip_2_ip4(IP4_ADDR_ANY);
}
/* reset new interface configuration state */
ip_addr_set_zero_ip4(&netif->ip_addr);
ip_addr_set_zero_ip4(&netif->netmask);
ip_addr_set_zero_ip4(&netif->gw);
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
ip_addr_set_zero_ip6(&netif->ip6_addr[i]);
netif->ip6_addr_state[i] = IP6_ADDR_INVALID;
#if LWIP_IPV6_ADDRESS_LIFETIMES
netif->ip6_addr_valid_life[i] = IP6_ADDR_LIFE_STATIC;
netif->ip6_addr_pref_life[i] = IP6_ADDR_LIFE_STATIC;
#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
}
netif->output_ip6 = netif_null_output_ip6;
#endif /* LWIP_IPV6 */
NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
netif->flags = 0;
#ifdef netif_get_client_data
memset(netif->client_data, 0, sizeof(netif->client_data));
#endif /* LWIP_NUM_NETIF_CLIENT_DATA */
#if LWIP_IPV6_AUTOCONFIG
/* IPv6 address autoconfiguration not enabled by default */
#ifdef LTE_NBIOT_SUPPORT
netif->ip6_autoconfig_enabled = 1;
#else
netif->ip6_autoconfig_enabled = 0;
#endif
#endif /* LWIP_IPV6_AUTOCONFIG */
#if LWIP_IPV6_SEND_ROUTER_SOLICIT
netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT;
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
#if LWIP_NETIF_STATUS_CALLBACK
netif->status_callback = NULL;
#endif /* LWIP_NETIF_STATUS_CALLBACK */
#if LWIP_NETIF_LINK_CALLBACK
netif->link_callback = NULL;
#endif /* LWIP_NETIF_LINK_CALLBACK */
#if LWIP_IGMP
netif->igmp_mac_filter = NULL;
#endif /* LWIP_IGMP */
#if LWIP_IPV6 && LWIP_IPV6_MLD
netif->mld_mac_filter = NULL;
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
#if ENABLE_LOOPBACK
netif->loop_first = NULL;
netif->loop_last = NULL;
#endif /* ENABLE_LOOPBACK */
/* remember netif specific state information data */
netif->state = state;
netif->num = netif_num;
netif->input = input;
NETIF_RESET_HINTS(netif);
#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
netif->loop_cnt_current = 0;
#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
#if LWIP_IPV4
netif_set_addr(netif, ipaddr, netmask, gw);
#endif /* LWIP_IPV4 */
/* call user specified initialization function for netif */
if (init(netif) != ERR_OK) {
return NULL;
}
#if !LWIP_SINGLE_NETIF
/* Assign a unique netif number in the range [0..254], so that (num+1) can
serve as an interface index that fits in a u8_t.
We assume that the new netif has not yet been added to the list here.
This algorithm is O(n^2), but that should be OK for lwIP.
*/
{
struct netif *netif2;
int num_netifs;
do {
if (netif->num == 255) {
netif->num = 0;
}
num_netifs = 0;
for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) {
num_netifs++;
LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255);
if (netif2->num == netif->num) {
netif->num++;
break;
}
}
} while (netif2 != NULL);
}
netif_num = netif->num + 1;
/* add this netif to the list */
netif->next = netif_list;
netif_list = netif;
#endif /* "LWIP_SINGLE_NETIF */
mib2_netif_added(netif);
#if LWIP_IGMP
/* start IGMP processing */
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_start(netif);
}
#endif /* LWIP_IGMP */
LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP",
netif->name[0], netif->name[1]));
#if LWIP_IPV4
LWIP_DEBUGF(NETIF_DEBUG, (" addr "));
ip4_addr_debug_print(NETIF_DEBUG, ipaddr);
LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
ip4_addr_debug_print(NETIF_DEBUG, netmask);
LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
ip4_addr_debug_print(NETIF_DEBUG, gw);
#endif /* LWIP_IPV4 */
LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL);
return netif;
}