Repository: moby/moby
File: libnetwork/drivers/bridge/internal/rlkclient/rootlesskit_client_linux.go (Go)

Code before:
	}

	if _, ok := c.protos[apiProto]; !ok {
		// This happens when apiProto="tcp6", portDriverName="slirp4netns",
		// because "slirp4netns" port driver does not support listening on IPv6 yet.
		//
		// Note that "slirp4netns" port driver is not used by default,
		// even when network driver is set to "slirp4netns".
		//
		// Most users are using "builtin" port driver and will not see this warning.
		return nil, fmt.Errorf("protocol %q is not supported by the RootlessKit port driver %q, discarding request for %q",
			proto,
			c.portDriverName,
			net.JoinHostPort(hostIP.String(), strconv.Itoa(hostPort)))
	}

	pm := c.client.PortManager()
	p := port.Spec{
		Proto:      apiProto,
		ParentIP:   hostIP.String(),
		ParentPort: hostPort,
		ChildIP:    childIP.String(),
		ChildPort:  hostPort,
	}
	st, err := pm.AddPort(ctx, p)
	if err != nil {
		return nil, fmt.Errorf("error while calling RootlessKit PortManager.AddPort(): %w", err)
	}
	deferFunc := func() error {
		if dErr := pm.RemovePort(context.WithoutCancel(ctx), st.ID); dErr != nil {
			return fmt.Errorf("error while calling RootlessKit PortManager.RemovePort(): %w", dErr)
		}
		return nil
	}
	return deferFunc, nil
}


Review comment (suggestion):
Related to that; I see at the start of this function we have logic for if there's no portdriverclient, in which case we return a stub remover func;

```
return func() error { return nil }, nil
```


(again, just exploring what would make "we tried to map the port, weren't able to, but it's ok to skip this port" fit into existing logic)

Code after:
	// for libnetwork >= 20201216
	//
	// See https://github.com/moby/libnetwork/pull/2604/files#diff-8fa48beed55dd033bf8e4f8c40b31cf69d0b2cc5d4bb53cde8594670ea6c938aR20
	// See also https://github.com/rootless-containers/rootlesskit/issues/231
	apiProto := proto
	if !strings.HasSuffix(apiProto, "4") && !strings.HasSuffix(apiProto, "6") {
		if hostIP.Is6() {
			apiProto += "6"
		} else {
			apiProto += "4"
		}
	}

	if _, ok := c.protos[apiProto]; !ok {
		// This happens when apiProto="tcp6", portDriverName="slirp4netns",
		// because "slirp4netns" port driver does not support listening on IPv6 yet.
		//
		// Note that "slirp4netns" port driver is not used by default,
		// even when network driver is set to "slirp4netns".
		//
		// Most users are using "builtin" port driver and will not see this warning.
		err := &ProtocolUnsupportedError{
			apiProto:       apiProto,
			portDriverName: c.portDriverName,
		}
		return nil, err
	}

	pm := c.client.PortManager()
	p := port.Spec{
		Proto:      apiProto,
		ParentIP:   hostIP.String(),
		ParentPort: hostPort,
		ChildIP:    childIP.String(),
		ChildPort:  hostPort,
	}
	st, err := pm.AddPort(ctx, p)
	if err != nil {
		return nil, fmt.Errorf("error while calling RootlessKit PortManager.AddPort(): %w", err)
	}
	deferFunc := func() error {
		if dErr := pm.RemovePort(context.WithoutCancel(ctx), st.ID); dErr != nil {
			return fmt.Errorf("error while calling RootlessKit PortManager.RemovePort(): %w", dErr)
		}
		return nil
	}
	return deferFunc, nil
}