// Code generated by protoc-gen-go. DO NOT EDIT.
// source: control.proto

/*
Package connector is a generated protocol buffer package.

It is generated from these files:
	control.proto

It has these top-level messages:
	GetPortsRequest
	SwitchPort
	GetPortsResponse
*/
package connector

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

import (
	context "golang.org/x/net/context"
	grpc "google.golang.org/grpc"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type SwitchPort_Speed int32

const (
	SwitchPort_SPEED_INVALID SwitchPort_Speed = 0
	SwitchPort_SPEED_100M    SwitchPort_Speed = 1
	SwitchPort_SPEED_1G      SwitchPort_Speed = 2
	SwitchPort_SPEED_10G     SwitchPort_Speed = 3
)

var SwitchPort_Speed_name = map[int32]string{
	0: "SPEED_INVALID",
	1: "SPEED_100M",
	2: "SPEED_1G",
	3: "SPEED_10G",
}
var SwitchPort_Speed_value = map[string]int32{
	"SPEED_INVALID": 0,
	"SPEED_100M":    1,
	"SPEED_1G":      2,
	"SPEED_10G":     3,
}

func (x SwitchPort_Speed) String() string {
	return proto.EnumName(SwitchPort_Speed_name, int32(x))
}
func (SwitchPort_Speed) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} }

type SwitchPort_LinkState int32

const (
	SwitchPort_LINKSTATE_INVALID SwitchPort_LinkState = 0
	SwitchPort_LINKSTATE_DOWN    SwitchPort_LinkState = 1
	SwitchPort_LINKSTATE_UP      SwitchPort_LinkState = 2
)

var SwitchPort_LinkState_name = map[int32]string{
	0: "LINKSTATE_INVALID",
	1: "LINKSTATE_DOWN",
	2: "LINKSTATE_UP",
}
var SwitchPort_LinkState_value = map[string]int32{
	"LINKSTATE_INVALID": 0,
	"LINKSTATE_DOWN":    1,
	"LINKSTATE_UP":      2,
}

func (x SwitchPort_LinkState) String() string {
	return proto.EnumName(SwitchPort_LinkState_name, int32(x))
}
func (SwitchPort_LinkState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 1} }

type SwitchPort_PortMode int32

const (
	SwitchPort_PORTMODE_INVALID SwitchPort_PortMode = 0
	// Interface is bridged to a VLAN, untagged.
	SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED SwitchPort_PortMode = 1
	// Interfaces is bridged to several tagged 802.1q VLANs.
	SwitchPort_PORTMODE_SWITCHPORT_TAGGED SwitchPort_PortMode = 2
	// Interface is in 'generic', both tagged 802.1q and untagged mode.
	SwitchPort_PORTMODE_SWITCHPORT_GENERIC SwitchPort_PortMode = 3
	// Interface is routed, ie routes packets from a separate L3 network
	// and the Switch is the default gateway for machines in this network.
	SwitchPort_PORTMODE_ROUTED SwitchPort_PortMode = 4
	// Interface is in a configuration state that cannot be clearly stated
	// in terms of this enum, and should be reconfigured.
	SwitchPort_PORTMODE_MANGLED SwitchPort_PortMode = 5
)

var SwitchPort_PortMode_name = map[int32]string{
	0: "PORTMODE_INVALID",
	1: "PORTMODE_SWITCHPORT_UNTAGGED",
	2: "PORTMODE_SWITCHPORT_TAGGED",
	3: "PORTMODE_SWITCHPORT_GENERIC",
	4: "PORTMODE_ROUTED",
	5: "PORTMODE_MANGLED",
}
var SwitchPort_PortMode_value = map[string]int32{
	"PORTMODE_INVALID":             0,
	"PORTMODE_SWITCHPORT_UNTAGGED": 1,
	"PORTMODE_SWITCHPORT_TAGGED":   2,
	"PORTMODE_SWITCHPORT_GENERIC":  3,
	"PORTMODE_ROUTED":              4,
	"PORTMODE_MANGLED":             5,
}

