diff --git a/clientv2/linux/data_change_api.go b/clientv2/linux/data_change_api.go index aa01e7a0d0..97766a6fd5 100644 --- a/clientv2/linux/data_change_api.go +++ b/clientv2/linux/data_change_api.go @@ -22,6 +22,7 @@ import ( vpp_abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" vpp_acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" vpp_l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" vpp_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -125,6 +126,12 @@ type PutDSL interface { PuntToHost(val *punt.ToHost) PutDSL // PuntException adds request to create or update exception to punt specific packets. PuntException(val *punt.Exception) PutDSL + // IPFIX adds a request to update VPP IP Flow Information eXport configuration. + IPFIX(val *ipfix.IPFIX) PutDSL + // FlowprobeParams adds a request to update VPP Flowprobe Params. + FlowprobeParams(val *ipfix.FlowProbeParams) PutDSL + // FlowprobeFeature adds a request to enable Flowprobe Feature on interface. + FlowprobeFeature(val *ipfix.FlowProbeFeature) PutDSL // Delete changes the DSL mode to allow removing an existing configuration. // See documentation for DataChangeDSL.Delete(). @@ -208,6 +215,8 @@ type DeleteDSL interface { PuntToHost(l3Proto punt.L3Protocol, l4Proto punt.L4Protocol, port uint32) DeleteDSL // PuntException adds request to delete exception to punt specific packets. PuntException(reason string) DeleteDSL + // FlowprobeFeature adds a request to disable Flowprobe Feature on interface. + FlowprobeFeature(val *ipfix.FlowProbeFeature) DeleteDSL // Put changes the DSL mode to allow configuration editing. // See documentation for DataChangeDSL.Put(). diff --git a/clientv2/linux/data_resync_api.go b/clientv2/linux/data_resync_api.go index 2d34ff214a..aa3e223430 100644 --- a/clientv2/linux/data_resync_api.go +++ b/clientv2/linux/data_resync_api.go @@ -22,6 +22,7 @@ import ( vpp_abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" vpp_acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" vpp_l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" vpp_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -105,6 +106,12 @@ type DataResyncDSL interface { PuntToHost(val *punt.ToHost) DataResyncDSL // PuntException adds request to create or update exception to punt specific packets. PuntException(val *punt.Exception) DataResyncDSL + // IPFIX adds IPFIX configuration to the RESYNC request. + IPFIX(val *ipfix.IPFIX) DataResyncDSL + // FlowprobeParams adds Flowprobe Params configuration to the RESYNC request. + FlowprobeParams(val *ipfix.FlowProbeParams) DataResyncDSL + // FlowprobeFeature adds Flowprobe Feature configuration to the RESYNC request. + FlowprobeFeature(val *ipfix.FlowProbeFeature) DataResyncDSL // Send propagates the RESYNC request to the plugins. Send() vpp_clientv2.Reply diff --git a/clientv2/linux/dbadapter/data_change_db.go b/clientv2/linux/dbadapter/data_change_db.go index 94547574b1..ec4232942a 100644 --- a/clientv2/linux/dbadapter/data_change_db.go +++ b/clientv2/linux/dbadapter/data_change_db.go @@ -27,6 +27,7 @@ import ( abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -275,6 +276,24 @@ func (dsl *PutDSL) PuntException(val *punt.Exception) linuxclient.PutDSL { return dsl } +// IPFIX adds a request to update VPP IP Flow Information eXport configuration. +func (dsl *PutDSL) IPFIX(val *ipfix.IPFIX) linuxclient.PutDSL { + dsl.parent.txn.Put(models.Key(val), val) + return dsl +} + +// FlowprobeParams adds a request to update VPP Flowprobe Params. +func (dsl *PutDSL) FlowprobeParams(val *ipfix.FlowProbeParams) linuxclient.PutDSL { + dsl.parent.txn.Put(models.Key(val), val) + return dsl +} + +// FlowprobeFeature adds a request to enable Flowprobe Feature on interface. +func (dsl *PutDSL) FlowprobeFeature(val *ipfix.FlowProbeFeature) linuxclient.PutDSL { + dsl.parent.txn.Put(models.Key(val), val) + return dsl +} + // Delete changes the DSL mode to allow removal of an existing configuration. func (dsl *PutDSL) Delete() linuxclient.DeleteDSL { return &DeleteDSL{dsl.parent, dsl.vppPut.Delete()} @@ -482,6 +501,12 @@ func (dsl *DeleteDSL) PuntException(reason string) linuxclient.DeleteDSL { return dsl } +// FlowprobeFeature adds a request to disable Flowprobe Feature on interface. +func (dsl *DeleteDSL) FlowprobeFeature(val *ipfix.FlowProbeFeature) linuxclient.DeleteDSL { + dsl.parent.txn.Delete(models.Key(val)) + return dsl +} + // Put changes the DSL mode to allow configuration editing. func (dsl *DeleteDSL) Put() linuxclient.PutDSL { return &PutDSL{dsl.parent, dsl.vppDelete.Put()} diff --git a/clientv2/linux/dbadapter/data_resync_db.go b/clientv2/linux/dbadapter/data_resync_db.go index cf4b4f98a7..0642bdf707 100644 --- a/clientv2/linux/dbadapter/data_resync_db.go +++ b/clientv2/linux/dbadapter/data_resync_db.go @@ -27,6 +27,7 @@ import ( abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -272,6 +273,33 @@ func (dsl *DataResyncDSL) PuntException(val *punt.Exception) linuxclient.DataRes return dsl } +// IPFIX adds IPFIX configuration to the RESYNC request. +func (dsl *DataResyncDSL) IPFIX(val *ipfix.IPFIX) linuxclient.DataResyncDSL { + key := models.Key(val) + dsl.txn.Put(key, val) + dsl.txnKeys = append(dsl.txnKeys, key) + + return dsl +} + +// FlowprobeParams adds Flowprobe Params configuration to the RESYNC request. +func (dsl *DataResyncDSL) FlowprobeParams(val *ipfix.FlowProbeParams) linuxclient.DataResyncDSL { + key := models.Key(val) + dsl.txn.Put(key, val) + dsl.txnKeys = append(dsl.txnKeys, key) + + return dsl +} + +// FlowprobeFeature adds Flowprobe Feature configuration to the RESYNC request. +func (dsl *DataResyncDSL) FlowprobeFeature(val *ipfix.FlowProbeFeature) linuxclient.DataResyncDSL { + key := models.Key(val) + dsl.txn.Put(key, val) + dsl.txnKeys = append(dsl.txnKeys, key) + + return dsl +} + // AppendKeys is a helper function that fills the keySet with values // pointed to by the iterator . func appendKeys(keys *keySet, it keyval.ProtoKeyIterator) { diff --git a/clientv2/vpp/data_change_api.go b/clientv2/vpp/data_change_api.go index 8b54a70657..1f8985fc84 100644 --- a/clientv2/vpp/data_change_api.go +++ b/clientv2/vpp/data_change_api.go @@ -18,6 +18,7 @@ import ( abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -99,6 +100,12 @@ type PutDSL interface { PuntToHost(val *punt.ToHost) PutDSL // PuntException adds request to create or update exception to punt specific packets. PuntException(val *punt.Exception) PutDSL + // IPFIX adds a request to update VPP IP Flow Information eXport configuration. + IPFIX(val *ipfix.IPFIX) PutDSL + // FlowprobeParams adds a request to update VPP Flowprobe Params. + FlowprobeParams(val *ipfix.FlowProbeParams) PutDSL + // FlowprobeFeature adds a request to enable Flowprobe Feature on interface. + FlowprobeFeature(val *ipfix.FlowProbeFeature) PutDSL // Delete changes the DSL mode to allow removal of an existing configuration. // See documentation for DataChangeDSL.Delete(). @@ -158,6 +165,8 @@ type DeleteDSL interface { PuntToHost(l3Proto punt.L3Protocol, l4Proto punt.L4Protocol, port uint32) DeleteDSL // PuntException adds request to delete exception to punt specific packets. PuntException(reason string) DeleteDSL + // FlowprobeFeature adds a request to disable Flowprobe Feature on interface. + FlowprobeFeature(val *ipfix.FlowProbeFeature) DeleteDSL // Put changes the DSL mode to allow configuration editing. // See documentation for DataChangeDSL.Put(). diff --git a/clientv2/vpp/data_resync_api.go b/clientv2/vpp/data_resync_api.go index d783b16037..6a05e0c8df 100644 --- a/clientv2/vpp/data_resync_api.go +++ b/clientv2/vpp/data_resync_api.go @@ -18,6 +18,7 @@ import ( abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -79,6 +80,12 @@ type DataResyncDSL interface { PuntToHost(val *punt.ToHost) DataResyncDSL // PuntException adds request to create or update exception to punt specific packets. PuntException(val *punt.Exception) DataResyncDSL + // IPFIX adds IPFIX configuration to the RESYNC request. + IPFIX(val *ipfix.IPFIX) DataResyncDSL + // FlowprobeParams adds Flowprobe Params configuration to the RESYNC request. + FlowprobeParams(val *ipfix.FlowProbeParams) DataResyncDSL + // FlowprobeFeature adds Flowprobe Feature configuration to the RESYNC request. + FlowprobeFeature(val *ipfix.FlowProbeFeature) DataResyncDSL // Send propagates the RESYNC request to the plugins. Send() Reply diff --git a/clientv2/vpp/dbadapter/data_change_db.go b/clientv2/vpp/dbadapter/data_change_db.go index fd1c4a1ec8..9847853305 100644 --- a/clientv2/vpp/dbadapter/data_change_db.go +++ b/clientv2/vpp/dbadapter/data_change_db.go @@ -26,6 +26,7 @@ import ( abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" intf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -216,6 +217,24 @@ func (dsl *PutDSL) PuntException(val *punt.Exception) vppclient.PutDSL { return dsl } +// IPFIX adds a request to update VPP IP Flow Information eXport configuration. +func (dsl *PutDSL) IPFIX(val *ipfix.IPFIX) vppclient.PutDSL { + dsl.parent.txn.Put(models.Key(val), val) + return dsl +} + +// FlowprobeParams adds a request to update VPP Flowprobe Params. +func (dsl *PutDSL) FlowprobeParams(val *ipfix.FlowProbeParams) vppclient.PutDSL { + dsl.parent.txn.Put(models.Key(val), val) + return dsl +} + +// FlowprobeFeature adds a request to enable Flowprobe Feature on interface. +func (dsl *PutDSL) FlowprobeFeature(val *ipfix.FlowProbeFeature) vppclient.PutDSL { + dsl.parent.txn.Put(models.Key(val), val) + return dsl +} + // Delete changes the DSL mode to allow removal of an existing configuration. func (dsl *PutDSL) Delete() vppclient.DeleteDSL { return &DeleteDSL{dsl.parent} @@ -366,6 +385,12 @@ func (dsl *DeleteDSL) PuntException(reason string) vppclient.DeleteDSL { return dsl } +// FlowprobeFeature adds a request to disable Flowprobe Feature on interface. +func (dsl *DeleteDSL) FlowprobeFeature(val *ipfix.FlowProbeFeature) vppclient.DeleteDSL { + dsl.parent.txn.Delete(models.Key(val)) + return dsl +} + // Put changes the DSL mode to allow configuration editing. func (dsl *DeleteDSL) Put() vppclient.PutDSL { return &PutDSL{dsl.parent} diff --git a/clientv2/vpp/dbadapter/data_resync_db.go b/clientv2/vpp/dbadapter/data_resync_db.go index e0ff24d5ca..183aba8473 100644 --- a/clientv2/vpp/dbadapter/data_resync_db.go +++ b/clientv2/vpp/dbadapter/data_resync_db.go @@ -26,6 +26,7 @@ import ( abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" intf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" @@ -256,6 +257,33 @@ func (dsl *DataResyncDSL) PuntException(val *punt.Exception) vppclient.DataResyn return dsl } +// IPFIX adds IPFIX configuration to the RESYNC request. +func (dsl *DataResyncDSL) IPFIX(val *ipfix.IPFIX) vppclient.DataResyncDSL { + key := models.Key(val) + dsl.txn.Put(key, val) + dsl.txnKeys = append(dsl.txnKeys, key) + + return dsl +} + +// FlowprobeParams adds Flowprobe Params configuration to the RESYNC request. +func (dsl *DataResyncDSL) FlowprobeParams(val *ipfix.FlowProbeParams) vppclient.DataResyncDSL { + key := models.Key(val) + dsl.txn.Put(key, val) + dsl.txnKeys = append(dsl.txnKeys, key) + + return dsl +} + +// FlowprobeFeature adds Flowprobe Feature configuration to the RESYNC request. +func (dsl *DataResyncDSL) FlowprobeFeature(val *ipfix.FlowProbeFeature) vppclient.DataResyncDSL { + key := models.Key(val) + dsl.txn.Put(key, val) + dsl.txnKeys = append(dsl.txnKeys, key) + + return dsl +} + // AppendKeys is a helper function that fills the keySet with values // pointed to by the iterator . func appendKeys(keys *keySet, it keyval.ProtoKeyIterator) { diff --git a/cmd/vpp-agent/app/vpp_agent.go b/cmd/vpp-agent/app/vpp_agent.go index 9762a7f4d4..98c4356240 100644 --- a/cmd/vpp-agent/app/vpp_agent.go +++ b/cmd/vpp-agent/app/vpp_agent.go @@ -41,6 +41,7 @@ import ( "go.ligato.io/vpp-agent/v3/plugins/vpp/abfplugin" "go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin" "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin" "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin" "go.ligato.io/vpp-agent/v3/plugins/vpp/l2plugin" "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin" @@ -172,6 +173,7 @@ type VPP struct { ABFPlugin *abfplugin.ABFPlugin ACLPlugin *aclplugin.ACLPlugin IfPlugin *ifplugin.IfPlugin + IPFIXPlugin *ipfixplugin.IPFIXPlugin IPSecPlugin *ipsecplugin.IPSecPlugin L2Plugin *l2plugin.L2Plugin L3Plugin *l3plugin.L3Plugin @@ -186,6 +188,7 @@ func DefaultVPP() VPP { ABFPlugin: &abfplugin.DefaultPlugin, ACLPlugin: &aclplugin.DefaultPlugin, IfPlugin: &ifplugin.DefaultPlugin, + IPFIXPlugin: &ipfixplugin.DefaultPlugin, IPSecPlugin: &ipsecplugin.DefaultPlugin, L2Plugin: &l2plugin.DefaultPlugin, L3Plugin: &l3plugin.DefaultPlugin, diff --git a/plugins/vpp/binapi/vpp1904/flowprobe/flowprobe.ba.go b/plugins/vpp/binapi/vpp1904/flowprobe/flowprobe.ba.go new file mode 100644 index 0000000000..93a9f32fee --- /dev/null +++ b/plugins/vpp/binapi/vpp1904/flowprobe/flowprobe.ba.go @@ -0,0 +1,140 @@ +// Code generated by GoVPP's binapi-generator. DO NOT EDIT. +// source: /usr/share/vpp/api/plugins/flowprobe.api.json + +/* +Package flowprobe is a generated VPP binary API for 'flowprobe' module. + +It consists of: + 4 messages + 2 services +*/ +package flowprobe + +import ( + bytes "bytes" + context "context" + api "git.fd.io/govpp.git/api" + struc "github.com/lunixbochs/struc" + io "io" + strconv "strconv" +) + +const ( + // ModuleName is the name of this module. + ModuleName = "flowprobe" + // APIVersion is the API version of this module. + APIVersion = "1.0.0" + // VersionCrc is the CRC of this module. + VersionCrc = 0x8c36cb50 +) + +// FlowprobeParams represents VPP binary API message 'flowprobe_params'. +type FlowprobeParams struct { + RecordL2 uint8 + RecordL3 uint8 + RecordL4 uint8 + ActiveTimer uint32 + PassiveTimer uint32 +} + +func (m *FlowprobeParams) Reset() { *m = FlowprobeParams{} } +func (*FlowprobeParams) GetMessageName() string { return "flowprobe_params" } +func (*FlowprobeParams) GetCrcString() string { return "574adc1c" } +func (*FlowprobeParams) GetMessageType() api.MessageType { return api.RequestMessage } + +// FlowprobeParamsReply represents VPP binary API message 'flowprobe_params_reply'. +type FlowprobeParamsReply struct { + Retval int32 +} + +func (m *FlowprobeParamsReply) Reset() { *m = FlowprobeParamsReply{} } +func (*FlowprobeParamsReply) GetMessageName() string { return "flowprobe_params_reply" } +func (*FlowprobeParamsReply) GetCrcString() string { return "e8d4e804" } +func (*FlowprobeParamsReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// FlowprobeTxInterfaceAddDel represents VPP binary API message 'flowprobe_tx_interface_add_del'. +type FlowprobeTxInterfaceAddDel struct { + IsAdd uint8 + Which uint8 + SwIfIndex uint32 +} + +func (m *FlowprobeTxInterfaceAddDel) Reset() { *m = FlowprobeTxInterfaceAddDel{} } +func (*FlowprobeTxInterfaceAddDel) GetMessageName() string { return "flowprobe_tx_interface_add_del" } +func (*FlowprobeTxInterfaceAddDel) GetCrcString() string { return "10c2fbab" } +func (*FlowprobeTxInterfaceAddDel) GetMessageType() api.MessageType { return api.RequestMessage } + +// FlowprobeTxInterfaceAddDelReply represents VPP binary API message 'flowprobe_tx_interface_add_del_reply'. +type FlowprobeTxInterfaceAddDelReply struct { + Retval int32 +} + +func (m *FlowprobeTxInterfaceAddDelReply) Reset() { *m = FlowprobeTxInterfaceAddDelReply{} } +func (*FlowprobeTxInterfaceAddDelReply) GetMessageName() string { + return "flowprobe_tx_interface_add_del_reply" +} +func (*FlowprobeTxInterfaceAddDelReply) GetCrcString() string { return "e8d4e804" } +func (*FlowprobeTxInterfaceAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +func init() { + api.RegisterMessage((*FlowprobeParams)(nil), "flowprobe.FlowprobeParams") + api.RegisterMessage((*FlowprobeParamsReply)(nil), "flowprobe.FlowprobeParamsReply") + api.RegisterMessage((*FlowprobeTxInterfaceAddDel)(nil), "flowprobe.FlowprobeTxInterfaceAddDel") + api.RegisterMessage((*FlowprobeTxInterfaceAddDelReply)(nil), "flowprobe.FlowprobeTxInterfaceAddDelReply") +} + +// Messages returns list of all messages in this module. +func AllMessages() []api.Message { + return []api.Message{ + (*FlowprobeParams)(nil), + (*FlowprobeParamsReply)(nil), + (*FlowprobeTxInterfaceAddDel)(nil), + (*FlowprobeTxInterfaceAddDelReply)(nil), + } +} + +// RPCService represents RPC service API for flowprobe module. +type RPCService interface { + FlowprobeParams(ctx context.Context, in *FlowprobeParams) (*FlowprobeParamsReply, error) + FlowprobeTxInterfaceAddDel(ctx context.Context, in *FlowprobeTxInterfaceAddDel) (*FlowprobeTxInterfaceAddDelReply, error) +} + +type serviceClient struct { + ch api.Channel +} + +func NewServiceClient(ch api.Channel) RPCService { + return &serviceClient{ch} +} + +func (c *serviceClient) FlowprobeParams(ctx context.Context, in *FlowprobeParams) (*FlowprobeParamsReply, error) { + out := new(FlowprobeParamsReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) FlowprobeTxInterfaceAddDel(ctx context.Context, in *FlowprobeTxInterfaceAddDel) (*FlowprobeTxInterfaceAddDelReply, error) { + out := new(FlowprobeTxInterfaceAddDelReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the GoVPP api package it is being compiled against. +// A compilation error at this line likely means your copy of the +// GoVPP api package needs to be updated. +const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package + +// Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage +var _ = bytes.NewBuffer +var _ = context.Background +var _ = io.Copy +var _ = strconv.Itoa +var _ = struc.Pack diff --git a/plugins/vpp/binapi/vpp1904/ipfix_export/ipfix_export.ba.go b/plugins/vpp/binapi/vpp1904/ipfix_export/ipfix_export.ba.go new file mode 100644 index 0000000000..ddf295ce9c --- /dev/null +++ b/plugins/vpp/binapi/vpp1904/ipfix_export/ipfix_export.ba.go @@ -0,0 +1,334 @@ +// Code generated by GoVPP's binapi-generator. DO NOT EDIT. +// source: /usr/share/vpp/api/core/ipfix_export.api.json + +/* +Package ipfix_export is a generated VPP binary API for 'ipfix_export' module. + +It consists of: + 12 messages + 6 services +*/ +package ipfix_export + +import ( + bytes "bytes" + context "context" + api "git.fd.io/govpp.git/api" + struc "github.com/lunixbochs/struc" + io "io" + strconv "strconv" +) + +const ( + // ModuleName is the name of this module. + ModuleName = "ipfix_export" + // APIVersion is the API version of this module. + APIVersion = "1.0.0" + // VersionCrc is the CRC of this module. + VersionCrc = 0x3e08644f +) + +// IpfixClassifyStreamDetails represents VPP binary API message 'ipfix_classify_stream_details'. +type IpfixClassifyStreamDetails struct { + DomainID uint32 + SrcPort uint16 +} + +func (m *IpfixClassifyStreamDetails) Reset() { *m = IpfixClassifyStreamDetails{} } +func (*IpfixClassifyStreamDetails) GetMessageName() string { return "ipfix_classify_stream_details" } +func (*IpfixClassifyStreamDetails) GetCrcString() string { return "2903539d" } +func (*IpfixClassifyStreamDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyStreamDump represents VPP binary API message 'ipfix_classify_stream_dump'. +type IpfixClassifyStreamDump struct{} + +func (m *IpfixClassifyStreamDump) Reset() { *m = IpfixClassifyStreamDump{} } +func (*IpfixClassifyStreamDump) GetMessageName() string { return "ipfix_classify_stream_dump" } +func (*IpfixClassifyStreamDump) GetCrcString() string { return "51077d14" } +func (*IpfixClassifyStreamDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixClassifyTableAddDel represents VPP binary API message 'ipfix_classify_table_add_del'. +type IpfixClassifyTableAddDel struct { + TableID uint32 + IPVersion uint8 + TransportProtocol uint8 + IsAdd uint8 +} + +func (m *IpfixClassifyTableAddDel) Reset() { *m = IpfixClassifyTableAddDel{} } +func (*IpfixClassifyTableAddDel) GetMessageName() string { return "ipfix_classify_table_add_del" } +func (*IpfixClassifyTableAddDel) GetCrcString() string { return "48efe167" } +func (*IpfixClassifyTableAddDel) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixClassifyTableAddDelReply represents VPP binary API message 'ipfix_classify_table_add_del_reply'. +type IpfixClassifyTableAddDelReply struct { + Retval int32 +} + +func (m *IpfixClassifyTableAddDelReply) Reset() { *m = IpfixClassifyTableAddDelReply{} } +func (*IpfixClassifyTableAddDelReply) GetMessageName() string { + return "ipfix_classify_table_add_del_reply" +} +func (*IpfixClassifyTableAddDelReply) GetCrcString() string { return "e8d4e804" } +func (*IpfixClassifyTableAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyTableDetails represents VPP binary API message 'ipfix_classify_table_details'. +type IpfixClassifyTableDetails struct { + TableID uint32 + IPVersion uint8 + TransportProtocol uint8 +} + +func (m *IpfixClassifyTableDetails) Reset() { *m = IpfixClassifyTableDetails{} } +func (*IpfixClassifyTableDetails) GetMessageName() string { return "ipfix_classify_table_details" } +func (*IpfixClassifyTableDetails) GetCrcString() string { return "973d0d5b" } +func (*IpfixClassifyTableDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyTableDump represents VPP binary API message 'ipfix_classify_table_dump'. +type IpfixClassifyTableDump struct{} + +func (m *IpfixClassifyTableDump) Reset() { *m = IpfixClassifyTableDump{} } +func (*IpfixClassifyTableDump) GetMessageName() string { return "ipfix_classify_table_dump" } +func (*IpfixClassifyTableDump) GetCrcString() string { return "51077d14" } +func (*IpfixClassifyTableDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixExporterDetails represents VPP binary API message 'ipfix_exporter_details'. +type IpfixExporterDetails struct { + CollectorAddress []byte `struc:"[16]byte"` + CollectorPort uint16 + SrcAddress []byte `struc:"[16]byte"` + VrfID uint32 + PathMtu uint32 + TemplateInterval uint32 + UDPChecksum uint8 +} + +func (m *IpfixExporterDetails) Reset() { *m = IpfixExporterDetails{} } +func (*IpfixExporterDetails) GetMessageName() string { return "ipfix_exporter_details" } +func (*IpfixExporterDetails) GetCrcString() string { return "742dddee" } +func (*IpfixExporterDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixExporterDump represents VPP binary API message 'ipfix_exporter_dump'. +type IpfixExporterDump struct{} + +func (m *IpfixExporterDump) Reset() { *m = IpfixExporterDump{} } +func (*IpfixExporterDump) GetMessageName() string { return "ipfix_exporter_dump" } +func (*IpfixExporterDump) GetCrcString() string { return "51077d14" } +func (*IpfixExporterDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// SetIpfixClassifyStream represents VPP binary API message 'set_ipfix_classify_stream'. +type SetIpfixClassifyStream struct { + DomainID uint32 + SrcPort uint16 +} + +func (m *SetIpfixClassifyStream) Reset() { *m = SetIpfixClassifyStream{} } +func (*SetIpfixClassifyStream) GetMessageName() string { return "set_ipfix_classify_stream" } +func (*SetIpfixClassifyStream) GetCrcString() string { return "c9cbe053" } +func (*SetIpfixClassifyStream) GetMessageType() api.MessageType { return api.RequestMessage } + +// SetIpfixClassifyStreamReply represents VPP binary API message 'set_ipfix_classify_stream_reply'. +type SetIpfixClassifyStreamReply struct { + Retval int32 +} + +func (m *SetIpfixClassifyStreamReply) Reset() { *m = SetIpfixClassifyStreamReply{} } +func (*SetIpfixClassifyStreamReply) GetMessageName() string { return "set_ipfix_classify_stream_reply" } +func (*SetIpfixClassifyStreamReply) GetCrcString() string { return "e8d4e804" } +func (*SetIpfixClassifyStreamReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// SetIpfixExporter represents VPP binary API message 'set_ipfix_exporter'. +type SetIpfixExporter struct { + CollectorAddress []byte `struc:"[16]byte"` + CollectorPort uint16 + SrcAddress []byte `struc:"[16]byte"` + VrfID uint32 + PathMtu uint32 + TemplateInterval uint32 + UDPChecksum uint8 +} + +func (m *SetIpfixExporter) Reset() { *m = SetIpfixExporter{} } +func (*SetIpfixExporter) GetMessageName() string { return "set_ipfix_exporter" } +func (*SetIpfixExporter) GetCrcString() string { return "4ff71dea" } +func (*SetIpfixExporter) GetMessageType() api.MessageType { return api.RequestMessage } + +// SetIpfixExporterReply represents VPP binary API message 'set_ipfix_exporter_reply'. +type SetIpfixExporterReply struct { + Retval int32 +} + +func (m *SetIpfixExporterReply) Reset() { *m = SetIpfixExporterReply{} } +func (*SetIpfixExporterReply) GetMessageName() string { return "set_ipfix_exporter_reply" } +func (*SetIpfixExporterReply) GetCrcString() string { return "e8d4e804" } +func (*SetIpfixExporterReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +func init() { + api.RegisterMessage((*IpfixClassifyStreamDetails)(nil), "ipfix_export.IpfixClassifyStreamDetails") + api.RegisterMessage((*IpfixClassifyStreamDump)(nil), "ipfix_export.IpfixClassifyStreamDump") + api.RegisterMessage((*IpfixClassifyTableAddDel)(nil), "ipfix_export.IpfixClassifyTableAddDel") + api.RegisterMessage((*IpfixClassifyTableAddDelReply)(nil), "ipfix_export.IpfixClassifyTableAddDelReply") + api.RegisterMessage((*IpfixClassifyTableDetails)(nil), "ipfix_export.IpfixClassifyTableDetails") + api.RegisterMessage((*IpfixClassifyTableDump)(nil), "ipfix_export.IpfixClassifyTableDump") + api.RegisterMessage((*IpfixExporterDetails)(nil), "ipfix_export.IpfixExporterDetails") + api.RegisterMessage((*IpfixExporterDump)(nil), "ipfix_export.IpfixExporterDump") + api.RegisterMessage((*SetIpfixClassifyStream)(nil), "ipfix_export.SetIpfixClassifyStream") + api.RegisterMessage((*SetIpfixClassifyStreamReply)(nil), "ipfix_export.SetIpfixClassifyStreamReply") + api.RegisterMessage((*SetIpfixExporter)(nil), "ipfix_export.SetIpfixExporter") + api.RegisterMessage((*SetIpfixExporterReply)(nil), "ipfix_export.SetIpfixExporterReply") +} + +// Messages returns list of all messages in this module. +func AllMessages() []api.Message { + return []api.Message{ + (*IpfixClassifyStreamDetails)(nil), + (*IpfixClassifyStreamDump)(nil), + (*IpfixClassifyTableAddDel)(nil), + (*IpfixClassifyTableAddDelReply)(nil), + (*IpfixClassifyTableDetails)(nil), + (*IpfixClassifyTableDump)(nil), + (*IpfixExporterDetails)(nil), + (*IpfixExporterDump)(nil), + (*SetIpfixClassifyStream)(nil), + (*SetIpfixClassifyStreamReply)(nil), + (*SetIpfixExporter)(nil), + (*SetIpfixExporterReply)(nil), + } +} + +// RPCService represents RPC service API for ipfix_export module. +type RPCService interface { + DumpIpfixClassifyStream(ctx context.Context, in *IpfixClassifyStreamDump) (RPCService_DumpIpfixClassifyStreamClient, error) + DumpIpfixClassifyTable(ctx context.Context, in *IpfixClassifyTableDump) (RPCService_DumpIpfixClassifyTableClient, error) + DumpIpfixExporter(ctx context.Context, in *IpfixExporterDump) (RPCService_DumpIpfixExporterClient, error) + IpfixClassifyTableAddDel(ctx context.Context, in *IpfixClassifyTableAddDel) (*IpfixClassifyTableAddDelReply, error) + SetIpfixClassifyStream(ctx context.Context, in *SetIpfixClassifyStream) (*SetIpfixClassifyStreamReply, error) + SetIpfixExporter(ctx context.Context, in *SetIpfixExporter) (*SetIpfixExporterReply, error) +} + +type serviceClient struct { + ch api.Channel +} + +func NewServiceClient(ch api.Channel) RPCService { + return &serviceClient{ch} +} + +func (c *serviceClient) DumpIpfixClassifyStream(ctx context.Context, in *IpfixClassifyStreamDump) (RPCService_DumpIpfixClassifyStreamClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixClassifyStreamClient{stream} + return x, nil +} + +type RPCService_DumpIpfixClassifyStreamClient interface { + Recv() (*IpfixClassifyStreamDetails, error) +} + +type serviceClient_DumpIpfixClassifyStreamClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixClassifyStreamClient) Recv() (*IpfixClassifyStreamDetails, error) { + m := new(IpfixClassifyStreamDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) DumpIpfixClassifyTable(ctx context.Context, in *IpfixClassifyTableDump) (RPCService_DumpIpfixClassifyTableClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixClassifyTableClient{stream} + return x, nil +} + +type RPCService_DumpIpfixClassifyTableClient interface { + Recv() (*IpfixClassifyTableDetails, error) +} + +type serviceClient_DumpIpfixClassifyTableClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixClassifyTableClient) Recv() (*IpfixClassifyTableDetails, error) { + m := new(IpfixClassifyTableDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) DumpIpfixExporter(ctx context.Context, in *IpfixExporterDump) (RPCService_DumpIpfixExporterClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixExporterClient{stream} + return x, nil +} + +type RPCService_DumpIpfixExporterClient interface { + Recv() (*IpfixExporterDetails, error) +} + +type serviceClient_DumpIpfixExporterClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixExporterClient) Recv() (*IpfixExporterDetails, error) { + m := new(IpfixExporterDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) IpfixClassifyTableAddDel(ctx context.Context, in *IpfixClassifyTableAddDel) (*IpfixClassifyTableAddDelReply, error) { + out := new(IpfixClassifyTableAddDelReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) SetIpfixClassifyStream(ctx context.Context, in *SetIpfixClassifyStream) (*SetIpfixClassifyStreamReply, error) { + out := new(SetIpfixClassifyStreamReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) SetIpfixExporter(ctx context.Context, in *SetIpfixExporter) (*SetIpfixExporterReply, error) { + out := new(SetIpfixExporterReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the GoVPP api package it is being compiled against. +// A compilation error at this line likely means your copy of the +// GoVPP api package needs to be updated. +const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package + +// Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage +var _ = bytes.NewBuffer +var _ = context.Background +var _ = io.Copy +var _ = strconv.Itoa +var _ = struc.Pack diff --git a/plugins/vpp/binapi/vpp1904/vpp1904.go b/plugins/vpp/binapi/vpp1904/vpp1904.go index 762c93f5b7..45bcee53d6 100644 --- a/plugins/vpp/binapi/vpp1904/vpp1904.go +++ b/plugins/vpp/binapi/vpp1904/vpp1904.go @@ -22,10 +22,12 @@ import ( "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/af_packet" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/bond" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/dhcp" + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/flowprobe" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/gre" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/gtpu" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/interfaces" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/ip" + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/ipfix_export" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/ipsec" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/l2" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/memclnt" @@ -54,6 +56,7 @@ func init() { gre.AllMessages, interfaces.AllMessages, ip.AllMessages, + ipfix_export.AllMessages, ipsec.AllMessages, l2.AllMessages, memclnt.AllMessages, @@ -68,6 +71,7 @@ func init() { Plugins: vpp.Messages( abf.AllMessages, acl.AllMessages, + flowprobe.AllMessages, gtpu.AllMessages, memif.AllMessages, nat.AllMessages, @@ -85,6 +89,7 @@ func init() { //go:generate binapigen --input-file=$VPP_API_DIR/core/gre.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/interface.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/ip.api.json +//go:generate binapigen --input-file=$VPP_API_DIR/core/ipfix_export.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/ipsec.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/l2.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/memclnt.api.json @@ -97,6 +102,7 @@ func init() { //go:generate binapigen --input-file=$VPP_API_DIR/core/vxlan_gpe.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/abf.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/acl.api.json +//go:generate binapigen --input-file=$VPP_API_DIR/plugins/flowprobe.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/gtpu.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/memif.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/nat.api.json diff --git a/plugins/vpp/binapi/vpp1908/flowprobe/flowprobe.ba.go b/plugins/vpp/binapi/vpp1908/flowprobe/flowprobe.ba.go new file mode 100644 index 0000000000..da673b34ec --- /dev/null +++ b/plugins/vpp/binapi/vpp1908/flowprobe/flowprobe.ba.go @@ -0,0 +1,140 @@ +// Code generated by GoVPP's binapi-generator. DO NOT EDIT. +// source: /usr/share/vpp/api/plugins/flowprobe.api.json + +/* +Package flowprobe is a generated VPP binary API for 'flowprobe' module. + +It consists of: + 4 messages + 2 services +*/ +package flowprobe + +import ( + bytes "bytes" + context "context" + api "git.fd.io/govpp.git/api" + struc "github.com/lunixbochs/struc" + io "io" + strconv "strconv" +) + +const ( + // ModuleName is the name of this module. + ModuleName = "flowprobe" + // APIVersion is the API version of this module. + APIVersion = "1.0.0" + // VersionCrc is the CRC of this module. + VersionCrc = 0xf2f0286c +) + +// FlowprobeParams represents VPP binary API message 'flowprobe_params'. +type FlowprobeParams struct { + RecordL2 uint8 + RecordL3 uint8 + RecordL4 uint8 + ActiveTimer uint32 + PassiveTimer uint32 +} + +func (m *FlowprobeParams) Reset() { *m = FlowprobeParams{} } +func (*FlowprobeParams) GetMessageName() string { return "flowprobe_params" } +func (*FlowprobeParams) GetCrcString() string { return "574adc1c" } +func (*FlowprobeParams) GetMessageType() api.MessageType { return api.RequestMessage } + +// FlowprobeParamsReply represents VPP binary API message 'flowprobe_params_reply'. +type FlowprobeParamsReply struct { + Retval int32 +} + +func (m *FlowprobeParamsReply) Reset() { *m = FlowprobeParamsReply{} } +func (*FlowprobeParamsReply) GetMessageName() string { return "flowprobe_params_reply" } +func (*FlowprobeParamsReply) GetCrcString() string { return "e8d4e804" } +func (*FlowprobeParamsReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// FlowprobeTxInterfaceAddDel represents VPP binary API message 'flowprobe_tx_interface_add_del'. +type FlowprobeTxInterfaceAddDel struct { + IsAdd uint8 + Which uint8 + SwIfIndex uint32 +} + +func (m *FlowprobeTxInterfaceAddDel) Reset() { *m = FlowprobeTxInterfaceAddDel{} } +func (*FlowprobeTxInterfaceAddDel) GetMessageName() string { return "flowprobe_tx_interface_add_del" } +func (*FlowprobeTxInterfaceAddDel) GetCrcString() string { return "10c2fbab" } +func (*FlowprobeTxInterfaceAddDel) GetMessageType() api.MessageType { return api.RequestMessage } + +// FlowprobeTxInterfaceAddDelReply represents VPP binary API message 'flowprobe_tx_interface_add_del_reply'. +type FlowprobeTxInterfaceAddDelReply struct { + Retval int32 +} + +func (m *FlowprobeTxInterfaceAddDelReply) Reset() { *m = FlowprobeTxInterfaceAddDelReply{} } +func (*FlowprobeTxInterfaceAddDelReply) GetMessageName() string { + return "flowprobe_tx_interface_add_del_reply" +} +func (*FlowprobeTxInterfaceAddDelReply) GetCrcString() string { return "e8d4e804" } +func (*FlowprobeTxInterfaceAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +func init() { + api.RegisterMessage((*FlowprobeParams)(nil), "flowprobe.FlowprobeParams") + api.RegisterMessage((*FlowprobeParamsReply)(nil), "flowprobe.FlowprobeParamsReply") + api.RegisterMessage((*FlowprobeTxInterfaceAddDel)(nil), "flowprobe.FlowprobeTxInterfaceAddDel") + api.RegisterMessage((*FlowprobeTxInterfaceAddDelReply)(nil), "flowprobe.FlowprobeTxInterfaceAddDelReply") +} + +// Messages returns list of all messages in this module. +func AllMessages() []api.Message { + return []api.Message{ + (*FlowprobeParams)(nil), + (*FlowprobeParamsReply)(nil), + (*FlowprobeTxInterfaceAddDel)(nil), + (*FlowprobeTxInterfaceAddDelReply)(nil), + } +} + +// RPCService represents RPC service API for flowprobe module. +type RPCService interface { + FlowprobeParams(ctx context.Context, in *FlowprobeParams) (*FlowprobeParamsReply, error) + FlowprobeTxInterfaceAddDel(ctx context.Context, in *FlowprobeTxInterfaceAddDel) (*FlowprobeTxInterfaceAddDelReply, error) +} + +type serviceClient struct { + ch api.Channel +} + +func NewServiceClient(ch api.Channel) RPCService { + return &serviceClient{ch} +} + +func (c *serviceClient) FlowprobeParams(ctx context.Context, in *FlowprobeParams) (*FlowprobeParamsReply, error) { + out := new(FlowprobeParamsReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) FlowprobeTxInterfaceAddDel(ctx context.Context, in *FlowprobeTxInterfaceAddDel) (*FlowprobeTxInterfaceAddDelReply, error) { + out := new(FlowprobeTxInterfaceAddDelReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the GoVPP api package it is being compiled against. +// A compilation error at this line likely means your copy of the +// GoVPP api package needs to be updated. +const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package + +// Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage +var _ = bytes.NewBuffer +var _ = context.Background +var _ = io.Copy +var _ = strconv.Itoa +var _ = struc.Pack diff --git a/plugins/vpp/binapi/vpp1908/ipfix_export/ipfix_export.ba.go b/plugins/vpp/binapi/vpp1908/ipfix_export/ipfix_export.ba.go new file mode 100644 index 0000000000..b022fd1a77 --- /dev/null +++ b/plugins/vpp/binapi/vpp1908/ipfix_export/ipfix_export.ba.go @@ -0,0 +1,366 @@ +// Code generated by GoVPP's binapi-generator. DO NOT EDIT. +// source: /usr/share/vpp/api/core/ipfix_export.api.json + +/* +Package ipfix_export is a generated VPP binary API for 'ipfix_export' module. + +It consists of: + 14 messages + 7 services +*/ +package ipfix_export + +import ( + bytes "bytes" + context "context" + api "git.fd.io/govpp.git/api" + struc "github.com/lunixbochs/struc" + io "io" + strconv "strconv" +) + +const ( + // ModuleName is the name of this module. + ModuleName = "ipfix_export" + // APIVersion is the API version of this module. + APIVersion = "1.0.1" + // VersionCrc is the CRC of this module. + VersionCrc = 0x3f920e13 +) + +// IpfixClassifyStreamDetails represents VPP binary API message 'ipfix_classify_stream_details'. +type IpfixClassifyStreamDetails struct { + DomainID uint32 + SrcPort uint16 +} + +func (m *IpfixClassifyStreamDetails) Reset() { *m = IpfixClassifyStreamDetails{} } +func (*IpfixClassifyStreamDetails) GetMessageName() string { return "ipfix_classify_stream_details" } +func (*IpfixClassifyStreamDetails) GetCrcString() string { return "2903539d" } +func (*IpfixClassifyStreamDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyStreamDump represents VPP binary API message 'ipfix_classify_stream_dump'. +type IpfixClassifyStreamDump struct{} + +func (m *IpfixClassifyStreamDump) Reset() { *m = IpfixClassifyStreamDump{} } +func (*IpfixClassifyStreamDump) GetMessageName() string { return "ipfix_classify_stream_dump" } +func (*IpfixClassifyStreamDump) GetCrcString() string { return "51077d14" } +func (*IpfixClassifyStreamDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixClassifyTableAddDel represents VPP binary API message 'ipfix_classify_table_add_del'. +type IpfixClassifyTableAddDel struct { + TableID uint32 + IPVersion uint8 + TransportProtocol uint8 + IsAdd uint8 +} + +func (m *IpfixClassifyTableAddDel) Reset() { *m = IpfixClassifyTableAddDel{} } +func (*IpfixClassifyTableAddDel) GetMessageName() string { return "ipfix_classify_table_add_del" } +func (*IpfixClassifyTableAddDel) GetCrcString() string { return "48efe167" } +func (*IpfixClassifyTableAddDel) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixClassifyTableAddDelReply represents VPP binary API message 'ipfix_classify_table_add_del_reply'. +type IpfixClassifyTableAddDelReply struct { + Retval int32 +} + +func (m *IpfixClassifyTableAddDelReply) Reset() { *m = IpfixClassifyTableAddDelReply{} } +func (*IpfixClassifyTableAddDelReply) GetMessageName() string { + return "ipfix_classify_table_add_del_reply" +} +func (*IpfixClassifyTableAddDelReply) GetCrcString() string { return "e8d4e804" } +func (*IpfixClassifyTableAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyTableDetails represents VPP binary API message 'ipfix_classify_table_details'. +type IpfixClassifyTableDetails struct { + TableID uint32 + IPVersion uint8 + TransportProtocol uint8 +} + +func (m *IpfixClassifyTableDetails) Reset() { *m = IpfixClassifyTableDetails{} } +func (*IpfixClassifyTableDetails) GetMessageName() string { return "ipfix_classify_table_details" } +func (*IpfixClassifyTableDetails) GetCrcString() string { return "973d0d5b" } +func (*IpfixClassifyTableDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyTableDump represents VPP binary API message 'ipfix_classify_table_dump'. +type IpfixClassifyTableDump struct{} + +func (m *IpfixClassifyTableDump) Reset() { *m = IpfixClassifyTableDump{} } +func (*IpfixClassifyTableDump) GetMessageName() string { return "ipfix_classify_table_dump" } +func (*IpfixClassifyTableDump) GetCrcString() string { return "51077d14" } +func (*IpfixClassifyTableDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixExporterDetails represents VPP binary API message 'ipfix_exporter_details'. +type IpfixExporterDetails struct { + CollectorAddress []byte `struc:"[16]byte"` + CollectorPort uint16 + SrcAddress []byte `struc:"[16]byte"` + VrfID uint32 + PathMtu uint32 + TemplateInterval uint32 + UDPChecksum uint8 +} + +func (m *IpfixExporterDetails) Reset() { *m = IpfixExporterDetails{} } +func (*IpfixExporterDetails) GetMessageName() string { return "ipfix_exporter_details" } +func (*IpfixExporterDetails) GetCrcString() string { return "742dddee" } +func (*IpfixExporterDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixExporterDump represents VPP binary API message 'ipfix_exporter_dump'. +type IpfixExporterDump struct{} + +func (m *IpfixExporterDump) Reset() { *m = IpfixExporterDump{} } +func (*IpfixExporterDump) GetMessageName() string { return "ipfix_exporter_dump" } +func (*IpfixExporterDump) GetCrcString() string { return "51077d14" } +func (*IpfixExporterDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixFlush represents VPP binary API message 'ipfix_flush'. +type IpfixFlush struct{} + +func (m *IpfixFlush) Reset() { *m = IpfixFlush{} } +func (*IpfixFlush) GetMessageName() string { return "ipfix_flush" } +func (*IpfixFlush) GetCrcString() string { return "51077d14" } +func (*IpfixFlush) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixFlushReply represents VPP binary API message 'ipfix_flush_reply'. +type IpfixFlushReply struct { + Retval int32 +} + +func (m *IpfixFlushReply) Reset() { *m = IpfixFlushReply{} } +func (*IpfixFlushReply) GetMessageName() string { return "ipfix_flush_reply" } +func (*IpfixFlushReply) GetCrcString() string { return "e8d4e804" } +func (*IpfixFlushReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// SetIpfixClassifyStream represents VPP binary API message 'set_ipfix_classify_stream'. +type SetIpfixClassifyStream struct { + DomainID uint32 + SrcPort uint16 +} + +func (m *SetIpfixClassifyStream) Reset() { *m = SetIpfixClassifyStream{} } +func (*SetIpfixClassifyStream) GetMessageName() string { return "set_ipfix_classify_stream" } +func (*SetIpfixClassifyStream) GetCrcString() string { return "c9cbe053" } +func (*SetIpfixClassifyStream) GetMessageType() api.MessageType { return api.RequestMessage } + +// SetIpfixClassifyStreamReply represents VPP binary API message 'set_ipfix_classify_stream_reply'. +type SetIpfixClassifyStreamReply struct { + Retval int32 +} + +func (m *SetIpfixClassifyStreamReply) Reset() { *m = SetIpfixClassifyStreamReply{} } +func (*SetIpfixClassifyStreamReply) GetMessageName() string { return "set_ipfix_classify_stream_reply" } +func (*SetIpfixClassifyStreamReply) GetCrcString() string { return "e8d4e804" } +func (*SetIpfixClassifyStreamReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// SetIpfixExporter represents VPP binary API message 'set_ipfix_exporter'. +type SetIpfixExporter struct { + CollectorAddress []byte `struc:"[16]byte"` + CollectorPort uint16 + SrcAddress []byte `struc:"[16]byte"` + VrfID uint32 + PathMtu uint32 + TemplateInterval uint32 + UDPChecksum uint8 +} + +func (m *SetIpfixExporter) Reset() { *m = SetIpfixExporter{} } +func (*SetIpfixExporter) GetMessageName() string { return "set_ipfix_exporter" } +func (*SetIpfixExporter) GetCrcString() string { return "4ff71dea" } +func (*SetIpfixExporter) GetMessageType() api.MessageType { return api.RequestMessage } + +// SetIpfixExporterReply represents VPP binary API message 'set_ipfix_exporter_reply'. +type SetIpfixExporterReply struct { + Retval int32 +} + +func (m *SetIpfixExporterReply) Reset() { *m = SetIpfixExporterReply{} } +func (*SetIpfixExporterReply) GetMessageName() string { return "set_ipfix_exporter_reply" } +func (*SetIpfixExporterReply) GetCrcString() string { return "e8d4e804" } +func (*SetIpfixExporterReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +func init() { + api.RegisterMessage((*IpfixClassifyStreamDetails)(nil), "ipfix_export.IpfixClassifyStreamDetails") + api.RegisterMessage((*IpfixClassifyStreamDump)(nil), "ipfix_export.IpfixClassifyStreamDump") + api.RegisterMessage((*IpfixClassifyTableAddDel)(nil), "ipfix_export.IpfixClassifyTableAddDel") + api.RegisterMessage((*IpfixClassifyTableAddDelReply)(nil), "ipfix_export.IpfixClassifyTableAddDelReply") + api.RegisterMessage((*IpfixClassifyTableDetails)(nil), "ipfix_export.IpfixClassifyTableDetails") + api.RegisterMessage((*IpfixClassifyTableDump)(nil), "ipfix_export.IpfixClassifyTableDump") + api.RegisterMessage((*IpfixExporterDetails)(nil), "ipfix_export.IpfixExporterDetails") + api.RegisterMessage((*IpfixExporterDump)(nil), "ipfix_export.IpfixExporterDump") + api.RegisterMessage((*IpfixFlush)(nil), "ipfix_export.IpfixFlush") + api.RegisterMessage((*IpfixFlushReply)(nil), "ipfix_export.IpfixFlushReply") + api.RegisterMessage((*SetIpfixClassifyStream)(nil), "ipfix_export.SetIpfixClassifyStream") + api.RegisterMessage((*SetIpfixClassifyStreamReply)(nil), "ipfix_export.SetIpfixClassifyStreamReply") + api.RegisterMessage((*SetIpfixExporter)(nil), "ipfix_export.SetIpfixExporter") + api.RegisterMessage((*SetIpfixExporterReply)(nil), "ipfix_export.SetIpfixExporterReply") +} + +// Messages returns list of all messages in this module. +func AllMessages() []api.Message { + return []api.Message{ + (*IpfixClassifyStreamDetails)(nil), + (*IpfixClassifyStreamDump)(nil), + (*IpfixClassifyTableAddDel)(nil), + (*IpfixClassifyTableAddDelReply)(nil), + (*IpfixClassifyTableDetails)(nil), + (*IpfixClassifyTableDump)(nil), + (*IpfixExporterDetails)(nil), + (*IpfixExporterDump)(nil), + (*IpfixFlush)(nil), + (*IpfixFlushReply)(nil), + (*SetIpfixClassifyStream)(nil), + (*SetIpfixClassifyStreamReply)(nil), + (*SetIpfixExporter)(nil), + (*SetIpfixExporterReply)(nil), + } +} + +// RPCService represents RPC service API for ipfix_export module. +type RPCService interface { + DumpIpfixClassifyStream(ctx context.Context, in *IpfixClassifyStreamDump) (RPCService_DumpIpfixClassifyStreamClient, error) + DumpIpfixClassifyTable(ctx context.Context, in *IpfixClassifyTableDump) (RPCService_DumpIpfixClassifyTableClient, error) + DumpIpfixExporter(ctx context.Context, in *IpfixExporterDump) (RPCService_DumpIpfixExporterClient, error) + IpfixClassifyTableAddDel(ctx context.Context, in *IpfixClassifyTableAddDel) (*IpfixClassifyTableAddDelReply, error) + IpfixFlush(ctx context.Context, in *IpfixFlush) (*IpfixFlushReply, error) + SetIpfixClassifyStream(ctx context.Context, in *SetIpfixClassifyStream) (*SetIpfixClassifyStreamReply, error) + SetIpfixExporter(ctx context.Context, in *SetIpfixExporter) (*SetIpfixExporterReply, error) +} + +type serviceClient struct { + ch api.Channel +} + +func NewServiceClient(ch api.Channel) RPCService { + return &serviceClient{ch} +} + +func (c *serviceClient) DumpIpfixClassifyStream(ctx context.Context, in *IpfixClassifyStreamDump) (RPCService_DumpIpfixClassifyStreamClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixClassifyStreamClient{stream} + return x, nil +} + +type RPCService_DumpIpfixClassifyStreamClient interface { + Recv() (*IpfixClassifyStreamDetails, error) +} + +type serviceClient_DumpIpfixClassifyStreamClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixClassifyStreamClient) Recv() (*IpfixClassifyStreamDetails, error) { + m := new(IpfixClassifyStreamDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) DumpIpfixClassifyTable(ctx context.Context, in *IpfixClassifyTableDump) (RPCService_DumpIpfixClassifyTableClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixClassifyTableClient{stream} + return x, nil +} + +type RPCService_DumpIpfixClassifyTableClient interface { + Recv() (*IpfixClassifyTableDetails, error) +} + +type serviceClient_DumpIpfixClassifyTableClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixClassifyTableClient) Recv() (*IpfixClassifyTableDetails, error) { + m := new(IpfixClassifyTableDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) DumpIpfixExporter(ctx context.Context, in *IpfixExporterDump) (RPCService_DumpIpfixExporterClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixExporterClient{stream} + return x, nil +} + +type RPCService_DumpIpfixExporterClient interface { + Recv() (*IpfixExporterDetails, error) +} + +type serviceClient_DumpIpfixExporterClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixExporterClient) Recv() (*IpfixExporterDetails, error) { + m := new(IpfixExporterDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) IpfixClassifyTableAddDel(ctx context.Context, in *IpfixClassifyTableAddDel) (*IpfixClassifyTableAddDelReply, error) { + out := new(IpfixClassifyTableAddDelReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) IpfixFlush(ctx context.Context, in *IpfixFlush) (*IpfixFlushReply, error) { + out := new(IpfixFlushReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) SetIpfixClassifyStream(ctx context.Context, in *SetIpfixClassifyStream) (*SetIpfixClassifyStreamReply, error) { + out := new(SetIpfixClassifyStreamReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) SetIpfixExporter(ctx context.Context, in *SetIpfixExporter) (*SetIpfixExporterReply, error) { + out := new(SetIpfixExporterReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the GoVPP api package it is being compiled against. +// A compilation error at this line likely means your copy of the +// GoVPP api package needs to be updated. +const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package + +// Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage +var _ = bytes.NewBuffer +var _ = context.Background +var _ = io.Copy +var _ = strconv.Itoa +var _ = struc.Pack diff --git a/plugins/vpp/binapi/vpp1908/vpp1908.go b/plugins/vpp/binapi/vpp1908/vpp1908.go index b166db0825..7e8384f935 100644 --- a/plugins/vpp/binapi/vpp1908/vpp1908.go +++ b/plugins/vpp/binapi/vpp1908/vpp1908.go @@ -22,10 +22,12 @@ import ( "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/af_packet" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/bond" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/dhcp" + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/flowprobe" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/gre" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/gtpu" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/interfaces" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/ip" + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/ipfix_export" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/ipip" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/ipsec" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/l2" @@ -56,6 +58,7 @@ func init() { gre.AllMessages, interfaces.AllMessages, ip.AllMessages, + ipfix_export.AllMessages, ipsec.AllMessages, l2.AllMessages, memclnt.AllMessages, @@ -71,6 +74,7 @@ func init() { Plugins: vpp.Messages( abf.AllMessages, acl.AllMessages, + flowprobe.AllMessages, gtpu.AllMessages, l3xc.AllMessages, memif.AllMessages, @@ -89,6 +93,7 @@ func init() { //go:generate binapigen --input-file=$VPP_API_DIR/core/gre.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/interface.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/ip.api.json +//go:generate binapigen --input-file=$VPP_API_DIR/core/ipfix_export.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/ipsec.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/l2.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/memclnt.api.json @@ -102,6 +107,7 @@ func init() { //go:generate binapigen --input-file=$VPP_API_DIR/core/ipip.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/abf.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/acl.api.json +//go:generate binapigen --input-file=$VPP_API_DIR/plugins/flowprobe.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/gtpu.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/l3xc.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/memif.api.json diff --git a/plugins/vpp/binapi/vpp2001/flowprobe/flowprobe.ba.go b/plugins/vpp/binapi/vpp2001/flowprobe/flowprobe.ba.go new file mode 100644 index 0000000000..91c58ab7de --- /dev/null +++ b/plugins/vpp/binapi/vpp2001/flowprobe/flowprobe.ba.go @@ -0,0 +1,212 @@ +// Code generated by GoVPP's binapi-generator. DO NOT EDIT. +// source: /usr/share/vpp/api/plugins/flowprobe.api.json + +/* +Package flowprobe is a generated VPP binary API for 'flowprobe' module. + +It consists of: + 8 enums + 1 alias + 4 messages + 2 services +*/ +package flowprobe + +import ( + bytes "bytes" + context "context" + api "git.fd.io/govpp.git/api" + struc "github.com/lunixbochs/struc" + io "io" + strconv "strconv" + + interface_types "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/interface_types" +) + +const ( + // ModuleName is the name of this module. + ModuleName = "flowprobe" + // VersionCrc is the CRC of this module. + VersionCrc = 0xbb4dfc0d +) + +// FlowprobeRecordFlags represents VPP binary API enum 'flowprobe_record_flags'. +type FlowprobeRecordFlags uint8 + +const ( + FLOWPROBE_RECORD_FLAG_L2 FlowprobeRecordFlags = 1 + FLOWPROBE_RECORD_FLAG_L3 FlowprobeRecordFlags = 2 + FLOWPROBE_RECORD_FLAG_L4 FlowprobeRecordFlags = 4 +) + +var FlowprobeRecordFlags_name = map[uint8]string{ + 1: "FLOWPROBE_RECORD_FLAG_L2", + 2: "FLOWPROBE_RECORD_FLAG_L3", + 4: "FLOWPROBE_RECORD_FLAG_L4", +} + +var FlowprobeRecordFlags_value = map[string]uint8{ + "FLOWPROBE_RECORD_FLAG_L2": 1, + "FLOWPROBE_RECORD_FLAG_L3": 2, + "FLOWPROBE_RECORD_FLAG_L4": 4, +} + +func (x FlowprobeRecordFlags) String() string { + s, ok := FlowprobeRecordFlags_name[uint8(x)] + if ok { + return s + } + return strconv.Itoa(int(x)) +} + +// FlowprobeWhichFlags represents VPP binary API enum 'flowprobe_which_flags'. +type FlowprobeWhichFlags uint8 + +const ( + FLOWPROBE_WHICH_FLAG_IP4 FlowprobeWhichFlags = 1 + FLOWPROBE_WHICH_FLAG_L2 FlowprobeWhichFlags = 2 + FLOWPROBE_WHICH_FLAG_IP6 FlowprobeWhichFlags = 4 +) + +var FlowprobeWhichFlags_name = map[uint8]string{ + 1: "FLOWPROBE_WHICH_FLAG_IP4", + 2: "FLOWPROBE_WHICH_FLAG_L2", + 4: "FLOWPROBE_WHICH_FLAG_IP6", +} + +var FlowprobeWhichFlags_value = map[string]uint8{ + "FLOWPROBE_WHICH_FLAG_IP4": 1, + "FLOWPROBE_WHICH_FLAG_L2": 2, + "FLOWPROBE_WHICH_FLAG_IP6": 4, +} + +func (x FlowprobeWhichFlags) String() string { + s, ok := FlowprobeWhichFlags_name[uint8(x)] + if ok { + return s + } + return strconv.Itoa(int(x)) +} + +type IfStatusFlags = interface_types.IfStatusFlags + +type IfType = interface_types.IfType + +type LinkDuplex = interface_types.LinkDuplex + +type MtuProto = interface_types.MtuProto + +type RxMode = interface_types.RxMode + +type SubIfFlags = interface_types.SubIfFlags + +type InterfaceIndex = interface_types.InterfaceIndex + +// FlowprobeParams represents VPP binary API message 'flowprobe_params'. +type FlowprobeParams struct { + RecordFlags FlowprobeRecordFlags + ActiveTimer uint32 + PassiveTimer uint32 +} + +func (m *FlowprobeParams) Reset() { *m = FlowprobeParams{} } +func (*FlowprobeParams) GetMessageName() string { return "flowprobe_params" } +func (*FlowprobeParams) GetCrcString() string { return "baa46c09" } +func (*FlowprobeParams) GetMessageType() api.MessageType { return api.RequestMessage } + +// FlowprobeParamsReply represents VPP binary API message 'flowprobe_params_reply'. +type FlowprobeParamsReply struct { + Retval int32 +} + +func (m *FlowprobeParamsReply) Reset() { *m = FlowprobeParamsReply{} } +func (*FlowprobeParamsReply) GetMessageName() string { return "flowprobe_params_reply" } +func (*FlowprobeParamsReply) GetCrcString() string { return "e8d4e804" } +func (*FlowprobeParamsReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// FlowprobeTxInterfaceAddDel represents VPP binary API message 'flowprobe_tx_interface_add_del'. +type FlowprobeTxInterfaceAddDel struct { + IsAdd bool + Which FlowprobeWhichFlags + SwIfIndex InterfaceIndex +} + +func (m *FlowprobeTxInterfaceAddDel) Reset() { *m = FlowprobeTxInterfaceAddDel{} } +func (*FlowprobeTxInterfaceAddDel) GetMessageName() string { return "flowprobe_tx_interface_add_del" } +func (*FlowprobeTxInterfaceAddDel) GetCrcString() string { return "b782c976" } +func (*FlowprobeTxInterfaceAddDel) GetMessageType() api.MessageType { return api.RequestMessage } + +// FlowprobeTxInterfaceAddDelReply represents VPP binary API message 'flowprobe_tx_interface_add_del_reply'. +type FlowprobeTxInterfaceAddDelReply struct { + Retval int32 +} + +func (m *FlowprobeTxInterfaceAddDelReply) Reset() { *m = FlowprobeTxInterfaceAddDelReply{} } +func (*FlowprobeTxInterfaceAddDelReply) GetMessageName() string { + return "flowprobe_tx_interface_add_del_reply" +} +func (*FlowprobeTxInterfaceAddDelReply) GetCrcString() string { return "e8d4e804" } +func (*FlowprobeTxInterfaceAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +func init() { + api.RegisterMessage((*FlowprobeParams)(nil), "flowprobe.FlowprobeParams") + api.RegisterMessage((*FlowprobeParamsReply)(nil), "flowprobe.FlowprobeParamsReply") + api.RegisterMessage((*FlowprobeTxInterfaceAddDel)(nil), "flowprobe.FlowprobeTxInterfaceAddDel") + api.RegisterMessage((*FlowprobeTxInterfaceAddDelReply)(nil), "flowprobe.FlowprobeTxInterfaceAddDelReply") +} + +// Messages returns list of all messages in this module. +func AllMessages() []api.Message { + return []api.Message{ + (*FlowprobeParams)(nil), + (*FlowprobeParamsReply)(nil), + (*FlowprobeTxInterfaceAddDel)(nil), + (*FlowprobeTxInterfaceAddDelReply)(nil), + } +} + +// RPCService represents RPC service API for flowprobe module. +type RPCService interface { + FlowprobeParams(ctx context.Context, in *FlowprobeParams) (*FlowprobeParamsReply, error) + FlowprobeTxInterfaceAddDel(ctx context.Context, in *FlowprobeTxInterfaceAddDel) (*FlowprobeTxInterfaceAddDelReply, error) +} + +type serviceClient struct { + ch api.Channel +} + +func NewServiceClient(ch api.Channel) RPCService { + return &serviceClient{ch} +} + +func (c *serviceClient) FlowprobeParams(ctx context.Context, in *FlowprobeParams) (*FlowprobeParamsReply, error) { + out := new(FlowprobeParamsReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) FlowprobeTxInterfaceAddDel(ctx context.Context, in *FlowprobeTxInterfaceAddDel) (*FlowprobeTxInterfaceAddDelReply, error) { + out := new(FlowprobeTxInterfaceAddDelReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the GoVPP api package it is being compiled against. +// A compilation error at this line likely means your copy of the +// GoVPP api package needs to be updated. +const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package + +// Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage +var _ = bytes.NewBuffer +var _ = context.Background +var _ = io.Copy +var _ = strconv.Itoa +var _ = struc.Pack diff --git a/plugins/vpp/binapi/vpp2001/ipfix_export/ipfix_export.ba.go b/plugins/vpp/binapi/vpp2001/ipfix_export/ipfix_export.ba.go new file mode 100644 index 0000000000..1a569f3ebf --- /dev/null +++ b/plugins/vpp/binapi/vpp2001/ipfix_export/ipfix_export.ba.go @@ -0,0 +1,402 @@ +// Code generated by GoVPP's binapi-generator. DO NOT EDIT. +// source: /usr/share/vpp/api/core/ipfix_export.api.json + +/* +Package ipfix_export is a generated VPP binary API for 'ipfix_export' module. + +It consists of: + 4 enums + 5 aliases + 6 types + 1 union + 14 messages + 7 services +*/ +package ipfix_export + +import ( + bytes "bytes" + context "context" + api "git.fd.io/govpp.git/api" + struc "github.com/lunixbochs/struc" + io "io" + strconv "strconv" + + ip_types "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ip_types" +) + +const ( + // ModuleName is the name of this module. + ModuleName = "ipfix_export" + // VersionCrc is the CRC of this module. + VersionCrc = 0xee6ea488 +) + +type AddressFamily = ip_types.AddressFamily + +type IPDscp = ip_types.IPDscp + +type IPEcn = ip_types.IPEcn + +type IPProto = ip_types.IPProto + +type AddressWithPrefix = ip_types.AddressWithPrefix + +type IP4Address = ip_types.IP4Address + +type IP4AddressWithPrefix = ip_types.IP4AddressWithPrefix + +type IP6Address = ip_types.IP6Address + +type IP6AddressWithPrefix = ip_types.IP6AddressWithPrefix + +type Address = ip_types.Address + +type IP4Prefix = ip_types.IP4Prefix + +type IP6Prefix = ip_types.IP6Prefix + +type Mprefix = ip_types.Mprefix + +type Prefix = ip_types.Prefix + +type PrefixMatcher = ip_types.PrefixMatcher + +type AddressUnion = ip_types.AddressUnion + +// IpfixClassifyStreamDetails represents VPP binary API message 'ipfix_classify_stream_details'. +type IpfixClassifyStreamDetails struct { + DomainID uint32 + SrcPort uint16 +} + +func (m *IpfixClassifyStreamDetails) Reset() { *m = IpfixClassifyStreamDetails{} } +func (*IpfixClassifyStreamDetails) GetMessageName() string { return "ipfix_classify_stream_details" } +func (*IpfixClassifyStreamDetails) GetCrcString() string { return "2903539d" } +func (*IpfixClassifyStreamDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyStreamDump represents VPP binary API message 'ipfix_classify_stream_dump'. +type IpfixClassifyStreamDump struct{} + +func (m *IpfixClassifyStreamDump) Reset() { *m = IpfixClassifyStreamDump{} } +func (*IpfixClassifyStreamDump) GetMessageName() string { return "ipfix_classify_stream_dump" } +func (*IpfixClassifyStreamDump) GetCrcString() string { return "51077d14" } +func (*IpfixClassifyStreamDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixClassifyTableAddDel represents VPP binary API message 'ipfix_classify_table_add_del'. +type IpfixClassifyTableAddDel struct { + TableID uint32 + IPVersion AddressFamily + TransportProtocol IPProto + IsAdd bool +} + +func (m *IpfixClassifyTableAddDel) Reset() { *m = IpfixClassifyTableAddDel{} } +func (*IpfixClassifyTableAddDel) GetMessageName() string { return "ipfix_classify_table_add_del" } +func (*IpfixClassifyTableAddDel) GetCrcString() string { return "5118bc5e" } +func (*IpfixClassifyTableAddDel) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixClassifyTableAddDelReply represents VPP binary API message 'ipfix_classify_table_add_del_reply'. +type IpfixClassifyTableAddDelReply struct { + Retval int32 +} + +func (m *IpfixClassifyTableAddDelReply) Reset() { *m = IpfixClassifyTableAddDelReply{} } +func (*IpfixClassifyTableAddDelReply) GetMessageName() string { + return "ipfix_classify_table_add_del_reply" +} +func (*IpfixClassifyTableAddDelReply) GetCrcString() string { return "e8d4e804" } +func (*IpfixClassifyTableAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyTableDetails represents VPP binary API message 'ipfix_classify_table_details'. +type IpfixClassifyTableDetails struct { + TableID uint32 + IPVersion AddressFamily + TransportProtocol IPProto +} + +func (m *IpfixClassifyTableDetails) Reset() { *m = IpfixClassifyTableDetails{} } +func (*IpfixClassifyTableDetails) GetMessageName() string { return "ipfix_classify_table_details" } +func (*IpfixClassifyTableDetails) GetCrcString() string { return "7c8351ec" } +func (*IpfixClassifyTableDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixClassifyTableDump represents VPP binary API message 'ipfix_classify_table_dump'. +type IpfixClassifyTableDump struct{} + +func (m *IpfixClassifyTableDump) Reset() { *m = IpfixClassifyTableDump{} } +func (*IpfixClassifyTableDump) GetMessageName() string { return "ipfix_classify_table_dump" } +func (*IpfixClassifyTableDump) GetCrcString() string { return "51077d14" } +func (*IpfixClassifyTableDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixExporterDetails represents VPP binary API message 'ipfix_exporter_details'. +type IpfixExporterDetails struct { + CollectorAddress Address + CollectorPort uint16 + SrcAddress Address + VrfID uint32 + PathMtu uint32 + TemplateInterval uint32 + UDPChecksum bool +} + +func (m *IpfixExporterDetails) Reset() { *m = IpfixExporterDetails{} } +func (*IpfixExporterDetails) GetMessageName() string { return "ipfix_exporter_details" } +func (*IpfixExporterDetails) GetCrcString() string { return "11e07413" } +func (*IpfixExporterDetails) GetMessageType() api.MessageType { return api.ReplyMessage } + +// IpfixExporterDump represents VPP binary API message 'ipfix_exporter_dump'. +type IpfixExporterDump struct{} + +func (m *IpfixExporterDump) Reset() { *m = IpfixExporterDump{} } +func (*IpfixExporterDump) GetMessageName() string { return "ipfix_exporter_dump" } +func (*IpfixExporterDump) GetCrcString() string { return "51077d14" } +func (*IpfixExporterDump) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixFlush represents VPP binary API message 'ipfix_flush'. +type IpfixFlush struct{} + +func (m *IpfixFlush) Reset() { *m = IpfixFlush{} } +func (*IpfixFlush) GetMessageName() string { return "ipfix_flush" } +func (*IpfixFlush) GetCrcString() string { return "51077d14" } +func (*IpfixFlush) GetMessageType() api.MessageType { return api.RequestMessage } + +// IpfixFlushReply represents VPP binary API message 'ipfix_flush_reply'. +type IpfixFlushReply struct { + Retval int32 +} + +func (m *IpfixFlushReply) Reset() { *m = IpfixFlushReply{} } +func (*IpfixFlushReply) GetMessageName() string { return "ipfix_flush_reply" } +func (*IpfixFlushReply) GetCrcString() string { return "e8d4e804" } +func (*IpfixFlushReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// SetIpfixClassifyStream represents VPP binary API message 'set_ipfix_classify_stream'. +type SetIpfixClassifyStream struct { + DomainID uint32 + SrcPort uint16 +} + +func (m *SetIpfixClassifyStream) Reset() { *m = SetIpfixClassifyStream{} } +func (*SetIpfixClassifyStream) GetMessageName() string { return "set_ipfix_classify_stream" } +func (*SetIpfixClassifyStream) GetCrcString() string { return "c9cbe053" } +func (*SetIpfixClassifyStream) GetMessageType() api.MessageType { return api.RequestMessage } + +// SetIpfixClassifyStreamReply represents VPP binary API message 'set_ipfix_classify_stream_reply'. +type SetIpfixClassifyStreamReply struct { + Retval int32 +} + +func (m *SetIpfixClassifyStreamReply) Reset() { *m = SetIpfixClassifyStreamReply{} } +func (*SetIpfixClassifyStreamReply) GetMessageName() string { return "set_ipfix_classify_stream_reply" } +func (*SetIpfixClassifyStreamReply) GetCrcString() string { return "e8d4e804" } +func (*SetIpfixClassifyStreamReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +// SetIpfixExporter represents VPP binary API message 'set_ipfix_exporter'. +type SetIpfixExporter struct { + CollectorAddress Address + CollectorPort uint16 + SrcAddress Address + VrfID uint32 + PathMtu uint32 + TemplateInterval uint32 + UDPChecksum bool +} + +func (m *SetIpfixExporter) Reset() { *m = SetIpfixExporter{} } +func (*SetIpfixExporter) GetMessageName() string { return "set_ipfix_exporter" } +func (*SetIpfixExporter) GetCrcString() string { return "69284e07" } +func (*SetIpfixExporter) GetMessageType() api.MessageType { return api.RequestMessage } + +// SetIpfixExporterReply represents VPP binary API message 'set_ipfix_exporter_reply'. +type SetIpfixExporterReply struct { + Retval int32 +} + +func (m *SetIpfixExporterReply) Reset() { *m = SetIpfixExporterReply{} } +func (*SetIpfixExporterReply) GetMessageName() string { return "set_ipfix_exporter_reply" } +func (*SetIpfixExporterReply) GetCrcString() string { return "e8d4e804" } +func (*SetIpfixExporterReply) GetMessageType() api.MessageType { return api.ReplyMessage } + +func init() { + api.RegisterMessage((*IpfixClassifyStreamDetails)(nil), "ipfix_export.IpfixClassifyStreamDetails") + api.RegisterMessage((*IpfixClassifyStreamDump)(nil), "ipfix_export.IpfixClassifyStreamDump") + api.RegisterMessage((*IpfixClassifyTableAddDel)(nil), "ipfix_export.IpfixClassifyTableAddDel") + api.RegisterMessage((*IpfixClassifyTableAddDelReply)(nil), "ipfix_export.IpfixClassifyTableAddDelReply") + api.RegisterMessage((*IpfixClassifyTableDetails)(nil), "ipfix_export.IpfixClassifyTableDetails") + api.RegisterMessage((*IpfixClassifyTableDump)(nil), "ipfix_export.IpfixClassifyTableDump") + api.RegisterMessage((*IpfixExporterDetails)(nil), "ipfix_export.IpfixExporterDetails") + api.RegisterMessage((*IpfixExporterDump)(nil), "ipfix_export.IpfixExporterDump") + api.RegisterMessage((*IpfixFlush)(nil), "ipfix_export.IpfixFlush") + api.RegisterMessage((*IpfixFlushReply)(nil), "ipfix_export.IpfixFlushReply") + api.RegisterMessage((*SetIpfixClassifyStream)(nil), "ipfix_export.SetIpfixClassifyStream") + api.RegisterMessage((*SetIpfixClassifyStreamReply)(nil), "ipfix_export.SetIpfixClassifyStreamReply") + api.RegisterMessage((*SetIpfixExporter)(nil), "ipfix_export.SetIpfixExporter") + api.RegisterMessage((*SetIpfixExporterReply)(nil), "ipfix_export.SetIpfixExporterReply") +} + +// Messages returns list of all messages in this module. +func AllMessages() []api.Message { + return []api.Message{ + (*IpfixClassifyStreamDetails)(nil), + (*IpfixClassifyStreamDump)(nil), + (*IpfixClassifyTableAddDel)(nil), + (*IpfixClassifyTableAddDelReply)(nil), + (*IpfixClassifyTableDetails)(nil), + (*IpfixClassifyTableDump)(nil), + (*IpfixExporterDetails)(nil), + (*IpfixExporterDump)(nil), + (*IpfixFlush)(nil), + (*IpfixFlushReply)(nil), + (*SetIpfixClassifyStream)(nil), + (*SetIpfixClassifyStreamReply)(nil), + (*SetIpfixExporter)(nil), + (*SetIpfixExporterReply)(nil), + } +} + +// RPCService represents RPC service API for ipfix_export module. +type RPCService interface { + DumpIpfixClassifyStream(ctx context.Context, in *IpfixClassifyStreamDump) (RPCService_DumpIpfixClassifyStreamClient, error) + DumpIpfixClassifyTable(ctx context.Context, in *IpfixClassifyTableDump) (RPCService_DumpIpfixClassifyTableClient, error) + DumpIpfixExporter(ctx context.Context, in *IpfixExporterDump) (RPCService_DumpIpfixExporterClient, error) + IpfixClassifyTableAddDel(ctx context.Context, in *IpfixClassifyTableAddDel) (*IpfixClassifyTableAddDelReply, error) + IpfixFlush(ctx context.Context, in *IpfixFlush) (*IpfixFlushReply, error) + SetIpfixClassifyStream(ctx context.Context, in *SetIpfixClassifyStream) (*SetIpfixClassifyStreamReply, error) + SetIpfixExporter(ctx context.Context, in *SetIpfixExporter) (*SetIpfixExporterReply, error) +} + +type serviceClient struct { + ch api.Channel +} + +func NewServiceClient(ch api.Channel) RPCService { + return &serviceClient{ch} +} + +func (c *serviceClient) DumpIpfixClassifyStream(ctx context.Context, in *IpfixClassifyStreamDump) (RPCService_DumpIpfixClassifyStreamClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixClassifyStreamClient{stream} + return x, nil +} + +type RPCService_DumpIpfixClassifyStreamClient interface { + Recv() (*IpfixClassifyStreamDetails, error) +} + +type serviceClient_DumpIpfixClassifyStreamClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixClassifyStreamClient) Recv() (*IpfixClassifyStreamDetails, error) { + m := new(IpfixClassifyStreamDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) DumpIpfixClassifyTable(ctx context.Context, in *IpfixClassifyTableDump) (RPCService_DumpIpfixClassifyTableClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixClassifyTableClient{stream} + return x, nil +} + +type RPCService_DumpIpfixClassifyTableClient interface { + Recv() (*IpfixClassifyTableDetails, error) +} + +type serviceClient_DumpIpfixClassifyTableClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixClassifyTableClient) Recv() (*IpfixClassifyTableDetails, error) { + m := new(IpfixClassifyTableDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) DumpIpfixExporter(ctx context.Context, in *IpfixExporterDump) (RPCService_DumpIpfixExporterClient, error) { + stream := c.ch.SendMultiRequest(in) + x := &serviceClient_DumpIpfixExporterClient{stream} + return x, nil +} + +type RPCService_DumpIpfixExporterClient interface { + Recv() (*IpfixExporterDetails, error) +} + +type serviceClient_DumpIpfixExporterClient struct { + api.MultiRequestCtx +} + +func (c *serviceClient_DumpIpfixExporterClient) Recv() (*IpfixExporterDetails, error) { + m := new(IpfixExporterDetails) + stop, err := c.MultiRequestCtx.ReceiveReply(m) + if err != nil { + return nil, err + } + if stop { + return nil, io.EOF + } + return m, nil +} + +func (c *serviceClient) IpfixClassifyTableAddDel(ctx context.Context, in *IpfixClassifyTableAddDel) (*IpfixClassifyTableAddDelReply, error) { + out := new(IpfixClassifyTableAddDelReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) IpfixFlush(ctx context.Context, in *IpfixFlush) (*IpfixFlushReply, error) { + out := new(IpfixFlushReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) SetIpfixClassifyStream(ctx context.Context, in *SetIpfixClassifyStream) (*SetIpfixClassifyStreamReply, error) { + out := new(SetIpfixClassifyStreamReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) SetIpfixExporter(ctx context.Context, in *SetIpfixExporter) (*SetIpfixExporterReply, error) { + out := new(SetIpfixExporterReply) + err := c.ch.SendRequest(in).ReceiveReply(out) + if err != nil { + return nil, err + } + return out, nil +} + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the GoVPP api package it is being compiled against. +// A compilation error at this line likely means your copy of the +// GoVPP api package needs to be updated. +const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package + +// Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage +var _ = bytes.NewBuffer +var _ = context.Background +var _ = io.Copy +var _ = strconv.Itoa +var _ = struc.Pack diff --git a/plugins/vpp/binapi/vpp2001/vpp2001.go b/plugins/vpp/binapi/vpp2001/vpp2001.go index 74b65b639d..f6bd4f7415 100644 --- a/plugins/vpp/binapi/vpp2001/vpp2001.go +++ b/plugins/vpp/binapi/vpp2001/vpp2001.go @@ -22,10 +22,12 @@ import ( "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/af_packet" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/bond" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/dhcp" + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/flowprobe" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/gre" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/gtpu" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/interfaces" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ip" + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ipfix_export" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ipip" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ipsec" "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/l2" @@ -56,6 +58,7 @@ func init() { gre.AllMessages, interfaces.AllMessages, ip.AllMessages, + ipfix_export.AllMessages, ipsec.AllMessages, l2.AllMessages, memclnt.AllMessages, @@ -71,6 +74,7 @@ func init() { Plugins: vpp.Messages( abf.AllMessages, acl.AllMessages, + flowprobe.AllMessages, gtpu.AllMessages, l3xc.AllMessages, memif.AllMessages, @@ -97,6 +101,7 @@ func init() { //go:generate binapigen --input-file=$VPP_API_DIR/core/interface.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/ip.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/ip_neighbor.api.json +//go:generate binapigen --input-file=$VPP_API_DIR/core/ipfix_export.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/ipsec.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/l2.api.json //go:generate binapigen --input-file=$VPP_API_DIR/core/memclnt.api.json @@ -110,6 +115,7 @@ func init() { //go:generate binapigen --input-file=$VPP_API_DIR/core/ipip.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/abf.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/acl.api.json +//go:generate binapigen --input-file=$VPP_API_DIR/plugins/flowprobe.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/gtpu.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/dhcp.api.json //go:generate binapigen --input-file=$VPP_API_DIR/plugins/l3xc.api.json diff --git a/plugins/vpp/ipfixplugin/descriptor/adapter/flowprobefeature.go b/plugins/vpp/ipfixplugin/descriptor/adapter/flowprobefeature.go new file mode 100644 index 0000000000..5e6ddaafb3 --- /dev/null +++ b/plugins/vpp/ipfixplugin/descriptor/adapter/flowprobefeature.go @@ -0,0 +1,233 @@ +// Code generated by adapter-generator. DO NOT EDIT. + +package adapter + +import ( + "github.com/golang/protobuf/proto" + . "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" + "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +////////// type-safe key-value pair with metadata ////////// + +type FlowProbeFeatureKVWithMetadata struct { + Key string + Value *vpp_ipfix.FlowProbeFeature + Metadata interface{} + Origin ValueOrigin +} + +////////// type-safe Descriptor structure ////////// + +type FlowProbeFeatureDescriptor struct { + Name string + KeySelector KeySelector + ValueTypeName string + KeyLabel func(key string) string + ValueComparator func(key string, oldValue, newValue *vpp_ipfix.FlowProbeFeature) bool + NBKeyPrefix string + WithMetadata bool + MetadataMapFactory MetadataMapFactory + Validate func(key string, value *vpp_ipfix.FlowProbeFeature) error + Create func(key string, value *vpp_ipfix.FlowProbeFeature) (metadata interface{}, err error) + Delete func(key string, value *vpp_ipfix.FlowProbeFeature, metadata interface{}) error + Update func(key string, oldValue, newValue *vpp_ipfix.FlowProbeFeature, oldMetadata interface{}) (newMetadata interface{}, err error) + UpdateWithRecreate func(key string, oldValue, newValue *vpp_ipfix.FlowProbeFeature, metadata interface{}) bool + Retrieve func(correlate []FlowProbeFeatureKVWithMetadata) ([]FlowProbeFeatureKVWithMetadata, error) + IsRetriableFailure func(err error) bool + DerivedValues func(key string, value *vpp_ipfix.FlowProbeFeature) []KeyValuePair + Dependencies func(key string, value *vpp_ipfix.FlowProbeFeature) []Dependency + RetrieveDependencies []string /* descriptor name */ +} + +////////// Descriptor adapter ////////// + +type FlowProbeFeatureDescriptorAdapter struct { + descriptor *FlowProbeFeatureDescriptor +} + +func NewFlowProbeFeatureDescriptor(typedDescriptor *FlowProbeFeatureDescriptor) *KVDescriptor { + adapter := &FlowProbeFeatureDescriptorAdapter{descriptor: typedDescriptor} + descriptor := &KVDescriptor{ + Name: typedDescriptor.Name, + KeySelector: typedDescriptor.KeySelector, + ValueTypeName: typedDescriptor.ValueTypeName, + KeyLabel: typedDescriptor.KeyLabel, + NBKeyPrefix: typedDescriptor.NBKeyPrefix, + WithMetadata: typedDescriptor.WithMetadata, + MetadataMapFactory: typedDescriptor.MetadataMapFactory, + IsRetriableFailure: typedDescriptor.IsRetriableFailure, + RetrieveDependencies: typedDescriptor.RetrieveDependencies, + } + if typedDescriptor.ValueComparator != nil { + descriptor.ValueComparator = adapter.ValueComparator + } + if typedDescriptor.Validate != nil { + descriptor.Validate = adapter.Validate + } + if typedDescriptor.Create != nil { + descriptor.Create = adapter.Create + } + if typedDescriptor.Delete != nil { + descriptor.Delete = adapter.Delete + } + if typedDescriptor.Update != nil { + descriptor.Update = adapter.Update + } + if typedDescriptor.UpdateWithRecreate != nil { + descriptor.UpdateWithRecreate = adapter.UpdateWithRecreate + } + if typedDescriptor.Retrieve != nil { + descriptor.Retrieve = adapter.Retrieve + } + if typedDescriptor.Dependencies != nil { + descriptor.Dependencies = adapter.Dependencies + } + if typedDescriptor.DerivedValues != nil { + descriptor.DerivedValues = adapter.DerivedValues + } + return descriptor +} + +func (da *FlowProbeFeatureDescriptorAdapter) ValueComparator(key string, oldValue, newValue proto.Message) bool { + typedOldValue, err1 := castFlowProbeFeatureValue(key, oldValue) + typedNewValue, err2 := castFlowProbeFeatureValue(key, newValue) + if err1 != nil || err2 != nil { + return false + } + return da.descriptor.ValueComparator(key, typedOldValue, typedNewValue) +} + +func (da *FlowProbeFeatureDescriptorAdapter) Validate(key string, value proto.Message) (err error) { + typedValue, err := castFlowProbeFeatureValue(key, value) + if err != nil { + return err + } + return da.descriptor.Validate(key, typedValue) +} + +func (da *FlowProbeFeatureDescriptorAdapter) Create(key string, value proto.Message) (metadata Metadata, err error) { + typedValue, err := castFlowProbeFeatureValue(key, value) + if err != nil { + return nil, err + } + return da.descriptor.Create(key, typedValue) +} + +func (da *FlowProbeFeatureDescriptorAdapter) Update(key string, oldValue, newValue proto.Message, oldMetadata Metadata) (newMetadata Metadata, err error) { + oldTypedValue, err := castFlowProbeFeatureValue(key, oldValue) + if err != nil { + return nil, err + } + newTypedValue, err := castFlowProbeFeatureValue(key, newValue) + if err != nil { + return nil, err + } + typedOldMetadata, err := castFlowProbeFeatureMetadata(key, oldMetadata) + if err != nil { + return nil, err + } + return da.descriptor.Update(key, oldTypedValue, newTypedValue, typedOldMetadata) +} + +func (da *FlowProbeFeatureDescriptorAdapter) Delete(key string, value proto.Message, metadata Metadata) error { + typedValue, err := castFlowProbeFeatureValue(key, value) + if err != nil { + return err + } + typedMetadata, err := castFlowProbeFeatureMetadata(key, metadata) + if err != nil { + return err + } + return da.descriptor.Delete(key, typedValue, typedMetadata) +} + +func (da *FlowProbeFeatureDescriptorAdapter) UpdateWithRecreate(key string, oldValue, newValue proto.Message, metadata Metadata) bool { + oldTypedValue, err := castFlowProbeFeatureValue(key, oldValue) + if err != nil { + return true + } + newTypedValue, err := castFlowProbeFeatureValue(key, newValue) + if err != nil { + return true + } + typedMetadata, err := castFlowProbeFeatureMetadata(key, metadata) + if err != nil { + return true + } + return da.descriptor.UpdateWithRecreate(key, oldTypedValue, newTypedValue, typedMetadata) +} + +func (da *FlowProbeFeatureDescriptorAdapter) Retrieve(correlate []KVWithMetadata) ([]KVWithMetadata, error) { + var correlateWithType []FlowProbeFeatureKVWithMetadata + for _, kvpair := range correlate { + typedValue, err := castFlowProbeFeatureValue(kvpair.Key, kvpair.Value) + if err != nil { + continue + } + typedMetadata, err := castFlowProbeFeatureMetadata(kvpair.Key, kvpair.Metadata) + if err != nil { + continue + } + correlateWithType = append(correlateWithType, + FlowProbeFeatureKVWithMetadata{ + Key: kvpair.Key, + Value: typedValue, + Metadata: typedMetadata, + Origin: kvpair.Origin, + }) + } + + typedValues, err := da.descriptor.Retrieve(correlateWithType) + if err != nil { + return nil, err + } + var values []KVWithMetadata + for _, typedKVWithMetadata := range typedValues { + kvWithMetadata := KVWithMetadata{ + Key: typedKVWithMetadata.Key, + Metadata: typedKVWithMetadata.Metadata, + Origin: typedKVWithMetadata.Origin, + } + kvWithMetadata.Value = typedKVWithMetadata.Value + values = append(values, kvWithMetadata) + } + return values, err +} + +func (da *FlowProbeFeatureDescriptorAdapter) DerivedValues(key string, value proto.Message) []KeyValuePair { + typedValue, err := castFlowProbeFeatureValue(key, value) + if err != nil { + return nil + } + return da.descriptor.DerivedValues(key, typedValue) +} + +func (da *FlowProbeFeatureDescriptorAdapter) Dependencies(key string, value proto.Message) []Dependency { + typedValue, err := castFlowProbeFeatureValue(key, value) + if err != nil { + return nil + } + return da.descriptor.Dependencies(key, typedValue) +} + +////////// Helper methods ////////// + +func castFlowProbeFeatureValue(key string, value proto.Message) (*vpp_ipfix.FlowProbeFeature, error) { + typedValue, ok := value.(*vpp_ipfix.FlowProbeFeature) + if !ok { + return nil, ErrInvalidValueType(key, value) + } + return typedValue, nil +} + +func castFlowProbeFeatureMetadata(key string, metadata Metadata) (interface{}, error) { + if metadata == nil { + return nil, nil + } + typedMetadata, ok := metadata.(interface{}) + if !ok { + return nil, ErrInvalidMetadataType(key) + } + return typedMetadata, nil +} diff --git a/plugins/vpp/ipfixplugin/descriptor/adapter/flowprobeparams.go b/plugins/vpp/ipfixplugin/descriptor/adapter/flowprobeparams.go new file mode 100644 index 0000000000..8b326d2253 --- /dev/null +++ b/plugins/vpp/ipfixplugin/descriptor/adapter/flowprobeparams.go @@ -0,0 +1,233 @@ +// Code generated by adapter-generator. DO NOT EDIT. + +package adapter + +import ( + "github.com/golang/protobuf/proto" + . "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" + "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +////////// type-safe key-value pair with metadata ////////// + +type FlowProbeParamsKVWithMetadata struct { + Key string + Value *vpp_ipfix.FlowProbeParams + Metadata interface{} + Origin ValueOrigin +} + +////////// type-safe Descriptor structure ////////// + +type FlowProbeParamsDescriptor struct { + Name string + KeySelector KeySelector + ValueTypeName string + KeyLabel func(key string) string + ValueComparator func(key string, oldValue, newValue *vpp_ipfix.FlowProbeParams) bool + NBKeyPrefix string + WithMetadata bool + MetadataMapFactory MetadataMapFactory + Validate func(key string, value *vpp_ipfix.FlowProbeParams) error + Create func(key string, value *vpp_ipfix.FlowProbeParams) (metadata interface{}, err error) + Delete func(key string, value *vpp_ipfix.FlowProbeParams, metadata interface{}) error + Update func(key string, oldValue, newValue *vpp_ipfix.FlowProbeParams, oldMetadata interface{}) (newMetadata interface{}, err error) + UpdateWithRecreate func(key string, oldValue, newValue *vpp_ipfix.FlowProbeParams, metadata interface{}) bool + Retrieve func(correlate []FlowProbeParamsKVWithMetadata) ([]FlowProbeParamsKVWithMetadata, error) + IsRetriableFailure func(err error) bool + DerivedValues func(key string, value *vpp_ipfix.FlowProbeParams) []KeyValuePair + Dependencies func(key string, value *vpp_ipfix.FlowProbeParams) []Dependency + RetrieveDependencies []string /* descriptor name */ +} + +////////// Descriptor adapter ////////// + +type FlowProbeParamsDescriptorAdapter struct { + descriptor *FlowProbeParamsDescriptor +} + +func NewFlowProbeParamsDescriptor(typedDescriptor *FlowProbeParamsDescriptor) *KVDescriptor { + adapter := &FlowProbeParamsDescriptorAdapter{descriptor: typedDescriptor} + descriptor := &KVDescriptor{ + Name: typedDescriptor.Name, + KeySelector: typedDescriptor.KeySelector, + ValueTypeName: typedDescriptor.ValueTypeName, + KeyLabel: typedDescriptor.KeyLabel, + NBKeyPrefix: typedDescriptor.NBKeyPrefix, + WithMetadata: typedDescriptor.WithMetadata, + MetadataMapFactory: typedDescriptor.MetadataMapFactory, + IsRetriableFailure: typedDescriptor.IsRetriableFailure, + RetrieveDependencies: typedDescriptor.RetrieveDependencies, + } + if typedDescriptor.ValueComparator != nil { + descriptor.ValueComparator = adapter.ValueComparator + } + if typedDescriptor.Validate != nil { + descriptor.Validate = adapter.Validate + } + if typedDescriptor.Create != nil { + descriptor.Create = adapter.Create + } + if typedDescriptor.Delete != nil { + descriptor.Delete = adapter.Delete + } + if typedDescriptor.Update != nil { + descriptor.Update = adapter.Update + } + if typedDescriptor.UpdateWithRecreate != nil { + descriptor.UpdateWithRecreate = adapter.UpdateWithRecreate + } + if typedDescriptor.Retrieve != nil { + descriptor.Retrieve = adapter.Retrieve + } + if typedDescriptor.Dependencies != nil { + descriptor.Dependencies = adapter.Dependencies + } + if typedDescriptor.DerivedValues != nil { + descriptor.DerivedValues = adapter.DerivedValues + } + return descriptor +} + +func (da *FlowProbeParamsDescriptorAdapter) ValueComparator(key string, oldValue, newValue proto.Message) bool { + typedOldValue, err1 := castFlowProbeParamsValue(key, oldValue) + typedNewValue, err2 := castFlowProbeParamsValue(key, newValue) + if err1 != nil || err2 != nil { + return false + } + return da.descriptor.ValueComparator(key, typedOldValue, typedNewValue) +} + +func (da *FlowProbeParamsDescriptorAdapter) Validate(key string, value proto.Message) (err error) { + typedValue, err := castFlowProbeParamsValue(key, value) + if err != nil { + return err + } + return da.descriptor.Validate(key, typedValue) +} + +func (da *FlowProbeParamsDescriptorAdapter) Create(key string, value proto.Message) (metadata Metadata, err error) { + typedValue, err := castFlowProbeParamsValue(key, value) + if err != nil { + return nil, err + } + return da.descriptor.Create(key, typedValue) +} + +func (da *FlowProbeParamsDescriptorAdapter) Update(key string, oldValue, newValue proto.Message, oldMetadata Metadata) (newMetadata Metadata, err error) { + oldTypedValue, err := castFlowProbeParamsValue(key, oldValue) + if err != nil { + return nil, err + } + newTypedValue, err := castFlowProbeParamsValue(key, newValue) + if err != nil { + return nil, err + } + typedOldMetadata, err := castFlowProbeParamsMetadata(key, oldMetadata) + if err != nil { + return nil, err + } + return da.descriptor.Update(key, oldTypedValue, newTypedValue, typedOldMetadata) +} + +func (da *FlowProbeParamsDescriptorAdapter) Delete(key string, value proto.Message, metadata Metadata) error { + typedValue, err := castFlowProbeParamsValue(key, value) + if err != nil { + return err + } + typedMetadata, err := castFlowProbeParamsMetadata(key, metadata) + if err != nil { + return err + } + return da.descriptor.Delete(key, typedValue, typedMetadata) +} + +func (da *FlowProbeParamsDescriptorAdapter) UpdateWithRecreate(key string, oldValue, newValue proto.Message, metadata Metadata) bool { + oldTypedValue, err := castFlowProbeParamsValue(key, oldValue) + if err != nil { + return true + } + newTypedValue, err := castFlowProbeParamsValue(key, newValue) + if err != nil { + return true + } + typedMetadata, err := castFlowProbeParamsMetadata(key, metadata) + if err != nil { + return true + } + return da.descriptor.UpdateWithRecreate(key, oldTypedValue, newTypedValue, typedMetadata) +} + +func (da *FlowProbeParamsDescriptorAdapter) Retrieve(correlate []KVWithMetadata) ([]KVWithMetadata, error) { + var correlateWithType []FlowProbeParamsKVWithMetadata + for _, kvpair := range correlate { + typedValue, err := castFlowProbeParamsValue(kvpair.Key, kvpair.Value) + if err != nil { + continue + } + typedMetadata, err := castFlowProbeParamsMetadata(kvpair.Key, kvpair.Metadata) + if err != nil { + continue + } + correlateWithType = append(correlateWithType, + FlowProbeParamsKVWithMetadata{ + Key: kvpair.Key, + Value: typedValue, + Metadata: typedMetadata, + Origin: kvpair.Origin, + }) + } + + typedValues, err := da.descriptor.Retrieve(correlateWithType) + if err != nil { + return nil, err + } + var values []KVWithMetadata + for _, typedKVWithMetadata := range typedValues { + kvWithMetadata := KVWithMetadata{ + Key: typedKVWithMetadata.Key, + Metadata: typedKVWithMetadata.Metadata, + Origin: typedKVWithMetadata.Origin, + } + kvWithMetadata.Value = typedKVWithMetadata.Value + values = append(values, kvWithMetadata) + } + return values, err +} + +func (da *FlowProbeParamsDescriptorAdapter) DerivedValues(key string, value proto.Message) []KeyValuePair { + typedValue, err := castFlowProbeParamsValue(key, value) + if err != nil { + return nil + } + return da.descriptor.DerivedValues(key, typedValue) +} + +func (da *FlowProbeParamsDescriptorAdapter) Dependencies(key string, value proto.Message) []Dependency { + typedValue, err := castFlowProbeParamsValue(key, value) + if err != nil { + return nil + } + return da.descriptor.Dependencies(key, typedValue) +} + +////////// Helper methods ////////// + +func castFlowProbeParamsValue(key string, value proto.Message) (*vpp_ipfix.FlowProbeParams, error) { + typedValue, ok := value.(*vpp_ipfix.FlowProbeParams) + if !ok { + return nil, ErrInvalidValueType(key, value) + } + return typedValue, nil +} + +func castFlowProbeParamsMetadata(key string, metadata Metadata) (interface{}, error) { + if metadata == nil { + return nil, nil + } + typedMetadata, ok := metadata.(interface{}) + if !ok { + return nil, ErrInvalidMetadataType(key) + } + return typedMetadata, nil +} diff --git a/plugins/vpp/ipfixplugin/descriptor/adapter/ipfix.go b/plugins/vpp/ipfixplugin/descriptor/adapter/ipfix.go new file mode 100644 index 0000000000..3cc5475a49 --- /dev/null +++ b/plugins/vpp/ipfixplugin/descriptor/adapter/ipfix.go @@ -0,0 +1,233 @@ +// Code generated by adapter-generator. DO NOT EDIT. + +package adapter + +import ( + "github.com/golang/protobuf/proto" + . "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" + "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +////////// type-safe key-value pair with metadata ////////// + +type IPFIXKVWithMetadata struct { + Key string + Value *vpp_ipfix.IPFIX + Metadata interface{} + Origin ValueOrigin +} + +////////// type-safe Descriptor structure ////////// + +type IPFIXDescriptor struct { + Name string + KeySelector KeySelector + ValueTypeName string + KeyLabel func(key string) string + ValueComparator func(key string, oldValue, newValue *vpp_ipfix.IPFIX) bool + NBKeyPrefix string + WithMetadata bool + MetadataMapFactory MetadataMapFactory + Validate func(key string, value *vpp_ipfix.IPFIX) error + Create func(key string, value *vpp_ipfix.IPFIX) (metadata interface{}, err error) + Delete func(key string, value *vpp_ipfix.IPFIX, metadata interface{}) error + Update func(key string, oldValue, newValue *vpp_ipfix.IPFIX, oldMetadata interface{}) (newMetadata interface{}, err error) + UpdateWithRecreate func(key string, oldValue, newValue *vpp_ipfix.IPFIX, metadata interface{}) bool + Retrieve func(correlate []IPFIXKVWithMetadata) ([]IPFIXKVWithMetadata, error) + IsRetriableFailure func(err error) bool + DerivedValues func(key string, value *vpp_ipfix.IPFIX) []KeyValuePair + Dependencies func(key string, value *vpp_ipfix.IPFIX) []Dependency + RetrieveDependencies []string /* descriptor name */ +} + +////////// Descriptor adapter ////////// + +type IPFIXDescriptorAdapter struct { + descriptor *IPFIXDescriptor +} + +func NewIPFIXDescriptor(typedDescriptor *IPFIXDescriptor) *KVDescriptor { + adapter := &IPFIXDescriptorAdapter{descriptor: typedDescriptor} + descriptor := &KVDescriptor{ + Name: typedDescriptor.Name, + KeySelector: typedDescriptor.KeySelector, + ValueTypeName: typedDescriptor.ValueTypeName, + KeyLabel: typedDescriptor.KeyLabel, + NBKeyPrefix: typedDescriptor.NBKeyPrefix, + WithMetadata: typedDescriptor.WithMetadata, + MetadataMapFactory: typedDescriptor.MetadataMapFactory, + IsRetriableFailure: typedDescriptor.IsRetriableFailure, + RetrieveDependencies: typedDescriptor.RetrieveDependencies, + } + if typedDescriptor.ValueComparator != nil { + descriptor.ValueComparator = adapter.ValueComparator + } + if typedDescriptor.Validate != nil { + descriptor.Validate = adapter.Validate + } + if typedDescriptor.Create != nil { + descriptor.Create = adapter.Create + } + if typedDescriptor.Delete != nil { + descriptor.Delete = adapter.Delete + } + if typedDescriptor.Update != nil { + descriptor.Update = adapter.Update + } + if typedDescriptor.UpdateWithRecreate != nil { + descriptor.UpdateWithRecreate = adapter.UpdateWithRecreate + } + if typedDescriptor.Retrieve != nil { + descriptor.Retrieve = adapter.Retrieve + } + if typedDescriptor.Dependencies != nil { + descriptor.Dependencies = adapter.Dependencies + } + if typedDescriptor.DerivedValues != nil { + descriptor.DerivedValues = adapter.DerivedValues + } + return descriptor +} + +func (da *IPFIXDescriptorAdapter) ValueComparator(key string, oldValue, newValue proto.Message) bool { + typedOldValue, err1 := castIPFIXValue(key, oldValue) + typedNewValue, err2 := castIPFIXValue(key, newValue) + if err1 != nil || err2 != nil { + return false + } + return da.descriptor.ValueComparator(key, typedOldValue, typedNewValue) +} + +func (da *IPFIXDescriptorAdapter) Validate(key string, value proto.Message) (err error) { + typedValue, err := castIPFIXValue(key, value) + if err != nil { + return err + } + return da.descriptor.Validate(key, typedValue) +} + +func (da *IPFIXDescriptorAdapter) Create(key string, value proto.Message) (metadata Metadata, err error) { + typedValue, err := castIPFIXValue(key, value) + if err != nil { + return nil, err + } + return da.descriptor.Create(key, typedValue) +} + +func (da *IPFIXDescriptorAdapter) Update(key string, oldValue, newValue proto.Message, oldMetadata Metadata) (newMetadata Metadata, err error) { + oldTypedValue, err := castIPFIXValue(key, oldValue) + if err != nil { + return nil, err + } + newTypedValue, err := castIPFIXValue(key, newValue) + if err != nil { + return nil, err + } + typedOldMetadata, err := castIPFIXMetadata(key, oldMetadata) + if err != nil { + return nil, err + } + return da.descriptor.Update(key, oldTypedValue, newTypedValue, typedOldMetadata) +} + +func (da *IPFIXDescriptorAdapter) Delete(key string, value proto.Message, metadata Metadata) error { + typedValue, err := castIPFIXValue(key, value) + if err != nil { + return err + } + typedMetadata, err := castIPFIXMetadata(key, metadata) + if err != nil { + return err + } + return da.descriptor.Delete(key, typedValue, typedMetadata) +} + +func (da *IPFIXDescriptorAdapter) UpdateWithRecreate(key string, oldValue, newValue proto.Message, metadata Metadata) bool { + oldTypedValue, err := castIPFIXValue(key, oldValue) + if err != nil { + return true + } + newTypedValue, err := castIPFIXValue(key, newValue) + if err != nil { + return true + } + typedMetadata, err := castIPFIXMetadata(key, metadata) + if err != nil { + return true + } + return da.descriptor.UpdateWithRecreate(key, oldTypedValue, newTypedValue, typedMetadata) +} + +func (da *IPFIXDescriptorAdapter) Retrieve(correlate []KVWithMetadata) ([]KVWithMetadata, error) { + var correlateWithType []IPFIXKVWithMetadata + for _, kvpair := range correlate { + typedValue, err := castIPFIXValue(kvpair.Key, kvpair.Value) + if err != nil { + continue + } + typedMetadata, err := castIPFIXMetadata(kvpair.Key, kvpair.Metadata) + if err != nil { + continue + } + correlateWithType = append(correlateWithType, + IPFIXKVWithMetadata{ + Key: kvpair.Key, + Value: typedValue, + Metadata: typedMetadata, + Origin: kvpair.Origin, + }) + } + + typedValues, err := da.descriptor.Retrieve(correlateWithType) + if err != nil { + return nil, err + } + var values []KVWithMetadata + for _, typedKVWithMetadata := range typedValues { + kvWithMetadata := KVWithMetadata{ + Key: typedKVWithMetadata.Key, + Metadata: typedKVWithMetadata.Metadata, + Origin: typedKVWithMetadata.Origin, + } + kvWithMetadata.Value = typedKVWithMetadata.Value + values = append(values, kvWithMetadata) + } + return values, err +} + +func (da *IPFIXDescriptorAdapter) DerivedValues(key string, value proto.Message) []KeyValuePair { + typedValue, err := castIPFIXValue(key, value) + if err != nil { + return nil + } + return da.descriptor.DerivedValues(key, typedValue) +} + +func (da *IPFIXDescriptorAdapter) Dependencies(key string, value proto.Message) []Dependency { + typedValue, err := castIPFIXValue(key, value) + if err != nil { + return nil + } + return da.descriptor.Dependencies(key, typedValue) +} + +////////// Helper methods ////////// + +func castIPFIXValue(key string, value proto.Message) (*vpp_ipfix.IPFIX, error) { + typedValue, ok := value.(*vpp_ipfix.IPFIX) + if !ok { + return nil, ErrInvalidValueType(key, value) + } + return typedValue, nil +} + +func castIPFIXMetadata(key string, metadata Metadata) (interface{}, error) { + if metadata == nil { + return nil, nil + } + typedMetadata, ok := metadata.(interface{}) + if !ok { + return nil, ErrInvalidMetadataType(key) + } + return typedMetadata, nil +} diff --git a/plugins/vpp/ipfixplugin/descriptor/flowprobe_feature.go b/plugins/vpp/ipfixplugin/descriptor/flowprobe_feature.go new file mode 100644 index 0000000000..567f8e62e1 --- /dev/null +++ b/plugins/vpp/ipfixplugin/descriptor/flowprobe_feature.go @@ -0,0 +1,121 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package descriptor + +import ( + "errors" + + "go.ligato.io/cn-infra/v2/logging" + + kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/descriptor/adapter" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +const ( + // FPFeatureDescriptorName is the name of the descriptor for + // VPP Flowprobe Feature configuration. + FPFeatureDescriptorName = "vpp-flowprobe-feature" +) + +// Validation errors: +var ( + // ErrIfaceNotDefined returned when interface in confiugration is empty string. + ErrIfaceNotDefined = errors.New("missing interface name for Flowprobe Feature") +) + +// FPFeatureDescriptor configures Flowprobe Feature for VPP. +type FPFeatureDescriptor struct { + ipfixHandler vppcalls.IpfixVppAPI + log logging.Logger +} + +// NewFPFeatureDescriptor creates a new instance of FPFeatureDescriptor. +func NewFPFeatureDescriptor(ipfixHandler vppcalls.IpfixVppAPI, log logging.PluginLogger) *kvs.KVDescriptor { + ctx := &FPFeatureDescriptor{ + ipfixHandler: ipfixHandler, + log: log.NewLogger("flowprobe-feature-descriptor"), + } + typedDescr := &adapter.FlowProbeFeatureDescriptor{ + Name: FPFeatureDescriptorName, + NBKeyPrefix: ipfix.ModelFlowprobeFeature.KeyPrefix(), + ValueTypeName: ipfix.ModelFlowprobeFeature.ProtoName(), + KeySelector: ipfix.ModelFlowprobeFeature.IsKeyValid, + KeyLabel: ipfix.ModelFlowprobeFeature.StripKeyPrefix, + WithMetadata: true, + Validate: ctx.Validate, + Create: ctx.Create, + Delete: ctx.Delete, + Retrieve: ctx.Retrieve, + Dependencies: ctx.Dependencies, + } + return adapter.NewFlowProbeFeatureDescriptor(typedDescr) +} + +// Validate checks if Flowprobe Feature configuration is good to send to VPP. +func (d *FPFeatureDescriptor) Validate(key string, value *ipfix.FlowProbeFeature) error { + if value.GetInterface() == "" { + return kvs.NewInvalidValueError(ErrIfaceNotDefined, "interface") + } + return nil +} + +// Create uses vppcalls to pass Flowprobe Feature configuration for interface to VPP. +func (d *FPFeatureDescriptor) Create(key string, val *ipfix.FlowProbeFeature) (metadata interface{}, err error) { + err = d.ipfixHandler.AddFPFeature(val) + return val, err +} + +// Delete uses vppcalls to remove Flowprobe Feature configuration for interface. +func (d *FPFeatureDescriptor) Delete(key string, val *ipfix.FlowProbeFeature, metadata interface{}) (err error) { + err = d.ipfixHandler.DelFPFeature(val) + return +} + +// Dependencies sets Flowprobe Params as a dependency which must be created +// before enabling Flowprobe Feature on an interface. +func (d *FPFeatureDescriptor) Dependencies(key string, val *ipfix.FlowProbeFeature) []kvs.Dependency { + return []kvs.Dependency{ + { + Label: "flowprobe-params", + Key: ipfix.FlowprobeParamsKey(), + }, + { + Label: "interface", + Key: interfaces.InterfaceKey(val.Interface), + }, + } +} + +// Retrieve hopes that configuration in correlate is actual configuration in VPP. +// As soon as VPP devs will add dump API calls, this methods should be fixed. +// TODO: waiting for https://jira.fd.io/browse/VPP-1861. +// +// Also, this method sets metadata, so descriptor for Flowprobe Params would know +// that there are some interfaces with Flowprobe Feature enabled. +func (d *FPFeatureDescriptor) Retrieve(correlate []adapter.FlowProbeFeatureKVWithMetadata) (retrieved []adapter.FlowProbeFeatureKVWithMetadata, err error) { + corr := make([]adapter.FlowProbeFeatureKVWithMetadata, len(correlate)) + for i, c := range correlate { + corr[i] = adapter.FlowProbeFeatureKVWithMetadata{ + Key: c.Key, + Value: c.Value, + Metadata: c.Value, + Origin: c.Origin, + } + } + return corr, nil +} diff --git a/plugins/vpp/ipfixplugin/descriptor/flowprobe_params.go b/plugins/vpp/ipfixplugin/descriptor/flowprobe_params.go new file mode 100644 index 0000000000..9bd55917a5 --- /dev/null +++ b/plugins/vpp/ipfixplugin/descriptor/flowprobe_params.go @@ -0,0 +1,128 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package descriptor + +import ( + "errors" + + "go.ligato.io/cn-infra/v2/idxmap" + "go.ligato.io/cn-infra/v2/logging" + + kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/descriptor/adapter" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +const ( + // FPParamsDescriptorName is the name of the descriptor for + // VPP Flowprobe Params configuration. + FPParamsDescriptorName = "vpp-flowprobe-params" +) + +var ( + // Validation errors: + + // ErrAllRecordFieldsDisabled returned when all record fields are set to false. + ErrAllRecordFieldsDisabled = errors.New("at least one of record fields (l2, l3, l4) must be set") + + // Non-retriable errors: + + // ErrFeatureEnabled informs the reason why Flowprobe Params can not be changed. + ErrFeatureEnabled = errors.New("can not change Flowprobe Params when Flowprobe Feature enabled on some interface") +) + +// FPParamsDescriptor configures Flowprobe Params for VPP. +type FPParamsDescriptor struct { + ipfixHandler vppcalls.IpfixVppAPI + featureMap idxmap.NamedMapping + log logging.Logger +} + +// NewFPParamsDescriptor creates a new instance of FPParamsDescriptor. +func NewFPParamsDescriptor(ipfixHandler vppcalls.IpfixVppAPI, featureMap idxmap.NamedMapping, log logging.PluginLogger) *kvs.KVDescriptor { + ctx := &FPParamsDescriptor{ + ipfixHandler: ipfixHandler, + featureMap: featureMap, + log: log.NewLogger("flowprobe-params-descriptor"), + } + typedDescr := &adapter.FlowProbeParamsDescriptor{ + Name: FPParamsDescriptorName, + NBKeyPrefix: ipfix.ModelFlowprobeParams.KeyPrefix(), + ValueTypeName: ipfix.ModelFlowprobeParams.ProtoName(), + KeySelector: ipfix.ModelFlowprobeParams.IsKeyValid, + KeyLabel: ipfix.ModelFlowprobeParams.StripKeyPrefix, + IsRetriableFailure: ctx.IsRetriableFailure, + Validate: ctx.Validate, + Create: ctx.Create, + Delete: ctx.Delete, + Update: ctx.Update, + Retrieve: ctx.Retrieve, + } + return adapter.NewFlowProbeParamsDescriptor(typedDescr) +} + +// Validate checks if Flowprobe Params are good to send to VPP. +func (d *FPParamsDescriptor) Validate(key string, value *ipfix.FlowProbeParams) error { + if !(value.GetRecordL2() || value.GetRecordL3() || value.GetRecordL4()) { + return kvs.NewInvalidValueError(ErrAllRecordFieldsDisabled, + "record_l2", "record_l3", "record_l4") + } + + return nil +} + +// IsRetriableFailure returns false if error is one of errors +// defined at the top of this file as non-retriable. +func (d *FPParamsDescriptor) IsRetriableFailure(err error) bool { + if errors.Is(err, ErrFeatureEnabled) { + return false + } + return true +} + +// Create passes Flowprobe Params to Update method. +func (d *FPParamsDescriptor) Create(key string, val *ipfix.FlowProbeParams) (metadata interface{}, err error) { + _, err = d.Update(key, nil, val, nil) + return +} + +// Update uses vppcalls to pass Flowprobe Params to VPP. +func (d *FPParamsDescriptor) Update(key string, oldVal, newVal *ipfix.FlowProbeParams, oldMetadata interface{}) (newMetadata interface{}, err error) { + // Check if there is at least one Flowporbe Feature configured on some interface. + if len(d.featureMap.ListAllNames()) > 0 { + err = ErrFeatureEnabled + return + } + err = d.ipfixHandler.SetFPParams(newVal) + return +} + +// Delete does nothing. +// +// Since all Flowprobe Features are dependent on Flowprobe Params, +// calling this method will also disable (move to "pending" state) +// all Flowprobe Features on interfaces. +// +// All the work will be done by KVScheduler :) +func (d *FPParamsDescriptor) Delete(key string, val *ipfix.FlowProbeParams, metadata interface{}) (err error) { + return +} + +// Retrieve hopes that configuration in correlate is actual configuration in VPP. +// As soon as VPP devs will add dump API calls, this methods should be fixed. +func (d *FPParamsDescriptor) Retrieve(correlate []adapter.FlowProbeParamsKVWithMetadata) (retrieved []adapter.FlowProbeParamsKVWithMetadata, err error) { + return correlate, nil +} diff --git a/plugins/vpp/ipfixplugin/descriptor/ipfix.go b/plugins/vpp/ipfixplugin/descriptor/ipfix.go new file mode 100644 index 0000000000..82a3f38f90 --- /dev/null +++ b/plugins/vpp/ipfixplugin/descriptor/ipfix.go @@ -0,0 +1,184 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package descriptor + +import ( + "errors" + + "go.ligato.io/cn-infra/v2/logging" + + "go.ligato.io/vpp-agent/v3/pkg/models" + kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/descriptor/adapter" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +const ( + // IPFIXDescriptorName is the name of the descriptor for + // VPP IP Flow Information eXport (IPFIX) configuration. + IPFIXDescriptorName = "vpp-ipfix" +) + +// Validation errors: +var ( + // ErrColAddrNotDefined returned when collector address in confiugration is empty string. + ErrColAddrNotDefined = errors.New("address of a collector was not provided") + // ErrSrcAddrNotDefined returned when source address in confiugration is empty string. + ErrSrcAddrNotDefined = errors.New("address of a source was not provided") + // ErrTooBigMTU informs about the maximum value for Path MTU. + ErrTooBigMTU = errors.New("too big value, maximum is 1450") + // ErrTooSmlMTU informs about the minimum value for Path MTU. + ErrTooSmlMTU = errors.New("too small value, minimum is 68") +) + +// IPFIXDescriptor configures IPFIX for VPP. +type IPFIXDescriptor struct { + ipfixHandler vppcalls.IpfixVppAPI + log logging.Logger +} + +// NewIPFIXDescriptor creates a new instance of IPFIXDescriptor. +func NewIPFIXDescriptor(ipfixHandler vppcalls.IpfixVppAPI, log logging.PluginLogger) *kvs.KVDescriptor { + ctx := &IPFIXDescriptor{ + ipfixHandler: ipfixHandler, + log: log.NewLogger("ipfix-descriptor"), + } + typedDescr := &adapter.IPFIXDescriptor{ + Name: IPFIXDescriptorName, + NBKeyPrefix: ipfix.ModelIPFIX.KeyPrefix(), + ValueTypeName: ipfix.ModelIPFIX.ProtoName(), + KeySelector: ipfix.ModelIPFIX.IsKeyValid, + KeyLabel: ipfix.ModelIPFIX.StripKeyPrefix, + ValueComparator: ctx.EquivalentIPFIX, + Validate: ctx.Validate, + Create: ctx.Create, + Delete: ctx.Delete, + Retrieve: ctx.Retrieve, + Update: ctx.Update, + } + return adapter.NewIPFIXDescriptor(typedDescr) +} + +// EquivalentIPFIX returns true if two IPFIX configurations are equal. +func (d *IPFIXDescriptor) EquivalentIPFIX(key string, oldValue, newValue *ipfix.IPFIX) bool { + if oldValue.GetCollector().GetAddress() != newValue.GetCollector().GetAddress() { + return false + } + + if oldValue.GetSourceAddress() != newValue.GetSourceAddress() { + return false + } + + oldPort := oldValue.GetCollector().GetPort() + newPort := newValue.GetCollector().GetPort() + if oldPort != newPort { + defaultPort := uint32(4739) + oldIsNotDefault := oldPort != 0 && oldPort != defaultPort + newIsNotDefault := newPort != 0 && newPort != defaultPort + + if oldIsNotDefault || newIsNotDefault { + return false + } + } + + if oldValue.GetVrfId() != newValue.GetVrfId() { + return false + } + + oldMTU := oldValue.GetPathMtu() + newMTU := newValue.GetPathMtu() + if oldMTU != newMTU { + defaultMTU := uint32(512) + oldIsNotDefault := oldMTU != 0 && oldMTU != defaultMTU + newIsNotDefault := newMTU != 0 && newMTU != defaultMTU + + if oldIsNotDefault || newIsNotDefault { + return false + } + } + + oldInterval := oldValue.GetTemplateInterval() + newInterval := newValue.GetTemplateInterval() + if oldInterval != newInterval { + defaultInterval := uint32(20) + oldIsNotDefault := oldInterval != 0 && oldInterval != defaultInterval + newIsNotDefault := newInterval != 0 && newInterval != defaultInterval + + if oldIsNotDefault || newIsNotDefault { + return false + } + } + + return true +} + +// Validate does basic check of VPP IPFIX configuration. +func (d *IPFIXDescriptor) Validate(key string, value *ipfix.IPFIX) error { + if value.GetCollector().GetAddress() == "" { + return kvs.NewInvalidValueError(ErrColAddrNotDefined, "collector.address") + } + + if value.GetSourceAddress() == "" { + return kvs.NewInvalidValueError(ErrSrcAddrNotDefined, "source_address") + } + + if mtu := value.GetPathMtu(); mtu == 0 { + // That's okay. No worries. VPP will use the default Path MTU value. + } else if mtu > vppcalls.MaxPathMTU { + return kvs.NewInvalidValueError(ErrTooBigMTU, "path_mtu") + } else if mtu < vppcalls.MinPathMTU { + return kvs.NewInvalidValueError(ErrTooSmlMTU, "path_mtu") + } + + return nil +} + +// Create calls Update method, because IPFIX configuration is always there and can not be created. +func (d *IPFIXDescriptor) Create(key string, val *ipfix.IPFIX) (metadata interface{}, err error) { + _, err = d.Update(key, nil, val, nil) + return +} + +// Update sets VPP IPFIX configuration. +func (d *IPFIXDescriptor) Update(key string, oldVal, newVal *ipfix.IPFIX, oldMetadata interface{}) (newMetadata interface{}, err error) { + err = d.ipfixHandler.SetExporter(newVal) + return +} + +// Delete does nothing, because there are neither ability +// nor reasons to delete VPP IPFIX configuration. +// You can only configure exporting in a way you want to. +func (d *IPFIXDescriptor) Delete(key string, val *ipfix.IPFIX, metadata interface{}) (err error) { + return nil +} + +// Retrieve returns configuration of IP Flow Infromation eXporter. +func (d *IPFIXDescriptor) Retrieve(correlate []adapter.IPFIXKVWithMetadata) (retrieved []adapter.IPFIXKVWithMetadata, err error) { + ipfixes, err := d.ipfixHandler.DumpExporters() + if err != nil { + return nil, err + } + + for _, e := range ipfixes { + retrieved = append(retrieved, adapter.IPFIXKVWithMetadata{ + Key: models.Key(e), + Value: e, + Origin: kvs.FromSB, + }) + } + + return retrieved, nil +} diff --git a/plugins/vpp/ipfixplugin/ipfixplugin.go b/plugins/vpp/ipfixplugin/ipfixplugin.go new file mode 100644 index 0000000000..fda98e6ffb --- /dev/null +++ b/plugins/vpp/ipfixplugin/ipfixplugin.go @@ -0,0 +1,103 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:generate descriptor-adapter --descriptor-name IPFIX --value-type *vpp_ipfix.IPFIX --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" --output-dir "descriptor" +//go:generate descriptor-adapter --descriptor-name FlowProbeFeature --value-type *vpp_ipfix.FlowProbeFeature --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" --output-dir "descriptor" +//go:generate descriptor-adapter --descriptor-name FlowProbeParams --value-type *vpp_ipfix.FlowProbeParams --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" --output-dir "descriptor" + +package ipfixplugin + +import ( + "errors" + + "go.ligato.io/cn-infra/v2/infra" + + "go.ligato.io/vpp-agent/v3/plugins/govppmux" + kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/descriptor" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + + _ "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls/vpp1904" + _ "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls/vpp1908" + _ "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls/vpp2001" +) + +// IPFIXPlugin is a plugin that manages IPFIX configuration in VPP. +// IPFIX - IP Flow Information Export (IPFIX). +// It allows to: +// - configure export of Flowprobe information; +// - configure Flowprobe Params; +// - enable/disable Flowprobe Feature for an interface. +// +// Things to rememmber: +// - Flowprobe Feature can not be configured for any interface, +// if Flowprobe Params were not set. +// - Flowprobe Params can not be changed, +// if Flowprobe Feature was enabled for at least one interface. +type IPFIXPlugin struct { + Deps + + // VPP handler. + ipfixHandler vppcalls.IpfixVppAPI +} + +// Deps represents dependencies for the plugin. +type Deps struct { + infra.PluginDeps + KVScheduler kvs.KVScheduler + VPP govppmux.API + IfPlugin ifplugin.API +} + +// Init initializes IPFIX plugin. +func (p *IPFIXPlugin) Init() (err error) { + // Even with IPFIX being part of a core of VPP, without Flowprobe plugin + // there would be no information to export, hence no point in this plugin. + if !p.VPP.IsPluginLoaded("flowprobe") { + p.Log.Warnf("VPP plugin Flowprobe was disabled by VPP") + return nil + } + + p.ipfixHandler = vppcalls.CompatibleIpfixVppHandler(p.VPP, p.IfPlugin.GetInterfaceIndex(), p.Log) + if p.ipfixHandler == nil { + return errors.New("IPFIX VPP handler is not available") + } + + ipfixDescriptor := descriptor.NewIPFIXDescriptor(p.ipfixHandler, p.Log) + err = p.KVScheduler.RegisterKVDescriptor(ipfixDescriptor) + if err != nil { + return err + } + + fpFeatureDescriptor := descriptor.NewFPFeatureDescriptor(p.ipfixHandler, p.Log) + err = p.KVScheduler.RegisterKVDescriptor(fpFeatureDescriptor) + if err != nil { + return err + } + + // Descriptor for Flowprobe Params will use `fpFeatureMM` to check + // if Flowprobe Params can be updated. If at least one item is in this + // map, than there is at least one interface with Flowprobe Feature + // enabled, hence Flowprobe Params update is not allowed. + fpFeatureMM := p.KVScheduler.GetMetadataMap(fpFeatureDescriptor.Name) + + fpParamsDescriptor := descriptor.NewFPParamsDescriptor(p.ipfixHandler, fpFeatureMM, p.Log) + err = p.KVScheduler.RegisterKVDescriptor(fpParamsDescriptor) + if err != nil { + return err + } + + return nil +} diff --git a/plugins/vpp/ipfixplugin/options.go b/plugins/vpp/ipfixplugin/options.go new file mode 100644 index 0000000000..c5b12d4f30 --- /dev/null +++ b/plugins/vpp/ipfixplugin/options.go @@ -0,0 +1,60 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ipfixplugin + +import ( + "go.ligato.io/cn-infra/v2/config" + "go.ligato.io/cn-infra/v2/logging" + + "go.ligato.io/vpp-agent/v3/plugins/govppmux" + "go.ligato.io/vpp-agent/v3/plugins/kvscheduler" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin" +) + +// DefaultPlugin is a default instance of IPFIXPlugin. +var DefaultPlugin = *NewPlugin() + +// NewPlugin creates a new Plugin with the provides Options. +func NewPlugin(opts ...Option) *IPFIXPlugin { + p := &IPFIXPlugin{} + + p.PluginName = "vpp-ipfixplugin" + p.KVScheduler = &kvscheduler.DefaultPlugin + p.VPP = &govppmux.DefaultPlugin + p.IfPlugin = &ifplugin.DefaultPlugin + + for _, o := range opts { + o(p) + } + + if p.Log == nil { + p.Log = logging.ForPlugin(p.String()) + } + if p.Cfg == nil { + p.Cfg = config.ForPlugin(p.String()) + } + + return p +} + +// Option is a function that can be used in NewPlugin to customize Plugin. +type Option func(*IPFIXPlugin) + +// UseDeps returns Option that can inject custom dependencies. +func UseDeps(f func(*Deps)) Option { + return func(p *IPFIXPlugin) { + f(&p.Deps) + } +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/doc.go b/plugins/vpp/ipfixplugin/vppcalls/doc.go new file mode 100644 index 0000000000..a9f4db9995 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/doc.go @@ -0,0 +1,16 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package vppcalls contains wrappers over VPP IPFIX and VPP Flowprobe binary APIs. +package vppcalls diff --git a/plugins/vpp/ipfixplugin/vppcalls/ipfix_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/ipfix_vppcalls.go new file mode 100644 index 0000000000..8022cdf8f6 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/ipfix_vppcalls.go @@ -0,0 +1,77 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vppcalls + +import ( + govppapi "git.fd.io/govpp.git/api" + "go.ligato.io/cn-infra/v2/logging" + + "go.ligato.io/vpp-agent/v3/plugins/vpp" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +const ( + // MinPathMTU and MaxPathMTU values were copied from VPP source code. + // If something will change, please, be kind and update values here + // and also update error messages in the IPFIX descriptor. + MinPathMTU = 68 + MaxPathMTU = 1450 +) + +// IpfixVppAPI provides methods for managing VPP IPFIX configuration. +type IpfixVppAPI interface { + SetExporter(conf *ipfix.IPFIX) error + DumpExporters() ([]*ipfix.IPFIX, error) + + SetFPParams(conf *ipfix.FlowProbeParams) error + + AddFPFeature(conf *ipfix.FlowProbeFeature) error + DelFPFeature(conf *ipfix.FlowProbeFeature) error +} + +var handler = vpp.RegisterHandler(vpp.HandlerDesc{ + Name: "ipfix", + HandlerAPI: (*IpfixVppAPI)(nil), +}) + +func AddIpfixHandlerVersion(version vpp.Version, msgs []govppapi.Message, + h func(ch govppapi.Channel, ifIdx ifaceidx.IfaceMetadataIndex, log logging.Logger) IpfixVppAPI, +) { + handler.AddVersion(vpp.HandlerVersion{ + Version: version, + Check: func(c vpp.Client) error { + ch, err := c.NewAPIChannel() + if err != nil { + return err + } + return ch.CheckCompatiblity(msgs...) + }, + NewHandler: func(c vpp.Client, a ...interface{}) vpp.HandlerAPI { + ch, err := c.NewAPIChannel() + if err != nil { + return err + } + return h(ch, a[0].(ifaceidx.IfaceMetadataIndex), a[1].(logging.Logger)) + }, + }) +} + +func CompatibleIpfixVppHandler(c vpp.Client, ifIdx ifaceidx.IfaceMetadataIndex, log logging.Logger) IpfixVppAPI { + if v := handler.FindCompatibleVersion(c); v != nil { + return v.NewHandler(c, ifIdx, log).(IpfixVppAPI) + } + return nil +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1904/dump_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/dump_vppcalls.go new file mode 100644 index 0000000000..bd729d4a3e --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/dump_vppcalls.go @@ -0,0 +1,65 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1904 + +import ( + "fmt" + "net" + + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/ipfix_export" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// DumpExporters returns configured IPFIX. +// Since it always only one IPFIX configuration, this method signature +// defined as it is to keep consistensy between different vppcalls packages. +// +// Caution: VPP 19.04 does not support IPv6 addresses for IPFIX configuration, +// but this may change in future versions. Be careful porting this method to +// another version of VPP. +// +func (h *IpfixVppHandler) DumpExporters() ([]*ipfix.IPFIX, error) { + var ipfixes []*ipfix.IPFIX + reqCtx := h.callsChannel.SendMultiRequest(&vpp_ipfix.IpfixExporterDump{}) + for { + details := &vpp_ipfix.IpfixExporterDetails{} + stop, err := reqCtx.ReceiveReply(details) + if stop { + break + } + if err != nil { + return nil, fmt.Errorf("failed to dump IPFIX: %v", err) + } + + collectorIPAddr := net.IP(details.CollectorAddress[:4]).To4() + sourceIPAddr := net.IP(details.SrcAddress[:4]).To4() + + ipfixes = append(ipfixes, + &ipfix.IPFIX{ + Collector: &ipfix.IPFIX_Collector{ + Address: collectorIPAddr.String(), + Port: uint32(details.CollectorPort), + }, + SourceAddress: sourceIPAddr.String(), + VrfId: details.VrfID, + PathMtu: details.PathMtu, + TemplateInterval: details.TemplateInterval, + }, + ) + + } + + return ipfixes, nil +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1904/flowprobe_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/flowprobe_vppcalls.go new file mode 100644 index 0000000000..7cfac5944c --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/flowprobe_vppcalls.go @@ -0,0 +1,99 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1904 + +import ( + "github.com/pkg/errors" + + vpp_flowprobe "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/flowprobe" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// SetFPParams sends message with configuration for Flowprobe. +func (h *IpfixVppHandler) SetFPParams(conf *ipfix.FlowProbeParams) error { + var rL2, rL3, rL4 uint8 + + if conf.GetRecordL2() { + rL2 = 1 + } + if conf.GetRecordL3() { + rL3 = 1 + } + if conf.GetRecordL4() { + rL4 = 1 + } + + if rL2 != 1 && rL3 != 1 && rL4 != 1 { + err := errors.New("one of the record fields (l2, l3 or l4) must be enabled") + return err + } + + req := &vpp_flowprobe.FlowprobeParams{ + RecordL2: rL2, + RecordL3: rL3, + RecordL4: rL4, + ActiveTimer: conf.GetActiveTimer(), + PassiveTimer: conf.GetPassiveTimer(), + } + reply := &vpp_flowprobe.FlowprobeParamsReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +func (h *IpfixVppHandler) sendFPFeature(isAdd uint8, conf *ipfix.FlowProbeFeature) error { + meta, found := h.ifIndexes.LookupByName(conf.Interface) + if !found { + return errors.Errorf("interface %s not found", conf.Interface) + } + + var flags uint8 + + if conf.GetL2() { + flags |= 0b001 + } + if conf.GetIp4() { + flags |= 0b010 + } + if conf.GetIp6() { + flags |= 0b100 + } + + req := &vpp_flowprobe.FlowprobeTxInterfaceAddDel{ + IsAdd: isAdd, + Which: flags, + SwIfIndex: meta.SwIfIndex, + } + reply := &vpp_flowprobe.FlowprobeTxInterfaceAddDelReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +// AddFPFeature sends message to enable Flowprobe on interface. +func (h *IpfixVppHandler) AddFPFeature(conf *ipfix.FlowProbeFeature) error { + return h.sendFPFeature(1, conf) +} + +// DelFPFeature sends message to disable Flowprobe on interface. +func (h *IpfixVppHandler) DelFPFeature(conf *ipfix.FlowProbeFeature) error { + return h.sendFPFeature(0, conf) +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1904/ipfix_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/ipfix_vppcalls.go new file mode 100644 index 0000000000..eba08125bf --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/ipfix_vppcalls.go @@ -0,0 +1,100 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1904 + +import ( + "bytes" + "errors" + "fmt" + "net" + + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/ipfix_export" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// SetExporter configures IP Flow Information eXport (IPFIX). +func (h *IpfixVppHandler) SetExporter(conf *ipfix.IPFIX) error { + collectorAddr, err := prepareAddress(conf.GetCollector().GetAddress()) + if err != nil { + return fmt.Errorf("bad collector address: %v", err) + } + + sourceAddr, err := prepareAddress(conf.GetSourceAddress()) + if err != nil { + return fmt.Errorf("bad source address: %v", err) + } + + collectorPort := uint16(conf.GetCollector().GetPort()) + if collectorPort == 0 { + // Will be set by VPP to the default value: 4739. + collectorPort = ^uint16(0) + } + + mtu := conf.GetPathMtu() + if mtu == 0 { + // Will be set by VPP to the default value: 512 bytes. + mtu = ^uint32(0) + } else if mtu < vppcalls.MinPathMTU || mtu > vppcalls.MaxPathMTU { + err := errors.New("path MTU is not in allowed range") + return err + } + + tmplInterval := conf.GetTemplateInterval() + if tmplInterval == 0 { + // Will be set by VPP to the default value: 20 sec. + tmplInterval = ^uint32(0) + } + + req := &vpp_ipfix.SetIpfixExporter{ + CollectorAddress: collectorAddr, + CollectorPort: collectorPort, + SrcAddress: sourceAddr, + VrfID: conf.GetVrfId(), + PathMtu: mtu, + TemplateInterval: tmplInterval, + } + reply := &vpp_ipfix.SetIpfixExporterReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +// prepareAddress validates and converts IP address, +// defined as a string, to bytes. +func prepareAddress(addrStr string) ([]byte, error) { + addrBytes := make([]byte, 4) + + addr := net.ParseIP(addrStr) + if addr == nil { + err := errors.New("can not parse address") + return addrBytes, err + } + if addr.To4() == nil { + err := errors.New("IPv6 is not supported") + return addrBytes, err + } + + copy(addrBytes, addr.To4()) + if bytes.Equal(addrBytes, []byte{0, 0, 0, 0}) { + err := errors.New("address must not be all zeros") + return addrBytes, err + } + + return addrBytes, nil +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1904/vppcalls_handlers.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/vppcalls_handlers.go new file mode 100644 index 0000000000..af8f49af28 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1904/vppcalls_handlers.go @@ -0,0 +1,52 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1904 + +import ( + govppapi "git.fd.io/govpp.git/api" + "go.ligato.io/cn-infra/v2/logging" + + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904" + vpp_fp "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/flowprobe" + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1904/ipfix_export" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" +) + +func init() { + var msgs []govppapi.Message + msgs = append(msgs, vpp_ipfix.AllMessages()...) + msgs = append(msgs, vpp_fp.AllMessages()...) + + vppcalls.AddIpfixHandlerVersion(vpp1904.Version, msgs, NewIpfixVppHandler) +} + +// IpfixVppHandler is accessor for IPFIX-related vppcalls methods. +type IpfixVppHandler struct { + callsChannel govppapi.Channel + ifIndexes ifaceidx.IfaceMetadataIndex + log logging.Logger +} + +// NewIpfixVppHandler creates new instance of IPFIX vppcalls handler. +func NewIpfixVppHandler(callsChan govppapi.Channel, + ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger, +) vppcalls.IpfixVppAPI { + return &IpfixVppHandler{ + callsChannel: callsChan, + ifIndexes: ifIndexes, + log: log, + } +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1908/dump_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/dump_vppcalls.go new file mode 100644 index 0000000000..c2f5b64634 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/dump_vppcalls.go @@ -0,0 +1,65 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1908 + +import ( + "fmt" + "net" + + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/ipfix_export" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// DumpExporters returns configured IPFIX. +// Since it always only one IPFIX configuration, this method signature +// defined as it is to keep consistensy between different vppcalls packages. +// +// Caution: VPP 19.08 does not support IPv6 addresses for IPFIX configuration, +// but this may change in future versions. Be careful porting this method to +// another version of VPP. +// +func (h *IpfixVppHandler) DumpExporters() ([]*ipfix.IPFIX, error) { + var ipfixes []*ipfix.IPFIX + reqCtx := h.callsChannel.SendMultiRequest(&vpp_ipfix.IpfixExporterDump{}) + for { + details := &vpp_ipfix.IpfixExporterDetails{} + stop, err := reqCtx.ReceiveReply(details) + if stop { + break + } + if err != nil { + return nil, fmt.Errorf("failed to dump IPFIX: %v", err) + } + + collectorIPAddr := net.IP(details.CollectorAddress[:4]).To4() + sourceIPAddr := net.IP(details.SrcAddress[:4]).To4() + + ipfixes = append(ipfixes, + &ipfix.IPFIX{ + Collector: &ipfix.IPFIX_Collector{ + Address: collectorIPAddr.String(), + Port: uint32(details.CollectorPort), + }, + SourceAddress: sourceIPAddr.String(), + VrfId: details.VrfID, + PathMtu: details.PathMtu, + TemplateInterval: details.TemplateInterval, + }, + ) + + } + + return ipfixes, nil +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1908/flowprobe_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/flowprobe_vppcalls.go new file mode 100644 index 0000000000..1b5a8c9d9f --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/flowprobe_vppcalls.go @@ -0,0 +1,99 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1908 + +import ( + "github.com/pkg/errors" + + vpp_flowprobe "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/flowprobe" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// SetFPParams sends message with configuration for Flowprobe. +func (h *IpfixVppHandler) SetFPParams(conf *ipfix.FlowProbeParams) error { + var rL2, rL3, rL4 uint8 + + if conf.GetRecordL2() { + rL2 = 1 + } + if conf.GetRecordL3() { + rL3 = 1 + } + if conf.GetRecordL4() { + rL4 = 1 + } + + if rL2 != 1 && rL3 != 1 && rL4 != 1 { + err := errors.New("one of the record fields (l2, l3 or l4) must be enabled") + return err + } + + req := &vpp_flowprobe.FlowprobeParams{ + RecordL2: rL2, + RecordL3: rL3, + RecordL4: rL4, + ActiveTimer: conf.GetActiveTimer(), + PassiveTimer: conf.GetPassiveTimer(), + } + reply := &vpp_flowprobe.FlowprobeParamsReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +func (h *IpfixVppHandler) sendFPFeature(isAdd uint8, conf *ipfix.FlowProbeFeature) error { + meta, found := h.ifIndexes.LookupByName(conf.Interface) + if !found { + return errors.Errorf("interface %s not found", conf.Interface) + } + + var flags uint8 + + if conf.GetL2() { + flags |= 0b001 + } + if conf.GetIp4() { + flags |= 0b010 + } + if conf.GetIp6() { + flags |= 0b100 + } + + req := &vpp_flowprobe.FlowprobeTxInterfaceAddDel{ + IsAdd: isAdd, + Which: flags, + SwIfIndex: meta.SwIfIndex, + } + reply := &vpp_flowprobe.FlowprobeTxInterfaceAddDelReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +// AddFPFeature sends message to enable Flowprobe on interface. +func (h *IpfixVppHandler) AddFPFeature(conf *ipfix.FlowProbeFeature) error { + return h.sendFPFeature(1, conf) +} + +// DelFPFeature sends message to disable Flowprobe on interface. +func (h *IpfixVppHandler) DelFPFeature(conf *ipfix.FlowProbeFeature) error { + return h.sendFPFeature(0, conf) +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1908/ipfix_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/ipfix_vppcalls.go new file mode 100644 index 0000000000..17930c2c7e --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/ipfix_vppcalls.go @@ -0,0 +1,100 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1908 + +import ( + "bytes" + "errors" + "fmt" + "net" + + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/ipfix_export" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// SetExporter configures IP Flow Information eXport (IPFIX). +func (h *IpfixVppHandler) SetExporter(conf *ipfix.IPFIX) error { + collectorAddr, err := prepareAddress(conf.GetCollector().GetAddress()) + if err != nil { + return fmt.Errorf("bad collector address: %v", err) + } + + sourceAddr, err := prepareAddress(conf.GetSourceAddress()) + if err != nil { + return fmt.Errorf("bad source address: %v", err) + } + + collectorPort := uint16(conf.GetCollector().GetPort()) + if collectorPort == 0 { + // Will be set by VPP to the default value: 4739. + collectorPort = ^uint16(0) + } + + mtu := conf.GetPathMtu() + if mtu == 0 { + // Will be set by VPP to the default value: 512 bytes. + mtu = ^uint32(0) + } else if mtu < vppcalls.MinPathMTU || mtu > vppcalls.MaxPathMTU { + err := errors.New("path MTU is not in allowed range") + return err + } + + tmplInterval := conf.GetTemplateInterval() + if tmplInterval == 0 { + // Will be set by VPP to the default value: 20 sec. + tmplInterval = ^uint32(0) + } + + req := &vpp_ipfix.SetIpfixExporter{ + CollectorAddress: collectorAddr, + CollectorPort: collectorPort, + SrcAddress: sourceAddr, + VrfID: conf.GetVrfId(), + PathMtu: mtu, + TemplateInterval: tmplInterval, + } + reply := &vpp_ipfix.SetIpfixExporterReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +// prepareAddress validates and converts IP address, +// defined as a string, to bytes. +func prepareAddress(addrStr string) ([]byte, error) { + addrBytes := make([]byte, 4) + + addr := net.ParseIP(addrStr) + if addr == nil { + err := errors.New("can not parse address") + return addrBytes, err + } + if addr.To4() == nil { + err := errors.New("IPv6 is not supported") + return addrBytes, err + } + + copy(addrBytes, addr.To4()) + if bytes.Equal(addrBytes, []byte{0, 0, 0, 0}) { + err := errors.New("address must not be all zeros") + return addrBytes, err + } + + return addrBytes, nil +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp1908/vppcalls_handlers.go b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/vppcalls_handlers.go new file mode 100644 index 0000000000..45d53bb6c8 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp1908/vppcalls_handlers.go @@ -0,0 +1,52 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp1908 + +import ( + govppapi "git.fd.io/govpp.git/api" + "go.ligato.io/cn-infra/v2/logging" + + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908" + vpp_fp "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/flowprobe" + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp1908/ipfix_export" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" +) + +func init() { + var msgs []govppapi.Message + msgs = append(msgs, vpp_ipfix.AllMessages()...) + msgs = append(msgs, vpp_fp.AllMessages()...) + + vppcalls.AddIpfixHandlerVersion(vpp1908.Version, msgs, NewIpfixVppHandler) +} + +// IpfixVppHandler is accessor for IPFIX-related vppcalls methods. +type IpfixVppHandler struct { + callsChannel govppapi.Channel + ifIndexes ifaceidx.IfaceMetadataIndex + log logging.Logger +} + +// NewIpfixVppHandler creates new instance of IPFIX vppcalls handler. +func NewIpfixVppHandler(callsChan govppapi.Channel, + ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger, +) vppcalls.IpfixVppAPI { + return &IpfixVppHandler{ + callsChannel: callsChan, + ifIndexes: ifIndexes, + log: log, + } +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp2001/dump_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/dump_vppcalls.go new file mode 100644 index 0000000000..fb0f103252 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/dump_vppcalls.go @@ -0,0 +1,65 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp2001 + +import ( + "fmt" + "net" + + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ipfix_export" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// DumpExporters returns configured IPFIX. +// Since it always only one IPFIX configuration, this method signature +// defined as it is to keep consistensy between different vppcalls packages. +// +// Caution: VPP 20.01 does not support IPv6 addresses for IPFIX configuration, +// but this may change in future versions. Be careful porting this method to +// another version of VPP. +// +func (h *IpfixVppHandler) DumpExporters() ([]*ipfix.IPFIX, error) { + var ipfixes []*ipfix.IPFIX + reqCtx := h.callsChannel.SendMultiRequest(&vpp_ipfix.IpfixExporterDump{}) + for { + details := &vpp_ipfix.IpfixExporterDetails{} + stop, err := reqCtx.ReceiveReply(details) + if stop { + break + } + if err != nil { + return nil, fmt.Errorf("failed to dump IPFIX: %v", err) + } + + collectorIPAddr := details.CollectorAddress.Un.GetIP4() + sourceIPAddr := details.SrcAddress.Un.GetIP4() + + ipfixes = append(ipfixes, + &ipfix.IPFIX{ + Collector: &ipfix.IPFIX_Collector{ + Address: net.IP(collectorIPAddr[:]).To4().String(), + Port: uint32(details.CollectorPort), + }, + SourceAddress: net.IP(sourceIPAddr[:]).To4().String(), + VrfId: details.VrfID, + PathMtu: details.PathMtu, + TemplateInterval: details.TemplateInterval, + }, + ) + + } + + return ipfixes, nil +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp2001/flowprobe_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/flowprobe_vppcalls.go new file mode 100644 index 0000000000..e732ee4c88 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/flowprobe_vppcalls.go @@ -0,0 +1,102 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp2001 + +import ( + "github.com/pkg/errors" + + vpp_flowprobe "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/flowprobe" + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/interface_types" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// SetFPParams sends message with configuration for Flowprobe. +func (h *IpfixVppHandler) SetFPParams(conf *ipfix.FlowProbeParams) error { + var flags vpp_flowprobe.FlowprobeRecordFlags + + if conf.GetRecordL2() { + flags |= vpp_flowprobe.FLOWPROBE_RECORD_FLAG_L2 + } + + if conf.GetRecordL3() { + flags |= vpp_flowprobe.FLOWPROBE_RECORD_FLAG_L3 + } + + if conf.GetRecordL4() { + flags |= vpp_flowprobe.FLOWPROBE_RECORD_FLAG_L4 + } + + if flags == 0 { + err := errors.New("one of the record fields (l2, l3 or l4) must be enabled") + return err + } + + req := &vpp_flowprobe.FlowprobeParams{ + RecordFlags: flags, + ActiveTimer: conf.GetActiveTimer(), + PassiveTimer: conf.GetPassiveTimer(), + } + reply := &vpp_flowprobe.FlowprobeParamsReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +func (h *IpfixVppHandler) sendFPFeature(isAdd bool, conf *ipfix.FlowProbeFeature) error { + meta, found := h.ifIndexes.LookupByName(conf.Interface) + if !found { + return errors.Errorf("interface %s not found", conf.Interface) + } + + var flags vpp_flowprobe.FlowprobeWhichFlags + + if conf.GetL2() { + flags |= vpp_flowprobe.FLOWPROBE_WHICH_FLAG_L2 + } + + if conf.GetIp4() { + flags |= vpp_flowprobe.FLOWPROBE_WHICH_FLAG_IP4 + } + + if conf.GetIp6() { + flags |= vpp_flowprobe.FLOWPROBE_WHICH_FLAG_IP6 + } + + req := &vpp_flowprobe.FlowprobeTxInterfaceAddDel{ + IsAdd: isAdd, + Which: flags, + SwIfIndex: interface_types.InterfaceIndex(meta.SwIfIndex), + } + reply := &vpp_flowprobe.FlowprobeTxInterfaceAddDelReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +// AddFPFeature sends message to enable Flowprobe on interface. +func (h *IpfixVppHandler) AddFPFeature(conf *ipfix.FlowProbeFeature) error { + return h.sendFPFeature(true, conf) +} + +// DelFPFeature sends message to disable Flowprobe on interface. +func (h *IpfixVppHandler) DelFPFeature(conf *ipfix.FlowProbeFeature) error { + return h.sendFPFeature(false, conf) +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp2001/ipfix_vppcalls.go b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/ipfix_vppcalls.go new file mode 100644 index 0000000000..3162c938a9 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/ipfix_vppcalls.go @@ -0,0 +1,107 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp2001 + +import ( + "bytes" + "errors" + "fmt" + "net" + + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ip_types" + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ipfix_export" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" +) + +// SetExporter configures IP Flow Information eXport (IPFIX). +func (h *IpfixVppHandler) SetExporter(conf *ipfix.IPFIX) error { + collectorAddr, err := prepareAddress(conf.GetCollector().GetAddress()) + if err != nil { + return fmt.Errorf("bad collector address: %v", err) + } + + sourceAddr, err := prepareAddress(conf.GetSourceAddress()) + if err != nil { + return fmt.Errorf("bad source address: %v", err) + } + + collectorPort := uint16(conf.GetCollector().GetPort()) + if collectorPort == 0 { + // Will be set by VPP to the default value: 4739. + collectorPort = ^uint16(0) + } + + mtu := conf.GetPathMtu() + if mtu == 0 { + // Will be set by VPP to the default value: 512 bytes. + mtu = ^uint32(0) + } else if mtu < vppcalls.MinPathMTU || mtu > vppcalls.MaxPathMTU { + err := errors.New("path MTU is not in allowed range") + return err + } + + tmplInterval := conf.GetTemplateInterval() + if tmplInterval == 0 { + // Will be set by VPP to the default value: 20 sec. + tmplInterval = ^uint32(0) + } + + req := &vpp_ipfix.SetIpfixExporter{ + CollectorAddress: collectorAddr, + CollectorPort: collectorPort, + SrcAddress: sourceAddr, + VrfID: conf.GetVrfId(), + PathMtu: mtu, + TemplateInterval: tmplInterval, + } + reply := &vpp_ipfix.SetIpfixExporterReply{} + + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return err + } + + return nil +} + +// prepareAddress validates and converts IP address, defined as a string, +// to the type which represents address in VPP binary API. +func prepareAddress(addrStr string) (ip_types.Address, error) { + var a ip_types.Address + + addr := net.ParseIP(addrStr) + if addr == nil { + err := errors.New("can not parse address") + return a, err + } + if addr.To4() == nil { + err := errors.New("IPv6 is not supported") + return a, err + } + + var addrBytes [4]byte + copy(addrBytes[:], addr.To4()) + if bytes.Equal(addrBytes[:], []byte{0, 0, 0, 0}) { + err := errors.New("address must not be all zeros") + return a, err + } + + a = ip_types.Address{ + Af: ip_types.ADDRESS_IP4, + Un: ip_types.AddressUnionIP4(addrBytes), + } + + return a, nil +} diff --git a/plugins/vpp/ipfixplugin/vppcalls/vpp2001/vppcalls_handlers.go b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/vppcalls_handlers.go new file mode 100644 index 0000000000..af51afa373 --- /dev/null +++ b/plugins/vpp/ipfixplugin/vppcalls/vpp2001/vppcalls_handlers.go @@ -0,0 +1,52 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp2001 + +import ( + govppapi "git.fd.io/govpp.git/api" + "go.ligato.io/cn-infra/v2/logging" + + "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001" + vpp_fp "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/flowprobe" + vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2001/ipfix_export" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" + "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" +) + +func init() { + var msgs []govppapi.Message + msgs = append(msgs, vpp_ipfix.AllMessages()...) + msgs = append(msgs, vpp_fp.AllMessages()...) + + vppcalls.AddIpfixHandlerVersion(vpp2001.Version, msgs, NewIpfixVppHandler) +} + +// IpfixVppHandler is accessor for IPFIX-related vppcalls methods. +type IpfixVppHandler struct { + callsChannel govppapi.Channel + ifIndexes ifaceidx.IfaceMetadataIndex + log logging.Logger +} + +// NewIpfixVppHandler creates new instance of IPFIX vppcalls handler. +func NewIpfixVppHandler(callsChan govppapi.Channel, + ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger, +) vppcalls.IpfixVppAPI { + return &IpfixVppHandler{ + callsChannel: callsChan, + ifIndexes: ifIndexes, + log: log, + } +} diff --git a/proto/ligato/vpp/ipfix/flowprobe.pb.go b/proto/ligato/vpp/ipfix/flowprobe.pb.go new file mode 100644 index 0000000000..938b864b3c --- /dev/null +++ b/proto/ligato/vpp/ipfix/flowprobe.pb.go @@ -0,0 +1,183 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: ligato/vpp/ipfix/flowprobe.proto + +package vpp_ipfix + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type FlowProbeFeature struct { + Interface string `protobuf:"bytes,1,opt,name=interface,proto3" json:"interface,omitempty"` + L2 bool `protobuf:"varint,2,opt,name=l2,proto3" json:"l2,omitempty"` + Ip4 bool `protobuf:"varint,3,opt,name=ip4,proto3" json:"ip4,omitempty"` + Ip6 bool `protobuf:"varint,4,opt,name=ip6,proto3" json:"ip6,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FlowProbeFeature) Reset() { *m = FlowProbeFeature{} } +func (m *FlowProbeFeature) String() string { return proto.CompactTextString(m) } +func (*FlowProbeFeature) ProtoMessage() {} +func (*FlowProbeFeature) Descriptor() ([]byte, []int) { + return fileDescriptor_a98beb1482001856, []int{0} +} + +func (m *FlowProbeFeature) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FlowProbeFeature.Unmarshal(m, b) +} +func (m *FlowProbeFeature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FlowProbeFeature.Marshal(b, m, deterministic) +} +func (m *FlowProbeFeature) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowProbeFeature.Merge(m, src) +} +func (m *FlowProbeFeature) XXX_Size() int { + return xxx_messageInfo_FlowProbeFeature.Size(m) +} +func (m *FlowProbeFeature) XXX_DiscardUnknown() { + xxx_messageInfo_FlowProbeFeature.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowProbeFeature proto.InternalMessageInfo + +func (m *FlowProbeFeature) GetInterface() string { + if m != nil { + return m.Interface + } + return "" +} + +func (m *FlowProbeFeature) GetL2() bool { + if m != nil { + return m.L2 + } + return false +} + +func (m *FlowProbeFeature) GetIp4() bool { + if m != nil { + return m.Ip4 + } + return false +} + +func (m *FlowProbeFeature) GetIp6() bool { + if m != nil { + return m.Ip6 + } + return false +} + +type FlowProbeParams struct { + ActiveTimer uint32 `protobuf:"varint,1,opt,name=active_timer,json=activeTimer,proto3" json:"active_timer,omitempty"` + PassiveTimer uint32 `protobuf:"varint,2,opt,name=passive_timer,json=passiveTimer,proto3" json:"passive_timer,omitempty"` + RecordL2 bool `protobuf:"varint,3,opt,name=record_l2,json=recordL2,proto3" json:"record_l2,omitempty"` + RecordL3 bool `protobuf:"varint,4,opt,name=record_l3,json=recordL3,proto3" json:"record_l3,omitempty"` + RecordL4 bool `protobuf:"varint,5,opt,name=record_l4,json=recordL4,proto3" json:"record_l4,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FlowProbeParams) Reset() { *m = FlowProbeParams{} } +func (m *FlowProbeParams) String() string { return proto.CompactTextString(m) } +func (*FlowProbeParams) ProtoMessage() {} +func (*FlowProbeParams) Descriptor() ([]byte, []int) { + return fileDescriptor_a98beb1482001856, []int{1} +} + +func (m *FlowProbeParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FlowProbeParams.Unmarshal(m, b) +} +func (m *FlowProbeParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FlowProbeParams.Marshal(b, m, deterministic) +} +func (m *FlowProbeParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowProbeParams.Merge(m, src) +} +func (m *FlowProbeParams) XXX_Size() int { + return xxx_messageInfo_FlowProbeParams.Size(m) +} +func (m *FlowProbeParams) XXX_DiscardUnknown() { + xxx_messageInfo_FlowProbeParams.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowProbeParams proto.InternalMessageInfo + +func (m *FlowProbeParams) GetActiveTimer() uint32 { + if m != nil { + return m.ActiveTimer + } + return 0 +} + +func (m *FlowProbeParams) GetPassiveTimer() uint32 { + if m != nil { + return m.PassiveTimer + } + return 0 +} + +func (m *FlowProbeParams) GetRecordL2() bool { + if m != nil { + return m.RecordL2 + } + return false +} + +func (m *FlowProbeParams) GetRecordL3() bool { + if m != nil { + return m.RecordL3 + } + return false +} + +func (m *FlowProbeParams) GetRecordL4() bool { + if m != nil { + return m.RecordL4 + } + return false +} + +func init() { + proto.RegisterType((*FlowProbeFeature)(nil), "ligato.vpp.ipfix.FlowProbeFeature") + proto.RegisterType((*FlowProbeParams)(nil), "ligato.vpp.ipfix.FlowProbeParams") +} + +func init() { proto.RegisterFile("ligato/vpp/ipfix/flowprobe.proto", fileDescriptor_a98beb1482001856) } + +var fileDescriptor_a98beb1482001856 = []byte{ + // 269 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xb1, 0x4e, 0xc3, 0x30, + 0x14, 0x45, 0x95, 0x14, 0x50, 0x63, 0x5a, 0x88, 0x3c, 0x59, 0x82, 0x21, 0x94, 0xa5, 0x0b, 0xb1, + 0x94, 0x44, 0x1d, 0x80, 0x89, 0xa1, 0x13, 0x43, 0x15, 0x31, 0xb1, 0x44, 0x6e, 0xea, 0x44, 0x96, + 0xdc, 0xfa, 0xc9, 0x31, 0x2e, 0x9f, 0xc5, 0x27, 0xa2, 0xd8, 0x29, 0x2d, 0xdd, 0x9e, 0xce, 0x3d, + 0xd2, 0xbb, 0xba, 0x28, 0x91, 0xa2, 0x65, 0x46, 0x51, 0x0b, 0x40, 0x05, 0x34, 0xe2, 0x9b, 0x36, + 0x52, 0xed, 0x41, 0xab, 0x35, 0x4f, 0x41, 0x2b, 0xa3, 0x70, 0xec, 0x8d, 0xd4, 0x02, 0xa4, 0xce, + 0x98, 0x6d, 0x50, 0xbc, 0x94, 0x6a, 0xbf, 0xea, 0xa5, 0x25, 0x67, 0xe6, 0x4b, 0x73, 0x7c, 0x8f, + 0x22, 0xb1, 0x33, 0x5c, 0x37, 0xac, 0xe6, 0x24, 0x48, 0x82, 0x79, 0x54, 0x1e, 0x01, 0xbe, 0x41, + 0xa1, 0xcc, 0x48, 0x98, 0x04, 0xf3, 0x71, 0x19, 0xca, 0x0c, 0xc7, 0x68, 0x24, 0xa0, 0x20, 0x23, + 0x07, 0xfa, 0xd3, 0x93, 0x05, 0xb9, 0x38, 0x90, 0xc5, 0xec, 0x27, 0x40, 0xb7, 0x7f, 0x6f, 0x56, + 0x4c, 0xb3, 0x6d, 0x87, 0x1f, 0xd0, 0x84, 0xd5, 0x46, 0x58, 0x5e, 0x19, 0xb1, 0xe5, 0xda, 0x3d, + 0x9a, 0x96, 0xd7, 0x9e, 0x7d, 0xf4, 0x08, 0x3f, 0xa2, 0x29, 0xb0, 0xae, 0x3b, 0x3a, 0xa1, 0x73, + 0x26, 0x03, 0xf4, 0xd2, 0x1d, 0x8a, 0x34, 0xaf, 0x95, 0xde, 0x54, 0x32, 0x1b, 0x5a, 0x8c, 0x3d, + 0x78, 0xcf, 0x4e, 0xc3, 0x7c, 0x28, 0x74, 0x08, 0xf3, 0xd3, 0xb0, 0x20, 0x97, 0xff, 0xc2, 0xe2, + 0xed, 0xf5, 0xf3, 0xb9, 0x55, 0xe9, 0xb0, 0x97, 0x70, 0xa3, 0x3e, 0xb1, 0x96, 0xef, 0x0c, 0xb5, + 0x39, 0x75, 0x6b, 0xd2, 0xf3, 0xb9, 0x5f, 0x2c, 0x40, 0xe5, 0xae, 0xf5, 0x95, 0x33, 0xf2, 0xdf, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x82, 0x3e, 0x5c, 0x93, 0x01, 0x00, 0x00, +} diff --git a/proto/ligato/vpp/ipfix/flowprobe.proto b/proto/ligato/vpp/ipfix/flowprobe.proto new file mode 100644 index 0000000000..68f9d9bd96 --- /dev/null +++ b/proto/ligato/vpp/ipfix/flowprobe.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package ligato.vpp.ipfix; + +option go_package = "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix;vpp_ipfix"; + +message FlowProbeFeature { + string interface = 1; + bool l2 = 2; + bool ip4 = 3; + bool ip6 = 4; +} + +message FlowProbeParams { + uint32 active_timer = 1; + uint32 passive_timer = 2; + bool record_l2 = 3; + bool record_l3 = 4; + bool record_l4 = 5; +} diff --git a/proto/ligato/vpp/ipfix/ipfix.pb.go b/proto/ligato/vpp/ipfix/ipfix.pb.go new file mode 100644 index 0000000000..33eaae3215 --- /dev/null +++ b/proto/ligato/vpp/ipfix/ipfix.pb.go @@ -0,0 +1,169 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: ligato/vpp/ipfix/ipfix.proto + +package vpp_ipfix + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// IPFIX defines the IP Flow Information eXport (IPFIX) configuration. +type IPFIX struct { + Collector *IPFIX_Collector `protobuf:"bytes,1,opt,name=collector,proto3" json:"collector,omitempty"` + SourceAddress string `protobuf:"bytes,2,opt,name=source_address,json=sourceAddress,proto3" json:"source_address,omitempty"` + VrfId uint32 `protobuf:"varint,3,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"` + PathMtu uint32 `protobuf:"varint,4,opt,name=path_mtu,json=pathMtu,proto3" json:"path_mtu,omitempty"` + TemplateInterval uint32 `protobuf:"varint,5,opt,name=template_interval,json=templateInterval,proto3" json:"template_interval,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IPFIX) Reset() { *m = IPFIX{} } +func (m *IPFIX) String() string { return proto.CompactTextString(m) } +func (*IPFIX) ProtoMessage() {} +func (*IPFIX) Descriptor() ([]byte, []int) { + return fileDescriptor_5026bdf499d44457, []int{0} +} + +func (m *IPFIX) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IPFIX.Unmarshal(m, b) +} +func (m *IPFIX) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IPFIX.Marshal(b, m, deterministic) +} +func (m *IPFIX) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPFIX.Merge(m, src) +} +func (m *IPFIX) XXX_Size() int { + return xxx_messageInfo_IPFIX.Size(m) +} +func (m *IPFIX) XXX_DiscardUnknown() { + xxx_messageInfo_IPFIX.DiscardUnknown(m) +} + +var xxx_messageInfo_IPFIX proto.InternalMessageInfo + +func (m *IPFIX) GetCollector() *IPFIX_Collector { + if m != nil { + return m.Collector + } + return nil +} + +func (m *IPFIX) GetSourceAddress() string { + if m != nil { + return m.SourceAddress + } + return "" +} + +func (m *IPFIX) GetVrfId() uint32 { + if m != nil { + return m.VrfId + } + return 0 +} + +func (m *IPFIX) GetPathMtu() uint32 { + if m != nil { + return m.PathMtu + } + return 0 +} + +func (m *IPFIX) GetTemplateInterval() uint32 { + if m != nil { + return m.TemplateInterval + } + return 0 +} + +type IPFIX_Collector struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IPFIX_Collector) Reset() { *m = IPFIX_Collector{} } +func (m *IPFIX_Collector) String() string { return proto.CompactTextString(m) } +func (*IPFIX_Collector) ProtoMessage() {} +func (*IPFIX_Collector) Descriptor() ([]byte, []int) { + return fileDescriptor_5026bdf499d44457, []int{0, 0} +} + +func (m *IPFIX_Collector) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IPFIX_Collector.Unmarshal(m, b) +} +func (m *IPFIX_Collector) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IPFIX_Collector.Marshal(b, m, deterministic) +} +func (m *IPFIX_Collector) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPFIX_Collector.Merge(m, src) +} +func (m *IPFIX_Collector) XXX_Size() int { + return xxx_messageInfo_IPFIX_Collector.Size(m) +} +func (m *IPFIX_Collector) XXX_DiscardUnknown() { + xxx_messageInfo_IPFIX_Collector.DiscardUnknown(m) +} + +var xxx_messageInfo_IPFIX_Collector proto.InternalMessageInfo + +func (m *IPFIX_Collector) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *IPFIX_Collector) GetPort() uint32 { + if m != nil { + return m.Port + } + return 0 +} + +func init() { + proto.RegisterType((*IPFIX)(nil), "ligato.vpp.ipfix.IPFIX") + proto.RegisterType((*IPFIX_Collector)(nil), "ligato.vpp.ipfix.IPFIX.Collector") +} + +func init() { proto.RegisterFile("ligato/vpp/ipfix/ipfix.proto", fileDescriptor_5026bdf499d44457) } + +var fileDescriptor_5026bdf499d44457 = []byte{ + // 275 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0x4d, 0x4b, 0xf4, 0x30, + 0x14, 0x85, 0xe9, 0xbc, 0xf3, 0xf1, 0x36, 0x52, 0x19, 0x03, 0x42, 0x14, 0x17, 0x55, 0x10, 0x0a, + 0x62, 0x0a, 0xce, 0xca, 0x0f, 0x10, 0x15, 0x84, 0x2e, 0x04, 0xe9, 0x4a, 0xdc, 0x94, 0xd8, 0xa6, + 0x35, 0xd0, 0x99, 0x5c, 0xd2, 0xdb, 0xe0, 0x5f, 0xf0, 0x5f, 0x8b, 0xb7, 0x56, 0x61, 0x36, 0xe1, + 0xde, 0x73, 0x9e, 0xc0, 0xb9, 0x87, 0x1d, 0xb5, 0xa6, 0x51, 0x68, 0x53, 0x0f, 0x90, 0x1a, 0xa8, + 0xcd, 0xc7, 0xf0, 0x4a, 0x70, 0x16, 0x2d, 0x5f, 0x0e, 0xae, 0xf4, 0x00, 0x92, 0xf4, 0x93, 0xcf, + 0x09, 0x9b, 0x65, 0xcf, 0x8f, 0xd9, 0x0b, 0xbf, 0x65, 0x61, 0x69, 0xdb, 0x56, 0x97, 0x68, 0x9d, + 0x08, 0xe2, 0x20, 0xd9, 0xb9, 0x38, 0x96, 0xdb, 0xbc, 0x24, 0x56, 0x3e, 0x8c, 0x60, 0xfe, 0xf7, + 0x87, 0x9f, 0xb2, 0xdd, 0xce, 0xf6, 0xae, 0xd4, 0x85, 0xaa, 0x2a, 0xa7, 0xbb, 0x4e, 0x4c, 0xe2, + 0x20, 0x09, 0xf3, 0x68, 0x50, 0xef, 0x06, 0x91, 0xef, 0xb3, 0xb9, 0x77, 0x75, 0x61, 0x2a, 0xf1, + 0x2f, 0x0e, 0x92, 0x28, 0x9f, 0x79, 0x57, 0x67, 0x15, 0x3f, 0x60, 0xff, 0x41, 0xe1, 0x7b, 0xb1, + 0xc6, 0x5e, 0x4c, 0xc9, 0x58, 0x7c, 0xef, 0x4f, 0xd8, 0xf3, 0x33, 0xb6, 0x87, 0x7a, 0x0d, 0xad, + 0x42, 0x5d, 0x98, 0x0d, 0x6a, 0xe7, 0x55, 0x2b, 0x66, 0xc4, 0x2c, 0x47, 0x23, 0xfb, 0xd1, 0x0f, + 0x2f, 0x59, 0xf8, 0x9b, 0x8e, 0x0b, 0xb6, 0x18, 0xb3, 0x04, 0x94, 0x65, 0x5c, 0x39, 0x67, 0x53, + 0xb0, 0x0e, 0x29, 0x62, 0x94, 0xd3, 0x7c, 0x7f, 0xf3, 0x7a, 0xd5, 0xd8, 0xf1, 0x64, 0x43, 0x1d, + 0x9e, 0xab, 0x46, 0x6f, 0x30, 0xf5, 0xab, 0x94, 0x0a, 0x4c, 0xb7, 0xdb, 0xbd, 0xf6, 0x00, 0x05, + 0x4d, 0x6f, 0x73, 0x22, 0x56, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x91, 0x5b, 0x87, 0xdc, 0x82, + 0x01, 0x00, 0x00, +} diff --git a/proto/ligato/vpp/ipfix/ipfix.proto b/proto/ligato/vpp/ipfix/ipfix.proto new file mode 100644 index 0000000000..2295821331 --- /dev/null +++ b/proto/ligato/vpp/ipfix/ipfix.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package ligato.vpp.ipfix; + +option go_package = "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix;vpp_ipfix"; + +// IPFIX defines the IP Flow Information eXport (IPFIX) configuration. +message IPFIX { + message Collector { + string address = 1; + uint32 port = 2; + } + Collector collector = 1; + string source_address = 2; + uint32 vrf_id = 3; + uint32 path_mtu = 4; + uint32 template_interval = 5; +} diff --git a/proto/ligato/vpp/ipfix/models.go b/proto/ligato/vpp/ipfix/models.go new file mode 100644 index 0000000000..b9491af32a --- /dev/null +++ b/proto/ligato/vpp/ipfix/models.go @@ -0,0 +1,59 @@ +// Copyright (c) 2020 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vpp_ipfix + +import ( + "go.ligato.io/vpp-agent/v3/pkg/models" +) + +// ModuleName is the module name used for models. +const ModuleName = "vpp.ipfix" + +var ( + ModelIPFIX = models.Register(&IPFIX{}, models.Spec{ + Module: ModuleName, + Version: "v2", + Type: "ipfix", + }) + + ModelFlowprobeParams = models.Register(&FlowProbeParams{}, models.Spec{ + Module: ModuleName, + Version: "v2", + Type: "flowprobe-params", + }) + + ModelFlowprobeFeature = models.Register(&FlowProbeFeature{}, models.Spec{ + Module: ModuleName, + Version: "v2", + Type: "flowprobe-feature", + }, models.WithNameTemplate("{{.Interface}}")) +) + +// IPFIXKey returns the prefix used in ETCD to store vpp IPFIX config. +func IPFIXKey() string { + return models.Key(&IPFIX{}) +} + +// FlowprobeParamsKey returns the prefix used in ETCD +// to store vpp Flowprobe params config. +func FlowprobeParamsKey() string { + return models.Key(&FlowProbeParams{}) +} + +// FlowprobeFeatureKey returns the prefix used in ETCD +// to store vpp Flowprobe feature config. +func FlowprobeFeatureKey() string { + return models.Key(&FlowProbeFeature{}) +} diff --git a/tests/integration/vpp/050_ipfix_test.go b/tests/integration/vpp/050_ipfix_test.go new file mode 100644 index 0000000000..e3b1aa5fe9 --- /dev/null +++ b/tests/integration/vpp/050_ipfix_test.go @@ -0,0 +1,138 @@ +package vpp + +import ( + "testing" + + . "github.com/onsi/gomega" + + "go.ligato.io/cn-infra/v2/logging/logrus" + + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" + ipfixplugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + vpp_ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" + + _ "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin" +) + +func TestIPFIX(t *testing.T) { + ctx := setupVPP(t) + defer ctx.teardownVPP() + + ifIdx := ifaceidx.NewIfaceIndex(logrus.NewLogger("test-if"), "test-if") + h := ipfixplugin_vppcalls.CompatibleIpfixVppHandler(ctx.vppClient, ifIdx, logrus.NewLogger("test")) + Expect(h).ToNot(BeNil(), "IPFIX VPP handler is not available") + + // Check default IPFIX configuration. + exporters, err := h.DumpExporters() + Expect(err).ToNot(HaveOccurred(), "failed to dump IPFIX configuration") + Expect(exporters).To(HaveLen(1), "dump must return only one record") + Expect(exporters[0].GetCollector().GetAddress()).To(Equal("0.0.0.0"), "unexpected initial address of collector") + + tests := []struct { + name string + ipfix *vpp_ipfix.IPFIX + shouldFail bool + }{ + { + name: "Simple test", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "10.10.10.10", + }, + SourceAddress: "20.20.20.20", + }, + shouldFail: false, + }, + { + name: "Collector IP 0.0.0.0 fail", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "0.0.0.0", + }, + SourceAddress: "20.20.20.20", + }, + shouldFail: true, + }, + { + name: "Source IP 0.0.0.0 fail", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "20.20.20.20", + }, + SourceAddress: "0.0.0.0", + }, + shouldFail: true, + }, + { + name: "Collector IP6 fail", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "2020::4:7", + }, + SourceAddress: "20.20.20.20", + }, + shouldFail: true, + }, + { + name: "Source IP6 fail", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "20.20.20.20", + }, + SourceAddress: "2020::4:7", + }, + shouldFail: true, + }, + { + name: "MTU is in range", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "10.10.10.10", + }, + SourceAddress: "20.20.20.20", + PathMtu: 256, + }, + shouldFail: false, + }, + { + name: "Too small MTU fail", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "10.10.10.10", + }, + SourceAddress: "20.20.20.20", + PathMtu: 1, + }, + shouldFail: true, + }, + { + name: "Too big MTU fail", + ipfix: &vpp_ipfix.IPFIX{ + Collector: &vpp_ipfix.IPFIX_Collector{ + Address: "10.10.10.10", + }, + SourceAddress: "20.20.20.20", + PathMtu: 9999, + }, + shouldFail: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.shouldFail { + Expect(h.SetExporter(test.ipfix)).ToNot(Succeed()) + return + } + + Expect(h.SetExporter(test.ipfix)).To(Succeed()) + + exporters, err := h.DumpExporters() + Expect(err).ToNot(HaveOccurred(), "failed to dump IPFIX configuration") + Expect(exporters).To(HaveLen(1), "dump must return only one record") + e := exporters[0] + Expect(e.GetCollector().GetAddress()).To(Equal(test.ipfix.GetCollector().GetAddress())) + Expect(e.GetSourceAddress()).To(Equal(test.ipfix.GetSourceAddress())) + }) + } +} diff --git a/tests/integration/vpp/051_flowprobe_test.go b/tests/integration/vpp/051_flowprobe_test.go new file mode 100644 index 0000000000..c72094e107 --- /dev/null +++ b/tests/integration/vpp/051_flowprobe_test.go @@ -0,0 +1,67 @@ +package vpp + +import ( + "testing" + + . "github.com/onsi/gomega" + + "go.ligato.io/cn-infra/v2/logging/logrus" + + "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" + ifplugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls" + ipfixplugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls" + vpp_ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix" + + _ "go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin" +) + +func TestFlowprobe(t *testing.T) { + ctx := setupVPP(t) + defer ctx.teardownVPP() + + // Prepare an interface to test Flowprobe feature enable/disable actions. + ih := ifplugin_vppcalls.CompatibleInterfaceVppHandler(ctx.vppClient, logrus.NewLogger("test")) + Expect(ih).ToNot(BeNil(), "Interface VPP handler is not available") + const ifName = "loop1" + ifIdx, err := ih.AddLoopbackInterface(ifName) + Expect(err).ToNot(HaveOccurred(), "failed to create an interface") + t.Logf("interface created with SwIfIndex=%v", ifIdx) + + // Create interface index and add there previously created interface. + ifIndexes := ifaceidx.NewIfaceIndex(logrus.NewLogger("test-if"), "test-if") + ifIndexes.Put(ifName, &ifaceidx.IfaceMetadata{SwIfIndex: ifIdx}) + + // Finally, create and start using IPFIX VPP handler. + h := ipfixplugin_vppcalls.CompatibleIpfixVppHandler(ctx.vppClient, ifIndexes, logrus.NewLogger("test")) + Expect(h).ToNot(BeNil(), "IPFIX VPP handler is not available") + + // Try to set empty Flowprobe params. This must fail. + Expect(h.SetFPParams(&vpp_ipfix.FlowProbeParams{})).ToNot(Succeed()) + + // But if at least one of params is set, everything should be ok. + Expect(h.SetFPParams(&vpp_ipfix.FlowProbeParams{RecordL2: true})).To(Succeed(), + "setting new params for Flowprobe failed", + ) + + // Try to add Flowprobe feature to the interface. + Expect(h.AddFPFeature(&vpp_ipfix.FlowProbeFeature{Interface: ifName})).To(Succeed(), + "enabling Flowprobe feature for interface failed", + ) + + // Try to update Flowprobe feature for the interface. + Expect(h.AddFPFeature(&vpp_ipfix.FlowProbeFeature{ + Interface: ifName, + L2: true, + })).ToNot(Succeed(), "updating Flowprobe feature on interface was not expected to work") + + // So to update, first it needs to be deleted... + Expect(h.DelFPFeature(&vpp_ipfix.FlowProbeFeature{Interface: ifName})).To(Succeed(), + "removing Flowprobe feature for interface failed", + ) + + // ... and afterwards created. + Expect(h.AddFPFeature(&vpp_ipfix.FlowProbeFeature{ + Interface: ifName, + L2: true, + })).To(Succeed(), "enabling Flowprobe feature for interface failed") +}