func (c *Context) validateNoTunnel() { policies, err := netlink.XfrmPolicyList(netlink.FAMILY_ALL) if err != nil { c.Fatalf("Failed to get policies: %v", err) } if len(policies) != 0 { c.Fatalf("Policies not removed") } states, err := netlink.XfrmStateList(netlink.FAMILY_ALL) if err != nil { c.Fatalf("Failed to get states: %v", err) } if len(states) != 0 { c.Fatalf("States not removed") } }
func (c *Context) validateTunnel(udp bool) { policies, err := netlink.XfrmPolicyList(netlink.FAMILY_ALL) if err != nil { c.Fatalf("Failed to get policies: %v", err) } if len(policies) != 4 { c.Fatalf("Wrong number of policies found: %v", policies) } c.validatePolicy(policies[0], "127.0.0.2", "127.0.0.1") c.validatePolicy(policies[1], "127.0.0.1", "127.0.0.2") c.validatePolicy(policies[2], "127.0.0.1", "127.0.0.2") c.validatePolicy(policies[3], "127.0.0.2", "127.0.0.1") states, err := netlink.XfrmStateList(netlink.FAMILY_ALL) if err != nil { c.Fatalf("Failed to get states: %v", err) } if len(states) != 2 { c.Fatalf("Wrong number of states found: %v", states) } c.validateState(states[0], "127.0.0.1", "127.0.0.2", udp) c.validateState(states[1], "127.0.0.2", "127.0.0.1", udp) }
func discoverTunnels() { glog.Infof("Discovering existing tunnels") lo, err := netlink.LinkByName("lo") if err != nil { glog.Errorf("Failed to get loopback device: %v", err) return } addrs, err := netlink.AddrList(lo, netlink.FAMILY_ALL) if err != nil { glog.Errorf("Failed to get addrs: %v", err) return } routes, err := netlink.RouteList(nil, netlink.FAMILY_ALL) if err != nil { glog.Errorf("Failed to get routes: %v", err) return } policies, err := netlink.XfrmPolicyList(netlink.FAMILY_ALL) if err != nil { glog.Errorf("Failed to get xfrm policies: %v", err) return } states, err := netlink.XfrmStateList(netlink.FAMILY_ALL) if err != nil { glog.Errorf("Failed to get xfrm states: %v", err) return } for _, addr := range addrs { if opts.cidr.Contains(addr.IP) { tunnel := client.Tunnel{} tunnel.Src = addr.IP err := reserveIP(tunnel.Src) if err != nil { glog.Warningf("Duplicate tunnel ip detected: %v", tunnel.Src) } tunnel.Dst = nil glog.Infof("Potential tunnel found from %s", tunnel.Src) for _, route := range routes { if route.Src == nil || !route.Src.Equal(tunnel.Src) { continue } tunnel.Dst = route.Dst.IP break } if tunnel.Dst == nil { glog.Warningf("could not find dst for tunnel src %s", tunnel.Src) continue } err = reserveIP(tunnel.Dst) if err != nil { glog.Warningf("Duplicate tunnel ip detected: %v", tunnel.Dst) } var dst net.IP for _, policy := range policies { if !policy.Dst.IP.Equal(tunnel.Dst) { continue } if len(policy.Tmpls) == 0 { glog.Warningf("Tunnel policy has no associated template") continue } dst = policy.Tmpls[0].Dst break } if dst == nil { glog.Warningf("could not find ip for tunnel between %s and %s", tunnel.Src, tunnel.Dst) continue } for _, state := range states { if !state.Dst.Equal(dst) { continue } tunnel.Reqid = state.Reqid if state.Auth == nil { glog.Warningf("Tunnel state has no associated authentication entry") continue } tunnel.AuthKey = state.Auth.Key if state.Crypt == nil { glog.Warningf("Tunnel state has no associated encryption entry") continue } tunnel.EncKey = state.Crypt.Key if state.Encap != nil { tunnel.SrcPort = state.Encap.SrcPort tunnel.SrcPort = state.Encap.DstPort } glog.Infof("Discovered tunnel between %v and %v over %v", tunnel.Src, tunnel.Dst, dst) var socket int if tunnel.SrcPort != 0 { socket, err = createEncapListener(tunnel.Src, tunnel.SrcPort) if err != nil { glog.Warningf("Failed to create udp listener: %v", err) } } addTunnel(dst.String(), &tunnel, socket) break } } } glog.Infof("Finished discovering existing tunnels") }
func (o *Overlay) cleanup() error { changed := false defer func() { if !changed { return } time.Sleep(2 * time.Second) if err := o.loadConns(); err != nil { logrus.Errorf("Failed to reload connections: %v", err) } if err := o.configure(); err != nil { logrus.Errorf("Failed to reconfigure: %v", err) } }() o.Lock() defer o.Unlock() previouslyUnknown := o.unknownSpis o.unknownSpis = map[string]int{} client, err := getClient() if err != nil { return err } defer client.Close() conns, err := client.ListAllVpnConnInfo() if err != nil { return err } knownSpis := map[string]bool{} badConns := map[string]bool{} for _, conn := range conns { if conn.Local_host != "127.0.0.1" && conn.Local_host != o.db.LocalIpAddress() { badConns[conn.IkeSaName] = true if conn.ChildSaName != "" { logrus.Infof("Terminating connection: %s %s != %s", conn.IkeSaName, conn.Local_host, o.db.LocalIpAddress()) err := client.Terminate(&goStrongswanVici.TerminateRequest{ Ike: conn.IkeSaName, }) if err != nil { logrus.Infof("Failed to termination connection %s: %v", conn.ChildSaName, err) } } } children := []goStrongswanVici.Child_sas{conn.Child_sas} for _, child := range conn.IkeSa.Child_sas { children = append(children, child) } for _, child := range children { for _, i := range []string{child.Spi_in, child.Spi_out} { if i != "" { if badConns[conn.IkeSaName] { previouslyUnknown[i] = 4 } else { knownSpis[i] = true } } } } } if len(badConns) > 0 { changed = true logrus.Infof("Bad connections %v", badConns) for badConn, _ := range badConns { logrus.Infof("Deleting %s", badConn) err := client.UnloadConn(&goStrongswanVici.UnloadConnRequest{ Name: badConn, }) if err != nil { logrus.Infof("Failed to delete %s: %v", badConn, err) } } } stateList, err := netlink.XfrmStateList(netlink.FAMILY_V4) if err != nil { return err } for _, state := range stateList { spi := fmt.Sprintf("%x", state.Spi) if !knownSpis[spi] { if previouslyUnknown[spi] > 3 { logrus.Infof("Deleting unknown SPI %s: %#v", spi, state) netlink.XfrmStateDel(&state) } else { o.unknownSpis[spi] = previouslyUnknown[spi] + 1 } } } if len(o.unknownSpis) > 0 { logrus.Infof("Unknown SPIs: %#v, Conns: %#v", o.unknownSpis, conns) } return nil }