Skip to content

Commit a3222dc

Browse files
williamtudavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 50e0f5c commit a3222dc

File tree

2 files changed

+56
-49
lines changed

2 files changed

+56
-49
lines changed

include/net/erspan.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,55 @@ struct erspanhdr {
5858
struct erspan_metadata md;
5959
};
6060

61+
static inline u8 tos_to_cos(u8 tos)
62+
{
63+
u8 dscp, cos;
64+
65+
dscp = tos >> 2;
66+
cos = dscp >> 3;
67+
return cos;
68+
}
69+
70+
static inline void erspan_build_header(struct sk_buff *skb,
71+
__be32 id, u32 index,
72+
bool truncate, bool is_ipv4)
73+
{
74+
struct ethhdr *eth = eth_hdr(skb);
75+
enum erspan_encap_type enc_type;
76+
struct erspanhdr *ershdr;
77+
struct qtag_prefix {
78+
__be16 eth_type;
79+
__be16 tci;
80+
} *qp;
81+
u16 vlan_tci = 0;
82+
u8 tos;
83+
84+
tos = is_ipv4 ? ip_hdr(skb)->tos :
85+
(ipv6_hdr(skb)->priority << 4) +
86+
(ipv6_hdr(skb)->flow_lbl[0] >> 4);
87+
88+
enc_type = ERSPAN_ENCAP_NOVLAN;
89+
90+
/* If mirrored packet has vlan tag, extract tci and
91+
* perserve vlan header in the mirrored frame.
92+
*/
93+
if (eth->h_proto == htons(ETH_P_8021Q)) {
94+
qp = (struct qtag_prefix *)(skb->data + 2 * ETH_ALEN);
95+
vlan_tci = ntohs(qp->tci);
96+
enc_type = ERSPAN_ENCAP_INFRAME;
97+
}
98+
99+
skb_push(skb, sizeof(*ershdr));
100+
ershdr = (struct erspanhdr *)skb->data;
101+
memset(ershdr, 0, sizeof(*ershdr));
102+
103+
ershdr->ver_vlan = htons((vlan_tci & VLAN_MASK) |
104+
(ERSPAN_VERSION << VER_OFFSET));
105+
ershdr->session_id = htons((u16)(ntohl(id) & ID_MASK) |
106+
((tos_to_cos(tos) << COS_OFFSET) & COS_MASK) |
107+
(enc_type << EN_OFFSET & EN_MASK) |
108+
((truncate << T_OFFSET) & T_MASK));
109+
ershdr->md.index = htonl(index & INDEX_MASK);
110+
}
111+
61112
#endif

net/ipv4/ip_gre.c

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
114114
static struct rtnl_link_ops ipgre_link_ops __read_mostly;
115115
static int ipgre_tunnel_init(struct net_device *dev);
116116
static void erspan_build_header(struct sk_buff *skb,
117-
__be32 id, u32 index, bool truncate);
117+
__be32 id, u32 index,
118+
bool truncate, bool is_ipv4);
118119

119120
static unsigned int ipgre_net_id __read_mostly;
120121
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,
589590
goto err_free_rt;
590591

591592
erspan_build_header(skb, tunnel_id_to_key32(key->tun_id),
592-
ntohl(md->index), truncate);
593+
ntohl(md->index), truncate, true);
593594

594595
gre_build_header(skb, 8, TUNNEL_SEQ,
595596
htons(ETH_P_ERSPAN), 0, htonl(tunnel->o_seqno++));
@@ -668,52 +669,6 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
668669
return NETDEV_TX_OK;
669670
}
670671

671-
static inline u8 tos_to_cos(u8 tos)
672-
{
673-
u8 dscp, cos;
674-
675-
dscp = tos >> 2;
676-
cos = dscp >> 3;
677-
return cos;
678-
}
679-
680-
static void erspan_build_header(struct sk_buff *skb,
681-
__be32 id, u32 index, bool truncate)
682-
{
683-
struct iphdr *iphdr = ip_hdr(skb);
684-
struct ethhdr *eth = eth_hdr(skb);
685-
enum erspan_encap_type enc_type;
686-
struct erspanhdr *ershdr;
687-
struct qtag_prefix {
688-
__be16 eth_type;
689-
__be16 tci;
690-
} *qp;
691-
u16 vlan_tci = 0;
692-
693-
enc_type = ERSPAN_ENCAP_NOVLAN;
694-
695-
/* If mirrored packet has vlan tag, extract tci and
696-
* perserve vlan header in the mirrored frame.
697-
*/
698-
if (eth->h_proto == htons(ETH_P_8021Q)) {
699-
qp = (struct qtag_prefix *)(skb->data + 2 * ETH_ALEN);
700-
vlan_tci = ntohs(qp->tci);
701-
enc_type = ERSPAN_ENCAP_INFRAME;
702-
}
703-
704-
skb_push(skb, sizeof(*ershdr));
705-
ershdr = (struct erspanhdr *)skb->data;
706-
memset(ershdr, 0, sizeof(*ershdr));
707-
708-
ershdr->ver_vlan = htons((vlan_tci & VLAN_MASK) |
709-
(ERSPAN_VERSION << VER_OFFSET));
710-
ershdr->session_id = htons((u16)(ntohl(id) & ID_MASK) |
711-
((tos_to_cos(iphdr->tos) << COS_OFFSET) & COS_MASK) |
712-
(enc_type << EN_OFFSET & EN_MASK) |
713-
((truncate << T_OFFSET) & T_MASK));
714-
ershdr->md.index = htonl(index & INDEX_MASK);
715-
}
716-
717672
static netdev_tx_t erspan_xmit(struct sk_buff *skb,
718673
struct net_device *dev)
719674
{
@@ -737,7 +692,8 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb,
737692
}
738693

739694
/* Push ERSPAN header */
740-
erspan_build_header(skb, tunnel->parms.o_key, tunnel->index, truncate);
695+
erspan_build_header(skb, tunnel->parms.o_key, tunnel->index,
696+
truncate, true);
741697
tunnel->parms.o_flags &= ~TUNNEL_KEY;
742698
__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN));
743699
return NETDEV_TX_OK;

0 commit comments

Comments
 (0)