From 64474e93876e428f293efaedfbbd2bd1d8f43153 Mon Sep 17 00:00:00 2001 From: Emanuele Gallone <26747011+EmanueleGallone@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:28:41 +0200 Subject: [PATCH] [SDFAB-1110] Add support for multiple application filters (#60) * First commit * Refactor * Generate new FARs and Application QERs for each app filter flag * Refactor * Refactor * Refactor * Refactor * Remove debug code * Fix incorrect handling of IDs * Fix default protocol * Refactor comment * Sync changes when modifying sessions * Use app filters also when modifying sessions to generate the correct IDs * Fix missing app filters when modifying sessions * Refactor * Add precedence in app filter format * Remove debug code * Add test cases for app filter parser * Fix format in app filter flag * Add check on baseID * Add validation step * Remove debug code --- api/pfcpsim.pb.go | 148 ++++++++++++++------------ api/pfcpsim.proto | 3 +- internal/pfcpctl/commands/helpers.go | 4 + internal/pfcpctl/commands/sessions.go | 34 ++++-- internal/pfcpsim/helpers.go | 54 +++++++--- internal/pfcpsim/helpers_test.go | 36 +++++-- internal/pfcpsim/server.go | 142 ++++++++++++++---------- 7 files changed, 262 insertions(+), 159 deletions(-) diff --git a/api/pfcpsim.pb.go b/api/pfcpsim.pb.go index cbaf33f..cb3136c 100644 --- a/api/pfcpsim.pb.go +++ b/api/pfcpsim.pb.go @@ -40,11 +40,11 @@ type CreateSessionRequest struct { // count represents the number of session Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` // baseID is used to create incremental IDs for PDRs, FARs, QERs - BaseID int32 `protobuf:"varint,2,opt,name=baseID,proto3" json:"baseID,omitempty"` - NodeBAddress string `protobuf:"bytes,3,opt,name=nodeBAddress,proto3" json:"nodeBAddress,omitempty"` - UeAddressPool string `protobuf:"bytes,4,opt,name=ueAddressPool,proto3" json:"ueAddressPool,omitempty"` - AppFilter string `protobuf:"bytes,5,opt,name=appFilter,proto3" json:"appFilter,omitempty"` - Qfi int32 `protobuf:"varint,6,opt,name=qfi,proto3" json:"qfi,omitempty"` // Should be uint8 + BaseID int32 `protobuf:"varint,2,opt,name=baseID,proto3" json:"baseID,omitempty"` + NodeBAddress string `protobuf:"bytes,3,opt,name=nodeBAddress,proto3" json:"nodeBAddress,omitempty"` + UeAddressPool string `protobuf:"bytes,4,opt,name=ueAddressPool,proto3" json:"ueAddressPool,omitempty"` + AppFilters []string `protobuf:"bytes,5,rep,name=appFilters,proto3" json:"appFilters,omitempty"` + Qfi int32 `protobuf:"varint,6,opt,name=qfi,proto3" json:"qfi,omitempty"` // Should be uint8 } func (x *CreateSessionRequest) Reset() { @@ -107,11 +107,11 @@ func (x *CreateSessionRequest) GetUeAddressPool() string { return "" } -func (x *CreateSessionRequest) GetAppFilter() string { +func (x *CreateSessionRequest) GetAppFilters() []string { if x != nil { - return x.AppFilter + return x.AppFilters } - return "" + return nil } func (x *CreateSessionRequest) GetQfi() int32 { @@ -129,11 +129,12 @@ type ModifySessionRequest struct { // count represents the number of session Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` // baseID is used to create incremental IDs for PDRs, FARs, QERs - BaseID int32 `protobuf:"varint,2,opt,name=baseID,proto3" json:"baseID,omitempty"` - NodeBAddress string `protobuf:"bytes,3,opt,name=nodeBAddress,proto3" json:"nodeBAddress,omitempty"` - UeAddressPool string `protobuf:"bytes,4,opt,name=ueAddressPool,proto3" json:"ueAddressPool,omitempty"` - BufferFlag bool `protobuf:"varint,5,opt,name=bufferFlag,proto3" json:"bufferFlag,omitempty"` - NotifyCPFlag bool `protobuf:"varint,6,opt,name=notifyCPFlag,proto3" json:"notifyCPFlag,omitempty"` + BaseID int32 `protobuf:"varint,2,opt,name=baseID,proto3" json:"baseID,omitempty"` + NodeBAddress string `protobuf:"bytes,3,opt,name=nodeBAddress,proto3" json:"nodeBAddress,omitempty"` + UeAddressPool string `protobuf:"bytes,4,opt,name=ueAddressPool,proto3" json:"ueAddressPool,omitempty"` + BufferFlag bool `protobuf:"varint,5,opt,name=bufferFlag,proto3" json:"bufferFlag,omitempty"` + NotifyCPFlag bool `protobuf:"varint,6,opt,name=notifyCPFlag,proto3" json:"notifyCPFlag,omitempty"` + AppFilters []string `protobuf:"bytes,7,rep,name=appFilters,proto3" json:"appFilters,omitempty"` } func (x *ModifySessionRequest) Reset() { @@ -210,6 +211,13 @@ func (x *ModifySessionRequest) GetNotifyCPFlag() bool { return false } +func (x *ModifySessionRequest) GetAppFilters() []string { + if x != nil { + return x.AppFilters + } + return nil +} + type ConfigureRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -420,7 +428,7 @@ var File_pfcpsim_proto protoreflect.FileDescriptor var file_pfcpsim_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x70, 0x66, 0x63, 0x70, 0x73, 0x69, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x03, 0x61, 0x70, 0x69, 0x22, 0xbe, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x03, 0x61, 0x70, 0x69, 0x22, 0xc0, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, @@ -429,62 +437,64 @@ var file_pfcpsim_proto_rawDesc = []byte{ 0x09, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x42, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x70, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x66, 0x69, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x03, 0x71, 0x66, 0x69, 0x22, 0xd2, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, - 0x6e, 0x6f, 0x64, 0x65, 0x42, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x42, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x6f, 0x6f, - 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, - 0x46, 0x6c, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x62, 0x75, 0x66, 0x66, - 0x65, 0x72, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x43, 0x50, 0x46, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6e, 0x6f, - 0x74, 0x69, 0x66, 0x79, 0x43, 0x50, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x64, 0x0a, 0x10, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, - 0x0a, 0x0c, 0x75, 0x70, 0x66, 0x4e, 0x33, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x75, 0x70, 0x66, 0x4e, 0x33, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x22, 0x44, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, - 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x22, 0x0e, 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x45, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, - 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xda, 0x02, - 0x0a, 0x07, 0x50, 0x46, 0x43, 0x50, 0x53, 0x69, 0x6d, 0x12, 0x33, 0x0a, 0x09, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2f, - 0x0a, 0x09, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x32, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x12, - 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x66, 0x69, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x71, 0x66, 0x69, 0x22, 0xf2, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x64, 0x69, + 0x66, 0x79, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x12, 0x22, + 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x42, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x42, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, + 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x65, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x46, 0x6c, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x43, 0x50, 0x46, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x43, 0x50, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x1e, 0x0a, 0x0a, + 0x61, 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x61, 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x64, 0x0a, 0x10, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x22, 0x0a, 0x0c, 0x75, 0x70, 0x66, 0x4e, 0x33, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x75, 0x70, 0x66, 0x4e, 0x33, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, + 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x22, 0x44, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x44, 0x22, 0x0e, 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x45, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, + 0xda, 0x02, 0x0a, 0x07, 0x50, 0x46, 0x43, 0x50, 0x53, 0x69, 0x6d, 0x12, 0x33, 0x0a, 0x09, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x3b, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, - 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, - 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x2f, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x32, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, + 0x65, 0x12, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x3b, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, + 0x2e, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/pfcpsim.proto b/api/pfcpsim.proto index 4a623cd..1b092b8 100644 --- a/api/pfcpsim.proto +++ b/api/pfcpsim.proto @@ -13,7 +13,7 @@ message CreateSessionRequest { int32 baseID = 2; string nodeBAddress = 3; string ueAddressPool = 4; - string appFilter = 5; + repeated string appFilters = 5; int32 qfi = 6; // Should be uint8 } @@ -26,6 +26,7 @@ message ModifySessionRequest { string ueAddressPool = 4; bool bufferFlag = 5; bool notifyCPFlag = 6; + repeated string appFilters = 7; } message ConfigureRequest { diff --git a/internal/pfcpctl/commands/helpers.go b/internal/pfcpctl/commands/helpers.go index 7431bd1..c4f9549 100644 --- a/internal/pfcpctl/commands/helpers.go +++ b/internal/pfcpctl/commands/helpers.go @@ -24,6 +24,10 @@ func connect() pb.PFCPSimClient { return pb.NewPFCPSimClient(conn) } +func validateArgs(args *commonArgs) { + +} + func disconnect() { if conn != nil { conn.Close() diff --git a/internal/pfcpctl/commands/sessions.go b/internal/pfcpctl/commands/sessions.go index c505097..c60b6f6 100644 --- a/internal/pfcpctl/commands/sessions.go +++ b/internal/pfcpctl/commands/sessions.go @@ -12,12 +12,22 @@ import ( ) type commonArgs struct { - Count int `short:"c" long:"count" default:"1" description:"The number of sessions to create"` - BaseID int `short:"i" long:"baseID" default:"1" description:"The base ID to use"` - UePool string `short:"u" long:"ue-pool" default:"17.0.0.0/24" description:"The UE pool address"` - GnBAddress string `short:"g" long:"gnb-addr" description:"The UE pool address"` - AppFilterString string `short:"a" long:"app-filter" description:"Specify an application filter. Format: '{ip | udp | tcp}:{IPv4 Prefix | any}:{- | any}:{allow | deny}' . e.g. 'udp:10.0.0.0/8:80-88:allow'"` - QFI uint8 `short:"q" long:"qfi" description:"The QFI value for QERs. Max value 64."` + Count int `short:"c" long:"count" default:"1" description:"The number of sessions to create"` + BaseID int `short:"i" long:"baseID" default:"1" description:"The base ID to use"` + UePool string `short:"u" long:"ue-pool" default:"17.0.0.0/24" description:"The UE pool address"` + GnBAddress string `short:"g" long:"gnb-addr" description:"The UE pool address"` + AppFilterString []string `short:"a" long:"app-filter" default:"ip:any:any:allow:100" description:"Specify an application filter. Format: '{ip | udp | tcp}:{IPv4 Prefix | any}:{- | any}:{allow | deny}:{rule-precedence}' . e.g. 'udp:10.0.0.0/8:80-88:allow:100'"` + QFI uint8 `short:"q" long:"qfi" description:"The QFI value for QERs. Max value 64."` +} + +func (a *commonArgs) validate() { + if a.BaseID <= 0 { + log.Fatalf("BaseID cannot be 0 or a negative number.") + } + + if a.Count <= 0 { + log.Fatalf("Count cannot be 0 or a negative number.") + } } type sessionCreate struct { @@ -36,8 +46,7 @@ type sessionModify struct { type sessionDelete struct { Args struct { - Count int `short:"c" long:"count" default:"1" description:"The number of sessions to create"` - BaseID int `short:"i" long:"baseID" default:"1" description:"The base ID to use"` + commonArgs } } @@ -59,12 +68,14 @@ func (s *sessionCreate) Execute(args []string) error { client := connect() defer disconnect() + s.Args.validate() + res, err := client.CreateSession(context.Background(), &pb.CreateSessionRequest{ Count: int32(s.Args.Count), BaseID: int32(s.Args.BaseID), NodeBAddress: s.Args.GnBAddress, UeAddressPool: s.Args.UePool, - AppFilter: s.Args.AppFilterString, + AppFilters: s.Args.AppFilterString, Qfi: int32(s.Args.QFI), }) @@ -81,6 +92,8 @@ func (s *sessionModify) Execute(args []string) error { client := connect() defer disconnect() + s.Args.validate() + res, err := client.ModifySession(context.Background(), &pb.ModifySessionRequest{ Count: int32(s.Args.Count), BaseID: int32(s.Args.BaseID), @@ -88,6 +101,7 @@ func (s *sessionModify) Execute(args []string) error { UeAddressPool: s.Args.UePool, BufferFlag: s.Args.BufferFlag, NotifyCPFlag: s.Args.NotifyCPFlag, + AppFilters: s.Args.AppFilterString, }) if err != nil { @@ -103,6 +117,8 @@ func (s *sessionDelete) Execute(args []string) error { client := connect() defer disconnect() + s.Args.validate() + res, err := client.DeleteSession(context.Background(), &pb.DeleteSessionRequest{ Count: int32(s.Args.Count), BaseID: int32(s.Args.BaseID), diff --git a/internal/pfcpsim/helpers.go b/internal/pfcpsim/helpers.go index 4737076..63e5b85 100644 --- a/internal/pfcpsim/helpers.go +++ b/internal/pfcpsim/helpers.go @@ -10,7 +10,10 @@ import ( "strings" "github.com/omec-project/pfcpsim/pkg/pfcpsim" + log "github.com/sirupsen/logrus" "github.com/wmnsk/go-pfcp/ie" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) const sdfFilterFormatWPort = "permit out %v from %v to assigned %v-%v" @@ -48,6 +51,16 @@ func isRemotePeerConnected() bool { return remotePeerConnected } +// isNumOfAppFiltersCorrect returns error if the number of the passed filter exceed the max number of supported application filters. +func isNumOfAppFiltersCorrect(filters []string) error { + if len(filters) > SessionStep/2 { + log.Errorf("Too many application filters: %v", filters) + return status.Error(codes.Aborted, "Too many application filters") + } + + return nil +} + // getLocalAddress returns the first IP address of the interfaceName, if specified, // otherwise returns the IP address of the first non-loopback interface // Returns error if fail occurs at any stage. @@ -80,15 +93,20 @@ func getLocalAddress(interfaceName string) (net.IP, error) { } // parseAppFilter parses an application filter. Returns a tuple formed by a formatted SDF filter -// and a uint8 representing the Application QER gate status. Returns error if fail occurs while validating the filter string. -func parseAppFilter(filter string) (string, uint8, error) { +// and a uint8 representing the Application QER gate status and a precedence. Returns error if fail occurs while validating the filter string. +func parseAppFilter(filter string) (string, uint8, uint32, error) { + if filter == "" { + // parsing a wildcard app filter + return "", ie.GateStatusOpen, 100, nil + } + result := strings.Split(filter, ":") - if len(result) != 4 { - return "", 0, pfcpsim.NewInvalidFormatError("Parser was not able to generate the correct number of arguments." + + if len(result) != 5 { + return "", 0, 0, pfcpsim.NewInvalidFormatError("Parser was not able to generate the correct number of arguments." + " Please make sure to use the right format") } - proto, ipNetAddr, portRange, action := result[0], result[1], result[2], result[3] + proto, ipNetAddr, portRange, action, precedence := result[0], result[1], result[2], result[3], result[4] var gateStatus uint8 switch action { @@ -97,40 +115,48 @@ func parseAppFilter(filter string) (string, uint8, error) { case "deny": gateStatus = ie.GateStatusClosed default: - return "", 0, pfcpsim.NewInvalidFormatError("Action. Please make sure to use 'allow' or 'deny'") + return "", 0, 0, pfcpsim.NewInvalidFormatError("Action. Please make sure to use 'allow' or 'deny'") } if !(proto == "ip" || proto == "udp" || proto == "tcp") { - return "", 0, pfcpsim.NewInvalidFormatError("Unsupported or unknown protocol.") + return "", 0, 0, pfcpsim.NewInvalidFormatError("Unsupported or unknown protocol.") + } + + precedenceConverted, err := strconv.Atoi(precedence) + if err != nil { + return "", 0, 0, pfcpsim.NewInvalidFormatError("Precedence. Please make sure it is a number", err) } + precedenceUint := uint32(precedenceConverted) + if ipNetAddr != "any" { _, _, err := net.ParseCIDR(ipNetAddr) if err != nil { - return "", 0, pfcpsim.NewInvalidFormatError("IP and subnet mask.", err) + return "", 0, 0, pfcpsim.NewInvalidFormatError("IP and subnet mask.", err) } } + if portRange != "any" { portList := strings.Split(portRange, "-") if !(len(portList) == 2) { - return "", 0, pfcpsim.NewInvalidFormatError("Port range. Please make sure to use dash '-' to separate the two ports") + return "", 0, 0, pfcpsim.NewInvalidFormatError("Port range. Please make sure to use dash '-' to separate the two ports") } lowerPort, err := strconv.Atoi(portList[0]) if err != nil { - return "", 0, pfcpsim.NewInvalidFormatError("Port range.", err) + return "", 0, 0, pfcpsim.NewInvalidFormatError("Port range.", err) } upperPort, err := strconv.Atoi(portList[1]) if err != nil { - return "", 0, pfcpsim.NewInvalidFormatError("Port range.", err) + return "", 0, 0, pfcpsim.NewInvalidFormatError("Port range.", err) } if lowerPort > upperPort { - return "", 0, pfcpsim.NewInvalidFormatError("Port range. Lower port is greater than upper port") + return "", 0, 0, pfcpsim.NewInvalidFormatError("Port range. Lower port is greater than upper port") } - return fmt.Sprintf(sdfFilterFormatWPort, proto, ipNetAddr, lowerPort, upperPort), gateStatus, nil + return fmt.Sprintf(sdfFilterFormatWPort, proto, ipNetAddr, lowerPort, upperPort), gateStatus, precedenceUint, nil } else { - return fmt.Sprintf(sdfFilterFormatWOPort, proto, ipNetAddr), gateStatus, nil + return fmt.Sprintf(sdfFilterFormatWOPort, proto, ipNetAddr), gateStatus, precedenceUint, nil } } diff --git a/internal/pfcpsim/helpers_test.go b/internal/pfcpsim/helpers_test.go index 06a8197..fa82fa8 100644 --- a/internal/pfcpsim/helpers_test.go +++ b/internal/pfcpsim/helpers_test.go @@ -18,6 +18,7 @@ func Test_parseAppFilter(t *testing.T) { type want struct { SDFFilter string gateStatus uint8 + precedence uint32 } tests := []struct { @@ -28,56 +29,62 @@ func Test_parseAppFilter(t *testing.T) { }{ {name: "Correct app filter", args: &args{ - filterString: "udp:10.0.0.0/8:80-80:allow", + filterString: "udp:10.0.0.0/8:80-80:allow:100", }, want: &want{ SDFFilter: "permit out udp from 10.0.0.0/8 to assigned 80-80", gateStatus: ie.GateStatusOpen, + precedence: 100, }, }, {name: "Correct app filter with deny", args: &args{ - filterString: "udp:10.0.0.0/8:80-80:deny", + filterString: "udp:10.0.0.0/8:80-80:deny:101", }, want: &want{ SDFFilter: "permit out udp from 10.0.0.0/8 to assigned 80-80", gateStatus: ie.GateStatusClosed, + precedence: 101, }, }, {name: "Correct app filter with deny-all policy", args: &args{ - filterString: "ip:0.0.0.0/0:any:deny", + filterString: "ip:0.0.0.0/0:any:deny:102", }, want: &want{ SDFFilter: "permit out ip from 0.0.0.0/0 to assigned", gateStatus: ie.GateStatusClosed, + precedence: 102, }, }, {name: "Correct app filter with deny-all policy 2", args: &args{ - filterString: "ip:any:any:deny", + filterString: "ip:any:any:deny:100", }, want: &want{ SDFFilter: "permit out ip from any to assigned", gateStatus: ie.GateStatusClosed, + precedence: 100, }, }, {name: "Correct app filter with allow-all policy", args: &args{ - filterString: "ip:any:any:allow", + filterString: "ip:any:any:allow:100", }, want: &want{ SDFFilter: "permit out ip from any to assigned", gateStatus: ie.GateStatusOpen, + precedence: 100, }, }, {name: "Correct app filter with allow-all policy 2", args: &args{ - filterString: "ip:0.0.0.0/0:any:allow", + filterString: "ip:0.0.0.0/0:any:allow:103", }, want: &want{ SDFFilter: "permit out ip from 0.0.0.0/0 to assigned", gateStatus: ie.GateStatusOpen, + precedence: 103, }, }, {name: "incorrect app filter bad protocol", @@ -94,12 +101,26 @@ func Test_parseAppFilter(t *testing.T) { want: &want{}, wantErr: true, }, + {name: "incorrect app filter missing precedence", + args: &args{ + filterString: "ip:10/8:80-80:allow", + }, + want: &want{}, + wantErr: true, + }, + {name: "incorrect app filter bad precedence", + args: &args{ + filterString: "ip:10/8:80-80:allow:test", + }, + want: &want{}, + wantErr: true, + }, } for _, tt := range tests { t.Run( tt.name, func(t *testing.T) { - filter, gateStatus, err := parseAppFilter(tt.args.filterString) + filter, gateStatus, precedence, err := parseAppFilter(tt.args.filterString) if tt.wantErr { require.Error(t, err) return @@ -107,6 +128,7 @@ func Test_parseAppFilter(t *testing.T) { require.Equal(t, tt.want.SDFFilter, filter) require.Equal(t, tt.want.gateStatus, gateStatus) + require.Equal(t, tt.want.precedence, precedence) }, ) } diff --git a/internal/pfcpsim/server.go b/internal/pfcpsim/server.go index ded8067..010cc5a 100644 --- a/internal/pfcpsim/server.go +++ b/internal/pfcpsim/server.go @@ -22,6 +22,12 @@ import ( // Its state is handled in internal/pfcpsim/state.go type pfcpSimService struct{} +// SessionStep identifies the step in loops, used while creating/modifying/deleting sessions and rules IDs. +// It should be high enough to avoid IDs overlap when creating sessions. 5 Applications should be enough. +// In theory with ROC limitations, we should expect max 8 applications (5 explicit applications + 3 filters +// to deny traffic to the RFC1918 IPs, in case we have a ALLOW-PUBLIC) +const SessionStep = 10 + func NewPFCPSimService(iface string) *pfcpSimService { interfaceName = iface return &pfcpSimService{} @@ -124,43 +130,58 @@ func (P pfcpSimService) CreateSession(ctx context.Context, request *pb.CreateSes return &pb.Response{}, status.Error(codes.Aborted, errMsg) } - var SDFFilter = "" - var qfi, gateStatus uint8 = 0, ieLib.GateStatusOpen - - if request.AppFilter != "" { - SDFFilter, gateStatus, err = parseAppFilter(request.AppFilter) - if err != nil { - return &pb.Response{}, status.Error(codes.Aborted, err.Error()) - } - - log.Infof("Successfully parsed application filter. SDF Filter: %v", SDFFilter) - } + var qfi uint8 = 0 if request.Qfi != 0 { qfi = uint8(request.Qfi) } - for i := baseID; i < (count*2 + baseID); i = i + 2 { + if err = isNumOfAppFiltersCorrect(request.AppFilters); err != nil { + return &pb.Response{}, err + } + + for i := baseID; i < (count*SessionStep + baseID); i = i + SessionStep { // using variables to ease comprehension on how rules are linked together uplinkTEID := uint32(i) ueAddress := iplib.NextIP(lastUEAddr) lastUEAddr = ueAddress - uplinkFarID := uint32(i) - downlinkFarID := uint32(i + 1) + sessQerID := uint32(0) + + var pdrs, fars []*ieLib.IE + + qers := []*ieLib.IE{ + // session QER + session.NewQERBuilder(). + WithID(sessQerID). + WithMethod(session.Create). + WithUplinkMBR(60000). + WithDownlinkMBR(60000). + Build(), + } + + // create as many PDRs, FARs and App QERs as the number of app filters provided through pfcpctl + ID := uint16(i) + + for _, appFilter := range request.AppFilters { + SDFFilter, gateStatus, precedence, err := parseAppFilter(appFilter) + if err != nil { + return &pb.Response{}, status.Error(codes.Aborted, err.Error()) + } + + log.Infof("Successfully parsed application filter. SDF Filter: %v", SDFFilter) - uplinkPdrID := uint16(i) - downlinkPdrID := uint16(i + 1) + uplinkPdrID := ID + downlinkPdrID := ID + 1 - sessQerID := uint32(i + 3) + uplinkFarID := uint32(ID) + downlinkFarID := uint32(ID + 1) - uplinkAppQerID := uint32(i) - downlinkAppQerID := uint32(i + 1) + uplinkAppQerID := uint32(ID) + downlinkAppQerID := uint32(ID + 1) - pdrs := []*ieLib.IE{ - // UplinkPDR - session.NewPDRBuilder(). + uplinkPDR := session.NewPDRBuilder(). WithID(uplinkPdrID). WithMethod(session.Create). WithTEID(uplinkTEID). @@ -169,72 +190,65 @@ func (P pfcpSimService) CreateSession(ctx context.Context, request *pb.CreateSes AddQERID(uplinkAppQerID). WithN3Address(upfN3Address). WithSDFFilter(SDFFilter). - WithPrecedence(100). + WithPrecedence(precedence). MarkAsUplink(). - BuildPDR(), + BuildPDR() - // DownlinkPDR - session.NewPDRBuilder(). + downlinkPDR := session.NewPDRBuilder(). WithID(downlinkPdrID). WithMethod(session.Create). - WithPrecedence(100). + WithPrecedence(precedence). WithUEAddress(ueAddress.String()). WithSDFFilter(SDFFilter). AddQERID(sessQerID). AddQERID(downlinkAppQerID). WithFARID(downlinkFarID). MarkAsDownlink(). - BuildPDR(), - } + BuildPDR() + + pdrs = append(pdrs, uplinkPDR) + pdrs = append(pdrs, downlinkPDR) - fars := []*ieLib.IE{ - // UplinkFAR - session.NewFARBuilder(). + uplinkFAR := session.NewFARBuilder(). WithID(uplinkFarID). WithAction(session.ActionForward). WithDstInterface(ieLib.DstInterfaceCore). WithMethod(session.Create). - BuildFAR(), + BuildFAR() - // DownlinkFAR - session.NewFARBuilder(). + downlinkFAR := session.NewFARBuilder(). WithID(downlinkFarID). WithAction(session.ActionDrop). WithMethod(session.Create). WithDstInterface(ieLib.DstInterfaceAccess). WithZeroBasedOuterHeaderCreation(). - BuildFAR(), - } + BuildFAR() - qers := []*ieLib.IE{ - // TODO make rates configurable by pfcpctl - // session QER - session.NewQERBuilder(). - WithID(sessQerID). - WithMethod(session.Create). - WithUplinkMBR(60000). - WithDownlinkMBR(60000). - Build(), + fars = append(fars, uplinkFAR) + fars = append(fars, downlinkFAR) - // Uplink application QER - session.NewQERBuilder(). + uplinkAppQER := session.NewQERBuilder(). WithID(uplinkAppQerID). WithMethod(session.Create). WithQFI(qfi). WithUplinkMBR(50000). WithDownlinkMBR(30000). WithGateStatus(gateStatus). - Build(), + Build() - // Downlink application QER - session.NewQERBuilder(). + downlinkAppQER := session.NewQERBuilder(). WithID(downlinkAppQerID). WithMethod(session.Create). WithQFI(qfi). WithUplinkMBR(50000). WithDownlinkMBR(30000). WithGateStatus(gateStatus). - Build(), + Build() + + qers = append(qers, uplinkAppQER) + qers = append(qers, downlinkAppQER) + + ID += 2 } sess, err := sim.EstablishSession(pdrs, fars, qers) @@ -280,23 +294,33 @@ func (P pfcpSimService) ModifySession(ctx context.Context, request *pb.ModifySes actions |= session.ActionForward } - for i := baseID; i < (count*2 + baseID); i = i + 2 { + if err := isNumOfAppFiltersCorrect(request.AppFilters); err != nil { + return &pb.Response{}, err + } + + for i := baseID; i < (count*SessionStep + baseID); i = i + SessionStep { + var newFARs []*ieLib.IE + + ID := uint32(i + 1) teid := uint32(i + 1) if request.BufferFlag || request.NotifyCPFlag { teid = 0 // When buffering, TEID = 0. } - newFARs := []*ieLib.IE{ - // Downlink FAR - session.NewFARBuilder(). - WithID(uint32(i + 1)). // Same FARID that was generated in create sessions + for _, _ = range request.AppFilters { + downlinkFAR := session.NewFARBuilder(). + WithID(ID). // Same FARID that was generated in create sessions WithMethod(session.Update). WithAction(actions). WithDstInterface(ieLib.DstInterfaceAccess). WithTEID(teid). WithDownlinkIP(nodeBaddress). - BuildFAR(), + BuildFAR() + + newFARs = append(newFARs, downlinkFAR) + + ID += 2 } sess, ok := getSession(i) @@ -335,7 +359,7 @@ func (P pfcpSimService) DeleteSession(ctx context.Context, request *pb.DeleteSes return &pb.Response{}, status.Error(codes.Aborted, err.Error()) } - for i := baseID; i < (count*2 + baseID); i = i + 2 { + for i := baseID; i < (count*SessionStep + baseID); i = i + SessionStep { sess, ok := getSession(i) if !ok { errMsg := "Session was nil. Check baseID"