From f7d8c947d113b313b351b1a5d07a4d3a97f422e3 Mon Sep 17 00:00:00 2001 From: Daniel Grau Date: Wed, 17 Jul 2024 21:49:07 +0000 Subject: [PATCH 1/3] Initial policer implementation --- dataplane/forwarding/protocol/attr.go | 4 + .../forwarding/protocol/metadata/metadata.go | 7 + dataplane/saiserver/acl.go | 7 + dataplane/saiserver/policer.go | 41 +++- dataplane/saiserver/switch.go | 21 ++ proto/forwarding/forwarding_common.pb.go | 187 +++++++++--------- proto/forwarding/forwarding_common.proto | 1 + 7 files changed, 173 insertions(+), 95 deletions(-) diff --git a/dataplane/forwarding/protocol/attr.go b/dataplane/forwarding/protocol/attr.go index 3b43fe4f..d008644b 100644 --- a/dataplane/forwarding/protocol/attr.go +++ b/dataplane/forwarding/protocol/attr.go @@ -191,6 +191,9 @@ var FieldAttr = map[fwdpb.PacketFieldNum]struct { fwdpb.PacketFieldNum_PACKET_FIELD_NUM_HOST_PORT_ID: { Sizes: []int{SizeUint64}, }, + fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID: { + Sizes: []int{SizeUint64}, + }, } // GroupAttr contains attributes for each packet header group. @@ -229,6 +232,7 @@ var GroupAttr = map[fwdpb.PacketHeaderGroup]struct { fwdpb.PacketFieldNum_PACKET_FIELD_NUM_OUTPUT_IFACE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_TUNNEL_ID, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_HOST_PORT_ID, + fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID, }, }, fwdpb.PacketHeaderGroup_PACKET_HEADER_GROUP_L2: { diff --git a/dataplane/forwarding/protocol/metadata/metadata.go b/dataplane/forwarding/protocol/metadata/metadata.go index 6a6ff735..279e7dbe 100644 --- a/dataplane/forwarding/protocol/metadata/metadata.go +++ b/dataplane/forwarding/protocol/metadata/metadata.go @@ -46,6 +46,7 @@ type Metadata struct { outputIface []byte // L3 output interface id. tunnelID []byte // Tunnel ID hostPortID []byte // Host port id + policer []byte // Policer ID desc *protocol.Desc // Protocol descriptor. } @@ -126,6 +127,8 @@ func (m *Metadata) Field(id fwdpacket.FieldID) ([]byte, error) { return m.tunnelID, nil case fwdpb.PacketFieldNum_PACKET_FIELD_NUM_HOST_PORT_ID: return m.hostPortID, nil + case fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID: + return m.policer, nil default: return nil, fmt.Errorf("metadata: Field %v failed, unsupported field", id) @@ -232,6 +235,9 @@ func (m *Metadata) updateSet(id fwdpacket.FieldID, arg []byte) (bool, error) { case fwdpb.PacketFieldNum_PACKET_FIELD_NUM_HOST_PORT_ID: m.hostPortID = arg return true, nil + case fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID: + m.policer = arg + return true, nil default: return false, fmt.Errorf("metadata: UpdateField failed, set unsupported for field %v", id) } @@ -287,6 +293,7 @@ func parse(frame *frame.Frame, desc *protocol.Desc) (protocol.Handler, fwdpb.Pac outputIface: make([]byte, protocol.FieldAttr[fwdpb.PacketFieldNum_PACKET_FIELD_NUM_OUTPUT_IFACE].DefaultSize), tunnelID: make([]byte, protocol.FieldAttr[fwdpb.PacketFieldNum_PACKET_FIELD_NUM_TUNNEL_ID].DefaultSize), hostPortID: make([]byte, protocol.FieldAttr[fwdpb.PacketFieldNum_PACKET_FIELD_NUM_HOST_PORT_ID].DefaultSize), + policer: make([]byte, protocol.FieldAttr[fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID].DefaultSize), attribute32: make(map[uint8][]byte), attribute24: make(map[uint8][]byte), attribute16: make(map[uint8][]byte), diff --git a/dataplane/saiserver/acl.go b/dataplane/saiserver/acl.go index 7f93ca2d..ce4f382d 100644 --- a/dataplane/saiserver/acl.go +++ b/dataplane/saiserver/acl.go @@ -328,6 +328,13 @@ func (a *acl) CreateAclEntry(ctx context.Context, req *saipb.CreateAclEntryReque }, }) } + if req.ActionSetPolicer != nil { + aReq.Actions = append(aReq.Actions, + fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID). + WithUint64Value(req.GetActionSetUserTrapId().GetOid())).Build(), + fwdconfig.Action(fwdconfig.LookupAction(policerTabler)).Build(), + ) + } cpuPortReq := &saipb.GetSwitchAttributeRequest{Oid: switchID, AttrType: []saipb.SwitchAttr{saipb.SwitchAttr_SWITCH_ATTR_CPU_PORT}} resp := &saipb.GetSwitchAttributeResponse{} diff --git a/dataplane/saiserver/policer.go b/dataplane/saiserver/policer.go index bb7b5892..6a1245fc 100644 --- a/dataplane/saiserver/policer.go +++ b/dataplane/saiserver/policer.go @@ -16,12 +16,15 @@ package saiserver import ( "context" + "fmt" "google.golang.org/grpc" + "github.com/openconfig/lemming/dataplane/forwarding/fwdconfig" "github.com/openconfig/lemming/dataplane/saiserver/attrmgr" saipb "github.com/openconfig/lemming/dataplane/proto/sai" + fwdpb "github.com/openconfig/lemming/proto/forwarding" ) type policer struct { @@ -39,16 +42,46 @@ func newPolicer(mgr *attrmgr.AttrMgr, dataplane switchDataplaneAPI, s *grpc.Serv return p } -// CreatePolicer return policer. -func (p *policer) CreatePolicer(context.Context, *saipb.CreatePolicerRequest) (*saipb.CreatePolicerResponse, error) { +// CreatePolicer creates a new policer, QOS is not actually supported.ß the GREEN action is always taken.ß +func (p *policer) CreatePolicer(ctx context.Context, req *saipb.CreatePolicerRequest) (*saipb.CreatePolicerResponse, error) { id := p.mgr.NextID() - // TODO: provide implementation. + + cpuPortReq := &saipb.GetSwitchAttributeRequest{Oid: switchID, AttrType: []saipb.SwitchAttr{saipb.SwitchAttr_SWITCH_ATTR_CPU_PORT}} + resp := &saipb.GetSwitchAttributeResponse{} + if err := p.mgr.PopulateAttributes(cpuPortReq, resp); err != nil { + return nil, err + } + + var action *fwdconfig.ActionBuilder + + switch req.GetGreenPacketAction() { + case saipb.PacketAction_PACKET_ACTION_TRAP: + action = fwdconfig.Action(fwdconfig.TransmitAction(fmt.Sprint(resp.GetAttr().GetCpuPort())).WithImmediate(true)) + default: + return nil, fmt.Errorf("unsupport policer action: %v", req.GetGreenPacketAction()) + } + + tReq := fwdconfig.TableEntryAddRequest(p.dataplane.ID(), policerTabler). + AppendEntry(fwdconfig.EntryDesc(fwdconfig.ExactEntry(fwdconfig.PacketFieldBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID).WithUint64(id))), action) + + if _, err := p.dataplane.TableEntryAdd(ctx, tReq.Build()); err != nil { + return nil, err + } + return &saipb.CreatePolicerResponse{ Oid: id, }, nil } -func (p *policer) RemovePolicer(context.Context, *saipb.RemovePolicerRequest) (*saipb.RemovePolicerResponse, error) { +// RemovePolicer removes the entry from the table. +func (p *policer) RemovePolicer(ctx context.Context, req *saipb.RemovePolicerRequest) (*saipb.RemovePolicerResponse, error) { + tReq := fwdconfig.TableEntryRemoveRequest(p.dataplane.ID(), policerTabler). + AppendEntry(fwdconfig.EntryDesc(fwdconfig.ExactEntry(fwdconfig.PacketFieldBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID).WithUint64(req.GetOid())))) + + if _, err := p.dataplane.TableEntryRemove(ctx, tReq.Build()); err != nil { + return nil, err + } + return &saipb.RemovePolicerResponse{}, nil } diff --git a/dataplane/saiserver/switch.go b/dataplane/saiserver/switch.go index fdd5cfdf..f256f0f7 100644 --- a/dataplane/saiserver/switch.go +++ b/dataplane/saiserver/switch.go @@ -109,6 +109,7 @@ const ( portToHostifTable = "cpu-output" tunTermTable = "tun-term" VlanTable = "vlan" + policerTabler = "policerTable" DefaultVlanId = 1 ) @@ -603,6 +604,26 @@ func (sw *saiSwitch) CreateSwitch(ctx context.Context, _ *saipb.CreateSwitchRequ return nil, err } + _, err = sw.dataplane.TableCreate(ctx, &fwdpb.TableCreateRequest{ + ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()}, + Desc: &fwdpb.TableDesc{ + TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: policerTabler}}, + TableType: fwdpb.TableType_TABLE_TYPE_EXACT, + Table: &fwdpb.TableDesc_Exact{ + Exact: &fwdpb.ExactTableDesc{ + FieldIds: []*fwdpb.PacketFieldId{{ + Field: &fwdpb.PacketField{ + FieldNum: fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID, + }, + }}, + }, + }, + }, + }) + if err != nil { + return nil, err + } + cpuPortID, err := sw.port.createCPUPort(ctx) if err != nil { return nil, err diff --git a/proto/forwarding/forwarding_common.pb.go b/proto/forwarding/forwarding_common.pb.go index 8e5f1cac..9e4cf4e7 100644 --- a/proto/forwarding/forwarding_common.pb.go +++ b/proto/forwarding/forwarding_common.pb.go @@ -280,6 +280,7 @@ const ( PacketFieldNum_PACKET_FIELD_NUM_OUTPUT_IFACE PacketFieldNum = 61 PacketFieldNum_PACKET_FIELD_NUM_TUNNEL_ID PacketFieldNum = 62 PacketFieldNum_PACKET_FIELD_NUM_HOST_PORT_ID PacketFieldNum = 63 + PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID PacketFieldNum = 65 PacketFieldNum_PACKET_FIELD_NUM_COUNT PacketFieldNum = 1000 ) @@ -330,6 +331,7 @@ var ( 61: "PACKET_FIELD_NUM_OUTPUT_IFACE", 62: "PACKET_FIELD_NUM_TUNNEL_ID", 63: "PACKET_FIELD_NUM_HOST_PORT_ID", + 65: "PACKET_FIELD_NUM_POLICER_ID", 1000: "PACKET_FIELD_NUM_COUNT", } PacketFieldNum_value = map[string]int32{ @@ -377,6 +379,7 @@ var ( "PACKET_FIELD_NUM_OUTPUT_IFACE": 61, "PACKET_FIELD_NUM_TUNNEL_ID": 62, "PACKET_FIELD_NUM_HOST_PORT_ID": 63, + "PACKET_FIELD_NUM_POLICER_ID": 65, "PACKET_FIELD_NUM_COUNT": 1000, } ) @@ -2717,7 +2720,7 @@ var file_proto_forwarding_forwarding_common_proto_rawDesc = []byte{ 0x0a, 0x13, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x49, 0x50, 0x10, 0x13, 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x10, 0xe8, 0x07, 0x2a, 0x8d, 0x0c, 0x0a, 0x0e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x46, + 0x54, 0x10, 0xe8, 0x07, 0x2a, 0xae, 0x0c, 0x0a, 0x0e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x41, 0x43, @@ -2812,98 +2815,100 @@ var file_proto_forwarding_forwarding_common_proto_rawDesc = []byte{ 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x5f, 0x54, 0x55, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x49, 0x44, 0x10, 0x3e, 0x12, 0x21, 0x0a, 0x1d, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x5f, 0x50, 0x4f, - 0x52, 0x54, 0x5f, 0x49, 0x44, 0x10, 0x3f, 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x41, 0x43, 0x4b, 0x45, - 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x5f, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x10, 0xe8, 0x07, 0x2a, 0xda, 0x0a, 0x0a, 0x09, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, - 0x0a, 0x15, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, - 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x55, - 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, - 0x53, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, - 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, - 0x53, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, - 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, - 0x10, 0x04, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, - 0x5f, 0x52, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, - 0x53, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, - 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, - 0x53, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, - 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x07, 0x12, 0x18, - 0x0a, 0x14, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, - 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x08, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, - 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x09, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, - 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x0a, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, - 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, - 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x0b, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, + 0x52, 0x54, 0x5f, 0x49, 0x44, 0x10, 0x3f, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x41, 0x43, 0x4b, 0x45, + 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x5f, 0x50, 0x4f, 0x4c, 0x49, + 0x43, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x10, 0x41, 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x41, 0x43, 0x4b, + 0x45, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x10, 0xe8, 0x07, 0x2a, 0xda, 0x0a, 0x0a, 0x09, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, + 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, + 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, + 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x4f, 0x43, 0x54, 0x45, + 0x54, 0x53, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, + 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, + 0x54, 0x53, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, + 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, + 0x53, 0x10, 0x04, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, + 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, + 0x54, 0x53, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, + 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, + 0x54, 0x53, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, + 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x07, 0x12, + 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, + 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x08, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, + 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x09, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, + 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x0a, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x4c, 0x49, 0x4d, 0x49, 0x54, - 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x0d, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, - 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x4c, 0x49, 0x4d, - 0x49, 0x54, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x0e, 0x12, 0x1b, 0x0a, 0x17, 0x43, - 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, - 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x0f, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, 0x43, 0x54, 0x45, - 0x54, 0x53, 0x10, 0x10, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, - 0x49, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, - 0x10, 0x11, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x12, 0x12, - 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, - 0x5f, 0x42, 0x41, 0x44, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x13, 0x12, 0x1c, - 0x0a, 0x18, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, - 0x42, 0x41, 0x44, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x14, 0x12, 0x24, 0x0a, 0x20, - 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x41, 0x44, - 0x4d, 0x49, 0x4e, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, - 0x10, 0x15, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, - 0x5f, 0x52, 0x58, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, - 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x16, 0x12, 0x24, 0x0a, 0x20, 0x43, 0x4f, 0x55, 0x4e, 0x54, - 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x44, - 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x17, 0x12, 0x23, 0x0a, - 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x41, - 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, - 0x10, 0x18, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, - 0x5f, 0x4d, 0x49, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, - 0x19, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, - 0x4d, 0x49, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x1a, 0x12, - 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x49, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, - 0x54, 0x53, 0x10, 0x1b, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, - 0x49, 0x44, 0x5f, 0x4d, 0x49, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x1c, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x43, 0x41, 0x50, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x1d, 0x12, 0x21, 0x0a, 0x1d, - 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x43, 0x41, 0x50, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x1e, 0x12, - 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x44, 0x45, - 0x43, 0x41, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, - 0x53, 0x10, 0x1f, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, - 0x44, 0x5f, 0x44, 0x45, 0x43, 0x41, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, - 0x54, 0x45, 0x54, 0x53, 0x10, 0x20, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, - 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, - 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x21, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, - 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x43, 0x4f, - 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x22, 0x12, - 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, - 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x23, - 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, - 0x58, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x24, + 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x0b, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x4c, 0x49, 0x4d, 0x49, + 0x54, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x0d, 0x12, 0x1f, 0x0a, 0x1b, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x4c, 0x49, + 0x4d, 0x49, 0x54, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x0e, 0x12, 0x1b, 0x0a, 0x17, + 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, + 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x0f, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, 0x43, 0x54, + 0x45, 0x54, 0x53, 0x10, 0x10, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, + 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, + 0x53, 0x10, 0x11, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, + 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x12, + 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, + 0x58, 0x5f, 0x42, 0x41, 0x44, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x13, 0x12, + 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, + 0x5f, 0x42, 0x41, 0x44, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x14, 0x12, 0x24, 0x0a, + 0x20, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x41, + 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, + 0x53, 0x10, 0x15, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, + 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, + 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x16, 0x12, 0x24, 0x0a, 0x20, 0x43, 0x4f, 0x55, 0x4e, + 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, + 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x17, 0x12, 0x23, + 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, + 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, + 0x53, 0x10, 0x18, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, + 0x44, 0x5f, 0x4d, 0x49, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, + 0x10, 0x19, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, + 0x5f, 0x4d, 0x49, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x1a, + 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x4d, + 0x49, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, + 0x45, 0x54, 0x53, 0x10, 0x1b, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, + 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x49, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x1c, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x43, 0x41, 0x50, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x1d, 0x12, 0x21, 0x0a, + 0x1d, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x43, 0x41, + 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x1e, + 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x44, + 0x45, 0x43, 0x41, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, + 0x54, 0x53, 0x10, 0x1f, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, + 0x49, 0x44, 0x5f, 0x44, 0x45, 0x43, 0x41, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, + 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x20, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x55, 0x4e, 0x54, + 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, + 0x45, 0x52, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, 0x21, 0x12, 0x23, 0x0a, 0x1f, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x22, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x52, - 0x58, 0x5f, 0x55, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, - 0x25, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, - 0x52, 0x58, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x55, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x43, - 0x4b, 0x45, 0x54, 0x53, 0x10, 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, - 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x55, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x50, 0x41, - 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x27, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, - 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x55, 0x43, 0x41, - 0x53, 0x54, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x28, 0x12, 0x13, 0x0a, 0x0e, - 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x41, 0x58, 0x10, 0xff, - 0x01, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6c, 0x65, 0x6d, 0x6d, 0x69, - 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, - 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x58, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, + 0x23, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, + 0x52, 0x58, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x5f, 0x4f, 0x43, 0x54, 0x45, 0x54, 0x53, 0x10, + 0x24, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, + 0x52, 0x58, 0x5f, 0x55, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, + 0x10, 0x25, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, + 0x5f, 0x52, 0x58, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x55, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x50, 0x41, + 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x55, 0x4e, 0x54, + 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x55, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x50, + 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x27, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4e, + 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x55, 0x43, + 0x41, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x53, 0x10, 0x28, 0x12, 0x13, 0x0a, + 0x0e, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x41, 0x58, 0x10, + 0xff, 0x01, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6c, 0x65, 0x6d, 0x6d, + 0x69, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/forwarding/forwarding_common.proto b/proto/forwarding/forwarding_common.proto index 67082d50..36385212 100644 --- a/proto/forwarding/forwarding_common.proto +++ b/proto/forwarding/forwarding_common.proto @@ -176,6 +176,7 @@ enum PacketFieldNum { PACKET_FIELD_NUM_OUTPUT_IFACE = 61; // Output L3 interface (metadata). PACKET_FIELD_NUM_TUNNEL_ID = 62; // Tunnel ID (metadata). PACKET_FIELD_NUM_HOST_PORT_ID = 63; // Host port id (metadata). + PACKET_FIELD_NUM_POLICER_ID = 65; // Policer id (metadata). PACKET_FIELD_NUM_COUNT = 1000; } From 274abc14ebaa1fa9690e32b5a6e51185df7c3580 Mon Sep 17 00:00:00 2001 From: Daniel Grau Date: Thu, 18 Jul 2024 17:31:31 +0000 Subject: [PATCH 2/3] test --- dataplane/saiserver/BUILD | 1 + dataplane/saiserver/acl.go | 2 +- dataplane/saiserver/policer_test.go | 162 ++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 dataplane/saiserver/policer_test.go diff --git a/dataplane/saiserver/BUILD b/dataplane/saiserver/BUILD index cb2c917e..48333a5d 100644 --- a/dataplane/saiserver/BUILD +++ b/dataplane/saiserver/BUILD @@ -43,6 +43,7 @@ go_test( srcs = [ "acl_test.go", "hostif_test.go", + "policer_test.go", "ports_test.go", "routing_test.go", "switch_test.go", diff --git a/dataplane/saiserver/acl.go b/dataplane/saiserver/acl.go index ce4f382d..3696b09d 100644 --- a/dataplane/saiserver/acl.go +++ b/dataplane/saiserver/acl.go @@ -331,7 +331,7 @@ func (a *acl) CreateAclEntry(ctx context.Context, req *saipb.CreateAclEntryReque if req.ActionSetPolicer != nil { aReq.Actions = append(aReq.Actions, fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID). - WithUint64Value(req.GetActionSetUserTrapId().GetOid())).Build(), + WithUint64Value(req.GetActionSetPolicer().GetOid())).Build(), fwdconfig.Action(fwdconfig.LookupAction(policerTabler)).Build(), ) } diff --git a/dataplane/saiserver/policer_test.go b/dataplane/saiserver/policer_test.go new file mode 100644 index 00000000..9d298124 --- /dev/null +++ b/dataplane/saiserver/policer_test.go @@ -0,0 +1,162 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package saiserver + +import ( + "context" + "encoding/binary" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/gnmi/errdiff" + "google.golang.org/grpc" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/testing/protocmp" + + saipb "github.com/openconfig/lemming/dataplane/proto/sai" + "github.com/openconfig/lemming/dataplane/saiserver/attrmgr" + fwdpb "github.com/openconfig/lemming/proto/forwarding" +) + +func TestCreatePolicer(t *testing.T) { + tests := []struct { + desc string + req *saipb.CreatePolicerRequest + wantErr string + want *fwdpb.TableEntryAddRequest + }{{ + desc: "trap action", + req: &saipb.CreatePolicerRequest{ + GreenPacketAction: saipb.PacketAction_PACKET_ACTION_TRAP.Enum(), + }, + want: &fwdpb.TableEntryAddRequest{ + ContextId: &fwdpb.ContextId{Id: "foo"}, + TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: policerTabler}}, + Entries: []*fwdpb.TableEntryAddRequest_Entry{{ + EntryDesc: &fwdpb.EntryDesc{ + Entry: &fwdpb.EntryDesc_Exact{ + Exact: &fwdpb.ExactEntryDesc{ + Fields: []*fwdpb.PacketFieldBytes{{ + FieldId: &fwdpb.PacketFieldId{ + Field: &fwdpb.PacketField{FieldNum: fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID}, + }, + Bytes: binary.BigEndian.AppendUint64(nil, 2), + }}, + }, + }, + }, + Actions: []*fwdpb.ActionDesc{{ + ActionType: fwdpb.ActionType_ACTION_TYPE_TRANSMIT, + Action: &fwdpb.ActionDesc_Transmit{ + Transmit: &fwdpb.TransmitActionDesc{ + PortId: &fwdpb.PortId{ObjectId: &fwdpb.ObjectId{Id: "10"}}, + Immediate: true, + }, + }, + }}, + }}, + }, + }} + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + dplane := &fakeSwitchDataplane{} + c, p, stopFn := newTestPolicer(t, dplane) + p.mgr.StoreAttributes(p.mgr.NextID(), &saipb.SwitchAttribute{ + CpuPort: proto.Uint64(10), + }) + defer stopFn() + _, gotErr := c.CreatePolicer(context.TODO(), tt.req) + if diff := errdiff.Check(gotErr, tt.wantErr); diff != "" { + t.Fatalf("CreatePolicer() unexpected err: %s", diff) + } + if gotErr != nil { + return + } + if d := cmp.Diff(dplane.gotEntryAddReqs[0], tt.want, protocmp.Transform()); d != "" { + t.Errorf("CreatePolicer() failed: diff(-got,+want)\n:%s", d) + } + }) + } +} + +func TestRemovePolicer(t *testing.T) { + tests := []struct { + desc string + req *saipb.RemovePolicerRequest + wantErr string + want *fwdpb.TableEntryRemoveRequest + }{{ + desc: "not found", + req: &saipb.RemovePolicerRequest{ + Oid: 3, + }, + wantErr: "not found", + }, { + desc: "success", + req: &saipb.RemovePolicerRequest{ + Oid: 2, + }, + want: &fwdpb.TableEntryRemoveRequest{ + ContextId: &fwdpb.ContextId{Id: "foo"}, + TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: policerTabler}}, + Entries: []*fwdpb.EntryDesc{{ + Entry: &fwdpb.EntryDesc_Exact{ + Exact: &fwdpb.ExactEntryDesc{ + Fields: []*fwdpb.PacketFieldBytes{{ + FieldId: &fwdpb.PacketFieldId{ + Field: &fwdpb.PacketField{FieldNum: fwdpb.PacketFieldNum_PACKET_FIELD_NUM_POLICER_ID}, + }, + Bytes: binary.BigEndian.AppendUint64(nil, 2), + }}, + }, + }, + }}, + }, + }} + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + dplane := &fakeSwitchDataplane{} + c, a, stopFn := newTestPolicer(t, dplane) + a.mgr.StoreAttributes(a.mgr.NextID(), &saipb.SwitchAttribute{ + CpuPort: proto.Uint64(10), + }) + defer stopFn() + _, err := c.CreatePolicer(context.TODO(), &saipb.CreatePolicerRequest{ + GreenPacketAction: saipb.PacketAction_PACKET_ACTION_TRAP.Enum(), + }) + if err != nil { + t.Fatal(err) + } + _, gotErr := c.RemovePolicer(context.Background(), tt.req) + if diff := errdiff.Check(gotErr, tt.wantErr); diff != "" { + t.Fatalf("RemovePolicer() unexpected err: %s", diff) + } + if gotErr != nil { + return + } + if d := cmp.Diff(dplane.gotEntryRemoveReqs[0], tt.want, protocmp.Transform()); d != "" { + t.Errorf("RemovePolicer() failed: diff(-got,+want)\n:%s", d) + } + }) + } +} + +func newTestPolicer(t testing.TB, api switchDataplaneAPI) (saipb.PolicerClient, *policer, func()) { + var p *policer + conn, _, stopFn := newTestServer(t, func(mgr *attrmgr.AttrMgr, srv *grpc.Server) { + p = newPolicer(mgr, api, srv) + }) + return saipb.NewPolicerClient(conn), p, stopFn +} From 1463b694a35edeec0a0a509c7ee9357c85399c2b Mon Sep 17 00:00:00 2001 From: Daniel Grau Date: Thu, 18 Jul 2024 20:12:05 +0000 Subject: [PATCH 3/3] feedback --- dataplane/saiserver/policer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataplane/saiserver/policer.go b/dataplane/saiserver/policer.go index 6a1245fc..407bdb3a 100644 --- a/dataplane/saiserver/policer.go +++ b/dataplane/saiserver/policer.go @@ -42,7 +42,7 @@ func newPolicer(mgr *attrmgr.AttrMgr, dataplane switchDataplaneAPI, s *grpc.Serv return p } -// CreatePolicer creates a new policer, QOS is not actually supported.ß the GREEN action is always taken.ß +// CreatePolicer creates a new policer, QOS is not actually supported.ß the GREEN action is always taken. func (p *policer) CreatePolicer(ctx context.Context, req *saipb.CreatePolicerRequest) (*saipb.CreatePolicerResponse, error) { id := p.mgr.NextID()