Skip to content

Commit ca70c10

Browse files
rleonklassert
authored andcommitted
xfrm: check for PMTU in tunnel mode for packet offload
In tunnel mode, for the packet offload, there were no PMTU signaling to the upper level about need to fragment the packet. As a solution, call to already existing xfrm[4|6]_tunnel_check_size() to perform that. Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent cc18f48 commit ca70c10

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

include/net/xfrm.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,15 @@ int xfrm_trans_queue(struct sk_buff *skb,
17811781
struct sk_buff *));
17821782
int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err);
17831783
int xfrm_output(struct sock *sk, struct sk_buff *skb);
1784+
int xfrm4_tunnel_check_size(struct sk_buff *skb);
1785+
#if IS_ENABLED(CONFIG_IPV6)
1786+
int xfrm6_tunnel_check_size(struct sk_buff *skb);
1787+
#else
1788+
static inline int xfrm6_tunnel_check_size(struct sk_buff *skb)
1789+
{
1790+
return -EMSGSIZE;
1791+
}
1792+
#endif
17841793

17851794
#if IS_ENABLED(CONFIG_NET_PKTGEN)
17861795
int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);

net/xfrm/xfrm_device.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,12 +418,12 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
418418
struct dst_entry *dst = skb_dst(skb);
419419
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
420420
struct net_device *dev = x->xso.dev;
421+
bool check_tunnel_size;
421422

422423
if (x->xso.type == XFRM_DEV_OFFLOAD_UNSPECIFIED)
423424
return false;
424425

425-
if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET ||
426-
((dev == xfrm_dst_path(dst)->dev) && !xdst->child->xfrm)) {
426+
if ((dev == xfrm_dst_path(dst)->dev) && !xdst->child->xfrm) {
427427
mtu = xfrm_state_mtu(x, xdst->child_mtu_cached);
428428
if (skb->len <= mtu)
429429
goto ok;
@@ -435,16 +435,22 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
435435
return false;
436436

437437
ok:
438+
check_tunnel_size = x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
439+
x->props.mode == XFRM_MODE_TUNNEL;
438440
switch (x->props.family) {
439441
case AF_INET:
440442
/* Check for IPv4 options */
441443
if (ip_hdr(skb)->ihl != 5)
442444
return false;
445+
if (check_tunnel_size && xfrm4_tunnel_check_size(skb))
446+
return false;
443447
break;
444448
case AF_INET6:
445449
/* Check for IPv6 extensions */
446450
if (ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr))
447451
return false;
452+
if (check_tunnel_size && xfrm6_tunnel_check_size(skb))
453+
return false;
448454
break;
449455
default:
450456
break;

net/xfrm/xfrm_output.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
786786
}
787787
EXPORT_SYMBOL_GPL(xfrm_output);
788788

789-
static int xfrm4_tunnel_check_size(struct sk_buff *skb)
789+
int xfrm4_tunnel_check_size(struct sk_buff *skb)
790790
{
791791
int mtu, ret = 0;
792792

@@ -812,6 +812,7 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
812812
out:
813813
return ret;
814814
}
815+
EXPORT_SYMBOL_GPL(xfrm4_tunnel_check_size);
815816

816817
static int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
817818
{
@@ -834,7 +835,7 @@ static int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
834835
}
835836

836837
#if IS_ENABLED(CONFIG_IPV6)
837-
static int xfrm6_tunnel_check_size(struct sk_buff *skb)
838+
int xfrm6_tunnel_check_size(struct sk_buff *skb)
838839
{
839840
int mtu, ret = 0;
840841
struct dst_entry *dst = skb_dst(skb);
@@ -864,6 +865,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
864865
out:
865866
return ret;
866867
}
868+
EXPORT_SYMBOL_GPL(xfrm6_tunnel_check_size);
867869
#endif
868870

869871
static int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb)

0 commit comments

Comments
 (0)