ip_gre: Refector the erpsan tunnel code.
Move two erspan functions to header file, erspan.h, so ipv6 erspan implementation can use it. Signed-off-by: William Tu <u9012063@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
50e0f5c038
commit
a3222dc95c
@ -58,4 +58,55 @@ struct erspanhdr {
|
||||
struct erspan_metadata md;
|
||||
};
|
||||
|
||||
static inline u8 tos_to_cos(u8 tos)
|
||||
{
|
||||
u8 dscp, cos;
|
||||
|
||||
dscp = tos >> 2;
|
||||
cos = dscp >> 3;
|
||||
return cos;
|
||||
}
|
||||
|
||||
static inline void erspan_build_header(struct sk_buff *skb,
|
||||
__be32 id, u32 index,
|
||||
bool truncate, bool is_ipv4)
|
||||
{
|
||||
struct ethhdr *eth = eth_hdr(skb);
|
||||
enum erspan_encap_type enc_type;
|
||||
struct erspanhdr *ershdr;
|
||||
struct qtag_prefix {
|
||||
__be16 eth_type;
|
||||
__be16 tci;
|
||||
} *qp;
|
||||
u16 vlan_tci = 0;
|
||||
u8 tos;
|
||||
|
||||
tos = is_ipv4 ? ip_hdr(skb)->tos :
|
||||
(ipv6_hdr(skb)->priority << 4) +
|
||||
(ipv6_hdr(skb)->flow_lbl[0] >> 4);
|
||||
|
||||
enc_type = ERSPAN_ENCAP_NOVLAN;
|
||||
|
||||
/* If mirrored packet has vlan tag, extract tci and
|
||||
* perserve vlan header in the mirrored frame.
|
||||
*/
|
||||
if (eth->h_proto == htons(ETH_P_8021Q)) {
|
||||
qp = (struct qtag_prefix *)(skb->data + 2 * ETH_ALEN);
|
||||
vlan_tci = ntohs(qp->tci);
|
||||
enc_type = ERSPAN_ENCAP_INFRAME;
|
||||
}
|
||||
|
||||
skb_push(skb, sizeof(*ershdr));
|
||||
ershdr = (struct erspanhdr *)skb->data;
|
||||
memset(ershdr, 0, sizeof(*ershdr));
|
||||
|
||||
ershdr->ver_vlan = htons((vlan_tci & VLAN_MASK) |
|
||||
(ERSPAN_VERSION << VER_OFFSET));
|
||||
ershdr->session_id = htons((u16)(ntohl(id) & ID_MASK) |
|
||||
((tos_to_cos(tos) << COS_OFFSET) & COS_MASK) |
|
||||
(enc_type << EN_OFFSET & EN_MASK) |
|
||||
((truncate << T_OFFSET) & T_MASK));
|
||||
ershdr->md.index = htonl(index & INDEX_MASK);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -114,7 +114,8 @@ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
|
||||
static struct rtnl_link_ops ipgre_link_ops __read_mostly;
|
||||
static int ipgre_tunnel_init(struct net_device *dev);
|
||||
static void erspan_build_header(struct sk_buff *skb,
|
||||
__be32 id, u32 index, bool truncate);
|
||||
__be32 id, u32 index,
|
||||
bool truncate, bool is_ipv4);
|
||||
|
||||
static unsigned int ipgre_net_id __read_mostly;
|
||||
static unsigned int gre_tap_net_id __read_mostly;
|
||||
@ -589,7 +590,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
goto err_free_rt;
|
||||
|
||||
erspan_build_header(skb, tunnel_id_to_key32(key->tun_id),
|
||||
ntohl(md->index), truncate);
|
||||
ntohl(md->index), truncate, true);
|
||||
|
||||
gre_build_header(skb, 8, TUNNEL_SEQ,
|
||||
htons(ETH_P_ERSPAN), 0, htonl(tunnel->o_seqno++));
|
||||
@ -668,52 +669,6 @@ free_skb:
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static inline u8 tos_to_cos(u8 tos)
|
||||
{
|
||||
u8 dscp, cos;
|
||||
|
||||
dscp = tos >> 2;
|
||||
cos = dscp >> 3;
|
||||
return cos;
|
||||
}
|
||||
|
||||
static void erspan_build_header(struct sk_buff *skb,
|
||||
__be32 id, u32 index, bool truncate)
|
||||
{
|
||||
struct iphdr *iphdr = ip_hdr(skb);
|
||||
struct ethhdr *eth = eth_hdr(skb);
|
||||
enum erspan_encap_type enc_type;
|
||||
struct erspanhdr *ershdr;
|
||||
struct qtag_prefix {
|
||||
__be16 eth_type;
|
||||
__be16 tci;
|
||||
} *qp;
|
||||
u16 vlan_tci = 0;
|
||||
|
||||
enc_type = ERSPAN_ENCAP_NOVLAN;
|
||||
|
||||
/* If mirrored packet has vlan tag, extract tci and
|
||||
* perserve vlan header in the mirrored frame.
|
||||
*/
|
||||
if (eth->h_proto == htons(ETH_P_8021Q)) {
|
||||
qp = (struct qtag_prefix *)(skb->data + 2 * ETH_ALEN);
|
||||
vlan_tci = ntohs(qp->tci);
|
||||
enc_type = ERSPAN_ENCAP_INFRAME;
|
||||
}
|
||||
|
||||
skb_push(skb, sizeof(*ershdr));
|
||||
ershdr = (struct erspanhdr *)skb->data;
|
||||
memset(ershdr, 0, sizeof(*ershdr));
|
||||
|
||||
ershdr->ver_vlan = htons((vlan_tci & VLAN_MASK) |
|
||||
(ERSPAN_VERSION << VER_OFFSET));
|
||||
ershdr->session_id = htons((u16)(ntohl(id) & ID_MASK) |
|
||||
((tos_to_cos(iphdr->tos) << COS_OFFSET) & COS_MASK) |
|
||||
(enc_type << EN_OFFSET & EN_MASK) |
|
||||
((truncate << T_OFFSET) & T_MASK));
|
||||
ershdr->md.index = htonl(index & INDEX_MASK);
|
||||
}
|
||||
|
||||
static netdev_tx_t erspan_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
@ -737,7 +692,8 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
/* Push ERSPAN header */
|
||||
erspan_build_header(skb, tunnel->parms.o_key, tunnel->index, truncate);
|
||||
erspan_build_header(skb, tunnel->parms.o_key, tunnel->index,
|
||||
truncate, true);
|
||||
tunnel->parms.o_flags &= ~TUNNEL_KEY;
|
||||
__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN));
|
||||
return NETDEV_TX_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user