Skip to content

Commit

Permalink
ip_gre: Refector the erpsan tunnel code.
Browse files Browse the repository at this point in the history
Move two erspan functions to header file, erspan.h, so ipv6
erspan implementation can use it.

Signed-off-by: William Tu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
williamtu authored and davem330 committed Dec 1, 2017
1 parent 50e0f5c commit a3222dc
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 49 deletions.
51 changes: 51 additions & 0 deletions include/net/erspan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
54 changes: 5 additions & 49 deletions net/ipv4/ip_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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++));
Expand Down Expand Up @@ -668,52 +669,6 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *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)
{
Expand All @@ -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;
Expand Down

0 comments on commit a3222dc

Please sign in to comment.