diff options
author | baude <bbaude@redhat.com> | 2020-10-06 12:24:21 -0500 |
---|---|---|
committer | baude <bbaude@redhat.com> | 2020-10-07 10:03:21 -0500 |
commit | fe3faa517e1bbc3b2e82afaae32d8712c844fdae (patch) | |
tree | 3b4a74edc98a2861d2e1b6bb1d9769e078b9ba3c /libpod/network/netconflist.go | |
parent | defb754945b3f99c1d786dac95d9b17b24f55e59 (diff) | |
download | podman-fe3faa517e1bbc3b2e82afaae32d8712c844fdae.tar.gz podman-fe3faa517e1bbc3b2e82afaae32d8712c844fdae.tar.bz2 podman-fe3faa517e1bbc3b2e82afaae32d8712c844fdae.zip |
prevent unpredictable results with network create|remove
due to a lack of "locking" on cni operations, we could get ourselves in trouble when doing rapid creation or removal of networks. added a simple file lock to deal with the collision and because it is not considered a performent path, use of the file lock should be ok. if proven otherwise in the future, some generic shared memory lock should be implemented for libpod and also used here.
moved pkog/network to libpod/network because libpod is now being pulled into the package and it has therefore lost its generic nature. this will make it easier to absorb into libpod as we try to make the network closer to core operations.
Fixes: #7807
Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'libpod/network/netconflist.go')
-rw-r--r-- | libpod/network/netconflist.go | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go new file mode 100644 index 000000000..8187fdb39 --- /dev/null +++ b/libpod/network/netconflist.go @@ -0,0 +1,155 @@ +package network + +import ( + "net" + "os" + "path/filepath" +) + +const ( + defaultIPv4Route = "0.0.0.0/0" + defaultIPv6Route = "::/0" +) + +// NcList describes a generic map +type NcList map[string]interface{} + +// NewNcList creates a generic map of values with string +// keys and adds in version and network name +func NewNcList(name, version string) NcList { + n := NcList{} + n["cniVersion"] = version + n["name"] = name + return n +} + +// NewHostLocalBridge creates a new LocalBridge for host-local +func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, ipamConf IPAMHostLocalConf) *HostLocalBridge { + hostLocalBridge := HostLocalBridge{ + PluginType: "bridge", + BrName: name, + IPMasq: ipMasq, + HairpinMode: true, + IPAM: ipamConf, + } + if isGateWay { + hostLocalBridge.IsGW = true + } + if isDefaultGW { + hostLocalBridge.IsDefaultGW = true + } + return &hostLocalBridge +} + +// NewIPAMHostLocalConf creates a new IPAMHostLocal configfuration +func NewIPAMHostLocalConf(subnet *net.IPNet, routes []IPAMRoute, ipRange net.IPNet, gw net.IP) (IPAMHostLocalConf, error) { + var ipamRanges [][]IPAMLocalHostRangeConf + ipamConf := IPAMHostLocalConf{ + PluginType: "host-local", + Routes: routes, + // Possible future support ? Leaving for clues + //ResolveConf: "", + //DataDir: "" + } + IPAMRange, err := newIPAMLocalHostRange(subnet, &ipRange, &gw) + if err != nil { + return ipamConf, err + } + ipamRanges = append(ipamRanges, IPAMRange) + ipamConf.Ranges = ipamRanges + return ipamConf, nil +} + +func newIPAMLocalHostRange(subnet *net.IPNet, ipRange *net.IPNet, gw *net.IP) ([]IPAMLocalHostRangeConf, error) { //nolint:interfacer + var ranges []IPAMLocalHostRangeConf + hostRange := IPAMLocalHostRangeConf{ + Subnet: subnet.String(), + } + // an user provided a range, we add it here + if ipRange.IP != nil { + first, err := FirstIPInSubnet(ipRange) + if err != nil { + return nil, err + } + last, err := LastIPInSubnet(ipRange) + if err != nil { + return nil, err + } + hostRange.RangeStart = first.String() + hostRange.RangeEnd = last.String() + } + if gw != nil { + hostRange.Gateway = gw.String() + } + ranges = append(ranges, hostRange) + return ranges, nil +} + +// NewIPAMRoute creates a new IPAM route configuration +func NewIPAMRoute(r *net.IPNet) IPAMRoute { //nolint:interfacer + return IPAMRoute{Dest: r.String()} +} + +// NewIPAMDefaultRoute creates a new IPAMDefault route of +// 0.0.0.0/0 for IPv4 or ::/0 for IPv6 +func NewIPAMDefaultRoute(isIPv6 bool) (IPAMRoute, error) { + route := defaultIPv4Route + if isIPv6 { + route = defaultIPv6Route + } + _, n, err := net.ParseCIDR(route) + if err != nil { + return IPAMRoute{}, err + } + return NewIPAMRoute(n), nil +} + +// NewPortMapPlugin creates a predefined, default portmapping +// configuration +func NewPortMapPlugin() PortMapConfig { + caps := make(map[string]bool) + caps["portMappings"] = true + p := PortMapConfig{ + PluginType: "portmap", + Capabilities: caps, + } + return p +} + +// NewFirewallPlugin creates a generic firewall plugin +func NewFirewallPlugin() FirewallConfig { + return FirewallConfig{ + PluginType: "firewall", + } +} + +// NewDNSNamePlugin creates the dnsname config with a given +// domainname +func NewDNSNamePlugin(domainName string) DNSNameConfig { + return DNSNameConfig{ + PluginType: "dnsname", + DomainName: domainName, + } +} + +// HasDNSNamePlugin looks to see if the dnsname cni plugin is present +func HasDNSNamePlugin(paths []string) bool { + for _, p := range paths { + if _, err := os.Stat(filepath.Join(p, "dnsname")); err == nil { + return true + } + } + 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 +} |