diff --git a/conf/parser.py b/conf/parser.py index 0987ffdde..cf0cb1fb8 100644 --- a/conf/parser.py +++ b/conf/parser.py @@ -49,6 +49,7 @@ def __init__(self, fname): self.enable_ntf = False self.notify_sockaddr = "/tmp/notifycp" self.endmarker_sockaddr = "/tmp/pfcpport" + self.enable_slice_metering = False def parse(self, ifaces): # Maximum number of flows to manage ip4 frags for re-assembly @@ -149,6 +150,13 @@ def parse(self, ifaces): print('Can\'t parse interface name(s)! Setting it to default values ({}, {})'.format( "access", "core")) + # Slice rate limits + try: + self.conf["slice_rate_limit_config"] + self.enable_slice_metering = True + except KeyError: + print("No slice rate limit! Disabling meter.") + # UnixPort Paths try: self.notify_sockaddr = self.conf["notify_sockaddr"] diff --git a/conf/up4.bess b/conf/up4.bess index 338150990..84cc8c535 100644 --- a/conf/up4.bess +++ b/conf/up4.bess @@ -199,10 +199,33 @@ if ntf: _in -> ntf _in = ntf -_in -> qerLookup::Qos(fields=[ {'attr_name':'src_iface', 'num_bytes':1}, \ - {'attr_name':'qer_id', 'num_bytes':4}, \ - {'attr_name':'fseid', 'num_bytes':8}], \ - values=[{'attr_name':'qfi', 'num_bytes':1}]) +_in -> qerLookup::Qos(fields=[{'attr_name':'src_iface', 'num_bytes':1}, \ + {'attr_name':'qer_id', 'num_bytes':4}, \ + {'attr_name':'fseid', 'num_bytes':8}], \ + values=[{'attr_name':'qfi', 'num_bytes':1}]) + +executeFAR::Split(size=1, attribute='action') +_in = executeFAR +if parser.enable_slice_metering: + # sliceMeter enforces a per slice, per direction meter rate limit + sliceMeter::Qos(fields=[{'attr_name':'action', 'num_bytes':1}, \ + {'attr_name':'tunnel_out_type', 'num_bytes':1}]) + # Reserved gates, reject rule adds with gate=1/2/3 + m_meter = 0 # Placeholder gate not connected. Will meter if lookup result returns this gate + m_green = 1 # For green traffic + m_yellow = 2 # For yellow traffic + m_red = 3 # For red traffic + # User defined gates + m_fail = 4 # For lookup failure traffic + m_unmeter = 5 # For unmetered traffic + # Admit green and yellow, drop red + sliceMeter:m_green -> executeFAR + sliceMeter:m_yellow -> executeFAR + sliceMeter:m_red -> sliceMeterRed::Sink() + sliceMeter:m_fail -> sliceMeterLookupFail::Sink() + sliceMeter:m_unmeter -> executeFAR + sliceMeter.set_default_gate(gate=m_fail) + _in = sliceMeter farLookup::ExactMatch(fields=[{'attr_name':'far_id', 'num_bytes':4}, \ {'attr_name':'fseid', 'num_bytes':8}], \ @@ -213,7 +236,7 @@ farLookup::ExactMatch(fields=[{'attr_name':'far_id', 'num_bytes':4}, \ {'attr_name':'tunnel_out_teid', 'num_bytes':4}, \ {'attr_name':'tunnel_out_udp_port', 'num_bytes':2}]):noGTPUEncap \ -> farMerge::Merge() \ - -> executeFAR::Split(size=1, attribute='action') + -> _in # Add logical pipeline when gtpudecap is needed pdrLookup:GTPUDecap \ @@ -338,7 +361,7 @@ accessFastBPF:GTPUGate \ _in = accessRxUDPCksum gate = 0 -# 2. Build the remaining first half of the UL pipeline before entering the shard pipeline +# 2. Build the remaining first half of the UL pipeline before entering the shared pipeline #ports[parser.access_ifname].rewrite \ _in:gate \ -> SetMetadata(attrs=[{'name':'src_iface', 'size':1, 'value_int':Access}]) \ diff --git a/conf/upf.json b/conf/upf.json index 239522fd0..25b1b05d3 100644 --- a/conf/upf.json +++ b/conf/upf.json @@ -89,6 +89,17 @@ "priority": 5 } ], + + "": "Optional slice-wide meter rate limits", + "slice_rate_limit_config": { + "": "uplink policer", + "n6_bps": 500000000, + "n6_burst_bytes": 3000, + "": "downlink policer", + "n3_bps": 500000000, + "n3_burst_bytes": 3000 + }, + "": "Control plane controller settings", "cpiface": { "enable_ue_ip_alloc": false, diff --git a/core/modules/qos.cc b/core/modules/qos.cc index 6427c490d..897610704 100644 --- a/core/modules/qos.cc +++ b/core/modules/qos.cc @@ -31,15 +31,12 @@ #include "qos.h" #include "utils/endian.h" -#include "utils/ether.h" #include "utils/format.h" #include #include #include -using bess::utils::Ethernet; - typedef enum { FIELD_TYPE = 0, VALUE_TYPE } Type; using bess::metadata::Attribute; #define metering_test 0 @@ -140,7 +137,7 @@ void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { default_gate = ACCESS_ONCE(default_gate_); int cnt = batch->cnt(); - struct value *val[cnt]; + value *val[cnt]; for (const auto &field : fields_) { int offset; @@ -190,7 +187,7 @@ void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { // meter if ogate is 0 if (ogate == METER_GATE) { uint64_t time = rte_rdtsc(); - uint32_t pkt_len = pkt->total_len() - sizeof(Ethernet); + uint32_t pkt_len = pkt->total_len() - val[j]->deduct_len; uint8_t color = rte_meter_trtcm_color_blind_check(&val[j]->m, &val[j]->p, time, pkt_len); @@ -377,7 +374,7 @@ CommandResponse Qos::CommandAdd(const bess::pb::QosCommandAddArg &arg) { MeteringKey key = {{0}}; MKey l; - struct value v; + value v; v.ogate = gate; CommandResponse err = ExtractKeyMask(arg, &key, &v.Data, &l); @@ -391,6 +388,12 @@ CommandResponse Qos::CommandAdd(const bess::pb::QosCommandAddArg &arg) { v.cbs = arg.cbs(); v.pbs = arg.pbs(); v.ebs = arg.ebs(); + if (arg.optional_deduct_len_case() == + bess::pb::QosCommandAddArg::OPTIONAL_DEDUCT_LEN_NOT_SET) { + v.deduct_len = 14; // Exclude Ethernet header by default + } else { + v.deduct_len = arg.deduct_len(); + } DLOG(INFO) << "Adding entry" << " cir: " << v.cir << " pir: " << v.pir << " cbs: " << v.cbs diff --git a/core/modules/qos.h b/core/modules/qos.h index 76a534773..db58e68e8 100644 --- a/core/modules/qos.h +++ b/core/modules/qos.h @@ -67,6 +67,7 @@ struct value { uint64_t cbs; uint64_t pbs; uint64_t ebs; + int64_t deduct_len; struct rte_meter_trtcm_profile p; struct rte_meter_trtcm m; MeteringKey Data; diff --git a/patches/bess/0015-Protobuf-changes-for-Qos.patch b/patches/bess/0015-Protobuf-changes-for-Qos.patch index 2280b2fc0..ff98b1bd6 100644 --- a/patches/bess/0015-Protobuf-changes-for-Qos.patch +++ b/patches/bess/0015-Protobuf-changes-for-Qos.patch @@ -11,7 +11,7 @@ diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index 25dfc81e..1f7058cd 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto -@@ -1291,3 +1291,38 @@ message MplsPopArg { +@@ -1291,3 +1291,41 @@ message MplsPopArg { message WorkerSplitArg { map worker_gates = 1; // ogate -> worker mask } @@ -28,6 +28,9 @@ index 25dfc81e..1f7058cd 100644 + uint64 cbs = 4; + uint64 pbs = 5; + uint64 ebs = 6; ++ oneof optional_deduct_len { ++ int64 deduct_len = 9; ++ } + repeated FieldData fields = 7; + repeated FieldData values = 8; +} @@ -50,6 +53,6 @@ index 25dfc81e..1f7058cd 100644 +message QosCommandSetDefaultGateArg { + uint64 gate = 1; +} --- +-- 2.17.1 diff --git a/pfcpiface/bess.go b/pfcpiface/bess.go index bb4270486..b930cc4f8 100644 --- a/pfcpiface/bess.go +++ b/pfcpiface/bess.go @@ -41,6 +41,13 @@ const ( qerGateUnmeter ) +const ( + // Internal gates for Slice meter. + sliceMeterGateMeter uint64 = iota + sliceMeterGateLookupFail = iota + 4 + sliceMeterGateUnmeter +) + var intEnc = func(u uint64) *pb.FieldData { return &pb.FieldData{Encoding: &pb.FieldData_ValueInt{ValueInt: u}} } @@ -400,6 +407,17 @@ func (b *bess) setUpfInfo(u *upf, conf *Conf) { go b.endMarkerSendLoop(b.endMarkerChan) } + + if conf.SliceMeterConfig.N6RateBps > 0 || conf.SliceMeterConfig.N3RateBps > 0 { + ctx, cancel := context.WithTimeout(context.Background(), Timeout) + defer cancel() + done := make(chan bool) + b.addSliceMeter(ctx, done, conf.SliceMeterConfig) + rc := b.GRPCJoin(1, Timeout, done) + if !rc { + log.Errorln("Unable to make GRPC calls") + } + } } func (b *bess) sim(u *upf, method string) { @@ -1010,6 +1028,112 @@ func (b *bess) delCounter(ctx context.Context, done chan<- bool, ctrID uint32, c }() } +func (b *bess) processSliceMeter(ctx context.Context, any *anypb.Any, method upfMsgType) { + if method != upfMsgTypeAdd && method != upfMsgTypeDel && method != upfMsgTypeClear { + log.Errorln("Invalid method name: ", method) + return + } + + methods := [...]string{"add", "add", "delete", "clear"} + + _, err := b.client.ModuleCommand( + ctx, &pb.CommandRequest{ + Name: "sliceMeter", + Cmd: methods[method], + Arg: any, + }, + ) + if err != nil { + log.Errorln("sliceMeter method failed!:", err) + } +} + +func (b *bess) addSliceMeter(ctx context.Context, done chan<- bool, meterConfig SliceMeterConfig) { + go func() { + var ( + any *anypb.Any + err error + cir, pir, cbs, ebs, pbs, gate uint64 + ) + + // Uplink N6 slice meter config + if meterConfig.N6RateBps != 0 { + gate = sliceMeterGateMeter + cir = 1 // Mark all traffic as yellow + pir = meterConfig.N6RateBps / 8 // bit/s to byte/s + } else { + gate = sliceMeterGateUnmeter + } + if meterConfig.N6BurstBytes != 0 { + cbs = 1 // Mark all traffic as yellow + pbs = meterConfig.N6BurstBytes + ebs = 0 // Unused + } else { + cbs = DefaultBurstSize + pbs = DefaultBurstSize + ebs = 0 // Unused + } + q := &pb.QosCommandAddArg{ + Gate: gate, + Cir: cir, /* committed info rate */ + Pir: pir, /* peak info rate */ + Cbs: cbs, /* committed burst size */ + Pbs: pbs, /* Peak burst size */ + Ebs: ebs, /* Excess burst size */ + OptionalDeductLen: &pb.QosCommandAddArg_DeductLen{0}, /* Include all headers */ + Fields: []*pb.FieldData{ + intEnc(uint64(farForwardU)), /* Action */ + intEnc(uint64(0)), /* tunnel_out_type */ + }, + } + any, err = anypb.New(q) + if err != nil { + log.Errorln("Error marshalling the rule", q, err) + return + } + b.processSliceMeter(ctx, any, upfMsgTypeAdd) + + // Downlink N3 slice meter config + if meterConfig.N3RateBps != 0 { + gate = sliceMeterGateMeter + cir = 1 // Mark all traffic as yellow + pir = meterConfig.N3RateBps / 8 // bit/s to byte/s + } else { + gate = sliceMeterGateUnmeter + } + if meterConfig.N3BurstBytes != 0 { + cbs = 1 // Mark all traffic as yellow + pbs = meterConfig.N3BurstBytes + ebs = 0 // Unused + } else { + cbs = DefaultBurstSize + pbs = DefaultBurstSize + ebs = 0 // Unused + } + // TODO: packet deduction should take GTPU extension header into account + q = &pb.QosCommandAddArg{ + Gate: gate, + Cir: cir, /* committed info rate */ + Pir: pir, /* peak info rate */ + Cbs: cbs, /* committed burst size */ + Pbs: pbs, /* Peak burst size */ + Ebs: ebs, /* Excess burst size */ + OptionalDeductLen: &pb.QosCommandAddArg_DeductLen{50}, /* Exclude Ethernet,IP,UDP,GTP header */ + Fields: []*pb.FieldData{ + intEnc(uint64(farForwardD)), /* Action */ + intEnc(uint64(1)), /* tunnel_out_type */ + }, + } + any, err = anypb.New(q) + if err != nil { + log.Errorln("Error marshalling the rule", q, err) + return + } + b.processSliceMeter(ctx, any, upfMsgTypeAdd) + done <- true + }() +} + func (b *bess) removeAllPDRs(ctx context.Context, done chan<- bool) { go func() { var ( diff --git a/pfcpiface/bess_pb/module_msg.pb.go b/pfcpiface/bess_pb/module_msg.pb.go index 88a2da518..29fde203a 100644 --- a/pfcpiface/bess_pb/module_msg.pb.go +++ b/pfcpiface/bess_pb/module_msg.pb.go @@ -5955,14 +5955,17 @@ type QosCommandAddArg struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Gate uint64 `protobuf:"varint,1,opt,name=gate,proto3" json:"gate,omitempty"` - Cir uint64 `protobuf:"varint,2,opt,name=cir,proto3" json:"cir,omitempty"` - Pir uint64 `protobuf:"varint,3,opt,name=pir,proto3" json:"pir,omitempty"` - Cbs uint64 `protobuf:"varint,4,opt,name=cbs,proto3" json:"cbs,omitempty"` - Pbs uint64 `protobuf:"varint,5,opt,name=pbs,proto3" json:"pbs,omitempty"` - Ebs uint64 `protobuf:"varint,6,opt,name=ebs,proto3" json:"ebs,omitempty"` - Fields []*FieldData `protobuf:"bytes,7,rep,name=fields,proto3" json:"fields,omitempty"` - Values []*FieldData `protobuf:"bytes,8,rep,name=values,proto3" json:"values,omitempty"` + Gate uint64 `protobuf:"varint,1,opt,name=gate,proto3" json:"gate,omitempty"` + Cir uint64 `protobuf:"varint,2,opt,name=cir,proto3" json:"cir,omitempty"` + Pir uint64 `protobuf:"varint,3,opt,name=pir,proto3" json:"pir,omitempty"` + Cbs uint64 `protobuf:"varint,4,opt,name=cbs,proto3" json:"cbs,omitempty"` + Pbs uint64 `protobuf:"varint,5,opt,name=pbs,proto3" json:"pbs,omitempty"` + Ebs uint64 `protobuf:"varint,6,opt,name=ebs,proto3" json:"ebs,omitempty"` + // Types that are assignable to OptionalDeductLen: + // *QosCommandAddArg_DeductLen + OptionalDeductLen isQosCommandAddArg_OptionalDeductLen `protobuf_oneof:"optional_deduct_len"` + Fields []*FieldData `protobuf:"bytes,7,rep,name=fields,proto3" json:"fields,omitempty"` + Values []*FieldData `protobuf:"bytes,8,rep,name=values,proto3" json:"values,omitempty"` } func (x *QosCommandAddArg) Reset() { @@ -6039,6 +6042,20 @@ func (x *QosCommandAddArg) GetEbs() uint64 { return 0 } +func (m *QosCommandAddArg) GetOptionalDeductLen() isQosCommandAddArg_OptionalDeductLen { + if m != nil { + return m.OptionalDeductLen + } + return nil +} + +func (x *QosCommandAddArg) GetDeductLen() int64 { + if x, ok := x.GetOptionalDeductLen().(*QosCommandAddArg_DeductLen); ok { + return x.DeductLen + } + return 0 +} + func (x *QosCommandAddArg) GetFields() []*FieldData { if x != nil { return x.Fields @@ -6053,6 +6070,16 @@ func (x *QosCommandAddArg) GetValues() []*FieldData { return nil } +type isQosCommandAddArg_OptionalDeductLen interface { + isQosCommandAddArg_OptionalDeductLen() +} + +type QosCommandAddArg_DeductLen struct { + DeductLen int64 `protobuf:"varint,9,opt,name=deduct_len,json=deductLen,proto3,oneof"` +} + +func (*QosCommandAddArg_DeductLen) isQosCommandAddArg_OptionalDeductLen() {} + type QosCommandDeleteArg struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7710,7 +7737,7 @@ var file_module_msg_proto_rawDesc = []byte{ 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x22, 0xd8, 0x01, 0x0a, 0x10, 0x51, 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x65, 0x73, 0x22, 0x90, 0x02, 0x0a, 0x10, 0x51, 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x41, 0x72, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x67, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x63, 0x69, 0x72, 0x12, 0x10, 0x0a, @@ -7718,22 +7745,25 @@ var file_module_msg_proto_rawDesc = []byte{ 0x10, 0x0a, 0x03, 0x63, 0x62, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x63, 0x62, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x62, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x70, 0x62, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x62, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x03, 0x65, 0x62, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, - 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x62, 0x2e, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x41, 0x0a, - 0x13, 0x51, 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x41, 0x72, 0x67, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, - 0x22, 0x14, 0x0a, 0x12, 0x51, 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x43, 0x6c, - 0x65, 0x61, 0x72, 0x41, 0x72, 0x67, 0x22, 0x31, 0x0a, 0x1b, 0x51, 0x6f, 0x73, 0x43, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x47, 0x61, - 0x74, 0x65, 0x41, 0x72, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x04, 0x67, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x52, 0x03, 0x65, 0x62, 0x73, 0x12, 0x1f, 0x0a, 0x0a, 0x64, 0x65, 0x64, 0x75, 0x63, 0x74, 0x5f, + 0x6c, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x09, 0x64, 0x65, 0x64, + 0x75, 0x63, 0x74, 0x4c, 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x62, + 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x15, + 0x0a, 0x13, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x64, 0x75, 0x63, + 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x22, 0x41, 0x0a, 0x13, 0x51, 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x67, 0x12, 0x2a, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, + 0x65, 0x73, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x61, + 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x51, 0x6f, 0x73, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x41, 0x72, 0x67, 0x22, 0x31, + 0x0a, 0x1b, 0x51, 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x47, 0x61, 0x74, 0x65, 0x41, 0x72, 0x67, 0x12, 0x12, 0x0a, + 0x04, 0x67, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x67, 0x61, 0x74, + 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -9389,6 +9419,9 @@ func file_module_msg_proto_init() { (*TimestampArg_Offset)(nil), (*TimestampArg_AttrName)(nil), } + file_module_msg_proto_msgTypes[103].OneofWrappers = []interface{}{ + (*QosCommandAddArg_DeductLen)(nil), + } file_module_msg_proto_msgTypes[111].OneofWrappers = []interface{}{ (*GenericEncapArg_EncapField_Attribute)(nil), (*GenericEncapArg_EncapField_Value)(nil), diff --git a/pfcpiface/main.go b/pfcpiface/main.go index d3c69f0a2..5088170c4 100644 --- a/pfcpiface/main.go +++ b/pfcpiface/main.go @@ -25,22 +25,23 @@ var ( // Conf : Json conf struct. type Conf struct { - Mode string `json:"mode"` - MaxSessions uint32 `json:"max_sessions"` - AccessIface IfaceType `json:"access"` - CoreIface IfaceType `json:"core"` - CPIface CPIfaceInfo `json:"cpiface"` - P4rtcIface P4rtcInfo `json:"p4rtciface"` - EnableP4rt bool `json:"enable_p4rt"` - SimInfo SimModeInfo `json:"sim"` - ConnTimeout uint32 `json:"conn_timeout"` - ReadTimeout uint32 `json:"read_timeout"` - EnableNotifyBess bool `json:"enable_notify_bess"` - EnableEndMarker bool `json:"enable_end_marker"` - NotifySockAddr string `json:"notify_sockaddr"` - EndMarkerSockAddr string `json:"endmarker_sockaddr"` - LogLevel string `json:"log_level"` - QciQosConfig []QciQosConfig `json:"qci_qos_config"` + Mode string `json:"mode"` + MaxSessions uint32 `json:"max_sessions"` + AccessIface IfaceType `json:"access"` + CoreIface IfaceType `json:"core"` + CPIface CPIfaceInfo `json:"cpiface"` + P4rtcIface P4rtcInfo `json:"p4rtciface"` + EnableP4rt bool `json:"enable_p4rt"` + SimInfo SimModeInfo `json:"sim"` + ConnTimeout uint32 `json:"conn_timeout"` + ReadTimeout uint32 `json:"read_timeout"` + EnableNotifyBess bool `json:"enable_notify_bess"` + EnableEndMarker bool `json:"enable_end_marker"` + NotifySockAddr string `json:"notify_sockaddr"` + EndMarkerSockAddr string `json:"endmarker_sockaddr"` + LogLevel string `json:"log_level"` + QciQosConfig []QciQosConfig `json:"qci_qos_config"` + SliceMeterConfig SliceMeterConfig `json:"slice_rate_limit_config"` } // QciQosConfig : Qos configured attributes. @@ -52,6 +53,13 @@ type QciQosConfig struct { SchedulingPriority uint32 `json:"priority"` } +type SliceMeterConfig struct { + N6RateBps uint64 `json:"n6_bps"` + N6BurstBytes uint64 `json:"n6_burst_bytes"` + N3RateBps uint64 `json:"n3_bps"` + N3BurstBytes uint64 `json:"n3_burst_bytes"` +} + // SimModeInfo : Sim mode attributes. type SimModeInfo struct { StartUEIP net.IP `json:"start_ue_ip"`