Merge remote-tracking branch 'origin/master' into st25fl1

This commit is contained in:
Gregory Nutt
2015-08-27 12:12:24 -06:00
16 changed files with 170 additions and 52 deletions
+9
View File
@@ -10889,4 +10889,13 @@
with the SAMV71 QSPI hardware (2015-08-25).
* drivers/rwbuffer.c: Fix some logic errors. From Dmitry Nikolaev
via Juha Niskanen (2015-08-26).
* net/socket and net/tcp: Fix a problem in whent there are multiple
network devices. Polls were being sent to all TCP sockets before.
This is not good because it means that packets may sometimes be
sent out on the wrong device. That is inefficient because it
will cause retransmissions and bad performance. But, worse, when
one of the devices is not Ethernet, it will have a different MSS
and, as a result, incorrect data transfers can cause crashes.
The fix is to lock into a single device once the MSS is locked
locked down (2015-08-27).
+1 -1
Submodule arch updated: 5f3f8a53bb...131d15e819
+1 -1
Submodule configs updated: e1e1873700...0198c46e0b
+24 -5
View File
@@ -96,6 +96,7 @@
struct lo_driver_s
{
bool lo_bifup; /* true:ifup false:ifdown */
bool lo_txdone; /* One RX packet was looped back */
WDOG_ID lo_polldog; /* TX poll timer */
struct work_s lo_work; /* For deferring work to the work queue */
@@ -111,7 +112,7 @@ struct lo_driver_s
static struct lo_driver_s g_loopback;
#ifdef CONFIG_NET_MULTIBUFFER
static uint8_t g_iobuffer[[MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE];
static uint8_t g_iobuffer[MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE];
#endif
/****************************************************************************
@@ -146,8 +147,8 @@ static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
*
* Description:
* Check if the network has any outgoing packets ready to send. This is
* a callback from devif_poll(). devif_poll() will be called only during
* normal TX polling.
* a callback from devif_poll() or devif_timer(). devif_poll() will be
* called only during normal TX polling.
*
* Parameters:
* dev - Reference to the NuttX driver state structure
@@ -201,6 +202,8 @@ static int lo_txpoll(FAR struct net_driver_s *dev)
ndbg("WARNING: Unrecognized packet type dropped: %02x\n", IPv4BUF->vhl);
priv->lo_dev.d_len = 0;
}
priv->lo_txdone = true;
}
return 0;
@@ -231,8 +234,19 @@ static void lo_poll_work(FAR void *arg)
/* Perform the poll */
state = net_lock();
priv->lo_txdone = false;
(void)devif_timer(&priv->lo_dev, lo_txpoll, LO_POLLHSEC);
/* Was something received and looped back? */
while (priv->lo_txdone)
{
/* Yes, poll again for more TX data */
priv->lo_txdone = false;
(void)devif_poll(&priv->lo_dev, lo_txpoll);
}
/* Setup the watchdog poll timer again */
(void)wd_start(priv->lo_polldog, LO_WDDELAY, lo_poll_expiry, 1, priv);
@@ -379,9 +393,14 @@ static void lo_txavail_work(FAR void *arg)
state = net_lock();
if (priv->lo_bifup)
{
/* If so, then poll the network for new XMIT data */
do
{
/* If so, then poll the network for new XMIT data */
(void)devif_poll(&priv->lo_dev, lo_txpoll);
priv->lo_txdone = false;
(void)devif_poll(&priv->lo_dev, lo_txpoll);
}
while (priv->lo_txdone);
}
net_unlock(state);
+1 -1
View File
@@ -102,7 +102,7 @@ config NET_SLIP_MTU
bytes of data: 40 + 128. I believe that is to allow for the 2x
worst cast packet expansion. Ideally we would like to advertise the
256 MSS, but restrict transfers to 128 bytes (possibly by modifying
the tcp_mss() macro).
the MSS value in the TCP connection structure).
config NET_SLIP_TCP_RECVWNDO
+2 -2
View File
@@ -423,8 +423,8 @@ uint16_t devif_dev_event(FAR struct net_driver_s *dev, void *pvconn,
* The amount of data that actually is sent out after a call to this
* function is determined by the maximum amount of data TCP allows. uIP
* will automatically crop the data so that only the appropriate
* amount of data is sent. The function tcp_mss() can be used to query
* uIP for the amount of data that actually will be sent.
* amount of data is sent. The mss field of the TCP connection structure
* can be used to determine the amount of data that actually will be sent.
*
* Note: This function does not guarantee that the sent data will
* arrive at the destination. If the data is lost in the network, the
+1 -1
View File
@@ -79,7 +79,7 @@
*
* Description:
* Notify the device driver that forwards the IPv4 address that the
* application waits for RX data.
* application waits for RX data.
*
* Parameters:
* lipaddr - The local board IPv6 address of the socket
+18 -8
View File
@@ -278,22 +278,32 @@ static uint16_t psock_connect_interrupt(FAR struct net_driver_s *dev,
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
if (pstate->tc_conn->domain == PF_INET)
if (pstate->tc_conn->domain == PF_INET)
#endif
{
pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev);
}
{
pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev);
}
#endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
else
else
#endif
{
pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev);
}
{
pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev);
}
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NETDEV_MULTINIC
/* We now have to filter all outgoing transfers so that they use only
* the MSS of this device.
*/
DEBUGASSERT(pstate->tc_conn->dev == NULL ||
pstate->tc_conn->dev == dev);
pstate->tc_conn->dev = dev;
#endif /* CONFIG_NETDEV_MULTINIC */
#endif /* CONFIG_NET_MULTILINK */
/* Wake up the waiting thread */
+18
View File
@@ -163,6 +163,24 @@ static uint16_t connection_event(FAR struct net_driver_s *dev,
else if ((flags & TCP_CONNECTED) != 0)
{
#if 0 /* REVISIT: Assertion fires. Why? */
#ifdef CONFIG_NETDEV_MULTINIC
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn;
/* Make sure that this is the device bound to the connection */
DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
conn->dev = dev;
#endif
#endif
/* If there is no local address assigned to the socket (perhaps
* because it was INADDR_ANY), then assign it the address of the
* connecting device.
*
* TODO: Implement this.
*/
/* Indicate that the socket is now connected */
psock->s_flags |= _SF_CONNECTED;
+14 -2
View File
@@ -324,6 +324,18 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon
FAR struct sendfile_s *pstate = (FAR struct sendfile_s *)pvpriv;
int ret;
#ifdef CONFIG_NETDEV_MULTINIC
/* The TCP socket is connected and, hence, should be bound to a device.
* Make sure that the polling device is the own that we are bound to.
*/
DEBUGASSERT(conn->dev != NULL);
if (dev != conn->dev)
{
return flags;
}
#endif
nllvdbg("flags: %04x acked: %d sent: %d\n",
flags, pstate->snd_acked, pstate->snd_sent);
@@ -354,9 +366,9 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon
uint32_t sndlen = pstate->snd_flen - pstate->snd_sent;
if (sndlen > tcp_mss(conn))
if (sndlen > conn->mss)
{
sndlen = tcp_mss(conn);
sndlen = conn->mss;
}
/* Check if we have "space" in the window */
+31 -14
View File
@@ -157,7 +157,7 @@ static inline void recvfrom_add_recvlen(FAR struct recvfrom_s *pstate,
* The number of bytes taken from the packet.
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
@@ -205,7 +205,7 @@ static size_t recvfrom_newdata(FAR struct net_driver_s *dev,
* None.
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
@@ -249,7 +249,7 @@ static void recvfrom_newpktdata(FAR struct net_driver_s *dev,
* None.
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
@@ -321,7 +321,7 @@ static inline void recvfrom_newtcpdata(FAR struct net_driver_s *dev,
* None.
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
@@ -353,7 +353,7 @@ static inline void recvfrom_newudpdata(FAR struct net_driver_s *dev,
* None
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
@@ -520,7 +520,7 @@ out:
* TRUE:timeout FALSE:no timeout
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
@@ -616,7 +616,7 @@ static inline void recvfrom_pktsender(FAR struct net_driver_s *dev,
#ifdef CONFIG_NET_PKT
static uint16_t recvfrom_pktinterrupt(FAR struct net_driver_s *dev,
FAR void *conn, FAR void *pvpriv,
FAR void *pvconn, FAR void *pvpriv,
uint16_t flags)
{
struct recvfrom_s *pstate = (struct recvfrom_s *)pvpriv;
@@ -744,24 +744,40 @@ static inline void recvfrom_tcpsender(FAR struct net_driver_s *dev,
*
* Parameters:
* dev The structure of the network driver that caused the interrupt
* conn The connection structure associated with the socket
* pvconn The connection structure associated with the socket
* flags Set of events describing why the callback was invoked
*
* Returned Value:
* None
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
#ifdef CONFIG_NET_TCP
static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev,
FAR void *conn, FAR void *pvpriv,
FAR void *pvconn, FAR void *pvpriv,
uint16_t flags)
{
FAR struct recvfrom_s *pstate = (struct recvfrom_s *)pvpriv;
#if 0 /* REVISIT: The assertion fires. Why? */
#ifdef CONFIG_NETDEV_MULTINIC
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
/* The TCP socket is connected and, hence, should be bound to a device.
* Make sure that the polling device is the own that we are bound to.
*/
DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
if (conn->dev != NULL && conn->dev != dev)
{
return flags;
}
#endif
#endif
nllvdbg("flags: %04x\n", flags);
/* 'priv' might be null in some race conditions (?) */
@@ -956,7 +972,7 @@ static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev,
* None
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
@@ -1049,7 +1065,8 @@ static inline void recvfrom_udpsender(struct net_driver_s *dev, struct recvfrom_
* Terminate the UDP transfer.
*
* Parameters:
* conn The connection structure associated with the socket
* pstate - The recvfrom state structure
* result - The result of the operation
*
* Returned Value:
* None
@@ -1086,14 +1103,14 @@ static void recvfrom_udp_terminate(FAR struct recvfrom_s *pstate, int result)
*
* Parameters:
* dev The structure of the network driver that caused the interrupt
* conn The connection structure associated with the socket
* pvconn The connection structure associated with the socket
* flags Set of events describing why the callback was invoked
*
* Returned Value:
* None
*
* Assumptions:
* Running at the interrupt level
* The network is locked.
*
****************************************************************************/
-6
View File
@@ -101,12 +101,6 @@
devif_conn_callback_free(g_netdevices, cb, NULL)
#endif
/* Get the current maximum segment size that can be sent on the current
* TCP connection.
*/
#define tcp_mss(conn) ((conn)->mss)
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* TCP write buffer access macros */
+17 -2
View File
@@ -1003,6 +1003,13 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr);
#ifdef CONFIG_NETDEV_MULTINIC
net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr);
/* We now have to filter all outgoing transfers so that they use
* only the MSS of this device.
*/
DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
conn->dev = dev;
#endif
/* Find the device that can receive packets on the network
@@ -1028,6 +1035,13 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
#ifdef CONFIG_NETDEV_MULTINIC
net_ipv4addr_copy(conn->u.ipv4.laddr,
net_ip4addr_conv32(ip->destipaddr));
/* We now have to filter all outgoing transfers so that they use
* only the MSS of this device.
*/
DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
conn->dev = dev;
#endif
/* Find the device that can receive packets on the network
@@ -1238,8 +1252,9 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
goto errout_with_lock;
}
/* Set up the local address (laddr) and the remote address (raddr) that describes the TCP connection.
*/
/* Set up the local address (laddr) and the remote address (raddr) that
* describes the TCP connection.
*/
#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
+1 -1
View File
@@ -243,7 +243,7 @@ bool tcp_islistener(uint16_t portno)
* Accept the new connection for the specified listening port.
*
* Assumptions:
* Called at interrupt level
* Called with the network locked.
*
****************************************************************************/
+14 -2
View File
@@ -338,6 +338,18 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
FAR struct socket *psock = (FAR struct socket *)pvpriv;
#ifdef CONFIG_NETDEV_MULTINIC
/* The TCP socket is connected and, hence, should be bound to a device.
* Make sure that the polling device is the own that we are bound to.
*/
DEBUGASSERT(conn->dev != NULL);
if (dev != conn->dev)
{
return flags;
}
#endif
nllvdbg("flags: %04x\n", flags);
/* If this packet contains an acknowledgement, then update the count of
@@ -697,9 +709,9 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
*/
sndlen = WRB_PKTLEN(wrb) - WRB_SENT(wrb);
if (sndlen > tcp_mss(conn))
if (sndlen > conn->mss)
{
sndlen = tcp_mss(conn);
sndlen = conn->mss;
}
if (sndlen > conn->winsize)
+18 -6
View File
@@ -290,6 +290,18 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
FAR struct send_s *pstate = (FAR struct send_s *)pvpriv;
#ifdef CONFIG_NETDEV_MULTINIC
/* The TCP socket is connected and, hence, should be bound to a device.
* Make sure that the polling device is the own that we are bound to.
*/
DEBUGASSERT(conn->dev != NULL);
if (dev != conn->dev)
{
return flags;
}
#endif
nllvdbg("flags: %04x acked: %d sent: %d\n",
flags, pstate->snd_acked, pstate->snd_sent);
@@ -442,12 +454,12 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
if (sndlen >= CONFIG_NET_TCP_SPLIT_SIZE)
{
/* sndlen is the number of bytes remaining to be sent.
* tcp_mss(conn) will return the number of bytes that can sent
* conn->mss will provide the number of bytes that can sent
* in one packet. The difference, then, is the number of bytes
* that would be sent in the next packet after this one.
*/
int32_t next_sndlen = sndlen - tcp_mss(conn);
int32_t next_sndlen = sndlen - conn->mss;
/* Is this the even packet in the packet pair transaction? */
@@ -474,13 +486,13 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
{
/* Will there be another (even) packet afer this one?
* (next_sndlen > 0) Will the split condition occur on that
* next, even packet? ((next_sndlen - tcp_mss(conn)) < 0) If
* next, even packet? ((next_sndlen - conn->mss) < 0) If
* so, then perform the split now to avoid the case where the
* byte count is less than CONFIG_NET_TCP_SPLIT_SIZE on the
* next pair.
*/
if (next_sndlen > 0 && (next_sndlen - tcp_mss(conn)) < 0)
if (next_sndlen > 0 && (next_sndlen - conn->mss) < 0)
{
/* Here, we know that sndlen must be MSS < sndlen <= 2*MSS
* and so (sndlen / 2) is <= MSS.
@@ -497,9 +509,9 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
#endif /* CONFIG_NET_TCP_SPLIT */
if (sndlen > tcp_mss(conn))
if (sndlen > conn->mss)
{
sndlen = tcp_mss(conn);
sndlen = conn->mss;
}
/* Check if we have "space" in the window */