diff --git a/dc/m6220-proxy/main.go b/dc/m6220-proxy/main.go
new file mode 100644
index 0000000..6fd972d
--- /dev/null
+++ b/dc/m6220-proxy/main.go
@@ -0,0 +1,277 @@
+package main
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+
+	"code.hackerspace.pl/hscloud/go/mirko"
+	"github.com/golang/glog"
+	"github.com/ziutek/telnet"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+
+	pb "code.hackerspace.pl/hscloud/dc/m6220-proxy/proto"
+	ipb "code.hackerspace.pl/hscloud/proto/infra"
+)
+
+var (
+	flagSwitchAddress  string
+	flagSwitchUsername string
+	flagSwitchPassword string
+)
+
+func init() {
+	flag.Set("logtostderr", "true")
+}
+
+type service struct {
+	connectionSemaphore chan int
+}
+
+func (s *service) connect() (*cliClient, error) {
+	s.connectionSemaphore <- 1
+	conn, err := telnet.Dial("tcp", flagSwitchAddress)
+	if err != nil {
+		<-s.connectionSemaphore
+		return nil, err
+	}
+
+	cli := newCliClient(conn, flagSwitchUsername, flagSwitchPassword)
+	return cli, nil
+}
+
+func (s *service) disconnect() {
+	<-s.connectionSemaphore
+}
+
+func (s *service) RunCommand(ctx context.Context, req *pb.RunCommandRequest) (*pb.RunCommandResponse, error) {
+	if req.Command == "" {
+		return nil, status.Error(codes.InvalidArgument, "command cannot be null")
+	}
+
+	cli, err := s.connect()
+	if err != nil {
+		return nil, status.Error(codes.Unavailable, "could not connect to switch")
+	}
+	defer s.disconnect()
+
+	lines, effective, err := cli.runCommand(ctx, req.Command)
+	if err != nil {
+		return nil, err
+	}
+	res := &pb.RunCommandResponse{
+		EffectiveCommand: effective,
+		Lines:            lines,
+	}
+	return res, nil
+}
+
+func (s *service) parseInterfaceStatus(res *ipb.GetPortsResponse, lines []string) error {
+	if len(lines) < 4 {
+		return fmt.Errorf("need at least 4 lines of output, got %d", len(lines))
+	}
+	if lines[0] != "" {
+		return fmt.Errorf("expected first line to be empty, is %q", lines[0])
+	}
+	header1parts := strings.Fields(lines[1])
+	if want := []string{"Port", "Description", "Duplex", "Speed", "Neg", "Link", "Flow", "Control"}; !reflect.DeepEqual(want, header1parts) {
+		return fmt.Errorf("expected header1 to be %v, got %v", want, header1parts)
+	}
+
+	header2parts := strings.Fields(lines[2])
+	if want := []string{"State", "Status"}; !reflect.DeepEqual(want, header2parts) {
+		return fmt.Errorf("expected header2 to be %v, got %v", want, header2parts)
+	}
+
+	if lines[3][0] != '-' {
+		return fmt.Errorf("expected header3 to start with -, got %q", lines[3])
+	}
+
+	for _, line := range lines[4:] {
+		parts := strings.Fields(line)
+		if len(parts) < 6 {
+			break
+		}
+		portName := parts[0]
+		if strings.HasPrefix(portName, "Gi") && strings.HasPrefix(portName, "Ti") {
+			break
+		}
+
+		speedStr := parts[len(parts)-4]
+		stateStr := parts[len(parts)-2]
+
+		port := &ipb.SwitchPort{
+			Name: portName,
+		}
+		if speedStr == "100" {
+			port.Speed = ipb.SwitchPort_SPEED_100M
+		} else if speedStr == "1000" {
+			port.Speed = ipb.SwitchPort_SPEED_1G
+		} else if speedStr == "10000" {
+			port.Speed = ipb.SwitchPort_SPEED_10G
+		}
+		if stateStr == "Up" {
+			port.LinkState = ipb.SwitchPort_LINKSTATE_UP
+		} else if stateStr == "Down" {
+			port.LinkState = ipb.SwitchPort_LINKSTATE_DOWN
+		}
+
+		res.Ports = append(res.Ports, port)
+	}
+
+	return nil
+}
+
+func (s *service) parseInterfaceConfig(port *ipb.SwitchPort, lines []string) error {
+	glog.Infof("%+v", port)
+	for _, line := range lines {
+		glog.Infof("%s: %q", port.Name, line)
+		parts := strings.Fields(line)
+		if len(parts) < 1 {
+			continue
+		}
+
+		if len(parts) >= 2 && parts[0] == "switchport" {
+			if parts[1] == "mode" {
+				if port.PortMode != ipb.SwitchPort_PORTMODE_INVALID {
+					return fmt.Errorf("redefinition of switchport mode")
+				}
+				if parts[2] == "access" {
+					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
+				} else if parts[2] == "trunk" {
+					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED
+				} else if parts[2] == "general" {
+					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC
+				} else {
+					port.PortMode = ipb.SwitchPort_PORTMODE_MANGLED
+				}
+			}
+
+			if parts[1] == "access" {
+				if port.PortMode == ipb.SwitchPort_PORTMODE_INVALID {
+					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
+				}
+				if len(parts) > 3 && parts[2] == "vlan" {
+					vlan, err := strconv.Atoi(parts[3])
+					if err != nil {
+						return fmt.Errorf("invalid vlan: %q", parts[3])
+					}
+					port.VlanNative = int32(vlan)
+				}
+			}
+
+			if parts[1] == "trunk" {
+				if len(parts) >= 5 && parts[2] == "allowed" && parts[3] == "vlan" {
+					vlans := strings.Split(parts[4], ",")
+					for _, vlan := range vlans {
+						vlanNum, err := strconv.Atoi(vlan)
+						if err != nil {
+							return fmt.Errorf("invalid vlan: %q", parts[3])
+						}
+						port.VlanTagged = append(port.VlanTagged, int32(vlanNum))
+					}
+				}
+			}
+		} else if len(parts) >= 2 && parts[0] == "mtu" {
+			mtu, err := strconv.Atoi(parts[1])
+			if err != nil {
+				return fmt.Errorf("invalid mtu: %q", parts[3])
+			}
+			port.Mtu = int32(mtu)
+		} else if len(parts) >= 2 && parts[0] == "spanning-tree" && parts[1] == "portfast" {
+			port.SpanningTreeMode = ipb.SwitchPort_SPANNING_TREE_MODE_PORTFAST
+		}
+	}
+
+	// no mode -> access
+	if port.PortMode == ipb.SwitchPort_PORTMODE_INVALID {
+		port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
+	}
+
+	// apply defaults
+	if port.Mtu == 0 {
+		port.Mtu = 1500
+	}
+	if port.SpanningTreeMode == ipb.SwitchPort_SPANNING_TREE_MODE_INVALID {
+		port.SpanningTreeMode = ipb.SwitchPort_SPANNING_TREE_MODE_AUTO_PORTFAST
+	}
+
+	// sanitize
+	if port.PortMode == ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED {
+		port.VlanTagged = []int32{}
+		port.Prefixes = []string{}
+		if port.VlanNative == 0 {
+			port.VlanNative = 1
+		}
+	} else if port.PortMode == ipb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED {
+		port.VlanNative = 0
+		port.Prefixes = []string{}
+	} else if port.PortMode == ipb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC {
+		port.Prefixes = []string{}
+		if port.VlanNative == 0 {
+			port.VlanNative = 1
+		}
+	}
+	return nil
+}
+
+func (s *service) GetPorts(ctx context.Context, req *ipb.GetPortsRequest) (*ipb.GetPortsResponse, error) {
+	cli, err := s.connect()
+	if err != nil {
+		return nil, status.Error(codes.Unavailable, "could not connect to switch")
+	}
+	defer s.disconnect()
+	res := &ipb.GetPortsResponse{}
+
+	statusLines, _, err := cli.runCommand(ctx, "show interface status")
+	if err != nil {
+		return nil, status.Error(codes.Unavailable, "could not get interface status from switch")
+	}
+
+	err = s.parseInterfaceStatus(res, statusLines)
+	if err != nil {
+		return nil, status.Errorf(codes.Unavailable, "could not parse interface status from switch: %v", err)
+	}
+
+	for _, port := range res.Ports {
+		configLines, _, err := cli.runCommand(ctx, "show run interface "+port.Name)
+		if err != nil {
+			return nil, status.Error(codes.Unavailable, "could not get interface config from switch")
+		}
+		err = s.parseInterfaceConfig(port, configLines)
+		if err != nil {
+			return nil, status.Errorf(codes.Unavailable, "could not parse interface config from switch: %v", err)
+		}
+	}
+
+	return res, nil
+}
+
+func main() {
+	flag.StringVar(&flagSwitchAddress, "switch_address", "127.0.0.1:23", "Telnet address of M6220")
+	flag.StringVar(&flagSwitchUsername, "switch_username", "admin", "Switch login username")
+	flag.StringVar(&flagSwitchPassword, "switch_password", "admin", "Switch login password")
+	flag.Parse()
+
+	s := &service{
+		connectionSemaphore: make(chan int, 1),
+	}
+
+	m := mirko.New()
+	if err := m.Listen(); err != nil {
+		glog.Exitf("Listen(): %v", err)
+	}
+
+	pb.RegisterM6220ProxyServer(m.GRPC(), s)
+	ipb.RegisterSwitchControlServer(m.GRPC(), s)
+
+	if err := m.Serve(); err != nil {
+		glog.Exitf("Serve(): %v", err)
+	}
+
+	select {}
+}
