Skip to content

Commit 3483c65

Browse files
lxingregkh
authored andcommitted
ip6_gre: skb_push ipv6hdr before packing the header in ip6gre_header
[ Upstream commit 76cc0d3282d4b933fa144fa41fbc5318e0fdca24 ] Now in ip6gre_header before packing the ipv6 header, it skb_push t->hlen which only includes encap_hlen + tun_hlen. It means greh and inner header would be over written by ipv6 stuff and ipv6h might have no chance to set up. Jianlin found this issue when using remote any on ip6_gre, the packets he captured on gre dev are truncated: 22:50:26.210866 Out ethertype IPv6 (0x86dd), length 120: truncated-ip6 -\ 8128 bytes missing!(flowlabel 0x92f40, hlim 0, next-header Options (0) \ payload length: 8192) ::1:2000:0 > ::1:0:86dd: HBH [trunc] ip-proto-128 \ 8184 It should also skb_push ipv6hdr so that ipv6h points to the right position to set ipv6 stuff up. This patch is to skb_push hlen + sizeof(*ipv6h) and also fix some indents in ip6gre_header. Fixes: c12b395 ("gre: Support GRE over IPv6") Reported-by: Jianlin Shi <jishi@redhat.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5356f7e commit 3483c65

1 file changed

Lines changed: 11 additions & 10 deletions

File tree

net/ipv6/ip6_gre.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,24 +1173,25 @@ static int ip6gre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
11731173
}
11741174

11751175
static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
1176-
unsigned short type,
1177-
const void *daddr, const void *saddr, unsigned int len)
1176+
unsigned short type, const void *daddr,
1177+
const void *saddr, unsigned int len)
11781178
{
11791179
struct ip6_tnl *t = netdev_priv(dev);
1180-
struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
1181-
__be16 *p = (__be16 *)(ipv6h+1);
1180+
struct ipv6hdr *ipv6h;
1181+
__be16 *p;
11821182

1183-
ip6_flow_hdr(ipv6h, 0,
1184-
ip6_make_flowlabel(dev_net(dev), skb,
1185-
t->fl.u.ip6.flowlabel, true,
1186-
&t->fl.u.ip6));
1183+
ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen + sizeof(*ipv6h));
1184+
ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb,
1185+
t->fl.u.ip6.flowlabel,
1186+
true, &t->fl.u.ip6));
11871187
ipv6h->hop_limit = t->parms.hop_limit;
11881188
ipv6h->nexthdr = NEXTHDR_GRE;
11891189
ipv6h->saddr = t->parms.laddr;
11901190
ipv6h->daddr = t->parms.raddr;
11911191

1192-
p[0] = t->parms.o_flags;
1193-
p[1] = htons(type);
1192+
p = (__be16 *)(ipv6h + 1);
1193+
p[0] = t->parms.o_flags;
1194+
p[1] = htons(type);
11941195

11951196
/*
11961197
* Set the source hardware address.

0 commit comments

Comments
 (0)