コード例 #1
0
ファイル: ovssflow.go プロジェクト: lebauce/skydive
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
}
コード例 #2
0
ファイル: netlink.go プロジェクト: lebauce/skydive
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++
					}
				}()
			}
		}
	}
}
コード例 #3
0
ファイル: pcap.go プロジェクト: lebauce/skydive
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
}
コード例 #4
0
ファイル: pcap.go プロジェクト: lebauce/skydive
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
}
コード例 #5
0
ファイル: netlink.go プロジェクト: lebauce/skydive
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))
}
コード例 #6
0
ファイル: neutron.go プロジェクト: safchain/skydive
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
}
コード例 #7
0
ファイル: ovssflow.go プロジェクト: lebauce/skydive
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
}
コード例 #8
0
ファイル: ondemand.go プロジェクト: fdebonneval/skydive
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)
}
コード例 #9
0
ファイル: ovssflow.go プロジェクト: lebauce/skydive
func isOvsBridge(n *graph.Node) bool {
	return n.Metadata()["UUID"] != "" && n.Metadata()["Type"] == "ovsbridge"
}
コード例 #10
0
ファイル: netlink.go プロジェクト: lebauce/skydive
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)
		}
	}
}