Skip to content

Commit 2f10d7d

Browse files
jukkarkartben
authored andcommitted
net: ethernet: Set the ptype by the caller in send
Instead of setting the upper protocol type in ethernet_send() by checking the protocol type bits, use the ptype that is already set by the caller. This allows new protocol types to be supported and makes the system extensible. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent f6971ae commit 2f10d7d

File tree

9 files changed

+77
-44
lines changed

9 files changed

+77
-44
lines changed

subsys/net/ip/ipv4.c

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_ipv4, CONFIG_NET_IPV4_LOG_LEVEL);
1717
#include <zephyr/net/net_stats.h>
1818
#include <zephyr/net/net_context.h>
1919
#include <zephyr/net/virtual.h>
20+
#include <zephyr/net/ethernet.h>
2021
#include "net_private.h"
2122
#include "connection.h"
2223
#include "net_stats.h"
@@ -133,6 +134,7 @@ int net_ipv4_finalize(struct net_pkt *pkt, uint8_t next_header_proto)
133134
}
134135

135136
net_pkt_set_data(pkt, &ipv4_access);
137+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);
136138

137139
if (IS_ENABLED(CONFIG_NET_UDP) &&
138140
next_header_proto == IPPROTO_UDP) {
@@ -452,6 +454,8 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback)
452454

453455
enum net_verdict net_ipv4_prepare_for_send(struct net_pkt *pkt)
454456
{
457+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);
458+
455459
if (IS_ENABLED(CONFIG_NET_IPV4_PMTU)) {
456460
struct net_pmtu_entry *entry;
457461
struct sockaddr_in dst = {

subsys/net/ip/ipv6.c

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ LOG_MODULE_REGISTER(net_ipv6, CONFIG_NET_IPV6_LOG_LEVEL);
3030
#include <zephyr/net/net_context.h>
3131
#include <zephyr/net/net_mgmt.h>
3232
#include <zephyr/net/virtual.h>
33+
#include <zephyr/net/ethernet.h>
3334
#include "net_private.h"
3435
#include "connection.h"
3536
#include "icmpv6.h"
@@ -142,6 +143,8 @@ int net_ipv6_finalize(struct net_pkt *pkt, uint8_t next_header_proto)
142143
return -ENOBUFS;
143144
}
144145

146+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IPV6);
147+
145148
if (IS_ENABLED(CONFIG_NET_UDP) &&
146149
next_header_proto == IPPROTO_UDP) {
147150
return net_udp_finalize(pkt, false);

subsys/net/ip/ipv6_nbr.c

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(net_ipv6_nd, CONFIG_NET_IPV6_ND_LOG_LEVEL);
2525
#include <zephyr/net/net_mgmt.h>
2626
#include <zephyr/net/dns_resolve.h>
2727
#include <zephyr/net/icmp.h>
28+
#include <zephyr/net/ethernet.h>
2829
#include "net_private.h"
2930
#include "connection.h"
3031
#include "icmpv6.h"
@@ -805,6 +806,8 @@ enum net_verdict net_ipv6_prepare_for_send(struct net_pkt *pkt)
805806
return NET_DROP;
806807
}
807808

809+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IPV6);
810+
808811
#if defined(CONFIG_NET_IPV6_FRAGMENT)
809812
/* If we have already fragmented the packet, the fragment id will
810813
* contain a proper value and we can skip other checks.

subsys/net/ip/net_context.c

+26
Original file line numberDiff line numberDiff line change
@@ -2566,23 +2566,49 @@ static int context_sendto(struct net_context *context,
25662566

25672567
if (net_context_get_proto(context) == IPPROTO_RAW) {
25682568
char type = (NET_IPV6_HDR(pkt)->vtc & 0xf0);
2569+
struct sockaddr_ll *ll_addr;
25692570

25702571
/* Set the family to pkt if detected */
25712572
switch (type) {
25722573
case 0x60:
25732574
net_pkt_set_family(pkt, AF_INET6);
2575+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IPV6);
25742576
break;
25752577
case 0x40:
25762578
net_pkt_set_family(pkt, AF_INET);
2579+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);
25772580
break;
25782581
default:
25792582
/* Not IP traffic, let it go forward as it is */
2583+
ll_addr = (struct sockaddr_ll *)dst_addr;
2584+
2585+
net_pkt_set_ll_proto_type(pkt,
2586+
ntohs(ll_addr->sll_protocol));
25802587
break;
25812588
}
25822589

