Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions subsys/net/ip/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_ipv4, CONFIG_NET_IPV4_LOG_LEVEL);
#include <zephyr/net/net_stats.h>
#include <zephyr/net/net_context.h>
#include <zephyr/net/virtual.h>
#include <zephyr/net/ethernet.h>
#include "net_private.h"
#include "connection.h"
#include "net_stats.h"
Expand Down Expand Up @@ -133,6 +134,7 @@ int net_ipv4_finalize(struct net_pkt *pkt, uint8_t next_header_proto)
}

net_pkt_set_data(pkt, &ipv4_access);
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);

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

enum net_verdict net_ipv4_prepare_for_send(struct net_pkt *pkt)
{
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);

if (IS_ENABLED(CONFIG_NET_IPV4_PMTU)) {
struct net_pmtu_entry *entry;
struct sockaddr_in dst = {
Expand Down
3 changes: 3 additions & 0 deletions subsys/net/ip/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ LOG_MODULE_REGISTER(net_ipv6, CONFIG_NET_IPV6_LOG_LEVEL);
#include <zephyr/net/net_context.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/virtual.h>
#include <zephyr/net/ethernet.h>
#include "net_private.h"
#include "connection.h"
#include "icmpv6.h"
Expand Down Expand Up @@ -142,6 +143,8 @@ int net_ipv6_finalize(struct net_pkt *pkt, uint8_t next_header_proto)
return -ENOBUFS;
}

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IPV6);

if (IS_ENABLED(CONFIG_NET_UDP) &&
next_header_proto == IPPROTO_UDP) {
return net_udp_finalize(pkt, false);
Expand Down
3 changes: 3 additions & 0 deletions subsys/net/ip/ipv6_nbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(net_ipv6_nd, CONFIG_NET_IPV6_ND_LOG_LEVEL);
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/dns_resolve.h>
#include <zephyr/net/icmp.h>
#include <zephyr/net/ethernet.h>
#include "net_private.h"
#include "connection.h"
#include "icmpv6.h"
Expand Down Expand Up @@ -805,6 +806,8 @@ enum net_verdict net_ipv6_prepare_for_send(struct net_pkt *pkt)
return NET_DROP;
}

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IPV6);

#if defined(CONFIG_NET_IPV6_FRAGMENT)
/* If we have already fragmented the packet, the fragment id will
* contain a proper value and we can skip other checks.
Expand Down
26 changes: 26 additions & 0 deletions subsys/net/ip/net_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -2566,23 +2566,49 @@ static int context_sendto(struct net_context *context,

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

/* Set the family to pkt if detected */
switch (type) {
case 0x60:
net_pkt_set_family(pkt, AF_INET6);
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IPV6);
break;
case 0x40:
net_pkt_set_family(pkt, AF_INET);
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);
break;
default:
/* Not IP traffic, let it go forward as it is */
ll_addr = (struct sockaddr_ll *)dst_addr;

net_pkt_set_ll_proto_type(pkt,
ntohs(ll_addr->sll_protocol));
break;
}

/* Pass to L2: */
ret = net_send_data(pkt);
} else {
struct sockaddr_ll_ptr *ll_src_addr;
struct sockaddr_ll *ll_dst_addr;

/* The destination address is set in remote for this
* socket type.
*/
ll_dst_addr = (struct sockaddr_ll *)&context->remote;
ll_src_addr = (struct sockaddr_ll_ptr *)&context->local;

net_pkt_lladdr_dst(pkt)->addr = ll_dst_addr->sll_addr;
net_pkt_lladdr_dst(pkt)->len =
sizeof(struct net_eth_addr);
net_pkt_lladdr_src(pkt)->addr = ll_src_addr->sll_addr;
net_pkt_lladdr_src(pkt)->len =
sizeof(struct net_eth_addr);

net_pkt_set_ll_proto_type(pkt,
ntohs(ll_dst_addr->sll_protocol));

net_if_queue_tx(net_pkt_iface(pkt), pkt);
}
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN &&
Expand Down
7 changes: 7 additions & 0 deletions subsys/net/l2/ethernet/arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ static inline struct net_pkt *arp_prepare(struct net_if *iface,
return NULL;
}

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
net_pkt_set_family(pkt, AF_INET);

