static struct net_pkt *prepare_vlan_pkt(struct eth_context *ctx, int count, u16_t *vlan_tag, int *status) { struct net_eth_vlan_hdr *hdr = (struct net_eth_vlan_hdr *)ctx->recv; struct net_pkt *pkt; u8_t pos; if (IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP)) { count -= NET_ETH_VLAN_HDR_SIZE; } pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, count, AF_UNSPEC, 0, NET_BUF_TIMEOUT); if (!pkt) { *status = -ENOMEM; return NULL; } net_pkt_set_vlan_tci(pkt, ntohs(hdr->vlan.tci)); *vlan_tag = net_pkt_vlan_tag(pkt); pos = 0; if (IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP)) { if (net_pkt_write(pkt, ctx->recv, 2 * sizeof(struct net_eth_addr))) { goto error; } pos = (2 * sizeof(struct net_eth_addr)) + NET_ETH_VLAN_HDR_SIZE; count -= (2 * sizeof(struct net_eth_addr)); } if (net_pkt_write(pkt, ctx->recv + pos, count)) { goto error; } #if CONFIG_NET_TC_RX_COUNT > 1 { enum net_priority prio; prio = net_vlan2priority(net_pkt_vlan_priority(pkt)); net_pkt_set_priority(pkt, prio); } #endif *status = 0; LOG_DBG("Recv pkt %p len %d", pkt, count); return pkt; error: net_pkt_unref(pkt); *status = -ENOBUFS; return NULL; }
static struct net_pkt *prepare_non_vlan_pkt(struct eth_context *ctx, int count, int *status) { struct net_pkt *pkt; pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, count, AF_UNSPEC, 0, NET_BUF_TIMEOUT); if (!pkt) { *status = -ENOMEM; return NULL; } if (net_pkt_write(pkt, ctx->recv, count)) { net_pkt_unref(pkt); *status = -ENOBUFS; return NULL; } *status = 0; LOG_DBG("Recv pkt %p len %d", pkt, count); return pkt; }
static void test_pkt_read_write_insert(void) { struct net_buf *read_frag; struct net_buf *temp_frag; struct net_pkt *pkt; struct net_buf *frag; u8_t read_data[100]; u16_t read_pos; u16_t len; u16_t pos; /* Example of multi fragment read, append and skip APS's */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); /* 1) Offset is with in input fragment. * Write app data after IPv6 and UDP header. (If the offset is after * IPv6 + UDP header size, api will create empty space till offset * and write data). */ frag = net_pkt_write(pkt, frag, NET_IPV6UDPH_LEN, &pos, 10, (u8_t *)sample_data, K_FOREVER); zassert_false(!frag || pos != 58, "Usecase 1: Write failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 1: Read failed"); zassert_false(memcmp(read_data, sample_data, 10), "Usecase 1: Read data mismatch"); /* 2) Write IPv6 and UDP header at offset 0. (Empty space is created * already in Usecase 1, just need to fill the header, at this point * there shouldn't be any length change). */ frag = net_pkt_write(pkt, frag, 0, &pos, NET_IPV6UDPH_LEN, (u8_t *)sample_data, K_FOREVER); zassert_false(!frag || pos != 48, "Usecase 2: Write failed"); read_frag = net_frag_read(frag, 0, &read_pos, NET_IPV6UDPH_LEN, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 2: Read failed"); zassert_false(memcmp(read_data, sample_data, NET_IPV6UDPH_LEN), "Usecase 2: Read data mismatch"); net_pkt_unref(pkt); pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* 3) Offset is in next to next fragment. * Write app data after 2 fragments. (If the offset far away, api will * create empty fragments(space) till offset and write data). */ frag = net_pkt_write(pkt, pkt->frags, 200, &pos, 10, (u8_t *)sample_data + 10, K_FOREVER); zassert_not_null(frag, "Usecase 3: Write failed"); read_frag = net_frag_read(frag, pos - 10, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 3: Read failed"); zassert_false(memcmp(read_data, sample_data + 10, 10), "Usecase 3: Read data mismatch"); /* 4) Offset is in next to next fragment (overwrite). * Write app data after 2 fragments. (Space is already available from * Usecase 3, this scenatio doesn't create any space, it just overwrites * the existing data. */ frag = net_pkt_write(pkt, pkt->frags, 190, &pos, 10, (u8_t *)sample_data, K_FOREVER); zassert_not_null(frag, "Usecase 4: Write failed"); read_frag = net_frag_read(frag, pos - 10, &read_pos, 20, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 4: Read failed"); zassert_false(memcmp(read_data, sample_data, 20), "Usecase 4: Read data mismatch"); net_pkt_unref(pkt); /* 5) Write 20 bytes in fragment which has only 10 bytes space. * API should overwrite on first 10 bytes and create extra 10 bytes * and write there. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); /* Create 10 bytes space. */ net_buf_add(frag, 10); frag = net_pkt_write(pkt, frag, 0, &pos, 20, (u8_t *)sample_data, K_FOREVER); zassert_false(!frag && pos != 20, "Usecase 5: Write failed"); read_frag = net_frag_read(frag, 0, &read_pos, 20, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 5: Read failed"); zassert_false(memcmp(read_data, sample_data, 20), "USecase 5: Read data mismatch"); net_pkt_unref(pkt); /* 6) First fragment is full, second fragment has 10 bytes tail room, * third fragment has 5 bytes. * Write data (30 bytes) in second fragment where offset is 10 bytes * before the tailroom. * So it should overwrite 10 bytes and create space for another 10 * bytes and write data. Third fragment 5 bytes overwritten and space * for 5 bytes created. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* First fragment make it fully occupied. */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); len = net_buf_tailroom(frag); net_buf_add(frag, len); /* 2nd fragment last 10 bytes tailroom, rest occupied */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); len = net_buf_tailroom(frag); net_buf_add(frag, len - 10); read_frag = temp_frag = frag; read_pos = frag->len - 10; /* 3rd fragment, only 5 bytes occupied */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); net_buf_add(frag, 5); temp_frag = net_pkt_write(pkt, temp_frag, temp_frag->len - 10, &pos, 30, (u8_t *) sample_data, K_FOREVER); zassert_not_null(temp_frag, "Use case 6: Write failed"); read_frag = net_frag_read(read_frag, read_pos, &read_pos, 30, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 6: Read failed"); zassert_false(memcmp(read_data, sample_data, 30), "Usecase 6: Read data mismatch"); net_pkt_unref(pkt); /* 7) Offset is with in input fragment. * Write app data after IPv6 and UDP header. (If the offset is after * IPv6 + UDP header size, api will create empty space till offset * and write data). Insert some app data after IPv6 + UDP header * before first set of app data. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* First fragment make it fully occupied. */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); frag = net_pkt_write(pkt, frag, NET_IPV6UDPH_LEN, &pos, 10, (u8_t *)sample_data + 10, K_FOREVER); zassert_false(!frag || pos != 58, "Usecase 7: Write failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 7: Read failed"); zassert_false(memcmp(read_data, sample_data + 10, 10), "Usecase 7: Read data mismatch"); zassert_true(net_pkt_insert(pkt, frag, NET_IPV6UDPH_LEN, 10, (u8_t *)sample_data, K_FOREVER), "Usecase 7: Insert failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 20, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 7: Read after failed"); zassert_false(memcmp(read_data, sample_data, 20), "Usecase 7: Read data mismatch after insertion"); /* Insert data outside input fragment length, error case. */ zassert_false(net_pkt_insert(pkt, frag, 70, 10, (u8_t *)sample_data, K_FOREVER), "Usecase 7: False insert failed"); net_pkt_unref(pkt); /* 8) Offset is with in input fragment. * Write app data after IPv6 and UDP header. (If the offset is after * IPv6 + UDP header size, api will create empty space till offset * and write data). Insert some app data after IPv6 + UDP header * before first set of app data. Insertion data is long which will * take two fragments. */ pkt = net_pkt_get_reserve_rx(0, K_FOREVER); net_pkt_set_ll_reserve(pkt, LL_RESERVE); /* First fragment make it fully occupied. */ frag = net_pkt_get_reserve_rx_data(net_pkt_ll_reserve(pkt), K_FOREVER); net_pkt_frag_add(pkt, frag); frag = net_pkt_write(pkt, frag, NET_IPV6UDPH_LEN, &pos, 10, (u8_t *)sample_data + 60, K_FOREVER); zassert_false(!frag || pos != 58, "Usecase 8: Write failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 10, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 8: Read failed"); zassert_false(memcmp(read_data, sample_data + 60, 10), "Usecase 8: Read data mismatch"); zassert_true(net_pkt_insert(pkt, frag, NET_IPV6UDPH_LEN, 60, (u8_t *)sample_data, K_FOREVER), "Usecase 8: Insert failed"); read_frag = net_frag_read(frag, NET_IPV6UDPH_LEN, &read_pos, 70, read_data); zassert_false(!read_frag && read_pos == 0xffff, "Usecase 8: Read after failed"); zassert_false(memcmp(read_data, sample_data, 70), "Usecase 8: Read data mismatch after insertion"); net_pkt_unref(pkt); DBG("test_pkt_read_write_insert passed\n"); }