func (x SwitchPort_PortMode) String() string {
	return proto.EnumName(SwitchPort_PortMode_name, int32(x))
}
func (SwitchPort_PortMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 2} }

type SwitchPort_SpanningTreeMode int32

const (
	SwitchPort_SPANNING_TREE_MODE_INVALID SwitchPort_SpanningTreeMode = 0
	// Send STP BPDU, on timeout switch to Forwarding.
	SwitchPort_SPANNING_TREE_MODE_AUTO_PORTFAST SwitchPort_SpanningTreeMode = 1
	// Switch to Forwarding immediately on link up.
	SwitchPort_SPANNING_TREE_MODE_PORTFAST SwitchPort_SpanningTreeMode = 2
)

var SwitchPort_SpanningTreeMode_name = map[int32]string{
	0: "SPANNING_TREE_MODE_INVALID",
	1: "SPANNING_TREE_MODE_AUTO_PORTFAST",
	2: "SPANNING_TREE_MODE_PORTFAST",
}
var SwitchPort_SpanningTreeMode_value = map[string]int32{
	"SPANNING_TREE_MODE_INVALID":       0,
	"SPANNING_TREE_MODE_AUTO_PORTFAST": 1,
	"SPANNING_TREE_MODE_PORTFAST":      2,
}

func (x SwitchPort_SpanningTreeMode) String() string {
	return proto.EnumName(SwitchPort_SpanningTreeMode_name, int32(x))
}
func (SwitchPort_SpanningTreeMode) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor0, []int{1, 3}
}

type GetPortsRequest struct {
}

