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 | ||
