macvlan networks

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

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude
2019-11-14 12:48:45 -06:00
parent 225f22b9d5
commit ef872dcd21
7 changed files with 104 additions and 5 deletions

View File

@ -274,6 +274,7 @@ type NetworkCreateValues struct {
IPRange net.IPNet
IPV6 bool
Network net.IPNet
MacVLAN string
}
type NetworkListValues struct {

View File

@ -41,6 +41,7 @@ func init() {
flags.IPVar(&networkCreateCommand.Gateway, "gateway", nil, "IPv4 or IPv6 gateway for the subnet")
flags.BoolVar(&networkCreateCommand.Internal, "internal", false, "restrict external access from this network")
flags.IPNetVar(&networkCreateCommand.IPRange, "ip-range", net.IPNet{}, "allocate container IP from range")
flags.StringVar(&networkCreateCommand.MacVLAN, "macvlan", "", "create a Macvlan connection based on this device")
// TODO not supported yet
//flags.StringVar(&networkCreateCommand.IPamDriver, "ipam-driver", "", "IP Address Management Driver")
// TODO enable when IPv6 is working
@ -50,6 +51,10 @@ func init() {
}
func networkcreateCmd(c *cliconfig.NetworkCreateValues) error {
var (
fileName string
err error
)
if err := network.IsSupportedDriver(c.Driver); err != nil {
return err
}
@ -66,7 +71,11 @@ func networkcreateCmd(c *cliconfig.NetworkCreateValues) error {
if err != nil {
return err
}
fileName, err := runtime.NetworkCreate(c)
if len(c.MacVLAN) > 0 {
fileName, err = runtime.NetworkCreateMacVLAN(c)
} else {
fileName, err = runtime.NetworkCreateBridge(c)
}
if err == nil {
fmt.Println(fileName)
}

View File

@ -980,6 +980,7 @@ _podman_network_create() {
--driver
--gateway
--ip-range
--macvlan
--subnet
"
local boolean_options="

View File

@ -7,8 +7,10 @@ podman\-network-create - Create a Podman CNI network
**podman network create** [*options*] name
## DESCRIPTION
Create a CNI-network configuration for use with Podman. At the time of this writing, the only network
type that can be created is a *bridge* network.
Create a CNI-network configuration for use with Podman. By default, Podman creates a bridge connection. A
*Macvlan* connection can be created with the *macvlan* option. In the case of *Macvlan* connections, the
CNI *dhcp* plugin needs to be activated or the container image must have a DHCP client to interact
with the host network's DHCP server.
If no options are provided, Podman will assign a free subnet and name for your network.
@ -38,6 +40,11 @@ Restrict external access of this network
Allocate container IP from a range. The range must be a complete subnet and in CIDR notation. The *ip-range* option
must be used with a *subnet* option.
**--macvlan**
Create a *Macvlan* based connection rather than a classic bridge. You must pass an interface name from the host for the
Macvlan connection.
**--subnet**
The subnet in CIDR notation.
@ -68,6 +75,12 @@ Create a network that uses a *192.168.55.0/24** subnet and has an IP address ran
/etc/cni/net.d/cni-podman-5.conflist
```
Create a Macvlan based network using the host interface eth0
```
# podman network create --macvlan eth0 newnet
/etc/cni/net.d/newnet.conflist
```
## SEE ALSO
podman(1), podman-network(1), podman-network-inspect(1)

View File

@ -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
}

View File

@ -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"`

View File

@ -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
}