aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
authorBen Greear <greearb@candelatech.com>2011-02-11 04:35:18 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-12 00:26:32 -0500
commit57f89bfa21403d902ee176ef988136b75d9ab30b (patch)
tree3ebee83312498997fdd4630acfe0cfccec84835c /net/packet/af_packet.c
parentab889e6607f6e3d52a76c5a43c8c4ad1d354da36 (diff)
network: Allow af_packet to transmit +4 bytes for VLAN packets.
This allows user-space to send a '1500' MTU VLAN packet on a 1500 MTU ethernet frame. The extra 4 bytes of a VLAN header is not usually charged against the MTU when other parts of the network stack is transmitting vlans... Signed-off-by: Ben Greear <greearb@candelatech.com> Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index c60649ec1193..5efef5b5879e 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -465,7 +465,7 @@ retry:
465 */ 465 */
466 466
467 err = -EMSGSIZE; 467 err = -EMSGSIZE;
468 if (len > dev->mtu + dev->hard_header_len) 468 if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN)
469 goto out_unlock; 469 goto out_unlock;
470 470
471 if (!skb) { 471 if (!skb) {
@@ -496,6 +496,19 @@ retry:
496 goto retry; 496 goto retry;
497 } 497 }
498 498
499 if (len > (dev->mtu + dev->hard_header_len)) {
500 /* Earlier code assumed this would be a VLAN pkt,
501 * double-check this now that we have the actual
502 * packet in hand.
503 */
504 struct ethhdr *ehdr;
505 skb_reset_mac_header(skb);
506 ehdr = eth_hdr(skb);
507 if (ehdr->h_proto != htons(ETH_P_8021Q)) {
508 err = -EMSGSIZE;
509 goto out_unlock;
510 }
511 }
499 512
500 skb->protocol = proto; 513 skb->protocol = proto;
501 skb->dev = dev; 514 skb->dev = dev;
@@ -1199,7 +1212,7 @@ static int packet_snd(struct socket *sock,
1199 } 1212 }
1200 1213
1201 err = -EMSGSIZE; 1214 err = -EMSGSIZE;
1202 if (!gso_type && (len > dev->mtu+reserve)) 1215 if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN))
1203 goto out_unlock; 1216 goto out_unlock;
1204 1217
1205 err = -ENOBUFS; 1218 err = -ENOBUFS;
@@ -1224,6 +1237,20 @@ static int packet_snd(struct socket *sock,
1224 if (err < 0) 1237 if (err < 0)
1225 goto out_free; 1238 goto out_free;
1226 1239
1240 if (!gso_type && (len > dev->mtu + reserve)) {
1241 /* Earlier code assumed this would be a VLAN pkt,
1242 * double-check this now that we have the actual
1243 * packet in hand.
1244 */
1245 struct ethhdr *ehdr;
1246 skb_reset_mac_header(skb);
1247 ehdr = eth_hdr(skb);
1248 if (ehdr->h_proto != htons(ETH_P_8021Q)) {
1249 err = -EMSGSIZE;
1250 goto out_free;
1251 }
1252 }
1253
1227 skb->protocol = proto; 1254 skb->protocol = proto;
1228 skb->dev = dev; 1255 skb->dev = dev;
1229 skb->priority = sk->sk_priority; 1256 skb->priority = sk->sk_priority;