func cmdAdd()

in cmd/kube-egress-cni-ipam/main.go [28:112]


func cmdAdd(args *skel.CmdArgs) error {
	log := logger.GetLogger()
	// get cni config
	config, err := conf.ParseCNIConfig(args.StdinData)
	if err != nil {
		return err
	}

	// get k8s metadata
	k8sInfo, err := conf.LoadK8sInfo(args.Args)
	if err != nil {
		return err
	}
	log.V(5).Info("ADD - IPAM configuration successfully read: %+v", *k8sInfo)

	// allocate ip
	if config == nil || config.IPAM.Type == "" {
		return errors.New("ipam should not be empty")
	}

	podNetNS, err := ns.GetNS(args.Netns)
	if err != nil {
		return err
	}
	defer podNetNS.Close()

	var v4Address, v6Address net.IPNet
	var ipv4AddrFound, ipv6AddrFound bool
	var extraRoutes []*types.Route
	err = podNetNS.Do(func(netNS ns.NetNS) error {
		eth0Link, err := netlink.LinkByName("eth0")
		if err != nil {
			return err
		}

		addrList, err := netlink.AddrList(eth0Link, netlink.FAMILY_V6)
		if err != nil {
			return err
		}
		for _, item := range addrList {
			if item.Scope == unix.RT_SCOPE_LINK {
				v6Address = *item.IPNet
				ipv6AddrFound = true
			}
		}

		addrList, err = netlink.AddrList(eth0Link, netlink.FAMILY_V4)
		if err != nil {
			return err
		}
		for _, item := range addrList {
			if item.Scope == unix.RT_SCOPE_UNIVERSE {
				v4Address = *item.IPNet
				ipv4AddrFound = true
			}
		}
		return nil
	})

	if err != nil {
		return err
	}
	if !ipv4AddrFound {
		return errors.New("there is no enough ipv4 addr allocated for this pod")
	}
	if !ipv6AddrFound {
		return errors.New("there is no enough ipv6 addr allocated for this pod")
	}

	result := &type100.Result{
		CNIVersion: type100.ImplementedSpecVersion,
		IPs: []*type100.IPConfig{
			{
				Address: v6Address,
				Gateway: net.ParseIP(consts.GatewayIP),
			},
			{
				Address: v4Address,
			},
		},
		Routes: extraRoutes,
	}
	// outputCmdArgs(args)
	return types.PrintResult(result, config.CNIVersion)
}