예제 #1
0
// leave call
func (driver *driver) leaveEndpoint(w http.ResponseWriter, r *http.Request) {
	var l api.LeaveRequest
	if err := json.NewDecoder(r.Body).Decode(&l); err != nil {
		sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
		return
	}
	Log.Infof("Leave request: %+v", &l)

	domainid, bridgeID := FindDomainFromNetwork(l.NetworkID)

	if_local_name := "tap" + l.EndpointID[:5]

	se_name, err := ifc_ctl.PgGetContainerDoorName()
	if err != nil {
		Log.Infof("Error attempting to find SE_name, will attempt ifc_ctl with default: %s", ifc_ctl.DEFAULT_SE_NAME)
		se_name = ifc_ctl.DEFAULT_SE_NAME
	}

	if se_name == "" {
		Log.Infof("Could not find SE name, will try to use default door name: %s", ifc_ctl.DEFAULT_SE_NAME)
		se_name = ifc_ctl.DEFAULT_SE_NAME
	}

	cmdStr := "sudo /opt/pg/bin/ifc_ctl " + se_name + " ifdown " + if_local_name
	Log.Infof("ifdown cmd: %s", cmdStr)
	cmd := exec.Command("/bin/sh", "-c", cmdStr)
	var ifdown bytes.Buffer
	cmd.Stdout = &ifdown
	if err := cmd.Run(); err != nil {
		Log.Error("Error thrown: ", err)
	}
	if ifdown.String() != "" {
		Log.Error(fmt.Errorf(ifdown.String()))
		errorResponse(w, "Unable to off-board container from PLUMgrid")
	}

	cmdStr = "sudo /opt/pg/bin/ifc_ctl " + se_name + " del_port " + if_local_name
	Log.Infof("delport cmd: %s", cmdStr)
	cmd = exec.Command("/bin/sh", "-c", cmdStr)
	var delport bytes.Buffer
	cmd.Stdout = &delport
	if err := cmd.Run(); err != nil {
		Log.Error("Error thrown: ", err)
	}
	if delport.String() != "" {
		Log.Error(fmt.Errorf(delport.String()))
		errorResponse(w, "Unable to off-board container from PLUMgrid")
	}

	if push_metaconfig {
		RemoveMetaconfig(domainid, bridgeID, l.EndpointID)
	}

	emptyResponse(w)
	Log.Infof("Leave %s:%s", l.NetworkID, l.EndpointID)
}
예제 #2
0
// join call
func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
	var j api.JoinRequest
	if err := json.NewDecoder(r.Body).Decode(&j); err != nil {
		sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
		return
	}
	Log.Infof("Join request: %+v", &j)

	netID := j.NetworkID
	endID := j.EndpointID
	domainid, bridgeID := FindDomainFromNetwork(netID)
	if domainid == "" {
		domainid = default_vd
	}
	gatewayIP := FindNetworkGateway(domainid, netID)

	local := vethPair(endID[:5])

	if_local_name := "tap" + endID[:5]

	link, _ := netlink.LinkByName(local.PeerName)
	mac := link.Attrs().HardwareAddr.String()
	Log.Infof("mac address: %s\n", mac)

	se_name, err := ifc_ctl.PgGetContainerDoorName()
	if err != nil {
		Log.Infof("Error attempting to find SE_name, will attempt ifc_ctl with default: %s", ifc_ctl.DEFAULT_SE_NAME)
		se_name = ifc_ctl.DEFAULT_SE_NAME
	}

	if se_name == "" {
		Log.Infof("Could not find SE name, will try to use default door name: %s", ifc_ctl.DEFAULT_SE_NAME)
		se_name = ifc_ctl.DEFAULT_SE_NAME
	}

	cmdStr := "sudo /opt/pg/bin/ifc_ctl " + se_name + " add_port " + if_local_name
	Log.Infof("addport cmd: %s", cmdStr)
	cmd := exec.Command("/bin/sh", "-c", cmdStr)
	var addport bytes.Buffer
	cmd.Stdout = &addport
	if err := cmd.Run(); err != nil {
		Log.Error("Error thrown: ", err)
	}
	if addport.String() != "" {
		Log.Error(fmt.Errorf(addport.String()))
		errorResponse(w, "Unable to on-board container onto PLUMgrid")
		return
	}

	cmdStr = "sudo /opt/pg/bin/ifc_ctl " + se_name + " ifup " + if_local_name + " access_container cont_" + endID[:8] + " " + mac + " pgtag2=" + bridgeID + " pgtag1=" + domainid
	Log.Infof("ifup cmd: %s", cmdStr)
	cmd = exec.Command("/bin/sh", "-c", cmdStr)
	var ifup bytes.Buffer
	cmd.Stdout = &ifup
	if err := cmd.Run(); err != nil {
		Log.Error("Error thrown: ", err)
	}
	if ifup.String() != "" {
		Log.Error(fmt.Errorf(ifup.String()))
		errorResponse(w, "Unable to on-board container onto PLUMgrid")
		return
	}

	if netlink.LinkSetUp(local) != nil {
		errorResponse(w, "unable to bring veth up")
		return
	}

	ifname := &api.InterfaceName{
		SrcName:   local.PeerName,
		DstPrefix: "ethpg",
	}

	res := &api.JoinResponse{
		InterfaceName: ifname,
		Gateway:       gatewayIP,
	}

	if push_metaconfig {
		SandBoxID := strings.Split(j.SandboxKey, "/")
		AddMetaconfig(domainid, bridgeID, SandBoxID[len(SandBoxID)-1], endID, mac)
	}

	objectResponse(w, res)
	Log.Infof("Join endpoint %s: %s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)

	if auto_arp {
		go func(net_ns_path string, pg_ifc_prefix string) {

			// Disallow this goroutine to work on any other thread than this one
			// since namespace ops (unshare, setns) are done for a single thread, we
			// must ensure that the goroutine does not jump from OS thread to thread
			for i := 0; i <= 4; i++ {
				runtime.LockOSThread()
				err := RunContainerArping(net_ns_path, pg_ifc_prefix)
				if err != nil {
					Log.Printf("Arping failed : %v", err)
				}
				runtime.UnlockOSThread()
				time.Sleep(1 * time.Second)
			}

		}(j.SandboxKey, ifname.DstPrefix)
	}
}