Start working task #14494: Implement SO_BINDTODEVICE

Implement binding TCP, UDP and RAW PCBs to a netif
This commit is contained in:
Dirk Ziegelmeier 2017-05-02 09:39:48 +02:00
parent 20fed63297
commit 13ffc86aef
8 changed files with 141 additions and 53 deletions

View File

@ -69,6 +69,12 @@ raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast)
{ {
LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
/* check if PCB is bound to specific netif */
if ((pcb->netif_idx != NETIF_NO_INDEX) &&
(pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
return 0;
}
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
/* Dual-stack: PCBs listening to any IP type also listen to any IP address */ /* Dual-stack: PCBs listening to any IP type also listen to any IP address */
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
@ -227,6 +233,25 @@ raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
return ERR_OK; return ERR_OK;
} }
/**
* @ingroup raw_raw
* Bind a RAW PCB.
*
* @param pcb RAW PCB to be bound with netif.
* @param netif netif to bind to. Can be NULL.
*
* @see raw_disconnect()
*/
void
raw_bind_netif(struct raw_pcb *pcb, const struct netif *netif)
{
if (netif != NULL) {
pcb->netif_idx = netif_get_index(netif);
} else {
pcb->netif_idx = NETIF_NO_INDEX;
}
}
/** /**
* @ingroup raw_raw * @ingroup raw_raw
* Connect an RAW PCB. This function is required by upper layers * Connect an RAW PCB. This function is required by upper layers
@ -279,6 +304,7 @@ raw_disconnect(struct raw_pcb *pcb)
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
} }
#endif #endif
pcb->netif_idx = NETIF_NO_INDEX;
/* mark PCB as unconnected */ /* mark PCB as unconnected */
pcb->flags &= ~RAW_FLAGS_CONNECTED; pcb->flags &= ~RAW_FLAGS_CONNECTED;
} }
@ -325,6 +351,9 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
if (pcb->netif_idx != NETIF_NO_INDEX) {
netif = netif_get_by_index(pcb->netif_idx);
} else {
#if LWIP_MULTICAST_TX_OPTIONS #if LWIP_MULTICAST_TX_OPTIONS
netif = NULL; netif = NULL;
if (ip_addr_ismulticast(ipaddr)) { if (ip_addr_ismulticast(ipaddr)) {
@ -344,6 +373,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
netif = ip_route(&pcb->local_ip, ipaddr); netif = ip_route(&pcb->local_ip, ipaddr);
} }
} }
}
if (netif == NULL) { if (netif == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));

View File

