diff --git a/include/net/arp.h b/include/net/arp.h index 4f8bfd3b80f..17367176440 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -27,10 +27,9 @@ #include -#define NET_ARP_BUF(buf) ((struct net_arp_hdr *)net_nbuf_ll(buf)) +#define NET_ARP_BUF(buf) ((struct net_arp_hdr *)net_nbuf_ip_data(buf)) struct net_arp_hdr { - struct net_eth_hdr eth_hdr; uint16_t hwtype; /* HTYPE */ uint16_t protocol; /* PTYPE */ uint8_t hwlen; /* HLEN */ diff --git a/net/yaip/l2/arp.c b/net/yaip/l2/arp.c index 95f4a60cee7..b65ffd821d6 100644 --- a/net/yaip/l2/arp.c +++ b/net/yaip/l2/arp.c @@ -113,6 +113,7 @@ static inline struct net_buf *prepare_arp(struct net_if *iface, { struct net_buf *buf, *frag; struct net_arp_hdr *hdr; + struct net_eth_hdr *eth; struct in_addr *my_addr; buf = net_nbuf_get_reserve_tx(0); @@ -131,6 +132,7 @@ static inline struct net_buf *prepare_arp(struct net_if *iface, net_nbuf_ll_reserve(buf) = sizeof(struct net_eth_hdr); hdr = NET_ARP_BUF(buf); + eth = NET_ETH_BUF(buf); /* If entry is not set, then we are just about to send * an ARP request using the data in pending net_buf. @@ -143,17 +145,17 @@ static inline struct net_buf *prepare_arp(struct net_if *iface, net_ipaddr_copy(&entry->ip, &NET_IPV4_BUF(pending)->dst); - memcpy(&hdr->eth_hdr.src.addr, + memcpy(ð->src.addr, net_if_get_link_addr(entry->iface)->addr, sizeof(struct net_eth_addr)); } else { - memcpy(&hdr->eth_hdr.src.addr, + memcpy(ð->src.addr, net_if_get_link_addr(iface)->addr, sizeof(struct net_eth_addr)); } - hdr->eth_hdr.type = htons(NET_ETH_PTYPE_ARP); - memset(&hdr->eth_hdr.dst.addr, 0xff, sizeof(struct net_eth_addr)); + eth->type = htons(NET_ETH_PTYPE_ARP); + memset(ð->dst.addr, 0xff, sizeof(struct net_eth_addr)); hdr->hwtype = htons(NET_ARP_HTYPE_ETH); hdr->protocol = htons(NET_ETH_PTYPE_IP); @@ -170,7 +172,7 @@ static inline struct net_buf *prepare_arp(struct net_if *iface, net_ipaddr_copy(&hdr->dst_ipaddr, &NET_IPV4_BUF(pending)->dst); } - memcpy(hdr->src_hwaddr.addr, hdr->eth_hdr.src.addr, + memcpy(hdr->src_hwaddr.addr, eth->src.addr, sizeof(struct net_eth_addr)); if (entry) { @@ -185,8 +187,7 @@ static inline struct net_buf *prepare_arp(struct net_if *iface, memset(&hdr->src_ipaddr, 0, sizeof(struct in_addr)); } - net_buf_add(frag, - sizeof(struct net_arp_hdr) - sizeof(struct net_eth_hdr)); + net_buf_add(frag, sizeof(struct net_arp_hdr)); return buf; @@ -311,8 +312,9 @@ static inline void send_pending(struct net_if *iface, struct net_buf **buf) { struct net_buf *pending = *buf; - NET_DBG("dst %s pending %p", - net_sprint_ipv4_addr(&NET_IPV4_BUF(pending)->dst), pending); + NET_DBG("dst %s pending %p frag %p", + net_sprint_ipv4_addr(&NET_IPV4_BUF(pending)->dst), pending, + pending->frags); *buf = NULL; @@ -355,6 +357,13 @@ static inline void arp_update(struct net_if *iface, memcpy(&arp_table[i].eth, hwaddr, sizeof(struct net_eth_addr)); + /* Set the dst in the pending packet */ + net_nbuf_ll_dst(arp_table[i].pending)->len = + sizeof(struct net_eth_addr); + net_nbuf_ll_dst(arp_table[i].pending)->addr = + (uint8_t *) + &NET_ETH_BUF(arp_table[i].pending)->dst.addr; + send_pending(iface, &arp_table[i].pending); } @@ -368,6 +377,7 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, { struct net_buf *buf, *frag; struct net_arp_hdr *hdr, *query; + struct net_eth_hdr *eth, *eth_query; buf = net_nbuf_get_reserve_tx(0); if (!buf) { @@ -385,13 +395,15 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, net_nbuf_ll_reserve(buf) = sizeof(struct net_eth_hdr); hdr = NET_ARP_BUF(buf); + eth = NET_ETH_BUF(buf); query = NET_ARP_BUF(req); + eth_query = NET_ETH_BUF(req); - hdr->eth_hdr.type = htons(NET_ETH_PTYPE_ARP); + eth->type = htons(NET_ETH_PTYPE_ARP); - memcpy(&hdr->eth_hdr.dst.addr, &query->eth_hdr.src.addr, + memcpy(ð->dst.addr, ð_query->src.addr, sizeof(struct net_eth_addr)); - memcpy(&hdr->eth_hdr.src.addr, net_if_get_link_addr(iface)->addr, + memcpy(ð->src.addr, net_if_get_link_addr(iface)->addr, sizeof(struct net_eth_addr)); hdr->hwtype = htons(NET_ARP_HTYPE_ETH); @@ -400,19 +412,15 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, hdr->protolen = sizeof(struct in_addr); hdr->opcode = htons(NET_ARP_REPLY); - memcpy(&hdr->dst_hwaddr.addr, &query->eth_hdr.src.addr, + memcpy(&hdr->dst_hwaddr.addr, ð_query->src.addr, sizeof(struct net_eth_addr)); - memcpy(&hdr->src_hwaddr.addr, &hdr->eth_hdr.src.addr, + memcpy(&hdr->src_hwaddr.addr, ð->src.addr, sizeof(struct net_eth_addr)); net_ipaddr_copy(&hdr->dst_ipaddr, &query->src_ipaddr); net_ipaddr_copy(&hdr->src_ipaddr, &query->dst_ipaddr); - /* The ethernet header is already added to fragment length (because - * of the reserve) so we must not add it again. - */ - net_buf_add(frag, - sizeof(struct net_arp_hdr) - sizeof(struct net_eth_hdr)); + net_buf_add(frag, sizeof(struct net_arp_hdr)); return buf; diff --git a/tests/net/arp/prj_x86.conf b/tests/net/arp/prj_x86.conf index 91879951557..e42150cd6dd 100644 --- a/tests/net/arp/prj_x86.conf +++ b/tests/net/arp/prj_x86.conf @@ -5,13 +5,15 @@ CONFIG_NET_IPV4=y CONFIG_NET_YAIP=y CONFIG_NET_BUF=y CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_NET_NBUF_RX_COUNT=3 -CONFIG_NET_NBUF_TX_COUNT=4 -CONFIG_NET_NBUF_DATA_COUNT=7 +CONFIG_NET_NBUF_RX_COUNT=5 +CONFIG_NET_NBUF_TX_COUNT=5 +CONFIG_NET_NBUF_DATA_COUNT=10 CONFIG_NET_LOG=y CONFIG_SYS_LOG_SHOW_COLOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT=3 CONFIG_NETWORK_IP_STACK_DEBUG_IPV4_ARP=y +CONFIG_NETWORK_IP_STACK_DEBUG_NET_BUF=y CONFIG_NETWORK_IP_STACK_DEBUG_IF=y CONFIG_NETWORK_IP_STACK_DEBUG_CORE=y +CONFIG_NETWORK_IP_STACK_DEBUG_L2=y diff --git a/tests/net/arp/src/main.c b/tests/net/arp/src/main.c index 076a327ce9c..c178b1e2ebb 100644 --- a/tests/net/arp/src/main.c +++ b/tests/net/arp/src/main.c @@ -48,8 +48,6 @@ static bool req_test; static char *app_data = "0123456789"; -static const struct net_eth_addr broadcast_eth_addr = { - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; static const struct net_eth_addr multicast_eth_addr = { { 0x01, 0x00, 0x5e, 0x01, 0x02, 0x03 } }; @@ -98,14 +96,12 @@ static struct net_eth_addr hwaddr = { { 0x42, 0x11, 0x69, 0xde, 0xfa, 0xec } }; static int send_status = -EINVAL; -#define NET_ARP_BUF(buf) ((struct net_arp_hdr *)net_nbuf_ll(buf)) - static int tester_send(struct net_if *iface, struct net_buf *buf) { struct net_eth_hdr *hdr; if (!buf->frags) { - printk("No data to send!"); + printk("No data to send!\n"); return -ENODATA; } @@ -119,8 +115,7 @@ static int tester_send(struct net_if *iface, struct net_buf *buf) hdr = (struct net_eth_hdr *)net_nbuf_ll(buf); if (ntohs(hdr->type) == NET_ETH_PTYPE_ARP) { - struct net_arp_hdr *arp_hdr = - (struct net_arp_hdr *)net_nbuf_ll(buf); + struct net_arp_hdr *arp_hdr = NET_ARP_BUF(buf); if (ntohs(arp_hdr->opcode) == NET_ARP_REPLY) { if (!req_test && buf != pending_buf) { @@ -195,6 +190,7 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, { struct net_buf *buf, *frag; struct net_arp_hdr *hdr; + struct net_eth_hdr *eth; buf = net_nbuf_get_reserve_tx(0); if (!buf) { @@ -210,12 +206,13 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, net_nbuf_iface(buf) = iface; net_nbuf_ll_reserve(buf) = net_buf_headroom(frag); - hdr = (struct net_arp_hdr *)net_nbuf_ll(buf); + hdr = NET_ARP_BUF(buf); + eth = NET_ETH_BUF(buf); - hdr->eth_hdr.type = htons(NET_ETH_PTYPE_ARP); + eth->type = htons(NET_ETH_PTYPE_ARP); - memset(&hdr->eth_hdr.dst.addr, 0xff, sizeof(struct net_eth_addr)); - memcpy(&hdr->eth_hdr.src.addr, net_if_get_link_addr(iface)->addr, + memset(ð->dst.addr, 0xff, sizeof(struct net_eth_addr)); + memcpy(ð->src.addr, net_if_get_link_addr(iface)->addr, sizeof(struct net_eth_addr)); hdr->hwtype = htons(NET_ARP_HTYPE_ETH); @@ -224,7 +221,7 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, hdr->protolen = sizeof(struct in_addr); hdr->opcode = htons(NET_ARP_REPLY); - memcpy(&hdr->dst_hwaddr.addr, &hdr->eth_hdr.src.addr, + memcpy(&hdr->dst_hwaddr.addr, ð->src.addr, sizeof(struct net_eth_addr)); memcpy(&hdr->src_hwaddr.addr, addr, sizeof(struct net_eth_addr)); @@ -232,7 +229,7 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, net_ipaddr_copy(&hdr->dst_ipaddr, &NET_ARP_BUF(req)->src_ipaddr); net_ipaddr_copy(&hdr->src_ipaddr, &NET_ARP_BUF(req)->dst_ipaddr); - net_buf_add(frag, sizeof(struct net_arp_hdr) - net_buf_headroom(frag)); + net_buf_add(frag, sizeof(struct net_arp_hdr)); return buf; @@ -247,6 +244,7 @@ static inline struct net_buf *prepare_arp_request(struct net_if *iface, { struct net_buf *buf, *frag; struct net_arp_hdr *hdr, *req_hdr; + struct net_eth_hdr *eth, *eth_req; buf = net_nbuf_get_reserve_rx(0); if (!buf) { @@ -262,13 +260,15 @@ static inline struct net_buf *prepare_arp_request(struct net_if *iface, net_nbuf_iface(buf) = iface; net_nbuf_ll_reserve(buf) = sizeof(struct net_eth_hdr); - hdr = (struct net_arp_hdr *)net_nbuf_ll(buf); - req_hdr = (struct net_arp_hdr *)net_nbuf_ll(req); + hdr = NET_ARP_BUF(buf); + eth = NET_ETH_BUF(buf); + req_hdr = NET_ARP_BUF(req); + eth_req = NET_ETH_BUF(req); - hdr->eth_hdr.type = htons(NET_ETH_PTYPE_ARP); + eth->type = htons(NET_ETH_PTYPE_ARP); - memset(&hdr->eth_hdr.dst.addr, 0xff, sizeof(struct net_eth_addr)); - memcpy(&hdr->eth_hdr.src.addr, addr, sizeof(struct net_eth_addr)); + memset(ð->dst.addr, 0xff, sizeof(struct net_eth_addr)); + memcpy(ð->src.addr, addr, sizeof(struct net_eth_addr)); hdr->hwtype = htons(NET_ARP_HTYPE_ETH); hdr->protocol = htons(NET_ETH_PTYPE_IP); @@ -282,7 +282,7 @@ static inline struct net_buf *prepare_arp_request(struct net_if *iface, net_ipaddr_copy(&hdr->src_ipaddr, &req_hdr->src_ipaddr); net_ipaddr_copy(&hdr->dst_ipaddr, &req_hdr->dst_ipaddr); - net_buf_add(frag, sizeof(struct net_arp_hdr) - net_buf_headroom(frag)); + net_buf_add(frag, sizeof(struct net_arp_hdr)); return buf; @@ -383,15 +383,15 @@ void main(void) eth_hdr = (struct net_eth_hdr *)net_nbuf_ll(buf); - if (memcmp(ð_hdr->dst.addr, &broadcast_eth_addr, + if (memcmp(ð_hdr->dst.addr, net_eth_broadcast_addr(), sizeof(struct net_eth_addr))) { char out[sizeof("xx:xx:xx:xx:xx:xx")]; snprintf(out, sizeof(out), net_sprint_ll_addr((uint8_t *)ð_hdr->dst.addr, sizeof(struct net_eth_addr))); printk("ETH addr dest invalid %s, should be %s", out, - net_sprint_ll_addr((uint8_t *)&broadcast_eth_addr, - sizeof(broadcast_eth_addr))); + net_sprint_ll_addr((uint8_t *)net_eth_broadcast_addr(), + sizeof(struct net_eth_addr))); return; } @@ -412,7 +412,7 @@ void main(void) sizeof(struct net_eth_addr))); printk("ETH maddr dest invalid %s, should be %s", out, net_sprint_ll_addr((uint8_t *)&multicast_eth_addr, - sizeof(broadcast_eth_addr))); + sizeof(struct net_eth_addr))); return; } @@ -489,12 +489,13 @@ void main(void) pending_buf = buf; /* buf2 should contain the arp header, verify it */ - if (memcmp(net_nbuf_ll(buf2), &broadcast_eth_addr, + if (memcmp(net_nbuf_ll(buf2), net_eth_broadcast_addr(), sizeof(struct net_eth_addr))) { printk("ARP ETH dest address invalid\n"); - net_hexdump("ETH dest correct", net_nbuf_ll(buf2), + net_hexdump("ETH dest wrong ", net_nbuf_ll(buf2), sizeof(struct net_eth_addr)); - net_hexdump("ETH dest wrong ", (uint8_t *)&broadcast_eth_addr, + net_hexdump("ETH dest correct", + (uint8_t *)net_eth_broadcast_addr(), sizeof(struct net_eth_addr)); return; } @@ -512,11 +513,12 @@ void main(void) return; } - arp_hdr = (struct net_arp_hdr *)net_nbuf_ll(buf2); + arp_hdr = NET_ARP_BUF(buf2); + eth_hdr = NET_ETH_BUF(buf2); - if (arp_hdr->eth_hdr.type != htons(NET_ETH_PTYPE_ARP)) { + if (eth_hdr->type != htons(NET_ETH_PTYPE_ARP)) { printk("ETH type 0x%x, should be 0x%x\n", - arp_hdr->eth_hdr.type, htons(NET_ETH_PTYPE_ARP)); + eth_hdr->type, htons(NET_ETH_PTYPE_ARP)); return; } @@ -570,6 +572,11 @@ void main(void) return; } + /* We could have send the new ARP request but for this test we + * just free it. + */ + net_nbuf_unref(buf2); + if (buf->ref != 2) { printk("ARP cache should own the original buffer\n"); return; @@ -590,7 +597,7 @@ void main(void) return; } - arp_hdr = (struct net_arp_hdr *)net_nbuf_ll(buf2); + arp_hdr = NET_ARP_BUF(buf2); if (!net_ipv4_addr_cmp(&arp_hdr->dst_ipaddr, &iface->ipv4.gw)) { char out[sizeof("xxx.xxx.xxx.xxx")]; @@ -614,11 +621,13 @@ void main(void) net_buf_ref(buf); buf2 = net_arp_prepare(buf); - if (buf2) { - printk("ARP cache should fail now\n"); + if (!buf2) { + printk("ARP cache is not sending the request again\n"); return; } + net_nbuf_unref(buf2); + /* Try to find the different destination, this should fail too * as the cache table should be full. */ @@ -630,8 +639,8 @@ void main(void) net_buf_ref(buf); buf2 = net_arp_prepare(buf); - if (buf2) { - printk("ARP cache should fail again\n"); + if (!buf2) { + printk("ARP cache did not send a req\n"); return; } @@ -648,20 +657,22 @@ void main(void) printk("Out of mem RX reply\n"); return; } + printk("%d buf %p\n", __LINE__, buf); frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr)); if (!frag) { printk("Out of mem DATA reply\n"); return; } + printk("%d frag %p\n", __LINE__, frag); net_buf_frag_add(buf, frag); net_nbuf_ll_reserve(buf) = net_buf_headroom(frag); net_nbuf_iface(buf) = iface; - arp_hdr = (struct net_arp_hdr *)net_nbuf_ll(buf); - net_buf_add(buf, sizeof(struct net_arp_hdr)); + arp_hdr = NET_ARP_BUF(buf); + net_buf_add(frag, sizeof(struct net_arp_hdr)); net_ipaddr_copy(&arp_hdr->dst_ipaddr, &dst); net_ipaddr_copy(&arp_hdr->src_ipaddr, &src); @@ -672,6 +683,7 @@ void main(void) return; } + /* The pending packet should now be sent */ switch (net_arp_input(buf2)) { case NET_OK: case NET_CONTINUE: @@ -714,9 +726,8 @@ void main(void) net_nbuf_iface(buf) = iface; send_status = -EINVAL; - arp_hdr = (struct net_arp_hdr *)net_nbuf_ll(buf); - net_buf_add(frag, sizeof(struct net_arp_hdr) - - net_nbuf_ll_reserve(buf)); + arp_hdr = NET_ARP_BUF(buf); + net_buf_add(frag, sizeof(struct net_arp_hdr)); net_ipaddr_copy(&arp_hdr->dst_ipaddr, &src); net_ipaddr_copy(&arp_hdr->src_ipaddr, &dst);