/* Avoid recursive loop with network packet capturing */
if (IS_ENABLED(CONFIG_NET_CAPTURE) && pending) {
net_pkt_set_captured(pkt, net_pkt_is_captured(pending));
Expand Down Expand Up @@ -498,6 +501,7 @@ static void arp_gratuitous_send(struct net_if *iface,

net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));
net_pkt_set_vlan_tag(pkt, net_eth_get_vlan_tag(iface));
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);

hdr = NET_ARP_HDR(pkt);

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

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
net_pkt_set_family(pkt, AF_INET);

return pkt;
}

Expand Down
59 changes: 15 additions & 44 deletions subsys/net/l2/ethernet/ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,9 +681,9 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
{
const struct ethernet_api *api = net_if_get_device(iface)->api;
struct ethernet_context *ctx = net_if_l2_data(iface);
uint16_t ptype = 0;
int ret;
uint16_t ptype = htons(net_pkt_ll_proto_type(pkt));
struct net_pkt *orig_pkt = pkt;
int ret;

if (!api) {
ret = -ENOENT;
Expand All @@ -703,65 +703,36 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
goto send;
}

if (IS_ENABLED(CONFIG_NET_IPV4) &&
net_pkt_family(pkt) == AF_INET) {
struct net_pkt *tmp;
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET &&
net_pkt_ll_proto_type(pkt) == NET_ETH_PTYPE_IP) {
if (!net_pkt_ipv4_acd(pkt)) {
struct net_pkt *tmp;

if (net_pkt_ipv4_acd(pkt)) {
ptype = htons(NET_ETH_PTYPE_ARP);
} else {
tmp = ethernet_ll_prepare_on_ipv4(iface, pkt);
if (!tmp) {
if (tmp == NULL) {
ret = -ENOMEM;
goto error;
} else if (IS_ENABLED(CONFIG_NET_ARP) && tmp != pkt) {
/* Original pkt got queued and is replaced
* by an ARP request packet.
*/
pkt = tmp;
ptype = htons(NET_ETH_PTYPE_ARP);
net_pkt_set_family(pkt, AF_INET);
} else {
ptype = htons(NET_ETH_PTYPE_IP);
ptype = htons(net_pkt_ll_proto_type(pkt));
}
}
} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
net_pkt_family(pkt) == AF_INET6) {
ptype = htons(NET_ETH_PTYPE_IPV6);
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
net_pkt_family(pkt) == AF_PACKET) {
struct net_context *context = net_pkt_context(pkt);

if (context && net_context_get_type(context) == SOCK_DGRAM) {
struct sockaddr_ll *dst_addr;
struct sockaddr_ll_ptr *src_addr;

/* The destination address is set in remote for this
* socket type.
*/
dst_addr = (struct sockaddr_ll *)&context->remote;
src_addr = (struct sockaddr_ll_ptr *)&context->local;

net_pkt_lladdr_dst(pkt)->addr = dst_addr->sll_addr;
net_pkt_lladdr_dst(pkt)->len =
sizeof(struct net_eth_addr);
net_pkt_lladdr_src(pkt)->addr = src_addr->sll_addr;
net_pkt_lladdr_src(pkt)->len =
sizeof(struct net_eth_addr);
ptype = dst_addr->sll_protocol;
} else {
if (!(context && net_context_get_type(context) == SOCK_DGRAM)) {
/* Raw packet, just send it */
goto send;
}
} else if (IS_ENABLED(CONFIG_NET_L2_PTP) && net_pkt_is_ptp(pkt)) {
ptype = htons(NET_ETH_PTYPE_PTP);
} else if (IS_ENABLED(CONFIG_NET_LLDP) && net_pkt_is_lldp(pkt)) {
ptype = htons(NET_ETH_PTYPE_LLDP);
} else if (IS_ENABLED(CONFIG_NET_ARP)) {
/* Unknown type: Unqueued pkt is an ARP reply.
*/
ptype = htons(NET_ETH_PTYPE_ARP);
net_pkt_set_family(pkt, AF_INET);
} else {
}

if (ptype == 0) {
/* Caller of this function has not set the ptype */
NET_ERR("No protocol set for pkt %p", pkt);
ret = -ENOTSUP;
goto error;
}
Expand Down
1 change: 1 addition & 0 deletions subsys/net/l2/ethernet/gptp/gptp_messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ static struct net_pkt *setup_gptp_frame(struct net_if *iface,

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

net_pkt_lladdr_src(pkt)->addr = net_if_get_link_addr(iface)->addr;
net_pkt_lladdr_src(pkt)->len = net_if_get_link_addr(iface)->len;
Expand Down
1 change: 1 addition & 0 deletions subsys/net/l2/ethernet/lldp/lldp.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ static int lldp_send(struct ethernet_lldp *lldp)
}

net_pkt_set_lldp(pkt, true);
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_LLDP);

ret = net_pkt_write(pkt, (uint8_t *)lldp->lldpdu,
sizeof(struct net_lldpdu));
Expand Down
19 changes: 19 additions & 0 deletions subsys/net/l2/ppp/ppp_l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
LOG_MODULE_REGISTER(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL);

#include <stdlib.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_l2.h>
#include <zephyr/net/net_if.h>
Expand Down Expand Up @@ -180,6 +181,24 @@ static int ppp_send(struct net_if *iface, struct net_pkt *pkt)
return -ENETDOWN;
}

/* PPP drivers only support IP packet types, therefore in order to be
* able to use AF_PACKET family sockets with PPP, we need to translate
* L2 proto type to packet family.
*/
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
net_pkt_family(pkt) == AF_PACKET) {
switch (net_pkt_ll_proto_type(pkt)) {
case ETH_P_IP:
net_pkt_set_family(pkt, AF_INET);
break;
case ETH_P_IPV6:
net_pkt_set_family(pkt, AF_INET6);
break;
default:
return -EPROTONOSUPPORT;
}
}

