func cmdAdd(args *skel.CmdArgs) error { n, err := loadNetConf(args.StdinData) if err != nil { return err } log.Debugf("Args %s", args) c, err := cnc.NewDefaultClient() if err != nil { return fmt.Errorf("error while starting cilium-client: %s", err) } netNs, err := ns.GetNS(args.Netns) if err != nil { return fmt.Errorf("failed to open netns %q: %s", args.Netns, err) } defer netNs.Close() if err := removeIfFromNSIfExists(netNs, args.IfName); err != nil { return fmt.Errorf("failed removing interface %q from namespace %q: %s", args.IfName, args.Netns, err) } var ep endpoint.Endpoint veth, peer, tmpIfName, err := plugins.SetupVeth(args.ContainerID, n.MTU, &ep) if err != nil { return err } defer func() { if err != nil { if err = netlink.LinkDel(veth); err != nil { log.Warningf("failed to clean up veth %q: %s", veth.Name, err) } } }() if err = netlink.LinkSetNsFd(*peer, int(netNs.Fd())); err != nil { return fmt.Errorf("unable to move veth pair %q to netns: %s", peer, err) } err = netNs.Do(func(_ ns.NetNS) error { err := renameLink(tmpIfName, args.IfName) if err != nil { return fmt.Errorf("failed to rename %q to %q: %s", tmpIfName, args.IfName, err) } return nil }) req := ipam.IPAMReq{} ipamConf, err := c.AllocateIP(ipam.CNIIPAMType, req) if err != nil { return err } defer func() { if err != nil && ipamConf != nil { if ipamConf.IP6 != nil { req := ipam.IPAMReq{IP: &ipamConf.IP6.IP.IP} if err = c.ReleaseIP(ipam.CNIIPAMType, req); err != nil { log.Warningf("failed to release allocated IPv6 of container ID %q: %s", args.ContainerID, err) } } if ipamConf.IP4 != nil { req := ipam.IPAMReq{IP: &ipamConf.IP4.IP.IP} if err = c.ReleaseIP(ipam.CNIIPAMType, req); err != nil { log.Warningf("failed to release allocated IPv4 of container ID %q: %s", args.ContainerID, err) } } } }() if err = netNs.Do(func(_ ns.NetNS) error { return configureIface(args.IfName, ipamConf) }); err != nil { return err } ep.IPv6 = addressing.DeriveCiliumIPv6(ipamConf.IP6.IP.IP) if ipamConf.IP4 != nil { ep.IPv4 = addressing.DeriveCiliumIPv4(ipamConf.IP4.IP.IP) } ep.NodeIP = ipamConf.IP6.Gateway ep.DockerID = args.ContainerID ep.SetID() if err = c.EndpointJoin(ep); err != nil { return fmt.Errorf("unable to create eBPF map: %s", err) } return createCNIReply(ipamConf) }