@@ -503,6 +503,47 @@ static void *packet_current_frame(struct packet_sock *po,
503503 return packet_lookup_frame (po , rb , rb -> head , status );
504504}
505505
506+ static u16 vlan_get_tci (const struct sk_buff * skb , struct net_device * dev )
507+ {
508+ struct vlan_hdr vhdr , * vh ;
509+ unsigned int header_len ;
510+
511+ if (!dev )
512+ return 0 ;
513+
514+ /* In the SOCK_DGRAM scenario, skb data starts at the network
515+ * protocol, which is after the VLAN headers. The outer VLAN
516+ * header is at the hard_header_len offset in non-variable
517+ * length link layer headers. If it's a VLAN device, the
518+ * min_header_len should be used to exclude the VLAN header
519+ * size.
520+ */
521+ if (dev -> min_header_len == dev -> hard_header_len )
522+ header_len = dev -> hard_header_len ;
523+ else if (is_vlan_dev (dev ))
524+ header_len = dev -> min_header_len ;
525+ else
526+ return 0 ;
527+
528+ vh = skb_header_pointer (skb , skb_mac_offset (skb ) + header_len ,
529+ sizeof (vhdr ), & vhdr );
530+ if (unlikely (!vh ))
531+ return 0 ;
532+
533+ return ntohs (vh -> h_vlan_TCI );
534+ }
535+
536+ static __be16 vlan_get_protocol_dgram (const struct sk_buff * skb )
537+ {
538+ __be16 proto = skb -> protocol ;
539+
540+ if (unlikely (eth_type_vlan (proto )))
541+ proto = __vlan_get_protocol_offset (skb , proto ,
542+ skb_mac_offset (skb ), NULL );
543+
544+ return proto ;
545+ }
546+
506547static void prb_del_retire_blk_timer (struct tpacket_kbdq_core * pkc )
507548{
508549 del_timer_sync (& pkc -> retire_blk_timer );
@@ -972,10 +1013,16 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *pkc,
9721013static void prb_fill_vlan_info (struct tpacket_kbdq_core * pkc ,
9731014 struct tpacket3_hdr * ppd )
9741015{
1016+ struct packet_sock * po = container_of (pkc , struct packet_sock , rx_ring .prb_bdqc );
1017+
9751018 if (skb_vlan_tag_present (pkc -> skb )) {
9761019 ppd -> hv1 .tp_vlan_tci = skb_vlan_tag_get (pkc -> skb );
9771020 ppd -> hv1 .tp_vlan_tpid = ntohs (pkc -> skb -> vlan_proto );
9781021 ppd -> tp_status = TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID ;
1022+ } else if (unlikely (po -> sk .sk_type == SOCK_DGRAM && eth_type_vlan (pkc -> skb -> protocol ))) {
1023+ ppd -> hv1 .tp_vlan_tci = vlan_get_tci (pkc -> skb , pkc -> skb -> dev );
1024+ ppd -> hv1 .tp_vlan_tpid = ntohs (pkc -> skb -> protocol );
1025+ ppd -> tp_status = TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID ;
9791026 } else {
9801027 ppd -> hv1 .tp_vlan_tci = 0 ;
9811028 ppd -> hv1 .tp_vlan_tpid = 0 ;
@@ -2395,6 +2442,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
23952442 h .h2 -> tp_vlan_tci = skb_vlan_tag_get (skb );
23962443 h .h2 -> tp_vlan_tpid = ntohs (skb -> vlan_proto );
23972444 status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID ;
2445+ } else if (unlikely (sk -> sk_type == SOCK_DGRAM && eth_type_vlan (skb -> protocol ))) {
2446+ h .h2 -> tp_vlan_tci = vlan_get_tci (skb , skb -> dev );
2447+ h .h2 -> tp_vlan_tpid = ntohs (skb -> protocol );
2448+ status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID ;
23982449 } else {
23992450 h .h2 -> tp_vlan_tci = 0 ;
24002451 h .h2 -> tp_vlan_tpid = 0 ;
@@ -2424,7 +2475,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
24242475 sll -> sll_halen = dev_parse_header (skb , sll -> sll_addr );
24252476 sll -> sll_family = AF_PACKET ;
24262477 sll -> sll_hatype = dev -> type ;
2427- sll -> sll_protocol = skb -> protocol ;
2478+ sll -> sll_protocol = (sk -> sk_type == SOCK_DGRAM ) ?
2479+ vlan_get_protocol_dgram (skb ) : skb -> protocol ;
24282480 sll -> sll_pkttype = skb -> pkt_type ;
24292481 if (unlikely (packet_sock_flag (po , PACKET_SOCK_ORIGDEV )))
24302482 sll -> sll_ifindex = orig_dev -> ifindex ;
@@ -3000,8 +3052,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
30003052 if (err )
30013053 goto out_free ;
30023054
3003- if (sock -> type == SOCK_RAW &&
3004- !dev_validate_header (dev , skb -> data , len )) {
3055+ if (( sock -> type == SOCK_RAW &&
3056+ !dev_validate_header (dev , skb -> data , len )) || ! skb -> len ) {
30053057 err = - EINVAL ;
30063058 goto out_free ;
30073059 }
@@ -3441,7 +3493,8 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
34413493 /* Original length was stored in sockaddr_ll fields */
34423494 origlen = PACKET_SKB_CB (skb )-> sa .origlen ;
34433495 sll -> sll_family = AF_PACKET ;
3444- sll -> sll_protocol = skb -> protocol ;
3496+ sll -> sll_protocol = (sock -> type == SOCK_DGRAM ) ?
3497+ vlan_get_protocol_dgram (skb ) : skb -> protocol ;
34453498 }
34463499
34473500 sock_recv_ts_and_drops (msg , sk , skb );
@@ -3498,6 +3551,21 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
34983551 aux .tp_vlan_tci = skb_vlan_tag_get (skb );
34993552 aux .tp_vlan_tpid = ntohs (skb -> vlan_proto );
35003553 aux .tp_status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID ;
3554+ } else if (unlikely (sock -> type == SOCK_DGRAM && eth_type_vlan (skb -> protocol ))) {
3555+ struct sockaddr_ll * sll = & PACKET_SKB_CB (skb )-> sa .ll ;
3556+ struct net_device * dev ;
3557+
3558+ rcu_read_lock ();
3559+ dev = dev_get_by_index_rcu (sock_net (sk ), sll -> sll_ifindex );
3560+ if (dev ) {
3561+ aux .tp_vlan_tci = vlan_get_tci (skb , dev );
3562+ aux .tp_vlan_tpid = ntohs (skb -> protocol );
3563+ aux .tp_status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID ;
3564+ } else {
3565+ aux .tp_vlan_tci = 0 ;
3566+ aux .tp_vlan_tpid = 0 ;
3567+ }
3568+ rcu_read_unlock ();
35013569 } else {
35023570 aux .tp_vlan_tci = 0 ;
35033571 aux .tp_vlan_tpid = 0 ;
0 commit comments