-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys/net/ipv6: Simplify type #14759
sys/net/ipv6: Simplify type #14759
Conversation
Also update accesses to that type
I compiled a selection of boards using BOARD="<board>" BUILD_IN_DOCKER=1 RIOT_CI_BUILD=1 DOCKER_MAKE_ARGS=-j DOCKER_ENVIRONMENT_CMDLINE="-e BINDIRBASE='<ref>-bin'" make -C tests/unittests/ tests-ipv6_addr For some I needed to remove Here are the results:
While for ARM the binary size remains unchanged, there seems to be some weird ROM/RAM trade-off happening for MSP430 and AVR. While the size overall decreases due to big improvements in the ROM usage, the usage in the data segment increases (most likely due to the public constants used by |
I observed similar behavior for |
On AVR the solution would be to use I'm not sure why this PR trades RAM for ROM for the MSP430.
The reasoning for this PR is not that it improves ROM/RAM consumption, but that the type can be used more consistently. E.g. |
Actually it does not use that type to decrease dependencies. |
I am aware of that. The question I am pondering is, if that re-usability justifies the significant increase in RAM usage. |
|
||
TEST_ASSERT_EQUAL_INT(0, a.u64[0].u64); /* Don't trust the macro ;) */ | ||
TEST_ASSERT_EQUAL_INT(1, byteorder_ntohll(a.u64[1])); | ||
TEST_ASSERT_EQUAL_INT(true, ipv6_addr_is_loopback(&a)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test also tests the function ipv6_addr_is_loopback()
so just using memcmp()
here somewhat nullifies the purpose of the test.
static const ipv6_addr_t solicited_node_addr = { | ||
.u8 = { | ||
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00 | ||
} | ||
}; | ||
*out = solicited_node_addr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use the already predefined prefix here?
static const ipv6_addr_t solicited_node_addr = { | |
.u8 = { | |
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00 | |
} | |
}; | |
*out = solicited_node_addr; | |
*out = ipv6_addr_solicited_node_prefix; |
@@ -246,15 +249,14 @@ static size_t _iphc_ipv6_decode(const uint8_t *iphc_hdr, | |||
|
|||
case IPHC_SAC_SAM_16: | |||
ipv6_addr_set_link_local_prefix(&ipv6_hdr->src); | |||
ipv6_hdr->src.u32[2] = byteorder_htonl(0x000000ff); | |||
ipv6_hdr->src.u16[6] = byteorder_htons(0xfe00); | |||
memcpy(&ipv6_hdr->src.u8[8], addr_fffe, sizeof(addr_fffe)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ipv6_hdr
was completely zeroed in l. 166 so it might make more sense to just set the non-zero values here and remove addr_fffe
altogether:
memcpy(&ipv6_hdr->src.u8[8], addr_fffe, sizeof(addr_fffe)); | |
ipv6_hdr->src.u8[11] = 0xff; | |
ipv6_hdr->src.u8[12] = 0xfe; |
@@ -276,8 +278,7 @@ static size_t _iphc_ipv6_decode(const uint8_t *iphc_hdr, | |||
|
|||
case IPHC_SAC_SAM_CTX_16: | |||
assert(ctx != NULL); | |||
ipv6_hdr->src.u32[2] = byteorder_htonl(0x000000ff); | |||
ipv6_hdr->src.u16[6] = byteorder_htons(0xfe00); | |||
memcpy(&ipv6_hdr->src.u8[8], addr_fffe, sizeof(addr_fffe)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
memcpy(&ipv6_hdr->src.u8[8], addr_fffe, sizeof(addr_fffe)); | |
ipv6_hdr->src.u8[11] = 0xff; | |
ipv6_hdr->src.u8[12] = 0xfe; |
@@ -330,15 +331,14 @@ static size_t _iphc_ipv6_decode(const uint8_t *iphc_hdr, | |||
|
|||
case IPHC_M_DAC_DAM_U_16: | |||
ipv6_addr_set_link_local_prefix(&ipv6_hdr->dst); | |||
ipv6_hdr->dst.u32[2] = byteorder_htonl(0x000000ff); | |||
ipv6_hdr->dst.u16[6] = byteorder_htons(0xfe00); | |||
memcpy(&ipv6_hdr->dst.u8[8], addr_fffe, sizeof(addr_fffe)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here
memcpy(&ipv6_hdr->dst.u8[8], addr_fffe, sizeof(addr_fffe)); | |
ipv6_hdr->dst.u8[11] = 0xff; | |
ipv6_hdr->dst.u8[12] = 0xfe; |
@@ -355,8 +355,7 @@ static size_t _iphc_ipv6_decode(const uint8_t *iphc_hdr, | |||
break; | |||
|
|||
case IPHC_M_DAC_DAM_U_CTX_16: | |||
ipv6_hdr->dst.u32[2] = byteorder_htonl(0x000000ff); | |||
ipv6_hdr->dst.u16[6] = byteorder_htons(0xfe00); | |||
memcpy(&ipv6_hdr->dst.u8[8], addr_fffe, sizeof(addr_fffe)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here
memcpy(&ipv6_hdr->dst.u8[8], addr_fffe, sizeof(addr_fffe)); | |
ipv6_hdr->dst.u8[11] = 0xff; | |
ipv6_hdr->dst.u8[12] = 0xfe; |
if ((ipv6_hdr->dst.u16[1].u16 == 0) && | ||
(ipv6_hdr->dst.u32[1].u32 == 0) && | ||
(ipv6_hdr->dst.u16[4].u16 == 0)) { | ||
if (!memcpy(&ipv6_hdr->dst.u8[2], zeros8, 8)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just from reading the code its not clear where zeros8
comes from, I'd rather compare byte-wise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you're saying that this
if (!memcpy(ipv6_hdr->dest.u8[2], zeros8, 8)) {
/* ... */
}
is less readable than this
int is_all_zero = 1;
for (size_t i = 2; i < 10; i++) {
if (ipv6_hdr->dst.u8[2] != 0) {
is_zero = 0;
break;
}
}
if (!is_all_zero) {
/* ... */
}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, but both your proposals are more obscure than
if ((ipv6_hdr->dest.u8[2] == 0) && (ipv6_hdr->dest.u8[3] == 0) &&
(ipv6_hdr->dest.u8[4] == 0) && (ipv6_hdr->dest.u8[5] == 0) &&
(ipv6_hdr->dest.u8[6] == 0) && (ipv6_hdr->dest.u8[7] == 0) &&
(ipv6_hdr->dest.u8[8] == 0) && (ipv6_hdr->dest.u8[9] == 0)) {
(I think even you reversed the logic in your second proposal ;-))
(ipv6_hdr->dst.u32[2].u32 == 0) && | ||
(ipv6_hdr->dst.u16[6].u16 == 0) && | ||
(ipv6_hdr->dst.u8[14] == 0)) { | ||
!memcmp(&ipv6_hdr->dst.u8[8], zeros8, 7)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
/* 8 bits. The address is derived using 8 bits carried inline */ | ||
iphc_hdr[IPHC2_IDX] |= IPHC_M_DAC_DAM_M_8; | ||
iphc_hdr[inline_pos++] = ipv6_hdr->dst.u8[15]; | ||
addr_comp = true; | ||
} | ||
/* if multicast address is of format ffXX::XX:XXXX */ | ||
else if ((ipv6_hdr->dst.u16[5].u16 == 0) && | ||
(ipv6_hdr->dst.u8[12] == 0)) { | ||
else if (!memcmp(&ipv6_hdr->dst.u8[10], &zeros8, 3)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Especially here.
@@ -1184,7 +1175,7 @@ static size_t _iphc_ipv6_encode(gnrc_pktsnip_t *pkt, | |||
} | |||
iphc_hdr[inline_pos++] = ipv6_hdr->dst.u8[1]; | |||
iphc_hdr[inline_pos++] = ipv6_hdr->dst.u8[2]; | |||
memcpy(iphc_hdr + inline_pos, ipv6_hdr->dst.u16 + 6, 4); | |||
memcpy(iphc_hdr + inline_pos, ipv6_hdr->dst.u8 + 12, 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memcpy(iphc_hdr + inline_pos, ipv6_hdr->dst.u8 + 12, 4); | |
memcpy(iphc_hdr + inline_pos, &ipv6_hdr->dst.u8[12], 4); |
_context_overlaps_iid(dst_ctx, &(ipv6_hdr->dst), &iid)) { | ||
/* 0 bits. The address is derived using the link-layer address */ | ||
iphc_hdr[IPHC2_IDX] |= IPHC_M_DAC_DAM_U_L2; | ||
addr_comp = true; | ||
} | ||
else if ((byteorder_ntohl(ipv6_hdr->dst.u32[2]) == 0x000000ff) && | ||
(byteorder_ntohs(ipv6_hdr->dst.u16[6]) == 0xfe00)) { | ||
else if (!memcmp(&ipv6_hdr->dst.u8[8], addr_fffe, sizeof(addr_fffe))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
Contribution description
Make
ipv6_addr_t
a simple byte array.Motivation
Using complex types makes interoperability of functions using this type with external code or even with
sock_udp_ep_t
harder, especially due to the alignment requirements. Using a simple type allows using these functions in the Sock API or in external code (specifically in a pkg I want to update) and thus prevents code duplication and increases maintainability.Testing procedure
Luckily, @miri64 wrote many unit tests that already helped to fix many bugs this PR previously contained. In addition to automatic tests, testing IPv6 communication would nake sense.
Issues/PRs references
#14737