func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) { var ( j api.JoinRequest err error ) if err := json.NewDecoder(r.Body).Decode(&j); err != nil { sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest) return } log.Debugf("Join request: %+v", &j) ep, err := driver.client.EndpointGetByDockerEPID(j.EndpointID) if err != nil { sendError(w, fmt.Sprintf("Error retrieving endpoint %s", err), http.StatusBadRequest) return } if ep == nil { sendError(w, "Endpoint does not exist", http.StatusBadRequest) return } veth, _, tmpIfName, err := plugins.SetupVeth(j.EndpointID, 1450, ep) if err != nil { sendError(w, "Error while setting up veth pair: "+err.Error(), http.StatusBadRequest) return } defer func() { if err != nil { if err = netlink.LinkDel(veth); err != nil { log.Warningf("failed to clean up veth %q: %s", veth.Name, err) } } }() ifname := &api.InterfaceName{ SrcName: tmpIfName, DstPrefix: ContainerInterfacePrefix, } if err = driver.client.EndpointJoin(*ep); err != nil { log.Errorf("Joining endpoint failed: %s", err) sendError(w, "Unable to create BPF map: "+err.Error(), http.StatusInternalServerError) } rep, err := driver.client.GetIPAMConf(ipam.LibnetworkIPAMType, ipam.IPAMReq{}) if err != nil { sendError(w, fmt.Sprintf("Could not get cilium IPAM configuration: %s", err), http.StatusBadRequest) } lnRoutes := []api.StaticRoute{} for _, route := range rep.IPAMConfig.IP6.Routes { nh := "" if route.IsL3() { nh = route.NextHop.String() } lnRoute := api.StaticRoute{ Destination: route.Destination.String(), RouteType: route.Type, NextHop: nh, } lnRoutes = append(lnRoutes, lnRoute) } if rep.IPAMConfig.IP4 != nil { for _, route := range rep.IPAMConfig.IP4.Routes { nh := "" if route.IsL3() { nh = route.NextHop.String() } lnRoute := api.StaticRoute{ Destination: route.Destination.String(), RouteType: route.Type, NextHop: nh, } lnRoutes = append(lnRoutes, lnRoute) } } res := &api.JoinResponse{ GatewayIPv6: rep.IPAMConfig.IP6.Gateway.String(), InterfaceName: ifname, StaticRoutes: lnRoutes, DisableGatewayService: true, } // FIXME? Having the following code results on a runtime error: docker: Error // response from daemon: oci runtime error: process_linux.go:334: running prestart // hook 0 caused "exit status 1: time=\"2016-10-26T06:33:17-07:00\" level=fatal // msg=\"failed to set gateway while updating gateway: file exists\" \n" // // If empty, it works as expected without docker runtime errors // if rep.IPAMConfig.IP4 != nil { // res.Gateway = rep.IPAMConfig.IP4.Gateway.String() // } log.Debugf("Join response: %+v", res) objectResponse(w, res) }
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) }