mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
ba3088c4bd
into separate patch files
531 lines
19 KiB
Diff
531 lines
19 KiB
Diff
*** stock_iot-lab_M3/openwsn/03b-IPv6/forwarding.c Thu Apr 24 11:01:36 2014
|
|
--- riot-openwsn-wip/openwsn/03b-IPv6/forwarding.c Thu Apr 24 16:55:54 2014
|
|
***************
|
|
*** 7,31 ****
|
|
#include "packetfunctions.h"
|
|
#include "neighbors.h"
|
|
#include "icmpv6.h"
|
|
#include "openudp.h"
|
|
#include "opentcp.h"
|
|
|
|
//=========================== variables =======================================
|
|
|
|
//=========================== prototypes ======================================
|
|
|
|
! error_t fowarding_send_internal_RoutingTable(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv);
|
|
void forwarding_getNextHop_RoutingTable(open_addr_t* destination, open_addr_t* addressToWrite);
|
|
! error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header);
|
|
|
|
//=========================== public ==========================================
|
|
|
|
/**
|
|
\brief Initialize this module.
|
|
*/
|
|
! void forwarding_init() {
|
|
}
|
|
|
|
/**
|
|
\brief Send a packet originating at this mote.
|
|
|
|
--- 7,36 ----
|
|
#include "packetfunctions.h"
|
|
#include "neighbors.h"
|
|
#include "icmpv6.h"
|
|
+ #include "icmpv6rpl.h"
|
|
#include "openudp.h"
|
|
#include "opentcp.h"
|
|
+ //#include "debugpins.h"
|
|
+ #include "scheduler.h"
|
|
|
|
//=========================== variables =======================================
|
|
|
|
//=========================== prototypes ======================================
|
|
|
|
! owerror_t forwarding_send_internal_RoutingTable(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht hopbyhop_header, uint8_t fw_SendOrfw_Rcv);
|
|
void forwarding_getNextHop_RoutingTable(open_addr_t* destination, open_addr_t* addressToWrite);
|
|
! owerror_t forwarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header);
|
|
! void forwarding_createHopByHopOption(rpl_hopoption_ht *hopbyhop_opt, uint8_t flags);
|
|
|
|
//=========================== public ==========================================
|
|
|
|
/**
|
|
\brief Initialize this module.
|
|
*/
|
|
! void forwarding_init(void) {
|
|
}
|
|
|
|
+
|
|
/**
|
|
\brief Send a packet originating at this mote.
|
|
|
|
***************
|
|
*** 34,41 ****
|
|
|
|
\param[in,out] msg Packet to send.
|
|
*/
|
|
! error_t forwarding_send(OpenQueueEntry_t* msg) {
|
|
ipv6_header_iht ipv6_header;
|
|
open_addr_t* myprefix;
|
|
open_addr_t* myadd64;
|
|
|
|
--- 39,48 ----
|
|
|
|
\param[in,out] msg Packet to send.
|
|
*/
|
|
! owerror_t forwarding_send(OpenQueueEntry_t* msg) {
|
|
ipv6_header_iht ipv6_header;
|
|
+ rpl_hopoption_ht hopbyhop_opt;
|
|
+
|
|
open_addr_t* myprefix;
|
|
open_addr_t* myadd64;
|
|
|
|
***************
|
|
*** 58,65 ****
|
|
//this is done here as send_internal is used by forwarding of packets as well which
|
|
//carry a hlim. This value is required to be set to a value as the following function can decrement it
|
|
ipv6_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT;
|
|
|
|
! return fowarding_send_internal_RoutingTable(msg,ipv6_header,PCKTSEND);
|
|
}
|
|
|
|
/**
|
|
--- 65,74 ----
|
|
//this is done here as send_internal is used by forwarding of packets as well which
|
|
//carry a hlim. This value is required to be set to a value as the following function can decrement it
|
|
ipv6_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT;
|
|
+ //create hop by hop option
|
|
+ forwarding_createHopByHopOption(&hopbyhop_opt, 0x00); //flags are 0x00 -- TODO check and define macro
|
|
|
|
! return forwarding_send_internal_RoutingTable(msg,ipv6_header,hopbyhop_opt,PCKTSEND);
|
|
}
|
|
|
|
/**
|
|
***************
|
|
*** 68,74 ****
|
|
\param[in,out] msg The packet just sent.
|
|
\param[in] error The outcome of sending it.
|
|
*/
|
|
! void forwarding_sendDone(OpenQueueEntry_t* msg, error_t error) {
|
|
|
|
// take ownership
|
|
msg->owner = COMPONENT_FORWARDING;
|
|
--- 77,83 ----
|
|
\param[in,out] msg The packet just sent.
|
|
\param[in] error The outcome of sending it.
|
|
*/
|
|
! void forwarding_sendDone(OpenQueueEntry_t* msg, owerror_t error) {
|
|
|
|
// take ownership
|
|
msg->owner = COMPONENT_FORWARDING;
|
|
***************
|
|
*** 108,126 ****
|
|
\param[in,out] msg The packet just sent.
|
|
\param[in] ipv6_header The information contained in the 6LoWPAN header.
|
|
*/
|
|
! void forwarding_receive(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header) {
|
|
|
|
// take ownership
|
|
msg->owner = COMPONENT_FORWARDING;
|
|
|
|
- // populate packets metadata with l4 information
|
|
- msg->l4_protocol = ipv6_header.next_header;
|
|
- msg->l4_protocol_compressed = ipv6_header.next_header_compressed;
|
|
|
|
! // populate packets metadata with l3 information
|
|
memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t));
|
|
memcpy(&(msg->l3_sourceAdd), &ipv6_header.src, sizeof(open_addr_t));
|
|
|
|
if (
|
|
(
|
|
idmanager_isMyAddress(&ipv6_header.dest)
|
|
--- 117,152 ----
|
|
\param[in,out] msg The packet just sent.
|
|
\param[in] ipv6_header The information contained in the 6LoWPAN header.
|
|
*/
|
|
! void forwarding_receive(OpenQueueEntry_t* msg,
|
|
! ipv6_header_iht ipv6_header,
|
|
! ipv6_hopbyhop_ht ipv6_hop_header,
|
|
! rpl_hopoption_ht hop_by_hop_option) {
|
|
!
|
|
! uint8_t temp_flags;
|
|
|
|
// take ownership
|
|
msg->owner = COMPONENT_FORWARDING;
|
|
|
|
|
|
! //contains a
|
|
! if (ipv6_header.next_header==IANA_IPv6HOPOPT){
|
|
! // populate packets metadata with l4 information
|
|
! msg->l4_protocol = ipv6_hop_header.nextHeader;
|
|
! msg->l4_protocol_compressed = ipv6_hop_header.next_header_compressed; // rfc 6282
|
|
!
|
|
! //process HOP BY HOP header
|
|
!
|
|
!
|
|
! }else{
|
|
! msg->l4_protocol = ipv6_header.next_header;
|
|
! msg->l4_protocol_compressed = ipv6_header.next_header_compressed; // rfc 6282
|
|
! }
|
|
!
|
|
! // populate packets metadata with l3 information
|
|
memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t));
|
|
memcpy(&(msg->l3_sourceAdd), &ipv6_header.src, sizeof(open_addr_t));
|
|
|
|
+
|
|
if (
|
|
(
|
|
idmanager_isMyAddress(&ipv6_header.dest)
|
|
***************
|
|
*** 128,136 ****
|
|
packetfunctions_isBroadcastMulticast(&ipv6_header.dest)
|
|
)
|
|
&&
|
|
ipv6_header.next_header!=IANA_IPv6ROUTE
|
|
) {
|
|
! // this packet is for me, but no routing header.
|
|
|
|
// indicate received packet to upper layer
|
|
switch(msg->l4_protocol) {
|
|
--- 154,163 ----
|
|
packetfunctions_isBroadcastMulticast(&ipv6_header.dest)
|
|
)
|
|
&&
|
|
+ //ipv6 header - next header will be IANA_IPv6HOPOPT or IANA_IPv6ROUTE
|
|
ipv6_header.next_header!=IANA_IPv6ROUTE
|
|
) {
|
|
! // this packet is for me, but no src routing header.
|
|
|
|
// indicate received packet to upper layer
|
|
switch(msg->l4_protocol) {
|
|
***************
|
|
*** 151,178 ****
|
|
}
|
|
} else {
|
|
// this packet is not for me: relay
|
|
!
|
|
// change the creator of the packet
|
|
msg->creator = COMPONENT_FORWARDING;
|
|
|
|
if (ipv6_header.next_header!=IANA_IPv6ROUTE) {
|
|
// no source routing header present
|
|
!
|
|
// resend as if from upper layer
|
|
! if (fowarding_send_internal_RoutingTable(msg, ipv6_header,PCKTFORWARD)==E_FAIL) {
|
|
openqueue_freePacketBuffer(msg);
|
|
}
|
|
} else {
|
|
! // source routing header present
|
|
!
|
|
! if (fowarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) {
|
|
! openqueue_freePacketBuffer(msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
! //=========================== private =========================================
|
|
|
|
/**
|
|
\brief Send a packet using the routing table to find the next hop.
|
|
--- 178,230 ----
|
|
}
|
|
} else {
|
|
// this packet is not for me: relay
|
|
!
|
|
// change the creator of the packet
|
|
msg->creator = COMPONENT_FORWARDING;
|
|
|
|
if (ipv6_header.next_header!=IANA_IPv6ROUTE) {
|
|
// no source routing header present
|
|
!
|
|
! //process HOP bY HOP header
|
|
! temp_flags = hop_by_hop_option.flags;
|
|
! if ((temp_flags & O_FLAG)!=0){
|
|
! //error wrong direction
|
|
! //what todo? print the error
|
|
! openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_DIRECTION,
|
|
! (errorparameter_t)1,
|
|
! (errorparameter_t)1);
|
|
! }
|
|
! if (hop_by_hop_option.senderRank < neighbors_getMyDAGrank()){
|
|
! //wrong rank relation.. loop detected
|
|
! temp_flags |= R_FLAG; //set r flag.
|
|
! openserial_printError(COMPONENT_FORWARDING,ERR_LOOP_DETECTED,
|
|
! (errorparameter_t) hop_by_hop_option.senderRank,
|
|
! (errorparameter_t) neighbors_getMyDAGrank());
|
|
! }
|
|
!
|
|
! //O flag should always be 0 as this is upstream route.
|
|
!
|
|
! forwarding_createHopByHopOption(&hop_by_hop_option, temp_flags);
|
|
!
|
|
!
|
|
// resend as if from upper layer
|
|
! if (forwarding_send_internal_RoutingTable(msg, ipv6_header,hop_by_hop_option,PCKTFORWARD)==E_FAIL) {
|
|
openqueue_freePacketBuffer(msg);
|
|
}
|
|
} else {
|
|
! // source routing header present
|
|
! if (forwarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) {
|
|
! //already freed by send_internal if it fails
|
|
! //todo change error type to another that says src_route failure.
|
|
! openserial_printError(COMPONENT_FORWARDING,ERR_INVALID_FWDMODE,
|
|
! (errorparameter_t)0,
|
|
! (errorparameter_t)0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
!
|
|
|
|
/**
|
|
\brief Send a packet using the routing table to find the next hop.
|
|
***************
|
|
*** 182,188 ****
|
|
\param[in] fw_SendOrfw_Rcv The packet is originating from this mote
|
|
(PCKTSEND), or forwarded (PCKTFORWARD).
|
|
*/
|
|
! error_t fowarding_send_internal_RoutingTable(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv) {
|
|
|
|
// retrieve the next hop from the routing table
|
|
forwarding_getNextHop_RoutingTable(&(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop));
|
|
--- 234,240 ----
|
|
\param[in] fw_SendOrfw_Rcv The packet is originating from this mote
|
|
(PCKTSEND), or forwarded (PCKTFORWARD).
|
|
*/
|
|
! owerror_t forwarding_send_internal_RoutingTable(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht hopbyhop_opt, uint8_t fw_SendOrfw_Rcv) {
|
|
|
|
// retrieve the next hop from the routing table
|
|
forwarding_getNextHop_RoutingTable(&(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop));
|
|
***************
|
|
*** 194,200 ****
|
|
}
|
|
|
|
// send to next lower layer
|
|
! return iphc_sendFromForwarding(msg, ipv6_header, fw_SendOrfw_Rcv);
|
|
}
|
|
|
|
/**
|
|
--- 246,252 ----
|
|
}
|
|
|
|
// send to next lower layer
|
|
! return iphc_sendFromForwarding(msg, ipv6_header, &hopbyhop_opt,fw_SendOrfw_Rcv);
|
|
}
|
|
|
|
/**
|
|
***************
|
|
*** 208,214 ****
|
|
\param[in,out] msg The packet to send.
|
|
\param[in] ipv6_header The packet's IPv6 header.
|
|
*/
|
|
! error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) {
|
|
uint8_t local_CmprE;
|
|
uint8_t local_CmprI;
|
|
uint8_t numAddr;
|
|
--- 260,266 ----
|
|
\param[in,out] msg The packet to send.
|
|
\param[in] ipv6_header The packet's IPv6 header.
|
|
*/
|
|
! owerror_t forwarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) {
|
|
uint8_t local_CmprE;
|
|
uint8_t local_CmprI;
|
|
uint8_t numAddr;
|
|
***************
|
|
*** 218,223 ****
|
|
--- 270,279 ----
|
|
uint8_t octetsAddressSize;
|
|
open_addr_t* prefix;
|
|
rpl_routing_ht* rpl_routing_hdr;
|
|
+
|
|
+ rpl_hopoption_ht hopbyhop_opt;
|
|
+
|
|
+ memset(&hopbyhop_opt,0,sizeof(rpl_hopoption_ht));//reset everything
|
|
|
|
// get my prefix
|
|
prefix = idmanager_getMyID(ADDR_PREFIX);
|
|
***************
|
|
*** 270,275 ****
|
|
--- 326,332 ----
|
|
openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL,
|
|
(errorparameter_t)msg->l4_protocol,
|
|
(errorparameter_t)1);
|
|
+ //not sure that this is correct as iphc will free it?
|
|
openqueue_freePacketBuffer(msg);
|
|
return E_FAIL;
|
|
}
|
|
***************
|
|
*** 297,304 ****
|
|
rpl_routing_hdr->SegmentsLeft--;
|
|
|
|
// find next hop address in source route
|
|
! addressposition = numAddr-(rpl_routing_hdr->SegmentsLeft);
|
|
!
|
|
// how many octets have the address?
|
|
if (rpl_routing_hdr->SegmentsLeft > 1){
|
|
octetsAddressSize = LENGTH_ADDR128b - local_CmprI; //max addr length - number of prefix octets that are elided in the internal route elements
|
|
--- 354,361 ----
|
|
rpl_routing_hdr->SegmentsLeft--;
|
|
|
|
// find next hop address in source route
|
|
! //addressposition = numAddr-(rpl_routing_hdr->SegmentsLeft);
|
|
! addressposition = rpl_routing_hdr->SegmentsLeft;
|
|
// how many octets have the address?
|
|
if (rpl_routing_hdr->SegmentsLeft > 1){
|
|
octetsAddressSize = LENGTH_ADDR128b - local_CmprI; //max addr length - number of prefix octets that are elided in the internal route elements
|
|
***************
|
|
*** 311,324 ****
|
|
msg->l2_nextORpreviousHop.type = ADDR_16B;
|
|
memcpy(
|
|
&(msg->l2_nextORpreviousHop.addr_16b),
|
|
! runningPointer+((addressposition-1)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
// write next hop
|
|
msg->l3_destinationAdd.type = ADDR_16B;
|
|
memcpy(
|
|
&(msg->l3_destinationAdd.addr_16b),
|
|
! runningPointer+((addressposition-1)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
break;
|
|
--- 368,381 ----
|
|
msg->l2_nextORpreviousHop.type = ADDR_16B;
|
|
memcpy(
|
|
&(msg->l2_nextORpreviousHop.addr_16b),
|
|
! runningPointer+((addressposition)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
// write next hop
|
|
msg->l3_destinationAdd.type = ADDR_16B;
|
|
memcpy(
|
|
&(msg->l3_destinationAdd.addr_16b),
|
|
! runningPointer+((addressposition)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
break;
|
|
***************
|
|
*** 327,333 ****
|
|
msg->l2_nextORpreviousHop.type = ADDR_64B;
|
|
memcpy(
|
|
&(msg->l2_nextORpreviousHop.addr_64b),
|
|
! runningPointer+((addressposition-1)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
|
|
--- 384,390 ----
|
|
msg->l2_nextORpreviousHop.type = ADDR_64B;
|
|
memcpy(
|
|
&(msg->l2_nextORpreviousHop.addr_64b),
|
|
! runningPointer+((addressposition)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
|
|
***************
|
|
*** 344,350 ****
|
|
|
|
memcpy(
|
|
&(msg->l3_destinationAdd.addr_128b[8]),
|
|
! runningPointer+((addressposition-1)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
|
|
--- 401,407 ----
|
|
|
|
memcpy(
|
|
&(msg->l3_destinationAdd.addr_128b[8]),
|
|
! runningPointer+((addressposition)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
|
|
***************
|
|
*** 354,367 ****
|
|
msg->l2_nextORpreviousHop.type = ADDR_128B;
|
|
memcpy(
|
|
&(msg->l2_nextORpreviousHop.addr_128b),
|
|
! runningPointer+((addressposition-1)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
// write next hop
|
|
msg->l3_destinationAdd.type = ADDR_128B;
|
|
memcpy(
|
|
&(msg->l3_destinationAdd.addr_128b),
|
|
! runningPointer+((addressposition-1)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
break;
|
|
--- 411,424 ----
|
|
msg->l2_nextORpreviousHop.type = ADDR_128B;
|
|
memcpy(
|
|
&(msg->l2_nextORpreviousHop.addr_128b),
|
|
! runningPointer+((addressposition)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
// write next hop
|
|
msg->l3_destinationAdd.type = ADDR_128B;
|
|
memcpy(
|
|
&(msg->l3_destinationAdd.addr_128b),
|
|
! runningPointer+((addressposition)*octetsAddressSize),
|
|
octetsAddressSize
|
|
);
|
|
break;
|
|
***************
|
|
*** 378,391 ****
|
|
}
|
|
|
|
// send to next lower layer
|
|
! return iphc_sendFromForwarding(msg, ipv6_header, PCKTFORWARD);
|
|
}
|
|
|
|
/**
|
|
\brief Retrieve the next hop's address from routing table.
|
|
|
|
\param[in] destination128b Final IPv6 destination address.
|
|
! \param[out]addressToWrite64b Location to write the EUI64 of next hop to.
|
|
*/
|
|
void forwarding_getNextHop_RoutingTable(open_addr_t* destination128b, open_addr_t* addressToWrite64b) {
|
|
uint8_t i;
|
|
--- 435,448 ----
|
|
}
|
|
|
|
// send to next lower layer
|
|
! return iphc_sendFromForwarding(msg, ipv6_header,&hopbyhop_opt, PCKTFORWARD);
|
|
}
|
|
|
|
/**
|
|
\brief Retrieve the next hop's address from routing table.
|
|
|
|
\param[in] destination128b Final IPv6 destination address.
|
|
! \param[out] addressToWrite64b Location to write the EUI64 of next hop to.
|
|
*/
|
|
void forwarding_getNextHop_RoutingTable(open_addr_t* destination128b, open_addr_t* addressToWrite64b) {
|
|
uint8_t i;
|
|
***************
|
|
*** 403,406 ****
|
|
// destination is remote, send to preferred parent
|
|
neighbors_getPreferredParentEui64(addressToWrite64b);
|
|
}
|
|
! }
|
|
\ No newline at end of file
|
|
--- 460,478 ----
|
|
// destination is remote, send to preferred parent
|
|
neighbors_getPreferredParentEui64(addressToWrite64b);
|
|
}
|
|
! }
|
|
! /*
|
|
! * HOP BY HOP HEADER OPTION
|
|
! */
|
|
!
|
|
!
|
|
! void forwarding_createHopByHopOption(rpl_hopoption_ht *hopbyhop_opt, uint8_t flags) {
|
|
! //set the rpl hop by hop header
|
|
! hopbyhop_opt->optionType = RPL_HOPBYHOP_HEADER_OPTION_TYPE;
|
|
! //8-bit field indicating the length of the option, in
|
|
! //octets, excluding the Option Type and Opt Data Len fields.
|
|
! hopbyhop_opt->optionLen = 0x04; //4-bytes, flags+instanceID+senderrank - no sub-tlvs
|
|
! hopbyhop_opt->flags = flags;
|
|
! hopbyhop_opt->rplInstanceID = icmpv6rpl_getRPLIntanceID(); //getit..
|
|
! hopbyhop_opt->senderRank = neighbors_getMyDAGrank(); //TODO change to DAGRAnk(rank) instead of rank
|
|
! }
|