Browse Source

net: ipv6: Avoid casting unaligned address to struct in6_addr

Rework the rest of the IPv6-related code to avoid casting. Use raw
variants of IPv6-related functions whenever possible (especially on the
critical data path). For the routing case, use a copy of the address to
avoid massive rework of the routing module.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
pull/91526/merge
Robert Lubos 1 week ago committed by Daniel DeGrasse
parent
commit
0f6dcb37d7
  1. 5
      subsys/net/ip/connection.c
  2. 32
      subsys/net/ip/icmpv6.c
  3. 95
      subsys/net/ip/ipv6.c
  4. 15
      subsys/net/ip/ipv6_fragment.c
  5. 21
      subsys/net/ip/net_core.c
  6. 2
      subsys/net/ip/net_if.c
  7. 17
      subsys/net/ip/tcp.c
  8. 2
      subsys/net/l2/ethernet/ethernet.c

5
subsys/net/ip/connection.c

@ -581,8 +581,7 @@ static bool conn_are_endpoints_valid(struct net_pkt *pkt, uint8_t family,
is_same_src_and_dst_addr = net_ipv4_addr_cmp_raw( is_same_src_and_dst_addr = net_ipv4_addr_cmp_raw(
ip_hdr->ipv4->src, ip_hdr->ipv4->dst); ip_hdr->ipv4->src, ip_hdr->ipv4->dst);
} else if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) { } else if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
is_my_src_addr = net_ipv6_is_my_addr( is_my_src_addr = net_ipv6_is_my_addr_raw(ip_hdr->ipv6->src);
(struct in6_addr *)ip_hdr->ipv6->src);
is_same_src_and_dst_addr = net_ipv6_addr_cmp_raw( is_same_src_and_dst_addr = net_ipv6_addr_cmp_raw(
ip_hdr->ipv6->src, ip_hdr->ipv6->dst); ip_hdr->ipv6->src, ip_hdr->ipv6->dst);
} else { } else {
@ -933,7 +932,7 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
is_bcast_pkt = true; is_bcast_pkt = true;
} }
} else if (IS_ENABLED(CONFIG_NET_IPV6) && pkt_family == AF_INET6) { } else if (IS_ENABLED(CONFIG_NET_IPV6) && pkt_family == AF_INET6) {
is_mcast_pkt = net_ipv6_is_addr_mcast((struct in6_addr *)ip_hdr->ipv6->dst); is_mcast_pkt = net_ipv6_is_addr_mcast_raw(ip_hdr->ipv6->dst);
} }
k_mutex_lock(&conn_lock, K_FOREVER); k_mutex_lock(&conn_lock, K_FOREVER);

32
subsys/net/ip/icmpv6.c

