FRRouting / frr

The FRRouting Protocol Suite
https://frrouting.org/
Other
3.27k stars 1.24k forks source link

FreeBSD / zebra / connected: GRE tunnels always unnumbered: peer / tunnel prefixlen vs. local prefixlen #3973

Open wowczarek opened 5 years ago

wowczarek commented 5 years ago

Description

FreeBSD. Migrated from 3.0.2 to 5.x. GRE tunnels used to run ospfd happily. After the move to frr 5, all GRE tunnels became unconditionally unnumbered, which broke all OSPF links, the only workaround was to set the all the other ends (not FRR) as unnumbered, borrowing from loopbacks. They all used to be happy /30s.

Since 3.0.2, the change was introduced where prefixlen == 32 sets IFA_UNNUMBERED. This in itself makes sense. However, at least in FreeBSD, the local end shows /32 and that is checked, not the point to point prefix length / tunnel subnet mask. GRE is one example but this probably applies to other p-t-p links like VTIs and whatnot.

So in 3.0.2 this probably worked only because /32 did not set IFA_UNNUMBERED.

Steps to Reproduce

  1. Bring up a GRE tunnel, say a /30 with local .1 and peer .2, optionally make it an active OSPF link
  2. This:
    vtysh
    show int gre[n]
    show ip ospf int gre[n]

Expected behavior: I would expect the interface not to be unnumbered.

Actual behavior: ospfd:

  This interface is UNNUMBERED, Area 0.0.0.0

show int gre[n]: Tunnel mask is not /32:

  inet x.x.x.1/32 peer x.x.x.2/30 unnumbered

Components

frr 5.0.1 release, frr 5.0.2 release, zebra / ospfd

Versions

Attachments

None available, but easily reproducible.

nicolerenee commented 5 years ago

I’m also seeing this issue when trying to connect to other vendor routers. The routes don’t get applied on the far end because the system can’t figure out the next hip since it’s reporting an IP of ‘0.0.0.7’.

begetan commented 5 years ago

I can confirm that this issue exists on different tunnel interfaces. We have tested gif and ipsec both.

Tested on FreeBSD 11.2, FreeBSD 12.0 FRR 6.0.2 This issue breaks normal operation of OSPF protocol. For example, command ospf network aren't working correctly.

For example Frr 3.0.2 on FreeBSD 10.3 works well. This commit broke things: https://github.com/FRRouting/frr/commit/abffde07a3f89f77dc45b7660323e41c39d4113c

FreeBSD has a slightly different way of determination of unbound configuration, so new patch always makes all tunnel interfaces as unnumbered, and force adds /32 mask for normally configured /30 tunnels. This breaks next-hop resolution process in OSPF + iBGP configuration

wowczarek commented 5 years ago

This commit broke things: abffde0

That's the one, yes.

tungdam commented 4 years ago

We got the same issue with version 6.0.2-2, debian10. Please consider fixing this

wowczarek commented 4 years ago

Interestingly, this is not an issue with ospfv3 where the interfaces show up correctly as point to point rather than unnumbered, and since ospf3 supports both inet and inet6, one of the workarounds that may be easier than force-switching to unnumbered, is to simply move to ospfv3 for both ipv4 and ipv6.

wowczarek commented 3 years ago

I think it really comes down to this:

zebra/connected.c IS:

            if (ifc->address->prefixlen == 32)
                    SET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
            else
                    UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);

zebra/connected.c SHOULD BE:

            if (CONNECTED_PEER(ifc)) {
                if(ifc->destination->prefixlen == 32)
                    SET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
                else
                    UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);

            } else {
                if(ifc->address->prefixlen == 32)
                    SET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
                else
                    UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
            }

Assuming that the assertion /32 == unnumbered is correct, for point to point interfaces, we should be looking at the destination netmask to establish this. This should, in theory, fix the issue, just need to test this. Again, assuming that the connected flag is already set when this is being looked at, which it probably is.

Clearly the issue is not specific to FreeBSD but rather all platforms, since this is common code - specifically platforms where these types of interfaces have the peer flag. On Linux this is not the case for GRE, hence not an issue.

Linux (show int gre1):

  inet 10.72.30.1/30