25832590
/* Pass to L2: */
25842591
ret = net_send_data(pkt);
25852592
} else {
2593+
struct sockaddr_ll_ptr *ll_src_addr;
2594+
struct sockaddr_ll *ll_dst_addr;
2595+
2596+
/* The destination address is set in remote for this
2597+
* socket type.
2598+
*/
2599+
ll_dst_addr = (struct sockaddr_ll *)&context->remote;
2600+
ll_src_addr = (struct sockaddr_ll_ptr *)&context->local;
2601+
2602+
net_pkt_lladdr_dst(pkt)->addr = ll_dst_addr->sll_addr;
2603+
net_pkt_lladdr_dst(pkt)->len =
2604+
sizeof(struct net_eth_addr);
2605+
net_pkt_lladdr_src(pkt)->addr = ll_src_addr->sll_addr;
2606+
net_pkt_lladdr_src(pkt)->len =
2607+
sizeof(struct net_eth_addr);
2608+
2609+
net_pkt_set_ll_proto_type(pkt,
2610+
ntohs(ll_dst_addr->sll_protocol));
2611+
25862612
net_if_queue_tx(net_pkt_iface(pkt), pkt);
25872613
}
25882614
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN &&

subsys/net/l2/ethernet/arp.c

+7
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ static inline struct net_pkt *arp_prepare(struct net_if *iface,
270270
return NULL;
271271
}
272272

