From ccd7dbe0e4aa698cb96f85a88dab149066420bb3 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Thu, 26 May 2011 15:46:44 +0000 Subject: [PATCH] Added ipX versions for routing --- src/core/raw.c | 62 ++++++++++--------------------------- src/core/tcp.c | 47 ++++++++-------------------- src/core/tcp_out.c | 29 ++++------------- src/core/udp.c | 29 +++++++++-------- src/include/ipv4/lwip/ip4.h | 2 ++ src/include/ipv6/lwip/ip6.h | 2 ++ src/include/lwip/ip.h | 17 ++++++++++ src/include/lwip/ip_addr.h | 9 ++++-- 8 files changed, 77 insertions(+), 120 deletions(-) diff --git a/src/core/raw.c b/src/core/raw.c index 3ac3b687..08840bea 100644 --- a/src/core/raw.c +++ b/src/core/raw.c @@ -224,13 +224,10 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) { err_t err; struct netif *netif; - ip_addr_t *src_ip; + ipX_addr_t *src_ip; struct pbuf *q; /* q will be sent down the stack */ s16_t header_size; -#if LWIP_IPV6 - ip6_addr_t *ip6addr = ip_2_ip6(ipaddr); -#endif /* LWIP_IPV6 */ - + ipX_addr_t *dst_ip = ip_2_ipX(ipaddr); LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); @@ -264,16 +261,10 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) } } -#if LWIP_IPV6 - if (pcb->isipv6) { - netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ip6addr); - } - else -#endif /* LWIP_IPV6 */ - netif = ip_route(ipaddr); + netif = ipX_route(pcb->isipv6, &pcb->local_ip, dst_ip); if (netif == NULL) { LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); - ipX_addr_debug_print(pcb->isipv6, RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ip_2_ipX(ipaddr)); + ipX_addr_debug_print(pcb->isipv6, RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, dst_ip); /* free any temporary header pbuf allocated by pbuf_header() */ if (q != p) { pbuf_free(q); @@ -299,45 +290,26 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) } #endif /* IP_SOF_BROADCAST */ - NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); - + if (ipX_addr_isany(pcb->isipv6, &pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = ipX_netif_get_local_ipX(pcb->isipv6, netif, dst_ip); #if LWIP_IPV6 - if (pcb->isipv6) { - ip6_addr_t *src6_ip; - if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { - /* select an IPv6 address from the netif as source address */ - src6_ip = ip6_select_source_address(netif, ip6addr); - if (src6_ip == NULL) { - /* No suitable source address was found. */ - err = ERR_RTE; - NETIF_SET_HWADDRHINT(netif, NULL); - /* did we chain a header earlier? */ - if (q != p) { - /* free the header */ - pbuf_free(q); - } - return ERR_RTE; + if (src_ip == NULL) { + if (q != p) { + pbuf_free(q); } - } else { - /* use RAW PCB local IPv6 address as source address */ - src6_ip = ipX_2_ip6(&pcb->local_ip); + return ERR_RTE; } - err = ip6_output_if(q, src6_ip, ip6addr, pcb->ttl, pcb->tos, pcb->protocol, netif); - } - else #endif /* LWIP_IPV6 */ - { - if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { - /* use outgoing network interface IP address as source address */ - src_ip = &(netif->ip_addr); - } else { - /* use RAW PCB local IP address as source address */ - src_ip = ipX_2_ip(&pcb->local_ip); - } - err = ip_output_if(q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); + } else { + /* use RAW PCB local IP address as source address */ + src_ip = &pcb->local_ip; } + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ipX_output_if(pcb->isipv6, q, ipX_2_ip(src_ip), ipX_2_ip(dst_ip), pcb->ttl, pcb->tos, pcb->protocol, netif); NETIF_SET_HWADDRHINT(netif, NULL); + /* did we chain a header earlier? */ if (q != p) { /* free the header */ diff --git a/src/core/tcp.c b/src/core/tcp.c index 55d8cce0..aa886171 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -689,40 +689,18 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, pcb->remote_port = port; /* check if we have a route to the remote host */ -#if LWIP_IPV6 - if (pcb->isipv6) { - if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { - /* no local IPv6 address set, yet. */ - ip6_addr_t * local_addr6; - struct netif *netif = ip6_route(ipX_2_ip6(&pcb->remote_ip), ipX_2_ip6(&pcb->remote_ip)); - if (netif == NULL) { - /* Don't even try to send a SYN packet if we have no route - since that will fail. */ - return ERR_RTE; - } - /* Select and IPv6 address from the netif. */ - local_addr6 = ip6_select_source_address(netif, ipX_2_ip6(&pcb->remote_ip)); - if (local_addr6 == NULL) { - /* Don't even try to send a SYN packet if we have no suitable - source address. */ - return ERR_RTE; - } - - ip6_addr_set(ipX_2_ip6(&pcb->local_ip), local_addr6); - } - } - else -#endif /* LWIP_IPV6 */ - if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { + if (ipX_addr_isany(pcb->isipv6, &pcb->local_ip)) { /* no local IP address set, yet. */ - struct netif *netif = ip_route(ipX_2_ip(&pcb->remote_ip)); - if (netif == NULL) { + struct netif *netif; + ipX_addr_t *local_ip; + ipX_route_get_local_ipX(pcb->isipv6, &pcb->remote_ip, &pcb->remote_ip, netif, local_ip); + if ((netif == NULL) || (local_ip == NULL)) { /* Don't even try to send a SYN packet if we have no route since that will fail. */ return ERR_RTE; } /* Use the netif's IP address as local address. */ - ip_addr_copy(*ipX_2_ip(&pcb->local_ip), netif->ip_addr); + ipX_addr_copy(pcb->isipv6, pcb->local_ip, *local_ip); } old_local_port = pcb->local_port; @@ -769,7 +747,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, pcb->ssthresh = pcb->mss * 10; #if LWIP_CALLBACK_API pcb->connected = connected; -#else /* LWIP_CALLBACK_API */ +#else /* LWIP_CALLBACK_API */ LWIP_UNUSED_ARG(connected); #endif /* LWIP_CALLBACK_API */ @@ -1554,18 +1532,15 @@ tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest u16_t mss_s; struct netif *outif; s16_t mtu; - s16_t iphlen = IP_HLEN; + outif = ipX_route(isipv6, src, dest); #if LWIP_IPV6 if (isipv6) { /* First look in destination cache, to see if there is a Path MTU. */ - outif = ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)); mtu = nd6_get_destination_mtu(ipX_2_ip6(dest), outif); - iphlen = IP6_HLEN; } else #endif /* LWIP_IPV6 */ { - outif = ip_route(ipX_2_ip(dest)); if (outif == NULL) { return sendmss; } @@ -1573,7 +1548,11 @@ tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest } if (mtu != 0) { - mss_s = mtu - iphlen - TCP_HLEN; + mss_s = mtu - IP_HLEN - TCP_HLEN; +#if LWIP_IPV6 + /* for IPv6, substract the difference in header size */ + mss_s -= (IP6_HLEN - IP_HLEN); +#endif /* LWIP_IPV6 */ /* RFC 1122, chap 4.2.2.6: * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize * We correct for TCP options in tcp_write(), and don't support IP options. diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index aeb0bc65..ad1e0e97 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -1049,7 +1049,6 @@ static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) { u16_t len; - struct netif *netif; u32_t *opts; /** @bug Exclude retransmitted segments from this count. */ @@ -1089,30 +1088,14 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) /* If we don't have a local IP address, we get one by calling ip_route(). */ -#if LWIP_IPV6 - if (pcb->isipv6) { - if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { - ip6_addr_t * local_addr6; - netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ipX_2_ip6(&pcb->remote_ip)); - if (netif == NULL) { - return; - } - /* Select and IPv6 address from the netif. */ - local_addr6 = ip6_select_source_address(netif, ipX_2_ip6(&pcb->remote_ip)); - if (local_addr6 == NULL) { - return; - } - ip6_addr_set(ipX_2_ip6(&pcb->local_ip), local_addr6); - } - } - else -#endif /* LWIP_IPV6 */ - if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { - netif = ip_route(ipX_2_ip(&pcb->remote_ip)); - if (netif == NULL) { + if (ipX_addr_isany(pcb->isipv6, &pcb->local_ip)) { + struct netif *netif; + ipX_addr_t *local_ip; + ipX_route_get_local_ipX(pcb->isipv6, &pcb->local_ip, &pcb->remote_ip, netif, local_ip); + if ((netif == NULL) || (local_ip == NULL)) { return; } - ip_addr_copy(*ipX_2_ip(&pcb->local_ip), netif->ip_addr); + ipX_addr_copy(pcb->isipv6, pcb->local_ip, *local_ip); } if (pcb->rttest == 0) { diff --git a/src/core/udp.c b/src/core/udp.c index b983609b..25d53111 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -479,29 +479,28 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, { #endif /* LWIP_CHECKSUM_ON_COPY */ struct netif *netif; + ipX_addr_t *dst_ip_route = ip_2_ipX(dst_ip); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); - /* find the outgoing network interface for this packet */ +#if LWIP_IPV6 || LWIP_IGMP + if (ipX_addr_ismulticast(pcb->isipv6, dst_ip_route)) { + /* For multicast, find a netif based on source address. */ #if LWIP_IPV6 - if (pcb->isipv6) { - if (ip6_addr_ismulticast(ip_2_ip6(dst_ip))) { - /* For multicast, find a netif based on source address. */ - netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ipX_2_ip6(&pcb->local_ip)); - } - else { - netif = ip6_route(ipX_2_ip6(&pcb->local_ip), ip_2_ip6(dst_ip)); - } - } - else + if (pcb->isipv6) { + dst_ip_route = &pcb->local_ip; + } else #endif /* LWIP_IPV6 */ - { #if LWIP_IGMP - netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip)); -#else - netif = ip_route(dst_ip); + { + dst_ip_route = ip_2_ipX(&pcb->multicast_ip); + } #endif /* LWIP_IGMP */ } +#endif /* LWIP_IPV6 || LWIP_IGMP */ + + /* find the outgoing network interface for this packet */ + netif = ipX_route(pcb->isipv6, &pcb->local_ip, dst_ip_route); /* no outgoing network interface could be found? */ if (netif == NULL) { diff --git a/src/include/ipv4/lwip/ip4.h b/src/include/ipv4/lwip/ip4.h index bfe1153d..0d3c70b6 100644 --- a/src/include/ipv4/lwip/ip4.h +++ b/src/include/ipv4/lwip/ip4.h @@ -126,6 +126,8 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u16_t optlen); #endif /* IP_OPTIONS_SEND */ +#define ip_netif_get_local_ipX(netif) (((netif) != NULL) ? ip_2_ipX(&((netif)->ip_addr)) : NULL) + #if IP_DEBUG void ip_debug_print(struct pbuf *p); #else diff --git a/src/include/ipv6/lwip/ip6.h b/src/include/ipv6/lwip/ip6.h index f8f7e8eb..b199c95a 100644 --- a/src/include/ipv6/lwip/ip6.h +++ b/src/include/ipv6/lwip/ip6.h @@ -178,6 +178,8 @@ err_t ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *des err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); #endif /* LWIP_IPV6_MLD */ +#define ip6_netif_get_local_ipX(netif, dest) (((netif) != NULL) ? \ + ip6_2_ipX(ip6_select_source_address(netif, dest)) : NULL) #if IP6_DEBUG void ip6_debug_print(struct pbuf *p); diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h index 4f856271..6564ea83 100644 --- a/src/include/lwip/ip.h +++ b/src/include/lwip/ip.h @@ -210,6 +210,14 @@ extern struct ip_globals ip_data; ((isipv6) ? \ ip6_output_hinted(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto, addr_hint) : \ ip_output_hinted(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto, addr_hint)) +#define ipX_route(isipv6, src, dest) \ + ((isipv6) ? \ + ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)) : \ + ip_route(ipX_2_ip(dest))) +#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ + ((isipv6) ? \ + ip6_netif_get_local_ipX(netif, ipX_2_ip6(dest)) : \ + ip_netif_get_local_ipX(netif)) #define ipX_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip_debug_print(p)) #else /* LWIP_IPV6 */ #define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ @@ -218,9 +226,18 @@ extern struct ip_globals ip_data; 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_route(isipv6, src, dest) \ + ip_route(ipX_2_ip(dest)) +#define ipX_netif_get_local_ip(isipv6, netif, dest) \ + ip_get_local_ip(netif) #define ipX_debug_print(is_ipv6, p) ip_debug_print(p) #endif /* LWIP_IPV6 */ +#define ipX_route_get_local_ipX(isipv6, src, dest, netif, ipXaddr) do { \ + (netif) = ipX_route(isipv6, src, dest); \ + (ipXaddr) = ipX_netif_get_local_ipX(isipv6, netif, dest); \ +}while(0) + #ifdef __cplusplus } #endif diff --git a/src/include/lwip/ip_addr.h b/src/include/lwip/ip_addr.h index 04ffa534..ae8e6ff3 100644 --- a/src/include/lwip/ip_addr.h +++ b/src/include/lwip/ip_addr.h @@ -58,10 +58,13 @@ static ip_addr_t* ip6_2_ip(ip6_addr_t *ip6addr) { return (ip_addr_t*)ip6addr; } static ipX_addr_t* ip_2_ipX(ip_addr_t *ipaddr) { return (ipX_addr_t*)ipaddr; } +static ipX_addr_t* ip6_2_ipX(ip6_addr_t *ip6addr) +{ return (ipX_addr_t*)ip6addr; } #else /* LWIP_ALLOW_STATIC_FN_IN_HEADER */ -#define ip_2_ip6(ipaddr) ((ip6_addr_t*)(ipaddr)) -#define ip6_2_ip(ip6addr) ((ip_addr_t*)(ip6addr)) -#define ip_2_ipX(ip_addr_t *ipaddr) ((ipX_addr_t*)ipaddr) +#define ip_2_ip6(ipaddr) ((ip6_addr_t*)(ipaddr)) +#define ip6_2_ip(ip6addr) ((ip_addr_t*)(ip6addr)) +#define ip_2_ipX(ip_addr_t *ipaddr) ((ipX_addr_t*)ipaddr) +#define ip6_2_ipX(ip6_addr_t *ip6addr) ((ipX_addr_t*)ip6addr) #endif /* LWIP_ALLOW_STATIC_FN_IN_HEADER*/ #define ipX_2_ip6(ip6addr) (&((ip6addr)->ip6)) #define ipX_2_ip(ipaddr) (&((ipaddr)->ip4))