diff --git a/wgengine/monitor/monitor_linux.go b/wgengine/monitor/monitor_linux.go index d705ed261..c3ca126fe 100644 --- a/wgengine/monitor/monitor_linux.go +++ b/wgengine/monitor/monitor_linux.go @@ -15,10 +15,13 @@ import ( "github.com/mdlayher/netlink" "golang.org/x/sys/unix" "inet.af/netaddr" + "tailscale.com/envknob" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" ) +var debugNetlinkMessages = envknob.Bool("TS_DEBUG_NETLINK") + // unspecifiedMessage is a minimal message implementation that should not // be ignored. In general, OS-specific implementations should use better // types and avoid this if they can. @@ -82,11 +85,16 @@ func (c *nlConn) Receive() (message, error) { c.logf("failed to parse type %v: %v", msg.Header.Type, err) return unspecifiedMessage{}, nil } - return &newAddrMessage{ + + nam := &newAddrMessage{ Label: rmsg.Attributes.Label, Addr: netaddrIP(rmsg.Attributes.Local), Delete: msg.Header.Type == unix.RTM_DELADDR, - }, nil + } + if debugNetlinkMessages { + c.logf("%+v", nam) + } + return nam, nil case unix.RTM_NEWROUTE, unix.RTM_DELROUTE: typeStr := "RTM_NEWROUTE" if msg.Header.Type == unix.RTM_DELROUTE { @@ -104,6 +112,11 @@ func (c *nlConn) Receive() (message, error) { if msg.Header.Type == unix.RTM_NEWROUTE && (rmsg.Attributes.Table == 255 || rmsg.Attributes.Table == 254) && (dst.IP().IsMulticast() || dst.IP().IsLinkLocalUnicast()) { + + if debugNetlinkMessages { + c.logf("%s ignored", typeStr) + } + // Normal Linux route changes on new interface coming up; don't log or react. return ignoreMessage{}, nil } @@ -126,12 +139,17 @@ func (c *nlConn) Receive() (message, error) { // (Debugging https://github.com/tailscale/tailscale/issues/643) return unspecifiedMessage{}, nil } - return &newRouteMessage{ + + nrm := &newRouteMessage{ Table: rmsg.Table, Src: src, Dst: dst, Gateway: gw, - }, nil + } + if debugNetlinkMessages { + c.logf("%+v", nrm) + } + return nrm, nil case unix.RTM_NEWRULE: // Probably ourselves adding it. return ignoreMessage{}, nil @@ -147,10 +165,14 @@ func (c *nlConn) Receive() (message, error) { // On `ip -4 rule del pref 5210 table main`, logs: // monitor: ip rule deleted: {Family:2 DstLength:0 SrcLength:0 Tos:0 Table:254 Protocol:0 Scope:0 Type:1 Flags:0 Attributes:{Dst: Src: Gateway: OutIface:0 Priority:5210 Table:254 Mark:4294967295 Expires: Metrics: Multipath:[]}} } - return ipRuleDeletedMessage{ + rdm := ipRuleDeletedMessage{ table: rmsg.Table, priority: rmsg.Attributes.Priority, - }, nil + } + if debugNetlinkMessages { + c.logf("%+v", rdm) + } + return rdm, nil default: c.logf("unhandled netlink msg type %+v, %q", msg.Header, msg.Data) return unspecifiedMessage{}, nil