fix(cubelet): name sandbox TAPs after IPv4 and reject oversize names - #1552
Conversation
| if isTapNotFound(err) { | ||
| continue | ||
| } | ||
| return err |
There was a problem hiding this comment.
The new two-candidate loop only treats LinkNotFoundError as "try the next name"; every other GetByName error aborts. But getTapByName returns a hard error for a device that exists under the candidate name yet is not a Cube TAP — e.g. "%s is not tap" when the link is a non-Tuntap netdev, or "not cube tap: %s" when the name fails parseCubeTapIP. So a host with an unrelated netdev named exactly like an allocated sandbox IP (a dummy/bridge/VXLAN given a dotted-quad name — the same kind of device your new TestListCubeTapsAcceptsBothNamesAndFiltersCIDR fixture includes as a netlink.Device named 192.168.0.12) will make the first iteration return "<ip> is not tap" and abort before ever consulting the legacy z<ip> candidate that this loop exists to find. The create then fails with a misleading error, and a genuinely stale legacy TAP at z<ip> is never destroyed.
listCubeTaps already tolerates such devices (it skips non-TUNTAP_MODE_TAP links), so getTapByName/cleanupConflictingTap should be consistent: treat "device exists but is not a Cube TAP" as "no conflicting tap under this name — continue", and only propagate real netlink errors.
There was a problem hiding this comment.
That makes sense.
Review: fix(cubelet): name sandbox TAPs after IPv4 and reject oversize names (#1552)AI-generated review — not human-approved. OverviewThe root cause is real and the fix is sound. I verified the diff compiles against the base tree (all callers of the changed Findings1. Missing explicit IFNAMSIZ guard — PR description overstates the code (low)The description says "Create fails before LinkAdd if the name is >= IFNAMSIZ", but no such guard exists: 2. Bare-IPv4 names drop the
|
| func candidateTapNames(ip string) []string { | ||
| current := tapName(ip) | ||
| legacy := legacyTapName(ip) | ||
| if current == legacy { |
There was a problem hiding this comment.
What does this check mean?
| func newTap(ip net.IP, mvmMacAddr string, mtu, cubeDevIdx int) (_ *tapDevice, retErr error) { | ||
| logger := CubeLog.WithContext(context.Background()) | ||
| name := tapName(ip.String()) | ||
| if err := validateTapName(name); err != nil { |
There was a problem hiding this comment.
This seems unnecessary.
| // parseCubeTapIP reverses tapName / legacyTapName and rejects unrelated host | ||
| // TAP devices. Both "192.168.0.10" and "z192.168.0.10" map to the same IPv4. | ||
| func parseCubeTapIP(name string) (net.IP, error) { | ||
| if ip := net.ParseIP(name).To4(); ip != nil { |
There was a problem hiding this comment.
Always trim prefix and parse IP?
The z+IPv4 scheme produced 16-byte names (e.g. z192.168.195.183). vishvananda/netlink LinkAdd copies into ifr_name[:15] and truncates silently, so create could succeed while later open/query used a different string than the kernel device. New creates use the dotted IPv4. Recover still accepts leftover z-prefixed names when the decoded address is in the configured sandbox CIDR. Signed-off-by: yarrischen <yarrischen@tencent.com> Co-authored-by: Cursor <cursoragent@cursor.com>
12218cd to
8ed36a2
Compare
| } | ||
|
|
||
| // tapName derives the deterministic host TAP name for a sandbox IP. | ||
| // New devices use the dotted IPv4; that string is at most 15 bytes and always |
There was a problem hiding this comment.
The PR description states "Create fails before LinkAdd if the name is >= IFNAMSIZ", but no such guard exists in this diff. newTap still calls netlink.LinkAdd(tapConfig) directly with name := tapName(ip.String()) (tap_device.go:130) — and tapName here just returns the input verbatim.
The fix works only because a dotted-quad IPv4 string is at most 15 bytes (e.g. 255.255.255.255), so the 16-byte z<ipv4> overflow can no longer occur. But TapDeviceAdapter.Create accepts any net.IP, and nothing prevents an IPv6 address (or any other 16+ char input) from reaching newTap in the future — in which case netlink.LinkAdd will silently truncate the name again and reproduce the exact bug this PR fixes.
Suggest making the described invariant explicit, e.g. in newTap:
name := tapName(ip.String())
if len(name) >= unix.IFNAMSIZ {
return nil, fmt.Errorf("tap name %q exceeds IFNAMSIZ", name)
}
The z+IPv4 scheme produced 16-byte names (e.g. z192.168.195.183). vishvananda/netlink LinkAdd copies into ifr_name[:15] and truncates silently, so create could succeed while later open/query used a different string than the kernel device.
New creates use the dotted IPv4. Recover still accepts leftover z-prefixed names when the decoded address is in the configured sandbox CIDR. Create fails before LinkAdd if the name is >= IFNAMSIZ.