diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 56e24d3fc..4b264e9f5 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -52,6 +52,12 @@ jobs: - name: Show all CI changes run: | git --no-pager diff + # Verify P4 constants + - name: Build P4 constants + id: check + run: | + make p4-constants + git update-index --refresh # Build again and commit - name: Build the BESS-UPF Docker image (after format) diff --git a/Makefile b/Makefile index 0fb0f3958..9fc743a99 100644 --- a/Makefile +++ b/Makefile @@ -100,12 +100,12 @@ test: .coverage -coverprofile=.coverage/coverage-unit.txt \ -covermode=atomic \ -v \ - ./pfcpiface + ./pfcpiface ./cmd/... p4-constants: $(info *** Generating go constants...) @docker run --rm -v $(CURDIR):/app -w /app \ - golang:latest go run ./scripts/go_gen_p4_const.go \ + golang:latest go run ./cmd/p4info_code_gen/p4info_code_gen.go \ -output internal/p4constants/p4constants.go -p4info conf/p4/bin/p4info.txt @docker run --rm -v $(CURDIR):/app -w /app \ golang:latest gofmt -w internal/p4constants/p4constants.go diff --git a/cmd/p4info_code_gen/p4info_code_gen.go b/cmd/p4info_code_gen/p4info_code_gen.go new file mode 100644 index 000000000..02df3d2e3 --- /dev/null +++ b/cmd/p4info_code_gen/p4info_code_gen.go @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022-present Open Networking Foundation + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/ettle/strcase" + "github.com/golang/protobuf/proto" + p4ConfigV1 "github.com/p4lang/p4runtime/go/p4/config/v1" +) + +const ( + p4infoPath = "conf/p4/bin/p4info.txt" + + defaultPackageName = "p4constants" + // copyrightHeader uses raw strings to avoid issues with reuse + copyrightHeader = `// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022-present Open Networking Foundation +` + + constOpen = "const (\n" + mapFormatString = "%v:\"%v\",\n" + listFormatString = "%v,\n" + constOrVarClose = ")\n" + + idTypeString = "uint32" + sizeTypeString = "uint64" + + hfVarPrefix = "Hdr_" + tblVarPrefix = "Table_" + ctrVarPrefix = "Counter_" + ctrSizeVarPrefix = "CounterSize_" + dirCtrVarPrefix = "DirectCounter_" + actVarPrefix = "Action_" + actparamVarPrefix = "ActionParam_" + actprofVarPrefix = "ActionProfile_" + packetmetaVarPrefix = "PacketMeta_" + mtrVarPrefix = "Meter_" + mtrSizeVarPrefix = "MeterSize_" +) + +func emitEntityConstant(prefix string, p4EntityName string, id uint32) string { + // see: https://go.dev/ref/spec#Identifiers + p4EntityName = prefix + "_" + p4EntityName + p4EntityName = strings.Replace(p4EntityName, ".", "_", -1) + p4EntityName = strcase.ToPascal(p4EntityName) + return fmt.Sprintf("%s \t %s = %v\n", p4EntityName, idTypeString, id) +} + +// TODO: collapse with emitEntityConstant +func emitEntitySizeConstant(prefix string, p4EntityName string, id int64) string { + // see: https://go.dev/ref/spec#Identifiers + p4EntityName = prefix + "_" + p4EntityName + p4EntityName = strings.Replace(p4EntityName, ".", "_", -1) + p4EntityName = strcase.ToPascal(p4EntityName) + return fmt.Sprintf("%s \t %s = %v\n", p4EntityName, sizeTypeString, id) +} + +func getPreambles(info *p4ConfigV1.P4Info, p4Type string) (preambles []*p4ConfigV1.Preamble) { + switch p4Type { + case "Table": + for _, e := range info.GetTables() { + preambles = append(preambles, e.GetPreamble()) + } + case "Action": + for _, e := range info.GetActions() { + preambles = append(preambles, e.GetPreamble()) + } + case "ActionProfile": + for _, e := range info.GetActionProfiles() { + preambles = append(preambles, e.GetPreamble()) + } + case "Counter": + for _, e := range info.GetCounters() { + preambles = append(preambles, e.GetPreamble()) + } + case "DirectCounter": + for _, e := range info.GetDirectCounters() { + preambles = append(preambles, e.GetPreamble()) + } + case "Meter": + for _, e := range info.GetMeters() { + preambles = append(preambles, e.GetPreamble()) + } + case "DirectMeter": + for _, e := range info.GetDirectMeters() { + preambles = append(preambles, e.GetPreamble()) + } + case "ControllerPacketMetadata": + for _, e := range info.GetControllerPacketMetadata() { + preambles = append(preambles, e.GetPreamble()) + } + case "ValueSet": + for _, e := range info.GetValueSets() { + preambles = append(preambles, e.GetPreamble()) + } + case "Register": + for _, e := range info.GetRegisters() { + preambles = append(preambles, e.GetPreamble()) + } + case "Digest": + for _, e := range info.GetDigests() { + preambles = append(preambles, e.GetPreamble()) + } + default: + panic("unknown p4 type " + p4Type) + } + + return +} + +func generateP4DataFunctions(info *p4ConfigV1.P4Info, p4Type string) string { + const mapFuncTemplate = "func Get%sIDToNameMap() map[%s]string {\n return map[%s]string {\n" + const listFuncTemplate = "func Get%sIDList() []%s {\n return []%s {\n" + + mapBuilder, listBuilder := strings.Builder{}, strings.Builder{} + mapBuilder.WriteString(fmt.Sprintf(mapFuncTemplate, p4Type, idTypeString, idTypeString)) + listBuilder.WriteString(fmt.Sprintf(listFuncTemplate, p4Type, idTypeString, idTypeString)) + + preambles := getPreambles(info, p4Type) + + for _, element := range preambles { + name, ID := element.GetName(), element.GetId() + + mapBuilder.WriteString(fmt.Sprintf(mapFormatString, ID, name)) + listBuilder.WriteString(fmt.Sprintf(listFormatString, ID)) + } + mapBuilder.WriteString("}\n}\n\n") + listBuilder.WriteString("}\n}\n\n") //Close declarations + + return mapBuilder.String() + listBuilder.String() +} + +func generateConstants(p4info *p4ConfigV1.P4Info) string { + constBuilder := strings.Builder{} + + constBuilder.WriteString(constOpen) + + //HeaderField IDs + constBuilder.WriteString("// HeaderFields\n") + for _, element := range p4info.GetTables() { + for _, matchField := range element.MatchFields { + tableName, name := element.GetPreamble().GetName(), matchField.GetName() + + constBuilder.WriteString(emitEntityConstant(hfVarPrefix+tableName, name, matchField.GetId())) + } + } + + // Tables + constBuilder.WriteString("// Tables\n") + for _, element := range p4info.GetTables() { + name, ID := element.GetPreamble().GetName(), element.GetPreamble().GetId() + + constBuilder.WriteString(emitEntityConstant(tblVarPrefix, name, ID)) + } + + // Actions + constBuilder.WriteString("// Actions\n") + for _, element := range p4info.GetActions() { + name, ID := element.GetPreamble().GetName(), element.GetPreamble().GetId() + + constBuilder.WriteString(emitEntityConstant(actVarPrefix, name, ID)) + } + + // Action Param IDs + constBuilder.WriteString("// ActionParams\n") + for _, element := range p4info.GetActions() { + for _, actionParam := range element.GetParams() { + actionName, name := element.GetPreamble().GetName(), actionParam.GetName() + + constBuilder.WriteString(emitEntityConstant(actparamVarPrefix+actionName, name, actionParam.GetId())) + } + } + + // Indirect Counters + constBuilder.WriteString("// IndirectCounters\n") + for _, element := range p4info.GetCounters() { + name, ID := element.GetPreamble().GetName(), element.GetPreamble().GetId() + + constBuilder.WriteString(emitEntityConstant(ctrVarPrefix, name, ID)) + constBuilder.WriteString(emitEntitySizeConstant(ctrSizeVarPrefix, name, element.GetSize())) + } + + // Direct Counters + constBuilder.WriteString("// DirectCounters\n") + for _, element := range p4info.GetDirectCounters() { + name, ID := element.GetPreamble().GetName(), element.GetPreamble().GetId() + + constBuilder.WriteString(emitEntityConstant(dirCtrVarPrefix, name, ID)) + } + + // Action profiles + constBuilder.WriteString("// ActionProfiles\n") + for _, element := range p4info.GetActionProfiles() { + name, ID := element.GetPreamble().GetName(), element.GetPreamble().GetId() + + constBuilder.WriteString(emitEntityConstant(actprofVarPrefix, name, ID)) + } + + // Packet metadata + constBuilder.WriteString("// PacketMetadata\n") + for _, element := range p4info.GetControllerPacketMetadata() { + name, ID := element.GetPreamble().GetName(), element.GetPreamble().GetId() + + constBuilder.WriteString(emitEntityConstant(packetmetaVarPrefix, name, ID)) + } + + // Meters + constBuilder.WriteString("// Meters\n") + for _, element := range p4info.GetMeters() { + name, ID := element.GetPreamble().GetName(), element.GetPreamble().GetId() + + constBuilder.WriteString(emitEntityConstant(mtrVarPrefix, name, ID)) + constBuilder.WriteString(emitEntitySizeConstant(mtrSizeVarPrefix, name, element.GetSize())) + } + + constBuilder.WriteString(constOrVarClose + "\n") + + return constBuilder.String() +} + +func mustGetP4Config(p4infopath string) *p4ConfigV1.P4Info { + p4infoBytes, err := ioutil.ReadFile(p4infopath) + if err != nil { + panic(fmt.Sprintf("Could not read P4Info file: %v", err)) + } + + var p4info p4ConfigV1.P4Info + + err = proto.UnmarshalText(string(p4infoBytes), &p4info) + if err != nil { + panic("Could not parse P4Info file") + } + + return &p4info +} + +func main() { + p4infoPath := flag.String("p4info", p4infoPath, "Path of the p4info file") + outputPath := flag.String("output", "-", "Default will print to Stdout") + packageName := flag.String("package", defaultPackageName, "Set the package name") + + flag.Parse() + + p4info := mustGetP4Config(*p4infoPath) + + sb := strings.Builder{} + + sb.WriteString(copyrightHeader + "\n") + sb.WriteString(fmt.Sprintf("package %s\n", *packageName)) + + sb.WriteString(generateConstants(p4info)) + sb.WriteString(generateP4DataFunctions(p4info, "Table")) + sb.WriteString(generateP4DataFunctions(p4info, "Action")) + sb.WriteString(generateP4DataFunctions(p4info, "ActionProfile")) + sb.WriteString(generateP4DataFunctions(p4info, "Counter")) + sb.WriteString(generateP4DataFunctions(p4info, "DirectCounter")) + sb.WriteString(generateP4DataFunctions(p4info, "Meter")) + sb.WriteString(generateP4DataFunctions(p4info, "DirectMeter")) + sb.WriteString(generateP4DataFunctions(p4info, "ControllerPacketMetadata")) + sb.WriteString(generateP4DataFunctions(p4info, "Register")) + + result := sb.String() + + if *outputPath == "-" { + fmt.Println(result) + } else { + if err := os.WriteFile(*outputPath, []byte(result), 0644); err != nil { + panic(fmt.Sprintf("Error while creating File: %v", err)) + } + } +} diff --git a/cmd/p4info_code_gen/p4info_code_gen_test.go b/cmd/p4info_code_gen/p4info_code_gen_test.go new file mode 100644 index 000000000..63c5fc17c --- /dev/null +++ b/cmd/p4info_code_gen/p4info_code_gen_test.go @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022-present Open Networking Foundation + +package main + +import ( + "io/fs" + "io/ioutil" + "strconv" + "strings" + "testing" + + p4ConfigV1 "github.com/p4lang/p4runtime/go/p4/config/v1" + "github.com/stretchr/testify/require" +) + +type generatorType int + +const ( + constant generatorType = iota + table + action + indirectCounter + directCounter + meter +) + +const testP4InfoString = ` +pkg_info { + arch: "v1model" +} +tables { + preamble { + id: 12345678 + name: "PreQosPipe.my_station" + alias: "my_station" + } + match_fields { + id: 1 + name: "dst_mac" + bitwidth: 48 + match_type: EXACT + } + action_refs { + id: 21257015 + } + size: 1024 +} +actions { + preamble { + id: 26090030 + name: "PreQosPipe.set_source_iface" + alias: "set_source_iface" + } + params { + id: 1 + name: "src_iface" + bitwidth: 8 + } + params { + id: 2 + name: "direction" + bitwidth: 8 + } + params { + id: 3 + name: "slice_id" + bitwidth: 4 + } +} +meters { + preamble { + id: 338231090 + name: "PreQosPipe.app_meter" + alias: "app_meter" + } + spec { + unit: BYTES + } + size: 1024 +} +counters { + preamble { + id: 315693181 + name: "PreQosPipe.pre_qos_counter" + alias: "pre_qos_counter" + } + spec { + unit: BOTH + } + size: 1024 +} +` + +func mustWriteStringToDisk(s string, path string) { + err := ioutil.WriteFile(path, []byte(s), fs.ModePerm) + if err != nil { + panic(err) + } +} + +func Test_generator(t *testing.T) { + p4infoPath := t.TempDir() + "/dummy_p4info.pb.txt" + mustWriteStringToDisk(testP4InfoString, p4infoPath) + + type args struct { + p4config *p4ConfigV1.P4Info + genType generatorType + } + + type want struct { + ID int + name string + } + + tests := []struct { + name string + args *args + want *want + wantErr bool + }{ + { + name: "verify table const", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: constant, + }, + want: &want{ + ID: 12345678, + name: "TablePreQosPipeMyStation", + }, + }, + { + name: "verify action const", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: constant, + }, + want: &want{ + ID: 26090030, + name: "ActionPreQosPipeSetSourceIface", + }, + }, + { + name: "non existing const", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: constant, + }, + want: &want{ + ID: 111111, + name: "test", + }, + wantErr: true, + }, + { + name: "verify meter size", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: constant, + }, + want: &want{ + ID: 1024, + name: "MeterSizePreQosPipeAppMeter", + }, + }, + { + name: "verify table map", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: table, + }, + want: &want{ + ID: 12345678, + name: "PreQosPipe.my_station", + }, + }, + { + name: "non existing element", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: table, + }, + want: &want{ + ID: 1111, + name: "test", + }, + wantErr: true, + }, + { + name: "verify meter map", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: meter, + }, + want: &want{ + ID: 338231090, + name: "PreQosPipe.app_meter", + }, + }, + { + name: "verify action map", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: action, + }, + want: &want{ + ID: 26090030, + name: "PreQosPipe.set_source_iface", + }, + }, + { + name: "non existing action", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: action, + }, + want: &want{ + ID: 1, + name: "test", + }, + wantErr: true, + }, + { + name: "verify indirect counter map", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: indirectCounter, + }, + want: &want{ + ID: 315693181, + name: "PreQosPipe.pre_qos_counter", + }, + }, + { + name: "non existing indirect counter", + args: &args{ + p4config: mustGetP4Config(p4infoPath), + genType: indirectCounter, + }, + want: &want{ + ID: 111, + name: "test", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := "" + + switch tt.args.genType { + case constant: + result = generateConstants(tt.args.p4config) + case table: + result = generateP4DataFunctions(tt.args.p4config, "Table") + case action: + result = generateP4DataFunctions(tt.args.p4config, "Action") + case meter: + result = generateP4DataFunctions(tt.args.p4config, "Meter") + case indirectCounter: + result = generateP4DataFunctions(tt.args.p4config, "Counter") + case directCounter: + result = generateP4DataFunctions(tt.args.p4config, "DirectCounter") + } + + idx := strings.Index(result, tt.want.name) + if idx == -1 && tt.wantErr { + return + } + + if idx != -1 && tt.wantErr { + t.Fatalf("Found unexpected entity name %s in generated code %s", tt.want.name, result) + } + + if idx == -1 { + t.Fatalf("Did not find expected entity name '%s' in generated code: %s", tt.want.name, result) + } + + line := strings.Join(strings.SplitN(result[idx:], "\n", 1), " ") + require.Contains(t, line, strconv.Itoa(tt.want.ID), "ID not found") + }) + } +} diff --git a/internal/p4constants/p4constants.go b/internal/p4constants/p4constants.go index de427b359..1fb669156 100644 --- a/internal/p4constants/p4constants.go +++ b/internal/p4constants/p4constants.go @@ -3,34 +3,33 @@ package p4constants -//noinspection GoSnakeCaseUsage const ( - // HeaderFields - HdrPreQosPipeRoutingRoutesV4dstPrefix uint32 = 1 - HdrPreQosPipeAclAclsinport uint32 = 1 - HdrPreQosPipeAclAclssrcIface uint32 = 2 - HdrPreQosPipeAclAclsethSrc uint32 = 3 - HdrPreQosPipeAclAclsethDst uint32 = 4 - HdrPreQosPipeAclAclsethType uint32 = 5 - HdrPreQosPipeAclAclsipv4Src uint32 = 6 - HdrPreQosPipeAclAclsipv4Dst uint32 = 7 - HdrPreQosPipeAclAclsipv4Proto uint32 = 8 - HdrPreQosPipeAclAclsl4Sport uint32 = 9 - HdrPreQosPipeAclAclsl4Dport uint32 = 10 - HdrPreQosPipeMyStationdstMac uint32 = 1 - HdrPreQosPipeInterfacesipv4DstPrefix uint32 = 1 - HdrPreQosPipeSessionsUplinkn3Address uint32 = 1 - HdrPreQosPipeSessionsUplinkteid uint32 = 2 - HdrPreQosPipeSessionsDownlinkueAddress uint32 = 1 - HdrPreQosPipeTerminationsUplinkueAddress uint32 = 1 - HdrPreQosPipeTerminationsUplinkappId uint32 = 2 - HdrPreQosPipeTerminationsDownlinkueAddress uint32 = 1 - HdrPreQosPipeTerminationsDownlinkappId uint32 = 2 - HdrPreQosPipeApplicationsappIpAddr uint32 = 1 - HdrPreQosPipeApplicationsappL4Port uint32 = 2 - HdrPreQosPipeApplicationsappIpProto uint32 = 3 - HdrPreQosPipeTunnelPeerstunnelPeerId uint32 = 1 + HdrPreQosPipeRoutingRoutesV4DstPrefix uint32 = 1 + HdrPreQosPipeAclAclsInport uint32 = 1 + HdrPreQosPipeAclAclsSrcIface uint32 = 2 + HdrPreQosPipeAclAclsEthSrc uint32 = 3 + HdrPreQosPipeAclAclsEthDst uint32 = 4 + HdrPreQosPipeAclAclsEthType uint32 = 5 + HdrPreQosPipeAclAclsIpv4Src uint32 = 6 + HdrPreQosPipeAclAclsIpv4Dst uint32 = 7 + HdrPreQosPipeAclAclsIpv4Proto uint32 = 8 + HdrPreQosPipeAclAclsL4Sport uint32 = 9 + HdrPreQosPipeAclAclsL4Dport uint32 = 10 + HdrPreQosPipeMyStationDstMac uint32 = 1 + HdrPreQosPipeInterfacesIpv4DstPrefix uint32 = 1 + HdrPreQosPipeSessionsUplinkN3Address uint32 = 1 + HdrPreQosPipeSessionsUplinkTeid uint32 = 2 + HdrPreQosPipeSessionsDownlinkUeAddress uint32 = 1 + HdrPreQosPipeTerminationsUplinkUeAddress uint32 = 1 + HdrPreQosPipeTerminationsUplinkAppId uint32 = 2 + HdrPreQosPipeTerminationsDownlinkUeAddress uint32 = 1 + HdrPreQosPipeTerminationsDownlinkAppId uint32 = 2 + HdrPreQosPipeApplicationsSliceId uint32 = 1 + HdrPreQosPipeApplicationsAppIpAddr uint32 = 2 + HdrPreQosPipeApplicationsAppL4Port uint32 = 3 + HdrPreQosPipeApplicationsAppIpProto uint32 = 4 + HdrPreQosPipeTunnelPeersTunnelPeerId uint32 = 1 // Tables TablePreQosPipeRoutingRoutesV4 uint32 = 39015874 TablePreQosPipeAclAcls uint32 = 47204971 @@ -69,40 +68,42 @@ const ( ActionPreQosPipeDoGtpuTunnel uint32 = 29247910 ActionPreQosPipeDoGtpuTunnelWithPsc uint32 = 31713420 // ActionParams - ActionParamPreQosPipeRoutingRoutesrcMac uint32 = 1 - ActionParamPreQosPipeRoutingRoutedstMac uint32 = 2 - ActionParamPreQosPipeRoutingRouteegressPort uint32 = 3 - ActionParamPreQosPipeAclSetPortport uint32 = 1 - ActionParamPreQosPipeSetSourceIfacesrcIface uint32 = 1 - ActionParamPreQosPipeSetSourceIfacedirection uint32 = 2 - ActionParamPreQosPipeSetSourceIfacesliceId uint32 = 3 - ActionParamPreQosPipeSetSessionUplinksessionMeterIdx uint32 = 1 - ActionParamPreQosPipeSetSessionDownlinktunnelPeerId uint32 = 1 - ActionParamPreQosPipeSetSessionDownlinksessionMeterIdx uint32 = 2 - ActionParamPreQosPipeSetSessionDownlinkBuffsessionMeterIdx uint32 = 1 - ActionParamPreQosPipeUplinkTermFwdNoTcctrIdx uint32 = 1 - ActionParamPreQosPipeUplinkTermFwdNoTcappMeterIdx uint32 = 2 - ActionParamPreQosPipeUplinkTermFwdctrIdx uint32 = 1 - ActionParamPreQosPipeUplinkTermFwdtc uint32 = 2 - ActionParamPreQosPipeUplinkTermFwdappMeterIdx uint32 = 3 - ActionParamPreQosPipeUplinkTermDropctrIdx uint32 = 1 - ActionParamPreQosPipeDownlinkTermFwdNoTcctrIdx uint32 = 1 - ActionParamPreQosPipeDownlinkTermFwdNoTcteid uint32 = 2 - ActionParamPreQosPipeDownlinkTermFwdNoTcqfi uint32 = 3 - ActionParamPreQosPipeDownlinkTermFwdNoTcappMeterIdx uint32 = 4 - ActionParamPreQosPipeDownlinkTermFwdctrIdx uint32 = 1 - ActionParamPreQosPipeDownlinkTermFwdteid uint32 = 2 - ActionParamPreQosPipeDownlinkTermFwdqfi uint32 = 3 - ActionParamPreQosPipeDownlinkTermFwdtc uint32 = 4 - ActionParamPreQosPipeDownlinkTermFwdappMeterIdx uint32 = 5 - ActionParamPreQosPipeDownlinkTermDropctrIdx uint32 = 1 - ActionParamPreQosPipeSetAppIdappId uint32 = 1 - ActionParamPreQosPipeLoadTunnelParamsrcAddr uint32 = 1 - ActionParamPreQosPipeLoadTunnelParamdstAddr uint32 = 2 - ActionParamPreQosPipeLoadTunnelParamsport uint32 = 3 + ActionParamPreQosPipeRoutingRouteSrcMac uint32 = 1 + ActionParamPreQosPipeRoutingRouteDstMac uint32 = 2 + ActionParamPreQosPipeRoutingRouteEgressPort uint32 = 3 + ActionParamPreQosPipeAclSetPortPort uint32 = 1 + ActionParamPreQosPipeSetSourceIfaceSrcIface uint32 = 1 + ActionParamPreQosPipeSetSourceIfaceDirection uint32 = 2 + ActionParamPreQosPipeSetSourceIfaceSliceId uint32 = 3 + ActionParamPreQosPipeSetSessionUplinkSessionMeterIdx uint32 = 1 + ActionParamPreQosPipeSetSessionDownlinkTunnelPeerId uint32 = 1 + ActionParamPreQosPipeSetSessionDownlinkSessionMeterIdx uint32 = 2 + ActionParamPreQosPipeSetSessionDownlinkBuffSessionMeterIdx uint32 = 1 + ActionParamPreQosPipeUplinkTermFwdNoTcCtrIdx uint32 = 1 + ActionParamPreQosPipeUplinkTermFwdNoTcAppMeterIdx uint32 = 2 + ActionParamPreQosPipeUplinkTermFwdCtrIdx uint32 = 1 + ActionParamPreQosPipeUplinkTermFwdTc uint32 = 2 + ActionParamPreQosPipeUplinkTermFwdAppMeterIdx uint32 = 3 + ActionParamPreQosPipeUplinkTermDropCtrIdx uint32 = 1 + ActionParamPreQosPipeDownlinkTermFwdNoTcCtrIdx uint32 = 1 + ActionParamPreQosPipeDownlinkTermFwdNoTcTeid uint32 = 2 + ActionParamPreQosPipeDownlinkTermFwdNoTcQfi uint32 = 3 + ActionParamPreQosPipeDownlinkTermFwdNoTcAppMeterIdx uint32 = 4 + ActionParamPreQosPipeDownlinkTermFwdCtrIdx uint32 = 1 + ActionParamPreQosPipeDownlinkTermFwdTeid uint32 = 2 + ActionParamPreQosPipeDownlinkTermFwdQfi uint32 = 3 + ActionParamPreQosPipeDownlinkTermFwdTc uint32 = 4 + ActionParamPreQosPipeDownlinkTermFwdAppMeterIdx uint32 = 5 + ActionParamPreQosPipeDownlinkTermDropCtrIdx uint32 = 1 + ActionParamPreQosPipeSetAppIdAppId uint32 = 1 + ActionParamPreQosPipeLoadTunnelParamSrcAddr uint32 = 1 + ActionParamPreQosPipeLoadTunnelParamDstAddr uint32 = 2 + ActionParamPreQosPipeLoadTunnelParamSport uint32 = 3 // IndirectCounters - CounterPreQosPipePreQosCounter uint32 = 315693181 - CounterPostQosPipePostQosCounter uint32 = 302958180 + CounterPreQosPipePreQosCounter uint32 = 315693181 + CounterSizePreQosPipePreQosCounter uint64 = 1024 + CounterPostQosPipePostQosCounter uint32 = 302958180 + CounterSizePostQosPipePostQosCounter uint64 = 1024 // DirectCounters DirectCounterAcls uint32 = 325583051 // ActionProfiles @@ -111,6 +112,180 @@ const ( PacketMetaPacketOut uint32 = 75327753 PacketMetaPacketIn uint32 = 80671331 // Meters - MeterPreQosPipeAppMeter uint32 = 338231090 - MeterPreQosPipeSessionMeter uint32 = 347593234 + MeterPreQosPipeAppMeter uint32 = 338231090 + MeterSizePreQosPipeAppMeter uint64 = 1024 + MeterPreQosPipeSessionMeter uint32 = 347593234 + MeterSizePreQosPipeSessionMeter uint64 = 1024 ) + +func GetTableIDToNameMap() map[uint32]string { + return map[uint32]string{ + 39015874: "PreQosPipe.Routing.routes_v4", + 47204971: "PreQosPipe.Acl.acls", + 40931612: "PreQosPipe.my_station", + 33923840: "PreQosPipe.interfaces", + 44976597: "PreQosPipe.sessions_uplink", + 34742049: "PreQosPipe.sessions_downlink", + 37595532: "PreQosPipe.terminations_uplink", + 34778590: "PreQosPipe.terminations_downlink", + 46868458: "PreQosPipe.applications", + 49497304: "PreQosPipe.tunnel_peers", + } +} + +func GetTableIDList() []uint32 { + return []uint32{ + 39015874, + 47204971, + 40931612, + 33923840, + 44976597, + 34742049, + 37595532, + 34778590, + 46868458, + 49497304, + } +} + +func GetActionIDToNameMap() map[uint32]string { + return map[uint32]string{ + 21257015: "NoAction", + 31448256: "PreQosPipe.Routing.drop", + 23965128: "PreQosPipe.Routing.route", + 30494847: "PreQosPipe.Acl.set_port", + 26495283: "PreQosPipe.Acl.punt", + 21596798: "PreQosPipe.Acl.clone_to_cpu", + 18812293: "PreQosPipe.Acl.drop", + 23766285: "PreQosPipe._initialize_metadata", + 26090030: "PreQosPipe.set_source_iface", + 28401267: "PreQosPipe.do_drop", + 19461580: "PreQosPipe.set_session_uplink", + 22196934: "PreQosPipe.set_session_uplink_drop", + 21848329: "PreQosPipe.set_session_downlink", + 20229579: "PreQosPipe.set_session_downlink_drop", + 20249483: "PreQosPipe.set_session_downlink_buff", + 21760615: "PreQosPipe.uplink_term_fwd_no_tc", + 28305359: "PreQosPipe.uplink_term_fwd", + 20977365: "PreQosPipe.uplink_term_drop", + 26185804: "PreQosPipe.downlink_term_fwd_no_tc", + 32699713: "PreQosPipe.downlink_term_fwd", + 31264233: "PreQosPipe.downlink_term_drop", + 23010411: "PreQosPipe.set_app_id", + 32742981: "PreQosPipe.load_tunnel_param", + 29247910: "PreQosPipe.do_gtpu_tunnel", + 31713420: "PreQosPipe.do_gtpu_tunnel_with_psc", + } +} + +func GetActionIDList() []uint32 { + return []uint32{ + 21257015, + 31448256, + 23965128, + 30494847, + 26495283, + 21596798, + 18812293, + 23766285, + 26090030, + 28401267, + 19461580, + 22196934, + 21848329, + 20229579, + 20249483, + 21760615, + 28305359, + 20977365, + 26185804, + 32699713, + 31264233, + 23010411, + 32742981, + 29247910, + 31713420, + } +} + +func GetActionProfileIDToNameMap() map[uint32]string { + return map[uint32]string{ + 297808402: "hashed_selector", + } +} + +func GetActionProfileIDList() []uint32 { + return []uint32{ + 297808402, + } +} + +func GetCounterIDToNameMap() map[uint32]string { + return map[uint32]string{ + 315693181: "PreQosPipe.pre_qos_counter", + 302958180: "PostQosPipe.post_qos_counter", + } +} + +func GetCounterIDList() []uint32 { + return []uint32{ + 315693181, + 302958180, + } +} + +func GetDirectCounterIDToNameMap() map[uint32]string { + return map[uint32]string{ + 325583051: "acls", + } +} + +func GetDirectCounterIDList() []uint32 { + return []uint32{ + 325583051, + } +} + +func GetMeterIDToNameMap() map[uint32]string { + return map[uint32]string{ + 338231090: "PreQosPipe.app_meter", + 347593234: "PreQosPipe.session_meter", + } +} + +func GetMeterIDList() []uint32 { + return []uint32{ + 338231090, + 347593234, + } +} + +func GetDirectMeterIDToNameMap() map[uint32]string { + return map[uint32]string{} +} + +func GetDirectMeterIDList() []uint32 { + return []uint32{} +} + +func GetControllerPacketMetadataIDToNameMap() map[uint32]string { + return map[uint32]string{ + 75327753: "packet_out", + 80671331: "packet_in", + } +} + +func GetControllerPacketMetadataIDList() []uint32 { + return []uint32{ + 75327753, + 80671331, + } +} + +func GetRegisterIDToNameMap() map[uint32]string { + return map[uint32]string{} +} + +func GetRegisterIDList() []uint32 { + return []uint32{} +} diff --git a/scripts/go_gen_p4_const.go b/scripts/go_gen_p4_const.go deleted file mode 100644 index a18f9d49b..000000000 --- a/scripts/go_gen_p4_const.go +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2022-present Open Networking Foundation - -package main - -import ( - "flag" - "fmt" - "io/ioutil" - "os" - "strings" - - "github.com/ettle/strcase" - "github.com/golang/protobuf/proto" - p4ConfigV1 "github.com/p4lang/p4runtime/go/p4/config/v1" -) - -const ( - P4infoPath = "conf/p4/bin/p4info.txt" - - DefaultPackageName = "p4constants" - // CopyrightHeader uses raw strings to avoid issues with reuse - CopyrightHeader = `// SPDX-License-Identifier: Apache-2.0 -// Copyright 2022-present Open Networking Foundation -` - - ConstOpen = "//noinspection GoSnakeCaseUsage\nconst (\n" - ConstClose = ")" - - IdTypeString = "uint32" - - HfVarPrefix = "Hdr_" - TblVarPrefix = "Table_" - CtrVarPrefix = "Counter_" - DirctrVarPrefix = "DirectCounter_" - ActVarPrefix = "Action_" - ActparamVarPrefix = "ActionParam_" - ActprofVarPrefix = "ActionProfile_" - PacketmetaVarPrefix = "PacketMeta_" - MtrVarPrefix = "Meter_" -) - -func emitEntityConstant(p4EntityName string, id uint32) string { - // see: https://go.dev/ref/spec#Identifiers - p4EntityName = strings.Replace(p4EntityName, ".", "_", -1) - p4EntityName = strcase.ToPascal(p4EntityName) - return fmt.Sprintf("%s \t %s = %v\n", p4EntityName, IdTypeString, id) -} - -func generateP4Constants(p4info *p4ConfigV1.P4Info, packageName string) string { - builder := strings.Builder{} - - builder.WriteString(CopyrightHeader + "\n") - - builder.WriteString(fmt.Sprintf("package %s\n", packageName)) - builder.WriteString(ConstOpen + "\n") - - //HeaderField IDs - builder.WriteString("// HeaderFields\n") - for _, element := range p4info.GetTables() { - for _, matchField := range element.MatchFields { - tableName := element.GetPreamble().GetName() - name := matchField.GetName() - builder.WriteString(emitEntityConstant(HfVarPrefix+tableName+name, matchField.GetId())) - } - } - // Tables - builder.WriteString("// Tables\n") - for _, element := range p4info.GetTables() { - name := element.GetPreamble().GetName() - builder.WriteString(emitEntityConstant(TblVarPrefix+name, element.GetPreamble().GetId())) - } - // Actions - builder.WriteString("// Actions\n") - for _, element := range p4info.GetActions() { - name := element.GetPreamble().GetName() - builder.WriteString(emitEntityConstant(ActVarPrefix+name, element.GetPreamble().GetId())) - } - // Action Param IDs - builder.WriteString("// ActionParams\n") - for _, element := range p4info.GetActions() { - for _, actionParam := range element.GetParams() { - actionName := element.GetPreamble().GetName() - name := actionParam.GetName() - builder.WriteString(emitEntityConstant(ActparamVarPrefix+actionName+name, actionParam.GetId())) - } - } - // Indirect Counters - builder.WriteString("// IndirectCounters\n") - for _, element := range p4info.GetCounters() { - name := element.GetPreamble().GetName() - builder.WriteString(emitEntityConstant(CtrVarPrefix+name, element.GetPreamble().GetId())) - } - // Direct Counters - builder.WriteString("// DirectCounters\n") - for _, element := range p4info.GetDirectCounters() { - name := element.GetPreamble().GetName() - builder.WriteString(emitEntityConstant(DirctrVarPrefix+name, element.GetPreamble().GetId())) - } - // Action profiles - builder.WriteString("// ActionProfiles\n") - for _, element := range p4info.GetActionProfiles() { - name := element.GetPreamble().GetName() - builder.WriteString(emitEntityConstant(ActprofVarPrefix+name, element.GetPreamble().GetId())) - } - // Packet metadata - builder.WriteString("// PacketMetadata\n") - for _, element := range p4info.GetControllerPacketMetadata() { - name := element.GetPreamble().GetName() - builder.WriteString(emitEntityConstant(PacketmetaVarPrefix+name, element.GetPreamble().GetId())) - } - // Meters - builder.WriteString("// Meters\n") - for _, element := range p4info.GetMeters() { - name := element.GetPreamble().GetName() - builder.WriteString(emitEntityConstant(MtrVarPrefix+name, element.GetPreamble().GetId())) - } - - builder.WriteString(ConstClose + "\n") - - return builder.String() -} - -func getP4Config(p4infopath string) *p4ConfigV1.P4Info { - p4infoBytes, err := ioutil.ReadFile(p4infopath) - if err != nil { - panic(fmt.Sprintf("Could not read P4Info file: %v", err)) - } - - var p4info p4ConfigV1.P4Info - - err = proto.UnmarshalText(string(p4infoBytes), &p4info) - if err != nil { - panic("Could not parse P4Info file") - } - - return &p4info -} - -func main() { - p4infoPath := flag.String("p4info", P4infoPath, "Path of the p4info file") - outputPath := flag.String("output", "-", "Default will print to Stdout") - packageName := flag.String("package", DefaultPackageName, "Set the package name") - - flag.Parse() - - p4config := getP4Config(*p4infoPath) - - result := generateP4Constants(p4config, *packageName) - - if *outputPath == "-" { - fmt.Println(result) - } else { - if err := os.WriteFile(*outputPath, []byte(result), 0644); err != nil { - panic(fmt.Sprintf("Error while creating File: %v", err)) - } - } -}