diff --git a/CHANGELOG b/CHANGELOG index 136e7a9a..29f606c5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,12 @@ HISTORY ++ New features: + 2007-07-13 Jared Grubb (integrated by Frédéric Bernon) + * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add + a link callback in the netif struct, and functions to handle it. Be carefull + for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) + if you want to be sure to be compatible with future changes... + 2007-06-30 Frédéric Bernon * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. diff --git a/src/core/netif.c b/src/core/netif.c index 9f46642c..5ca79620 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -48,6 +48,17 @@ #include "netif/etharp.h" #endif /* LWIP_ARP */ +#if LWIP_NETIF_CALLBACK +#define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); } +#else +#define NETIF_STATUS_CALLBACK(n) { /* NOP */ } +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +#define NETIF_LINK_CALLBACK(n) { if (n->link_callback) (n->link_callback)(n); } +#else +#define NETIF_LINK_CALLBACK(n) { /* NOP */ } +#endif /* LWIP_NETIF_LINK_CALLBACK */ struct netif *netif_list = NULL; struct netif *netif_default = NULL; @@ -100,6 +111,9 @@ netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, #if LWIP_NETIF_CALLBACK netif->status_callback = NULL; #endif /* LWIP_NETIF_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + netif->link_callback = NULL; +#endif /* LWIP_NETIF_LINK_CALLBACK */ /* remember netif specific state information data */ netif->state = state; @@ -364,10 +378,8 @@ void netif_set_up(struct netif *netif) snmp_get_sysuptime(&netif->ts); #endif /* LWIP_SNMP */ -#if LWIP_NETIF_CALLBACK - if ( netif->status_callback ) - (netif->status_callback)( netif ); -#endif /* LWIP_NETIF_CALLBACK */ + NETIF_LINK_CALLBACK(netif); + NETIF_STATUS_CALLBACK(netif); #if LWIP_ARP /** For Ethernet network interfaces, we would like to send a @@ -408,10 +420,8 @@ void netif_set_down(struct netif *netif) snmp_get_sysuptime(&netif->ts); #endif -#if LWIP_NETIF_CALLBACK - if ( netif->status_callback ) - (netif->status_callback)( netif ); -#endif /* LWIP_NETIF_CALLBACK */ + NETIF_LINK_CALLBACK(netif); + NETIF_STATUS_CALLBACK(netif); } } @@ -425,3 +435,40 @@ void netif_set_status_callback( struct netif *netif, void (* status_callback)(st netif->status_callback = status_callback; } #endif /* LWIP_NETIF_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +/** + * Set callback to be called when link is brought up/down + */ +void netif_set_link_callback( struct netif *netif, void (* link_callback)(struct netif *netif )) +{ + if ( netif ) + netif->link_callback = link_callback; +} +/** + * Called by a driver when its link goes down + */ +void netif_set_link_down( struct netif *netif ) +{ + netif->flags &= ~NETIF_FLAG_LINK_UP; +} + +/** + * Called by a driver when its link goes up + */ +void netif_set_link_up( struct netif *netif ) +{ + netif->flags |= NETIF_FLAG_LINK_UP; + +#if LWIP_ARP + /** For Ethernet network interfaces, we would like to send a + * "gratuitous ARP"; this is an ARP packet sent by a node in order + * to spontaneously cause other nodes to update an entry in their + * ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6. + */ + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_query(netif, &(netif->ip_addr), NULL); + } +#endif /* LWIP_ARP */ +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index fefe7638..80f2635a 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -64,18 +64,18 @@ extern "C" { * a software flag used to control whether this network * interface is enabled and processes traffic. */ -#define NETIF_FLAG_UP 0x1U +#define NETIF_FLAG_UP 0x01U /** if set, the netif has broadcast capability */ -#define NETIF_FLAG_BROADCAST 0x2U +#define NETIF_FLAG_BROADCAST 0x02U /** if set, the netif is one end of a point-to-point connection */ -#define NETIF_FLAG_POINTTOPOINT 0x4U +#define NETIF_FLAG_POINTTOPOINT 0x04U /** if set, the interface is configured using DHCP */ -#define NETIF_FLAG_DHCP 0x08U +#define NETIF_FLAG_DHCP 0x08U /** if set, the interface has an active link * (set by the network interface driver) */ -#define NETIF_FLAG_LINK_UP 0x10U +#define NETIF_FLAG_LINK_UP 0x10U /** if set, the netif is an device using ARP */ -#define NETIF_FLAG_ETHARP 0x20U +#define NETIF_FLAG_ETHARP 0x20U /** Generic data structure used for all lwIP network interfaces. * The following fields should be filled in by the initialization @@ -106,7 +106,12 @@ struct netif { /** This function is called when the netif state is set to up or down */ void (* status_callback)(struct netif *netif); -#endif /* end, LWIP_NETIF_CALLBACK */ +#endif /* LWIP_NETIF_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + /** This function is called when the netif link is set to up or down + */ + void (* link_callback)(struct netif *netif); +#endif /* LWIP_NETIF_LINK_CALLBACK */ /** This field can be set by the device driver and could point * to state information for the device. */ void *state; @@ -217,9 +222,18 @@ u8_t netif_is_up(struct netif *netif); /* * Set callback to be called when interface is brought up/down */ -void netif_set_status_callback( struct netif *netif, void (* status_callback)(struct netif *netif )); +void netif_set_status_callback( struct netif *netif, void (* status_callback)(struct netif *netif)); #endif /* LWIP_NETIF_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK +/* + * Set callback to be called when link is brought up/down + */ +void netif_set_link_callback( struct netif *netif, void (* link_callback)(struct netif *netif)); +void netif_set_link_down( struct netif *netif); +void netif_set_link_up( struct netif *netif); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + #ifdef __cplusplus } #endif diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index aeb42663..edbb9423 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -476,11 +476,16 @@ #define LWIP_NETIF_API 0 #endif -/* Support network interface callbacks */ +/* Support network interface status callback */ #ifndef LWIP_NETIF_CALLBACK #define LWIP_NETIF_CALLBACK 0 #endif +/* Support network interface link callback */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + /** Cache link-layer-address hints (e.g. table indices) in struct netif. TCP and UDP can make use of this to prevent scanning the ARP table for every sent packet. While this is faster for big ARP tables or many diff --git a/src/netif/ethernetif.c b/src/netif/ethernetif.c index 202e7105..6f8a80e2 100644 --- a/src/netif/ethernetif.c +++ b/src/netif/ethernetif.c @@ -91,7 +91,7 @@ low_level_init(struct netif *netif) /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; /* Do whatever else is needed to initialize interface. */ } @@ -241,7 +241,7 @@ ethernetif_input(struct netif *netif) pbuf_free(p); p = NULL; } - break; + break; #else /* ETHARP_TCPIP_ETHINPUT */ #if ETHARP_TCPIP_INPUT