mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-19 05:10:40 +00:00
raw: add core support for multicast TX options
The patch simply copies the relevant bits from the UDP implementation. Perhaps most notably, the patch does *not* copy the IPv4-only UDP support for IP_MULTICAST_IF, because that option can also be implemented using the interface index based approach. Largely thanks to this omission, at least on 32-bit platforms, this patch does not increase the RAW PCB size at all.
This commit is contained in:
parent
ab8119360e
commit
6ce9a01c3e
@ -95,8 +95,8 @@ PACK_STRUCT_END
|
|||||||
#if (!LWIP_UDP && LWIP_DHCP)
|
#if (!LWIP_UDP && LWIP_DHCP)
|
||||||
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
|
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
#if (!LWIP_UDP && LWIP_MULTICAST_TX_OPTIONS)
|
#if (!LWIP_UDP && !LWIP_RAW && LWIP_MULTICAST_TX_OPTIONS)
|
||||||
#error "If you want to use LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 in your lwipopts.h"
|
#error "If you want to use LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 and/or LWIP_RAW=1 in your lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
#if (!LWIP_UDP && LWIP_DNS)
|
#if (!LWIP_UDP && LWIP_DNS)
|
||||||
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
|
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||||
|
@ -220,7 +220,7 @@ raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
|
|||||||
* This is legacy support: scope-aware callers should always provide properly
|
* This is legacy support: scope-aware callers should always provide properly
|
||||||
* zoned source addresses. */
|
* zoned source addresses. */
|
||||||
if (IP_IS_V6(&pcb->local_ip) &&
|
if (IP_IS_V6(&pcb->local_ip) &&
|
||||||
ip6_addr_lacks_zone(ip_2_ip6(&pcb->local_ip), IP6_UNICAST)) {
|
ip6_addr_lacks_zone(ip_2_ip6(&pcb->local_ip), IP6_UNKNOWN)) {
|
||||||
ip6_addr_select_zone(ip_2_ip6(&pcb->local_ip), ip_2_ip6(&pcb->local_ip));
|
ip6_addr_select_zone(ip_2_ip6(&pcb->local_ip), ip_2_ip6(&pcb->local_ip));
|
||||||
}
|
}
|
||||||
#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
|
#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
|
||||||
@ -325,12 +325,29 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
|
|||||||
|
|
||||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
|
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
|
||||||
|
|
||||||
|
#if LWIP_MULTICAST_TX_OPTIONS
|
||||||
|
netif = NULL;
|
||||||
|
if (ip_addr_ismulticast(ipaddr) && (pcb->mcast_ifindex != NETIF_NO_INDEX)) {
|
||||||
|
/* For multicast-destined packets, use the user-provided interface index to
|
||||||
|
* determine the outgoing interface, if an interface index is set and a
|
||||||
|
* matching netif can be found. Otherwise, fall back to regular routing. */
|
||||||
|
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||||
|
if (pcb->mcast_ifindex == netif_num_to_index(netif)) {
|
||||||
|
break; /* found! */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netif == NULL)
|
||||||
|
#endif /* LWIP_MULTICAST_TX_OPTIONS */
|
||||||
|
{
|
||||||
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
|
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
|
||||||
/* Don't call ip_route() with IP_ANY_TYPE */
|
/* Don't call ip_route() with IP_ANY_TYPE */
|
||||||
netif = ip_route(IP46_ADDR_ANY(IP_GET_TYPE(ipaddr)), ipaddr);
|
netif = ip_route(IP46_ADDR_ANY(IP_GET_TYPE(ipaddr)), ipaddr);
|
||||||
} else {
|
} else {
|
||||||
netif = ip_route(&pcb->local_ip, ipaddr);
|
netif = ip_route(&pcb->local_ip, ipaddr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (netif == NULL) {
|
if (netif == NULL) {
|
||||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
|
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
|
||||||
@ -338,7 +355,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
|
|||||||
return ERR_RTE;
|
return ERR_RTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip_addr_isany(&pcb->local_ip)) {
|
if (ip_addr_isany(&pcb->local_ip) || ip_addr_ismulticast(&pcb->local_ip)) {
|
||||||
/* use outgoing network interface IP address as source address */
|
/* use outgoing network interface IP address as source address */
|
||||||
src_ip = ip_netif_get_local_ip(netif, ipaddr);
|
src_ip = ip_netif_get_local_ip(netif, ipaddr);
|
||||||
#if LWIP_IPV6
|
#if LWIP_IPV6
|
||||||
@ -374,6 +391,7 @@ raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
|
|||||||
err_t err;
|
err_t err;
|
||||||
struct pbuf *q; /* q will be sent down the stack */
|
struct pbuf *q; /* q will be sent down the stack */
|
||||||
s16_t header_size;
|
s16_t header_size;
|
||||||
|
u8_t ttl;
|
||||||
|
|
||||||
if ((pcb == NULL) || (dst_ip == NULL) || (netif == NULL) || (src_ip == NULL) ||
|
if ((pcb == NULL) || (dst_ip == NULL) || (netif == NULL) || (src_ip == NULL) ||
|
||||||
!IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
|
!IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
|
||||||
@ -397,6 +415,7 @@ raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
|
|||||||
if (p->len < header_size) {
|
if (p->len < header_size) {
|
||||||
return ERR_VAL;
|
return ERR_VAL;
|
||||||
}
|
}
|
||||||
|
/* @todo multicast loop support, if at all desired for this scenario.. */
|
||||||
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
|
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
|
||||||
err = ip_output_if_hdrincl(p, src_ip, dst_ip, netif);
|
err = ip_output_if_hdrincl(p, src_ip, dst_ip, netif);
|
||||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||||
@ -446,6 +465,13 @@ raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
|
|||||||
}
|
}
|
||||||
#endif /* IP_SOF_BROADCAST */
|
#endif /* IP_SOF_BROADCAST */
|
||||||
|
|
||||||
|
/* Multicast Loop? */
|
||||||
|
#if LWIP_MULTICAST_TX_OPTIONS
|
||||||
|
if (((pcb->flags & RAW_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) {
|
||||||
|
q->flags |= PBUF_FLAG_MCASTLOOP;
|
||||||
|
}
|
||||||
|
#endif /* LWIP_MULTICAST_TX_OPTIONS */
|
||||||
|
|
||||||
#if LWIP_IPV6
|
#if LWIP_IPV6
|
||||||
/* If requested, based on the IPV6_CHECKSUM socket option per RFC3542,
|
/* If requested, based on the IPV6_CHECKSUM socket option per RFC3542,
|
||||||
compute the checksum and update the checksum in the payload. */
|
compute the checksum and update the checksum in the payload. */
|
||||||
@ -456,8 +482,15 @@ raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Determine TTL to use */
|
||||||
|
#if LWIP_MULTICAST_TX_OPTIONS
|
||||||
|
ttl = (ip_addr_ismulticast(dst_ip) ? raw_get_multicast_ttl(pcb) : pcb->ttl);
|
||||||
|
#else /* LWIP_MULTICAST_TX_OPTIONS */
|
||||||
|
ttl = pcb->ttl;
|
||||||
|
#endif /* LWIP_MULTICAST_TX_OPTIONS */
|
||||||
|
|
||||||
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
|
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
|
||||||
err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, pcb->protocol, netif);
|
err = ip_output_if(q, src_ip, dst_ip, ttl, pcb->tos, pcb->protocol, netif);
|
||||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||||
|
|
||||||
/* did we chain a header earlier? */
|
/* did we chain a header earlier? */
|
||||||
@ -538,6 +571,9 @@ raw_new(u8_t proto)
|
|||||||
memset(pcb, 0, sizeof(struct raw_pcb));
|
memset(pcb, 0, sizeof(struct raw_pcb));
|
||||||
pcb->protocol = proto;
|
pcb->protocol = proto;
|
||||||
pcb->ttl = RAW_TTL;
|
pcb->ttl = RAW_TTL;
|
||||||
|
#if LWIP_MULTICAST_TX_OPTIONS
|
||||||
|
raw_set_multicast_ttl(pcb, RAW_TTL);
|
||||||
|
#endif /* LWIP_MULTICAST_TX_OPTIONS */
|
||||||
pcb->next = raw_pcbs;
|
pcb->next = raw_pcbs;
|
||||||
raw_pcbs = pcb;
|
raw_pcbs = pcb;
|
||||||
}
|
}
|
||||||
|
@ -986,7 +986,7 @@
|
|||||||
* core support for the corresponding IPv6 options.
|
* core support for the corresponding IPv6 options.
|
||||||
*/
|
*/
|
||||||
#if !defined LWIP_MULTICAST_TX_OPTIONS || defined __DOXYGEN__
|
#if !defined LWIP_MULTICAST_TX_OPTIONS || defined __DOXYGEN__
|
||||||
#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && LWIP_UDP)
|
#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
@ -54,6 +54,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define RAW_FLAGS_CONNECTED 0x01U
|
#define RAW_FLAGS_CONNECTED 0x01U
|
||||||
#define RAW_FLAGS_HDRINCL 0x02U
|
#define RAW_FLAGS_HDRINCL 0x02U
|
||||||
|
#define RAW_FLAGS_MULTICAST_LOOP 0x04U
|
||||||
|
|
||||||
struct raw_pcb;
|
struct raw_pcb;
|
||||||
|
|
||||||
@ -80,6 +81,13 @@ struct raw_pcb {
|
|||||||
u8_t protocol;
|
u8_t protocol;
|
||||||
u8_t flags;
|
u8_t flags;
|
||||||
|
|
||||||
|
#if LWIP_MULTICAST_TX_OPTIONS
|
||||||
|
/** outgoing network interface for multicast packets, by interface index (if nonzero) */
|
||||||
|
u8_t mcast_ifindex;
|
||||||
|
/** TTL for outgoing multicast packets */
|
||||||
|
u8_t mcast_ttl;
|
||||||
|
#endif /* LWIP_MULTICAST_TX_OPTIONS */
|
||||||
|
|
||||||
/** receive callback function */
|
/** receive callback function */
|
||||||
raw_recv_fn recv;
|
raw_recv_fn recv;
|
||||||
/* user-supplied argument for the recv callback */
|
/* user-supplied argument for the recv callback */
|
||||||
@ -118,6 +126,13 @@ void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_a
|
|||||||
/* for compatibility with older implementation */
|
/* for compatibility with older implementation */
|
||||||
#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto)
|
#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto)
|
||||||
|
|
||||||
|
#if LWIP_MULTICAST_TX_OPTIONS
|
||||||
|
#define raw_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx))
|
||||||
|
#define raw_get_multicast_netif_index(pcb) ((pcb)->mcast_ifindex)
|
||||||
|
#define raw_set_multicast_ttl(pcb, value) ((pcb)->mcast_ttl = (value))
|
||||||
|
#define raw_get_multicast_ttl(pcb) ((pcb)->mcast_ttl)
|
||||||
|
#endif /* LWIP_MULTICAST_TX_OPTIONS */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user