| //go:build linux |
| |
| package overlay |
| |
| import ( |
| "context" |
| "errors" |
| "fmt" |
| "net/netip" |
| |
| "github.com/containerd/log" |
| "github.com/moby/moby/v2/daemon/internal/netiputil" |
| "github.com/moby/moby/v2/daemon/libnetwork/driverapi" |
| "github.com/moby/moby/v2/daemon/libnetwork/internal/hashable" |
| "github.com/moby/moby/v2/daemon/libnetwork/netutils" |
| "github.com/moby/moby/v2/daemon/libnetwork/ns" |
| ) |
| |
| type endpointTable map[string]*endpoint |
| |
| type endpoint struct { |
| id string |
| nid string |
| ifName string |
| mac hashable.MACAddr |
| addr netip.Prefix |
| } |
| |
| func (d *driver) CreateEndpoint(_ context.Context, nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]any) error { |
| var err error |
| if err = validateID(nid, eid); err != nil { |
| return err |
| } |
| |
| // Since we perform lazy configuration make sure we try |
| // configuring the driver when we enter CreateEndpoint since |
| // CreateNetwork may not be called in every node. |
| if err := d.configure(); err != nil { |
| return err |
| } |
| |
| n, unlock, err := d.lockNetwork(nid) |
| if err != nil { |
| return err |
| } |
| defer unlock() |
| |
| ep := &endpoint{ |
| id: eid, |
| nid: n.id, |
| } |
| var ok bool |
| ep.addr, ok = netiputil.ToPrefix(ifInfo.Address()) |
| if !ok { |
| return errors.New("create endpoint was not passed interface IP address") |
| } |
| |
| if s := n.getSubnetforIP(ep.addr); s == nil { |
| return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid) |
| } |
| |
| if ifmac := ifInfo.MacAddress(); ifmac != nil { |
| var ok bool |
| ep.mac, ok = hashable.MACAddrFromSlice(ifInfo.MacAddress()) |
| if !ok { |
| return fmt.Errorf("invalid MAC address %q assigned to endpoint: unexpected length", ifmac) |
| } |
| } else { |
| var ok bool |
| ep.mac, ok = hashable.MACAddrFromSlice(netutils.GenerateMACFromIP(ep.addr.Addr().AsSlice())) |
| if !ok { |
| panic("GenerateMACFromIP returned a HardwareAddress that is not a MAC-48") |
| } |
| if err := ifInfo.SetMacAddress(ep.mac.AsSlice()); err != nil { |
| return err |
| } |
| } |
| |
| n.endpoints[ep.id] = ep |
| |
| return nil |
| } |
| |
| func (d *driver) DeleteEndpoint(nid, eid string) error { |
| nlh := ns.NlHandle() |
| |
| if err := validateID(nid, eid); err != nil { |
| return err |
| } |
| |
| n, unlock, err := d.lockNetwork(nid) |
| if err != nil { |
| return err |
| } |
| defer unlock() |
| |
| ep := n.endpoints[eid] |
| if ep == nil { |
| return fmt.Errorf("endpoint id %q not found", eid) |
| } |
| |
| delete(n.endpoints, eid) |
| |
| if ep.ifName == "" { |
| return nil |
| } |
| |
| link, err := nlh.LinkByName(ep.ifName) |
| if err != nil { |
| log.G(context.TODO()).Debugf("Failed to retrieve interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err) |
| return nil |
| } |
| if err := nlh.LinkDel(link); err != nil { |
| log.G(context.TODO()).Debugf("Failed to delete interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err) |
| } |
| |
| return nil |
| } |
| |
| func (d *driver) EndpointOperInfo(nid, eid string) (map[string]any, error) { |
| return make(map[string]any), nil |
| } |