func CmdAdd(skelArgs *skel.CmdArgs) error {
	cniArgs, err := cmdCommon(skelArgs, "Add")
	defer glog.Flush()
	if err != nil {
		return err
	}
	netns, err := ns.GetNS(cniArgs.Netns)
	if err != nil {
		msg := fmt.Sprintf("Failed to open netns %s: %v", cniArgs.Netns, err)
		glog.Error(msg)
		return fmt.Errorf(msg)
	}
	defer netns.Close()
	connection, err := agent.Init(cniArgs.K8SArgs.PodName,
		cniArgs.ContrailArgs.Dir, cniArgs.ContrailArgs.VRouterArgs.Ip,
		cniArgs.ContrailArgs.VRouterArgs.Port)
	if err != nil {
		glog.Error(fmt.Sprintf("Error initializing connection : %s",
			err.Error()))
		return err
	}
	defer connection.Close()
	result, err := getVmiFromVRouter(connection, cniArgs)
	if err != nil {
		glog.Error(fmt.Sprintf("Error querying vmi <%s> from VRouter : %s",
			cniArgs.K8SArgs.PodName, err.Error()))
		return err
	}
	typesResult := args.VRouterResultToCniResult(result)
	hostIfName, err := processContainerAdd(netns, cniArgs, result.Mac,
		typesResult)
	if err != nil {
		glog.Error(fmt.Sprintf("Error modifying container <%s> : %s",
			cniArgs.K8SArgs.PodName, err.Error()))
		return err
	}
	connection, err = ipc.Init("",
		cniArgs.ContrailArgs.Dir, cniArgs.ContrailArgs.VRouterArgs.Ip,
		cniArgs.ContrailArgs.VRouterArgs.Port)
	if err != nil {
		return err
	}
	var warn error
	err, warn = processVRouterAdd(connection, cniArgs, hostIfName)
	if err != nil {
		glog.Error(fmt.Sprintf("Error adding interface to VRouter : %s",
			err.Error()))
		return err
	}
	if warn != nil {
		glog.Warning(fmt.Sprintf("Error adding interface to VRouter : %s",
			warn.Error()))
	}
	glog.V(2).Info(fmt.Sprintf("Result : %+v", typesResult))
	return typesResult.Print()
}
ADD command handler
package cni
import (
	"../agent"
	"../args"
	"flag"
	"fmt"
	"github.com/containernetworking/cni/pkg/ip"
	"github.com/containernetworking/cni/pkg/ipam"
	"github.com/containernetworking/cni/pkg/ns"
	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
	"github.com/golang/glog"
	"github.com/vishvananda/netlink"
	"net"
)
const CniVersion = "0.2.0"
func applyLogging(args args.LoggingArgs) {
	flag.Parse()
	flag.Lookup("log_dir").Value.Set(args.Dir)
	flag.Lookup("v").Value.Set(args.Level)
	return
}
func cmdCommon(skelArgs *skel.CmdArgs, cmd string) (*args.CniArgs, error) {
	cniArgs, err := args.Get(skelArgs)
	if err != nil {
		return nil, err
	}
	applyLogging(cniArgs.ContrailArgs.Logging)
	glog.V(2).Info(fmt.Sprintf("%s with ContainerId : <%s>, Netns : <%s>, IfName : <%s>, Args <%s>, Stdin %s\n",
		cmd, skelArgs.ContainerID, skelArgs.Netns, skelArgs.IfName,
		skelArgs.Args, string(skelArgs.StdinData)))
	glog.V(2).Info(fmt.Sprintf("Parsed information %+v\n", cniArgs))
	return cniArgs, nil
}
func processContainerAdd(netns ns.NetNS, cniArgs *args.CniArgs, mac string,
	typesResult *types.Result) (string, error) {
	hwAddr, mac_err := net.ParseMAC(mac)
	if mac_err != nil {
		return "", fmt.Errorf("Error parsing MAC address ", mac, " Error ",
			mac_err)
	}
	var hostIfName string
	err := netns.Do(func(hostNS ns.NetNS) error {
		link, _, err := ip.SetupVeth(cniArgs.IfName, cniArgs.ContrailArgs.Mtu,
			hostNS)
		if err != nil {
			return err
		}
		hostIfName = link.Attrs().Name
		err = ip.SetHWAddr(cniArgs.IfName, hwAddr)
		if err != nil {
			return err
		}
		err = ipam.ConfigureIface(cniArgs.IfName, typesResult)
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return "", err
	}
	return hostIfName, nil
}
func processVRouterAdd(agent *agent.Connection, cniArgs *args.CniArgs,
	hostIfName string) (error, error) {
	return agent.AddVm(cniArgs.K8SArgs.PodName, cniArgs.Netns,
		cniArgs.ContainerID, hostIfName, cniArgs.IfName)
}
func getVmiFromVRouter(agent *agent.Connection,
	cniArgs *args.CniArgs) (*agent.Result, error) {
	result, err := agent.GetVmiInfo(cniArgs.ContainerID, cniArgs.IfName,
		cniArgs.ContrailArgs.VRouterArgs.PollTimeout,
		cniArgs.ContrailArgs.VRouterArgs.PollRetries)
	if err != nil {
		return nil, err
	}
	return result, nil
}