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 | |
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>
-rw-r--r-- | include/uapi/linux/if_packet.h | 24 | ||||
-rw-r--r-- | net/packet/af_packet.c | 14 |
2 files changed, 24 insertions, 14 deletions
diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h index 9185dc9a4485..e9d844c80c11 100644 --- a/include/uapi/linux/if_packet.h +++ b/include/uapi/linux/if_packet.h | |||
@@ -84,17 +84,18 @@ struct tpacket_auxdata { | |||
84 | __u16 tp_mac; | 84 | __u16 tp_mac; |
85 | __u16 tp_net; | 85 | __u16 tp_net; |
86 | __u16 tp_vlan_tci; | 86 | __u16 tp_vlan_tci; |
87 | __u16 tp_padding; | 87 | __u16 tp_vlan_tpid; |
88 | }; | 88 | }; |
89 | 89 | ||
90 | /* Rx ring - header status */ | 90 | /* Rx ring - header status */ |
91 | #define TP_STATUS_KERNEL 0 | 91 | #define TP_STATUS_KERNEL 0 |
92 | #define TP_STATUS_USER (1 << 0) | 92 | #define TP_STATUS_USER (1 << 0) |
93 | #define TP_STATUS_COPY (1 << 1) | 93 | #define TP_STATUS_COPY (1 << 1) |
94 | #define TP_STATUS_LOSING (1 << 2) | 94 | #define TP_STATUS_LOSING (1 << 2) |
95 | #define TP_STATUS_CSUMNOTREADY (1 << 3) | 95 | #define TP_STATUS_CSUMNOTREADY (1 << 3) |
96 | #define TP_STATUS_VLAN_VALID (1 << 4) /* auxdata has valid tp_vlan_tci */ | 96 | #define TP_STATUS_VLAN_VALID (1 << 4) /* auxdata has valid tp_vlan_tci */ |
97 | #define TP_STATUS_BLK_TMO (1 << 5) | 97 | #define TP_STATUS_BLK_TMO (1 << 5) |
98 | #define TP_STATUS_VLAN_TPID_VALID (1 << 6) /* auxdata has valid tp_vlan_tpid */ | ||
98 | 99 | ||
99 | /* Tx ring - header status */ | 100 | /* Tx ring - header status */ |
100 | #define TP_STATUS_AVAILABLE 0 | 101 | #define TP_STATUS_AVAILABLE 0 |
@@ -133,12 +134,15 @@ struct tpacket2_hdr { | |||
133 | __u32 tp_sec; | 134 | __u32 tp_sec; |
134 | __u32 tp_nsec; | 135 | __u32 tp_nsec; |
135 | __u16 tp_vlan_tci; | 136 | __u16 tp_vlan_tci; |
136 | __u8 tp_padding[6]; | 137 | __u16 tp_vlan_tpid; |
138 | __u8 tp_padding[4]; | ||
137 | }; | 139 | }; |
138 | 140 | ||
139 | struct tpacket_hdr_variant1 { | 141 | struct tpacket_hdr_variant1 { |
140 | __u32 tp_rxhash; | 142 | __u32 tp_rxhash; |
141 | __u32 tp_vlan_tci; | 143 | __u32 tp_vlan_tci; |
144 | __u16 tp_vlan_tpid; | ||
145 | __u16 tp_padding; | ||
142 | }; | 146 | }; |
143 | 147 | ||
144 | struct tpacket3_hdr { | 148 | struct tpacket3_hdr { |
@@ -154,7 +158,7 @@ struct tpacket3_hdr { | |||
154 | union { | 158 | union { |
155 | struct tpacket_hdr_variant1 hv1; | 159 | struct tpacket_hdr_variant1 hv1; |
156 | }; | 160 | }; |
157 | __u8 tp_padding[12]; | 161 | __u8 tp_padding[8]; |
158 | }; | 162 | }; |
159 | 163 | ||
160 | struct tpacket_bd_ts { | 164 | struct tpacket_bd_ts { |
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 | ||