Repository: moby/moby
File: libnetwork/drivers/bridge/bridge_linux.go (Go)

Code before:

			endpoint.addrv6 = &net.IPNet{IP: ip6, Mask: network.Mask}
			if err = ifInfo.SetIPAddress(endpoint.addrv6); err != nil {
				return err
			}
		}
	}

	if err = d.storeUpdate(ctx, endpoint); err != nil {
		return fmt.Errorf("failed to save bridge endpoint %.7s to store: %v", endpoint.id, err)
	}

	return nil
}

// createVeth creates a veth device with one end in the container's network namespace,
// if it can get hold of the netns path and open the handles. In that case, it returns
// a netlink handle in the container's namespace that must be closed by the caller.
//
// If the netns path isn't available, possibly because the netns hasn't been created
// yet, or it's not possible to get a netns or netlink handle in the container's
// namespace - both ends of the veth device are created in nlh's netns, and no netlink
// handle is returned.
//
// (Only the error from creating the interface is returned. Failure to create the
// interface in the container's netns is not an error.)
func createVeth(ctx context.Context, hostIfName, containerIfName string, ifInfo driverapi.InterfaceInfo, nlh nlwrap.Handle) (nlhCtr *nlwrap.Handle, retErr error) {
	veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0},
		PeerName:  containerIfName,
	}

	if nspath := ifInfo.NetnsPath(); nspath == "" {
		log.G(ctx).WithField("ifname", containerIfName).Debug("No container netns path, creating interface in host netns")
	} else if netnsh, err := netns.GetFromPath(nspath); err != nil {
		log.G(ctx).WithFields(log.Fields{
			"error":  err,
			"netns":  nspath,
			"ifname": containerIfName,
		}).Warn("No container netns, creating interface in host netns")
	} else {
		defer netnsh.Close()

		if nh, err := nlwrap.NewHandleAt(netnsh, syscall.NETLINK_ROUTE); err != nil {
			log.G(ctx).WithFields(log.Fields{
				"error": err,
				"netns": nspath,
			}).Warn("No netlink handle for container, creating interface in host netns")
		} else {
			defer func() {
				if retErr != nil {

Review comment (bug):
I was about to ask whether the underlying error should be preserved (`%w`), but then noticed that `types.InternalErrorf` uses `fmt.Sprintf`, which doesn't allow `%w`.

And then I noticed that libnetwork's `InternalError` does _NOT_ implement `errdefs.System`, which may be _intentional_ or _unintentional_, but something to look into.

(It not implementing `errdefs.System` or any other `errdefs` will mean that while it gets returned as a 500 status, it will also trigger the "FIXME" debug logs; https://github.com/moby/moby/blob/29e2353f8041521bf38438142643a7bf2fa2936b/api/server/httpstatus/status.go#L64-L68


In either case; I started to somewhat dismantle the libnetwork errors; first step is in;

- https://github.com/moby/moby/pull/49318

Code after:
			"netns":  nspath,
			"ifname": containerIfName,
		}).Warn("No container netns, creating interface in host netns")
	} else {
		defer netnsh.Close()

		if nh, err := nlwrap.NewHandleAt(netnsh, syscall.NETLINK_ROUTE); err != nil {
			log.G(ctx).WithFields(log.Fields{
				"error": err,
				"netns": nspath,
			}).Warn("No netlink handle for container, creating interface in host netns")
		} else {
			defer func() {
				if retErr != nil {
					nh.Close()
				}
			}()

			veth.PeerNamespace = netlink.NsFd(netnsh)
			nlhCtr = &nh
			ifInfo.SetCreatedInContainer(true)
		}
	}

	if err := nlh.LinkAdd(veth); err != nil {
		return nil, types.InternalErrorf("failed to add the host (%s) <=> sandbox (%s) pair interfaces: %v", hostIfName, containerIfName, err)
	}
	return nlhCtr, nil
}

func (d *driver) linkUp(ctx context.Context, host netlink.Link) error {
	ctx, span := otel.Tracer("").Start(ctx, "libnetwork.drivers.bridge.linkUp", trace.WithAttributes(
		attribute.String("host", host.Attrs().Name)))
	defer span.End()

	return d.nlh.LinkSetUp(host)
}

func (d *driver) DeleteEndpoint(nid, eid string) error {
	var err error

	// Get the network handler and make sure it exists
	d.Lock()
	n, ok := d.networks[nid]
	d.Unlock()

	if !ok {
		return types.InternalMaskableErrorf("network %s does not exist", nid)
	}
	if n == nil {
		return driverapi.ErrNoNetwork(nid)