273+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
274+
net_pkt_set_family(pkt, AF_INET);
275+
273276
/* Avoid recursive loop with network packet capturing */
274277
if (IS_ENABLED(CONFIG_NET_CAPTURE) && pending) {
275278
net_pkt_set_captured(pkt, net_pkt_is_captured(pending));
@@ -498,6 +501,7 @@ static void arp_gratuitous_send(struct net_if *iface,
498501

499502
net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
500503
net_pkt_set_vlan_tag(pkt, net_eth_get_vlan_tag(iface));
504+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
501505

502506
hdr = NET_ARP_HDR(pkt);
503507

@@ -751,6 +755,9 @@ static inline struct net_pkt *arp_prepare_reply(struct net_if *iface,
751755
net_pkt_lladdr_dst(pkt)->addr = (uint8_t *)&hdr->dst_hwaddr.addr;
752756
net_pkt_lladdr_dst(pkt)->len = sizeof(struct net_eth_addr);
753757

758+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
759+
net_pkt_set_family(pkt, AF_INET);
760+
754761
return pkt;
755762
}
756763

subsys/net/l2/ethernet/ethernet.c

+14-44
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,9 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
674674
{
675675
const struct ethernet_api *api = net_if_get_device(iface)->api;
676676
struct ethernet_context *ctx = net_if_l2_data(iface);
677-
uint16_t ptype = 0;
678-
int ret;
677+
uint16_t ptype = htons(net_pkt_ll_proto_type(pkt));
679678
struct net_pkt *orig_pkt = pkt;
679+
int ret;
680680

681681
if (!api) {
682682
ret = -ENOENT;
@@ -696,65 +696,35 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
696696
goto send;
697697
}
698698

699-
if (IS_ENABLED(CONFIG_NET_IPV4) &&
700-
net_pkt_family(pkt) == AF_INET) {
701-
struct net_pkt *tmp;
699+
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
700+
if (!net_pkt_ipv4_acd(pkt)) {
701+
struct net_pkt *tmp;
702702

703-
if (net_pkt_ipv4_acd(pkt)) {
704-
ptype = htons(NET_ETH_PTYPE_ARP);
705-
} else {
706703
tmp = ethernet_ll_prepare_on_ipv4(iface, pkt);
707-
if (!tmp) {
704+
if (tmp == NULL) {
708705
ret = -ENOMEM;
709706
goto error;
710707
} else if (IS_ENABLED(CONFIG_NET_ARP) && tmp != pkt) {
711708
/* Original pkt got queued and is replaced
712709
* by an ARP request packet.
713710
*/
714711
pkt = tmp;
715-
ptype = htons(NET_ETH_PTYPE_ARP);
716-
net_pkt_set_family(pkt, AF_INET);
717-
} else {
718-
ptype = htons(NET_ETH_PTYPE_IP);
712+
ptype = htons(net_pkt_ll_proto_type(pkt));
719713
}
720714
}
721-
} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
722-
net_pkt_family(pkt) == AF_INET6) {
723-
ptype = htons(NET_ETH_PTYPE_IPV6);
724715
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
725716
net_pkt_family(pkt) == AF_PACKET) {
726717
struct net_context *context = net_pkt_context(pkt);
727718

728-
if (context && net_context_get_type(context) == SOCK_DGRAM) {
729-
struct sockaddr_ll *dst_addr;
730-
struct sockaddr_ll_ptr *src_addr;
731-
732-
/* The destination address is set in remote for this
733-
* socket type.
734-
*/
735-
dst_addr = (struct sockaddr_ll *)&context->remote;
736-
src_addr = (struct sockaddr_ll_ptr *)&context->local;
737-
738-
net_pkt_lladdr_dst(pkt)->addr = dst_addr->sll_addr;
739-
net_pkt_lladdr_dst(pkt)->len =
740-
sizeof(struct net_eth_addr);
741-
net_pkt_lladdr_src(pkt)->addr = src_addr->sll_addr;
742-
net_pkt_lladdr_src(pkt)->len =
743-
sizeof(struct net_eth_addr);
744-
ptype = dst_addr->sll_protocol;
745-
} else {
719+
if (!(context && net_context_get_type(context) == SOCK_DGRAM)) {
720+
/* Raw packet, just send it */
746721
goto send;
747722
}
748-
} else if (IS_ENABLED(CONFIG_NET_L2_PTP) && net_pkt_is_ptp(pkt)) {
749-
ptype = htons(NET_ETH_PTYPE_PTP);
750-
} else if (IS_ENABLED(CONFIG_NET_LLDP) && net_pkt_is_lldp(pkt)) {
751-
ptype = htons(NET_ETH_PTYPE_LLDP);
752-
} else if (IS_ENABLED(CONFIG_NET_ARP)) {
753-
/* Unknown type: Unqueued pkt is an ARP reply.
754-
*/
755-
ptype = htons(NET_ETH_PTYPE_ARP);
756-
net_pkt_set_family(pkt, AF_INET);
757-
} else {
723+
}
724+
725+
if (ptype == 0) {
726+
/* Caller of this function has not set the ptype */
727+
NET_ERR("No protocol set for pkt %p", pkt);
758728
ret = -ENOTSUP;
759729
goto error;
760730
}

subsys/net/l2/ethernet/gptp/gptp_messages.c

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ static struct net_pkt *setup_gptp_frame(struct net_if *iface,
170170

171171
net_buf_add(pkt->buffer, sizeof(struct gptp_hdr) + extra_header);
172172
net_pkt_set_ptp(pkt, true);
173+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_PTP);
173174

174175
net_pkt_lladdr_src(pkt)->addr = net_if_get_link_addr(iface)->addr;
175176
net_pkt_lladdr_src(pkt)->len = net_if_get_link_addr(iface)->len;

subsys/net/l2/ethernet/lldp/lldp.c

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static int lldp_send(struct ethernet_lldp *lldp)
114114
}
115115

116116
net_pkt_set_lldp(pkt, true);
117+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_LLDP);
117118

118119
ret = net_pkt_write(pkt, (uint8_t *)lldp->lldpdu,
119120
sizeof(struct net_lldpdu));

tests/net/arp/src/main.c

+18
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ static inline struct net_pkt *prepare_arp_reply(struct net_if *iface,
215215

216216
net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
217217

218+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
219+
218220
return pkt;
219221
}
220222

@@ -265,6 +267,8 @@ static inline struct net_pkt *prepare_arp_request(struct net_if *iface,
265267

266268
net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
267269

270+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
271+
268272
return pkt;
269273
}
270274

@@ -373,6 +377,8 @@ ZTEST(arp_fn_tests, test_arp)
373377
net_ipv4_addr_copy_raw(ipv4->src, (uint8_t *)&src);
374378
net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);
375379

380+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);
381+
376382
memcpy(net_buf_add(pkt->buffer, len), app_data, len);
377383

378384
pkt2 = net_arp_prepare(pkt, &dst, NULL);
@@ -381,6 +387,9 @@ ZTEST(arp_fn_tests, test_arp)
381387
* stored in ARP table.
382388
*/
383389

390+
zassert_equal(net_pkt_ll_proto_type(pkt2), NET_ETH_PTYPE_ARP,
391+
"ARP packet type is wrong");
392+
384393
/**TESTPOINTS: Check packets*/
385394
zassert_not_equal((void *)(pkt2), (void *)(pkt),
386395
/* The packets cannot be the same as the ARP cache has
@@ -530,6 +539,8 @@ ZTEST(arp_fn_tests, test_arp)
530539
net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
531540
net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&src);
532541

542+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
543+
533544
pkt2 = prepare_arp_reply(iface, pkt, &eth_hwaddr, &eth_hdr);
534545

535546
zassert_not_null(pkt2, "ARP reply generation failed.");
@@ -554,6 +565,9 @@ ZTEST(arp_fn_tests, test_arp)
554565

555566
net_pkt_unref(pkt);
556567

568+
/* Clear the ARP cache so that old entries do not confuse the tests */
569+
net_arp_clear_cache(iface);
570+
557571
/* Then feed in ARP request */
558572
pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
559573
sizeof(struct net_arp_hdr),
@@ -571,6 +585,8 @@ ZTEST(arp_fn_tests, test_arp)
571585
net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&src);
572586
net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);
573587

588+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
589+
574590
pkt2 = prepare_arp_request(iface, pkt, &eth_hwaddr, &eth_hdr);
575591

576592
/**TESTPOINT: Check if ARP request generation failed*/
@@ -633,6 +649,8 @@ ZTEST(arp_fn_tests, test_arp)
633649

634650
net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
635651

652+
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
653+
636654
verdict = net_arp_input(pkt, eth_hdr);
637655
zassert_not_equal(verdict, NET_DROP, "Gratuitous ARP failed");
638656

0 commit comments

Comments
 (0)