func (o *OvsSFlowProbesHandler) UnregisterProbe(n *graph.Node) error { if isOvsBridge(n) { err := o.unregisterProbe(n.Metadata()["UUID"].(string)) if err != nil { return err } } return nil }
func (u *NetLinkProbe) handleIntfIsVeth(intf *graph.Node, link netlink.Link) { if link.Type() != "veth" { return } stats, err := ethtool.Stats(link.Attrs().Name) if err != nil { logging.GetLogger().Errorf("Unable get stats from ethtool: %s", err.Error()) return } if index, ok := stats["peer_ifindex"]; ok { peerResolver := func() bool { // re get the interface from the graph since the interface could have been deleted if u.Graph.GetNode(intf.ID) == nil { return false } // got more than 1 peer, unable to find the right one, wait for the other to discover peer := u.Graph.LookupFirstNode(graph.Metadata{"IfIndex": int64(index), "Type": "veth"}) if peer != nil && !u.Graph.AreLinked(peer, intf) { u.Graph.Link(peer, intf, graph.Metadata{"RelationType": "layer2", "Type": "veth"}) return true } return false } if int64(index) > intf.Metadata()["IfIndex"].(int64) { ok := peerResolver() if !ok { // retry few seconds later since the right peer can be insert later go func() { ok := false try := 0 for { if ok || try > 10 { return } time.Sleep(time.Millisecond * 200) u.Graph.Lock() ok = peerResolver() u.Graph.Unlock() try++ } }() } } } }
func (p *PcapProbesHandler) UnregisterProbe(n *graph.Node) error { p.probesLock.Lock() defer p.probesLock.Unlock() if name, ok := n.Metadata()["Name"]; ok && name != "" { ifName := name.(string) err := p.unregisterProbe(ifName) if err != nil { return err } } return nil }
func (p *PcapProbesHandler) RegisterProbe(n *graph.Node, capture *api.Capture) error { logging.GetLogger().Debugf("Starting pcap capture on %s", n.Metadata()["Name"]) if name, ok := n.Metadata()["Name"]; ok && name != "" { ifName := name.(string) if _, ok := p.probes[ifName]; ok { return errors.New(fmt.Sprintf("A pcap probe already exists for %s", ifName)) } nodes := p.graph.LookupShortestPath(n, graph.Metadata{"Type": "host"}, topology.IsOwnershipEdge) if len(nodes) == 0 { return errors.New(fmt.Sprintf("Failed to determine probePath for %s", ifName)) } handle, err := pcap.OpenLive(ifName, snaplen, true, time.Second) if err != nil { return err } if capture.BPFFilter != "" { handle.SetBPFFilter(capture.BPFFilter) } probePath := topology.NodePath{nodes}.Marshal() packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packetChannel := packetSource.Packets() probe := &PcapProbe{ handle: handle, channel: packetChannel, probePath: probePath, } p.probesLock.Lock() p.probes[ifName] = probe p.probesLock.Unlock() p.wg.Add(1) go func() { defer p.wg.Done() for packet := range probe.channel { p.handlePacket(probe, packet) } }() } return nil }
func (u *NetLinkProbe) onLinkDeleted(index int) { logging.GetLogger().Debugf("Link %d deleted", index) u.Graph.Lock() defer u.Graph.Unlock() var intf *graph.Node intfs := u.Graph.LookupNodes(graph.Metadata{"IfIndex": int64(index)}) switch l := len(intfs); { case l == 1: intf = intfs[0] case l > 1: Loop: for _, i := range intfs { parents := u.Graph.LookupParentNodes(i, nil) for _, parent := range parents { if parent.ID == u.Root.ID { intf = i break Loop } } } } // case of removing the interface from a bridge if intf != nil { parents := u.Graph.LookupParentNodes(intf, graph.Metadata{"Type": "bridge"}) for _, parent := range parents { u.Graph.Unlink(parent, intf) } } // check wheter the interface has been deleted or not // we get a delete event when an interace is removed from a bridge _, err := netlink.LinkByIndex(index) if err != nil && intf != nil { if driver, ok := intf.Metadata()["Driver"]; ok { // if openvswitch do not remove let's do the job by ovs piece of code if driver == "openvswitch" { u.Graph.Unlink(u.Root, intf) } else { u.Graph.DelNode(intf) } } } delete(u.indexToChildrenQueue, int64(index)) }
func (mapper *NeutronMapper) EnhanceNode(node *graph.Node) { mac, ok := node.Metadata()["MAC"] if !ok { return } a, f := mapper.cache.Get(mac.(string)) if f { attrs := a.(Attributes) mapper.updateNode(node, &attrs) return } mapper.nodeUpdaterChan <- node.ID }
func (o *OvsSFlowProbesHandler) RegisterProbe(n *graph.Node, capture *api.Capture) error { if isOvsBridge(n) { nodes := o.Graph.LookupShortestPath(n, graph.Metadata{"Type": "host"}, topology.IsOwnershipEdge) if len(nodes) == 0 { return errors.New(fmt.Sprintf("Failed to determine probePath for %v", n)) } probePath := topology.NodePath{nodes}.Marshal() err := o.RegisterProbeOnBridge(n.Metadata()["UUID"].(string), probePath) if err != nil { return err } } return nil }
func (o *OnDemandProbeListener) probeFromType(n *graph.Node) FlowProbe { var probeName string switch n.Metadata()["Type"] { case "ovsbridge": probeName = "ovssflow" default: probeName = "pcap" } probe := o.Probes.GetProbe(probeName) if probe == nil { return nil } return probe.(FlowProbe) }
func isOvsBridge(n *graph.Node) bool { return n.Metadata()["UUID"] != "" && n.Metadata()["Type"] == "ovsbridge" }
func (u *NetLinkProbe) addLinkToTopology(link netlink.Link) { logging.GetLogger().Debugf("Link \"%s(%d)\" added", link.Attrs().Name, link.Attrs().Index) u.Graph.Lock() defer u.Graph.Unlock() driver, _ := ethtool.DriverName(link.Attrs().Name) if driver == "" && link.Type() == "bridge" { driver = "bridge" } metadata := graph.Metadata{ "Name": link.Attrs().Name, "Type": link.Type(), "IfIndex": int64(link.Attrs().Index), "MAC": link.Attrs().HardwareAddr.String(), "MTU": int64(link.Attrs().MTU), "Driver": driver, } /*ipv4 := u.getLinkIPV4Addr(link) if len(ipv4) > 0 { metadata["IPV4"] = ipv4 }*/ if vlan, ok := link.(*netlink.Vlan); ok { metadata["Vlan"] = vlan.VlanId } if (link.Attrs().Flags & net.FlagUp) > 0 { metadata["State"] = "UP" } else { metadata["State"] = "DOWN" } var intf *graph.Node switch driver { case "bridge": intf = u.addBridgeLinkToTopology(link, metadata) case "openvswitch": intf = u.addOvsLinkToTopology(link, metadata) // always prefer Type from ovs metadata["Type"] = intf.Metadata()["Type"] default: intf = u.addGenericLinkToTopology(link, metadata) } // merge metadata if the interface returned is not a new one if intf != nil { m := intf.Metadata() updated := false for k, nv := range metadata { if ov, ok := m[k]; ok && nv == ov { continue } m[k] = nv updated = true } if updated { u.Graph.SetMetadata(intf, m) } } }