Skip to content

Commit 19f9ce5

Browse files
jukkarnashif
authored andcommitted
net: ipv6_fragment: Add PMTU support
If PMTU is enabled, then use the MTU value from it instead of always using network interface MTU. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 2658286 commit 19f9ce5

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

subsys/net/ip/ipv6_fragment.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ static int send_ipv6_fragment(struct net_pkt *pkt,
686686
}
687687

688688
int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
689-
uint16_t pkt_len)
689+
uint16_t pkt_len, uint16_t mtu)
690690
{
691691
uint16_t next_hdr_off;
692692
uint16_t last_hdr_off;
@@ -713,12 +713,12 @@ int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
713713
/* The Maximum payload can fit into each packet after IPv6 header,
714714
* Extension headers and Fragmentation header.
715715
*/
716-
fit_len = NET_IPV6_MTU - NET_IPV6_FRAGH_LEN -
716+
fit_len = (int)mtu - NET_IPV6_FRAGH_LEN -
717717
(net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt));
718718
if (fit_len <= 0) {
719719
/* Must be invalid extension headers length */
720720
NET_DBG("No room for IPv6 payload MTU %d hdrs_len %d",
721-
NET_IPV6_MTU, NET_IPV6_FRAGH_LEN +
721+
mtu, NET_IPV6_FRAGH_LEN +
722722
net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt));
723723
return -EINVAL;
724724
}

subsys/net/ip/ipv6_nbr.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -810,13 +810,31 @@ enum net_verdict net_ipv6_prepare_for_send(struct net_pkt *pkt)
810810
* contain a proper value and we can skip other checks.
811811
*/
812812
if (net_pkt_ipv6_fragment_id(pkt) == 0U) {
813-
uint16_t mtu = net_if_get_mtu(net_pkt_iface(pkt));
814813
size_t pkt_len = net_pkt_get_len(pkt);
814+
uint16_t mtu;
815+
816+
if (IS_ENABLED(CONFIG_NET_IPV6_PMTU)) {
817+
struct sockaddr_in6 dst = {
818+
.sin6_family = AF_INET6,
819+
};
820+
821+
net_ipv6_addr_copy_raw((uint8_t *)&dst.sin6_addr, ip_hdr->dst);
822+
823+
ret = net_pmtu_get_mtu((struct sockaddr *)&dst);
824+
if (ret <= 0) {
825+
goto use_interface_mtu;
826+
}
827+
828+
mtu = ret;
829+
} else {
830+
use_interface_mtu:
831+
mtu = net_if_get_mtu(net_pkt_iface(pkt));
832+
mtu = MAX(NET_IPV6_MTU, mtu);
833+
}
815834

816-
mtu = MAX(NET_IPV6_MTU, mtu);
817835
if (mtu < pkt_len) {
818836
ret = net_ipv6_send_fragmented_pkt(net_pkt_iface(pkt),
819-
pkt, pkt_len);
837+
pkt, pkt_len, mtu);
820838
if (ret < 0) {
821839
NET_DBG("Cannot fragment IPv6 pkt (%d)", ret);
822840
return NET_DROP;

subsys/net/ip/net_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
245245

246246
#if defined(CONFIG_NET_IPV6_FRAGMENT)
247247
int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
248-
uint16_t pkt_len);
248+
uint16_t pkt_len, uint16_t mtu);
249249
#endif
250250

251251
extern const char *net_verdict2str(enum net_verdict verdict);

0 commit comments

Comments
 (0)