diff options
author | Atzm Watanabe <atzm@stratosphere.co.jp> | 2013-12-17 08:53:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-18 00:36:16 -0500 |
commit | a0cdfcf39362410d5ea983f4daf67b38de129408 (patch) | |
tree | 31de8d8010bafd58bade0701fb3f501bd6e4c0a7 /net/packet | |
parent | e4d26f4b080f55e9577b45e6b51a04971eb459e9 (diff) |
packet: deliver VLAN TPID to userspace
This enables userspace to get VLAN TPID as well as the VLAN TCI.
Signed-off-by: Atzm Watanabe <atzm@stratosphere.co.jp>
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r-- | net/packet/af_packet.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index f281999ba92e..dd3840846ce2 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -977,9 +977,11 @@ static void prb_fill_vlan_info(struct tpacket_kbdq_core *pkc, | |||
977 | { | 977 | { |
978 | if (vlan_tx_tag_present(pkc->skb)) { | 978 | if (vlan_tx_tag_present(pkc->skb)) { |
979 | ppd->hv1.tp_vlan_tci = vlan_tx_tag_get(pkc->skb); | 979 | ppd->hv1.tp_vlan_tci = vlan_tx_tag_get(pkc->skb); |
980 | ppd->tp_status = TP_STATUS_VLAN_VALID; | 980 | ppd->hv1.tp_vlan_tpid = ntohs(pkc->skb->vlan_proto); |
981 | ppd->tp_status = TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; | ||
981 | } else { | 982 | } else { |
982 | ppd->hv1.tp_vlan_tci = 0; | 983 | ppd->hv1.tp_vlan_tci = 0; |
984 | ppd->hv1.tp_vlan_tpid = 0; | ||
983 | ppd->tp_status = TP_STATUS_AVAILABLE; | 985 | ppd->tp_status = TP_STATUS_AVAILABLE; |
984 | } | 986 | } |
985 | } | 987 | } |
@@ -987,6 +989,7 @@ static void prb_fill_vlan_info(struct tpacket_kbdq_core *pkc, | |||
987 | static void prb_run_all_ft_ops(struct tpacket_kbdq_core *pkc, | 989 | static void prb_run_all_ft_ops(struct tpacket_kbdq_core *pkc, |
988 | struct tpacket3_hdr *ppd) | 990 | struct tpacket3_hdr *ppd) |
989 | { | 991 | { |
992 | ppd->hv1.tp_padding = 0; | ||
990 | prb_fill_vlan_info(pkc, ppd); | 993 | prb_fill_vlan_info(pkc, ppd); |
991 | 994 | ||
992 | if (pkc->feature_req_word & TP_FT_REQ_FILL_RXHASH) | 995 | if (pkc->feature_req_word & TP_FT_REQ_FILL_RXHASH) |
@@ -1925,9 +1928,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |||
1925 | h.h2->tp_nsec = ts.tv_nsec; | 1928 | h.h2->tp_nsec = ts.tv_nsec; |
1926 | if (vlan_tx_tag_present(skb)) { | 1929 | if (vlan_tx_tag_present(skb)) { |
1927 | h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); | 1930 | h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); |
1928 | status |= TP_STATUS_VLAN_VALID; | 1931 | h.h2->tp_vlan_tpid = ntohs(skb->vlan_proto); |
1932 | status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; | ||
1929 | } else { | 1933 | } else { |
1930 | h.h2->tp_vlan_tci = 0; | 1934 | h.h2->tp_vlan_tci = 0; |
1935 | h.h2->tp_vlan_tpid = 0; | ||
1931 | } | 1936 | } |
1932 | memset(h.h2->tp_padding, 0, sizeof(h.h2->tp_padding)); | 1937 | memset(h.h2->tp_padding, 0, sizeof(h.h2->tp_padding)); |
1933 | hdrlen = sizeof(*h.h2); | 1938 | hdrlen = sizeof(*h.h2); |
@@ -2875,11 +2880,12 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
2875 | aux.tp_net = skb_network_offset(skb); | 2880 | aux.tp_net = skb_network_offset(skb); |
2876 | if (vlan_tx_tag_present(skb)) { | 2881 | if (vlan_tx_tag_present(skb)) { |
2877 | aux.tp_vlan_tci = vlan_tx_tag_get(skb); | 2882 | aux.tp_vlan_tci = vlan_tx_tag_get(skb); |
2878 | aux.tp_status |= TP_STATUS_VLAN_VALID; | 2883 | aux.tp_vlan_tpid = ntohs(skb->vlan_proto); |
2884 | aux.tp_status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; | ||
2879 | } else { | 2885 | } else { |
2880 | aux.tp_vlan_tci = 0; | 2886 | aux.tp_vlan_tci = 0; |
2887 | aux.tp_vlan_tpid = 0; | ||
2881 | } | 2888 | } |
2882 | aux.tp_padding = 0; | ||
2883 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); | 2889 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); |
2884 | } | 2890 | } |
2885 | 2891 | ||