func (m *GetPortsRequest) Reset()                    { *m = GetPortsRequest{} }
func (m *GetPortsRequest) String() string            { return proto.CompactTextString(m) }
func (*GetPortsRequest) ProtoMessage()               {}
func (*GetPortsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

type SwitchPort struct {
	Name      string               `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
	Speed     SwitchPort_Speed     `protobuf:"varint,2,opt,name=speed,enum=connector.SwitchPort_Speed" json:"speed,omitempty"`
	LinkState SwitchPort_LinkState `protobuf:"varint,3,opt,name=link_state,json=linkState,enum=connector.SwitchPort_LinkState" json:"link_state,omitempty"`
	PortMode  SwitchPort_PortMode  `protobuf:"varint,4,opt,name=port_mode,json=portMode,enum=connector.SwitchPort_PortMode" json:"port_mode,omitempty"`
	// For PORTMODE_SWITCHPORT_UNTAGGED and PORTMODE_SWITCHPORT_GENERIC, the
	// VLAN ID that this interface is natively bridged to.
	VlanNative int32 `protobuf:"varint,5,opt,name=vlan_native,json=vlanNative" json:"vlan_native,omitempty"`
	// For PORTMODE_SWITCHPORT_TAGGED and PORTMODE_SWITCHPORT_GENERIC, the VLAN
	// IDs that the interface is bridged to using 802.1q tags.
	VlanTagged []int32 `protobuf:"varint,6,rep,packed,name=vlan_tagged,json=vlanTagged" json:"vlan_tagged,omitempty"`
	// For PORTMODE_ROUTED
	Prefixes []string `protobuf:"bytes,7,rep,name=prefixes" json:"prefixes,omitempty"`
	// Interface MTU
	Mtu              int32                       `protobuf:"varint,8,opt,name=mtu" json:"mtu,omitempty"`
	SpanningTreeMode SwitchPort_SpanningTreeMode `protobuf:"varint,9,opt,name=spanning_tree_mode,json=spanningTreeMode,enum=connector.SwitchPort_SpanningTreeMode" json:"spanning_tree_mode,omitempty"`
}

func (m *SwitchPort) Reset()                    { *m = SwitchPort{} }
func (m *SwitchPort) String() string            { return proto.CompactTextString(m) }
func (*SwitchPort) ProtoMessage()               {}
func (*SwitchPort) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }

func (m *SwitchPort) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *SwitchPort) GetSpeed() SwitchPort_Speed {
	if m != nil {
		return m.Speed
	}
	return SwitchPort_SPEED_INVALID
}

func (m *SwitchPort) GetLinkState() SwitchPort_LinkState {
	if m != nil {
		return m.LinkState
	}
	return SwitchPort_LINKSTATE_INVALID
}

func (m *SwitchPort) GetPortMode() SwitchPort_PortMode {
	if m != nil {
		return m.PortMode
	}
	return SwitchPort_PORTMODE_INVALID
}

func (m *SwitchPort) GetVlanNative() int32 {
	if m != nil {
		return m.VlanNative
	}
	return 0
}

func (m *SwitchPort) GetVlanTagged() []int32 {
	if m != nil {
		return m.VlanTagged
	}
	return nil
}

func (m *SwitchPort) GetPrefixes() []string {
	if m != nil {
		return m.Prefixes
	}
	return nil
}

func (m *SwitchPort) GetMtu() int32 {
	if m != nil {
		return m.Mtu
	}
	return 0
}

func (m *SwitchPort) GetSpanningTreeMode() SwitchPort_SpanningTreeMode {
	if m != nil {
		return m.SpanningTreeMode
	}
	return SwitchPort_SPANNING_TREE_MODE_INVALID
}

type GetPortsResponse struct {
	Ports []*SwitchPort `protobuf:"bytes,1,rep,name=ports" json:"ports,omitempty"`
}

func (m *GetPortsResponse) Reset()                    { *m = GetPortsResponse{} }
func (m *GetPortsResponse) String() string            { return proto.CompactTextString(m) }
func (*GetPortsResponse) ProtoMessage()               {}
func (*GetPortsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }

func (m *GetPortsResponse) GetPorts() []*SwitchPort {
	if m != nil {
		return m.Ports
	}
	return nil
}

func init() {
	proto.RegisterType((*GetPortsRequest)(nil), "connector.GetPortsRequest")
	proto.RegisterType((*SwitchPort)(nil), "connector.SwitchPort")
	proto.RegisterType((*GetPortsResponse)(nil), "connector.GetPortsResponse")
	proto.RegisterEnum("connector.SwitchPort_Speed", SwitchPort_Speed_name, SwitchPort_Speed_value)
	proto.RegisterEnum("connector.SwitchPort_LinkState", SwitchPort_LinkState_name, SwitchPort_LinkState_value)
	proto.RegisterEnum("connector.SwitchPort_PortMode", SwitchPort_PortMode_name, SwitchPort_PortMode_value)
	proto.RegisterEnum("connector.SwitchPort_SpanningTreeMode", SwitchPort_SpanningTreeMode_name, SwitchPort_SpanningTreeMode_value)
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// Client API for SwitchControl service

type SwitchControlClient interface {
	GetPorts(ctx context.Context, in *GetPortsRequest, opts ...grpc.CallOption) (*GetPortsResponse, error)
}

type switchControlClient struct {
	cc *grpc.ClientConn
}

func NewSwitchControlClient(cc *grpc.ClientConn) SwitchControlClient {
	return &switchControlClient{cc}
}

func (c *switchControlClient) GetPorts(ctx context.Context, in *GetPortsRequest, opts ...grpc.CallOption) (*GetPortsResponse, error) {
	out := new(GetPortsResponse)
	err := grpc.Invoke(ctx, "/connector.SwitchControl/GetPorts", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for SwitchControl service

type SwitchControlServer interface {
	GetPorts(context.Context, *GetPortsRequest) (*GetPortsResponse, error)
}

func RegisterSwitchControlServer(s *grpc.Server, srv SwitchControlServer) {
	s.RegisterService(&_SwitchControl_serviceDesc, srv)
}

func _SwitchControl_GetPorts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetPortsRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SwitchControlServer).GetPorts(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/connector.SwitchControl/GetPorts",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SwitchControlServer).GetPorts(ctx, req.(*GetPortsRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _SwitchControl_serviceDesc = grpc.ServiceDesc{
	ServiceName: "connector.SwitchControl",
	HandlerType: (*SwitchControlServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetPorts",
			Handler:    _SwitchControl_GetPorts_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "control.proto",
}

func init() { proto.RegisterFile("control.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
	// 561 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xd1, 0x6e, 0x9b, 0x4a,
	0x10, 0xbd, 0x98, 0x38, 0x17, 0x26, 0x71, 0xb2, 0x99, 0x36, 0x12, 0x72, 0xaa, 0x04, 0xa1, 0xaa,
	0xb2, 0x54, 0xc9, 0x4a, 0xd2, 0xc7, 0x4a, 0xad, 0x90, 0xa1, 0x04, 0xd5, 0xc6, 0xd6, 0xb2, 0x6e,
	0x1e, 0x11, 0xb5, 0xb7, 0x29, 0x8a, 0xb3, 0x50, 0xd8, 0xa4, 0xed, 0x4f, 0xf5, 0x6f, 0xfa, 0x3f,
	0x15, 0x10, 0xe3, 0xd4, 0xa2, 0x2f, 0x68, 0xe6, 0xcc, 0x39, 0xb3, 0x87, 0xd1, 0xce, 0x42, 0x6f,
	0x91, 0x0a, 0x99, 0xa7, 0xab, 0x61, 0x96, 0xa7, 0x32, 0x45, 0x7d, 0x91, 0x0a, 0xc1, 0x17, 0x32,
	0xcd, 0xad, 0x23, 0x38, 0xf4, 0xb8, 0x9c, 0xa5, 0xb9, 0x2c, 0x28, 0xff, 0x76, 0xcf, 0x0b, 0x69,
	0xfd, 0xde, 0x05, 0x08, 0xbf, 0x27, 0x72, 0xf1, 0xb5, 0x84, 0x11, 0x61, 0x47, 0xc4, 0x77, 0xdc,
	0x50, 0x4c, 0x65, 0xa0, 0xd3, 0x2a, 0xc6, 0x0b, 0xe8, 0x16, 0x19, 0xe7, 0x4b, 0xa3, 0x63, 0x2a,
	0x83, 0x83, 0xcb, 0x93, 0x61, 0xd3, 0x70, 0xb8, 0x51, 0x0e, 0xc3, 0x92, 0x42, 0x6b, 0x26, 0xbe,
	0x03, 0x58, 0x25, 0xe2, 0x36, 0x2a, 0x64, 0x2c, 0xb9, 0xa1, 0x56, 0xba, 0xb3, 0x76, 0xdd, 0x38,
	0x11, 0xb7, 0x61, 0x49, 0xa3, 0xfa, 0x6a, 0x1d, 0xe2, 0x5b, 0xd0, 0xb3, 0x34, 0x97, 0xd1, 0x5d,
	0xba, 0xe4, 0xc6, 0x4e, 0x25, 0x3f, 0x6d, 0x97, 0x97, 0x9f, 0x49, 0xba, 0xe4, 0x54, 0xcb, 0x1e,
	0x23, 0x3c, 0x83, 0xbd, 0x87, 0x55, 0x2c, 0x22, 0x11, 0xcb, 0xe4, 0x81, 0x1b, 0x5d, 0x53, 0x19,
	0x74, 0x29, 0x94, 0x50, 0x50, 0x21, 0x0d, 0x41, 0xc6, 0x37, 0x37, 0x7c, 0x69, 0xec, 0x9a, 0xea,
	0x9a, 0xc0, 0x2a, 0x04, 0xfb, 0xa0, 0x65, 0x39, 0xff, 0x92, 0xfc, 0xe0, 0x85, 0xf1, 0xbf, 0xa9,
	0x0e, 0x74, 0xda, 0xe4, 0x48, 0x40, 0xbd, 0x93, 0xf7, 0x86, 0x56, 0x75, 0x2d, 0x43, 0x64, 0x80,
	0x45, 0x16, 0x0b, 0x91, 0x88, 0x9b, 0x48, 0xe6, 0x9c, 0xd7, 0xae, 0xf5, 0xca, 0xf5, 0xab, 0x7f,
	0x0d, 0xab, 0xe6, 0xb3, 0x9c, 0xf3, 0xca, 0x3d, 0x29, 0xb6, 0x10, 0xcb, 0x83, 0x6e, 0x35, 0x52,
	0x3c, 0x82, 0x5e, 0x38, 0x73, 0x5d, 0x27, 0xf2, 0x83, 0x4f, 0xf6, 0xd8, 0x77, 0xc8, 0x7f, 0x78,
	0x00, 0x50, 0x43, 0x17, 0xe7, 0xe7, 0x13, 0xa2, 0xe0, 0x3e, 0x68, 0x8f, 0xb9, 0x47, 0x3a, 0xd8,
	0x03, 0x7d, 0x5d, 0xf5, 0x88, 0x6a, 0x5d, 0x81, 0xde, 0xcc, 0x18, 0x8f, 0xe1, 0x68, 0xec, 0x07,
	0x1f, 0x43, 0x66, 0x33, 0xf7, 0x49, 0x43, 0x84, 0x83, 0x0d, 0xec, 0x4c, 0xaf, 0x03, 0xa2, 0x20,
	0x81, 0xfd, 0x0d, 0x36, 0x9f, 0x91, 0x8e, 0xf5, 0x4b, 0x01, 0x6d, 0x3d, 0x6f, 0x7c, 0x0e, 0x64,
	0x36, 0xa5, 0x6c, 0x32, 0x75, 0x9e, 0x36, 0x32, 0xe1, 0x45, 0x83, 0x86, 0xd7, 0x3e, 0x1b, 0x5d,
	0x95, 0x69, 0x34, 0x0f, 0x98, 0xed, 0x79, 0xae, 0x43, 0x14, 0x3c, 0x85, 0x7e, 0x1b, 0xe3, 0xb1,
	0xde, 0xc1, 0x33, 0x38, 0x69, 0xab, 0x7b, 0x6e, 0xe0, 0x52, 0x7f, 0x44, 0x54, 0x7c, 0x06, 0x87,
	0x0d, 0x81, 0x4e, 0xe7, 0xcc, 0x75, 0xc8, 0xce, 0x5f, 0x6e, 0x26, 0x76, 0xe0, 0x8d, 0x5d, 0x87,
	0x74, 0xad, 0x9f, 0x40, 0xb6, 0x27, 0x5d, 0x9e, 0x1f, 0xce, 0xec, 0x20, 0xf0, 0x03, 0x2f, 0x62,
	0xd4, 0x75, 0xa3, 0xad, 0x3f, 0x78, 0x09, 0x66, 0x4b, 0xdd, 0x9e, 0xb3, 0x69, 0x54, 0x9e, 0xf0,
	0xc1, 0x0e, 0x19, 0x51, 0x4a, 0x97, 0x2d, 0xac, 0x86, 0xd0, 0xb1, 0xde, 0x03, 0xd9, 0xac, 0x5a,
	0x91, 0xa5, 0xa2, 0xe0, 0xf8, 0x1a, 0xba, 0xe5, 0x25, 0x2d, 0x0c, 0xc5, 0x54, 0x07, 0x7b, 0x97,
	0xc7, 0xad, 0x77, 0x83, 0xd6, 0x9c, 0x4b, 0x06, 0xbd, 0x1a, 0x1c, 0xd5, 0xdb, 0x8c, 0x23, 0xd0,
	0xd6, 0x1d, 0xb1, 0xff, 0x44, 0xba, 0xb5, 0xd1, 0xfd, 0x93, 0xd6, 0x5a, 0x6d, 0xe1, 0xf3, 0x6e,
	0xf5, 0x26, 0xbc, 0xf9, 0x13, 0x00, 0x00, 0xff, 0xff, 0xae, 0x71, 0xa0, 0x75, 0x24, 0x04, 0x00,
	0x00,
}
