From b983e5340f8ba0051572b14f59293212ab6a4336 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 12 Aug 2020 13:12:56 -0700 Subject: [PATCH] wgengine/monitor: add, clean up netlink logging on route changes Updates #643 --- wgengine/monitor/monitor_linux.go | 73 ++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/wgengine/monitor/monitor_linux.go b/wgengine/monitor/monitor_linux.go index 651affc39..d832fdf8d 100644 --- a/wgengine/monitor/monitor_linux.go +++ b/wgengine/monitor/monitor_linux.go @@ -87,28 +87,39 @@ func (c *nlConn) Receive() (message, error) { Addr: netaddrIP(rmsg.Attributes.Local), Delete: msg.Header.Type == unix.RTM_DELADDR, }, nil - case unix.RTM_NEWROUTE: + case unix.RTM_NEWROUTE, unix.RTM_DELROUTE: + typeStr := "RTM_NEWROUTE" + if msg.Header.Type == unix.RTM_DELROUTE { + typeStr = "RTM_DELROUTE" + } var rmsg rtnetlink.RouteMessage if err := rmsg.UnmarshalBinary(msg.Data); err != nil { - c.logf("RTM_NEWROUTE: failed to parse: %v", err) + c.logf("%s: failed to parse: %v", typeStr, err) + return unspecifiedMessage{}, nil + } + src := netaddrIPPrefix(rmsg.Attributes.Src, rmsg.SrcLength) + dst := netaddrIPPrefix(rmsg.Attributes.Dst, rmsg.DstLength) + gw := netaddrIP(rmsg.Attributes.Gateway) + + if msg.Header.Type == unix.RTM_NEWROUTE && rmsg.Table == tsTable && rmsg.DstLength == 32 { + // Don't log. Spammy and normal to see a bunch of these on start-up, + // which we make ourselves. + } else { + c.logf("%s: src=%v, dst=%v, gw=%v, outif=%v, table=%v", typeStr, + condNetAddrPrefix(src), condNetAddrPrefix(dst), condNetAddrIP(gw), + rmsg.Attributes.OutIface, rmsg.Attributes.Table) + } + if msg.Header.Type == unix.RTM_DELROUTE { + // Just logging it for now. + // (Debugging https://github.com/tailscale/tailscale/issues/643) return unspecifiedMessage{}, nil } return &newRouteMessage{ Table: rmsg.Table, - Src: netaddrIP(rmsg.Attributes.Src), - Dst: netaddrIP(rmsg.Attributes.Dst), - Gateway: netaddrIP(rmsg.Attributes.Gateway), + Src: src, + Dst: dst, + Gateway: gw, }, nil - case unix.RTM_DELROUTE: - var rmsg rtnetlink.RouteMessage - if err := rmsg.UnmarshalBinary(msg.Data); err != nil { - c.logf("RTM_DELROUTE: failed to parse: %v", err) - return unspecifiedMessage{}, nil - } - // Just log it for now, but don't bubble it up. - // (Debugging https://github.com/tailscale/tailscale/issues/643) - c.logf("RTM_DELROUTE: %+v", rmsg) - return unspecifiedMessage{}, nil default: c.logf("unhandled netlink msg type %+v, %q", msg.Header, msg.Data) return unspecifiedMessage{}, nil @@ -120,14 +131,36 @@ func netaddrIP(std net.IP) netaddr.IP { return ip } -// newRouteMessage is a message for a new route being added. -type newRouteMessage struct { - Src, Dst, Gateway netaddr.IP - Table uint8 +func netaddrIPPrefix(std net.IP, bits uint8) netaddr.IPPrefix { + ip, _ := netaddr.FromStdIP(std) + return netaddr.IPPrefix{IP: ip, Bits: bits} } +func condNetAddrPrefix(ipp netaddr.IPPrefix) string { + if ipp.IP.IsZero() { + return "" + } + return ipp.String() +} + +func condNetAddrIP(ip netaddr.IP) string { + if ip.IsZero() { + return "" + } + return ip.String() +} + +// newRouteMessage is a message for a new route being added. +type newRouteMessage struct { + Src, Dst netaddr.IPPrefix + Gateway netaddr.IP + Table uint8 +} + +const tsTable = 52 + func (m *newRouteMessage) ignore() bool { - return m.Table == 88 || tsaddr.IsTailscaleIP(m.Dst) + return m.Table == tsTable || tsaddr.IsTailscaleIP(m.Dst.IP) } // newAddrMessage is a message for a new address being added.