diff --git a/drivers/macvlan/macvlan.go b/drivers/macvlan/macvlan.go index 49b9fbae00..70bec82024 100644 --- a/drivers/macvlan/macvlan.go +++ b/drivers/macvlan/macvlan.go @@ -46,6 +46,7 @@ type endpoint struct { srcName string dbIndex uint64 dbExists bool + runtime string } type network struct { diff --git a/drivers/macvlan/macvlan_endpoint.go b/drivers/macvlan/macvlan_endpoint.go index 3e5ccb29f8..a55fe31bdb 100644 --- a/drivers/macvlan/macvlan_endpoint.go +++ b/drivers/macvlan/macvlan_endpoint.go @@ -40,6 +40,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, return err } } + // disallow portmapping -p if opt, ok := epOptions[netlabel.PortMap]; ok { if _, ok := opt.([]types.PortBinding); ok { @@ -57,6 +58,18 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, } } + // Setup the runtime to default to namespace, override if specified + ep.runtime = "namespace" + if opt, ok := epOptions["runtime"]; ok { + if runtime, ok := opt.(string); ok { + if runtime != "namespace" && runtime != "vm" { + logrus.Warnf("driver does not support [%s] runtime", runtime) + } else { + ep.runtime = runtime + } + } + } + if err := d.storeUpdate(ep); err != nil { return fmt.Errorf("failed to save macvlan endpoint %s to store: %v", ep.id[0:7], err) } diff --git a/drivers/macvlan/macvlan_joinleave.go b/drivers/macvlan/macvlan_joinleave.go index cf5c2a4bf9..bdd80b8995 100644 --- a/drivers/macvlan/macvlan_joinleave.go +++ b/drivers/macvlan/macvlan_joinleave.go @@ -28,7 +28,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, return fmt.Errorf("error generating an interface name: %s", err) } // create the netlink macvlan interface - vethName, err := createMacVlan(containerIfName, n.config.Parent, n.config.MacvlanMode) + vethName, err := createMacVlan(containerIfName, n.config.Parent, n.config.MacvlanMode, endpoint.runtime) if err != nil { return err } diff --git a/drivers/macvlan/macvlan_setup.go b/drivers/macvlan/macvlan_setup.go index b5b4be3499..88322531ca 100644 --- a/drivers/macvlan/macvlan_setup.go +++ b/drivers/macvlan/macvlan_setup.go @@ -16,8 +16,8 @@ const ( macvlanMajorVer = 9 // minimum macvlan major kernel support ) -// Create the macvlan slave specifying the source name -func createMacVlan(containerIfName, parent, macvlanMode string) (string, error) { +// Create the macvlan slave specifying the source name and the runtime type +func createMacVlan(containerIfName, parent, macvlanMode, runtime string) (string, error) { // Set the macvlan mode. Default is bridge mode mode, err := setMacVlanMode(macvlanMode) if err != nil { @@ -32,20 +32,40 @@ func createMacVlan(containerIfName, parent, macvlanMode string) (string, error) if err != nil { return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", macvlanType, parent, err) } - // Create a macvlan link - macvlan := &netlink.Macvlan{ - LinkAttrs: netlink.LinkAttrs{ - Name: containerIfName, - ParentIndex: parentLink.Attrs().Index, - }, - Mode: mode, - } - if err := ns.NlHandle().LinkAdd(macvlan); err != nil { - // If a user creates a macvlan and ipvlan on same parent, only one slave iface can be active at a time. - return "", fmt.Errorf("failed to create the %s port: %v", macvlanType, err) - } - return macvlan.Attrs().Name, nil + if runtime == "vm" { + // Create a macvtap link + macvtap := &netlink.Macvtap{ + Macvlan: netlink.Macvlan{ + LinkAttrs: netlink.LinkAttrs{ + Name: containerIfName, + ParentIndex: parentLink.Attrs().Index, + }, + Mode: mode, + }, + } + + if err := ns.NlHandle().LinkAdd(macvtap); err != nil { + return "", fmt.Errorf("failed to create the %s port: %v", macvlanType, err) + } + + return macvtap.Attrs().Name, nil + } else { + // Create a macvlan link + macvlan := &netlink.Macvlan{ + LinkAttrs: netlink.LinkAttrs{ + Name: containerIfName, + ParentIndex: parentLink.Attrs().Index, + }, + Mode: mode, + } + if err := ns.NlHandle().LinkAdd(macvlan); err != nil { + // If a user creates a macvlan and ipvlan on same parent, only one slave iface can be active at a time. + return "", fmt.Errorf("failed to create the %s port: %v", macvlanType, err) + } + + return macvlan.Attrs().Name, nil + } } // setMacVlanMode setter for one of the four macvlan port types diff --git a/drivers/macvlan/macvlan_store.go b/drivers/macvlan/macvlan_store.go index 3fd92786bf..1d23bb89de 100644 --- a/drivers/macvlan/macvlan_store.go +++ b/drivers/macvlan/macvlan_store.go @@ -255,6 +255,7 @@ func (ep *endpoint) MarshalJSON() ([]byte, error) { epMap["id"] = ep.id epMap["nid"] = ep.nid epMap["SrcName"] = ep.srcName + epMap["runtime"] = ep.runtime if len(ep.mac) != 0 { epMap["MacAddress"] = ep.mac.String() } @@ -295,6 +296,7 @@ func (ep *endpoint) UnmarshalJSON(b []byte) error { ep.id = epMap["id"].(string) ep.nid = epMap["nid"].(string) ep.srcName = epMap["SrcName"].(string) + ep.runtime = epMap["runtime"].(string) return nil }