Skip to content

Commit a2b78e9

Browse files
David L Stevensdavem330
David L Stevens
authored andcommitted
sunvnet: generate ICMP PTMUD messages for smaller port MTUs
This patch sends ICMP and ICMPv6 messages for Path MTU Discovery when a remote port MTU is smaller than the device MTU. This allows mixing newer VIO protocol devices that support MTU negotiation with older devices that do not on the same vswitch. It also allows Linux-Linux LDOMs to use 64K-1 data packets even though Solaris vswitch is limited to <16K MTU. Signed-off-by: David L Stevens <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 42db672 commit a2b78e9

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

drivers/net/ethernet/sun/sunvnet.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
#include <linux/mutex.h>
1818
#include <linux/if_vlan.h>
1919

20+
#if IS_ENABLED(CONFIG_IPV6)
21+
#include <linux/icmpv6.h>
22+
#endif
23+
24+
#include <net/icmp.h>
25+
#include <net/route.h>
26+
2027
#include <asm/vio.h>
2128
#include <asm/ldc.h>
2229

@@ -913,8 +920,36 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
913920
if (unlikely(!skb))
914921
goto out_dropped;
915922

916-
if (skb->len > port->rmtu)
923+
if (skb->len > port->rmtu) {
924+
unsigned long localmtu = port->rmtu - ETH_HLEN;
925+
926+
if (vio_version_after_eq(&port->vio, 1, 3))
927+
localmtu -= VLAN_HLEN;
928+
929+
if (skb->protocol == htons(ETH_P_IP)) {
930+
struct flowi4 fl4;
931+
struct rtable *rt = NULL;
932+
933+
memset(&fl4, 0, sizeof(fl4));
934+
fl4.flowi4_oif = dev->ifindex;
935+
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
936+
fl4.daddr = ip_hdr(skb)->daddr;
937+
fl4.saddr = ip_hdr(skb)->saddr;
938+
939+
rt = ip_route_output_key(dev_net(dev), &fl4);
940+
if (!IS_ERR(rt)) {
941+
skb_dst_set(skb, &rt->dst);
942+
icmp_send(skb, ICMP_DEST_UNREACH,
943+
ICMP_FRAG_NEEDED,
944+
htonl(localmtu));
945+
}
946+
}
947+
#if IS_ENABLED(CONFIG_IPV6)
948+
else if (skb->protocol == htons(ETH_P_IPV6))
949+
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu);
950+
#endif
917951
goto out_dropped;
952+
}
918953

919954
spin_lock_irqsave(&port->vio.lock, flags);
920955

0 commit comments

Comments
 (0)