diff options
author | Wei Liu <wei.liu2@citrix.com> | 2013-04-21 22:20:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-22 15:37:01 -0400 |
commit | 9ecd1a75d977e2e8c48139c7d3efed183f898d94 (patch) | |
tree | daba39f085896184b65d1724e5441cda6ee213a5 /drivers/net/xen-netfront.c | |
parent | 697089dc13c52d668322ac6cb8548520de27ed0e (diff) |
xen-netfront: reduce gso_max_size to account for max TCP header
The maximum packet including header that can be handled by netfront / netback
wire format is 65535. Reduce gso_max_size accordingly.
Drop skb and print warning when skb->len > 65535. This can 1) save the effort
to send malformed packet to netback, 2) help spotting misconfiguration of
netfront in the future.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r-- | drivers/net/xen-netfront.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 1bb2e2072a6a..1db101415069 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/ethtool.h> | 37 | #include <linux/ethtool.h> |
38 | #include <linux/if_ether.h> | 38 | #include <linux/if_ether.h> |
39 | #include <linux/tcp.h> | 39 | #include <net/tcp.h> |
40 | #include <linux/udp.h> | 40 | #include <linux/udp.h> |
41 | #include <linux/moduleparam.h> | 41 | #include <linux/moduleparam.h> |
42 | #include <linux/mm.h> | 42 | #include <linux/mm.h> |
@@ -547,6 +547,16 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
547 | unsigned int len = skb_headlen(skb); | 547 | unsigned int len = skb_headlen(skb); |
548 | unsigned long flags; | 548 | unsigned long flags; |
549 | 549 | ||
550 | /* If skb->len is too big for wire format, drop skb and alert | ||
551 | * user about misconfiguration. | ||
552 | */ | ||
553 | if (unlikely(skb->len > XEN_NETIF_MAX_TX_SIZE)) { | ||
554 | net_alert_ratelimited( | ||
555 | "xennet: skb->len = %u, too big for wire format\n", | ||
556 | skb->len); | ||
557 | goto drop; | ||
558 | } | ||
559 | |||
550 | slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) + | 560 | slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) + |
551 | xennet_count_skb_frag_slots(skb); | 561 | xennet_count_skb_frag_slots(skb); |
552 | if (unlikely(slots > MAX_SKB_FRAGS + 1)) { | 562 | if (unlikely(slots > MAX_SKB_FRAGS + 1)) { |
@@ -1058,7 +1068,8 @@ err: | |||
1058 | 1068 | ||
1059 | static int xennet_change_mtu(struct net_device *dev, int mtu) | 1069 | static int xennet_change_mtu(struct net_device *dev, int mtu) |
1060 | { | 1070 | { |
1061 | int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN; | 1071 | int max = xennet_can_sg(dev) ? |
1072 | XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER : ETH_DATA_LEN; | ||
1062 | 1073 | ||
1063 | if (mtu > max) | 1074 | if (mtu > max) |
1064 | return -EINVAL; | 1075 | return -EINVAL; |
@@ -1362,6 +1373,8 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1362 | SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); | 1373 | SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); |
1363 | SET_NETDEV_DEV(netdev, &dev->dev); | 1374 | SET_NETDEV_DEV(netdev, &dev->dev); |
1364 | 1375 | ||
1376 | netif_set_gso_max_size(netdev, XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER); | ||
1377 | |||
1365 | np->netdev = netdev; | 1378 | np->netdev = netdev; |
1366 | 1379 | ||
1367 | netif_carrier_off(netdev); | 1380 | netif_carrier_off(netdev); |