From 91afa7f7f4b2bed68475741c3287ffcac4299b2c Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 7 Oct 2015 10:59:12 +0100 Subject: [PATCH 1/4] Include selected overlay type in connection status --- router/fastdp.go | 4 ++++ router/overlay.go | 7 +++++++ router/overlay_switch.go | 12 ++++++++++++ router/sleeve.go | 4 ++++ router/status.go | 5 ++++- 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/router/fastdp.go b/router/fastdp.go index 7208094a..e292c9f6 100644 --- a/router/fastdp.go +++ b/router/fastdp.go @@ -662,6 +662,10 @@ func (fwd *fastDatapathForwarder) ControlMessage(tag byte, msg []byte) { } } +func (fwd *fastDatapathForwarder) DisplayName() string { + return "fastdp" +} + func (fwd *fastDatapathForwarder) handleHeartbeatAck() { log.Debug(fwd.logPrefix(), "handleHeartbeatAck") diff --git a/router/overlay.go b/router/overlay.go index e8b44ab1..85e23e42 100644 --- a/router/overlay.go +++ b/router/overlay.go @@ -88,6 +88,9 @@ type OverlayForwarder interface { // compatibility, and should always be // ProtocolOverlayControlMessage for non-sleeve overlays. ControlMessage(tag byte, msg []byte) + + // User facing overlay name + DisplayName() string } type NullOverlay struct{} @@ -129,3 +132,7 @@ func (NullOverlay) Stop() { func (NullOverlay) ControlMessage(byte, []byte) { } + +func (NullOverlay) DisplayName() string { + return "null" +} diff --git a/router/overlay_switch.go b/router/overlay_switch.go index b2ae6af3..1022c5e3 100644 --- a/router/overlay_switch.go +++ b/router/overlay_switch.go @@ -393,3 +393,15 @@ func (fwd *overlaySwitchForwarder) ControlMessage(tag byte, msg []byte) { subFwd.ControlMessage(msg[1], msg[2:]) } } + +func (fwd *overlaySwitchForwarder) DisplayName() string { + fwd.lock.Lock() + best := fwd.best + fwd.lock.Unlock() + + if best == nil { + return "none" + } + + return best.DisplayName() +} diff --git a/router/sleeve.go b/router/sleeve.go index a2e2fd2e..e24956aa 100644 --- a/router/sleeve.go +++ b/router/sleeve.go @@ -593,6 +593,10 @@ func (fwd *sleeveForwarder) ControlMessage(tag byte, msg []byte) { } } +func (fwd *sleeveForwarder) DisplayName() string { + return "sleeve" +} + func (fwd *sleeveForwarder) Stop() { fwd.sleeve.removeForwarder(fwd.remotePeer.Name, fwd) diff --git a/router/status.go b/router/status.go index bbb10d41..f2e97c99 100644 --- a/router/status.go +++ b/router/status.go @@ -1,6 +1,7 @@ package router import ( + "fmt" "time" ) @@ -170,7 +171,9 @@ func NewLocalConnectionStatusSlice(cm *ConnectionMaker) []LocalConnectionStatus if conn.Established() { state = "established" } - slice = append(slice, LocalConnectionStatus{conn.RemoteTCPAddr(), conn.Outbound(), state, conn.Remote().String()}) + lc, _ := conn.(*LocalConnection) + info := fmt.Sprintf("%-6v %v", lc.forwarder.DisplayName(), conn.Remote()) + slice = append(slice, LocalConnectionStatus{conn.RemoteTCPAddr(), conn.Outbound(), state, info}) } for address, target := range cm.targets { add := func(state, info string) { From ddfc8c2fa40b90c4e8726b82f6ca0701598eed19 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 7 Oct 2015 17:42:14 +0100 Subject: [PATCH 2/4] Handle JSON report marshalling error --- prog/weaver/http.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/prog/weaver/http.go b/prog/weaver/http.go index c432e849..a53f59c8 100644 --- a/prog/weaver/http.go +++ b/prog/weaver/http.go @@ -161,7 +161,12 @@ func HandleHTTP(muxRouter *mux.Router, version string, router *weave.Router, all } muxRouter.Methods("GET").Path("/report").Headers("Accept", "application/json").HandlerFunc( func(w http.ResponseWriter, r *http.Request) { - json, _ := json.MarshalIndent(status(), "", " ") + json, err := json.MarshalIndent(status(), "", " ") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + Log.Error("Error during report marshalling: ", err) + return + } w.Header().Set("Content-Type", "application/json") w.Write(json) }) From eaf1f7cc131ebee449e35bc1bd521d18130c48a4 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 7 Oct 2015 17:43:31 +0100 Subject: [PATCH 3/4] Include overlay diagnostics in report JSON --- router/fastdp.go | 72 ++++++++++++++++++++++++++++++++++++++++ router/overlay.go | 7 ++++ router/overlay_switch.go | 8 +++++ router/sleeve.go | 4 +++ router/status.go | 4 ++- 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/router/fastdp.go b/router/fastdp.go index e292c9f6..e3043370 100644 --- a/router/fastdp.go +++ b/router/fastdp.go @@ -2,6 +2,7 @@ package router import ( "encoding/binary" + "encoding/json" "fmt" "net" "sync" @@ -321,6 +322,77 @@ func (fastDatapathOverlay) AddFeaturesTo(features map[string]string) { // OverlaySwitch. } +type FlowStatus odp.FlowInfo + +func (flowStatus *FlowStatus) MarshalJSON() ([]byte, error) { + type jsonFlowStatus struct { + FlowKeys []string + Actions []string + Packets uint64 + Bytes uint64 + Used uint64 + } + + flowKeys := make([]string, 0, len(flowStatus.FlowKeys)) + for _, flowKey := range flowStatus.FlowKeys { + if !flowKey.Ignored() { + flowKeys = append(flowKeys, fmt.Sprint(flowKey)) + } + } + + actions := make([]string, 0, len(flowStatus.Actions)) + for _, action := range flowStatus.Actions { + actions = append(actions, fmt.Sprint(action)) + } + + return json.Marshal(&jsonFlowStatus{flowKeys, actions, + flowStatus.Packets, flowStatus.Bytes, flowStatus.Used}) +} + +type VportStatus odp.Vport + +func (vport *VportStatus) MarshalJSON() ([]byte, error) { + type jsonVportStatus struct { + ID odp.VportID + Name string + TypeName string + } + + return json.Marshal(&jsonVportStatus{vport.ID, vport.Spec.Name(), + vport.Spec.TypeName()}) +} + +func (fastdp fastDatapathOverlay) Diagnostics() interface{} { + lock := fastdp.startLock() + defer lock.unlock() + + vports, err := fastdp.dp.EnumerateVports() + if err != nil { + log.Warn(err) + } + vportStatuses := make([]VportStatus, 0, len(vports)) + for _, vport := range vports { + vportStatuses = append(vportStatuses, VportStatus(vport)) + } + + flows, err := fastdp.dp.EnumerateFlows() + if err != nil { + log.Warn(err) + } + flowStatuses := make([]FlowStatus, 0, len(flows)) + for _, flow := range flows { + flowStatuses = append(flowStatuses, FlowStatus(flow)) + } + + return struct { + Vports []VportStatus + Flows []FlowStatus + }{ + vportStatuses, + flowStatuses, + } +} + func (fastdp fastDatapathOverlay) StartConsumingPackets(localPeer *Peer, peers *Peers, consumer OverlayConsumer) error { fastdp.lock.Lock() diff --git a/router/overlay.go b/router/overlay.go index 85e23e42..168cb9f3 100644 --- a/router/overlay.go +++ b/router/overlay.go @@ -21,6 +21,9 @@ type Overlay interface { // Enhance a features map with overlay-related features AddFeaturesTo(map[string]string) + + // Obtain diagnostic information specific to the overlay + Diagnostics() interface{} } type ForwarderParams struct { @@ -136,3 +139,7 @@ func (NullOverlay) ControlMessage(byte, []byte) { func (NullOverlay) DisplayName() string { return "null" } + +func (NullOverlay) Diagnostics() interface{} { + return nil +} diff --git a/router/overlay_switch.go b/router/overlay_switch.go index 1022c5e3..2602d24b 100644 --- a/router/overlay_switch.go +++ b/router/overlay_switch.go @@ -35,6 +35,14 @@ func (osw *OverlaySwitch) AddFeaturesTo(features map[string]string) { features["Overlays"] = strings.Join(osw.overlayNames, " ") } +func (osw *OverlaySwitch) Diagnostics() interface{} { + diagnostics := make(map[string]interface{}) + for name, overlay := range osw.overlays { + diagnostics[name] = overlay.Diagnostics() + } + return diagnostics +} + func (osw *OverlaySwitch) InvalidateRoutes() { for _, overlay := range osw.overlays { overlay.InvalidateRoutes() diff --git a/router/sleeve.go b/router/sleeve.go index e24956aa..374b34ef 100644 --- a/router/sleeve.go +++ b/router/sleeve.go @@ -133,6 +133,10 @@ func (*SleeveOverlay) AddFeaturesTo(map[string]string) { // No features to be provided, to facilitate compatibility } +func (*SleeveOverlay) Diagnostics() interface{} { + return nil +} + func (sleeve *SleeveOverlay) lookupForwarder(peer PeerName) *sleeveForwarder { sleeve.lock.Lock() defer sleeve.lock.Unlock() diff --git a/router/status.go b/router/status.go index f2e97c99..53d45cdc 100644 --- a/router/status.go +++ b/router/status.go @@ -22,6 +22,7 @@ type Status struct { BroadcastRoutes []BroadcastRouteStatus Connections []LocalConnectionStatus Targets []string + OverlayDiagnostics interface{} } type MACStatus struct { @@ -80,7 +81,8 @@ func NewStatus(router *Router) *Status { NewUnicastRouteStatusSlice(router.Routes), NewBroadcastRouteStatusSlice(router.Routes), NewLocalConnectionStatusSlice(router.ConnectionMaker), - NewTargetSlice(router.ConnectionMaker)} + NewTargetSlice(router.ConnectionMaker), + router.Overlay.Diagnostics()} } func NewMACStatusSlice(cache *MacCache) []MACStatus { From ed4ed5fdcd8ce53e3be604a47491139cf5f1fe3e Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 8 Oct 2015 11:39:54 +0100 Subject: [PATCH 4/4] Include short peer ID in report JSON --- router/status.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/router/status.go b/router/status.go index 53d45cdc..469f9329 100644 --- a/router/status.go +++ b/router/status.go @@ -36,6 +36,7 @@ type PeerStatus struct { Name string NickName string UID PeerUID + ShortID PeerShortID Version uint64 Connections []ConnectionStatus } @@ -122,6 +123,7 @@ func NewPeerStatusSlice(peers *Peers) []PeerStatus { peer.Name.String(), peer.NickName, peer.UID, + peer.ShortID, peer.Version, connections}) })