aboutsummaryrefslogtreecommitdiffstats
path: root/binapigen
diff options
context:
space:
mode:
Diffstat (limited to 'binapigen')
-rw-r--r--binapigen/binapigen.go42
-rw-r--r--binapigen/binapigen_test.go6
-rw-r--r--binapigen/gen_encoding.go12
-rw-r--r--binapigen/gen_helpers.go81
-rw-r--r--binapigen/gen_helpers_test.go31
-rw-r--r--binapigen/gen_http.go (renamed from binapigen/gen_rest.go)14
-rw-r--r--binapigen/gen_rpc.go16
-rw-r--r--binapigen/generate.go84
-rw-r--r--binapigen/generate_test.go21
-rw-r--r--binapigen/generator.go65
-rw-r--r--binapigen/generator_test.go94
-rw-r--r--binapigen/run.go16
-rw-r--r--binapigen/types.go64
-rw-r--r--binapigen/vppapi.go28
-rw-r--r--binapigen/vppapi/api_schema.go16
-rw-r--r--binapigen/vppapi/integration_test.go2
-rw-r--r--binapigen/vppapi/parse_json.go48
-rw-r--r--binapigen/vppapi/testdata/ip.api.json3096
-rw-r--r--binapigen/vppapi/testdata/union.api.json231
-rw-r--r--binapigen/vppapi/util.go23
-rw-r--r--binapigen/vppapi/vppapi.go25
-rw-r--r--binapigen/vppapi/vppapi_test.go2
22 files changed, 2982 insertions, 1035 deletions
diff --git a/binapigen/binapigen.go b/binapigen/binapigen.go
index 2dbd661..5c9553f 100644
--- a/binapigen/binapigen.go
+++ b/binapigen/binapigen.go
@@ -20,7 +20,7 @@ import (
"strconv"
"strings"
- "git.fd.io/govpp.git/binapigen/vppapi"
+ "go.fd.io/govpp/binapigen/vppapi"
)
// generatedCodeVersion indicates a version of the generated code.
@@ -71,7 +71,10 @@ func newFile(gen *Generator, apifile *vppapi.File, packageName GoPackageName, im
}
for _, enumType := range apifile.EnumTypes {
- file.Enums = append(file.Enums, newEnum(gen, file, enumType))
+ file.Enums = append(file.Enums, newEnum(gen, file, enumType, false))
+ }
+ for _, enumflagType := range apifile.EnumflagTypes {
+ file.Enums = append(file.Enums, newEnum(gen, file, enumflagType, true))
}
for _, aliasType := range apifile.AliasTypes {
file.Aliases = append(file.Aliases, newAlias(gen, file, aliasType))
@@ -167,15 +170,18 @@ type Enum struct {
vppapi.EnumType
GoIdent
+
+ IsFlag bool
}
-func newEnum(gen *Generator, file *File, apitype vppapi.EnumType) *Enum {
+func newEnum(gen *Generator, file *File, apitype vppapi.EnumType, isFlag bool) *Enum {
typ := &Enum{
EnumType: apitype,
GoIdent: GoIdent{
GoName: camelCaseName(apitype.Name),
GoImportPath: file.GoImportPath,
},
+ IsFlag: isFlag,
}
gen.enumsByName[typ.Name] = typ
return typ
@@ -243,8 +249,8 @@ func newStruct(gen *Generator, file *File, apitype vppapi.StructType) *Struct {
},
}
gen.structsByName[typ.Name] = typ
- for _, fieldType := range apitype.Fields {
- field := newField(gen, file, typ, fieldType)
+ for i, fieldType := range apitype.Fields {
+ field := newField(gen, file, typ, fieldType, i)
typ.Fields = append(typ.Fields, field)
}
return typ
@@ -271,13 +277,13 @@ func newUnion(gen *Generator, file *File, apitype vppapi.UnionType) *Union {
typ := &Union{
UnionType: apitype,
GoIdent: GoIdent{
- GoName: camelCaseName(apitype.Name),
+ GoName: withSuffix(camelCaseName(apitype.Name), "Union"),
GoImportPath: file.GoImportPath,
},
}
gen.unionsByName[typ.Name] = typ
- for _, fieldType := range apitype.Fields {
- field := newField(gen, file, typ, fieldType)
+ for i, fieldType := range apitype.Fields {
+ field := newField(gen, file, typ, fieldType, i)
typ.Fields = append(typ.Fields, field)
}
return typ
@@ -302,11 +308,12 @@ const (
msgTypeEvent // msg_id, client_index
)
-// message fields
+// common message fields
const (
fieldMsgID = "_vl_msg_id"
fieldClientIndex = "client_index"
fieldContext = "context"
+ fieldRetval = "retval"
)
// field options
@@ -343,7 +350,7 @@ func newMessage(gen *Generator, file *File, apitype vppapi.Message) *Message {
}
}
n++
- field := newField(gen, file, msg, fieldType)
+ field := newField(gen, file, msg, fieldType, n)
msg.Fields = append(msg.Fields, field)
}
return msg
@@ -394,12 +401,24 @@ func getMsgType(m vppapi.Message) (msgType, error) {
return typ, nil
}
+func getRetvalField(m *Message) *Field {
+ for _, field := range m.Fields {
+ if field.Name == fieldRetval {
+ return field
+ }
+ }
+ return nil
+}
+
// Field represents a field for message or struct/union types.
type Field struct {
vppapi.Field
GoName string
+ // Index defines field index in parent.
+ Index int
+
// DefaultValue is a default value of field or
// nil if default value is not defined for field.
DefaultValue interface{}
@@ -423,10 +442,11 @@ type Field struct {
FieldSizeFrom *Field
}
-func newField(gen *Generator, file *File, parent interface{}, apitype vppapi.Field) *Field {
+func newField(gen *Generator, file *File, parent interface{}, apitype vppapi.Field, index int) *Field {
typ := &Field{
Field: apitype,
GoName: camelCaseName(apitype.Name),
+ Index: index,
}
switch p := parent.(type) {
case *Message:
diff --git a/binapigen/binapigen_test.go b/binapigen/binapigen_test.go
index 9a25420..c9bfba7 100644
--- a/binapigen/binapigen_test.go
+++ b/binapigen/binapigen_test.go
@@ -19,7 +19,7 @@ import (
. "github.com/onsi/gomega"
- "git.fd.io/govpp.git/binapigen/vppapi"
+ "go.fd.io/govpp/binapigen/vppapi"
)
func TestGenerator(t *testing.T) {
@@ -40,11 +40,11 @@ func TestGenerator(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
RegisterTestingT(t)
- apifiles := []*vppapi.File{test.file}
+ apiFiles := []*vppapi.File{test.file}
gen, err := New(Options{
ImportPrefix: "test",
- }, apifiles, nil)
+ }, apiFiles, nil)
Expect(err).ToNot(HaveOccurred(), "unexpected generator error: %v", err)
Expect(gen.Files).To(HaveLen(1))
diff --git a/binapigen/gen_encoding.go b/binapigen/gen_encoding.go
index d946771..ca1e848 100644
--- a/binapigen/gen_encoding.go
+++ b/binapigen/gen_encoding.go
@@ -21,10 +21,6 @@ import (
"github.com/sirupsen/logrus"
)
-func init() {
- //RegisterPlugin("encoding", GenerateEncoding)
-}
-
func genMessageSize(g *GenFile, name string, fields []*Field) {
g.P("func (m *", name, ") Size() (size int) {")
g.P("if m == nil { return 0 }")
@@ -230,7 +226,7 @@ func encodeBaseType(g *GenFile, typ, orig, name string, length int, sizefrom str
g.P("buf.EncodeBytes(", name, "[:], ", length, ")")
}
return
- case I8, I16, U16, I32, U32, I64, U64, F64:
+ case I8, I16, U16, I32, U32, I64, U64, F64, BOOL:
gotype := BaseTypesGo[typ]
if length != 0 {
g.P("for i := 0; i < ", length, "; i++ {")
@@ -268,7 +264,7 @@ func encodeBaseType(g *GenFile, typ, orig, name string, length int, sizefrom str
}
if isArray {
switch typ {
- case I8, U8, I16, U16, I32, U32, I64, U64, F64:
+ case I8, U8, I16, U16, I32, U32, I64, U64, F64, BOOL:
g.P("}")
}
}
@@ -369,7 +365,7 @@ func decodeBaseType(g *GenFile, typ, orig, name string, length int, sizefrom str
g.P("copy(", name, "[:], buf.DecodeBytes(", size, "))")
}
return
- case I8, I16, U16, I32, U32, I64, U64, F64:
+ case I8, I16, U16, I32, U32, I64, U64, F64, BOOL:
if alloc {
g.P(name, " = make([]", orig, ", ", size, ")")
}
@@ -401,7 +397,7 @@ func decodeBaseType(g *GenFile, typ, orig, name string, length int, sizefrom str
}
if isArray {
switch typ {
- case I8, U8, I16, U16, I32, U32, I64, U64, F64:
+ case I8, U8, I16, U16, I32, U32, I64, U64, F64, BOOL:
g.P("}")
}
}
diff --git a/binapigen/gen_helpers.go b/binapigen/gen_helpers.go
index 5eafc76..0fc303d 100644
--- a/binapigen/gen_helpers.go
+++ b/binapigen/gen_helpers.go
@@ -22,6 +22,7 @@ func init() {
const (
fmtPkg = GoImportPath("fmt")
netPkg = GoImportPath("net")
+ timePkg = GoImportPath("time")
stringsPkg = GoImportPath("strings")
)
@@ -54,16 +55,19 @@ func genIPConversion(g *GenFile, structName string, ipv int) {
g.P(" return ", netPkg.Ident("IP"), "(x[:]).To16()")
}
g.P("}")
+ g.P()
// String method
g.P("func (x ", structName, ") String() string {")
g.P(" return x.ToIP().String()")
g.P("}")
+ g.P()
// MarshalText method
g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
g.P(" return []byte(x.String()), nil")
g.P("}")
+ g.P()
// UnmarshalText method
g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
@@ -84,6 +88,12 @@ func genAddressConversion(g *GenFile, structName string) {
g.P(" if ip == nil {")
g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid address: %s\", s)")
g.P(" }")
+ g.P(" return ", structName, "FromIP(ip), nil")
+ g.P("}")
+ g.P()
+
+ // AddressFromIP method
+ g.P("func ", structName, "FromIP(ip ", netPkg.Ident("IP"), ") ", structName, " {")
g.P(" var addr ", structName)
g.P(" if ip.To4() == nil {")
g.P(" addr.Af = ADDRESS_IP6")
@@ -96,8 +106,9 @@ func genAddressConversion(g *GenFile, structName string) {
g.P(" copy(ip4[:], ip.To4())")
g.P(" addr.Un.SetIP4(ip4)")
g.P(" }")
- g.P(" return addr, nil")
+ g.P(" return addr")
g.P("}")
+ g.P()
// ToIP method
g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
@@ -109,16 +120,19 @@ func genAddressConversion(g *GenFile, structName string) {
g.P(" return ", netPkg.Ident("IP"), "(ip4[:]).To4()")
g.P(" }")
g.P("}")
+ g.P()
// String method
g.P("func (x ", structName, ") String() string {")
g.P(" return x.ToIP().String()")
g.P("}")
+ g.P()
// MarshalText method
g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
g.P(" return []byte(x.String()), nil")
g.P("}")
+ g.P()
// UnmarshalText method
g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
@@ -169,6 +183,7 @@ func genIPPrefixConversion(g *GenFile, structName string, ipv int) {
g.P(" }")
g.P(" return prefix, nil")
g.P("}")
+ g.P()
// ToIPNet method
g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
@@ -180,24 +195,20 @@ func genIPPrefixConversion(g *GenFile, structName string, ipv int) {
g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
g.P(" return ipnet")
g.P("}")
+ g.P()
// String method
g.P("func (x ", structName, ") String() string {")
g.P(" ip := x.Address.String()")
g.P(" return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
- /*if ipv == 4 {
- g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
- } else {
- g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
- }
- g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
- g.P(" return ipnet.String()")*/
g.P("}")
+ g.P()
// MarshalText method
g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
g.P(" return []byte(x.String()), nil")
g.P("}")
+ g.P()
// UnmarshalText method
g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
@@ -240,6 +251,7 @@ func genPrefixConversion(g *GenFile, structName string) {
g.P(" }")
g.P(" return prefix, nil")
g.P("}")
+ g.P()
// ToIPNet method
g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
@@ -252,17 +264,20 @@ func genPrefixConversion(g *GenFile, structName string) {
g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
g.P(" return ipnet")
g.P("}")
+ g.P()
// String method
g.P("func (x ", structName, ") String() string {")
g.P(" ip := x.Address.String()")
g.P(" return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
g.P("}")
+ g.P()
// MarshalText method
g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
g.P(" return []byte(x.String()), nil")
g.P("}")
+ g.P()
// UnmarshalText method
g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
@@ -285,16 +300,19 @@ func genAddressWithPrefixConversion(g *GenFile, structName string) {
g.P(" }")
g.P(" return ", structName, "(prefix), nil")
g.P("}")
+ g.P()
// String method
g.P("func (x ", structName, ") String() string {")
g.P(" return Prefix(x).String()")
g.P("}")
+ g.P()
// MarshalText method
g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
g.P(" return []byte(x.String()), nil")
g.P("}")
+ g.P()
// UnmarshalText method
g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
@@ -319,21 +337,25 @@ func genMacAddressConversion(g *GenFile, structName string) {
g.P(" copy(macaddr[:], mac[:])")
g.P(" return macaddr, nil")
g.P("}")
+ g.P()
// ToMAC method
g.P("func (x ", structName, ") ToMAC() ", netPkg.Ident("HardwareAddr"), " {")
g.P(" return ", netPkg.Ident("HardwareAddr"), "(x[:])")
g.P("}")
+ g.P()
// String method
g.P("func (x ", structName, ") String() string {")
g.P(" return x.ToMAC().String()")
g.P("}")
+ g.P()
// MarshalText method
g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
g.P(" return []byte(x.String()), nil")
g.P("}")
+ g.P()
// UnmarshalText method
g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
@@ -346,3 +368,46 @@ func genMacAddressConversion(g *GenFile, structName string) {
g.P("}")
g.P()
}
+
+func genTimestampConversion(g *GenFile, structName string) {
+ // NewTimestamp method
+ g.P("func New", structName, "(t ", timePkg.Ident("Time"), ") ", structName, " {")
+ g.P(" sec := int64(t.Unix())")
+ g.P(" nsec := int32(t.Nanosecond())")
+ g.P(" ns := float64(sec) + float64(nsec / 1e9)")
+ g.P(" return ", structName, "(ns)")
+ g.P("}")
+ g.P()
+
+ // ToTime method
+ g.P("func (x ", structName, ") ToTime() ", timePkg.Ident("Time"), " {")
+ g.P(" ns := int64(x * 1e9)")
+ g.P(" sec := ns / 1e9")
+ g.P(" nsec := ns % 1e9")
+ g.P(" return ", timePkg.Ident("Unix"), "(sec, nsec)")
+ g.P("}")
+ g.P()
+
+ // String method
+ g.P("func (x ", structName, ") String() string {")
+ g.P(" return x.ToTime().String()")
+ g.P("}")
+ g.P()
+
+ // MarshalText method
+ g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
+ g.P(" return []byte(x.ToTime().Format(", timePkg.Ident("RFC3339Nano"), ")), nil")
+ g.P("}")
+ g.P()
+
+ // UnmarshalText method
+ g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
+ g.P(" t, err := ", timePkg.Ident("Parse"), "(", timePkg.Ident("RFC3339Nano"), ", string(text))")
+ g.P(" if err != nil {")
+ g.P(" return err")
+ g.P(" }")
+ g.P(" *x = New", structName, "(t)")
+ g.P(" return nil")
+ g.P("}")
+ g.P()
+}
diff --git a/binapigen/gen_helpers_test.go b/binapigen/gen_helpers_test.go
index 371fd6c..a8d159f 100644
--- a/binapigen/gen_helpers_test.go
+++ b/binapigen/gen_helpers_test.go
@@ -17,11 +17,13 @@ package binapigen
import (
"strings"
"testing"
+ "time"
. "github.com/onsi/gomega"
- "git.fd.io/govpp.git/binapi/ethernet_types"
- "git.fd.io/govpp.git/binapi/ip_types"
+ "go.fd.io/govpp/binapi/ethernet_types"
+ "go.fd.io/govpp/binapi/ip_types"
+ "go.fd.io/govpp/binapi/vpe_types"
)
func TestGeneratedParseAddress(t *testing.T) {
@@ -154,3 +156,28 @@ func TestGeneratedParseMACError(t *testing.T) {
_, err := ethernet_types.ParseMacAddress("malformed_mac")
Expect(err).Should(HaveOccurred())
}
+
+func TestGeneratedParseTimestamp(t *testing.T) {
+ RegisterTestingT(t)
+
+ var data = []struct {
+ input time.Time
+ result vpe_types.Timestamp
+ }{
+ {time.Unix(0, 0), vpe_types.Timestamp(0)},
+ {time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
+ vpe_types.Timestamp(9.466848e+08)},
+ }
+
+ for _, entry := range data {
+ t.Run(entry.input.String(), func(t *testing.T) {
+ ts := vpe_types.NewTimestamp(entry.input)
+ Expect(ts).To(Equal(entry.result))
+
+ Expect(entry.input.Equal(ts.ToTime())).To(BeTrue())
+
+ originTime := ts.String()
+ Expect(originTime).To(Equal(entry.input.Local().String()))
+ })
+ }
+}
diff --git a/binapigen/gen_rest.go b/binapigen/gen_http.go
index 6ddb57a..4c9697e 100644
--- a/binapigen/gen_rest.go
+++ b/binapigen/gen_http.go
@@ -20,7 +20,7 @@ import (
)
func init() {
- RegisterPlugin("rest", GenerateREST)
+ RegisterPlugin("http", GenerateHTTP)
}
// library dependencies
@@ -30,16 +30,16 @@ const (
jsonPkg = GoImportPath("encoding/json")
)
-func GenerateREST(gen *Generator, file *File) *GenFile {
+func GenerateHTTP(gen *Generator, file *File) *GenFile {
if file.Service == nil {
return nil
}
logf("----------------------------")
- logf(" Generate REST - %s", file.Desc.Name)
+ logf(" Generate HTTP - %s", file.Desc.Name)
logf("----------------------------")
- filename := path.Join(file.FilenamePrefix, file.Desc.Name+"_rest.ba.go")
+ filename := path.Join(file.FilenamePrefix, file.Desc.Name+"_http.ba.go")
g := gen.NewGenFile(filename, file.GoImportPath)
g.file = file
@@ -51,15 +51,15 @@ func GenerateREST(gen *Generator, file *File) *GenFile {
// generate RPC service
if len(file.Service.RPCs) > 0 {
- genRESTHandler(g, file.Service)
+ genHTTPHandler(g, file.Service)
}
return g
}
-func genRESTHandler(g *GenFile, svc *Service) {
+func genHTTPHandler(g *GenFile, svc *Service) {
// generate handler constructor
- g.P("func RESTHandler(rpc ", serviceApiName, ") ", httpPkg.Ident("Handler"), " {")
+ g.P("func HTTPHandler(rpc ", serviceApiName, ") ", httpPkg.Ident("Handler"), " {")
g.P(" mux := ", httpPkg.Ident("NewServeMux"), "()")
// generate http handlers for rpc
diff --git a/binapigen/gen_rpc.go b/binapigen/gen_rpc.go
index ba23f4a..fa123f0 100644
--- a/binapigen/gen_rpc.go
+++ b/binapigen/gen_rpc.go
@@ -71,7 +71,7 @@ func GenerateRPC(gen *Generator, file *File) *GenFile {
func genService(g *GenFile, svc *Service) {
// generate comment
- g.P("// ", serviceApiName, " defines RPC service ", g.file.Desc.Name, ".")
+ g.P("// ", serviceApiName, " defines RPC service ", g.file.Desc.Name, ".")
// generate service interface
g.P("type ", serviceApiName, " interface {")
@@ -152,6 +152,8 @@ func genService(g *GenFile, svc *Service) {
g.P(" case *", msgDetails.GoIdent, ":")
g.P(" return m, nil")
g.P(" case *", msgReply.GoIdent, ":")
+ g.P(" err = c.Stream.Close()")
+ g.P(" if err != nil { return nil, err }")
g.P(" return nil, ", ioPkg.Ident("EOF"))
g.P(" default:")
g.P(" return nil, ", fmtPkg.Ident("Errorf"), "(\"unexpected message: %T %v\", m, m)")
@@ -160,12 +162,22 @@ func genService(g *GenFile, svc *Service) {
g.P("out := new(", rpc.MsgReply.GoIdent, ")")
g.P("err := c.conn.Invoke(ctx, in, out)")
g.P("if err != nil { return nil, err }")
- g.P("return out, nil")
+ if retvalField := getRetvalField(rpc.MsgReply); retvalField != nil {
+ if fieldType := getFieldType(g, retvalField); fieldType == "int32" {
+ g.P("return out, ", govppApiPkg.Ident("RetvalToVPPApiError"), "(out.", retvalField.GoName, ")")
+ } else {
+ g.P("return out, ", govppApiPkg.Ident("RetvalToVPPApiError"), "(int32(out.", retvalField.GoName, "))")
+ }
+ } else {
+ g.P("return out, nil")
+ }
} else {
g.P("stream, err := c.conn.NewStream(ctx)")
g.P("if err != nil { return err }")
g.P("err = stream.SendMsg(in)")
g.P("if err != nil { return err }")
+ g.P("err = stream.Close()")
+ g.P("if err != nil { return err }")
g.P("return nil")
}
g.P("}")
diff --git a/binapigen/generate.go b/binapigen/generate.go
index 679dd54..2be33d1 100644
--- a/binapigen/generate.go
+++ b/binapigen/generate.go
@@ -21,15 +21,15 @@ import (
"strconv"
"strings"
- "git.fd.io/govpp.git/internal/version"
+ "go.fd.io/govpp/version"
)
// library dependencies
const (
strconvPkg = GoImportPath("strconv")
- govppApiPkg = GoImportPath("git.fd.io/govpp.git/api")
- govppCodecPkg = GoImportPath("git.fd.io/govpp.git/codec")
+ govppApiPkg = GoImportPath("go.fd.io/govpp/api")
+ govppCodecPkg = GoImportPath("go.fd.io/govpp/codec")
)
// generated names
@@ -41,6 +41,19 @@ const (
fieldUnionData = "XXX_UnionData" // name for the union data field
)
+// option keys
+const (
+ msgStatus = "status"
+ msgDeprecated = "deprecated"
+ msgInProgress = "in_progress"
+)
+
+// generated option messages
+const (
+ deprecatedMsg = "the message will be removed in the future versions"
+ inProgressMsg = "the message form may change in the future versions"
+)
+
func GenerateAPI(gen *Generator, file *File) *GenFile {
logf("----------------------------")
logf(" Generate API - %s", file.Desc.Name)
@@ -55,7 +68,9 @@ func GenerateAPI(gen *Generator, file *File) *GenFile {
g.P("// versions:")
g.P("// binapi-generator: ", version.Version())
g.P("// VPP: ", g.gen.vppVersion)
- g.P("// source: ", g.file.Desc.Path)
+ if !gen.opts.NoSourcePathInfo {
+ g.P("// source: ", g.file.Desc.Path)
+ }
}
g.P()
@@ -75,14 +90,12 @@ func GenerateAPI(gen *Generator, file *File) *GenFile {
g.P("const _ = ", govppApiPkg.Ident("GoVppAPIPackageIsVersion"), generatedCodeVersion)
g.P()
- if !file.isTypesFile() {
- g.P("const (")
- g.P(apiName, " = ", strconv.Quote(g.file.Desc.Name))
- g.P(apiVersion, " = ", strconv.Quote(g.file.Version))
- g.P(apiCrc, " = ", g.file.Desc.CRC)
- g.P(")")
- g.P()
- }
+ g.P("const (")
+ g.P(apiName, " = ", strconv.Quote(g.file.Desc.Name))
+ g.P(apiVersion, " = ", strconv.Quote(g.file.Version))
+ g.P(apiCrc, " = ", g.file.Desc.CRC)
+ g.P(")")
+ g.P()
for _, enum := range g.file.Enums {
genEnum(g, enum)
@@ -143,6 +156,23 @@ func genTypeComment(g *GenFile, goName string, vppName string, objKind string) {
g.P("// ", goName, " defines ", objKind, " '", vppName, "'.")
}
+func genTypeOptionComment(g *GenFile, options map[string]string) {
+ // all messages for API versions < 1.0.0 are in_progress by default
+ if msg, ok := options[msgInProgress]; ok || options[msgStatus] == msgInProgress ||
+ len(g.file.Version) > 1 && g.file.Version[0:2] == "0." {
+ if msg == "" {
+ msg = inProgressMsg
+ }
+ g.P("// InProgress: ", msg)
+ }
+ if msg, ok := options[msgDeprecated]; ok || options[msgStatus] == msgDeprecated {
+ if msg == "" {
+ msg = deprecatedMsg
+ }
+ g.P("// Deprecated: ", msg)
+ }
+}
+
func genEnum(g *GenFile, enum *Enum) {
logf("gen ENUM %s (%s) - %d entries", enum.GoName, enum.Name, len(enum.Entries))
@@ -176,7 +206,7 @@ func genEnum(g *GenFile, enum *Enum) {
g.P(")")
g.P()
- if isEnumFlag(enum) {
+ if enum.IsFlag || isEnumFlag(enum) {
size := BaseTypeSizes[enum.Type] * 8
g.P("func (x ", enum.GoName, ") String() string {")
g.P(" s, ok := ", enum.GoName, "_name[", gotype, "(x)]")
@@ -244,6 +274,8 @@ func genAlias(g *GenFile, alias *Alias) {
genAddressWithPrefixConversion(g, alias.GoName)
case "mac_address":
genMacAddressConversion(g, alias.GoName)
+ case "timestamp":
+ genTimestampConversion(g, alias.GoName)
}
}
@@ -283,8 +315,10 @@ func genUnion(g *GenFile, union *Union) {
g.P("type ", union.GoName, " struct {")
+ // generate field comments
+ g.P("// ", union.GoName, " can be one of:")
for _, field := range union.Fields {
- g.P("// ", field.GoName, " *", getFieldType(g, field))
+ g.P("// - ", field.GoName, " *", getFieldType(g, field))
}
// generate data field
@@ -297,22 +331,23 @@ func genUnion(g *GenFile, union *Union) {
// generate methods for fields
for _, field := range union.Fields {
- genUnionFieldMethods(g, union.GoName, field)
+ genUnionField(g, union, field)
}
g.P()
}
-func genUnionFieldMethods(g *GenFile, structName string, field *Field) {
- getterStruct := fieldGoType(g, field)
+func genUnionField(g *GenFile, union *Union, field *Field) {
+ fieldType := fieldGoType(g, field)
+ constructorName := union.GoName + field.GoName
// Constructor
- g.P("func ", structName, field.GoName, "(a ", getterStruct, ") (u ", structName, ") {")
+ g.P("func ", constructorName, "(a ", fieldType, ") (u ", union.GoName, ") {")
g.P(" u.Set", field.GoName, "(a)")
g.P(" return")
g.P("}")
// Setter
- g.P("func (u *", structName, ") Set", field.GoName, "(a ", getterStruct, ") {")
+ g.P("func (u *", union.GoName, ") Set", field.GoName, "(a ", fieldType, ") {")
g.P(" buf := ", govppCodecPkg.Ident("NewBuffer"), "(u.", fieldUnionData, "[:])")
encodeField(g, field, "a", func(name string) string {
return "a." + name
@@ -320,16 +355,24 @@ func genUnionFieldMethods(g *GenFile, structName string, field *Field) {
g.P("}")
// Getter
- g.P("func (u *", structName, ") Get", field.GoName, "() (a ", getterStruct, ") {")
+ g.P("func (u *", union.GoName, ") Get", field.GoName, "() (a ", fieldType, ") {")
g.P(" buf := ", govppCodecPkg.Ident("NewBuffer"), "(u.", fieldUnionData, "[:])")
decodeField(g, field, "a", func(name string) string {
return "a." + name
}, 0)
g.P(" return")
g.P("}")
+
g.P()
}
+func withSuffix(s string, suffix string) string {
+ if strings.HasSuffix(s, suffix) {
+ return s
+ }
+ return s + suffix
+}
+
func genField(g *GenFile, fields []*Field, i int) {
field := fields[i]
@@ -438,6 +481,7 @@ func genMessage(g *GenFile, msg *Message) {
logf("gen MESSAGE %s (%s) - %d fields", msg.GoName, msg.Name, len(msg.Fields))
genTypeComment(g, msg.GoIdent.GoName, msg.Name, "message")
+ genTypeOptionComment(g, msg.Options)
// generate message definition
if len(msg.Fields) == 0 {
diff --git a/binapigen/generate_test.go b/binapigen/generate_test.go
index 2fa5dc6..2a94636 100644
--- a/binapigen/generate_test.go
+++ b/binapigen/generate_test.go
@@ -20,8 +20,8 @@ import (
. "github.com/onsi/gomega"
- "git.fd.io/govpp.git/binapi/ip_types"
- "git.fd.io/govpp.git/binapigen/vppapi"
+ "go.fd.io/govpp/binapi/ip_types"
+ "go.fd.io/govpp/binapigen/vppapi"
)
const testOutputDir = "test_output_dir"
@@ -47,7 +47,7 @@ func GenerateFromFile(file string, opts Options) error {
return nil
}
-func TestGenerateFromFile(t *testing.T) {
+func TestGenerateFromFileACL(t *testing.T) {
RegisterTestingT(t)
// remove directory created during test
@@ -62,6 +62,21 @@ func TestGenerateFromFile(t *testing.T) {
Expect(fileInfo.Name()).To(BeEquivalentTo("acl.ba.go"))
}
+func TestGenerateFromFileIP(t *testing.T) {
+ RegisterTestingT(t)
+
+ // remove directory created during test
+ defer os.RemoveAll(testOutputDir)
+
+ opts := Options{OutputDir: testOutputDir}
+ err := GenerateFromFile("vppapi/testdata/ip.api.json", opts)
+ Expect(err).ShouldNot(HaveOccurred())
+ fileInfo, err := os.Stat(testOutputDir + "/ip/ip.ba.go")
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(fileInfo.IsDir()).To(BeFalse())
+ Expect(fileInfo.Name()).To(BeEquivalentTo("ip.ba.go"))
+}
+
func TestGenerateFromFileInputError(t *testing.T) {
RegisterTestingT(t)
diff --git a/binapigen/generator.go b/binapigen/generator.go
index ce0954a..009c0ec 100644
--- a/binapigen/generator.go
+++ b/binapigen/generator.go
@@ -32,12 +32,13 @@ import (
"github.com/sirupsen/logrus"
- "git.fd.io/govpp.git/binapigen/vppapi"
+ "go.fd.io/govpp/binapigen/vppapi"
)
type Generator struct {
Files []*File
FilesByName map[string]*File
+ FilesByPath map[string]*File
opts Options
apifiles []*vppapi.File
@@ -53,11 +54,12 @@ type Generator struct {
messagesByName map[string]*Message
}
-func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator, error) {
+func New(opts Options, apiFiles []*vppapi.File, filesToGen []string) (*Generator, error) {
gen := &Generator{
FilesByName: make(map[string]*File),
+ FilesByPath: make(map[string]*File),
opts: opts,
- apifiles: apifiles,
+ apifiles: apiFiles,
filesToGen: filesToGen,
enumsByName: map[string]*Enum{},
aliasesByName: map[string]*Alias{},
@@ -68,9 +70,9 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator
// Normalize API files
SortFilesByImports(gen.apifiles)
- for _, apifile := range apifiles {
- RemoveImportedTypes(gen.apifiles, apifile)
- SortFileObjectsByName(apifile)
+ for _, apiFile := range apiFiles {
+ RemoveImportedTypes(gen.apifiles, apiFile)
+ SortFileObjectsByName(apiFile)
}
// prepare package names and import paths
@@ -96,6 +98,7 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator
}
gen.Files = append(gen.Files, file)
gen.FilesByName[apifile.Name] = file
+ gen.FilesByPath[apifile.Path] = file
logrus.Debugf("added file %q (path: %v)", apifile.Name, apifile.Path)
}
@@ -103,16 +106,24 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator
// mark files for generation
if len(gen.filesToGen) > 0 {
logrus.Debugf("Checking %d files to generate: %v", len(gen.filesToGen), gen.filesToGen)
- for _, genfile := range gen.filesToGen {
- file, ok := gen.FilesByName[genfile]
- if !ok {
- return nil, fmt.Errorf("nol API file found for: %v", genfile)
+ for _, genFile := range gen.filesToGen {
+ markGen := func(file *File) {
+ file.Generate = true
+ // generate all imported files
+ for _, impFile := range file.importedFiles(gen) {
+ impFile.Generate = true
+ }
}
- file.Generate = true
- // generate all imported files
- for _, impFile := range file.importedFiles(gen) {
- impFile.Generate = true
+ if file, ok := gen.FilesByName[genFile]; ok {
+ markGen(file)
+ continue
+ }
+ logrus.Debugf("File %s was not found by name", genFile)
+ if file, ok := gen.FilesByPath[genFile]; ok {
+ markGen(file)
+ continue
}
+ return nil, fmt.Errorf("no API file found for: %v", genFile)
}
} else {
logrus.Debugf("Files to generate not specified, marking all %d files for generate", len(gen.Files))
@@ -212,6 +223,13 @@ func (g *GenFile) Content() ([]byte, error) {
return g.injectImports(g.buf.Bytes())
}
+func getImportClass(importPath string) int {
+ if !strings.Contains(importPath, ".") {
+ return 0 /* std */
+ }
+ return 1 /* External */
+}
+
// injectImports parses source, injects import block declaration with all imports and return formatted
func (g *GenFile) injectImports(original []byte) ([]byte, error) {
// Parse source code
@@ -233,7 +251,7 @@ func (g *GenFile) injectImports(original []byte) ([]byte, error) {
var importPaths []Import
for importPath := range g.packageNames {
importPaths = append(importPaths, Import{
- Name: string(g.packageNames[GoImportPath(importPath)]),
+ Name: string(g.packageNames[importPath]),
Path: string(importPath),
})
}
@@ -248,7 +266,12 @@ func (g *GenFile) injectImports(original []byte) ([]byte, error) {
}
// Sort imports by import path
sort.Slice(importPaths, func(i, j int) bool {
- return importPaths[i].Path < importPaths[j].Path
+ ci := getImportClass(importPaths[i].Path)
+ cj := getImportClass(importPaths[j].Path)
+ if ci == cj {
+ return importPaths[i].Path < importPaths[j].Path
+ }
+ return ci < cj
})
// Inject new import block into parsed AST
if len(importPaths) > 0 {
@@ -264,14 +287,20 @@ func (g *GenFile) injectImports(original []byte) ([]byte, error) {
}
// Prepare the import block
impDecl := &ast.GenDecl{Tok: token.IMPORT, TokPos: pos, Lparen: pos, Rparen: pos}
- for _, importPath := range importPaths {
+ for i, importPath := range importPaths {
var name *ast.Ident
if importPath.Name == "_" || strings.Contains(importPath.Path, ".") {
name = &ast.Ident{Name: importPath.Name, NamePos: pos}
}
+ value := strconv.Quote(importPath.Path)
+ if i < len(importPaths)-1 {
+ if getImportClass(importPath.Path) != getImportClass(importPaths[i+1].Path) {
+ value += "\n"
+ }
+ }
impDecl.Specs = append(impDecl.Specs, &ast.ImportSpec{
Name: name,
- Path: &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(importPath.Path), ValuePos: pos},
+ Path: &ast.BasicLit{Kind: token.STRING, Value: value, ValuePos: pos},
EndPos: pos,
})
}
diff --git a/binapigen/generator_test.go b/binapigen/generator_test.go
index 1dfaca4..8c2046d 100644
--- a/binapigen/generator_test.go
+++ b/binapigen/generator_test.go
@@ -15,11 +15,17 @@
package binapigen
import (
+ "bufio"
+ "fmt"
+ "go.fd.io/govpp/binapigen/vppapi"
+ . "github.com/onsi/gomega"
+ "os"
+ "strings"
"testing"
)
func TestGoModule(t *testing.T) {
- const expected = "git.fd.io/govpp.git/binapi"
+ const expected = "go.fd.io/govpp/binapi"
impPath, err := resolveImportPath("../binapi")
if err != nil {
@@ -45,10 +51,94 @@ func TestBinapiTypeSizes(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- size := getSizeOfBinapiTypeLength(test.input, 1)
+ size := getSizeOfBinapiBaseType(test.input, 1)
if size != test.expsize {
t.Errorf("expected %d, got %d", test.expsize, size)
}
})
}
}
+
+func TestBinapiUnionSizes(t *testing.T) {
+ RegisterTestingT(t)
+
+ // order of the union sizes in file generated from union.api.json
+ var sizes = []int{16, 4, 32, 16, 64, 111}
+
+ // remove directory created during test
+ defer func() {
+ err := os.RemoveAll(testOutputDir)
+ Expect(err).ToNot(HaveOccurred())
+ }()
+
+ err := GenerateFromFile("vppapi/testdata/union.api.json", Options{OutputDir: testOutputDir})
+ Expect(err).ShouldNot(HaveOccurred())
+
+ file, err := os.Open(testOutputDir + "/union/union.ba.go")
+ Expect(err).ShouldNot(HaveOccurred())
+ defer func() {
+ err := file.Close()
+ Expect(err).ToNot(HaveOccurred())
+ }()
+
+ // the generated line with union size is in format XXX_UnionData [<size>]byte
+ // the prefix identifies these lines (the starting tab is important)
+ prefix := fmt.Sprintf("\t%s", "XXX_UnionData [")
+
+ index := 0
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ if strings.HasPrefix(scanner.Text(), prefix) {
+ Expect(scanner.Text()).To(Equal(prefix + fmt.Sprintf("%d]byte", sizes[index])))
+ index++
+ }
+ }
+ // ensure all union sizes were found and tested
+ Expect(index).To(Equal(len(sizes)))
+}
+
+// Typed data used for union size evaluation testing.
+type typeTestData struct {
+ typ string
+ value string
+ fields []*typeTestData
+}
+
+func (t typeTestData) getUnion(name string) *Union {
+ return &Union{
+ UnionType: vppapi.UnionType{Name: name},
+ Fields: t.getUnionFields(name),
+ }
+}
+
+func (t typeTestData) getUnionFields(parentName string) (fields []*Field) {
+ for i, field := range t.fields {
+ var (
+ dataType string
+ aliasType *Alias
+ enumType *Enum
+ structType *Struct
+ unionType *Union
+ )
+ switch field.typ {
+ case "alias":
+ aliasType = &Alias{AliasType: vppapi.AliasType{Name: fmt.Sprintf("%s_alias_%d", parentName, i), Type: field.value}}
+ case "enum":
+ enumType = &Enum{EnumType: vppapi.EnumType{Name: fmt.Sprintf("%s_enum_%d", parentName, i), Type: field.value}}
+ case "struct":
+ structType = &Struct{Fields: field.getUnionFields(fmt.Sprintf("%s_struct_%d", parentName, i))}
+ case "union":
+ unionType = field.getUnion(parentName)
+ default:
+ dataType = field.value
+ }
+ fields = append(fields, &Field{
+ Field: vppapi.Field{Name: fmt.Sprintf("%s_field_%d", parentName, i), Type: dataType},
+ TypeAlias: aliasType,
+ TypeEnum: enumType,
+ TypeStruct: structType,
+ TypeUnion: unionType,
+ })
+ }
+ return fields
+}
diff --git a/binapigen/run.go b/binapigen/run.go
index d3a181a..5a1059a 100644
--- a/binapigen/run.go
+++ b/binapigen/run.go
@@ -25,13 +25,14 @@ import (
"github.com/sirupsen/logrus"
- "git.fd.io/govpp.git/binapigen/vppapi"
+ "go.fd.io/govpp/binapigen/vppapi"
)
type Options struct {
- OutputDir string // output directory for generated files
- ImportPrefix string // prefix for import paths
- NoVersionInfo bool // disables generating version info
+ OutputDir string // output directory for generated files
+ ImportPrefix string // prefix for import paths
+ NoVersionInfo bool // disables generating version info
+ NoSourcePathInfo bool // disables the 'source: /path' comment
}
func Run(apiDir string, filesToGenerate []string, opts Options, f func(*Generator) error) {
@@ -42,7 +43,7 @@ func Run(apiDir string, filesToGenerate []string, opts Options, f func(*Generato
}
func run(apiDir string, filesToGenerate []string, opts Options, fn func(*Generator) error) error {
- apifiles, err := vppapi.ParseDir(apiDir)
+ apiFiles, err := vppapi.ParseDir(apiDir)
if err != nil {
return err
}
@@ -52,10 +53,10 @@ func run(apiDir string, filesToGenerate []string, opts Options, fn func(*Generat
if err != nil {
return fmt.Errorf("cannot resolve import path for output dir %s: %w", opts.OutputDir, err)
}
- logrus.Infof("resolved import path prefix: %s", opts.ImportPrefix)
+ logrus.Debugf("resolved import path prefix: %s", opts.ImportPrefix)
}
- gen, err := New(opts, apifiles, filesToGenerate)
+ gen, err := New(opts, apiFiles, filesToGenerate)
if err != nil {
return err
}
@@ -72,7 +73,6 @@ func run(apiDir string, filesToGenerate []string, opts Options, fn func(*Generat
return err
}
}
-
if err = gen.Generate(); err != nil {
return err
}
diff --git a/binapigen/types.go b/binapigen/types.go
index 1d0dae5..addb122 100644
--- a/binapigen/types.go
+++ b/binapigen/types.go
@@ -128,45 +128,59 @@ func getFieldType(g *GenFile, field *Field) string {
return gotype
}
-func getSizeOfBinapiTypeLength(typ string, length int) (size int) {
- if n := BaseTypeSizes[typ]; n > 0 {
- if length > 0 {
- return n * length
- } else {
- return n
+func getUnionSize(union *Union) (maxSize int) {
+ for _, field := range union.Fields {
+ if size, isBaseType := getSizeOfField(field); isBaseType {
+ logrus.Panicf("union %s field %s has unexpected type %q", union.Name, field.Name, field.Type)
+ } else if size > maxSize {
+ maxSize = size
}
}
+ //logf("getUnionSize: %s %+v max=%v", union.Name, union.Fields, maxSize)
return
}
-func getSizeOfType(typ *Struct) (size int) {
+func getSizeOfField(field *Field) (size int, isBaseType bool) {
+ if alias := field.TypeAlias; alias != nil {
+ size = getSizeOfBinapiBaseType(alias.Type, alias.Length)
+ return
+ }
+ if enum := field.TypeEnum; enum != nil {
+ size = getSizeOfBinapiBaseType(enum.Type, field.Length)
+ return
+ }
+ if structType := field.TypeStruct; structType != nil {
+ size = getSizeOfStruct(structType)
+ return
+ }
+ if union := field.TypeUnion; union != nil {
+ size = getUnionSize(union)
+ return
+ }
+ return size, true
+}
+
+func getSizeOfStruct(typ *Struct) (size int) {
for _, field := range typ.Fields {
- if enum := field.TypeEnum; enum != nil {
- size += getSizeOfBinapiTypeLength(enum.Type, field.Length)
+ fieldSize, isBaseType := getSizeOfField(field)
+ if isBaseType {
+ size += getSizeOfBinapiBaseType(field.Type, field.Length)
continue
}
- size += getSizeOfBinapiTypeLength(field.Type, field.Length)
+ size += fieldSize
}
return size
}
-func getUnionSize(union *Union) (maxSize int) {
- for _, field := range union.Fields {
- if typ := field.TypeStruct; typ != nil {
- if size := getSizeOfType(typ); size > maxSize {
- maxSize = size
- }
- continue
- }
- if alias := field.TypeAlias; alias != nil {
- if size := getSizeOfBinapiTypeLength(alias.Type, alias.Length); size > maxSize {
- maxSize = size
- }
- continue
+// Returns size of base type multiplied by length. Length equal to zero
+// returns base type size.
+func getSizeOfBinapiBaseType(typ string, length int) (size int) {
+ if n := BaseTypeSizes[typ]; n > 0 {
+ if length > 1 {
+ return n * length
} else {
- logrus.Panicf("no type or alias found for union %s field type %q", union.Name, field.Type)
+ return n
}
}
- //logf("getUnionSize: %s %+v max=%v", union.Name, union.Fields, maxSize)
return
}
diff --git a/binapigen/vppapi.go b/binapigen/vppapi.go
index 7388ad5..5e2db28 100644
--- a/binapigen/vppapi.go
+++ b/binapigen/vppapi.go
@@ -18,7 +18,7 @@ import (
"log"
"sort"
- "git.fd.io/govpp.git/binapigen/vppapi"
+ "go.fd.io/govpp/binapigen/vppapi"
)
func SortFileObjectsByName(file *vppapi.File) {
@@ -28,6 +28,9 @@ func SortFileObjectsByName(file *vppapi.File) {
sort.SliceStable(file.EnumTypes, func(i, j int) bool {
return file.EnumTypes[i].Name < file.EnumTypes[j].Name
})
+ sort.SliceStable(file.EnumflagTypes, func(i, j int) bool {
+ return file.EnumflagTypes[i].Name < file.EnumflagTypes[j].Name
+ })
sort.Slice(file.AliasTypes, func(i, j int) bool {
return file.AliasTypes[i].Name < file.AliasTypes[j].Name
})
@@ -151,6 +154,22 @@ func ListImportedTypes(apifiles []*vppapi.File, file *vppapi.File) []string {
}
}
}
+ for _, t := range file.EnumflagTypes {
+ var imported bool
+ for _, imp := range typeFiles {
+ for _, at := range imp.EnumflagTypes {
+ if at.Name != t.Name {
+ continue
+ }
+ importedTypes = append(importedTypes, t.Name)
+ imported = true
+ break
+ }
+ if imported {
+ break
+ }
+ }
+ }
for _, t := range file.UnionTypes {
var imported bool
for _, imp := range typeFiles {
@@ -186,6 +205,12 @@ func RemoveImportedTypes(apifiles []*vppapi.File, apifile *vppapi.File) {
enums = append(enums, enumType)
}
}
+ var enumflags []vppapi.EnumType
+ for _, enumflagType := range apifile.EnumflagTypes {
+ if !isImportedType(enumflagType.Name) {
+ enumflags = append(enumflags, enumflagType)
+ }
+ }
var aliases []vppapi.AliasType
for _, aliasType := range apifile.AliasTypes {
if !isImportedType(aliasType.Name) {
@@ -205,6 +230,7 @@ func RemoveImportedTypes(apifiles []*vppapi.File, apifile *vppapi.File) {
}
}
apifile.EnumTypes = enums
+ apifile.EnumflagTypes = enumflags
apifile.AliasTypes = aliases
apifile.StructTypes = structs
apifile.UnionTypes = unions
diff --git a/binapigen/vppapi/api_schema.go b/binapigen/vppapi/api_schema.go
index 7eceab3..4dd0ac9 100644
--- a/binapigen/vppapi/api_schema.go
+++ b/binapigen/vppapi/api_schema.go
@@ -24,10 +24,11 @@ type (
Options map[string]string `json:",omitempty"`
Imports []string `json:",omitempty"`
- AliasTypes []AliasType `json:",omitempty"`
- EnumTypes []EnumType `json:",omitempty"`
- StructTypes []StructType `json:",omitempty"`
- UnionTypes []UnionType `json:",omitempty"`
+ AliasTypes []AliasType `json:",omitempty"`
+ EnumTypes []EnumType `json:",omitempty"`
+ EnumflagTypes []EnumType `json:",omitempty"`
+ StructTypes []StructType `json:",omitempty"`
+ UnionTypes []UnionType `json:",omitempty"`
Messages []Message `json:",omitempty"`
Service *Service `json:",omitempty"`
@@ -61,9 +62,10 @@ type (
}
Message struct {
- Name string
- Fields []Field
- CRC string
+ Name string
+ Fields []Field
+ CRC string
+ Options map[string]string
}
Field struct {
diff --git a/binapigen/vppapi/integration_test.go b/binapigen/vppapi/integration_test.go
index 9d619b8..c3df45c 100644
--- a/binapigen/vppapi/integration_test.go
+++ b/binapigen/vppapi/integration_test.go
@@ -20,7 +20,7 @@ import (
"encoding/json"
"testing"
- "git.fd.io/govpp.git/binapigen/vppapi"
+ "go.fd.io/govpp/binapigen/vppapi"
)
func TestParse(t *testing.T) {
diff --git a/binapigen/vppapi/parse_json.go b/binapigen/vppapi/parse_json.go
index d14865c..ed7bcad 100644
--- a/binapigen/vppapi/parse_json.go
+++ b/binapigen/vppapi/parse_json.go
@@ -41,14 +41,16 @@ const (
fileMessages = "messages"
fileUnions = "unions"
fileEnums = "enums"
+ fileEnumflags = "enumflags"
fileAliases = "aliases"
fileServices = "services"
fileImports = "imports"
// type keys
- messageCrc = "crc"
- enumType = "enumtype"
- aliasLength = "length"
- aliasType = "type"
+ messageCrc = "crc"
+ messageOptions = "options"
+ enumType = "enumtype"
+ aliasLength = "length"
+ aliasType = "type"
// service
serviceReply = "reply"
serviceStream = "stream"
@@ -129,6 +131,20 @@ func parseJSON(data []byte) (module *File, err error) {
module.EnumTypes = append(module.EnumTypes, *enum)
}
+ // parse enumflags types
+ enumflagsNode := jsonRoot.Map(fileEnumflags)
+ module.EnumflagTypes = make([]EnumType, 0)
+ for i := 0; i < enumflagsNode.Len(); i++ {
+ enumflag, err := parseEnum(enumflagsNode.At(i))
+ if err != nil {
+ return nil, err
+ }
+ if exists(enumflag.Name) {
+ continue
+ }
+ module.EnumflagTypes = append(module.EnumflagTypes, *enumflag)
+ }
+
// parse alias types
aliasesNode := jsonRoot.Map(fileAliases)
if aliasesNode.GetType() == jsongo.TypeMap {
@@ -360,10 +376,30 @@ func parseMessage(msgNode *jsongo.Node) (*Message, error) {
if !ok {
return nil, fmt.Errorf("message crc invalid or missing")
}
+ var msgOpts map[string]string
+ msgOptsNode := msgNode.At(msgNode.Len() - 1).Map(messageOptions)
+ if msgOptsNode.GetType() == jsongo.TypeMap {
+ msgOpts = make(map[string]string)
+ for _, opt := range msgOptsNode.GetKeys() {
+ if _, ok := opt.(string); !ok {
+ logf("invalid message option key, expected string")
+ continue
+ }
+ msgOpts[opt.(string)] = ""
+ if msgOptsNode.At(opt).Get() != nil {
+ if optMsgStr, ok := msgOptsNode.At(opt).Get().(string); ok {
+ msgOpts[opt.(string)] = optMsgStr
+ } else {
+ logf("invalid message option value, expected string")
+ }
+ }
+ }
+ }
msg := Message{
- Name: msgName,
- CRC: msgCRC,
+ Name: msgName,
+ CRC: msgCRC,
+ Options: msgOpts,
}
// loop through message fields, skip first (name) and last (crc)
diff --git a/binapigen/vppapi/testdata/ip.api.json b/binapigen/vppapi/testdata/ip.api.json
index 530b6d6..32be996 100644
--- a/binapigen/vppapi/testdata/ip.api.json
+++ b/binapigen/vppapi/testdata/ip.api.json
@@ -1,633 +1,594 @@
{
- "services": [
- {
- "ip_source_and_port_range_check_add_del": {
- "reply": "ip_source_and_port_range_check_add_del_reply"
- }
- },
- {
- "ip6_fib_dump": {
- "reply": "ip6_fib_details",
- "stream": true
- }
- },
- {
- "want_ip6_nd_events": {
- "reply": "want_ip6_nd_events_reply"
- }
- },
- {
- "ip_punt_police": {
- "reply": "ip_punt_police_reply"
- }
- },
- {
- "set_arp_neighbor_limit": {
- "reply": "set_arp_neighbor_limit_reply"
- }
- },
- {
- "ip6nd_proxy_add_del": {
- "reply": "ip6nd_proxy_add_del_reply"
- }
- },
- {
- "ioam_disable": {
- "reply": "ioam_disable_reply"
- }
- },
- {
- "ip_table_add_del": {
- "reply": "ip_table_add_del_reply"
- }
- },
- {
- "ip_neighbor_dump": {
- "reply": "ip_neighbor_details",
- "stream": true
- }
- },
- {
- "ip4_arp_event": {
- "reply": null
- }
- },
- {
- "ip_punt_redirect": {
- "reply": "ip_punt_redirect_reply"
- }
- },
- {
- "sw_interface_ip6nd_ra_prefix": {
- "reply": "sw_interface_ip6nd_ra_prefix_reply"
- }
- },
- {
- "reset_fib": {
- "reply": "reset_fib_reply"
- }
- },
- {
- "ip6_mfib_dump": {
- "reply": "ip6_mfib_details",
- "stream": true
- }
- },
- {
- "sw_interface_ip6nd_ra_config": {
- "reply": "sw_interface_ip6nd_ra_config_reply"
- }
- },
- {
- "sw_interface_ip6_enable_disable": {
- "reply": "sw_interface_ip6_enable_disable_reply"
- }
- },
- {
- "sw_interface_ip6_set_link_local_address": {
- "reply": "sw_interface_ip6_set_link_local_address_reply"
- }
- },
- {
- "mfib_signal_dump": {
- "reply": "mfib_signal_details",
- "stream": true
- }
- },
- {
- "ip_container_proxy_add_del": {
- "reply": "ip_container_proxy_add_del_reply"
- }
- },
- {
- "ip_mfib_dump": {
- "reply": "ip_mfib_details",
- "stream": true
- }
- },
- {
- "ip_address_dump": {
- "reply": "ip_address_details",
- "stream": true
- }
- },
- {
- "ip_dump": {
- "reply": "ip_details",
- "stream": true
- }
- },
- {
- "ip_neighbor_add_del": {
- "reply": "ip_neighbor_add_del_reply"
- }
- },
- {
- "proxy_arp_intfc_enable_disable": {
- "reply": "proxy_arp_intfc_enable_disable_reply"
- }
- },
- {
- "proxy_arp_add_del": {
- "reply": "proxy_arp_add_del_reply"
- }
- },
- {
- "ip_add_del_route": {
- "reply": "ip_add_del_route_reply"
- }
- },
- {
- "ip6nd_proxy_dump": {
- "reply": "ip6nd_proxy_details",
- "stream": true
- }
- },
- {
- "ip_fib_dump": {
- "reply": "ip_fib_details",
- "stream": true
- }
- },
- {
- "want_ip4_arp_events": {
- "reply": "want_ip4_arp_events_reply"
- }
- },
- {
- "ioam_enable": {
- "reply": "ioam_enable_reply"
- }
- },
- {
- "ip6_nd_event": {
- "reply": null
- }
- },
- {
- "ip_mroute_add_del": {
- "reply": "ip_mroute_add_del_reply"
- }
- },
- {
- "ip_source_and_port_range_check_interface_add_del": {
- "reply": "ip_source_and_port_range_check_interface_add_del_reply"
- }
- },
- {
- "set_ip_flow_hash": {
- "reply": "set_ip_flow_hash_reply"
- }
- }
- ],
- "vl_api_version": "0xb395c625",
- "enums": [],
- "messages": [
+ "types": [
[
- "ip_table_add_del",
+ "address",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_address_family_t",
+ "af"
],
[
- "u32",
- "client_index"
- ],
- [
- "u32",
- "context"
- ],
+ "vl_api_address_union_t",
+ "un"
+ ]
+ ],
+ [
+ "prefix",
[
- "u32",
- "table_id"
+ "vl_api_address_t",
+ "address"
],
[
"u8",
- "is_ipv6"
- ],
+ "len"
+ ]
+ ],
+ [
+ "ip4_address_and_mask",
[
- "u8",
- "is_add"
+ "vl_api_ip4_address_t",
+ "addr"
],
[
- "u8",
- "name",
- 64
- ],
- {
- "crc": "0x0240c89d"
- }
+ "vl_api_ip4_address_t",
+ "mask"
+ ]
],
[
- "ip_table_add_del_reply",
+ "ip6_address_and_mask",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_ip6_address_t",
+ "addr"
],
[
- "u32",
- "context"
- ],
- [
- "i32",
- "retval"
- ],
- {
- "crc": "0xe8d4e804"
- }
+ "vl_api_ip6_address_t",
+ "mask"
+ ]
],
[
- "ip_fib_dump",
+ "mprefix",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_address_family_t",
+ "af"
],
[
- "u32",
- "client_index"
+ "u16",
+ "grp_address_length"
],
[
- "u32",
- "context"
+ "vl_api_address_union_t",
+ "grp_address"
],
- {
- "crc": "0x51077d14"
- }
+ [
+ "vl_api_address_union_t",
+ "src_address"
+ ]
],
[
- "ip_fib_details",
+ "ip6_prefix",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_ip6_address_t",
+ "address"
],
[
- "u32",
- "context"
- ],
+ "u8",
+ "len"
+ ]
+ ],
+ [
+ "ip4_prefix",
[
- "u32",
- "table_id"
+ "vl_api_ip4_address_t",
+ "address"
],
[
"u8",
- "table_name",
- 64
- ],
+ "len"
+ ]
+ ],
+ [
+ "prefix_matcher",
[
"u8",
- "address_length"
+ "le"
],
[
"u8",
- "address",
- 4
+ "ge"
+ ]
+ ],
+ [
+ "fib_mpls_label",
+ [
+ "u8",
+ "is_uniform"
],
[
"u32",
- "count"
+ "label"
],
[
- "vl_api_fib_path_t",
- "path",
- 0,
- "count"
+ "u8",
+ "ttl"
],
- {
- "crc": "0x99dfd73b"
- }
+ [
+ "u8",
+ "exp"
+ ]
],
[
- "ip6_fib_dump",
+ "fib_path_nh",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_address_union_t",
+ "address"
],
[
"u32",
- "client_index"
+ "via_label"
],
[
"u32",
- "context"
+ "obj_id"
],
- {
- "crc": "0x51077d14"
- }
+ [
+ "u32",
+ "classify_table_index"
+ ]
],
[
- "ip6_fib_details",
+ "fib_path",
[
- "u16",
- "_vl_msg_id"
+ "u32",
+ "sw_if_index"
],
[
"u32",
- "context"
+ "table_id"
],
[
"u32",
- "table_id"
+ "rpf_id"
],
[
"u8",
- "table_name",
- 64
+ "weight"
],
[
"u8",
- "address_length"
+ "preference"
],
[
- "u8",
- "address",
- 16
+ "vl_api_fib_path_type_t",
+ "type"
],
[
- "u32",
- "count"
+ "vl_api_fib_path_flags_t",
+ "flags"
],
[
- "vl_api_fib_path_t",
- "path",
- 0,
- "count"
+ "vl_api_fib_path_nh_proto_t",
+ "proto"
],
- {
- "crc": "0xabd0060e"
- }
- ],
- [
- "ip_neighbor_dump",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_fib_path_nh_t",
+ "nh"
],
[
- "u32",
- "client_index"
+ "u8",
+ "n_labels"
],
[
- "u32",
- "context"
+ "vl_api_fib_mpls_label_t",
+ "label_stack",
+ 16
+ ]
+ ],
+ [
+ "address",
+ [
+ "vl_api_address_family_t",
+ "af"
],
[
- "u32",
- "sw_if_index"
+ "vl_api_address_union_t",
+ "un"
+ ]
+ ],
+ [
+ "prefix",
+ [
+ "vl_api_address_t",
+ "address"
],
[
"u8",
- "is_ipv6"
+ "len"
+ ]
+ ],
+ [
+ "ip4_address_and_mask",
+ [
+ "vl_api_ip4_address_t",
+ "addr"
],
- {
- "crc": "0x6b7bcd0a"
- }
+ [
+ "vl_api_ip4_address_t",
+ "mask"
+ ]
],
[
- "ip_neighbor_details",
+ "ip6_address_and_mask",
+ [
+ "vl_api_ip6_address_t",
+ "addr"
+ ],
+ [
+ "vl_api_ip6_address_t",
+ "mask"
+ ]
+ ],
+ [
+ "mprefix",
+ [
+ "vl_api_address_family_t",
+ "af"
+ ],
[
"u16",
- "_vl_msg_id"
+ "grp_address_length"
],
[
- "u32",
- "context"
+ "vl_api_address_union_t",
+ "grp_address"
],
[
- "u32",
- "sw_if_index"
+ "vl_api_address_union_t",
+ "src_address"
+ ]
+ ],
+ [
+ "ip6_prefix",
+ [
+ "vl_api_ip6_address_t",
+ "address"
],
[
"u8",
- "is_static"
+ "len"
+ ]
+ ],
+ [
+ "ip4_prefix",
+ [
+ "vl_api_ip4_address_t",
+ "address"
],
[
"u8",
- "is_ipv6"
+ "len"
+ ]
+ ],
+ [
+ "prefix_matcher",
+ [
+ "u8",
+ "le"
],
[
"u8",
- "mac_address",
- 6
+ "ge"
+ ]
+ ],
+ [
+ "fib_mpls_label",
+ [
+ "u8",
+ "is_uniform"
+ ],
+ [
+ "u32",
+ "label"
],
[
"u8",
- "ip_address",
- 16
+ "ttl"
],
- {
- "crc": "0x85e32a72"
- }
+ [
+ "u8",
+ "exp"
+ ]
],
[
- "ip_neighbor_add_del",
+ "fib_path_nh",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_address_union_t",
+ "address"
],
[
"u32",
- "client_index"
+ "via_label"
],
[
"u32",
- "context"
+ "obj_id"
],
[
"u32",
+ "classify_table_index"
+ ]
+ ],
+ [
+ "fib_path",
+ [
+ "u32",
"sw_if_index"
],
[
- "u8",
- "is_add"
+ "u32",
+ "table_id"
],
[
- "u8",
- "is_ipv6"
+ "u32",
+ "rpf_id"
],
[
"u8",
- "is_static"
+ "weight"
],
[
"u8",
- "is_no_adj_fib"
+ "preference"
],
[
- "u8",
- "mac_address",
- 6
+ "vl_api_fib_path_type_t",
+ "type"
+ ],
+ [
+ "vl_api_fib_path_flags_t",
+ "flags"
+ ],
+ [
+ "vl_api_fib_path_nh_proto_t",
+ "proto"
+ ],
+ [
+ "vl_api_fib_path_nh_t",
+ "nh"
],
[
"u8",
- "dst_address",
- 16
+ "n_labels"
],
- {
- "crc": "0x4711eb25"
- }
+ [
+ "vl_api_fib_mpls_label_t",
+ "label_stack",
+ 16
+ ]
],
[
- "ip_neighbor_add_del_reply",
+ "address",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_address_family_t",
+ "af"
],
[
- "u32",
- "context"
- ],
+ "vl_api_address_union_t",
+ "un"
+ ]
+ ],
+ [
+ "prefix",
[
- "i32",
- "retval"
+ "vl_api_address_t",
+ "address"
],
- {
- "crc": "0xe8d4e804"
- }
+ [
+ "u8",
+ "len"
+ ]
],
[
- "set_ip_flow_hash",
+ "ip4_address_and_mask",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_ip4_address_t",
+ "addr"
],
[
- "u32",
- "client_index"
- ],
+ "vl_api_ip4_address_t",
+ "mask"
+ ]
+ ],
+ [
+ "ip6_address_and_mask",
[
- "u32",
- "context"
+ "vl_api_ip6_address_t",
+ "addr"
],
[
- "u32",
- "vrf_id"
+ "vl_api_ip6_address_t",
+ "mask"
+ ]
+ ],
+ [
+ "mprefix",
+ [
+ "vl_api_address_family_t",
+ "af"
],
[
- "u8",
- "is_ipv6"
+ "u16",
+ "grp_address_length"
],
[
- "u8",
- "src"
+ "vl_api_address_union_t",
+ "grp_address"
],
[
- "u8",
- "dst"
+ "vl_api_address_union_t",
+ "src_address"
+ ]
+ ],
+ [
+ "ip6_prefix",
+ [
+ "vl_api_ip6_address_t",
+ "address"
],
[
"u8",
- "sport"
+ "len"
+ ]
+ ],
+ [
+ "ip4_prefix",
+ [
+ "vl_api_ip4_address_t",
+ "address"
],
[
"u8",
- "dport"
- ],
+ "len"
+ ]
+ ],
+ [
+ "prefix_matcher",
[
"u8",
- "proto"
+ "le"
],
[
"u8",
- "reverse"
- ],
- {
- "crc": "0x32ebf737"
- }
+ "ge"
+ ]
],
[
- "set_ip_flow_hash_reply",
+ "mfib_path",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_mfib_itf_flags_t",
+ "itf_flags"
],
[
+ "vl_api_fib_path_t",
+ "path"
+ ]
+ ],
+ [
+ "ip_table",
+ [
"u32",
- "context"
+ "table_id"
],
[
- "i32",
- "retval"
+ "bool",
+ "is_ip6"
],
- {
- "crc": "0xe8d4e804"
- }
+ [
+ "string",
+ "name",
+ 64
+ ]
],
[
- "sw_interface_ip6nd_ra_config",
- [
- "u16",
- "_vl_msg_id"
- ],
+ "ip_route",
[
"u32",
- "client_index"
+ "table_id"
],
[
"u32",
- "context"
+ "stats_index"
],
[
- "u32",
- "sw_if_index"
+ "vl_api_prefix_t",
+ "prefix"
],
[
"u8",
- "suppress"
+ "n_paths"
],
[
- "u8",
- "managed"
+ "vl_api_fib_path_t",
+ "paths",
+ 0,
+ "n_paths"
+ ]
+ ],
+ [
+ "ip_mroute",
+ [
+ "u32",
+ "table_id"
],
[
- "u8",
- "other"
+ "vl_api_mfib_entry_flags_t",
+ "entry_flags"
],
[
- "u8",
- "ll_option"
+ "u32",
+ "rpf_id"
],
[
- "u8",
- "send_unicast"
+ "vl_api_mprefix_t",
+ "prefix"
],
[
"u8",
- "cease"
+ "n_paths"
],
[
- "u8",
- "is_no"
+ "vl_api_mfib_path_t",
+ "paths",
+ 0,
+ "n_paths"
+ ]
+ ],
+ [
+ "punt_redirect",
+ [
+ "vl_api_interface_index_t",
+ "rx_sw_if_index"
],
[
- "u8",
- "default_router"
+ "vl_api_interface_index_t",
+ "tx_sw_if_index"
],
[
- "u32",
- "max_interval"
+ "vl_api_address_t",
+ "nh"
+ ]
+ ]
+ ],
+ "messages": [
+ [
+ "ip_table_add_del",
+ [
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
- "min_interval"
+ "client_index"
],
[
"u32",
- "lifetime"
+ "context"
],
[
- "u32",
- "initial_count"
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
],
[
- "u32",
- "initial_interval"
+ "vl_api_ip_table_t",
+ "table"
],
{
- "crc": "0xc3f02daa"
+ "crc": "0x0ffdaec0"
}
],
[
- "sw_interface_ip6nd_ra_config_reply",
+ "ip_table_add_del_reply",
[
"u16",
"_vl_msg_id"
@@ -645,7 +606,7 @@
}
],
[
- "sw_interface_ip6nd_ra_prefix",
+ "ip_table_dump",
[
"u16",
"_vl_msg_id"
@@ -658,57 +619,34 @@
"u32",
"context"
],
+ {
+ "crc": "0x51077d14"
+ }
+ ],
+ [
+ "ip_table_replace_begin",
[
- "u32",
- "sw_if_index"
- ],
- [
- "u8",
- "address",
- 16
- ],
- [
- "u8",
- "address_length"
- ],
- [
- "u8",
- "use_default"
- ],
- [
- "u8",
- "no_advertise"
- ],
- [
- "u8",
- "off_link"
- ],
- [
- "u8",
- "no_autoconfig"
- ],
- [
- "u8",
- "no_onlink"
+ "u16",
+ "_vl_msg_id"
],
[
- "u8",
- "is_no"
+ "u32",
+ "client_index"
],
[
"u32",
- "val_lifetime"
+ "context"
],
[
- "u32",
- "pref_lifetime"
+ "vl_api_ip_table_t",
+ "table"
],
{
- "crc": "0xca763c9a"
+ "crc": "0xb9d2e09e"
}
],
[
- "sw_interface_ip6nd_ra_prefix_reply",
+ "ip_table_replace_begin_reply",
[
"u16",
"_vl_msg_id"
@@ -726,7 +664,7 @@
}
],
[
- "ip6nd_proxy_add_del",
+ "ip_table_replace_end",
[
"u16",
"_vl_msg_id"
@@ -740,24 +678,15 @@
"context"
],
[
- "u32",
- "sw_if_index"
- ],
- [
- "u8",
- "is_del"
- ],
- [
- "u8",
- "address",
- 16
+ "vl_api_ip_table_t",
+ "table"
],
{
- "crc": "0xd95f0fa0"
+ "crc": "0xb9d2e09e"
}
],
[
- "ip6nd_proxy_add_del_reply",
+ "ip_table_replace_end_reply",
[
"u16",
"_vl_msg_id"
@@ -775,7 +704,7 @@
}
],
[
- "ip6nd_proxy_details",
+ "ip_table_flush",
[
"u16",
"_vl_msg_id"
@@ -789,38 +718,51 @@
"context"
],
[
+ "vl_api_ip_table_t",
+ "table"
+ ],
+ {
+ "crc": "0xb9d2e09e"
+ }
+ ],
+ [
+ "ip_table_flush_reply",
+ [
+ "u16",
+ "_vl_msg_id"
+ ],
+ [
"u32",
- "sw_if_index"
+ "context"
],
[
- "u8",
- "address",
- 16
+ "i32",
+ "retval"
],
{
- "crc": "0xd73bf1ab"
+ "crc": "0xe8d4e804"
}
],
[
- "ip6nd_proxy_dump",
+ "ip_table_details",
[
"u16",
"_vl_msg_id"
],
[
"u32",
- "client_index"
+ "context"
],
[
- "u32",
- "context"
+ "vl_api_ip_table_t",
+ "table"
],
{
- "crc": "0x51077d14"
+ "crc": "0xc79fca0f"
}
],
[
- "sw_interface_ip6_enable_disable",
+ "ip_route_add_del",
[
"u16",
"_vl_msg_id"
@@ -834,19 +776,26 @@
"context"
],
[
- "u32",
- "sw_if_index"
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
],
[
- "u8",
- "enable"
+ "bool",
+ "is_multipath"
+ ],
+ [
+ "vl_api_ip_route_t",
+ "route"
],
{
- "crc": "0xa36fadc0"
+ "crc": "0xc1ff832d"
}
],
[
- "sw_interface_ip6_enable_disable_reply",
+ "ip_route_add_del_reply",
[
"u16",
"_vl_msg_id"
@@ -859,12 +808,16 @@
"i32",
"retval"
],
+ [
+ "u32",
+ "stats_index"
+ ],
{
- "crc": "0xe8d4e804"
+ "crc": "0x1992deab"
}
],
[
- "sw_interface_ip6_set_link_local_address",
+ "ip_route_dump",
[
"u16",
"_vl_msg_id"
@@ -878,20 +831,15 @@
"context"
],
[
- "u32",
- "sw_if_index"
- ],
- [
- "u8",
- "address",
- 16
+ "vl_api_ip_table_t",
+ "table"
],
{
- "crc": "0xd73bf1ab"
+ "crc": "0xb9d2e09e"
}
],
[
- "sw_interface_ip6_set_link_local_address_reply",
+ "ip_route_details",
[
"u16",
"_vl_msg_id"
@@ -901,15 +849,15 @@
"context"
],
[
- "i32",
- "retval"
+ "vl_api_ip_route_t",
+ "route"
],
{
- "crc": "0xe8d4e804"
+ "crc": "0xd1ffaae1"
}
],
[
- "ip_add_del_route",
+ "ip_route_lookup",
[
"u16",
"_vl_msg_id"
@@ -924,122 +872,146 @@
],
[
"u32",
- "next_hop_sw_if_index"
+ "table_id"
],
[
- "u32",
- "table_id"
+ "u8",
+ "exact"
],
[
- "u32",
- "classify_table_index"
+ "vl_api_prefix_t",
+ "prefix"
],
+ {
+ "crc": "0xe2986185"
+ }
+ ],
+ [
+ "ip_route_lookup_reply",
[
- "u32",
- "next_hop_table_id"
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
- "next_hop_id"
+ "context"
],
[
- "u8",
- "is_add"
+ "i32",
+ "retval"
],
[
- "u8",
- "is_drop"
+ "vl_api_ip_route_t",
+ "route"
],
+ {
+ "crc": "0xae99de8e"
+ }
+ ],
+ [
+ "set_ip_flow_hash",
[
- "u8",
- "is_unreach"
+ "u16",
+ "_vl_msg_id"
],
[
- "u8",
- "is_prohibit"
+ "u32",
+ "client_index"
],
[
- "u8",
- "is_ipv6"
+ "u32",
+ "context"
],
[
- "u8",
- "is_local"
+ "u32",
+ "vrf_id"
],
[
- "u8",
- "is_classify"
+ "bool",
+ "is_ipv6"
],
[
- "u8",
- "is_multipath"
+ "bool",
+ "src"
],
[
- "u8",
- "is_resolve_host"
+ "bool",
+ "dst"
],
[
- "u8",
- "is_resolve_attached"
+ "bool",
+ "sport"
],
[
- "u8",
- "is_dvr"
+ "bool",
+ "dport"
],
[
- "u8",
- "is_source_lookup"
+ "bool",
+ "proto"
],
[
- "u8",
- "is_udp_encap"
+ "bool",
+ "reverse"
],
[
- "u8",
- "next_hop_weight"
+ "bool",
+ "symmetric"
],
+ {
+ "crc": "0x084ee09e"
+ }
+ ],
+ [
+ "set_ip_flow_hash_reply",
[
- "u8",
- "next_hop_preference"
+ "u16",
+ "_vl_msg_id"
],
[
- "u8",
- "next_hop_proto"
+ "u32",
+ "context"
],
[
- "u8",
- "dst_address_length"
+ "i32",
+ "retval"
],
+ {
+ "crc": "0xe8d4e804"
+ }
+ ],
+ [
+ "set_ip_flow_hash_v2",
[
- "u8",
- "dst_address",
- 16
+ "u16",
+ "_vl_msg_id"
],
[
- "u8",
- "next_hop_address",
- 16
+ "u32",
+ "client_index"
],
[
- "u8",
- "next_hop_n_out_labels"
+ "u32",
+ "context"
],
[
"u32",
- "next_hop_via_label"
+ "table_id"
],
[
- "u32",
- "next_hop_out_label_stack",
- 0,
- "next_hop_n_out_labels"
+ "vl_api_address_family_t",
+ "af"
+ ],
+ [
+ "vl_api_ip_flow_hash_config_t",
+ "flow_hash_config"
],
{
- "crc": "0xc85f8290"
+ "crc": "0x6d132100"
}
],
[
- "ip_add_del_route_reply",
+ "set_ip_flow_hash_v2_reply",
[
"u16",
"_vl_msg_id"
@@ -1057,7 +1029,7 @@
}
],
[
- "ip_mroute_add_del",
+ "set_ip_flow_hash_router_id",
[
"u16",
"_vl_msg_id"
@@ -1072,64 +1044,58 @@
],
[
"u32",
- "next_hop_sw_if_index"
- ],
- [
- "u32",
- "table_id"
- ],
- [
- "u32",
- "entry_flags"
+ "router_id"
],
+ {
+ "crc": "0x03e4f48e"
+ }
+ ],
+ [
+ "set_ip_flow_hash_router_id_reply",
[
- "u32",
- "itf_flags"
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
- "rpf_id"
+ "context"
],
[
- "u32",
- "bier_imp"
+ "i32",
+ "retval"
],
+ {
+ "crc": "0xe8d4e804"
+ }
+ ],
+ [
+ "sw_interface_ip6_enable_disable",
[
"u16",
- "grp_address_length"
- ],
- [
- "u8",
- "next_hop_afi"
- ],
- [
- "u8",
- "is_add"
+ "_vl_msg_id"
],
[
- "u8",
- "is_ipv6"
+ "u32",
+ "client_index"
],
[
- "u8",
- "is_local"
+ "u32",
+ "context"
],
[
- "u8",
- "grp_address",
- 16
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "u8",
- "src_address",
- 16
+ "bool",
+ "enable"
],
{
- "crc": "0xc37112f7"
+ "crc": "0xae6cfcfb"
}
],
[
- "ip_mroute_add_del_reply",
+ "sw_interface_ip6_enable_disable_reply",
[
"u16",
"_vl_msg_id"
@@ -1147,7 +1113,7 @@
}
],
[
- "ip_mfib_dump",
+ "ip_mtable_dump",
[
"u16",
"_vl_msg_id"
@@ -1165,57 +1131,84 @@
}
],
[
- "ip_mfib_details",
+ "ip_mtable_details",
[
"u16",
"_vl_msg_id"
],
[
"u32",
- "context"
+ "client_index"
],
[
"u32",
- "table_id"
+ "context"
+ ],
+ [
+ "vl_api_ip_table_t",
+ "table"
+ ],
+ {
+ "crc": "0xb9d2e09e"
+ }
+ ],
+ [
+ "ip_mroute_add_del",
+ [
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
- "entry_flags"
+ "client_index"
],
[
"u32",
- "rpf_id"
+ "context"
],
[
- "u8",
- "address_length"
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
],
[
- "u8",
- "grp_address",
- 4
+ "bool",
+ "is_multipath"
],
[
- "u8",
- "src_address",
- 4
+ "vl_api_ip_mroute_t",
+ "route"
+ ],
+ {
+ "crc": "0x0dd7e790"
+ }
+ ],
+ [
+ "ip_mroute_add_del_reply",
+ [
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
- "count"
+ "context"
],
[
- "vl_api_fib_path_t",
- "path",
- 0,
- "count"
+ "i32",
+ "retval"
+ ],
+ [
+ "u32",
+ "stats_index"
],
{
- "crc": "0x5e530d5e"
+ "crc": "0x1992deab"
}
],
[
- "ip6_mfib_dump",
+ "ip_mroute_dump",
[
"u16",
"_vl_msg_id"
@@ -1228,12 +1221,16 @@
"u32",
"context"
],
+ [
+ "vl_api_ip_table_t",
+ "table"
+ ],
{
- "crc": "0x51077d14"
+ "crc": "0xb9d2e09e"
}
],
[
- "ip6_mfib_details",
+ "ip_mroute_details",
[
"u16",
"_vl_msg_id"
@@ -1243,39 +1240,37 @@
"context"
],
[
- "u32",
- "table_id"
- ],
- [
- "u8",
- "address_length"
+ "vl_api_ip_mroute_t",
+ "route"
],
+ {
+ "crc": "0xc5cb23fc"
+ }
+ ],
+ [
+ "ip_address_details",
[
- "u8",
- "grp_address",
- 16
+ "u16",
+ "_vl_msg_id"
],
[
- "u8",
- "src_address",
- 16
+ "u32",
+ "context"
],
[
- "u32",
- "count"
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "vl_api_fib_path_t",
- "path",
- 0,
- "count"
+ "vl_api_address_with_prefix_t",
+ "prefix"
],
{
- "crc": "0xe02dcb4b"
+ "crc": "0xb1199745"
}
],
[
- "ip_address_details",
+ "ip_address_dump",
[
"u16",
"_vl_msg_id"
@@ -1289,28 +1284,41 @@
"context"
],
[
- "u8",
- "ip",
- 16
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "u8",
- "prefix_length"
+ "bool",
+ "is_ipv6"
+ ],
+ {
+ "crc": "0x2d033de4"
+ }
+ ],
+ [
+ "ip_unnumbered_details",
+ [
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
+ "context"
+ ],
+ [
+ "vl_api_interface_index_t",
"sw_if_index"
],
[
- "u8",
- "is_ipv6"
+ "vl_api_interface_index_t",
+ "ip_sw_if_index"
],
{
- "crc": "0xbc7442f2"
+ "crc": "0xaa12a483"
}
],
[
- "ip_address_dump",
+ "ip_unnumbered_dump",
[
"u16",
"_vl_msg_id"
@@ -1324,15 +1332,14 @@
"context"
],
[
- "u32",
- "sw_if_index"
- ],
- [
- "u8",
- "is_ipv6"
+ "vl_api_interface_index_t",
+ "sw_if_index",
+ {
+ "default": 4294967295
+ }
],
{
- "crc": "0x6b7bcd0a"
+ "crc": "0xf9e6675e"
}
],
[
@@ -1343,18 +1350,18 @@
],
[
"u32",
- "sw_if_index"
+ "context"
],
[
- "u32",
- "context"
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "u8",
+ "bool",
"is_ipv6"
],
{
- "crc": "0x452ffc5a"
+ "crc": "0xeb152d07"
}
],
[
@@ -1372,11 +1379,11 @@
"context"
],
[
- "u8",
+ "bool",
"is_ipv6"
],
{
- "crc": "0xde883da4"
+ "crc": "0x98d231ca"
}
],
[
@@ -1405,14 +1412,10 @@
],
[
"u32",
- "client_index"
- ],
- [
- "u32",
"context"
],
[
- "u32",
+ "vl_api_interface_index_t",
"sw_if_index"
],
[
@@ -1420,18 +1423,8 @@
"table_id"
],
[
- "u16",
- "grp_address_len"
- ],
- [
- "u8",
- "grp_address",
- 16
- ],
- [
- "u8",
- "src_address",
- 16
+ "vl_api_mprefix_t",
+ "prefix"
],
[
"u16",
@@ -1443,7 +1436,7 @@
256
],
{
- "crc": "0x791bbeab"
+ "crc": "0x64398a9a"
}
],
[
@@ -1465,15 +1458,18 @@
"policer_index"
],
[
- "u8",
- "is_add"
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
],
[
- "u8",
+ "bool",
"is_ip6"
],
{
- "crc": "0x38691592"
+ "crc": "0xdb867cea"
}
],
[
@@ -1509,28 +1505,18 @@
"context"
],
[
- "u32",
- "rx_sw_if_index"
+ "vl_api_punt_redirect_t",
+ "punt"
],
[
- "u32",
- "tx_sw_if_index"
- ],
- [
- "u8",
- "is_add"
- ],
- [
- "u8",
- "is_ip6"
- ],
- [
- "u8",
- "nh",
- 16
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
],
{
- "crc": "0x996b6603"
+ "crc": "0xa9a5592c"
}
],
[
@@ -1552,7 +1538,7 @@
}
],
[
- "ip_container_proxy_add_del",
+ "ip_punt_redirect_dump",
[
"u16",
"_vl_msg_id"
@@ -1566,28 +1552,66 @@
"context"
],
[
- "u8",
- "ip",
- 16
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "u8",
- "is_ip4"
+ "bool",
+ "is_ipv6"
],
+ {
+ "crc": "0x2d033de4"
+ }
+ ],
+ [
+ "ip_punt_redirect_details",
[
- "u8",
- "plen"
+ "u16",
+ "_vl_msg_id"
+ ],
+ [
+ "u32",
+ "context"
+ ],
+ [
+ "vl_api_punt_redirect_t",
+ "punt"
+ ],
+ {
+ "crc": "0x3924f5d3"
+ }
+ ],
+ [
+ "ip_container_proxy_add_del",
+ [
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
+ "client_index"
+ ],
+ [
+ "u32",
+ "context"
+ ],
+ [
+ "vl_api_prefix_t",
+ "pfx"
+ ],
+ [
+ "vl_api_interface_index_t",
"sw_if_index"
],
[
- "u8",
- "is_add"
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
],
{
- "crc": "0x0a355d39"
+ "crc": "0x91189f40"
}
],
[
@@ -1609,7 +1633,7 @@
}
],
[
- "ip_source_and_port_range_check_add_del",
+ "ip_container_proxy_dump",
[
"u16",
"_vl_msg_id"
@@ -1622,22 +1646,56 @@
"u32",
"context"
],
+ {
+ "crc": "0x51077d14"
+ }
+ ],
+ [
+ "ip_container_proxy_details",
[
- "u8",
- "is_ipv6"
+ "u16",
+ "_vl_msg_id"
],
[
- "u8",
- "is_add"
+ "u32",
+ "context"
],
[
- "u8",
- "mask_length"
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "u8",
- "address",
- 16
+ "vl_api_prefix_t",
+ "prefix"
+ ],
+ {
+ "crc": "0x0ee460e8"
+ }
+ ],
+ [
+ "ip_source_and_port_range_check_add_del",
+ [
+ "u16",
+ "_vl_msg_id"
+ ],
+ [
+ "u32",
+ "client_index"
+ ],
+ [
+ "u32",
+ "context"
+ ],
+ [
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
+ ],
+ [
+ "vl_api_prefix_t",
+ "prefix"
],
[
"u8",
@@ -1658,7 +1716,7 @@
"vrf_id"
],
{
- "crc": "0x03d6b03a"
+ "crc": "0x8bfc76f2"
}
],
[
@@ -1694,11 +1752,14 @@
"context"
],
[
- "u8",
- "is_add"
+ "bool",
+ "is_add",
+ {
+ "default": "true"
+ }
],
[
- "u32",
+ "vl_api_interface_index_t",
"sw_if_index"
],
[
@@ -1718,7 +1779,7 @@
"udp_out_vrf_id"
],
{
- "crc": "0x6966bc44"
+ "crc": "0xe1ba8987"
}
],
[
@@ -1740,7 +1801,7 @@
}
],
[
- "want_ip4_arp_events",
+ "sw_interface_ip6_set_link_local_address",
[
"u16",
"_vl_msg_id"
@@ -1754,23 +1815,19 @@
"context"
],
[
- "u8",
- "enable_disable"
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "u32",
- "pid"
- ],
- [
- "u32",
- "address"
+ "vl_api_ip6_address_t",
+ "ip"
],
{
- "crc": "0x77e06379"
+ "crc": "0x2931d9fa"
}
],
[
- "want_ip4_arp_events_reply",
+ "sw_interface_ip6_set_link_local_address_reply",
[
"u16",
"_vl_msg_id"
@@ -1788,7 +1845,7 @@
}
],
[
- "ip4_arp_event",
+ "sw_interface_ip6_get_link_local_address",
[
"u16",
"_vl_msg_id"
@@ -1799,31 +1856,40 @@
],
[
"u32",
- "address"
+ "context"
],
[
- "u32",
- "pid"
+ "vl_api_interface_index_t",
+ "sw_if_index"
+ ],
+ {
+ "crc": "0xf9e6675e"
+ }
+ ],
+ [
+ "sw_interface_ip6_get_link_local_address_reply",
+ [
+ "u16",
+ "_vl_msg_id"
],
[
"u32",
- "sw_if_index"
+ "context"
],
[
- "u8",
- "new_mac",
- 6
+ "i32",
+ "retval"
],
[
- "u8",
- "mac_ip"
+ "vl_api_ip6_address_t",
+ "ip"
],
{
- "crc": "0xef7235f7"
+ "crc": "0xd16b7130"
}
],
[
- "want_ip6_nd_events",
+ "ioam_enable",
[
"u16",
"_vl_msg_id"
@@ -1837,24 +1903,35 @@
"context"
],
[
- "u8",
- "enable_disable"
+ "u16",
+ "id"
],
[
- "u32",
- "pid"
+ "bool",
+ "seqno"
],
[
- "u8",
- "address",
- 16
+ "bool",
+ "analyse"
+ ],
+ [
+ "bool",
+ "pot_enable"
+ ],
+ [
+ "bool",
+ "trace_enable"
+ ],
+ [
+ "u32",
+ "node_id"
],
{
- "crc": "0x1cf65fbb"
+ "crc": "0x51ccd868"
}
],
[
- "want_ip6_nd_events_reply",
+ "ioam_enable_reply",
[
"u16",
"_vl_msg_id"
@@ -1872,7 +1949,7 @@
}
],
[
- "ip6_nd_event",
+ "ioam_disable",
[
"u16",
"_vl_msg_id"
@@ -1883,32 +1960,36 @@
],
[
"u32",
- "pid"
+ "context"
],
[
- "u32",
- "sw_if_index"
+ "u16",
+ "id"
],
+ {
+ "crc": "0x6b16a45e"
+ }
+ ],
+ [
+ "ioam_disable_reply",
[
- "u8",
- "address",
- 16
+ "u16",
+ "_vl_msg_id"
],
[
- "u8",
- "new_mac",
- 6
+ "u32",
+ "context"
],
[
- "u8",
- "mac_ip"
+ "i32",
+ "retval"
],
{
- "crc": "0x96ab2fdd"
+ "crc": "0xe8d4e804"
}
],
[
- "proxy_arp_add_del",
+ "ip_reassembly_set",
[
"u16",
"_vl_msg_id"
@@ -1923,28 +2004,34 @@
],
[
"u32",
- "vrf_id"
+ "timeout_ms"
],
[
- "u8",
- "is_add"
+ "u32",
+ "max_reassemblies"
],
[
- "u8",
- "low_address",
- 4
+ "u32",
+ "max_reassembly_length"
],
[
- "u8",
- "hi_address",
- 4
+ "u32",
+ "expire_walk_interval_ms"
+ ],
+ [
+ "bool",
+ "is_ip6"
+ ],
+ [
+ "vl_api_ip_reass_type_t",
+ "type"
],
{
- "crc": "0xc2442918"
+ "crc": "0x16467d25"
}
],
[
- "proxy_arp_add_del_reply",
+ "ip_reassembly_set_reply",
[
"u16",
"_vl_msg_id"
@@ -1962,7 +2049,7 @@
}
],
[
- "proxy_arp_intfc_enable_disable",
+ "ip_reassembly_get",
[
"u16",
"_vl_msg_id"
@@ -1976,19 +2063,19 @@
"context"
],
[
- "u32",
- "sw_if_index"
+ "bool",
+ "is_ip6"
],
[
- "u8",
- "enable_disable"
+ "vl_api_ip_reass_type_t",
+ "type"
],
{
- "crc": "0x69d24598"
+ "crc": "0xea13ff63"
}
],
[
- "proxy_arp_intfc_enable_disable_reply",
+ "ip_reassembly_get_reply",
[
"u16",
"_vl_msg_id"
@@ -2001,12 +2088,32 @@
"i32",
"retval"
],
+ [
+ "u32",
+ "timeout_ms"
+ ],
+ [
+ "u32",
+ "max_reassemblies"
+ ],
+ [
+ "u32",
+ "max_reassembly_length"
+ ],
+ [
+ "u32",
+ "expire_walk_interval_ms"
+ ],
+ [
+ "bool",
+ "is_ip6"
+ ],
{
- "crc": "0xe8d4e804"
+ "crc": "0xd5eb8d34"
}
],
[
- "reset_fib",
+ "ip_reassembly_enable_disable",
[
"u16",
"_vl_msg_id"
@@ -2020,19 +2127,27 @@
"context"
],
[
- "u32",
- "vrf_id"
+ "vl_api_interface_index_t",
+ "sw_if_index"
],
[
- "u8",
- "is_ipv6"
+ "bool",
+ "enable_ip4"
+ ],
+ [
+ "bool",
+ "enable_ip6"
+ ],
+ [
+ "vl_api_ip_reass_type_t",
+ "type"
],
{
- "crc": "0x8553ebd9"
+ "crc": "0x885c85a6"
}
],
[
- "reset_fib_reply",
+ "ip_reassembly_enable_disable_reply",
[
"u16",
"_vl_msg_id"
@@ -2048,199 +2163,1416 @@
{
"crc": "0xe8d4e804"
}
+ ]
+ ],
+ "unions": [
+ [
+ "address_union",
+ [
+ "vl_api_ip4_address_t",
+ "ip4"
+ ],
+ [
+ "vl_api_ip6_address_t",
+ "ip6"
+ ]
],
[
- "set_arp_neighbor_limit",
+ "address_union",
[
- "u16",
- "_vl_msg_id"
+ "vl_api_ip4_address_t",
+ "ip4"
],
[
- "u32",
- "client_index"
+ "vl_api_ip6_address_t",
+ "ip6"
+ ]
+ ],
+ [
+ "address_union",
+ [
+ "vl_api_ip4_address_t",
+ "ip4"
],
[
- "u32",
- "context"
+ "vl_api_ip6_address_t",
+ "ip6"
+ ]
+ ]
+ ],
+ "enums": [
+ [
+ "if_status_flags",
+ [
+ "IF_STATUS_API_FLAG_ADMIN_UP",
+ 1
],
[
- "u8",
- "is_ipv6"
+ "IF_STATUS_API_FLAG_LINK_UP",
+ 2
],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "mtu_proto",
[
- "u32",
- "arp_neighbor_limit"
+ "MTU_PROTO_API_L3",
+ 0
+ ],
+ [
+ "MTU_PROTO_API_IP4",
+ 1
+ ],
+ [
+ "MTU_PROTO_API_IP6",
+ 2
+ ],
+ [
+ "MTU_PROTO_API_MPLS",
+ 3
],
{
- "crc": "0x97d01fd6"
+ "enumtype": "u32"
}
],
[
- "set_arp_neighbor_limit_reply",
+ "link_duplex",
[
- "u16",
- "_vl_msg_id"
+ "LINK_DUPLEX_API_UNKNOWN",
+ 0
],
[
- "u32",
- "context"
+ "LINK_DUPLEX_API_HALF",
+ 1
],
[
- "i32",
- "retval"
+ "LINK_DUPLEX_API_FULL",
+ 2
],
{
- "crc": "0xe8d4e804"
+ "enumtype": "u32"
}
],
[
- "ioam_enable",
+ "sub_if_flags",
[
- "u16",
- "_vl_msg_id"
+ "SUB_IF_API_FLAG_NO_TAGS",
+ 1
],
[
- "u32",
- "client_index"
+ "SUB_IF_API_FLAG_ONE_TAG",
+ 2
],
[
- "u32",
- "context"
+ "SUB_IF_API_FLAG_TWO_TAGS",
+ 4
],
[
- "u16",
- "id"
+ "SUB_IF_API_FLAG_DOT1AD",
+ 8
],
[
- "u8",
- "seqno"
+ "SUB_IF_API_FLAG_EXACT_MATCH",
+ 16
],
[
- "u8",
- "analyse"
+ "SUB_IF_API_FLAG_DEFAULT",
+ 32
],
[
- "u8",
- "pot_enable"
+ "SUB_IF_API_FLAG_OUTER_VLAN_ID_ANY",
+ 64
],
[
- "u8",
- "trace_enable"
+ "SUB_IF_API_FLAG_INNER_VLAN_ID_ANY",
+ 128
],
[
- "u32",
- "node_id"
+ "SUB_IF_API_FLAG_MASK_VNET",
+ 254
+ ],
+ [
+ "SUB_IF_API_FLAG_DOT1AH",
+ 256
],
{
- "crc": "0x9392e032"
+ "enumtype": "u32"
}
],
[
- "ioam_enable_reply",
+ "rx_mode",
[
- "u16",
- "_vl_msg_id"
+ "RX_MODE_API_UNKNOWN",
+ 0
],
[
- "u32",
- "context"
+ "RX_MODE_API_POLLING",
+ 1
],
[
- "i32",
- "retval"
+ "RX_MODE_API_INTERRUPT",
+ 2
+ ],
+ [
+ "RX_MODE_API_ADAPTIVE",
+ 3
+ ],
+ [
+ "RX_MODE_API_DEFAULT",
+ 4
],
{
- "crc": "0xe8d4e804"
+ "enumtype": "u32"
}
],
[
- "ioam_disable",
+ "if_type",
[
- "u16",
- "_vl_msg_id"
+ "IF_API_TYPE_HARDWARE",
+ 0
],
[
- "u32",
- "client_index"
+ "IF_API_TYPE_SUB",
+ 1
],
[
- "u32",
- "context"
+ "IF_API_TYPE_P2P",
+ 2
],
[
- "u16",
- "id"
+ "IF_API_TYPE_PIPE",
+ 3
],
{
- "crc": "0x6b16a45e"
+ "enumtype": "u32"
}
],
[
- "ioam_disable_reply",
+ "address_family",
[
- "u16",
- "_vl_msg_id"
+ "ADDRESS_IP4",
+ 0
],
[
- "u32",
- "context"
+ "ADDRESS_IP6",
+ 1
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_feature_location",
+ [
+ "IP_API_FEATURE_INPUT",
+ 0
],
[
- "i32",
- "retval"
+ "IP_API_FEATURE_OUTPUT",
+ 1
+ ],
+ [
+ "IP_API_FEATURE_LOCAL",
+ 2
+ ],
+ [
+ "IP_API_FEATURE_PUNT",
+ 3
+ ],
+ [
+ "IP_API_FEATURE_DROP",
+ 4
],
{
- "crc": "0xe8d4e804"
+ "enumtype": "u8"
}
- ]
- ],
- "types": [
+ ],
[
- "fib_path",
+ "ip_ecn",
[
- "u32",
- "sw_if_index"
+ "IP_API_ECN_NONE",
+ 0
],
[
- "u32",
- "table_id"
+ "IP_API_ECN_ECT0",
+ 1
],
[
- "u8",
- "weight"
+ "IP_API_ECN_ECT1",
+ 2
],
[
- "u8",
- "preference"
+ "IP_API_ECN_CE",
+ 3
],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_dscp",
[
- "u8",
- "is_local"
+ "IP_API_DSCP_CS0",
+ 0
],
[
- "u8",
- "is_drop"
+ "IP_API_DSCP_CS1",
+ 8
],
[
- "u8",
- "is_unreach"
+ "IP_API_DSCP_AF11",
+ 10
],
[
- "u8",
- "is_prohibit"
+ "IP_API_DSCP_AF12",
+ 12
],
[
- "u8",
- "afi"
+ "IP_API_DSCP_AF13",
+ 14
],
[
- "u8",
- "next_hop",
+ "IP_API_DSCP_CS2",
+ 16
+ ],
+ [
+ "IP_API_DSCP_AF21",
+ 18
+ ],
+ [
+ "IP_API_DSCP_AF22",
+ 20
+ ],
+ [
+ "IP_API_DSCP_AF23",
+ 22
+ ],
+ [
+ "IP_API_DSCP_CS3",
+ 24
+ ],
+ [
+ "IP_API_DSCP_AF31",
+ 26
+ ],
+ [
+ "IP_API_DSCP_AF32",
+ 28
+ ],
+ [
+ "IP_API_DSCP_AF33",
+ 30
+ ],
+ [
+ "IP_API_DSCP_CS4",
+ 32
+ ],
+ [
+ "IP_API_DSCP_AF41",
+ 34
+ ],
+ [
+ "IP_API_DSCP_AF42",
+ 36
+ ],
+ [
+ "IP_API_DSCP_AF43",
+ 38
+ ],
+ [
+ "IP_API_DSCP_CS5",
+ 40
+ ],
+ [
+ "IP_API_DSCP_EF",
+ 46
+ ],
+ [
+ "IP_API_DSCP_CS6",
+ 48
+ ],
+ [
+ "IP_API_DSCP_CS7",
+ 50
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_proto",
+ [
+ "IP_API_PROTO_HOPOPT",
+ 0
+ ],
+ [
+ "IP_API_PROTO_ICMP",
+ 1
+ ],
+ [
+ "IP_API_PROTO_IGMP",
+ 2
+ ],
+ [
+ "IP_API_PROTO_TCP",
+ 6
+ ],
+ [
+ "IP_API_PROTO_UDP",
+ 17
+ ],
+ [
+ "IP_API_PROTO_GRE",
+ 47
+ ],
+ [
+ "IP_API_PROTO_ESP",
+ 50
+ ],
+ [
+ "IP_API_PROTO_AH",
+ 51
+ ],
+ [
+ "IP_API_PROTO_ICMP6",
+ 58
+ ],
+ [
+ "IP_API_PROTO_EIGRP",
+ 88
+ ],
+ [
+ "IP_API_PROTO_OSPF",
+ 89
+ ],
+ [
+ "IP_API_PROTO_SCTP",
+ 132
+ ],
+ [
+ "IP_API_PROTO_RESERVED",
+ 255
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "fib_path_nh_proto",
+ [
+ "FIB_API_PATH_NH_PROTO_IP4",
+ 0
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_IP6",
+ 1
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_MPLS",
+ 2
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_ETHERNET",
+ 3
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_BIER",
+ 4
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "fib_path_flags",
+ [
+ "FIB_API_PATH_FLAG_NONE",
+ 0
+ ],
+ [
+ "FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED",
+ 1
+ ],
+ [
+ "FIB_API_PATH_FLAG_RESOLVE_VIA_HOST",
+ 2
+ ],
+ [
+ "FIB_API_PATH_FLAG_POP_PW_CW",
+ 4
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "fib_path_type",
+ [
+ "FIB_API_PATH_TYPE_NORMAL",
+ 0
+ ],
+ [
+ "FIB_API_PATH_TYPE_LOCAL",
+ 1
+ ],
+ [
+ "FIB_API_PATH_TYPE_DROP",
+ 2
+ ],
+ [
+ "FIB_API_PATH_TYPE_UDP_ENCAP",
+ 3
+ ],
+ [
+ "FIB_API_PATH_TYPE_BIER_IMP",
+ 4
+ ],
+ [
+ "FIB_API_PATH_TYPE_ICMP_UNREACH",
+ 5
+ ],
+ [
+ "FIB_API_PATH_TYPE_ICMP_PROHIBIT",
+ 6
+ ],
+ [
+ "FIB_API_PATH_TYPE_SOURCE_LOOKUP",
+ 7
+ ],
+ [
+ "FIB_API_PATH_TYPE_DVR",
+ 8
+ ],
+ [
+ "FIB_API_PATH_TYPE_INTERFACE_RX",
+ 9
+ ],
+ [
+ "FIB_API_PATH_TYPE_CLASSIFY",
+ 10
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "address_family",
+ [
+ "ADDRESS_IP4",
+ 0
+ ],
+ [
+ "ADDRESS_IP6",
+ 1
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_feature_location",
+ [
+ "IP_API_FEATURE_INPUT",
+ 0
+ ],
+ [
+ "IP_API_FEATURE_OUTPUT",
+ 1
+ ],
+ [
+ "IP_API_FEATURE_LOCAL",
+ 2
+ ],
+ [
+ "IP_API_FEATURE_PUNT",
+ 3
+ ],
+ [
+ "IP_API_FEATURE_DROP",
+ 4
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_ecn",
+ [
+ "IP_API_ECN_NONE",
+ 0
+ ],
+ [
+ "IP_API_ECN_ECT0",
+ 1
+ ],
+ [
+ "IP_API_ECN_ECT1",
+ 2
+ ],
+ [
+ "IP_API_ECN_CE",
+ 3
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_dscp",
+ [
+ "IP_API_DSCP_CS0",
+ 0
+ ],
+ [
+ "IP_API_DSCP_CS1",
+ 8
+ ],
+ [
+ "IP_API_DSCP_AF11",
+ 10
+ ],
+ [
+ "IP_API_DSCP_AF12",
+ 12
+ ],
+ [
+ "IP_API_DSCP_AF13",
+ 14
+ ],
+ [
+ "IP_API_DSCP_CS2",
+ 16
+ ],
+ [
+ "IP_API_DSCP_AF21",
+ 18
+ ],
+ [
+ "IP_API_DSCP_AF22",
+ 20
+ ],
+ [
+ "IP_API_DSCP_AF23",
+ 22
+ ],
+ [
+ "IP_API_DSCP_CS3",
+ 24
+ ],
+ [
+ "IP_API_DSCP_AF31",
+ 26
+ ],
+ [
+ "IP_API_DSCP_AF32",
+ 28
+ ],
+ [
+ "IP_API_DSCP_AF33",
+ 30
+ ],
+ [
+ "IP_API_DSCP_CS4",
+ 32
+ ],
+ [
+ "IP_API_DSCP_AF41",
+ 34
+ ],
+ [
+ "IP_API_DSCP_AF42",
+ 36
+ ],
+ [
+ "IP_API_DSCP_AF43",
+ 38
+ ],
+ [
+ "IP_API_DSCP_CS5",
+ 40
+ ],
+ [
+ "IP_API_DSCP_EF",
+ 46
+ ],
+ [
+ "IP_API_DSCP_CS6",
+ 48
+ ],
+ [
+ "IP_API_DSCP_CS7",
+ 50
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_proto",
+ [
+ "IP_API_PROTO_HOPOPT",
+ 0
+ ],
+ [
+ "IP_API_PROTO_ICMP",
+ 1
+ ],
+ [
+ "IP_API_PROTO_IGMP",
+ 2
+ ],
+ [
+ "IP_API_PROTO_TCP",
+ 6
+ ],
+ [
+ "IP_API_PROTO_UDP",
+ 17
+ ],
+ [
+ "IP_API_PROTO_GRE",
+ 47
+ ],
+ [
+ "IP_API_PROTO_ESP",
+ 50
+ ],
+ [
+ "IP_API_PROTO_AH",
+ 51
+ ],
+ [
+ "IP_API_PROTO_ICMP6",
+ 58
+ ],
+ [
+ "IP_API_PROTO_EIGRP",
+ 88
+ ],
+ [
+ "IP_API_PROTO_OSPF",
+ 89
+ ],
+ [
+ "IP_API_PROTO_SCTP",
+ 132
+ ],
+ [
+ "IP_API_PROTO_RESERVED",
+ 255
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "fib_path_nh_proto",
+ [
+ "FIB_API_PATH_NH_PROTO_IP4",
+ 0
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_IP6",
+ 1
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_MPLS",
+ 2
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_ETHERNET",
+ 3
+ ],
+ [
+ "FIB_API_PATH_NH_PROTO_BIER",
+ 4
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "fib_path_flags",
+ [
+ "FIB_API_PATH_FLAG_NONE",
+ 0
+ ],
+ [
+ "FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED",
+ 1
+ ],
+ [
+ "FIB_API_PATH_FLAG_RESOLVE_VIA_HOST",
+ 2
+ ],
+ [
+ "FIB_API_PATH_FLAG_POP_PW_CW",
+ 4
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "fib_path_type",
+ [
+ "FIB_API_PATH_TYPE_NORMAL",
+ 0
+ ],
+ [
+ "FIB_API_PATH_TYPE_LOCAL",
+ 1
+ ],
+ [
+ "FIB_API_PATH_TYPE_DROP",
+ 2
+ ],
+ [
+ "FIB_API_PATH_TYPE_UDP_ENCAP",
+ 3
+ ],
+ [
+ "FIB_API_PATH_TYPE_BIER_IMP",
+ 4
+ ],
+ [
+ "FIB_API_PATH_TYPE_ICMP_UNREACH",
+ 5
+ ],
+ [
+ "FIB_API_PATH_TYPE_ICMP_PROHIBIT",
+ 6
+ ],
+ [
+ "FIB_API_PATH_TYPE_SOURCE_LOOKUP",
+ 7
+ ],
+ [
+ "FIB_API_PATH_TYPE_DVR",
+ 8
+ ],
+ [
+ "FIB_API_PATH_TYPE_INTERFACE_RX",
+ 9
+ ],
+ [
+ "FIB_API_PATH_TYPE_CLASSIFY",
+ 10
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "address_family",
+ [
+ "ADDRESS_IP4",
+ 0
+ ],
+ [
+ "ADDRESS_IP6",
+ 1
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_feature_location",
+ [
+ "IP_API_FEATURE_INPUT",
+ 0
+ ],
+ [
+ "IP_API_FEATURE_OUTPUT",
+ 1
+ ],
+ [
+ "IP_API_FEATURE_LOCAL",
+ 2
+ ],
+ [
+ "IP_API_FEATURE_PUNT",
+ 3
+ ],
+ [
+ "IP_API_FEATURE_DROP",
+ 4
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_ecn",
+ [
+ "IP_API_ECN_NONE",
+ 0
+ ],
+ [
+ "IP_API_ECN_ECT0",
+ 1
+ ],
+ [
+ "IP_API_ECN_ECT1",
+ 2
+ ],
+ [
+ "IP_API_ECN_CE",
+ 3
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_dscp",
+ [
+ "IP_API_DSCP_CS0",
+ 0
+ ],
+ [
+ "IP_API_DSCP_CS1",
+ 8
+ ],
+ [
+ "IP_API_DSCP_AF11",
+ 10
+ ],
+ [
+ "IP_API_DSCP_AF12",
+ 12
+ ],
+ [
+ "IP_API_DSCP_AF13",
+ 14
+ ],
+ [
+ "IP_API_DSCP_CS2",
+ 16
+ ],
+ [
+ "IP_API_DSCP_AF21",
+ 18
+ ],
+ [
+ "IP_API_DSCP_AF22",
+ 20
+ ],
+ [
+ "IP_API_DSCP_AF23",
+ 22
+ ],
+ [
+ "IP_API_DSCP_CS3",
+ 24
+ ],
+ [
+ "IP_API_DSCP_AF31",
+ 26
+ ],
+ [
+ "IP_API_DSCP_AF32",
+ 28
+ ],
+ [
+ "IP_API_DSCP_AF33",
+ 30
+ ],
+ [
+ "IP_API_DSCP_CS4",
+ 32
+ ],
+ [
+ "IP_API_DSCP_AF41",
+ 34
+ ],
+ [
+ "IP_API_DSCP_AF42",
+ 36
+ ],
+ [
+ "IP_API_DSCP_AF43",
+ 38
+ ],
+ [
+ "IP_API_DSCP_CS5",
+ 40
+ ],
+ [
+ "IP_API_DSCP_EF",
+ 46
+ ],
+ [
+ "IP_API_DSCP_CS6",
+ 48
+ ],
+ [
+ "IP_API_DSCP_CS7",
+ 50
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "ip_proto",
+ [
+ "IP_API_PROTO_HOPOPT",
+ 0
+ ],
+ [
+ "IP_API_PROTO_ICMP",
+ 1
+ ],
+ [
+ "IP_API_PROTO_IGMP",
+ 2
+ ],
+ [
+ "IP_API_PROTO_TCP",
+ 6
+ ],
+ [
+ "IP_API_PROTO_UDP",
+ 17
+ ],
+ [
+ "IP_API_PROTO_GRE",
+ 47
+ ],
+ [
+ "IP_API_PROTO_ESP",
+ 50
+ ],
+ [
+ "IP_API_PROTO_AH",
+ 51
+ ],
+ [
+ "IP_API_PROTO_ICMP6",
+ 58
+ ],
+ [
+ "IP_API_PROTO_EIGRP",
+ 88
+ ],
+ [
+ "IP_API_PROTO_OSPF",
+ 89
+ ],
+ [
+ "IP_API_PROTO_SCTP",
+ 132
+ ],
+ [
+ "IP_API_PROTO_RESERVED",
+ 255
+ ],
+ {
+ "enumtype": "u8"
+ }
+ ],
+ [
+ "mfib_entry_flags",
+ [
+ "MFIB_API_ENTRY_FLAG_NONE",
+ 0
+ ],
+ [
+ "MFIB_API_ENTRY_FLAG_SIGNAL",
+ 1
+ ],
+ [
+ "MFIB_API_ENTRY_FLAG_DROP",
+ 2
+ ],
+ [
+ "MFIB_API_ENTRY_FLAG_CONNECTED",
+ 4
+ ],
+ [
+ "MFIB_API_ENTRY_FLAG_ACCEPT_ALL_ITF",
+ 8
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "mfib_itf_flags",
+ [
+ "MFIB_API_ITF_FLAG_NONE",
+ 0
+ ],
+ [
+ "MFIB_API_ITF_FLAG_NEGATE_SIGNAL",
+ 1
+ ],
+ [
+ "MFIB_API_ITF_FLAG_ACCEPT",
+ 2
+ ],
+ [
+ "MFIB_API_ITF_FLAG_FORWARD",
+ 4
+ ],
+ [
+ "MFIB_API_ITF_FLAG_SIGNAL_PRESENT",
+ 8
+ ],
+ [
+ "MFIB_API_ITF_FLAG_DONT_PRESERVE",
+ 16
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "if_status_flags",
+ [
+ "IF_STATUS_API_FLAG_ADMIN_UP",
+ 1
+ ],
+ [
+ "IF_STATUS_API_FLAG_LINK_UP",
+ 2
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "mtu_proto",
+ [
+ "MTU_PROTO_API_L3",
+ 0
+ ],
+ [
+ "MTU_PROTO_API_IP4",
+ 1
+ ],
+ [
+ "MTU_PROTO_API_IP6",
+ 2
+ ],
+ [
+ "MTU_PROTO_API_MPLS",
+ 3
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "link_duplex",
+ [
+ "LINK_DUPLEX_API_UNKNOWN",
+ 0
+ ],
+ [
+ "LINK_DUPLEX_API_HALF",
+ 1
+ ],
+ [
+ "LINK_DUPLEX_API_FULL",
+ 2
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "sub_if_flags",
+ [
+ "SUB_IF_API_FLAG_NO_TAGS",
+ 1
+ ],
+ [
+ "SUB_IF_API_FLAG_ONE_TAG",
+ 2
+ ],
+ [
+ "SUB_IF_API_FLAG_TWO_TAGS",
+ 4
+ ],
+ [
+ "SUB_IF_API_FLAG_DOT1AD",
+ 8
+ ],
+ [
+ "SUB_IF_API_FLAG_EXACT_MATCH",
+ 16
+ ],
+ [
+ "SUB_IF_API_FLAG_DEFAULT",
+ 32
+ ],
+ [
+ "SUB_IF_API_FLAG_OUTER_VLAN_ID_ANY",
+ 64
+ ],
+ [
+ "SUB_IF_API_FLAG_INNER_VLAN_ID_ANY",
+ 128
+ ],
+ [
+ "SUB_IF_API_FLAG_MASK_VNET",
+ 254
+ ],
+ [
+ "SUB_IF_API_FLAG_DOT1AH",
+ 256
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "rx_mode",
+ [
+ "RX_MODE_API_UNKNOWN",
+ 0
+ ],
+ [
+ "RX_MODE_API_POLLING",
+ 1
+ ],
+ [
+ "RX_MODE_API_INTERRUPT",
+ 2
+ ],
+ [
+ "RX_MODE_API_ADAPTIVE",
+ 3
+ ],
+ [
+ "RX_MODE_API_DEFAULT",
+ 4
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "if_type",
+ [
+ "IF_API_TYPE_HARDWARE",
+ 0
+ ],
+ [
+ "IF_API_TYPE_SUB",
+ 1
+ ],
+ [
+ "IF_API_TYPE_P2P",
+ 2
+ ],
+ [
+ "IF_API_TYPE_PIPE",
+ 3
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ],
+ [
+ "ip_reass_type",
+ [
+ "IP_REASS_TYPE_FULL",
+ 0
+ ],
+ [
+ "IP_REASS_TYPE_SHALLOW_VIRTUAL",
+ 1
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ]
+ ],
+ "enumflags": [
+ [
+ "ip_flow_hash_config",
+ [
+ "IP_API_FLOW_HASH_SRC_IP",
+ 1
+ ],
+ [
+ "IP_API_FLOW_HASH_DST_IP",
+ 2
+ ],
+ [
+ "IP_API_FLOW_HASH_SRC_PORT",
+ 4
+ ],
+ [
+ "IP_API_FLOW_HASH_DST_PORT",
+ 8
+ ],
+ [
+ "IP_API_FLOW_HASH_PROTO",
16
],
+ [
+ "IP_API_FLOW_HASH_REVERSE",
+ 32
+ ],
+ [
+ "IP_API_FLOW_HASH_SYMETRIC",
+ 64
+ ],
+ [
+ "IP_API_FLOW_HASH_FLOW_LABEL",
+ 128
+ ],
{
- "crc": "0xcd899e0a"
+ "enumtype": "u32"
}
]
- ]
+ ],
+ "services": {
+ "ip_table_add_del": {
+ "reply": "ip_table_add_del_reply"
+ },
+ "ip_table_dump": {
+ "reply": "ip_table_details",
+ "stream": true
+ },
+ "ip_table_replace_begin": {
+ "reply": "ip_table_replace_begin_reply"
+ },
+ "ip_table_replace_end": {
+ "reply": "ip_table_replace_end_reply"
+ },
+ "ip_table_flush": {
+ "reply": "ip_table_flush_reply"
+ },
+ "ip_route_add_del": {
+ "reply": "ip_route_add_del_reply"
+ },
+ "ip_route_dump": {
+ "reply": "ip_route_details",
+ "stream": true
+ },
+ "ip_route_lookup": {
+ "reply": "ip_route_lookup_reply"
+ },
+ "set_ip_flow_hash": {
+ "reply": "set_ip_flow_hash_reply"
+ },
+ "set_ip_flow_hash_v2": {
+ "reply": "set_ip_flow_hash_v2_reply"
+ },
+ "set_ip_flow_hash_router_id": {
+ "reply": "set_ip_flow_hash_router_id_reply"
+ },
+ "sw_interface_ip6_enable_disable": {
+ "reply": "sw_interface_ip6_enable_disable_reply"
+ },
+ "ip_mtable_dump": {
+ "reply": "ip_mtable_details",
+ "stream": true
+ },
+ "ip_mroute_add_del": {
+ "reply": "ip_mroute_add_del_reply"
+ },
+ "ip_mroute_dump": {
+ "reply": "ip_mroute_details",
+ "stream": true
+ },
+ "ip_address_dump": {
+ "reply": "ip_address_details",
+ "stream": true
+ },
+ "ip_unnumbered_dump": {
+ "reply": "ip_unnumbered_details",
+ "stream": true
+ },
+ "ip_dump": {
+ "reply": "ip_details",
+ "stream": true
+ },
+ "mfib_signal_dump": {
+ "reply": "mfib_signal_details",
+ "stream": true
+ },
+ "ip_punt_police": {
+ "reply": "ip_punt_police_reply"
+ },
+ "ip_punt_redirect": {
+ "reply": "ip_punt_redirect_reply"
+ },
+ "ip_punt_redirect_dump": {
+ "reply": "ip_punt_redirect_details",
+ "stream": true
+ },
+ "ip_container_proxy_add_del": {
+ "reply": "ip_container_proxy_add_del_reply"
+ },
+ "ip_container_proxy_dump": {
+ "reply": "ip_container_proxy_details",
+ "stream": true
+ },
+ "ip_source_and_port_range_check_add_del": {
+ "reply": "ip_source_and_port_range_check_add_del_reply"
+ },
+ "ip_source_and_port_range_check_interface_add_del": {
+ "reply": "ip_source_and_port_range_check_interface_add_del_reply"
+ },
+ "sw_interface_ip6_set_link_local_address": {
+ "reply": "sw_interface_ip6_set_link_local_address_reply"
+ },
+ "sw_interface_ip6_get_link_local_address": {
+ "reply": "sw_interface_ip6_get_link_local_address_reply"
+ },
+ "ioam_enable": {
+ "reply": "ioam_enable_reply"
+ },
+ "ioam_disable": {
+ "reply": "ioam_disable_reply"
+ },
+ "ip_reassembly_set": {
+ "reply": "ip_reassembly_set_reply"
+ },
+ "ip_reassembly_get": {
+ "reply": "ip_reassembly_get_reply"
+ },
+ "ip_reassembly_enable_disable": {
+ "reply": "ip_reassembly_enable_disable_reply"
+ }
+ },
+ "options": {
+ "version": "3.0.3"
+ },
+ "aliases": {
+ "interface_index": {
+ "type": "u32"
+ },
+ "ip4_address": {
+ "type": "u8",
+ "length": 4
+ },
+ "ip6_address": {
+ "type": "u8",
+ "length": 16
+ },
+ "address_with_prefix": {
+ "type": "vl_api_prefix_t"
+ },
+ "ip4_address_with_prefix": {
+ "type": "vl_api_ip4_prefix_t"
+ },
+ "ip6_address_with_prefix": {
+ "type": "vl_api_ip6_prefix_t"
+ },
+ "mac_address": {
+ "type": "u8",
+ "length": 6
+ }
+ },
+ "vl_api_version": "0xf2f5f4e"
}
diff --git a/binapigen/vppapi/testdata/union.api.json b/binapigen/vppapi/testdata/union.api.json
new file mode 100644
index 0000000..0811f22
--- /dev/null
+++ b/binapigen/vppapi/testdata/union.api.json
@@ -0,0 +1,231 @@
+{
+ "services": [],
+ "vl_api_version": "0x1db2ece9",
+ "enums": [
+ [
+ "enum1",
+ [
+ "ENUM_1_VALUE_1",
+ 1
+ ],
+ [
+ "ENUM_1_VALUE_2",
+ 2
+ ],
+ {
+ "enumtype": "u16"
+ }
+ ],
+ [
+ "enum2",
+ [
+ "ENUM_2_VALUE_1",
+ 10
+ ],
+ [
+ "ENUM_2_VALUE_2",
+ 20
+ ],
+ {
+ "enumtype": "u32"
+ }
+ ]
+ ],
+ "messages": [],
+ "types": [
+ [
+ "type1",
+ [
+ "u8",
+ "field1",
+ 16
+ ],
+ [
+ "u8",
+ "field2",
+ 16
+ ]
+ ],
+ [
+ "type2",
+ [
+ "u16",
+ "field1"
+ ],
+ [
+ "u32",
+ "field2"
+ ],
+ [
+ "u32",
+ "field3"
+ ]
+ ],
+ [
+ "type3",
+ [
+ "u8",
+ "field1",
+ 64
+ ]
+ ],
+ [
+ "type4",
+ [
+ "u8",
+ "field1"
+ ],
+ [
+ "u8",
+ "field2",
+ 16
+ ]
+ ],
+ [
+ "type5",
+ [
+ "u32",
+ "field1"
+ ],
+ [
+ "union5",
+ "field2"
+ ]
+ ],
+ [
+ "type6",
+ [
+ "u16",
+ "field1"
+ ],
+ [
+ "u32",
+ "field2"
+ ],
+ [
+ "type4",
+ "field3"
+ ],
+ [
+ "u16",
+ "field4"
+ ],
+ [
+ "u32",
+ "field5"
+ ],
+ [
+ "u32",
+ "field6"
+ ]
+ ],
+ [
+ "complex_type",
+ [
+ "u32",
+ "field1"
+ ],
+ [
+ "u8",
+ "field2"
+ ],
+ [
+ "u8",
+ "field3"
+ ],
+ [
+ "u32",
+ "field4"
+ ],
+ [
+ "type5",
+ "field5"
+ ],
+ [
+ "type6",
+ "field6"
+ ]
+ ]
+ ],
+ "unions": [
+ [
+ "union1",
+ [
+ "vl_api_alias1_t",
+ "alias1"
+ ],
+ [
+ "vl_api_alias2_t",
+ "alias2"
+ ]
+ ],
+ [
+ "union2",
+ [
+ "vl_api_enum1_t",
+ "enum1"
+ ],
+ [
+ "vl_api_enum2_t",
+ "enum2"
+ ]
+ ],
+ [
+ "union3",
+ [
+ "vl_api_type1_t",
+ "type1"
+ ],
+ [
+ "vl_api_type2_t",
+ "type2"
+ ]
+ ],
+ [
+ "union4",
+ [
+ "vl_api_union1_t",
+ "union1"
+ ],
+ [
+ "vl_api_union2_t",
+ "union2"
+ ]
+ ],
+ [
+ "union5",
+ [
+ "vl_api_type1_t",
+ "type1"
+ ],
+ [
+ "vl_api_type3_t",
+ "type3"
+ ]
+ ],
+ [
+ "union6",
+ [
+ "vl_api_type1_t",
+ "type1"
+ ],
+ [
+ "vl_api_complex_type_t",
+ "type3"
+ ]
+ ]
+ ],
+ "aliases": {
+ "alias1": {
+ "type": "u8",
+ "length": 4
+ },
+ "alias2": {
+ "type": "u8",
+ "length": 16
+ },
+ "alias3": {
+ "type": "u32"
+ }
+ }
+}
diff --git a/binapigen/vppapi/util.go b/binapigen/vppapi/util.go
index 87f2e55..1374bb9 100644
--- a/binapigen/vppapi/util.go
+++ b/binapigen/vppapi/util.go
@@ -26,7 +26,9 @@ import (
)
const (
- VPPVersionEnvVar = "VPP_VERSION"
+ VPPVersionEnvVar = "VPP_VERSION"
+ VPPDirEnvVar = "VPP_DIR"
+ versionScriptPath = "./src/scripts/version"
)
// ResolveVPPVersion resolves version of the VPP for target directory.
@@ -35,17 +37,17 @@ const (
func ResolveVPPVersion(apidir string) string {
// check env variable override
if ver := os.Getenv(VPPVersionEnvVar); ver != "" {
- logrus.Debugf("VPP version was manually set to %q via %s env var", ver, VPPVersionEnvVar)
+ logrus.Infof("VPP version was manually set to %q via %s env var", ver, VPPVersionEnvVar)
return ver
}
// assuming VPP package is installed
- if path.Clean(apidir) == DefaultDir {
+ if _, err := exec.LookPath("vpp"); err == nil {
version, err := GetVPPVersionInstalled()
if err != nil {
logrus.Warnf("resolving VPP version from installed package failed: %v", err)
} else {
- logrus.Debugf("resolved VPP version from installed package: %v", version)
+ logrus.Infof("resolved VPP version from installed package: %v", version)
return version
}
}
@@ -60,7 +62,7 @@ func ResolveVPPVersion(apidir string) string {
if err != nil {
logrus.Warnf("resolving VPP version from version script failed: %v", err)
} else {
- logrus.Debugf("resolved VPP version from version script: %v", version)
+ logrus.Infof("resolved VPP version from version script: %v", version)
return version
}
}
@@ -85,14 +87,13 @@ func GetVPPVersionInstalled() (string, error) {
return strings.TrimSpace(string(out)), nil
}
-const versionScriptPath = "./src/scripts/version"
-
// GetVPPVersionRepo retrieves VPP version using script in repo directory.
func GetVPPVersionRepo(repoDir string) (string, error) {
- if _, err := os.Stat(versionScriptPath); err != nil {
+ scriptPath := path.Join(repoDir, versionScriptPath)
+ if _, err := os.Stat(scriptPath); err != nil {
return "", err
}
- cmd := exec.Command(versionScriptPath)
+ cmd := exec.Command(scriptPath)
cmd.Dir = repoDir
out, err := cmd.CombinedOutput()
if err != nil {
@@ -102,6 +103,10 @@ func GetVPPVersionRepo(repoDir string) (string, error) {
}
func findGitRepoRootDir(dir string) (string, error) {
+ if conf := os.Getenv(VPPDirEnvVar); conf != "" {
+ logrus.Infof("VPP directory was manually set to %q via %s env var", conf, VPPDirEnvVar)
+ return conf, nil
+ }
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
cmd.Dir = dir
out, err := cmd.CombinedOutput()
diff --git a/binapigen/vppapi/vppapi.go b/binapigen/vppapi/vppapi.go
index 665fa81..b54d287 100644
--- a/binapigen/vppapi/vppapi.go
+++ b/binapigen/vppapi/vppapi.go
@@ -24,6 +24,9 @@ import (
const (
// DefaultDir is default location of API files.
DefaultDir = "/usr/share/vpp/api"
+
+ // APIFileExtension is a VPP API file extension suffix
+ APIFileExtension = ".api.json"
)
// FindFiles finds API files located in dir or in a nested directory that is not nested deeper than deep.
@@ -40,7 +43,7 @@ func FindFiles(dir string, deep int) (files []string, err error) {
} else {
files = append(files, nested...)
}
- } else if !e.IsDir() && strings.HasSuffix(e.Name(), ".api.json") {
+ } else if !e.IsDir() && strings.HasSuffix(e.Name(), APIFileExtension) {
files = append(files, filepath.Join(dir, e.Name()))
}
}
@@ -54,13 +57,13 @@ func Parse() ([]*File, error) {
// ParseDir finds and parses API files in given directory and returns parsed files.
// Supports API files in JSON format (.api.json) only.
-func ParseDir(apidir string) ([]*File, error) {
- list, err := FindFiles(apidir, 1)
+func ParseDir(apiDir string) ([]*File, error) {
+ list, err := FindFiles(apiDir, 1)
if err != nil {
return nil, err
}
- logf("found %d files in API dir %q", len(list), apidir)
+ logf("found %d files in API dir %q", len(list), apiDir)
var files []*File
for _, file := range list {
@@ -74,17 +77,17 @@ func ParseDir(apidir string) ([]*File, error) {
}
// ParseFile parses API file and returns File.
-func ParseFile(apifile string) (*File, error) {
- if !strings.HasSuffix(apifile, ".api.json") {
- return nil, fmt.Errorf("unsupported file format: %q", apifile)
+func ParseFile(apiFile string) (*File, error) {
+ if !strings.HasSuffix(apiFile, APIFileExtension) {
+ return nil, fmt.Errorf("unsupported file format: %q", apiFile)
}
- data, err := ioutil.ReadFile(apifile)
+ data, err := ioutil.ReadFile(apiFile)
if err != nil {
- return nil, fmt.Errorf("reading file %s failed: %v", apifile, err)
+ return nil, fmt.Errorf("reading file %s failed: %v", apiFile, err)
}
- base := filepath.Base(apifile)
+ base := filepath.Base(apiFile)
name := base[:strings.Index(base, ".")]
logf("parsing file %q", base)
@@ -94,7 +97,7 @@ func ParseFile(apifile string) (*File, error) {
return nil, fmt.Errorf("parsing file %s failed: %v", base, err)
}
module.Name = name
- module.Path = apifile
+ module.Path = apiFile
return module, nil
}
diff --git a/binapigen/vppapi/vppapi_test.go b/binapigen/vppapi/vppapi_test.go
index 027cc1f..a555d9f 100644
--- a/binapigen/vppapi/vppapi_test.go
+++ b/binapigen/vppapi/vppapi_test.go
@@ -27,7 +27,7 @@ func TestGetInputFiles(t *testing.T) {
result, err := FindFiles("testdata", 1)
Expect(err).ShouldNot(HaveOccurred())
- Expect(result).To(HaveLen(5))
+ Expect(result).To(HaveLen(6))
for _, file := range result {
Expect(file).To(BeAnExistingFile())
}