mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
ip_tunnel: allow to inherit from VLAN encapsulated IP
The current code allows to inherit the TOS, TTL, DF from the payload when skb->protocol is ETH_P_IP or ETH_P_IPV6. However when the payload is VLAN encapsulated (e.g because the tunnel is of type GRETAP), then this inheriting does not work, because the visible skb->protocol is of type ETH_P_8021Q or ETH_P_8021AD. Instead of skb->protocol, use skb_protocol(). Signed-off-by: Matthias May <matthias.may@westermo.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b6afeb87ad
commit
7ae29fd1be
@ -641,6 +641,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
const struct iphdr *inner_iph;
|
||||
unsigned int max_headroom; /* The extra header space needed */
|
||||
struct rtable *rt = NULL; /* Route to the other host */
|
||||
__be16 payload_protocol;
|
||||
bool use_cache = false;
|
||||
struct flowi4 fl4;
|
||||
bool md = false;
|
||||
@ -651,6 +652,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
|
||||
inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
|
||||
connected = (tunnel->parms.iph.daddr != 0);
|
||||
payload_protocol = skb_protocol(skb, true);
|
||||
|
||||
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
||||
|
||||
@ -670,13 +672,12 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
dst = tun_info->key.u.ipv4.dst;
|
||||
md = true;
|
||||
connected = true;
|
||||
}
|
||||
else if (skb->protocol == htons(ETH_P_IP)) {
|
||||
} else if (payload_protocol == htons(ETH_P_IP)) {
|
||||
rt = skb_rtable(skb);
|
||||
dst = rt_nexthop(rt, inner_iph->daddr);
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
else if (payload_protocol == htons(ETH_P_IPV6)) {
|
||||
const struct in6_addr *addr6;
|
||||
struct neighbour *neigh;
|
||||
bool do_tx_error_icmp;
|
||||
@ -716,10 +717,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
tos = tnl_params->tos;
|
||||
if (tos & 0x1) {
|
||||
tos &= ~0x1;
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
if (payload_protocol == htons(ETH_P_IP)) {
|
||||
tos = inner_iph->tos;
|
||||
connected = false;
|
||||
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
} else if (payload_protocol == htons(ETH_P_IPV6)) {
|
||||
tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
|
||||
connected = false;
|
||||
}
|
||||
@ -765,7 +766,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
}
|
||||
|
||||
df = tnl_params->frag_off;
|
||||
if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
|
||||
if (payload_protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
|
||||
df |= (inner_iph->frag_off & htons(IP_DF));
|
||||
|
||||
if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, 0, 0, false)) {
|
||||
@ -786,10 +787,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
|
||||
ttl = tnl_params->ttl;
|
||||
if (ttl == 0) {
|
||||
if (skb->protocol == htons(ETH_P_IP))
|
||||
if (payload_protocol == htons(ETH_P_IP))
|
||||
ttl = inner_iph->ttl;
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
else if (skb->protocol == htons(ETH_P_IPV6))
|
||||
else if (payload_protocol == htons(ETH_P_IPV6))
|
||||
ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
|
||||
#endif
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user