-
Notifications
You must be signed in to change notification settings - Fork 797
Description
Netlink still makes use of Golang's net package, instead of the newer netip package to represent prefixes and addresses. In multiple instances netlink checks if a user-given address is a IPv4 or an IPv6 address via nl.GetIPFamily(). This function calls ip.To4() and if this returns anything other than nil we identify ip to be a IPv4 address. The problem is that the function contract is not that .To4 returns not-nil for IPv4 addresses but it returns non-nil if the address can be represented as IPv4. The second definition includes IPv4-mapped IPv6 addresses, while the first does not.
Example:
I want to create the following route entry:
2300:5800:ab00::2 via ::ffff:100.95.128.2 dev br3 proto bgp onlink
With ip one can do this by calling:
ip route add 2300:5800:ab00::2 via ::ffff:100.95.128.2 dev br3 proto bgp onlink
One would assume that the following Go code works:
nlh.RouteAdd(
&netlink.Route{
LinkIndex: remoteBridge.Attrs().Index, // some index
Dst: route.Dst, // 2300:5800:ab00::2/128
Gw: hostAddress.AsSlice(), //::ffff:100.95.128.2
Flags: int(unix.RTNH_F_ONLINK), // onlink
Protocol: 186, // bgp
},
)But it returns gateway, source, and destination ip are not the same IP family since it translates the Gw to an IPv4 first. Moreover, there's no way to override this interpretation with e.g., another Family field.
Note that this behavior exists in multiple places around the code and not only in nl.GetIPFamily(). For example, in neighHandle() there's an direct call to .To4 to again decide if an address is a IPv4 or IPv6.
related issue: #908
Interestingly, changing Gw with a Via struct also doesn't work:
nlh.RouteAdd(
&netlink.Route{
LinkIndex: remoteBridge.Attrs().Index, // some index
Dst: route.Dst, // 2300:5800:ab00::2/128
Via: &netlink.Via{
AddrFamily: netlink.FAMILY_V6,
Addr: hostAddress.AsSlice(), //::ffff:100.95.128.2
},
Flags: int(unix.RTNH_F_ONLINK), // onlink
Protocol: 186, // bgp
},
)As this returns invalid argument. Though I haven't debugged the reason for this one yet.