diff options
Diffstat (limited to 'net/openvswitch/vport.c')
-rw-r--r-- | net/openvswitch/vport.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 12a36ac21eda..ef19d0b77d13 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -537,3 +537,33 @@ int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, return vport->ops->get_egress_tun_info(vport, skb, upcall); } + +static unsigned int packet_length(const struct sk_buff *skb) +{ + unsigned int length = skb->len - ETH_HLEN; + + if (skb->protocol == htons(ETH_P_8021Q)) + length -= VLAN_HLEN; + + return length; +} + +void ovs_vport_send(struct vport *vport, struct sk_buff *skb) +{ + int mtu = vport->dev->mtu; + + if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { + net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", + vport->dev->name, + packet_length(skb), mtu); + vport->dev->stats.tx_errors++; + goto drop; + } + + skb->dev = vport->dev; + vport->ops->send(skb); + return; + +drop: + kfree_skb(skb); +} |