mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-22 16:34:25 +01:00
feat: support via gateway for v6 multihop for v4 routes (#1521)
Co-authored-by: Nate Brown <nbrown.us@gmail.com>
This commit is contained in:
@@ -586,48 +586,42 @@ func (t *tun) isGatewayInVpnNetworks(gwAddr netip.Addr) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *tun) getGatewaysFromRoute(r *netlink.Route) routing.Gateways {
|
func (t *tun) getGatewaysFromRoute(r *netlink.Route) routing.Gateways {
|
||||||
|
|
||||||
var gateways routing.Gateways
|
var gateways routing.Gateways
|
||||||
|
|
||||||
link, err := netlink.LinkByName(t.Device)
|
link, err := netlink.LinkByName(t.Device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.l.WithField("Devicename", t.Device).Error("Ignoring route update: failed to get link by name")
|
t.l.WithField("deviceName", t.Device).Error("Ignoring route update: failed to get link by name")
|
||||||
return gateways
|
return gateways
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this route is relevant to our interface and there is a gateway then add it
|
// If this route is relevant to our interface and there is a gateway then add it
|
||||||
if r.LinkIndex == link.Attrs().Index && len(r.Gw) > 0 {
|
if r.LinkIndex == link.Attrs().Index {
|
||||||
gwAddr, ok := netip.AddrFromSlice(r.Gw)
|
gwAddr, ok := getGatewayAddr(r.Gw, r.Via)
|
||||||
if !ok {
|
if ok {
|
||||||
t.l.WithField("route", r).Debug("Ignoring route update, invalid gateway address")
|
if t.isGatewayInVpnNetworks(gwAddr) {
|
||||||
} else {
|
|
||||||
gwAddr = gwAddr.Unmap()
|
|
||||||
|
|
||||||
if !t.isGatewayInVpnNetworks(gwAddr) {
|
|
||||||
// Gateway isn't in our overlay network, ignore
|
|
||||||
t.l.WithField("route", r).Debug("Ignoring route update, not in our network")
|
|
||||||
} else {
|
|
||||||
gateways = append(gateways, routing.NewGateway(gwAddr, 1))
|
gateways = append(gateways, routing.NewGateway(gwAddr, 1))
|
||||||
|
} else {
|
||||||
|
// Gateway isn't in our overlay network, ignore
|
||||||
|
t.l.WithField("route", r).Debug("Ignoring route update, gateway is not in our network")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
t.l.WithField("route", r).Debug("Ignoring route update, invalid gateway or via address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range r.MultiPath {
|
for _, p := range r.MultiPath {
|
||||||
// If this route is relevant to our interface and there is a gateway then add it
|
// If this route is relevant to our interface and there is a gateway then add it
|
||||||
if p.LinkIndex == link.Attrs().Index && len(p.Gw) > 0 {
|
if p.LinkIndex == link.Attrs().Index {
|
||||||
gwAddr, ok := netip.AddrFromSlice(p.Gw)
|
gwAddr, ok := getGatewayAddr(p.Gw, p.Via)
|
||||||
if !ok {
|
if ok {
|
||||||
t.l.WithField("route", r).Debug("Ignoring multipath route update, invalid gateway address")
|
if t.isGatewayInVpnNetworks(gwAddr) {
|
||||||
} else {
|
|
||||||
gwAddr = gwAddr.Unmap()
|
|
||||||
|
|
||||||
if !t.isGatewayInVpnNetworks(gwAddr) {
|
|
||||||
// Gateway isn't in our overlay network, ignore
|
|
||||||
t.l.WithField("route", r).Debug("Ignoring route update, not in our network")
|
|
||||||
} else {
|
|
||||||
// p.Hops+1 = weight of the route
|
|
||||||
gateways = append(gateways, routing.NewGateway(gwAddr, p.Hops+1))
|
gateways = append(gateways, routing.NewGateway(gwAddr, p.Hops+1))
|
||||||
|
} else {
|
||||||
|
// Gateway isn't in our overlay network, ignore
|
||||||
|
t.l.WithField("route", r).Debug("Ignoring route update, gateway is not in our network")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
t.l.WithField("route", r).Debug("Ignoring route update, invalid gateway or via address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -636,10 +630,27 @@ func (t *tun) getGatewaysFromRoute(r *netlink.Route) routing.Gateways {
|
|||||||
return gateways
|
return gateways
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGatewayAddr(gw net.IP, via netlink.Destination) (netip.Addr, bool) {
|
||||||
|
// Try to use the old RTA_GATEWAY first
|
||||||
|
gwAddr, ok := netip.AddrFromSlice(gw)
|
||||||
|
if !ok {
|
||||||
|
// Fallback to the new RTA_VIA
|
||||||
|
rVia, ok := via.(*netlink.Via)
|
||||||
|
if ok {
|
||||||
|
gwAddr, ok = netip.AddrFromSlice(rVia.Addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if gwAddr.IsValid() {
|
||||||
|
gwAddr = gwAddr.Unmap()
|
||||||
|
return gwAddr, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return netip.Addr{}, false
|
||||||
|
}
|
||||||
|
|
||||||
func (t *tun) updateRoutes(r netlink.RouteUpdate) {
|
func (t *tun) updateRoutes(r netlink.RouteUpdate) {
|
||||||
|
|
||||||
gateways := t.getGatewaysFromRoute(&r.Route)
|
gateways := t.getGatewaysFromRoute(&r.Route)
|
||||||
|
|
||||||
if len(gateways) == 0 {
|
if len(gateways) == 0 {
|
||||||
// No gateways relevant to our network, no routing changes required.
|
// No gateways relevant to our network, no routing changes required.
|
||||||
t.l.WithField("route", r).Debug("Ignoring route update, no gateways")
|
t.l.WithField("route", r).Debug("Ignoring route update, no gateways")
|
||||||
|
|||||||
Reference in New Issue
Block a user