Esempio n. 1
0
func destroyTunnel(dst net.IP) (net.IP, error) {
	// Determine the src and dst ips for the tunnel
	key := dst.String()
	tunnel := getTunnel(dst.String())
	if tunnel == nil {
		s := fmt.Sprintf("Failed to find tunnel to dst %s", dst)
		glog.Errorf(s)
		return nil, fmt.Errorf(s)
	}

	src := opts.src

	srcNet := netlink.NewIPNet(tunnel.Src)
	dstNet := netlink.NewIPNet(tunnel.Dst)

	glog.Infof("Destroying Tunnel: %v, %v", tunnel.Src, tunnel.Dst)

	for _, state := range getStates(tunnel.Reqid, src, dst, 0, 0, nil, nil) {
		// crate xfrm state rules
		err := netlink.XfrmStateDel(&state)
		if err != nil {
			glog.Errorf("Failed to delete state %v: %v", state, err)
		}
	}

	for _, policy := range getPolicies(tunnel.Reqid, src, dst, srcNet, dstNet) {
		// create xfrm policy rules
		err := netlink.XfrmPolicyDel(&policy)
		if err != nil {
			glog.Errorf("Failed to delete policy %v: %v", policy, err)
		}
	}

	index, err := getLinkIndex(src)
	if err != nil {
		glog.Errorf("Failed to get link for address: %v", err)
	} else {

		// del source route to tunnel ips device
		route := &netlink.Route{
			Scope:     netlink.SCOPE_LINK,
			Src:       tunnel.Src,
			Dst:       dstNet,
			LinkIndex: index,
		}
		err = netlink.RouteDel(route)
		if err != nil {
			glog.Errorf("Failed to delete route %v: %v", route, err)
		}
	}

	// del IP address to loopback device
	lo, err := netlink.LinkByName("lo")
	if err != nil {
		glog.Errorf("Failed to get loopback device: %v", err)
	} else {
		err = netlink.AddrDel(lo, &netlink.Addr{IPNet: srcNet})
		if err != nil {
			glog.Errorf("Failed to delete %v from loopback: %v", tunnel.Src, err)
		}
	}
	if tunnel.SrcPort != 0 {
		deleteEncapListener(getListener(key))
		releasePort(tunnel.SrcPort)
	}
	unreserveIP(tunnel.Src)
	unreserveIP(tunnel.Dst)
	removeTunnel(key)
	glog.Infof("Finished destroying tunnel: %v, %v", tunnel.Src, tunnel.Dst)
	return opts.external, nil
}
Esempio n. 2
0
func buildTunnelLocal(dst net.IP, tunnel *client.Tunnel) (net.IP, *client.Tunnel, error) {
	var socket int
	if tunnel.SrcPort != 0 {
		var err error
		socket, err = createEncapListener(tunnel.Src, tunnel.SrcPort)
		if err != nil {
			glog.Errorf("Failed to create udp listener: %v", err)
			return nil, nil, err
		}
	}
	addTunnel(dst.String(), tunnel, socket)

	src := opts.src

	srcNet := netlink.NewIPNet(tunnel.Src)
	dstNet := netlink.NewIPNet(tunnel.Dst)

	glog.Infof("Building tunnel: %v, %v", tunnel.Src, tunnel.Dst)
	// add IP address to loopback device
	lo, err := netlink.LinkByName("lo")
	if err != nil {
		glog.Errorf("Failed to get loopback device: %v", err)
		return nil, nil, err
	}
	err = netlink.AddrAdd(lo, &netlink.Addr{IPNet: srcNet})
	if err != nil {
		glog.Errorf("Failed to add %v to loopback: %v", tunnel.Src, err)
		return nil, nil, err
	}

	index, err := getLinkIndex(src)
	if err != nil {
		glog.Errorf("Failed to get link for address: %v", err)
		return nil, nil, err
	}
	// add source route to tunnel ips device
	route := &netlink.Route{
		Scope:     netlink.SCOPE_LINK,
		Src:       tunnel.Src,
		Dst:       dstNet,
		LinkIndex: index,
	}
	err = netlink.RouteAdd(route)
	if err != nil {
		glog.Errorf("Failed to add route %v: %v", route, err)
		return nil, nil, err
	}

	for _, policy := range getPolicies(tunnel.Reqid, src, dst, srcNet, dstNet) {
		glog.Infof("building Policy: %v", policy)
		// create xfrm policy rules
		err = netlink.XfrmPolicyAdd(&policy)
		if err != nil {
			if err == syscall.EEXIST {
				glog.Infof("Skipped adding policy %v because it already exists", policy)
			} else {
				glog.Errorf("Failed to add policy %v: %v", policy, err)
				return nil, nil, err
			}
		}
	}
	for _, state := range getStates(tunnel.Reqid, src, dst, tunnel.SrcPort, tunnel.DstPort, tunnel.AuthKey, tunnel.EncKey) {
		glog.Infof("building State: %v", state)
		// crate xfrm state rules
		err = netlink.XfrmStateAdd(&state)
		if err != nil {
			if err == syscall.EEXIST {
				glog.Infof("Skipped adding state %v because it already exists", state)
			} else {
				glog.Errorf("Failed to add state %v: %v", state, err)
				return nil, nil, err
			}
		}
	}
	glog.Infof("Finished building tunnel: %v, %v", tunnel.Src, tunnel.Dst)
	return opts.external, tunnel, nil
}