diff --git a/dc/topo/service.go b/dc/topo/service.go
new file mode 100644
index 0000000..8919939
--- /dev/null
+++ b/dc/topo/service.go
@@ -0,0 +1,235 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"sort"
+	"strings"
+
+	"vbom.ml/util/sortorder"
+
+	"code.hackerspace.pl/hscloud/go/mirko"
+	"code.hackerspace.pl/hscloud/go/statusz"
+	ipb "code.hackerspace.pl/hscloud/proto/infra"
+
+	"code.hackerspace.pl/hscloud/dc/topo/assets"
+	"code.hackerspace.pl/hscloud/dc/topo/graph"
+	"code.hackerspace.pl/hscloud/dc/topo/state"
+)
+
+type Service struct {
+	gr  *graph.Graph
+	stm *state.StateManager
+}
+
+func NewService(gr *graph.Graph, stm *state.StateManager) *Service {
+	return &Service{
+		gr:  gr,
+		stm: stm,
+	}
+}
+
+const topologyFragment = `
+  <script src="/assets/viz.js"></script>
+  <script>
+
+    var viz = new Viz({ workerURL: '/assets/full.render.js' });
+	var xmlhttp = new XMLHttpRequest();
+	xmlhttp.onreadystatechange = function() {
+      if (this.readyState == 4 && this.status == 200) {
+        var dot = this.responseText;
+        viz.renderSVGElement(dot)
+        .then(function(element) {
+          document.getElementById("graph").appendChild(element);
+        });
+      }
+    };
+    xmlhttp.open('GET', '/debug/graphviz');
+    xmlhttp.send();
+
+  </script>
+  <div id="graph" style="text-align: center;"></div>
+`
+
+const switchportsFragment = `
+    <style type="text/css">
+		.table td,th {
+			background-color: #eee;
+			padding: 0.2em 0.4em 0.2em 0.4em;
+		}
+		.table th {
+			background-color: #c0c0c0;
+		}
+		.table {
+			background-color: #fff;
+			border-spacing: 0.2em;
+			margin-left: auto;
+			margin-right: auto;
+		}
+	</style>
+	<div>
+	<table class="table">
+		<tr>
+      		<th>Switch</th>
+      		<th>Port</th>
+			<th>Link State</th>
+			<th>Port Mode</th>
+			<th>MTU</th>
+			<th>Sync Status</th>
+		</tr>
+		{{range .Ports }}
+		{{ if .Managed }}
+		<tr>
+		{{ else }}
+		<tr style="opacity: 0.5">
+		{{ end}}
+			<td style="text-align: right;">{{ .Switch }}</td>
+			<td>{{ .Name }}</td>
+			{{ if eq .State "DOWN" }}
+			<td style="background-color: #ff3030;">{{ .State }}</td>
+			{{ else }}
+			<td>{{ .State }}</td>
+			{{ end }}
+			<td>{{ .Mode }}</td>
+			<td>{{ .MTU }}</td>
+			{{ if .Managed }}
+			<td style="background-color: #30ff30;">OK</td>
+			{{ else }}
+			<td><i>Unmanaged</i></td>
+			{{ end }}
+		</tr>
+		{{end}}
+	</table>
+	</div>
+`
+
+func (s *Service) Setup(m *mirko.Mirko) {
+	m.HTTPMux().Handle("/assets/", http.StripPrefix("/assets/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		data, ok := assets.Data[r.RequestURI]
+		if !ok {
+			http.NotFound(w, r)
+			return
+		}
+
+		if strings.HasSuffix(r.RequestURI, ".js") {
+			w.Header().Set("Content-Type", "text/javascript")
+		}
+
+		w.Write(data)
+	})))
+	m.HTTPMux().HandleFunc("/debug/graphviz", s.httpHandleGraphviz)
+	statusz.AddStatusPart("Switch Ports", switchportsFragment, s.statusHandleSwitchports)
+	statusz.AddStatusPart("Topology", topologyFragment, func(ctx context.Context) interface{} {
+		return nil
+	})
+}
+
+func (s *Service) statusHandleSwitchports(ctx context.Context) interface{} {
+	managedPorts := make(map[string]bool)
+	s.gr.Mu.RLock()
+	for _, sw := range s.gr.Switches {
+		for _, port := range sw.Ports {
+			managedPorts[sw.Name+"|"+port.Name] = true
+		}
+	}
+	s.gr.Mu.RUnlock()
+
+	s.stm.Mu.RLock()
+	defer s.stm.Mu.RUnlock()
+
+	res := struct {
+		Ports []*struct {
+			Switch  string
+			Name    string
+			State   string
+			Mode    string
+			Managed bool
+			MTU     string
+		}
+	}{}
+	for _, sw := range s.stm.Switches {
+		for _, po := range sw.Ports {
+			state := "INVALID"
+			switch po.Proto.LinkState {
+			case ipb.SwitchPort_LINKSTATE_DOWN:
+				state = "DOWN"
+			case ipb.SwitchPort_LINKSTATE_UP:
+				state = "UP"
+			}
+			mode := "INVALID"
+			switch po.Proto.PortMode {
+			case ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED:
+				mode = fmt.Sprintf("UNTAGGED (%d)", po.Proto.VlanNative)
+			case ipb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED:
+				mode = fmt.Sprintf("TAGGED (%v)", po.Proto.VlanTagged)
+			case ipb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC:
+				mode = "GENERIC"
+			case ipb.SwitchPort_PORTMODE_ROUTED:
+				mode = "ROUTED"
+			case ipb.SwitchPort_PORTMODE_MANGLED:
+				mode = "MANGLED"
+			}
+
+			managed := managedPorts[sw.Name+"|"+po.Proto.Name]
+			res.Ports = append(res.Ports, &struct {
+				Switch  string
+				Name    string
+				State   string
+				Mode    string
+				Managed bool
+				MTU     string
+			}{
+				Switch:  sw.Name,
+				Name:    po.Proto.Name,
+				State:   state,
+				Mode:    mode,
+				Managed: managed,
+				MTU:     fmt.Sprintf("%d", po.Proto.Mtu),
+			})
+		}
+	}
+
+	return res
+}
+
+func (s *Service) httpHandleGraphviz(w http.ResponseWriter, r *http.Request) {
+	fmt.Fprintf(w, "graph G {\n")
+	fmt.Fprintf(w, "  ranksep = 2\n")
+	fmt.Fprintf(w, "  splines = polyline\n")
+	fmt.Fprintf(w, "  rankdir = LR\n")
+	for _, machine := range s.gr.Machines {
+		portNames := []string{}
+		for _, port := range machine.Ports {
+			name := fmt.Sprintf("<%s> %s", port.Name, port.Name)
+			portNames = append(portNames, name)
+		}
+		ports := strings.Join(portNames, "|")
+		fmt.Fprintf(w, "  %s [shape=record label=\"{ %s | { %s }}\"]\n", machine.Name, machine.Name, ports)
+	}
+	for _, sw := range s.gr.Switches {
+		portNames := []string{}
+		portsOrdered := []*graph.SwitchPort{}
+		for _, port := range sw.Ports {
+			portsOrdered = append(portsOrdered, port)
+		}
+		sort.Slice(portsOrdered, func(i, j int) bool {
+			return sortorder.NaturalLess(portsOrdered[i].Name, portsOrdered[j].Name)
+		})
+		for _, port := range portsOrdered {
+			name := fmt.Sprintf("<%s> %s", port.Name, port.Name)
+			portNames = append(portNames, name)
+		}
+		ports := strings.Join(portNames, "|")
+		fmt.Fprintf(w, "  %s [shape=record label=\"{{ %s } | %s}\"]\n", sw.Name, ports, sw.Name)
+	}
+	for _, machine := range s.gr.Machines {
+		for _, port := range machine.Ports {
+			if port.OtherEnd == nil {
+				continue
+			}
+			fmt.Fprintf(w, "  %s:%q:e -- %s:%q:w\n", machine.Name, port.Name, port.OtherEnd.Switch.Name, port.OtherEnd.Name)
+		}
+	}
+	fmt.Fprintf(w, "}\n")
+}
