1package macvlan
2
3import (
4	"fmt"
5
6	"github.com/docker/libnetwork/driverapi"
7	"github.com/docker/libnetwork/netlabel"
8	"github.com/docker/libnetwork/netutils"
9	"github.com/docker/libnetwork/ns"
10	"github.com/docker/libnetwork/osl"
11	"github.com/docker/libnetwork/types"
12	"github.com/sirupsen/logrus"
13)
14
15// CreateEndpoint assigns the mac, ip and endpoint id for the new container
16func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
17	epOptions map[string]interface{}) error {
18	defer osl.InitOSContext()()
19
20	if err := validateID(nid, eid); err != nil {
21		return err
22	}
23	n, err := d.getNetwork(nid)
24	if err != nil {
25		return fmt.Errorf("network id %q not found", nid)
26	}
27	ep := &endpoint{
28		id:     eid,
29		nid:    nid,
30		addr:   ifInfo.Address(),
31		addrv6: ifInfo.AddressIPv6(),
32		mac:    ifInfo.MacAddress(),
33	}
34	if ep.addr == nil {
35		return fmt.Errorf("create endpoint was not passed an IP address")
36	}
37	if ep.mac == nil {
38		ep.mac = netutils.GenerateMACFromIP(ep.addr.IP)
39		if err := ifInfo.SetMacAddress(ep.mac); err != nil {
40			return err
41		}
42	}
43	// disallow portmapping -p
44	if opt, ok := epOptions[netlabel.PortMap]; ok {
45		if _, ok := opt.([]types.PortBinding); ok {
46			if len(opt.([]types.PortBinding)) > 0 {
47				logrus.Warnf("%s driver does not support port mappings", macvlanType)
48			}
49		}
50	}
51	// disallow port exposure --expose
52	if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
53		if _, ok := opt.([]types.TransportPort); ok {
54			if len(opt.([]types.TransportPort)) > 0 {
55				logrus.Warnf("%s driver does not support port exposures", macvlanType)
56			}
57		}
58	}
59
60	if err := d.storeUpdate(ep); err != nil {
61		return fmt.Errorf("failed to save macvlan endpoint %.7s to store: %v", ep.id, err)
62	}
63
64	n.addEndpoint(ep)
65
66	return nil
67}
68
69// DeleteEndpoint removes the endpoint and associated netlink interface
70func (d *driver) DeleteEndpoint(nid, eid string) error {
71	defer osl.InitOSContext()()
72	if err := validateID(nid, eid); err != nil {
73		return err
74	}
75	n := d.network(nid)
76	if n == nil {
77		return fmt.Errorf("network id %q not found", nid)
78	}
79	ep := n.endpoint(eid)
80	if ep == nil {
81		return fmt.Errorf("endpoint id %q not found", eid)
82	}
83	if link, err := ns.NlHandle().LinkByName(ep.srcName); err == nil {
84		if err := ns.NlHandle().LinkDel(link); err != nil {
85			logrus.WithError(err).Warnf("Failed to delete interface (%s)'s link on endpoint (%s) delete", ep.srcName, ep.id)
86		}
87	}
88
89	if err := d.storeDelete(ep); err != nil {
90		logrus.Warnf("Failed to remove macvlan endpoint %.7s from store: %v", ep.id, err)
91	}
92
93	n.deleteEndpoint(ep.id)
94
95	return nil
96}
97