Skip to content

Commit 78d7b40

Browse files
rveerama1nashif
authored andcommitted
net: 6lo: Fix source address uncompression
When src and dst addresses are compressed based on context information, uncompression method should verify CID bit, SAC and DAC bits and context ID's. But it has missed some cases which resulted in invalid uncompressed IPv6 header. e.g. CID is set, SAC is 0 and DAC is 1 and context id's provided. Uncompression method assumed that src address is compressed based on context information but it is not. Signed-off-by: Ravi kumar Veeramally <[email protected]>
1 parent fc84b73 commit 78d7b40

File tree

3 files changed

+57
-60
lines changed

3 files changed

+57
-60
lines changed

subsys/net/ip/6lo.c

Lines changed: 33 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -862,11 +862,6 @@ static inline u8_t uncompress_sa(struct net_pkt *pkt,
862862
struct net_ipv6_hdr *ipv6,
863863
u8_t offset)
864864
{
865-
if (CIPHC[1] & NET_6LO_IPHC_SAC_1) {
866-
NET_DBG("SAC_1");
867-
NET_DBG("SAM_00 unspecified address");
868-
return offset;
869-
}
870865

871866
NET_DBG("SAC_0");
872867

@@ -913,16 +908,11 @@ static inline u8_t uncompress_sa_ctx(struct net_pkt *pkt,
913908
u8_t offset,
914909
struct net_6lo_context *ctx)
915910
{
916-
if (!ctx) {
917-
return uncompress_sa(pkt, ipv6, offset);
918-
}
911+
NET_DBG("SAC_1");
919912

920913
switch (CIPHC[1] & NET_6LO_IPHC_SAM_11) {
921914
case NET_6LO_IPHC_SAM_00:
922-
NET_DBG("SAM_00 full src addr inlined");
923-
924-
memcpy(ipv6->src.s6_addr, &CIPHC[offset], 16);
925-
offset += 16;
915+
NET_DBG("SAM_00 unspecified address");
926916
break;
927917
case NET_6LO_IPHC_SAM_01:
928918
NET_DBG("SAM_01 last 64 bits are inlined");
@@ -978,8 +968,6 @@ static inline u8_t uncompress_da_mcast(struct net_pkt *pkt,
978968
NET_DBG("Dst is multicast");
979969

980970
if (CIPHC[1] & NET_6LO_IPHC_DAC_1) {
981-
/* TODO: DAM00 Unicast-Prefix-based IPv6 Multicast Addresses */
982-
/* Reserved DAM_01, DAM_10, DAM_11 */
983971
NET_WARN("Unsupported DAM options");
984972
return 0;
985973
}
@@ -1033,17 +1021,12 @@ static inline u8_t uncompress_da(struct net_pkt *pkt,
10331021
struct net_ipv6_hdr *ipv6,
10341022
u8_t offset)
10351023
{
1024+
NET_DBG("DAC_0");
1025+
10361026
if (CIPHC[1] & NET_6LO_IPHC_M_1) {
10371027
return uncompress_da_mcast(pkt, ipv6, offset);
10381028
}
10391029

1040-
if (CIPHC[1] & NET_6LO_IPHC_DAC_1) {
1041-
/* Invalid case: ctx doesn't exists , but DAC is 1*/
1042-
return 0;
1043-
}
1044-
1045-
NET_DBG("DAC_0");
1046-
10471030
switch (CIPHC[1] & NET_6LO_IPHC_DAM_11) {
10481031
case NET_6LO_IPHC_DAM_00:
10491032
NET_DBG("DAM_00 full dst addr inlined");
@@ -1087,21 +1070,12 @@ static inline u8_t uncompress_da_ctx(struct net_pkt *pkt,
10871070
u8_t offset,
10881071
struct net_6lo_context *ctx)
10891072
{
1090-
if (!ctx) {
1091-
return uncompress_da(pkt, ipv6, offset);
1092-
}
1073+
NET_DBG("DAC_1");
10931074

10941075
if (CIPHC[1] & NET_6LO_IPHC_M_1) {
10951076
return uncompress_da_mcast(pkt, ipv6, offset);
10961077
}
10971078

1098-
if (!(CIPHC[1] & NET_6LO_IPHC_DAC_1)) {
1099-
/* Invalid case: ctx exists but DAC is 0. */
1100-
return 0;
1101-
}
1102-
1103-
NET_DBG("DAC_1");
1104-
11051079
switch (CIPHC[1] & NET_6LO_IPHC_DAM_11) {
11061080
case NET_6LO_IPHC_DAM_01:
11071081
NET_DBG("DAM_01 last 64 bits are inlined");
@@ -1210,7 +1184,7 @@ static inline u8_t uncompress_nh_udp(struct net_pkt *pkt,
12101184

12111185
#if defined(CONFIG_NET_6LO_CONTEXT)
12121186
/* Helper function to uncompress src and dst contexts */
1213-
static inline bool uncompress_cid(struct net_pkt *pkt,
1187+
static inline void uncompress_cid(struct net_pkt *pkt,
12141188
struct net_6lo_context **src,
12151189
struct net_6lo_context **dst)
12161190
{
@@ -1230,17 +1204,6 @@ static inline bool uncompress_cid(struct net_pkt *pkt,
12301204
if (!(*dst)) {
12311205
NET_DBG("Unknown dst cid %d", cid);
12321206
}
1233-
1234-
/* If CID flag set and src or dst context not available means,
1235-
* either we don't have context information or we received
1236-
* corrupted packet.
1237-
*/
1238-
if (!*src && !*dst) {
1239-
NET_ERR("Context information does not exist in cache");
1240-
return false;
1241-
}
1242-
1243-
return true;
12441207
}
12451208
#endif
12461209

@@ -1259,10 +1222,7 @@ static inline bool uncompress_IPHC_header(struct net_pkt *pkt)
12591222

12601223
if (CIPHC[1] & NET_6LO_IPHC_CID_1) {
12611224
#if defined(CONFIG_NET_6LO_CONTEXT)
1262-
if (!uncompress_cid(pkt, &src, &dst)) {
1263-
return false;
1264-
}
1265-
1225+
uncompress_cid(pkt, &src, &dst);
12661226
offset++;
12671227
#else
12681228
NET_WARN("Context based uncompression not enabled");
@@ -1298,25 +1258,42 @@ static inline bool uncompress_IPHC_header(struct net_pkt *pkt)
12981258

12991259
/* Uncompress Source Address */
13001260
#if defined(CONFIG_NET_6LO_CONTEXT)
1301-
offset = uncompress_sa_ctx(pkt, ipv6, offset, src);
1302-
if (!offset) {
1303-
goto fail;
1261+
if (CIPHC[1] & NET_6LO_IPHC_SAC_1) {
1262+
if (!src) {
1263+
NET_ERR("SAC is set but src context doesn't exists");
1264+
goto fail;
1265+
}
1266+
1267+
offset = uncompress_sa_ctx(pkt, ipv6, offset, src);
1268+
} else {
1269+
offset = uncompress_sa(pkt, ipv6, offset);
13041270
}
13051271
#else
13061272
offset = uncompress_sa(pkt, ipv6, offset);
13071273
#endif
13081274

13091275
/* Uncompress Destination Address */
13101276
#if defined(CONFIG_NET_6LO_CONTEXT)
1311-
offset = uncompress_da_ctx(pkt, ipv6, offset, dst);
1312-
if (!offset) {
1313-
goto fail;
1277+
if (CIPHC[1] & NET_6LO_IPHC_DAC_1) {
1278+
if (CIPHC[1] & NET_6LO_IPHC_M_1) {
1279+
/* TODO: DAM00 Unicast-Prefix-based IPv6 Multicast
1280+
* Addresses. DAM_01, DAM_10 and DAM_11 are reserved.
1281+
*/
1282+
NET_ERR("DAC_1 and M_1 is not supported");
1283+
goto fail;
1284+
}
1285+
1286+
if (!dst) {
1287+
NET_ERR("DAC is set but dst context doesn't exists");
1288+
goto fail;
1289+
}
1290+
1291+
offset = uncompress_da_ctx(pkt, ipv6, offset, dst);
1292+
} else {
1293+
offset = uncompress_da(pkt, ipv6, offset);
13141294
}
13151295
#else
13161296
offset = uncompress_da(pkt, ipv6, offset);
1317-
if (!offset) {
1318-
goto fail;
1319-
}
13201297
#endif
13211298

13221299
net_buf_add(frag, NET_IPV6H_LEN);

tests/net/6lo/src/main.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ static struct net_6lo_data test_data_4 = {
456456
.ipv6.len = { 0x00, 0x00 },
457457
.ipv6.nexthdr = IPPROTO_UDP,
458458
.ipv6.hop_limit = 0xff,
459-
.ipv6.src = src_sac1_sam00,
459+
.ipv6.src = src_sam00,
460460
.ipv6.dst = dst_m1_dam00,
461461
.nh.udp.src_port = htons(udp_src_port_16bit),
462462
.nh.udp.dst_port = htons(udp_dst_port_16bit),
@@ -795,6 +795,25 @@ static struct net_6lo_data test_data_22 = {
795795
.small = true,
796796
.iphc = true
797797
};
798+
799+
static struct net_6lo_data test_data_23 = {
800+
.ipv6.vtc = 0x60,
801+
.ipv6.tcflow = 0x20,
802+
.ipv6.flow = 0x3412,
803+
.ipv6.len = { 0x00, 0x00 },
804+
.ipv6.nexthdr = IPPROTO_UDP,
805+
.ipv6.hop_limit = 0xff,
806+
.ipv6.src = src_sam00,
807+
.ipv6.dst = dst_dac1_dam01,
808+
.nh.udp.src_port = htons(udp_src_port_8bit_y),
809+
.nh.udp.dst_port = htons(udp_dst_port_8bit),
810+
.nh.udp.len = 0x00,
811+
.nh.udp.chksum = 0x00,
812+
.nh_udp = true,
813+
.nh_icmp = false,
814+
.small = false,
815+
.iphc = true
816+
};
798817
#endif
799818

800819
static int test_6lo(struct net_6lo_data *data)
@@ -856,7 +875,7 @@ static const struct {
856875
{ "test_6lo_sam00_dam00", &test_data_1},
857876
{ "test_6lo_sam01_dam01", &test_data_2},
858877
{ "test_6lo_sam10_dam10", &test_data_3},
859-
{ "test_6lo_sac1_sam00_m1_dam00", &test_data_4},
878+
{ "test_6lo_sam00_m1_dam00", &test_data_4},
860879
{ "test_6lo_sam01_m1_dam01", &test_data_5},
861880
{ "test_6lo_sam10_m1_dam10", &test_data_6},
862881
{ "test_6lo_sam10_m1_dam10_no_udp", &test_data_7},
@@ -876,6 +895,7 @@ static const struct {
876895
{ "test_6lo_sac1_sam01_m1_dam01", &test_data_20},
877896
{ "test_6lo_sac1_sam10_m1_dam10", &test_data_21},
878897
{ "test_6lo_sac1_sam11_m1_dam10", &test_data_22},
898+
{ "test_6lo_sac0_sam00_dac1_dam01", &test_data_23},
879899
#endif
880900
};
881901

tests/net/ieee802154/fragment/src/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ static struct net_fragment_data test_data_4 = {
337337
.ipv6.len = { 0x00, 0x00 },
338338
.ipv6.nexthdr = IPPROTO_UDP,
339339
.ipv6.hop_limit = 0xff,
340-
.ipv6.src = src_sac1_sam00,
340+
.ipv6.src = src_sam00,
341341
.ipv6.dst = dst_m1_dam00,
342342
.udp.src_port = htons(udp_src_port_16bit),
343343
.udp.dst_port = htons(udp_dst_port_16bit),
@@ -506,7 +506,7 @@ static const struct {
506506
{ "test_fragment_sam00_dam00", &test_data_1},
507507
{ "test_fragment_sam01_dam01", &test_data_2},
508508
{ "test_fragment_sam10_dam10", &test_data_3},
509-
{ "test_fragment_sac1_sam00_m1_dam00", &test_data_4},
509+
{ "test_fragment_sam00_m1_dam00", &test_data_4},
510510
{ "test_fragment_sam01_m1_dam01", &test_data_5},
511511
{ "test_fragment_sam10_m1_dam10", &test_data_6},
512512
{ "test_fragment_ipv6_dispatch_small", &test_data_7},

0 commit comments

Comments
 (0)