diff mbox series

[ipsec/vti,2/2] vti6: process icmp msg when IPv6 is fragmented

Message ID 1552865877-13401-3-git-send-email-bram-yvahk@mail.wizbit.be
State Awaiting Upstream
Delegated to: David Miller
Headers show
Series Fragmentation of IPv4 in VTI | expand

Commit Message

Bram Yvakh March 17, 2019, 11:37 p.m. UTC
In the error function the 'nexthdr' of the (original) IPv6 header
was used to check for which protocol it was.

When the (original) IPv6 packet is fragmented however then nexthdr
is set to 'NEXTHDR_FRAGMENT' and this causes the code to return
early and not process the ICMP error.

Signed-off-by: Bram Yvahk <bram-yvahk@mail.wizbit.be>
---
 net/ipv6/ip6_vti.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 47f178c..9582ffd 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -590,7 +590,7 @@  vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-		    u8 type, u8 code, int offset, __be32 info)
+		    u8 type, u8 code, int offset, __be32 info, int protocol)
 {
 	__be32 spi;
 	__u32 mark;
@@ -601,7 +601,6 @@  static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	struct ip_comp_hdr *ipch;
 	struct net *net = dev_net(skb->dev);
 	const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data;
-	int protocol = iph->nexthdr;
 
 	t = vti6_tnl_lookup(dev_net(skb->dev), &iph->daddr, &iph->saddr);
 	if (!t)
@@ -645,6 +644,24 @@  static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	return 0;
 }
 
+static int vti6_esp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			u8 type, u8 code, int offset, __be32 info)
+{
+	return vti6_err(skb, opt, type, code, offset, info, IPPROTO_ESP);
+}
+
+static int vti6_ah_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+		       u8 type, u8 code, int offset, __be32 info)
+{
+	return vti6_err(skb, opt, type, code, offset, info, IPPROTO_AH);
+}
+
+static int vti6_ipcomp_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			   u8 type, u8 code, int offset, __be32 info)
+{
+	return vti6_err(skb, opt, type, code, offset, info, IPPROTO_COMP);
+}
+
 static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu)
 {
 	struct net_device *dev = t->dev;
@@ -1189,21 +1206,21 @@  static struct pernet_operations vti6_net_ops = {
 static struct xfrm6_protocol vti_esp6_protocol __read_mostly = {
 	.handler	=	vti6_rcv,
 	.cb_handler	=	vti6_rcv_cb,
-	.err_handler	=	vti6_err,
+	.err_handler	=	vti6_esp_err,
 	.priority	=	100,
 };
 
 static struct xfrm6_protocol vti_ah6_protocol __read_mostly = {
 	.handler	=	vti6_rcv,
 	.cb_handler	=	vti6_rcv_cb,
-	.err_handler	=	vti6_err,
+	.err_handler	=	vti6_ah_err,
 	.priority	=	100,
 };
 
 static struct xfrm6_protocol vti_ipcomp6_protocol __read_mostly = {
 	.handler	=	vti6_rcv,
 	.cb_handler	=	vti6_rcv_cb,
-	.err_handler	=	vti6_err,
+	.err_handler	=	vti6_ipcomp_err,
 	.priority	=	100,
 };