@ -546,7 +546,7 @@ tcp_abort(struct tcp_pcb *pcb)
* *
* @param pcb the tcp_pcb to bind (no check is done whether this pcb is * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
* already bound!) * already bound!)
* @param ipaddr the local ip address to bind to (use IP4_ADDR_ANY to bind * @param ipaddr the local ip address to bind to (use IPx_ADDR_ANY to bind
* to any local address * to any local address
* @param port the local port to bind to * @param port the local port to bind to
* @return ERR_USE if the port is already in use * @return ERR_USE if the port is already in use
@ -639,6 +639,24 @@ tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
return ERR_OK; return ERR_OK;
} }
/**
* @ingroup tcp_raw
* Binds the connection to a netif and IP address.
*
* @param pcb the tcp_pcb to bind.
* @param netif the netif to bind to. Can be NULL.
*/
void
tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif)
{
if (netif != NULL) {
pcb->netif_idx = netif_get_index(netif);
} else {
pcb->netif_idx = NETIF_NO_INDEX;
}
}
#if LWIP_CALLBACK_API #if LWIP_CALLBACK_API
/** /**
* Default accept callback if no accept callback is specified by the user. * Default accept callback if no accept callback is specified by the user.

View File

@ -268,6 +268,12 @@ tcp_input(struct pbuf *p, struct netif *inp)
are LISTENing for incoming connections. */ are LISTENing for incoming connections. */
prev = NULL; prev = NULL;
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
/* check if PCB is bound to specific netif */
if ((pcb->netif_idx != NETIF_NO_INDEX) &&
(pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
continue;
}
if (lpcb->local_port == tcphdr->dest) { if (lpcb->local_port == tcphdr->dest) {
if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) { if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) {
/* found an ANY TYPE (IPv4/IPv6) match */ /* found an ANY TYPE (IPv4/IPv6) match */

View File

@ -129,9 +129,14 @@ again:
static u8_t static u8_t
udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast) udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
{ {
LWIP_UNUSED_ARG(inp); /* in IPv6 only case */
LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
/* check if PCB is bound to specific netif */
if ((pcb->netif_idx != NETIF_NO_INDEX) &&
(pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
return 0;
}
/* Dual-stack: PCBs listening to any IP type also listen to any IP address */ /* Dual-stack: PCBs listening to any IP type also listen to any IP address */
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
#if LWIP_IPV4 && IP_SOF_BROADCAST_RECV #if LWIP_IPV4 && IP_SOF_BROADCAST_RECV
@ -522,6 +527,9 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
if (pcb->netif_idx != NETIF_NO_INDEX) {
netif = netif_get_by_index(pcb->netif_idx);
} else {
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
/* Don't call ip_route() with IP_ANY_TYPE */ /* Don't call ip_route() with IP_ANY_TYPE */
src_ip_route = IP46_ADDR_ANY(IP_GET_TYPE(dst_ip)); src_ip_route = IP46_ADDR_ANY(IP_GET_TYPE(dst_ip));
@ -567,6 +575,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
/* find the outgoing network interface for this packet */ /* find the outgoing network interface for this packet */
netif = ip_route(src_ip_route, dst_ip); netif = ip_route(src_ip_route, dst_ip);
} }
}
/* no outgoing network interface could be found? */ /* no outgoing network interface could be found? */
if (netif == NULL) { if (netif == NULL) {
@ -994,6 +1003,25 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
return ERR_OK; return ERR_OK;
} }
/**
* @ingroup udp_raw
* Bind an UDP PCB to a specific netif.
*
* @param pcb UDP PCB to be bound.
* @param netif netif to bind udp pcb to. Can be NULL.
*
* @see udp_disconnect()
*/
void
udp_bind_netif(struct udp_pcb *pcb, const struct netif *netif)
{
if (netif != NULL) {
pcb->netif_idx = netif_get_index(netif);
} else {
pcb->netif_idx = NETIF_NO_INDEX;
}
}
/** /**
* @ingroup udp_raw * @ingroup udp_raw
* Connect an UDP PCB. * Connect an UDP PCB.
@ -1079,6 +1107,7 @@ udp_disconnect(struct udp_pcb *pcb)
} }
#endif #endif
pcb->remote_port = 0; pcb->remote_port = 0;
pcb->netif_idx = NETIF_NO_INDEX;
/* mark PCB as unconnected */ /* mark PCB as unconnected */
pcb->flags &= ~UDP_FLAGS_CONNECTED; pcb->flags &= ~UDP_FLAGS_CONNECTED;
} }

View File

@ -77,6 +77,8 @@ extern "C" {
/* ip addresses in network byte order */ \ /* ip addresses in network byte order */ \
ip_addr_t local_ip; \ ip_addr_t local_ip; \
ip_addr_t remote_ip; \ ip_addr_t remote_ip; \
/* Bound netif index */ \
u8_t netif_idx; \
/* Socket options */ \ /* Socket options */ \
u8_t so_options; \ u8_t so_options; \
/* Type Of Service */ \ /* Type Of Service */ \

View File

@ -105,6 +105,7 @@ struct raw_pcb * raw_new (u8_t proto);
struct raw_pcb * raw_new_ip_type(u8_t type, u8_t proto); struct raw_pcb * raw_new_ip_type(u8_t type, u8_t proto);
void raw_remove (struct raw_pcb *pcb); void raw_remove (struct raw_pcb *pcb);
err_t raw_bind (struct raw_pcb *pcb, const ip_addr_t *ipaddr); err_t raw_bind (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
void raw_bind_netif (struct raw_pcb *pcb, const struct netif *netif);
err_t raw_connect (struct raw_pcb *pcb, const ip_addr_t *ipaddr); err_t raw_connect (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
void raw_disconnect (struct raw_pcb *pcb); void raw_disconnect (struct raw_pcb *pcb);

View File

@ -385,6 +385,7 @@ void tcp_backlog_accepted(struct tcp_pcb* pcb);
void tcp_recved (struct tcp_pcb *pcb, u16_t len); void tcp_recved (struct tcp_pcb *pcb, u16_t len);
err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port); u16_t port);
void tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif);
err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port, tcp_connected_fn connected); u16_t port, tcp_connected_fn connected);

View File

@ -121,6 +121,7 @@ struct udp_pcb * udp_new_ip_type(u8_t type);
void udp_remove (struct udp_pcb *pcb); void udp_remove (struct udp_pcb *pcb);
err_t udp_bind (struct udp_pcb *pcb, const ip_addr_t *ipaddr, err_t udp_bind (struct udp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port); u16_t port);
void udp_bind_netif (struct udp_pcb *pcb, const struct netif* netif);
err_t udp_connect (struct udp_pcb *pcb, const ip_addr_t *ipaddr, err_t udp_connect (struct udp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port); u16_t port);
void udp_disconnect (struct udp_pcb *pcb); void udp_disconnect (struct udp_pcb *pcb);