ret = net_l2_send(api->send, net_if_get_device(iface), iface, pkt);
if (!ret) {
ret = net_pkt_get_len(pkt);
Expand Down
18 changes: 18 additions & 0 deletions tests/net/arp/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ static inline struct net_pkt *prepare_arp_reply(struct net_if *iface,

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

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);

return pkt;
}

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

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

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);

return pkt;
}

Expand Down Expand Up @@ -373,6 +377,8 @@ ZTEST(arp_fn_tests, test_arp)
net_ipv4_addr_copy_raw(ipv4->src, (uint8_t *)&src);
net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_IP);

memcpy(net_buf_add(pkt->buffer, len), app_data, len);

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

zassert_equal(net_pkt_ll_proto_type(pkt2), NET_ETH_PTYPE_ARP,
"ARP packet type is wrong");

/**TESTPOINTS: Check packets*/
zassert_not_equal((void *)(pkt2), (void *)(pkt),
/* The packets cannot be the same as the ARP cache has
Expand Down Expand Up @@ -530,6 +539,8 @@ ZTEST(arp_fn_tests, test_arp)
net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&src);

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);

pkt2 = prepare_arp_reply(iface, pkt, &eth_hwaddr, &eth_hdr);

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

net_pkt_unref(pkt);

/* Clear the ARP cache so that old entries do not confuse the tests */
net_arp_clear_cache(iface);

/* Then feed in ARP request */
pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
sizeof(struct net_arp_hdr),
Expand All @@ -571,6 +585,8 @@ ZTEST(arp_fn_tests, test_arp)
net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&src);
net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);

pkt2 = prepare_arp_request(iface, pkt, &eth_hwaddr, &eth_hdr);

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

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

net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);

verdict = net_arp_input(pkt, eth_hdr);
zassert_not_equal(verdict, NET_DROP, "Gratuitous ARP failed");

Expand Down