DORMANTno replies

[PATCH] net/ipv6/ip6_gre.c NBMA support

From: Aleksey Shumnik <hidden>
Date: 2022-08-30 15:21:05
Subsystem: networking [general], networking [ipv4/ipv6], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds

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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help