From ef872dcd21c60af70ab1848a7e0c873f142f6f44 Mon Sep 17 00:00:00 2001
From: baude <bbaude@redhat.com>
Date: Thu, 14 Nov 2019 12:48:45 -0600
Subject: macvlan networks

add the ability to a macvlan network with podman network create.

Signed-off-by: baude <bbaude@redhat.com>
---
 pkg/adapter/network.go     | 51 ++++++++++++++++++++++++++++++++++++++++++++--
 pkg/network/config.go      | 16 +++++++++++++++
 pkg/network/netconflist.go | 12 +++++++++++
 3 files changed, 77 insertions(+), 2 deletions(-)

(limited to 'pkg')

diff --git a/pkg/adapter/network.go b/pkg/adapter/network.go
index 9659ae339..160e334e9 100644
--- a/pkg/adapter/network.go
+++ b/pkg/adapter/network.go
@@ -153,8 +153,8 @@ func (r *LocalRuntime) removeNetwork(ctx context.Context, name string, container
 	return nil
 }
 
-// NetworkCreate creates a CNI network
-func (r *LocalRuntime) NetworkCreate(cli *cliconfig.NetworkCreateValues) (string, error) {
+// NetworkCreateBridge creates a CNI network
+func (r *LocalRuntime) NetworkCreateBridge(cli *cliconfig.NetworkCreateValues) (string, error) {
 	isGateway := true
 	ipMasq := true
 	subnet := &cli.Network
@@ -262,3 +262,50 @@ func (r *LocalRuntime) NetworkCreate(cli *cliconfig.NetworkCreateValues) (string
 	err = ioutil.WriteFile(cniPathName, b, 0644)
 	return cniPathName, err
 }
+
+// NetworkCreateMacVLAN creates a CNI network
+func (r *LocalRuntime) NetworkCreateMacVLAN(cli *cliconfig.NetworkCreateValues) (string, error) {
+	var (
+		name    string
+		plugins []network.CNIPlugins
+	)
+	liveNetNames, err := network.GetLiveNetworkNames()
+	if err != nil {
+		return "", err
+	}
+	// Make sure the host-device exists
+	if !util.StringInSlice(cli.MacVLAN, liveNetNames) {
+		return "", errors.Errorf("failed to find network interface %q", cli.MacVLAN)
+	}
+	if len(cli.InputArgs) > 0 {
+		name = cli.InputArgs[0]
+		netNames, err := network.GetNetworkNamesFromFileSystem()
+		if err != nil {
+			return "", err
+		}
+		if util.StringInSlice(name, netNames) {
+			return "", errors.Errorf("the network name %s is already used", name)
+		}
+	}
+	if len(name) < 1 {
+		name, err = network.GetFreeDeviceName()
+		if err != nil {
+			return "", err
+		}
+	}
+	ncList := network.NewNcList(name, cniversion.Current())
+	macvlan := network.NewMacVLANPlugin(cli.MacVLAN)
+	plugins = append(plugins, macvlan)
+	ncList["plugins"] = plugins
+	b, err := json.MarshalIndent(ncList, "", "   ")
+	if err != nil {
+		return "", err
+	}
+	cniConfigPath, err := getCNIConfDir(r)
+	if err != nil {
+		return "", err
+	}
+	cniPathName := filepath.Join(cniConfigPath, fmt.Sprintf("%s.conflist", name))
+	err = ioutil.WriteFile(cniPathName, b, 0644)
+	return cniPathName, err
+}
diff --git a/pkg/network/config.go b/pkg/network/config.go
index 37eb0dd64..e47b16143 100644
--- a/pkg/network/config.go
+++ b/pkg/network/config.go
@@ -90,6 +90,22 @@ func (p PortMapConfig) Bytes() ([]byte, error) {
 	return json.MarshalIndent(p, "", "\t")
 }
 
+type IPAMDHCP struct {
+	DHCP string `json:"type"`
+}
+
+// MacVLANConfig describes the macvlan config
+type MacVLANConfig struct {
+	PluginType string   `json:"type"`
+	Master     string   `json:"master"`
+	IPAM       IPAMDHCP `json:"ipam"`
+}
+
+// Bytes outputs the configuration as []byte
+func (p MacVLANConfig) Bytes() ([]byte, error) {
+	return json.MarshalIndent(p, "", "\t")
+}
+
 // FirewallConfig describes the firewall plugin
 type FirewallConfig struct {
 	PluginType string `json:"type"`
diff --git a/pkg/network/netconflist.go b/pkg/network/netconflist.go
index e19051b88..a8217097a 100644
--- a/pkg/network/netconflist.go
+++ b/pkg/network/netconflist.go
@@ -132,3 +132,15 @@ func HasDNSNamePlugin(paths []string) bool {
 	}
 	return false
 }
+
+// NewMacVLANPlugin creates a macvlanconfig with a given device name
+func NewMacVLANPlugin(device string) MacVLANConfig {
+	i := IPAMDHCP{DHCP: "dhcp"}
+
+	m := MacVLANConfig{
+		PluginType: "macvlan",
+		Master:     device,
+		IPAM:       i,
+	}
+	return m
+}
-- 
cgit v1.2.3-54-g00ecf