FreeBSD (show int gre1), which shows this exact problem:

  inet 10.72.30.1/32 peer 10.72.30.2/30 unnumbered
wowczarek commented 3 years ago

Ha, looks like someone's picked this up via pfsense bug tracker and tested this for me. Confirmed that this fixes the issue in FreeBSD - gre no longer shows up as unnumbered. I'll submit a PR.

makton-dev commented 3 years ago

Wanted to update.. PFSense is using 7.5.1_1 for FRR. I grabbed that, updated the connected.c as stated above, compiled it (using the compile config from PFSense) and copied the updated zebra executable over to the PFSense router. Problem is now resolved for me and my router has joined the 2 needed neighbors. Netgate will not update packages till this is pushed up and I needed this fix now, for the work I'm doing. Many thanks to @wowczarek for the fix!!

Waffle2 commented 3 years ago

Thank you - I confirm it works perfect on my system as well!

blakangel commented 2 years ago

Just want to chime in - this was a big showstopper for us at work when we did pfSense upgrades to 2.5. We ended up deploying custom frr package w/ the above patch and all our pfsense <-> Cisco GRE tunnels are now functioning normally. Thank you for the patch!

Vorona commented 2 years ago

I Use Opnsense: OPNsense 21.7.6-amd64FreeBSD 12.1-RELEASE-p21-HBSDOpenSSL 1.1.1l 24 Aug 2021

FRR version: gate# show version FRRouting 7.5.1 (gate). Copyright 1996-2005 Kunihiro Ishiguro, et al. configured with: '--enable-user=frr' '--enable-group=frr' '--enable-vty-group=frrvty' '--disable-doc-html' '--sysconfdir=/usr/local/etc/frr' '--localstatedir=/var/run/frr' '--disable-backtrace' '--disable-nhrpd' '--disable-pimd' '--disable-vrrpd' '--with-vtysh-pager=cat' '--disable-config-rollbacks' '--disable-datacenter' '--enable-fpm' '--disable-ldpd' '--without-libpam' '--enable-rpki' '--disable-shell-access' '--disable-snmp' '--disable-tcmalloc' '--enable-vtysh' '--prefix=/usr/local' '--mandir=/usr/local/man' '--disable-silent-rules' '--infodir=/usr/local/share/info/' '--build=amd64-portbld-freebsd12.2' 'build_alias=amd64-portbld-freebsd12.2' 'PKG_CONFIG=pkgconf' 'CC=cc' 'CFLAGS=-O2 -pipe -fstack-protector-strong -fno-strict-aliasing ' 'LDFLAGS= -L/usr/local/lib -L/usr/local/lib -fstack-protector-strong ' 'LIBS=' 'CPPFLAGS=-I/usr/local/include -I/usr/local/include' 'CPP=cpp' 'CXX=c++' 'CXXFLAGS=-O2 -pipe -fstack-protector-strong -fno-strict-aliasing ' 'PYTHON=/usr/local/bin/python3.8'

same issue:

gate# show ip ospf interface gre1 gre1 is up ifindex 10, MTU 1476 bytes, BW 0 Mbit <UP,POINTOPOINT,RUNNING,MULTICAST> This interface is UNNUMBERED, Area 172.16.117.0 MTU mismatch detection: enabled Router ID 172.26.0.1, Network Type POINTOPOINT, Cost: 10 Transmit Delay is 1 sec, State Point-To-Point, Priority 1 No backup designated router on this network Multicast group memberships: OSPFAllRouters Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5 Hello due in 5.018s Neighbor Count is 1, Adjacent neighbor count is 1

gate# show interface gre1 Interface gre1 is up, line protocol is up Link ups: 1 last: 2021/12/07 17:37:21.41 Link downs: 0 last: (never) vrf: default index 10 metric 1 mtu 1476 speed 0 flags: <UP,POINTOPOINT,RUNNING,MULTICAST> Type: Unknown inet 100.100.100.41/32 peer 100.100.100.42/30 unnumbered inet6 fe80::803f:8828:7c0:2a13/64 Interface Type Other Interface Slave Type None input packets 6913, bytes 1141987, dropped 0, multicast packets 0 input errors 0 output packets 6966, bytes 1225693, multicast packets 0 output errors 59 collisions 0