@ -104,15 +104,19 @@ static int icmpv6_handle_echo_request(struct net_icmp_ctx *ctx,
{ {
struct net_pkt *reply = NULL; struct net_pkt *reply = NULL;
struct net_ipv6_hdr *ip_hdr = hdr->ipv6; struct net_ipv6_hdr *ip_hdr = hdr->ipv6;
struct in6_addr req_src, req_dst;
const struct in6_addr *src; const struct in6_addr *src;
int16_t payload_len; int16_t payload_len;
ARG_UNUSED(user_data); ARG_UNUSED(user_data);
ARG_UNUSED(icmp_hdr); ARG_UNUSED(icmp_hdr);
net_ipv6_addr_copy_raw(req_src.s6_addr, ip_hdr->src);
net_ipv6_addr_copy_raw(req_dst.s6_addr, ip_hdr->dst);
NET_DBG("Received Echo Request from %s to %s", NET_DBG("Received Echo Request from %s to %s",
net_sprint_ipv6_addr(&ip_hdr->src), net_sprint_ipv6_addr(&req_src),
net_sprint_ipv6_addr(&ip_hdr->dst)); net_sprint_ipv6_addr(&req_dst));
payload_len = ntohs(ip_hdr->len) - payload_len = ntohs(ip_hdr->len) -
net_pkt_ipv6_ext_len(pkt) - NET_ICMPH_LEN; net_pkt_ipv6_ext_len(pkt) - NET_ICMPH_LEN;
@ -129,16 +133,16 @@ static int icmpv6_handle_echo_request(struct net_icmp_ctx *ctx,
goto drop; goto drop;
} }
if (net_ipv6_is_addr_mcast((struct in6_addr *)ip_hdr->dst)) { if (net_ipv6_is_addr_mcast_raw(ip_hdr->dst)) {
src = net_if_ipv6_select_src_addr(net_pkt_iface(pkt), src = net_if_ipv6_select_src_addr(net_pkt_iface(pkt),
(struct in6_addr *)ip_hdr->src); &req_src);
if (net_ipv6_is_addr_unspecified(src)) { if (net_ipv6_is_addr_unspecified(src)) {
NET_DBG("DROP: No src address match"); NET_DBG("DROP: No src address match");
goto drop; goto drop;
} }
} else { } else {
src = (struct in6_addr *)ip_hdr->dst; src = &req_dst;
} }
/* We must not set the destination ll address here but trust /* We must not set the destination ll address here but trust
@ -151,7 +155,7 @@ static int icmpv6_handle_echo_request(struct net_icmp_ctx *ctx,
net_pkt_set_ip_dscp(reply, net_pkt_ip_dscp(pkt)); net_pkt_set_ip_dscp(reply, net_pkt_ip_dscp(pkt));
net_pkt_set_ip_ecn(reply, net_pkt_ip_ecn(pkt)); net_pkt_set_ip_ecn(reply, net_pkt_ip_ecn(pkt));
if (net_ipv6_create(reply, src, (struct in6_addr *)ip_hdr->src)) { if (net_ipv6_create(reply, src, &req_src)) {
NET_DBG("DROP: wrong buffer"); NET_DBG("DROP: wrong buffer");
goto drop; goto drop;
} }
@ -167,7 +171,7 @@ static int icmpv6_handle_echo_request(struct net_icmp_ctx *ctx,
NET_DBG("Sending Echo Reply from %s to %s", NET_DBG("Sending Echo Reply from %s to %s",
net_sprint_ipv6_addr(src), net_sprint_ipv6_addr(src),
net_sprint_ipv6_addr(&ip_hdr->src)); net_sprint_ipv6_addr(&req_src));
if (net_try_send_data(reply, K_NO_WAIT) < 0) { if (net_try_send_data(reply, K_NO_WAIT) < 0) {
goto drop; goto drop;
@ -192,6 +196,7 @@ int net_icmpv6_send_error(struct net_pkt *orig, uint8_t type, uint8_t code,
{ {
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr); NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
int err = -EIO; int err = -EIO;
struct in6_addr orig_src, orig_dst;
struct net_ipv6_hdr *ip_hdr; struct net_ipv6_hdr *ip_hdr;
const struct in6_addr *src; const struct in6_addr *src;
struct net_pkt *pkt; struct net_pkt *pkt;
@ -223,6 +228,9 @@ int net_icmpv6_send_error(struct net_pkt *orig, uint8_t type, uint8_t code,
net_pkt_cursor_init(orig); net_pkt_cursor_init(orig);
} }
net_ipv6_addr_copy_raw(orig_src.s6_addr, ip_hdr->src);
net_ipv6_addr_copy_raw(orig_dst.s6_addr, ip_hdr->dst);
if (ip_hdr->nexthdr == IPPROTO_UDP) { if (ip_hdr->nexthdr == IPPROTO_UDP) {
copy_len = sizeof(struct net_ipv6_hdr) + copy_len = sizeof(struct net_ipv6_hdr) +
sizeof(struct net_udp_hdr); sizeof(struct net_udp_hdr);
@ -284,14 +292,14 @@ int net_icmpv6_send_error(struct net_pkt *orig, uint8_t type, uint8_t code,
net_pkt_lladdr_src(pkt)->len = net_pkt_lladdr_dst(orig)->len; net_pkt_lladdr_src(pkt)->len = net_pkt_lladdr_dst(orig)->len;
net_pkt_lladdr_dst(pkt)->len = net_pkt_lladdr_src(orig)->len; net_pkt_lladdr_dst(pkt)->len = net_pkt_lladdr_src(orig)->len;
if (net_ipv6_is_addr_mcast((struct in6_addr *)ip_hdr->dst)) { if (net_ipv6_is_addr_mcast_raw(ip_hdr->dst)) {
src = net_if_ipv6_select_src_addr(net_pkt_iface(pkt), src = net_if_ipv6_select_src_addr(net_pkt_iface(pkt),
(struct in6_addr *)ip_hdr->dst); &orig_dst);
} else { } else {
src = (struct in6_addr *)ip_hdr->dst; src = &orig_dst;
} }
if (net_ipv6_create(pkt, src, (struct in6_addr *)ip_hdr->src) || if (net_ipv6_create(pkt, src, &orig_src) ||
net_icmpv6_create(pkt, type, code)) { net_icmpv6_create(pkt, type, code)) {
goto drop; goto drop;
} }
@ -319,7 +327,7 @@ int net_icmpv6_send_error(struct net_pkt *orig, uint8_t type, uint8_t code,
NET_DBG("Sending ICMPv6 Error Message type %d code %d param %d" NET_DBG("Sending ICMPv6 Error Message type %d code %d param %d"
" from %s to %s", type, code, param, " from %s to %s", type, code, param,
net_sprint_ipv6_addr(src), net_sprint_ipv6_addr(src),
net_sprint_ipv6_addr(&ip_hdr->src)); net_sprint_ipv6_addr(&orig_src));
if (net_try_send_data(pkt, K_NO_WAIT) >= 0) { if (net_try_send_data(pkt, K_NO_WAIT) >= 0) {
net_stats_update_icmp_sent(net_pkt_iface(pkt)); net_stats_update_icmp_sent(net_pkt_iface(pkt));

95
subsys/net/ip/ipv6.c

@ -186,7 +186,7 @@ static inline bool ipv6_drop_on_unknown_option(struct net_pkt *pkt,
case 0x40: case 0x40:
break; break;
case 0xc0: case 0xc0:
if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst)) { if (net_ipv6_is_addr_mcast_raw(hdr->dst)) {
break; break;
} }
@ -307,8 +307,8 @@ static struct net_route_entry *add_route(struct net_if *iface,
#endif /* CONFIG_NET_ROUTE */ #endif /* CONFIG_NET_ROUTE */
static void ipv6_no_route_info(struct net_pkt *pkt, static void ipv6_no_route_info(struct net_pkt *pkt,
struct in6_addr *src, const uint8_t *src,
struct in6_addr *dst) const uint8_t *dst)
{ {
NET_DBG("Will not route pkt %p ll src %s to dst %s between interfaces", NET_DBG("Will not route pkt %p ll src %s to dst %s between interfaces",
pkt, net_sprint_ipv6_addr(src), pkt, net_sprint_ipv6_addr(src),
@ -321,15 +321,17 @@ static enum net_verdict ipv6_route_packet(struct net_pkt *pkt,
{ {
struct net_route_entry *route; struct net_route_entry *route;
struct in6_addr *nexthop; struct in6_addr *nexthop;
struct in6_addr src_ip, dst_ip;
bool found; bool found;
net_ipv6_addr_copy_raw(src_ip.s6_addr, hdr->src);
net_ipv6_addr_copy_raw(dst_ip.s6_addr, hdr->dst);
/* Check if the packet can be routed */ /* Check if the packet can be routed */
if (IS_ENABLED(CONFIG_NET_ROUTING)) { if (IS_ENABLED(CONFIG_NET_ROUTING)) {
found = net_route_get_info(NULL, (struct in6_addr *)hdr->dst, found = net_route_get_info(NULL, &dst_ip, &route, &nexthop);
&route, &nexthop);
} else { } else {
found = net_route_get_info(net_pkt_iface(pkt), found = net_route_get_info(net_pkt_iface(pkt), &dst_ip,
(struct in6_addr *)hdr->dst,
&route, &nexthop); &route, &nexthop);
} }
@ -337,11 +339,11 @@ static enum net_verdict ipv6_route_packet(struct net_pkt *pkt,
int ret; int ret;
if (IS_ENABLED(CONFIG_NET_ROUTING) && if (IS_ENABLED(CONFIG_NET_ROUTING) &&
(net_ipv6_is_ll_addr((struct in6_addr *)hdr->src) || (net_ipv6_is_ll_addr(&src_ip) ||
net_ipv6_is_ll_addr((struct in6_addr *)hdr->dst))) { net_ipv6_is_ll_addr(&dst_ip))) {
/* RFC 4291 ch 2.5.6 */ /* RFC 4291 ch 2.5.6 */
ipv6_no_route_info(pkt, (struct in6_addr *)hdr->src, ipv6_no_route_info(pkt, hdr->src, hdr->dst);
(struct in6_addr *)hdr->dst);
goto drop; goto drop;
} }
@ -365,8 +367,7 @@ static enum net_verdict ipv6_route_packet(struct net_pkt *pkt,
pkt, net_pkt_orig_iface(pkt), pkt, net_pkt_orig_iface(pkt),
net_pkt_iface(pkt)); net_pkt_iface(pkt));
add_route(net_pkt_orig_iface(pkt), add_route(net_pkt_orig_iface(pkt), &src_ip, 128);
(struct in6_addr *)hdr->src, 128);
} }
ret = net_route_packet(pkt, nexthop); ret = net_route_packet(pkt, nexthop);
@ -382,7 +383,7 @@ static enum net_verdict ipv6_route_packet(struct net_pkt *pkt,
struct net_if *iface = NULL; struct net_if *iface = NULL;
int ret; int ret;
if (net_if_ipv6_addr_onlink(&iface, (struct in6_addr *)hdr->dst)) { if (net_if_ipv6_addr_onlink(&iface, &dst_ip)) {
ret = net_route_packet_if(pkt, iface); ret = net_route_packet_if(pkt, iface);
if (ret < 0) { if (ret < 0) {
NET_DBG("Cannot re-route pkt %p " NET_DBG("Cannot re-route pkt %p "
@ -394,7 +395,7 @@ static enum net_verdict ipv6_route_packet(struct net_pkt *pkt,
} }
NET_DBG("No route to %s pkt %p dropped", NET_DBG("No route to %s pkt %p dropped",
net_sprint_ipv6_addr(&hdr->dst), pkt); net_sprint_ipv6_addr(&dst_ip), pkt);
} }
drop: drop:
@ -427,9 +428,9 @@ static enum net_verdict ipv6_forward_mcast_packet(struct net_pkt *pkt,
* 3. is from link local source * 3. is from link local source
* 4. hop limit is or would become zero * 4. hop limit is or would become zero
*/ */
if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->src) || if (net_ipv6_is_addr_mcast_raw(hdr->src) ||
net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) || net_ipv6_is_addr_mcast_iface_raw(hdr->dst) ||
net_ipv6_is_ll_addr((struct in6_addr *)hdr->src) || hdr->hop_limit <= 1) { net_ipv6_is_ll_addr_raw(hdr->src) || hdr->hop_limit <= 1) {
return NET_CONTINUE; return NET_CONTINUE;
} }
@ -462,11 +463,11 @@ static uint8_t extension_to_bitmap(uint8_t header, uint8_t ext_bitmap)
} }
} }
static inline bool is_src_non_tentative_itself(struct in6_addr *src) static inline bool is_src_non_tentative_itself(const uint8_t *src)
{ {
struct net_if_addr *ifaddr; struct net_if_addr *ifaddr;
ifaddr = net_if_ipv6_addr_lookup(src, NULL); ifaddr = net_if_ipv6_addr_lookup_raw(src, NULL);
if (ifaddr != NULL && ifaddr->addr_state != NET_ADDR_TENTATIVE) { if (ifaddr != NULL && ifaddr->addr_state != NET_ADDR_TENTATIVE) {
return true; return true;
} }
@ -518,37 +519,37 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
net_sprint_ipv6_addr(&hdr->src), net_sprint_ipv6_addr(&hdr->src),
net_sprint_ipv6_addr(&hdr->dst)); net_sprint_ipv6_addr(&hdr->dst));
if (net_ipv6_is_addr_unspecified((struct in6_addr *)hdr->src)) { if (net_ipv6_is_addr_unspecified_raw(hdr->src)) {
/* If this is a possible DAD message, let it pass. Extra checks /* If this is a possible DAD message, let it pass. Extra checks
* are done in duplicate address detection code to verify that * are done in duplicate address detection code to verify that
* the packet is ok. * the packet is ok.
*/ */
if (!(IS_ENABLED(CONFIG_NET_IPV6_DAD) && if (!(IS_ENABLED(CONFIG_NET_IPV6_DAD) &&
net_ipv6_is_addr_solicited_node((struct in6_addr *)hdr->dst))) { net_ipv6_is_addr_solicited_node_raw(hdr->dst))) {
NET_DBG("DROP: src addr is %s", "unspecified"); NET_DBG("DROP: src addr is %s", "unspecified");
goto drop; goto drop;
} }
} }
if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->src) || if (net_ipv6_is_addr_mcast_raw(hdr->src) ||
net_ipv6_is_addr_mcast_scope((struct in6_addr *)hdr->dst, 0)) { net_ipv6_is_addr_mcast_scope_raw(hdr->dst, 0)) {
NET_DBG("DROP: multicast packet"); NET_DBG("DROP: multicast packet");
goto drop; goto drop;
} }
if (!is_loopback) { if (!is_loopback) {
if (net_ipv6_is_addr_loopback((struct in6_addr *)hdr->dst) || if (net_ipv6_is_addr_loopback_raw(hdr->dst) ||
net_ipv6_is_addr_loopback((struct in6_addr *)hdr->src)) { net_ipv6_is_addr_loopback_raw(hdr->src)) {
NET_DBG("DROP: ::1 packet"); NET_DBG("DROP: ::1 packet");
goto drop; goto drop;
} }
if (net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) || if (net_ipv6_is_addr_mcast_iface_raw(hdr->dst) ||
(net_ipv6_is_addr_mcast_group( (net_ipv6_is_addr_mcast_group_raw(
(struct in6_addr *)hdr->dst, hdr->dst,
net_ipv6_unspecified_address()) && (const uint8_t *)net_ipv6_unspecified_address()) &&
(net_ipv6_is_addr_mcast_site((struct in6_addr *)hdr->dst) || (net_ipv6_is_addr_mcast_site_raw(hdr->dst) ||
net_ipv6_is_addr_mcast_org((struct in6_addr *)hdr->dst)))) { net_ipv6_is_addr_mcast_org_raw(hdr->dst)))) {
NET_DBG("DROP: invalid scope multicast packet"); NET_DBG("DROP: invalid scope multicast packet");
goto drop; goto drop;
} }
@ -559,7 +560,7 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
* This check is done later on if routing features are enabled. * This check is done later on if routing features are enabled.
*/ */
if (!IS_ENABLED(CONFIG_NET_ROUTING) && !IS_ENABLED(CONFIG_NET_ROUTE_MCAST) && if (!IS_ENABLED(CONFIG_NET_ROUTING) && !IS_ENABLED(CONFIG_NET_ROUTE_MCAST) &&
is_src_non_tentative_itself((struct in6_addr *)hdr->src)) { is_src_non_tentative_itself(hdr->src)) {
NET_DBG("DROP: src addr is %s", "mine"); NET_DBG("DROP: src addr is %s", "mine");
goto drop; goto drop;
} }
@ -589,7 +590,7 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
} }
if (IS_ENABLED(CONFIG_NET_ROUTE_MCAST) && if (IS_ENABLED(CONFIG_NET_ROUTE_MCAST) &&
net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst) && !net_pkt_forwarding(pkt)) { net_ipv6_is_addr_mcast_raw(hdr->dst) && !net_pkt_forwarding(pkt)) {
/* If the packet is a multicast packet and multicast routing /* If the packet is a multicast packet and multicast routing
* is activated, we give the packet to the routing engine. * is activated, we give the packet to the routing engine.
* *
@ -603,14 +604,14 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
} }
} }
if (!net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst)) { if (!net_ipv6_is_addr_mcast_raw(hdr->dst)) {
if (!net_if_ipv6_addr_lookup_by_iface(pkt_iface, (struct in6_addr *)hdr->dst)) { if (!net_if_ipv6_addr_lookup_by_iface_raw(pkt_iface, hdr->dst)) {
if (ipv6_route_packet(pkt, hdr) == NET_OK) { if (ipv6_route_packet(pkt, hdr) == NET_OK) {
return NET_OK; return NET_OK;
} }
NET_DBG("DROP: no such address %s in iface %d", NET_DBG("DROP: no such address %s in iface %d",
net_sprint_ipv6_addr((struct in6_addr *)hdr->dst), net_sprint_ipv6_addr(hdr->dst),
net_if_get_by_iface(pkt_iface)); net_if_get_by_iface(pkt_iface));
goto drop; goto drop;
} }
@ -621,25 +622,23 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
* RFC 4291 ch 2.5.6 * RFC 4291 ch 2.5.6
*/ */
if (IS_ENABLED(CONFIG_NET_ROUTING) && if (IS_ENABLED(CONFIG_NET_ROUTING) &&
net_ipv6_is_ll_addr((struct in6_addr *)hdr->src) && net_ipv6_is_ll_addr_raw(hdr->src) &&
!net_if_ipv6_addr_lookup_by_iface( !net_if_ipv6_addr_lookup_by_iface_raw(pkt_iface, hdr->dst)) {
pkt_iface, (struct in6_addr *)hdr->dst)) { ipv6_no_route_info(pkt, hdr->src, hdr->dst);
ipv6_no_route_info(pkt, (struct in6_addr *)hdr->src,
(struct in6_addr *)hdr->dst);
NET_DBG("DROP: cross interface boundary"); NET_DBG("DROP: cross interface boundary");
goto drop; goto drop;
} }
} }
if ((IS_ENABLED(CONFIG_NET_ROUTING) || IS_ENABLED(CONFIG_NET_ROUTE_MCAST)) && if ((IS_ENABLED(CONFIG_NET_ROUTING) || IS_ENABLED(CONFIG_NET_ROUTE_MCAST)) &&
!is_loopback && is_src_non_tentative_itself((struct in6_addr *)hdr->src)) { !is_loopback && is_src_non_tentative_itself(hdr->src)) {
NET_DBG("DROP: src addr is %s", "mine"); NET_DBG("DROP: src addr is %s", "mine");
goto drop; goto drop;
} }
if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst) && if (net_ipv6_is_addr_mcast_raw(hdr->dst) &&
!(net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) || !(net_ipv6_is_addr_mcast_iface_raw(hdr->dst) ||
net_ipv6_is_addr_mcast_link_all_nodes((struct in6_addr *)hdr->dst))) { net_ipv6_is_addr_mcast_link_all_nodes_raw(hdr->dst))) {
/* If we receive a packet with a interface-local or /* If we receive a packet with a interface-local or
* link-local all-nodes multicast destination address we * link-local all-nodes multicast destination address we
* always have to pass it to the upper layer. * always have to pass it to the upper layer.
@ -650,9 +649,7 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
* packet will be dropped. * packet will be dropped.
* RFC4291 ch 2.7.1, ch 2.8 * RFC4291 ch 2.7.1, ch 2.8
*/ */
if_mcast_addr = net_if_ipv6_maddr_lookup( if_mcast_addr = net_if_ipv6_maddr_lookup_raw(hdr->dst, &pkt_iface);
(struct in6_addr *)hdr->dst, &pkt_iface);
if (!if_mcast_addr || if (!if_mcast_addr ||
!net_if_ipv6_maddr_is_joined(if_mcast_addr)) { !net_if_ipv6_maddr_is_joined(if_mcast_addr)) {
NET_DBG("DROP: packet for unjoined multicast address"); NET_DBG("DROP: packet for unjoined multicast address");

15
subsys/net/ip/ipv6_fragment.c

@ -121,16 +121,16 @@ fail:
} }
static struct net_ipv6_reassembly *reassembly_get(uint32_t id, static struct net_ipv6_reassembly *reassembly_get(uint32_t id,
struct in6_addr *src, const uint8_t *src,
struct in6_addr *dst) const uint8_t *dst)
{ {
int i, avail = -1; int i, avail = -1;
for (i = 0; i < CONFIG_NET_IPV6_FRAGMENT_MAX_COUNT; i++) { for (i = 0; i < CONFIG_NET_IPV6_FRAGMENT_MAX_COUNT; i++) {
if (k_work_delayable_remaining_get(&reassembly[i].timer) && if (k_work_delayable_remaining_get(&reassembly[i].timer) &&
reassembly[i].id == id && reassembly[i].id == id &&
net_ipv6_addr_cmp(src, &reassembly[i].src) && net_ipv6_addr_cmp_raw(src, reassembly[i].src.s6_addr) &&
net_ipv6_addr_cmp(dst, &reassembly[i].dst)) { net_ipv6_addr_cmp_raw(dst, reassembly[i].dst.s6_addr)) {
return &reassembly[i]; return &reassembly[i];
} }
@ -149,8 +149,8 @@ static struct net_ipv6_reassembly *reassembly_get(uint32_t id,
k_work_reschedule(&reassembly[avail].timer, IPV6_REASSEMBLY_TIMEOUT); k_work_reschedule(&reassembly[avail].timer, IPV6_REASSEMBLY_TIMEOUT);
net_ipaddr_copy(&reassembly[avail].src, src); net_ipv6_addr_copy_raw(reassembly[avail].src.s6_addr, src);
net_ipaddr_copy(&reassembly[avail].dst, dst); net_ipv6_addr_copy_raw(reassembly[avail].dst.s6_addr, dst);
reassembly[avail].id = id; reassembly[avail].id = id;
@ -492,8 +492,7 @@ enum net_verdict net_ipv6_handle_fragment_hdr(struct net_pkt *pkt,
goto drop; goto drop;
} }
reass = reassembly_get(id, (struct in6_addr *)hdr->src, reass = reassembly_get(id, hdr->src, hdr->dst);
(struct in6_addr *)hdr->dst);
if (!reass) { if (!reass) {
NET_DBG("Cannot get reassembly slot, dropping pkt %p", pkt); NET_DBG("Cannot get reassembly slot, dropping pkt %p", pkt);
goto drop; goto drop;

21
subsys/net/ip/net_core.c

@ -230,8 +230,8 @@ static inline int check_ip(struct net_pkt *pkt)
return 0; return 0;
} }
#endif #endif
if (net_ipv6_addr_cmp((struct in6_addr *)NET_IPV6_HDR(pkt)->dst, if (net_ipv6_addr_cmp_raw(NET_IPV6_HDR(pkt)->dst,
net_ipv6_unspecified_address())) { (const uint8_t *)net_ipv6_unspecified_address())) {
NET_DBG("DROP: IPv6 dst address missing"); NET_DBG("DROP: IPv6 dst address missing");
ret = -EADDRNOTAVAIL; ret = -EADDRNOTAVAIL;
goto drop; goto drop;
@ -240,10 +240,8 @@ static inline int check_ip(struct net_pkt *pkt)
/* If the destination address is our own, then route it /* If the destination address is our own, then route it
* back to us (if it is not already forwarded). * back to us (if it is not already forwarded).
*/ */
if ((net_ipv6_is_addr_loopback( if ((net_ipv6_is_addr_loopback_raw(NET_IPV6_HDR(pkt)->dst) ||
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst) || net_ipv6_is_my_addr_raw(NET_IPV6_HDR(pkt)->dst)) &&
net_ipv6_is_my_addr(
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) &&
!net_pkt_forwarding(pkt)) { !net_pkt_forwarding(pkt)) {
struct in6_addr addr; struct in6_addr addr;
@ -267,8 +265,7 @@ static inline int check_ip(struct net_pkt *pkt)
* in local host, so this is similar as how ::1 unicast * in local host, so this is similar as how ::1 unicast
* addresses are handled. See RFC 3513 ch 2.7 for details. * addresses are handled. See RFC 3513 ch 2.7 for details.
*/ */
if (net_ipv6_is_addr_mcast_iface( if (net_ipv6_is_addr_mcast_iface_raw(NET_IPV6_HDR(pkt)->dst)) {
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) {
NET_DBG("IPv6 interface scope mcast dst address"); NET_DBG("IPv6 interface scope mcast dst address");
return 1; return 1;
} }
@ -276,8 +273,7 @@ static inline int check_ip(struct net_pkt *pkt)
/* The source check must be done after the destination check /* The source check must be done after the destination check
* as having src ::1 is perfectly ok if dst is ::1 too. * as having src ::1 is perfectly ok if dst is ::1 too.
*/ */
if (net_ipv6_is_addr_loopback( if (net_ipv6_is_addr_loopback_raw(NET_IPV6_HDR(pkt)->src)) {
(struct in6_addr *)NET_IPV6_HDR(pkt)->src)) {
NET_DBG("DROP: IPv6 loopback src address"); NET_DBG("DROP: IPv6 loopback src address");
ret = -EADDRNOTAVAIL; ret = -EADDRNOTAVAIL;
goto drop; goto drop;
@ -378,9 +374,8 @@ static inline bool process_multicast(struct net_pkt *pkt)
#endif #endif
#if defined(CONFIG_NET_IPV6) #if defined(CONFIG_NET_IPV6)
if (family == AF_INET6) { if (family == AF_INET6) {
const struct in6_addr *dst = (const struct in6_addr *)&NET_IPV6_HDR(pkt)->dst; return net_ipv6_is_addr_mcast_raw(NET_IPV6_HDR(pkt)->dst) &&
net_context_get_ipv6_mcast_loop(ctx);
return net_ipv6_is_addr_mcast(dst) && net_context_get_ipv6_mcast_loop(ctx);
} }
#endif #endif
return false; return false;

2
subsys/net/ip/net_if.c

@ -893,7 +893,7 @@ static struct net_if_router *iface_router_add(struct net_if *iface,
NET_DBG("interface %p router %s lifetime %u default %d " NET_DBG("interface %p router %s lifetime %u default %d "
"added", iface, "added", iface,
net_sprint_ipv6_addr((struct in6_addr *)addr), net_sprint_ipv6_addr(addr),
lifetime, routers[i].is_default); lifetime, routers[i].is_default);
} else if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) { } else if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
memcpy(net_if_router_ipv4(&routers[i]), addr, memcpy(net_if_router_ipv4(&routers[i]), addr,

17
subsys/net/ip/tcp.c

@ -1360,10 +1360,8 @@ static bool is_destination_local(struct net_pkt *pkt)
} }
if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) { if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
if (net_ipv6_is_addr_loopback( if (net_ipv6_is_addr_loopback_raw(NET_IPV6_HDR(pkt)->dst) ||
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst) || net_ipv6_is_my_addr_raw(NET_IPV6_HDR(pkt)->dst)) {
net_ipv6_is_my_addr(
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) {
return true; return true;
} }
} }
@ -1396,9 +1394,12 @@ void net_tcp_reply_rst(struct net_pkt *pkt)
(struct in_addr *)NET_IPV4_HDR(pkt)->dst, (struct in_addr *)NET_IPV4_HDR(pkt)->dst,
(struct in_addr *)NET_IPV4_HDR(pkt)->src); (struct in_addr *)NET_IPV4_HDR(pkt)->src);
} else if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) { } else if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
ret = net_ipv6_create(rst, struct in6_addr src, dst;
(struct in6_addr *)NET_IPV6_HDR(pkt)->dst,
(struct in6_addr *)NET_IPV6_HDR(pkt)->src); net_ipv6_addr_copy_raw(src.s6_addr, NET_IPV6_HDR(pkt)->src);
net_ipv6_addr_copy_raw(dst.s6_addr, NET_IPV6_HDR(pkt)->dst);
ret = net_ipv6_create(rst, &dst, &src);
} else { } else {
ret = -EINVAL; ret = -EINVAL;
} }
@ -2976,7 +2977,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
break; break;
} }
net_ipaddr_copy(&conn->context->remote, &conn->dst.sa); memcpy(&conn->context->remote, &conn->dst.sa, sizeof(conn->dst.sa));
/* Check if v4-mapping-to-v6 needs to be done for /* Check if v4-mapping-to-v6 needs to be done for
* the accepted socket. * the accepted socket.

2
subsys/net/l2/ethernet/ethernet.c

@ -524,7 +524,7 @@ static bool ethernet_fill_in_dst_on_ipv6_mcast(struct net_pkt *pkt,
struct net_eth_addr *dst) struct net_eth_addr *dst)
{ {
if (net_pkt_family(pkt) == AF_INET6 && if (net_pkt_family(pkt) == AF_INET6 &&
net_ipv6_is_addr_mcast((struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) { net_ipv6_is_addr_mcast_raw(NET_IPV6_HDR(pkt)->dst)) {
memcpy(dst, (uint8_t *)multicast_eth_addr.addr, memcpy(dst, (uint8_t *)multicast_eth_addr.addr,
sizeof(struct net_eth_addr) - 4); sizeof(struct net_eth_addr) - 4);
memcpy((uint8_t *)dst + 2, memcpy((uint8_t *)dst + 2,

Loading…
Cancel
Save