* [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels
@ 2017-11-11 11:06 Xin Long
2017-11-11 11:06 ` [PATCH net-next 1/5] ip6_gre: add the process for redirect in ip6gre_err Xin Long
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Xin Long @ 2017-11-11 11:06 UTC (permalink / raw)
To: network dev; +Cc: davem, Yasuyuki Kozakai, Dmitry Kozlov
Now let's say there are 3 kinds of icmp packets to process for tunnels,
toobig(needfrag), redirect, others, their process should be:
- toobig(needfrag)
update the lower dst's pmtu by route cache, also update sk dst's pmtu
if possible, or it will be fine if sk dst pmtu will get updated on tx
path.
- redirect
update the lower dst's gw by route cache and return, no need to send
this redirect packet to user sk.
- others
send the packet to user's sk, or it will also be fine to use err_count
to count it and report fail link on tx path.
All ipv4 tunnels basically follow this while some of ipv6 tunnels are
doing in different ways, like ip6gre and ip6_tunnels update tnl dev's
mtu instead of updating lower dst pmtu, no redirect process on their
err_handlers, which doesn't make any sense and even causes performance
problems.
This patchset is to improve the process of redirect and toobig for ip6gre
ip4ip6, ip6ip6 tunnels, as in ipv4 tunnels.
Xin Long (5):
ip6_gre: add the process for redirect in ip6gre_err
ip6_gre: process toobig in a better way
ip6_tunnel: add the process for redirect in ip6_tnl_err
ip6_tunnel: process toobig in a better way
ip6_tunnel: clean up ip4ip6 and ip6ip6's err_handlers
net/ipv6/ip6_gre.c | 20 ++++++----------
net/ipv6/ip6_tunnel.c | 64 ++++++++++++++++++++++-----------------------------
2 files changed, 34 insertions(+), 50 deletions(-)
--
2.1.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net-next 1/5] ip6_gre: add the process for redirect in ip6gre_err
2017-11-11 11:06 [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels Xin Long
@ 2017-11-11 11:06 ` Xin Long
2017-11-11 11:06 ` [PATCH net-next 2/5] ip6_gre: process toobig in a better way Xin Long
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Xin Long @ 2017-11-11 11:06 UTC (permalink / raw)
To: network dev; +Cc: davem, Yasuyuki Kozakai, Dmitry Kozlov
This patch is to add redirect icmp packet process for ip6gre by
calling ip6_redirect() in ip6gre_err(), as in vti6_err.
Prior to this patch, there's even no route cache generated after
receiving redirect.
Reported-by: Jianlin Shi <jishi@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/ipv6/ip6_gre.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 3e10c51..0684d0c 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -369,6 +369,7 @@ static void ip6gre_tunnel_uninit(struct net_device *dev)
static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
+ struct net *net = dev_net(skb->dev);
const struct gre_base_hdr *greh;
const struct ipv6hdr *ipv6h;
int grehlen = sizeof(*greh);
@@ -442,6 +443,10 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
mtu = IPV6_MIN_MTU;
t->dev->mtu = mtu;
return;
+ case NDISC_REDIRECT:
+ ip6_redirect(skb, net, skb->dev->ifindex, 0,
+ sock_net_uid(net, NULL));
+ return;
}
if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 2/5] ip6_gre: process toobig in a better way
2017-11-11 11:06 [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels Xin Long
2017-11-11 11:06 ` [PATCH net-next 1/5] ip6_gre: add the process for redirect in ip6gre_err Xin Long
@ 2017-11-11 11:06 ` Xin Long
2017-11-11 11:06 ` [PATCH net-next 3/5] ip6_tunnel: add the process for redirect in ip6_tnl_err Xin Long
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Xin Long @ 2017-11-11 11:06 UTC (permalink / raw)
To: network dev; +Cc: davem, Yasuyuki Kozakai, Dmitry Kozlov
Now ip6gre processes toobig icmp packet by setting gre dev's mtu in
ip6gre_err, which would cause few things not good:
- It couldn't set mtu with dev_set_mtu due to it's not in user context,
which causes route cache and idev->cnf.mtu6 not to be updated.
- It has to update sk dst pmtu in tx path according to gredev->mtu for
ip6gre, while it updates pmtu again according to lower dst pmtu in
ip6_tnl_xmit.
- To change dev->mtu by toobig icmp packet is not a good idea, it should
only work on pmtu.
This patch is to process toobig by updating the lower dst's pmtu, as later
sk dst pmtu will be updated in ip6_tnl_xmit, the same way as in ip4gre.
Note that gre dev's mtu will not be updated any more, it doesn't make any
sense to change dev's mtu after receiving a toobig packet.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/ipv6/ip6_gre.c | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 0684d0c..b90bad7 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -403,9 +403,8 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return;
switch (type) {
- __u32 teli;
struct ipv6_tlv_tnl_enc_lim *tel;
- __u32 mtu;
+ __u32 teli;
case ICMPV6_DEST_UNREACH:
net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n",
t->parms.name);
@@ -436,12 +435,7 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}
return;
case ICMPV6_PKT_TOOBIG:
- mtu = be32_to_cpu(info) - offset - t->tun_hlen;
- if (t->dev->type == ARPHRD_ETHER)
- mtu -= ETH_HLEN;
- if (mtu < IPV6_MIN_MTU)
- mtu = IPV6_MIN_MTU;
- t->dev->mtu = mtu;
+ ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL));
return;
case NDISC_REDIRECT:
ip6_redirect(skb, net, skb->dev->ifindex, 0,
@@ -508,7 +502,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
__u32 *pmtu, __be16 proto)
{
struct ip6_tnl *tunnel = netdev_priv(dev);
- struct dst_entry *dst = skb_dst(skb);
__be16 protocol;
if (dev->type == ARPHRD_ETHER)
@@ -527,10 +520,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
protocol, tunnel->parms.o_key, htonl(tunnel->o_seqno));
- /* TooBig packet may have updated dst->dev's mtu */
- if (dst && dst_mtu(dst) > dst->dev->mtu)
- dst->ops->update_pmtu(dst, NULL, skb, dst->dev->mtu);
-
return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu,
NEXTHDR_GRE);
}
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 3/5] ip6_tunnel: add the process for redirect in ip6_tnl_err
2017-11-11 11:06 [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels Xin Long
2017-11-11 11:06 ` [PATCH net-next 1/5] ip6_gre: add the process for redirect in ip6gre_err Xin Long
2017-11-11 11:06 ` [PATCH net-next 2/5] ip6_gre: process toobig in a better way Xin Long
@ 2017-11-11 11:06 ` Xin Long
2017-11-11 11:06 ` [PATCH net-next 4/5] ip6_tunnel: process toobig in a better way Xin Long
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Xin Long @ 2017-11-11 11:06 UTC (permalink / raw)
To: network dev; +Cc: davem, Yasuyuki Kozakai, Dmitry Kozlov
The same process for redirect in "ip6_gre: add the process for redirect
in ip6gre_err" is needed by ip4ip6 and ip6ip6 as well.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/ipv6/ip6_tunnel.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 439d65f..a1f704c 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -471,15 +471,16 @@ static int
ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
u8 *type, u8 *code, int *msg, __u32 *info, int offset)
{
- const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) skb->data;
- struct ip6_tnl *t;
- int rel_msg = 0;
+ const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
+ struct net *net = dev_net(skb->dev);
u8 rel_type = ICMPV6_DEST_UNREACH;
u8 rel_code = ICMPV6_ADDR_UNREACH;
- u8 tproto;
__u32 rel_info = 0;
- __u16 len;
+ struct ip6_tnl *t;
int err = -ENOENT;
+ int rel_msg = 0;
+ u8 tproto;
+ __u16 len;
/* If the packet doesn't contain the original IPv6 header we are
in trouble since we might need the source address for further
@@ -543,6 +544,10 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
rel_msg = 1;
}
break;
+ case NDISC_REDIRECT:
+ ip6_redirect(skb, net, skb->dev->ifindex, 0,
+ sock_net_uid(net, NULL));
+ break;
}
*type = rel_type;
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 4/5] ip6_tunnel: process toobig in a better way
2017-11-11 11:06 [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels Xin Long
` (2 preceding siblings ...)
2017-11-11 11:06 ` [PATCH net-next 3/5] ip6_tunnel: add the process for redirect in ip6_tnl_err Xin Long
@ 2017-11-11 11:06 ` Xin Long
2017-11-11 11:06 ` [PATCH net-next 5/5] ip6_tunnel: clean up ip4ip6 and ip6ip6's err_handlers Xin Long
2017-11-13 1:44 ` [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Xin Long @ 2017-11-11 11:06 UTC (permalink / raw)
To: network dev; +Cc: davem, Yasuyuki Kozakai, Dmitry Kozlov
The same improvement in "ip6_gre: process toobig in a better way"
is needed by ip4ip6 and ip6ip6 as well.
Note that ip4ip6 and ip6ip6 will also update sk dst pmtu in their
err_handlers. Like I said before, gre6 could not do this as it's
inner proto is not certain. But for all of them, sk dst pmtu will
be updated in tx path if in need.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/ipv6/ip6_tunnel.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a1f704c..7e9e205 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -498,9 +498,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
err = 0;
switch (*type) {
- __u32 teli;
struct ipv6_tlv_tnl_enc_lim *tel;
- __u32 mtu;
+ __u32 mtu, teli;
case ICMPV6_DEST_UNREACH:
net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n",
t->parms.name);
@@ -531,11 +530,11 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
}
break;
case ICMPV6_PKT_TOOBIG:
+ ip6_update_pmtu(skb, net, htonl(*info), 0, 0,
+ sock_net_uid(net, NULL));
mtu = *info - offset;
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
- t->dev->mtu = mtu;
-
len = sizeof(*ipv6h) + ntohs(ipv6h->payload_len);
if (len > mtu) {
rel_type = ICMPV6_PKT_TOOBIG;
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 5/5] ip6_tunnel: clean up ip4ip6 and ip6ip6's err_handlers
2017-11-11 11:06 [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels Xin Long
` (3 preceding siblings ...)
2017-11-11 11:06 ` [PATCH net-next 4/5] ip6_tunnel: process toobig in a better way Xin Long
@ 2017-11-11 11:06 ` Xin Long
2017-11-13 1:44 ` [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Xin Long @ 2017-11-11 11:06 UTC (permalink / raw)
To: network dev; +Cc: davem, Yasuyuki Kozakai, Dmitry Kozlov
This patch is to remove some useless codes of redirect and fix some
indents on ip4ip6 and ip6ip6's err_handlers.
Note that redirect icmp packet is already processed in ip6_tnl_err,
the old redirect codes in ip4ip6_err actually never worked even
before this patch. Besides, there's no need to send redirect to
user's sk, it's for lower dst, so just remove it in this patch.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/ipv6/ip6_tunnel.c | 42 ++++++++++++++----------------------------
1 file changed, 14 insertions(+), 28 deletions(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 7e9e205..00882fd 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -563,13 +563,12 @@ static int
ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
- int rel_msg = 0;
- u8 rel_type = type;
- u8 rel_code = code;
__u32 rel_info = ntohl(info);
- int err;
- struct sk_buff *skb2;
const struct iphdr *eiph;
+ struct sk_buff *skb2;
+ int err, rel_msg = 0;
+ u8 rel_type = type;
+ u8 rel_code = code;
struct rtable *rt;
struct flowi4 fl4;
@@ -594,10 +593,6 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
rel_type = ICMP_DEST_UNREACH;
rel_code = ICMP_FRAG_NEEDED;
break;
- case NDISC_REDIRECT:
- rel_type = ICMP_REDIRECT;
- rel_code = ICMP_REDIR_HOST;
- /* fall through */
default:
return 0;
}
@@ -616,33 +611,26 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
eiph = ip_hdr(skb2);
/* Try to guess incoming interface */
- rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL,
- eiph->saddr, 0,
- 0, 0,
- IPPROTO_IPIP, RT_TOS(eiph->tos), 0);
+ rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL, eiph->saddr,
+ 0, 0, 0, IPPROTO_IPIP, RT_TOS(eiph->tos), 0);
if (IS_ERR(rt))
goto out;
skb2->dev = rt->dst.dev;
+ ip_rt_put(rt);
/* route "incoming" packet */
if (rt->rt_flags & RTCF_LOCAL) {
- ip_rt_put(rt);
- rt = NULL;
rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL,
- eiph->daddr, eiph->saddr,
- 0, 0,
- IPPROTO_IPIP,
- RT_TOS(eiph->tos), 0);
- if (IS_ERR(rt) ||
- rt->dst.dev->type != ARPHRD_TUNNEL) {
+ eiph->daddr, eiph->saddr, 0, 0,
+ IPPROTO_IPIP, RT_TOS(eiph->tos), 0);
+ if (IS_ERR(rt) || rt->dst.dev->type != ARPHRD_TUNNEL) {
if (!IS_ERR(rt))
ip_rt_put(rt);
goto out;
}
skb_dst_set(skb2, &rt->dst);
} else {
- ip_rt_put(rt);
if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
skb2->dev) ||
skb_dst(skb2)->dev->type != ARPHRD_TUNNEL)
@@ -654,10 +642,9 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (rel_info > dst_mtu(skb_dst(skb2)))
goto out;
- skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), NULL, skb2, rel_info);
+ skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), NULL, skb2,
+ rel_info);
}
- if (rel_type == ICMP_REDIRECT)
- skb_dst(skb2)->ops->redirect(skb_dst(skb2), NULL, skb2);
icmp_send(skb2, rel_type, rel_code, htonl(rel_info));
@@ -670,11 +657,10 @@ static int
ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
- int rel_msg = 0;
+ __u32 rel_info = ntohl(info);
+ int err, rel_msg = 0;
u8 rel_type = type;
u8 rel_code = code;
- __u32 rel_info = ntohl(info);
- int err;
err = ip6_tnl_err(skb, IPPROTO_IPV6, opt, &rel_type, &rel_code,
&rel_msg, &rel_info, offset);
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels
2017-11-11 11:06 [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels Xin Long
` (4 preceding siblings ...)
2017-11-11 11:06 ` [PATCH net-next 5/5] ip6_tunnel: clean up ip4ip6 and ip6ip6's err_handlers Xin Long
@ 2017-11-13 1:44 ` David Miller
5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2017-11-13 1:44 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, yasuyuki.kozakai, xeb
From: Xin Long <lucien.xin@gmail.com>
Date: Sat, 11 Nov 2017 19:06:48 +0800
> Now let's say there are 3 kinds of icmp packets to process for tunnels,
> toobig(needfrag), redirect, others, their process should be:
>
> - toobig(needfrag)
> update the lower dst's pmtu by route cache, also update sk dst's pmtu
> if possible, or it will be fine if sk dst pmtu will get updated on tx
> path.
>
> - redirect
> update the lower dst's gw by route cache and return, no need to send
> this redirect packet to user sk.
>
> - others
> send the packet to user's sk, or it will also be fine to use err_count
> to count it and report fail link on tx path.
>
> All ipv4 tunnels basically follow this while some of ipv6 tunnels are
> doing in different ways, like ip6gre and ip6_tunnels update tnl dev's
> mtu instead of updating lower dst pmtu, no redirect process on their
> err_handlers, which doesn't make any sense and even causes performance
> problems.
>
> This patchset is to improve the process of redirect and toobig for ip6gre
> ip4ip6, ip6ip6 tunnels, as in ipv4 tunnels.
Series applied, thank you.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-11-13 1:44 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-11 11:06 [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels Xin Long
2017-11-11 11:06 ` [PATCH net-next 1/5] ip6_gre: add the process for redirect in ip6gre_err Xin Long
2017-11-11 11:06 ` [PATCH net-next 2/5] ip6_gre: process toobig in a better way Xin Long
2017-11-11 11:06 ` [PATCH net-next 3/5] ip6_tunnel: add the process for redirect in ip6_tnl_err Xin Long
2017-11-11 11:06 ` [PATCH net-next 4/5] ip6_tunnel: process toobig in a better way Xin Long
2017-11-11 11:06 ` [PATCH net-next 5/5] ip6_tunnel: clean up ip4ip6 and ip6ip6's err_handlers Xin Long
2017-11-13 1:44 ` [PATCH net-next 0/5] net: improve the process of redirect and toobig for ipv6 tunnels David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).