|
|
|
@ -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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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, Gateway netaddr.IP
|
|
|
|
|
Table uint8
|
|
|
|
|
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.
|
|
|
|
|