[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CAJGXZLhT3njx-Vvy=kK6WfD4BEmO=tWcASehpiZ18G-k7k++eg@mail.gmail.com>
Date: Tue, 30 Aug 2022 18:20:48 +0300
From: Aleksey Shumnik <ashumnik9@...il.com>
To: netdev@...r.kernel.org
Cc: Jakub Kicinski <kuba@...nel.org>, xeb@...l.ru,
kuznet@....inr.ac.ru, David Ahern <dsahern@...il.com>,
Ido Schimmel <idosch@...sch.org>
Subject: [PATCH] net/ipv6/ip6_gre.c NBMA support
Dear Maintainers,
While I was studying the capabilities of the ip6_gre driver to support
NBMA networks, I found a bug:
When sending a packet over the NBMA network, the following sequence of
functions occurs:
ip6gre_tunnel_xmit() -> ip6_tnl_xmit_ctl() -> ip6_tnl_get_cap() ->
...
if (ltype == IPV6_ADDR_ANY || rtype == IPV6_ADDR_ANY) {
flags = IP6_TNL_F_CAP_PER_PACKET;
...
After that, the packages are dropped, but if skip ip6_tnl_xmit_ctl()
ip6gre_tunnel_xmit() -> ip6gre_xmit_ipv4() / ip6gre_xmit_ipv6() /
ip6gre_xmit_other() -> __gre6_xmit() -> ip6_tnl_xmit() ->
...
/* NBMA tunnel */
if (ipv6_addr_any(&t->parms.raddr)) {
...
It is strange that at first when checking addr_type == IPV6_ADDR_ANY
packages are dropped, but after that there is ipv6_addr_any(addr)
which leads to neigh_lookup() end etc.
It turns out that the same check leads to different actions. In
addition, due to the fact that the package is dropped, there is no
neighbor_lookup and the package will not be sent.
It looks like ip6_gre supports NBMA, but does not allow it to work,
because of this and other possible bugs.
This is most likely not the final patch, but for now I offer such a
patch to solve the problem.
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index a9051df..34c6c5b 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -896,8 +896,14 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
if (!pskb_inet_may_pull(skb))
goto tx_err;
- if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
- goto tx_err;
+ if (dev->header_ops) {
+ const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
+ if (!ip6_tnl_xmit_ctl(t, &ipv6h->saddr, &ipv6h->daddr))
+ goto tx_err;
+ } else {
+ if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
+ goto tx_err;
+ }
switch (skb->protocol) {
case htons(ETH_P_IP):
If the network is NBMA, then the remote address is not set in the
tunnel parameters, and then the packets will always drop on the
ip6_tnl_xmit_ctl() function, I propose a solution, if there is an ipv6
header in skb, then take the destination and source addresses from
skb, and not from the tunnel parameters.
Powered by blists - more mailing lists