diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/ipv4/ip4.c lwip_pcp/core/ipv4/ip4.c --- lwip/core/ipv4/ip4.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/ipv4/ip4.c 2011-12-01 11:07:48.000000000 +0100 @@ -813,7 +813,7 @@ return ip_output_if(p, src, dest, ttl, tos, proto, netif); } -#if LWIP_NETIF_HWADDRHINT +#if LWIP_USE_HINTS /** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint * before calling ip_output_if. * @@ -826,7 +826,7 @@ * @param ttl the TTL value to be set in the IP header * @param tos the TOS value to be set in the IP header * @param proto the PROTOCOL to be set in the IP header - * @param addr_hint address hint pointer set to netif->addr_hint before + * @param pcb_hint pcb hint pointer set to NETIF_SET_HINTS() before * calling ip_output_if() * * @return ERR_RTE if no route is found @@ -834,7 +834,7 @@ */ err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) + u8_t ttl, u8_t tos, u8_t proto, struct ip_pcb* pcb_hint) { struct netif *netif; err_t err; @@ -850,13 +850,13 @@ return ERR_RTE; } - NETIF_SET_HWADDRHINT(netif, addr_hint); + NETIF_SET_HINTS(netif, pcb_hint); err = ip_output_if(p, src, dest, ttl, tos, proto, netif); - NETIF_SET_HWADDRHINT(netif, NULL); + NETIF_RESET_HINTS(netif); return err; } -#endif /* LWIP_NETIF_HWADDRHINT*/ +#endif /* LWIP_USE_HINTS*/ #if IP_DEBUG /* Print an IP header by using LWIP_DEBUGF diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/ipv6/ip6.c lwip_pcp/core/ipv6/ip6.c --- lwip/core/ipv6/ip6.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/ipv6/ip6.c 2011-12-01 11:07:48.000000000 +0100 @@ -846,7 +846,7 @@ } -#if LWIP_NETIF_HWADDRHINT +#if LWIP_USE_HINTS /** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint * before calling ip6_output_if. * @@ -860,7 +860,7 @@ * @param hl the Hop Limit value to be set in the IPv6 header * @param tc the Traffic Class value to be set in the IPv6 header * @param nexth the Next Header to be set in the IPv6 header - * @param addr_hint address hint pointer set to netif->addr_hint before + * @param pcb_hint pcb hint pointer set to NETIF_SET_HINTS() before * calling ip_output_if() * * @return ERR_RTE if no route is found @@ -868,7 +868,7 @@ */ err_t ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint) + u8_t hl, u8_t tc, u8_t nexth, struct ip_pcb* pcb_hint) { struct netif *netif; err_t err; @@ -891,13 +891,13 @@ return ERR_RTE; } - NETIF_SET_HWADDRHINT(netif, addr_hint); + NETIF_SET_HINTS(netif, pcb_hint); err = ip6_output_if(p, src, dest, hl, tc, nexth, netif); - NETIF_SET_HWADDRHINT(netif, NULL); + NETIF_RESET_HINTS(netif); return err; } -#endif /* LWIP_NETIF_HWADDRHINT*/ +#endif /* LWIP_USE_HINTS*/ #if LWIP_IPV6_MLD /** diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/netif.c lwip_pcp/core/netif.c --- lwip/core/netif.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/netif.c 2011-12-01 11:07:48.000000000 +0100 @@ -203,7 +203,7 @@ netif->state = state; netif->num = netif_num++; netif->input = input; - NETIF_SET_HWADDRHINT(netif, NULL); + NETIF_RESET_HINTS(netif); #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS netif->loop_cnt_current = 0; #endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ @@ -677,7 +677,9 @@ LWIP_UNUSED_ARG(ipaddr); /* Allocate a new pbuf */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/pbuf.c lwip_pcp/core/pbuf.c --- lwip/core/pbuf.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/pbuf.c 2011-12-01 11:07:48.000000000 +0100 @@ -224,6 +224,10 @@ case PBUF_LINK: /* add room for link layer header */ offset = PBUF_LINK_HLEN; +#if LWIP_VLAN_PCP + /* add room for VLAN header */ + offset += PBUF_VLAN_HLEN; +#endif /* LWIP_VLAN_PCP */ break; case PBUF_RAW: offset = 0; @@ -383,6 +387,10 @@ case PBUF_LINK: /* add room for link layer header */ offset = PBUF_LINK_HLEN; +#if LWIP_VLAN_PCP + /* add room for VLAN header */ + offset += PBUF_VLAN_HLEN; +#endif /* LWIP_VLAN_PCP */ break; case PBUF_RAW: offset = 0; diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/raw.c lwip_pcp/core/raw.c --- lwip/core/raw.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/raw.c 2011-12-01 11:07:48.000000000 +0100 @@ -306,9 +306,9 @@ src_ip = &pcb->local_ip; } - NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + NETIF_SET_HINTS(netif, pcb); err = ipX_output_if(PCB_ISIPV6(pcb), q, ipX_2_ip(src_ip), ipX_2_ip(dst_ip), pcb->ttl, pcb->tos, pcb->protocol, netif); - NETIF_SET_HWADDRHINT(netif, NULL); + NETIF_RESET_HINTS(netif); /* did we chain a header earlier? */ if (q != p) { diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/tcp.c lwip_pcp/core/tcp.c --- lwip/core/tcp.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/tcp.c 2011-12-01 11:07:48.000000000 +0100 @@ -183,7 +183,7 @@ /* don't call tcp_abort here: we must not deallocate the pcb since that might not be expected when calling tcp_close */ tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); + pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb), (struct ip_pcb*)pcb); tcp_pcb_purge(pcb); @@ -388,7 +388,7 @@ #endif /* TCP_QUEUE_OOSEQ */ if (reset) { LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); - tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb), (struct ip_pcb*)pcb); } memp_free(MEMP_TCP_PCB, pcb); TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); @@ -553,6 +553,9 @@ lpcb->so_options |= SOF_ACCEPTCONN; lpcb->ttl = pcb->ttl; lpcb->tos = pcb->tos; +#if LWIP_VLAN_PCP + lpcb->tci = pcb->tci; +#endif /* LWIP_VLAN_PCP */ #if LWIP_IPV6 PCB_ISIPV6(lpcb) = PCB_ISIPV6(pcb); lpcb->accept_any_ip_version = 0; @@ -983,7 +986,7 @@ if (pcb_reset) { tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); + pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb), (struct ip_pcb*)pcb); } err_fn = pcb->errf; diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/tcp_in.c lwip_pcp/core/tcp_in.c --- lwip/core/tcp_in.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/tcp_in.c 2011-12-01 11:07:48.000000000 +0100 @@ -418,7 +418,7 @@ TCP_STATS_INC(tcp.proterr); TCP_STATS_INC(tcp.drop); tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6(), NULL); } pbuf_free(p); } @@ -462,7 +462,7 @@ RST. */ LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6(), (struct ip_pcb*)pcb); } else if (flags & TCP_SYN) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); #if TCP_LISTEN_BACKLOG @@ -501,6 +501,9 @@ #if LWIP_CALLBACK_API npcb->accept = pcb->accept; #endif /* LWIP_CALLBACK_API */ +#if LWIP_VLAN_PCP + npcb->tci = pcb->tci; +#endif /* LWIP_VLAN_PCP */ /* inherit socket options */ npcb->so_options = pcb->so_options & SOF_INHERITED; /* Register the new PCB so that we can begin receiving segments @@ -554,7 +557,7 @@ if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { /* If the SYN is in the window it is an error, send a reset */ tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6(), (struct ip_pcb*)pcb); return ERR_OK; } } else if (flags & TCP_FIN) { @@ -688,7 +691,7 @@ else if (flags & TCP_ACK) { /* send a RST to bring the other side in a non-synchronized state. */ tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6(), (struct ip_pcb*)pcb); } break; case SYN_RCVD: @@ -731,7 +734,7 @@ } else { /* incorrect ACK number, send RST */ tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6(), (struct ip_pcb*)pcb); } } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { /* Looks like another copy of the SYN - retransmit our SYN-ACK */ diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/tcp_out.c lwip_pcp/core/tcp_out.c --- lwip/core/tcp_out.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/tcp_out.c 2011-12-01 11:07:48.000000000 +0100 @@ -98,7 +98,8 @@ u32_t seqno_be /* already in network byte order */) { struct tcp_hdr *tcphdr; - struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); + struct pbuf *p = pbuf_alloc( PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); + if (p != NULL) { LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", (p->len >= TCP_HLEN + optlen)); @@ -533,7 +534,7 @@ if (apiflags & TCP_WRITE_FLAG_COPY) { /* If copy is set, memory should be allocated and data copied * into pbuf */ - if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, pcb->mss, &oversize, pcb, apiflags, queue == NULL)) == NULL) { + if ((p = tcp_pbuf_prealloc( PBUF_TRANSPORT, seglen + optlen, pcb->mss, &oversize, pcb, apiflags, queue == NULL)) == NULL) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); goto memerr; } @@ -550,7 +551,7 @@ #if TCP_OVERSIZE LWIP_ASSERT("oversize == 0", oversize == 0); #endif /* TCP_OVERSIZE */ - if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { + if ((p2 = pbuf_alloc( PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); goto memerr; } @@ -562,7 +563,7 @@ p2->payload = (u8_t*)arg + pos; /* Second, allocate a pbuf for the headers. */ - if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + if ((p = pbuf_alloc( PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { /* If allocation fails, we have to deallocate the data pbuf as * well. */ pbuf_free(p2); @@ -874,13 +875,13 @@ tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, &pcb->local_ip, &pcb->remote_ip); #endif -#if LWIP_NETIF_HWADDRHINT - ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, - IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ - ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, +#if LWIP_USE_HINTS + ipX_output_hinted(PCB_ISIPV6(pcb),p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, + IP_PROTO_TCP, (struct ip_pcb*)pcb); +#else /* LWIP_USE_HINTS*/ + ipX_output(PCB_ISIPV6(pcb),p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ +#endif /* LWIP_USE_HINTS*/ pbuf_free(p); return ERR_OK; @@ -1154,13 +1155,13 @@ #endif /* TCP_CHECKSUM_ON_COPY */ TCP_STATS_INC(tcp.xmit); -#if LWIP_NETIF_HWADDRHINT +#if LWIP_USE_HINTS ipX_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, - pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ + pcb->ttl, pcb->tos, IP_PROTO_TCP, (struct ip_pcb*)pcb); +#else /* LWIP_USE_HINTS*/ ipX_output(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ +#endif /* LWIP_USE_HINTS*/ } /** @@ -1190,10 +1191,14 @@ #if LWIP_IPV6 , u8_t isipv6 #endif /* LWIP_IPV6 */ +#if LWIP_USE_HINTS + , struct ip_pcb *pcb +#endif /* LWIP_USE_HINTS */ ) { struct pbuf *p; struct tcp_hdr *tcphdr; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); if (p == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); @@ -1220,7 +1225,17 @@ local_ip, remote_ip); #endif /* Send output with hardcoded TTL/HL since we have no access to the pcb */ +#if LWIP_USE_HINTS + if( pcb != NULL ) + { + ipX_output_hinted(isipv6, p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP, pcb); + } + else +#endif /* LWIP_USE_HINTS*/ + { ipX_output(isipv6, p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + } + pbuf_free(p); LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); } @@ -1383,13 +1398,12 @@ TCP_STATS_INC(tcp.xmit); /* Send output to IP */ -#if LWIP_NETIF_HWADDRHINT +#if LWIP_USE_HINTS ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, - pcb->ttl, 0, IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ - ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - 0, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ + pcb->ttl, 0, IP_PROTO_TCP, (struct ip_pcb*)pcb); +#else /* LWIP_USE_HINTS*/ + ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_USE_HINTS*/ pbuf_free(p); @@ -1463,12 +1477,12 @@ TCP_STATS_INC(tcp.xmit); /* Send output to IP */ -#if LWIP_NETIF_HWADDRHINT +#if LWIP_USE_HINTS ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - 0, IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ + 0, IP_PROTO_TCP, (struct ip_pcb*)pcb); +#else /* LWIP_USE_HINTS*/ ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ +#endif /* LWIP_USE_HINTS*/ pbuf_free(p); diff -r -u --strip-trailing-cr --ignore-space-change lwip/core/udp.c lwip_pcp/core/udp.c --- lwip/core/udp.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/core/udp.c 2011-12-01 11:07:48.000000000 +0100 @@ -657,6 +657,7 @@ if (pbuf_header(p, UDP_HLEN)) { /* allocate header in a separate new pbuf */ q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); + /* new header pbuf could not be allocated? */ if (q == NULL) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); @@ -837,9 +838,9 @@ LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); /* output to IP */ - NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint)); + NETIF_SET_HINTS(netif, pcb); err = ipX_output_if(PCB_ISIPV6(pcb), q, src_ip, dst_ip, pcb->ttl, pcb->tos, ip_proto, netif); - NETIF_SET_HWADDRHINT(netif, NULL); + NETIF_RESET_HINTS(netif); /* TODO: must this be increased even if error occured? */ snmp_inc_udpoutdatagrams(); diff -r -u --strip-trailing-cr --ignore-space-change lwip/include/ipv4/lwip/ip4.h lwip_pcp/include/ipv4/lwip/ip4.h --- lwip/include/ipv4/lwip/ip4.h 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/include/ipv4/lwip/ip4.h 2011-12-01 11:07:50.000000000 +0100 @@ -119,10 +119,10 @@ err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); -#if LWIP_NETIF_HWADDRHINT +#if LWIP_USE_HINT err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ +#endif /* LWIP_USE_HINT */ #if IP_OPTIONS_SEND err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, diff -r -u --strip-trailing-cr --ignore-space-change lwip/include/ipv6/lwip/ip6.h lwip_pcp/include/ipv6/lwip/ip6.h --- lwip/include/ipv6/lwip/ip6.h 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/include/ipv6/lwip/ip6.h 2011-12-01 11:07:48.000000000 +0100 @@ -170,10 +170,10 @@ u8_t hl, u8_t tc, u8_t nexth); err_t ip6_output_if(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); -#if LWIP_NETIF_HWADDRHINT +#if LWIP_USE_HINTS err_t ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ + u8_t hl, u8_t tc, u8_t nexth, struct ip_pcb* pcb_hint); +#endif /* LWIP_USE_HINTS */ #if LWIP_IPV6_MLD err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); #endif /* LWIP_IPV6_MLD */ diff -r -u --strip-trailing-cr --ignore-space-change lwip/include/lwip/ip.h lwip_pcp/include/lwip/ip.h --- lwip/include/lwip/ip.h 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/include/lwip/ip.h 2011-12-01 11:07:50.000000000 +0100 @@ -60,6 +60,34 @@ #define IP_PCB_ADDRHINT #endif /* LWIP_NETIF_HWADDRHINT */ +#if LWIP_VLAN_PCP + + /* + ** Control field contains the priority level. The + ** priorities are from 0 (best effort) to 7 (highest). + ** ON/OFF field set to one indicates that IEEE 802.1Q + ** tags are turned off (Canonical Format Indicator is + ** always set to zero for Ethernet switches). + ** + ** VLAN Identifier (VID) is a 12 bit field specifying + ** the VLAN to which the frame belongs. The reserved + ** value 0x000 indicates that the frame does not belong + ** to any VLAN, 4095 is reserved, hence allow the + ** identification of 4094 ((2^12) - 2) VLANs. + ** + ** |------------- Tag Control Information -------------| + ** + ** 3 bits 1 bit 12 bits + ** +---------------------------------------------------+ + ** | PCP | ON/OFF(CFI) | VID | + ** +---------------------------------------------------+ + */ + +#define IP_PCB_PCPHINT ;u16_t tci +#else +#define IP_PCB_PCPHINT +#endif /* LWIP_VLAN_PCP */ + #if LWIP_IPV6 #define IP_PCB_ISIPV6_MEMBER u8_t isipv6; #define IP_PCB_IPVER_EQ(pcb1, pcb2) ((pcb1)->isipv6 == (pcb2)->isipv6) @@ -89,6 +117,8 @@ u8_t tos; \ /* Time To Live */ \ u8_t ttl \ + /* VLAN PCP hint */ \ + IP_PCB_PCPHINT \ /* link layer address resolution hint */ \ IP_PCB_ADDRHINT @@ -224,8 +254,8 @@ ip_output(p, src, dest, ttl, tos, proto) #define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ ip_output_if(p, src, dest, ttl, tos, proto, netif) -#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ - ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) +#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, pcb_hint) \ + ip_output_hinted(p, src, dest, ttl, tos, proto, pcb_hint) #define ipX_route(isipv6, src, dest) \ ip_route(ipX_2_ip(dest)) #define ipX_netif_get_local_ipX(isipv6, netif, dest) \ diff -r -u --strip-trailing-cr --ignore-space-change lwip/include/lwip/netif.h lwip_pcp/include/lwip/netif.h --- lwip/include/lwip/netif.h 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/include/lwip/netif.h 2011-12-01 11:07:48.000000000 +0100 @@ -120,7 +120,7 @@ * @param ipaddr The IP address to which the packet shall be sent */ typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, - ip_addr_t *ipaddr); + ip_addr_t *ipaddr ); #if LWIP_IPV6 /** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet * shall be sent. For ethernet netif, set this to 'nd_output' and set @@ -270,6 +270,9 @@ #if LWIP_NETIF_HWADDRHINT u8_t *addr_hint; #endif /* LWIP_NETIF_HWADDRHINT */ +#if LWIP_VLAN_PCP + u16_t tci; +#endif /* LWIP_VLAN_PCP */ #if ENABLE_LOOPBACK /* List of packets to be queued for ourselves. */ struct pbuf *loop_first; @@ -374,11 +377,31 @@ void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit); #endif /* LWIP_IPV6 */ -#if LWIP_NETIF_HWADDRHINT -#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) -#else /* LWIP_NETIF_HWADDRHINT */ -#define NETIF_SET_HWADDRHINT(netif, hint) -#endif /* LWIP_NETIF_HWADDRHINT */ +#ifndef NETIF_SET_HINTS +#if LWIP_NETIF_HWADDRHINT && LWIP_VLAN_PCP +#define NETIF_SET_HINTS( netif, pcb ) (netif)->addr_hint = &((pcb)->addr_hint); (netif)->tci = (pcb)->tci +#elif LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HINTS( netif, pcb ) (netif)->addr_hint = &((pcb)->addr_hint) +#elif LWIP_VLAN_PCP +#define NETIF_SET_HINTS( netif, pcb ) (netif)->tci = (pcb)->tci +#else +#define NETIF_SET_HINTS( netif, pcb ) +#endif +#endif + +#ifndef NETIF_RESET_HINTS +#if LWIP_NETIF_HWADDRHINT && LWIP_VLAN_PCP +#define NETIF_RESET_HINTS( netif ) (netif)->addr_hint = NULL; (netif)->tci = 0 +#elif LWIP_NETIF_HWADDRHINT +#define NETIF_RESET_HINTS( netif ) (netif)->addr_hint = NULL +#elif LWIP_VLAN_PCP +#define NETIF_RESET_HINTS( netif ) (netif)->tci = 0 +#else +#define NETIF_RESET_HINTS( netif ) +#endif +#endif + + #ifdef __cplusplus } diff -r -u --strip-trailing-cr --ignore-space-change lwip/include/lwip/opt.h lwip_pcp/include/lwip/opt.h --- lwip/include/lwip/opt.h 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/include/lwip/opt.h 2011-12-01 11:07:48.000000000 +0100 @@ -45,6 +45,7 @@ #include "lwipopts.h" #include "lwip/debug.h" + /* ----------------------------------------------- ---------- Platform specific locking ---------- @@ -468,6 +469,19 @@ #define ETHARP_SUPPORT_VLAN 0 #endif +/** + * LWIP_VLAN_PCP==1: Enable outgoing VLAN taggning of frames on a per-PCB basis + * for QoS purposes. With this feature enabled, each PCB has a new variable: "tci". + * (Tag Control Identifier). The TCI contains three fields: VID, CFI and PCP. + * VID is the VLAN ID, which should be set to zero. + * The "CFI" bit is used to enable or disable VLAN tags for the PCB. + * PCP (Priority Code Point) is a 3 bit field used for Ethernet level QoS. + */ +#ifndef LWIP_VLAN_PCP +#define LWIP_VLAN_PCP 0 +#endif + + /** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP * might be disabled */ @@ -1158,6 +1172,11 @@ #endif /** + * Enable "hints" if either LWIP_NETIF_HWADDRHINT or LWIP_VLAN_PCP is enabled. + */ +#define LWIP_USE_HINTS (LWIP_NETIF_HWADDRHINT || LWIP_VLAN_PCP) + +/** * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP * address equal to the netif IP address, looping them back up the stack. */ diff -r -u --strip-trailing-cr --ignore-space-change lwip/include/lwip/pbuf.h lwip_pcp/include/lwip/pbuf.h --- lwip/include/lwip/pbuf.h 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/include/lwip/pbuf.h 2011-12-01 11:07:48.000000000 +0100 @@ -53,6 +53,7 @@ #else #define PBUF_IP_HLEN 20 #endif +#define PBUF_VLAN_HLEN 4 typedef enum { PBUF_TRANSPORT, diff -r -u --strip-trailing-cr --ignore-space-change lwip/include/lwip/tcp_impl.h lwip_pcp/include/lwip/tcp_impl.h --- lwip/include/lwip/tcp_impl.h 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/include/lwip/tcp_impl.h 2011-12-01 11:07:48.000000000 +0100 @@ -451,13 +451,26 @@ #if LWIP_IPV6 , u8_t isipv6 #endif /* LWIP_IPV6 */ +#if LWIP_USE_HINTS + , struct ip_pcb *pcb +#endif /* LWIP_USE_HINTS */ ); #if LWIP_IPV6 -#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ +#if LWIP_USE_HINTS +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6, pcb) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6, pcb) +#else /* LWIP_USE_HINTS */ +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6, pcb) \ tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) +#endif /* LWIP_USE_HINTS */ #else /* LWIP_IPV6 */ -#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ +#if LWIP_USE_HINTS +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6, pcb) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, pcb) +#else /* LWIP_USE_HINTS */ +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6, pcb) \ tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port) +#endif /* LWIP_USE_HINTS */ #endif /* LWIP_IPV6 */ u32_t tcp_next_iss(void); diff -r -u --strip-trailing-cr --ignore-space-change lwip/netif/etharp.c lwip_pcp/netif/etharp.c --- lwip/netif/etharp.c 2011-12-01 11:13:22.000000000 +0100 +++ lwip_pcp/netif/etharp.c 2011-12-01 11:07:48.000000000 +0100 @@ -421,7 +421,14 @@ (netif->hwaddr_len == ETHARP_HWADDR_LEN)); ETHADDR32_COPY(ðhdr->dest, dst); ETHADDR16_COPY(ðhdr->src, src); + +#if LWIP_VLAN_PCP + if( PP_HTONS(ethhdr->type) != ETHTYPE_VLAN ) +#endif /* LWIP_VLAN_PCP */ + { ethhdr->type = PP_HTONS(ETHTYPE_IP); + } + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); /* send the packet */ return netif->linkoutput(netif, p); @@ -877,7 +884,7 @@ * or the return type of either etharp_query() or etharp_send_ip(). */ err_t -etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr ) { struct eth_addr *dest; struct eth_addr mcastaddr; @@ -887,6 +894,34 @@ LWIP_ASSERT("q != NULL", q != NULL); LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); +#if LWIP_VLAN_PCP + if( netif->tci & 0x1000 ) /* Check tag bit */ + { + struct eth_vlan_hdr* vlanhdr; + + /* make room for Ethernet VLAN header - should not fail */ + if( pbuf_header(q, sizeof(struct eth_vlan_hdr)) != 0) + { + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + return ERR_BUF; + } + + /* Tag Protocol Identifier (TPID): a 16-bit field set to a value of 0x8100 in + ** order to identify the frame as an IEEE 802.1Q-tagged frame. This field is + ** located at the same offset as the EtherType/Length field in untagged frames, + ** and is thus used to distinguish the frame from untagged frames. + ** + ** Since the offset, ethhdr->type now indicates IEEE 802.1Q tag and vlanhdr->tpid + ** relates to the EtherType/Length field. + */ + + vlanhdr = (struct eth_vlan_hdr *)q->payload; + vlanhdr->prio_vid = htons( netif->tci & 0xEFFF ); + vlanhdr->tpid = PP_HTONS(ETHTYPE_IP); + /* make room for Ethernet header - should not fail */ if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { /* bail out */ @@ -896,6 +931,26 @@ return ERR_BUF; } + ((struct eth_hdr *)q->payload)->type = PP_HTONS(ETHTYPE_VLAN); + } + else +#endif /* LWIP_VLAN_PCP */ + { + /* make room for Ethernet header - should not fail */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + return ERR_BUF; + } + /* + ** Clear Ethernet header type field to indicate to etharp_send_ip + ** that this frame has no VLAN tag. + */ + ((struct eth_hdr *)q->payload)->type = 0; + } + /* outside local network? if so, this can neither be a global broadcast nor a subnet broadcast. */ if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) &&