mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #3183 from authmillenon/ng_ipv6/enh/loopback
ng_ipv6: add loopback support
This commit is contained in:
commit
c14587f829
@ -285,19 +285,28 @@ static int _fill_ipv6_hdr(kernel_pid_t iface, ng_pktsnip_t *ipv6,
|
|||||||
DEBUG("ipv6: set next header to %" PRIu8 "\n", hdr->nh);
|
DEBUG("ipv6: set next header to %" PRIu8 "\n", hdr->nh);
|
||||||
|
|
||||||
if (hdr->hl == 0) {
|
if (hdr->hl == 0) {
|
||||||
hdr->hl = ng_ipv6_netif_get(iface)->cur_hl;
|
if (iface == KERNEL_PID_UNDEF) {
|
||||||
|
hdr->hl = NG_IPV6_NETIF_DEFAULT_HL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hdr->hl = ng_ipv6_netif_get(iface)->cur_hl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ng_ipv6_addr_is_unspecified(&hdr->src)) {
|
if (ng_ipv6_addr_is_unspecified(&hdr->src)) {
|
||||||
ng_ipv6_addr_t *src = ng_ipv6_netif_find_best_src_addr(iface, &hdr->dst);
|
if (ng_ipv6_addr_is_loopback(&hdr->dst)) {
|
||||||
|
ng_ipv6_addr_set_loopback(&hdr->src);
|
||||||
if (src != NULL) {
|
|
||||||
DEBUG("ipv6: set packet source to %s\n",
|
|
||||||
ng_ipv6_addr_to_str(addr_str, src, sizeof(addr_str)));
|
|
||||||
memcpy(&hdr->src, src, sizeof(ng_ipv6_addr_t));
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ng_ipv6_addr_t *src = ng_ipv6_netif_find_best_src_addr(iface, &hdr->dst);
|
||||||
|
|
||||||
/* Otherwise leave unspecified */
|
if (src != NULL) {
|
||||||
|
DEBUG("ipv6: set packet source to %s\n",
|
||||||
|
ng_ipv6_addr_to_str(addr_str, src, sizeof(addr_str)));
|
||||||
|
memcpy(&hdr->src, src, sizeof(ng_ipv6_addr_t));
|
||||||
|
}
|
||||||
|
/* Otherwise leave unspecified */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("ipv6: calculate checksum for upper header.\n");
|
DEBUG("ipv6: calculate checksum for upper header.\n");
|
||||||
@ -456,6 +465,7 @@ static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
|
|||||||
{
|
{
|
||||||
kernel_pid_t iface = KERNEL_PID_UNDEF;
|
kernel_pid_t iface = KERNEL_PID_UNDEF;
|
||||||
ng_pktsnip_t *ipv6, *payload;
|
ng_pktsnip_t *ipv6, *payload;
|
||||||
|
ng_ipv6_addr_t *tmp;
|
||||||
ng_ipv6_hdr_t *hdr;
|
ng_ipv6_hdr_t *hdr;
|
||||||
/* seize payload as temporary variable */
|
/* seize payload as temporary variable */
|
||||||
payload = ng_pktbuf_start_write(pkt);
|
payload = ng_pktbuf_start_write(pkt);
|
||||||
@ -480,11 +490,50 @@ static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hdr = ipv6->data;
|
hdr = ipv6->data;
|
||||||
payload = ipv6->next; /* TODO: parse extension headers */
|
payload = ipv6->next;
|
||||||
|
|
||||||
if (ng_ipv6_addr_is_multicast(&hdr->dst)) {
|
if (ng_ipv6_addr_is_multicast(&hdr->dst)) {
|
||||||
_send_multicast(iface, pkt, ipv6, payload, prep_hdr);
|
_send_multicast(iface, pkt, ipv6, payload, prep_hdr);
|
||||||
}
|
}
|
||||||
|
else if ((ng_ipv6_addr_is_loopback(&hdr->dst)) || /* dst is loopback address */
|
||||||
|
((iface == KERNEL_PID_UNDEF) && /* or dst registered to any local interface */
|
||||||
|
((iface = ng_ipv6_netif_find_by_addr(&tmp, &hdr->dst)) != KERNEL_PID_UNDEF)) ||
|
||||||
|
((iface != KERNEL_PID_UNDEF) && /* or dst registered to given interface */
|
||||||
|
(ng_ipv6_netif_find_addr(iface, &hdr->dst) != NULL))) {
|
||||||
|
uint8_t *rcv_data;
|
||||||
|
ng_pktsnip_t *ptr = ipv6, *rcv_pkt;
|
||||||
|
|
||||||
|
if (prep_hdr) {
|
||||||
|
if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
|
||||||
|
/* error on filling up header */
|
||||||
|
ng_pktbuf_release(pkt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rcv_pkt = ng_pktbuf_add(NULL, NULL, ng_pkt_len(ipv6), NG_NETTYPE_IPV6);
|
||||||
|
|
||||||
|
if (rcv_pkt == NULL) {
|
||||||
|
DEBUG("ipv6: error on generating loopback packet\n");
|
||||||
|
ng_pktbuf_release(pkt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcv_data = rcv_pkt->data;
|
||||||
|
|
||||||
|
/* "reverse" packet (by making it one snip as if received from NIC) */
|
||||||
|
while (ptr != NULL) {
|
||||||
|
memcpy(rcv_data, ptr->data, ptr->size);
|
||||||
|
rcv_data += ptr->size;
|
||||||
|
ptr = ptr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
ng_pktbuf_release(pkt);
|
||||||
|
|
||||||
|
DEBUG("ipv6: packet is addressed to myself => loopback\n");
|
||||||
|
|
||||||
|
ng_netapi_receive(ng_ipv6_pid, rcv_pkt);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
uint8_t l2addr_len = NG_IPV6_NC_L2_ADDR_MAX;
|
uint8_t l2addr_len = NG_IPV6_NC_L2_ADDR_MAX;
|
||||||
uint8_t l2addr[l2addr_len];
|
uint8_t l2addr[l2addr_len];
|
||||||
@ -513,7 +562,10 @@ static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
|
|||||||
/* functions for receiving */
|
/* functions for receiving */
|
||||||
static inline bool _pkt_not_for_me(kernel_pid_t *iface, ng_ipv6_hdr_t *hdr)
|
static inline bool _pkt_not_for_me(kernel_pid_t *iface, ng_ipv6_hdr_t *hdr)
|
||||||
{
|
{
|
||||||
if (*iface == KERNEL_PID_UNDEF) {
|
if (ng_ipv6_addr_is_loopback(&hdr->dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (*iface == KERNEL_PID_UNDEF) {
|
||||||
*iface = ng_ipv6_netif_find_by_addr(NULL, &hdr->dst);
|
*iface = ng_ipv6_netif_find_by_addr(NULL, &hdr->dst);
|
||||||
return (*iface == KERNEL_PID_UNDEF);
|
return (*iface == KERNEL_PID_UNDEF);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user