diff --git a/.gitignore b/.gitignore
index ad281e4..b592198 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,6 @@ dist
 kubeconfig
 .idea
 *~
-vendor
 net.d
 addstats
 delstats
diff --git a/calico.go b/calico.go
index d97d947..9478ed6 100644
--- a/calico.go
+++ b/calico.go
@@ -440,7 +440,7 @@ func cmdDel(args *skel.CmdArgs) error {
 }
 
 // VERSION is filled out during the build process (using git describe output)
-var VERSION string
+var VERSION string = "v0.6.0"
 
 func main() {
 	// Set up logging formatting.
diff --git a/ipam/calico-ipam.go b/ipam/calico-ipam.go
index f37c045..8557e20 100644
--- a/ipam/calico-ipam.go
+++ b/ipam/calico-ipam.go
@@ -35,7 +35,7 @@ import (
 )
 
 // VERSION is filled out during the build process (using git describe output)
-var VERSION string
+var VERSION string = "v0.6.0"
 
 func main() {
 	// Set up logging formatting.
diff --git a/k8s-install/scripts/install-cni.sh b/k8s-install/scripts/install-cni.sh
index 02374de..3f63329 100755
--- a/k8s-install/scripts/install-cni.sh
+++ b/k8s-install/scripts/install-cni.sh
@@ -34,7 +34,7 @@ if [ "$(ls ${SECRETS_MOUNT_DIR} 3>/dev/null)" ];
 then
 	echo "Installing any TLS assets from ${SECRETS_MOUNT_DIR}"
 	mkdir -p /host/etc/cni/net.d/calico-tls
-	cp ${SECRETS_MOUNT_DIR}/* /host/etc/cni/net.d/calico-tls/
+	cp ${SECRETS_MOUNT_DIR}/* /host/etc/cni/net.d/calico-tls/ || true  # workaround lost+found directory in secrets mount
 fi
 
 # If the TLS assets actually exist, update the variables to populate into the
@@ -125,18 +125,18 @@ EOF
 
 # Insert any of the supported "auto" parameters.
 SERVICEACCOUNT_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
-grep "__KUBERNETES_SERVICE_HOST__" $TMP_CONF && sed -i s/__KUBERNETES_SERVICE_HOST__/${KUBERNETES_SERVICE_HOST}/g $TMP_CONF
-grep "__KUBERNETES_SERVICE_PORT__" $TMP_CONF && sed -i s/__KUBERNETES_SERVICE_PORT__/${KUBERNETES_SERVICE_PORT}/g $TMP_CONF
-sed -i s/__KUBERNETES_NODE_NAME__/${KUBERNETES_NODE_NAME:-$(hostname)}/g $TMP_CONF
-sed -i s/__KUBECONFIG_FILENAME__/calico-kubeconfig/g $TMP_CONF
+grep "__KUBERNETES_SERVICE_HOST__" $TMP_CONF && sed s/__KUBERNETES_SERVICE_HOST__/${KUBERNETES_SERVICE_HOST}/g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+grep "__KUBERNETES_SERVICE_PORT__" $TMP_CONF && sed s/__KUBERNETES_SERVICE_PORT__/${KUBERNETES_SERVICE_PORT}/g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+sed s/__KUBERNETES_NODE_NAME__/${KUBERNETES_NODE_NAME:-$(hostname)}/g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+sed s/__KUBECONFIG_FILENAME__/calico-kubeconfig/g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
 
 # Use alternative command character "~", since these include a "/".
-sed -i s~__KUBECONFIG_FILEPATH__~${HOST_CNI_NET_DIR}/calico-kubeconfig~g $TMP_CONF
-sed -i s~__ETCD_CERT_FILE__~${CNI_CONF_ETCD_CERT:-}~g $TMP_CONF
-sed -i s~__ETCD_KEY_FILE__~${CNI_CONF_ETCD_KEY:-}~g $TMP_CONF
-sed -i s~__ETCD_CA_CERT_FILE__~${CNI_CONF_ETCD_CA:-}~g $TMP_CONF
-sed -i s~__ETCD_ENDPOINTS__~${ETCD_ENDPOINTS:-}~g $TMP_CONF
-sed -i s~__LOG_LEVEL__~${LOG_LEVEL:-warn}~g $TMP_CONF
+sed s~__KUBECONFIG_FILEPATH__~${HOST_CNI_NET_DIR}/calico-kubeconfig~g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+sed s~__ETCD_CERT_FILE__~${CNI_CONF_ETCD_CERT:-}~g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+sed s~__ETCD_KEY_FILE__~${CNI_CONF_ETCD_KEY:-}~g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+sed s~__ETCD_CA_CERT_FILE__~${CNI_CONF_ETCD_CA:-}~g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+sed s~__ETCD_ENDPOINTS__~${ETCD_ENDPOINTS:-}~g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
+sed s~__LOG_LEVEL__~${LOG_LEVEL:-warn}~g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
 
 CNI_CONF_NAME=${CNI_CONF_NAME:-10-calico.conf}
 CNI_OLD_CONF_NAME=${CNI_OLD_CONF_NAME:-10-calico.conf}
@@ -145,7 +145,7 @@ CNI_OLD_CONF_NAME=${CNI_OLD_CONF_NAME:-10-calico.conf}
 # This way auth token is not visible in the logs.
 echo "CNI config: $(cat ${TMP_CONF})"
 
-sed -i s/__SERVICEACCOUNT_TOKEN__/${SERVICEACCOUNT_TOKEN:-}/g $TMP_CONF
+sed s/__SERVICEACCOUNT_TOKEN__/${SERVICEACCOUNT_TOKEN:-}/g $TMP_CONF > ${TMP_CONF}.1 && mv ${TMP_CONF}.1 $TMP_CONF
 
 # Delete old CNI config files for upgrades.
 if [ "${CNI_CONF_NAME}" != "${CNI_OLD_CONF_NAME}" ]; then
@@ -171,9 +171,9 @@ while [ "$should_sleep" == "true"  ]; do
 	# has been updated.  A bit hokey, but likely good enough.
 	if [ "$(ls ${SECRETS_MOUNT_DIR} 2>/dev/null)" ];
 	then
-        stat_output=$(stat -c%y ${SECRETS_MOUNT_DIR}/etcd-cert 2>/dev/null)
+        stat_output=$(LANG=C istat ${SECRETS_MOUNT_DIR}/etcd-cert 2>/dev/null | grep -i 'last modified')
         sleep 10;
-        if [ "$stat_output" != "$(stat -c%y ${SECRETS_MOUNT_DIR}/etcd-cert 2>/dev/null)" ]; then
+        if [ "$stat_output" != "$(LANG=C istat ${SECRETS_MOUNT_DIR}/etcd-cert 2>/dev/null | grep -i 'last modified')" ]; then
             echo "Updating installed secrets at: $(date)"
             cp ${SECRETS_MOUNT_DIR}/* /host/etc/cni/net.d/calico-tls/
         fi
diff --git a/utils/network.go b/utils/network.go
index 8837be1..d609255 100644
--- a/utils/network.go
+++ b/utils/network.go
@@ -1,3 +1,5 @@
+// +build !aix
+
 package utils
 
 import (
diff --git a/utils/network_aix.go b/utils/network_aix.go
new file mode 100644
index 0000000..d4eee98
--- /dev/null
+++ b/utils/network_aix.go
@@ -0,0 +1,24 @@
+package utils
+
+import (
+	"fmt"
+	"os/exec"
+	"strings"
+
+	"github.com/containernetworking/cni/pkg/skel"
+	"github.com/containernetworking/cni/pkg/types/current"
+	"github.com/projectcalico/cni-plugin/types"
+	"github.com/sirupsen/logrus"
+)
+
+// DoNetworking performs the networking for the given config and IPAM result
+func DoNetworking(args *skel.CmdArgs, conf types.NetConf, result *current.Result, logger *logrus.Entry, desiredVethName string) (hostVethName, contVethMAC string, err error) {
+	// We use the same interface name in WPAR than in Global
+	contVethName := args.IfName
+	hostVethName = contVethName
+
+	out, err := exec.Command("/bin/sh", "-c", fmt.Sprintf("LANG=C /usr/bin/entstat -d '%s' | grep 'Hardware Address' | cut -d' ' -f3", contVethName)).Output()
+	contVethMAC = strings.TrimSpace(string(out))
+
+	return hostVethName, contVethMAC, nil
+}
diff --git a/utils/utils.go b/utils/utils.go
index 0633742..6678f01 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -1,3 +1,5 @@
+// +build !aix
+
 // Copyright 2015 Tigera Inc
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/utils/utils_aix.go b/utils/utils_aix.go
new file mode 100644
index 0000000..88949f2
--- /dev/null
+++ b/utils/utils_aix.go
@@ -0,0 +1,386 @@
+// Copyright 2015 Tigera Inc
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package utils
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net"
+	"os"
+	"regexp"
+	"strings"
+
+	"github.com/containernetworking/cni/pkg/skel"
+	cnitypes "github.com/containernetworking/cni/pkg/types"
+	"github.com/containernetworking/cni/pkg/types/current"
+	"github.com/containernetworking/plugins/pkg/ipam"
+	"github.com/containernetworking/plugins/pkg/ns"
+	"github.com/projectcalico/cni-plugin/types"
+	"github.com/projectcalico/libcalico-go/lib/apiconfig"
+	api "github.com/projectcalico/libcalico-go/lib/apis/v3"
+	client "github.com/projectcalico/libcalico-go/lib/clientv3"
+	"github.com/projectcalico/libcalico-go/lib/names"
+	cnet "github.com/projectcalico/libcalico-go/lib/net"
+	"github.com/projectcalico/libcalico-go/lib/options"
+	"github.com/sirupsen/logrus"
+)
+
+func Min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
+
+// DetermineNodename gets the node name, in order of priority:
+// 1. Hostname field in NetConf (DEPRECATED).
+// 2. Nodename field in NetConf.
+// 3. OS Hostname.
+func DetermineNodename(conf types.NetConf) string {
+	nodename, _ := names.Hostname()
+	if conf.Hostname != "" {
+		nodename = conf.Hostname
+		logrus.Warn("Configuration option 'hostname' is deprecated, use 'nodename' instead.")
+	}
+	if conf.Nodename != "" {
+		nodename = conf.Nodename
+	}
+	return nodename
+}
+
+// CreateOrUpdate creates the WorkloadEndpoint if ResourceVersion is not specified,
+// or Update if it's specified.
+func CreateOrUpdate(ctx context.Context, client client.Interface, wep *api.WorkloadEndpoint) (*api.WorkloadEndpoint, error) {
+	if wep.ResourceVersion != "" {
+		return client.WorkloadEndpoints().Update(ctx, wep, options.SetOptions{})
+	}
+
+	return client.WorkloadEndpoints().Create(ctx, wep, options.SetOptions{})
+}
+
+// CleanUpNamespace deletes the devices in the network namespace.
+func CleanUpNamespace(args *skel.CmdArgs, logger *logrus.Entry) error {
+	// Only try to delete the device if a namespace was passed in.
+	if args.Netns != "" {
+		logger.Debug("Checking namespace & device exist.")
+		devErr := ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
+			return nil
+		})
+
+		if devErr == nil {
+			fmt.Fprintf(os.Stderr, "Calico CNI deleting device in netns %s\n", args.Netns)
+			err := ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
+				return nil
+			})
+
+			if err != nil {
+				return err
+			}
+		} else {
+			logger.Info("veth does not exist, no need to clean up.")
+		}
+	}
+
+	return nil
+}
+
+// CleanUpIPAM calls IPAM plugin to release the IP address.
+// It also contains IPAM plugin specific changes needed before calling the plugin.
+func CleanUpIPAM(conf types.NetConf, args *skel.CmdArgs, logger *logrus.Entry) error {
+	fmt.Fprint(os.Stderr, "Calico CNI releasing IP address\n")
+	logger.WithFields(logrus.Fields{"paths": os.Getenv("CNI_PATH"),
+		"type": conf.IPAM.Type}).Debug("Looking for IPAM plugin in paths")
+
+	// We need to replace "usePodCidr" with a valid, but dummy podCidr string with "host-local" IPAM.
+	if conf.IPAM.Type == "host-local" && strings.EqualFold(conf.IPAM.Subnet, "usePodCidr") {
+		// host-local IPAM releases the IP by ContainerID, so podCidr isn't really used to release the IP.
+		// It just needs a valid CIDR, but it doesn't have to be the CIDR associated with the host.
+		dummyPodCidr := "0.0.0.0/0"
+		var stdinData map[string]interface{}
+
+		err := json.Unmarshal(args.StdinData, &stdinData)
+		if err != nil {
+			return err
+		}
+
+		logger.WithField("podCidr", dummyPodCidr).Info("Using a dummy podCidr to release the IP")
+		stdinData["ipam"].(map[string]interface{})["subnet"] = dummyPodCidr
+
+		args.StdinData, err = json.Marshal(stdinData)
+		if err != nil {
+			return err
+		}
+		logger.WithField("stdin", string(args.StdinData)).Debug("Updated stdin data for Delete Cmd")
+	}
+
+	err := ipam.ExecDel(conf.IPAM.Type, args.StdinData)
+
+	if err != nil {
+		logger.Error(err)
+	}
+
+	return err
+}
+
+// ValidateNetworkName checks that the network name meets felix's expectations
+func ValidateNetworkName(name string) error {
+	matched, err := regexp.MatchString(`^[a-zA-Z0-9_\.\-]+$`, name)
+	if err != nil {
+		return err
+	}
+	if !matched {
+		return errors.New("invalid characters detected in the given network name. " +
+			"Only letters a-z, numbers 0-9, and symbols _.- are supported")
+	}
+	return nil
+}
+
+// AddIgnoreUnknownArgs appends the 'IgnoreUnknown=1' option to CNI_ARGS before calling the IPAM plugin. Otherwise, it will
+// complain about the Kubernetes arguments. See https://github.com/kubernetes/kubernetes/pull/24983
+func AddIgnoreUnknownArgs() error {
+	cniArgs := "IgnoreUnknown=1"
+	if os.Getenv("CNI_ARGS") != "" {
+		cniArgs = fmt.Sprintf("%s;%s", cniArgs, os.Getenv("CNI_ARGS"))
+	}
+	return os.Setenv("CNI_ARGS", cniArgs)
+}
+
+// CreateResultFromEndpoint takes a WorkloadEndpoint, extracts IP information
+// and populates that into a CNI Result.
+func CreateResultFromEndpoint(wep *api.WorkloadEndpoint) (*current.Result, error) {
+	result := &current.Result{}
+	for _, v := range wep.Spec.IPNetworks {
+		parsedIPConfig := current.IPConfig{}
+
+		ipAddr, ipNet, err := net.ParseCIDR(v)
+		if err != nil {
+			return nil, err
+		}
+
+		parsedIPConfig.Address = *ipNet
+
+		if ipAddr.To4() != nil {
+			parsedIPConfig.Version = "4"
+		} else {
+			parsedIPConfig.Version = "6"
+		}
+
+		result.IPs = append(result.IPs, &parsedIPConfig)
+	}
+
+	return result, nil
+}
+
+// PopulateEndpointNets takes a WorkloadEndpoint and a CNI Result, extracts IP address and mask
+// and populates that information into the WorkloadEndpoint.
+func PopulateEndpointNets(wep *api.WorkloadEndpoint, result *current.Result) error {
+	if len(result.IPs) == 0 {
+		return errors.New("IPAM plugin did not return any IP addresses")
+	}
+
+	for _, ipNet := range result.IPs {
+		if ipNet.Version == "4" {
+			ipNet.Address.Mask = net.CIDRMask(32, 32)
+		} else {
+			ipNet.Address.Mask = net.CIDRMask(128, 128)
+		}
+
+		wep.Spec.IPNetworks = append(wep.Spec.IPNetworks, ipNet.Address.String())
+	}
+
+	return nil
+}
+
+type WEPIdentifiers struct {
+	Namespace string
+	WEPName   string
+	names.WorkloadEndpointIdentifiers
+}
+
+// GetIdentifiers takes CNI command arguments, and extracts identifiers i.e. pod name, pod namespace,
+// container ID, endpoint(container interface name) and orchestratorID based on the orchestrator.
+func GetIdentifiers(args *skel.CmdArgs, nodename string) (*WEPIdentifiers, error) {
+	// Determine if running under k8s by checking the CNI args
+	k8sArgs := types.K8sArgs{}
+	if err := cnitypes.LoadArgs(args.Args, &k8sArgs); err != nil {
+		return nil, err
+	}
+	logrus.Debugf("Getting WEP identifiers with arguments: %s, for node %s", args.Args, nodename)
+	logrus.Debugf("Loaded k8s arguments: %v", k8sArgs)
+
+	epIDs := WEPIdentifiers{}
+	epIDs.ContainerID = args.ContainerID
+	epIDs.Node = nodename
+	epIDs.Endpoint = args.IfName
+
+	// Check if the workload is running under Kubernetes.
+	if string(k8sArgs.K8S_POD_NAMESPACE) != "" && string(k8sArgs.K8S_POD_NAME) != "" {
+		epIDs.Orchestrator = "k8s"
+		epIDs.Pod = string(k8sArgs.K8S_POD_NAME)
+		epIDs.Namespace = string(k8sArgs.K8S_POD_NAMESPACE)
+	} else {
+		epIDs.Orchestrator = "cni"
+		epIDs.Pod = ""
+		// For any non-k8s orchestrator we set the namespace to default.
+		epIDs.Namespace = "default"
+
+		// Warning: CNITestArgs is used for test purpose only and subject to change without prior notice.
+		CNITestArgs := types.CNITestArgs{}
+		if err := cnitypes.LoadArgs(args.Args, &CNITestArgs); err == nil {
+			// Set namespace with the value passed by CNI test args.
+			if string(CNITestArgs.CNI_TEST_NAMESPACE) != "" {
+				epIDs.Namespace = string(CNITestArgs.CNI_TEST_NAMESPACE)
+			}
+		}
+	}
+
+	return &epIDs, nil
+}
+
+func GetHandleID(netName string, containerID string, workload string) (string, error) {
+	handleID := fmt.Sprintf("%s.%s", netName, containerID)
+	logrus.WithFields(logrus.Fields{
+		"Network":     netName,
+		"ContainerID": containerID,
+		"Workload":    workload,
+		"HandleID":    handleID,
+	}).Debug("Generated IPAM handle")
+	return handleID, nil
+}
+
+func CreateClient(conf types.NetConf) (client.Interface, error) {
+	if err := ValidateNetworkName(conf.Name); err != nil {
+		return nil, err
+	}
+
+	// Use the config file to override environment variables.
+	// These variables will be loaded into the client config.
+	if conf.EtcdAuthority != "" {
+		if err := os.Setenv("ETCD_AUTHORITY", conf.EtcdAuthority); err != nil {
+			return nil, err
+		}
+	}
+	if conf.EtcdEndpoints != "" {
+		if err := os.Setenv("ETCD_ENDPOINTS", conf.EtcdEndpoints); err != nil {
+			return nil, err
+		}
+	}
+	if conf.EtcdScheme != "" {
+		if err := os.Setenv("ETCD_SCHEME", conf.EtcdScheme); err != nil {
+			return nil, err
+		}
+	}
+	if conf.EtcdKeyFile != "" {
+		if err := os.Setenv("ETCD_KEY_FILE", conf.EtcdKeyFile); err != nil {
+			return nil, err
+		}
+	}
+	if conf.EtcdCertFile != "" {
+		if err := os.Setenv("ETCD_CERT_FILE", conf.EtcdCertFile); err != nil {
+			return nil, err
+		}
+	}
+	if conf.EtcdCaCertFile != "" {
+		if err := os.Setenv("ETCD_CA_CERT_FILE", conf.EtcdCaCertFile); err != nil {
+			return nil, err
+		}
+	}
+	if conf.DatastoreType != "" {
+		if err := os.Setenv("DATASTORE_TYPE", conf.DatastoreType); err != nil {
+			return nil, err
+		}
+	}
+
+	// Set Kubernetes specific variables for use with the Kubernetes libcalico backend.
+	if conf.Kubernetes.Kubeconfig != "" {
+		if err := os.Setenv("KUBECONFIG", conf.Kubernetes.Kubeconfig); err != nil {
+			return nil, err
+		}
+	}
+	if conf.Kubernetes.K8sAPIRoot != "" {
+		if err := os.Setenv("K8S_API_ENDPOINT", conf.Kubernetes.K8sAPIRoot); err != nil {
+			return nil, err
+		}
+	}
+	if conf.Policy.K8sAuthToken != "" {
+		if err := os.Setenv("K8S_API_TOKEN", conf.Policy.K8sAuthToken); err != nil {
+			return nil, err
+		}
+	}
+	logrus.Infof("Configured environment: %+v", os.Environ())
+
+	// Load the client config from the current environment.
+	clientConfig, err := apiconfig.LoadClientConfig("")
+	if err != nil {
+		return nil, err
+	}
+
+	// Create a new client.
+	calicoClient, err := client.New(*clientConfig)
+	if err != nil {
+		return nil, err
+	}
+	return calicoClient, nil
+}
+
+// ReleaseIPAllocation is called to cleanup IPAM allocations if something goes wrong during
+// CNI ADD execution.
+func ReleaseIPAllocation(logger *logrus.Entry, ipamType string, stdinData []byte) {
+	logger.Info("Cleaning up IP allocations for failed ADD")
+	if err := os.Setenv("CNI_COMMAND", "DEL"); err != nil {
+		// Failed to set CNI_COMMAND to DEL.
+		logger.Warning("Failed to set CNI_COMMAND=DEL")
+	} else {
+		if err := ipam.ExecDel(ipamType, stdinData); err != nil {
+			// Failed to cleanup the IP allocation.
+			logger.Warning("Failed to clean up IP allocations for failed ADD")
+		}
+	}
+}
+
+// Set up logging for both Calico and libcalico using the provided log level,
+func ConfigureLogging(logLevel string) {
+	if strings.EqualFold(logLevel, "debug") {
+		logrus.SetLevel(logrus.DebugLevel)
+	} else if strings.EqualFold(logLevel, "info") {
+		logrus.SetLevel(logrus.InfoLevel)
+	} else {
+		// Default level
+		logrus.SetLevel(logrus.WarnLevel)
+	}
+
+	logrus.SetOutput(os.Stderr)
+}
+
+// Takes as array of IPv4 or IPv6 pools and parses them into an array of IPnet's
+func ParsePools(pools []string, isv4 bool) ([]cnet.IPNet, error) {
+	result := []cnet.IPNet{}
+	for _, p := range pools {
+		_, cidr, err := net.ParseCIDR(p)
+		if err != nil {
+			return nil, fmt.Errorf("error parsing pool %q: %s", p, err)
+		}
+		ip := cidr.IP
+		if isv4 && ip.To4() == nil {
+			return nil, fmt.Errorf("%q isn't a IPv4 address", ip)
+		}
+		if !isv4 && ip.To4() != nil {
+			return nil, fmt.Errorf("%q isn't a IPv6 address", ip)
+		}
+		result = append(result, cnet.IPNet{*cidr})
+	}
+	return result, nil
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go b/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
index bab5737..bd88b11 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// +build darwin dragonfly freebsd linux netbsd opensbd solaris
+// +build aix darwin dragonfly freebsd linux netbsd opensbd solaris
 
 package invoke
 
diff --git a/vendor/github.com/containernetworking/plugins/pkg/ip/addr.go b/vendor/github.com/containernetworking/plugins/pkg/ip/addr.go
index b4db50b..f3b426b 100644
--- a/vendor/github.com/containernetworking/plugins/pkg/ip/addr.go
+++ b/vendor/github.com/containernetworking/plugins/pkg/ip/addr.go
@@ -1,3 +1,5 @@
+// +build !aix
+
 // Copyright 2017 CNI authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/vendor/github.com/containernetworking/plugins/pkg/ip/addr_aix.go b/vendor/github.com/containernetworking/plugins/pkg/ip/addr_aix.go
new file mode 100644
index 0000000..9a3231d
--- /dev/null
+++ b/vendor/github.com/containernetworking/plugins/pkg/ip/addr_aix.go
@@ -0,0 +1,19 @@
+// Copyright 2017 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ip
+
+func SettleAddresses(ifName string, timeout int) error {
+	return nil
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_aix.go b/vendor/github.com/sirupsen/logrus/terminal_aix.go
new file mode 100644
index 0000000..6841999
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_aix.go
@@ -0,0 +1,26 @@
+// Based on ssh/terminal:
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build aix
+
+package logrus
+
+import (
+	"io"
+	"os"
+	"syscall"
+)
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+	var termios syscall.Termios
+	switch v := f.(type) {
+	case *os.File:
+		err := syscall.Tcgetattr(int(v.Fd()), &termios)
+		return err == nil
+	default:
+		return false
+	}
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go b/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go
new file mode 100644
index 0000000..c906345
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go
@@ -0,0 +1,102 @@
+// Based on ssh/terminal:
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package terminal
+
+import (
+	"io"
+	"syscall"
+)
+
+// State represents the state of the terminal.
+type State struct {
+	termios syscall.Termios
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	var termios syscall.Termios
+	err := syscall.Tcgetattr(fd, &termios)
+	return err == nil
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	var oldState State
+	if err := syscall.Tcgetattr(fd, &oldState.termios); err != nil {
+		return nil, err
+	}
+
+	newState := oldState.termios
+	newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
+	newState.Oflag &^= syscall.OPOST
+	newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
+	newState.Cflag &^= syscall.CSIZE | syscall.PARENB
+	newState.Cflag |= syscall.CS8
+
+	if err := syscall.Tcsetattr(fd, syscall.TCSANOW, &newState); err != nil {
+		return nil, err
+	}
+	return &oldState, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, oldState *State) error {
+	return syscall.Tcsetattr(fd, syscall.TCSANOW, &oldState.termios)
+}
+
+// passwordReader is an io.Reader that reads from a specific file descriptor.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+	return syscall.Read(int(r), buf)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	var oldState syscall.Termios
+	if err := syscall.Tcgetattr(fd, &oldState); err != nil {
+		return nil, err
+	}
+
+	newState := oldState
+	newState.Lflag &^= syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL
+	if err := syscall.Tcsetattr(fd, syscall.TCSANOW, &newState); err != nil {
+		return nil, err
+	}
+
+	defer func() {
+		syscall.Tcsetattr(fd, syscall.TCSANOW, &oldState)
+	}()
+
+	var buf [16]byte
+	var ret []byte
+	for {
+		n, err := syscall.Read(fd, buf[:])
+		if err != nil {
+			return nil, err
+		}
+		if n == 0 {
+			if len(ret) == 0 {
+				return nil, io.EOF
+			}
+			break
+		}
+		if buf[n-1] == '\n' {
+			n--
+		}
+		ret = append(ret, buf[:n]...)
+		if n < len(buf) {
+			break
+		}
+	}
+
+	return ret, nil
+}
