diff --git a/CHANGELOG b/CHANGELOG index b2cb7e90..d61ff15b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,11 @@ HISTORY ++ New features: + 2015-08-30: Simon Goldschmidt + * support IPv4 source based routing: define LWIP_HOOK_IP4_ROUTE_SRC to point + to a routing function + + 2015-08-05: Simon Goldschmidt * many files: allow multicast socket options IP_MULTICAST_TTL, IP_MULTICAST_IF and IP_MULTICAST_LOOP to be used without IGMP diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index d1c47f11..ebe066d3 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -113,6 +113,24 @@ ip4_set_default_multicast_netif(struct netif* default_multicast_netif) } #endif /* LWIP_MULTICAST_TX_OPTIONS */ +#ifdef LWIP_HOOK_IP4_ROUTE_SRC +/** + * Source based IPv4 routing must be fully implemented in + * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides he parameters. + */ +struct netif * +ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src) +{ + if (src != NULL) { + struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, src); + if (netif != NULL) { + return netif; + } + } + return ip4_route(dest); +} +#endif /* LWIP_HOOK_IP4_ROUTE_SRC */ + /** * Finds the appropriate network interface for a given IP address. It * searches the list of network interfaces linearly. A match is found @@ -127,7 +145,12 @@ ip4_route(const ip4_addr_t *dest) { struct netif *netif; -#ifdef LWIP_HOOK_IP4_ROUTE +#ifdef LWIP_HOOK_IP4_ROUTE_SRC + netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, NULL); + if (netif != NULL) { + return netif; + } +#elif defined(LWIP_HOOK_IP4_ROUTE) netif = LWIP_HOOK_IP4_ROUTE(dest); if (netif != NULL) { return netif; @@ -253,7 +276,7 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) } /* Find network interface where to forward this IP packet to. */ - netif = ip4_route(ip4_current_dest_addr()); + netif = ip4_route_src(ip4_current_dest_addr(), ip4_current_src_addr()); if (netif == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), @@ -937,7 +960,7 @@ ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - if ((netif = ip4_route(dest)) == NULL) { + if ((netif = ip4_route_src(dest, src)) == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); IP_STATS_INC(ip.rterr); @@ -975,7 +998,7 @@ ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - if ((netif = ip4_route(dest)) == NULL) { + if ((netif = ip4_route_src(dest, src)) == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); IP_STATS_INC(ip.rterr); diff --git a/src/core/tcp.c b/src/core/tcp.c index 6edab081..188bcf80 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -1788,12 +1788,12 @@ tcp_next_iss(void) */ u16_t tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest -#if LWIP_IPV6 +#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING , const ip_addr_t *src -#if LWIP_IPV4 +#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */ +#if LWIP_IPV6 && LWIP_IPV4 , u8_t isipv6 -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ +#endif /* LWIP_IPV6 && LWIP_IPV4 */ ) { u16_t mss_s; diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h index 92ecb8f0..f43b5ec9 100644 --- a/src/include/lwip/ip.h +++ b/src/include/lwip/ip.h @@ -262,7 +262,7 @@ extern struct ip_globals ip_data; #define ip_route(isipv6, src, dest) \ ((isipv6) ? \ ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \ - ip4_route(ip_2_ip4(dest))) + ip4_route_src(ip_2_ip4(dest), ip_2_ip4(src))) #define ip_netif_get_local_ip(isipv6, netif, dest, storage) ((isipv6) ? \ ip6_2_ip(ip6_netif_get_local_ip(netif, ip_2_ip6(dest)), storage) : \ ip4_2_ip(ip4_netif_get_local_ip(netif), storage)) @@ -278,7 +278,7 @@ err_t ip_input(struct pbuf *p, struct netif *inp); #define ip_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ ip4_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) #define ip_route(isipv6, src, dest) \ - ip4_route(dest) + ip4_route_src(dest, src) #define ip_netif_get_local_ip(isipv6, netif, dest, storage) \ ip4_netif_get_local_ip(netif) #define ip_debug_print(is_ipv6, p) ip4_debug_print(p) diff --git a/src/include/lwip/ip4.h b/src/include/lwip/ip4.h index 2447e250..8a06c4e6 100644 --- a/src/include/lwip/ip4.h +++ b/src/include/lwip/ip4.h @@ -47,6 +47,12 @@ extern "C" { #endif +#ifdef LWIP_HOOK_IP4_ROUTE_SRC +#define LWIP_IPV4_SRC_ROUTING 1 +#else +#define LWIP_IPV4_SRC_ROUTING 0 +#endif + /** Currently, the function ip_output_if_opt() is only used with IGMP */ #define IP_OPTIONS_SEND (LWIP_IPV4 && LWIP_IGMP) @@ -108,6 +114,11 @@ PACK_STRUCT_END #define ip_init() /* Compatibility define, no init needed. */ struct netif *ip4_route(const ip4_addr_t *dest); +#if LWIP_IPV4_SRC_ROUTING +struct netif *ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src); +#else /* LWIP_IPV4_SRC_ROUTING */ +#define ip4_route_src(dest, src) ip4_route(dest) +#endif /* LWIP_IPV4_SRC_ROUTING */ err_t ip4_input(struct pbuf *p, struct netif *inp); err_t ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto); diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 359a0c26..4e1588a1 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -2767,6 +2767,11 @@ * that case, ip_route() continues as normal. */ +/** + * LWIP_HOOK_IP4_ROUTE_SRC(dest, src): + * - source-based routing for IPv4 (see LWIP_HOOK_IP4_ROUTE(), src may be NULL) + */ + /** * LWIP_HOOK_ETHARP_GET_GW(netif, dest): * - called from etharp_output() (IPv4) diff --git a/src/include/lwip/tcp_impl.h b/src/include/lwip/tcp_impl.h index 51401223..8c53cc47 100644 --- a/src/include/lwip/tcp_impl.h +++ b/src/include/lwip/tcp_impl.h @@ -494,16 +494,16 @@ void tcp_trigger_input_pcb_close(void); #if TCP_CALCULATE_EFF_SEND_MSS u16_t tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest -#if LWIP_IPV6 +#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING , const ip_addr_t *src -#if LWIP_IPV4 +#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */ +#if LWIP_IPV6 && LWIP_IPV4 , u8_t isipv6 -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ +#endif /* LWIP_IPV6 && LWIP_IPV4 */ ); #if LWIP_IPV4 && LWIP_IPV6 #define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src, isipv6) -#elif LWIP_IPV6 +#elif LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING #define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src) #else /* LWIP_IPV4 && LWIP_IPV6 */ #define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest)