IPv6 -- various fixed from problems found in testing

This commit is contained in:
Gregory Nutt 2015-01-21 10:29:18 -06:00
parent 4498bf9f5b
commit 3202819328
5 changed files with 62 additions and 22 deletions

View file

@ -148,7 +148,7 @@ void arp_out(FAR struct net_driver_s *dev)
{
/* Clear the indication and let the packet continue on its way. */
IFF_CLR_IPv6(dev->d_flags);
IFF_CLR_NOARP(dev->d_flags);
return;
}
#endif

View file

@ -188,6 +188,13 @@ void icmpv6_input(FAR struct net_driver_s *dev)
adv->flags[1] = 0;
adv->flags[2] = 0;
adv->flags[3] = 0;
/* Copy the target address into the Neighbor Advertisement message */
net_ipv6addr_copy(adv->tgtaddr, dev->d_ipv6addr);
/* Set up the options */
adv->opttype = ICMPv6_OPT_TGTLLADDR; /* Option type */
adv->optlen = 1; /* Option length = 1 octet */

View file

@ -64,10 +64,12 @@
/****************************************************************************
* Private Data
****************************************************************************/
/* First 6 swords of the multi-cast address in network byte order */
static const uint16_t g_icmpv_mcastaddr[6] =
{
0xff02, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001
HTONS(0xff02), HTONS(0x0000), HTONS(0x0000), HTONS(0x0000),
HTONS(0x0000), HTONS(0x0001)
};
/****************************************************************************
@ -99,22 +101,22 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
/* Set up the IPv6 header (most is probably already in place) */
icmp = ICMPv6BUF;
icmp->vtc = 0x60; /* Version/traffic class (MS) */
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
icmp->flow = 0; /* Flow label (LS) */
icmp->vtc = 0x60; /* Version/traffic class (MS) */
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
icmp->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */
icmp->len[0] = (sizeof(struct icmpv6_neighbor_solicit_s) >> 8);
icmp->len[1] = (sizeof(struct icmpv6_neighbor_solicit_s) & 0xff);
icmp->proto = IP_PROTO_ICMP6; /* Next header */
icmp->ttl = IP_TTL; /* Hop limit */
icmp->proto = IP_PROTO_ICMP6; /* Next header */
icmp->ttl = 255; /* Hop limit */
/* Set the multicast destination IP address */
memcpy(icmp->destipaddr, g_icmpv_mcastaddr, 6*sizeof(uint16_t));
icmp->destipaddr[6] = ipaddr[6] | 0xff00;
icmp->destipaddr[6] = ipaddr[6] | HTONS(0xff00);
icmp->destipaddr[7] = ipaddr[7];
/* Add out IPv6 address as the source address */
@ -130,6 +132,13 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
sol->flags[1] = 0;
sol->flags[2] = 0;
sol->flags[3] = 0;
/* Copy the target address into the Neighbor Solicitation message */
net_ipv6addr_copy(sol->tgtaddr, ipaddr);
/* Set up the options */
sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
sol->optlen = 1; /* Option length = 1 octet */
@ -153,10 +162,6 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
if (dev->d_lltype == NET_LL_ETHERNET)
#endif
{
/* Add the size of the Ethernet header */
dev->d_len += ETH_HDRLEN;
/* Set the destination IPv6 multicast Ethernet address:
*
* For IPv6 multicast addresses, the Ethernet MAC is derived by
@ -193,6 +198,18 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
}
#endif
/* Add the size of the layer layer header to the total size of the
* outgoing packet.
*/
#if defined(CONFIG_NET_MULTILINK)
dev->d_len += dev->d_llhdrlen;
#elif defined(CONFIG_NET_ETHERNET)
dev->d_len += ETH_HDRLEN;
#else /* if defined(CONFIG_NET_SLIP) */
/* SLIP has no link layer header */
#endif
nllvdbg("Outgoing ICMPv6 Neighbor Solicitation length: %d (%d)\n",
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);

View file

@ -131,25 +131,25 @@ void neighbor_out(FAR struct net_driver_s *dev)
FAR struct ipv6_hdr_s *ip = IPv6BUF;
net_ipv6addr_t ipaddr;
/* Skip sending ARP requests when the frame to be transmitted was
/* Skip sending Neighbor Solicitations when the frame to be transmitted was
* written into a packet socket or if we are sending certain Neighbor
* messages (soliciation, advertisement, echo request).
* messages (solicitation, advertisement, echo request).
*/
if (IFF_IS_NOARP(dev->d_flags))
{
/* Clear the indication and let the packet continue on its way. */
IFF_CLR_IPv6(dev->d_flags);
IFF_CLR_NOARP(dev->d_flags);
return;
}
/* Find the destination IPv6 address in the ARP table and construct
* the Ethernet header. If the destination IPv6 address isn't on the
* local network, we use the default router's IPv6 address instead.
/* Find the destination IPv6 address in the Neighbor Table and construct
* the Ethernet header. If the destination IPv6 address isn't on the local
* network, we use the default router's IPv6 address instead.
*
* If not ARP table entry is found, we overwrite the original IPv6
* packet with an ARP request for the IPv6 address.
* If no Neighbor Table entry is found, we overwrite the original IPv6
* packet with an Neighbor Solicitation Request for the IPv6 address.
*/
/* First check if destination is a IPv6 multicast address. IPv6
@ -240,5 +240,19 @@ void neighbor_out(FAR struct net_driver_s *dev)
memcpy(eth->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
eth->type = HTONS(ETHTYPE_IP6);
/* Add the size of the layer layer header to the total size of the
* outgoing packet.
*/
#if defined(CONFIG_NET_MULTILINK)
dev->d_len += dev->d_llhdrlen;
#elif defined(CONFIG_NET_ETHERNET)
dev->d_len += ETH_HDRLEN;
#else /* if defined(CONFIG_NET_SLIP) */
/* SLIP has no link layer header */
#endif
nllvdbg("Outgoing IPv6 Packet length: %d (%d)\n",
dev->d_len, (ip->len[0] << 8) | ip->len[1]);
}

View file

@ -170,6 +170,8 @@ static inline void tcp_ipv4_sendcomplete(FAR struct net_driver_s *dev,
ipv4->ipchksum = 0;
ipv4->ipchksum = ~ipv4_chksum(dev);
nllvdbgi("IPv4 length: %d\n", ((int)ipv4->len << 8) + ipv4->len[1]);
}
#endif /* CONFIG_NET_IPv4 */
@ -226,6 +228,8 @@ static inline void tcp_ipv6_sendcomplete(FAR struct net_driver_s *dev,
ipv6->vtc = 0x60;
ipv6->tcf = 0x00;
ipv6->flow = 0x00;
nllvdbg("IPv6 length: %d\n", ((int)ipv6->len << 8) + ipv6->len[1]);
}
#endif /* CONFIG_NET_IPv6 */
@ -250,8 +254,6 @@ static inline void tcp_ipv6_sendcomplete(FAR struct net_driver_s *dev,
static void tcp_sendcomplete(FAR struct net_driver_s *dev,
FAR struct tcp_hdr_s *tcp)
{
nllvdbg("TCP payload: %d (%d) bytes\n", dev->d_sndlen, dev->d_len);
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (IFF_IS_IPv6(dev->d_flags))