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 }
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 }