diff --git a/.gitignore b/.gitignore index 7230ca6c10..9bc44df588 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,7 @@ /tests/robot/variables/jozo_local_variables.robot # vpp directory -/vpp/ \ No newline at end of file +/vpp/ + +# exclude vendor +!/vendor/**/* diff --git a/.travis.yml b/.travis.yml index eebd521dbd..8c103afbc9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ sudo: required language: go go: - - "1.10.x" + - "1.11.x" addons: apt: diff --git a/CHANGELOG.md b/CHANGELOG.md index 8322fc77be..7bd594619b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,53 @@ +# Release v1.7-vpp18.10 (2018-10-2) + +## Compatibility +- VPP 18.10-rc0~505-ge23edac +- cn-infra v1.6 +- GO 1.11 + +## New Features +- [vpp-ifplugin](plugins/vpp/ifplugin) + * It is now possible to dump unnumbered interface data + * Rx-placement now uses specific binary API to configure instead of generic CLI API +- [vpp-l2plugin](plugins/vpp/l2plugin) + * Bridge domain ARP termination table can now be dumped +- [vpp-ifplugin](plugins/linux/ifplugin) + * Linux interface watcher was reintroduced. + * Linux interfaces can be now dumped. +- [vpp-l3plugin](plugins/linux/l3plugin) + * Linux ARP entries and routes can be dumped. + +## Improvements +- [vpp-plugins](plugins/vpp) + * Improved error propagation in all the VPP plugins. Majority of errors now print the stack trace to + the log output allowing better error tracing and debugging. + * Stopwatch was removed from all vppcalls +- [linux-plugins](plugins/linux) + * Improved error propagation in all Linux plugins (same way as for VPP) + * Stopwatch was removed from all linuxcalls +- [govpp-plugn](plugins/govppmux) + * Tracer (introduced in cn-infra 1.6) added to VPP message processing, replacing stopwatch. + The measurement should be more precise and logged for all binary API calls. Also the rest + plugin now allows showing traced entries. + +## Docker image + * The image can now be built on ARM64 platform + +## Bugfix + * Corrected several cases where various errors were silently ignored + * GRPC registration is now done in Init() phase, ensuring that it finishes before GRPC server + is started + * Removed occasional cases where Linux tap interface was not configured correctly + * Fixed FIB configuration failures caused by wrong updating of the metadata after several + modifications + * No additional characters are added to NAT tag and can be now configured with the full length + without index out of range errors + * Linux interface resync registers all VETH-type interfaces, despite the peer is not known + * Status publishing to ETCD/Consul now should work properly + * Fixed occasional failure caused by concurrent map access inside Linux plugin interface + configurator + * VPP route dump now correctly recognizes route type + # Release v1.6-vpp18.10 (2018-08-24) ## Compatibility @@ -13,14 +63,14 @@ visible in [app package vpp-agent](app/vpp_agent.go). All examples were also updated. ## Breaking Changes -- Flavors were replaces with [new way](app) of managing plugins. +- Flavors were replaced with [new way](app) of managing plugins. - REST interface URLs were changed, see [readme](plugins/rest/README.md) for complete list. ## New Features - [rest plugin](plugins/rest) - * All VPP configuration types are now supported to be dumped using REST. Output consists from two parts; - data formatted as NB proto model, and metadata with VPP specific configuration (interface indexes, different - counters, etc.). + * All VPP configuration types are now supported to be dumped using REST. The output consists of two parts; + data formatted as NB proto model, and metadata with VPP specific configuration (interface indexes, + different counters, etc.). * REST prefix was changed. The new URL now contains API version and purpose (dump, put). The list of all URLs can be found in the [readme](plugins/rest/README.md) - [ifplugin](plugins/vpp/ifplugin) @@ -28,12 +78,12 @@ [nat proto file](plugins/vpp/model/nat/nat.proto) - [l3plugin](plugins/vpp/l3plugin) * Vpp-agent now knows about DROP-type routes. They can be configured and also dumped. VPP default routes, which are - DROP-type are recognized and registered. Currently, resync does not remove or correlate such a route type + DROP-type is recognized and registered. Currently, resync does not remove or correlate such a route type automatically, so no default routes are unintentionally removed. * New configurator for L3 IP scan neighbor was added, allowing to set/unset IP scan neigh parameters to the VPP. ## Docker Images -- using Ubuntu 18.04 as base image +- using Ubuntu 18.04 as the base image ## Improvements - [vpp plugins](plugins/vpp) @@ -41,18 +91,18 @@ Configurators now use special handler object to access vppcalls. This should prevent duplicates and make vppcalls cleaner and more understandable. - [ifplugin](plugins/vpp/ifplugin) - * VPP interface DHCP configuration can now be dumped, and added to resync processing + * VPP interface DHCP configuration can now be dumped and added to resync processing * Interfaces and also L3 routes can be configured for non-zero VRF table if IPv6 is used. - [examples](examples) * All examples were reworked to use new flavors concept. The purpose was not changed. ## Bugfix * if VPP routes are dumped, all paths are returned -* NAT load-ballanced static mappings should be resynced correctly +* NAT load-balanced static mappings should be resynced correctly * telemetry plugin now correctly parses parentheses for `show node counters` -* telemetry plugin will not hide an error caused by value loading if config file is not present -* linux plugin namespace handler now correctly handles namespace switching for interfaces with IPv6 addresses. - Default IPv6 address (link local) will not be moved to new namespace, if there is no more IPv6 addresses +* telemetry plugin will not hide an error caused by value loading if the config file is not present +* Linux plugin namespace handler now correctly handles namespace switching for interfaces with IPv6 addresses. + Default IPv6 address (link local) will not be moved to the new namespace if there are no more IPv6 addresses configured within the interface. This should prevent failures in some cases where IPv6 is not enabled in the destination namespace. * VxLAN with non-zero VRF can be successfully removed @@ -67,8 +117,8 @@ ## Bugfix - [Telemetry](plugins/telemetry) - * Fixed bug where lack of config file could cause continuous polling. The interval now also - cannot be changed to value less than 5 seconds. + * Fixed bug where lack of config file could cause continuous polling. The interval now also + cannot be changed to a value less than 5 seconds. * Telemetry plugin is now closed properly # Release v1.5.1 (2018-07-20) @@ -81,8 +131,8 @@ - [Telemetry](plugins/telemetry) * Default polling interval was raised to 30s. * Added option to use telemetry config file to change polling interval, or turn the polling off, - disabling the telemetry plugin. The change was added due to several reports where often polling - is suspicious of interrupting VPP worker threads and causing packet drops and/or other + disabling the telemetry plugin. The change was added due to several reports where often polling + is suspicious of interrupting VPP worker threads and causing packet drops and/or other negative impacts. More information how to use the config file can be found in the [readme](plugins/telemetry/README.md) @@ -93,7 +143,7 @@ - cn-infra v1.4 ## Breaking Changes -- The package `etcdv3` was renamed to `etcd`, along with it's flag and configuration file. +- The package `etcdv3` was renamed to `etcd`, along with its flag and configuration file. - The package `defaultplugins` was renamed to `vpp` to make the purpose of the package clear ## New Features @@ -107,9 +157,9 @@ ## Bugfix -- Fixed few issues with parsing VPP metrics from CLI for [Telemetry](plugins/telemetry). -- Fixed bug in GoVPP ocurring after some request timed out, causing - the channel to receive replies from previous request and always returning error. +- Fixed a few issues with parsing VPP metrics from CLI for [Telemetry](plugins/telemetry). +- Fixed bug in GoVPP occurring after some request timed out, causing + the channel to receive replies from the previous request and always returning an error. - Fixed issue which prevented setting interface to non-existing VRF. - Fixed bug where removal of an af-packet interface caused attached Veth to go DOWN. - Fixed NAT44 address pool resolution which was not correct in some cases. @@ -120,7 +170,7 @@ and keep both unset by default. - Refactored and cleaned up execute scripts and remove unused scripts. - Fixed some issues with `RETAIN_SUPERVISOR` option. -- Location of supervisord pid file is now explicitely set to +- Location of supervisord pid file is now explicitly set to `/run/supervisord.pid` in *supervisord.conf* file. - The vpp-agent is now started with single flag `--config-dir=/opt/vpp-agent/dev`, and will automatically load all configuration from that directory. @@ -136,7 +186,7 @@ A minor release using newer VPP v18.04 version. ## Bugfix - VPP submodule was removed from the project. It should prevent various problems with dependency resolution. -- Fixed known bug present in previous version of the VPP, issued as +- Fixed known bug present in the previous version of the VPP, issued as [VPP-1280](https://jira.fd.io/browse/VPP-1280). Current version contains appropriate fix. # Release v1.4 (2018-05-24) @@ -147,7 +197,7 @@ A minor release using newer VPP v18.04 version. ## New Features - [Consul](https://www.consul.io/) - * Consul is now supported as an key-value store alternative to ETCD. + * Consul is now supported as a key-value store alternative to ETCD. More information in the [readme](https://github.com/ligato/cn-infra/blob/master/db/keyval/consul/README.md). - [Telemetry](plugins/telemetry) * New plugin for collecting telemetry data about VPP metrics @@ -158,7 +208,7 @@ A minor release using newer VPP v18.04 version. passing through that interface. - [GRPC](plugins/vpp/rpc) * Vpp-agent itself can act as a GRPC server (no need for external executable) - * All configuration types are supported (incl. linux interfaces, routes and ARP) + * All configuration types are supported (incl. Linux interfaces, routes and ARP) * Client can read VPP notifications via vpp-agent. - [SR plugin](plugins/vpp/srplugin) * New plugin with support for Segment Routing. @@ -170,8 +220,8 @@ A minor release using newer VPP v18.04 version. - __vpp-agent-grpc__ executable merged with [vpp-agent](cmd/vpp-agent) command. - [govppmux](plugins/govppmux) * [configure reply timeout](plugins/govppmux/README.md) can be configured. - * Support for VPP started with custom shared memory prefix. SHM may be configured via govpp - plugin config file. More info in the [readme](plugins/govppmux/README.md) + * Support for VPP started with custom shared memory prefix. SHM may be configured via the GoVPP + plugin config file. More info in the [readme](plugins/govppmux/README.md) ## Examples - [localclient_linux](examples/localclient_vpp) now contains two examples, the old one demonstrating @@ -182,13 +232,13 @@ A minor release using newer VPP v18.04 version. [tap](examples/localclient_linux/tap) was added. ## Bugfix - * Fixed case where creation of linux route with unreachable gateway thrown error. The route is - now appropriately cached and created when possible. - * Fixed issue with GoVPP channels returning errors after timeout. + * Fixed case where the creation of the Linux route with unreachable gateway threw an error. + The route is now appropriately cached and created when possible. + * Fixed issue with GoVPP channels returning errors after a timeout. * Fixed various issues related to caching and resync in L2 cross-connect - * Split horizon group is now correctly assigned if interface is created after bridge domain - * Fixed issue where creation of FIB while interface was not a part of - the bridge domain returned error. + * Split horizon group is now correctly assigned if an interface is created after bridge domain + * Fixed issue where the creation of FIB while the interface was not a part of + the bridge domain returned an error. ## Other * Overall redundancy cleanup and corrected naming for all proto models. @@ -209,14 +259,14 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github ## New Features - [ipsecplugin](plugins/vpp/ipsecplugin) * New plugin for IPSec added. The IPSec is supported for VPP only - with linux set manually for now. IKEv2 is not yet supported. + with Linux set manually for now. IKEv2 is not yet supported. More information in the [readme](plugins/vpp/ipsecplugin/README.md). - [nsplugin](plugins/linux/nsplugin) * New namespace plugin added. The configurator handles common namespace and microservice processing and communication with other Linux plugins. - [ifplugin](plugins/vpp/ifplugin) * Added support for Network address translation. NAT plugin supports - configuration of NAT44 interfaces, address pools and DNAT. + a configuration of NAT44 interfaces, address pools and DNAT. More information in the [readme](plugins/vpp/ifplugin/README.md). * DHCP can now be configured for the interface - [l2plugin](plugins/vpp/l2plugin) @@ -229,23 +279,23 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github ## Improvements - [aclplugin](plugins/vpp/aclplugin) - * Removed configuration order of interfaces. Access list can be now + * Removed configuration order of interfaces. The access list can be now configured even if interfaces do not exist yet, and add them later. - [vpp-agent-ctl](cmd/vpp-agent-ctl) * The vpp-agent-ctl was refactored and command info was updated. ## Docker Images - * VPP can be build and run in release or debug mode. + * VPP can be built and run in the release or debug mode. Read more information in the [readme](https://github.com/ligato/vpp-agent/blob/pantheon-dev/docker/dev/README.md). * Production image is now smaller by roughly 40% (229MB). ## Bugfix * Resync of ifplugin in both, VPP and Linux, was improved. Interfaces with the same configuration data are not recreated during resync. - * STN do not fail if IP address with mask is provided. + * STN does not fail if IP address with a mask is provided. * Fixed ingress/egress interface resolution in ACL. * Linux routes now check network reachability for gateway address b - before configuration. It should prevent "network unreachable" errors + before configuration. It should prevent "network unreachable" errors during config. * Corrected bridge domain crash in case non-bvi interface was added to another non-bvi interface. @@ -259,13 +309,13 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github ### Improvements - [aclplugin](plugins/vpp/aclplugin) - * Improved resync of ACL entries. Every new ACL entry is correctly configured in the VPP and all obosolete entries are read and removed. + * Improved resync of ACL entries. Every new ACL entry is correctly configured in the VPP and all obsolete entries are read and removed. - [ifplugin](plugins/vpp/ifplugin) * Improved resync of interfaces, BFD sessions, authentication keys, echo functions and STN. Better resolution of persistence config for interfaces. - [l2plugin](plugins/vpp/l2plugin) - * Improved resync of bridge domains, FIB entries and xConnect pairs. Resync now better correlates configuration present on the VPP with the NB setup. + * Improved resync of bridge domains, FIB entries, and xConnect pairs. Resync now better correlates configuration present on the VPP with the NB setup. - (Linux) [ifplugin](plugins/linux/l3plugin) - * ARP does not need the interface to be present on the VPP. Configuration is cached and put to the VPP if requirements are fullfiled. + * ARP does not need the interface to be present on the VPP. Configuration is cached and put to the VPP if requirements are fulfilled. ### Fixes * [vpp-agent-grpc](cmd/vpp-agent) (removed in 1.4 release, since then it is a part of the vpp-agent) now compiles properly @@ -285,8 +335,8 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github - Fixed bridge domain BVI modification resolution ## Known Issues -- VPP can occasionally cause deadlock during checksum calculation (https://jira.fd.io/browse/VPP-1134) -- VPP-Agent might not properly handle initialization across plugins (this is not occuring currently, but needs to be tested more) +- VPP can occasionally cause a deadlock during checksum calculation (https://jira.fd.io/browse/VPP-1134) +- VPP-Agent might not properly handle initialization across plugins (this is not occurring currently, but needs to be tested more) # Release v1.1 (2018-01-22) @@ -296,20 +346,20 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github ### New Features - [ifplugin](plugins/vpp/ifplugin) - - added support for un-numbered interfaces. Interface can be marked as un-numbered with information - about another interface containing required IP address. Un-numbered interface does not need to have + - added support for un-numbered interfaces. The nterface can be marked as un-numbered with information + about another interface containing required IP address. A un-numbered interface does not need to have IP address set. - added support for virtio-based TAPv2 interfaces. - - interface status is no longer stored in the ETCD by default and it can be turned on using appropriate + - interface status is no longer stored in the ETCD by default and it can be turned on using the appropriate setting in vpp-plugin.conf. See [readme](plugins/vpp/README.md) for more details. - [l2plugin](plugins/vpp/l2plugin) - - bridge domain status is no longer stored in the ETCD by default and it can be turned on using appropriate + - bridge domain status is no longer stored in the ETCD by default and it can be turned on using the appropriate setting in vpp-plugin.conf. See [readme](plugins/vpp/README.md) for more details. ### Improvements - [ifplugin](plugins/vpp/ifplugin) - - default MTU value was removed in order to be able to just pass empty MTU field. MTU now can be - set only in interface configuration (preffered) or defined in vpp-plugin.conf. If none of them + - default MTU value was removed in order to be able to just pass empty MTU field. MTU now can be + set only in interface configuration (preferred) or defined in vpp-plugin.conf. If none of them is set, MTU value will be empty. - interface state data are stored in statuscheck readiness probe - [l3plugin](plugins/vpp/l3plugin) @@ -320,10 +370,10 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github be configured without interface already present. ### Localclient -- added API for ARP entries, L4 features, Application namespaces and STN rules. +- added API for ARP entries, L4 features, Application namespaces, and STN rules. ### Logging -- consolidated and improved logging in vpp and linux plugins. +- consolidated and improved logging in vpp and Linux plugins. ### Bugfix - fixed skip-resync parameter if vpp-plugin.conf is not provided. @@ -332,8 +382,8 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github - microservice and veth-interface related events are synchronized. ## Known Issues -- VPP can occasionally cause deadlock during checksum calculation (https://jira.fd.io/browse/VPP-1134) -- VPP-Agent might not properly handle initialization across plugins (this is not occuring currently, but needs to be tested more) +- VPP can occasionally cause a deadlock during checksum calculation (https://jira.fd.io/browse/VPP-1134) +- VPP-Agent might not properly handle initialization across plugins (this is not occurring currently, but needs to be tested more) # Release v1.0.8 (2017-11-21) @@ -349,7 +399,7 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github other types of interfaces supports also INTERRUPT and ADAPTIVE. Fields to set QueueID/QueueIDValid are also available - [l4plugin](plugins/vpp/l4plugin) - - added new l4 plugin to the VPP plugins. It can be used to enable/disable L4 features + - added new l4 plugin to the VPP plugins. It can be used to enable/disable L4 features and configure application namespaces. See respective [readme](plugins/vpp/l4plugin/README.md) in L4 plugin for more details. - support for VPP plugins/l3plugin ARP configuration. The configurator can perform the @@ -360,14 +410,14 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github - added possibility to add interface to any VRF table. - [resync](plugins/vpp/data_resync.go) - resync error propagation improved. If any resynced configuration fails, rest of the resync - completes and will not be interrupted. All errors which appears during resync are logged after. -- added defaultpligins API. + completes and will not be interrupted. All errors which appear during resync are logged after. +- added defaultplugins API. - API contains new Method `DisableResync(keyPrefix ...string)`. One or more ETCD key prefixes can be used as a parameter to disable resync for that specific key(s). ### Linux plugin - [l3plugin](plugins/linux/l3plugin) - - route configuration do not return error if required interface is missing. Instead, the + - route configuration does not return an error if the required interface is missing. Instead, the route data are internally stored and configured when the interface appears. ### GOVPP @@ -377,7 +427,7 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github - improved in multiple vpp-agent packages ### Minor fixes/improvements -- removed deadlinks from README files +- removed dead links from README files # Release v1.0.7 (2017-10-30) @@ -388,16 +438,16 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github ### Major Themes - [Default VPP plugin](plugins/vpp) - - added resync strategies. Resync of VPP plugins can be set using + - added resync strategies. Resync of VPP plugins can be set using defaultpluigns config file; Resync can be set to full (always resync everything) or - dependent on VPP configuration (if there is none, skip resync). Resync can be also - forced to skip using parameter. See appropriate changelog in + dependent on VPP configuration (if there is none, skip resync). Resync can be also + forced to skip using the parameter. See appropriate changelog in [VPP plugins](plugins/vpp) for details. ### New Features - [Linuxplugins L3Plugin](plugins/linux/l3plugin) - - added support for basic CRUD operations with static Address resolution protocol + - added support for basic CRUD operations with the static Address resolution protocol entries and static Routes. # Release v1.0.6 (2017-10-17) @@ -408,7 +458,7 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github ### Major Themes - [LinuxPlugin](plugins/linux) - - Configuration of vEth interfaces modified. Veth configuration defines + - The configuration of vEth interfaces modified. Veth configuration defines two names: symbolic used internally and the one used in host OS. `HostIfName` field is optional. If it is not defined, the name in the host OS will be the same as the symbolic one - defined by `Name` field. @@ -426,7 +476,7 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github - [Kafka Partitions](vendor/github.com/ligato/cn-infra/messaging/kafka) - Changes in offset handling, only automatically partitioned messages (hash, random) have their offset marked. Manually partitioned messages are not marked. - - Implemented post-init consumer (for manual partitioner only) which allows to start + - Implemented post-init consumer (for manual partitioner only) which allows starting consuming after kafka-plugin Init() - Minimalistic examples & documentation for Kafka API will be improved in a later release. @@ -435,14 +485,14 @@ The vpp-agent is now using custom VPP branch [stable-1801-contiv](https://github ### Major Themes - [Kafka Partitions](vendor/github.com/ligato/cn-infra/messaging/kafka) - - Implemented new methods that allow to specificy partitions & offset parameters: + - Implemented new methods that allow to specify partitions & offset parameters: * publish: Mux.NewSyncPublisherToPartition() & Mux.NewAsyncPublisherToPartition() * watch: ProtoWatcher.WatchPartition() - Minimalistic examples & documentation for Kafka API will be improved in a later release. - [Flavors](flavors) - reduced to only [local.FlavorVppLocal](flavors/local/local_flavor.go) & [vpp.Flavor](flavors/vpp/vpp_flavor.go) - [goVpp] - - updated version waits until vpp is ready to accept a new connection + - updated version waits until the VPP is ready to accept a new connection # Release v1.0.3 (2017-09-05) @@ -453,7 +503,7 @@ Enabled support for wathing data store `OfDifferentAgent()` - see: * [examples/examples/idx_bd_cache](examples/idx_bd_cache/main.go) * [examples/idx_veth_cache](examples/idx_veth_cache/main.go) -Preview of new Kafka client API methods that allows to fill also partition and offset argument. New methods implementation ignores these new parameters for now (fallbacking to existing implementation based on `github.com/bsm/sarama-cluster` and `github.com/Shopify/sarama`). +Preview of new Kafka client API methods that allows to fill also partition and offset argument. New methods implementation ignores these new parameters for now (fallback to existing implementation based on `github.com/bsm/sarama-cluster` and `github.com/Shopify/sarama`). ## Compatibility - VPP version v17.10-rc0~265-g809bc74 (upgraded because of VPP MEMIF fixes). @@ -465,10 +515,10 @@ Preview of new Kafka client API methods that allows to fill also partition and o ### Major Themes -Algorithms for applying northbound configuration (stored in ETCD key value data store) +Algorithms for applying northbound configuration (stored in ETCD key-value data store) to VPP in the proper order of VPP binary API calls implemented in [Default VPP plugin](plugins/vpp): - network interfaces, especially: - - MEMIFs (optimized dataplane network interface tailored for a container to container network connectivity) + - MEMIFs (optimized data plane network interface tailored for a container to container network connectivity) - VETHs (standard Linux Virtual Ethernet network interface) - AF_Packets (for accessing VETHs and similar type of interface) - VXLANs, Physical Network Interfaces, loopbacks ... @@ -480,12 +530,12 @@ Support for Linux VETH northbound configuration implemented in [Linux Plugin](pl applied in proper order with VPP AF_Packet configuration. Data Synchronization during startup for network interfaces & L2 BD -(support for situation when ETCD contain configuration before VPP Agent starts). +(support for the situation when ETCD contain configuration before VPP Agent starts). Data replication and events: - Updating operational data in ETCD (VPP indexes such as sw_if_index) and statistics (port counters). - Updating statistics in Redis (optional once redis.conf available - see flags). -- Publishing link up/down events to Kafka message bus. +- Publishing links up/down events to Kafka message bus. Miscellaneous: - [Examples](examples) diff --git a/Gopkg.lock b/Gopkg.lock index 700a767e81..6064ef08d7 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,7 +3,7 @@ [[projects]] branch = "master" - digest = "1:090b939a424724c096b5002d62ea42d9a69dc5fecc3eae0218955a5c6e4070ac" + digest = "1:3fa2890ef3ed05d15ce02afff2c464c0f09a6945288fc9f3bc2746191873e988" name = "git.fd.io/govpp.git" packages = [ "adapter", @@ -16,8 +16,7 @@ "core", ] pruneopts = "UT" - revision = "a3bb834db727a3ac9a1ffcfeae9265e5dead851f" - source = "github.com/FDio/govpp" + revision = "62d19032621c7db801b313a1e19e787cfb1fbc3e" [[projects]] branch = "master" @@ -82,20 +81,28 @@ version = "v0.4.1" [[projects]] - digest = "1:4fdffd1724c105db8c394019cfc2444fd23466be04812850506437361ee5de55" + digest = "1:526d64d0a3ac6c24875724a9355895be56a21f89a5d3ab5ba88d91244269a7d8" name = "github.com/bsm/sarama-cluster" packages = ["."] pruneopts = "UT" - revision = "cf455bc755fe41ac9bb2861e7a961833d9c2ecc3" - version = "v2.1.13" + revision = "c618e605e15c0d7535f6c96ff8efbb0dba4fd66c" + version = "v2.1.15" [[projects]] branch = "master" - digest = "1:85f4b0e48294ebfd3282f631a27c72e324c3b980e095fa254d34292bd182719d" + digest = "1:c3806bfe3d2c9baa0d4ebd90f0a59c7505969bcaab024b5185d20ccd66c9400c" name = "github.com/buger/goterm" packages = ["."] pruneopts = "UT" - revision = "ef0fa5b75d0fa2b31323463783a6e90353771116" + revision = "6d19e6a8df12fdfc44a90a24b677a6d04a80b91f" + +[[projects]] + branch = "master" + digest = "1:1ed8f94f16010f9e1a419a818ec8ed5765d04561e6bfcc872e3a5a16fbae08b2" + name = "github.com/containerd/console" + packages = ["."] + pruneopts = "UT" + revision = "c12b1e7919c14469339a5d38f2f8ed9b64a9de23" [[projects]] branch = "master" @@ -106,7 +113,7 @@ revision = "b2b946a77f5973f420514090d6f6dd58b08303f0" [[projects]] - digest = "1:78c50fbac6adb72e7b55afeb23390e8c5fdfb2983ad42240e549cc25bc8486a8" + digest = "1:85fce1e2e3ec72eecab2a2fd8fb85d7a825f0d5cd841652fe0ad980bbe22dd4a" name = "github.com/coreos/etcd" packages = [ "auth/authpb", @@ -116,10 +123,39 @@ "etcdserver/etcdserverpb", "mvcc/mvccpb", "pkg/tlsutil", + "pkg/types", ] pruneopts = "UT" - revision = "66722b1ada68fcd5227db853ee92003169a975c8" - version = "v3.2.0" + revision = "fca8add78a9d926166eb739b8e4a124434025ba3" + version = "v3.3.9" + +[[projects]] + digest = "1:85968a9e07d94b5f3d15993b9884ab5fcc41c8b7b6418df8b6a3baa387bb8d68" + name = "github.com/coreos/go-systemd" + packages = [ + "activation", + "dbus", + "util", + ] + pruneopts = "UT" + revision = "39ca1b05acc7ad1220e09f133283b8859a8b71ab" + version = "v17" + +[[projects]] + digest = "1:6e2ff82d2fe11ee35ec8dceb4346b8144a761f1c8655592c4ebe99a92fcec327" + name = "github.com/coreos/pkg" + packages = ["dlopen"] + pruneopts = "UT" + revision = "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1" + version = "v4" + +[[projects]] + digest = "1:ec52d81d56e55d307da2d3dfc97ab952f9cec61d7df839ba5dd464ec08f9759e" + name = "github.com/cyphar/filepath-securejoin" + packages = ["."] + pruneopts = "UT" + revision = "06bda8370f45268db985f7af15732444d94ed51c" + version = "v0.2.1" [[projects]] digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" @@ -129,6 +165,14 @@ revision = "346938d642f2ec3594ed81d874461961cd0faa76" version = "v1.1.0" +[[projects]] + digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55" + name = "github.com/dgrijalva/jwt-go" + packages = ["."] + pruneopts = "UT" + revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" + version = "v3.2.0" + [[projects]] digest = "1:4ec8504b68b75f562efc4b291cba33194f88eaa4e68d9fc449e5b7ca68539329" name = "github.com/docker/docker" @@ -179,7 +223,7 @@ name = "github.com/docker/libnetwork" packages = ["ipamutils"] pruneopts = "UT" - revision = "19279f0492417475b6bfbd0aa529f73e8f178fb5" + revision = "9ffeaf7d8b64fa0eb64cc27835dc1a5a90328024" [[projects]] digest = "1:1f0c7ab489b407a7f8f9ad16c25a504d28ab461517a971d341388a56156c1bd7" @@ -258,6 +302,14 @@ revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7" version = "v1.0.0" +[[projects]] + digest = "1:aacef5f5e45685f2aeda5534d0a750dee6859de7e9088cdd06192787bb01ae6d" + name = "github.com/go-errors/errors" + packages = ["."] + pruneopts = "UT" + revision = "a6af135bd4e28680facf08a3d206b454abc877a4" + version = "v1.0.1" + [[projects]] digest = "1:991bb96360eb8db70a40e9c496769fe6a7bbac4047f8376494d9837397078327" name = "github.com/go-redis/redis" @@ -276,7 +328,15 @@ version = "v6.13.2" [[projects]] - digest = "1:47f4b03084d147ec4523ed341449f6dd40fdc2b6fe35375c6bd255ec03163b02" + digest = "1:57fa4c058c21ce25d0b7272518dd746065117abf6cc706158b0d361202024520" + name = "github.com/godbus/dbus" + packages = ["."] + pruneopts = "UT" + revision = "a389bdde4dd695d414e47b755e95e72b7826432c" + version = "v4.1.0" + +[[projects]] + digest = "1:9b56c3d59d7899c60a02f4d0e8592fe70b19f3b6b47553849b20fe63a62efe66" name = "github.com/gogo/protobuf" packages = [ "gogoproto", @@ -300,22 +360,29 @@ "protoc-gen-gogo", "protoc-gen-gogo/descriptor", "protoc-gen-gogo/generator", + "protoc-gen-gogo/generator/internal/remap", "protoc-gen-gogo/grpc", "protoc-gen-gogo/plugin", "vanity", "vanity/command", ] pruneopts = "UT" - revision = "342cbe0a04158f6dcb03ca0079991a51a4248c02" - version = "v0.5" + revision = "636bf0302bc95575d69441b25a2603156ffdddf1" + version = "v1.1.1" [[projects]] branch = "master" - digest = "1:9b0e71863f18fc5de645a263184c8a6409ae731e847b35b25da4be818f1975fa" + digest = "1:823d6cdd461935cd426e76e4eec90c22938db664054eabda0bcf63ec0274566e" name = "github.com/golang/protobuf" - packages = ["proto"] + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp", + ] pruneopts = "UT" - revision = "c65a0412e71e8b9b3bfd22925720d23c0f054237" + revision = "b27b920f9e71b439b873b17bf99f56467623814a" [[projects]] branch = "master" @@ -391,7 +458,7 @@ [[projects]] branch = "master" - digest = "1:6dd5650e3030d5060e7df8d92f6a4c69b2361978ecc7d00dec3d371b6cbbae86" + digest = "1:f2ea352b0b7340255d66e7578a5e12bb4e594d3207c0e778327865a73d213119" name = "github.com/ligato/cn-infra" packages = [ "agent", @@ -417,6 +484,7 @@ "logging/logmanager", "logging/logrus", "logging/measure", + "logging/measure/model/apitrace", "messaging", "messaging/kafka", "messaging/kafka/client", @@ -424,6 +492,8 @@ "rpc/grpc", "rpc/prometheus", "rpc/rest", + "rpc/rest/security", + "rpc/rest/security/model/access-security", "servicelabel", "utils/addrs", "utils/clienttls", @@ -431,15 +501,15 @@ "utils/safeclose", ] pruneopts = "T" - revision = "664a4d1263a2679014006424616880df0067a4ba" + revision = "d988900fbcc23fd235cf6a47d403fe12857064e9" [[projects]] branch = "master" - digest = "1:3b55e68f7806bd4a804c9ac871c4e0cc224cc822feb7fa5e0bd7f1bfb4c31cfa" + digest = "1:7616dd8d9ddca4d4d8aa0e3793f66015c8c8bf9a3f2387be6be59347f43a75c0" name = "github.com/logrusorgru/aurora.git" packages = ["."] pruneopts = "UT" - revision = "ca24023cc0175fdf372518cb1c5062cc86db2634" + revision = "d694e6f975a9109e2b063829d563a7c153c4b53c" [[projects]] branch = "master" @@ -473,6 +543,14 @@ pruneopts = "UT" revision = "f15292f7a699fcc1a38a80977f80a046874ba8ac" +[[projects]] + branch = "master" + digest = "1:a8fbf0fec8d03cb034316610ec25ad82d577ec709a4068bb2d139cf5c744ef56" + name = "github.com/mrunalp/fileutils" + packages = ["."] + pruneopts = "UT" + revision = "7d4729fb36185a7c1719923406c9d40e54fb93c7" + [[projects]] digest = "1:6221a3a452964b1ff30efdc22209b124d54d04373e5993264d3fa9b13da0659d" name = "github.com/namsral/flag" @@ -482,7 +560,7 @@ version = "v1.7.4-pre" [[projects]] - digest = "1:038734db8a70cdd73d4215081b22236e2aed3e65ca0727f6afd0ed839630e738" + digest = "1:29f294e6a3b9d30629266b2765a8c203056387941e600405b8e8871c84653042" name = "github.com/onsi/gomega" packages = [ ".", @@ -499,8 +577,8 @@ "types", ] pruneopts = "UT" - revision = "003f63b7f4cff3fc95357005358af2de0f5fe152" - version = "v1.3.0" + revision = "b6ea1ea48f981d0f615a154a45eabb9dd466556d" + version = "v1.4.1" [[projects]] digest = "1:ee4d4af67d93cc7644157882329023ce9a7bcfce956a079069a9405521c7cc8d" @@ -522,12 +600,51 @@ version = "v1.0.1" [[projects]] - digest = "1:38ee335aedf4626620f3cf8f605661e71abdcce7b40b38921962beb3980f0a20" + digest = "1:47b264080750861f49f1a151972f9e3bb57fef9f6601ad22ac08dcb8a4b3af6f" name = "github.com/opencontainers/runc" - packages = ["libcontainer/user"] + packages = [ + ".", + "libcontainer", + "libcontainer/apparmor", + "libcontainer/cgroups", + "libcontainer/cgroups/fs", + "libcontainer/cgroups/systemd", + "libcontainer/configs", + "libcontainer/configs/validate", + "libcontainer/criurpc", + "libcontainer/intelrdt", + "libcontainer/keys", + "libcontainer/mount", + "libcontainer/nsenter", + "libcontainer/seccomp", + "libcontainer/specconv", + "libcontainer/stacktrace", + "libcontainer/system", + "libcontainer/user", + "libcontainer/utils", + ] + pruneopts = "UT" + revision = "4fc53a81fb7c994640722ac585fa9ca548971871" + version = "v1.0.0-rc5" + +[[projects]] + digest = "1:57234a321bf1f8f98a8a9a5122a2404cc60d0800516f4ab7a7b2375e4b2d19ea" + name = "github.com/opencontainers/runtime-spec" + packages = ["specs-go"] + pruneopts = "UT" + revision = "4e3b9264a330d094b0386c3703c5f379119711e8" + version = "v1.0.1" + +[[projects]] + digest = "1:5c65c485fa22fdfd6937db07aaf879904a4745770ee416d8d1f2a1434dc2d8ce" + name = "github.com/opencontainers/selinux" + packages = [ + "go-selinux", + "go-selinux/label", + ] pruneopts = "UT" - revision = "baf6536d6259209c3edfa2b22237af82942d3dfa" - version = "v0.1.1" + revision = "ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d" + version = "v1.0.0-rc1" [[projects]] digest = "1:5e73b34a27d827212102605789de00bd411b2e434812133c83935fe9897c75e1" @@ -617,31 +734,47 @@ version = "v1.2.0" [[projects]] - digest = "1:14b7e5f64170ca9942d257036dba61b096a900adb1b2ddecf7a7bc0d44de9e4c" + digest = "1:76b02b3f516299ddfed21a4e7ce26cda0b9a57f14575bfe4aa2d644ea0e8e24c" + name = "github.com/seccomp/libseccomp-golang" + packages = ["."] + pruneopts = "UT" + revision = "e3496e3a417d1dc9ecdceca5af2513271fed37a0" + version = "v0.9.0" + +[[projects]] + digest = "1:606e395bc6f4011ae992e7ae0c613839d20ea097b8a9468e1683b22cefd8fd77" name = "github.com/sirupsen/logrus" packages = [ ".", "hooks/syslog", ] pruneopts = "UT" - revision = "d682213848ed68c0a260ca37d6dd5ace8423f5ba" - version = "v1.0.4" + revision = "3e01752db0189b9157070a0e1668a620f9a85da2" + version = "v1.0.6" [[projects]] - digest = "1:7ffc0983035bc7e297da3688d9fe19d60a420e9c38bef23f845c53788ed6a05e" + digest = "1:645cabccbb4fa8aab25a956cbcbdf6a6845ca736b2c64e197ca7cbb9d210b939" name = "github.com/spf13/cobra" packages = ["."] pruneopts = "UT" - revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b" - version = "v0.0.1" + revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385" + version = "v0.0.3" [[projects]] - digest = "1:1b21a2b4058a779f290c7341cd93267492e0ecea6c8b54f64a4a5fd7ff131034" + digest = "1:dab83a1bbc7ad3d7a6ba1a1cc1760f25ac38cdf7d96a5cdd55cd915a4f5ceaf9" name = "github.com/spf13/pflag" packages = ["."] pruneopts = "UT" - revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" - version = "v1.0.0" + revision = "9a97c102cda95a86cec2345a6f09f55a939babf5" + version = "v1.0.2" + +[[projects]] + branch = "master" + digest = "1:e865a1cd94806d1bb0eaa0bffba2ccb5e25ac42e1f55328c83d5e3399c9961a4" + name = "github.com/syndtr/gocapability" + packages = ["capability"] + pruneopts = "UT" + revision = "33e07d32887e1e06b7c025f27ce52f62c7990bc0" [[projects]] digest = "1:eaa6698f44de8f2977e93c9b946e60a8af75f565058658aad2df8032b55c84e5" @@ -653,76 +786,79 @@ [[projects]] branch = "master" - digest = "1:0d7055e14293468d8a849d858d43e86d4d1be9f5361ec23813b55393b299f558" - name = "github.com/ungerik/pkgreflect" + digest = "1:e833d953c8467158fd0250a053ec390dd899945d4c6b87b07920ad431fc80dfe" + name = "github.com/unrolled/render" packages = ["."] pruneopts = "UT" - revision = "bfeb2a93186329a0bb03885bea902e86842f633d" + revision = "65450fb6b2d3595beca39f969c411db8f8d5c806" [[projects]] - branch = "master" - digest = "1:e833d953c8467158fd0250a053ec390dd899945d4c6b87b07920ad431fc80dfe" - name = "github.com/unrolled/render" + digest = "1:b24d38b282bacf9791408a080f606370efa3d364e4b5fd9ba0f7b87786d3b679" + name = "github.com/urfave/cli" packages = ["."] pruneopts = "UT" - revision = "65450fb6b2d3595beca39f969c411db8f8d5c806" + revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1" + version = "v1.20.0" [[projects]] branch = "master" - digest = "1:a33371c267e87664981ede8804eff9aac0e36d234deef66b176858c9476e63d4" + digest = "1:5f912b2a10701e13b05b826b29620f8ed5a83e855b1d4114dfff489535a96df3" name = "github.com/vishvananda/netlink" packages = [ ".", "nl", ] pruneopts = "UT" - revision = "5f5d5cddcf414bb44941b9c6c0d2df31253ec40e" + revision = "56b1bd27a9a363862ef67916bb450fe240787d07" [[projects]] branch = "master" - digest = "1:02b1d1b48bf853ea2a9bea029ffe54e3fd7804903a0eda9a78191db8984300d2" + digest = "1:e4e30678fb2560b5c62f6308c5023d6c294fc7713216fa379411cc74465e866f" name = "github.com/vishvananda/netns" packages = ["."] pruneopts = "UT" - revision = "be1fbeda19366dea804f00efff2dd73a1642fdcc" + revision = "13995c7128ccc8e51e9a6bd2b551020a27180abd" [[projects]] branch = "master" - digest = "1:707ec3bb6ccc1cd330b8789467fa6cd8dad40f63fed028ba777a6c2ca13a9838" + digest = "1:19f86cbdeb3e5cf117b52da99a655e2438ec65ae3240687ef4a520582e825df8" name = "golang.org/x/crypto" - packages = ["ssh/terminal"] + packages = [ + "bcrypt", + "blowfish", + "ssh/terminal", + ] pruneopts = "UT" revision = "3d37316aaa6bd9929127ac9a527abf408178ea7b" [[projects]] branch = "master" - digest = "1:322768c2d083e730e27856aef1551d7ebc9e209f9e9549aca9d4e1cb095b5e87" + digest = "1:6b9d693aad7155c20f594c83ffb8e4dc74db309236a99459a384f57264dbad24" name = "golang.org/x/net" packages = [ "context", "html", "html/atom", "html/charset", + "http/httpguts", "http2", "http2/hpack", "idna", "internal/timeseries", - "lex/httplex", "trace", ] pruneopts = "UT" - revision = "0ed95abb35c445290478a5348a7b38bb154135fd" + revision = "26e67e76b6c3f6ce91f7c52def5af501b4e0f3a2" [[projects]] - branch = "master" - digest = "1:322dcd045c1f20b4604d829832fbbb7cb29f2f7615179736c57b4f2a4ca25ee3" + digest = "1:0dafafed83f125cdc945a014b2dec15e5b5d8cd2d77a2d1e3763120b08ab381b" name = "golang.org/x/sys" packages = [ "unix", "windows", ] pruneopts = "UT" - revision = "af50095a40f9041b3b38960738837185c26e9419" + revision = "4910a1d54f876d7b22162a85f4d066d3ee649450" [[projects]] branch = "master" @@ -760,25 +896,48 @@ revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3" [[projects]] - digest = "1:2b235a29dd809925b0149f8625d9b9f8dcb92fdb6f1f661ac6188e419098cd96" + branch = "master" + digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c" + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + pruneopts = "UT" + revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4" + +[[projects]] + digest = "1:c52f29435ecb5b76c37e7f0098b6a50dbe60f8624d820827d0fede75c40199a1" name = "google.golang.org/grpc" packages = [ ".", + "balancer", + "balancer/base", + "balancer/roundrobin", "codes", + "connectivity", "credentials", + "encoding", + "encoding/proto", "grpclog", + "health/grpc_health_v1", "internal", + "internal/backoff", + "internal/channelz", + "internal/envconfig", + "internal/grpcrand", + "internal/transport", "keepalive", "metadata", "naming", "peer", + "resolver", + "resolver/dns", + "resolver/passthrough", "stats", + "status", "tap", - "transport", ] pruneopts = "UT" - revision = "8050b9cbc271307e5a716a9d782803d09b0d6f2d" - version = "v1.2.1" + revision = "8dea3dc473e90c8179e519d91302d0597c0ca1d1" + version = "v1.15.0" [[projects]] branch = "v2" @@ -802,9 +961,9 @@ "github.com/elazarl/go-bindata-assetfs", "github.com/fsouza/go-dockerclient", "github.com/ghodss/yaml", + "github.com/go-errors/errors", "github.com/gogo/protobuf/proto", "github.com/gogo/protobuf/protoc-gen-gogo", - "github.com/golang/protobuf/proto", "github.com/ligato/cn-infra/agent", "github.com/ligato/cn-infra/config", "github.com/ligato/cn-infra/datasync", @@ -827,11 +986,13 @@ "github.com/ligato/cn-infra/logging/logmanager", "github.com/ligato/cn-infra/logging/logrus", "github.com/ligato/cn-infra/logging/measure", + "github.com/ligato/cn-infra/logging/measure/model/apitrace", "github.com/ligato/cn-infra/messaging", "github.com/ligato/cn-infra/messaging/kafka", "github.com/ligato/cn-infra/rpc/grpc", "github.com/ligato/cn-infra/rpc/prometheus", "github.com/ligato/cn-infra/rpc/rest", + "github.com/ligato/cn-infra/rpc/rest/security/model/access-security", "github.com/ligato/cn-infra/servicelabel", "github.com/ligato/cn-infra/utils/addrs", "github.com/ligato/cn-infra/utils/safeclose", @@ -839,11 +1000,11 @@ "github.com/lunixbochs/struc", "github.com/namsral/flag", "github.com/onsi/gomega", + "github.com/opencontainers/runc", "github.com/prometheus/client_golang/prometheus", "github.com/prometheus/client_golang/prometheus/promhttp", "github.com/sirupsen/logrus", "github.com/spf13/cobra", - "github.com/ungerik/pkgreflect", "github.com/unrolled/render", "github.com/vishvananda/netlink", "github.com/vishvananda/netns", diff --git a/Gopkg.toml b/Gopkg.toml index b6f7ac238a..28c29c41df 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -5,10 +5,12 @@ required = [ "git.fd.io/govpp.git/cmd/binapi-generator", - "github.com/ungerik/pkgreflect", - "github.com/gogo/protobuf/protoc-gen-gogo" + "github.com/gogo/protobuf/protoc-gen-gogo", + "github.com/opencontainers/runc" ] +# Constraints + [[constraint]] branch = "master" name = "github.com/ligato/cn-infra" @@ -16,7 +18,6 @@ required = [ [[constraint]] branch = "master" name = "git.fd.io/govpp.git" - source = "github.com/FDio/govpp" [[constraint]] branch = "master" @@ -32,11 +33,7 @@ required = [ [[constraint]] name = "github.com/gogo/protobuf" - version = "0.5.0" - -[[constraint]] - branch = "master" - name = "github.com/golang/protobuf" + version = "1.1.1" [[constraint]] branch = "master" @@ -76,11 +73,31 @@ required = [ [[constraint]] name = "google.golang.org/grpc" - version = "1.2.1" + version = "1.14.0" + +# Overrides [[override]] name = "github.com/docker/libnetwork" - revision = "19279f0492417475b6bfbd0aa529f73e8f178fb5" + revision = "9ffeaf7d8b64fa0eb64cc27835dc1a5a90328024" + +[[override]] + name = "github.com/Shopify/sarama" + version = "~1.15.0" + +[[override]] + name = "github.com/bsm/sarama-cluster" + version = "2.1.11" + +[[override]] + name = "github.com/coreos/etcd" + version = "=3.3.9" + +[[constraint]] + name = "github.com/opencontainers/runc" + version = "v1.0.0-rc5" + +# Prunes [prune] go-tests = true diff --git a/Makefile b/Makefile index 5606cd87e1..434adf13f5 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ include vpp.env -VERSION ?= $(shell git describe --always --tags --dirty) -COMMIT ?= $(shell git rev-parse HEAD) -DATE := $(shell date +'%Y-%m-%dT%H:%M%:z') +VERSION ?= $(shell git describe --always --tags --dirty) +COMMIT ?= $(shell git rev-parse HEAD) +DATE ?= $(shell git log -1 --format="%ct" | xargs -I{} date -d @{} +'%Y-%m-%dT%H:%M%:z') CNINFRA := github.com/ligato/vpp-agent/vendor/github.com/ligato/cn-infra/agent LDFLAGS = -X $(CNINFRA).BuildVersion=$(VERSION) -X $(CNINFRA).CommitHash=$(COMMIT) -X $(CNINFRA).BuildDate=$(DATE) @@ -11,6 +11,11 @@ ifeq ($(NOSTRIP),) LDFLAGS += -w -s endif +ifeq ($(BUILDPIE),y) +GO_BUILD_ARGS += -buildmode=pie +LDFLAGS += -extldflags=-Wl,-z,now,-z,relro +endif + ifeq ($(V),1) GO_BUILD_ARGS += -v endif @@ -105,44 +110,17 @@ get-proto-generators: # Generate proto models generate-proto: get-proto-generators @echo "=> generating proto" - cd plugins/linux/ifplugin && go generate - cd plugins/linux/l3plugin && go generate - cd plugins/vpp/aclplugin && go generate - cd plugins/vpp/ifplugin && go generate - cd plugins/vpp/ipsecplugin && go generate - cd plugins/vpp/l2plugin && go generate - cd plugins/vpp/l3plugin && go generate - cd plugins/vpp/l4plugin && go generate - cd plugins/vpp/rpc && go generate - cd plugins/vpp/srplugin && go generate + cd plugins/linux/model && go generate + cd plugins/vpp/model && go generate # Get generator tools get-binapi-generators: go install ./vendor/git.fd.io/govpp.git/cmd/binapi-generator - go install ./vendor/github.com/ungerik/pkgreflect # Generate binary api generate-binapi: get-binapi-generators @echo "=> generating binapi" cd plugins/vpp/binapi && go generate - cd plugins/vpp/binapi/acl && pkgreflect - cd plugins/vpp/binapi/af_packet && pkgreflect - cd plugins/vpp/binapi/bfd && pkgreflect - cd plugins/vpp/binapi/dhcp && pkgreflect - cd plugins/vpp/binapi/interfaces && pkgreflect - cd plugins/vpp/binapi/ip && pkgreflect - cd plugins/vpp/binapi/ipsec && pkgreflect - cd plugins/vpp/binapi/l2 && pkgreflect - cd plugins/vpp/binapi/memif && pkgreflect - cd plugins/vpp/binapi/nat && pkgreflect - cd plugins/vpp/binapi/session && pkgreflect - cd plugins/vpp/binapi/sr && pkgreflect - cd plugins/vpp/binapi/stats && pkgreflect - cd plugins/vpp/binapi/stn && pkgreflect - cd plugins/vpp/binapi/tap && pkgreflect - cd plugins/vpp/binapi/tapv2 && pkgreflect - cd plugins/vpp/binapi/vpe && pkgreflect - cd plugins/vpp/binapi/vxlan && pkgreflect @echo "=> applying fix patches" find plugins/vpp/binapi -maxdepth 1 -type f -name '*.patch' -exec patch --no-backup-if-mismatch -p1 -i {} \; @@ -236,6 +214,14 @@ yamllint: get-yamllint @echo "=> linting the yaml files" yamllint -c .yamllint.yml $(shell git ls-files '*.yaml' '*.yml' | grep -v 'vendor/') +images: dev-image prod-image + +dev-image: + ./docker/dev/build.sh + +prod-image: + ./docker/prod/build.sh + .PHONY: build clean \ install cmd examples clean-examples test \ test-cover test-cover-html test-cover-xml \ @@ -244,4 +230,5 @@ yamllint: get-yamllint get-linters lint format \ get-linkcheck check-links \ travis \ - get-yamllint yamllint + get-yamllint yamllint \ + images dev-image prod-image diff --git a/README.md b/README.md index 92342c3718..8775c3d6a5 100644 --- a/README.md +++ b/README.md @@ -80,12 +80,14 @@ of VNFs based on the VPP Agent: ## Quickstart For a quick start with the VPP Agent, you can use pre-built Docker images with -the Agent and VPP on [Dockerhub][14]. +the Agent and VPP on [Dockerhub][14] (or this for [ARM64][17]). 0. Start ETCD and Kafka on your host (e.g. in Docker as described [here][15]). Note: **The Agent in the pre-built Docker image will not start if it can't connect to both Etcd and Kafka**. + Note: **For ARM64 see the information for [kafka][18] and for [etcd][19]**. + 1. Run VPP + VPP Agent in a Docker image: ``` docker pull ligato/vpp-agent @@ -133,4 +135,7 @@ If you are interested in contributing, please see the [contribution guidelines]( [13]: https://github.com/ligato/cn-infra/tree/master/core [14]: https://hub.docker.com/r/ligato/vpp-agent/ [15]: docker/dev/README.md#running-etcd-server-on-local-host -[16]: https://github.com/ligato/cn-infra \ No newline at end of file +[16]: https://github.com/ligato/cn-infra +[17]: https://hub.docker.com/r/ligato/vpp-agent-arm64/ +[18]: docs/arm64/kafka.md +[19]: docs/arm64/etcd.md diff --git a/app/vpp_agent.go b/app/vpp_agent.go index 5044b9d641..22bfa39077 100644 --- a/app/vpp_agent.go +++ b/app/vpp_agent.go @@ -26,6 +26,7 @@ import ( "github.com/ligato/cn-infra/db/keyval/etcd" "github.com/ligato/cn-infra/db/keyval/redis" "github.com/ligato/cn-infra/health/probe" + "github.com/ligato/cn-infra/health/statuscheck" "github.com/ligato/cn-infra/logging/logmanager" "github.com/ligato/cn-infra/messaging/kafka" "github.com/ligato/vpp-agent/plugins/linux" @@ -60,15 +61,16 @@ func New() *VPPAgent { consulDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&consul.DefaultPlugin)) redisDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&redis.DefaultPlugin)) - watcher := datasync.KVProtoWatchers{ + watchers := datasync.KVProtoWatchers{ local.Get(), etcdDataSync, consulDataSync, } - publisher := datasync.KVProtoWriters{ + writers := datasync.KVProtoWriters{ etcdDataSync, consulDataSync, } + statuscheck.DefaultPlugin.Transport = writers ifStatePub := msgsync.NewPlugin( msgsync.UseMessaging(&kafka.DefaultPlugin), @@ -78,8 +80,8 @@ func New() *VPPAgent { ) vppPlugin := vpp.NewPlugin(vpp.UseDeps(func(deps *vpp.Deps) { - deps.Publish = publisher - deps.Watcher = watcher + deps.Publish = writers + deps.Watcher = watchers deps.IfStatePub = ifStatePub deps.DataSyncs = map[string]datasync.KeyProtoValWriter{ "etcd": etcdDataSync, @@ -89,7 +91,7 @@ func New() *VPPAgent { })) linuxPlugin := linux.NewPlugin(linux.UseDeps(func(deps *linux.Deps) { deps.VPP = vppPlugin - deps.Watcher = watcher + deps.Watcher = watchers })) vppPlugin.Deps.Linux = linuxPlugin @@ -99,6 +101,7 @@ func New() *VPPAgent { restPlugin := rest.NewPlugin(rest.UseDeps(func(deps *rest.Deps) { deps.VPP = vppPlugin + deps.Linux = linuxPlugin })) return &VPPAgent{ diff --git a/clientv1/vpp/grpcadapter/data_change_grpc.go b/clientv1/vpp/grpcadapter/data_change_grpc.go index 0de0491a80..e60d87a2c0 100644 --- a/clientv1/vpp/grpcadapter/data_change_grpc.go +++ b/clientv1/vpp/grpcadapter/data_change_grpc.go @@ -420,7 +420,7 @@ func getRequestFromData(data []proto.Message) *rpc.DataRequest { case *linuxL3.LinuxStaticRoutes_Route: request.LinuxRoutes = append(request.LinuxRoutes, typedItem) default: - logrus.DefaultLogger().Warn("Unsupported data for GRPC request: %s", typedItem.String()) + logrus.DefaultLogger().Warnf("Unsupported data for GRPC request: %v", typedItem) } } diff --git a/cmd/agentctl/utils/db_utils.go b/cmd/agentctl/utils/db_utils.go index dd0504cabc..3ee9ef44f1 100644 --- a/cmd/agentctl/utils/db_utils.go +++ b/cmd/agentctl/utils/db_utils.go @@ -20,7 +20,7 @@ import ( "sort" "strings" - "github.com/golang/protobuf/proto" + "github.com/gogo/protobuf/proto" "github.com/ligato/cn-infra/db/keyval" "github.com/ligato/cn-infra/health/statuscheck/model/status" diff --git a/cmd/vpp-agent-ctl/data_cmd.go b/cmd/vpp-agent-ctl/data_cmd.go index 12ff32ab63..faff039b8b 100644 --- a/cmd/vpp-agent-ctl/data_cmd.go +++ b/cmd/vpp-agent-ctl/data_cmd.go @@ -220,6 +220,7 @@ func (ctl *VppAgentCtl) createBfdKey() { authKey := bfd.SingleHopBFD{ Keys: []*bfd.SingleHopBFD_Key{ { + Name: "bfdKey1", Id: 1, AuthenticationType: bfd.SingleHopBFD_Key_METICULOUS_KEYED_SHA1, // or Keyed sha1 Secret: "1981491891941891", @@ -499,6 +500,7 @@ func (ctl *VppAgentCtl) createVethPair() { Mtu: 1500, IpAddresses: []string{ "192.168.22.1/24", + "10.0.2.2/24", }, Veth: &linuxIf.LinuxInterfaces_Interface_Veth{ PeerIfName: "veth2", diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 37b091bf1c..5c33d7784e 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -39,16 +39,14 @@ RUN apt-get update \ telnet unzip wget \ && rm -rf /var/lib/apt/lists/* -# build & install Protobuf -RUN git clone --depth=1 https://github.com/google/protobuf.git \ - && cd protobuf \ - && ./autogen.sh \ - && ./configure \ - && make -j4 \ - && make install \ - && ldconfig \ - && cd .. \ - && rm -rf protobuf +# install Protobuf +ARG PROTOC_VERSION=3.6.1 +ARG PROTOC_OS_ARCH=linux_x86_64 +RUN wget -q https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-${PROTOC_OS_ARCH}.zip \ + && unzip protoc-${PROTOC_VERSION}-${PROTOC_OS_ARCH}.zip -d protoc3 \ + && mv protoc3/bin/protoc /usr/local/bin \ + && mv protoc3/include/google /usr/local/include \ + && rm -rf protoc-${PROTOC_VERSION}-${PROTOC_OS_ARCH}.zip protoc3 RUN mkdir -p /opt/vpp-agent/dev /opt/vpp-agent/plugin @@ -63,6 +61,7 @@ RUN set -eux; \ git clone "${VPP_REPO_URL}" vpp; \ cd vpp; \ git checkout "${VPP_COMMIT}"; \ + sed -i -e 's/vpp vom japi/vpp/g' build-data/platforms/vpp.mk; \ export UNATTENDED=y; \ make install-dep dpdk-install-dev; \ if [ -n "${VPP_DEBUG_DEB}" ]; then \ @@ -77,7 +76,7 @@ RUN set -eux; \ find . -type f -name '*.o' -exec rm -rf '{}' \; # install Go -ENV GOLANG_VERSION 1.10.3 +ENV GOLANG_VERSION 1.11.1 ARG GOLANG_OS_ARCH=linux-amd64 RUN wget -O go.tgz "https://golang.org/dl/go${GOLANG_VERSION}.${GOLANG_OS_ARCH}.tar.gz" \ && tar -C /usr/local -xzf go.tgz \ @@ -110,12 +109,13 @@ COPY \ ARG VERSION ARG COMMIT +ARG DATE # copy & build agent COPY . $GOPATH/src/github.com/ligato/vpp-agent RUN cd $GOPATH/src/github.com/ligato/vpp-agent \ - && VERSION=$VERSION COMMIT=$COMMIT make install + && VERSION=$VERSION COMMIT=$COMMIT DATE=$DATE make install WORKDIR / diff --git a/docker/dev/README.md b/docker/dev/README.md index 8c0aab5424..cadbbeaccb 100644 --- a/docker/dev/README.md +++ b/docker/dev/README.md @@ -13,6 +13,11 @@ This image is used for development and debugging. ## Get the official image +Supported architectures are: +* AMD64 (a.k.a. x86_64) +* ARM64 (a.k.a. aarch64) - see [arm64 docker image][3]. + +Here follows the information related to AMD64 architecture: For a quick start with the development image, you can download the [official image](https://hub.docker.com/r/ligato/dev-vpp-agent/) from **DockerHub**. @@ -37,6 +42,17 @@ and use following sources: - **VPP-Agent** version from local repository - **VPP** from repository and commit specified in `vpp.env` file +Note: The script build.sh will recognize the architecture (AMD64 or ARM64) and build the proper image. + +### Pushing docker image to repository +To push the docker image into your repository, type: +``` +REPO_OWNER=yourdockerhubreponame ./push_image.sh +``` +Warning: use only IMMEDIATELY after docker/dev/build.sh to prevent INCONSISTENCIES such as: +* after building image you switch to other branch which will result in mismatch of version of image and its tag +* you do not build the new image but only simply run this script which will result in mismatch version of image and its tag because the image is older than repository + ### Build VPP in _debug_ mode By default the image builds **VPP** _.deb_ packages in **release** mode. @@ -196,6 +212,7 @@ Call the agent via ETCD using the testing client: vpp-agent-ctl /opt/vpp-agent/dev/etcd.conf -tap vpp-agent-ctl /opt/vpp-agent/dev/etcd.conf -tapd ``` +Note: **For ARM64 see the information about [etcd][2]**. ## Running Kafka on Local Host @@ -204,6 +221,7 @@ You can start Kafka in a separate container: sudo docker run -p 2181:2181 -p 9092:9092 --name kafka --rm \ --env ADVERTISED_HOST=172.17.0.1 --env ADVERTISED_PORT=9092 spotify/kafka ``` +Note: **For ARM64 see the information about [kafka][1]**. ## Rebuilding the Agent ``` @@ -331,3 +349,7 @@ console. - Use the newly built agent as described in Section '[Running VPP and the Agent](#running-vpp-and-the-agent)'. + +[1]: ../../docs/arm64/kafka.md +[2]: ../../docs/arm64/etcd.md +[3]: ../../docs/arm64/docker_images.md diff --git a/docker/dev/build.sh b/docker/dev/build.sh index 75909891af..1fa83af136 100755 --- a/docker/dev/build.sh +++ b/docker/dev/build.sh @@ -1,4 +1,7 @@ #!/bin/bash +# Before run of this script you can set environmental variables +# IMAGE_TAG, DOCKERFILE, BASE_IMG, GOLANG_OS_ARCH, .. then export them +# and to use defined values instead of default ones cd "$(dirname "$0")" @@ -8,23 +11,51 @@ IMAGE_TAG=${IMAGE_TAG:-'dev_vpp_agent'} DOCKERFILE=${DOCKERFILE:-'Dockerfile'} BASE_IMG=${BASE_IMG:-'ubuntu:18.04'} -GOLANG_OS_ARCH=${GOLANG_OS_ARCH:-'linux-amd64'} + +BUILDARCH=`uname -m` +case "$BUILDARCH" in + "aarch64" ) + GOLANG_OS_ARCH=${GOLANG_OS_ARCH:-'linux-arm64'} + PROTOC_OS_ARCH=${PROTOC_OS_ARCH:-'linux-aarch_64'} + ;; + + "x86_64" ) + # for AMD64 platform is used the default image (without suffix -amd64) + GOLANG_OS_ARCH=${GOLANG_OS_ARCH:-'linux-amd64'} + PROTOC_OS_ARCH=${PROTOC_OS_ARCH:-'linux-x86_64'} + ;; + * ) + echo "Architecture ${BUILDARCH} is not supported." + exit + ;; +esac + source ../../vpp.env VPP_DEBUG_DEB=${VPP_DEBUG_DEB:-} VERSION=$(git describe --always --tags --dirty) COMMIT=$(git rev-parse HEAD) +DATE=$(git log -1 --format="%ct" | xargs -I{} date -d @{} +'%Y-%m-%dT%H:%M%:z') echo "==============================" -echo "VPP repo URL: ${VPP_REPO_URL}" -echo "VPP commit: ${VPP_COMMIT}" echo -echo "Agent version: ${VERSION}" -echo "Agent commit: ${COMMIT}" +echo "VPP" +echo "-----------------------------" +echo " repo URL: ${VPP_REPO_URL}" +echo " commit: ${VPP_COMMIT}" +echo "-----------------------------" +echo +echo "Agent" +echo "-----------------------------" +echo " version: ${VERSION}" +echo " commit: ${COMMIT}" +echo " date: ${DATE}" +echo "-----------------------------" echo echo "base image: ${BASE_IMG}" echo "image tag: ${IMAGE_TAG}" +echo "architecture: ${BUILDARCH}" echo "==============================" docker build -f ${DOCKERFILE} \ @@ -34,6 +65,8 @@ docker build -f ${DOCKERFILE} \ --build-arg VPP_REPO_URL=${VPP_REPO_URL} \ --build-arg VPP_DEBUG_DEB=${VPP_DEBUG_DEB} \ --build-arg GOLANG_OS_ARCH=${GOLANG_OS_ARCH} \ + --build-arg PROTOC_OS_ARCH=${PROTOC_OS_ARCH} \ --build-arg VERSION=${VERSION} \ --build-arg COMMIT=${COMMIT} \ + --build-arg DATE=${DATE} \ ${DOCKER_BUILD_ARGS} ../.. diff --git a/docker/dev/push_image.sh b/docker/dev/push_image.sh new file mode 100755 index 0000000000..9aab65e858 --- /dev/null +++ b/docker/dev/push_image.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Usage: examples +# ./push_image.sh +# BRANCH_HEAD_TAG=`git describe` ./push_image.sh +# REPO_OWNER=stanislavchlebec BRANCH_HEAD_TAG=`git describe` ./push_image.sh +# LOCAL_IMAGE='prod_vpp_agent:latest' IMAGE_NAME='vpp-agent' ./push_image.sh + +# Warning: use only IMMEDIATELY after docker/dev/build.sh to prevent INCONSISTENCIES such as +# a) after building image you switch to other branch which will result in mismatch of version of image and its tag +# b) you do not build the new image but only simply run this script which will result in mismatch version of image and its tag because the image is older than repository + +set -e + +# detect branch name +BRANCH_NAME="$(git symbolic-ref HEAD 2>/dev/null)" || BRANCH_NAME="(unnamed branch)" # detached HEAD +BRANCH_NAME=${BRANCH_NAME##refs/heads/} +BRANCH_HEAD_TAG=${BRANCH_HEAD_TAG:-"`git name-rev --name-only --tags HEAD`"} +VERSION=$(git describe --always --tags --dirty) + +LOCAL_IMAGE=${LOCAL_IMAGE:-'dev_vpp_agent:latest'} +REPO_OWNER=${REPO_OWNER:-'ligato'} +IMAGE_NAME=${IMAGE_NAME:-'dev-vpp-agent'} + +#To prepare for future fat manifest image by multi-arch manifest, +#now build the docker image with its arch +#For fat manifest, please refer +#https://docs.docker.com/registry/spec/manifest-v2-2/#example-manifest-list + +BUILDARCH=`uname -m` + +case "$BUILDARCH" in + "aarch64" ) + ARCH_SUFFIX='arm64' + ;; + + "x86_64" ) + # for AMD64 platform is also used the default image (without suffix -amd64) + ARCH_SUFFIX='amd64' + ;; + * ) + echo "Architecture ${BUILDARCH} is not supported." + exit 1 + ;; +esac + + +echo "==============================" +echo "Architecture: ${BUILDARCH}" +echo "==============================" + +case "${BRANCH_NAME}" in + "master" ) + if [ ${BRANCH_HEAD_TAG} != "undefined" ] ; then + if [ ${BUILDARCH} = "x86_64" ] ; then + # for AMD64 platform is used also the default image (without suffix -amd64) + docker tag ${LOCAL_IMAGE} ${REPO_OWNER}/${IMAGE_NAME}:${BRANCH_HEAD_TAG} + docker push ${REPO_OWNER}/${IMAGE_NAME}:${BRANCH_HEAD_TAG} + docker tag ${LOCAL_IMAGE} ${REPO_OWNER}/${IMAGE_NAME}:latest + docker push ${REPO_OWNER}/${IMAGE_NAME}:latest + fi + docker tag ${LOCAL_IMAGE} ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:${BRANCH_HEAD_TAG} + docker push ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:${BRANCH_HEAD_TAG} + docker tag ${LOCAL_IMAGE} ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:latest + docker push ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:latest + else + echo "For branch ${BRANCH_NAME} is no setup for tagging and pushing docker images because HEAD has no tag." + fi + ;; + "(unnamed branch)" ) + docker tag ${LOCAL_IMAGE} ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:${VERSION} + echo "Repository is in detached HEAD state - please push manually:" + echo docker push ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:${VERSION} + ;; + * ) + docker tag ${LOCAL_IMAGE} ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:${BRANCH_NAME} + docker push ${REPO_OWNER}/${IMAGE_NAME}-${ARCH_SUFFIX}:${BRANCH_NAME} + ;; +esac diff --git a/docker/dev/vpp-plugin.conf b/docker/dev/vpp-plugin.conf index 44614926b5..5ca0087e63 100644 --- a/docker/dev/vpp-plugin.conf +++ b/docker/dev/vpp-plugin.conf @@ -1,2 +1,2 @@ stopwatch: true -status-publishers: [redis] \ No newline at end of file +status-publishers: [etcd, redis] \ No newline at end of file diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile index 258cee9765..a13ac7470f 100644 --- a/docker/prod/Dockerfile +++ b/docker/prod/Dockerfile @@ -1,6 +1,6 @@ FROM dev_vpp_agent as devimg -FROM ubuntu:18.04 +FROM ubuntu:18.04 as base RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -30,13 +30,18 @@ COPY --from=devimg \ /opt/vpp-agent/dev/vpp/build-root/vpp-plugins*.deb \ /opt/vpp/ -RUN cd /opt/vpp/ && dpkg -i vpp_*.deb vpp-lib_*.deb vpp-plugins_*.deb +RUN cd /opt/vpp/ \ + && dpkg -i vpp_*.deb vpp-lib_*.deb vpp-plugins_*.deb \ + && rm vpp*.deb + +FROM scratch + +COPY --from=base / / # install agent COPY --from=devimg \ /go/bin/vpp-agent \ /go/bin/vpp-agent-ctl \ - /go/bin/agentctl \ /bin/ # copy configs diff --git a/docker/prod/README.md b/docker/prod/README.md index 1d1e3a7874..c3fd0c872a 100644 --- a/docker/prod/README.md +++ b/docker/prod/README.md @@ -7,10 +7,12 @@ This image is a lightweight version of the dev_vpp_agent image. It contains: ### Getting a pre-built image from Dockerhub For a quick start with the VPP Agent, you can use pre-build Docker images with -the Agent and VPP on [Dockerhub](https://hub.docker.com/r/ligato/vpp-agent/). +the Agent and VPP on [Dockerhub](https://hub.docker.com/r/ligato/vpp-agent/) or this for [ARM64](https://hub.docker.com/r/ligato/vpp-agent-arm64/). + ``` docker pull ligato/vpp-agent ``` +Note: **For ARM64 see more: [getting an ARM64 image][2]**. ### Building locally At first you need to have built of downloaded the `dev_vpp_agent` image. @@ -94,4 +96,5 @@ sudo docker exec -it vpp_agent bash You can use the image the same way as the development image, see this [README](../dev/README.md). -[1]: https://github.com/moby/moby/issues/26173 \ No newline at end of file +[1]: https://github.com/moby/moby/issues/26173 +[2]: docs/arm64/docker_images.md#production-images diff --git a/docker/prod/build.sh b/docker/prod/build.sh index c74fb9223b..4867a88398 100755 --- a/docker/prod/build.sh +++ b/docker/prod/build.sh @@ -1,4 +1,7 @@ #!/bin/bash +# Before run of this script you can set environmental variables +# IMAGE_TAG ... then export them +# and to use defined values instead of default ones cd "$(dirname "$0")" @@ -6,4 +9,17 @@ set -e IMAGE_TAG=${IMAGE_TAG:-'prod_vpp_agent'} -sudo docker build ${DOCKER_BUILD_ARGS} --tag ${IMAGE_TAG} . +BUILDARCH=`uname -m` +case "$BUILDARCH" in + "aarch64" ) + ;; + + "x86_64" ) + ;; + * ) + echo "Architecture ${BUILDARCH} is not supported." + exit + ;; +esac + +docker build ${DOCKER_BUILD_ARGS} --tag ${IMAGE_TAG} . diff --git a/docker/prod/push_image.sh b/docker/prod/push_image.sh new file mode 100755 index 0000000000..88c16ae530 --- /dev/null +++ b/docker/prod/push_image.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Usage: examples +# ./push_image.sh +# BRANCH_HEAD_TAG='git describe' ./push_image.sh +# REPO_OWNER=stanislavchlebec BRANCH_HEAD_TAG=`git describe` ./push_image.sh +# LOCAL_IMAGE='prod_vpp_agent:latest' IMAGE_NAME='vpp-agent' ./push_image.sh + +# Warning: use only IMMEDIATELY after docker/dev/build.sh to prevent INCONSISTENCIES such as +# a) after building image you switch to other branch which will result in mismatch of version of image and its tag +# b) you do not build the new image but only simply run this script which will result in mismatch version of image and its tag because the image is older than repository +LOCAL_IMAGE='prod_vpp_agent:latest' IMAGE_NAME='vpp-agent' ../dev/push_image.sh diff --git a/docs/arm64/README.md b/docs/arm64/README.md new file mode 100644 index 0000000000..63895262be --- /dev/null +++ b/docs/arm64/README.md @@ -0,0 +1,43 @@ +# VPP Agent on ARM64 + +###### Please note that the content of this repository is currently **WORK IN PROGRESS**. + +The VPP Agent is successfully built also for ARM64 platform. +In this folder you find the documentation related to ARM64: +- Notes about [etcd on ARM6][3] +- Notes about [kafka on ARM64][2] +- Short description how to pull the [ARM64 images][4] from dockerhub and to start it. + +## Quickstart + +For a quick start with the VPP Agent, you can use pre-built Docker images with +the Agent and VPP on [Dockerhub][1]. + +0. Start ETCD and Kafka on your host (e.g. in Docker as described [here][3] and [here][2] ). + Note: **The Agent in the pre-built Docker image will not start if it can't + connect to both Etcd and Kafka**. + +1. Run VPP + VPP Agent in a Docker image: +``` +docker pull ligato/vpp-agent-arm64 +docker run -it --name vpp --rm ligato/vpp-agent-arm64 +``` + +2. Configure the VPP agent using agentctl: +``` +docker exec -it vpp agentctl -h +``` + +3. Check the configuration (using agentctl or directly using VPP console): +``` +docker exec -it vpp agentctl -e 172.17.0.1:2379 show +docker exec -it vpp vppctl -s localhost:5002 +``` + +## Next Steps +Read the README for the [Development Docker Image](../../docker/dev/README.md) for more details. + +[1]: https://hub.docker.com/r/ligato/vpp-agent-arm64/ +[2]: kafka.md +[3]: etcd.md +[4]: docker_images.md diff --git a/docs/arm64/docker_images.md b/docs/arm64/docker_images.md new file mode 100644 index 0000000000..7417ee4117 --- /dev/null +++ b/docs/arm64/docker_images.md @@ -0,0 +1,27 @@ +## Get the official image for AMR64 platform + +### Development images +For a quick start with the development image, you can download +the [official image for ARM64 platform](https://hub.docker.com/r/ligato/dev-vpp-agent-arm64/) from **DockerHub**. + +```sh +$ docker pull docker.io/ligato/dev-vpp-agent-arm64 # latest release (stable) +$ docker pull docker.io/ligato/dev-vpp-agent-arm64:pantheon-dev # bleeding edge (unstable) +``` + +List of all available docker image tags for development image can +be found [here for ARM64](https://hub.docker.com/r/ligato/dev-vpp-agent-arm64/tags/). + +### Production images +For a quick start with the VPP Agent, you can use pre-build Docker images with +the Agent and VPP on Dockerhub: +the [official image for ARM64 platform](https://hub.docker.com/r/ligato/vpp-agent-arm64/). +``` +docker pull ligato/vpp-agent-arm64 +``` + +## Quick start command for arm64 docker image +``` +docker pull ligato/vpp-agent-arm64 +docker run -it --name vpp --rm ligato/vpp-agent-arm64 +``` diff --git a/docs/arm64/etcd.md b/docs/arm64/etcd.md new file mode 100644 index 0000000000..f66f2e9531 --- /dev/null +++ b/docs/arm64/etcd.md @@ -0,0 +1,25 @@ + +## Running Etcd Server on Local Host - ARM64 platform + +You can run an ETCD server in a separate container on your local +host as follows: +``` +sudo docker run -p 2379:2379 --name etcd -e ETCDCTL_API=3 -e ETCD_UNSUPPORTED_ARCH=arm64 \ + quay.io/coreos/etcd:v3.3.8-arm64 /usr/local/bin/etcd \ + -advertise-client-urls http://0.0.0.0:2379 \ + -listen-client-urls http://0.0.0.0:2379 +``` +The ETCD server will be available on your host OS IP (most likely +`172.17.0.1` in the default docker environment) on port `2379`. + +Call the agent via ETCD using the testing client: +``` +vpp-agent-ctl /opt/vpp-agent/dev/etcd.conf -tap +vpp-agent-ctl /opt/vpp-agent/dev/etcd.conf -tapd +``` +**Note for ARM64:** + +Check for proper etcd ARM64 docker image in the [official repository](https://quay.io/repository/coreos/etcd?tag=latest&tab=tags). +Currently you must use the parameter "-e ETCD_UNSUPPORTED_ARCH=arm64". +``` +``` diff --git a/docs/arm64/kafka.md b/docs/arm64/kafka.md new file mode 100644 index 0000000000..3bf17fb81d --- /dev/null +++ b/docs/arm64/kafka.md @@ -0,0 +1,38 @@ + +## Running Kafka on Local Host for ARM64 platform + +There is no official spotify/kafka image for ARM64 platform. +You can build an image following steps at the [repository](https://github.com/spotify/docker-kafka#build-from-source). +However you need to modify the kafka/Dockerfile before building like this: +``` +#FROM java:openjdk-8-jre +#arm version needs this.... +FROM openjdk:8-jre +... +... +#ENV KAFKA_VERSION 0.10.1.0 +#arm version needs this.... +ENV KAFKA_VERSION 0.10.2.1 +... +... + +``` + +1. For preparing kafka-arm64 image please follow these steps: +``` +git clone https://github.com/spotify/docker-kafka.git +cd docker-kafka +sed -i -e "s/FROM java:openjdk-8-jre/FROM openjdk:8-jre/g" kafka/Dockerfile +sed -i -e "s/ENV KAFKA_VERSION 0.10.1.0/ENV KAFKA_VERSION 0.10.2.1/g" kafka/Dockerfile +docker build -t kafka-arm64 kafka/ +``` + + + + + +2. Then you can start Kafka in a separate container: +``` +sudo docker run -p 2181:2181 -p 9092:9092 --name kafka --rm \ + --env ADVERTISED_HOST=172.17.0.1 --env ADVERTISED_PORT=9092 kafka-arm64 +``` diff --git a/examples/README.md b/examples/README.md index 95efa9180c..d9d9f93729 100644 --- a/examples/README.md +++ b/examples/README.md @@ -54,6 +54,7 @@ Current examples: -advertise-client-urls http://0.0.0.0:2379 \ -listen-client-urls http://0.0.0.0:2379 ``` + Note: **For ARM64 see the information for [etcd][3]**. **2. Start Kafka on localhost** @@ -61,7 +62,8 @@ Current examples: sudo docker run -p 2181:2181 -p 9092:9092 --name kafka --rm \ --env ADVERTISED_HOST=172.17.0.1 --env ADVERTISED_PORT=9092 spotify/kafka ``` - + Note: **For ARM64 see the information for [kafka][2]**. + **3. Start VPP** ``` vpp unix { interactive } plugins { plugin dpdk_plugin.so { disable } } @@ -75,4 +77,6 @@ Current examples: --etcd-config=/opt/vpp-agent/dev/etcd.conf \ --kafka-config=/opt/vpp-agent/dev/kafka.conf ``` -[1]: https://github.com/ligato/cn-infra/tree/master/examples \ No newline at end of file +[1]: https://github.com/ligato/cn-infra/tree/master/examples +[2]: docs/arm64/kafka.md +[3]: docs/arm64/etcd.md diff --git a/examples/localclient_linux/tap/main.go b/examples/localclient_linux/tap/main.go index 24eb05ae34..2104d5baf8 100644 --- a/examples/localclient_linux/tap/main.go +++ b/examples/localclient_linux/tap/main.go @@ -72,14 +72,14 @@ var ( * | | | | * * | +-----+--------+ *------+-------+ | * * | | tap1 | | (tap2) | | * - * | | 10.0.0.11/24 | | 10.0.0.21/24 | | * + * | | 10.0.0.11/24 | | 20.0.0.11/24 | | * * | +-----+--------+ +------+-------+ | * * | | | | * * +-------+-------------------+------------+ * * | | * * +-------+----------+ +-----+------------+ * * | linux-tap1 | | linux-tap2 | * - * | IP: 10.0.0.12/24 | | IP: 10.0.0.22\24 | * + * | IP: 10.0.0.12/24 | | IP: 20.0.0.12\24 | * * | Namespace: ns1 | | Namespace: ns2 | * * +------------------+ +------------------+ * * * @@ -269,7 +269,7 @@ func tap2() *vpp_intf.Interfaces_Interface { Enabled: true, PhysAddress: "D5:BC:DC:12:E4:0E", IpAddresses: []string{ - "10.0.0.21/24", + "20.0.0.11/24", }, Tap: &vpp_intf.Interfaces_Interface_Tap{ HostIfName: "linux-tap2", @@ -322,7 +322,7 @@ func linuxTap2() *linux_intf.LinuxInterfaces_Interface { }, Mtu: 1500, IpAddresses: []string{ - "10.0.0.22/24", + "20.0.0.12/24", }, } } diff --git a/plugins/govppmux/README.md b/plugins/govppmux/README.md index cdf3e9bc71..883808f455 100644 --- a/plugins/govppmux/README.md +++ b/plugins/govppmux/README.md @@ -79,3 +79,12 @@ elapses, the request fails - *shm-prefix* - used for connection to a VPP instance which is not using default shared memory prefix - *resync-after-reconnect* - allows to run resync after recoonection + +## Trace + +Duration of the VPP binary api call can be measured using trace feature. These data are logged after +every event(any resync, interfaces, bridge domains, fib entries etc.). Enable trace in govpp.conf: + +`trace-enabled: true` or `trace-enabled: false` + +Trace is disabled by default (if there is no config available). \ No newline at end of file diff --git a/plugins/govppmux/govpp.conf b/plugins/govppmux/govpp.conf index f0fece8b53..7206d80311 100644 --- a/plugins/govppmux/govpp.conf +++ b/plugins/govppmux/govpp.conf @@ -1,3 +1,7 @@ +# Enable or disable feature to measure binary API call duration. Measured time is shown directly in log (info level). +# Measurement is taken also for certain procedures, like resync of plugin startup. Turned off by default. +trace-enabled: false + # Custom shared memory prefix for VPP. Not used by default. shm-prefix: diff --git a/plugins/govppmux/govpp_channel.go b/plugins/govppmux/govpp_channel.go index bfed46541e..7509a509b4 100644 --- a/plugins/govppmux/govpp_channel.go +++ b/plugins/govppmux/govpp_channel.go @@ -1,8 +1,24 @@ +// Copyright (c) 2018 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 govppmux import ( "time" + "github.com/ligato/cn-infra/logging/measure" + govppapi "git.fd.io/govpp.git/api" "git.fd.io/govpp.git/core" "github.com/ligato/cn-infra/logging/logrus" @@ -15,6 +31,14 @@ type goVppChan struct { govppapi.Channel // Retry data retry retryConfig + // tracer used to measure binary api call duration + tracer measure.Tracer +} + +// helper struct holding info about retry configuration +type retryConfig struct { + attempts int + timeout time.Duration } // govppRequestCtx is custom govpp RequestCtx. @@ -27,16 +51,52 @@ type govppRequestCtx struct { requestMsg govppapi.Message // Retry data retry retryConfig + // Tracer object + tracer measure.Tracer + // Start time + start time.Time } -// helper struct holding info about retry configuration -type retryConfig struct { - attempts int - timeout time.Duration +// govppMultirequestCtx is custom govpp MultiRequestCtx. +type govppMultirequestCtx struct { + // Original multi request context + requestCtx govppapi.MultiRequestCtx + // Parameter for sendRequest + requestMsg govppapi.Message + // Tracer object + tracer measure.Tracer + // Start time + start time.Time +} + +// SendRequest sends asynchronous request to the vpp and receives context used to receive reply. +// Plugin govppmux allows to re-send retry which failed because of disconnected vpp, if enabled. +func (c *goVppChan) SendRequest(request govppapi.Message) govppapi.RequestCtx { + start := time.Now() + + sendRequest := c.Channel.SendRequest + // Send request now and wait for context + requestCtx := sendRequest(request) + + // Return context with value and function which allows to send request again if needed + return &govppRequestCtx{ + requestCtx: requestCtx, + sendRequest: sendRequest, + requestMsg: request, + retry: c.retry, + tracer: c.tracer, + start: start, + } } // ReceiveReply handles request and returns error if occurred. Also does retry if this option is available. func (r *govppRequestCtx) ReceiveReply(reply govppapi.Message) error { + defer func() { + if r.tracer != nil { + r.tracer.LogTime(r.requestMsg.GetMessageName(), r.start) + } + }() + var timeout time.Duration maxAttempts := r.retry.attempts if r.retry.timeout > 0 { // Default value is 500ms @@ -61,13 +121,33 @@ func (r *govppRequestCtx) ReceiveReply(reply govppapi.Message) error { return err } -// SendRequest sends asynchronous request to the vpp and receives context used to receive reply. -// Plugin govppmux allows to re-send retry which failed because of disconnected vpp, if enabled. -func (c *goVppChan) SendRequest(request govppapi.Message) govppapi.RequestCtx { - sendRequest := c.Channel.SendRequest +// SendMultiRequest sends asynchronous request to the vpp and receives context used to receive reply. +func (c *goVppChan) SendMultiRequest(request govppapi.Message) govppapi.MultiRequestCtx { + start := time.Now() + + sendMultiRequest := c.Channel.SendMultiRequest // Send request now and wait for context - requestCtx := sendRequest(request) + requestCtx := sendMultiRequest(request) // Return context with value and function which allows to send request again if needed - return &govppRequestCtx{requestCtx, sendRequest, request, c.retry} + return &govppMultirequestCtx{ + requestCtx: requestCtx, + requestMsg: request, + tracer: c.tracer, + start: start, + } +} + +// ReceiveReply handles request and returns error if occurred. +func (r *govppMultirequestCtx) ReceiveReply(reply govppapi.Message) (bool, error) { + // Receive reply from original send + last, err := r.requestCtx.ReceiveReply(reply) + if last { + defer func() { + if r.tracer != nil { + r.tracer.LogTime(r.requestMsg.GetMessageName(), r.start) + } + }() + } + return last, err } diff --git a/plugins/govppmux/options.go b/plugins/govppmux/options.go index 77798e189c..59ce76c61d 100644 --- a/plugins/govppmux/options.go +++ b/plugins/govppmux/options.go @@ -15,6 +15,7 @@ package govppmux import ( + "github.com/ligato/cn-infra/datasync/resync" "github.com/ligato/cn-infra/health/statuscheck" ) @@ -27,6 +28,7 @@ func NewPlugin(opts ...Option) *Plugin { p.PluginName = "govpp" p.StatusCheck = &statuscheck.DefaultPlugin + p.Resync = &resync.DefaultPlugin for _, o := range opts { o(p) diff --git a/plugins/govppmux/plugin_api_govppmux.go b/plugins/govppmux/plugin_api_govppmux.go index a9878d6891..bc696b7007 100644 --- a/plugins/govppmux/plugin_api_govppmux.go +++ b/plugins/govppmux/plugin_api_govppmux.go @@ -16,8 +16,17 @@ package govppmux import ( govppapi "git.fd.io/govpp.git/api" + "github.com/ligato/cn-infra/logging/measure/model/apitrace" ) +// TraceAPI is extended API with ability to get traced VPP binary API calls +type TraceAPI interface { + API + + // GetTrace serves to obtain measured binary API calls + GetTrace() *apitrace.Trace +} + // API for other plugins to get connectivity to VPP. type API interface { // NewAPIChannel returns a new API channel for communication with VPP via govpp core. diff --git a/plugins/govppmux/plugin_impl_govppmux.go b/plugins/govppmux/plugin_impl_govppmux.go index a5db6c5a04..272daa0d6e 100644 --- a/plugins/govppmux/plugin_impl_govppmux.go +++ b/plugins/govppmux/plugin_impl_govppmux.go @@ -16,10 +16,13 @@ package govppmux import ( "context" - "errors" "sync" "time" + "github.com/go-errors/errors" + "github.com/ligato/cn-infra/logging/measure" + "github.com/ligato/cn-infra/logging/measure/model/apitrace" + "git.fd.io/govpp.git/adapter" govppapi "git.fd.io/govpp.git/api" govpp "git.fd.io/govpp.git/core" @@ -46,6 +49,10 @@ type Plugin struct { // Cancel can be used to cancel all goroutines and their jobs inside of the plugin. cancel context.CancelFunc + + // Plugin-wide tracer instance used to trace and time-measure binary API calls. Can be nil if not set. + tracer measure.Tracer + // Wait group allows to wait until all goroutines of the plugin have finished. wg sync.WaitGroup } @@ -60,6 +67,7 @@ type Deps struct { // Config groups the configurable parameter of GoVpp. type Config struct { + TraceEnabled bool `json:"trace-enabled"` HealthCheckProbeInterval time.Duration `json:"health-check-probe-interval"` HealthCheckReplyTimeout time.Duration `json:"health-check-reply-timeout"` HealthCheckThreshold int `json:"health-check-threshold"` @@ -102,9 +110,13 @@ func (plugin *Plugin) Init() error { return err } if found { - govpp.SetHealthCheckProbeInterval(plugin.config.HealthCheckProbeInterval) - govpp.SetHealthCheckReplyTimeout(plugin.config.HealthCheckReplyTimeout) - govpp.SetHealthCheckThreshold(plugin.config.HealthCheckThreshold) + govpp.HealthCheckProbeInterval = plugin.config.HealthCheckProbeInterval + govpp.HealthCheckReplyTimeout = plugin.config.HealthCheckReplyTimeout + govpp.HealthCheckThreshold = plugin.config.HealthCheckThreshold + if plugin.config.TraceEnabled { + plugin.tracer = measure.NewTracer("govpp-mux") + plugin.Log.Info("VPP API trace enabled") + } } if plugin.vppAdapter == nil { @@ -172,7 +184,7 @@ func (plugin *Plugin) NewAPIChannel() (govppapi.Channel, error) { plugin.config.RetryRequestCount, plugin.config.RetryRequestTimeout, } - return &goVppChan{ch, retryCfg}, nil + return &goVppChan{ch, retryCfg, plugin.tracer}, nil } // NewAPIChannelBuffered returns a new API channel for communication with VPP via govpp core. @@ -193,7 +205,16 @@ func (plugin *Plugin) NewAPIChannelBuffered(reqChanBufSize, replyChanBufSize int plugin.config.RetryRequestCount, plugin.config.RetryRequestTimeout, } - return &goVppChan{ch, retryCfg}, nil + return &goVppChan{ch, retryCfg, plugin.tracer}, nil +} + +// GetTrace returns all trace entries measured so far +func (plugin *Plugin) GetTrace() *apitrace.Trace { + if !plugin.config.TraceEnabled { + plugin.Log.Warnf("VPP API trace is disabled") + return nil + } + return plugin.tracer.Get() } // handleVPPConnectionEvents handles VPP connection events. diff --git a/plugins/linux/README.md b/plugins/linux/README.md index 35e99b0008..864d3477e7 100644 --- a/plugins/linux/README.md +++ b/plugins/linux/README.md @@ -8,15 +8,4 @@ is currently supported. Detailed description can be found in particular READMEs: - [nsplugin](nsplugin) In general, the northbound configuration is translated to a sequence of Netlink API -calls (using `github.com/vishvananda/netlink` and `github.com/vishvananda/netns` libraries). - -## Config file - -*Stopwatch* - -Duration of the linux netlink procedure can be measured using stopwatch feature. These data are logged after -every event(any resync, interfaces, routes, etc.). Enable stopwatch in linux.conf: - -`stopwatch: true` or `stopwatch: false` - -Stopwatch is disabled by default (if there is no config available). \ No newline at end of file +calls (using `github.com/vishvananda/netlink` and `github.com/vishvananda/netns` libraries). \ No newline at end of file diff --git a/plugins/linux/data_change.go b/plugins/linux/data_change.go index 16a87277c2..c4e051e0a3 100644 --- a/plugins/linux/data_change.go +++ b/plugins/linux/data_change.go @@ -25,7 +25,9 @@ import ( func (plugin *Plugin) changePropagateRequest(dataChng datasync.ChangeEvent) error { var err error key := dataChng.GetKey() - plugin.Log.Debugf("Start processing change for key: %s", key) + + plugin.Log.WithField("revision", dataChng.GetRevision()). + Debugf("Processing change for key: %q", key) if strings.HasPrefix(key, interfaces.InterfaceKeyPrefix()) { var value, prevValue interfaces.LinuxInterfaces_Interface @@ -71,12 +73,15 @@ func (plugin *Plugin) dataChangeIface(diff bool, value *interfaces.LinuxInterfac changeType datasync.Op) error { plugin.Log.Debug("dataChangeIface ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.ifConfigurator.DeleteLinuxInterface(prevValue) + err = plugin.ifConfigurator.DeleteLinuxInterface(prevValue) } else if diff { - return plugin.ifConfigurator.ModifyLinuxInterface(value, prevValue) + err = plugin.ifConfigurator.ModifyLinuxInterface(value, prevValue) + } else { + err = plugin.ifConfigurator.ConfigureLinuxInterface(value) } - return plugin.ifConfigurator.ConfigureLinuxInterface(value) + return plugin.ifConfigurator.LogError(err) } // DataChangeArp propagates data change to the arpConfigurator @@ -84,12 +89,15 @@ func (plugin *Plugin) dataChangeArp(diff bool, value *l3.LinuxStaticArpEntries_A changeType datasync.Op) error { plugin.Log.Debug("dataChangeArp ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.arpConfigurator.DeleteLinuxStaticArpEntry(prevValue) + err = plugin.arpConfigurator.DeleteLinuxStaticArpEntry(prevValue) } else if diff { - return plugin.arpConfigurator.ModifyLinuxStaticArpEntry(value, prevValue) + err = plugin.arpConfigurator.ModifyLinuxStaticArpEntry(value, prevValue) + } else { + err = plugin.arpConfigurator.ConfigureLinuxStaticArpEntry(value) } - return plugin.arpConfigurator.ConfigureLinuxStaticArpEntry(value) + return plugin.arpConfigurator.LogError(err) } // DataChangeRoute propagates data change to the routeConfigurator @@ -97,10 +105,13 @@ func (plugin *Plugin) dataChangeRoute(diff bool, value *l3.LinuxStaticRoutes_Rou changeType datasync.Op) error { plugin.Log.Debug("dataChangeRoute ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.routeConfigurator.DeleteLinuxStaticRoute(prevValue) + err = plugin.routeConfigurator.DeleteLinuxStaticRoute(prevValue) } else if diff { - return plugin.routeConfigurator.ModifyLinuxStaticRoute(value, prevValue) + err = plugin.routeConfigurator.ModifyLinuxStaticRoute(value, prevValue) + } else { + err = plugin.routeConfigurator.ConfigureLinuxStaticRoute(value) } - return plugin.routeConfigurator.ConfigureLinuxStaticRoute(value) + return plugin.routeConfigurator.LogError(err) } diff --git a/plugins/linux/data_resync.go b/plugins/linux/data_resync.go index e76f91053c..b9503400bd 100644 --- a/plugins/linux/data_resync.go +++ b/plugins/linux/data_resync.go @@ -19,7 +19,6 @@ import ( "strings" "github.com/ligato/cn-infra/datasync" - "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" "github.com/ligato/vpp-agent/plugins/linux/model/l3" ) @@ -53,16 +52,16 @@ func (plugin *Plugin) resyncPropageRequest(req *DataResyncReq) error { // store all resync errors var resyncErrs []error - if errs := plugin.ifConfigurator.Resync(req.Interfaces); errs != nil { - resyncErrs = append(resyncErrs, errs...) + if err := plugin.ifConfigurator.Resync(req.Interfaces); err != nil { + resyncErrs = append(resyncErrs, plugin.ifConfigurator.LogError(err)) } - if errs := plugin.arpConfigurator.Resync(req.ARPs); errs != nil { - resyncErrs = append(resyncErrs, errs...) + if err := plugin.arpConfigurator.Resync(req.ARPs); err != nil { + resyncErrs = append(resyncErrs, plugin.arpConfigurator.LogError(err)) } - if errs := plugin.routeConfigurator.Resync(req.Routes); errs != nil { - resyncErrs = append(resyncErrs, errs...) + if err := plugin.routeConfigurator.Resync(req.Routes); err != nil { + resyncErrs = append(resyncErrs, plugin.routeConfigurator.LogError(err)) } // log errors if any @@ -76,77 +75,87 @@ func (plugin *Plugin) resyncPropageRequest(req *DataResyncReq) error { return fmt.Errorf("%v errors occured during linuxplugin resync", len(resyncErrs)) } -func resyncParseEvent(resyncEv datasync.ResyncEvent, log logging.Logger) *DataResyncReq { +func (plugin *Plugin) resyncParseEvent(resyncEv datasync.ResyncEvent) *DataResyncReq { req := NewDataResyncReq() - for key := range resyncEv.GetValues() { - log.Debug("Received RESYNC key ", key) - } for key, resyncData := range resyncEv.GetValues() { + plugin.Log.Debug("Received RESYNC key ", key) if strings.HasPrefix(key, interfaces.InterfaceKeyPrefix()) { - numInterfaces := resyncAppendInterface(resyncData, req) - log.Debug("Received RESYNC interface values ", numInterfaces) + plugin.resyncAppendInterface(resyncData, req) } else if strings.HasPrefix(key, l3.StaticArpKeyPrefix()) { - numARPs := resyncAppendARPs(resyncData, req) - log.Debug("Received RESYNC ARP entry values ", numARPs) + plugin.resyncAppendARPs(resyncData, req) } else if strings.HasPrefix(key, l3.StaticRouteKeyPrefix()) { - numRoutes := resyncAppendRoutes(resyncData, req) - log.Debug("Received RESYNC route values ", numRoutes) + plugin.resyncAppendRoutes(resyncData, req) } else { - log.Warn("ignoring ", resyncEv) + plugin.Log.Warn("ignoring ", resyncEv) } } return req } -func resyncAppendInterface(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) resyncAppendInterface(iterator datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { - if interfaceData, stop := resyncData.GetNext(); stop { + if interfaceData, stop := iterator.GetNext(); stop { break } else { value := &interfaces.LinuxInterfaces_Interface{} - err := interfaceData.GetValue(value) - if err == nil { - req.Interfaces = append(req.Interfaces, value) - num++ + if err := interfaceData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of Linux interface: %v", err) + continue } + req.Interfaces = append(req.Interfaces, value) + num++ + + plugin.Log.WithField("revision", interfaceData.GetRevision()). + Debugf("Processing resync for key: %q", interfaceData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC Linux interface values %d", num) } -func resyncAppendARPs(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) resyncAppendARPs(iterator datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { - if arpData, stop := resyncData.GetNext(); stop { + if arpData, stop := iterator.GetNext(); stop { break } else { value := &l3.LinuxStaticArpEntries_ArpEntry{} - err := arpData.GetValue(value) - if err == nil { - req.ARPs = append(req.ARPs, value) - num++ + if err := arpData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of Linux ARP: %v", err) + continue } + req.ARPs = append(req.ARPs, value) + num++ + + plugin.Log.WithField("revision", arpData.GetRevision()). + Debugf("Processing resync for key: %q", arpData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC Linux ARP entry values %d", num) } -func resyncAppendRoutes(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) resyncAppendRoutes(iterator datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { - if routeData, stop := resyncData.GetNext(); stop { + if routeData, stop := iterator.GetNext(); stop { break } else { value := &l3.LinuxStaticRoutes_Route{} - err := routeData.GetValue(value) - if err == nil { - req.Routes = append(req.Routes, value) - num++ + if err := routeData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of Linux ARP: %v", err) + continue } + req.Routes = append(req.Routes, value) + num++ + + plugin.Log.WithField("revision", routeData.GetRevision()). + Debugf("Processing resync for key: %q", routeData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC Linux Route values %d", num) } func (plugin *Plugin) subscribeWatcher() (err error) { diff --git a/plugins/linux/ifplugin/data_resync.go b/plugins/linux/ifplugin/data_resync.go index 53776652b6..963b2cdf5a 100644 --- a/plugins/linux/ifplugin/data_resync.go +++ b/plugins/linux/ifplugin/data_resync.go @@ -16,11 +16,10 @@ package ifplugin import ( "bytes" - "fmt" "net" "strconv" - "time" + "github.com/go-errors/errors" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" "github.com/ligato/vpp-agent/plugins/linux/nsplugin" @@ -45,54 +44,53 @@ type LinuxDataPair struct { // 2. If interface does not exist, will be created anew // 3. If interface exists, it is correlated and modified if needed. // Resync configures an initial set of interfaces. Existing Linux interfaces are registered and potentially re-configured. -func (plugin *LinuxInterfaceConfigurator) Resync(nbIfs []*interfaces.LinuxInterfaces_Interface) (errs []error) { - plugin.log.Debugf("RESYNC Linux interface begin.") - - defer func(t time.Time) { - plugin.stopwatch.TimeLog("resync-linux-interfaces").LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (c *LinuxInterfaceConfigurator) Resync(nbIfs []*interfaces.LinuxInterfaces_Interface) error { nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() // Cache for interfaces modified later (interface name/link data) linkMap := make(map[string]*LinuxDataPair) + var errs []error // Iterate over NB configuration. Look for interfaces with the same host name for _, nbIf := range nbIfs { - plugin.handleOptionalHostIfName(nbIf) - plugin.addInterfaceToCache(nbIf) + c.handleOptionalHostIfName(nbIf) + c.addInterfaceToCache(nbIf) // Find linux equivalent for every NB interface and register it - linkIf, err := plugin.findLinuxInterface(nbIf, nsMgmtCtx) + linkIf, err := c.findLinuxInterface(nbIf, nsMgmtCtx) if err != nil { errs = append(errs, err) - continue } if linkIf != nil { // If interface was found, it will be compared and modified in the next step - plugin.log.Debugf("RESYNC Linux interface %v: interface found in namespace", nbIf.Name) + c.log.Debugf("linux interface %s resync: interface found in namespace", nbIf.Name) linkMap[nbIf.Name] = &LinuxDataPair{ linuxIfData: linkIf, nbIfData: nbIf, } } else { // If not, configure it - plugin.log.Debugf("RESYNC Linux interface %v: interface not found and will be configured", nbIf.Name) - if err := plugin.ConfigureLinuxInterface(nbIf); err != nil { - errs = append(errs, err) + c.log.Debugf("linux interface %s resync: interface not found and will be configured", nbIf.Name) + if err := c.ConfigureLinuxInterface(nbIf); err != nil { + errs = append(errs, errors.Errorf("linux interface %s resync error: %v", nbIf.Name, err)) } } } // Process all interfaces waiting for modification. All NB interfaces are already registered at this point. for linkName, linkDataPair := range linkMap { - linuxIf := plugin.reconstructIfConfig(linkDataPair.linuxIfData, linkDataPair.nbIfData.Namespace, linkName) + linuxIf, err := c.reconstructIfConfig(linkDataPair.linuxIfData, linkDataPair.nbIfData.Namespace, linkName) + if err != nil { + errs = append(errs, errors.Errorf("linux interface %s resync: failed to reconstruct interface configuration: %v", + linkName, err)) + } // For VETH, resolve peer if linkDataPair.nbIfData.Type == interfaces.LinuxInterfaces_VETH { // Search registered config for peer var found bool - for _, cachedIfCfg := range plugin.ifByName { + c.mapMu.RLock() + for _, cachedIfCfg := range c.ifByName { if cachedIfCfg.config != nil && cachedIfCfg.config.Type == interfaces.LinuxInterfaces_VETH { if cachedIfCfg.config.Veth != nil && cachedIfCfg.config.Veth.PeerIfName == linuxIf.HostIfName { found = true @@ -102,8 +100,9 @@ func (plugin *LinuxInterfaceConfigurator) Resync(nbIfs []*interfaces.LinuxInterf } } } + c.mapMu.RUnlock() if found { - plugin.log.Debugf("RESYNC Linux interface %v: found peer %v", linkName, linuxIf.Veth.PeerIfName) + c.log.Debugf("linux interface %s resync: found peer %s", linkName, linuxIf.Veth.PeerIfName) } else { // No info about the peer, use the same as in the NB config linuxIf.Veth = &interfaces.LinuxInterfaces_Interface_Veth{ @@ -112,54 +111,62 @@ func (plugin *LinuxInterfaceConfigurator) Resync(nbIfs []*interfaces.LinuxInterf } } // Check if interface needs to be modified - if plugin.isLinuxIfModified(linkDataPair.nbIfData, linuxIf) { - plugin.log.Debugf("RESYNC Linux interface %s: configuration changed, interface will be modified", linkName) - if err := plugin.ModifyLinuxInterface(linkDataPair.nbIfData, linuxIf); err != nil { - errs = append(errs, err) + if c.isLinuxIfModified(linkDataPair.nbIfData, linuxIf) { + c.log.Debugf("linux interface %s resync: configuration changed, interface will be modified", linkName) + if err := c.ModifyLinuxInterface(linkDataPair.nbIfData, linuxIf); err != nil { + errs = append(errs, errors.Errorf("linux interface %s resync error: %v", linkName, err)) } } else { - plugin.log.Debugf("RESYNC Linux interface %s: data was not changed", linkName) + c.log.Debugf("linux interface %s resync: data unchanged", linkName) } } // Register all interfaces in default namespace which were not already registered linkList, err := netlink.LinkList() if err != nil { - plugin.log.Errorf("Failed to read linux interfaces: %v", err) - errs = append(errs, err) + errs = append(errs, errors.Errorf("linux interface resync error: failed to read interfaces: %v", err)) } for _, link := range linkList { if link.Attrs() == nil { continue } attrs := link.Attrs() - _, _, found := plugin.ifIndexes.LookupIdx(attrs.Name) + _, _, found := c.ifIndexes.LookupIdx(attrs.Name) if !found { - // If interface is veth, do not register it. Agent does not know where the other - // end is or if it even exists. - if link.Type() == veth { - continue - } // Register interface with name (other parameters can be read if needed) - plugin.ifIndexes.RegisterName(attrs.Name, plugin.ifIdxSeq, &ifaceidx.IndexedLinuxInterface{ + c.ifIndexes.RegisterName(attrs.Name, c.ifIdxSeq, &ifaceidx.IndexedLinuxInterface{ Index: uint32(attrs.Index), Data: &interfaces.LinuxInterfaces_Interface{ Name: attrs.Name, HostIfName: attrs.Name, }, }) - plugin.ifIdxSeq++ + c.ifIdxSeq++ + } + } + + if len(errs) > 0 { + for _, e := range errs { + c.log.Error(e) } + return errors.Errorf("%v resync errors encountered", len(errs)) } - plugin.log.WithField("cfg", plugin).Debug("RESYNC Interface end. ", errs) + c.log.Info("Linux interface resync done") - return + return nil } // Reconstruct common interface configuration from netlink.Link data -func (plugin *LinuxInterfaceConfigurator) reconstructIfConfig(linuxIf netlink.Link, ns *interfaces.LinuxInterfaces_Interface_Namespace, name string) *interfaces.LinuxInterfaces_Interface { +func (c *LinuxInterfaceConfigurator) reconstructIfConfig(linuxIf netlink.Link, ns *interfaces.LinuxInterfaces_Interface_Namespace, name string) (*interfaces.LinuxInterfaces_Interface, error) { linuxIfAttr := linuxIf.Attrs() + + // Prepare list of addresses + addresses, err := c.getLinuxAddresses(linuxIf, ns) + if err != nil { + return nil, err + } + return &interfaces.LinuxInterfaces_Interface{ Name: name, Type: func(ifType string) interfaces.LinuxInterfaces_InterfaceType { @@ -174,7 +181,7 @@ func (plugin *LinuxInterfaceConfigurator) reconstructIfConfig(linuxIf netlink.Li } return true }(linuxIfAttr.OperState), - IpAddresses: plugin.getLinuxInterfaces(linuxIf, ns), + IpAddresses: addresses, PhysAddress: func(hwAddr net.HardwareAddr) (mac string) { if hwAddr != nil { mac = hwAddr.String() @@ -183,31 +190,30 @@ func (plugin *LinuxInterfaceConfigurator) reconstructIfConfig(linuxIf netlink.Li }(linuxIfAttr.HardwareAddr), Mtu: uint32(linuxIfAttr.MTU), HostIfName: linuxIfAttr.Name, - } + }, nil } // Reads linux interface IP addresses -func (plugin *LinuxInterfaceConfigurator) getLinuxInterfaces(linuxIf netlink.Link, ns *interfaces.LinuxInterfaces_Interface_Namespace) (addresses []string) { +func (c *LinuxInterfaceConfigurator) getLinuxAddresses(linuxIf netlink.Link, ns *interfaces.LinuxInterfaces_Interface_Namespace) (addresses []string, err error) { // Move to proper namespace if ns != nil { - if !plugin.nsHandler.IsNamespaceAvailable(ns) { - plugin.log.Errorf("RESYNC Linux interface %s: namespace is not available", linuxIf.Attrs().Name) - return + if !c.nsHandler.IsNamespaceAvailable(ns) { + return nil, errors.Errorf("linux interface %s resync error: namespace is not available", + linuxIf.Attrs().Name) } // Switch to namespace - revertNs, err := plugin.nsHandler.SwitchToNamespace(nsplugin.NewNamespaceMgmtCtx(), ns) + revertNs, err := c.nsHandler.SwitchToNamespace(nsplugin.NewNamespaceMgmtCtx(), ns) if err != nil { - plugin.log.Errorf("RESYNC Linux interface %s: failed to switch to namespace %s: %v", - linuxIf.Attrs().Name, ns.Name, err) - return + return nil, errors.Errorf("linux interface %s resync error: failed to switch to namespace", + linuxIf.Attrs().Name) } defer revertNs() } addressList, err := netlink.AddrList(linuxIf, netlink.FAMILY_ALL) if err != nil { - plugin.log.Errorf("failed to read linux interface %s address list: %v", linuxIf.Attrs().Name, err) - return + return nil, errors.Errorf("linux interface %s resync error: failed to read IP addresses", + linuxIf.Attrs().Name) } for _, address := range addressList { @@ -216,22 +222,21 @@ func (plugin *LinuxInterfaceConfigurator) getLinuxInterfaces(linuxIf netlink.Lin addresses = append(addresses, addrStr) } - return addresses + return addresses, nil } // Compare interface fields in order to find differences. -func (plugin *LinuxInterfaceConfigurator) isLinuxIfModified(nbIf, linuxIf *interfaces.LinuxInterfaces_Interface) bool { - plugin.log.Debugf("Linux interface RESYNC comparison started for interface %s", nbIf.Name) - +func (c *LinuxInterfaceConfigurator) isLinuxIfModified(nbIf, linuxIf *interfaces.LinuxInterfaces_Interface) bool { + c.log.Debugf("Linux interface RESYNC comparison started for interface %s", nbIf.Name) // Type if nbIf.Type != linuxIf.Type { - plugin.log.Debugf("Linux interface RESYNC comparison: type changed (NB: %v, Linux: %v)", + c.log.Debugf("Linux interface RESYNC comparison: type changed (NB: %v, Linux: %v)", nbIf.Type, linuxIf.Type) return true } // Enabled if nbIf.Enabled != linuxIf.Enabled { - plugin.log.Debugf("Linux interface RESYNC comparison: enabled value changed (NB: %t, Linux: %t)", + c.log.Debugf("Linux interface RESYNC comparison: enabled value changed (NB: %t, Linux: %t)", nbIf.Enabled, linuxIf.Enabled) return true } @@ -247,7 +252,7 @@ func (plugin *LinuxInterfaceConfigurator) isLinuxIfModified(nbIf, linuxIf *inter linuxIf.IpAddresses = linuxIf.IpAddresses[:newIPIdx] // IP address count if len(nbIf.IpAddresses) != len(linuxIf.IpAddresses) { - plugin.log.Debugf("Linux interface RESYNC comparison: ip address count does not match (NB: %d, Linux: %d)", + c.log.Debugf("Linux interface RESYNC comparison: ip address count does not match (NB: %d, Linux: %d)", len(nbIf.IpAddresses), len(linuxIf.IpAddresses)) return true } @@ -257,12 +262,12 @@ func (plugin *LinuxInterfaceConfigurator) isLinuxIfModified(nbIf, linuxIf *inter for _, linuxIP := range linuxIf.IpAddresses { pNbIP, nbIPNet, err := net.ParseCIDR(nbIP) if err != nil { - plugin.log.Error(err) + c.log.Error(err) continue } pVppIP, vppIPNet, err := net.ParseCIDR(linuxIP) if err != nil { - plugin.log.Error(err) + c.log.Error(err) continue } if nbIPNet.Mask.String() == vppIPNet.Mask.String() && bytes.Compare(pNbIP, pVppIP) == 0 { @@ -271,33 +276,33 @@ func (plugin *LinuxInterfaceConfigurator) isLinuxIfModified(nbIf, linuxIf *inter } } if !ipFound { - plugin.log.Debugf("Interface RESYNC comparison: linux interface %v does not contain IP %s", nbIf.Name, nbIP) + c.log.Debugf("Interface RESYNC comparison: linux interface %v does not contain IP %s", nbIf.Name, nbIP) return true } } // Physical address if nbIf.PhysAddress != "" && nbIf.PhysAddress != linuxIf.PhysAddress { - plugin.log.Debugf("Interface RESYNC comparison: MAC address changed (NB: %s, Linux: %s)", + c.log.Debugf("Interface RESYNC comparison: MAC address changed (NB: %s, Linux: %s)", nbIf.PhysAddress, linuxIf.PhysAddress) return true } // MTU (if NB value is set) if nbIf.Mtu != 0 && nbIf.Mtu != linuxIf.Mtu { - plugin.log.Debugf("Interface RESYNC comparison: MTU changed (NB: %d, Linux: %d)", + c.log.Debugf("Interface RESYNC comparison: MTU changed (NB: %d, Linux: %d)", nbIf.Mtu, linuxIf.Mtu) return true } switch nbIf.Type { case interfaces.LinuxInterfaces_VETH: if nbIf.Veth == nil && linuxIf.Veth != nil || nbIf.Veth != nil && linuxIf.Veth == nil { - plugin.log.Debugf("Interface RESYNC comparison: VETH setup changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: VETH setup changed (NB: %v, VPP: %v)", nbIf.Veth, linuxIf.Veth) return true } if nbIf.Veth != nil && linuxIf.Veth != nil { // VETH peer name if nbIf.Veth.PeerIfName != linuxIf.Veth.PeerIfName { - plugin.log.Debugf("Interface RESYNC comparison: VETH peer name changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: VETH peer name changed (NB: %s, VPP: %s)", nbIf.Veth.PeerIfName, linuxIf.Veth.PeerIfName) return true } @@ -305,7 +310,7 @@ func (plugin *LinuxInterfaceConfigurator) isLinuxIfModified(nbIf, linuxIf *inter case interfaces.LinuxInterfaces_AUTO_TAP: // Host name for TAP if nbIf.HostIfName != linuxIf.HostIfName { - plugin.log.Debugf("Interface RESYNC comparison: TAP host name changed (NB: %d, Linux: %d)", + c.log.Debugf("Interface RESYNC comparison: TAP host name changed (NB: %d, Linux: %d)", nbIf.HostIfName, linuxIf.HostIfName) return true } @@ -316,21 +321,19 @@ func (plugin *LinuxInterfaceConfigurator) isLinuxIfModified(nbIf, linuxIf *inter } // Looks for linux interface. Returns net.Link object if found -func (plugin *LinuxInterfaceConfigurator) findLinuxInterface(nbIf *interfaces.LinuxInterfaces_Interface, nsMgmtCtx *nsplugin.NamespaceMgmtCtx) (netlink.Link, error) { - plugin.log.Debugf("Looking for Linux interface %v", nbIf.HostIfName) - +func (c *LinuxInterfaceConfigurator) findLinuxInterface(nbIf *interfaces.LinuxInterfaces_Interface, nsMgmtCtx *nsplugin.NamespaceMgmtCtx) (netlink.Link, error) { // Move to proper namespace if nbIf.Namespace != nil { - if !plugin.nsHandler.IsNamespaceAvailable(nbIf.Namespace) { + if !c.nsHandler.IsNamespaceAvailable(nbIf.Namespace) { // Not and error - plugin.log.Debugf("Interface %s is not ready to be configured, namespace %s is not available", + c.log.Debugf("Interface %s is not ready to be configured, namespace %s is not available", nbIf.Name, nbIf.Namespace.Name) return nil, nil } // Switch to namespace - revertNs, err := plugin.nsHandler.SwitchToNamespace(nsMgmtCtx, nbIf.Namespace) + revertNs, err := c.nsHandler.SwitchToNamespace(nsMgmtCtx, nbIf.Namespace) if err != nil { - return nil, fmt.Errorf("RESYNC Linux interface %s: failed to switch to namespace %s: %v", + return nil, errors.Errorf("linux interface %s resync: failed to switch to namespace %s: %v", nbIf.HostIfName, nbIf.Namespace.Name, err) } defer revertNs() @@ -343,36 +346,37 @@ func (plugin *LinuxInterfaceConfigurator) findLinuxInterface(nbIf *interfaces.Li // Interface was not found return nil, nil } - return nil, fmt.Errorf("RESYNC Linux interface %s: %v", nbIf.HostIfName, err) + return nil, errors.Errorf("linux interface %s resync: %v", nbIf.HostIfName, err) } if linkIf == nil || linkIf.Attrs() == nil { - return nil, fmt.Errorf("RESYNC Linux interface %v: link is nil", nbIf.HostIfName) + return nil, errors.Errorf("linux interface %s resync: link is nil", nbIf.HostIfName) } // Add interface to cache - plugin.registerLinuxInterface(uint32(linkIf.Attrs().Index), nbIf) + c.registerLinuxInterface(uint32(linkIf.Attrs().Index), nbIf) return linkIf, nil } // Register linux interface -func (plugin *LinuxInterfaceConfigurator) registerLinuxInterface(linuxIfIdx uint32, nbIf *interfaces.LinuxInterfaces_Interface) { +func (c *LinuxInterfaceConfigurator) registerLinuxInterface(linuxIfIdx uint32, nbIf *interfaces.LinuxInterfaces_Interface) { // Register interface with its name - plugin.ifIndexes.RegisterName(nbIf.Name, plugin.ifIdxSeq, &ifaceidx.IndexedLinuxInterface{ + c.ifIndexes.RegisterName(nbIf.Name, c.ifIdxSeq, &ifaceidx.IndexedLinuxInterface{ Index: linuxIfIdx, Data: nbIf, }) - plugin.ifIdxSeq++ + c.ifIdxSeq++ + c.log.Debugf("linux interface %s registered", nbIf.Name) } // Add interface to cache -func (plugin *LinuxInterfaceConfigurator) addInterfaceToCache(nbIf *interfaces.LinuxInterfaces_Interface) *LinuxInterfaceConfig { +func (c *LinuxInterfaceConfigurator) addInterfaceToCache(nbIf *interfaces.LinuxInterfaces_Interface) *LinuxInterfaceConfig { switch nbIf.Type { case interfaces.LinuxInterfaces_AUTO_TAP: - return plugin.addToCache(nbIf, nil) + return c.addToCache(nbIf, nil) case interfaces.LinuxInterfaces_VETH: - peerConfig := plugin.getInterfaceConfig(nbIf.Veth.PeerIfName) - return plugin.addToCache(nbIf, peerConfig) + peerConfig := c.getInterfaceConfig(nbIf.Veth.PeerIfName) + return c.addToCache(nbIf, peerConfig) } return nil } diff --git a/plugins/linux/ifplugin/export_test.go b/plugins/linux/ifplugin/export_test.go new file mode 100644 index 0000000000..8d335c6815 --- /dev/null +++ b/plugins/linux/ifplugin/export_test.go @@ -0,0 +1,27 @@ +// Copyright (c) 2018 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 ifplugin + +import ( + "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" + "github.com/ligato/vpp-agent/plugins/linux/nsplugin" +) + +// Export for testing + +func SetInterfaceNamespace(ifCfg *LinuxInterfaceConfigurator, ctx *nsplugin.NamespaceMgmtCtx, ifName string, + namespace *interfaces.LinuxInterfaces_Interface_Namespace) error { + return ifCfg.setInterfaceNamespace(ctx, ifName, namespace) +} diff --git a/plugins/linux/ifplugin/interface_config.go b/plugins/linux/ifplugin/interface_config.go index 820934b452..4268bb85bf 100644 --- a/plugins/linux/ifplugin/interface_config.go +++ b/plugins/linux/ifplugin/interface_config.go @@ -12,31 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/interfaces --gogo_out=../model/interfaces ../model/interfaces/interfaces.proto - package ifplugin import ( + "bytes" "context" - "fmt" "net" "sync" - "github.com/ligato/vpp-agent/plugins/linux/nsplugin" - "github.com/vishvananda/netlink" - - "bytes" - + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/linuxcalls" "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" + "github.com/ligato/vpp-agent/plugins/linux/nsplugin" vppIf "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" + "github.com/vishvananda/netlink" ) +// LinkNotFoundErr represents netlink error return value from 'GetLinkByName' if interface does not exist +const LinkNotFoundErr = "Link not found" + // LinuxInterfaceConfig is used to cache the configuration of Linux interfaces. type LinuxInterfaceConfig struct { config *interfaces.LinuxInterfaces_Interface @@ -54,13 +52,17 @@ type LinuxInterfaceConfigurator struct { // In-memory mappings ifIndexes ifaceidx.LinuxIfIndexRW ifIdxSeq uint32 - ifByName map[string]*LinuxInterfaceConfig // interface name -> interface configuration - ifsByMs map[string][]*LinuxInterfaceConfig // microservice label -> list of interfaces attached to this microservice + + // mapMu protects ifByName and ifsByMs maps + mapMu sync.RWMutex + ifByName map[string]*LinuxInterfaceConfig // interface name -> interface configuration + ifsByMs map[string][]*LinuxInterfaceConfig // microservice label -> list of interfaces attached to this microservice ifCachedConfigs ifaceidx.LinuxIfIndexRW pIfCachedConfigSeq uint32 // Channels + ifNotif chan *LinuxInterfaceStateNotification ifMsNotif chan *nsplugin.MicroserviceEvent // Go routine management @@ -70,113 +72,118 @@ type LinuxInterfaceConfigurator struct { wg sync.WaitGroup // Wait group allows to wait until all goroutines of the plugin have finished. // Linux namespace/calls handler - ifHandler linuxcalls.NetlinkAPI - nsHandler nsplugin.NamespaceAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch + ifHandler linuxcalls.NetlinkAPI + nsHandler nsplugin.NamespaceAPI + sysHandler nsplugin.SystemAPI } // Init linux plugin and start go routines. -func (plugin *LinuxInterfaceConfigurator) Init(logging logging.PluginLogger, ifHandler linuxcalls.NetlinkAPI, nsHandler nsplugin.NamespaceAPI, - ifIndexes ifaceidx.LinuxIfIndexRW, ifNotif chan *nsplugin.MicroserviceEvent, stopwatch *measure.Stopwatch) (err error) { +func (c *LinuxInterfaceConfigurator) Init(logging logging.PluginLogger, ifHandler linuxcalls.NetlinkAPI, nsHandler nsplugin.NamespaceAPI, + sysHandler nsplugin.SystemAPI, ifIndexes ifaceidx.LinuxIfIndexRW, ifMsNotif chan *nsplugin.MicroserviceEvent, + ifNotif chan *LinuxInterfaceStateNotification) (err error) { // Logger - plugin.log = logging.NewLogger("-if-conf") - plugin.log.Debug("Initializing Linux Interface configurator") + c.log = logging.NewLogger("if-conf") // Mappings - plugin.ifIndexes = ifIndexes - plugin.ifByName = make(map[string]*LinuxInterfaceConfig) - plugin.ifsByMs = make(map[string][]*LinuxInterfaceConfig) - plugin.ifIdxSeq = 1 - plugin.ifCachedConfigs = ifaceidx.NewLinuxIfIndex(nametoidx.NewNameToIdx(plugin.log, "linux_if_cache", nil)) - plugin.pIfCachedConfigSeq = 1 + c.ifIndexes = ifIndexes + c.ifByName = make(map[string]*LinuxInterfaceConfig) + c.ifsByMs = make(map[string][]*LinuxInterfaceConfig) + c.ifIdxSeq = 1 + c.ifCachedConfigs = ifaceidx.NewLinuxIfIndex(nametoidx.NewNameToIdx(c.log, "linux_if_cache", nil)) + c.pIfCachedConfigSeq = 1 - // Init channel - plugin.ifMsNotif = ifNotif + // Set channels + c.ifNotif = ifNotif + c.ifMsNotif = ifMsNotif - plugin.ctx, plugin.cancel = context.WithCancel(context.Background()) + c.ctx, c.cancel = context.WithCancel(context.Background()) // Interface and namespace handlers - plugin.ifHandler = ifHandler - plugin.nsHandler = nsHandler + c.ifHandler = ifHandler + c.nsHandler = nsHandler + c.sysHandler = sysHandler - // Configurator-wide stopwatch instance - plugin.stopwatch = stopwatch + // Start watching on linux and microservice events + go c.watchLinuxStateUpdater() + go c.watchMicroservices(c.ctx) - // Start watching on microservice events - go plugin.watchMicroservices(plugin.ctx) + c.log.Info("Linux interface configurator initialized") return err } // Close does nothing for linux interface configurator. State and notification channels are closed in linux plugin. -func (plugin *LinuxInterfaceConfigurator) Close() error { +func (c *LinuxInterfaceConfigurator) Close() error { return nil } // GetLinuxInterfaceIndexes returns in-memory mapping of linux inerfaces -func (plugin *LinuxInterfaceConfigurator) GetLinuxInterfaceIndexes() ifaceidx.LinuxIfIndex { - return plugin.ifIndexes +func (c *LinuxInterfaceConfigurator) GetLinuxInterfaceIndexes() ifaceidx.LinuxIfIndex { + return c.ifIndexes } // GetInterfaceByNameCache returns cache of interface <-> config entries -func (plugin *LinuxInterfaceConfigurator) GetInterfaceByNameCache() map[string]*LinuxInterfaceConfig { - return plugin.ifByName +func (c *LinuxInterfaceConfigurator) GetInterfaceByNameCache() map[string]*LinuxInterfaceConfig { + return c.ifByName } // GetInterfaceByMsCache returns cache of microservice <-> interface list -func (plugin *LinuxInterfaceConfigurator) GetInterfaceByMsCache() map[string][]*LinuxInterfaceConfig { - return plugin.ifsByMs +func (c *LinuxInterfaceConfigurator) GetInterfaceByMsCache() map[string][]*LinuxInterfaceConfig { + return c.ifsByMs } -// GetCachedLinuxIfIndexes gives access to mapping of not configurated interface indexes. -func (plugin *LinuxInterfaceConfigurator) GetCachedLinuxIfIndexes() ifaceidx.LinuxIfIndex { - return plugin.ifCachedConfigs +// GetCachedLinuxIfIndexes gives access to mapping of not configured interface indexes. +func (c *LinuxInterfaceConfigurator) GetCachedLinuxIfIndexes() ifaceidx.LinuxIfIndex { + return c.ifCachedConfigs } // ConfigureLinuxInterface reacts to a new northbound Linux interface config by creating and configuring // the interface in the host network stack through Netlink API. -func (plugin *LinuxInterfaceConfigurator) ConfigureLinuxInterface(linuxIf *interfaces.LinuxInterfaces_Interface) error { - plugin.cfgLock.Lock() - defer plugin.cfgLock.Unlock() +func (c *LinuxInterfaceConfigurator) ConfigureLinuxInterface(linuxIf *interfaces.LinuxInterfaces_Interface) error { + c.cfgLock.Lock() + defer c.cfgLock.Unlock() - plugin.handleOptionalHostIfName(linuxIf) - plugin.log.Infof("Configuring new Linux interface %v", linuxIf.HostIfName) + c.handleOptionalHostIfName(linuxIf) // Linux interface type resolution switch linuxIf.Type { case interfaces.LinuxInterfaces_VETH: // Get peer interface config if exists and cache the original configuration with peer if linuxIf.Veth == nil { - return fmt.Errorf("VETH interface %v has no peer defined", linuxIf.HostIfName) + return errors.Errorf("VETH interface %v has no peer defined", linuxIf.HostIfName) } - peerConfig := plugin.getInterfaceConfig(linuxIf.Veth.PeerIfName) - ifConfig := plugin.addToCache(linuxIf, peerConfig) + peerConfig := c.getInterfaceConfig(linuxIf.Veth.PeerIfName) + ifConfig := c.addToCache(linuxIf, peerConfig) - return plugin.configureVethInterface(ifConfig, peerConfig) + if err := c.configureVethInterface(ifConfig, peerConfig); err != nil { + return err + } case interfaces.LinuxInterfaces_AUTO_TAP: + hostIfName := linuxIf.HostIfName if linuxIf.Tap != nil && linuxIf.Tap.TempIfName != "" { - return plugin.configureTapInterface(linuxIf.Tap.TempIfName, linuxIf) + hostIfName = linuxIf.Tap.TempIfName + } + if err := c.configureTapInterface(hostIfName, linuxIf); err != nil { + return err } - - return plugin.configureTapInterface(linuxIf.HostIfName, linuxIf) - default: - return fmt.Errorf("unknown linux interface type: %v", linuxIf.Type) + return errors.Errorf("unknown linux interface type: %v", linuxIf.Type) } + + c.log.Infof("Linux interface %s with hostIfName %s configured", linuxIf.Name, linuxIf.HostIfName) + + return nil } // ModifyLinuxInterface applies changes in the NB configuration of a Linux interface into the host network stack // through Netlink API. -func (plugin *LinuxInterfaceConfigurator) ModifyLinuxInterface(newLinuxIf, oldLinuxIf *interfaces.LinuxInterfaces_Interface) (err error) { +func (c *LinuxInterfaceConfigurator) ModifyLinuxInterface(newLinuxIf, oldLinuxIf *interfaces.LinuxInterfaces_Interface) (err error) { // If host names are not defined, name == host name - plugin.handleOptionalHostIfName(newLinuxIf) - plugin.handleOptionalHostIfName(oldLinuxIf) - plugin.log.Infof("Modifying Linux interface %v", newLinuxIf.HostIfName) + c.handleOptionalHostIfName(newLinuxIf) + c.handleOptionalHostIfName(oldLinuxIf) if oldLinuxIf.Type != newLinuxIf.Type { - return fmt.Errorf("%v: linux interface type change not allowed", newLinuxIf.Name) + return errors.Errorf("modify linux interface %s: type change not allowed", newLinuxIf.Name) } // Get old and new peer/host interfaces (peers for VETH, host for TAP) @@ -193,424 +200,381 @@ func (plugin *LinuxInterfaceConfigurator) ModifyLinuxInterface(newLinuxIf, oldLi } // Prepare namespace objects of new and old interfaces - newIfaceNs := plugin.nsHandler.IfNsToGeneric(newLinuxIf.Namespace) - oldIfaceNs := plugin.nsHandler.IfNsToGeneric(oldLinuxIf.Namespace) + newIfaceNs := c.nsHandler.IfNsToGeneric(newLinuxIf.Namespace) + oldIfaceNs := c.nsHandler.IfNsToGeneric(oldLinuxIf.Namespace) if newPeer != oldPeer || newLinuxIf.HostIfName != oldLinuxIf.HostIfName || newIfaceNs.CompareNamespaces(oldIfaceNs) != 0 { // Change of the peer interface (VETH) or host (TAP) or the namespace requires to create the interface from the scratch. - err := plugin.DeleteLinuxInterface(oldLinuxIf) + err := c.DeleteLinuxInterface(oldLinuxIf) if err == nil { - err = plugin.ConfigureLinuxInterface(newLinuxIf) + err = c.ConfigureLinuxInterface(newLinuxIf) } return err } - plugin.cfgLock.Lock() - defer plugin.cfgLock.Unlock() + c.cfgLock.Lock() + defer c.cfgLock.Unlock() // Update the cached configuration. - plugin.removeFromCache(oldLinuxIf) - peer := plugin.getInterfaceConfig(newPeer) - plugin.addToCache(newLinuxIf, peer) + c.removeFromCache(oldLinuxIf) + peer := c.getInterfaceConfig(newPeer) + c.addToCache(newLinuxIf, peer) // Verify required namespace - if !plugin.nsHandler.IsNamespaceAvailable(newLinuxIf.Namespace) { - plugin.log.Errorf("unable to configure linux interface %v: interface namespace is not available", - newLinuxIf.HostIfName) - return nil + if !c.nsHandler.IsNamespaceAvailable(newLinuxIf.Namespace) { + return errors.Errorf("failed to modify linux interface %s: new namespace is not available", + newLinuxIf.Name) } - // Validate configuration/namespace according to interface type + // Validate peer for veth if newLinuxIf.Type == interfaces.LinuxInterfaces_VETH { if peer == nil { // Interface doesn't actually exist physically. - plugin.log.Infof("cannot configure linux interface %v: peer interface %v is not configured yet", + return errors.Errorf("unable to modify linux veth interface %v: peer interface %v is not configured yet", newLinuxIf.HostIfName, newPeer) - return nil } - if !plugin.nsHandler.IsNamespaceAvailable(oldLinuxIf.Namespace) { - plugin.log.Warnf("unable to modify linux interface %v: peer interface namespace is not available", + if !c.nsHandler.IsNamespaceAvailable(oldLinuxIf.Namespace) { + return errors.Errorf("unable to modify linux veth interface %v: peer interface namespace is not available", oldLinuxIf.HostIfName) - return nil } - if !plugin.nsHandler.IsNamespaceAvailable(newLinuxIf.Namespace) { - plugin.log.Warnf("unable to modify linux interface %v: interface namespace is not available", - newLinuxIf.HostIfName) - return nil - } - } else if newLinuxIf.Type == interfaces.LinuxInterfaces_AUTO_TAP { - if !plugin.nsHandler.IsNamespaceAvailable(newLinuxIf.Namespace) { - // Interface doesn't actually exist physically. - plugin.log.WithField("ifName", newLinuxIf.Name).Debug("Linux interface is not ready to be re-configured") - return nil - } - } else { - plugin.log.Warnf("Unknown interface type %v", newLinuxIf.Type) - - return nil } // The namespace was not changed so interface can be reconfigured nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - return plugin.modifyLinuxInterface(nsMgmtCtx, oldLinuxIf, newLinuxIf) + if err := c.modifyLinuxInterface(nsMgmtCtx, oldLinuxIf, newLinuxIf); err != nil { + return err + } + + c.log.Infof("Linux interface %s modified", newLinuxIf.Name) + return } // DeleteLinuxInterface reacts to a removed NB configuration of a Linux interface. -func (plugin *LinuxInterfaceConfigurator) DeleteLinuxInterface(linuxIf *interfaces.LinuxInterfaces_Interface) error { - plugin.cfgLock.Lock() - defer plugin.cfgLock.Unlock() +func (c *LinuxInterfaceConfigurator) DeleteLinuxInterface(linuxIf *interfaces.LinuxInterfaces_Interface) error { + c.cfgLock.Lock() + defer c.cfgLock.Unlock() - plugin.handleOptionalHostIfName(linuxIf) - plugin.log.Infof("Removing Linux interface %v", linuxIf.HostIfName) + c.handleOptionalHostIfName(linuxIf) - oldConfig := plugin.removeFromCache(linuxIf) + oldConfig := c.removeFromCache(linuxIf) var peerConfig *LinuxInterfaceConfig if oldConfig != nil { peerConfig = oldConfig.peer } if linuxIf.Type == interfaces.LinuxInterfaces_AUTO_TAP { - if _, _, exists := plugin.ifCachedConfigs.LookupIdx(linuxIf.HostIfName); exists { + if _, _, exists := c.ifCachedConfigs.LookupIdx(linuxIf.HostIfName); exists { // Unregister TAP from the in-memory map - plugin.log.Infof("Removing Linux Tap interface %v from cache", linuxIf.HostIfName) - plugin.ifCachedConfigs.UnregisterName(linuxIf.HostIfName) + c.ifCachedConfigs.UnregisterName(linuxIf.HostIfName) + c.log.Debugf("tap linux interface removed from cache %s", linuxIf.Name) return nil } - return plugin.deleteTapInterface(oldConfig) + if err := c.deleteTapInterface(oldConfig); err != nil { + return err + } } else if linuxIf.Type == interfaces.LinuxInterfaces_VETH { - return plugin.deleteVethInterface(oldConfig, peerConfig) + if err := c.deleteVethInterface(oldConfig, peerConfig); err != nil { + return err + } } - plugin.log.Warnf("Unknown type of interface: %v", linuxIf.Type) + + c.log.Infof("Linux interface %s removed", linuxIf.HostIfName) + return nil } // Validate, create and configure VETH type linux interface -func (plugin *LinuxInterfaceConfigurator) configureVethInterface(ifConfig, peerConfig *LinuxInterfaceConfig) error { - plugin.log.WithFields(logging.Fields{"name": ifConfig.config.Name, "hostName": ifConfig.config.HostIfName, - "peer": ifConfig.config.Veth.PeerIfName}).Debug("Configuring new Veth interface") +func (c *LinuxInterfaceConfigurator) configureVethInterface(ifConfig, peerConfig *LinuxInterfaceConfig) error { // Create VETH after both end's configs and target namespaces are available. if peerConfig == nil { - plugin.log.Infof("cannot configure linux interface %v: peer interface %v is not configured yet", + c.log.Infof("cannot configure linux interface %s: peer interface %s is not configured yet", ifConfig.config.HostIfName, ifConfig.config.Veth.PeerIfName) return nil } - if !plugin.nsHandler.IsNamespaceAvailable(ifConfig.config.Namespace) { - plugin.log.Warnf("unable to configure linux interface %v: interface namespace is not available", - ifConfig.config.HostIfName) - return nil + if !c.nsHandler.IsNamespaceAvailable(ifConfig.config.Namespace) { + return errors.Errorf("failed to configure veth interface %s: namespace %q is not available", + ifConfig.config.Name, ifConfig.config.Namespace) } - if !plugin.nsHandler.IsNamespaceAvailable(peerConfig.config.Namespace) { - plugin.log.Warnf("unable to configure linux interface %v: peer namespace is not available", - ifConfig.config.HostIfName) - return nil + if !c.nsHandler.IsNamespaceAvailable(peerConfig.config.Namespace) { + return errors.Errorf("failed to configure veth interface %s: peer namespace %q is not available", + ifConfig.config.Name, peerConfig.config.Namespace) } nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() // Prepare generic veth config namespace object - vethNs := plugin.nsHandler.IfNsToGeneric(plugin.nsHandler.GetConfigNamespace()) + vethNs := c.nsHandler.IfNsToGeneric(c.nsHandler.GetConfigNamespace()) // Switch to veth cfg namespace - revertNs, err := plugin.nsHandler.SwitchNamespace(vethNs, nsMgmtCtx) + revertNs, err := c.nsHandler.SwitchNamespace(vethNs, nsMgmtCtx) if err != nil { - return err + return errors.Errorf("failed to configure veth interface %s, error switching namespaces: %v", + ifConfig.config.Name, err) } defer revertNs() - if err := plugin.addVethInterfacePair(nsMgmtCtx, ifConfig.config, peerConfig.config); err != nil { + if err := c.addVethInterfacePair(nsMgmtCtx, ifConfig.config, peerConfig.config); err != nil { return err } - if err := plugin.configureLinuxInterface(nsMgmtCtx, ifConfig.config); err != nil { + if err := c.configureLinuxInterface(nsMgmtCtx, ifConfig.config); err != nil { return err } - if err := plugin.configureLinuxInterface(nsMgmtCtx, peerConfig.config); err != nil { + if err := c.configureLinuxInterface(nsMgmtCtx, peerConfig.config); err != nil { return err } - plugin.log.Infof("Linux interface %v with hostIfName %v configured", ifConfig.config.Name, ifConfig.config.HostIfName) - return nil } // Validate and apply linux TAP configuration to the interface. The interface is not created here, it is added // to the default namespace when it's VPP end is configured -func (plugin *LinuxInterfaceConfigurator) configureTapInterface(hostIfName string, linuxIf *interfaces.LinuxInterfaces_Interface) error { +func (c *LinuxInterfaceConfigurator) configureTapInterface(hostIfName string, linuxIf *interfaces.LinuxInterfaces_Interface) error { // TAP (auto) interface looks for existing interface with the same host name or temp name (cached without peer) var ifConfig *LinuxInterfaceConfig - _, ifConfigData, exists := plugin.ifCachedConfigs.LookupIdx(hostIfName) + _, ifConfigData, exists := c.ifCachedConfigs.LookupIdx(hostIfName) if exists { - ifConfig = plugin.addToCache(ifConfigData.Data, nil) + ifConfig = c.addToCache(ifConfigData.Data, nil) ifConfig.config = ifConfigData.Data - plugin.log.Infof("Using existing Linux Tap interface %v configuration entry %v", hostIfName, ifConfig.config) + c.log.Debugf("linux tap interface %s exists, can be configured", hostIfName) } else { if linuxIf != nil { - ifConfig = plugin.addToCache(linuxIf, nil) - plugin.ifCachedConfigs.RegisterName(hostIfName, plugin.pIfCachedConfigSeq, &ifaceidx.IndexedLinuxInterface{ - Index: plugin.pIfCachedConfigSeq, + ifConfig = c.addToCache(linuxIf, nil) + c.ifCachedConfigs.RegisterName(hostIfName, c.pIfCachedConfigSeq, &ifaceidx.IndexedLinuxInterface{ + Index: c.pIfCachedConfigSeq, Data: ifConfig.config, }) - plugin.pIfCachedConfigSeq++ - plugin.log.Infof("Creating new Linux Tap interface %v configuration entry %v", hostIfName, ifConfig.config) + c.pIfCachedConfigSeq++ + c.log.Debugf("creating new Linux Tap interface %v configuration entry", hostIfName) } else { - plugin.log.Infof("There is no Linux Tap configuration entry for interface %v", hostIfName) + c.log.Infof("there is no linux tap configuration entry for interface %v", hostIfName) return nil } } - plugin.log.WithFields(logging.Fields{"name": ifConfig.config.Name, - "hostName": ifConfig.config.HostIfName}).Debug("Applying new Linux TAP interface configuration") - // Tap interfaces can be processed directly using config and also via linux interface events. This check // should prevent to process the same interface multiple times. - _, _, exists = plugin.ifIndexes.LookupIdx(ifConfig.config.Name) + _, _, exists = c.ifIndexes.LookupIdx(ifConfig.config.Name) if exists { - plugin.log.Debugf("TAP interface %v already processed", ifConfig.config.Name) + c.log.Debugf("TAP interface %s already processed", ifConfig.config.Name) return nil } - // Search default namespace for appropriate interface - linuxIfs, err := plugin.ifHandler.GetLinkList() - if err != nil { - return fmt.Errorf("failed to read linux interfaces: %v", err) - } - - nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - - // Verify availability of namespace from configuration - if !plugin.nsHandler.IsNamespaceAvailable(ifConfig.config.Namespace) { - plugin.log.Errorf("unable to apply linux TAP configuration %v: destination namespace is not available", - ifConfig.config.Name, ifConfig.config.HostIfName) - return nil - } - - // Check if TAP temporary name is defined + // At this point, agent knows that VPP TAP interface exists, so let's find out its linux side. First, check + // if temporary name is defined if ifConfig.config.Tap == nil || ifConfig.config.Tap.TempIfName == "" { - plugin.log.Debugf("Tap interface %v temporary name not defined", ifConfig.config.HostIfName) // In such a case, set temp name as host (look for interface named as host name) ifConfig.config.Tap = &interfaces.LinuxInterfaces_Interface_Tap{ TempIfName: ifConfig.config.HostIfName, } } - - // Try to find temp interface in default namespace. - var found bool - for _, linuxIf := range linuxIfs { - if ifConfig.config.Tap.TempIfName == linuxIf.Attrs().Name { - if linuxIf.Type() == tap { - found = true - break - } - plugin.log.Debugf("Linux TAP config %v found linux interface %v, but it is not the TAP interface type", - ifConfig.config.Name, ifConfig.config.HostIfName) - } - } - if !found { - plugin.log.Debugf("Linux TAP config %v did not found the linux interface with name %v", ifConfig.config.Name, + // Now look for interface + _, err := c.ifHandler.GetLinkByName(ifConfig.config.Tap.TempIfName) + if err != nil && err.Error() == LinkNotFoundErr { + c.log.Debugf("linux tap interface %s is registered but not ready yet, configuration postponed", ifConfig.config.Tap.TempIfName) return nil + } else if err != nil { + return errors.Errorf("failed to read TAP interface %s from linux: %v", ifConfig.config.Tap.TempIfName, err) + } + + nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() + + // Verify availability of namespace from configuration + if !c.nsHandler.IsNamespaceAvailable(ifConfig.config.Namespace) { + return errors.Errorf("failed to apply linux tap %s config: destination namespace %s is not available", + ifConfig.config.Name, ifConfig.config.Namespace) } - plugin.ifCachedConfigs.UnregisterName(ifConfig.config.HostIfName) + c.ifCachedConfigs.UnregisterName(hostIfName) + c.log.Debugf("cached linux tap interface %s unregistered", ifConfig.config.Name) - return plugin.configureLinuxInterface(nsMgmtCtx, ifConfig.config) + return c.configureLinuxInterface(nsMgmtCtx, ifConfig.config) } // Set linux interface to proper namespace and configure attributes -func (plugin *LinuxInterfaceConfigurator) configureLinuxInterface(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, ifConfig *interfaces.LinuxInterfaces_Interface) (err error) { +func (c *LinuxInterfaceConfigurator) configureLinuxInterface(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, ifConfig *interfaces.LinuxInterfaces_Interface) (err error) { if ifConfig.HostIfName == "" { - return fmt.Errorf("host interface not specified for %v", ifConfig.Name) + return errors.Errorf("failed to configure linux interface %s: required host name not specified", ifConfig.Name) } // Use temporary/host name (according to type) to set interface to different namespace if ifConfig.Type == interfaces.LinuxInterfaces_AUTO_TAP { - err = plugin.nsHandler.SetInterfaceNamespace(nsMgmtCtx, ifConfig.Tap.TempIfName, ifConfig.Namespace) + err = c.setInterfaceNamespace(nsMgmtCtx, ifConfig.Tap.TempIfName, ifConfig.Namespace) if err != nil { - return fmt.Errorf("failed to set TAP interface %s to namespace %s: %v", ifConfig.Tap.TempIfName, ifConfig.Namespace, err) + return errors.Errorf("failed to set TAP interface %s to namespace %s: %v", + ifConfig.Tap.TempIfName, ifConfig.Namespace, err) } } else { - err = plugin.nsHandler.SetInterfaceNamespace(nsMgmtCtx, ifConfig.HostIfName, ifConfig.Namespace) + err = c.setInterfaceNamespace(nsMgmtCtx, ifConfig.HostIfName, ifConfig.Namespace) if err != nil { - return fmt.Errorf("failed to set interface %s to namespace %s: %v", ifConfig.HostIfName, ifConfig.Namespace, err) + return errors.Errorf("failed to set interface %s to namespace %s: %v", + ifConfig.HostIfName, ifConfig.Namespace, err) } } // Continue configuring interface in its namespace. - revertNs, err := plugin.nsHandler.SwitchToNamespace(nsMgmtCtx, ifConfig.Namespace) + revertNs, err := c.nsHandler.SwitchToNamespace(nsMgmtCtx, ifConfig.Namespace) if err != nil { - return fmt.Errorf("failed to switch network namespace: %v", err) + return errors.Errorf("failed to switch network namespace: %v", err) } defer revertNs() // For TAP interfaces only - rename interface to the actual host name if needed if ifConfig.Type == interfaces.LinuxInterfaces_AUTO_TAP { if ifConfig.HostIfName != ifConfig.Tap.TempIfName { - if err := plugin.ifHandler.RenameInterface(ifConfig.Tap.TempIfName, ifConfig.HostIfName); err != nil { - plugin.log.Errorf("Failed to rename TAP interface from %s to %s: %v", ifConfig.Tap.TempIfName, + if err := c.ifHandler.RenameInterface(ifConfig.Tap.TempIfName, ifConfig.HostIfName); err != nil { + return errors.Errorf("failed to rename TAP interface from %s to %s: %v", ifConfig.Tap.TempIfName, ifConfig.HostIfName, err) - return err } } else { - plugin.log.Debugf("Renaming of TAP interface %v skipped, host name is the same as temporary", ifConfig.HostIfName) + c.log.Debugf("Renaming of TAP interface %v skipped, host name is the same as temporary", ifConfig.HostIfName) } } - var wasErr error - // Set interface up. if ifConfig.Enabled { - err := plugin.ifHandler.SetInterfaceUp(ifConfig.HostIfName) + err := c.ifHandler.SetInterfaceUp(ifConfig.HostIfName) if nil != err { - wasErr = fmt.Errorf("failed to enable Linux interface: %v", err) - plugin.log.Error(wasErr) + return errors.Errorf("failed to set linux interface %s up: %v", ifConfig.Name, err) } } // Set interface MAC address if ifConfig.PhysAddress != "" { - err = plugin.ifHandler.SetInterfaceMac(ifConfig.HostIfName, ifConfig.PhysAddress) + err = c.ifHandler.SetInterfaceMac(ifConfig.HostIfName, ifConfig.PhysAddress) if err != nil { - wasErr = fmt.Errorf("cannot assign MAC '%s': %v", ifConfig.PhysAddress, err) - plugin.log.Error(wasErr) + return errors.Errorf("failed to set MAC address %s to linux interface %s: %v", + ifConfig.PhysAddress, ifConfig.Name, err) } - plugin.log.Debugf("MAC '%s' set to interface %s", ifConfig.PhysAddress, ifConfig.HostIfName) } // Set interface IP addresses ipAddresses, err := addrs.StrAddrsToStruct(ifConfig.IpAddresses) if err != nil { - plugin.log.Error(err) - wasErr = err + return errors.Errorf("failed to convert IP addresses %s: %v", ipAddresses, err) } // Get all configured interface addresses - confAddresses, err := plugin.ifHandler.GetAddressList(ifConfig.HostIfName) + confAddresses, err := c.ifHandler.GetAddressList(ifConfig.HostIfName) if err != nil { - plugin.log.Error(err) - wasErr = err + return errors.Errorf("failed to read IP addresses from linux interface %s: %v", ifConfig.Name, err) } - for i, ipAddress := range ipAddresses { + for _, ipAddress := range ipAddresses { // Check link local addresses which cannot be reassigned - if addressExists(confAddresses, ipAddresses[i]) { - plugin.log.Debugf("Cannot assign %s to interface %s, IP already exists", - ipAddresses[i].IP.String(), ifConfig.HostIfName) + if addressExists(confAddresses, ipAddress) { + c.log.Debugf("Cannot assign %s to linux interface %s, IP already exists", + ipAddress.IP.String(), ifConfig.HostIfName) continue } - err = plugin.ifHandler.AddInterfaceIP(ifConfig.HostIfName, ipAddresses[i]) + err = c.ifHandler.AddInterfaceIP(ifConfig.HostIfName, ipAddress) if err != nil { - err = fmt.Errorf("cannot assign IP address '%s': %v", ipAddress, err) - plugin.log.Error(err) - wasErr = err - } else { - plugin.log.Debugf("IP address '%s' set to interface %s", ipAddress, ifConfig.HostIfName) + return errors.Errorf("faield to add IP address %s to linux interface %s: %v", + ipAddress, ifConfig.Name, err) } } if ifConfig.Mtu != 0 { - plugin.ifHandler.SetInterfaceMTU(ifConfig.HostIfName, int(ifConfig.Mtu)) - plugin.log.Debugf("MTU %d set to interface %s", ifConfig.Mtu, ifConfig.HostIfName) + if err := c.ifHandler.SetInterfaceMTU(ifConfig.HostIfName, int(ifConfig.Mtu)); err != nil { + return errors.Errorf("failed to set MTU %d to linux interface %s: %v", + ifConfig.Mtu, ifConfig.Name, err) + } } - netIf, err := plugin.ifHandler.GetInterfaceByName(ifConfig.HostIfName) + netIf, err := c.ifHandler.GetInterfaceByName(ifConfig.HostIfName) if err != nil { - return fmt.Errorf("failed to get index of the Linux interface %s: %v", ifConfig.HostIfName, err) + return errors.Errorf("failed to get index of the linux interface %s: %v", ifConfig.HostIfName, err) } // Register interface with its original name and store host name in metadata - plugin.ifIndexes.RegisterName(ifConfig.Name, plugin.ifIdxSeq, &ifaceidx.IndexedLinuxInterface{ + c.ifIndexes.RegisterName(ifConfig.Name, c.ifIdxSeq, &ifaceidx.IndexedLinuxInterface{ Index: uint32(netIf.Index), Data: ifConfig, }) - plugin.ifIdxSeq++ - plugin.log.WithFields(logging.Fields{"ifName": ifConfig.Name, "ifIdx": netIf.Index}). - Info("An entry added into ifState.") + c.ifIdxSeq++ + c.log.Debugf("Linux interface %s registered", ifConfig.Name) - return wasErr + return nil } // Update linux interface attributes in it's namespace -func (plugin *LinuxInterfaceConfigurator) modifyLinuxInterface(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, +func (c *LinuxInterfaceConfigurator) modifyLinuxInterface(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, oldIfConfig, newIfConfig *interfaces.LinuxInterfaces_Interface) error { // Switch to required namespace - revertNs, err := plugin.nsHandler.SwitchToNamespace(nsMgmtCtx, oldIfConfig.Namespace) + revertNs, err := c.nsHandler.SwitchToNamespace(nsMgmtCtx, oldIfConfig.Namespace) if err != nil { - return fmt.Errorf("failed to switch network namespace: %v", err) + return errors.Errorf("linux interface %s modify: failed to switch to namespace: %v", newIfConfig.Name, err) } defer revertNs() - // Verify that the interface already exists in the Linux namespace. - _, err = plugin.ifHandler.GetInterfaceByName(oldIfConfig.HostIfName) + // Check if the interface already exists in the Linux namespace. If not, it still may be configured somewhere else. + _, err = c.ifHandler.GetInterfaceByName(oldIfConfig.HostIfName) if err != nil { - plugin.log.Debugf("Host interface %v was not found", oldIfConfig.HostIfName) + c.log.Debugf("Host interface %v was not found: %v", oldIfConfig.HostIfName, err) // If host does not exist, configure new setup as a new one - return plugin.ConfigureLinuxInterface(newIfConfig) + return c.ConfigureLinuxInterface(newIfConfig) } - var wasErr error - // Set admin status. if newIfConfig.Enabled != oldIfConfig.Enabled { if newIfConfig.Enabled { - err = plugin.ifHandler.SetInterfaceUp(newIfConfig.HostIfName) + err = c.ifHandler.SetInterfaceUp(newIfConfig.HostIfName) } else { - err = plugin.ifHandler.SetInterfaceDown(newIfConfig.HostIfName) + err = c.ifHandler.SetInterfaceDown(newIfConfig.HostIfName) } if nil != err { - wasErr = fmt.Errorf("failed to enable/disable Linux interface: %v", err) + return errors.Errorf("failed to enable/disable Linux interface %s: %v", newIfConfig.Name, err) } } // Configure new MAC address if set. if newIfConfig.PhysAddress != "" && newIfConfig.PhysAddress != oldIfConfig.PhysAddress { - plugin.log.WithFields(logging.Fields{"PhysAddress": newIfConfig.PhysAddress, "hostIfName": newIfConfig.HostIfName}). - Debug("MAC address re-configured.") - err := plugin.ifHandler.SetInterfaceMac(newIfConfig.HostIfName, newIfConfig.PhysAddress) + err := c.ifHandler.SetInterfaceMac(newIfConfig.HostIfName, newIfConfig.PhysAddress) if err != nil { - wasErr = fmt.Errorf("failed to assign physical address to a Linux interface: %v", err) - plugin.log.Error(wasErr) + return errors.Errorf("failed to reconfigure MAC address for linux interface %s: %v", + newIfConfig.Name, err) } } // IP addresses newAddrs, err := addrs.StrAddrsToStruct(newIfConfig.IpAddresses) if err != nil { - plugin.log.Error(err) - wasErr = err + return errors.Errorf("linux interface modify: failed to convert IP addresses for %s: %v", + newIfConfig.Name, err) } oldAddrs, err := addrs.StrAddrsToStruct(oldIfConfig.IpAddresses) if err != nil { - plugin.log.Error(err) - wasErr = err + return errors.Errorf("linux interface modify: failed to convert IP addresses for %s: %v", + newIfConfig.Name, err) } var del, add []*net.IPNet del, add = addrs.DiffAddr(newAddrs, oldAddrs) for i := range del { - plugin.log.WithFields(logging.Fields{"IP address": del[i], "hostIfName": newIfConfig.HostIfName}).Debug("IP address deleted.") - err := plugin.ifHandler.DelInterfaceIP(newIfConfig.HostIfName, del[i]) + err := c.ifHandler.DelInterfaceIP(newIfConfig.HostIfName, del[i]) if nil != err { - wasErr = fmt.Errorf("failed to unassign IPv4 address from a Linux interface: %v", err) - plugin.log.Error(wasErr) + return errors.Errorf("failed to remove IPv4 address from a Linux interface %s: %v", + newIfConfig.Name, err) } } // Get all configured interface addresses - confAddresses, err := plugin.ifHandler.GetAddressList(newIfConfig.HostIfName) + confAddresses, err := c.ifHandler.GetAddressList(newIfConfig.HostIfName) if err != nil { - plugin.log.Error(err) - wasErr = err + return errors.Errorf("linux interface modify: failed to read IP addresses from %s: %v", + newIfConfig.Name, err) } for i := range add { - plugin.log.WithFields(logging.Fields{"IP address": add[i], "hostIfName": newIfConfig.HostIfName}).Debug("IP address added.") + c.log.WithFields(logging.Fields{"IP address": add[i], "hostIfName": newIfConfig.HostIfName}).Debug("IP address added.") // Check link local addresses which cannot be reassigned if addressExists(confAddresses, add[i]) { - plugin.log.Debugf("Cannot assign %s to interface %s, IP already exists", + c.log.Debugf("Cannot assign %s to interface %s, IP already exists", add[i].IP.String(), newIfConfig.HostIfName) continue } - err := plugin.ifHandler.AddInterfaceIP(newIfConfig.HostIfName, add[i]) + err := c.ifHandler.AddInterfaceIP(newIfConfig.HostIfName, add[i]) if nil != err { - wasErr = fmt.Errorf("failed to assign IPv4 address to a Linux interface: %v", err) - plugin.log.Error(wasErr) + return errors.Errorf("linux interface modify: failed to add IP addresses %s to %s: %v", + add[i], newIfConfig.Name, err) } } @@ -618,80 +582,80 @@ func (plugin *LinuxInterfaceConfigurator) modifyLinuxInterface(nsMgmtCtx *nsplug if newIfConfig.Mtu != oldIfConfig.Mtu { mtu := newIfConfig.Mtu if mtu > 0 { - plugin.log.WithFields(logging.Fields{"MTU": mtu, "hostIfName": newIfConfig.HostIfName}).Debug("MTU re-configured.") - err := plugin.ifHandler.SetInterfaceMTU(newIfConfig.HostIfName, int(mtu)) + err := c.ifHandler.SetInterfaceMTU(newIfConfig.HostIfName, int(mtu)) if nil != err { - wasErr = fmt.Errorf("failed to set MTU of a Linux interface: %v", err) - plugin.log.Error(wasErr) + return errors.Errorf("failed to reconfigure MTU for the linux interface %s: %v", + newIfConfig.Name, err) } } } - plugin.log.Infof("Linux interface %v modified", newIfConfig.Name) - - return wasErr + return nil } // Remove VETH type interface -func (plugin *LinuxInterfaceConfigurator) deleteVethInterface(ifConfig, peerConfig *LinuxInterfaceConfig) error { - plugin.log.Debugf("Removing VETH interface %v ", ifConfig.config.HostIfName) +func (c *LinuxInterfaceConfigurator) deleteVethInterface(ifConfig, peerConfig *LinuxInterfaceConfig) error { // Veth interface removal - if ifConfig == nil || ifConfig.config == nil || !plugin.nsHandler.IsNamespaceAvailable(ifConfig.config.Namespace) || - peerConfig == nil || peerConfig.config == nil || !plugin.nsHandler.IsNamespaceAvailable(peerConfig.config.Namespace) { + if ifConfig == nil || ifConfig.config == nil || !c.nsHandler.IsNamespaceAvailable(ifConfig.config.Namespace) || + peerConfig == nil || peerConfig.config == nil || !c.nsHandler.IsNamespaceAvailable(peerConfig.config.Namespace) { name := "" if ifConfig != nil && ifConfig.config != nil { name = ifConfig.config.Name } - plugin.log.WithField("ifName", name).Debug("VETH interface doesn't exist") + c.log.Debug("VETH interface %s doesn't exist, nothing to remove", name) return nil } // Move to the namespace with the interface. nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - revertNs, err := plugin.nsHandler.SwitchToNamespace(nsMgmtCtx, ifConfig.config.Namespace) + revertNs, err := c.nsHandler.SwitchToNamespace(nsMgmtCtx, ifConfig.config.Namespace) if err != nil { - return fmt.Errorf("failed to switch network namespace: %v", err) + return errors.Errorf("delete interface %s: failed to switch network namespace: %v", + ifConfig.config.Name, err) } defer revertNs() - err = plugin.ifHandler.DelVethInterfacePair(ifConfig.config.HostIfName, peerConfig.config.HostIfName) + err = c.ifHandler.DelVethInterfacePair(ifConfig.config.HostIfName, peerConfig.config.HostIfName) if err != nil { - return fmt.Errorf("failed to delete VETH interface: %v", err) + return errors.Errorf("failed to delete VETH pait %s-%s: %v", + ifConfig.config.Name, peerConfig.config.Name, err) } // Unregister both VETH ends from the in-memory map (following triggers notifications for all subscribers). - plugin.ifIndexes.UnregisterName(ifConfig.config.Name) - plugin.ifIndexes.UnregisterName(peerConfig.config.Name) + c.ifIndexes.UnregisterName(ifConfig.config.Name) + c.ifIndexes.UnregisterName(peerConfig.config.Name) + c.log.Debugf("Interface %s and its peer %s were unregistered", + ifConfig.config.Name, peerConfig.config.Name) - plugin.log.Infof("Linux Interface %v removed", ifConfig.config.Name) + c.log.Infof("Linux Interface %s removed", ifConfig.config.Name) return nil } -func (plugin *LinuxInterfaceConfigurator) moveTapInterfaceToDefaultNamespace(ifConfig *interfaces.LinuxInterfaces_Interface) error { - plugin.log.Infof("moving linux tap interface %v to default namespace", ifConfig.HostIfName) - if !plugin.nsHandler.IsNamespaceAvailable(ifConfig.Namespace) { - plugin.log.Warnf("Unable to remove linux TAP configuration: cannot access namespace %v", ifConfig.Namespace.Name) - return nil +func (c *LinuxInterfaceConfigurator) moveTapInterfaceToDefaultNamespace(ifConfig *interfaces.LinuxInterfaces_Interface) error { + if !c.nsHandler.IsNamespaceAvailable(ifConfig.Namespace) { + return errors.Errorf("failed to move tap interface %s to default namespace: namespace not available", ifConfig.Name) } // Move to the namespace with the interface. nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - revertNs, err := plugin.nsHandler.SwitchToNamespace(nsMgmtCtx, ifConfig.Namespace) + revertNs, err := c.nsHandler.SwitchToNamespace(nsMgmtCtx, ifConfig.Namespace) if err != nil { - return fmt.Errorf("failed to switch network namespace: %v", err) + return errors.Errorf("failed to move tap interface %s to default namespace: cannot switch namespace: %v", + ifConfig.Name, err) } defer revertNs() // Get all IP addresses currently configured on the interface. It is not enough to just remove all IP addresses // present in the ifConfig object, there can be default IP address which needs to be removed as well. var ipAddresses []*net.IPNet - link, err := plugin.ifHandler.GetLinkList() + link, err := c.ifHandler.GetLinkList() for _, linuxIf := range link { if linuxIf.Attrs().Name == ifConfig.HostIfName { - IPlist, err := plugin.ifHandler.GetAddressList(linuxIf.Attrs().Name) + IPlist, err := c.ifHandler.GetAddressList(linuxIf.Attrs().Name) if err != nil { - return err + return errors.Errorf("failed to read IP addresses from interface %s: %v", + ifConfig.Name, err) } for _, address := range IPlist { ipAddresses = append(ipAddresses, address.IPNet) @@ -700,11 +664,10 @@ func (plugin *LinuxInterfaceConfigurator) moveTapInterfaceToDefaultNamespace(ifC } } // Remove all IP addresses from the TAP - var wasErr error for _, ipAddress := range ipAddresses { - if err := plugin.ifHandler.DelInterfaceIP(ifConfig.HostIfName, ipAddress); err != nil { - plugin.log.Error(err) - wasErr = err + if err := c.ifHandler.DelInterfaceIP(ifConfig.HostIfName, ipAddress); err != nil { + return errors.Errorf("failed to remove IP address %s from interface %s: %v", + ipAddresses, ifConfig.HostIfName, err) } } @@ -712,131 +675,127 @@ func (plugin *LinuxInterfaceConfigurator) moveTapInterfaceToDefaultNamespace(ifC if ifConfig.Type == interfaces.LinuxInterfaces_AUTO_TAP { // Rename to its original name (if possible) if ifConfig.Tap == nil || ifConfig.Tap.TempIfName == "" { - plugin.log.Warnf("Cannot restore linux TAP %v interface state, original name (temp) is not available", ifConfig.HostIfName) + c.log.Debugf("Cannot restore linux tap interface %s, original name (temp) is not available", ifConfig.HostIfName) ifConfig.Tap = &interfaces.LinuxInterfaces_Interface_Tap{ TempIfName: ifConfig.HostIfName, } } if ifConfig.Tap.TempIfName == ifConfig.HostIfName { - plugin.log.Debugf("Renaming of TAP interface %v skipped, host name is the same as temporary", ifConfig.HostIfName) + c.log.Debugf("Renaming of TAP interface %v skipped, host name is the same as temporary", ifConfig.HostIfName) } else { - if err := plugin.ifHandler.RenameInterface(ifConfig.HostIfName, ifConfig.Tap.TempIfName); err != nil { + if err := c.ifHandler.RenameInterface(ifConfig.HostIfName, ifConfig.Tap.TempIfName); err != nil { - plugin.log.Errorf("Failed to rename TAP interface from %s to %s: %v", ifConfig.HostIfName, + return errors.Errorf("failed to rename TAP interface from %s to %s: %v", ifConfig.HostIfName, ifConfig.Tap.TempIfName, err) - wasErr = err } } - err = plugin.nsHandler.SetInterfaceNamespace(nsMgmtCtx, ifConfig.Tap.TempIfName, &interfaces.LinuxInterfaces_Interface_Namespace{}) + err = c.setInterfaceNamespace(nsMgmtCtx, ifConfig.Tap.TempIfName, &interfaces.LinuxInterfaces_Interface_Namespace{}) if err != nil { - return fmt.Errorf("failed to set Linux TAP interface %s to namespace %s: %v", ifConfig.Tap.TempIfName, "default", err) + return errors.Errorf("failed to set Linux TAP interface %s to default namespace: %v", ifConfig.Tap.TempIfName, err) } } else { - err = plugin.nsHandler.SetInterfaceNamespace(nsMgmtCtx, ifConfig.HostIfName, &interfaces.LinuxInterfaces_Interface_Namespace{}) + err = c.setInterfaceNamespace(nsMgmtCtx, ifConfig.HostIfName, &interfaces.LinuxInterfaces_Interface_Namespace{}) if err != nil { - return fmt.Errorf("failed to set Linux TAP interface %s to namespace %s: %v", ifConfig.HostIfName, "default", err) + return errors.Errorf("failed to set Linux TAP interface %s to default namespace: %v", ifConfig.HostIfName, err) } } - return wasErr + return nil } // Un-configure TAP interface, set original name and return it to the default namespace (do not delete, // the interface will be removed together with the peer (VPP TAP)) -func (plugin *LinuxInterfaceConfigurator) deleteTapInterface(ifConfig *LinuxInterfaceConfig) error { +func (c *LinuxInterfaceConfigurator) deleteTapInterface(ifConfig *LinuxInterfaceConfig) error { if ifConfig == nil || ifConfig.config == nil { - plugin.log.Warn("Unable to remove linux TAP configuration: no data available") - return nil + return errors.Errorf("failed to remove tap interface, no data available") } - plugin.log.Debugf("Removing Linux TAP configuration %v from interface %v ", ifConfig.config.Name, ifConfig.config.HostIfName) // Move to default namespace - err := plugin.moveTapInterfaceToDefaultNamespace(ifConfig.config) - - if err == nil { - // Unregister TAP from the in-memory map - plugin.ifIndexes.UnregisterName(ifConfig.config.Name) + err := c.moveTapInterfaceToDefaultNamespace(ifConfig.config) + if err != nil { + return err } + // Unregister TAP from the in-memory map + c.ifIndexes.UnregisterName(ifConfig.config.Name) + c.log.Debugf("Interface %s unregistered", ifConfig.config) - return err + return nil } // removeObsoleteVeth deletes VETH interface which should no longer exist. -func (plugin *LinuxInterfaceConfigurator) removeObsoleteVeth(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, vethName string, hostIfName string, ns *interfaces.LinuxInterfaces_Interface_Namespace) error { - plugin.log.WithFields(logging.Fields{"vethName": vethName, "hostIfName": hostIfName, "ns": plugin.nsHandler.IfaceNsToString(ns)}). - Debug("Attempting to remove obsolete VETH") - - revertNs, err := plugin.nsHandler.SwitchToNamespace(nsMgmtCtx, ns) +func (c *LinuxInterfaceConfigurator) removeObsoleteVeth(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, vethName, hostIfName string, ns *interfaces.LinuxInterfaces_Interface_Namespace) error { + revertNs, err := c.nsHandler.SwitchToNamespace(nsMgmtCtx, ns) defer revertNs() if err != nil { // Already removed as namespace no longer exists. - plugin.ifIndexes.UnregisterName(vethName) + c.ifIndexes.UnregisterName(vethName) + c.log.Debugf("obsolete veth %s namespace does not exist, unregistered", vethName) return nil } - exists, err := plugin.ifHandler.InterfaceExists(hostIfName) + exists, err := c.ifHandler.InterfaceExists(hostIfName) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to verify veth %s (hostname %s) presence: %v", vethName, hostIfName, err) } if !exists { // already removed - plugin.ifIndexes.UnregisterName(vethName) + if _, _, exists := c.ifIndexes.UnregisterName(vethName); exists { + c.log.Debugf("obsolete veth %s does not exist, unregistered", vethName) + } return nil } - ifType, err := plugin.ifHandler.GetInterfaceType(hostIfName) + ifType, err := c.ifHandler.GetInterfaceType(hostIfName) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to get obsolete veth %s (hostname %s) type: %v", vethName, hostIfName, err) } if ifType != veth { - return fmt.Errorf("interface '%s' already exists and is not VETH", vethName) + return errors.Errorf("obsolete veth %s exists, but it is not an veth type interface", vethName) } - peerName, err := plugin.ifHandler.GetVethPeerName(hostIfName) + peerName, err := c.ifHandler.GetVethPeerName(hostIfName) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to get veth %s (hostname %s) peer name: %v", vethName, hostIfName, err) } - plugin.log.WithFields(logging.Fields{"ifName": vethName, "peerName": peerName}). - Debug("Removing obsolete VETH interface") - err = plugin.ifHandler.DelVethInterfacePair(hostIfName, peerName) + err = c.ifHandler.DelVethInterfacePair(hostIfName, peerName) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to remove obsolete veth %s: %v", vethName, err) } - plugin.ifIndexes.UnregisterName(vethName) + c.ifIndexes.UnregisterName(vethName) + c.log.Debugf("obsolete veth %s unregistered", vethName) return nil } // addVethInterfacePair creates a new VETH interface with a "clean" configuration. -func (plugin *LinuxInterfaceConfigurator) addVethInterfacePair(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, +func (c *LinuxInterfaceConfigurator) addVethInterfacePair(nsMgmtCtx *nsplugin.NamespaceMgmtCtx, iface, peer *interfaces.LinuxInterfaces_Interface) error { - err := plugin.removeObsoleteVeth(nsMgmtCtx, iface.Name, iface.HostIfName, iface.Namespace) + err := c.removeObsoleteVeth(nsMgmtCtx, iface.Name, iface.HostIfName, iface.Namespace) if err != nil { return err } - err = plugin.removeObsoleteVeth(nsMgmtCtx, peer.Name, peer.HostIfName, peer.Namespace) + err = c.removeObsoleteVeth(nsMgmtCtx, peer.Name, peer.HostIfName, peer.Namespace) if err != nil { return err } // VETH is first created in its own cfg namespace so it has to be removed there as well. - err = plugin.removeObsoleteVeth(nsMgmtCtx, iface.Name, iface.HostIfName, plugin.nsHandler.GetConfigNamespace()) + err = c.removeObsoleteVeth(nsMgmtCtx, iface.Name, iface.HostIfName, c.nsHandler.GetConfigNamespace()) if err != nil { return err } - err = plugin.removeObsoleteVeth(nsMgmtCtx, peer.Name, peer.HostIfName, plugin.nsHandler.GetConfigNamespace()) + err = c.removeObsoleteVeth(nsMgmtCtx, peer.Name, peer.HostIfName, c.nsHandler.GetConfigNamespace()) if err != nil { return err } - err = plugin.ifHandler.AddVethInterfacePair(iface.HostIfName, peer.HostIfName) + err = c.ifHandler.AddVethInterfacePair(iface.HostIfName, peer.HostIfName) if err != nil { - return fmt.Errorf("failed to create new VETH: %v", err) + return errors.Errorf("failed to create new VETH %s: %v", iface.Name, err) } return nil } // getInterfaceConfig returns cached configuration of a given interface. -func (plugin *LinuxInterfaceConfigurator) getInterfaceConfig(ifName string) *LinuxInterfaceConfig { - config, ok := plugin.ifByName[ifName] +func (c *LinuxInterfaceConfigurator) getInterfaceConfig(ifName string) *LinuxInterfaceConfig { + c.mapMu.RLock() + defer c.mapMu.RUnlock() + + config, ok := c.ifByName[ifName] if ok { return config } @@ -844,67 +803,172 @@ func (plugin *LinuxInterfaceConfigurator) getInterfaceConfig(ifName string) *Lin } // addToCache adds interface configuration into the cache. -func (plugin *LinuxInterfaceConfigurator) addToCache(iface *interfaces.LinuxInterfaces_Interface, peerIface *LinuxInterfaceConfig) *LinuxInterfaceConfig { - config := &LinuxInterfaceConfig{config: iface, peer: peerIface} - plugin.ifByName[iface.Name] = config +func (c *LinuxInterfaceConfigurator) addToCache(iface *interfaces.LinuxInterfaces_Interface, peerIface *LinuxInterfaceConfig) *LinuxInterfaceConfig { + c.log.Debugf("linux interface config %s cached to if-by-name", iface.Name) + + c.mapMu.Lock() + defer c.mapMu.Unlock() + + config := &LinuxInterfaceConfig{ + config: iface, + peer: peerIface, + } + c.ifByName[iface.Name] = config if peerIface != nil { peerIface.peer = config } + if iface.Namespace != nil && iface.Namespace.Type == interfaces.LinuxInterfaces_Interface_Namespace_MICROSERVICE_REF_NS { - if _, ok := plugin.ifsByMs[iface.Namespace.Microservice]; ok { - plugin.ifsByMs[iface.Namespace.Microservice] = append(plugin.ifsByMs[iface.Namespace.Microservice], config) + if _, ok := c.ifsByMs[iface.Namespace.Microservice]; ok { + c.ifsByMs[iface.Namespace.Microservice] = append(c.ifsByMs[iface.Namespace.Microservice], config) + c.log.Debugf("linux interface config %s cached for microservice-ref-ns", iface.Name) } else { - plugin.ifsByMs[iface.Namespace.Microservice] = []*LinuxInterfaceConfig{config} + c.ifsByMs[iface.Namespace.Microservice] = []*LinuxInterfaceConfig{config} + c.log.Debugf("linux interface config %s cached for microservice", iface.Name) } } - plugin.log.Debugf("Linux interface with name %v added to cache (peer: %v)", - iface.Name, peerIface) return config } // removeFromCache removes interfaces configuration from the cache. -func (plugin *LinuxInterfaceConfigurator) removeFromCache(iface *interfaces.LinuxInterfaces_Interface) *LinuxInterfaceConfig { - if config, ok := plugin.ifByName[iface.Name]; ok { +func (c *LinuxInterfaceConfigurator) removeFromCache(iface *interfaces.LinuxInterfaces_Interface) *LinuxInterfaceConfig { + c.mapMu.Lock() + defer c.mapMu.Unlock() + + if config, ok := c.ifByName[iface.Name]; ok { if config.peer != nil { config.peer.peer = nil } if iface.Namespace != nil && iface.Namespace.Type == interfaces.LinuxInterfaces_Interface_Namespace_MICROSERVICE_REF_NS { var filtered []*LinuxInterfaceConfig - for _, intf := range plugin.ifsByMs[iface.Namespace.Microservice] { + for _, intf := range c.ifsByMs[iface.Namespace.Microservice] { if intf.config.Name != iface.Name { filtered = append(filtered, intf) } } - plugin.ifsByMs[iface.Namespace.Microservice] = filtered + c.ifsByMs[iface.Namespace.Microservice] = filtered } - delete(plugin.ifByName, iface.Name) - plugin.log.Debugf("Linux interface with name %v was removed from cache", iface.Name) + + delete(c.ifByName, iface.Name) + c.log.Debugf("Linux interface with name %v was removed from if-by-name cache", iface.Name) + return config } return nil } +// Watcher receives events from state updater about created/removed linux interfaces and performs appropriate actions +func (c *LinuxInterfaceConfigurator) watchLinuxStateUpdater() { + c.log.Debugf("Linux interface state watcher started") + + for { + linuxIf, ok := <-c.ifNotif + if !ok { + c.log.Debugf("linux interface watcher ended") + return + } + ifName := linuxIf.attributes.Name + + switch { + case linuxIf.interfaceType == tap: + if linuxIf.interfaceState == netlink.OperDown { + // Find whether it is a registered tap interface and un-register it. Otherwise the change is ignored. + for _, idxName := range c.ifIndexes.GetMapping().ListNames() { + _, ifMeta, found := c.ifIndexes.LookupIdx(idxName) + if !found { + // Should not happen + c.log.Warnf("Interface %s not found in the mapping", idxName) + continue + } + if ifMeta == nil { + // Should not happen + c.log.Warnf("Interface %s metadata does not exist", idxName) + continue + } + if ifMeta.Data.HostIfName == "" { + c.log.Warnf("No info about host name for %s", idxName) + continue + } + if ifMeta.Data.HostIfName == ifName { + // Registered Linux TAP interface was removed, add it to cache. Pull out metadata, so they can be + // saved in cache as well + _, unregMeta, _ := c.ifIndexes.UnregisterName(ifName) + c.log.Debugf("Tap interface %s unregistered according to linux state event", ifName) + if _, _, found := c.ifCachedConfigs.LookupIdx(ifName); !found && unregMeta != nil { + c.ifCachedConfigs.RegisterName(ifMeta.Data.HostIfName, c.pIfCachedConfigSeq, unregMeta) + c.pIfCachedConfigSeq++ + c.log.Debugf("removed linux TAP %s registered to cache according to linux state event", + ifName) + } + } + } + } else { + // Event that a TAP interface was created. Look for TAP which is using this interface as the other end. + for _, cachedIfConfig := range c.getCachedIfConfigByName(ifName) { + // Host interface was found, configure linux TAP + err := c.ConfigureLinuxInterface(cachedIfConfig) + if err != nil { + c.LogError(errors.Errorf("failed to process linux interface %s creation from event: %v", ifName, err)) + } + } + } + default: + c.log.Debugf("Linux interface type %v state processing skipped", linuxIf.interfaceType) + } + + } +} + +func (c *LinuxInterfaceConfigurator) getCachedIfConfigByName(ifName string) (ifConfigs []*interfaces.LinuxInterfaces_Interface) { + c.mapMu.RLock() + defer c.mapMu.RUnlock() + + for _, ifConfig := range c.ifByName { + if ifConfig == nil || ifConfig.config == nil { + c.log.Warnf("Cached config for interface %s is empty", ifName) + continue + } + if ifConfig.config.GetTap().GetTempIfName() == ifName || ifConfig.config.GetHostIfName() == ifName { + // Skip processed interfaces + _, _, exists := c.ifIndexes.LookupIdx(ifConfig.config.Name) + if exists { + continue + } + ifConfigs = append(ifConfigs, ifConfig.config) + } + } + return +} + +func (c *LinuxInterfaceConfigurator) getIfsByMsLabel(label string) []*LinuxInterfaceConfig { + c.mapMu.RLock() + defer c.mapMu.RUnlock() + + return c.ifsByMs[label] +} + // watchMicroservices handles events from namespace plugin -func (plugin *LinuxInterfaceConfigurator) watchMicroservices(ctx context.Context) { - plugin.wg.Add(1) - defer plugin.wg.Done() +func (c *LinuxInterfaceConfigurator) watchMicroservices(ctx context.Context) { + c.wg.Add(1) + defer c.wg.Done() nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() for { select { - case msEvent := <-plugin.ifMsNotif: + case msEvent := <-c.ifMsNotif: if msEvent == nil { continue } microservice := msEvent.Microservice if microservice == nil { - plugin.log.Error("Empty microservice event") + c.log.Error("Empty microservice event") continue } if msEvent.EventType == nsplugin.NewMicroservice { skip := make(map[string]struct{}) /* interfaces to be skipped in subsequent iterations */ - for _, iface := range plugin.ifsByMs[microservice.Label] { + + for _, iface := range c.getIfsByMsLabel(microservice.Label) { if _, toSkip := skip[iface.config.Name]; toSkip { continue } @@ -913,53 +977,54 @@ func (plugin *LinuxInterfaceConfigurator) watchMicroservices(ctx context.Context // peer will be processed in this iteration and skipped in the subsequent ones. skip[peer.config.Name] = struct{}{} } - if peer != nil && plugin.nsHandler.IsNamespaceAvailable(peer.config.Namespace) { + if peer != nil && c.nsHandler.IsNamespaceAvailable(peer.config.Namespace) { // Prepare generic vet cfg namespace object - ifaceNs := plugin.nsHandler.IfNsToGeneric(plugin.nsHandler.GetConfigNamespace()) + ifaceNs := c.nsHandler.IfNsToGeneric(c.nsHandler.GetConfigNamespace()) // Switch to veth cfg namespace - revertNs, err := plugin.nsHandler.SwitchNamespace(ifaceNs, nsMgmtCtx) + revertNs, err := c.nsHandler.SwitchNamespace(ifaceNs, nsMgmtCtx) if err != nil { + c.log.Errorf("failed to switch namespace: %v", err) return } // VETH is ready to be created and configured - err = plugin.addVethInterfacePair(nsMgmtCtx, iface.config, peer.config) + err = c.addVethInterfacePair(nsMgmtCtx, iface.config, peer.config) if err != nil { - plugin.log.Error(err.Error()) + c.log.Error(err.Error()) continue } - if err := plugin.configureLinuxInterface(nsMgmtCtx, iface.config); err != nil { - plugin.log.Warnf("failed to configure VETH interface %s: %v", iface.config.Name, err) - } else if err := plugin.configureLinuxInterface(nsMgmtCtx, peer.config); err != nil { - plugin.log.Warnf("failed to configure VETH interface %s: %v", peer.config.Name, err) + if err := c.configureLinuxInterface(nsMgmtCtx, iface.config); err != nil { + c.log.Errorf("failed to configure VETH interface %s: %v", iface.config.Name, err) + } else if err := c.configureLinuxInterface(nsMgmtCtx, peer.config); err != nil { + c.log.Errorf("failed to configure VETH interface %s: %v", peer.config.Name, err) } revertNs() } else { - plugin.log.Debugf("peer VETH %v is not ready yet, microservice: %+v", iface.config.Name, microservice) + c.log.Debugf("peer VETH %v is not ready yet, microservice: %+v", iface.config.Name, microservice) } } } else if msEvent.EventType == nsplugin.TerminatedMicroservice { - for _, iface := range plugin.ifsByMs[microservice.Label] { - plugin.removeObsoleteVeth(nsMgmtCtx, iface.config.Name, iface.config.HostIfName, iface.config.Namespace) + for _, iface := range c.getIfsByMsLabel(microservice.Label) { + c.removeObsoleteVeth(nsMgmtCtx, iface.config.Name, iface.config.HostIfName, iface.config.Namespace) if iface.peer != nil && iface.peer.config != nil { - plugin.removeObsoleteVeth(nsMgmtCtx, iface.peer.config.Name, iface.peer.config.HostIfName, iface.peer.config.Namespace) + c.removeObsoleteVeth(nsMgmtCtx, iface.peer.config.Name, iface.peer.config.HostIfName, iface.peer.config.Namespace) } else { - plugin.log.Warnf("Obsolete peer for %s not removed, no peer data", iface.config.Name) + c.log.Warnf("Obsolete peer for %s not removed, no peer data", iface.config.Name) } } } else { - plugin.log.Errorf("Unknown microservice event type: %s", msEvent.EventType) + c.log.Errorf("Unknown microservice event type: %s", msEvent.EventType) } - case <-plugin.ctx.Done(): + case <-c.ctx.Done(): return } } } // If hostIfName is not set, symbolic name will be used. -func (plugin *LinuxInterfaceConfigurator) handleOptionalHostIfName(config *interfaces.LinuxInterfaces_Interface) { +func (c *LinuxInterfaceConfigurator) handleOptionalHostIfName(config *interfaces.LinuxInterfaces_Interface) { if config.HostIfName == "" { config.HostIfName = config.Name } @@ -975,12 +1040,10 @@ func addressExists(configured []netlink.Addr, provided *net.IPNet) bool { } // ResolveCreatedVPPInterface resolves a new vpp interfaces -func (plugin *LinuxInterfaceConfigurator) ResolveCreatedVPPInterface(ifConfigMetaData *vppIf.Interfaces_Interface) error { - plugin.log.Infof("Linux IF configurator: resolve created vpp interface %v", ifConfigMetaData) - +func (c *LinuxInterfaceConfigurator) ResolveCreatedVPPInterface(ifConfigMetaData *vppIf.Interfaces_Interface) error { if ifConfigMetaData == nil { - plugin.log.Warn("Unable to resolve created VPP interfaces, no Linux TAP configuration data available") - return nil + return errors.Errorf("unable to resolve registered VPP interface %s, no configuration data available", + ifConfigMetaData.Name) } if ifConfigMetaData.Type != vppIf.InterfaceType_TAP_INTERFACE { @@ -995,26 +1058,29 @@ func (plugin *LinuxInterfaceConfigurator) ResolveCreatedVPPInterface(ifConfigMet hostIfName = ifConfigMetaData.GetName() } if hostIfName == "" { - plugin.log.Warn("Unable to resolve created VPP interfaces, incomplete Linux TAP configuration data") - return nil + return errors.Errorf("unable to resolve registered VPP interface %s, incomplete configuration data", + ifConfigMetaData.Name) } var linuxIf *interfaces.LinuxInterfaces_Interface - _, data, exists := plugin.ifCachedConfigs.LookupIdx(hostIfName) + _, data, exists := c.ifCachedConfigs.LookupIdx(hostIfName) if exists && data != nil { linuxIf = data.Data } - return plugin.configureTapInterface(hostIfName, linuxIf) + if err := c.configureTapInterface(hostIfName, linuxIf); err != nil { + return errors.Errorf("failed to configure linux interface %s with registered VPP interface %s: %v", + ifConfigMetaData.Name, linuxIf, err) + } + + return nil } // ResolveDeletedVPPInterface resolves removed vpp interfaces -func (plugin *LinuxInterfaceConfigurator) ResolveDeletedVPPInterface(ifConfigMetaData *vppIf.Interfaces_Interface) error { - plugin.log.Infof("Linux IF configurator: resolve deleted vpp interface %v", ifConfigMetaData) - +func (c *LinuxInterfaceConfigurator) ResolveDeletedVPPInterface(ifConfigMetaData *vppIf.Interfaces_Interface) error { if ifConfigMetaData == nil { - plugin.log.Warn("Unable to resolve deleted VPP interfaces, no Linux TAP configuration data available") - return nil + return errors.Errorf("unable to resolve unregistered VPP interface %s, no configuration data available", + ifConfigMetaData.Name) } if ifConfigMetaData.Type != vppIf.InterfaceType_TAP_INTERFACE { @@ -1029,27 +1095,148 @@ func (plugin *LinuxInterfaceConfigurator) ResolveDeletedVPPInterface(ifConfigMet hostIfName = ifConfigMetaData.GetName() } if hostIfName == "" { - plugin.log.Warn("Unable to resolve deleted VPP interfaces, incomplete Linux TAP configuration data") - return nil + return errors.Errorf("unable to resolve unregistered VPP interface %s, incomplete configuration data", + ifConfigMetaData.Name) } - plugin.log.Infof("Resolving linux tap interface host(%v), name(%v)", hostIfName, ifConfigMetaData.Name) - _, ifConfig, exists := plugin.ifIndexes.LookupIdx(ifConfigMetaData.Name) + _, ifConfig, exists := c.ifIndexes.LookupIdx(ifConfigMetaData.Name) if exists { // Move linux tap configuration to cache - plugin.log.Infof("Registering linux tap interface configuration %v", ifConfig.Data.Name) - plugin.ifCachedConfigs.RegisterName(hostIfName, plugin.pIfCachedConfigSeq, &ifaceidx.IndexedLinuxInterface{ - Index: plugin.pIfCachedConfigSeq, + c.ifCachedConfigs.RegisterName(hostIfName, c.pIfCachedConfigSeq, &ifaceidx.IndexedLinuxInterface{ + Index: c.pIfCachedConfigSeq, Data: ifConfig.Data, }) // Unregister TAP from the in-memory map - plugin.log.Infof("Unregistering linux tap interface %v", ifConfig.Data.Name) - plugin.ifIndexes.UnregisterName(ifConfig.Data.Name) + c.ifIndexes.UnregisterName(ifConfig.Data.Name) + c.pIfCachedConfigSeq++ + c.log.Infof("Linux tap %s configuration unregistered and moved to cache", ifConfig.Data.Name) + if err := c.moveTapInterfaceToDefaultNamespace(ifConfig.Data); err != nil { + return errors.Errorf("failed to resolve unregistered VPP interface %s: %v", ifConfigMetaData.Name, err) + } + } + + return nil +} + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *LinuxInterfaceConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} + +// SetInterfaceNamespace moves a given Linux interface into a specified namespace. +func (c *LinuxInterfaceConfigurator) setInterfaceNamespace(ctx *nsplugin.NamespaceMgmtCtx, ifName string, namespace *interfaces.LinuxInterfaces_Interface_Namespace) error { + // Convert microservice namespace + var err error + if namespace != nil && namespace.Type == interfaces.LinuxInterfaces_Interface_Namespace_MICROSERVICE_REF_NS { + // Convert namespace + ifNs := c.nsHandler.ConvertMicroserviceNsToPidNs(namespace.Microservice) + // Back to interface ns type + namespace, err = ifNs.GenericToIfaceNs() + if err != nil { + return errors.Errorf("failed to convert generic interface namespace: %v", err) + } + if namespace == nil { + return errors.Errorf("microservice is not available for %s", ifName) + } + } + + ifaceNs := c.nsHandler.IfNsToGeneric(namespace) + + // Get network namespace file descriptor + ns, err := c.nsHandler.GetOrCreateNamespace(ifaceNs) + if err != nil { + return errors.Errorf("faield to get or create namespace %s: %v", namespace.Name, err) + } + defer ns.Close() + + // Get the link plugin. + link, err := c.ifHandler.GetLinkByName(ifName) + if err != nil { + return errors.Errorf("failed to get link for interface %s: %v", ifName, err) + } + + // When interface moves from one namespace to another, it loses all its IP addresses, admin status + // and MTU configuration -- we need to remember the interface configuration before the move + // and re-configure the interface in the new namespace. + addresses, isIPv6, err := c.getLinuxIfAddrs(link.Attrs().Name) + if err != nil { + return errors.Errorf("failed to get IP address list from interface %s: %v", link.Attrs().Name, err) + } + + // Move the interface into the namespace. + err = c.sysHandler.LinkSetNsFd(link, int(ns)) + if err != nil { + return errors.Errorf("failed to set interface %s file descriptor: %v", link.Attrs().Name, err) + } + + // Re-configure interface in its new namespace + revertNs, err := c.nsHandler.SwitchNamespace(ifaceNs, ctx) + if err != nil { + return errors.Errorf("failed to switch namespace: %v", err) + } + defer revertNs() + + if link.Attrs().Flags&net.FlagUp == 1 { + // Re-enable interface + err = c.ifHandler.SetInterfaceUp(ifName) + if nil != err { + return errors.Errorf("failed to re-enable Linux interface `%s`: %v", ifName, err) + } + } + + // Re-add IP addresses + for _, address := range addresses { + // Skip IPv6 link local address if there is no other IPv6 address + if !isIPv6 && address.IP.IsLinkLocalUnicast() { + continue + } + err = c.ifHandler.AddInterfaceIP(ifName, address) + if err != nil { + if err.Error() == "file exists" { + continue + } + return errors.Errorf("failed to re-assign IP address to a Linux interface `%s`: %v", ifName, err) + } + } - plugin.log.Infof("Linux interface configuration entry %v moved to cache : %v", ifConfig.Data.Name, ifConfig.Data) - plugin.pIfCachedConfigSeq++ - plugin.moveTapInterfaceToDefaultNamespace(ifConfig.Data) + // Revert back the MTU config + err = c.ifHandler.SetInterfaceMTU(ifName, link.Attrs().MTU) + if nil != err { + return errors.Errorf("failed to re-assign MTU of a Linux interface `%s`: %v", ifName, err) } return nil } + +// getLinuxIfAddrs returns a list of IP addresses for given linux interface with info whether there is IPv6 address +// (except default link local) +func (c *LinuxInterfaceConfigurator) getLinuxIfAddrs(ifName string) ([]*net.IPNet, bool, error) { + var networks []*net.IPNet + addresses, err := c.ifHandler.GetAddressList(ifName) + if err != nil { + return nil, false, errors.Errorf("failed to get IP address set from linux interface %s", ifName) + } + var containsIPv6 bool + for _, ipAddr := range addresses { + network, ipv6, err := addrs.ParseIPWithPrefix(ipAddr.String()) + if err != nil { + return nil, false, errors.Errorf("failed to parse IP address %s", ipAddr.String()) + } + // Set once if IP address is version 6 and not a link local address + if !containsIPv6 && ipv6 && !ipAddr.IP.IsLinkLocalUnicast() { + containsIPv6 = true + } + networks = append(networks, network) + } + + return networks, containsIPv6, nil +} diff --git a/plugins/linux/ifplugin/interface_config_test.go b/plugins/linux/ifplugin/interface_config_test.go index 80247ca894..a13476600e 100644 --- a/plugins/linux/ifplugin/interface_config_test.go +++ b/plugins/linux/ifplugin/interface_config_test.go @@ -18,9 +18,12 @@ import ( "fmt" "net" "testing" + "time" + + "github.com/go-errors/errors" + "github.com/vishvananda/netlink" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/linux/ifplugin" @@ -35,8 +38,8 @@ import ( // Test init function func TestLinuxInterfaceConfiguratorInit(t *testing.T) { - plugin, _, _, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, _, _, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Base fields Expect(plugin).ToNot(BeNil()) Expect(msChan).ToNot(BeNil()) @@ -53,8 +56,8 @@ func TestLinuxInterfaceConfiguratorInit(t *testing.T) { // Configure simple Veth without peer func TestLinuxConfiguratorAddSingleVeth(t *testing.T) { - plugin, _, _, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, _, _, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) data := getVethInterface("veth1", "peer1", 1) err := plugin.ConfigureLinuxInterface(data) @@ -64,8 +67,8 @@ func TestLinuxConfiguratorAddSingleVeth(t *testing.T) { // Configure Veth with missing data func TestLinuxConfiguratorAddSingleVethWithoutData(t *testing.T) { - plugin, _, _, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, _, _, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) data := getVethInterface("veth1", "peer1", 1) data.HostIfName = "" @@ -76,12 +79,22 @@ func TestLinuxConfiguratorAddSingleVethWithoutData(t *testing.T) { // Configure simple Veth with peer func TestLinuxConfiguratorAddVethPair(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) nsMock.When("IsNamespaceAvailable").ThenReturn(true) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v2", + }, + }) ifMock.When("GetInterfaceByName").ThenReturn(&net.Interface{ Index: 1, }) @@ -113,12 +126,30 @@ func TestLinuxConfiguratorAddVethPair(t *testing.T) { // Configure simple Veth with peer in microservice-type namespace func TestLinuxConfiguratorAddVethPairInMicroserviceNs(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) nsMock.When("IsNamespaceAvailable").ThenReturn(true) + nsMock.When("ConvertMicroserviceNsToPidNs").ThenReturn(&nsplugin.Namespace{ + Type: nsplugin.PidRefNs, + }, + ) + nsMock.When("ConvertMicroserviceNsToPidNs").ThenReturn(&nsplugin.Namespace{ + Type: nsplugin.PidRefNs, + }, + ) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v2", + }, + }) ifMock.When("GetInterfaceByName").ThenReturn(&net.Interface{ Index: 1, }) @@ -154,8 +185,8 @@ func TestLinuxConfiguratorAddVethPairInMicroserviceNs(t *testing.T) { // Configure simple Veth with peer while Veth ns is not available func TestLinuxConfiguratorAddVethPairVethNsNotAvailable(t *testing.T) { - plugin, _, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, _, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(false) @@ -169,7 +200,7 @@ func TestLinuxConfiguratorAddVethPairVethNsNotAvailable(t *testing.T) { Expect(data).ToNot(BeNil()) // Configure second veth err = plugin.ConfigureLinuxInterface(getVethInterface("veth2", "veth1", 1)) - Expect(err).ShouldNot(HaveOccurred()) + Expect(err).Should(HaveOccurred()) data, found = plugin.GetInterfaceByNameCache()["veth2"] Expect(found).To(BeTrue()) Expect(data).ToNot(BeNil()) @@ -185,8 +216,8 @@ func TestLinuxConfiguratorAddVethPairVethNsNotAvailable(t *testing.T) { // Configure simple Veth with peer while peer ns is not available func TestLinuxConfiguratorAddVethPairPeerNsNotAvailable(t *testing.T) { - plugin, _, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, _, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -200,7 +231,7 @@ func TestLinuxConfiguratorAddVethPairPeerNsNotAvailable(t *testing.T) { Expect(data).ToNot(BeNil()) // Configure second veth err = plugin.ConfigureLinuxInterface(getVethInterface("veth2", "veth1", 1)) - Expect(err).ShouldNot(HaveOccurred()) + Expect(err).Should(HaveOccurred()) data, found = plugin.GetInterfaceByNameCache()["veth2"] Expect(found).To(BeTrue()) Expect(data).ToNot(BeNil()) @@ -216,8 +247,8 @@ func TestLinuxConfiguratorAddVethPairPeerNsNotAvailable(t *testing.T) { // Configure simple Veth with peer while switching ns returns error func TestLinuxConfiguratorAddVethPairSwitchNsError(t *testing.T) { - plugin, _, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, _, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -237,13 +268,31 @@ func TestLinuxConfiguratorAddVethPairSwitchNsError(t *testing.T) { // Configure simple Veth with peer while peer ns is not available func TestLinuxConfiguratorAddVethPairPeerSwitchToNsWhileRemovingObsoleteErr(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) nsMock.When("IsNamespaceAvailable").ThenReturn(true) nsMock.When("SwitchToNamespace").ThenReturn(fmt.Errorf("remove-obsolete-1-err")) + nsMock.When("ConvertMicroserviceNsToPidNs").ThenReturn(&nsplugin.Namespace{ + Type: nsplugin.PidRefNs, + }, + ) + nsMock.When("ConvertMicroserviceNsToPidNs").ThenReturn(&nsplugin.Namespace{ + Type: nsplugin.PidRefNs, + }, + ) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v2", + }, + }) ifMock.When("GetInterfaceByName").ThenReturn(&net.Interface{ Index: 1, }) @@ -263,12 +312,30 @@ func TestLinuxConfiguratorAddVethPairPeerSwitchToNsWhileRemovingObsoleteErr(t *t // Configure simple Veth with peer while there is an obsolete veth which needs to be removed. Covers all 4 cases. func TestLinuxConfiguratorAddVethPairPeerRemoveObsolete(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) nsMock.When("IsNamespaceAvailable").ThenReturn(true) + nsMock.When("ConvertMicroserviceNsToPidNs").ThenReturn(&nsplugin.Namespace{ + Type: nsplugin.PidRefNs, + }, + ) + nsMock.When("ConvertMicroserviceNsToPidNs").ThenReturn(&nsplugin.Namespace{ + Type: nsplugin.PidRefNs, + }, + ) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Veth{ + LinkAttrs: netlink.LinkAttrs{ + Name: "v2", + }, + }) // First obsolete veth removal ifMock.When("InterfaceExists").ThenReturn(true) ifMock.When("GetInterfaceType").ThenReturn("veth") @@ -305,8 +372,8 @@ func TestLinuxConfiguratorAddVethPairPeerRemoveObsolete(t *testing.T) { // Configure simple Veth with peer while there is an obsolete veth - interface exists error func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteIfExistsError(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -326,8 +393,8 @@ func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteIfExistsError(t *testing. // Configure simple Veth with peer while there is an obsolete veth - interface type error func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteIfTypeError(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -348,8 +415,8 @@ func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteIfTypeError(t *testing.T) // Configure simple Veth with peer while there is an obsolete veth - interface type does not match error func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteIfTypeMatchError(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -374,8 +441,8 @@ func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteIfTypeMatchError(t *testi // Configure simple Veth with peer while there is an obsolete veth - get peer name error func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteGetPeerNameError(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -405,8 +472,8 @@ func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteGetPeerNameError(t *testi // Configure simple Veth with peer while there is an obsolete veth - delete obsotele interface error func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteDeletePeerNameError(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -444,8 +511,8 @@ func TestLinuxConfiguratorAddVethPairPeerRemoveObsoleteDeletePeerNameError(t *te // Configure simple Veth with peer - add veth pair error func TestLinuxConfiguratorAddVethPairError(t *testing.T) { - plugin, ifMock, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) @@ -462,48 +529,282 @@ func TestLinuxConfiguratorAddVethPairError(t *testing.T) { // Configure Tap with hostIfName func TestLinuxConfiguratorAddTap_TempIfName(t *testing.T) { - plugin, _, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) + // Link is searched for twice + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + ifMock.When("GetInterfaceByName").ThenReturn(&net.Interface{ + Index: 10, + }) data := getTapInterface("tap1", "", "TempIfName") err := plugin.ConfigureLinuxInterface(data) Expect(err).ShouldNot(HaveOccurred()) - Expect(plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames()).To(HaveLen(0)) - Expect(plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames()).To(HaveLen(1)) + Expect(plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames()).To(HaveLen(0)) + Expect(plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames()).To(HaveLen(1)) // Verify registration - _, metadata, found := plugin.GetCachedLinuxIfIndexes().LookupIdx("TempIfName") + _, metadata, found := plugin.GetLinuxInterfaceIndexes().LookupIdx("tap1") Expect(found).To(BeTrue()) Expect(metadata).ToNot(BeNil()) } // Configure Tap with hostIfName func TestLinuxConfiguratorAddTap_HostIfName(t *testing.T) { - plugin, _, nsMock, msChan, msNotif := ifTestSetup(t) - defer ifTestTeardown(plugin, msChan, msNotif) + plugin, ifMock, nsMock, _, msChan, msNotif, ifnotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifnotif) // Linux/namespace calls nsMock.When("IsNamespaceAvailable").ThenReturn(true) + // Link is searched for twice + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + ifMock.When("GetInterfaceByName").ThenReturn(&net.Interface{ + Index: 10, + }) data := getTapInterface("tap1", "HostIfName", "") err := plugin.ConfigureLinuxInterface(data) Expect(err).ShouldNot(HaveOccurred()) - Expect(plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames()).To(HaveLen(0)) - Expect(plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames()).To(HaveLen(1)) + Expect(plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames()).To(HaveLen(0)) + Expect(plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames()).To(HaveLen(1)) // Verify registration - _, metadata, found := plugin.GetCachedLinuxIfIndexes().LookupIdx("HostIfName") + _, metadata, found := plugin.GetLinuxInterfaceIndexes().LookupIdx("tap1") Expect(found).To(BeTrue()) Expect(metadata).ToNot(BeNil()) } +// Configure linux tap where interface is registered but does not exist yet. Then use event to start +// configuration again +func TestLinuxConfiguratorAddTapTempIfNameWithWatcher(t *testing.T) { + plugin, ifMock, nsMock, _, msChan, msNotif, ifNotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifNotif) + + // Linux/namespace calls + nsMock.When("IsNamespaceAvailable").ThenReturn(true) + ifMock.When("GetLinkByName").ThenReturn(errors.New(ifplugin.LinkNotFoundErr)) + // Link is searched for twice + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + // Watcher + ifMock.When("GetInterfaceByName").ThenReturn(&net.Interface{ + Index: 10, + }) + + data := getTapInterface("tap1", "", "TempIfName") + err := plugin.ConfigureLinuxInterface(data) + Expect(err).ShouldNot(HaveOccurred()) + Expect(plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames()).To(HaveLen(1)) + Expect(plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames()).To(HaveLen(0)) + // Verify interface registration and empty cache + _, metadata, found := plugin.GetCachedLinuxIfIndexes().LookupIdx("TempIfName") + Expect(found).To(BeTrue()) + Expect(metadata).ToNot(BeNil()) + // Give some time to watcher to start + time.Sleep(500 * time.Millisecond) + // Send event that interface appeared in linux + ifNotif <- ifplugin.NewLinuxInterfaceStateNotification("tun", netlink.OperUp, &netlink.LinkAttrs{ + Name: "TempIfName", + }) + Eventually(func() []string { + return plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames() + }, 2).Should(HaveLen(0)) + Eventually(func() []string { + return plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames() + }, 2).Should(HaveLen(1)) + Eventually(func() bool { + _, _, found = plugin.GetLinuxInterfaceIndexes().LookupIdx("tap1") + return found + }, 2).Should(BeTrue()) +} + +// Configure linux tap where interface was created but then an event about its removal arrived. +func TestLinuxConfiguratorRemoveTapHostIfNameWithWatcher(t *testing.T) { + plugin, ifMock, nsMock, _, msChan, msNotif, ifNotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifNotif) + + // Linux/namespace calls + nsMock.When("IsNamespaceAvailable").ThenReturn(true) + // Link is searched for twice + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "t1", + }, + }) + ifMock.When("GetInterfaceByName").ThenReturn(&net.Interface{ + Index: 10, + }) + + data := getTapInterface("tap1", "", "TempIfName") + err := plugin.ConfigureLinuxInterface(data) + Expect(err).ShouldNot(HaveOccurred()) + Expect(plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames()).To(HaveLen(0)) + Expect(plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames()).To(HaveLen(1)) + // Verify cache registration + _, metadata, found := plugin.GetLinuxInterfaceIndexes().LookupIdx("tap1") + Expect(found).To(BeTrue()) + Expect(metadata).ToNot(BeNil()) + // Give some time to watcher to start + time.Sleep(500 * time.Millisecond) + // Send event that interface appeared in linux + ifNotif <- ifplugin.NewLinuxInterfaceStateNotification("tun", netlink.OperDown, &netlink.LinkAttrs{ + Name: "tap1", + }) + Eventually(func() []string { + return plugin.GetLinuxInterfaceIndexes().GetMapping().ListNames() + }, 2).Should(HaveLen(0)) + Eventually(func() []string { + return plugin.GetCachedLinuxIfIndexes().GetMapping().ListNames() + }, 2).Should(HaveLen(1)) + Eventually(func() bool { + _, _, found = plugin.GetCachedLinuxIfIndexes().LookupIdx("tap1") + return found + }, 2).Should(BeTrue()) +} + +/* Namespace handler Test Setup */ + +func TestSetInterfaceNamespace(t *testing.T) { + plugin, ifMock, _, sysMock, msChan, msNotif, ifNotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifNotif) + + // IP address list + var ipAddresses []netlink.Addr + ipAddresses = append(ipAddresses, + netlink.Addr{IPNet: getIPNetAddress("10.0.0.1/24")}, + netlink.Addr{IPNet: getIPNetAddress("172.168.0.1/24")}, + netlink.Addr{IPNet: getIPNetAddress("192.168.0.1/24")}, + // Link local address which should be skipped + netlink.Addr{IPNet: getIPNetAddress("fe80::883f:c3ff:fe9e:fba/64")}) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "if1", + Flags: net.FlagUp, + }, + }) + ifMock.When("GetAddressList").ThenReturn(ipAddresses) + sysMock.When("LinkSetNsFd").ThenReturn() + + // Context and namespace + ctx := nsplugin.NewNamespaceMgmtCtx() + ns := &interfaces.LinuxInterfaces_Interface_Namespace{ + Type: interfaces.LinuxInterfaces_Interface_Namespace_NAMED_NS, + } + + err := ifplugin.SetInterfaceNamespace(plugin, ctx, "if1", ns) + Expect(err).To(BeNil()) + + // Check calls to ensure that only required IP addresses were configured + num, calls := ifMock.GetCallsFor("AddInterfaceIP") + Expect(num).To(Equal(3)) + Expect(calls).ToNot(BeNil()) + for callIdx, call := range calls { + ifName := call[0].(string) + Expect(ifName).To(Equal("if1")) + ipAdd := call[1].(*net.IPNet) + if callIdx == 1 { + Expect(ipAdd.String()).To(Equal("10.0.0.1/24")) + } + if callIdx == 2 { + Expect(ipAdd.String()).To(Equal("172.168.0.1/24")) + } + if callIdx == 3 { + Expect(ipAdd.String()).To(Equal("192.168.0.1/24")) + } + } +} + +func TestSetInterfaceNamespaceIPv6(t *testing.T) { + plugin, ifMock, _, sysMock, msChan, msNotif, ifNotif := ifTestSetup(t) + defer ifTestTeardown(plugin, msChan, msNotif, ifNotif) + + // IP address list + var ipAddresses []netlink.Addr + ipAddresses = append(ipAddresses, + netlink.Addr{IPNet: getIPNetAddress("10.0.0.1/24")}, + netlink.Addr{IPNet: getIPNetAddress("172.168.0.1/24")}, + // Link local address should not be skipped if there is another non-link-local IPv6 + netlink.Addr{IPNet: getIPNetAddress("fe80::883f:c3ff:fe9e:fba/64")}, + netlink.Addr{IPNet: getIPNetAddress("ad48::42:e8ff:feb1:e976/64")}) + ifMock.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ + LinkAttrs: netlink.LinkAttrs{ + Name: "if1", + Flags: net.FlagUp, + }, + }) + ifMock.When("GetAddressList").ThenReturn(ipAddresses) + sysMock.When("LinkSetNsFd").ThenReturn() + + // Context and namespace + ctx := nsplugin.NewNamespaceMgmtCtx() + ns := &interfaces.LinuxInterfaces_Interface_Namespace{ + Type: interfaces.LinuxInterfaces_Interface_Namespace_NAMED_NS, + } + + err := ifplugin.SetInterfaceNamespace(plugin, ctx, "if1", ns) + Expect(err).To(BeNil()) + + // Check calls to ensure that only required IP addresses were configured + num, calls := ifMock.GetCallsFor("AddInterfaceIP") + Expect(num).To(Equal(4)) + Expect(calls).ToNot(BeNil()) + for callIdx, call := range calls { + ifName := call[0].(string) + Expect(ifName).To(Equal("if1")) + ipAdd := call[1].(*net.IPNet) + if callIdx == 1 { + Expect(ipAdd.String()).To(Equal("10.0.0.1/24")) + } + if callIdx == 2 { + Expect(ipAdd.String()).To(Equal("172.168.0.1/24")) + } + if callIdx == 3 { + Expect(ipAdd.String()).To(Equal("fe80::883f:c3ff:fe9e:fba/64")) + } + if callIdx == 4 { + Expect(ipAdd.String()).To(Equal("ad48::42:e8ff:feb1:e976/64")) + } + } +} + // Todo /* Interface Test Setup */ func ifTestSetup(t *testing.T) (*ifplugin.LinuxInterfaceConfigurator, *linuxmock.IfNetlinkHandlerMock, *linuxmock.NamespacePluginMock, - chan *nsplugin.MicroserviceCtx, chan *nsplugin.MicroserviceEvent) { + *linuxmock.SystemMock, chan *nsplugin.MicroserviceCtx, chan *nsplugin.MicroserviceEvent, chan *ifplugin.LinuxInterfaceStateNotification) { RegisterTestingT(t) // Loggers @@ -515,24 +816,23 @@ func ifTestSetup(t *testing.T) (*ifplugin.LinuxInterfaceConfigurator, *linuxmock swIfIndexes := ifaceidx.NewLinuxIfIndex(nametoidx.NewNameToIdx(pluginLog, "if", nil)) msChan := make(chan *nsplugin.MicroserviceCtx, 100) ifMicroserviceNotif := make(chan *nsplugin.MicroserviceEvent, 100) + ifNotif := make(chan *ifplugin.LinuxInterfaceStateNotification, 100) // Configurator plugin := &ifplugin.LinuxInterfaceConfigurator{} linuxMock := linuxmock.NewIfNetlinkHandlerMock() nsMock := linuxmock.NewNamespacePluginMock() - err := plugin.Init(pluginLog, linuxMock, nsMock, swIfIndexes, - ifMicroserviceNotif, measure.NewStopwatch("LinuxIfTest", pluginLog)) + sysMock := linuxmock.NewSystemMock() + err := plugin.Init(pluginLog, linuxMock, nsMock, sysMock, swIfIndexes, ifMicroserviceNotif, ifNotif) Expect(err).To(BeNil()) - return plugin, linuxMock, nsMock, msChan, ifMicroserviceNotif + return plugin, linuxMock, nsMock, sysMock, msChan, ifMicroserviceNotif, ifNotif } func ifTestTeardown(plugin *ifplugin.LinuxInterfaceConfigurator, - msChan chan *nsplugin.MicroserviceCtx, msNotif chan *nsplugin.MicroserviceEvent) { - err := safeclose.Close(msNotif) - Expect(err).To(BeNil()) - err = safeclose.Close(msChan) + msChan chan *nsplugin.MicroserviceCtx, msNotif chan *nsplugin.MicroserviceEvent, ifNotif chan *ifplugin.LinuxInterfaceStateNotification) { + err := plugin.Close() Expect(err).To(BeNil()) - err = plugin.Close() + err = safeclose.Close(msNotif, msChan, ifNotif) Expect(err).To(BeNil()) logging.DefaultRegistry.ClearRegistry() } @@ -575,3 +875,10 @@ func getTapInterface(ifName, hostIfName string, tempIfName string) *interfaces.L }, } } + +func getIPNetAddress(ipAddr string) *net.IPNet { + ip, ipNet, err := net.ParseCIDR(ipAddr) + ipNet.IP = ip + Expect(err).To(BeNil()) + return ipNet +} diff --git a/plugins/linux/ifplugin/interface_stage.go b/plugins/linux/ifplugin/interface_stage.go deleted file mode 100644 index 5d84bf0ab0..0000000000 --- a/plugins/linux/ifplugin/interface_stage.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2018 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 ifplugin - -import ( - "context" - "sync" - - "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/utils/safeclose" - "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" - "github.com/vishvananda/netlink" -) - -// LinuxInterfaceStateNotification aggregates operational status derived from netlink with -// the details (state) about the interface. -type LinuxInterfaceStateNotification struct { - // State of the network interface - interfaceType string - interfaceState netlink.LinkOperState - attributes *netlink.LinkAttrs -} - -// LinuxInterfaceStateUpdater processes all linux interface state data -type LinuxInterfaceStateUpdater struct { - log logging.Logger - cfgLock sync.Mutex - - // Go routine management - wg sync.WaitGroup - - // Linux interface state - stateWatcherRunning bool - ifStateChan chan *LinuxInterfaceStateNotification - ifWatcherNotifCh chan netlink.LinkUpdate - ifWatcherDoneCh chan struct{} -} - -// Init channels for interface state watcher, start it in separate go routine and subscribe to default namespace -func (plugin *LinuxInterfaceStateUpdater) Init(ctx context.Context, logger logging.PluginLogger, ifIndexes ifaceidx.LinuxIfIndexRW, - stateChan chan *LinuxInterfaceStateNotification) error { - // Logger - plugin.log = logger.NewLogger("-if-state") - plugin.log.Debug("Initializing Linux Interface State Updater") - - // Channels - plugin.ifStateChan = stateChan - plugin.ifWatcherNotifCh = make(chan netlink.LinkUpdate, 10) - plugin.ifWatcherDoneCh = make(chan struct{}) - - // Start watch on linux interfaces - go plugin.watchLinuxInterfaces(ctx) - - // Subscribe to default linux namespace - return plugin.subscribeInterfaceState() -} - -// Close watcher channel (state chan is closed in LinuxInterfaceConfigurator) -func (plugin *LinuxInterfaceStateUpdater) Close() error { - return safeclose.Close(plugin.ifWatcherNotifCh, plugin.ifWatcherDoneCh) -} - -// Subscribe to linux default namespace -func (plugin *LinuxInterfaceStateUpdater) subscribeInterfaceState() error { - if !plugin.stateWatcherRunning { - plugin.stateWatcherRunning = true - err := netlink.LinkSubscribe(plugin.ifWatcherNotifCh, plugin.ifWatcherDoneCh) - if err != nil { - return err - } - } - return nil -} - -// Watch linux interfaces and send events to processing -func (plugin *LinuxInterfaceStateUpdater) watchLinuxInterfaces(ctx context.Context) { - plugin.log.Debugf("Watching on linux link notifications") - - plugin.wg.Add(1) - defer plugin.wg.Done() - - for { - select { - case linkNotif := <-plugin.ifWatcherNotifCh: - plugin.processLinkNotification(linkNotif) - - case <-ctx.Done(): - close(plugin.ifWatcherDoneCh) - return - } - } -} - -// Prepare notification and send it to the state channel -func (plugin *LinuxInterfaceStateUpdater) processLinkNotification(link netlink.Link) { - linkAttrs := link.Attrs() - - if linkAttrs == nil { - return - } - - plugin.cfgLock.Lock() - defer plugin.cfgLock.Unlock() - - plugin.log.Debugf("Processing Linux link update: Name=%v Type=%v OperState=%v Index=%v HwAddr=%v", - linkAttrs.Name, link.Type(), linkAttrs.OperState, linkAttrs.Index, linkAttrs.HardwareAddr) - - // Prepare linux link notification - linkNotif := &LinuxInterfaceStateNotification{ - interfaceType: link.Type(), - interfaceState: linkAttrs.OperState, - attributes: link.Attrs(), - } - - select { - case plugin.ifStateChan <- linkNotif: - // Notification sent - default: - plugin.log.Warn("Unable to send to the linux if state notification channel - buffer is full.") - } -} diff --git a/plugins/linux/ifplugin/interface_state.go b/plugins/linux/ifplugin/interface_state.go new file mode 100644 index 0000000000..b8c35e1234 --- /dev/null +++ b/plugins/linux/ifplugin/interface_state.go @@ -0,0 +1,155 @@ +// Copyright (c) 2018 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 ifplugin + +import ( + "context" + "sync" + + "github.com/go-errors/errors" + "github.com/ligato/cn-infra/logging" + "github.com/ligato/cn-infra/utils/safeclose" + "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" + "github.com/vishvananda/netlink" +) + +// LinuxInterfaceStateNotification aggregates operational status derived from netlink with +// the details (state) about the interface. +type LinuxInterfaceStateNotification struct { + // State of the network interface + interfaceType string + interfaceState netlink.LinkOperState + attributes *netlink.LinkAttrs +} + +// LinuxInterfaceStateUpdater processes all linux interface state data +type LinuxInterfaceStateUpdater struct { + log logging.Logger + cfgLock sync.Mutex + + // Go routine management + wg sync.WaitGroup + + // Linux interface state + stateWatcherRunning bool + ifStateChan chan *LinuxInterfaceStateNotification + ifWatcherNotifCh chan netlink.LinkUpdate + ifWatcherDoneCh chan struct{} +} + +// Init channels for interface state watcher, start it in separate go routine and subscribe to default namespace +func (c *LinuxInterfaceStateUpdater) Init(ctx context.Context, logger logging.PluginLogger, ifIndexes ifaceidx.LinuxIfIndexRW, + stateChan chan *LinuxInterfaceStateNotification) error { + // Logger + c.log = logger.NewLogger("if-state") + + // Channels + c.ifStateChan = stateChan + c.ifWatcherNotifCh = make(chan netlink.LinkUpdate, 10) + c.ifWatcherDoneCh = make(chan struct{}) + + // Start watch on linux interfaces + go c.watchLinuxInterfaces(ctx) + + // Subscribe to default linux namespace + if err := c.subscribeInterfaceState(); err != nil { + return errors.Errorf("failed to subscribe interface state: %v", err) + } + + c.log.Debug("Linux interface state updater initialized") + + return nil +} + +// Close watcher channel (state chan is closed in LinuxInterfaceConfigurator) +func (c *LinuxInterfaceStateUpdater) Close() error { + if err := safeclose.Close(c.ifWatcherNotifCh); err != nil { + return errors.Errorf("failed to safeclose linux interface state updater: %v", err) + } + return nil +} + +// NewLinuxInterfaceStateNotification builds up new linux interface notification object +func NewLinuxInterfaceStateNotification(ifType string, ifState netlink.LinkOperState, attrs *netlink.LinkAttrs) *LinuxInterfaceStateNotification { + return &LinuxInterfaceStateNotification{ + interfaceType: ifType, + interfaceState: ifState, + attributes: attrs, + } +} + +// Subscribe to linux default namespace +func (c *LinuxInterfaceStateUpdater) subscribeInterfaceState() error { + if !c.stateWatcherRunning { + c.stateWatcherRunning = true + err := netlink.LinkSubscribe(c.ifWatcherNotifCh, c.ifWatcherDoneCh) + if err != nil { + return errors.Errorf("failed to subscribe link: %v", err) + } + } + return nil +} + +// Watch linux interfaces and send events to processing +func (c *LinuxInterfaceStateUpdater) watchLinuxInterfaces(ctx context.Context) { + c.log.Debugf("Watching on linux link notifications") + + c.wg.Add(1) + defer c.wg.Done() + + for { + select { + case linkNotif := <-c.ifWatcherNotifCh: + c.processLinkNotification(linkNotif) + + case <-ctx.Done(): + close(c.ifWatcherDoneCh) + close(c.ifStateChan) + return + } + } +} + +// Prepare notification and send it to the state channel +func (c *LinuxInterfaceStateUpdater) processLinkNotification(link netlink.Link) { + if link == nil || link.Attrs() == nil { + return + } + + c.cfgLock.Lock() + defer c.cfgLock.Unlock() + + select { + // Prepare and send linux link notification + case c.ifStateChan <- NewLinuxInterfaceStateNotification(link.Type(), link.Attrs().OperState, link.Attrs()): + // Notification sent + default: + c.log.Warn("Unable to send to the linux if state notification channel - buffer is full.") + } +} + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *LinuxInterfaceStateUpdater) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/linux/ifplugin/linuxcalls/admin_linuxcalls.go b/plugins/linux/ifplugin/linuxcalls/admin_linuxcalls.go index 5a6847baa8..c0d5e21928 100644 --- a/plugins/linux/ifplugin/linuxcalls/admin_linuxcalls.go +++ b/plugins/linux/ifplugin/linuxcalls/admin_linuxcalls.go @@ -14,34 +14,14 @@ // +build !windows,!darwin -// Copyright (c) 2017 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 linuxcalls import ( - "time" - "github.com/vishvananda/netlink" ) // SetInterfaceDown calls Netlink API LinkSetDown. func (handler *NetLinkHandler) SetInterfaceDown(ifName string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("interface-admin-down").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return err @@ -51,10 +31,6 @@ func (handler *NetLinkHandler) SetInterfaceDown(ifName string) error { // SetInterfaceUp calls Netlink API LinkSetUp. func (handler *NetLinkHandler) SetInterfaceUp(ifName string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("interface-admin-up").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return err diff --git a/plugins/linux/ifplugin/linuxcalls/dump_link_linuxcalls.go b/plugins/linux/ifplugin/linuxcalls/dump_link_linuxcalls.go new file mode 100644 index 0000000000..c3bf5a367f --- /dev/null +++ b/plugins/linux/ifplugin/linuxcalls/dump_link_linuxcalls.go @@ -0,0 +1,188 @@ +// Copyright (c) 2018 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 linuxcalls + +import ( + "github.com/go-errors/errors" + "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" + "github.com/ligato/vpp-agent/plugins/linux/nsplugin" + "github.com/vishvananda/netlink" +) + +// LinuxInterfaceDetails is the wrapper structure for the linux interface northbound API structure. +type LinuxInterfaceDetails struct { + Interface *interfaces.LinuxInterfaces_Interface `json:"linux_interface"` + Meta *LinuxInterfaceMeta `json:"linux_interface_meta"` +} + +// LinuxInterfaceMeta is combination of proto-modelled Interface data and linux provided metadata +type LinuxInterfaceMeta struct { + Index int `json:"index"` + Name string `json:"name"` + Alias string `json:"alias"` + OperState string `json:"oper_state"` + Flags string `json:"flags"` + MacAddr string `json:"mac_addr"` + Mtu int `json:"mtu"` + Type string `json:"type"` + NetNsID int `json:"net_ns_id"` + NumTxQueues int `json:"num_tx_queues"` + TxQueueLen int `json:"tx_queue_len"` + NumRxQueues int `json:"num_rx_queues"` +} + +// DumpInterfaces is an implementation of linux interface handler +func (h *NetLinkHandler) DumpInterfaces() ([]*LinuxInterfaceDetails, error) { + var ifs []*LinuxInterfaceDetails + + ctx := nsplugin.NewNamespaceMgmtCtx() + + // Vpp-agent should know all the configured interfaces, and all the interfaces from default namespace. Use index + // map to iterate over them + for _, ifName := range h.ifIndexes.GetMapping().ListNames() { + ifDetails := &LinuxInterfaceDetails{} + + _, meta, found := h.ifIndexes.LookupIdx(ifName) + if !found { + h.log.Warnf("Expected interface %s not found in the mapping", ifName) + continue + } + if meta == nil || meta.Data == nil { + h.log.Warnf("Expected interface %s metadata are missing", ifName) + continue + } + + // Copy base configuration from mapping metadata. Linux specific fields are stored in LinuxInterfaceMeta. + ifDetails.Interface = meta.Data + + // Check the interface namespace + link, linkAddrs, err := h.dumpInterfaceData(ifName, h.nsHandler.IfNsToGeneric(meta.Data.Namespace), ctx) + if err != nil { + // Do not return error, read what is possible + h.log.Errorf("failed to get interface %s data: %v", ifName, err) + continue + } + + if link == nil || link.Attrs() == nil { + h.log.Warnf("Unable to get link data for interface %s", ifName) + continue + } + + linkAttrs := link.Attrs() + // Base fields + linuxMeta := &LinuxInterfaceMeta{ + Index: linkAttrs.Index, + Name: linkAttrs.Name, + Alias: linkAttrs.Alias, + OperState: linkAttrs.OperState.String(), + Flags: linkAttrs.Flags.String(), + Mtu: linkAttrs.MTU, + Type: linkAttrs.EncapType, + NetNsID: linkAttrs.NetNsID, + NumTxQueues: linkAttrs.NumTxQueues, + TxQueueLen: linkAttrs.TxQLen, + NumRxQueues: linkAttrs.NumRxQueues, + } + + // IP addresses + var ipAddrs []string + for _, linkAddr := range linkAddrs { + ipAddrs = append(ipAddrs, linkAddr.String()) + } + + // MAC address + if linkAttrs.HardwareAddr != nil { + linuxMeta.MacAddr = linkAttrs.HardwareAddr.String() + } + + ifDetails.Meta = linuxMeta + ifs = append(ifs, ifDetails) + } + + return ifs, nil +} + +// LinuxInterfaceStatistics returns linux interface name/index with statistics data +type LinuxInterfaceStatistics struct { + Name string + Index int + Statistics *netlink.LinkStatistics +} + +// DumpInterfaceStatistics is an implementation of linux interface handler +func (h *NetLinkHandler) DumpInterfaceStatistics() ([]*LinuxInterfaceStatistics, error) { + var ifs []*LinuxInterfaceStatistics + + ctx := nsplugin.NewNamespaceMgmtCtx() + + // Iterate over all known interfaces + for _, ifName := range h.ifIndexes.GetMapping().ListNames() { + _, meta, found := h.ifIndexes.LookupIdx(ifName) + if !found { + h.log.Warnf("Expected interface %s not found in the mapping", ifName) + continue + } + if meta == nil || meta.Data == nil { + h.log.Warnf("Expected interface %s metadata are missing", ifName) + continue + } + + // Check the interface namespace + link, _, err := h.dumpInterfaceData(ifName, h.nsHandler.IfNsToGeneric(meta.Data.Namespace), ctx) + if err != nil { + // Do not return error, read what is possible + h.log.Errorf("failed to get interface %s data: %v", ifName, err) + continue + } + + if link == nil || link.Attrs() == nil { + h.log.Warnf("Unable to get link data for interface %s", ifName) + continue + } + + linkAttrs := link.Attrs() + + // Fill data + linuxStats := &LinuxInterfaceStatistics{ + Name: linkAttrs.Name, + Index: linkAttrs.Index, + Statistics: linkAttrs.Statistics, + } + + ifs = append(ifs, linuxStats) + } + + return ifs, nil +} + +// Reads interface data and ip addresses from provided namespace +func (h *NetLinkHandler) dumpInterfaceData(ifName string, ns *nsplugin.Namespace, ctx *nsplugin.NamespaceMgmtCtx) (netlink.Link, []netlink.Addr, error) { + revert, err := h.nsHandler.SwitchNamespace(ns, ctx) + defer revert() + + if err != nil { + return nil, nil, errors.Errorf("failed to switch to namespace %s: %v", ns.Name, err) + } + link, err := h.GetLinkByName(ifName) + if err != nil { + return nil, nil, errors.Errorf("failed to get interface %s from namespace %s: %v", ifName, ns.Name, err) + } + linkAddrs, err := h.GetAddressList(ifName) + if err != nil { + return nil, nil, errors.Errorf("failed to get interface %s addresses: %v", ifName, err) + } + + return link, linkAddrs, nil +} diff --git a/plugins/linux/ifplugin/linuxcalls/ip_linuxcalls.go b/plugins/linux/ifplugin/linuxcalls/ip_linuxcalls.go index 1fccb48681..aa767d1ead 100644 --- a/plugins/linux/ifplugin/linuxcalls/ip_linuxcalls.go +++ b/plugins/linux/ifplugin/linuxcalls/ip_linuxcalls.go @@ -14,35 +14,16 @@ // +build !windows,!darwin -// Copyright (c) 2017 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 linuxcalls import ( "net" - "time" "github.com/vishvananda/netlink" ) // GetAddressList calls AddrList netlink API func (handler *NetLinkHandler) GetAddressList(ifName string) ([]netlink.Addr, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("get-address-list").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return nil, err @@ -53,10 +34,6 @@ func (handler *NetLinkHandler) GetAddressList(ifName string) ([]netlink.Addr, er // AddInterfaceIP calls AddrAdd Netlink API. func (handler *NetLinkHandler) AddInterfaceIP(ifName string, addr *net.IPNet) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("add-interface-ip").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return err @@ -67,10 +44,6 @@ func (handler *NetLinkHandler) AddInterfaceIP(ifName string, addr *net.IPNet) er // DelInterfaceIP calls AddrDel Netlink API. func (handler *NetLinkHandler) DelInterfaceIP(ifName string, addr *net.IPNet) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("del-interface-ip").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return err @@ -81,10 +54,6 @@ func (handler *NetLinkHandler) DelInterfaceIP(ifName string, addr *net.IPNet) er // SetInterfaceMTU calls LinkSetMTU Netlink API. func (handler *NetLinkHandler) SetInterfaceMTU(ifName string, mtu int) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("set-interface-mtu").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return err diff --git a/plugins/linux/ifplugin/linuxcalls/link_linuxcalls.go b/plugins/linux/ifplugin/linuxcalls/link_linuxcalls.go index 5a51ffb368..8972c72ac1 100644 --- a/plugins/linux/ifplugin/linuxcalls/link_linuxcalls.go +++ b/plugins/linux/ifplugin/linuxcalls/link_linuxcalls.go @@ -14,53 +14,26 @@ // +build !windows,!darwin -// Copyright (c) 2017 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 linuxcalls import ( "net" - "time" "github.com/vishvananda/netlink" ) // GetLinkByName calls netlink API to get Link type from interface name func (handler *NetLinkHandler) GetLinkByName(ifName string) (netlink.Link, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("get-link-from-interface").LogTimeEntry(time.Since(t)) - }(time.Now()) - return netlink.LinkByName(ifName) } // GetLinkList calls netlink API to get all Links in namespace func (handler *NetLinkHandler) GetLinkList() ([]netlink.Link, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("get-link-list").LogTimeEntry(time.Since(t)) - }(time.Now()) - return netlink.LinkList() } // GetInterfaceType returns the type (string representation) of a given interface. func (handler *NetLinkHandler) GetInterfaceType(ifName string) (string, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("get-interface-type").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return "", err @@ -70,10 +43,6 @@ func (handler *NetLinkHandler) GetInterfaceType(ifName string) (string, error) { // InterfaceExists checks if interface with a given name exists. func (handler *NetLinkHandler) InterfaceExists(ifName string) (bool, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("interface-exists").LogTimeEntry(time.Since(t)) - }(time.Now()) - _, err := handler.GetLinkByName(ifName) if err == nil { return true, nil @@ -86,10 +55,6 @@ func (handler *NetLinkHandler) InterfaceExists(ifName string) (bool, error) { // RenameInterface changes the name of the interface to . func (handler *NetLinkHandler) RenameInterface(ifName string, newName string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("rename-interface").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return err @@ -111,9 +76,5 @@ func (handler *NetLinkHandler) RenameInterface(ifName string, newName string) er // GetInterfaceByName return *net.Interface type from interface name func (handler *NetLinkHandler) GetInterfaceByName(ifName string) (*net.Interface, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("get-interface-by-name").LogTimeEntry(time.Since(t)) - }(time.Now()) - return net.InterfaceByName(ifName) } diff --git a/plugins/linux/ifplugin/linuxcalls/mac_linuxcalls.go b/plugins/linux/ifplugin/linuxcalls/mac_linuxcalls.go index 11540d71c3..6f47cf5cc6 100644 --- a/plugins/linux/ifplugin/linuxcalls/mac_linuxcalls.go +++ b/plugins/linux/ifplugin/linuxcalls/mac_linuxcalls.go @@ -14,35 +14,15 @@ // +build !windows,!darwin -// Copyright (c) 2017 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 linuxcalls import ( - "net" - "time" - "github.com/vishvananda/netlink" + "net" ) // SetInterfaceMac calls LinkSetHardwareAddr netlink API. func (handler *NetLinkHandler) SetInterfaceMac(ifName string, macAddress string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("set-interface-mac").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return err diff --git a/plugins/linux/ifplugin/linuxcalls/mock_linuxcalls.go b/plugins/linux/ifplugin/linuxcalls/mock_linuxcalls.go index 1396e48d1e..a184e60446 100644 --- a/plugins/linux/ifplugin/linuxcalls/mock_linuxcalls.go +++ b/plugins/linux/ifplugin/linuxcalls/mock_linuxcalls.go @@ -14,20 +14,6 @@ // +build windows darwin -// Copyright (c) 2017 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 linuxcalls import ( diff --git a/plugins/linux/ifplugin/linuxcalls/netlink_api.go b/plugins/linux/ifplugin/linuxcalls/netlink_api.go index 7ee532748c..578ca56ec0 100644 --- a/plugins/linux/ifplugin/linuxcalls/netlink_api.go +++ b/plugins/linux/ifplugin/linuxcalls/netlink_api.go @@ -17,12 +17,21 @@ package linuxcalls import ( "net" - "github.com/ligato/cn-infra/logging/measure" "github.com/vishvananda/netlink" + + "github.com/ligato/cn-infra/logging" + "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" + "github.com/ligato/vpp-agent/plugins/linux/nsplugin" ) // NetlinkAPI interface covers all methods inside linux calls package needed to manage linux interfaces. type NetlinkAPI interface { + NetlinkAPIWrite + NetlinkAPIRead +} + +// NetlinkAPIWrite interface covers write methods inside linux calls package needed to manage linux interfaces. +type NetlinkAPIWrite interface { // AddVethInterfacePair configures two connected VETH interfaces AddVethInterfacePair(ifName, peerIfName string) error // DelVethInterfacePair removes VETH pair @@ -41,30 +50,42 @@ type NetlinkAPI interface { SetInterfaceMTU(ifName string, mtu int) error // RenameInterface changes interface host name RenameInterface(ifName string, newName string) error +} + +// NetlinkAPIRead interface covers read methods inside linux calls package needed to manage linux interfaces. +type NetlinkAPIRead interface { // GetLinkByName returns netlink interface type GetLinkByName(ifName string) (netlink.Link, error) // GetLinkList return all links from namespace GetLinkList() ([]netlink.Link, error) // GetAddressList reads all IP addresses GetAddressList(ifName string) ([]netlink.Addr, error) - // InterfaceExists verifies interface existence - InterfaceExists(ifName string) (bool, error) // GetInterfaceType returns linux interface type GetInterfaceType(ifName string) (string, error) // GetVethPeerName returns VETH's peer name GetVethPeerName(ifName string) (string, error) // GetInterfaceByName returns *net.Interface type from name GetInterfaceByName(ifName string) (*net.Interface, error) + // DumpInterfaces returns all configured linux interfaces in all namespaces in proto-modelled format with metadata + DumpInterfaces() ([]*LinuxInterfaceDetails, error) + // DumpInterfaceStatistics returns statistics data for all known interfaces interfaces + DumpInterfaceStatistics() ([]*LinuxInterfaceStatistics, error) + // InterfaceExists verifies interface existence + InterfaceExists(ifName string) (bool, error) } // NetLinkHandler is accessor for netlink methods type NetLinkHandler struct { - stopwatch *measure.Stopwatch + nsHandler nsplugin.NamespaceAPI + ifIndexes ifaceidx.LinuxIfIndex + log logging.Logger } // NewNetLinkHandler creates new instance of netlink handler -func NewNetLinkHandler(stopwatch *measure.Stopwatch) *NetLinkHandler { +func NewNetLinkHandler(nsHandler nsplugin.NamespaceAPI, ifIndexes ifaceidx.LinuxIfIndex, log logging.Logger) *NetLinkHandler { return &NetLinkHandler{ - stopwatch: stopwatch, + nsHandler: nsHandler, + ifIndexes: ifIndexes, + log: log, } } diff --git a/plugins/linux/ifplugin/linuxcalls/veth_linuxcalls.go b/plugins/linux/ifplugin/linuxcalls/veth_linuxcalls.go index cc54a95364..2c69f88960 100644 --- a/plugins/linux/ifplugin/linuxcalls/veth_linuxcalls.go +++ b/plugins/linux/ifplugin/linuxcalls/veth_linuxcalls.go @@ -32,17 +32,12 @@ package linuxcalls import ( "fmt" - "time" "github.com/vishvananda/netlink" ) // AddVethInterfacePair calls LinkAdd Netlink API for the Netlink.Veth interface type. func (handler *NetLinkHandler) AddVethInterfacePair(ifName, peerIfName string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("add-veth-iface-pair").LogTimeEntry(time.Since(t)) - }(time.Now()) - // Veth pair params veth := &netlink.Veth{ LinkAttrs: netlink.LinkAttrs{ @@ -59,10 +54,6 @@ func (handler *NetLinkHandler) AddVethInterfacePair(ifName, peerIfName string) e // DelVethInterfacePair calls LinkDel Netlink API for the Netlink.Veth interface type. func (handler *NetLinkHandler) DelVethInterfacePair(ifName, peerIfName string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("del-veth-iface-pair").LogTimeEntry(time.Since(t)) - }(time.Now()) - // Veth pair params. veth := &netlink.Veth{ LinkAttrs: netlink.LinkAttrs{ @@ -79,10 +70,6 @@ func (handler *NetLinkHandler) DelVethInterfacePair(ifName, peerIfName string) e // GetVethPeerName return the peer name for a given VETH interface. func (handler *NetLinkHandler) GetVethPeerName(ifName string) (string, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("get-veth-peer-name").LogTimeEntry(time.Since(t)) - }(time.Now()) - link, err := handler.GetLinkByName(ifName) if err != nil { return "", err diff --git a/plugins/linux/l3plugin/arp_config.go b/plugins/linux/l3plugin/arp_config.go index df5a996a30..21848ba4dc 100644 --- a/plugins/linux/l3plugin/arp_config.go +++ b/plugins/linux/l3plugin/arp_config.go @@ -12,17 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/l3 --gogo_out=../model/l3 ../model/l3/l3.proto - package l3plugin import ( "fmt" "net" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" - "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/l3plugin/l3idx" "github.com/ligato/vpp-agent/plugins/linux/l3plugin/linuxcalls" @@ -52,9 +49,6 @@ type LinuxArpConfigurator struct { // Linux namespace/calls handler l3Handler linuxcalls.NetlinkAPI nsHandler nsplugin.NamespaceAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // ArpToInterface is an object which stores ARP-to-interface pairs used in cache. @@ -66,58 +60,54 @@ type ArpToInterface struct { } // GetArpIndexes returns arp in-memory indexes -func (plugin *LinuxArpConfigurator) GetArpIndexes() l3idx.LinuxARPIndexRW { - return plugin.arpIndexes +func (c *LinuxArpConfigurator) GetArpIndexes() l3idx.LinuxARPIndexRW { + return c.arpIndexes } // GetArpInterfaceCache returns internal non-configurable interface cache, mainly for testing purpose -func (plugin *LinuxArpConfigurator) GetArpInterfaceCache() map[string]*ArpToInterface { - return plugin.arpIfCache +func (c *LinuxArpConfigurator) GetArpInterfaceCache() map[string]*ArpToInterface { + return c.arpIfCache } // Init initializes ARP configurator and starts goroutines -func (plugin *LinuxArpConfigurator) Init(logger logging.PluginLogger, l3Handler linuxcalls.NetlinkAPI, nsHandler nsplugin.NamespaceAPI, - ifIndexes ifaceidx.LinuxIfIndexRW, stopwatch *measure.Stopwatch) error { +func (c *LinuxArpConfigurator) Init(logger logging.PluginLogger, l3Handler linuxcalls.NetlinkAPI, nsHandler nsplugin.NamespaceAPI, + arpIndexes l3idx.LinuxARPIndexRW, ifIndexes ifaceidx.LinuxIfIndexRW) error { // Logger - plugin.log = logger.NewLogger("-arp-conf") - plugin.log.Debug("Initializing Linux ARP configurator") + c.log = logger.NewLogger("arp-conf") // In-memory mappings - plugin.ifIndexes = ifIndexes - plugin.arpIndexes = l3idx.NewLinuxARPIndex(nametoidx.NewNameToIdx(plugin.log, "linux_arp_indexes", nil)) - plugin.arpIfCache = make(map[string]*ArpToInterface) - plugin.arpIdxSeq = 1 + c.ifIndexes = ifIndexes + c.arpIndexes = arpIndexes + c.arpIfCache = make(map[string]*ArpToInterface) + c.arpIdxSeq = 1 // L3 and namespace handler - plugin.l3Handler = l3Handler - plugin.nsHandler = nsHandler + c.l3Handler = l3Handler + c.nsHandler = nsHandler - // Configurator-wide stopwatch instance - plugin.stopwatch = stopwatch + c.log.Debug("Linux ARP configurator initialized") return nil } // Close closes all goroutines started during Init -func (plugin *LinuxArpConfigurator) Close() error { +func (c *LinuxArpConfigurator) Close() error { return nil } // ConfigureLinuxStaticArpEntry reacts to a new northbound Linux ARP entry config by creating and configuring // the entry in the host network stack through Netlink API. -func (plugin *LinuxArpConfigurator) ConfigureLinuxStaticArpEntry(arpEntry *l3.LinuxStaticArpEntries_ArpEntry) error { - plugin.log.Infof("Configuring Linux ARP entry %v", arpEntry.Name) +func (c *LinuxArpConfigurator) ConfigureLinuxStaticArpEntry(arpEntry *l3.LinuxStaticArpEntries_ArpEntry) error { var err error - // Prepare ARP entry object neigh := &netlink.Neigh{} // Find interface - _, ifData, found := plugin.ifIndexes.LookupIdx(arpEntry.Interface) + _, ifData, found := c.ifIndexes.LookupIdx(arpEntry.Interface) if !found || ifData == nil { - plugin.log.Debugf("cannot create ARP entry %s due to missing interface %s (found: %v, data: %v), cached", + c.log.Debugf("cannot create ARP entry %s due to missing interface %s (found: %v, data: %v), cached", arpEntry.Name, arpEntry.Interface, found, ifData) - plugin.arpIfCache[arpEntry.Name] = &ArpToInterface{ + c.arpIfCache[arpEntry.Name] = &ArpToInterface{ arp: arpEntry, ifName: arpEntry.Interface, isAdd: true, @@ -137,8 +127,8 @@ func (plugin *LinuxArpConfigurator) ConfigureLinuxStaticArpEntry(arpEntry *l3.Li // Set MAC address var mac net.HardwareAddr if mac, err = net.ParseMAC(arpEntry.HwAddress); err != nil { - return fmt.Errorf("cannot create ARP entry %v, unable to parse MAC address %v, error: %v", arpEntry.Name, - arpEntry.HwAddress, err) + return errors.Errorf("failed to create linux ARP entry %s, unable to parse MAC address %s, error: %v", + arpEntry.Name, arpEntry.HwAddress, err) } neigh.HardwareAddr = mac @@ -150,44 +140,41 @@ func (plugin *LinuxArpConfigurator) ConfigureLinuxStaticArpEntry(arpEntry *l3.Li // Prepare namespace of related interface nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - arpNs := plugin.nsHandler.ArpNsToGeneric(arpEntry.Namespace) + arpNs := c.nsHandler.ArpNsToGeneric(arpEntry.Namespace) // ARP entry has to be created in the same namespace as the interface - revertNs, err := plugin.nsHandler.SwitchNamespace(arpNs, nsMgmtCtx) + revertNs, err := c.nsHandler.SwitchNamespace(arpNs, nsMgmtCtx) if err != nil { - return err + return errors.Errorf("failed to switch namespace: %v", err) } defer revertNs() // Create a new ARP entry in interface namespace - err = plugin.l3Handler.AddArpEntry(arpEntry.Name, neigh) + err = c.l3Handler.AddArpEntry(arpEntry.Name, neigh) if err != nil { - plugin.log.Errorf("adding arp entry %q failed: %v (%+v)", arpEntry.Name, err, neigh) - return err + return errors.Errorf("failed to add linux ARP entry %s: %v", arpEntry.Name, err) } // Register created ARP entry - plugin.arpIndexes.RegisterName(ArpIdentifier(neigh), plugin.arpIdxSeq, arpEntry) - plugin.arpIdxSeq++ - plugin.log.Debugf("ARP entry %v registered as %v", arpEntry.Name, ArpIdentifier(neigh)) + c.arpIndexes.RegisterName(ArpIdentifier(neigh), c.arpIdxSeq, arpEntry) + c.arpIdxSeq++ + c.log.Debugf("ARP entry %v registered as %v", arpEntry.Name, ArpIdentifier(neigh)) - plugin.log.Infof("Linux ARP entry %v configured", arpEntry.Name) + c.log.Infof("Linux ARP entry %s configured", arpEntry.Name) return nil } // ModifyLinuxStaticArpEntry applies changes in the NB configuration of a Linux ARP through Netlink API. -func (plugin *LinuxArpConfigurator) ModifyLinuxStaticArpEntry(newArpEntry *l3.LinuxStaticArpEntries_ArpEntry, oldArpEntry *l3.LinuxStaticArpEntries_ArpEntry) (err error) { - plugin.log.Infof("Modifying Linux ARP entry %v", newArpEntry.Name) - +func (c *LinuxArpConfigurator) ModifyLinuxStaticArpEntry(newArpEntry *l3.LinuxStaticArpEntries_ArpEntry, oldArpEntry *l3.LinuxStaticArpEntries_ArpEntry) (err error) { // If the namespace of the new ARP entry was changed, the old entry needs to be removed and the new one created // in the new namespace // If interface or IP address was changed, the old entry needs to be removed and recreated as well. In such a case, // ModifyArpEntry (analogy to 'ip neigh replace') would create a new entry instead of modifying the existing one callReplace := true - oldArpNs := plugin.nsHandler.ArpNsToGeneric(oldArpEntry.Namespace) - newArpNs := plugin.nsHandler.ArpNsToGeneric(newArpEntry.Namespace) + oldArpNs := c.nsHandler.ArpNsToGeneric(oldArpEntry.Namespace) + newArpNs := c.nsHandler.ArpNsToGeneric(newArpEntry.Namespace) result := oldArpNs.CompareNamespaces(newArpNs) if result != 0 || oldArpEntry.Interface != newArpEntry.Interface || oldArpEntry.IpAddr != newArpEntry.IpAddr { callReplace = false @@ -195,34 +182,38 @@ func (plugin *LinuxArpConfigurator) ModifyLinuxStaticArpEntry(newArpEntry *l3.Li // Remove old entry and configure a new one, then return if !callReplace { - if err := plugin.DeleteLinuxStaticArpEntry(oldArpEntry); err != nil { - return nil + if err := c.DeleteLinuxStaticArpEntry(oldArpEntry); err != nil { + return errors.Errorf("linux ARP modify: failed to remove old entry %s: %v", oldArpEntry.Name, err) + } + if err := c.ConfigureLinuxStaticArpEntry(newArpEntry); err != nil { + return errors.Errorf("linux ARP modify: failed to add new entry %s: %v", oldArpEntry.Name, err) } - return plugin.ConfigureLinuxStaticArpEntry(newArpEntry) + return nil } // Create modified ARP entry object neigh := &netlink.Neigh{} // Find interface - _, ifData, found := plugin.ifIndexes.LookupIdx(newArpEntry.Interface) + _, ifData, found := c.ifIndexes.LookupIdx(newArpEntry.Interface) if !found || ifData == nil { - return fmt.Errorf("cannot create ARP entry %s due to missing interface %s (found: %v, data: %v), cached", + c.log.Debugf("cannot create ARP entry %s due to missing interface %s, cached", newArpEntry.Name, newArpEntry.Interface, found, ifData) + return nil } neigh.LinkIndex = int(ifData.Index) // Set IP address ipAddr := net.ParseIP(newArpEntry.IpAddr) if ipAddr == nil { - return fmt.Errorf("cannot create ARP entry %v, unable to parse IP address %v", newArpEntry.Name, newArpEntry.IpAddr) + return errors.Errorf("cannot create ARP entry %s, unable to parse IP address %s", newArpEntry.Name, newArpEntry.IpAddr) } neigh.IP = ipAddr // Set MAC address var mac net.HardwareAddr if mac, err = net.ParseMAC(newArpEntry.HwAddress); err != nil { - return fmt.Errorf("cannot create ARP entry %v, unable to parse MAC address %v, error: %v", newArpEntry.Name, + return errors.Errorf("cannot create ARP entry %s, unable to parse MAC address %s: %v", newArpEntry.Name, newArpEntry.HwAddress, err) } neigh.HardwareAddr = mac @@ -235,38 +226,35 @@ func (plugin *LinuxArpConfigurator) ModifyLinuxStaticArpEntry(newArpEntry *l3.Li // Prepare namespace of related interface nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - arpNs := plugin.nsHandler.ArpNsToGeneric(newArpEntry.Namespace) + arpNs := c.nsHandler.ArpNsToGeneric(newArpEntry.Namespace) // ARP entry has to be created in the same namespace as the interface - revertNs, err := plugin.nsHandler.SwitchNamespace(arpNs, nsMgmtCtx) + revertNs, err := c.nsHandler.SwitchNamespace(arpNs, nsMgmtCtx) if err != nil { - return err + return errors.Errorf("failed to switch namespace: %v", err) } defer revertNs() - err = plugin.l3Handler.SetArpEntry(newArpEntry.Name, neigh) + err = c.l3Handler.SetArpEntry(newArpEntry.Name, neigh) if err != nil { - plugin.log.Errorf("modifying arp entry %q failed: %v (%+v)", newArpEntry.Name, err, neigh) - return err + return errors.Errorf("modifying arp entry %q failed: %v (%+v)", newArpEntry.Name, err, neigh) } - plugin.log.Infof("Linux ARP entry %v modified", newArpEntry.Name) + c.log.Infof("Linux ARP entry %s modified", newArpEntry.Name) return nil } // DeleteLinuxStaticArpEntry reacts to a removed NB configuration of a Linux ARP entry. -func (plugin *LinuxArpConfigurator) DeleteLinuxStaticArpEntry(arpEntry *l3.LinuxStaticArpEntries_ArpEntry) (err error) { - plugin.log.Infof("Deleting Linux ARP entry %v", arpEntry.Name) - +func (c *LinuxArpConfigurator) DeleteLinuxStaticArpEntry(arpEntry *l3.LinuxStaticArpEntries_ArpEntry) (err error) { // Prepare ARP entry object neigh := &netlink.Neigh{} // Find interface - _, ifData, foundIface := plugin.ifIndexes.LookupIdx(arpEntry.Interface) + _, ifData, foundIface := c.ifIndexes.LookupIdx(arpEntry.Interface) if !foundIface || ifData == nil { - plugin.log.Debugf("cannot remove ARP entry %v due to missing interface %v, cached", arpEntry.Name, arpEntry.Interface) - plugin.arpIfCache[arpEntry.Name] = &ArpToInterface{ + c.log.Debugf("cannot remove ARP entry %v due to missing interface %v, cached", arpEntry.Name, arpEntry.Interface) + c.arpIfCache[arpEntry.Name] = &ArpToInterface{ arp: arpEntry, ifName: arpEntry.Interface, } @@ -277,25 +265,25 @@ func (plugin *LinuxArpConfigurator) DeleteLinuxStaticArpEntry(arpEntry *l3.Linux // Set IP address ipAddr := net.ParseIP(arpEntry.IpAddr) if ipAddr == nil { - return fmt.Errorf("cannot create ARP entry %v, unable to parse IP address %v", arpEntry.Name, arpEntry.IpAddr) + return errors.Errorf("cannot create ARP entry %s, unable to parse IP address %s", arpEntry.Name, arpEntry.IpAddr) } neigh.IP = ipAddr // Prepare namespace of related interface nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - arpNs := plugin.nsHandler.ArpNsToGeneric(arpEntry.Namespace) + arpNs := c.nsHandler.ArpNsToGeneric(arpEntry.Namespace) // ARP entry has to be removed from the same namespace as the interface - revertNs, err := plugin.nsHandler.SwitchNamespace(arpNs, nsMgmtCtx) + revertNs, err := c.nsHandler.SwitchNamespace(arpNs, nsMgmtCtx) if err != nil { - return err + return errors.Errorf("failed to switch namespace: %v", err) } defer revertNs() // Read all ARP entries configured for interface - entries, err := plugin.l3Handler.GetArpEntries(int(ifData.Index), noFamilyFilter) + entries, err := c.l3Handler.GetArpEntries(int(ifData.Index), noFamilyFilter) if err != nil { - return err + return errors.Errorf("failed to read ARP entries for index %d: %v", ifData.Index, err) } // Look for ARP to remove. If it already does not exist, return @@ -307,57 +295,53 @@ func (plugin *LinuxArpConfigurator) DeleteLinuxStaticArpEntry(arpEntry *l3.Linux } } if !found { - plugin.log.Infof("ARP entry with IP %v and link index %v not configured, skipped", neigh.IP.String(), neigh.LinkIndex) + c.log.Debugf("ARP entry with IP %v and link index %v not configured, skipped", neigh.IP.String(), neigh.LinkIndex) return nil } // Remove the ARP entry from the interface namespace - err = plugin.l3Handler.DelArpEntry(arpEntry.Name, neigh) + err = c.l3Handler.DelArpEntry(arpEntry.Name, neigh) if err != nil { - plugin.log.Errorf("deleting arp entry %q failed: %v (%+v)", arpEntry.Name, err, neigh) - return err + return errors.Errorf("failed to remove linux ARP entry %s: %v", arpEntry.Name, err) } - _, _, found = plugin.arpIndexes.UnregisterName(ArpIdentifier(neigh)) - if !found { - plugin.log.Warnf("Attempt to unregister non-existing ARP entry %v", arpEntry.Name) - } else { - plugin.log.Debugf("ARP entry unregistered %v", arpEntry.Name) + _, _, found = c.arpIndexes.UnregisterName(ArpIdentifier(neigh)) + if found { + c.log.Debugf("Linux ARP entry %s unregistered", arpEntry.Name) } - plugin.log.Infof("Linux ARP entry %v removed", arpEntry.Name) + c.log.Infof("Linux ARP entry %s removed", arpEntry.Name) return nil } // LookupLinuxArpEntries reads all ARP entries from all interfaces and registers them if needed -func (plugin *LinuxArpConfigurator) LookupLinuxArpEntries() error { - plugin.log.Infof("Browsing Linux ARP entries") +func (c *LinuxArpConfigurator) LookupLinuxArpEntries() error { + c.log.Debugf("Browsing Linux ARP entries") // Set interface index and family to 0 reads all arp entries from all of the interfaces - entries, err := plugin.l3Handler.GetArpEntries(noIfaceIdxFilter, noFamilyFilter) + entries, err := c.l3Handler.GetArpEntries(noIfaceIdxFilter, noFamilyFilter) if err != nil { - return err + return errors.Errorf("failed to read linux ARP entries: %v", err) } for _, entry := range entries { - plugin.log.WithField("interface", entry.LinkIndex).Debugf("Found new static linux ARP entry") - _, arp, found := plugin.arpIndexes.LookupIdx(ArpIdentifier(&entry)) + _, arp, found := c.arpIndexes.LookupIdx(ArpIdentifier(&entry)) if !found { var ifName string if arp == nil || arp.Namespace == nil { - ifName, _, _ = plugin.ifIndexes.LookupNameByNamespace(uint32(entry.LinkIndex), ifaceidx.DefNs) + ifName, _, _ = c.ifIndexes.LookupNameByNamespace(uint32(entry.LinkIndex), ifaceidx.DefNs) } else { - ifName, _, _ = plugin.ifIndexes.LookupNameByNamespace(uint32(entry.LinkIndex), arp.Namespace.Name) + ifName, _, _ = c.ifIndexes.LookupNameByNamespace(uint32(entry.LinkIndex), arp.Namespace.Name) } - plugin.arpIndexes.RegisterName(ArpIdentifier(&entry), plugin.arpIdxSeq, &l3.LinuxStaticArpEntries_ArpEntry{ + c.arpIndexes.RegisterName(ArpIdentifier(&entry), c.arpIdxSeq, &l3.LinuxStaticArpEntries_ArpEntry{ // Register fields required to reconstruct ARP identifier Interface: ifName, IpAddr: entry.IP.String(), HwAddress: entry.HardwareAddr.String(), }) - plugin.arpIdxSeq++ - plugin.log.Debugf("ARP entry registered as %v", ArpIdentifier(&entry)) + c.arpIdxSeq++ + c.log.Debugf("ARP entry registered as %s", ArpIdentifier(&entry)) } } @@ -365,84 +349,92 @@ func (plugin *LinuxArpConfigurator) LookupLinuxArpEntries() error { } // ResolveCreatedInterface resolves a new linux interface from ARP perspective -func (plugin *LinuxArpConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { - plugin.log.Debugf("Linux ARP configurator: resolve created interface %v", ifName) - +func (c *LinuxArpConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { // Look for ARP entries where the interface is used - var wasErr error - for arpName, arpIfPair := range plugin.arpIfCache { + for arpName, arpIfPair := range c.arpIfCache { if arpIfPair.ifName == ifName && arpIfPair.isAdd { - plugin.log.Debugf("Cached ARP %v for interface %v created", arpName, ifName) - if err := plugin.ConfigureLinuxStaticArpEntry(arpIfPair.arp); err != nil { - plugin.log.Error(err) - wasErr = err + if err := c.ConfigureLinuxStaticArpEntry(arpIfPair.arp); err != nil { + return errors.Errorf("failed to configure linux ARP %s with registered interface %s: %v", + arpIfPair.arp.Name, ifName, err) } - delete(plugin.arpIfCache, arpName) + delete(c.arpIfCache, arpName) } else if arpIfPair.ifName == ifName && !arpIfPair.isAdd { - plugin.log.Debugf("Cached ARP %v for interface %v removed", arpName, ifName) - if err := plugin.DeleteLinuxStaticArpEntry(arpIfPair.arp); err != nil { - plugin.log.Error(err) - wasErr = err + c.log.Debugf("Cached ARP %v for interface %v removed", arpName, ifName) + if err := c.DeleteLinuxStaticArpEntry(arpIfPair.arp); err != nil { + return errors.Errorf("failed to remove linux ARP %s with registered interface %s: %v", + arpIfPair.arp.Name, ifName, err) } - delete(plugin.arpIfCache, arpName) + delete(c.arpIfCache, arpName) } + c.log.Debugf("Linux ARP %s removed from cache", arpName) } - return wasErr + return nil } // ResolveDeletedInterface resolves removed linux interface from ARP perspective -func (plugin *LinuxArpConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { - plugin.log.Debugf("Linux ARP configurator: resolve deleted interface %v", ifName) - +func (c *LinuxArpConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { // Read cache at first and remove obsolete entries - for arpName, arpToIface := range plugin.arpIfCache { + for arpName, arpToIface := range c.arpIfCache { if arpToIface.ifName == ifName && !arpToIface.isAdd { - delete(plugin.arpIfCache, arpName) + delete(c.arpIfCache, arpName) } } // Read mapping of ARP entries and find all using removed interface - for _, arpName := range plugin.arpIndexes.GetMapping().ListNames() { - _, arp, found := plugin.arpIndexes.LookupIdx(arpName) + for _, arpName := range c.arpIndexes.GetMapping().ListNames() { + _, arp, found := c.arpIndexes.LookupIdx(arpName) if !found { // Should not happend but better to log it - plugin.log.Warnf("ARP %v not found in the mapping", arpName) - continue + return errors.Errorf("failed to resolve unregistered interface for ARP: entry %s not found", arpName) } if arp == nil { - plugin.log.Warnf("ARP %v - no data available", arpName) - continue + return errors.Errorf("failed to resolve unregistered interface for ARP: no data available") } if arp.Interface == ifName { // Unregister ip := net.ParseIP(arp.IpAddr) if ip == nil { - plugin.log.Errorf("ARP %v - cannot unregister, invalid IP %v", arpName, arp.IpAddr) - continue + return errors.Errorf("failed to resolve unregistered interface for ARP %s: invalid IP address %s", + arpName, arp.IpAddr) } mac, err := net.ParseMAC(arp.HwAddress) if err != nil { - plugin.log.Errorf("ARP %v - cannot unregister, invalid MAC %v: %v", arpName, arp.HwAddress, err) - continue + return errors.Errorf("failed to resolve unregistered interface for ARP %s: invalid MAC address %s", + arpName, arp.HwAddress) } - plugin.arpIndexes.UnregisterName(ArpIdentifier(&netlink.Neigh{ + c.arpIndexes.UnregisterName(ArpIdentifier(&netlink.Neigh{ LinkIndex: int(ifIdx), IP: ip, HardwareAddr: mac, })) // Cache - plugin.arpIfCache[arpName] = &ArpToInterface{ + c.arpIfCache[arpName] = &ArpToInterface{ arp: arp, ifName: ifName, isAdd: true, } + c.log.Debugf("Linux ARP entry %s unregistered and removed from cache", arpName) } } return nil } +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *LinuxArpConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} + // ArpIdentifier generates unique ARP ID used in mapping func ArpIdentifier(arp *netlink.Neigh) string { return fmt.Sprintf("iface%v-%v-%v", arp.LinkIndex, arp.IP.String(), arp.HardwareAddr) diff --git a/plugins/linux/l3plugin/arp_config_test.go b/plugins/linux/l3plugin/arp_config_test.go index e563968975..40bb2faedb 100644 --- a/plugins/linux/l3plugin/arp_config_test.go +++ b/plugins/linux/l3plugin/arp_config_test.go @@ -18,10 +18,11 @@ import ( "fmt" "testing" + "github.com/ligato/vpp-agent/plugins/linux/l3plugin/l3idx" + "net" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/l3plugin" @@ -162,11 +163,12 @@ func arpTestSetup(t *testing.T) (*l3plugin.LinuxArpConfigurator, *linuxmock.L3Ne nsHandleLog.SetLevel(logging.DebugLevel) // Linux interface indexes ifIndexes := ifaceidx.NewLinuxIfIndex(nametoidx.NewNameToIdx(pluginLog, "if", nil)) + arpIndexes := l3idx.NewLinuxARPIndex(nametoidx.NewNameToIdx(pluginLog, "arp", nil)) // Configurator plugin := &l3plugin.LinuxArpConfigurator{} linuxMock := linuxmock.NewL3NetlinkHandlerMock() nsMock := linuxmock.NewNamespacePluginMock() - err := plugin.Init(pluginLog, linuxMock, nsMock, ifIndexes, measure.NewStopwatch("LinuxArpTest", pluginLog)) + err := plugin.Init(pluginLog, linuxMock, nsMock, arpIndexes, ifIndexes) Expect(err).To(BeNil()) return plugin, linuxMock, nsMock, ifIndexes diff --git a/plugins/linux/l3plugin/data_resync.go b/plugins/linux/l3plugin/data_resync.go index 0e7ed2b11c..b0d2174361 100644 --- a/plugins/linux/l3plugin/data_resync.go +++ b/plugins/linux/l3plugin/data_resync.go @@ -15,10 +15,9 @@ package l3plugin import ( - "fmt" "net" - "time" + "github.com/go-errors/errors" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/model/l3" "github.com/ligato/vpp-agent/plugins/linux/nsplugin" @@ -26,66 +25,52 @@ import ( ) // Resync configures an initial set of ARPs. Existing Linux ARPs are registered and potentially re-configured. -func (plugin *LinuxArpConfigurator) Resync(arpEntries []*l3.LinuxStaticArpEntries_ArpEntry) (errs []error) { - plugin.log.WithField("cfg", plugin).Debug("RESYNC ARPs begin.") - - defer func(t time.Time) { - plugin.stopwatch.TimeLog("configure-linux-arp").LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (c *LinuxArpConfigurator) Resync(arpEntries []*l3.LinuxStaticArpEntries_ArpEntry) error { // Create missing arp entries and update existing ones for _, entry := range arpEntries { - err := plugin.ConfigureLinuxStaticArpEntry(entry) + err := c.ConfigureLinuxStaticArpEntry(entry) if err != nil { - errs = append(errs, err) + return errors.Errorf("linux ARP resync: failed to configure ARP %s: %v", entry.Name, err) } } // Dump pre-existing not managed arp entries - err := plugin.LookupLinuxArpEntries() + err := c.LookupLinuxArpEntries() if err != nil { - errs = append(errs, err) + return errors.Errorf("linux ARP resync: failed to lookup ARP entries: %v", err) } - plugin.log.WithField("cfg", plugin).Debug("RESYNC ARPs end. ") + c.log.Info("Linux ARP resync done") - return + return nil } // Resync configures an initial set of static routes. Existing Linux static routes are registered and potentially // re-configured. Resync does not remove any linux route. -func (plugin *LinuxRouteConfigurator) Resync(nbRoutes []*l3.LinuxStaticRoutes_Route) (errs []error) { - plugin.log.WithField("cfg", plugin).Debug("RESYNC static routes begin.") - - defer func(t time.Time) { - plugin.stopwatch.TimeLog("configure-linux-route").LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (c *LinuxRouteConfigurator) Resync(nbRoutes []*l3.LinuxStaticRoutes_Route) error { nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() // First step is to find a linux equivalent for NB route config for _, nbRoute := range nbRoutes { // Route interface exists if nbRoute.Interface != "" { - _, _, found := plugin.ifIndexes.LookupIdx(nbRoute.Interface) + _, _, found := c.ifIndexes.LookupIdx(nbRoute.Interface) if !found { // If route interface does not exist, cache it - plugin.log.Debugf("RESYNC static route %v: interface %s does not exists, moving to cache", + c.rtCachedIfRoutes.RegisterName(nbRoute.Name, c.rtIdxSeq, nbRoute) + c.rtIdxSeq++ + c.log.Debugf("Linux route %s resync: interface %s does not exists, moved to cache", nbRoute.Name, nbRoute.Interface) - plugin.rtCachedIfRoutes.RegisterName(nbRoute.Name, plugin.rtIdxSeq, nbRoute) - plugin.rtIdxSeq++ continue } } // There can be several routes found according to matching parameters - linuxRtList, err := plugin.findLinuxRoutes(nbRoute, nsMgmtCtx) + linuxRtList, err := c.findLinuxRoutes(nbRoute, nsMgmtCtx) if err != nil { - plugin.log.Error(err) - errs = append(errs, err) - continue + return errors.Errorf("linux route %s resync: %v", nbRoute.Name, err) } - plugin.log.Debugf("found %d linux routes to compare for %s", len(linuxRtList), nbRoute.Name) + c.log.Debugf("found %d linux routes to compare for %s", len(linuxRtList), nbRoute.Name) // Find at least one route which has the same parameters var rtFound bool for rtIdx, linuxRtEntry := range linuxRtList { @@ -100,67 +85,67 @@ func (plugin *LinuxRouteConfigurator) Resync(nbRoutes []*l3.LinuxStaticRoutes_Ro } else { nsName = nbRoute.Namespace.Name } - _, ifData, found = plugin.ifIndexes.LookupNameByNamespace(uint32(linuxRtEntry.LinkIndex), nsName) + _, ifData, found = c.ifIndexes.LookupNameByNamespace(uint32(linuxRtEntry.LinkIndex), nsName) if !found || ifData == nil { - plugin.log.Debugf("Interface %d (data %v) not found for route", linuxRtEntry.LinkIndex, ifData) + c.log.Debugf("Interface %d (data %v) not found for route", linuxRtEntry.LinkIndex, ifData) } else { hostName = ifData.Data.HostIfName } } - linuxRt := plugin.transformRoute(linuxRtEntry, hostName) - if plugin.isRouteEqual(rtIdx, nbRoute, linuxRt) { + linuxRt := c.transformRoute(linuxRtEntry, hostName) + if c.isRouteEqual(rtIdx, nbRoute, linuxRt) { rtFound = true break } } if rtFound { // Register route if found - plugin.log.Debugf("RESYNC Linux routes: %s was found and will be registered without additional changes", nbRoute.Name) - plugin.rtIndexes.RegisterName(nbRoute.Name, plugin.rtIdxSeq, nbRoute) - plugin.rtIdxSeq++ + c.rtIndexes.RegisterName(nbRoute.Name, c.rtIdxSeq, nbRoute) + c.rtIdxSeq++ + c.log.Debugf("Linux route resync: %s was found and registered without additional changes", nbRoute.Name) // Resolve cached routes if !nbRoute.Default { - plugin.retryDefaultRoutes(nbRoute) + if err := c.retryDefaultRoutes(nbRoute); err != nil { + return errors.Errorf("Linux route resync error: retrying cached default routes caused %v", err) + } } } else { // Configure route if not found - plugin.log.Debugf("RESYNC Linux routes: %s was not found and will be configured", nbRoute.Name) - if err := plugin.ConfigureLinuxStaticRoute(nbRoute); err != nil { - plugin.log.Error(err) - errs = append(errs, err) + c.log.Debugf("RLinux route resync: %s was not found and will be configured", nbRoute.Name) + if err := c.ConfigureLinuxStaticRoute(nbRoute); err != nil { + return errors.Errorf("linux route resync error: failed to configure %s: %v", nbRoute.Name, err) } } } - return + return nil } // Look for routes similar to provided NB config in respective namespace. Routes can be read using destination address // or interface. FOr every config, both ways are used. -func (plugin *LinuxRouteConfigurator) findLinuxRoutes(nbRoute *l3.LinuxStaticRoutes_Route, nsMgmtCtx *nsplugin.NamespaceMgmtCtx) ([]netlink.Route, error) { - plugin.log.Debugf("Looking for equivalent linux routes for %s", nbRoute.Name) - +func (c *LinuxRouteConfigurator) findLinuxRoutes(nbRoute *l3.LinuxStaticRoutes_Route, nsMgmtCtx *nsplugin.NamespaceMgmtCtx) ([]netlink.Route, error) { + c.log.Debugf("Looking for equivalent linux routes for %s", nbRoute.Name) // Move to proper namespace if nbRoute.Namespace != nil { // Switch to namespace - routeNs := plugin.nsHandler.RouteNsToGeneric(nbRoute.Namespace) - revertNs, err := plugin.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) + routeNs := c.nsHandler.RouteNsToGeneric(nbRoute.Namespace) + revertNs, err := c.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) if err != nil { - return nil, fmt.Errorf("RESYNC Linux route %s: failed to switch to namespace %s: %v", + return nil, errors.Errorf("Linux route %s resync error: failed to switch to namespace %s: %v", nbRoute.Name, nbRoute.Namespace.Name, err) } defer revertNs() } var linuxRoutes []netlink.Route // Look for routes using destination IP address - if nbRoute.DstIpAddr != "" && plugin.networkReachable(nbRoute.Namespace, nbRoute.DstIpAddr) { + if nbRoute.DstIpAddr != "" && c.networkReachable(nbRoute.Namespace, nbRoute.DstIpAddr) { _, dstNetIP, err := net.ParseCIDR(nbRoute.DstIpAddr) if err != nil { - return nil, fmt.Errorf("failed to parse destination IP address %s: %v", nbRoute.DstIpAddr, err) + return nil, errors.Errorf("failed to parse destination IP address %s: %v", nbRoute.DstIpAddr, err) } linuxRts, err := netlink.RouteGet(dstNetIP.IP) if err != nil { - return nil, fmt.Errorf("failed to read linux route %s using address %s: %v", + return nil, errors.Errorf("failed to read linux route %s using address %s: %v", nbRoute.Name, nbRoute.DstIpAddr, err) } if linuxRts != nil { @@ -170,21 +155,21 @@ func (plugin *LinuxRouteConfigurator) findLinuxRoutes(nbRoute *l3.LinuxStaticRou // Look for routes using interface if nbRoute.Interface != "" { // Look whether interface is registered - _, meta, found := plugin.ifIndexes.LookupIdx(nbRoute.Interface) + _, meta, found := c.ifIndexes.LookupIdx(nbRoute.Interface) if !found { // Should not happen, was successfully checked before - plugin.log.Errorf("Route %s interface %s is missing from the mapping", nbRoute.Name, nbRoute.Interface) + return nil, errors.Errorf("route %s interface %s is missing from the mapping", nbRoute.Name, nbRoute.Interface) } else if meta == nil || meta.Data == nil { - plugin.log.Errorf("Interface %s data missing", nbRoute.Interface) + return nil, errors.Errorf("interface %s data missing", nbRoute.Interface) } else { // Look for interface using host name link, err := netlink.LinkByName(meta.Data.HostIfName) if err != nil { - return nil, fmt.Errorf("failed to read interface %s: %v", meta.Data.HostIfName, err) + return nil, errors.Errorf("failed to read interface %s: %v", meta.Data.HostIfName, err) } linuxRts, err := netlink.RouteList(link, netlink.FAMILY_ALL) if err != nil { - return nil, fmt.Errorf("failed to read linux route %s using interface %s: %v", + return nil, errors.Errorf("failed to read linux route %s using interface %s: %v", nbRoute.Name, meta.Data.HostIfName, err) } if linuxRts != nil { @@ -194,33 +179,33 @@ func (plugin *LinuxRouteConfigurator) findLinuxRoutes(nbRoute *l3.LinuxStaticRou } if len(linuxRoutes) == 0 { - plugin.log.Debugf("Equivalent for route %s was not found", nbRoute.Name) + c.log.Debugf("Equivalent for route %s was not found", nbRoute.Name) } return linuxRoutes, nil } // Compare all route parameters and returns true if routes are equal, false otherwise -func (plugin *LinuxRouteConfigurator) isRouteEqual(rtIdx int, nbRoute, linuxRt *l3.LinuxStaticRoutes_Route) bool { +func (c *LinuxRouteConfigurator) isRouteEqual(rtIdx int, nbRoute, linuxRt *l3.LinuxStaticRoutes_Route) bool { // Interface (if exists) if nbRoute.Interface != "" && nbRoute.Interface != linuxRt.Interface { - plugin.log.Debugf("Linux route %d: interface is different (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: interface is different (NB: %s, Linux: %s)", rtIdx, nbRoute.Interface, linuxRt.Interface) return false } // Default route if nbRoute.Default { if !linuxRt.Default { - plugin.log.Debugf("Linux route %d: NB route is default, but linux route is not", rtIdx) + c.log.Debugf("Linux route %d: NB route is default, but linux route is not", rtIdx) return false } if nbRoute.GwAddr != linuxRt.GwAddr { - plugin.log.Debugf("Linux route %d: gateway is different (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: gateway is different (NB: %s, Linux: %s)", rtIdx, nbRoute.GwAddr, linuxRt.GwAddr) return false } if nbRoute.Metric != linuxRt.Metric { - plugin.log.Debugf("Linux route %d: metric is different (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: metric is different (NB: %s, Linux: %s)", rtIdx, nbRoute.Metric, linuxRt.Metric) return false } @@ -229,33 +214,33 @@ func (plugin *LinuxRouteConfigurator) isRouteEqual(rtIdx int, nbRoute, linuxRt * // Static route _, nbIPNet, err := net.ParseCIDR(nbRoute.DstIpAddr) if err != nil { - plugin.log.Error(err) + c.log.Error(err) return false } if nbIPNet.IP.String() != linuxRt.DstIpAddr { - plugin.log.Debugf("Linux route %d: destination address is different (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: destination address is different (NB: %s, Linux: %s)", rtIdx, nbIPNet.IP.String(), linuxRt.DstIpAddr) return false } // Compare source IP/gateway if nbRoute.SrcIpAddr == "" && linuxRt.SrcIpAddr != "" || nbRoute.SrcIpAddr != "" && linuxRt.SrcIpAddr == "" { if nbRoute.SrcIpAddr == "" && nbRoute.SrcIpAddr != linuxRt.GwAddr { - plugin.log.Debugf("Linux route %d: source does not match gateway (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: source does not match gateway (NB: %s, Linux: %s)", rtIdx, nbRoute.SrcIpAddr, linuxRt.SrcIpAddr) return false } else if linuxRt.SrcIpAddr == "" && nbRoute.GwAddr != linuxRt.SrcIpAddr { - plugin.log.Debugf("Linux route %d: source does not match gateway (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: source does not match gateway (NB: %s, Linux: %s)", rtIdx, nbRoute.SrcIpAddr, linuxRt.SrcIpAddr) return false } } else if nbRoute.SrcIpAddr != "" && linuxRt.SrcIpAddr != "" && nbRoute.SrcIpAddr != linuxRt.SrcIpAddr { - plugin.log.Debugf("Linux route %d: source address is different (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: source address is different (NB: %s, Linux: %s)", rtIdx, nbRoute.SrcIpAddr, linuxRt.SrcIpAddr) return false } if nbRoute.SrcIpAddr != "" && nbRoute.SrcIpAddr != linuxRt.SrcIpAddr { - plugin.log.Debugf("Linux route %d: source address is different (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: source address is different (NB: %s, Linux: %s)", rtIdx, nbRoute.SrcIpAddr, linuxRt.SrcIpAddr) return false } @@ -266,7 +251,7 @@ func (plugin *LinuxRouteConfigurator) isRouteEqual(rtIdx int, nbRoute, linuxRt * } } else if linuxRt.Scope != nil { if nbRoute.Scope.Type != linuxRt.Scope.Type { - plugin.log.Debugf("Linux route %d: scope is different (NB: %s, Linux: %s)", + c.log.Debugf("Linux route %d: scope is different (NB: %s, Linux: %s)", rtIdx, nbRoute.Scope.Type, linuxRt.Scope.Type) return false } @@ -276,7 +261,7 @@ func (plugin *LinuxRouteConfigurator) isRouteEqual(rtIdx int, nbRoute, linuxRt * } // Parse netlink type scope to proto -func (plugin *LinuxRouteConfigurator) parseLinuxRouteScope(scope netlink.Scope) *l3.LinuxStaticRoutes_Route_Scope { +func (c *LinuxRouteConfigurator) parseLinuxRouteScope(scope netlink.Scope) *l3.LinuxStaticRoutes_Route_Scope { switch scope { case netlink.SCOPE_UNIVERSE: return &l3.LinuxStaticRoutes_Route_Scope{ @@ -295,7 +280,7 @@ func (plugin *LinuxRouteConfigurator) parseLinuxRouteScope(scope netlink.Scope) Type: l3.LinuxStaticRoutes_Route_Scope_SITE, } default: - plugin.log.Infof("Unknown scope type, setting to default (link): %v", scope) + c.log.Infof("Unknown scope type, setting to default (link): %v", scope) return &l3.LinuxStaticRoutes_Route_Scope{ Type: l3.LinuxStaticRoutes_Route_Scope_LINK, } diff --git a/plugins/linux/l3plugin/linuxcalls/arp_linuxcalls.go b/plugins/linux/l3plugin/linuxcalls/arp_linuxcalls.go index 5024e2b4e7..d6ed9262e0 100644 --- a/plugins/linux/l3plugin/linuxcalls/arp_linuxcalls.go +++ b/plugins/linux/l3plugin/linuxcalls/arp_linuxcalls.go @@ -17,44 +17,26 @@ package linuxcalls import ( - "time" - "github.com/vishvananda/netlink" ) // AddArpEntry creates a new static ARP entry func (handler *NetLinkHandler) AddArpEntry(name string, arpEntry *netlink.Neigh) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("add-arp-entry").LogTimeEntry(time.Since(t)) - }(time.Now()) - return netlink.NeighAdd(arpEntry) } // SetArpEntry updates existing arp entry func (handler *NetLinkHandler) SetArpEntry(name string, arpEntry *netlink.Neigh) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("set-arp-entry").LogTimeEntry(time.Since(t)) - }(time.Now()) - return netlink.NeighSet(arpEntry) } // DelArpEntry removes an static ARP entry func (handler *NetLinkHandler) DelArpEntry(name string, arpEntry *netlink.Neigh) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("del-arp-entry").LogTimeEntry(time.Since(t)) - }(time.Now()) - return netlink.NeighDel(arpEntry) } // GetArpEntries reads all configured static ARP entries for given interface // and parameters works as filters, if they are set to zero, all arp entries are returned func (handler *NetLinkHandler) GetArpEntries(interfaceIdx int, family int) ([]netlink.Neigh, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog("get-arp-entries").LogTimeEntry(time.Since(t)) - }(time.Now()) - return netlink.NeighList(interfaceIdx, family) } diff --git a/plugins/linux/l3plugin/linuxcalls/dump_l3_linuxcalls.go b/plugins/linux/l3plugin/linuxcalls/dump_l3_linuxcalls.go new file mode 100644 index 0000000000..632e82e1a0 --- /dev/null +++ b/plugins/linux/l3plugin/linuxcalls/dump_l3_linuxcalls.go @@ -0,0 +1,300 @@ +// Copyright (c) 2018 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 linuxcalls + +import ( + "net" + "strings" + + "github.com/go-errors/errors" + "github.com/ligato/vpp-agent/plugins/linux/model/l3" + "github.com/ligato/vpp-agent/plugins/linux/nsplugin" + "github.com/vishvananda/netlink" +) + +// LinuxArpDetails is the wrapper structure for the linux ARP northbound API structure. +type LinuxArpDetails struct { + Arp *l3.LinuxStaticArpEntries_ArpEntry `json:"linux_arp"` + Meta *LinuxArpMeta `json:"linux_arp_meta"` +} + +// LinuxArpMeta is combination of proto-modelled ARP data and linux provided metadata +type LinuxArpMeta struct { + LinkIndex int `json:"link_index"` + Family int `json:"family"` + State int `json:"state"` + Type int `json:"type"` + Flags int `json:"flags"` + Vlan int `json:"vlan"` + VNI int `json:"vni"` +} + +// DumpArpEntries is an implementation of linux L3 handler +func (h *NetLinkHandler) DumpArpEntries() ([]*LinuxArpDetails, error) { + var arps []*LinuxArpDetails + + ctx := nsplugin.NewNamespaceMgmtCtx() + + // Iterate over all known ARP entries + for _, arpName := range h.arpIndexes.GetMapping().ListNames() { + arpDetails := &LinuxArpDetails{} + + _, meta, found := h.arpIndexes.LookupIdx(arpName) + if !found { + h.log.Warnf("Expected ARP %s not found in the mapping", arpName) + continue + } + if meta == nil { + h.log.Warnf("Expected ARP %s metadata are missing", arpName) + continue + } + + // Copy base configuration from mapping metadata. Linux specific fields are stored in LinuxArpMeta. + arpDetails.Arp = meta + linuxArp, err := h.dumpArpData(meta, ctx) + if err != nil { + // Do not return error, read what is possible + h.log.Errorf("failed to get ARP %s data: %v", arpName, err) + continue + } + + if linuxArp == nil { + h.log.Warnf("Linux equivalent for ARP %s not found", arpName) + continue + } + + // Base fields + arpMeta := &LinuxArpMeta{ + LinkIndex: linuxArp.LinkIndex, + Family: linuxArp.Family, + State: linuxArp.State, + Type: linuxArp.Type, + Flags: linuxArp.Flags, + Vlan: linuxArp.Vlan, + VNI: linuxArp.VNI, + } + + arpDetails.Meta = arpMeta + arps = append(arps, arpDetails) + } + + return arps, nil +} + +// LinuxRouteDetails is the wrapper structure for the linux route northbound API structure. +type LinuxRouteDetails struct { + Route *l3.LinuxStaticRoutes_Route `json:"linux_route"` + Meta *LinuxRouteMeta `json:"linux_route_meta"` +} + +// LinuxRouteMeta is combination of proto-modelled route data and linux provided metadata +type LinuxRouteMeta struct { + LinkIndex int `json:"link_index"` + ILinkIndex int `json:"ilink_index"` + Scope int `json:"scope"` + Protocol int `json:"protocol"` + Priority int `json:"priority"` + Table int `json:"table"` + Type int `json:"type"` + Tos int `json:"tos"` + Flags int `json:"flags"` + MTU int `json:"mtu"` + AdvMSS int `json:"adv_mss"` + NextHops []*nextHop `json:"next_hops"` +} + +// Helper struct for next hops +type nextHop struct { + Index int + Hops int + GwIP string + Flags int +} + +// DumpRoutes is an implementation of linux route handler +func (h *NetLinkHandler) DumpRoutes() ([]*LinuxRouteDetails, error) { + var routes []*LinuxRouteDetails + + ctx := nsplugin.NewNamespaceMgmtCtx() + + // Iterate over all known Route entries + for _, rtName := range h.routeIndexes.GetMapping().ListNames() { + rtDetails := &LinuxRouteDetails{} + + _, meta, found := h.routeIndexes.LookupIdx(rtName) + if !found { + h.log.Warnf("Expected route %s not found in the mapping", rtName) + continue + } + if meta == nil { + h.log.Warnf("Expected route %s metadata are missing", rtName) + continue + } + + // Copy base configuration from mapping metadata. Linux specific fields are stored in LinuxRouteMeta. + rtDetails.Route = meta + linuxRt, err := h.dumpRouteData(meta, ctx) + if err != nil { + // Do not return error, read what is possible + h.log.Errorf("failed to get route %s data: %v", rtName, err) + continue + } + + if linuxRt == nil { + h.log.Warnf("Linux equivalent for route %s not found", rtName) + continue + } + + // Base fields + rtMeta := &LinuxRouteMeta{ + LinkIndex: linuxRt.LinkIndex, + ILinkIndex: linuxRt.ILinkIndex, + Scope: int(linuxRt.Scope), + Protocol: linuxRt.Protocol, + Priority: linuxRt.Priority, + Table: linuxRt.Table, + Type: linuxRt.Type, + Tos: linuxRt.Tos, + Flags: linuxRt.Flags, + MTU: linuxRt.MTU, + AdvMSS: linuxRt.AdvMSS, + NextHops: func(nhInfo []*netlink.NexthopInfo) (hops []*nextHop) { + for _, nh := range nhInfo { + hops = append(hops, &nextHop{ + Index: nh.LinkIndex, + Hops: nh.Hops, + GwIP: nh.Gw.String(), + Flags: nh.Flags, + }) + } + return hops + }(linuxRt.MultiPath), + } + + rtDetails.Meta = rtMeta + routes = append(routes, rtDetails) + } + + return routes, nil +} + +// Reads interface data and ip addresses from provided namespace +func (h *NetLinkHandler) dumpArpData(arp *l3.LinuxStaticArpEntries_ArpEntry, ctx *nsplugin.NamespaceMgmtCtx) (*netlink.Neigh, error) { + revert, err := h.nsHandler.SwitchNamespace(h.nsHandler.ArpNsToGeneric(arp.Namespace), ctx) + defer revert() + + var linuxArpEntry *netlink.Neigh + + if err != nil { + return nil, errors.Errorf("failed to switch to namespace: %v", err) + } + linuxArps, err := h.GetArpEntries(0, 0) // No interface/family filter + if err != nil { + return nil, errors.Errorf("failed to get ARPs from namespace: %v", err) + } + + // Parse correct ARP + for _, linuxArp := range linuxArps { + // Parse interface + if arp.Interface != "" { + _, meta, found := h.ifIndexes.LookupIdx(arp.Interface) + if !found || meta == nil { + h.log.Warnf("Interface %s for ARP %s not found", arp.Namespace, arp.Name) + continue + } + if meta.Index != uint32(linuxArp.LinkIndex) { + continue + } + } + // Parse MAC address + nbMac := strings.ToLower(arp.HwAddress) + linuxMac := strings.ToLower(linuxArp.HardwareAddr.String()) + if nbMac != linuxMac { + continue + } + // Parse IP address + if arp.IpAddr != linuxArp.IP.String() { + continue + } + + linuxArpEntry = &linuxArp + } + + return linuxArpEntry, nil +} + +// Reads interface data and ip addresses from provided namespace +func (h *NetLinkHandler) dumpRouteData(rt *l3.LinuxStaticRoutes_Route, ctx *nsplugin.NamespaceMgmtCtx) (*netlink.Route, error) { + revert, err := h.nsHandler.SwitchNamespace(h.nsHandler.RouteNsToGeneric(rt.Namespace), ctx) + defer revert() + + var linuxRtEntry *netlink.Route + + if err != nil { + return nil, errors.Errorf("failed to switch to namespace: %v", err) + } + + linuxRoutes, err := h.GetStaticRoutes(nil, 0) // Means no filter, dump all + if err != nil { + return nil, errors.Errorf("failed to read linux routes: %v", err) + } + + // Parse correct Route + for _, linuxRt := range linuxRoutes { + // Parse interface + if rt.Interface != "" { + _, meta, found := h.ifIndexes.LookupIdx(rt.Interface) + if !found || meta == nil { + h.log.Warnf("Interface %s for Route %s not found", rt.Namespace, rt.Name) + continue + } + if meta.Index != uint32(linuxRt.LinkIndex) { + continue + } + } + // Parse Dst if exists + if rt.DstIpAddr != "" { + if linuxRt.Dst == nil { + continue + } + _, rtIP, err := net.ParseCIDR(rt.DstIpAddr) + if err != nil { + h.log.Errorf("Failed to parse IP address %s: %v", rt.DstIpAddr, err) + continue + } + if rtIP.String() != linuxRt.Dst.String() { + continue + } + } + // Parse Gw if exists + if rt.GwAddr != "" { + rtIP := net.ParseIP(rt.GwAddr) + if rtIP.String() != linuxRt.Gw.String() { + continue + } + } + // Parse Src if exists + if rt.SrcIpAddr != "" { + rtIP := net.ParseIP(rt.SrcIpAddr) + if rtIP.String() != linuxRt.Src.String() { + continue + } + } + + linuxRtEntry = &linuxRt + } + + return linuxRtEntry, nil +} diff --git a/plugins/linux/l3plugin/linuxcalls/netlink_api.go b/plugins/linux/l3plugin/linuxcalls/netlink_api.go index 53560ff560..3b86881913 100644 --- a/plugins/linux/l3plugin/linuxcalls/netlink_api.go +++ b/plugins/linux/l3plugin/linuxcalls/netlink_api.go @@ -15,12 +15,21 @@ package linuxcalls import ( - "github.com/ligato/cn-infra/logging/measure" + "github.com/ligato/cn-infra/logging" + "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" + "github.com/ligato/vpp-agent/plugins/linux/l3plugin/l3idx" + "github.com/ligato/vpp-agent/plugins/linux/nsplugin" "github.com/vishvananda/netlink" ) // NetlinkAPI interface covers all methods inside linux calls package needed to manage linux ARP entries and routes. type NetlinkAPI interface { + NetlinkAPIWrite + NetlinkAPIRead +} + +// NetlinkAPIWrite interface covers write methods inside linux calls package needed to manage linux ARP entries and routes. +type NetlinkAPIWrite interface { /* ARP */ // AddArpEntry configures new linux ARP entry AddArpEntry(name string, arpEntry *netlink.Neigh) error @@ -28,8 +37,6 @@ type NetlinkAPI interface { SetArpEntry(name string, arpEntry *netlink.Neigh) error // DelArpEntry removes linux ARP entry DelArpEntry(name string, arpEntry *netlink.Neigh) error - // GetArpEntries returns all configured ARP entries from current namespace - GetArpEntries(interfaceIdx int, family int) ([]netlink.Neigh, error) /* Routes */ // AddStaticRoute adds new linux static route AddStaticRoute(name string, route *netlink.Route) error @@ -39,14 +46,40 @@ type NetlinkAPI interface { DelStaticRoute(name string, route *netlink.Route) error } +// NetlinkAPIRead interface covers read methods inside linux calls package needed to manage linux ARP entries and routes. +type NetlinkAPIRead interface { + /* ARP */ + // GetArpEntries returns all configured ARP entries from current namespace in raw netlink format. Possible to + // filter by interface and IP family. + GetArpEntries(interfaceIdx int, family int) ([]netlink.Neigh, error) + // DumpArpEntries returns all configured ARP entries known to VPP agent from all known namespaces + // in proto-modelled format + DumpArpEntries() ([]*LinuxArpDetails, error) + /* Routes */ + // GetStaticRoutes reads all linux routes from current namespace. Possible to filter by interface and IP family. + GetStaticRoutes(link netlink.Link, family int) ([]netlink.Route, error) + // DumpRoutes returns all configured routes entries known to VPP agent from all known namespaces + // in proto-modelled format + DumpRoutes() ([]*LinuxRouteDetails, error) +} + // NetLinkHandler is accessor for netlink methods type NetLinkHandler struct { - stopwatch *measure.Stopwatch + nsHandler nsplugin.NamespaceAPI + ifIndexes ifaceidx.LinuxIfIndex + arpIndexes l3idx.LinuxARPIndex + routeIndexes l3idx.LinuxRouteIndex + log logging.Logger } // NewNetLinkHandler creates new instance of netlink handler -func NewNetLinkHandler(stopwatch *measure.Stopwatch) *NetLinkHandler { +func NewNetLinkHandler(nsHandler nsplugin.NamespaceAPI, ifIndexes ifaceidx.LinuxIfIndex, arpIndexes l3idx.LinuxARPIndex, routeIndexes l3idx.LinuxRouteIndex, + log logging.Logger) *NetLinkHandler { return &NetLinkHandler{ - stopwatch: stopwatch, + nsHandler: nsHandler, + ifIndexes: ifIndexes, + arpIndexes: arpIndexes, + routeIndexes: routeIndexes, + log: log, } } diff --git a/plugins/linux/l3plugin/linuxcalls/route_linuxcalls.go b/plugins/linux/l3plugin/linuxcalls/route_linuxcalls.go index 2ed25de6e0..f6a2fcc3da 100644 --- a/plugins/linux/l3plugin/linuxcalls/route_linuxcalls.go +++ b/plugins/linux/l3plugin/linuxcalls/route_linuxcalls.go @@ -17,34 +17,25 @@ package linuxcalls import ( - "time" - "github.com/vishvananda/netlink" ) // AddStaticRoute creates the new static route -func (handler *NetLinkHandler) AddStaticRoute(name string, route *netlink.Route) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("add-static-route").LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NetLinkHandler) AddStaticRoute(name string, route *netlink.Route) error { return netlink.RouteAdd(route) } // ReplaceStaticRoute removes the static route -func (handler *NetLinkHandler) ReplaceStaticRoute(name string, route *netlink.Route) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("replace-static-route").LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NetLinkHandler) ReplaceStaticRoute(name string, route *netlink.Route) error { return netlink.RouteReplace(route) } // DelStaticRoute removes the static route -func (handler *NetLinkHandler) DelStaticRoute(name string, route *netlink.Route) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog("del-static-route").LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NetLinkHandler) DelStaticRoute(name string, route *netlink.Route) error { return netlink.RouteDel(route) } + +// GetStaticRoutes reads linux routes. Possible to filter by interface and IP family. +func (h *NetLinkHandler) GetStaticRoutes(link netlink.Link, family int) ([]netlink.Route, error) { + return netlink.RouteList(link, family) +} diff --git a/plugins/linux/l3plugin/route_config.go b/plugins/linux/l3plugin/route_config.go index fc8233fefb..06f4d875c7 100644 --- a/plugins/linux/l3plugin/route_config.go +++ b/plugins/linux/l3plugin/route_config.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/l3 --gogo_out=../model/l3 ../model/l3/l3.proto - package l3plugin import ( @@ -23,8 +21,8 @@ import ( "strconv" "strings" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/l3plugin/l3idx" @@ -58,75 +56,68 @@ type LinuxRouteConfigurator struct { // Linux namespace/calls handler l3Handler linuxcalls.NetlinkAPI nsHandler nsplugin.NamespaceAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init initializes static route configurator and starts goroutines -func (plugin *LinuxRouteConfigurator) Init(logger logging.PluginLogger, l3Handler linuxcalls.NetlinkAPI, nsHandler nsplugin.NamespaceAPI, - ifIndexes ifaceidx.LinuxIfIndexRW, stopwatch *measure.Stopwatch) error { +func (c *LinuxRouteConfigurator) Init(logger logging.PluginLogger, l3Handler linuxcalls.NetlinkAPI, nsHandler nsplugin.NamespaceAPI, + rtIndexes l3idx.LinuxRouteIndexRW, ifIndexes ifaceidx.LinuxIfIndexRW) error { // Logger - plugin.log = logger.NewLogger("-route-conf") - plugin.log.Debug("Initializing Linux Route configurator") + c.log = logger.NewLogger("route-conf") // Mappings - plugin.ifIndexes = ifIndexes - plugin.rtIndexes = l3idx.NewLinuxRouteIndex(nametoidx.NewNameToIdx(plugin.log, "linux_route_indexes", nil)) - plugin.rtAutoIndexes = l3idx.NewLinuxRouteIndex(nametoidx.NewNameToIdx(plugin.log, "linux_auto_route_indexes", nil)) - plugin.rtCachedIfRoutes = l3idx.NewLinuxRouteIndex(nametoidx.NewNameToIdx(plugin.log, "linux_cached_route_indexes", nil)) - plugin.rtCachedGwRoutes = make(map[string]*l3.LinuxStaticRoutes_Route) + c.ifIndexes = ifIndexes + c.rtIndexes = rtIndexes + c.rtAutoIndexes = l3idx.NewLinuxRouteIndex(nametoidx.NewNameToIdx(c.log, "linux_auto_route_indexes", nil)) + c.rtCachedIfRoutes = l3idx.NewLinuxRouteIndex(nametoidx.NewNameToIdx(c.log, "linux_cached_route_indexes", nil)) + c.rtCachedGwRoutes = make(map[string]*l3.LinuxStaticRoutes_Route) // L3 and namespace handler - plugin.l3Handler = l3Handler - plugin.nsHandler = nsHandler + c.l3Handler = l3Handler + c.nsHandler = nsHandler - // Configurator-wide stopwatch instance - plugin.stopwatch = stopwatch + c.log.Debug("Linux Route configurator initialized") return nil } // Close does nothing for route configurator -func (plugin *LinuxRouteConfigurator) Close() error { +func (c *LinuxRouteConfigurator) Close() error { return nil } // GetRouteIndexes returns route in-memory indexes -func (plugin *LinuxRouteConfigurator) GetRouteIndexes() l3idx.LinuxRouteIndexRW { - return plugin.rtIndexes +func (c *LinuxRouteConfigurator) GetRouteIndexes() l3idx.LinuxRouteIndexRW { + return c.rtIndexes } // GetAutoRouteIndexes returns automatic route in-memory indexes -func (plugin *LinuxRouteConfigurator) GetAutoRouteIndexes() l3idx.LinuxRouteIndexRW { - return plugin.rtAutoIndexes +func (c *LinuxRouteConfigurator) GetAutoRouteIndexes() l3idx.LinuxRouteIndexRW { + return c.rtAutoIndexes } // GetCachedRoutes returns cached route in-memory indexes -func (plugin *LinuxRouteConfigurator) GetCachedRoutes() l3idx.LinuxRouteIndexRW { - return plugin.rtCachedIfRoutes +func (c *LinuxRouteConfigurator) GetCachedRoutes() l3idx.LinuxRouteIndexRW { + return c.rtCachedIfRoutes } // GetCachedGatewayRoutes returns in-memory indexes of unreachable gateway routes -func (plugin *LinuxRouteConfigurator) GetCachedGatewayRoutes() map[string]*l3.LinuxStaticRoutes_Route { - return plugin.rtCachedGwRoutes +func (c *LinuxRouteConfigurator) GetCachedGatewayRoutes() map[string]*l3.LinuxStaticRoutes_Route { + return c.rtCachedGwRoutes } // ConfigureLinuxStaticRoute reacts to a new northbound Linux static route config by creating and configuring // the route in the host network stack through Netlink API. -func (plugin *LinuxRouteConfigurator) ConfigureLinuxStaticRoute(route *l3.LinuxStaticRoutes_Route) error { - plugin.log.Infof("Configuring linux static route %s", route.Name) - +func (c *LinuxRouteConfigurator) ConfigureLinuxStaticRoute(route *l3.LinuxStaticRoutes_Route) error { // Prepare route object netLinkRoute := &netlink.Route{} if route.Interface != "" { // Find interface - _, ifData, foundIface := plugin.ifIndexes.LookupIdx(route.Interface) + _, ifData, foundIface := c.ifIndexes.LookupIdx(route.Interface) if !foundIface || ifData == nil { - plugin.log.Infof("Static route %s requires non-existing interface %s, moving to cache", route.Name, route.Interface) - plugin.rtCachedIfRoutes.RegisterName(route.Name, plugin.rtIdxSeq, route) - plugin.rtIdxSeq++ + c.rtCachedIfRoutes.RegisterName(route.Name, c.rtIdxSeq, route) + c.rtIdxSeq++ + c.log.Debugf("Static route %s requires non-existing interface %s, moved to cache", route.Name, route.Interface) return nil } netLinkRoute.LinkIndex = int(ifData.Index) @@ -134,61 +125,59 @@ func (plugin *LinuxRouteConfigurator) ConfigureLinuxStaticRoute(route *l3.LinuxS // Check gateway reachability if route.Default || route.GwAddr != "" { - if !plugin.networkReachable(route.Namespace, route.GwAddr) { - plugin.rtCachedGwRoutes[route.Name] = route - plugin.log.Debugf("Default/Gateway route %s cached, gateway address %s is currently unreachable", + if !c.networkReachable(route.Namespace, route.GwAddr) { + c.rtCachedGwRoutes[route.Name] = route + c.log.Debugf("Default/Gateway route %s cached, gateway address %s is currently unreachable", route.Name, route.GwAddr) return nil } } // Check if route was not cached before, eventually remove it - _, ok := plugin.rtCachedGwRoutes[route.Name] + _, ok := c.rtCachedGwRoutes[route.Name] if ok { - delete(plugin.rtCachedGwRoutes, route.Name) + delete(c.rtCachedGwRoutes, route.Name) + c.log.Debugf("route %s previously cached as unreachable was removed from cache", route.Name) } // Default route if route.Default { - err := plugin.createDefaultRoute(netLinkRoute, route) - if err != nil { - plugin.log.Error(err) + if err := c.createDefaultRoute(netLinkRoute, route); err != nil { return err } } else { // Static route - err := plugin.createStaticRoute(netLinkRoute, route) - if err != nil { - plugin.log.Error(err) + if err := c.createStaticRoute(netLinkRoute, route); err != nil { return err } } // Prepare and switch to namespace where the route belongs nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - routeNs := plugin.nsHandler.RouteNsToGeneric(route.Namespace) - revertNs, err := plugin.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) + routeNs := c.nsHandler.RouteNsToGeneric(route.Namespace) + revertNs, err := c.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to switch namespace for route %s: %v", route.Name, err) } defer revertNs() - err = plugin.l3Handler.AddStaticRoute(route.Name, netLinkRoute) + err = c.l3Handler.AddStaticRoute(route.Name, netLinkRoute) if err != nil { - plugin.log.Errorf("adding static route %s failed: %v (%+v)", route.Name, err, netLinkRoute) - return err + return errors.Errorf("failed to add static route %s: %v", route.Name, err) } - plugin.rtIndexes.RegisterName(RouteIdentifier(netLinkRoute), plugin.rtIdxSeq, route) - plugin.rtIdxSeq++ - plugin.log.Debugf("Route %s registered", route.Name) + c.rtIndexes.RegisterName(RouteIdentifier(netLinkRoute), c.rtIdxSeq, route) + c.rtIdxSeq++ + c.log.Debugf("Route %s registered", route.Name) - plugin.log.Infof("Linux static route %s configured", route.Name) + c.log.Infof("Linux static route %s configured", route.Name) // Retry default routes if some of them is not configurable now if !route.Default { - plugin.retryDefaultRoutes(route) + if err := c.retryDefaultRoutes(route); err != nil { + return errors.Errorf("failed to retry default routes (after configuration of %s): %v", + route.Name, err) + } } return nil @@ -196,20 +185,19 @@ func (plugin *LinuxRouteConfigurator) ConfigureLinuxStaticRoute(route *l3.LinuxS // ModifyLinuxStaticRoute applies changes in the NB configuration of a Linux static route into the host network stack // through Netlink API. -func (plugin *LinuxRouteConfigurator) ModifyLinuxStaticRoute(newRoute *l3.LinuxStaticRoutes_Route, oldRoute *l3.LinuxStaticRoutes_Route) error { - plugin.log.Infof("Modifying linux static route %s", newRoute.Name) +func (c *LinuxRouteConfigurator) ModifyLinuxStaticRoute(newRoute *l3.LinuxStaticRoutes_Route, oldRoute *l3.LinuxStaticRoutes_Route) error { var err error - // Prepare route object netLinkRoute := &netlink.Route{} if newRoute.Interface != "" { // Find interface - _, ifData, foundIface := plugin.ifIndexes.LookupIdx(newRoute.Interface) + _, ifData, foundIface := c.ifIndexes.LookupIdx(newRoute.Interface) if !foundIface || ifData == nil { - plugin.log.Infof("Modified static route %s requires non-existing interface %s, moving to cache", newRoute.Name, newRoute.Interface) - plugin.rtCachedIfRoutes.RegisterName(newRoute.Name, plugin.rtIdxSeq, newRoute) - plugin.rtIdxSeq++ + c.rtCachedIfRoutes.RegisterName(newRoute.Name, c.rtIdxSeq, newRoute) + c.rtIdxSeq++ + c.log.Debugf("Modified static route %s requires non-existing interface %s, moving to cache", + newRoute.Name, newRoute.Interface) return nil } netLinkRoute.LinkIndex = int(ifData.Index) @@ -217,18 +205,19 @@ func (plugin *LinuxRouteConfigurator) ModifyLinuxStaticRoute(newRoute *l3.LinuxS // Check gateway reachability if newRoute.Default || newRoute.GwAddr != "" { - if !plugin.networkReachable(newRoute.Namespace, newRoute.GwAddr) { - plugin.rtCachedGwRoutes[newRoute.Name] = newRoute - plugin.log.Debugf("Default/Gateway route %s cached, gateway address %s is currently unreachable", + if !c.networkReachable(newRoute.Namespace, newRoute.GwAddr) { + c.rtCachedGwRoutes[newRoute.Name] = newRoute + c.log.Debugf("Default/Gateway route %s cached, gateway address %s is currently unreachable", newRoute.Name, newRoute.GwAddr) return nil } } // Check if route was not cached before, eventually remove it - _, ok := plugin.rtCachedGwRoutes[newRoute.Name] + _, ok := c.rtCachedGwRoutes[newRoute.Name] if ok { - delete(plugin.rtCachedGwRoutes, newRoute.Name) + delete(c.rtCachedGwRoutes, newRoute.Name) + c.log.Debugf("route %s previously cached as unreachable was removed from cache", newRoute.Name) } // If the namespace of the new route was changed, the old route needs to be removed and the new one created in the @@ -238,8 +227,8 @@ func (plugin *LinuxRouteConfigurator) ModifyLinuxStaticRoute(newRoute *l3.LinuxS // the existing one var replace bool - oldRouteNs := plugin.nsHandler.RouteNsToGeneric(oldRoute.Namespace) - newRouteNs := plugin.nsHandler.RouteNsToGeneric(newRoute.Namespace) + oldRouteNs := c.nsHandler.RouteNsToGeneric(oldRoute.Namespace) + newRouteNs := c.nsHandler.RouteNsToGeneric(newRoute.Namespace) result := oldRouteNs.CompareNamespaces(newRouteNs) if result != 0 || oldRoute.Interface != newRoute.Interface { replace = true @@ -251,74 +240,70 @@ func (plugin *LinuxRouteConfigurator) ModifyLinuxStaticRoute(newRoute *l3.LinuxS // In this case old route has to be removed replace = true } - err := plugin.createDefaultRoute(netLinkRoute, newRoute) + err := c.createDefaultRoute(netLinkRoute, newRoute) if err != nil { - plugin.log.Error(err) return err } } else { if oldRoute.DstIpAddr != newRoute.Interface { replace = true } - if err = plugin.createStaticRoute(netLinkRoute, newRoute); err != nil { - plugin.log.Error(err) + if err = c.createStaticRoute(netLinkRoute, newRoute); err != nil { return err } } // Static route will be removed and created anew if replace { - return plugin.recreateLinuxStaticRoute(netLinkRoute, newRoute) + return c.recreateLinuxStaticRoute(netLinkRoute, newRoute) } // Prepare namespace of related interface nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - routeNs := plugin.nsHandler.RouteNsToGeneric(newRoute.Namespace) + routeNs := c.nsHandler.RouteNsToGeneric(newRoute.Namespace) // route has to be created in the same namespace as the interface - revertNs, err := plugin.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) + revertNs, err := c.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to switch namspace while modifying route %s: %v", newRoute.Name, err) } defer revertNs() // Remove old route and create a new one - if err = plugin.DeleteLinuxStaticRoute(oldRoute); err != nil { - plugin.log.Errorf("deleting static route %s failed: %v (%+v)", oldRoute.Name, err, oldRoute) - return err + if err = c.DeleteLinuxStaticRoute(oldRoute); err != nil { + return errors.Errorf("modify linux route: failed to remove obsolete route %s: %v", oldRoute.Name, err) } - if err = plugin.l3Handler.AddStaticRoute(newRoute.Name, netLinkRoute); err != nil { - plugin.log.Errorf("adding static route %s failed: %v (%+v)", newRoute.Name, err, netLinkRoute) - return err + if err = c.l3Handler.AddStaticRoute(newRoute.Name, netLinkRoute); err != nil { + return errors.Errorf("modify linux route: failed to add new route %s: %v", newRoute.Name, err) } - plugin.log.Infof("Linux static route %s modified", newRoute.Name) + c.log.Infof("Linux static route %s modified", newRoute.Name) // Retry default routes if some of them is not configurable if !newRoute.Default { - plugin.retryDefaultRoutes(newRoute) + if err := c.retryDefaultRoutes(newRoute); err != nil { + return errors.Errorf("failed to retry default routes (after modification of %s): %v", + newRoute.Name, err) + } } return nil } // DeleteLinuxStaticRoute reacts to a removed NB configuration of a Linux static route entry. -func (plugin *LinuxRouteConfigurator) DeleteLinuxStaticRoute(route *l3.LinuxStaticRoutes_Route) error { - plugin.log.Infof("Removing linux static route %s", route.Name) +func (c *LinuxRouteConfigurator) DeleteLinuxStaticRoute(route *l3.LinuxStaticRoutes_Route) error { var err error - // Check if route is in cache waiting on interface - if _, _, found := plugin.rtCachedIfRoutes.LookupIdx(route.Name); found { - plugin.rtCachedIfRoutes.UnregisterName(route.Name) - plugin.log.Debugf("Route %s removed from interface cache", route.Name) + if _, _, found := c.rtCachedIfRoutes.LookupIdx(route.Name); found { + c.rtCachedIfRoutes.UnregisterName(route.Name) + c.log.Debugf("Route %s removed from interface cache", route.Name) return nil } // Check if route is in cache waiting for gateway address reachability - for _, cachedRoute := range plugin.rtCachedGwRoutes { + for _, cachedRoute := range c.rtCachedGwRoutes { if cachedRoute.Name == route.Name { - delete(plugin.rtCachedGwRoutes, cachedRoute.Name) - plugin.log.Debugf("Route %s removed from gw cache", route.Name) + delete(c.rtCachedGwRoutes, cachedRoute.Name) + c.log.Debugf("Route %s removed from gw cache", route.Name) return nil } } @@ -328,9 +313,9 @@ func (plugin *LinuxRouteConfigurator) DeleteLinuxStaticRoute(route *l3.LinuxStat if route.Interface != "" { // Find interface - _, ifData, foundIface := plugin.ifIndexes.LookupIdx(route.Interface) + _, ifData, foundIface := c.ifIndexes.LookupIdx(route.Interface) if !foundIface || ifData == nil { - return fmt.Errorf("cannot delete static route %s, interface %s not found", route.Name, route.Interface) + return errors.Errorf("cannot delete static route %s, interface %s not found", route.Name, route.Interface) } netLinkRoute.LinkIndex = int(ifData.Index) } @@ -342,12 +327,13 @@ func (plugin *LinuxRouteConfigurator) DeleteLinuxStaticRoute(route *l3.LinuxStat dstIPAddr := &net.IPNet{} _, dstIPAddr, err = net.ParseCIDR(route.DstIpAddr) if err != nil { - plugin.log.Error(err) + c.log.Error(err) return err } netLinkRoute.Dst = dstIPAddr } else { - plugin.log.Error("static route's dst address mask not set, route %s may not be removed", route.Name) + // Do not return error + c.log.Error("static route's dst address mask not set, route %s may not be removable", route.Name) } } // Gateway IP address @@ -356,55 +342,50 @@ func (plugin *LinuxRouteConfigurator) DeleteLinuxStaticRoute(route *l3.LinuxStat if gateway != nil { netLinkRoute.Gw = gateway } else { - plugin.log.Error("static route's gateway address %s has incorrect format, route %s may not be removed", + // Do not return error + c.log.Error("static route's gateway address %s has incorrect format, route %s may not be removable", route.GwAddr, route.Name) } } if netLinkRoute.Dst == nil && netLinkRoute.Gw == nil { - return fmt.Errorf("cannot delete static route %s, requred at least destination or gateway address", route.Name) + return errors.Errorf("cannot delete static route %s, required at least destination or gateway address", route.Name) } // Scope if route.Scope != nil { - netLinkRoute.Scope = plugin.parseRouteScope(route.Scope) + netLinkRoute.Scope = c.parseRouteScope(route.Scope) } // Prepare and switch to the namespace where the route belongs nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - routeNs := plugin.nsHandler.RouteNsToGeneric(route.Namespace) - revertNs, err := plugin.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) + routeNs := c.nsHandler.RouteNsToGeneric(route.Namespace) + revertNs, err := c.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to switch namespace while removing route %s: %v", route.Name, err) } defer revertNs() - err = plugin.l3Handler.DelStaticRoute(route.Name, netLinkRoute) + err = c.l3Handler.DelStaticRoute(route.Name, netLinkRoute) if err != nil { - plugin.log.Errorf("deleting static route %q failed: %v (%+v)", route.Name, err, netLinkRoute) - return err + return errors.Errorf("failed to remove linux static route %s: %v", route.Name, err) } - _, _, found := plugin.rtIndexes.UnregisterName(RouteIdentifier(netLinkRoute)) - if !found { - plugin.log.Warnf("Attempt to unregister non-registered route %s", route.Name) + _, _, found := c.rtIndexes.UnregisterName(RouteIdentifier(netLinkRoute)) + if found { + c.log.Debugf("Route %s unregistered", route.Name) } - plugin.log.Debugf("Route %s unregistered", route.Name) - plugin.log.Infof("Linux static route %s removed", route.Name) + c.log.Infof("Linux static route %s removed", route.Name) return nil } // ResolveCreatedInterface manages static routes for new interface. Linux interface also creates its own route which // can make other routes accessible and ready to create - the case is also resolved here. -func (plugin *LinuxRouteConfigurator) ResolveCreatedInterface(name string, index uint32) error { - plugin.log.Infof("Linux static route configurator: resolve new interface %s (idx %d)", name, index) - +func (c *LinuxRouteConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { // Search mapping for cached routes using the new interface - cachedIfRoutes := plugin.rtCachedIfRoutes.LookupNamesByInterface(name) + cachedIfRoutes := c.rtCachedIfRoutes.LookupNamesByInterface(ifName) if len(cachedIfRoutes) > 0 { - plugin.log.Debugf("Found %d cached routes for interface %s", len(cachedIfRoutes), name) // Store default routes, they have to be configured as the last ones var defRoutes []*l3.LinuxStaticRoutes_Route // Static routes @@ -413,38 +394,39 @@ func (plugin *LinuxRouteConfigurator) ResolveCreatedInterface(name string, index defRoutes = append(defRoutes, cachedRoute) continue } - if err := plugin.ConfigureLinuxStaticRoute(cachedRoute); err != nil { - plugin.log.Warn(err) - return err + if err := c.ConfigureLinuxStaticRoute(cachedRoute); err != nil { + return errors.Errorf("failed to configure cached route %s with registered interface %s: %v", + cachedRoute.Name, ifName, err) } // Remove from cache - plugin.rtCachedIfRoutes.UnregisterName(cachedRoute.Name) + c.rtCachedIfRoutes.UnregisterName(cachedRoute.Name) + c.log.Debugf("cached linux route %s unregistered", cachedRoute.Name) } // Default routes for _, cachedDefaultRoute := range defRoutes { - if err := plugin.ConfigureLinuxStaticRoute(cachedDefaultRoute); err != nil { - plugin.log.Warn(err) - return err + if err := c.ConfigureLinuxStaticRoute(cachedDefaultRoute); err != nil { + return errors.Errorf("failed to configure cached default route %s with registered interface %s: %v", + cachedDefaultRoute.Name, ifName, err) } // Remove from cache - plugin.rtCachedIfRoutes.UnregisterName(cachedDefaultRoute.Name) + c.rtCachedIfRoutes.UnregisterName(cachedDefaultRoute.Name) + c.log.Debugf("cached default linux route %s unregistered", cachedDefaultRoute.Name) } } // Interface also created its own route, so try to re-configure default routes - err := plugin.processAutoRoutes(name, index) + err := c.processAutoRoutes(ifName, ifIdx) if err != nil { - plugin.log.Error(err) + return err } // Try to reconfigure cached gateway routes - if len(plugin.rtCachedGwRoutes) > 0 { - plugin.log.Debugf("Found %d cached gateway routes", len(cachedIfRoutes)) + if len(c.rtCachedGwRoutes) > 0 { // Store default routes, they have to be configured as the last ones defRoutes := make(map[string]*l3.LinuxStaticRoutes_Route) - for _, cachedRoute := range plugin.rtCachedGwRoutes { + for _, cachedRoute := range c.rtCachedGwRoutes { // Check accessibility - if !plugin.networkReachable(cachedRoute.Namespace, cachedRoute.GwAddr) { + if !c.networkReachable(cachedRoute.Namespace, cachedRoute.GwAddr) { continue } else { } @@ -452,21 +434,23 @@ func (plugin *LinuxRouteConfigurator) ResolveCreatedInterface(name string, index defRoutes[cachedRoute.Name] = cachedRoute continue } - if err := plugin.ConfigureLinuxStaticRoute(cachedRoute); err != nil { - plugin.log.Warn(err) - return err + if err := c.ConfigureLinuxStaticRoute(cachedRoute); err != nil { + return errors.Errorf("failed to configure cached gateway route %s with registered interface %s: %v", + cachedRoute.Name, ifName, err) } // Remove from cache - delete(plugin.rtCachedGwRoutes, cachedRoute.Name) + delete(c.rtCachedGwRoutes, cachedRoute.Name) + c.log.Debugf("cached gateway route %s unregistered", cachedRoute.Name) } // Default routes for _, cachedDefaultRoute := range defRoutes { - if err := plugin.ConfigureLinuxStaticRoute(cachedDefaultRoute); err != nil { - plugin.log.Warn(err) - return err + if err := c.ConfigureLinuxStaticRoute(cachedDefaultRoute); err != nil { + return errors.Errorf("failed to configure cached default gateway route %s with registered interface %s: %v", + cachedDefaultRoute.Name, ifName, err) } // Remove from cache - delete(plugin.rtCachedGwRoutes, cachedDefaultRoute.Name) + delete(c.rtCachedGwRoutes, cachedDefaultRoute.Name) + c.log.Debugf("cached default gateway route %s unregistered", cachedDefaultRoute.Name) } } @@ -474,23 +458,35 @@ func (plugin *LinuxRouteConfigurator) ResolveCreatedInterface(name string, index } // ResolveDeletedInterface manages static routes for removed interface -func (plugin *LinuxRouteConfigurator) ResolveDeletedInterface(name string, index uint32) error { - plugin.log.Infof("Linux static route configurator: resolve deleted interface %v (idx %d)", name, index) - +func (c *LinuxRouteConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { // Search mapping for configured linux routes using the new interface - confRoutes := plugin.rtIndexes.LookupNamesByInterface(name) + confRoutes := c.rtIndexes.LookupNamesByInterface(ifName) if len(confRoutes) > 0 { - plugin.log.Debugf("Found %d routes belonging to the removed interface %s", len(confRoutes), name) for _, rt := range confRoutes { // Add to un-configured. If the interface will be recreated, all routes are configured back - plugin.rtCachedIfRoutes.RegisterName(rt.Name, plugin.rtIdxSeq, rt) - plugin.rtIdxSeq++ + c.rtCachedIfRoutes.RegisterName(rt.Name, c.rtIdxSeq, rt) + c.rtIdxSeq++ + c.log.Debugf("route %s registered to cache since the interface %s was unregistered", rt.Name, ifName) } } return nil } +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *LinuxRouteConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} + // RouteIdentifier generates unique route ID used in mapping func RouteIdentifier(route *netlink.Route) string { if route.Dst == nil || route.Dst.String() == ipv4AddrAny || route.Dst.String() == ipv6AddrAny { @@ -500,11 +496,11 @@ func RouteIdentifier(route *netlink.Route) string { } // Create default route object with gateway address. Destination address has to be set in such a case -func (plugin *LinuxRouteConfigurator) createDefaultRoute(netLinkRoute *netlink.Route, route *l3.LinuxStaticRoutes_Route) (err error) { +func (c *LinuxRouteConfigurator) createDefaultRoute(netLinkRoute *netlink.Route, route *l3.LinuxStaticRoutes_Route) (err error) { // Gateway gateway := net.ParseIP(route.GwAddr) if gateway == nil { - return fmt.Errorf("unable to create route %s as default, gateway is nil", route.Name) + return errors.Errorf("unable to create route %s as default, gateway is nil", route.Name) } netLinkRoute.Gw = gateway @@ -514,13 +510,12 @@ func (plugin *LinuxRouteConfigurator) createDefaultRoute(netLinkRoute *netlink.R dstIPAddr = ipv4AddrAny } if dstIPAddr != ipv4AddrAny && dstIPAddr != ipv6AddrAny { - plugin.log.Warnf("route marked as default has dst address set to %s. The address will be ignored", dstIPAddr) + c.log.Warnf("route marked as default has dst address set to %s. The address will be ignored", dstIPAddr) dstIPAddr = ipv4AddrAny } _, netLinkRoute.Dst, err = net.ParseCIDR(dstIPAddr) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to parse destination address %s for route %s: %v", dstIPAddr, route.Name, err) } // Priority @@ -528,12 +523,11 @@ func (plugin *LinuxRouteConfigurator) createDefaultRoute(netLinkRoute *netlink.R netLinkRoute.Priority = int(route.Metric) } - plugin.log.Debugf("Creating default route with gw ip %s", netLinkRoute.Gw) return nil } // Create static route from provided data -func (plugin *LinuxRouteConfigurator) createStaticRoute(netLinkRoute *netlink.Route, route *l3.LinuxStaticRoutes_Route) error { +func (c *LinuxRouteConfigurator) createStaticRoute(netLinkRoute *netlink.Route, route *l3.LinuxStaticRoutes_Route) error { var err error // Destination IP address if route.DstIpAddr != "" { @@ -542,34 +536,33 @@ func (plugin *LinuxRouteConfigurator) createStaticRoute(netLinkRoute *netlink.Ro if len(addressWithPrefix) > 1 { _, dstIPAddr, err = net.ParseCIDR(route.DstIpAddr) if err != nil { - return err + return errors.Errorf("failed to parse destination address %s for route %s: %v", + route.DstIpAddr, route.Name, err) } } else { - return fmt.Errorf("cannot create static route %s, dst address net mask not set", route.Name) + return errors.Errorf("cannot create static route %s, dst address net mask not set", route.Name) } - plugin.log.Infof("IP address %s set as dst for route %s", route.DstIpAddr, route.Name) + c.log.Debugf("IP address %s set as dst for route %s", route.DstIpAddr, route.Name) netLinkRoute.Dst = dstIPAddr } else { - return fmt.Errorf("cannot create static route %s, destination addres not set", route.Name) + return errors.Errorf("cannot create static route %s, destination address not set", route.Name) } // Set gateway if exists gateway := net.ParseIP(route.GwAddr) if gateway != nil { netLinkRoute.Gw = gateway - plugin.log.Infof("Gateway address %s set for route %s", route.GwAddr, route.Name) } // Source IP address is exists srcIPAddr := net.ParseIP(route.SrcIpAddr) if srcIPAddr != nil { netLinkRoute.Src = srcIPAddr - plugin.log.Infof("IP address %s set as src for route %s", route.SrcIpAddr, route.Name) } // Scope if route.Scope != nil { - netLinkRoute.Scope = plugin.parseRouteScope(route.Scope) + netLinkRoute.Scope = c.parseRouteScope(route.Scope) } // Priority @@ -580,33 +573,34 @@ func (plugin *LinuxRouteConfigurator) createStaticRoute(netLinkRoute *netlink.Ro // Table netLinkRoute.Table = int(route.Table) - plugin.log.Debugf("Creating static route with destination ip %s", netLinkRoute.Dst) return nil } // Update linux static route using modify (analogy to 'ip route replace') -func (plugin *LinuxRouteConfigurator) recreateLinuxStaticRoute(netLinkRoute *netlink.Route, route *l3.LinuxStaticRoutes_Route) error { - plugin.log.Debugf("Route %s modification caused the route to be removed and crated again", route.Name) +func (c *LinuxRouteConfigurator) recreateLinuxStaticRoute(netLinkRoute *netlink.Route, route *l3.LinuxStaticRoutes_Route) error { + c.log.Debugf("Route %s modification caused the route to be removed and crated again", route.Name) // Prepare namespace of related interface nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() - routeNs := plugin.nsHandler.RouteNsToGeneric(route.Namespace) + routeNs := c.nsHandler.RouteNsToGeneric(route.Namespace) // route has to be created in the same namespace as the interface - revertNs, err := plugin.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) + revertNs, err := c.nsHandler.SwitchNamespace(routeNs, nsMgmtCtx) if err != nil { - plugin.log.Error(err) - return err + return errors.Errorf("failed to switch namespace while configuring route %s: %v", route.Name, err) } defer revertNs() // Update existing route - return plugin.l3Handler.ReplaceStaticRoute(route.Name, netLinkRoute) + if err := c.l3Handler.ReplaceStaticRoute(route.Name, netLinkRoute); err != nil { + return errors.Errorf("failed to replace static rotue %s: %v", route.Name, err) + } + + return nil } // Tries to configure again cached default/gateway routes (as a reaction to the new route) -func (plugin *LinuxRouteConfigurator) retryDefaultRoutes(route *l3.LinuxStaticRoutes_Route) { - plugin.log.Debug("Retrying to configure default routes") - for _, defRoute := range plugin.rtCachedGwRoutes { +func (c *LinuxRouteConfigurator) retryDefaultRoutes(route *l3.LinuxStaticRoutes_Route) error { + for _, defRoute := range c.rtCachedGwRoutes { // Filter routes from different namespaces if defRoute.Namespace != nil && route.Namespace == nil || defRoute.Namespace == nil && route.Namespace != nil { continue @@ -619,46 +613,45 @@ func (plugin *LinuxRouteConfigurator) retryDefaultRoutes(route *l3.LinuxStaticRo gwIPParsed := net.ParseIP(defRoute.GwAddr) _, dstNet, err := net.ParseCIDR(route.DstIpAddr) if err != nil { - plugin.log.Errorf("Error parsing IP address %s: %v", route.DstIpAddr, err) - continue + return errors.Errorf("failed to parse destination address %s of cached default route %s: %v", + route.DstIpAddr, route.Name, err) } if dstNet.Contains(gwIPParsed) { // Default/Gateway route can be now configured - if err := plugin.ConfigureLinuxStaticRoute(defRoute); err != nil { - plugin.log.Errorf("Error while configuring route %s: %v", route.Name, err) + if err := c.ConfigureLinuxStaticRoute(defRoute); err != nil { + return errors.Errorf("failed to configure cached default route %s: %v", defRoute.Name, err) } - delete(plugin.rtCachedGwRoutes, defRoute.Name) - } else { - plugin.log.Debugf("%s is not within %s", defRoute.GwAddr, dstNet.IP) + delete(c.rtCachedGwRoutes, defRoute.Name) + c.log.Debugf("default route %s removed from cache", defRoute.Name) } } + + return nil } // Handles automatic route created by adding interface. Method look for routes related to the interface and its // IP address in its namespace. // Note: read route's destination address does not contain mask. This value is determined from interfaces' IP address. // Automatic routes are store in separate mapping and their names are generated. -func (plugin *LinuxRouteConfigurator) processAutoRoutes(ifName string, ifIdx uint32) error { - plugin.log.Debugf("Processing automatic interfaces for %s", ifName) +func (c *LinuxRouteConfigurator) processAutoRoutes(ifName string, ifIdx uint32) error { // Look for metadata - _, ifData, found := plugin.ifIndexes.LookupIdx(ifName) + _, ifData, found := c.ifIndexes.LookupIdx(ifName) if !found { - return fmt.Errorf("interface %s not found in the mapping", ifName) + return errors.Errorf("interface %s not found in the mapping", ifName) } if ifData == nil || ifData.Data == nil { - return fmt.Errorf("interface %s data not found in the mapping", ifName) + return errors.Errorf("interface %s data not found in the mapping", ifName) } // Move to interface with the interface if ifData.Data.Namespace != nil { nsMgmtCtx := nsplugin.NewNamespaceMgmtCtx() // Switch to namespace - ifNs := plugin.nsHandler.IfNsToGeneric(ifData.Data.Namespace) - revertNs, err := plugin.nsHandler.SwitchNamespace(ifNs, nsMgmtCtx) + ifNs := c.nsHandler.IfNsToGeneric(ifData.Data.Namespace) + revertNs, err := c.nsHandler.SwitchNamespace(ifNs, nsMgmtCtx) if err != nil { - return fmt.Errorf("RESYNC Linux route %s: failed to switch to namespace %s: %v", - ifData.Data.Name, ifData.Data.Namespace.Name, err) + return errors.Errorf("failed to switch to namespace: %v", err) } defer revertNs() } @@ -666,13 +659,13 @@ func (plugin *LinuxRouteConfigurator) processAutoRoutes(ifName string, ifIdx uin // Get interface link, err := netlink.LinkByName(ifData.Data.HostIfName) if err != nil { - return fmt.Errorf("cannot read linux interface %s (host %s): %v", ifName, ifData.Data.HostIfName, err) + return errors.Errorf("cannot read linux interface %s (host %s): %v", ifName, ifData.Data.HostIfName, err) } // Read all routes belonging to the interface linuxRts, err := netlink.RouteList(link, netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("cannot read linux routes for interface %s (host %s): %v", ifName, ifData.Data.HostIfName, err) + return errors.Errorf("cannot read linux routes for interface %s (host %s): %v", ifName, ifData.Data.HostIfName, err) } // Iterate over link addresses and look for ones related to t @@ -680,13 +673,13 @@ func (plugin *LinuxRouteConfigurator) processAutoRoutes(ifName string, ifIdx uin if linuxRt.Dst == nil { continue } - route := plugin.transformRoute(linuxRt, ifData.Data.HostIfName) + route := c.transformRoute(linuxRt, ifData.Data.HostIfName) // Route's destination address is read without mask. Use interface data to fill it. var routeFound bool for ipIdx, ifIP := range ifData.Data.IpAddresses { _, ifDst, err := net.ParseCIDR(ifIP) if err != nil { - return err + return errors.Errorf("failed to parse IP address %s: %v", ifIP, err) } if bytes.Compare(linuxRt.Dst.IP, ifDst.IP) == 0 { // Transform destination IP and namespace @@ -696,25 +689,28 @@ func (plugin *LinuxRouteConfigurator) processAutoRoutes(ifName string, ifIdx uin } } if !routeFound { - plugin.log.Debugf("Route with IP %s skipped", linuxRt.Dst.IP.String()) + c.log.Debugf("Route with IP %s skipped", linuxRt.Dst.IP.String()) continue } // Generate name route.Name = ifName + strconv.Itoa(rtIdx) // In case there is obsolete route with the same name, remove it - plugin.rtAutoIndexes.UnregisterName(route.Name) - plugin.rtAutoIndexes.RegisterName(route.Name, plugin.rtIdxSeq, route) - plugin.rtIdxSeq++ + // TODO use update metadata (needs to be implemented in custom mapping) + c.rtAutoIndexes.UnregisterName(route.Name) + c.rtAutoIndexes.RegisterName(route.Name, c.rtIdxSeq, route) + c.rtIdxSeq++ // Also try to configure default routes - plugin.retryDefaultRoutes(route) + if err := c.retryDefaultRoutes(route); err != nil { + return errors.Errorf("auto route processing: error retrying default routes: %v", err) + } } return nil } // Transform linux netlink route type to proto message type -func (plugin *LinuxRouteConfigurator) transformRoute(linuxRt netlink.Route, ifName string) *l3.LinuxStaticRoutes_Route { +func (c *LinuxRouteConfigurator) transformRoute(linuxRt netlink.Route, ifName string) *l3.LinuxStaticRoutes_Route { var dstAddr, srcAddr, gwAddr string // Destination address if linuxRt.Dst != nil { @@ -745,7 +741,7 @@ func (plugin *LinuxRouteConfigurator) transformRoute(linuxRt netlink.Route, ifNa DstIpAddr: dstAddr, SrcIpAddr: srcAddr, GwAddr: gwAddr, - Scope: plugin.parseLinuxRouteScope(linuxRt.Scope), + Scope: c.parseLinuxRouteScope(linuxRt.Scope), Metric: uint32(linuxRt.Priority), Table: uint32(linuxRt.Table), } @@ -779,7 +775,7 @@ func transformNamespace(ifNs *interfaces.LinuxInterfaces_Interface_Namespace) *l } // Agent route scope -> netlink route scope -func (plugin *LinuxRouteConfigurator) parseRouteScope(scope *l3.LinuxStaticRoutes_Route_Scope) netlink.Scope { +func (c *LinuxRouteConfigurator) parseRouteScope(scope *l3.LinuxStaticRoutes_Route_Scope) netlink.Scope { switch scope.Type { case l3.LinuxStaticRoutes_Route_Scope_GLOBAL: return netlink.SCOPE_UNIVERSE @@ -790,25 +786,25 @@ func (plugin *LinuxRouteConfigurator) parseRouteScope(scope *l3.LinuxStaticRoute case l3.LinuxStaticRoutes_Route_Scope_SITE: return netlink.SCOPE_SITE default: - plugin.log.Infof("Unknown scope type, setting to default (link): %v", scope.Type) + c.log.Infof("Unknown scope type, setting to default (link): %v", scope.Type) return netlink.SCOPE_LINK } } // Verifies whether address network is reachable. -func (plugin *LinuxRouteConfigurator) networkReachable(ns *l3.LinuxStaticRoutes_Route_Namespace, ipAddress string) bool { +func (c *LinuxRouteConfigurator) networkReachable(ns *l3.LinuxStaticRoutes_Route_Namespace, ipAddress string) bool { // Try for registered configuration routes - registeredRoute, err := plugin.rtIndexes.LookupRouteByIP(ns, ipAddress) + registeredRoute, err := c.rtIndexes.LookupRouteByIP(ns, ipAddress) if err != nil { - plugin.log.Errorf("Failed to resolve accessibility of %s (registered): %v", ipAddress, err) + c.log.Errorf("Failed to resolve accessibility of %s (registered): %v", ipAddress, err) } // Try for registered automatic (interface-added) routes - autoRoute, err := plugin.rtAutoIndexes.LookupRouteByIP(ns, ipAddress) + autoRoute, err := c.rtAutoIndexes.LookupRouteByIP(ns, ipAddress) if err != nil { - plugin.log.Errorf("Failed to resolve accessibility of %s (auto): %v", ipAddress, err) + c.log.Errorf("Failed to resolve accessibility of %s (auto): %v", ipAddress, err) } if registeredRoute != nil || autoRoute != nil { - plugin.log.Debugf("Network %s is reachable", ipAddress) + c.log.Debugf("Network %s is reachable", ipAddress) return true } return false diff --git a/plugins/linux/l3plugin/route_config_test.go b/plugins/linux/l3plugin/route_config_test.go index 03453ba067..ef260aec31 100644 --- a/plugins/linux/l3plugin/route_config_test.go +++ b/plugins/linux/l3plugin/route_config_test.go @@ -19,8 +19,9 @@ import ( "net" "testing" + "github.com/ligato/vpp-agent/plugins/linux/l3plugin/l3idx" + "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/l3plugin" @@ -326,11 +327,12 @@ func routeTestSetup(t *testing.T) (*l3plugin.LinuxRouteConfigurator, *linuxmock. nsHandleLog.SetLevel(logging.DebugLevel) // Linux interface indexes ifIndexes := ifaceidx.NewLinuxIfIndex(nametoidx.NewNameToIdx(pluginLog, "if", nil)) + rtIndexes := l3idx.NewLinuxRouteIndex(nametoidx.NewNameToIdx(pluginLog, "rt", nil)) // Configurator plugin := &l3plugin.LinuxRouteConfigurator{} linuxMock := linuxmock.NewL3NetlinkHandlerMock() nsMock := linuxmock.NewNamespacePluginMock() - err := plugin.Init(pluginLog, linuxMock, nsMock, ifIndexes, measure.NewStopwatch("LinuxRouteTest", pluginLog)) + err := plugin.Init(pluginLog, linuxMock, nsMock, rtIndexes, ifIndexes) Expect(err).To(BeNil()) return plugin, linuxMock, nsMock, ifIndexes diff --git a/plugins/linux/linuxplugin.conf b/plugins/linux/linuxplugin.conf index 6e09eb0564..28a881b747 100644 --- a/plugins/linux/linuxplugin.conf +++ b/plugins/linux/linuxplugin.conf @@ -1,6 +1,2 @@ -# Enable or disable feature to measure netlink API call duration. Measured time is shown directly in log (info level). -# Measurement is taken also for certain procedures, like resync of plugin startup. Turned off by default. -stopwatch: false - # Used to disable entire linux plugin functionality. Turned off by default. disabled: false \ No newline at end of file diff --git a/plugins/linux/linuxplugin_api.go b/plugins/linux/linuxplugin_api.go index 3da57f5bee..448a8ebb05 100644 --- a/plugins/linux/linuxplugin_api.go +++ b/plugins/linux/linuxplugin_api.go @@ -17,6 +17,7 @@ package linux import ( "github.com/ligato/vpp-agent/plugins/linux/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/linux/l3plugin/l3idx" + "github.com/ligato/vpp-agent/plugins/linux/nsplugin" ) // API of Linux Plugin @@ -35,4 +36,7 @@ type API interface { // route indexes. This mapping is especially helpful for plugins that need to watch for newly added or deleted // Linux routes. GetLinuxRouteIndexes() l3idx.LinuxRouteIndex + + // GetNamespaceHandler gives access to namespace API which allows plugins to manipulate with linux namespaces + GetNamespaceHandler() nsplugin.NamespaceAPI } diff --git a/plugins/linux/linuxplugin_init.go b/plugins/linux/linuxplugin_init.go index 026854434e..6b80b4e108 100644 --- a/plugins/linux/linuxplugin_init.go +++ b/plugins/linux/linuxplugin_init.go @@ -23,7 +23,6 @@ import ( "github.com/ligato/cn-infra/datasync" "github.com/ligato/cn-infra/health/statuscheck" "github.com/ligato/cn-infra/infra" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/servicelabel" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -45,9 +44,10 @@ type Plugin struct { disabled bool // Configurators - ifConfigurator *ifplugin.LinuxInterfaceConfigurator - arpConfigurator *l3plugin.LinuxArpConfigurator - routeConfigurator *l3plugin.LinuxRouteConfigurator + ifConfigurator *ifplugin.LinuxInterfaceConfigurator + ifLinuxStateUpdater *ifplugin.LinuxInterfaceStateUpdater + arpConfigurator *l3plugin.LinuxArpConfigurator + routeConfigurator *l3plugin.LinuxRouteConfigurator // Shared indexes ifIndexes ifaceidx.LinuxIfIndexRW @@ -60,6 +60,7 @@ type Plugin struct { // Channels (watch, notification, ...) which should be closed ifIndexesWatchChan chan ifaceidx.LinuxIfIndexDto vppIfIndexesWatchChan chan ifaceVPP.SwIfIdxDto + ifLinuxNotifChan chan *ifplugin.LinuxInterfaceStateNotification ifMicroserviceNotif chan *nsplugin.MicroserviceEvent resyncChan chan datasync.ResyncEvent changeChan chan datasync.ChangeEvent // TODO dedicated type abstracted from ETCD @@ -68,9 +69,6 @@ type Plugin struct { // Registrations watchDataReg datasync.WatchRegistration - // From config file - stopwatch *measure.Stopwatch - // Common cancel context.CancelFunc // Cancel can be used to cancel all goroutines and their jobs inside of the plugin. wg sync.WaitGroup // Wait group allows to wait until all goroutines of the plugin have finished. @@ -112,6 +110,11 @@ func (plugin *Plugin) GetLinuxRouteIndexes() l3idx.LinuxRouteIndex { return plugin.routeConfigurator.GetRouteIndexes() } +// GetNamespaceHandler gives access to namespace API which allows plugins to manipulate with linux namespaces +func (plugin *Plugin) GetNamespaceHandler() nsplugin.NamespaceAPI { + return plugin.nsHandler +} + // InjectVppIfIndexes injects VPP interfaces mapping into Linux plugin func (plugin *Plugin) InjectVppIfIndexes(indexes ifaceVPP.SwIfIndex) { plugin.vppIfIndexes = indexes @@ -132,12 +135,6 @@ func (plugin *Plugin) Init() error { plugin.Log.Infof("Disabling Linux plugin") return nil } - if config.Stopwatch { - plugin.Log.Infof("stopwatch enabled for %v", plugin.PluginName) - plugin.stopwatch = measure.NewStopwatch("LinuxPlugin", plugin.Log) - } else { - plugin.Log.Infof("stopwatch disabled for %v", plugin.PluginName) - } } else { plugin.Log.Infof("stopwatch disabled for %v", plugin.PluginName) } @@ -186,6 +183,8 @@ func (plugin *Plugin) Close() error { return safeclose.Close( // Configurators plugin.ifConfigurator, plugin.arpConfigurator, plugin.routeConfigurator, + // Status updater + plugin.ifLinuxStateUpdater, // Channels plugin.ifIndexesWatchChan, plugin.ifMicroserviceNotif, plugin.changeChan, plugin.resyncChan, plugin.msChan, @@ -198,12 +197,9 @@ func (plugin *Plugin) Close() error { func (plugin *Plugin) initNs() error { plugin.Log.Infof("Init Linux namespace handler") - // Shared interface linux calls handler - plugin.ifHandler = ifLinuxcalls.NewNetLinkHandler(plugin.stopwatch) - namespaceHandler := &nsplugin.NsHandler{} plugin.nsHandler = namespaceHandler - return namespaceHandler.Init(plugin.Log, plugin.ifHandler, nsplugin.NewSystemHandler(), plugin.msChan, + return namespaceHandler.Init(plugin.Log, nsplugin.NewSystemHandler(), plugin.msChan, plugin.ifMicroserviceNotif) } @@ -214,11 +210,19 @@ func (plugin *Plugin) initIF(ctx context.Context) error { // Init shared interface index mapping plugin.ifIndexes = ifaceidx.NewLinuxIfIndex(nametoidx.NewNameToIdx(plugin.Log, "linux_if_indexes", nil)) + // Shared interface linux calls handler + plugin.ifHandler = ifLinuxcalls.NewNetLinkHandler(plugin.nsHandler, plugin.ifIndexes, plugin.Log) + // Linux interface configurator + plugin.ifLinuxNotifChan = make(chan *ifplugin.LinuxInterfaceStateNotification, 10) plugin.ifConfigurator = &ifplugin.LinuxInterfaceConfigurator{} - if err := plugin.ifConfigurator.Init(plugin.Log, plugin.ifHandler, plugin.nsHandler, plugin.ifIndexes, - plugin.ifMicroserviceNotif, plugin.stopwatch); err != nil { - return err + if err := plugin.ifConfigurator.Init(plugin.Log, plugin.ifHandler, plugin.nsHandler, nsplugin.NewSystemHandler(), + plugin.ifIndexes, plugin.ifMicroserviceNotif, plugin.ifLinuxNotifChan); err != nil { + return plugin.ifConfigurator.LogError(err) + } + plugin.ifLinuxStateUpdater = &ifplugin.LinuxInterfaceStateUpdater{} + if err := plugin.ifLinuxStateUpdater.Init(ctx, plugin.Log, plugin.ifIndexes, plugin.ifLinuxNotifChan); err != nil { + return plugin.ifConfigurator.LogError(err) } return nil @@ -228,18 +232,26 @@ func (plugin *Plugin) initIF(ctx context.Context) error { func (plugin *Plugin) initL3() error { plugin.Log.Infof("Init Linux L3 plugin") + // Init shared ARP/Route index mapping + arpIndexes := l3idx.NewLinuxARPIndex(nametoidx.NewNameToIdx(plugin.Log, "linux_arp_indexes", nil)) + routeIndexes := l3idx.NewLinuxRouteIndex(nametoidx.NewNameToIdx(plugin.Log, "linux_route_indexes", nil)) + // L3 linux calls handler - l3Handler := l3Linuxcalls.NewNetLinkHandler(plugin.stopwatch) + l3Handler := l3Linuxcalls.NewNetLinkHandler(plugin.nsHandler, plugin.ifIndexes, arpIndexes, routeIndexes, plugin.Log) // Linux ARP configurator plugin.arpConfigurator = &l3plugin.LinuxArpConfigurator{} - if err := plugin.arpConfigurator.Init(plugin.Log, l3Handler, plugin.nsHandler, plugin.ifIndexes, plugin.stopwatch); err != nil { - return err + if err := plugin.arpConfigurator.Init(plugin.Log, l3Handler, plugin.nsHandler, arpIndexes, plugin.ifIndexes); err != nil { + return plugin.arpConfigurator.LogError(err) } // Linux Route configurator plugin.routeConfigurator = &l3plugin.LinuxRouteConfigurator{} - return plugin.routeConfigurator.Init(plugin.Log, l3Handler, plugin.nsHandler, plugin.ifIndexes, plugin.stopwatch) + if err := plugin.routeConfigurator.Init(plugin.Log, l3Handler, plugin.nsHandler, routeIndexes, plugin.ifIndexes); err != nil { + plugin.routeConfigurator.LogError(err) + } + + return nil } func (plugin *Plugin) retrieveLinuxConfig() (*Config, error) { diff --git a/plugins/linux/model/gen.go b/plugins/linux/model/gen.go new file mode 100644 index 0000000000..f76e2eaafd --- /dev/null +++ b/plugins/linux/model/gen.go @@ -0,0 +1,18 @@ +// Copyright (c) 2018 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 protoc --proto_path=interfaces --gogo_out=interfaces interfaces/interfaces.proto +//go:generate protoc --proto_path=l3 --gogo_out=l3 l3/l3.proto + +package model diff --git a/plugins/linux/model/interfaces/interfaces.pb.go b/plugins/linux/model/interfaces/interfaces.pb.go index 3d68a3d0ee..1e826c3518 100644 --- a/plugins/linux/model/interfaces/interfaces.pb.go +++ b/plugins/linux/model/interfaces/interfaces.pb.go @@ -1,15 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: interfaces.proto -/* -Package interfaces is a generated protocol buffer package. - -It is generated from these files: - interfaces.proto - -It has these top-level messages: - LinuxInterfaces -*/ package interfaces import proto "github.com/gogo/protobuf/proto" @@ -47,7 +38,7 @@ func (x LinuxInterfaces_InterfaceType) String() string { return proto.EnumName(LinuxInterfaces_InterfaceType_name, int32(x)) } func (LinuxInterfaces_InterfaceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0} + return fileDescriptor_interfaces_e1580d882dd65c0f, []int{0, 0} } type LinuxInterfaces_Interface_Namespace_NamespaceType int32 @@ -76,17 +67,39 @@ func (x LinuxInterfaces_Interface_Namespace_NamespaceType) String() string { return proto.EnumName(LinuxInterfaces_Interface_Namespace_NamespaceType_name, int32(x)) } func (LinuxInterfaces_Interface_Namespace_NamespaceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 0, 0} + return fileDescriptor_interfaces_e1580d882dd65c0f, []int{0, 0, 0, 0} } type LinuxInterfaces struct { - Interface []*LinuxInterfaces_Interface `protobuf:"bytes,1,rep,name=interface" json:"interface,omitempty"` + Interface []*LinuxInterfaces_Interface `protobuf:"bytes,1,rep,name=interface" json:"interface,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LinuxInterfaces) Reset() { *m = LinuxInterfaces{} } +func (m *LinuxInterfaces) String() string { return proto.CompactTextString(m) } +func (*LinuxInterfaces) ProtoMessage() {} +func (*LinuxInterfaces) Descriptor() ([]byte, []int) { + return fileDescriptor_interfaces_e1580d882dd65c0f, []int{0} +} +func (m *LinuxInterfaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxInterfaces.Unmarshal(m, b) +} +func (m *LinuxInterfaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxInterfaces.Marshal(b, m, deterministic) +} +func (dst *LinuxInterfaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxInterfaces.Merge(dst, src) +} +func (m *LinuxInterfaces) XXX_Size() int { + return xxx_messageInfo_LinuxInterfaces.Size(m) +} +func (m *LinuxInterfaces) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxInterfaces.DiscardUnknown(m) } -func (m *LinuxInterfaces) Reset() { *m = LinuxInterfaces{} } -func (m *LinuxInterfaces) String() string { return proto.CompactTextString(m) } -func (*LinuxInterfaces) ProtoMessage() {} -func (*LinuxInterfaces) Descriptor() ([]byte, []int) { return fileDescriptorInterfaces, []int{0} } +var xxx_messageInfo_LinuxInterfaces proto.InternalMessageInfo func (m *LinuxInterfaces) GetInterface() []*LinuxInterfaces_Interface { if m != nil { @@ -96,25 +109,45 @@ func (m *LinuxInterfaces) GetInterface() []*LinuxInterfaces_Interface { } type LinuxInterfaces_Interface struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - Type LinuxInterfaces_InterfaceType `protobuf:"varint,3,opt,name=type,proto3,enum=interfaces.LinuxInterfaces_InterfaceType" json:"type,omitempty"` - Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` - IpAddresses []string `protobuf:"bytes,5,rep,name=ip_addresses,json=ipAddresses" json:"ip_addresses,omitempty"` - PhysAddress string `protobuf:"bytes,6,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` - Mtu uint32 `protobuf:"varint,7,opt,name=mtu,proto3" json:"mtu,omitempty"` - HostIfName string `protobuf:"bytes,8,opt,name=host_if_name,json=hostIfName,proto3" json:"host_if_name,omitempty"` - Namespace *LinuxInterfaces_Interface_Namespace `protobuf:"bytes,9,opt,name=namespace" json:"namespace,omitempty"` - Veth *LinuxInterfaces_Interface_Veth `protobuf:"bytes,10,opt,name=veth" json:"veth,omitempty"` - Tap *LinuxInterfaces_Interface_Tap `protobuf:"bytes,11,opt,name=tap" json:"tap,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Type LinuxInterfaces_InterfaceType `protobuf:"varint,3,opt,name=type,proto3,enum=interfaces.LinuxInterfaces_InterfaceType" json:"type,omitempty"` + Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` + IpAddresses []string `protobuf:"bytes,5,rep,name=ip_addresses,json=ipAddresses" json:"ip_addresses,omitempty"` + PhysAddress string `protobuf:"bytes,6,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` + Mtu uint32 `protobuf:"varint,7,opt,name=mtu,proto3" json:"mtu,omitempty"` + HostIfName string `protobuf:"bytes,8,opt,name=host_if_name,json=hostIfName,proto3" json:"host_if_name,omitempty"` + Namespace *LinuxInterfaces_Interface_Namespace `protobuf:"bytes,9,opt,name=namespace" json:"namespace,omitempty"` + Veth *LinuxInterfaces_Interface_Veth `protobuf:"bytes,10,opt,name=veth" json:"veth,omitempty"` + Tap *LinuxInterfaces_Interface_Tap `protobuf:"bytes,11,opt,name=tap" json:"tap,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxInterfaces_Interface) Reset() { *m = LinuxInterfaces_Interface{} } func (m *LinuxInterfaces_Interface) String() string { return proto.CompactTextString(m) } func (*LinuxInterfaces_Interface) ProtoMessage() {} func (*LinuxInterfaces_Interface) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0} + return fileDescriptor_interfaces_e1580d882dd65c0f, []int{0, 0} } +func (m *LinuxInterfaces_Interface) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxInterfaces_Interface.Unmarshal(m, b) +} +func (m *LinuxInterfaces_Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxInterfaces_Interface.Marshal(b, m, deterministic) +} +func (dst *LinuxInterfaces_Interface) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxInterfaces_Interface.Merge(dst, src) +} +func (m *LinuxInterfaces_Interface) XXX_Size() int { + return xxx_messageInfo_LinuxInterfaces_Interface.Size(m) +} +func (m *LinuxInterfaces_Interface) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxInterfaces_Interface.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxInterfaces_Interface proto.InternalMessageInfo func (m *LinuxInterfaces_Interface) GetName() string { if m != nil { @@ -194,19 +227,39 @@ func (m *LinuxInterfaces_Interface) GetTap() *LinuxInterfaces_Interface_Tap { } type LinuxInterfaces_Interface_Namespace struct { - Type LinuxInterfaces_Interface_Namespace_NamespaceType `protobuf:"varint,1,opt,name=type,proto3,enum=interfaces.LinuxInterfaces_Interface_Namespace_NamespaceType" json:"type,omitempty"` - Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` - Microservice string `protobuf:"bytes,3,opt,name=microservice,proto3" json:"microservice,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Filepath string `protobuf:"bytes,5,opt,name=filepath,proto3" json:"filepath,omitempty"` + Type LinuxInterfaces_Interface_Namespace_NamespaceType `protobuf:"varint,1,opt,name=type,proto3,enum=interfaces.LinuxInterfaces_Interface_Namespace_NamespaceType" json:"type,omitempty"` + Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` + Microservice string `protobuf:"bytes,3,opt,name=microservice,proto3" json:"microservice,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Filepath string `protobuf:"bytes,5,opt,name=filepath,proto3" json:"filepath,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxInterfaces_Interface_Namespace) Reset() { *m = LinuxInterfaces_Interface_Namespace{} } func (m *LinuxInterfaces_Interface_Namespace) String() string { return proto.CompactTextString(m) } func (*LinuxInterfaces_Interface_Namespace) ProtoMessage() {} func (*LinuxInterfaces_Interface_Namespace) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 0} + return fileDescriptor_interfaces_e1580d882dd65c0f, []int{0, 0, 0} +} +func (m *LinuxInterfaces_Interface_Namespace) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxInterfaces_Interface_Namespace.Unmarshal(m, b) +} +func (m *LinuxInterfaces_Interface_Namespace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxInterfaces_Interface_Namespace.Marshal(b, m, deterministic) } +func (dst *LinuxInterfaces_Interface_Namespace) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxInterfaces_Interface_Namespace.Merge(dst, src) +} +func (m *LinuxInterfaces_Interface_Namespace) XXX_Size() int { + return xxx_messageInfo_LinuxInterfaces_Interface_Namespace.Size(m) +} +func (m *LinuxInterfaces_Interface_Namespace) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxInterfaces_Interface_Namespace.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxInterfaces_Interface_Namespace proto.InternalMessageInfo func (m *LinuxInterfaces_Interface_Namespace) GetType() LinuxInterfaces_Interface_Namespace_NamespaceType { if m != nil { @@ -244,15 +297,35 @@ func (m *LinuxInterfaces_Interface_Namespace) GetFilepath() string { } type LinuxInterfaces_Interface_Veth struct { - PeerIfName string `protobuf:"bytes,1,opt,name=peer_if_name,json=peerIfName,proto3" json:"peer_if_name,omitempty"` + PeerIfName string `protobuf:"bytes,1,opt,name=peer_if_name,json=peerIfName,proto3" json:"peer_if_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxInterfaces_Interface_Veth) Reset() { *m = LinuxInterfaces_Interface_Veth{} } func (m *LinuxInterfaces_Interface_Veth) String() string { return proto.CompactTextString(m) } func (*LinuxInterfaces_Interface_Veth) ProtoMessage() {} func (*LinuxInterfaces_Interface_Veth) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 1} + return fileDescriptor_interfaces_e1580d882dd65c0f, []int{0, 0, 1} +} +func (m *LinuxInterfaces_Interface_Veth) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxInterfaces_Interface_Veth.Unmarshal(m, b) +} +func (m *LinuxInterfaces_Interface_Veth) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxInterfaces_Interface_Veth.Marshal(b, m, deterministic) +} +func (dst *LinuxInterfaces_Interface_Veth) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxInterfaces_Interface_Veth.Merge(dst, src) +} +func (m *LinuxInterfaces_Interface_Veth) XXX_Size() int { + return xxx_messageInfo_LinuxInterfaces_Interface_Veth.Size(m) } +func (m *LinuxInterfaces_Interface_Veth) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxInterfaces_Interface_Veth.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxInterfaces_Interface_Veth proto.InternalMessageInfo func (m *LinuxInterfaces_Interface_Veth) GetPeerIfName() string { if m != nil { @@ -262,15 +335,35 @@ func (m *LinuxInterfaces_Interface_Veth) GetPeerIfName() string { } type LinuxInterfaces_Interface_Tap struct { - TempIfName string `protobuf:"bytes,1,opt,name=temp_if_name,json=tempIfName,proto3" json:"temp_if_name,omitempty"` + TempIfName string `protobuf:"bytes,1,opt,name=temp_if_name,json=tempIfName,proto3" json:"temp_if_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxInterfaces_Interface_Tap) Reset() { *m = LinuxInterfaces_Interface_Tap{} } func (m *LinuxInterfaces_Interface_Tap) String() string { return proto.CompactTextString(m) } func (*LinuxInterfaces_Interface_Tap) ProtoMessage() {} func (*LinuxInterfaces_Interface_Tap) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 2} + return fileDescriptor_interfaces_e1580d882dd65c0f, []int{0, 0, 2} +} +func (m *LinuxInterfaces_Interface_Tap) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxInterfaces_Interface_Tap.Unmarshal(m, b) +} +func (m *LinuxInterfaces_Interface_Tap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxInterfaces_Interface_Tap.Marshal(b, m, deterministic) } +func (dst *LinuxInterfaces_Interface_Tap) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxInterfaces_Interface_Tap.Merge(dst, src) +} +func (m *LinuxInterfaces_Interface_Tap) XXX_Size() int { + return xxx_messageInfo_LinuxInterfaces_Interface_Tap.Size(m) +} +func (m *LinuxInterfaces_Interface_Tap) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxInterfaces_Interface_Tap.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxInterfaces_Interface_Tap proto.InternalMessageInfo func (m *LinuxInterfaces_Interface_Tap) GetTempIfName() string { if m != nil { @@ -289,9 +382,9 @@ func init() { proto.RegisterEnum("interfaces.LinuxInterfaces_Interface_Namespace_NamespaceType", LinuxInterfaces_Interface_Namespace_NamespaceType_name, LinuxInterfaces_Interface_Namespace_NamespaceType_value) } -func init() { proto.RegisterFile("interfaces.proto", fileDescriptorInterfaces) } +func init() { proto.RegisterFile("interfaces.proto", fileDescriptor_interfaces_e1580d882dd65c0f) } -var fileDescriptorInterfaces = []byte{ +var fileDescriptor_interfaces_e1580d882dd65c0f = []byte{ // 499 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xc1, 0x6e, 0x9b, 0x40, 0x10, 0x0d, 0x86, 0xd8, 0x30, 0xd8, 0x09, 0xda, 0x1e, 0xba, 0xe2, 0x44, 0x2d, 0x55, 0xa1, 0x3d, diff --git a/plugins/linux/model/l3/l3.pb.go b/plugins/linux/model/l3/l3.pb.go index b13b0e7676..34332a5614 100644 --- a/plugins/linux/model/l3/l3.pb.go +++ b/plugins/linux/model/l3/l3.pb.go @@ -1,16 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: l3.proto -/* -Package l3 is a generated protocol buffer package. - -It is generated from these files: - l3.proto - -It has these top-level messages: - LinuxStaticRoutes - LinuxStaticArpEntries -*/ package l3 import proto "github.com/gogo/protobuf/proto" @@ -54,7 +44,7 @@ func (x LinuxStaticRoutes_Route_Namespace_NamespaceType) String() string { return proto.EnumName(LinuxStaticRoutes_Route_Namespace_NamespaceType_name, int32(x)) } func (LinuxStaticRoutes_Route_Namespace_NamespaceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorL3, []int{0, 0, 0, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{0, 0, 0, 0} } type LinuxStaticRoutes_Route_Scope_ScopeType int32 @@ -83,7 +73,7 @@ func (x LinuxStaticRoutes_Route_Scope_ScopeType) String() string { return proto.EnumName(LinuxStaticRoutes_Route_Scope_ScopeType_name, int32(x)) } func (LinuxStaticRoutes_Route_Scope_ScopeType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorL3, []int{0, 0, 1, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{0, 0, 1, 0} } type LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType int32 @@ -112,7 +102,7 @@ func (x LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType) String() string return proto.EnumName(LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType_name, int32(x)) } func (LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorL3, []int{1, 0, 0, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1, 0, 0, 0} } type LinuxStaticArpEntries_ArpEntry_IpFamily_Family int32 @@ -141,7 +131,7 @@ func (x LinuxStaticArpEntries_ArpEntry_IpFamily_Family) String() string { return proto.EnumName(LinuxStaticArpEntries_ArpEntry_IpFamily_Family_name, int32(x)) } func (LinuxStaticArpEntries_ArpEntry_IpFamily_Family) EnumDescriptor() ([]byte, []int) { - return fileDescriptorL3, []int{1, 0, 1, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1, 0, 1, 0} } type LinuxStaticArpEntries_ArpEntry_NudState_NudStateType int32 @@ -170,18 +160,40 @@ func (x LinuxStaticArpEntries_ArpEntry_NudState_NudStateType) String() string { return proto.EnumName(LinuxStaticArpEntries_ArpEntry_NudState_NudStateType_name, int32(x)) } func (LinuxStaticArpEntries_ArpEntry_NudState_NudStateType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorL3, []int{1, 0, 2, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1, 0, 2, 0} } // static ip routes type LinuxStaticRoutes struct { - Route []*LinuxStaticRoutes_Route `protobuf:"bytes,1,rep,name=route" json:"route,omitempty"` + Route []*LinuxStaticRoutes_Route `protobuf:"bytes,1,rep,name=route" json:"route,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LinuxStaticRoutes) Reset() { *m = LinuxStaticRoutes{} } +func (m *LinuxStaticRoutes) String() string { return proto.CompactTextString(m) } +func (*LinuxStaticRoutes) ProtoMessage() {} +func (*LinuxStaticRoutes) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{0} +} +func (m *LinuxStaticRoutes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticRoutes.Unmarshal(m, b) +} +func (m *LinuxStaticRoutes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticRoutes.Marshal(b, m, deterministic) +} +func (dst *LinuxStaticRoutes) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticRoutes.Merge(dst, src) +} +func (m *LinuxStaticRoutes) XXX_Size() int { + return xxx_messageInfo_LinuxStaticRoutes.Size(m) +} +func (m *LinuxStaticRoutes) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticRoutes.DiscardUnknown(m) } -func (m *LinuxStaticRoutes) Reset() { *m = LinuxStaticRoutes{} } -func (m *LinuxStaticRoutes) String() string { return proto.CompactTextString(m) } -func (*LinuxStaticRoutes) ProtoMessage() {} -func (*LinuxStaticRoutes) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{0} } +var xxx_messageInfo_LinuxStaticRoutes proto.InternalMessageInfo func (m *LinuxStaticRoutes) GetRoute() []*LinuxStaticRoutes_Route { if m != nil { @@ -191,23 +203,45 @@ func (m *LinuxStaticRoutes) GetRoute() []*LinuxStaticRoutes_Route { } type LinuxStaticRoutes_Route struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"` - Namespace *LinuxStaticRoutes_Route_Namespace `protobuf:"bytes,3,opt,name=namespace" json:"namespace,omitempty"` - Interface string `protobuf:"bytes,5,opt,name=interface,proto3" json:"interface,omitempty"` - Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"` - Scope *LinuxStaticRoutes_Route_Scope `protobuf:"bytes,7,opt,name=scope" json:"scope,omitempty"` - DstIpAddr string `protobuf:"bytes,8,opt,name=dst_ip_addr,json=dstIpAddr,proto3" json:"dst_ip_addr,omitempty"` - SrcIpAddr string `protobuf:"bytes,9,opt,name=src_ip_addr,json=srcIpAddr,proto3" json:"src_ip_addr,omitempty"` - GwAddr string `protobuf:"bytes,10,opt,name=gw_addr,json=gwAddr,proto3" json:"gw_addr,omitempty"` - Metric uint32 `protobuf:"varint,11,opt,name=metric,proto3" json:"metric,omitempty"` - Table uint32 `protobuf:"varint,12,opt,name=table,proto3" json:"table,omitempty"` -} - -func (m *LinuxStaticRoutes_Route) Reset() { *m = LinuxStaticRoutes_Route{} } -func (m *LinuxStaticRoutes_Route) String() string { return proto.CompactTextString(m) } -func (*LinuxStaticRoutes_Route) ProtoMessage() {} -func (*LinuxStaticRoutes_Route) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{0, 0} } + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"` + Namespace *LinuxStaticRoutes_Route_Namespace `protobuf:"bytes,3,opt,name=namespace" json:"namespace,omitempty"` + Interface string `protobuf:"bytes,5,opt,name=interface,proto3" json:"interface,omitempty"` + Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"` + Scope *LinuxStaticRoutes_Route_Scope `protobuf:"bytes,7,opt,name=scope" json:"scope,omitempty"` + DstIpAddr string `protobuf:"bytes,8,opt,name=dst_ip_addr,json=dstIpAddr,proto3" json:"dst_ip_addr,omitempty"` + SrcIpAddr string `protobuf:"bytes,9,opt,name=src_ip_addr,json=srcIpAddr,proto3" json:"src_ip_addr,omitempty"` + GwAddr string `protobuf:"bytes,10,opt,name=gw_addr,json=gwAddr,proto3" json:"gw_addr,omitempty"` + Metric uint32 `protobuf:"varint,11,opt,name=metric,proto3" json:"metric,omitempty"` + Table uint32 `protobuf:"varint,12,opt,name=table,proto3" json:"table,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LinuxStaticRoutes_Route) Reset() { *m = LinuxStaticRoutes_Route{} } +func (m *LinuxStaticRoutes_Route) String() string { return proto.CompactTextString(m) } +func (*LinuxStaticRoutes_Route) ProtoMessage() {} +func (*LinuxStaticRoutes_Route) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{0, 0} +} +func (m *LinuxStaticRoutes_Route) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticRoutes_Route.Unmarshal(m, b) +} +func (m *LinuxStaticRoutes_Route) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticRoutes_Route.Marshal(b, m, deterministic) +} +func (dst *LinuxStaticRoutes_Route) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticRoutes_Route.Merge(dst, src) +} +func (m *LinuxStaticRoutes_Route) XXX_Size() int { + return xxx_messageInfo_LinuxStaticRoutes_Route.Size(m) +} +func (m *LinuxStaticRoutes_Route) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticRoutes_Route.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxStaticRoutes_Route proto.InternalMessageInfo func (m *LinuxStaticRoutes_Route) GetName() string { if m != nil { @@ -287,19 +321,39 @@ func (m *LinuxStaticRoutes_Route) GetTable() uint32 { } type LinuxStaticRoutes_Route_Namespace struct { - Type LinuxStaticRoutes_Route_Namespace_NamespaceType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticRoutes_Route_Namespace_NamespaceType" json:"type,omitempty"` - Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` - Microservice string `protobuf:"bytes,3,opt,name=microservice,proto3" json:"microservice,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Filepath string `protobuf:"bytes,5,opt,name=filepath,proto3" json:"filepath,omitempty"` + Type LinuxStaticRoutes_Route_Namespace_NamespaceType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticRoutes_Route_Namespace_NamespaceType" json:"type,omitempty"` + Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` + Microservice string `protobuf:"bytes,3,opt,name=microservice,proto3" json:"microservice,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Filepath string `protobuf:"bytes,5,opt,name=filepath,proto3" json:"filepath,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxStaticRoutes_Route_Namespace) Reset() { *m = LinuxStaticRoutes_Route_Namespace{} } func (m *LinuxStaticRoutes_Route_Namespace) String() string { return proto.CompactTextString(m) } func (*LinuxStaticRoutes_Route_Namespace) ProtoMessage() {} func (*LinuxStaticRoutes_Route_Namespace) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{0, 0, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{0, 0, 0} +} +func (m *LinuxStaticRoutes_Route_Namespace) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticRoutes_Route_Namespace.Unmarshal(m, b) +} +func (m *LinuxStaticRoutes_Route_Namespace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticRoutes_Route_Namespace.Marshal(b, m, deterministic) } +func (dst *LinuxStaticRoutes_Route_Namespace) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticRoutes_Route_Namespace.Merge(dst, src) +} +func (m *LinuxStaticRoutes_Route_Namespace) XXX_Size() int { + return xxx_messageInfo_LinuxStaticRoutes_Route_Namespace.Size(m) +} +func (m *LinuxStaticRoutes_Route_Namespace) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticRoutes_Route_Namespace.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxStaticRoutes_Route_Namespace proto.InternalMessageInfo func (m *LinuxStaticRoutes_Route_Namespace) GetType() LinuxStaticRoutes_Route_Namespace_NamespaceType { if m != nil { @@ -337,15 +391,35 @@ func (m *LinuxStaticRoutes_Route_Namespace) GetFilepath() string { } type LinuxStaticRoutes_Route_Scope struct { - Type LinuxStaticRoutes_Route_Scope_ScopeType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticRoutes_Route_Scope_ScopeType" json:"type,omitempty"` + Type LinuxStaticRoutes_Route_Scope_ScopeType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticRoutes_Route_Scope_ScopeType" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxStaticRoutes_Route_Scope) Reset() { *m = LinuxStaticRoutes_Route_Scope{} } func (m *LinuxStaticRoutes_Route_Scope) String() string { return proto.CompactTextString(m) } func (*LinuxStaticRoutes_Route_Scope) ProtoMessage() {} func (*LinuxStaticRoutes_Route_Scope) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{0, 0, 1} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{0, 0, 1} } +func (m *LinuxStaticRoutes_Route_Scope) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticRoutes_Route_Scope.Unmarshal(m, b) +} +func (m *LinuxStaticRoutes_Route_Scope) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticRoutes_Route_Scope.Marshal(b, m, deterministic) +} +func (dst *LinuxStaticRoutes_Route_Scope) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticRoutes_Route_Scope.Merge(dst, src) +} +func (m *LinuxStaticRoutes_Route_Scope) XXX_Size() int { + return xxx_messageInfo_LinuxStaticRoutes_Route_Scope.Size(m) +} +func (m *LinuxStaticRoutes_Route_Scope) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticRoutes_Route_Scope.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxStaticRoutes_Route_Scope proto.InternalMessageInfo func (m *LinuxStaticRoutes_Route_Scope) GetType() LinuxStaticRoutes_Route_Scope_ScopeType { if m != nil { @@ -356,13 +430,35 @@ func (m *LinuxStaticRoutes_Route_Scope) GetType() LinuxStaticRoutes_Route_Scope_ // static arp entires type LinuxStaticArpEntries struct { - ArpEntry []*LinuxStaticArpEntries_ArpEntry `protobuf:"bytes,1,rep,name=arp_entry,json=arpEntry" json:"arp_entry,omitempty"` + ArpEntry []*LinuxStaticArpEntries_ArpEntry `protobuf:"bytes,1,rep,name=arp_entry,json=arpEntry" json:"arp_entry,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *LinuxStaticArpEntries) Reset() { *m = LinuxStaticArpEntries{} } -func (m *LinuxStaticArpEntries) String() string { return proto.CompactTextString(m) } -func (*LinuxStaticArpEntries) ProtoMessage() {} -func (*LinuxStaticArpEntries) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{1} } +func (m *LinuxStaticArpEntries) Reset() { *m = LinuxStaticArpEntries{} } +func (m *LinuxStaticArpEntries) String() string { return proto.CompactTextString(m) } +func (*LinuxStaticArpEntries) ProtoMessage() {} +func (*LinuxStaticArpEntries) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1} +} +func (m *LinuxStaticArpEntries) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticArpEntries.Unmarshal(m, b) +} +func (m *LinuxStaticArpEntries) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticArpEntries.Marshal(b, m, deterministic) +} +func (dst *LinuxStaticArpEntries) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticArpEntries.Merge(dst, src) +} +func (m *LinuxStaticArpEntries) XXX_Size() int { + return xxx_messageInfo_LinuxStaticArpEntries.Size(m) +} +func (m *LinuxStaticArpEntries) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticArpEntries.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxStaticArpEntries proto.InternalMessageInfo func (m *LinuxStaticArpEntries) GetArpEntry() []*LinuxStaticArpEntries_ArpEntry { if m != nil { @@ -372,21 +468,41 @@ func (m *LinuxStaticArpEntries) GetArpEntry() []*LinuxStaticArpEntries_ArpEntry } type LinuxStaticArpEntries_ArpEntry struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Namespace *LinuxStaticArpEntries_ArpEntry_Namespace `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` - Interface string `protobuf:"bytes,3,opt,name=interface,proto3" json:"interface,omitempty"` - IpFamily *LinuxStaticArpEntries_ArpEntry_IpFamily `protobuf:"bytes,4,opt,name=ip_family,json=ipFamily" json:"ip_family,omitempty"` - State *LinuxStaticArpEntries_ArpEntry_NudState `protobuf:"bytes,5,opt,name=state" json:"state,omitempty"` - IpAddr string `protobuf:"bytes,6,opt,name=ip_addr,json=ipAddr,proto3" json:"ip_addr,omitempty"` - HwAddress string `protobuf:"bytes,7,opt,name=hw_address,json=hwAddress,proto3" json:"hw_address,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Namespace *LinuxStaticArpEntries_ArpEntry_Namespace `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` + Interface string `protobuf:"bytes,3,opt,name=interface,proto3" json:"interface,omitempty"` + IpFamily *LinuxStaticArpEntries_ArpEntry_IpFamily `protobuf:"bytes,4,opt,name=ip_family,json=ipFamily" json:"ip_family,omitempty"` + State *LinuxStaticArpEntries_ArpEntry_NudState `protobuf:"bytes,5,opt,name=state" json:"state,omitempty"` + IpAddr string `protobuf:"bytes,6,opt,name=ip_addr,json=ipAddr,proto3" json:"ip_addr,omitempty"` + HwAddress string `protobuf:"bytes,7,opt,name=hw_address,json=hwAddress,proto3" json:"hw_address,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxStaticArpEntries_ArpEntry) Reset() { *m = LinuxStaticArpEntries_ArpEntry{} } func (m *LinuxStaticArpEntries_ArpEntry) String() string { return proto.CompactTextString(m) } func (*LinuxStaticArpEntries_ArpEntry) ProtoMessage() {} func (*LinuxStaticArpEntries_ArpEntry) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{1, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1, 0} +} +func (m *LinuxStaticArpEntries_ArpEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry.Unmarshal(m, b) +} +func (m *LinuxStaticArpEntries_ArpEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry.Marshal(b, m, deterministic) } +func (dst *LinuxStaticArpEntries_ArpEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry.Merge(dst, src) +} +func (m *LinuxStaticArpEntries_ArpEntry) XXX_Size() int { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry.Size(m) +} +func (m *LinuxStaticArpEntries_ArpEntry) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxStaticArpEntries_ArpEntry proto.InternalMessageInfo func (m *LinuxStaticArpEntries_ArpEntry) GetName() string { if m != nil { @@ -438,11 +554,14 @@ func (m *LinuxStaticArpEntries_ArpEntry) GetHwAddress() string { } type LinuxStaticArpEntries_ArpEntry_Namespace struct { - Type LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType" json:"type,omitempty"` - Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` - Microservice string `protobuf:"bytes,3,opt,name=microservice,proto3" json:"microservice,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Filepath string `protobuf:"bytes,5,opt,name=filepath,proto3" json:"filepath,omitempty"` + Type LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType" json:"type,omitempty"` + Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` + Microservice string `protobuf:"bytes,3,opt,name=microservice,proto3" json:"microservice,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Filepath string `protobuf:"bytes,5,opt,name=filepath,proto3" json:"filepath,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxStaticArpEntries_ArpEntry_Namespace) Reset() { @@ -451,9 +570,26 @@ func (m *LinuxStaticArpEntries_ArpEntry_Namespace) Reset() { func (m *LinuxStaticArpEntries_ArpEntry_Namespace) String() string { return proto.CompactTextString(m) } func (*LinuxStaticArpEntries_ArpEntry_Namespace) ProtoMessage() {} func (*LinuxStaticArpEntries_ArpEntry_Namespace) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{1, 0, 0} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1, 0, 0} +} +func (m *LinuxStaticArpEntries_ArpEntry_Namespace) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_Namespace.Unmarshal(m, b) +} +func (m *LinuxStaticArpEntries_ArpEntry_Namespace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_Namespace.Marshal(b, m, deterministic) +} +func (dst *LinuxStaticArpEntries_ArpEntry_Namespace) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_Namespace.Merge(dst, src) +} +func (m *LinuxStaticArpEntries_ArpEntry_Namespace) XXX_Size() int { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_Namespace.Size(m) +} +func (m *LinuxStaticArpEntries_ArpEntry_Namespace) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_Namespace.DiscardUnknown(m) } +var xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_Namespace proto.InternalMessageInfo + func (m *LinuxStaticArpEntries_ArpEntry_Namespace) GetType() LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType { if m != nil { return m.Type @@ -490,7 +626,10 @@ func (m *LinuxStaticArpEntries_ArpEntry_Namespace) GetFilepath() string { } type LinuxStaticArpEntries_ArpEntry_IpFamily struct { - Family LinuxStaticArpEntries_ArpEntry_IpFamily_Family `protobuf:"varint,1,opt,name=family,proto3,enum=l3.LinuxStaticArpEntries_ArpEntry_IpFamily_Family" json:"family,omitempty"` + Family LinuxStaticArpEntries_ArpEntry_IpFamily_Family `protobuf:"varint,1,opt,name=family,proto3,enum=l3.LinuxStaticArpEntries_ArpEntry_IpFamily_Family" json:"family,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) Reset() { @@ -499,9 +638,26 @@ func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) Reset() { func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) String() string { return proto.CompactTextString(m) } func (*LinuxStaticArpEntries_ArpEntry_IpFamily) ProtoMessage() {} func (*LinuxStaticArpEntries_ArpEntry_IpFamily) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{1, 0, 1} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1, 0, 1} +} +func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_IpFamily.Unmarshal(m, b) +} +func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_IpFamily.Marshal(b, m, deterministic) +} +func (dst *LinuxStaticArpEntries_ArpEntry_IpFamily) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_IpFamily.Merge(dst, src) +} +func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) XXX_Size() int { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_IpFamily.Size(m) +} +func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_IpFamily.DiscardUnknown(m) } +var xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_IpFamily proto.InternalMessageInfo + func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) GetFamily() LinuxStaticArpEntries_ArpEntry_IpFamily_Family { if m != nil { return m.Family @@ -510,7 +666,10 @@ func (m *LinuxStaticArpEntries_ArpEntry_IpFamily) GetFamily() LinuxStaticArpEntr } type LinuxStaticArpEntries_ArpEntry_NudState struct { - Type LinuxStaticArpEntries_ArpEntry_NudState_NudStateType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticArpEntries_ArpEntry_NudState_NudStateType" json:"type,omitempty"` + Type LinuxStaticArpEntries_ArpEntry_NudState_NudStateType `protobuf:"varint,1,opt,name=type,proto3,enum=l3.LinuxStaticArpEntries_ArpEntry_NudState_NudStateType" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LinuxStaticArpEntries_ArpEntry_NudState) Reset() { @@ -519,8 +678,25 @@ func (m *LinuxStaticArpEntries_ArpEntry_NudState) Reset() { func (m *LinuxStaticArpEntries_ArpEntry_NudState) String() string { return proto.CompactTextString(m) } func (*LinuxStaticArpEntries_ArpEntry_NudState) ProtoMessage() {} func (*LinuxStaticArpEntries_ArpEntry_NudState) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{1, 0, 2} + return fileDescriptor_l3_1f5d3a24c2616ed3, []int{1, 0, 2} +} +func (m *LinuxStaticArpEntries_ArpEntry_NudState) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_NudState.Unmarshal(m, b) +} +func (m *LinuxStaticArpEntries_ArpEntry_NudState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_NudState.Marshal(b, m, deterministic) +} +func (dst *LinuxStaticArpEntries_ArpEntry_NudState) XXX_Merge(src proto.Message) { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_NudState.Merge(dst, src) } +func (m *LinuxStaticArpEntries_ArpEntry_NudState) XXX_Size() int { + return xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_NudState.Size(m) +} +func (m *LinuxStaticArpEntries_ArpEntry_NudState) XXX_DiscardUnknown() { + xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_NudState.DiscardUnknown(m) +} + +var xxx_messageInfo_LinuxStaticArpEntries_ArpEntry_NudState proto.InternalMessageInfo func (m *LinuxStaticArpEntries_ArpEntry_NudState) GetType() LinuxStaticArpEntries_ArpEntry_NudState_NudStateType { if m != nil { @@ -546,9 +722,9 @@ func init() { proto.RegisterEnum("l3.LinuxStaticArpEntries_ArpEntry_NudState_NudStateType", LinuxStaticArpEntries_ArpEntry_NudState_NudStateType_name, LinuxStaticArpEntries_ArpEntry_NudState_NudStateType_value) } -func init() { proto.RegisterFile("l3.proto", fileDescriptorL3) } +func init() { proto.RegisterFile("l3.proto", fileDescriptor_l3_1f5d3a24c2616ed3) } -var fileDescriptorL3 = []byte{ +var fileDescriptor_l3_1f5d3a24c2616ed3 = []byte{ // 756 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x55, 0x4b, 0x6f, 0xda, 0x4c, 0x14, 0x8d, 0x31, 0x36, 0xf6, 0x05, 0xf2, 0xf9, 0x9b, 0x3e, 0x62, 0xd1, 0x87, 0x28, 0x52, 0x25, diff --git a/plugins/linux/nsplugin/microservices.go b/plugins/linux/nsplugin/microservices.go index 395ab3649e..18bdc46179 100644 --- a/plugins/linux/nsplugin/microservices.go +++ b/plugins/linux/nsplugin/microservices.go @@ -72,33 +72,33 @@ type MicroserviceCtx struct { } // HandleMicroservices handles microservice changes -func (plugin *NsHandler) HandleMicroservices(ctx *MicroserviceCtx) { +func (h *NsHandler) HandleMicroservices(ctx *MicroserviceCtx) { var err error var newest int64 var containers []docker.APIContainers var nextCreated []string // First check if any microservice has terminated. - plugin.cfgLock.Lock() - for container := range plugin.microServiceByID { - details, err := plugin.dockerClient.InspectContainer(container) + h.cfgLock.Lock() + for container := range h.microServiceByID { + details, err := h.dockerClient.InspectContainer(container) if err != nil || !details.State.Running { - plugin.processTerminatedMicroservice(ctx.nsMgmtCtx, container) + h.processTerminatedMicroservice(ctx.nsMgmtCtx, container) } } - plugin.cfgLock.Unlock() + h.cfgLock.Unlock() // Now check if previously created containers have transitioned to the state "running". for _, container := range ctx.created { - details, err := plugin.dockerClient.InspectContainer(container) + details, err := h.dockerClient.InspectContainer(container) if err == nil { if details.State.Running { - plugin.detectMicroservice(ctx.nsMgmtCtx, details) + h.detectMicroservice(ctx.nsMgmtCtx, details) } else if details.State.Status == "created" { nextCreated = append(nextCreated, container) } } else { - plugin.log.Debugf("Inspect container ID %v failed: %v", container, err) + h.log.Debugf("Inspect container ID %v failed: %v", container, err) } } ctx.created = nextCreated @@ -112,33 +112,33 @@ func (plugin *NsHandler) HandleMicroservices(ctx *MicroserviceCtx) { if ctx.since != "" { listOpts.Filters["since"] = []string{ctx.since} } - containers, err = plugin.dockerClient.ListContainers(listOpts) + containers, err = h.dockerClient.ListContainers(listOpts) if err != nil { // If 'since' container was not found, list all containers (404 is required to support older docker version) if dockerErr, ok := err.(*docker.Error); ok && (dockerErr.Status == 500 || dockerErr.Status == 404) { // Reset filter and list containers again - plugin.log.Debug("clearing 'since' %s", ctx.since) + h.log.Debug("clearing 'since' %s", ctx.since) ctx.since = "" delete(listOpts.Filters, "since") - containers, err = plugin.dockerClient.ListContainers(listOpts) + containers, err = h.dockerClient.ListContainers(listOpts) } if err != nil { // If there is other error, return it - plugin.log.Errorf("Error listing docker containers: %v", err) + h.log.Errorf("Error listing docker containers: %v", err) return } } for _, container := range containers { - plugin.log.Debugf("processing new container %v with state %v", container.ID, container.State) + h.log.Debugf("processing new container %v with state %v", container.ID, container.State) if container.State == "running" && container.Created > ctx.lastInspected { // Inspect the container to get the list of defined environment variables. - details, err := plugin.dockerClient.InspectContainer(container.ID) + details, err := h.dockerClient.InspectContainer(container.ID) if err != nil { - plugin.log.Debugf("Inspect container %v failed: %v", container.ID, err) + h.log.Debugf("Inspect container %v failed: %v", container.ID, err) continue } - plugin.detectMicroservice(ctx.nsMgmtCtx, details) + h.detectMicroservice(ctx.nsMgmtCtx, details) } if container.State == "created" { ctx.created = append(ctx.created, container.ID) @@ -156,21 +156,22 @@ func (plugin *NsHandler) HandleMicroservices(ctx *MicroserviceCtx) { // detectMicroservice inspects container to see if it is a microservice. // If microservice is detected, processNewMicroservice() is called to process it. -func (plugin *NsHandler) detectMicroservice(nsMgmtCtx *NamespaceMgmtCtx, container *docker.Container) { +func (h *NsHandler) detectMicroservice(nsMgmtCtx *NamespaceMgmtCtx, container *docker.Container) { // Search for the microservice label. var label string for _, env := range container.Config.Env { if strings.HasPrefix(env, servicelabel.MicroserviceLabelEnvVar+"=") { label = env[len(servicelabel.MicroserviceLabelEnvVar)+1:] if label != "" { - plugin.log.Debugf("detected container as microservice: Name=%v ID=%v Created=%v State.StartedAt=%v", container.Name, container.ID, container.Created, container.State.StartedAt) + h.log.Debugf("detected container as microservice: Name=%q ID=%v Created=%v State.StartedAt=%v", + container.Name, container.ID, container.Created, container.State.StartedAt) last := microserviceContainerCreated[label] if last.After(container.Created) { - plugin.log.Debugf("ignoring older container created at %v as microservice: %+v", last, container) + h.log.Debugf("ignoring older container created at %v as microservice: %+v", last, container) continue } microserviceContainerCreated[label] = container.Created - plugin.processNewMicroservice(nsMgmtCtx, label, container.ID, container.State.Pid) + h.processNewMicroservice(nsMgmtCtx, label, container.ID, container.State.Pid) } } } @@ -178,26 +179,26 @@ func (plugin *NsHandler) detectMicroservice(nsMgmtCtx *NamespaceMgmtCtx, contain // processNewMicroservice is triggered every time a new microservice gets freshly started. All pending interfaces are moved // to its namespace. -func (plugin *NsHandler) processNewMicroservice(nsMgmtCtx *NamespaceMgmtCtx, microserviceLabel string, id string, pid int) { - plugin.cfgLock.Lock() - defer plugin.cfgLock.Unlock() +func (h *NsHandler) processNewMicroservice(nsMgmtCtx *NamespaceMgmtCtx, microserviceLabel string, id string, pid int) { + h.cfgLock.Lock() + defer h.cfgLock.Unlock() - microservice, restarted := plugin.microServiceByLabel[microserviceLabel] + microservice, restarted := h.microServiceByLabel[microserviceLabel] if restarted { - plugin.processTerminatedMicroservice(nsMgmtCtx, microservice.ID) - plugin.log.WithFields(logging.Fields{"label": microserviceLabel, "new-pid": pid, "new-id": id}). + h.processTerminatedMicroservice(nsMgmtCtx, microservice.ID) + h.log.WithFields(logging.Fields{"label": microserviceLabel, "new-pid": pid, "new-id": id}). Warn("Microservice has been restarted") } else { - plugin.log.WithFields(logging.Fields{"label": microserviceLabel, "pid": pid, "id": id}). + h.log.WithFields(logging.Fields{"label": microserviceLabel, "pid": pid, "id": id}). Debug("Discovered new microservice") } microservice = &Microservice{Label: microserviceLabel, PID: pid, ID: id} - plugin.microServiceByLabel[microserviceLabel] = microservice - plugin.microServiceByID[id] = microservice + h.microServiceByLabel[microserviceLabel] = microservice + h.microServiceByID[id] = microservice // Send notification to interface configurator - plugin.ifMicroserviceNotif <- &MicroserviceEvent{ + h.ifMicroserviceNotif <- &MicroserviceEvent{ Microservice: microservice, EventType: NewMicroservice, } @@ -205,32 +206,32 @@ func (plugin *NsHandler) processNewMicroservice(nsMgmtCtx *NamespaceMgmtCtx, mic // processTerminatedMicroservice is triggered every time a known microservice has terminated. All associated interfaces // become obsolete and are thus removed. -func (plugin *NsHandler) processTerminatedMicroservice(nsMgmtCtx *NamespaceMgmtCtx, id string) { - microservice, exists := plugin.microServiceByID[id] +func (h *NsHandler) processTerminatedMicroservice(nsMgmtCtx *NamespaceMgmtCtx, id string) { + microservice, exists := h.microServiceByID[id] if !exists { - plugin.log.WithFields(logging.Fields{"id": id}). + h.log.WithFields(logging.Fields{"id": id}). Warn("Detected removal of an unknown microservice") return } - plugin.log.WithFields(logging.Fields{"label": microservice.Label, "pid": microservice.PID, "id": microservice.ID}). + h.log.WithFields(logging.Fields{"label": microservice.Label, "pid": microservice.PID, "id": microservice.ID}). Debug("Microservice has terminated") - delete(plugin.microServiceByLabel, microservice.Label) - delete(plugin.microServiceByID, microservice.ID) + delete(h.microServiceByLabel, microservice.Label) + delete(h.microServiceByID, microservice.ID) // Send notification to interface configurator - plugin.ifMicroserviceNotif <- &MicroserviceEvent{ + h.ifMicroserviceNotif <- &MicroserviceEvent{ Microservice: microservice, EventType: TerminatedMicroservice, } } // trackMicroservices is running in the background and maintains a map of microservice labels to container info. -func (plugin *NsHandler) trackMicroservices(ctx context.Context) { - plugin.wg.Add(1) +func (h *NsHandler) trackMicroservices(ctx context.Context) { + h.wg.Add(1) defer func() { - plugin.wg.Done() - plugin.log.Debugf("Microservice tracking ended") + h.wg.Done() + h.log.Debugf("Microservice tracking ended") }() msCtx := &MicroserviceCtx{ @@ -243,9 +244,9 @@ func (plugin *NsHandler) trackMicroservices(ctx context.Context) { for { select { case <-timer.C: - if err := plugin.dockerClient.Ping(); err != nil { + if err := h.dockerClient.Ping(); err != nil { if clientOk { - plugin.log.Errorf("Docker ping check failed: %v", err) + h.log.Errorf("Docker ping check failed: %v", err) } clientOk = false @@ -255,7 +256,7 @@ func (plugin *NsHandler) trackMicroservices(ctx context.Context) { } if !clientOk { - plugin.log.Infof("Docker ping check OK") + h.log.Infof("Docker ping check OK") /*if info, err := plugin.dockerClient.Info(); err != nil { plugin.Log.Errorf("Retrieving docker info failed: %v", err) timer.Reset(dockerRetryPeriod) @@ -268,14 +269,14 @@ func (plugin *NsHandler) trackMicroservices(ctx context.Context) { clientOk = true select { - case plugin.microserviceChan <- msCtx: - case <-plugin.ctx.Done(): + case h.microserviceChan <- msCtx: + case <-h.ctx.Done(): return } // Sleep before another refresh. timer.Reset(dockerRefreshPeriod) - case <-plugin.ctx.Done(): + case <-h.ctx.Done(): return } } diff --git a/plugins/linux/nsplugin/namespaces.go b/plugins/linux/nsplugin/namespaces.go index 4b2f95d9b9..96f8c0005b 100644 --- a/plugins/linux/nsplugin/namespaces.go +++ b/plugins/linux/nsplugin/namespaces.go @@ -15,7 +15,6 @@ package nsplugin import ( - "fmt" "os" "path" "runtime" @@ -23,6 +22,7 @@ import ( "strings" "syscall" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" intf "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" "github.com/ligato/vpp-agent/plugins/linux/model/l3" @@ -89,7 +89,7 @@ func (ns *Namespace) CompareNamespaces(nsToCompare *Namespace) int { // GenericToIfaceNs converts generic namespace to interface-type namespace func (ns *Namespace) GenericToIfaceNs() (*intf.LinuxInterfaces_Interface_Namespace, error) { if ns == nil { - return nil, fmt.Errorf("provided namespace is nil") + return nil, errors.Errorf("provided namespace is nil") } var namespaceType intf.LinuxInterfaces_Interface_Namespace_NamespaceType switch ns.Type { @@ -106,9 +106,9 @@ func (ns *Namespace) GenericToIfaceNs() (*intf.LinuxInterfaces_Interface_Namespa } // GenericToRouteNs converts generic namespace to arp-type namespace -func (plugin *NsHandler) GenericToRouteNs(ns *Namespace) (*l3.LinuxStaticRoutes_Route_Namespace, error) { +func (h *NsHandler) GenericToRouteNs(ns *Namespace) (*l3.LinuxStaticRoutes_Route_Namespace, error) { if ns == nil { - return nil, fmt.Errorf("provided namespace is nil") + return nil, errors.Errorf("provided namespace is nil") } var namespaceType l3.LinuxStaticRoutes_Route_Namespace_NamespaceType switch ns.Type { @@ -125,9 +125,9 @@ func (plugin *NsHandler) GenericToRouteNs(ns *Namespace) (*l3.LinuxStaticRoutes_ } // GenericToArpNs converts generic namespace to arp-type namespace -func (plugin *NsHandler) GenericToArpNs(ns *Namespace) (*l3.LinuxStaticArpEntries_ArpEntry_Namespace, error) { +func (h *NsHandler) GenericToArpNs(ns *Namespace) (*l3.LinuxStaticArpEntries_ArpEntry_Namespace, error) { if ns == nil { - return nil, fmt.Errorf("provided namespace is nil") + return nil, errors.Errorf("provided namespace is nil") } var namespaceType l3.LinuxStaticArpEntries_ArpEntry_Namespace_NamespaceType switch ns.Type { @@ -163,7 +163,7 @@ func (ns *Namespace) GenericNsToString() string { } // IfaceNsToString returns a string representation of a namespace suitable for logging purposes. -func (plugin *NsHandler) IfaceNsToString(namespace *intf.LinuxInterfaces_Interface_Namespace) string { +func (h *NsHandler) IfaceNsToString(namespace *intf.LinuxInterfaces_Interface_Namespace) string { if namespace != nil { switch namespace.Type { case intf.LinuxInterfaces_Interface_Namespace_PID_REF_NS: @@ -182,9 +182,6 @@ func (plugin *NsHandler) IfaceNsToString(namespace *intf.LinuxInterfaces_Interfa // createNamedNetNs creates a new named Linux network namespace. // It does exactly the same thing as the command "ip netns add NAMESPACE". func (ns *Namespace) createNamedNetNs(sysHandler SystemAPI, log logging.Logger) (netns.NsHandle, error) { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Debug("Creating new named Linux namespace") - // Lock the OS Thread so we don't accidentally switch namespaces. runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -192,18 +189,14 @@ func (ns *Namespace) createNamedNetNs(sysHandler SystemAPI, log logging.Logger) // Save the current network namespace. origns, err := netns.Get() if err != nil { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("Failed to get the original namespace") - return netns.None(), err + return netns.None(), errors.Errorf("failed to get original namespace: %v", err) } defer origns.Close() // Create directory for namespace mounts. err = sysHandler.MkDirAll(netNsMountDir, 0755) if err != nil { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("Failed to create directory for namespace mounts") - return netns.None(), err + return netns.None(), errors.Errorf("failed to create directory for namespace mounts: %v", err) } /* Make it possible for network namespace mounts to propagate between @@ -219,16 +212,12 @@ func (ns *Namespace) createNamedNetNs(sysHandler SystemAPI, log logging.Logger) break } if e, ok := err.(syscall.Errno); !ok || e != syscall.EINVAL || mountedNetnsDir { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("mount --make-shared failed") - return netns.None(), err + return netns.None(), errors.Errorf("%s mount --make-shared failed: %v", ns.Name, err) } /* Upgrade netNsMountDir to a mount point */ err = syscall.Mount(netNsMountDir, netNsMountDir, "none", syscall.MS_BIND, "") if err != nil { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("mount --bind failed") - return netns.None(), err + return netns.None(), errors.Errorf("%s mount --bind failed: %v", ns.Name, err) } mountedNetnsDir = true } @@ -237,9 +226,8 @@ func (ns *Namespace) createNamedNetNs(sysHandler SystemAPI, log logging.Logger) netnsMountFile := path.Join(netNsMountDir, ns.Name) file, err := sysHandler.OpenFile(netnsMountFile, os.O_RDONLY|os.O_CREATE|os.O_EXCL, 0444) if err != nil { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("failed to create destination path for the namespace mount") - return netns.None(), err + return netns.None(), errors.Errorf("failed to create destination path for the namespace %s mount: %v", + ns.Name, err) } file.Close() @@ -248,7 +236,7 @@ func (ns *Namespace) createNamedNetNs(sysHandler SystemAPI, log logging.Logger) if err != nil { log.WithFields(logging.Fields{"namespace": ns.Name}). Error("failed to create namespace") - return netns.None(), err + return netns.None(), errors.Errorf("failed to create namespace %s: %v", ns.Name, err) } netns.Set(newNsHandle) @@ -261,9 +249,7 @@ func (ns *Namespace) createNamedNetNs(sysHandler SystemAPI, log logging.Logger) if err != nil { newNsHandle.Close() - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("failed to create namespace bind-mount") - return netns.None(), err + return netns.None(), errors.Errorf("failed to create namespace %s bind-mount: %v", ns.Name, err) } return newNsHandle, nil @@ -272,22 +258,17 @@ func (ns *Namespace) createNamedNetNs(sysHandler SystemAPI, log logging.Logger) // deleteNamedNetNs deletes an existing named Linux network namespace. // It does exactly the same thing as the command "ip netns del NAMESPACE". func (ns *Namespace) deleteNamedNetNs(sysHandler SystemAPI, log logging.Logger) error { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Debug("Deleting named Linux namespace") - // Unmount the namespace. netnsMountFile := path.Join(netNsMountDir, ns.Name) err := sysHandler.Unmount(netnsMountFile, syscall.MNT_DETACH) if err != nil { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("failed to unmount namespace") + return errors.Errorf("failed to unmount namespace %s: %v", ns.Name, err) } // Remove file path used for the mount. err = sysHandler.Remove(netnsMountFile) if err != nil { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("failed to remove namespace file") + return errors.Errorf("failed to remove namespace %s: %v", ns.Name, err) } return err @@ -298,15 +279,9 @@ func (ns *Namespace) namedNetNsExists(log logging.Logger) (bool, error) { netnsMountFile := path.Join(netNsMountDir, ns.Name) if _, err := os.Stat(netnsMountFile); err != nil { if os.IsNotExist(err) { - log.WithFields(logging.Fields{"namespace": ns.Name}). - Debug("namespace not found") return false, nil } - log.WithFields(logging.Fields{"namespace": ns.Name}). - Error("failed to read namespace") - return false, err + return false, errors.Errorf("failed to read namespace %s: %v", ns.Name, err) } - log.WithFields(logging.Fields{"namespace": ns.Name}). - Debug("namespace found") return true, nil } diff --git a/plugins/linux/nsplugin/ns_handler.go b/plugins/linux/nsplugin/ns_handler.go index fd7541643d..55f6b49329 100644 --- a/plugins/linux/nsplugin/ns_handler.go +++ b/plugins/linux/nsplugin/ns_handler.go @@ -16,18 +16,13 @@ package nsplugin import ( "context" - "errors" - "fmt" - "net" - "os" "runtime" "sync" "syscall" "github.com/fsouza/go-dockerclient" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - ipAddrs "github.com/ligato/cn-infra/utils/addrs" - "github.com/ligato/vpp-agent/plugins/linux/ifplugin/linuxcalls" intf "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" "github.com/ligato/vpp-agent/plugins/linux/model/l3" "github.com/vishvananda/netns" @@ -60,7 +55,6 @@ type NsHandler struct { configNs *intf.LinuxInterfaces_Interface_Namespace // Handlers - ifHandler linuxcalls.NetlinkAPI sysHandler SystemAPI // Context within which all goroutines are running @@ -72,181 +66,85 @@ type NsHandler struct { } // Init namespace handler caches and create config namespace -func (plugin *NsHandler) Init(logger logging.PluginLogger, ifHandler linuxcalls.NetlinkAPI, sysHandler SystemAPI, - msChan chan *MicroserviceCtx, ifNotif chan *MicroserviceEvent) error { +func (h *NsHandler) Init(logger logging.PluginLogger, sysHandler SystemAPI, msChan chan *MicroserviceCtx, + ifNotif chan *MicroserviceEvent) error { // Logger - plugin.log = logger.NewLogger("-ns-handler") - plugin.log.Infof("Initializing namespace handler plugin") + h.log = logger.NewLogger("ns-handler") // Init channels - plugin.microserviceChan = msChan - plugin.ifMicroserviceNotif = ifNotif + h.microserviceChan = msChan + h.ifMicroserviceNotif = ifNotif - plugin.ctx, plugin.cancel = context.WithCancel(context.Background()) + h.ctx, h.cancel = context.WithCancel(context.Background()) - plugin.microServiceByLabel = make(map[string]*Microservice) - plugin.microServiceByID = make(map[string]*Microservice) + h.microServiceByLabel = make(map[string]*Microservice) + h.microServiceByID = make(map[string]*Microservice) - // Handlers - plugin.ifHandler = ifHandler - plugin.sysHandler = sysHandler + // System handler + h.sysHandler = sysHandler // Default namespace var err error - plugin.defaultNs, err = netns.Get() + h.defaultNs, err = netns.Get() if err != nil { - return fmt.Errorf("failed to init default namespace: %v", err) + return errors.Errorf("failed to init default namespace: %v", err) } // Docker client - plugin.dockerClient, err = docker.NewClientFromEnv() + h.dockerClient, err = docker.NewClientFromEnv() if err != nil { - plugin.log.WithFields(logging.Fields{ - "DOCKER_HOST": os.Getenv("DOCKER_HOST"), - "DOCKER_TLS_VERIFY": os.Getenv("DOCKER_TLS_VERIFY"), - "DOCKER_CERT_PATH": os.Getenv("DOCKER_CERT_PATH"), - }).Errorf("Failed to get docker client instance from the environment variables: %v", err) - return err + return errors.Errorf("failed to get docker client instance from the environment variables: %v", err) } - plugin.log.Debugf("Using docker client endpoint: %+v", plugin.dockerClient.Endpoint()) + h.log.Debugf("Using docker client endpoint: %+v", h.dockerClient.Endpoint()) // Create config namespace (for VETHs) - err = plugin.prepareConfigNamespace() + if err = h.prepareConfigNamespace(); err != nil { + return errors.Errorf("failed to prepare config namespace: %v", err) + } // Start microservice tracker - go plugin.trackMicroservices(plugin.ctx) + go h.trackMicroservices(h.ctx) - return err + h.log.Infof("Namespace handler plugin initialized") + + return nil } // Close pre-configured namespace -func (plugin *NsHandler) Close() error { - var wasErr error - if plugin.configNs != nil { +func (h *NsHandler) Close() error { + if h.configNs != nil { // Remove veth pre-configure namespace - ns := plugin.IfNsToGeneric(plugin.configNs) - wasErr = ns.deleteNamedNetNs(plugin.sysHandler, plugin.log) - plugin.cancel() - plugin.wg.Wait() + ns := h.IfNsToGeneric(h.configNs) + if err := ns.deleteNamedNetNs(h.sysHandler, h.log); err != nil { + return errors.Errorf("failed to delete named namspace: %v", err) + } + h.cancel() + h.wg.Wait() } - return wasErr + return nil } // GetConfigNamespace return configuration namespace object -func (plugin *NsHandler) GetConfigNamespace() *intf.LinuxInterfaces_Interface_Namespace { - return plugin.configNs +func (h *NsHandler) GetConfigNamespace() *intf.LinuxInterfaces_Interface_Namespace { + return h.configNs } // GetMicroserviceByLabel returns internal microservice-by-label mapping -func (plugin *NsHandler) GetMicroserviceByLabel() map[string]*Microservice { - return plugin.microServiceByLabel +func (h *NsHandler) GetMicroserviceByLabel() map[string]*Microservice { + return h.microServiceByLabel } // GetMicroserviceByID returns internal microservice-by-id mapping -func (plugin *NsHandler) GetMicroserviceByID() map[string]*Microservice { - return plugin.microServiceByID -} - -// SetInterfaceNamespace moves a given Linux interface into a specified namespace. -func (plugin *NsHandler) SetInterfaceNamespace(ctx *NamespaceMgmtCtx, ifName string, namespace *intf.LinuxInterfaces_Interface_Namespace) error { - // Convert microservice namespace - var err error - if namespace != nil && namespace.Type == intf.LinuxInterfaces_Interface_Namespace_MICROSERVICE_REF_NS { - // Convert namespace - ifNs := plugin.convertMicroserviceNsToPidNs(namespace.Microservice) - // Back to interface ns type - namespace, err = ifNs.GenericToIfaceNs() - if err != nil { - return err - } - if namespace == nil { - return &unavailableMicroserviceErr{} - } - } - - ifaceNs := plugin.IfNsToGeneric(namespace) - - // Get network namespace file descriptor - ns, err := plugin.getOrCreateNs(ifaceNs) - if err != nil { - return err - } - defer ns.Close() - - // Get the link plugin. - link, err := plugin.ifHandler.GetLinkByName(ifName) - if err != nil { - return err - } - - // When interface moves from one namespace to another, it loses all its IP addresses, admin status - // and MTU configuration -- we need to remember the interface configuration before the move - // and re-configure the interface in the new namespace. - addresses, isIPv6, err := plugin.getLinuxIfAddrs(link.Attrs().Name) - if err != nil { - return err - } - - // Move the interface into the namespace. - err = plugin.sysHandler.LinkSetNsFd(link, int(ns)) - if err != nil { - return err - } - plugin.log.WithFields(logging.Fields{"ifName": ifName, "dest-namespace": plugin.IfaceNsToString(namespace), - "dest-namespace-fd": int(ns)}). - Debug("Moved Linux interface across namespaces") - - // Re-configure interface in its new namespace - revertNs, err := plugin.SwitchNamespace(ifaceNs, ctx) - if err != nil { - return err - } - defer revertNs() - - if link.Attrs().Flags&net.FlagUp == 1 { - // Re-enable interface - err = plugin.ifHandler.SetInterfaceUp(ifName) - if nil != err { - return fmt.Errorf("failed to enable Linux interface `%s`: %v", ifName, err) - } - plugin.log.WithFields(logging.Fields{"ifName": ifName}). - Debug("Linux interface was re-enabled") - } - - // Re-add IP addresses - for _, address := range addresses { - // Skip IPv6 link local address if there is no other IPv6 address - if !isIPv6 && address.IP.IsLinkLocalUnicast() { - continue - } - err = plugin.ifHandler.AddInterfaceIP(ifName, address) - if err != nil { - if err.Error() == "file exists" { - continue - } - return fmt.Errorf("failed to assign IP address to a Linux interface `%s`: %v", ifName, err) - } - plugin.log.WithFields(logging.Fields{"ifName": ifName, "addr": address}). - Debug("IP address was re-assigned to Linux interface") - } - - // Revert back the MTU config - err = plugin.ifHandler.SetInterfaceMTU(ifName, link.Attrs().MTU) - if nil != err { - return fmt.Errorf("failed to set MTU of a Linux interface `%s`: %v", ifName, err) - } - plugin.log.WithFields(logging.Fields{"ifName": ifName, "mtu": link.Attrs().MTU}). - Debug("MTU was reconfigured for Linux interface") - - return nil +func (h *NsHandler) GetMicroserviceByID() map[string]*Microservice { + return h.microServiceByID } // SwitchToNamespace switches the network namespace of the current thread. -func (plugin *NsHandler) SwitchToNamespace(nsMgmtCtx *NamespaceMgmtCtx, ns *intf.LinuxInterfaces_Interface_Namespace) (revert func(), err error) { +func (h *NsHandler) SwitchToNamespace(nsMgmtCtx *NamespaceMgmtCtx, ns *intf.LinuxInterfaces_Interface_Namespace) (revert func(), err error) { if ns != nil && ns.Type == intf.LinuxInterfaces_Interface_Namespace_MICROSERVICE_REF_NS { // Convert namespace - ifNs := plugin.convertMicroserviceNsToPidNs(ns.Microservice) + ifNs := h.ConvertMicroserviceNsToPidNs(ns.Microservice) // Back to interface ns type ns, err = ifNs.GenericToIfaceNs() if err != nil { @@ -258,18 +156,18 @@ func (plugin *NsHandler) SwitchToNamespace(nsMgmtCtx *NamespaceMgmtCtx, ns *intf } // Prepare generic namespace object - ifaceNs := plugin.IfNsToGeneric(ns) + ifaceNs := h.IfNsToGeneric(ns) - return plugin.SwitchNamespace(ifaceNs, nsMgmtCtx) + return h.SwitchNamespace(ifaceNs, nsMgmtCtx) } // SwitchNamespace switches the network namespace of the current thread. // Caller should eventually call the returned "revert" function in order to get back to the original // network namespace (for example using "defer revert()"). -func (plugin *NsHandler) SwitchNamespace(ns *Namespace, ctx *NamespaceMgmtCtx) (revert func(), err error) { +func (h *NsHandler) SwitchNamespace(ns *Namespace, ctx *NamespaceMgmtCtx) (revert func(), err error) { var nsHandle netns.NsHandle if ns != nil && ns.Type == MicroserviceRefNs { - ns = plugin.convertMicroserviceNsToPidNs(ns.Microservice) + ns = h.ConvertMicroserviceNsToPidNs(ns.Microservice) if ns == nil { return func() {}, &unavailableMicroserviceErr{} } @@ -282,7 +180,7 @@ func (plugin *NsHandler) SwitchNamespace(ns *Namespace, ctx *NamespaceMgmtCtx) ( } // Get network namespace file descriptor. - nsHandle, err = plugin.getOrCreateNs(ns) + nsHandle, err = h.GetOrCreateNamespace(ns) if err != nil { return func() {}, err } @@ -293,40 +191,34 @@ func (plugin *NsHandler) SwitchNamespace(ns *Namespace, ctx *NamespaceMgmtCtx) ( // Lock the OS Thread so we don't accidentally switch namespaces later. runtime.LockOSThread() ctx.lockedOsThread = true - plugin.log.Debug("Locked OS thread") } // Switch the namespace. - l := plugin.log.WithFields(logging.Fields{"ns": nsHandle.String(), "ns-fd": int(nsHandle)}) - if err := plugin.sysHandler.SetNamespace(nsHandle); err != nil { + l := h.log.WithFields(logging.Fields{"ns": nsHandle.String(), "ns-fd": int(nsHandle)}) + if err := h.sysHandler.SetNamespace(nsHandle); err != nil { l.Errorf("Failed to switch Linux network namespace (%v): %v", ns.GenericNsToString(), err) - } else { - l.Debugf("Switched Linux network namespace (%v)", ns.GenericNsToString()) } return func() { - l := plugin.log.WithFields(logging.Fields{"orig-ns": origns.String(), "orig-ns-fd": int(origns)}) + l := h.log.WithFields(logging.Fields{"orig-ns": origns.String(), "orig-ns-fd": int(origns)}) if err := netns.Set(origns); err != nil { l.Errorf("Failed to switch Linux network namespace: %v", err) - } else { - l.Debugf("Switched back to the original Linux network namespace") } origns.Close() if !alreadyLocked { runtime.UnlockOSThread() ctx.lockedOsThread = false - plugin.log.Debug("Unlocked OS thread") } }, nil } // IsNamespaceAvailable returns true if the destination namespace is available. -func (plugin *NsHandler) IsNamespaceAvailable(ns *intf.LinuxInterfaces_Interface_Namespace) bool { +func (h *NsHandler) IsNamespaceAvailable(ns *intf.LinuxInterfaces_Interface_Namespace) bool { if ns != nil && ns.Type == intf.LinuxInterfaces_Interface_Namespace_MICROSERVICE_REF_NS { - if plugin.dockerClient == nil { + if h.dockerClient == nil { return false } - _, available := plugin.microServiceByLabel[ns.Microservice] + _, available := h.microServiceByLabel[ns.Microservice] return available } return true @@ -334,7 +226,7 @@ func (plugin *NsHandler) IsNamespaceAvailable(ns *intf.LinuxInterfaces_Interface // IfNsToGeneric converts interface-type namespace to generic type namespace. Such an object can be used to call common // namespace-related methods -func (plugin *NsHandler) IfNsToGeneric(ns *intf.LinuxInterfaces_Interface_Namespace) *Namespace { +func (h *NsHandler) IfNsToGeneric(ns *intf.LinuxInterfaces_Interface_Namespace) *Namespace { if ns == nil { return &Namespace{} } @@ -343,7 +235,7 @@ func (plugin *NsHandler) IfNsToGeneric(ns *intf.LinuxInterfaces_Interface_Namesp // ArpNsToGeneric converts arp-type namespace to generic type namespace. Such an object can be used to call common // namespace-related methods -func (plugin *NsHandler) ArpNsToGeneric(ns *l3.LinuxStaticArpEntries_ArpEntry_Namespace) *Namespace { +func (h *NsHandler) ArpNsToGeneric(ns *l3.LinuxStaticArpEntries_ArpEntry_Namespace) *Namespace { if ns == nil { return &Namespace{} } @@ -352,95 +244,99 @@ func (plugin *NsHandler) ArpNsToGeneric(ns *l3.LinuxStaticArpEntries_ArpEntry_Na // RouteNsToGeneric converts route-type namespace to generic type namespace. Such an object can be used to call common // namespace-related methods -func (plugin *NsHandler) RouteNsToGeneric(ns *l3.LinuxStaticRoutes_Route_Namespace) *Namespace { +func (h *NsHandler) RouteNsToGeneric(ns *l3.LinuxStaticRoutes_Route_Namespace) *Namespace { if ns == nil { return &Namespace{} } return &Namespace{Type: int32(ns.Type), Pid: ns.Pid, Microservice: ns.Microservice, Name: ns.Name, FilePath: ns.Filepath} } -// getOrCreateNs returns an existing Linux network namespace or creates a new one if it doesn't exist yet. +// GetOrCreateNamespace returns an existing Linux network namespace or creates a new one if it doesn't exist yet. // It is, however, only possible to create "named" namespaces. For PID-based namespaces, process with // the given PID must exists, otherwise the function returns an error. -func (plugin *NsHandler) getOrCreateNs(ns *Namespace) (netns.NsHandle, error) { +func (h *NsHandler) GetOrCreateNamespace(ns *Namespace) (netns.NsHandle, error) { var nsHandle netns.NsHandle var err error if ns == nil { - return dupNsHandle(plugin.defaultNs) + return dupNsHandle(h.defaultNs) } switch ns.Type { case PidRefNs: if ns.Pid == 0 { // We consider scheduler's PID as the representation of the default namespace. - return dupNsHandle(plugin.defaultNs) + return dupNsHandle(h.defaultNs) } nsHandle, err = netns.GetFromPid(int(ns.Pid)) if err != nil { - return netns.None(), err + return netns.None(), errors.Errorf("failed to get namespace handle from pid: %v", err) } case NamedNs: if ns.Name == "" { - return dupNsHandle(plugin.defaultNs) + return dupNsHandle(h.defaultNs) } - nsHandle, err = plugin.sysHandler.GetNamespaceFromName(ns.Name) + nsHandle, err = h.sysHandler.GetNamespaceFromName(ns.Name) if err != nil { // Create named namespace if it doesn't exist yet. - _, err = ns.createNamedNetNs(plugin.sysHandler, plugin.log) + _, err = ns.createNamedNetNs(h.sysHandler, h.log) if err != nil { - return netns.None(), err + return netns.None(), errors.Errorf("failed to create named net namspace: %v", err) } nsHandle, err = netns.GetFromName(ns.Name) if err != nil { - return netns.None(), errors.New("unable to get namespace by name") + return netns.None(), errors.Errorf("unable to get namespace by name") } } case FileRefNs: if ns.FilePath == "" { - return dupNsHandle(plugin.defaultNs) + return dupNsHandle(h.defaultNs) } nsHandle, err = netns.GetFromPath(ns.FilePath) if err != nil { - return netns.None(), err + return netns.None(), errors.Errorf("failed to get file %s from path: %v", ns.FilePath, err) } case MicroserviceRefNs: - return netns.None(), errors.New("unable to convert microservice label to PID at this level") + return netns.None(), errors.Errorf("unable to convert microservice label to PID at this level") } return nsHandle, nil } // Create named namespace used for VETH interface creation instead of the default one. -func (plugin *NsHandler) prepareConfigNamespace() error { +func (h *NsHandler) prepareConfigNamespace() error { // Prepare namespace proto object. ns := &Namespace{ Type: NamedNs, Name: configNamespace, } // Check if namespace exists. - found, err := ns.namedNetNsExists(plugin.log) + found, err := ns.namedNetNsExists(h.log) if err != nil { - return err + return errors.Errorf("failed to evaluate namespace %s presence: %v", ns.Name, err) } // Remove namespace if exists. if found { - err := ns.deleteNamedNetNs(plugin.sysHandler, plugin.log) + err := ns.deleteNamedNetNs(h.sysHandler, h.log) if err != nil { - return err + return errors.Errorf("failed to delete namespace %s: %v", ns.Name, err) } } - _, err = ns.createNamedNetNs(plugin.sysHandler, plugin.log) + _, err = ns.createNamedNetNs(h.sysHandler, h.log) + if err != nil { + return errors.Errorf("failed to create namespace %s: %v", ns.Name, err) + } + h.configNs, err = ns.GenericToIfaceNs() if err != nil { - return err + return errors.Errorf("failed to convert generic namespace %s to interface-type namespace: %v", + ns.Name, err) } - plugin.configNs, err = ns.GenericToIfaceNs() - return err + return nil } -// convertMicroserviceNsToPidNs converts microservice-referenced namespace into the PID-referenced namespace. -func (plugin *NsHandler) convertMicroserviceNsToPidNs(microserviceLabel string) (pidNs *Namespace) { - if microservice, ok := plugin.microServiceByLabel[microserviceLabel]; ok { +// ConvertMicroserviceNsToPidNs converts microservice-referenced namespace into the PID-referenced namespace. +func (h *NsHandler) ConvertMicroserviceNsToPidNs(microserviceLabel string) (pidNs *Namespace) { + if microservice, ok := h.microServiceByLabel[microserviceLabel]; ok { pidNamespace := &Namespace{} pidNamespace.Type = PidRefNs pidNamespace.Pid = uint32(microservice.PID) @@ -449,30 +345,6 @@ func (plugin *NsHandler) convertMicroserviceNsToPidNs(microserviceLabel string) return nil } -// getLinuxIfAddrs returns a list of IP addresses for given linux interface with info whether there is IPv6 address -// (except default link local) -func (plugin *NsHandler) getLinuxIfAddrs(ifName string) ([]*net.IPNet, bool, error) { - var networks []*net.IPNet - addrs, err := plugin.ifHandler.GetAddressList(ifName) - if err != nil { - return nil, false, fmt.Errorf("failed to get IP address set from linux interface %s", ifName) - } - var containsIPv6 bool - for _, ipAddr := range addrs { - network, ipv6, err := ipAddrs.ParseIPWithPrefix(ipAddr.String()) - if err != nil { - return nil, false, fmt.Errorf("failed to parse IP address %s", ipAddr.String()) - } - // Set once if IP address is version 6 and not a link local address - if !containsIPv6 && ipv6 && !ipAddr.IP.IsLinkLocalUnicast() { - containsIPv6 = true - } - networks = append(networks, network) - } - - return networks, containsIPv6, nil -} - // dupNsHandle duplicates namespace handle. func dupNsHandle(ns netns.NsHandle) (netns.NsHandle, error) { dup, err := syscall.Dup(int(ns)) diff --git a/plugins/linux/nsplugin/ns_handler_api.go b/plugins/linux/nsplugin/ns_handler_api.go index 73c44c632e..7ff1179fb1 100644 --- a/plugins/linux/nsplugin/ns_handler_api.go +++ b/plugins/linux/nsplugin/ns_handler_api.go @@ -17,6 +17,7 @@ package nsplugin import ( "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" "github.com/ligato/vpp-agent/plugins/linux/model/l3" + "github.com/vishvananda/netns" ) // NamespaceAPI defines all methods required for managing namespaces and microservices @@ -28,16 +29,19 @@ type NamespaceAPI interface { // NsManagement defines methods to manage namespaces type NsManagement interface { + // GetOrCreateNamespace returns an existing Linux network namespace or creates a new one if it doesn't exist yet. + // Only named namespaces can be created + GetOrCreateNamespace(ns *Namespace) (netns.NsHandle, error) // IsNamespaceAvailable verifies whether required namespace exists and is accessible IsNamespaceAvailable(ns *interfaces.LinuxInterfaces_Interface_Namespace) bool // SwitchNamespace switches the network namespace of the current thread SwitchNamespace(ns *Namespace, ctx *NamespaceMgmtCtx) (revert func(), err error) // SwitchToNamespace switches the network namespace of the current thread // todo merge these two methods if possible SwitchToNamespace(nsMgmtCtx *NamespaceMgmtCtx, ns *interfaces.LinuxInterfaces_Interface_Namespace) (revert func(), err error) - // SetInterfaceNamespace moves linux interface to desired namespace - SetInterfaceNamespace(ctx *NamespaceMgmtCtx, ifName string, namespace *interfaces.LinuxInterfaces_Interface_Namespace) error // GetConfigNamespace returns configuration namespace (used for VETHs) GetConfigNamespace() *interfaces.LinuxInterfaces_Interface_Namespace + //ConvertMicroserviceNsToPidNs converts microservice-referenced namespace into the PID-referenced namespace + ConvertMicroserviceNsToPidNs(msLabel string) (pidNs *Namespace) } // NsConvertor defines common methods to convert namespace types diff --git a/plugins/linux/nsplugin/ns_handler_test.go b/plugins/linux/nsplugin/ns_handler_test.go index 13b81010ec..0fc88f7ead 100644 --- a/plugins/linux/nsplugin/ns_handler_test.go +++ b/plugins/linux/nsplugin/ns_handler_test.go @@ -17,15 +17,11 @@ package nsplugin_test import ( "testing" - "net" - "github.com/ligato/cn-infra/logging" - "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" + "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/plugins/linux/nsplugin" "github.com/ligato/vpp-agent/tests/linuxmock" . "github.com/onsi/gomega" - "github.com/vishvananda/netlink" - "github.com/ligato/cn-infra/utils/safeclose" ) /* Linux namespace handler init and close */ @@ -45,111 +41,6 @@ func TestNsHandlerInit(t *testing.T) { // todo test microservice tracker } -/* Namespace handler Test Setup */ - -func TestSetInterfaceNamespace(t *testing.T) { - plugin, ifHandler, sysHandler, msChan, ifNotif := nsHandlerTestSetup(t) - defer nsHandlerTestTeardown(plugin, ifHandler, sysHandler, msChan, ifNotif) - - // IP address list - var ipAddresses []netlink.Addr - ipAddresses = append(ipAddresses, - netlink.Addr{IPNet: getIPNetAddress("10.0.0.1/24")}, - netlink.Addr{IPNet: getIPNetAddress("172.168.0.1/24")}, - netlink.Addr{IPNet: getIPNetAddress("192.168.0.1/24")}, - // Link local address which should be skipped - netlink.Addr{IPNet: getIPNetAddress("fe80::883f:c3ff:fe9e:fba/64")}) - ifHandler.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ - LinkAttrs: netlink.LinkAttrs{ - Name: "if1", - Flags: net.FlagUp, - }, - }) - ifHandler.When("GetAddressList").ThenReturn(ipAddresses) - sysHandler.When("LinkSetNsFd").ThenReturn() - - // Context and namespace - ctx := nsplugin.NewNamespaceMgmtCtx() - ns := &interfaces.LinuxInterfaces_Interface_Namespace{ - Type: interfaces.LinuxInterfaces_Interface_Namespace_NAMED_NS, - } - - err := plugin.SetInterfaceNamespace(ctx, "if1", ns) - Expect(err).To(BeNil()) - - // Check calls to ensure that only required IP addresses were configured - num, calls := ifHandler.GetCallsFor("AddInterfaceIP") - Expect(num).To(Equal(3)) - Expect(calls).ToNot(BeNil()) - for callIdx, call := range calls { - ifName := call[0].(string) - Expect(ifName).To(Equal("if1")) - ipAdd := call[1].(*net.IPNet) - if callIdx == 1 { - Expect(ipAdd.String()).To(Equal("10.0.0.1/24")) - } - if callIdx == 2 { - Expect(ipAdd.String()).To(Equal("172.168.0.1/24")) - } - if callIdx == 3 { - Expect(ipAdd.String()).To(Equal("192.168.0.1/24")) - } - } -} - -func TestSetInterfaceNamespaceIPv6(t *testing.T) { - plugin, ifHandler, sysHandler, msChan, ifNotif := nsHandlerTestSetup(t) - defer nsHandlerTestTeardown(plugin, ifHandler, sysHandler, msChan, ifNotif) - - // IP address list - var ipAddresses []netlink.Addr - ipAddresses = append(ipAddresses, - netlink.Addr{IPNet: getIPNetAddress("10.0.0.1/24")}, - netlink.Addr{IPNet: getIPNetAddress("172.168.0.1/24")}, - // Link local address should not be skipped if there is another non-link-local IPv6 - netlink.Addr{IPNet: getIPNetAddress("fe80::883f:c3ff:fe9e:fba/64")}, - netlink.Addr{IPNet: getIPNetAddress("ad48::42:e8ff:feb1:e976/64")}) - ifHandler.When("GetLinkByName").ThenReturn(&netlink.Tuntap{ - LinkAttrs: netlink.LinkAttrs{ - Name: "if1", - Flags: net.FlagUp, - }, - }) - ifHandler.When("GetAddressList").ThenReturn(ipAddresses) - sysHandler.When("LinkSetNsFd").ThenReturn() - - // Context and namespace - ctx := nsplugin.NewNamespaceMgmtCtx() - ns := &interfaces.LinuxInterfaces_Interface_Namespace{ - Type: interfaces.LinuxInterfaces_Interface_Namespace_NAMED_NS, - } - - err := plugin.SetInterfaceNamespace(ctx, "if1", ns) - Expect(err).To(BeNil()) - - // Check calls to ensure that only required IP addresses were configured - num, calls := ifHandler.GetCallsFor("AddInterfaceIP") - Expect(num).To(Equal(4)) - Expect(calls).ToNot(BeNil()) - for callIdx, call := range calls { - ifName := call[0].(string) - Expect(ifName).To(Equal("if1")) - ipAdd := call[1].(*net.IPNet) - if callIdx == 1 { - Expect(ipAdd.String()).To(Equal("10.0.0.1/24")) - } - if callIdx == 2 { - Expect(ipAdd.String()).To(Equal("172.168.0.1/24")) - } - if callIdx == 3 { - Expect(ipAdd.String()).To(Equal("fe80::883f:c3ff:fe9e:fba/64")) - } - if callIdx == 4 { - Expect(ipAdd.String()).To(Equal("ad48::42:e8ff:feb1:e976/64")) - } - } -} - func nsHandlerTestSetup(t *testing.T) (*nsplugin.NsHandler, *linuxmock.IfNetlinkHandlerMock, *linuxmock.SystemMock, chan *nsplugin.MicroserviceCtx, chan *nsplugin.MicroserviceEvent) { RegisterTestingT(t) @@ -165,7 +56,7 @@ func nsHandlerTestSetup(t *testing.T) (*nsplugin.NsHandler, *linuxmock.IfNetlink ifNotif := make(chan *nsplugin.MicroserviceEvent) // Configurator plugin := &nsplugin.NsHandler{} - err := plugin.Init(pluginLog, ifHandler, sysHandler, msChan, ifNotif) + err := plugin.Init(pluginLog, sysHandler, msChan, ifNotif) Expect(err).To(BeNil()) return plugin, ifHandler, sysHandler, msChan, ifNotif @@ -178,10 +69,3 @@ func nsHandlerTestTeardown(plugin *nsplugin.NsHandler, ifHnadler *linuxmock.IfNe Expect(err).To(BeNil()) logging.DefaultRegistry.ClearRegistry() } - -func getIPNetAddress(ipAddr string) *net.IPNet { - ip, ipNet, err := net.ParseCIDR(ipAddr) - ipNet.IP = ip - Expect(err).To(BeNil()) - return ipNet -} diff --git a/plugins/linux/watch_events.go b/plugins/linux/watch_events.go index 50c584e729..0cb702e704 100644 --- a/plugins/linux/watch_events.go +++ b/plugins/linux/watch_events.go @@ -69,7 +69,7 @@ func (plugin *Plugin) watchEvents(ctx context.Context) { } func (plugin *Plugin) onResyncEvent(e datasync.ResyncEvent) { - req := resyncParseEvent(e, plugin.Log) + req := plugin.resyncParseEvent(e) err := plugin.resyncPropageRequest(req) e.Done(err) } @@ -81,20 +81,32 @@ func (plugin *Plugin) onChangeEvent(e datasync.ChangeEvent) { func (plugin *Plugin) onLinuxIfaceEvent(e ifaceidx.LinuxIfIndexDto) { if e.IsDelete() { - plugin.arpConfigurator.ResolveDeletedInterface(e.Name, e.Idx) - plugin.routeConfigurator.ResolveDeletedInterface(e.Name, e.Idx) + if err := plugin.arpConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.arpConfigurator.LogError(err) + } + if err := plugin.routeConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.routeConfigurator.LogError(err) + } } else { - plugin.arpConfigurator.ResolveCreatedInterface(e.Name, e.Idx) - plugin.routeConfigurator.ResolveCreatedInterface(e.Name, e.Idx) + if err := plugin.arpConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.arpConfigurator.LogError(err) + } + if err := plugin.routeConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.routeConfigurator.LogError(err) + } } e.Done() } func (plugin *Plugin) onVppIfaceEvent(e ifaceVPP.SwIfIdxDto) { if e.IsDelete() { - plugin.ifConfigurator.ResolveDeletedVPPInterface(e.Metadata) + if err := plugin.ifConfigurator.ResolveDeletedVPPInterface(e.Metadata); err != nil { + plugin.ifConfigurator.LogError(err) + } } else { - plugin.ifConfigurator.ResolveCreatedVPPInterface(e.Metadata) + if err := plugin.ifConfigurator.ResolveCreatedVPPInterface(e.Metadata); err != nil { + plugin.ifConfigurator.LogError(err) + } } e.Done() } diff --git a/plugins/rest/README.md b/plugins/rest/README.md index 23f56465f2..b718144a45 100644 --- a/plugins/rest/README.md +++ b/plugins/rest/README.md @@ -25,9 +25,9 @@ curl GET http://0.0.0.0:9191/vpp/dump/v1/acl/ip curl GET http://0.0.0.0:9191/vpp/dump/v1/acl/macip ``` -**Interfaces** +**VPP Interfaces** -REST plugin exposes configured interfaces, which can be show all together, or only interfaces +REST plugin exposes configured VPP interfaces, which can be show all together, or only interfaces of specific type. ``` @@ -40,6 +40,15 @@ curl GET http://0.0.0.0:9191/vpp/dump/v1/interfaces/vxlan curl GET http://0.0.0.0:9191/vpp/dump/v1/interfaces/afpacket ``` +**Linux Interfaces** + +REST plugin exposes configured Linux interfaces. All configured interfaces are dumped, together +with all interfaces in default namespace + +``` +curl GET https://0.0.0.0:9191/linux/dump/v1/interfaces +``` + **BFD** REST plugin allows to dump bidirectional forwarding detection sessions, authentication keys, @@ -93,6 +102,15 @@ curl GET http://0.0.0.0:9191/vpp/dump/v1/proxyarp/ranges curl GET http://0.0.0.0:9191/vpp/dump/v1/routes ``` +**Linux L3 plugin** + +Linux ARP and linux routes exposed via REST: + +``` +curl GET http://0.0.0.0:9191/linux/dump/v1/arps +curl GET http://0.0.0.0:9191/linux/dump/v1/routes +``` + **L4 plugin** L4 plugin exposes session configuration: diff --git a/plugins/rest/plugin_impl_rest.go b/plugins/rest/plugin_impl_rest.go index dd4e9ca04b..f658b4bbf2 100644 --- a/plugins/rest/plugin_impl_rest.go +++ b/plugins/rest/plugin_impl_rest.go @@ -16,13 +16,20 @@ package rest import ( "fmt" + "net/http" "sync" + access "github.com/ligato/cn-infra/rpc/rest/security/model/access-security" + + "github.com/ligato/vpp-agent/plugins/linux" + "git.fd.io/govpp.git/api" "github.com/ligato/cn-infra/infra" "github.com/ligato/cn-infra/rpc/rest" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/plugins/govppmux" + iflinuxcalls "github.com/ligato/vpp-agent/plugins/linux/ifplugin/linuxcalls" + l3linuxcalls "github.com/ligato/vpp-agent/plugins/linux/l3plugin/linuxcalls" "github.com/ligato/vpp-agent/plugins/rest/resturl" "github.com/ligato/vpp-agent/plugins/vpp" aclvppcalls "github.com/ligato/vpp-agent/plugins/vpp/aclplugin/vppcalls" @@ -50,7 +57,7 @@ type Plugin struct { vppChan api.Channel dumpChan api.Channel - // Handlers + // VPP Handlers aclHandler aclvppcalls.ACLVppRead ifHandler ifvppcalls.IfVppRead bfdHandler ifvppcalls.BfdVppRead @@ -64,6 +71,9 @@ type Plugin struct { pArpHandler l3vppcalls.ProxyArpVppRead rtHandler l3vppcalls.RouteVppRead l4Handler l4vppcalls.L4VppRead + // Linux handlers + linuxIfHandler iflinuxcalls.NetlinkAPI + linuxL3Handler l3linuxcalls.NetlinkAPI govppmux sync.Mutex } @@ -72,8 +82,9 @@ type Plugin struct { type Deps struct { infra.PluginDeps HTTPHandlers rest.HTTPHandlers - GoVppmux govppmux.API + GoVppmux govppmux.TraceAPI VPP vpp.API + Linux linux.API } // index defines map of main index page entries @@ -100,27 +111,80 @@ func (plugin *Plugin) Init() (err error) { if plugin.dumpChan, err = plugin.GoVppmux.NewAPIChannel(); err != nil { return err } - // Indexes + // VPP Indexes ifIndexes := plugin.VPP.GetSwIfIndexes() bdIndexes := plugin.VPP.GetBDIndexes() spdIndexes := plugin.VPP.GetIPSecSPDIndexes() + // Initialize VPP handlers + plugin.aclHandler = aclvppcalls.NewACLVppHandler(plugin.vppChan, plugin.dumpChan) + plugin.ifHandler = ifvppcalls.NewIfVppHandler(plugin.vppChan, plugin.Log) + plugin.bfdHandler = ifvppcalls.NewBfdVppHandler(plugin.vppChan, ifIndexes, plugin.Log) + plugin.natHandler = ifvppcalls.NewNatVppHandler(plugin.vppChan, plugin.dumpChan, ifIndexes, plugin.Log) + plugin.stnHandler = ifvppcalls.NewStnVppHandler(plugin.vppChan, ifIndexes, plugin.Log) + plugin.ipSecHandler = ipsecvppcalls.NewIPsecVppHandler(plugin.vppChan, ifIndexes, spdIndexes, plugin.Log) + plugin.bdHandler = l2vppcalls.NewBridgeDomainVppHandler(plugin.vppChan, ifIndexes, plugin.Log) + plugin.fibHandler = l2vppcalls.NewFibVppHandler(plugin.vppChan, plugin.dumpChan, ifIndexes, bdIndexes, plugin.Log) + plugin.xcHandler = l2vppcalls.NewXConnectVppHandler(plugin.vppChan, ifIndexes, plugin.Log) + plugin.arpHandler = l3vppcalls.NewArpVppHandler(plugin.vppChan, ifIndexes, plugin.Log) + plugin.pArpHandler = l3vppcalls.NewProxyArpVppHandler(plugin.vppChan, ifIndexes, plugin.Log) + plugin.rtHandler = l3vppcalls.NewRouteVppHandler(plugin.vppChan, ifIndexes, plugin.Log) + plugin.l4Handler = l4vppcalls.NewL4VppHandler(plugin.vppChan, plugin.Log) + // Linux indexes and handlers + if plugin.Linux != nil { + linuxIfIndexes := plugin.Linux.GetLinuxIfIndexes() + linuxArpIndexes := plugin.Linux.GetLinuxARPIndexes() + linuxRtIndexes := plugin.Linux.GetLinuxRouteIndexes() + // Initialize Linux handlers + linuxNsHandler := plugin.Linux.GetNamespaceHandler() + plugin.linuxIfHandler = iflinuxcalls.NewNetLinkHandler(linuxNsHandler, linuxIfIndexes, plugin.Log) + plugin.linuxL3Handler = l3linuxcalls.NewNetLinkHandler(linuxNsHandler, linuxIfIndexes, linuxArpIndexes, linuxRtIndexes, plugin.Log) + } + + plugin.index = &index{ + ItemMap: getIndexMap(), + } + + // Register permission groups, used if REST security is enabled + plugin.HTTPHandlers.RegisterPermissionGroup(getPermissionsGroups()...) + + return nil +} - // Initialize handlers - plugin.aclHandler = aclvppcalls.NewACLVppHandler(plugin.vppChan, plugin.dumpChan, nil) - plugin.ifHandler = ifvppcalls.NewIfVppHandler(plugin.vppChan, plugin.Log, nil) - plugin.bfdHandler = ifvppcalls.NewBfdVppHandler(plugin.vppChan, ifIndexes, plugin.Log, nil) - plugin.natHandler = ifvppcalls.NewNatVppHandler(plugin.vppChan, plugin.dumpChan, ifIndexes, plugin.Log, nil) - plugin.stnHandler = ifvppcalls.NewStnVppHandler(plugin.vppChan, ifIndexes, plugin.Log, nil) - plugin.ipSecHandler = ipsecvppcalls.NewIPsecVppHandler(plugin.vppChan, ifIndexes, spdIndexes, plugin.Log, nil) - plugin.bdHandler = l2vppcalls.NewBridgeDomainVppHandler(plugin.vppChan, ifIndexes, plugin.Log, nil) - plugin.fibHandler = l2vppcalls.NewFibVppHandler(plugin.vppChan, plugin.dumpChan, ifIndexes, bdIndexes, plugin.Log, nil) - plugin.xcHandler = l2vppcalls.NewXConnectVppHandler(plugin.vppChan, ifIndexes, plugin.Log, nil) - plugin.arpHandler = l3vppcalls.NewArpVppHandler(plugin.vppChan, ifIndexes, plugin.Log, nil) - plugin.pArpHandler = l3vppcalls.NewProxyArpVppHandler(plugin.vppChan, ifIndexes, plugin.Log, nil) - plugin.rtHandler = l3vppcalls.NewRouteVppHandler(plugin.vppChan, ifIndexes, plugin.Log, nil) - plugin.l4Handler = l4vppcalls.NewL4VppHandler(plugin.vppChan, plugin.Log, nil) - - // Fill index item lists +// AfterInit is used to register HTTP handlers +func (plugin *Plugin) AfterInit() (err error) { + plugin.Log.Debug("REST API Plugin is up and running") + + // VPP handlers + plugin.registerAccessListHandlers() + plugin.registerInterfaceHandlers() + plugin.registerBfdHandlers() + plugin.registerNatHandlers() + plugin.registerStnHandlers() + plugin.registerIPSecHandlers() + plugin.registerL2Handlers() + plugin.registerL3Handlers() + plugin.registerL4Handlers() + // Linux handlers + if plugin.Linux != nil { + plugin.registerLinuxInterfaceHandlers() + plugin.registerLinuxL3Handlers() + } + // Telemetry, command, index, tracer + plugin.registerTracerHandler() + plugin.registerTelemetryHandlers() + plugin.registerCommandHandler() + plugin.registerIndexHandlers() + + return nil +} + +// Close is used to clean up resources used by Plugin +func (plugin *Plugin) Close() (err error) { + return safeclose.Close(plugin.vppChan, plugin.dumpChan) +} + +// Fill index item lists +func getIndexMap() map[string][]indexItem { idxMap := map[string][]indexItem{ "ACL plugin": { {Name: "IP-type access lists", Path: resturl.ACLIP}, @@ -147,10 +211,10 @@ func (plugin *Plugin) Init() (err error) { {Name: "Cross connects", Path: resturl.Xc}, }, "L3 plugin": { - {Name: "Bridge domains", Path: resturl.Bd}, - {Name: "Bridge domain IDs", Path: resturl.BdID}, - {Name: "L2Fibs", Path: resturl.Fib}, - {Name: "Cross connects", Path: resturl.Xc}, + {Name: "Routes", Path: resturl.Routes}, + {Name: "ARPs", Path: resturl.Arps}, + {Name: "Proxy ARP interfaces", Path: resturl.PArpIfs}, + {Name: "Proxy ARP ranges", Path: resturl.PArpRngs}, }, "L4 plugin": { {Name: "L4 sessions", Path: resturl.Sessions}, @@ -161,36 +225,68 @@ func (plugin *Plugin) Init() (err error) { {Name: "Runtime", Path: resturl.TRuntime}, {Name: "Node count", Path: resturl.TNodeCount}, }, + "Tracer": { + {Name: "Binary API", Path: resturl.Tracer}, + }, } - - plugin.index = &index{ - ItemMap: idxMap, - } - - return nil + return idxMap } -// AfterInit is used to register HTTP handlers -func (plugin *Plugin) AfterInit() (err error) { - plugin.Log.Debug("REST API Plugin is up and running") - - plugin.registerAccessListHandlers() - plugin.registerInterfaceHandlers() - plugin.registerBfdHandlers() - plugin.registerNatHandlers() - plugin.registerStnHandlers() - plugin.registerIPSecHandlers() - plugin.registerL2Handlers() - plugin.registerL3Handlers() - plugin.registerL4Handlers() - plugin.registerTelemetryHandlers() - plugin.registerCommandHandler() - plugin.registerIndexHandlers() +// Create permission groups (tracer, telemetry, dump - optionally add more in the future). Used only if +// REST security is enabled in plugin +func getPermissionsGroups() []*access.PermissionGroup { + tracerPg := &access.PermissionGroup{ + Name: "tracer", + Permissions: []*access.PermissionGroup_Permissions{ + newPermission(resturl.Index, http.MethodGet), + newPermission(resturl.Tracer, http.MethodGet), + }, + } + telemetryPg := &access.PermissionGroup{ + Name: "telemetry", + Permissions: []*access.PermissionGroup_Permissions{ + newPermission(resturl.Index, http.MethodGet), + newPermission(resturl.Telemetry, http.MethodGet), + newPermission(resturl.TMemory, http.MethodGet), + newPermission(resturl.TRuntime, http.MethodGet), + newPermission(resturl.TNodeCount, http.MethodGet), + }, + } + dumpPg := &access.PermissionGroup{ + Name: "dump", + Permissions: []*access.PermissionGroup_Permissions{ + newPermission(resturl.Index, http.MethodGet), + newPermission(resturl.ACLIP, http.MethodGet), + newPermission(resturl.ACLMACIP, http.MethodGet), + newPermission(resturl.Interface, http.MethodGet), + newPermission(resturl.Loopback, http.MethodGet), + newPermission(resturl.Ethernet, http.MethodGet), + newPermission(resturl.Memif, http.MethodGet), + newPermission(resturl.Tap, http.MethodGet), + newPermission(resturl.VxLan, http.MethodGet), + newPermission(resturl.AfPacket, http.MethodGet), + newPermission(resturl.IPSecSpd, http.MethodGet), + newPermission(resturl.IPSecSa, http.MethodGet), + newPermission(resturl.IPSecTnIf, http.MethodGet), + newPermission(resturl.Bd, http.MethodGet), + newPermission(resturl.BdID, http.MethodGet), + newPermission(resturl.Fib, http.MethodGet), + newPermission(resturl.Xc, http.MethodGet), + newPermission(resturl.Arps, http.MethodGet), + newPermission(resturl.Routes, http.MethodGet), + newPermission(resturl.PArpIfs, http.MethodGet), + newPermission(resturl.PArpRngs, http.MethodGet), + newPermission(resturl.Sessions, http.MethodGet), + }, + } - return nil + return []*access.PermissionGroup{tracerPg, telemetryPg, dumpPg} } -// Close is used to clean up resources used by Plugin -func (plugin *Plugin) Close() (err error) { - return safeclose.Close(plugin.vppChan, plugin.dumpChan) +// Returns permission object with url and provided methods +func newPermission(url string, methods ...string) *access.PermissionGroup_Permissions { + return &access.PermissionGroup_Permissions{ + Url: url, + AllowedMethods: methods, + } } diff --git a/plugins/rest/rest_handlers.go b/plugins/rest/rest_handlers.go index 221c7443dd..cc19ba34bc 100644 --- a/plugins/rest/rest_handlers.go +++ b/plugins/rest/rest_handlers.go @@ -170,7 +170,7 @@ func (plugin *Plugin) registerL3Handlers() { }) } -// Registers L3 plugin REST handlers +// Registers L4 plugin REST handlers func (plugin *Plugin) registerL4Handlers() { // GET static routes plugin.registerHTTPHandler(resturl.Sessions, GET, func() (interface{}, error) { @@ -178,6 +178,30 @@ func (plugin *Plugin) registerL4Handlers() { }) } +// Registers linux interface plugin REST handlers +func (plugin *Plugin) registerLinuxInterfaceHandlers() { + // GET linux interfaces + plugin.registerHTTPHandler(resturl.LinuxInterface, GET, func() (interface{}, error) { + return plugin.linuxIfHandler.DumpInterfaces() + }) + // GET linux interface stats + plugin.registerHTTPHandler(resturl.LinuxInterfaceStats, GET, func() (interface{}, error) { + return plugin.linuxIfHandler.DumpInterfaceStatistics() + }) +} + +// Registers linux L3 plugin REST handlers +func (plugin *Plugin) registerLinuxL3Handlers() { + // GET linux routes + plugin.registerHTTPHandler(resturl.LinuxRoutes, GET, func() (interface{}, error) { + return plugin.linuxL3Handler.DumpRoutes() + }) + // GET linux ARPs + plugin.registerHTTPHandler(resturl.LinuxArps, GET, func() (interface{}, error) { + return plugin.linuxL3Handler.DumpArpEntries() + }) +} + // Registers Telemetry handler func (plugin *Plugin) registerTelemetryHandlers() { plugin.HTTPHandlers.RegisterHTTPHandler(resturl.Telemetry, plugin.telemetryHandler, GET) @@ -186,6 +210,11 @@ func (plugin *Plugin) registerTelemetryHandlers() { plugin.HTTPHandlers.RegisterHTTPHandler(resturl.TNodeCount, plugin.telemetryNodeCountHandler, GET) } +// Registers Tracer handler +func (plugin *Plugin) registerTracerHandler() { + plugin.HTTPHandlers.RegisterHTTPHandler(resturl.Tracer, plugin.tracerHandler, GET) +} + // Registers command handler func (plugin *Plugin) registerCommandHandler() { plugin.HTTPHandlers.RegisterHTTPHandler(resturl.Command, plugin.commandHandler, POST) @@ -415,3 +444,29 @@ func (plugin *Plugin) telemetryNodeCountHandler(formatter *render.Render) http.H formatter.JSON(w, http.StatusOK, nodeCounters) } } + +// tracerHandler - returns binary API call trace +func (plugin *Plugin) tracerHandler(formatter *render.Render) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + ch, err := plugin.GoVppmux.NewAPIChannel() + if err != nil { + plugin.Log.Errorf("Error creating channel: %v", err) + formatter.JSON(w, http.StatusInternalServerError, err) + return + } + defer ch.Close() + + entries := plugin.GoVppmux.GetTrace() + if err != nil { + plugin.Log.Errorf("Sending command failed: %v", err) + formatter.JSON(w, http.StatusInternalServerError, err) + return + } + if entries == nil { + formatter.JSON(w, http.StatusOK, "VPP api trace is disabled") + return + } + + formatter.JSON(w, http.StatusOK, entries) + } +} diff --git a/plugins/rest/resturl/rest_url.go b/plugins/rest/resturl/rest_url.go index 15f1aee09a..fbb68855f7 100644 --- a/plugins/rest/resturl/rest_url.go +++ b/plugins/rest/resturl/rest_url.go @@ -32,24 +32,32 @@ const ( BfdAuthKey = "/vpp/dump/v1/bfd/authkeys" ) -// Interface REST urls +// VPP interface REST urls const ( - // restInterface is rest interface path + // Interface is rest interface path Interface = "/vpp/dump/v1/interfaces" - // restLoopback is path for loopback interface + // Loopback is path for loopback interface Loopback = "/vpp/dump/v1/interfaces/loopback" - // restLoopback is path for physical interface + // Ethernet is path for physical interface Ethernet = "/vpp/dump/v1/interfaces/ethernet" - // restLoopback is path for memif interface + // Memif is path for memif interface Memif = "/vpp/dump/v1/interfaces/memif" - // restLoopback is path for tap interface + // Tap is path for tap interface Tap = "/vpp/dump/v1/interfaces/tap" - // restAfPacket is path for af-packet interface + // AfPacket is path for af-packet interface AfPacket = "/vpp/dump/v1/interfaces/afpacket" - // restLoopback is path for vxlan interface + // VxLan is path for vxlan interface VxLan = "/vpp/dump/v1/interfaces/vxlan" ) +// Linux interface REST urls +const ( + // LinuxInterface is a linux interface rest path + LinuxInterface = "/linux/dump/v1/interfaces" + // LinuxInterfaceStats is a linux interface statistics rest path + LinuxInterfaceStats = "/linux/dump/v1/interfaces/statistics" +) + // NAT REST urls const ( // NatURL is a REST path of a NAT @@ -88,7 +96,7 @@ const ( Xc = "/vpp/dump/v1/xc" ) -// L3 plugin +// VPP L3 plugin const ( // Routes is rest static route path Routes = "/vpp/dump/v1/routes" @@ -100,6 +108,14 @@ const ( PArpRngs = "/vpp/dump/v1/proxyarp/ranges" ) +// Linux L3 plugin +const ( + // LinuxRoutes is the rest linux route path + LinuxRoutes = "/linux/dump/v1/routes" + // LinuxArps is the rest linux ARPs path + LinuxArps = "/linux/dump/v1/arps" +) + // L4 plugin const ( // Sessions is rest L4 configuration path @@ -121,6 +137,12 @@ const ( TNodeCount = "/vpp/telemetry/nodecount" ) +// Tracer +const ( + // Traced binary API calls + Tracer = "/vpp/binapitrace" +) + // Index const ( // Index can be used to get the full index page diff --git a/plugins/vpp/README.md b/plugins/vpp/README.md index 4c2c5fa196..00fd160b06 100644 --- a/plugins/vpp/README.md +++ b/plugins/vpp/README.md @@ -13,7 +13,6 @@ The default plugins can use configuration file `vpp.conf` to: * set global maximum transmission unit - * enable/disable stopwatch * set VPP resync strategy * to enable/disable status publishers @@ -28,15 +27,6 @@ `mtu: ` - *Stopwatch* - - Duration of the VPP binary api call can be measured using stopwatch feature. These data are logged after - every event(any resync, interfaces, bridge domains, fib entries etc.). Enable stopwatch in vpp.conf: - - `stopwatch: true` or `stopwatch: false` - - Stopwatch is disabled by default (if there is no config available). - *Resync Strategy* There are two strategies available for VPP resync: diff --git a/plugins/vpp/aclplugin/acl_config.go b/plugins/vpp/aclplugin/acl_config.go index 882ec9fac5..588cd08dc7 100644 --- a/plugins/vpp/aclplugin/acl_config.go +++ b/plugins/vpp/aclplugin/acl_config.go @@ -12,18 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/acl --gogo_out=../model/acl ../model/acl/acl.proto - // Package aclplugin implements the ACL Plugin that handles management of VPP // Access lists. package aclplugin import ( - "fmt" - govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -69,162 +65,153 @@ type ACLConfigurator struct { // ACL VPP calls handler aclHandler vppcalls.ACLVppAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init goroutines, channels and mappings. -func (plugin *ACLConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *ACLConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-acl-plugin") - plugin.log.Infof("Initializing ACL configurator") + c.log = logger.NewLogger("acl-plugin") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.l2AclIndexes = aclidx.NewACLIndex(nametoidx.NewNameToIdx(plugin.log, "acl_l2_indexes", nil)) - plugin.l3l4AclIndexes = aclidx.NewACLIndex(nametoidx.NewNameToIdx(plugin.log, "acl_l3_l4_indexes", nil)) + c.ifIndexes = swIfIndexes + c.l2AclIndexes = aclidx.NewACLIndex(nametoidx.NewNameToIdx(c.log, "acl_l2_indexes", nil)) + c.l3l4AclIndexes = aclidx.NewACLIndex(nametoidx.NewNameToIdx(c.log, "acl_l3_l4_indexes", nil)) // VPP channels - plugin.vppChan, err = goVppMux.NewAPIChannel() + c.vppChan, err = goVppMux.NewAPIChannel() if err != nil { - return err + return errors.Errorf("failed to create API channel: %v", err) } - plugin.vppDumpChan, err = goVppMux.NewAPIChannel() + c.vppDumpChan, err = goVppMux.NewAPIChannel() if err != nil { - return err - } - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("ACL-configurator", plugin.log) + return errors.Errorf("failed to create dump API channel: %v", err) } // ACL binary api handler - plugin.aclHandler = vppcalls.NewACLVppHandler(plugin.vppChan, plugin.vppDumpChan, plugin.stopwatch) + c.aclHandler = vppcalls.NewACLVppHandler(c.vppChan, c.vppDumpChan) + + c.log.Infof("ACL configurator initialized") return nil } // Close GOVPP channel. -func (plugin *ACLConfigurator) Close() error { - return safeclose.Close(plugin.vppChan, plugin.vppDumpChan) +func (c *ACLConfigurator) Close() error { + if err := safeclose.Close(c.vppChan, c.vppDumpChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose interface configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *ACLConfigurator) clearMapping() { - plugin.l2AclIndexes.Clear() - plugin.l3l4AclIndexes.Clear() +func (c *ACLConfigurator) clearMapping() { + c.l2AclIndexes.Clear() + c.l3l4AclIndexes.Clear() } // GetL2AclIfIndexes exposes l2 acl interface name-to-index mapping -func (plugin *ACLConfigurator) GetL2AclIfIndexes() aclidx.ACLIndexRW { - return plugin.l2AclIndexes +func (c *ACLConfigurator) GetL2AclIfIndexes() aclidx.ACLIndexRW { + return c.l2AclIndexes } // GetL3L4AclIfIndexes exposes l3/l4 acl interface name-to-index mapping -func (plugin *ACLConfigurator) GetL3L4AclIfIndexes() aclidx.ACLIndexRW { - return plugin.l3l4AclIndexes +func (c *ACLConfigurator) GetL3L4AclIfIndexes() aclidx.ACLIndexRW { + return c.l3l4AclIndexes } // ConfigureACL creates access list with provided rules and sets this list to every relevant interface. -func (plugin *ACLConfigurator) ConfigureACL(acl *acl.AccessLists_Acl) error { - plugin.log.Infof("Configuring new ACL %v", acl.AclName) - +func (c *ACLConfigurator) ConfigureACL(acl *acl.AccessLists_Acl) error { if len(acl.Rules) == 0 { - plugin.log.Debugf("ACL %v has no rules set, skipping configuration", acl.AclName) - return nil + return errors.Errorf("failed to configure ACL %s, no rules to set", acl.AclName) } - rules, isL2MacIP := plugin.validateRules(acl.AclName, acl.Rules) + rules, isL2MacIP := c.validateRules(acl.AclName, acl.Rules) // Configure ACL rules. var vppACLIndex uint32 var err error if isL2MacIP { - vppACLIndex, err = plugin.aclHandler.AddMacIPACL(rules, acl.AclName) + vppACLIndex, err = c.aclHandler.AddMacIPACL(rules, acl.AclName) if err != nil { - return err + return errors.Errorf("failed to add MAC IP ACL %s: %v", acl.AclName, err) } // Index used for L2 registration is ACLIndex + 1 (ACL indexes start from 0). agentACLIndex := vppACLIndex + 1 - plugin.l2AclIndexes.RegisterName(acl.AclName, agentACLIndex, acl) - plugin.log.Debugf("ACL %v registered with index %v", acl.AclName, agentACLIndex) + c.l2AclIndexes.RegisterName(acl.AclName, agentACLIndex, acl) + c.log.Debugf("ACL %s registered to L2 mapping", acl.AclName) } else { - vppACLIndex, err = plugin.aclHandler.AddIPACL(rules, acl.AclName) + vppACLIndex, err = c.aclHandler.AddIPACL(rules, acl.AclName) if err != nil { - return err + return errors.Errorf("failed to add IP ACL %s: %v", acl.AclName, err) } // Index used for L3L4 registration is aclIndex + 1 (ACL indexes start from 0). agentACLIndex := vppACLIndex + 1 - plugin.l3l4AclIndexes.RegisterName(acl.AclName, agentACLIndex, acl) - plugin.log.Debugf("ACL %v registered with index %v", acl.AclName, agentACLIndex) + c.l3l4AclIndexes.RegisterName(acl.AclName, agentACLIndex, acl) + c.log.Debugf("ACL %s registered to L3/L4 mapping", acl.AclName) } // Set ACL to interfaces. if ifaces := acl.GetInterfaces(); ifaces != nil { if isL2MacIP { - aclIfIndices := plugin.getOrCacheInterfaces(acl.Interfaces.Ingress, vppACLIndex, L2) - err := plugin.aclHandler.SetMacIPACLToInterface(vppACLIndex, aclIfIndices) + aclIfIndices := c.getOrCacheInterfaces(acl.Interfaces.Ingress, vppACLIndex, L2) + err := c.aclHandler.SetMacIPACLToInterface(vppACLIndex, aclIfIndices) if err != nil { - return err + return errors.Errorf("failed to set MAC IP ACL %s to interface(s) %v: %v", + acl.AclName, acl.Interfaces.Ingress, err) } } else { - aclIfInIndices := plugin.getOrCacheInterfaces(acl.Interfaces.Ingress, vppACLIndex, INGRESS) - err = plugin.aclHandler.SetACLToInterfacesAsIngress(vppACLIndex, aclIfInIndices) + aclIfInIndices := c.getOrCacheInterfaces(acl.Interfaces.Ingress, vppACLIndex, INGRESS) + err = c.aclHandler.SetACLToInterfacesAsIngress(vppACLIndex, aclIfInIndices) if err != nil { - return err + return errors.Errorf("failed to set IP ACL %s to interface(s) %v as ingress: %v", + acl.AclName, acl.Interfaces.Ingress, err) } - aclIfEgIndices := plugin.getOrCacheInterfaces(acl.Interfaces.Egress, vppACLIndex, EGRESS) - err = plugin.aclHandler.SetACLToInterfacesAsEgress(vppACLIndex, aclIfEgIndices) + aclIfEgIndices := c.getOrCacheInterfaces(acl.Interfaces.Egress, vppACLIndex, EGRESS) + err = c.aclHandler.SetACLToInterfacesAsEgress(vppACLIndex, aclIfEgIndices) if err != nil { - return err + return errors.Errorf("failed to set IP ACL %s to interface(s) %v as egress: %v", + acl.AclName, acl.Interfaces.Ingress, err) } } - } else { - plugin.log.Infof("No interface configured for ACL %v", acl.AclName) } + c.log.Infof("ACL %s configured with ID %d", acl.AclName, vppACLIndex) + return nil } // ModifyACL modifies previously created access list. L2 access list is removed and recreated, // L3/L4 access list is modified directly. List of interfaces is refreshed as well. -func (plugin *ACLConfigurator) ModifyACL(oldACL, newACL *acl.AccessLists_Acl) (err error) { - plugin.log.Infof("Modifying ACL %v", oldACL.AclName) - +func (c *ACLConfigurator) ModifyACL(oldACL, newACL *acl.AccessLists_Acl) error { if newACL.Rules != nil { // Validate rules. - rules, isL2MacIP := plugin.validateRules(newACL.AclName, newACL.Rules) + rules, isL2MacIP := c.validateRules(newACL.AclName, newACL.Rules) var vppACLIndex uint32 if isL2MacIP { - agentACLIndex, _, found := plugin.l2AclIndexes.LookupIdx(oldACL.AclName) + agentACLIndex, _, found := c.l2AclIndexes.LookupIdx(oldACL.AclName) if !found { - plugin.log.Infof("ACL %v index not found", oldACL.AclName) - return nil + return errors.Errorf("cannot modify IP MAC ACL %s, index not found in the mapping", oldACL.AclName) } // Index used in VPP = index used in mapping - 1 vppACLIndex = agentACLIndex - 1 } else { - agentACLIndex, _, found := plugin.l3l4AclIndexes.LookupIdx(oldACL.AclName) + agentACLIndex, _, found := c.l3l4AclIndexes.LookupIdx(oldACL.AclName) if !found { - plugin.log.Infof("ACL %v index not found", oldACL.AclName) - return nil + return errors.Errorf("cannot modify IP ACL %s, index not found in the mapping", oldACL.AclName) } vppACLIndex = agentACLIndex - 1 } if isL2MacIP { // L2 ACL - err := plugin.aclHandler.ModifyMACIPACL(vppACLIndex, rules, newACL.AclName) + err := c.aclHandler.ModifyMACIPACL(vppACLIndex, rules, newACL.AclName) if err != nil { - return err + return errors.Errorf("failed to modify MAC IP ACL %s: %v", newACL.AclName, err) } // There is no need to update index because modified ACL keeps the old one. } else { // L3/L4 ACL can be modified directly. - err := plugin.aclHandler.ModifyIPACL(vppACLIndex, rules, newACL.AclName) + err := c.aclHandler.ModifyIPACL(vppACLIndex, rules, newACL.AclName) if err != nil { - return err + return errors.Errorf("failed to modify IP ACL %s: %v", newACL.AclName, err) } // There is no need to update index because modified ACL keeps the old one. } @@ -233,118 +220,128 @@ func (plugin *ACLConfigurator) ModifyACL(oldACL, newACL *acl.AccessLists_Acl) (e if isL2MacIP { // Remove L2 ACL from old interfaces. if oldACL.Interfaces != nil { - - err := plugin.aclHandler.RemoveMacIPIngressACLFromInterfaces(vppACLIndex, plugin.getInterfaces(oldACL.Interfaces.Ingress)) + err := c.aclHandler.RemoveMacIPIngressACLFromInterfaces(vppACLIndex, c.getInterfaces(oldACL.Interfaces.Ingress)) if err != nil { - return err + return errors.Errorf("failed to remove MAC IP ingress interfaces from ACL %s: %v", + oldACL.AclName, err) } } // Put L2 ACL to new interfaces. if newACL.Interfaces != nil { - aclMacInterfaces := plugin.getOrCacheInterfaces(newACL.Interfaces.Ingress, vppACLIndex, L2) - err := plugin.aclHandler.SetMacIPACLToInterface(vppACLIndex, aclMacInterfaces) + aclMacInterfaces := c.getOrCacheInterfaces(newACL.Interfaces.Ingress, vppACLIndex, L2) + err := c.aclHandler.SetMacIPACLToInterface(vppACLIndex, aclMacInterfaces) if err != nil { - return err + return errors.Errorf("failed to set MAC IP ingress interfaces to ACL %s: %v", + newACL.AclName, err) } } - } else { - aclOldInInterfaces := plugin.getInterfaces(oldACL.Interfaces.Ingress) - aclOldEgInterfaces := plugin.getInterfaces(oldACL.Interfaces.Egress) - aclNewInInterfaces := plugin.getOrCacheInterfaces(newACL.Interfaces.Ingress, vppACLIndex, INGRESS) - aclNewEgInterfaces := plugin.getOrCacheInterfaces(newACL.Interfaces.Egress, vppACLIndex, EGRESS) + aclOldInInterfaces := c.getInterfaces(oldACL.Interfaces.Ingress) + aclOldEgInterfaces := c.getInterfaces(oldACL.Interfaces.Egress) + aclNewInInterfaces := c.getOrCacheInterfaces(newACL.Interfaces.Ingress, vppACLIndex, INGRESS) + aclNewEgInterfaces := c.getOrCacheInterfaces(newACL.Interfaces.Egress, vppACLIndex, EGRESS) addedInInterfaces, removedInInterfaces := diffInterfaces(aclOldInInterfaces, aclNewInInterfaces) addedEgInterfaces, removedEgInterfaces := diffInterfaces(aclOldEgInterfaces, aclNewEgInterfaces) if len(removedInInterfaces) > 0 { - err = plugin.aclHandler.RemoveIPIngressACLFromInterfaces(vppACLIndex, removedInInterfaces) + err := c.aclHandler.RemoveIPIngressACLFromInterfaces(vppACLIndex, removedInInterfaces) if err != nil { - return err + return errors.Errorf("failed to remove IP ingress interfaces from ACL %s: %v", + oldACL.AclName, err) } } if len(removedEgInterfaces) > 0 { - err = plugin.aclHandler.RemoveIPEgressACLFromInterfaces(vppACLIndex, removedEgInterfaces) + err := c.aclHandler.RemoveIPEgressACLFromInterfaces(vppACLIndex, removedEgInterfaces) if err != nil { - return err + return errors.Errorf("failed to remove IP egress interfaces from ACL %s: %v", + oldACL.AclName, err) } } if len(addedInInterfaces) > 0 { - err = plugin.aclHandler.SetACLToInterfacesAsIngress(vppACLIndex, addedInInterfaces) + err := c.aclHandler.SetACLToInterfacesAsIngress(vppACLIndex, addedInInterfaces) if err != nil { - return err + return errors.Errorf("failed to set IP ingress interfaces to ACL %s: %v", + newACL.AclName, err) } } if len(addedEgInterfaces) > 0 { - err = plugin.aclHandler.SetACLToInterfacesAsEgress(vppACLIndex, addedEgInterfaces) + err := c.aclHandler.SetACLToInterfacesAsEgress(vppACLIndex, addedEgInterfaces) if err != nil { - return err + return errors.Errorf("failed to add IP egress interfaces to ACL %s: %v", + oldACL.AclName, err) } } } } - return err + c.log.Info("ACL %s modified", newACL.AclName) + + return nil } // DeleteACL removes existing ACL. To detach ACL from interfaces, list of interfaces has to be provided. -func (plugin *ACLConfigurator) DeleteACL(acl *acl.AccessLists_Acl) (err error) { - plugin.log.Infof("Deleting ACL %v", acl.AclName) - +func (c *ACLConfigurator) DeleteACL(acl *acl.AccessLists_Acl) (err error) { // Get ACL index. Keep in mind that all ACL Indices were incremented by 1. - agentL2AclIndex, _, l2AclFound := plugin.l2AclIndexes.LookupIdx(acl.AclName) - agentL3L4AclIndex, _, l3l4AclFound := plugin.l3l4AclIndexes.LookupIdx(acl.AclName) + agentL2AclIndex, _, l2AclFound := c.l2AclIndexes.LookupIdx(acl.AclName) + agentL3L4AclIndex, _, l3l4AclFound := c.l3l4AclIndexes.LookupIdx(acl.AclName) if !l2AclFound && !l3l4AclFound { - return fmt.Errorf("ACL %v not found, cannot be removed", acl.AclName) + return errors.Errorf("cannot remove ACL %s, index not found in the mapping", acl.AclName) } if l2AclFound { // Remove interfaces from L2 ACL. vppACLIndex := agentL2AclIndex - 1 if acl.Interfaces != nil { - err := plugin.aclHandler.RemoveMacIPIngressACLFromInterfaces(vppACLIndex, plugin.getInterfaces(acl.Interfaces.Ingress)) + err := c.aclHandler.RemoveMacIPIngressACLFromInterfaces(vppACLIndex, c.getInterfaces(acl.Interfaces.Ingress)) if err != nil { - return err + return errors.Errorf("failed to remove MAC IP interfaces from ACL %s: %v", + acl.AclName, err) } } // Remove ACL L2. - err := plugin.aclHandler.DeleteMacIPACL(vppACLIndex) + err := c.aclHandler.DeleteMacIPACL(vppACLIndex) if err != nil { - return err + return errors.Errorf("failed to remove MAC IP ACL %s: %v", acl.AclName, err) } // Unregister. - plugin.l2AclIndexes.UnregisterName(acl.AclName) + c.l2AclIndexes.UnregisterName(acl.AclName) + c.log.Debugf("ACL %s unregistered from L2 mapping", acl.AclName) } if l3l4AclFound { // Remove interfaces. vppACLIndex := agentL3L4AclIndex - 1 if acl.Interfaces != nil { - err = plugin.aclHandler.RemoveIPIngressACLFromInterfaces(vppACLIndex, plugin.getInterfaces(acl.Interfaces.Ingress)) + err = c.aclHandler.RemoveIPIngressACLFromInterfaces(vppACLIndex, c.getInterfaces(acl.Interfaces.Ingress)) if err != nil { - return err + return errors.Errorf("failed to remove IP ingress interfaces from ACL %s: %v", + acl.AclName, err) } - err = plugin.aclHandler.RemoveIPEgressACLFromInterfaces(vppACLIndex, plugin.getInterfaces(acl.Interfaces.Egress)) + err = c.aclHandler.RemoveIPEgressACLFromInterfaces(vppACLIndex, c.getInterfaces(acl.Interfaces.Egress)) if err != nil { - return err + return errors.Errorf("failed to remove IP egress interfaces from ACL %s: %v", + acl.AclName, err) } } // Remove ACL L3/L4. - err := plugin.aclHandler.DeleteIPACL(vppACLIndex) + err := c.aclHandler.DeleteIPACL(vppACLIndex) if err != nil { - return err + return errors.Errorf("failed to remove IP ACL %s: %v", acl.AclName, err) } // Unregister. - plugin.l3l4AclIndexes.UnregisterName(acl.AclName) + c.l3l4AclIndexes.UnregisterName(acl.AclName) + c.log.Debugf("ACL %s unregistered from L3/L4 mapping", acl.AclName) } + c.log.Infof("ACL %s removed", acl.AclName) + return err } // DumpIPACL returns all configured IP ACLs in proto format -func (plugin *ACLConfigurator) DumpIPACL() (acls []*acl.AccessLists_Acl, err error) { - aclsWithIndex, err := plugin.aclHandler.DumpIPACL(plugin.ifIndexes) +func (c *ACLConfigurator) DumpIPACL() (acls []*acl.AccessLists_Acl, err error) { + aclsWithIndex, err := c.aclHandler.DumpIPACL(c.ifIndexes) if err != nil { - plugin.log.Error(err) - return nil, err + return nil, errors.Errorf("failed to dump IP ACLs: %v", err) } for _, aclWithIndex := range aclsWithIndex { acls = append(acls, aclWithIndex.ACL) @@ -353,11 +350,11 @@ func (plugin *ACLConfigurator) DumpIPACL() (acls []*acl.AccessLists_Acl, err err } // DumpMACIPACL returns all configured MACIP ACLs in proto format -func (plugin *ACLConfigurator) DumpMACIPACL() (acls []*acl.AccessLists_Acl, err error) { - aclsWithIndex, err := plugin.aclHandler.DumpMACIPACL(plugin.ifIndexes) +func (c *ACLConfigurator) DumpMACIPACL() (acls []*acl.AccessLists_Acl, err error) { + aclsWithIndex, err := c.aclHandler.DumpMACIPACL(c.ifIndexes) if err != nil { - plugin.log.Error(err) - return nil, err + c.log.Error(err) + return nil, errors.Errorf("failed to dump MAC IP ACLs: %v", err) } for _, aclWithIndex := range aclsWithIndex { acls = append(acls, aclWithIndex.ACL) @@ -366,9 +363,9 @@ func (plugin *ACLConfigurator) DumpMACIPACL() (acls []*acl.AccessLists_Acl, err } // Returns a list of existing ACL interfaces -func (plugin *ACLConfigurator) getInterfaces(interfaces []string) (configurableIfs []uint32) { +func (c *ACLConfigurator) getInterfaces(interfaces []string) (configurableIfs []uint32) { for _, name := range interfaces { - ifIdx, _, found := plugin.ifIndexes.LookupIdx(name) + ifIdx, _, found := c.ifIndexes.LookupIdx(name) if !found { continue } @@ -397,66 +394,52 @@ func diffInterfaces(oldInterfaces, newInterfaces []uint32) (added, removed []uin } // ResolveCreatedInterface configures new interface for every ACL found in cache -func (plugin *ACLConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { - plugin.log.Debugf("ACL configurator: resolving new interface %v", ifName) - +func (c *ACLConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { // Iterate over cache in order to find out where the interface is used - var wasErr error - for entryIdx, aclCacheEntry := range plugin.ifCache { + for entryIdx, aclCacheEntry := range c.ifCache { if aclCacheEntry.ifName == ifName { - var ifIndices []uint32 switch aclCacheEntry.ifAttr { case L2: - if err := plugin.aclHandler.SetMacIPACLToInterface(aclCacheEntry.aclID, append(ifIndices, ifIdx)); err != nil { - plugin.log.Error(err) - wasErr = err + if err := c.aclHandler.SetMacIPACLToInterface(aclCacheEntry.aclID, []uint32{ifIdx}); err != nil { + return errors.Errorf("failed to set MAC IP ACL %v to interface %v: %v", aclCacheEntry.aclID, ifName, err) } case INGRESS: - if err := plugin.aclHandler.SetACLToInterfacesAsIngress(aclCacheEntry.aclID, append(ifIndices, ifIdx)); err != nil { - plugin.log.Error(err) - wasErr = err + if err := c.aclHandler.SetACLToInterfacesAsIngress(aclCacheEntry.aclID, []uint32{ifIdx}); err != nil { + return errors.Errorf("failed to set ACL %v as ingress to interface %v: %v", aclCacheEntry.aclID, ifName, err) } case EGRESS: - if err := plugin.aclHandler.SetACLToInterfacesAsEgress(aclCacheEntry.aclID, append(ifIndices, ifIdx)); err != nil { - plugin.log.Error(err) - wasErr = err + if err := c.aclHandler.SetACLToInterfacesAsEgress(aclCacheEntry.aclID, []uint32{ifIdx}); err != nil { + return errors.Errorf("failed to set ACL %v as egress to interface %v: %v", aclCacheEntry.aclID, ifName, err) } default: - plugin.log.Warnf("ACL interface is not defined as L2, ingress or egress") + return errors.Errorf("ACL %v for interface %v is set as %q and not as L2, ingress or egress", aclCacheEntry.aclID, ifName, aclCacheEntry.ifAttr) } // Remove from cache - plugin.log.Debugf("New interface %s (%s) configured for ACL %d, removed from cache", + c.log.Debugf("New interface %s (%s) configured for ACL %d, removed from cache", ifName, aclCacheEntry.ifAttr, aclCacheEntry.aclID) - plugin.ifCache = append(plugin.ifCache[:entryIdx], plugin.ifCache[entryIdx+1:]...) + c.ifCache = append(c.ifCache[:entryIdx], c.ifCache[entryIdx+1:]...) } } - plugin.log.Debugf("ACL configurator: new interface %v resolution done", ifName) - - return wasErr + return nil } // ResolveDeletedInterface puts removed interface to cache, including acl index. Note: it's not needed to remove ACL // from interface manually, VPP handles it itself and such an behavior would cause errors (ACLs cannot be dumped // from non-existing interface) -func (plugin *ACLConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { - plugin.log.Debugf("ACL configurator: resolving deleted interface %v", ifName) - - var wasErr error - +func (c *ACLConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { // L3/L4 ingress/egress ACLs - for _, aclName := range plugin.l3l4AclIndexes.GetMapping().ListNames() { - aclIdx, aclData, found := plugin.l3l4AclIndexes.LookupIdx(aclName) + for _, aclName := range c.l3l4AclIndexes.GetMapping().ListNames() { + aclIdx, aclData, found := c.l3l4AclIndexes.LookupIdx(aclName) if !found { - plugin.log.Warnf("ACL %v not found in the mapping", aclName) - continue + return errors.Errorf("cannot resolve ACL %s for interface %s, not found in the mapping", aclName, ifName) } vppACLIdx := aclIdx - 1 if ifaces := aclData.GetInterfaces(); ifaces != nil { // Look over ingress interfaces for _, iface := range ifaces.Ingress { if iface == ifName { - plugin.ifCache = append(plugin.ifCache, &ACLIfCacheEntry{ + c.ifCache = append(c.ifCache, &ACLIfCacheEntry{ ifName: ifName, aclID: vppACLIdx, ifAttr: INGRESS, @@ -466,7 +449,7 @@ func (plugin *ACLConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint // Look over egress interfaces for _, iface := range ifaces.Egress { if iface == ifName { - plugin.ifCache = append(plugin.ifCache, &ACLIfCacheEntry{ + c.ifCache = append(c.ifCache, &ACLIfCacheEntry{ ifName: ifName, aclID: vppACLIdx, ifAttr: EGRESS, @@ -476,18 +459,17 @@ func (plugin *ACLConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint } } // L2 ACLs - for _, aclName := range plugin.l2AclIndexes.GetMapping().ListNames() { - aclIdx, aclData, found := plugin.l2AclIndexes.LookupIdx(aclName) + for _, aclName := range c.l2AclIndexes.GetMapping().ListNames() { + aclIdx, aclData, found := c.l2AclIndexes.LookupIdx(aclName) if !found { - plugin.log.Warnf("ACL %v not found in the mapping", aclName) - continue + return errors.Errorf("cannot resolve ACL %s for interface %s, not found in the mapping", aclName, ifName) } vppACLIdx := aclIdx - 1 if ifaces := aclData.GetInterfaces(); ifaces != nil { // Look over ingress interfaces for _, ingressIf := range ifaces.Ingress { if ingressIf == ifName { - plugin.ifCache = append(plugin.ifCache, &ACLIfCacheEntry{ + c.ifCache = append(c.ifCache, &ACLIfCacheEntry{ ifName: ifName, aclID: vppACLIdx, ifAttr: L2, @@ -497,24 +479,22 @@ func (plugin *ACLConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint } } - plugin.log.Debugf("ACL configurator: resolution done for removed interface %v", ifName) - - return wasErr + return nil } // Returns a list of interfaces configurable on the ACL. If interface is missing, put it to the cache. It will be // configured when available -func (plugin *ACLConfigurator) getOrCacheInterfaces(interfaces []string, acl uint32, attr string) (configurableIfs []uint32) { +func (c *ACLConfigurator) getOrCacheInterfaces(interfaces []string, acl uint32, attr string) (configurableIfs []uint32) { for _, name := range interfaces { - ifIdx, _, found := plugin.ifIndexes.LookupIdx(name) + ifIdx, _, found := c.ifIndexes.LookupIdx(name) if !found { // Put interface to cache - plugin.ifCache = append(plugin.ifCache, &ACLIfCacheEntry{ + c.ifCache = append(c.ifCache, &ACLIfCacheEntry{ ifName: name, aclID: acl, ifAttr: attr, }) - plugin.log.Debugf("Interface %s (%s) not found for ACL %v, moving to cache", name, attr, acl) + c.log.Debugf("Interface %s (%s) not found for ACL %s, moving to cache", name, attr, acl) continue } configurableIfs = append(configurableIfs, ifIdx) @@ -525,13 +505,13 @@ func (plugin *ACLConfigurator) getOrCacheInterfaces(interfaces []string, acl uin // Validate rules provided in ACL. Every rule has to contain actions and matches. // Current limitation: L2 and L3/4 have to be split to different ACLs and // there cannot be L2 rules and L3/4 rules in the same ACL. -func (plugin *ACLConfigurator) validateRules(aclName string, rules []*acl.AccessLists_Acl_Rule) ([]*acl.AccessLists_Acl_Rule, bool) { +func (c *ACLConfigurator) validateRules(aclName string, rules []*acl.AccessLists_Acl_Rule) ([]*acl.AccessLists_Acl_Rule, bool) { var validL3L4Rules []*acl.AccessLists_Acl_Rule var validL2Rules []*acl.AccessLists_Acl_Rule for index, rule := range rules { if rule.GetMatch() == nil { - plugin.log.Warnf("Rule %v from acl %v does not contain match", index, aclName) + c.log.Warnf("invalid ACL %s: rule %d does not contain match", aclName, index) continue } if rule.GetMatch().GetIpRule() != nil { @@ -542,7 +522,7 @@ func (plugin *ACLConfigurator) validateRules(aclName string, rules []*acl.Access } } if len(validL3L4Rules) > 0 && len(validL2Rules) > 0 { - plugin.log.Errorf("ACL %v contains even L2 rules and L3/L4 rules. This case is not supported yet, only L3/L4 rules will be resolved", + c.log.Warnf("ACL %s contains L2 rules and L3/L4 rules as well. This case is not supported, only L3/L4 rules will be resolved", aclName) return validL3L4Rules, false } else if len(validL3L4Rules) > 0 { @@ -551,3 +531,12 @@ func (plugin *ACLConfigurator) validateRules(aclName string, rules []*acl.Access return validL2Rules, true } } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *ACLConfigurator) LogError(err error) error { + if err == nil { + return nil + } + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + return err +} diff --git a/plugins/vpp/aclplugin/acl_config_test.go b/plugins/vpp/aclplugin/acl_config_test.go index 80d116e7c8..25c48ae16b 100644 --- a/plugins/vpp/aclplugin/acl_config_test.go +++ b/plugins/vpp/aclplugin/acl_config_test.go @@ -15,8 +15,6 @@ package aclplugin_test import ( - "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" "github.com/ligato/cn-infra/logging" @@ -28,6 +26,7 @@ import ( "github.com/ligato/vpp-agent/plugins/vpp/model/acl" "github.com/ligato/vpp-agent/tests/vppcallmock" . "github.com/onsi/gomega" + "testing" ) var ipAcls = acl.AccessLists_Acl{ @@ -76,16 +75,11 @@ var macipAcls = acl.AccessLists_Acl{ func TestConfigureACL(t *testing.T) { ctx, connection, plugin := aclTestSetup(t, false) defer aclTestTeardown(connection, plugin) - - acl1 := acl.AccessLists_Acl{AclName: "acl1"} - err := plugin.ConfigureACL(&acl1) - Expect(err).To(BeNil()) - // ipAcl Replies ctx.MockVpp.MockReply(&acl_api.ACLAddReplaceReply{}) // Test configure ipAcl - err = plugin.ConfigureACL(&ipAcls) + err := plugin.ConfigureACL(&ipAcls) Expect(err).To(BeNil()) // macipAcl Replies @@ -125,9 +119,9 @@ func TestModifyNonExistingACL(t *testing.T) { // Test modify ipAcl err := plugin.ModifyACL(&ipAcls, &ipAcl) - Expect(err).To(BeNil()) + Expect(err).ToNot(BeNil()) err = plugin.ModifyACL(&macipAcls, &macipAcl) - Expect(err).To(BeNil()) + Expect(err).ToNot(BeNil()) } // Test modification of given acl @@ -396,7 +390,7 @@ func aclTestSetup(t *testing.T, createIfs bool) (*vppcallmock.TestCtx, *core.Con RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -416,7 +410,7 @@ func aclTestSetup(t *testing.T, createIfs bool) (*vppcallmock.TestCtx, *core.Con // Configurator plugin := &aclplugin.ACLConfigurator{} - err = plugin.Init(log, connection, ifIndexes, false) + err = plugin.Init(log, connection, ifIndexes) Expect(err).To(BeNil()) return ctx, connection, plugin diff --git a/plugins/vpp/aclplugin/data_resync.go b/plugins/vpp/aclplugin/data_resync.go index 8cd23f4e01..a70bea71c8 100644 --- a/plugins/vpp/aclplugin/data_resync.go +++ b/plugins/vpp/aclplugin/data_resync.go @@ -15,31 +15,24 @@ package aclplugin import ( + "github.com/go-errors/errors" "github.com/ligato/vpp-agent/plugins/vpp/model/acl" ) // Resync writes ACLs to the empty VPP. -func (plugin *ACLConfigurator) Resync(nbACLs []*acl.AccessLists_Acl) error { - plugin.log.Debug("Resync ACLs started") - // Calculate and log acl resync. - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *ACLConfigurator) Resync(nbACLs []*acl.AccessLists_Acl) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Retrieve existing IpACL config - vppIPACLs, err := plugin.aclHandler.DumpIPACL(plugin.ifIndexes) + vppIPACLs, err := c.aclHandler.DumpIPACL(c.ifIndexes) if err != nil { - return err + return errors.Errorf("ACL resync error: failed to dump IP ACLs: %v", err) } // Retrieve existing MacIpACL config - vppMacIPACLs, err := plugin.aclHandler.DumpMACIPACL(plugin.ifIndexes) + vppMacIPACLs, err := c.aclHandler.DumpMACIPACL(c.ifIndexes) if err != nil { - return err + return errors.Errorf("ACL resync error: failed to dump MAC IP ACLs: %v", err) } // Remove all configured VPP ACLs @@ -52,36 +45,37 @@ func (plugin *ACLConfigurator) Resync(nbACLs []*acl.AccessLists_Acl) error { ipRulesExist := len(vppIPACL.ACL.Rules) > 0 && vppIPACL.ACL.Rules[0].GetMatch().GetIpRule() != nil if ipRulesExist { - if err := plugin.aclHandler.DeleteIPACL(vppIPACL.Meta.Index); err != nil { - plugin.log.Error(err) - return err + if err := c.aclHandler.DeleteIPACL(vppIPACL.Meta.Index); err != nil { + return errors.Errorf("ACL resync error: failed to remove IP ACL %s: %v", vppIPACL.ACL.AclName, err) } // Unregister. - plugin.l3l4AclIndexes.UnregisterName(vppIPACL.ACL.AclName) + c.l3l4AclIndexes.UnregisterName(vppIPACL.ACL.AclName) + c.log.Debugf("ACL %s unregistered from L3/L4 mapping", vppIPACL.ACL.AclName) continue } } for _, vppMacIPACL := range vppMacIPACLs { ipRulesExist := len(vppMacIPACL.ACL.Rules) > 0 && vppMacIPACL.ACL.Rules[0].GetMatch().GetMacipRule() != nil - if ipRulesExist { - if err := plugin.aclHandler.DeleteMacIPACL(vppMacIPACL.Meta.Index); err != nil { - plugin.log.Error(err) - return err + if err := c.aclHandler.DeleteMacIPACL(vppMacIPACL.Meta.Index); err != nil { + return errors.Errorf("ACL resync error: failed to delete MAC IP ACL %s: %v", vppMacIPACL.ACL.AclName, err) } // Unregister. - plugin.l2AclIndexes.UnregisterName(vppMacIPACL.ACL.AclName) + c.l2AclIndexes.UnregisterName(vppMacIPACL.ACL.AclName) + c.log.Debugf("ACL %s unregistered from L2 mapping", vppMacIPACL.ACL.AclName) continue } } // Configure new ACLs for _, nbACL := range nbACLs { - if err := plugin.ConfigureACL(nbACL); err != nil { - plugin.log.Error(err) - return err + if err := c.ConfigureACL(nbACL); err != nil { + c.log.Error(err) + return errors.Errorf("ACL resync error: failed to configure ACL %s: %v", nbACL.AclName, err) } } + c.log.Info("ACL resync done") + return nil } diff --git a/plugins/vpp/aclplugin/vppcalls/acl_vppcalls.go b/plugins/vpp/aclplugin/vppcalls/acl_vppcalls.go index e3cdf6b5d4..aeedab3b75 100644 --- a/plugins/vpp/aclplugin/vppcalls/acl_vppcalls.go +++ b/plugins/vpp/aclplugin/vppcalls/acl_vppcalls.go @@ -18,7 +18,6 @@ import ( "fmt" "net" "strings" - "time" govppapi "git.fd.io/govpp.git/api" aclapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/acl" @@ -40,11 +39,7 @@ func GetACLPluginVersion(ch govppapi.Channel) (string, error) { } // AddIPACL implements ACL handler. -func (handler *ACLVppHandler) AddIPACL(rules []*acl.AccessLists_Acl_Rule, aclName string) (uint32, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(aclapi.ACLAddReplace{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) AddIPACL(rules []*acl.AccessLists_Acl_Rule, aclName string) (uint32, error) { // Prepare Ip rules aclIPRules, err := transformACLIpRules(rules) if err != nil { @@ -62,7 +57,7 @@ func (handler *ACLVppHandler) AddIPACL(rules []*acl.AccessLists_Acl_Rule, aclNam } reply := &aclapi.ACLAddReplaceReply{} - if err = handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err = h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return 0, fmt.Errorf("failed to write ACL %v: %v", aclName, err) } else if reply.Retval != 0 { return 0, fmt.Errorf("%s returned %v while writing ACL %v to VPP", reply.GetMessageName(), reply.Retval, aclName) @@ -72,13 +67,9 @@ func (handler *ACLVppHandler) AddIPACL(rules []*acl.AccessLists_Acl_Rule, aclNam } // AddMacIPACL implements ACL handler. -func (handler *ACLVppHandler) AddMacIPACL(rules []*acl.AccessLists_Acl_Rule, aclName string) (uint32, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(aclapi.MacipACLAdd{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) AddMacIPACL(rules []*acl.AccessLists_Acl_Rule, aclName string) (uint32, error) { // Prepare MAc Ip rules - aclMacIPRules, err := handler.transformACLMacIPRules(rules) + aclMacIPRules, err := h.transformACLMacIPRules(rules) if err != nil { return 0, err } @@ -93,7 +84,7 @@ func (handler *ACLVppHandler) AddMacIPACL(rules []*acl.AccessLists_Acl_Rule, acl } reply := &aclapi.MacipACLAddReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return 0, fmt.Errorf("failed to write ACL %v: %v", aclName, err) } else if reply.Retval != 0 { return 0, fmt.Errorf("%s returned %v while writing ACL %v to VPP", reply.GetMessageName(), reply.Retval, aclName) @@ -103,11 +94,7 @@ func (handler *ACLVppHandler) AddMacIPACL(rules []*acl.AccessLists_Acl_Rule, acl } // ModifyIPACL implements ACL handler. -func (handler *ACLVppHandler) ModifyIPACL(aclIndex uint32, rules []*acl.AccessLists_Acl_Rule, aclName string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(aclapi.ACLAddReplace{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) ModifyIPACL(aclIndex uint32, rules []*acl.AccessLists_Acl_Rule, aclName string) error { // Prepare Ip rules aclIPRules, err := transformACLIpRules(rules) if err != nil { @@ -125,7 +112,7 @@ func (handler *ACLVppHandler) ModifyIPACL(aclIndex uint32, rules []*acl.AccessLi } reply := &aclapi.ACLAddReplaceReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return fmt.Errorf("failed to write ACL %v: %v", aclName, err) } else if reply.Retval != 0 { return fmt.Errorf("%s returned %v while writing ACL %v to VPP", reply.GetMessageName(), reply.Retval, aclName) @@ -135,13 +122,9 @@ func (handler *ACLVppHandler) ModifyIPACL(aclIndex uint32, rules []*acl.AccessLi } // ModifyMACIPACL implements ACL handler. -func (handler *ACLVppHandler) ModifyMACIPACL(aclIndex uint32, rules []*acl.AccessLists_Acl_Rule, aclName string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(aclapi.ACLAddReplace{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) ModifyMACIPACL(aclIndex uint32, rules []*acl.AccessLists_Acl_Rule, aclName string) error { // Prepare MAc Ip rules - aclMacIPRules, err := handler.transformACLMacIPRules(rules) + aclMacIPRules, err := h.transformACLMacIPRules(rules) if err != nil { return err } @@ -157,7 +140,7 @@ func (handler *ACLVppHandler) ModifyMACIPACL(aclIndex uint32, rules []*acl.Acces } reply := &aclapi.MacipACLAddReplaceReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return fmt.Errorf("failed to write ACL %v: %v", aclName, err) } else if reply.Retval != 0 { return fmt.Errorf("%s returned %v while writing ACL %v to VPP", reply.GetMessageName(), reply.Retval, aclName) @@ -167,17 +150,13 @@ func (handler *ACLVppHandler) ModifyMACIPACL(aclIndex uint32, rules []*acl.Acces } // DeleteIPACL implements ACL handler. -func (handler *ACLVppHandler) DeleteIPACL(aclIndex uint32) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(aclapi.ACLDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) DeleteIPACL(aclIndex uint32) error { req := &aclapi.ACLDel{ ACLIndex: aclIndex, } reply := &aclapi.ACLDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return fmt.Errorf("failed to remove L3/L4 ACL %v: %v", aclIndex, err) } else if reply.Retval != 0 { return fmt.Errorf("%s returned %v while removing L3/L4 ACL %v", reply.GetMessageName(), reply.Retval, aclIndex) @@ -187,17 +166,13 @@ func (handler *ACLVppHandler) DeleteIPACL(aclIndex uint32) error { } // DeleteMacIPACL implements ACL handler. -func (handler *ACLVppHandler) DeleteMacIPACL(aclIndex uint32) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(aclapi.MacipACLDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) DeleteMacIPACL(aclIndex uint32) error { req := &aclapi.MacipACLDel{ ACLIndex: aclIndex, } reply := &aclapi.MacipACLDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return fmt.Errorf("failed to remove L2 ACL %v: %v", aclIndex, err) } else if reply.Retval != 0 { return fmt.Errorf("%s returned %v while removing L2 ACL %v", reply.GetMessageName(), reply.Retval, aclIndex) @@ -236,7 +211,7 @@ func transformACLIpRules(rules []*acl.AccessLists_Acl_Rule) (aclIPRules []aclapi return aclIPRules, nil } -func (handler *ACLVppHandler) transformACLMacIPRules(rules []*acl.AccessLists_Acl_Rule) (aclMacIPRules []aclapi.MacipACLRule, err error) { +func (h *ACLVppHandler) transformACLMacIPRules(rules []*acl.AccessLists_Acl_Rule) (aclMacIPRules []aclapi.MacipACLRule, err error) { for _, rule := range rules { aclMacIPRule := &aclapi.MacipACLRule{ IsPermit: uint8(rule.AclAction), diff --git a/plugins/vpp/aclplugin/vppcalls/acl_vppcalls_test.go b/plugins/vpp/aclplugin/vppcalls/acl_vppcalls_test.go index 65b12d4f15..9b5402f38c 100644 --- a/plugins/vpp/aclplugin/vppcalls/acl_vppcalls_test.go +++ b/plugins/vpp/aclplugin/vppcalls/acl_vppcalls_test.go @@ -23,7 +23,7 @@ import ( . "github.com/onsi/gomega" ) -var aclNoRules = []*acl.AccessLists_Acl_Rule{} +var aclNoRules []*acl.AccessLists_Acl_Rule var aclErr1Rules = []*acl.AccessLists_Acl_Rule{ { @@ -257,7 +257,7 @@ func TestAddIPAcl(t *testing.T) { defer ctx.TeardownTestCtx() ctx.MockVpp.MockReply(&acl_api.ACLAddReplaceReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) aclIndex, err := aclHandler.AddIPACL(aclIPrules, "test0") Expect(err).To(BeNil()) @@ -290,7 +290,7 @@ func TestAddMacIPAcl(t *testing.T) { defer ctx.TeardownTestCtx() ctx.MockVpp.MockReply(&acl_api.MacipACLAddReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) aclIndex, err := aclHandler.AddMacIPACL(aclMACIPrules, "test6") Expect(err).To(BeNil()) @@ -324,7 +324,7 @@ func TestDeleteIPAcl(t *testing.T) { defer ctx.TeardownTestCtx() ctx.MockVpp.MockReply(&acl_api.ACLAddReplaceReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) aclIndex, err := aclHandler.AddIPACL(aclIPrules, "test_del0") Expect(err).To(BeNil()) @@ -369,7 +369,7 @@ func TestDeleteMACIPAcl(t *testing.T) { defer ctx.TeardownTestCtx() ctx.MockVpp.MockReply(&acl_api.MacipACLAddReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) aclIndex, err := aclHandler.AddMacIPACL(aclMACIPrules, "test_del2") Expect(err).To(BeNil()) @@ -414,7 +414,7 @@ func TestModifyIPAcl(t *testing.T) { defer ctx.TeardownTestCtx() ctx.MockVpp.MockReply(&acl_api.ACLAddReplaceReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) aclIndex, err := aclHandler.AddIPACL(aclIPrules, "test_modify") Expect(err).To(BeNil()) @@ -472,7 +472,7 @@ func TestModifyMACIPAcl(t *testing.T) { defer ctx.TeardownTestCtx() ctx.MockVpp.MockReply(&acl_api.MacipACLAddReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) aclIndex, err := aclHandler.AddMacIPACL(aclMACIPrules, "test_modify") Expect(err).To(BeNil()) diff --git a/plugins/vpp/aclplugin/vppcalls/api_vppcalls.go b/plugins/vpp/aclplugin/vppcalls/api_vppcalls.go index d6c37178b4..e7ca4e933e 100644 --- a/plugins/vpp/aclplugin/vppcalls/api_vppcalls.go +++ b/plugins/vpp/aclplugin/vppcalls/api_vppcalls.go @@ -16,7 +16,6 @@ package vppcalls import ( govppapi "git.fd.io/govpp.git/api" - "github.com/ligato/cn-infra/logging/measure" aclapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/acl" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/vpp/model/acl" @@ -84,16 +83,14 @@ type ACLVppRead interface { // ACLVppHandler is accessor for acl-related vppcalls methods type ACLVppHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel dumpChannel govppapi.Channel } // NewACLVppHandler creates new instance of acl vppcalls handler -func NewACLVppHandler(callsChan, dumpChan govppapi.Channel, stopwatch *measure.Stopwatch) *ACLVppHandler { +func NewACLVppHandler(callsChan, dumpChan govppapi.Channel) *ACLVppHandler { return &ACLVppHandler{ callsChannel: callsChan, dumpChannel: dumpChan, - stopwatch: stopwatch, } } diff --git a/plugins/vpp/aclplugin/vppcalls/dump_vppcalls.go b/plugins/vpp/aclplugin/vppcalls/dump_vppcalls.go index c94ec1737e..d2efadd95b 100644 --- a/plugins/vpp/aclplugin/vppcalls/dump_vppcalls.go +++ b/plugins/vpp/aclplugin/vppcalls/dump_vppcalls.go @@ -18,7 +18,6 @@ import ( "bytes" "fmt" "net" - "time" "github.com/ligato/cn-infra/logging/logrus" acl_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/acl" @@ -55,11 +54,11 @@ type ACLToInterface struct { } // DumpIPACL implements ACL handler. -func (handler *ACLVppHandler) DumpIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*ACLDetails, error) { +func (h *ACLVppHandler) DumpIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*ACLDetails, error) { ruleIPData := make(map[ACLMeta][]*acl.AccessLists_Acl_Rule) // get all ACLs with IP ruleData - IPRuleACLs, err := handler.DumpIPAcls() + IPRuleACLs, err := h.DumpIPAcls() if len(IPRuleACLs) < 1 || err != nil { return nil, err } @@ -72,7 +71,7 @@ func (handler *ACLVppHandler) DumpIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*ACLD if len(IPRules) > 0 { for _, IPRule := range IPRules { - ruleDetails, err := handler.getIPRuleDetails(IPRule) + ruleDetails, err := h.getIPRuleDetails(IPRule) if err != nil { return nil, fmt.Errorf("failed to get IP Rule %v details: %v", IPRule, err) } @@ -89,7 +88,7 @@ func (handler *ACLVppHandler) DumpIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*ACLD } // Get all ACL indices with ingress and egress interfaces - interfaceData, err := handler.DumpIPACLInterfaces(indices, swIfIndices) + interfaceData, err := h.DumpIPACLInterfaces(indices, swIfIndices) if err != nil { return nil, err } @@ -114,11 +113,11 @@ func (handler *ACLVppHandler) DumpIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*ACLD } // DumpMACIPACL implements ACL handler. -func (handler *ACLVppHandler) DumpMACIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*ACLDetails, error) { +func (h *ACLVppHandler) DumpMACIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*ACLDetails, error) { ruleMACIPData := make(map[ACLMeta][]*acl.AccessLists_Acl_Rule) // get all ACLs with MACIP ruleData - MACIPRuleACLs, err := handler.DumpMacIPAcls() + MACIPRuleACLs, err := h.DumpMacIPAcls() if len(MACIPRuleACLs) < 1 || err != nil { return nil, err } @@ -130,7 +129,7 @@ func (handler *ACLVppHandler) DumpMACIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*A if len(MACIPRules) > 0 { for _, MACIPRule := range MACIPRules { - ruleDetails, err := handler.getMACIPRuleDetails(MACIPRule) + ruleDetails, err := h.getMACIPRuleDetails(MACIPRule) if err != nil { return nil, fmt.Errorf("failed to get MACIP Rule %v details: %v", MACIPRule, err) } @@ -147,7 +146,7 @@ func (handler *ACLVppHandler) DumpMACIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*A } // Get all ACL indices with ingress and egress interfaces - interfaceData, err := handler.DumpMACIPACLInterfaces(indices, swIfIndices) + interfaceData, err := h.DumpMACIPACLInterfaces(indices, swIfIndices) if err != nil { return nil, err } @@ -171,11 +170,7 @@ func (handler *ACLVppHandler) DumpMACIPACL(swIfIndices ifaceidx.SwIfIndex) ([]*A } // DumpIPACLInterfaces implements ACL handler. -func (handler *ACLVppHandler) DumpIPACLInterfaces(indices []uint32, swIfIndices ifaceidx.SwIfIndex) (map[uint32]*acl.AccessLists_Acl_Interfaces, error) { - defer func(start time.Time) { - handler.stopwatch.TimeLog(&acl_api.ACLInterfaceListDump{}).LogTimeEntry(time.Since(start)) - }(time.Now()) - +func (h *ACLVppHandler) DumpIPACLInterfaces(indices []uint32, swIfIndices ifaceidx.SwIfIndex) (map[uint32]*acl.AccessLists_Acl_Interfaces, error) { // list of ACL-to-interfaces aclsWithInterfaces := make(map[uint32]*acl.AccessLists_Acl_Interfaces) if swIfIndices == nil { @@ -188,7 +183,7 @@ func (handler *ACLVppHandler) DumpIPACLInterfaces(indices []uint32, swIfIndices msgIP := &acl_api.ACLInterfaceListDump{ SwIfIndex: 0xffffffff, // dump all } - reqIP := handler.dumpChannel.SendMultiRequest(msgIP) + reqIP := h.dumpChannel.SendMultiRequest(msgIP) for { replyIP := &acl_api.ACLInterfaceListDetails{} stop, err := reqIP.ReceiveReply(replyIP) @@ -251,11 +246,7 @@ func (handler *ACLVppHandler) DumpIPACLInterfaces(indices []uint32, swIfIndices } // DumpMACIPACLInterfaces implements ACL handler. -func (handler *ACLVppHandler) DumpMACIPACLInterfaces(indices []uint32, swIfIndices ifaceidx.SwIfIndex) (map[uint32]*acl.AccessLists_Acl_Interfaces, error) { - defer func(start time.Time) { - handler.stopwatch.TimeLog(acl_api.ACLInterfaceListDump{}).LogTimeEntry(time.Since(start)) - }(time.Now()) - +func (h *ACLVppHandler) DumpMACIPACLInterfaces(indices []uint32, swIfIndices ifaceidx.SwIfIndex) (map[uint32]*acl.AccessLists_Acl_Interfaces, error) { // list of ACL-to-interfaces aclsWithInterfaces := make(map[uint32]*acl.AccessLists_Acl_Interfaces) if swIfIndices == nil { @@ -268,7 +259,7 @@ func (handler *ACLVppHandler) DumpMACIPACLInterfaces(indices []uint32, swIfIndic msgMACIP := &acl_api.MacipACLInterfaceListDump{ SwIfIndex: 0xffffffff, // dump all } - reqMACIP := handler.dumpChannel.SendMultiRequest(msgMACIP) + reqMACIP := h.dumpChannel.SendMultiRequest(msgMACIP) for { replyMACIP := &acl_api.MacipACLInterfaceListDetails{} stop, err := reqMACIP.ReceiveReply(replyMACIP) @@ -313,18 +304,14 @@ func (handler *ACLVppHandler) DumpMACIPACLInterfaces(indices []uint32, swIfIndic } // DumpIPAcls implements ACL handler. -func (handler *ACLVppHandler) DumpIPAcls() (map[ACLMeta][]acl_api.ACLRule, error) { - defer func(start time.Time) { - handler.stopwatch.TimeLog(acl_api.ACLDump{}).LogTimeEntry(time.Since(start)) - }(time.Now()) - +func (h *ACLVppHandler) DumpIPAcls() (map[ACLMeta][]acl_api.ACLRule, error) { aclIPRules := make(map[ACLMeta][]acl_api.ACLRule) var wasErr error req := &acl_api.ACLDump{ ACLIndex: 0xffffffff, } - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &acl_api.ACLDetails{} stop, err := reqContext.ReceiveReply(msg) @@ -347,18 +334,14 @@ func (handler *ACLVppHandler) DumpIPAcls() (map[ACLMeta][]acl_api.ACLRule, error } // DumpMacIPAcls implements ACL handler. -func (handler *ACLVppHandler) DumpMacIPAcls() (map[ACLMeta][]acl_api.MacipACLRule, error) { - defer func(start time.Time) { - handler.stopwatch.TimeLog(acl_api.MacipACLDump{}).LogTimeEntry(time.Since(start)) - }(time.Now()) - +func (h *ACLVppHandler) DumpMacIPAcls() (map[ACLMeta][]acl_api.MacipACLRule, error) { aclMACIPRules := make(map[ACLMeta][]acl_api.MacipACLRule) var wasErr error req := &acl_api.MacipACLDump{ ACLIndex: 0xffffffff, } - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &acl_api.MacipACLDetails{} stop, err := reqContext.ReceiveReply(msg) @@ -380,12 +363,12 @@ func (handler *ACLVppHandler) DumpMacIPAcls() (map[ACLMeta][]acl_api.MacipACLRul } // DumpInterfaceIPAcls implements ACL handler. -func (handler *ACLVppHandler) DumpInterfaceIPAcls(swIndex uint32) (acl.AccessLists, error) { +func (h *ACLVppHandler) DumpInterfaceIPAcls(swIndex uint32) (acl.AccessLists, error) { allACLs := acl.AccessLists{ Acls: []*acl.AccessLists_Acl{}, } - res, err := handler.DumpInterfaceIPACLs(swIndex) + res, err := h.DumpInterfaceIPACLs(swIndex) if err != nil { return allACLs, err } @@ -395,7 +378,7 @@ func (handler *ACLVppHandler) DumpInterfaceIPAcls(swIndex uint32) (acl.AccessLis } for aidx := range res.Acls { - ipACL, err := handler.getIPACLDetails(uint32(aidx)) + ipACL, err := h.getIPACLDetails(uint32(aidx)) if err != nil { return allACLs, err } @@ -405,12 +388,12 @@ func (handler *ACLVppHandler) DumpInterfaceIPAcls(swIndex uint32) (acl.AccessLis } // DumpInterfaceMACIPAcls implements ACL handler. -func (handler *ACLVppHandler) DumpInterfaceMACIPAcls(swIndex uint32) (acl.AccessLists, error) { +func (h *ACLVppHandler) DumpInterfaceMACIPAcls(swIndex uint32) (acl.AccessLists, error) { allACLs := acl.AccessLists{ Acls: []*acl.AccessLists_Acl{}, } - resMacIP, err := handler.DumpInterfaceMACIPACLs(swIndex) + resMacIP, err := h.DumpInterfaceMACIPACLs(swIndex) if err != nil { return allACLs, err } @@ -420,7 +403,7 @@ func (handler *ACLVppHandler) DumpInterfaceMACIPAcls(swIndex uint32) (acl.Access } for aidx := range resMacIP.Acls { - macipACL, err := handler.getMACIPACLDetails(uint32(aidx)) + macipACL, err := h.getMACIPACLDetails(uint32(aidx)) if err != nil { return allACLs, err } @@ -430,17 +413,13 @@ func (handler *ACLVppHandler) DumpInterfaceMACIPAcls(swIndex uint32) (acl.Access } // DumpInterfaceIPACLs implements ACL handler. -func (handler *ACLVppHandler) DumpInterfaceIPACLs(swIndex uint32) (*acl_api.ACLInterfaceListDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(acl_api.ACLInterfaceListDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) DumpInterfaceIPACLs(swIndex uint32) (*acl_api.ACLInterfaceListDetails, error) { req := &acl_api.ACLInterfaceListDump{ SwIfIndex: swIndex, } reply := &acl_api.ACLInterfaceListDetails{} - if err := handler.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { return nil, err } @@ -448,17 +427,13 @@ func (handler *ACLVppHandler) DumpInterfaceIPACLs(swIndex uint32) (*acl_api.ACLI } // DumpInterfaceMACIPACLs implements ACL handler. -func (handler *ACLVppHandler) DumpInterfaceMACIPACLs(swIndex uint32) (*acl_api.MacipACLInterfaceListDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(acl_api.MacipACLInterfaceListDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) DumpInterfaceMACIPACLs(swIndex uint32) (*acl_api.MacipACLInterfaceListDetails, error) { req := &acl_api.MacipACLInterfaceListDump{ SwIfIndex: swIndex, } reply := &acl_api.MacipACLInterfaceListDetails{} - if err := handler.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { return nil, err } @@ -466,16 +441,12 @@ func (handler *ACLVppHandler) DumpInterfaceMACIPACLs(swIndex uint32) (*acl_api.M } // DumpInterfaces implements ACL handler. -func (handler *ACLVppHandler) DumpInterfaces() ([]*acl_api.ACLInterfaceListDetails, []*acl_api.MacipACLInterfaceListDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(acl_api.ACLInterfaceListDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ACLVppHandler) DumpInterfaces() ([]*acl_api.ACLInterfaceListDetails, []*acl_api.MacipACLInterfaceListDetails, error) { msgIPACL := &acl_api.ACLInterfaceListDump{ SwIfIndex: 0xffffffff, // dump all } - reqIPACL := handler.dumpChannel.SendMultiRequest(msgIPACL) + reqIPACL := h.dumpChannel.SendMultiRequest(msgIPACL) var IPaclInterfaces []*acl_api.ACLInterfaceListDetails for { @@ -495,7 +466,7 @@ func (handler *ACLVppHandler) DumpInterfaces() ([]*acl_api.ACLInterfaceListDetai SwIfIndex: 0xffffffff, // dump all } - reqMACIPACL := handler.dumpChannel.SendMultiRequest(msgMACIPACL) + reqMACIPACL := h.dumpChannel.SendMultiRequest(msgMACIPACL) var MACIPaclInterfaces []*acl_api.MacipACLInterfaceListDetails for { @@ -514,16 +485,16 @@ func (handler *ACLVppHandler) DumpInterfaces() ([]*acl_api.ACLInterfaceListDetai return IPaclInterfaces, MACIPaclInterfaces, nil } -func (handler *ACLVppHandler) getIPRuleDetails(rule acl_api.ACLRule) (*acl.AccessLists_Acl_Rule, error) { +func (h *ACLVppHandler) getIPRuleDetails(rule acl_api.ACLRule) (*acl.AccessLists_Acl_Rule, error) { // Resolve rule actions - aclAction, err := handler.resolveRuleAction(rule.IsPermit) + aclAction, err := h.resolveRuleAction(rule.IsPermit) if err != nil { return nil, err } // Resolve rule matches match := &acl.AccessLists_Acl_Rule_Match{ - IpRule: handler.getIPRuleMatches(rule), + IpRule: h.getIPRuleMatches(rule), } return &acl.AccessLists_Acl_Rule{ @@ -534,13 +505,13 @@ func (handler *ACLVppHandler) getIPRuleDetails(rule acl_api.ACLRule) (*acl.Acces // getIPACLDetails gets details for a given IP ACL from VPP and translates // them from the binary VPP API format into the ACL Plugin's NB format. -func (handler *ACLVppHandler) getIPACLDetails(idx uint32) (aclRule *acl.AccessLists_Acl, err error) { +func (h *ACLVppHandler) getIPACLDetails(idx uint32) (aclRule *acl.AccessLists_Acl, err error) { req := &acl_api.ACLDump{ ACLIndex: uint32(idx), } reply := &acl_api.ACLDetails{} - if err := handler.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { return nil, err } @@ -548,13 +519,13 @@ func (handler *ACLVppHandler) getIPACLDetails(idx uint32) (aclRule *acl.AccessLi for _, r := range reply.R { rule := &acl.AccessLists_Acl_Rule{} - ipRule, _ := handler.getIPRuleDetails(r) + ipRule, _ := h.getIPRuleDetails(r) match := &acl.AccessLists_Acl_Rule_Match{ IpRule: ipRule.GetMatch().GetIpRule(), } - aclAction, err := handler.resolveRuleAction(r.IsPermit) + aclAction, err := h.resolveRuleAction(r.IsPermit) if err != nil { return nil, err } @@ -567,16 +538,16 @@ func (handler *ACLVppHandler) getIPACLDetails(idx uint32) (aclRule *acl.AccessLi return &acl.AccessLists_Acl{Rules: ruleData, AclName: string(bytes.SplitN(reply.Tag, []byte{0x00}, 2)[0])}, nil } -func (handler *ACLVppHandler) getMACIPRuleDetails(rule acl_api.MacipACLRule) (*acl.AccessLists_Acl_Rule, error) { +func (h *ACLVppHandler) getMACIPRuleDetails(rule acl_api.MacipACLRule) (*acl.AccessLists_Acl_Rule, error) { // Resolve rule actions - aclAction, err := handler.resolveRuleAction(rule.IsPermit) + aclAction, err := h.resolveRuleAction(rule.IsPermit) if err != nil { return nil, err } // Resolve rule matches match := &acl.AccessLists_Acl_Rule_Match{ - MacipRule: handler.getMACIPRuleMatches(rule), + MacipRule: h.getMACIPRuleMatches(rule), } return &acl.AccessLists_Acl_Rule{ @@ -587,13 +558,13 @@ func (handler *ACLVppHandler) getMACIPRuleDetails(rule acl_api.MacipACLRule) (*a // getMACIPACLDetails gets details for a given MACIP ACL from VPP and translates // them from the binary VPP API format into the ACL Plugin's NB format. -func (handler *ACLVppHandler) getMACIPACLDetails(idx uint32) (aclRule *acl.AccessLists_Acl, err error) { +func (h *ACLVppHandler) getMACIPACLDetails(idx uint32) (aclRule *acl.AccessLists_Acl, err error) { req := &acl_api.MacipACLDump{ ACLIndex: uint32(idx), } reply := &acl_api.MacipACLDetails{} - if err := handler.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { return nil, err } @@ -601,13 +572,13 @@ func (handler *ACLVppHandler) getMACIPACLDetails(idx uint32) (aclRule *acl.Acces for _, r := range reply.R { rule := &acl.AccessLists_Acl_Rule{} - ipRule, _ := handler.getMACIPRuleDetails(r) + ipRule, _ := h.getMACIPRuleDetails(r) match := &acl.AccessLists_Acl_Rule_Match{ IpRule: ipRule.GetMatch().GetIpRule(), } - aclAction, err := handler.resolveRuleAction(r.IsPermit) + aclAction, err := h.resolveRuleAction(r.IsPermit) if err != nil { return nil, err } @@ -622,7 +593,7 @@ func (handler *ACLVppHandler) getMACIPACLDetails(idx uint32) (aclRule *acl.Acces // getIPRuleMatches translates an IP rule from the binary VPP API format into the // ACL Plugin's NB format -func (handler *ACLVppHandler) getIPRuleMatches(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule { +func (h *ACLVppHandler) getIPRuleMatches(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule { var srcIP, dstIP string if r.IsIPv6 == 1 { srcIP = net.IP(r.SrcIPAddr).To16().String() @@ -641,18 +612,18 @@ func (handler *ACLVppHandler) getIPRuleMatches(r acl_api.ACLRule) *acl.AccessLis switch r.Proto { case TCPProto: - ipRule.Tcp = handler.getTCPMatchRule(r) + ipRule.Tcp = h.getTCPMatchRule(r) case UDPProto: - ipRule.Udp = handler.getUDPMatchRule(r) + ipRule.Udp = h.getUDPMatchRule(r) case ICMPv4Proto, ICMPv6Proto: - ipRule.Icmp = handler.getIcmpMatchRule(r) + ipRule.Icmp = h.getIcmpMatchRule(r) } return ipRule } // getMACIPRuleMatches translates an MACIP rule from the binary VPP API format into the // ACL Plugin's NB format -func (handler *ACLVppHandler) getMACIPRuleMatches(rule acl_api.MacipACLRule) *acl.AccessLists_Acl_Rule_Match_MacIpRule { +func (h *ACLVppHandler) getMACIPRuleMatches(rule acl_api.MacipACLRule) *acl.AccessLists_Acl_Rule_Match_MacIpRule { var srcAddr string if rule.IsIPv6 == 1 { srcAddr = net.IP(rule.SrcIPAddr).To16().String() @@ -669,7 +640,7 @@ func (handler *ACLVppHandler) getMACIPRuleMatches(rule acl_api.MacipACLRule) *ac // getTCPMatchRule translates a TCP match rule from the binary VPP API format // into the ACL Plugin's NB format -func (handler *ACLVppHandler) getTCPMatchRule(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule_Tcp { +func (h *ACLVppHandler) getTCPMatchRule(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule_Tcp { dstPortRange := &acl.AccessLists_Acl_Rule_Match_IpRule_PortRange{ LowerPort: uint32(r.DstportOrIcmpcodeFirst), UpperPort: uint32(r.DstportOrIcmpcodeLast), @@ -689,7 +660,7 @@ func (handler *ACLVppHandler) getTCPMatchRule(r acl_api.ACLRule) *acl.AccessList // getUDPMatchRule translates a UDP match rule from the binary VPP API format // into the ACL Plugin's NB format -func (handler *ACLVppHandler) getUDPMatchRule(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule_Udp { +func (h *ACLVppHandler) getUDPMatchRule(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule_Udp { dstPortRange := &acl.AccessLists_Acl_Rule_Match_IpRule_PortRange{ LowerPort: uint32(r.DstportOrIcmpcodeFirst), UpperPort: uint32(r.DstportOrIcmpcodeLast), @@ -707,7 +678,7 @@ func (handler *ACLVppHandler) getUDPMatchRule(r acl_api.ACLRule) *acl.AccessList // getIcmpMatchRule translates an ICMP match rule from the binary VPP API // format into the ACL Plugin's NB format -func (handler *ACLVppHandler) getIcmpMatchRule(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule_Icmp { +func (h *ACLVppHandler) getIcmpMatchRule(r acl_api.ACLRule) *acl.AccessLists_Acl_Rule_Match_IpRule_Icmp { icmp := &acl.AccessLists_Acl_Rule_Match_IpRule_Icmp{ Icmpv6: r.IsIPv6 > 0, IcmpCodeRange: &acl.AccessLists_Acl_Rule_Match_IpRule_Icmp_Range{}, @@ -717,7 +688,7 @@ func (handler *ACLVppHandler) getIcmpMatchRule(r acl_api.ACLRule) *acl.AccessLis } // Returns rule action representation in model according to the vpp input -func (handler *ACLVppHandler) resolveRuleAction(isPermit uint8) (acl.AclAction, error) { +func (h *ACLVppHandler) resolveRuleAction(isPermit uint8) (acl.AclAction, error) { switch isPermit { case 0: return acl.AclAction_DENY, nil diff --git a/plugins/vpp/aclplugin/vppcalls/dump_vppcalls_test.go b/plugins/vpp/aclplugin/vppcalls/dump_vppcalls_test.go index fc588c2138..252a5c49f3 100644 --- a/plugins/vpp/aclplugin/vppcalls/dump_vppcalls_test.go +++ b/plugins/vpp/aclplugin/vppcalls/dump_vppcalls_test.go @@ -30,7 +30,7 @@ import ( func TestGetIPRuleMatch(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) defer ctx.TeardownTestCtx() - aclHandler := NewACLVppHandler(ctx.MockChannel, nil, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, nil) icmpV4Rule := aclHandler.getIPRuleMatches(acl_api.ACLRule{ SrcIPAddr: []byte{10, 0, 0, 1}, @@ -82,7 +82,7 @@ func TestGetIPRuleMatch(t *testing.T) { func TestGetMACIPRuleMatches(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) defer ctx.TeardownTestCtx() - aclHandler := NewACLVppHandler(ctx.MockChannel, nil, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, nil) macipV4Rule := aclHandler.getMACIPRuleMatches(acl_api.MacipACLRule{ IsPermit: 1, @@ -140,7 +140,7 @@ func TestDumpIPACL(t *testing.T) { }) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "test", nil)) swIfIndexes.RegisterName("if0", 1, nil) @@ -186,7 +186,7 @@ func TestDumpMACIPACL(t *testing.T) { }) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "test", nil)) swIfIndexes.RegisterName("if0", 1, nil) @@ -213,7 +213,7 @@ func TestDumpACLInterfaces(t *testing.T) { }) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "test", nil)) swIfIndexes.RegisterName("if0", 1, nil) @@ -238,7 +238,7 @@ func TestDumpMACIPACLInterfaces(t *testing.T) { }) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "test-sw_if_indexes", ifaceidx.IndexMetadata)) swIfIndexes.RegisterName("if0", 1, nil) @@ -265,7 +265,7 @@ func TestDumpIPAcls(t *testing.T) { }) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) IPRuleACLs, err := aclHandler.DumpIPAcls() Expect(err).To(Succeed()) @@ -284,7 +284,7 @@ func TestDumpMacIPAcls(t *testing.T) { }) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) MacIPRuleACLs, err := aclHandler.DumpMacIPAcls() Expect(err).To(Succeed()) @@ -312,7 +312,7 @@ func TestDumpInterfaceIPAcls(t *testing.T) { R: []acl_api.ACLRule{{IsPermit: 2}, {IsPermit: 0}}, }) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) ACLs, err := aclHandler.DumpInterfaceIPAcls(0) Expect(err).To(Succeed()) @@ -339,7 +339,7 @@ func TestDumpInterfaceMACIPAcls(t *testing.T) { R: []acl_api.MacipACLRule{{IsPermit: 2}, {IsPermit: 1}}, }) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) ACLs, err := aclHandler.DumpInterfaceMACIPAcls(0) Expect(err).To(Succeed()) @@ -350,7 +350,7 @@ func TestDumpInterface(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) defer ctx.TeardownTestCtx() - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) ctx.MockVpp.MockReply(&acl_api.ACLInterfaceListDetails{ SwIfIndex: 0, @@ -418,7 +418,7 @@ func TestDumpInterfaces(t *testing.T) { }) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) IPacls, MACIPacls, err := aclHandler.DumpInterfaces() Expect(err).To(BeNil()) diff --git a/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls.go b/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls.go index bc69d12056..5188a7a342 100644 --- a/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls.go +++ b/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls.go @@ -16,9 +16,7 @@ package vppcalls import ( "fmt" - "time" - "github.com/ligato/cn-infra/logging/measure" acl_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/acl" ) @@ -30,8 +28,8 @@ type ACLInterfaceLogicalReq struct { } // SetACLToInterfacesAsIngress implements ACL handler. -func (handler *ACLVppHandler) SetACLToInterfacesAsIngress(ACLIndex uint32, ifIndices []uint32) error { - return handler.requestSetACLToInterfaces(&ACLInterfaceLogicalReq{ +func (h *ACLVppHandler) SetACLToInterfacesAsIngress(ACLIndex uint32, ifIndices []uint32) error { + return h.requestSetACLToInterfaces(&ACLInterfaceLogicalReq{ aclIndex: ACLIndex, ifIndices: ifIndices, ingress: true, @@ -39,8 +37,8 @@ func (handler *ACLVppHandler) SetACLToInterfacesAsIngress(ACLIndex uint32, ifInd } // RemoveIPIngressACLFromInterfaces implements ACL handler. -func (handler *ACLVppHandler) RemoveIPIngressACLFromInterfaces(ACLIndex uint32, ifIndices []uint32) error { - return handler.requestRemoveInterfacesFromACL(&ACLInterfaceLogicalReq{ +func (h *ACLVppHandler) RemoveIPIngressACLFromInterfaces(ACLIndex uint32, ifIndices []uint32) error { + return h.requestRemoveInterfacesFromACL(&ACLInterfaceLogicalReq{ aclIndex: ACLIndex, ifIndices: ifIndices, ingress: true, @@ -48,8 +46,8 @@ func (handler *ACLVppHandler) RemoveIPIngressACLFromInterfaces(ACLIndex uint32, } // SetACLToInterfacesAsEgress implements ACL handler. -func (handler *ACLVppHandler) SetACLToInterfacesAsEgress(ACLIndex uint32, ifIndices []uint32) error { - return handler.requestSetACLToInterfaces(&ACLInterfaceLogicalReq{ +func (h *ACLVppHandler) SetACLToInterfacesAsEgress(ACLIndex uint32, ifIndices []uint32) error { + return h.requestSetACLToInterfaces(&ACLInterfaceLogicalReq{ aclIndex: ACLIndex, ifIndices: ifIndices, ingress: false, @@ -57,8 +55,8 @@ func (handler *ACLVppHandler) SetACLToInterfacesAsEgress(ACLIndex uint32, ifIndi } // RemoveIPEgressACLFromInterfaces implements ACL handler. -func (handler *ACLVppHandler) RemoveIPEgressACLFromInterfaces(ACLIndex uint32, ifIndices []uint32) error { - return handler.requestRemoveInterfacesFromACL(&ACLInterfaceLogicalReq{ +func (h *ACLVppHandler) RemoveIPEgressACLFromInterfaces(ACLIndex uint32, ifIndices []uint32) error { + return h.requestRemoveInterfacesFromACL(&ACLInterfaceLogicalReq{ aclIndex: ACLIndex, ifIndices: ifIndices, ingress: false, @@ -66,12 +64,8 @@ func (handler *ACLVppHandler) RemoveIPEgressACLFromInterfaces(ACLIndex uint32, i } // SetMacIPACLToInterface implements ACL handler. -func (handler *ACLVppHandler) SetMacIPACLToInterface(aclIndex uint32, ifIndices []uint32) error { - setACLStopwatch := measure.GetTimeLog(acl_api.MacipACLInterfaceAddDel{}, handler.stopwatch) +func (h *ACLVppHandler) SetMacIPACLToInterface(aclIndex uint32, ifIndices []uint32) error { for _, ingressIfIdx := range ifIndices { - // Measure MacipACLInterfaceAddDel time - start := time.Now() - req := &acl_api.MacipACLInterfaceAddDel{ ACLIndex: aclIndex, IsAdd: 1, @@ -80,30 +74,21 @@ func (handler *ACLVppHandler) SetMacIPACLToInterface(aclIndex uint32, ifIndices reply := &acl_api.MacipACLInterfaceAddDelReply{} - err := handler.callsChannel.SendRequest(req).ReceiveReply(reply) + err := h.callsChannel.SendRequest(req).ReceiveReply(reply) if err != nil { return fmt.Errorf("failed to set interface %d to L2 ACL %d: %v", ingressIfIdx, aclIndex, err) } if reply.Retval != 0 { return fmt.Errorf("set interface %d to L2 ACL %d returned %d", ingressIfIdx, aclIndex, reply.Retval) } - - // Log MacipACLInterfaceAddDel time measurement results. - if setACLStopwatch != nil { - setACLStopwatch.LogTimeEntry(time.Since(start)) - } } return nil } // RemoveMacIPIngressACLFromInterfaces implements ACL handler. -func (handler *ACLVppHandler) RemoveMacIPIngressACLFromInterfaces(removedACLIndex uint32, ifIndices []uint32) error { - setACLStopwatch := measure.GetTimeLog(acl_api.MacipACLInterfaceAddDel{}, handler.stopwatch) +func (h *ACLVppHandler) RemoveMacIPIngressACLFromInterfaces(removedACLIndex uint32, ifIndices []uint32) error { for _, ifIdx := range ifIndices { - // Measure MacipACLInterfaceAddDel time. - start := time.Now() - req := &acl_api.MacipACLInterfaceAddDel{ ACLIndex: removedACLIndex, SwIfIndex: ifIdx, @@ -112,30 +97,24 @@ func (handler *ACLVppHandler) RemoveMacIPIngressACLFromInterfaces(removedACLInde reply := &acl_api.MacipACLInterfaceAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return fmt.Errorf("failed to remove L2 ACL %d from interface %d: %v", removedACLIndex, ifIdx, err) } if reply.Retval != 0 { return fmt.Errorf("remove L2 ACL %d from interface %d returned error %d", removedACLIndex, removedACLIndex, reply.Retval) } - - // Log MacipACLInterfaceAddDel time measurement results. - if setACLStopwatch != nil { - setACLStopwatch.LogTimeEntry(time.Since(start)) - } } return nil } -func (handler *ACLVppHandler) requestSetACLToInterfaces(logicalReq *ACLInterfaceLogicalReq) error { - setACLStopwatch := measure.GetTimeLog(acl_api.ACLInterfaceSetACLList{}, handler.stopwatch) +func (h *ACLVppHandler) requestSetACLToInterfaces(logicalReq *ACLInterfaceLogicalReq) error { for _, aclIfIdx := range logicalReq.ifIndices { // Create acl list with new entry var ACLs []uint32 // All previously assigned ACLs have to be dumped and added to acl list - aclInterfaceDetails, err := handler.DumpInterfaceIPACLs(aclIfIdx) + aclInterfaceDetails, err := h.DumpInterfaceIPACLs(aclIfIdx) if err != nil { return err } @@ -163,9 +142,6 @@ func (handler *ACLVppHandler) requestSetACLToInterfaces(logicalReq *ACLInterface } } - // Measure ACLInterfaceSetACLList time - start := time.Now() - msg := &acl_api.ACLInterfaceSetACLList{ Acls: ACLs, Count: uint8(len(ACLs)), @@ -174,32 +150,26 @@ func (handler *ACLVppHandler) requestSetACLToInterfaces(logicalReq *ACLInterface } reply := &acl_api.ACLInterfaceSetACLListReply{} - err = handler.callsChannel.SendRequest(msg).ReceiveReply(reply) + err = h.callsChannel.SendRequest(msg).ReceiveReply(reply) if err != nil { return err } if reply.Retval != 0 { return fmt.Errorf("setting up interface ACL list returned %v", reply.Retval) } - - // Log ACLInterfaceSetACLList time measurement results - if setACLStopwatch != nil { - setACLStopwatch.LogTimeEntry(time.Since(start)) - } } return nil } -func (handler *ACLVppHandler) requestRemoveInterfacesFromACL(logicalReq *ACLInterfaceLogicalReq) error { - setACLStopwatch := measure.GetTimeLog(acl_api.ACLInterfaceSetACLList{}, handler.stopwatch) +func (h *ACLVppHandler) requestRemoveInterfacesFromACL(logicalReq *ACLInterfaceLogicalReq) error { var wasErr error for _, aclIfIdx := range logicalReq.ifIndices { // Create empty ACL list var ACLs []uint32 // All assigned ACLs have to be dumped - aclInterfaceDetails, err := handler.DumpInterfaceIPACLs(aclIfIdx) + aclInterfaceDetails, err := h.DumpInterfaceIPACLs(aclIfIdx) if err != nil { return err } @@ -222,9 +192,6 @@ func (handler *ACLVppHandler) requestRemoveInterfacesFromACL(logicalReq *ACLInte } } - // Measure ACLInterfaceSetACLList time - start := time.Now() - msg := &acl_api.ACLInterfaceSetACLList{ Acls: ACLs, Count: uint8(len(ACLs)), @@ -233,18 +200,13 @@ func (handler *ACLVppHandler) requestRemoveInterfacesFromACL(logicalReq *ACLInte } reply := &acl_api.ACLInterfaceSetACLListReply{} - err = handler.callsChannel.SendRequest(msg).ReceiveReply(reply) + err = h.callsChannel.SendRequest(msg).ReceiveReply(reply) if err != nil { wasErr = err } if reply.Retval != 0 { wasErr = fmt.Errorf("setting up interface ACL list returned %v", reply.Retval) } - - // Log ACLInterfaceSetACLList time measurement results - if setACLStopwatch != nil { - setACLStopwatch.LogTimeEntry(time.Since(start)) - } } return wasErr diff --git a/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls_test.go b/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls_test.go index f29ed00201..00f36abc94 100644 --- a/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls_test.go +++ b/plugins/vpp/aclplugin/vppcalls/interfaces_vppcalls_test.go @@ -27,7 +27,7 @@ func TestRequestSetACLToInterfaces(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) defer ctx.TeardownTestCtx() - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) ctx.MockVpp.MockReply(&acl_api.ACLInterfaceListDetails{ SwIfIndex: 0, @@ -81,7 +81,7 @@ func TestRequestRemoveInterfacesFromACL(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) defer ctx.TeardownTestCtx() - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) ctx.MockVpp.MockReply(&acl_api.ACLInterfaceListDetails{ SwIfIndex: 0, @@ -135,7 +135,7 @@ func TestSetMacIPAclToInterface(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) defer ctx.TeardownTestCtx() - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) ctx.MockVpp.MockReply(&acl_api.MacipACLInterfaceAddDelReply{}) err := aclHandler.SetMacIPACLToInterface(0, []uint32{0}) @@ -157,7 +157,7 @@ func TestRemoveMacIPIngressACLFromInterfaces(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) defer ctx.TeardownTestCtx() - aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel, nil) + aclHandler := NewACLVppHandler(ctx.MockChannel, ctx.MockChannel) ctx.MockVpp.MockReply(&acl_api.MacipACLInterfaceAddDelReply{}) err := aclHandler.RemoveMacIPIngressACLFromInterfaces(1, []uint32{0}) diff --git a/plugins/vpp/binapi/acl/acl.ba.go b/plugins/vpp/binapi/acl/acl.ba.go index 195c8e91ed..9ad0faf115 100644 --- a/plugins/vpp/binapi/acl/acl.ba.go +++ b/plugins/vpp/binapi/acl/acl.ba.go @@ -1,16 +1,14 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/acl.api.json +// source: /usr/share/vpp/api/acl.api.json /* -Package acl is a generated VPP binary API of the 'acl' VPP module. + Package acl is a generated from VPP binary API module 'acl'. -It is generated from this file: - acl.api.json + It contains following objects: + 34 messages + 2 types + 17 services -It contains these VPP binary API objects: - 34 messages - 2 types - 17 services */ package acl @@ -19,13 +17,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Types */ // ACLRule represents the VPP binary API type 'acl_rule'. -// Generated from 'acl.api.json', line 922: // // "acl_rule", // [ @@ -110,7 +108,6 @@ func (*ACLRule) GetCrcString() string { } // MacipACLRule represents the VPP binary API type 'macip_acl_rule'. -// Generated from 'acl.api.json', line 982: // // "macip_acl_rule", // [ @@ -163,7 +160,6 @@ func (*MacipACLRule) GetCrcString() string { /* Messages */ // ACLPluginGetVersion represents the VPP binary API message 'acl_plugin_get_version'. -// Generated from 'acl.api.json', line 4: // // "acl_plugin_get_version", // [ @@ -193,12 +189,8 @@ func (*ACLPluginGetVersion) GetCrcString() string { func (*ACLPluginGetVersion) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLPluginGetVersion() api.Message { - return &ACLPluginGetVersion{} -} // ACLPluginGetVersionReply represents the VPP binary API message 'acl_plugin_get_version_reply'. -// Generated from 'acl.api.json', line 22: // // "acl_plugin_get_version_reply", // [ @@ -235,12 +227,8 @@ func (*ACLPluginGetVersionReply) GetCrcString() string { func (*ACLPluginGetVersionReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLPluginGetVersionReply() api.Message { - return &ACLPluginGetVersionReply{} -} // ACLPluginControlPing represents the VPP binary API message 'acl_plugin_control_ping'. -// Generated from 'acl.api.json', line 44: // // "acl_plugin_control_ping", // [ @@ -270,12 +258,8 @@ func (*ACLPluginControlPing) GetCrcString() string { func (*ACLPluginControlPing) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLPluginControlPing() api.Message { - return &ACLPluginControlPing{} -} // ACLPluginControlPingReply represents the VPP binary API message 'acl_plugin_control_ping_reply'. -// Generated from 'acl.api.json', line 62: // // "acl_plugin_control_ping_reply", // [ @@ -317,12 +301,8 @@ func (*ACLPluginControlPingReply) GetCrcString() string { func (*ACLPluginControlPingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLPluginControlPingReply() api.Message { - return &ACLPluginControlPingReply{} -} // ACLAddReplace represents the VPP binary API message 'acl_add_replace'. -// Generated from 'acl.api.json', line 88: // // "acl_add_replace", // [ @@ -376,12 +356,8 @@ func (*ACLAddReplace) GetCrcString() string { func (*ACLAddReplace) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLAddReplace() api.Message { - return &ACLAddReplace{} -} // ACLAddReplaceReply represents the VPP binary API message 'acl_add_replace_reply'. -// Generated from 'acl.api.json', line 125: // // "acl_add_replace_reply", // [ @@ -418,12 +394,8 @@ func (*ACLAddReplaceReply) GetCrcString() string { func (*ACLAddReplaceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLAddReplaceReply() api.Message { - return &ACLAddReplaceReply{} -} // ACLDel represents the VPP binary API message 'acl_del'. -// Generated from 'acl.api.json', line 147: // // "acl_del", // [ @@ -459,12 +431,8 @@ func (*ACLDel) GetCrcString() string { func (*ACLDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLDel() api.Message { - return &ACLDel{} -} // ACLDelReply represents the VPP binary API message 'acl_del_reply'. -// Generated from 'acl.api.json', line 169: // // "acl_del_reply", // [ @@ -496,12 +464,8 @@ func (*ACLDelReply) GetCrcString() string { func (*ACLDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLDelReply() api.Message { - return &ACLDelReply{} -} // ACLInterfaceAddDel represents the VPP binary API message 'acl_interface_add_del'. -// Generated from 'acl.api.json', line 187: // // "acl_interface_add_del", // [ @@ -552,12 +516,8 @@ func (*ACLInterfaceAddDel) GetCrcString() string { func (*ACLInterfaceAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLInterfaceAddDel() api.Message { - return &ACLInterfaceAddDel{} -} // ACLInterfaceAddDelReply represents the VPP binary API message 'acl_interface_add_del_reply'. -// Generated from 'acl.api.json', line 221: // // "acl_interface_add_del_reply", // [ @@ -589,12 +549,8 @@ func (*ACLInterfaceAddDelReply) GetCrcString() string { func (*ACLInterfaceAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLInterfaceAddDelReply() api.Message { - return &ACLInterfaceAddDelReply{} -} // ACLInterfaceSetACLList represents the VPP binary API message 'acl_interface_set_acl_list'. -// Generated from 'acl.api.json', line 239: // // "acl_interface_set_acl_list", // [ @@ -647,12 +603,8 @@ func (*ACLInterfaceSetACLList) GetCrcString() string { func (*ACLInterfaceSetACLList) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLInterfaceSetACLList() api.Message { - return &ACLInterfaceSetACLList{} -} // ACLInterfaceSetACLListReply represents the VPP binary API message 'acl_interface_set_acl_list_reply'. -// Generated from 'acl.api.json', line 275: // // "acl_interface_set_acl_list_reply", // [ @@ -684,12 +636,8 @@ func (*ACLInterfaceSetACLListReply) GetCrcString() string { func (*ACLInterfaceSetACLListReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLInterfaceSetACLListReply() api.Message { - return &ACLInterfaceSetACLListReply{} -} // ACLDump represents the VPP binary API message 'acl_dump'. -// Generated from 'acl.api.json', line 293: // // "acl_dump", // [ @@ -725,12 +673,8 @@ func (*ACLDump) GetCrcString() string { func (*ACLDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLDump() api.Message { - return &ACLDump{} -} // ACLDetails represents the VPP binary API message 'acl_details'. -// Generated from 'acl.api.json', line 315: // // "acl_details", // [ @@ -780,12 +724,8 @@ func (*ACLDetails) GetCrcString() string { func (*ACLDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLDetails() api.Message { - return &ACLDetails{} -} // ACLInterfaceListDump represents the VPP binary API message 'acl_interface_list_dump'. -// Generated from 'acl.api.json', line 348: // // "acl_interface_list_dump", // [ @@ -821,12 +761,8 @@ func (*ACLInterfaceListDump) GetCrcString() string { func (*ACLInterfaceListDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLInterfaceListDump() api.Message { - return &ACLInterfaceListDump{} -} // ACLInterfaceListDetails represents the VPP binary API message 'acl_interface_list_details'. -// Generated from 'acl.api.json', line 370: // // "acl_interface_list_details", // [ @@ -875,12 +811,8 @@ func (*ACLInterfaceListDetails) GetCrcString() string { func (*ACLInterfaceListDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLInterfaceListDetails() api.Message { - return &ACLInterfaceListDetails{} -} // MacipACLAdd represents the VPP binary API message 'macip_acl_add'. -// Generated from 'acl.api.json', line 402: // // "macip_acl_add", // [ @@ -929,12 +861,8 @@ func (*MacipACLAdd) GetCrcString() string { func (*MacipACLAdd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMacipACLAdd() api.Message { - return &MacipACLAdd{} -} // MacipACLAddReply represents the VPP binary API message 'macip_acl_add_reply'. -// Generated from 'acl.api.json', line 435: // // "macip_acl_add_reply", // [ @@ -971,12 +899,8 @@ func (*MacipACLAddReply) GetCrcString() string { func (*MacipACLAddReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMacipACLAddReply() api.Message { - return &MacipACLAddReply{} -} // MacipACLAddReplace represents the VPP binary API message 'macip_acl_add_replace'. -// Generated from 'acl.api.json', line 457: // // "macip_acl_add_replace", // [ @@ -1030,12 +954,8 @@ func (*MacipACLAddReplace) GetCrcString() string { func (*MacipACLAddReplace) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMacipACLAddReplace() api.Message { - return &MacipACLAddReplace{} -} // MacipACLAddReplaceReply represents the VPP binary API message 'macip_acl_add_replace_reply'. -// Generated from 'acl.api.json', line 494: // // "macip_acl_add_replace_reply", // [ @@ -1072,12 +992,8 @@ func (*MacipACLAddReplaceReply) GetCrcString() string { func (*MacipACLAddReplaceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMacipACLAddReplaceReply() api.Message { - return &MacipACLAddReplaceReply{} -} // MacipACLDel represents the VPP binary API message 'macip_acl_del'. -// Generated from 'acl.api.json', line 516: // // "macip_acl_del", // [ @@ -1113,12 +1029,8 @@ func (*MacipACLDel) GetCrcString() string { func (*MacipACLDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMacipACLDel() api.Message { - return &MacipACLDel{} -} // MacipACLDelReply represents the VPP binary API message 'macip_acl_del_reply'. -// Generated from 'acl.api.json', line 538: // // "macip_acl_del_reply", // [ @@ -1150,12 +1062,8 @@ func (*MacipACLDelReply) GetCrcString() string { func (*MacipACLDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMacipACLDelReply() api.Message { - return &MacipACLDelReply{} -} // MacipACLInterfaceAddDel represents the VPP binary API message 'macip_acl_interface_add_del'. -// Generated from 'acl.api.json', line 556: // // "macip_acl_interface_add_del", // [ @@ -1201,12 +1109,8 @@ func (*MacipACLInterfaceAddDel) GetCrcString() string { func (*MacipACLInterfaceAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMacipACLInterfaceAddDel() api.Message { - return &MacipACLInterfaceAddDel{} -} // MacipACLInterfaceAddDelReply represents the VPP binary API message 'macip_acl_interface_add_del_reply'. -// Generated from 'acl.api.json', line 586: // // "macip_acl_interface_add_del_reply", // [ @@ -1238,12 +1142,8 @@ func (*MacipACLInterfaceAddDelReply) GetCrcString() string { func (*MacipACLInterfaceAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMacipACLInterfaceAddDelReply() api.Message { - return &MacipACLInterfaceAddDelReply{} -} // MacipACLDump represents the VPP binary API message 'macip_acl_dump'. -// Generated from 'acl.api.json', line 604: // // "macip_acl_dump", // [ @@ -1279,12 +1179,8 @@ func (*MacipACLDump) GetCrcString() string { func (*MacipACLDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMacipACLDump() api.Message { - return &MacipACLDump{} -} // MacipACLDetails represents the VPP binary API message 'macip_acl_details'. -// Generated from 'acl.api.json', line 626: // // "macip_acl_details", // [ @@ -1334,12 +1230,8 @@ func (*MacipACLDetails) GetCrcString() string { func (*MacipACLDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMacipACLDetails() api.Message { - return &MacipACLDetails{} -} // MacipACLInterfaceGet represents the VPP binary API message 'macip_acl_interface_get'. -// Generated from 'acl.api.json', line 659: // // "macip_acl_interface_get", // [ @@ -1369,12 +1261,8 @@ func (*MacipACLInterfaceGet) GetCrcString() string { func (*MacipACLInterfaceGet) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMacipACLInterfaceGet() api.Message { - return &MacipACLInterfaceGet{} -} // MacipACLInterfaceGetReply represents the VPP binary API message 'macip_acl_interface_get_reply'. -// Generated from 'acl.api.json', line 677: // // "macip_acl_interface_get_reply", // [ @@ -1413,12 +1301,8 @@ func (*MacipACLInterfaceGetReply) GetCrcString() string { func (*MacipACLInterfaceGetReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMacipACLInterfaceGetReply() api.Message { - return &MacipACLInterfaceGetReply{} -} // MacipACLInterfaceListDump represents the VPP binary API message 'macip_acl_interface_list_dump'. -// Generated from 'acl.api.json', line 701: // // "macip_acl_interface_list_dump", // [ @@ -1454,12 +1338,8 @@ func (*MacipACLInterfaceListDump) GetCrcString() string { func (*MacipACLInterfaceListDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMacipACLInterfaceListDump() api.Message { - return &MacipACLInterfaceListDump{} -} // MacipACLInterfaceListDetails represents the VPP binary API message 'macip_acl_interface_list_details'. -// Generated from 'acl.api.json', line 723: // // "macip_acl_interface_list_details", // [ @@ -1503,12 +1383,8 @@ func (*MacipACLInterfaceListDetails) GetCrcString() string { func (*MacipACLInterfaceListDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMacipACLInterfaceListDetails() api.Message { - return &MacipACLInterfaceListDetails{} -} // ACLInterfaceSetEtypeWhitelist represents the VPP binary API message 'acl_interface_set_etype_whitelist'. -// Generated from 'acl.api.json', line 751: // // "acl_interface_set_etype_whitelist", // [ @@ -1561,12 +1437,8 @@ func (*ACLInterfaceSetEtypeWhitelist) GetCrcString() string { func (*ACLInterfaceSetEtypeWhitelist) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLInterfaceSetEtypeWhitelist() api.Message { - return &ACLInterfaceSetEtypeWhitelist{} -} // ACLInterfaceSetEtypeWhitelistReply represents the VPP binary API message 'acl_interface_set_etype_whitelist_reply'. -// Generated from 'acl.api.json', line 787: // // "acl_interface_set_etype_whitelist_reply", // [ @@ -1598,12 +1470,8 @@ func (*ACLInterfaceSetEtypeWhitelistReply) GetCrcString() string { func (*ACLInterfaceSetEtypeWhitelistReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLInterfaceSetEtypeWhitelistReply() api.Message { - return &ACLInterfaceSetEtypeWhitelistReply{} -} // ACLInterfaceEtypeWhitelistDump represents the VPP binary API message 'acl_interface_etype_whitelist_dump'. -// Generated from 'acl.api.json', line 805: // // "acl_interface_etype_whitelist_dump", // [ @@ -1639,12 +1507,8 @@ func (*ACLInterfaceEtypeWhitelistDump) GetCrcString() string { func (*ACLInterfaceEtypeWhitelistDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewACLInterfaceEtypeWhitelistDump() api.Message { - return &ACLInterfaceEtypeWhitelistDump{} -} // ACLInterfaceEtypeWhitelistDetails represents the VPP binary API message 'acl_interface_etype_whitelist_details'. -// Generated from 'acl.api.json', line 827: // // "acl_interface_etype_whitelist_details", // [ @@ -1693,9 +1557,6 @@ func (*ACLInterfaceEtypeWhitelistDetails) GetCrcString() string { func (*ACLInterfaceEtypeWhitelistDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewACLInterfaceEtypeWhitelistDetails() api.Message { - return &ACLInterfaceEtypeWhitelistDetails{} -} /* Services */ diff --git a/plugins/vpp/binapi/acl/pkgreflect.go b/plugins/vpp/binapi/acl/pkgreflect.go deleted file mode 100644 index 93a79a71fc..0000000000 --- a/plugins/vpp/binapi/acl/pkgreflect.go +++ /dev/null @@ -1,89 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package acl - -import "reflect" - -var Types = map[string]reflect.Type{ - "ACLAddReplace": reflect.TypeOf((*ACLAddReplace)(nil)).Elem(), - "ACLAddReplaceReply": reflect.TypeOf((*ACLAddReplaceReply)(nil)).Elem(), - "ACLDel": reflect.TypeOf((*ACLDel)(nil)).Elem(), - "ACLDelReply": reflect.TypeOf((*ACLDelReply)(nil)).Elem(), - "ACLDetails": reflect.TypeOf((*ACLDetails)(nil)).Elem(), - "ACLDump": reflect.TypeOf((*ACLDump)(nil)).Elem(), - "ACLInterfaceAddDel": reflect.TypeOf((*ACLInterfaceAddDel)(nil)).Elem(), - "ACLInterfaceAddDelReply": reflect.TypeOf((*ACLInterfaceAddDelReply)(nil)).Elem(), - "ACLInterfaceEtypeWhitelistDetails": reflect.TypeOf((*ACLInterfaceEtypeWhitelistDetails)(nil)).Elem(), - "ACLInterfaceEtypeWhitelistDump": reflect.TypeOf((*ACLInterfaceEtypeWhitelistDump)(nil)).Elem(), - "ACLInterfaceListDetails": reflect.TypeOf((*ACLInterfaceListDetails)(nil)).Elem(), - "ACLInterfaceListDump": reflect.TypeOf((*ACLInterfaceListDump)(nil)).Elem(), - "ACLInterfaceSetACLList": reflect.TypeOf((*ACLInterfaceSetACLList)(nil)).Elem(), - "ACLInterfaceSetACLListReply": reflect.TypeOf((*ACLInterfaceSetACLListReply)(nil)).Elem(), - "ACLInterfaceSetEtypeWhitelist": reflect.TypeOf((*ACLInterfaceSetEtypeWhitelist)(nil)).Elem(), - "ACLInterfaceSetEtypeWhitelistReply": reflect.TypeOf((*ACLInterfaceSetEtypeWhitelistReply)(nil)).Elem(), - "ACLPluginControlPing": reflect.TypeOf((*ACLPluginControlPing)(nil)).Elem(), - "ACLPluginControlPingReply": reflect.TypeOf((*ACLPluginControlPingReply)(nil)).Elem(), - "ACLPluginGetVersion": reflect.TypeOf((*ACLPluginGetVersion)(nil)).Elem(), - "ACLPluginGetVersionReply": reflect.TypeOf((*ACLPluginGetVersionReply)(nil)).Elem(), - "ACLRule": reflect.TypeOf((*ACLRule)(nil)).Elem(), - "MacipACLAdd": reflect.TypeOf((*MacipACLAdd)(nil)).Elem(), - "MacipACLAddReplace": reflect.TypeOf((*MacipACLAddReplace)(nil)).Elem(), - "MacipACLAddReplaceReply": reflect.TypeOf((*MacipACLAddReplaceReply)(nil)).Elem(), - "MacipACLAddReply": reflect.TypeOf((*MacipACLAddReply)(nil)).Elem(), - "MacipACLDel": reflect.TypeOf((*MacipACLDel)(nil)).Elem(), - "MacipACLDelReply": reflect.TypeOf((*MacipACLDelReply)(nil)).Elem(), - "MacipACLDetails": reflect.TypeOf((*MacipACLDetails)(nil)).Elem(), - "MacipACLDump": reflect.TypeOf((*MacipACLDump)(nil)).Elem(), - "MacipACLInterfaceAddDel": reflect.TypeOf((*MacipACLInterfaceAddDel)(nil)).Elem(), - "MacipACLInterfaceAddDelReply": reflect.TypeOf((*MacipACLInterfaceAddDelReply)(nil)).Elem(), - "MacipACLInterfaceGet": reflect.TypeOf((*MacipACLInterfaceGet)(nil)).Elem(), - "MacipACLInterfaceGetReply": reflect.TypeOf((*MacipACLInterfaceGetReply)(nil)).Elem(), - "MacipACLInterfaceListDetails": reflect.TypeOf((*MacipACLInterfaceListDetails)(nil)).Elem(), - "MacipACLInterfaceListDump": reflect.TypeOf((*MacipACLInterfaceListDump)(nil)).Elem(), - "MacipACLRule": reflect.TypeOf((*MacipACLRule)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewACLAddReplace": reflect.ValueOf(NewACLAddReplace), - "NewACLAddReplaceReply": reflect.ValueOf(NewACLAddReplaceReply), - "NewACLDel": reflect.ValueOf(NewACLDel), - "NewACLDelReply": reflect.ValueOf(NewACLDelReply), - "NewACLDetails": reflect.ValueOf(NewACLDetails), - "NewACLDump": reflect.ValueOf(NewACLDump), - "NewACLInterfaceAddDel": reflect.ValueOf(NewACLInterfaceAddDel), - "NewACLInterfaceAddDelReply": reflect.ValueOf(NewACLInterfaceAddDelReply), - "NewACLInterfaceEtypeWhitelistDetails": reflect.ValueOf(NewACLInterfaceEtypeWhitelistDetails), - "NewACLInterfaceEtypeWhitelistDump": reflect.ValueOf(NewACLInterfaceEtypeWhitelistDump), - "NewACLInterfaceListDetails": reflect.ValueOf(NewACLInterfaceListDetails), - "NewACLInterfaceListDump": reflect.ValueOf(NewACLInterfaceListDump), - "NewACLInterfaceSetACLList": reflect.ValueOf(NewACLInterfaceSetACLList), - "NewACLInterfaceSetACLListReply": reflect.ValueOf(NewACLInterfaceSetACLListReply), - "NewACLInterfaceSetEtypeWhitelist": reflect.ValueOf(NewACLInterfaceSetEtypeWhitelist), - "NewACLInterfaceSetEtypeWhitelistReply": reflect.ValueOf(NewACLInterfaceSetEtypeWhitelistReply), - "NewACLPluginControlPing": reflect.ValueOf(NewACLPluginControlPing), - "NewACLPluginControlPingReply": reflect.ValueOf(NewACLPluginControlPingReply), - "NewACLPluginGetVersion": reflect.ValueOf(NewACLPluginGetVersion), - "NewACLPluginGetVersionReply": reflect.ValueOf(NewACLPluginGetVersionReply), - "NewMacipACLAdd": reflect.ValueOf(NewMacipACLAdd), - "NewMacipACLAddReplace": reflect.ValueOf(NewMacipACLAddReplace), - "NewMacipACLAddReplaceReply": reflect.ValueOf(NewMacipACLAddReplaceReply), - "NewMacipACLAddReply": reflect.ValueOf(NewMacipACLAddReply), - "NewMacipACLDel": reflect.ValueOf(NewMacipACLDel), - "NewMacipACLDelReply": reflect.ValueOf(NewMacipACLDelReply), - "NewMacipACLDetails": reflect.ValueOf(NewMacipACLDetails), - "NewMacipACLDump": reflect.ValueOf(NewMacipACLDump), - "NewMacipACLInterfaceAddDel": reflect.ValueOf(NewMacipACLInterfaceAddDel), - "NewMacipACLInterfaceAddDelReply": reflect.ValueOf(NewMacipACLInterfaceAddDelReply), - "NewMacipACLInterfaceGet": reflect.ValueOf(NewMacipACLInterfaceGet), - "NewMacipACLInterfaceGetReply": reflect.ValueOf(NewMacipACLInterfaceGetReply), - "NewMacipACLInterfaceListDetails": reflect.ValueOf(NewMacipACLInterfaceListDetails), - "NewMacipACLInterfaceListDump": reflect.ValueOf(NewMacipACLInterfaceListDump), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/af_packet/af_packet.ba.go b/plugins/vpp/binapi/af_packet/af_packet.ba.go index 0255708bd0..9ba4c93e3a 100644 --- a/plugins/vpp/binapi/af_packet/af_packet.ba.go +++ b/plugins/vpp/binapi/af_packet/af_packet.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/af_packet.api.json +// source: /usr/share/vpp/api/af_packet.api.json /* -Package af_packet is a generated VPP binary API of the 'af_packet' VPP module. + Package af_packet is a generated from VPP binary API module 'af_packet'. -It is generated from this file: - af_packet.api.json + It contains following objects: + 8 messages + 4 services -It contains these VPP binary API objects: - 8 messages - 4 services */ package af_packet @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // AfPacketCreate represents the VPP binary API message 'af_packet_create'. -// Generated from 'af_packet.api.json', line 4: // // "af_packet_create", // [ @@ -72,12 +70,8 @@ func (*AfPacketCreate) GetCrcString() string { func (*AfPacketCreate) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAfPacketCreate() api.Message { - return &AfPacketCreate{} -} // AfPacketCreateReply represents the VPP binary API message 'af_packet_create_reply'. -// Generated from 'af_packet.api.json', line 36: // // "af_packet_create_reply", // [ @@ -114,12 +108,8 @@ func (*AfPacketCreateReply) GetCrcString() string { func (*AfPacketCreateReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAfPacketCreateReply() api.Message { - return &AfPacketCreateReply{} -} // AfPacketDelete represents the VPP binary API message 'af_packet_delete'. -// Generated from 'af_packet.api.json', line 58: // // "af_packet_delete", // [ @@ -156,12 +146,8 @@ func (*AfPacketDelete) GetCrcString() string { func (*AfPacketDelete) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAfPacketDelete() api.Message { - return &AfPacketDelete{} -} // AfPacketDeleteReply represents the VPP binary API message 'af_packet_delete_reply'. -// Generated from 'af_packet.api.json', line 81: // // "af_packet_delete_reply", // [ @@ -193,12 +179,8 @@ func (*AfPacketDeleteReply) GetCrcString() string { func (*AfPacketDeleteReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAfPacketDeleteReply() api.Message { - return &AfPacketDeleteReply{} -} // AfPacketSetL4CksumOffload represents the VPP binary API message 'af_packet_set_l4_cksum_offload'. -// Generated from 'af_packet.api.json', line 99: // // "af_packet_set_l4_cksum_offload", // [ @@ -239,12 +221,8 @@ func (*AfPacketSetL4CksumOffload) GetCrcString() string { func (*AfPacketSetL4CksumOffload) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAfPacketSetL4CksumOffload() api.Message { - return &AfPacketSetL4CksumOffload{} -} // AfPacketSetL4CksumOffloadReply represents the VPP binary API message 'af_packet_set_l4_cksum_offload_reply'. -// Generated from 'af_packet.api.json', line 125: // // "af_packet_set_l4_cksum_offload_reply", // [ @@ -276,12 +254,8 @@ func (*AfPacketSetL4CksumOffloadReply) GetCrcString() string { func (*AfPacketSetL4CksumOffloadReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAfPacketSetL4CksumOffloadReply() api.Message { - return &AfPacketSetL4CksumOffloadReply{} -} // AfPacketDump represents the VPP binary API message 'af_packet_dump'. -// Generated from 'af_packet.api.json', line 143: // // "af_packet_dump", // [ @@ -311,12 +285,8 @@ func (*AfPacketDump) GetCrcString() string { func (*AfPacketDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAfPacketDump() api.Message { - return &AfPacketDump{} -} // AfPacketDetails represents the VPP binary API message 'af_packet_details'. -// Generated from 'af_packet.api.json', line 161: // // "af_packet_details", // [ @@ -354,9 +324,6 @@ func (*AfPacketDetails) GetCrcString() string { func (*AfPacketDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAfPacketDetails() api.Message { - return &AfPacketDetails{} -} /* Services */ diff --git a/plugins/vpp/binapi/af_packet/pkgreflect.go b/plugins/vpp/binapi/af_packet/pkgreflect.go deleted file mode 100644 index 672639d753..0000000000 --- a/plugins/vpp/binapi/af_packet/pkgreflect.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package af_packet - -import "reflect" - -var Types = map[string]reflect.Type{ - "AfPacketCreate": reflect.TypeOf((*AfPacketCreate)(nil)).Elem(), - "AfPacketCreateReply": reflect.TypeOf((*AfPacketCreateReply)(nil)).Elem(), - "AfPacketDelete": reflect.TypeOf((*AfPacketDelete)(nil)).Elem(), - "AfPacketDeleteReply": reflect.TypeOf((*AfPacketDeleteReply)(nil)).Elem(), - "AfPacketDetails": reflect.TypeOf((*AfPacketDetails)(nil)).Elem(), - "AfPacketDump": reflect.TypeOf((*AfPacketDump)(nil)).Elem(), - "AfPacketSetL4CksumOffload": reflect.TypeOf((*AfPacketSetL4CksumOffload)(nil)).Elem(), - "AfPacketSetL4CksumOffloadReply": reflect.TypeOf((*AfPacketSetL4CksumOffloadReply)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewAfPacketCreate": reflect.ValueOf(NewAfPacketCreate), - "NewAfPacketCreateReply": reflect.ValueOf(NewAfPacketCreateReply), - "NewAfPacketDelete": reflect.ValueOf(NewAfPacketDelete), - "NewAfPacketDeleteReply": reflect.ValueOf(NewAfPacketDeleteReply), - "NewAfPacketDetails": reflect.ValueOf(NewAfPacketDetails), - "NewAfPacketDump": reflect.ValueOf(NewAfPacketDump), - "NewAfPacketSetL4CksumOffload": reflect.ValueOf(NewAfPacketSetL4CksumOffload), - "NewAfPacketSetL4CksumOffloadReply": reflect.ValueOf(NewAfPacketSetL4CksumOffloadReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/bfd/bfd.ba.go b/plugins/vpp/binapi/bfd/bfd.ba.go index a52d293692..620d2c364e 100644 --- a/plugins/vpp/binapi/bfd/bfd.ba.go +++ b/plugins/vpp/binapi/bfd/bfd.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/bfd.api.json +// source: /usr/share/vpp/api/bfd.api.json /* -Package bfd is a generated VPP binary API of the 'bfd' VPP module. + Package bfd is a generated from VPP binary API module 'bfd'. -It is generated from this file: - bfd.api.json + It contains following objects: + 26 messages + 13 services -It contains these VPP binary API objects: - 26 messages - 13 services */ package bfd @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // BfdUDPSetEchoSource represents the VPP binary API message 'bfd_udp_set_echo_source'. -// Generated from 'bfd.api.json', line 4: // // "bfd_udp_set_echo_source", // [ @@ -60,12 +58,8 @@ func (*BfdUDPSetEchoSource) GetCrcString() string { func (*BfdUDPSetEchoSource) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPSetEchoSource() api.Message { - return &BfdUDPSetEchoSource{} -} // BfdUDPSetEchoSourceReply represents the VPP binary API message 'bfd_udp_set_echo_source_reply'. -// Generated from 'bfd.api.json', line 26: // // "bfd_udp_set_echo_source_reply", // [ @@ -97,12 +91,8 @@ func (*BfdUDPSetEchoSourceReply) GetCrcString() string { func (*BfdUDPSetEchoSourceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPSetEchoSourceReply() api.Message { - return &BfdUDPSetEchoSourceReply{} -} // BfdUDPDelEchoSource represents the VPP binary API message 'bfd_udp_del_echo_source'. -// Generated from 'bfd.api.json', line 44: // // "bfd_udp_del_echo_source", // [ @@ -132,12 +122,8 @@ func (*BfdUDPDelEchoSource) GetCrcString() string { func (*BfdUDPDelEchoSource) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPDelEchoSource() api.Message { - return &BfdUDPDelEchoSource{} -} // BfdUDPDelEchoSourceReply represents the VPP binary API message 'bfd_udp_del_echo_source_reply'. -// Generated from 'bfd.api.json', line 62: // // "bfd_udp_del_echo_source_reply", // [ @@ -169,12 +155,8 @@ func (*BfdUDPDelEchoSourceReply) GetCrcString() string { func (*BfdUDPDelEchoSourceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPDelEchoSourceReply() api.Message { - return &BfdUDPDelEchoSourceReply{} -} // BfdUDPAdd represents the VPP binary API message 'bfd_udp_add'. -// Generated from 'bfd.api.json', line 80: // // "bfd_udp_add", // [ @@ -257,12 +239,8 @@ func (*BfdUDPAdd) GetCrcString() string { func (*BfdUDPAdd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPAdd() api.Message { - return &BfdUDPAdd{} -} // BfdUDPAddReply represents the VPP binary API message 'bfd_udp_add_reply'. -// Generated from 'bfd.api.json', line 140: // // "bfd_udp_add_reply", // [ @@ -294,12 +272,8 @@ func (*BfdUDPAddReply) GetCrcString() string { func (*BfdUDPAddReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPAddReply() api.Message { - return &BfdUDPAddReply{} -} // BfdUDPMod represents the VPP binary API message 'bfd_udp_mod'. -// Generated from 'bfd.api.json', line 158: // // "bfd_udp_mod", // [ @@ -367,12 +341,8 @@ func (*BfdUDPMod) GetCrcString() string { func (*BfdUDPMod) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPMod() api.Message { - return &BfdUDPMod{} -} // BfdUDPModReply represents the VPP binary API message 'bfd_udp_mod_reply'. -// Generated from 'bfd.api.json', line 206: // // "bfd_udp_mod_reply", // [ @@ -404,12 +374,8 @@ func (*BfdUDPModReply) GetCrcString() string { func (*BfdUDPModReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPModReply() api.Message { - return &BfdUDPModReply{} -} // BfdUDPDel represents the VPP binary API message 'bfd_udp_del'. -// Generated from 'bfd.api.json', line 224: // // "bfd_udp_del", // [ @@ -462,12 +428,8 @@ func (*BfdUDPDel) GetCrcString() string { func (*BfdUDPDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPDel() api.Message { - return &BfdUDPDel{} -} // BfdUDPDelReply represents the VPP binary API message 'bfd_udp_del_reply'. -// Generated from 'bfd.api.json', line 260: // // "bfd_udp_del_reply", // [ @@ -499,12 +461,8 @@ func (*BfdUDPDelReply) GetCrcString() string { func (*BfdUDPDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPDelReply() api.Message { - return &BfdUDPDelReply{} -} // BfdUDPSessionDump represents the VPP binary API message 'bfd_udp_session_dump'. -// Generated from 'bfd.api.json', line 278: // // "bfd_udp_session_dump", // [ @@ -534,12 +492,8 @@ func (*BfdUDPSessionDump) GetCrcString() string { func (*BfdUDPSessionDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPSessionDump() api.Message { - return &BfdUDPSessionDump{} -} // BfdUDPSessionDetails represents the VPP binary API message 'bfd_udp_session_details'. -// Generated from 'bfd.api.json', line 296: // // "bfd_udp_session_details", // [ @@ -623,12 +577,8 @@ func (*BfdUDPSessionDetails) GetCrcString() string { func (*BfdUDPSessionDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPSessionDetails() api.Message { - return &BfdUDPSessionDetails{} -} // BfdUDPSessionSetFlags represents the VPP binary API message 'bfd_udp_session_set_flags'. -// Generated from 'bfd.api.json', line 356: // // "bfd_udp_session_set_flags", // [ @@ -686,12 +636,8 @@ func (*BfdUDPSessionSetFlags) GetCrcString() string { func (*BfdUDPSessionSetFlags) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPSessionSetFlags() api.Message { - return &BfdUDPSessionSetFlags{} -} // BfdUDPSessionSetFlagsReply represents the VPP binary API message 'bfd_udp_session_set_flags_reply'. -// Generated from 'bfd.api.json', line 396: // // "bfd_udp_session_set_flags_reply", // [ @@ -723,12 +669,8 @@ func (*BfdUDPSessionSetFlagsReply) GetCrcString() string { func (*BfdUDPSessionSetFlagsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPSessionSetFlagsReply() api.Message { - return &BfdUDPSessionSetFlagsReply{} -} // WantBfdEvents represents the VPP binary API message 'want_bfd_events'. -// Generated from 'bfd.api.json', line 414: // // "want_bfd_events", // [ @@ -769,12 +711,8 @@ func (*WantBfdEvents) GetCrcString() string { func (*WantBfdEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantBfdEvents() api.Message { - return &WantBfdEvents{} -} // WantBfdEventsReply represents the VPP binary API message 'want_bfd_events_reply'. -// Generated from 'bfd.api.json', line 440: // // "want_bfd_events_reply", // [ @@ -806,12 +744,8 @@ func (*WantBfdEventsReply) GetCrcString() string { func (*WantBfdEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantBfdEventsReply() api.Message { - return &WantBfdEventsReply{} -} // BfdAuthSetKey represents the VPP binary API message 'bfd_auth_set_key'. -// Generated from 'bfd.api.json', line 458: // // "bfd_auth_set_key", // [ @@ -863,12 +797,8 @@ func (*BfdAuthSetKey) GetCrcString() string { func (*BfdAuthSetKey) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdAuthSetKey() api.Message { - return &BfdAuthSetKey{} -} // BfdAuthSetKeyReply represents the VPP binary API message 'bfd_auth_set_key_reply'. -// Generated from 'bfd.api.json', line 493: // // "bfd_auth_set_key_reply", // [ @@ -900,12 +830,8 @@ func (*BfdAuthSetKeyReply) GetCrcString() string { func (*BfdAuthSetKeyReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdAuthSetKeyReply() api.Message { - return &BfdAuthSetKeyReply{} -} // BfdAuthDelKey represents the VPP binary API message 'bfd_auth_del_key'. -// Generated from 'bfd.api.json', line 511: // // "bfd_auth_del_key", // [ @@ -941,12 +867,8 @@ func (*BfdAuthDelKey) GetCrcString() string { func (*BfdAuthDelKey) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdAuthDelKey() api.Message { - return &BfdAuthDelKey{} -} // BfdAuthDelKeyReply represents the VPP binary API message 'bfd_auth_del_key_reply'. -// Generated from 'bfd.api.json', line 533: // // "bfd_auth_del_key_reply", // [ @@ -978,12 +900,8 @@ func (*BfdAuthDelKeyReply) GetCrcString() string { func (*BfdAuthDelKeyReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdAuthDelKeyReply() api.Message { - return &BfdAuthDelKeyReply{} -} // BfdAuthKeysDump represents the VPP binary API message 'bfd_auth_keys_dump'. -// Generated from 'bfd.api.json', line 551: // // "bfd_auth_keys_dump", // [ @@ -1013,12 +931,8 @@ func (*BfdAuthKeysDump) GetCrcString() string { func (*BfdAuthKeysDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdAuthKeysDump() api.Message { - return &BfdAuthKeysDump{} -} // BfdAuthKeysDetails represents the VPP binary API message 'bfd_auth_keys_details'. -// Generated from 'bfd.api.json', line 569: // // "bfd_auth_keys_details", // [ @@ -1060,12 +974,8 @@ func (*BfdAuthKeysDetails) GetCrcString() string { func (*BfdAuthKeysDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdAuthKeysDetails() api.Message { - return &BfdAuthKeysDetails{} -} // BfdUDPAuthActivate represents the VPP binary API message 'bfd_udp_auth_activate'. -// Generated from 'bfd.api.json', line 595: // // "bfd_udp_auth_activate", // [ @@ -1133,12 +1043,8 @@ func (*BfdUDPAuthActivate) GetCrcString() string { func (*BfdUDPAuthActivate) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPAuthActivate() api.Message { - return &BfdUDPAuthActivate{} -} // BfdUDPAuthActivateReply represents the VPP binary API message 'bfd_udp_auth_activate_reply'. -// Generated from 'bfd.api.json', line 643: // // "bfd_udp_auth_activate_reply", // [ @@ -1170,12 +1076,8 @@ func (*BfdUDPAuthActivateReply) GetCrcString() string { func (*BfdUDPAuthActivateReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPAuthActivateReply() api.Message { - return &BfdUDPAuthActivateReply{} -} // BfdUDPAuthDeactivate represents the VPP binary API message 'bfd_udp_auth_deactivate'. -// Generated from 'bfd.api.json', line 661: // // "bfd_udp_auth_deactivate", // [ @@ -1233,12 +1135,8 @@ func (*BfdUDPAuthDeactivate) GetCrcString() string { func (*BfdUDPAuthDeactivate) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBfdUDPAuthDeactivate() api.Message { - return &BfdUDPAuthDeactivate{} -} // BfdUDPAuthDeactivateReply represents the VPP binary API message 'bfd_udp_auth_deactivate_reply'. -// Generated from 'bfd.api.json', line 701: // // "bfd_udp_auth_deactivate_reply", // [ @@ -1270,9 +1168,6 @@ func (*BfdUDPAuthDeactivateReply) GetCrcString() string { func (*BfdUDPAuthDeactivateReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBfdUDPAuthDeactivateReply() api.Message { - return &BfdUDPAuthDeactivateReply{} -} /* Services */ diff --git a/plugins/vpp/binapi/bfd/pkgreflect.go b/plugins/vpp/binapi/bfd/pkgreflect.go deleted file mode 100644 index 4d70693065..0000000000 --- a/plugins/vpp/binapi/bfd/pkgreflect.go +++ /dev/null @@ -1,71 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package bfd - -import "reflect" - -var Types = map[string]reflect.Type{ - "BfdAuthDelKey": reflect.TypeOf((*BfdAuthDelKey)(nil)).Elem(), - "BfdAuthDelKeyReply": reflect.TypeOf((*BfdAuthDelKeyReply)(nil)).Elem(), - "BfdAuthKeysDetails": reflect.TypeOf((*BfdAuthKeysDetails)(nil)).Elem(), - "BfdAuthKeysDump": reflect.TypeOf((*BfdAuthKeysDump)(nil)).Elem(), - "BfdAuthSetKey": reflect.TypeOf((*BfdAuthSetKey)(nil)).Elem(), - "BfdAuthSetKeyReply": reflect.TypeOf((*BfdAuthSetKeyReply)(nil)).Elem(), - "BfdUDPAdd": reflect.TypeOf((*BfdUDPAdd)(nil)).Elem(), - "BfdUDPAddReply": reflect.TypeOf((*BfdUDPAddReply)(nil)).Elem(), - "BfdUDPAuthActivate": reflect.TypeOf((*BfdUDPAuthActivate)(nil)).Elem(), - "BfdUDPAuthActivateReply": reflect.TypeOf((*BfdUDPAuthActivateReply)(nil)).Elem(), - "BfdUDPAuthDeactivate": reflect.TypeOf((*BfdUDPAuthDeactivate)(nil)).Elem(), - "BfdUDPAuthDeactivateReply": reflect.TypeOf((*BfdUDPAuthDeactivateReply)(nil)).Elem(), - "BfdUDPDel": reflect.TypeOf((*BfdUDPDel)(nil)).Elem(), - "BfdUDPDelEchoSource": reflect.TypeOf((*BfdUDPDelEchoSource)(nil)).Elem(), - "BfdUDPDelEchoSourceReply": reflect.TypeOf((*BfdUDPDelEchoSourceReply)(nil)).Elem(), - "BfdUDPDelReply": reflect.TypeOf((*BfdUDPDelReply)(nil)).Elem(), - "BfdUDPMod": reflect.TypeOf((*BfdUDPMod)(nil)).Elem(), - "BfdUDPModReply": reflect.TypeOf((*BfdUDPModReply)(nil)).Elem(), - "BfdUDPSessionDetails": reflect.TypeOf((*BfdUDPSessionDetails)(nil)).Elem(), - "BfdUDPSessionDump": reflect.TypeOf((*BfdUDPSessionDump)(nil)).Elem(), - "BfdUDPSessionSetFlags": reflect.TypeOf((*BfdUDPSessionSetFlags)(nil)).Elem(), - "BfdUDPSessionSetFlagsReply": reflect.TypeOf((*BfdUDPSessionSetFlagsReply)(nil)).Elem(), - "BfdUDPSetEchoSource": reflect.TypeOf((*BfdUDPSetEchoSource)(nil)).Elem(), - "BfdUDPSetEchoSourceReply": reflect.TypeOf((*BfdUDPSetEchoSourceReply)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "WantBfdEvents": reflect.TypeOf((*WantBfdEvents)(nil)).Elem(), - "WantBfdEventsReply": reflect.TypeOf((*WantBfdEventsReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewBfdAuthDelKey": reflect.ValueOf(NewBfdAuthDelKey), - "NewBfdAuthDelKeyReply": reflect.ValueOf(NewBfdAuthDelKeyReply), - "NewBfdAuthKeysDetails": reflect.ValueOf(NewBfdAuthKeysDetails), - "NewBfdAuthKeysDump": reflect.ValueOf(NewBfdAuthKeysDump), - "NewBfdAuthSetKey": reflect.ValueOf(NewBfdAuthSetKey), - "NewBfdAuthSetKeyReply": reflect.ValueOf(NewBfdAuthSetKeyReply), - "NewBfdUDPAdd": reflect.ValueOf(NewBfdUDPAdd), - "NewBfdUDPAddReply": reflect.ValueOf(NewBfdUDPAddReply), - "NewBfdUDPAuthActivate": reflect.ValueOf(NewBfdUDPAuthActivate), - "NewBfdUDPAuthActivateReply": reflect.ValueOf(NewBfdUDPAuthActivateReply), - "NewBfdUDPAuthDeactivate": reflect.ValueOf(NewBfdUDPAuthDeactivate), - "NewBfdUDPAuthDeactivateReply": reflect.ValueOf(NewBfdUDPAuthDeactivateReply), - "NewBfdUDPDel": reflect.ValueOf(NewBfdUDPDel), - "NewBfdUDPDelEchoSource": reflect.ValueOf(NewBfdUDPDelEchoSource), - "NewBfdUDPDelEchoSourceReply": reflect.ValueOf(NewBfdUDPDelEchoSourceReply), - "NewBfdUDPDelReply": reflect.ValueOf(NewBfdUDPDelReply), - "NewBfdUDPMod": reflect.ValueOf(NewBfdUDPMod), - "NewBfdUDPModReply": reflect.ValueOf(NewBfdUDPModReply), - "NewBfdUDPSessionDetails": reflect.ValueOf(NewBfdUDPSessionDetails), - "NewBfdUDPSessionDump": reflect.ValueOf(NewBfdUDPSessionDump), - "NewBfdUDPSessionSetFlags": reflect.ValueOf(NewBfdUDPSessionSetFlags), - "NewBfdUDPSessionSetFlagsReply": reflect.ValueOf(NewBfdUDPSessionSetFlagsReply), - "NewBfdUDPSetEchoSource": reflect.ValueOf(NewBfdUDPSetEchoSource), - "NewBfdUDPSetEchoSourceReply": reflect.ValueOf(NewBfdUDPSetEchoSourceReply), - "NewWantBfdEvents": reflect.ValueOf(NewWantBfdEvents), - "NewWantBfdEventsReply": reflect.ValueOf(NewWantBfdEventsReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/dhcp/dhcp.ba.go b/plugins/vpp/binapi/dhcp/dhcp.ba.go index 7726cce201..a044a23662 100644 --- a/plugins/vpp/binapi/dhcp/dhcp.ba.go +++ b/plugins/vpp/binapi/dhcp/dhcp.ba.go @@ -1,16 +1,14 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/dhcp.api.json +// source: /usr/share/vpp/api/dhcp.api.json /* -Package dhcp is a generated VPP binary API of the 'dhcp' VPP module. + Package dhcp is a generated from VPP binary API module 'dhcp'. -It is generated from this file: - dhcp.api.json + It contains following objects: + 25 messages + 5 types + 11 services -It contains these VPP binary API objects: - 25 messages - 5 types - 11 services */ package dhcp @@ -19,13 +17,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Types */ // DHCPClient represents the VPP binary API type 'dhcp_client'. -// Generated from 'dhcp.api.json', line 825: // // "dhcp_client", // [ @@ -75,7 +73,6 @@ func (*DHCPClient) GetCrcString() string { } // DHCPLease represents the VPP binary API type 'dhcp_lease'. -// Generated from 'dhcp.api.json', line 857: // // "dhcp_lease", // [ @@ -137,7 +134,6 @@ func (*DHCPLease) GetCrcString() string { } // DHCPServer represents the VPP binary API type 'dhcp_server'. -// Generated from 'dhcp.api.json', line 899: // // "dhcp_server", // [ @@ -166,7 +162,6 @@ func (*DHCPServer) GetCrcString() string { } // DHCP6AddressInfo represents the VPP binary API type 'dhcp6_address_info'. -// Generated from 'dhcp.api.json', line 914: // // "dhcp6_address_info", // [ @@ -200,7 +195,6 @@ func (*DHCP6AddressInfo) GetCrcString() string { } // DHCP6PdPrefixInfo represents the VPP binary API type 'dhcp6_pd_prefix_info'. -// Generated from 'dhcp.api.json', line 933: // // "dhcp6_pd_prefix_info", // [ @@ -241,7 +235,6 @@ func (*DHCP6PdPrefixInfo) GetCrcString() string { /* Messages */ // DHCPProxyConfig represents the VPP binary API message 'dhcp_proxy_config'. -// Generated from 'dhcp.api.json', line 4: // // "dhcp_proxy_config", // [ @@ -304,12 +297,8 @@ func (*DHCPProxyConfig) GetCrcString() string { func (*DHCPProxyConfig) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCPProxyConfig() api.Message { - return &DHCPProxyConfig{} -} // DHCPProxyConfigReply represents the VPP binary API message 'dhcp_proxy_config_reply'. -// Generated from 'dhcp.api.json', line 48: // // "dhcp_proxy_config_reply", // [ @@ -341,12 +330,8 @@ func (*DHCPProxyConfigReply) GetCrcString() string { func (*DHCPProxyConfigReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCPProxyConfigReply() api.Message { - return &DHCPProxyConfigReply{} -} // DHCPProxySetVss represents the VPP binary API message 'dhcp_proxy_set_vss'. -// Generated from 'dhcp.api.json', line 66: // // "dhcp_proxy_set_vss", // [ @@ -413,12 +398,8 @@ func (*DHCPProxySetVss) GetCrcString() string { func (*DHCPProxySetVss) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCPProxySetVss() api.Message { - return &DHCPProxySetVss{} -} // DHCPProxySetVssReply represents the VPP binary API message 'dhcp_proxy_set_vss_reply'. -// Generated from 'dhcp.api.json', line 113: // // "dhcp_proxy_set_vss_reply", // [ @@ -450,12 +431,8 @@ func (*DHCPProxySetVssReply) GetCrcString() string { func (*DHCPProxySetVssReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCPProxySetVssReply() api.Message { - return &DHCPProxySetVssReply{} -} // DHCPClientConfig represents the VPP binary API message 'dhcp_client_config'. -// Generated from 'dhcp.api.json', line 131: // // "dhcp_client_config", // [ @@ -496,12 +473,8 @@ func (*DHCPClientConfig) GetCrcString() string { func (*DHCPClientConfig) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCPClientConfig() api.Message { - return &DHCPClientConfig{} -} // DHCPClientConfigReply represents the VPP binary API message 'dhcp_client_config_reply'. -// Generated from 'dhcp.api.json', line 157: // // "dhcp_client_config_reply", // [ @@ -533,12 +506,8 @@ func (*DHCPClientConfigReply) GetCrcString() string { func (*DHCPClientConfigReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCPClientConfigReply() api.Message { - return &DHCPClientConfigReply{} -} // DHCPComplEvent represents the VPP binary API message 'dhcp_compl_event'. -// Generated from 'dhcp.api.json', line 175: // // "dhcp_compl_event", // [ @@ -575,12 +544,8 @@ func (*DHCPComplEvent) GetCrcString() string { func (*DHCPComplEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewDHCPComplEvent() api.Message { - return &DHCPComplEvent{} -} // DHCPClientDump represents the VPP binary API message 'dhcp_client_dump'. -// Generated from 'dhcp.api.json', line 197: // // "dhcp_client_dump", // [ @@ -610,12 +575,8 @@ func (*DHCPClientDump) GetCrcString() string { func (*DHCPClientDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCPClientDump() api.Message { - return &DHCPClientDump{} -} // DHCPClientDetails represents the VPP binary API message 'dhcp_client_details'. -// Generated from 'dhcp.api.json', line 215: // // "dhcp_client_details", // [ @@ -652,12 +613,8 @@ func (*DHCPClientDetails) GetCrcString() string { func (*DHCPClientDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCPClientDetails() api.Message { - return &DHCPClientDetails{} -} // DHCPProxyDump represents the VPP binary API message 'dhcp_proxy_dump'. -// Generated from 'dhcp.api.json', line 237: // // "dhcp_proxy_dump", // [ @@ -693,12 +650,8 @@ func (*DHCPProxyDump) GetCrcString() string { func (*DHCPProxyDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCPProxyDump() api.Message { - return &DHCPProxyDump{} -} // DHCPProxyDetails represents the VPP binary API message 'dhcp_proxy_details'. -// Generated from 'dhcp.api.json', line 259: // // "dhcp_proxy_details", // [ @@ -774,12 +727,8 @@ func (*DHCPProxyDetails) GetCrcString() string { func (*DHCPProxyDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCPProxyDetails() api.Message { - return &DHCPProxyDetails{} -} // DHCP6DuidLlSet represents the VPP binary API message 'dhcp6_duid_ll_set'. -// Generated from 'dhcp.api.json', line 313: // // "dhcp6_duid_ll_set", // [ @@ -816,12 +765,8 @@ func (*DHCP6DuidLlSet) GetCrcString() string { func (*DHCP6DuidLlSet) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCP6DuidLlSet() api.Message { - return &DHCP6DuidLlSet{} -} // DHCP6DuidLlSetReply represents the VPP binary API message 'dhcp6_duid_ll_set_reply'. -// Generated from 'dhcp.api.json', line 336: // // "dhcp6_duid_ll_set_reply", // [ @@ -853,12 +798,8 @@ func (*DHCP6DuidLlSetReply) GetCrcString() string { func (*DHCP6DuidLlSetReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCP6DuidLlSetReply() api.Message { - return &DHCP6DuidLlSetReply{} -} // DHCP6ClientsEnableDisable represents the VPP binary API message 'dhcp6_clients_enable_disable'. -// Generated from 'dhcp.api.json', line 354: // // "dhcp6_clients_enable_disable", // [ @@ -894,12 +835,8 @@ func (*DHCP6ClientsEnableDisable) GetCrcString() string { func (*DHCP6ClientsEnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCP6ClientsEnableDisable() api.Message { - return &DHCP6ClientsEnableDisable{} -} // DHCP6ClientsEnableDisableReply represents the VPP binary API message 'dhcp6_clients_enable_disable_reply'. -// Generated from 'dhcp.api.json', line 376: // // "dhcp6_clients_enable_disable_reply", // [ @@ -931,12 +868,8 @@ func (*DHCP6ClientsEnableDisableReply) GetCrcString() string { func (*DHCP6ClientsEnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCP6ClientsEnableDisableReply() api.Message { - return &DHCP6ClientsEnableDisableReply{} -} // DHCP6SendClientMessage represents the VPP binary API message 'dhcp6_send_client_message'. -// Generated from 'dhcp.api.json', line 394: // // "dhcp6_send_client_message", // [ @@ -1029,12 +962,8 @@ func (*DHCP6SendClientMessage) GetCrcString() string { func (*DHCP6SendClientMessage) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCP6SendClientMessage() api.Message { - return &DHCP6SendClientMessage{} -} // DHCP6SendClientMessageReply represents the VPP binary API message 'dhcp6_send_client_message_reply'. -// Generated from 'dhcp.api.json', line 462: // // "dhcp6_send_client_message_reply", // [ @@ -1066,12 +995,8 @@ func (*DHCP6SendClientMessageReply) GetCrcString() string { func (*DHCP6SendClientMessageReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCP6SendClientMessageReply() api.Message { - return &DHCP6SendClientMessageReply{} -} // DHCP6PdSendClientMessage represents the VPP binary API message 'dhcp6_pd_send_client_message'. -// Generated from 'dhcp.api.json', line 480: // // "dhcp6_pd_send_client_message", // [ @@ -1164,12 +1089,8 @@ func (*DHCP6PdSendClientMessage) GetCrcString() string { func (*DHCP6PdSendClientMessage) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDHCP6PdSendClientMessage() api.Message { - return &DHCP6PdSendClientMessage{} -} // DHCP6PdSendClientMessageReply represents the VPP binary API message 'dhcp6_pd_send_client_message_reply'. -// Generated from 'dhcp.api.json', line 548: // // "dhcp6_pd_send_client_message_reply", // [ @@ -1201,12 +1122,8 @@ func (*DHCP6PdSendClientMessageReply) GetCrcString() string { func (*DHCP6PdSendClientMessageReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDHCP6PdSendClientMessageReply() api.Message { - return &DHCP6PdSendClientMessageReply{} -} // WantDHCP6ReplyEvents represents the VPP binary API message 'want_dhcp6_reply_events'. -// Generated from 'dhcp.api.json', line 566: // // "want_dhcp6_reply_events", // [ @@ -1247,12 +1164,8 @@ func (*WantDHCP6ReplyEvents) GetCrcString() string { func (*WantDHCP6ReplyEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantDHCP6ReplyEvents() api.Message { - return &WantDHCP6ReplyEvents{} -} // WantDHCP6ReplyEventsReply represents the VPP binary API message 'want_dhcp6_reply_events_reply'. -// Generated from 'dhcp.api.json', line 592: // // "want_dhcp6_reply_events_reply", // [ @@ -1284,12 +1197,8 @@ func (*WantDHCP6ReplyEventsReply) GetCrcString() string { func (*WantDHCP6ReplyEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantDHCP6ReplyEventsReply() api.Message { - return &WantDHCP6ReplyEventsReply{} -} // WantDHCP6PdReplyEvents represents the VPP binary API message 'want_dhcp6_pd_reply_events'. -// Generated from 'dhcp.api.json', line 610: // // "want_dhcp6_pd_reply_events", // [ @@ -1330,12 +1239,8 @@ func (*WantDHCP6PdReplyEvents) GetCrcString() string { func (*WantDHCP6PdReplyEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantDHCP6PdReplyEvents() api.Message { - return &WantDHCP6PdReplyEvents{} -} // WantDHCP6PdReplyEventsReply represents the VPP binary API message 'want_dhcp6_pd_reply_events_reply'. -// Generated from 'dhcp.api.json', line 636: // // "want_dhcp6_pd_reply_events_reply", // [ @@ -1367,12 +1272,8 @@ func (*WantDHCP6PdReplyEventsReply) GetCrcString() string { func (*WantDHCP6PdReplyEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantDHCP6PdReplyEventsReply() api.Message { - return &WantDHCP6PdReplyEventsReply{} -} // DHCP6ReplyEvent represents the VPP binary API message 'dhcp6_reply_event'. -// Generated from 'dhcp.api.json', line 654: // // "dhcp6_reply_event", // [ @@ -1456,12 +1357,8 @@ func (*DHCP6ReplyEvent) GetCrcString() string { func (*DHCP6ReplyEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewDHCP6ReplyEvent() api.Message { - return &DHCP6ReplyEvent{} -} // DHCP6PdReplyEvent represents the VPP binary API message 'dhcp6_pd_reply_event'. -// Generated from 'dhcp.api.json', line 714: // // "dhcp6_pd_reply_event", // [ @@ -1545,9 +1442,6 @@ func (*DHCP6PdReplyEvent) GetCrcString() string { func (*DHCP6PdReplyEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewDHCP6PdReplyEvent() api.Message { - return &DHCP6PdReplyEvent{} -} /* Services */ diff --git a/plugins/vpp/binapi/dhcp/pkgreflect.go b/plugins/vpp/binapi/dhcp/pkgreflect.go deleted file mode 100644 index fc14944f15..0000000000 --- a/plugins/vpp/binapi/dhcp/pkgreflect.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package dhcp - -import "reflect" - -var Types = map[string]reflect.Type{ - "DHCP6AddressInfo": reflect.TypeOf((*DHCP6AddressInfo)(nil)).Elem(), - "DHCP6ClientsEnableDisable": reflect.TypeOf((*DHCP6ClientsEnableDisable)(nil)).Elem(), - "DHCP6ClientsEnableDisableReply": reflect.TypeOf((*DHCP6ClientsEnableDisableReply)(nil)).Elem(), - "DHCP6DuidLlSet": reflect.TypeOf((*DHCP6DuidLlSet)(nil)).Elem(), - "DHCP6DuidLlSetReply": reflect.TypeOf((*DHCP6DuidLlSetReply)(nil)).Elem(), - "DHCP6PdPrefixInfo": reflect.TypeOf((*DHCP6PdPrefixInfo)(nil)).Elem(), - "DHCP6PdReplyEvent": reflect.TypeOf((*DHCP6PdReplyEvent)(nil)).Elem(), - "DHCP6PdSendClientMessage": reflect.TypeOf((*DHCP6PdSendClientMessage)(nil)).Elem(), - "DHCP6PdSendClientMessageReply": reflect.TypeOf((*DHCP6PdSendClientMessageReply)(nil)).Elem(), - "DHCP6ReplyEvent": reflect.TypeOf((*DHCP6ReplyEvent)(nil)).Elem(), - "DHCP6SendClientMessage": reflect.TypeOf((*DHCP6SendClientMessage)(nil)).Elem(), - "DHCP6SendClientMessageReply": reflect.TypeOf((*DHCP6SendClientMessageReply)(nil)).Elem(), - "DHCPClient": reflect.TypeOf((*DHCPClient)(nil)).Elem(), - "DHCPClientConfig": reflect.TypeOf((*DHCPClientConfig)(nil)).Elem(), - "DHCPClientConfigReply": reflect.TypeOf((*DHCPClientConfigReply)(nil)).Elem(), - "DHCPClientDetails": reflect.TypeOf((*DHCPClientDetails)(nil)).Elem(), - "DHCPClientDump": reflect.TypeOf((*DHCPClientDump)(nil)).Elem(), - "DHCPComplEvent": reflect.TypeOf((*DHCPComplEvent)(nil)).Elem(), - "DHCPLease": reflect.TypeOf((*DHCPLease)(nil)).Elem(), - "DHCPProxyConfig": reflect.TypeOf((*DHCPProxyConfig)(nil)).Elem(), - "DHCPProxyConfigReply": reflect.TypeOf((*DHCPProxyConfigReply)(nil)).Elem(), - "DHCPProxyDetails": reflect.TypeOf((*DHCPProxyDetails)(nil)).Elem(), - "DHCPProxyDump": reflect.TypeOf((*DHCPProxyDump)(nil)).Elem(), - "DHCPProxySetVss": reflect.TypeOf((*DHCPProxySetVss)(nil)).Elem(), - "DHCPProxySetVssReply": reflect.TypeOf((*DHCPProxySetVssReply)(nil)).Elem(), - "DHCPServer": reflect.TypeOf((*DHCPServer)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "WantDHCP6PdReplyEvents": reflect.TypeOf((*WantDHCP6PdReplyEvents)(nil)).Elem(), - "WantDHCP6PdReplyEventsReply": reflect.TypeOf((*WantDHCP6PdReplyEventsReply)(nil)).Elem(), - "WantDHCP6ReplyEvents": reflect.TypeOf((*WantDHCP6ReplyEvents)(nil)).Elem(), - "WantDHCP6ReplyEventsReply": reflect.TypeOf((*WantDHCP6ReplyEventsReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewDHCP6ClientsEnableDisable": reflect.ValueOf(NewDHCP6ClientsEnableDisable), - "NewDHCP6ClientsEnableDisableReply": reflect.ValueOf(NewDHCP6ClientsEnableDisableReply), - "NewDHCP6DuidLlSet": reflect.ValueOf(NewDHCP6DuidLlSet), - "NewDHCP6DuidLlSetReply": reflect.ValueOf(NewDHCP6DuidLlSetReply), - "NewDHCP6PdReplyEvent": reflect.ValueOf(NewDHCP6PdReplyEvent), - "NewDHCP6PdSendClientMessage": reflect.ValueOf(NewDHCP6PdSendClientMessage), - "NewDHCP6PdSendClientMessageReply": reflect.ValueOf(NewDHCP6PdSendClientMessageReply), - "NewDHCP6ReplyEvent": reflect.ValueOf(NewDHCP6ReplyEvent), - "NewDHCP6SendClientMessage": reflect.ValueOf(NewDHCP6SendClientMessage), - "NewDHCP6SendClientMessageReply": reflect.ValueOf(NewDHCP6SendClientMessageReply), - "NewDHCPClientConfig": reflect.ValueOf(NewDHCPClientConfig), - "NewDHCPClientConfigReply": reflect.ValueOf(NewDHCPClientConfigReply), - "NewDHCPClientDetails": reflect.ValueOf(NewDHCPClientDetails), - "NewDHCPClientDump": reflect.ValueOf(NewDHCPClientDump), - "NewDHCPComplEvent": reflect.ValueOf(NewDHCPComplEvent), - "NewDHCPProxyConfig": reflect.ValueOf(NewDHCPProxyConfig), - "NewDHCPProxyConfigReply": reflect.ValueOf(NewDHCPProxyConfigReply), - "NewDHCPProxyDetails": reflect.ValueOf(NewDHCPProxyDetails), - "NewDHCPProxyDump": reflect.ValueOf(NewDHCPProxyDump), - "NewDHCPProxySetVss": reflect.ValueOf(NewDHCPProxySetVss), - "NewDHCPProxySetVssReply": reflect.ValueOf(NewDHCPProxySetVssReply), - "NewWantDHCP6PdReplyEvents": reflect.ValueOf(NewWantDHCP6PdReplyEvents), - "NewWantDHCP6PdReplyEventsReply": reflect.ValueOf(NewWantDHCP6PdReplyEventsReply), - "NewWantDHCP6ReplyEvents": reflect.ValueOf(NewWantDHCP6ReplyEvents), - "NewWantDHCP6ReplyEventsReply": reflect.ValueOf(NewWantDHCP6ReplyEventsReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/interfaces/interfaces.ba.go b/plugins/vpp/binapi/interfaces/interfaces.ba.go index f6083ea362..e00fc55f31 100644 --- a/plugins/vpp/binapi/interfaces/interfaces.ba.go +++ b/plugins/vpp/binapi/interfaces/interfaces.ba.go @@ -1,16 +1,14 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/interface.api.json +// source: /usr/share/vpp/api/interface.api.json /* -Package interfaces is a generated VPP binary API of the 'interface' VPP module. + Package interfaces is a generated from VPP binary API module 'interface'. -It is generated from this file: - interface.api.json + It contains following objects: + 51 messages + 3 types + 25 services -It contains these VPP binary API objects: - 47 messages - 3 types - 23 services */ package interfaces @@ -19,13 +17,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Types */ // VlibCounter represents the VPP binary API type 'vlib_counter'. -// Generated from 'interface.api.json', line 1348: // // "vlib_counter", // [ @@ -53,7 +51,6 @@ func (*VlibCounter) GetCrcString() string { } // VnetCombinedCounter represents the VPP binary API type 'vnet_combined_counter'. -// Generated from 'interface.api.json', line 1362: // // "vnet_combined_counter", // [ @@ -156,7 +153,6 @@ func (*VnetCombinedCounter) GetCrcString() string { } // VnetSimpleCounter represents the VPP binary API type 'vnet_simple_counter'. -// Generated from 'interface.api.json', line 1436: // // "vnet_simple_counter", // [ @@ -226,7 +222,6 @@ func (*VnetSimpleCounter) GetCrcString() string { /* Messages */ // SwInterfaceSetFlags represents the VPP binary API message 'sw_interface_set_flags'. -// Generated from 'interface.api.json', line 4: // // "sw_interface_set_flags", // [ @@ -267,12 +262,8 @@ func (*SwInterfaceSetFlags) GetCrcString() string { func (*SwInterfaceSetFlags) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetFlags() api.Message { - return &SwInterfaceSetFlags{} -} // SwInterfaceSetFlagsReply represents the VPP binary API message 'sw_interface_set_flags_reply'. -// Generated from 'interface.api.json', line 30: // // "sw_interface_set_flags_reply", // [ @@ -304,12 +295,8 @@ func (*SwInterfaceSetFlagsReply) GetCrcString() string { func (*SwInterfaceSetFlagsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetFlagsReply() api.Message { - return &SwInterfaceSetFlagsReply{} -} // HwInterfaceSetMtu represents the VPP binary API message 'hw_interface_set_mtu'. -// Generated from 'interface.api.json', line 48: // // "hw_interface_set_mtu", // [ @@ -350,12 +337,8 @@ func (*HwInterfaceSetMtu) GetCrcString() string { func (*HwInterfaceSetMtu) GetMessageType() api.MessageType { return api.RequestMessage } -func NewHwInterfaceSetMtu() api.Message { - return &HwInterfaceSetMtu{} -} // HwInterfaceSetMtuReply represents the VPP binary API message 'hw_interface_set_mtu_reply'. -// Generated from 'interface.api.json', line 74: // // "hw_interface_set_mtu_reply", // [ @@ -387,12 +370,8 @@ func (*HwInterfaceSetMtuReply) GetCrcString() string { func (*HwInterfaceSetMtuReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewHwInterfaceSetMtuReply() api.Message { - return &HwInterfaceSetMtuReply{} -} // SwInterfaceSetMtu represents the VPP binary API message 'sw_interface_set_mtu'. -// Generated from 'interface.api.json', line 92: // // "sw_interface_set_mtu", // [ @@ -434,12 +413,8 @@ func (*SwInterfaceSetMtu) GetCrcString() string { func (*SwInterfaceSetMtu) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetMtu() api.Message { - return &SwInterfaceSetMtu{} -} // SwInterfaceSetMtuReply represents the VPP binary API message 'sw_interface_set_mtu_reply'. -// Generated from 'interface.api.json', line 119: // // "sw_interface_set_mtu_reply", // [ @@ -471,12 +446,8 @@ func (*SwInterfaceSetMtuReply) GetCrcString() string { func (*SwInterfaceSetMtuReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetMtuReply() api.Message { - return &SwInterfaceSetMtuReply{} -} // SwInterfaceSetIPDirectedBroadcast represents the VPP binary API message 'sw_interface_set_ip_directed_broadcast'. -// Generated from 'interface.api.json', line 137: // // "sw_interface_set_ip_directed_broadcast", // [ @@ -517,12 +488,8 @@ func (*SwInterfaceSetIPDirectedBroadcast) GetCrcString() string { func (*SwInterfaceSetIPDirectedBroadcast) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetIPDirectedBroadcast() api.Message { - return &SwInterfaceSetIPDirectedBroadcast{} -} // SwInterfaceSetIPDirectedBroadcastReply represents the VPP binary API message 'sw_interface_set_ip_directed_broadcast_reply'. -// Generated from 'interface.api.json', line 163: // // "sw_interface_set_ip_directed_broadcast_reply", // [ @@ -554,12 +521,8 @@ func (*SwInterfaceSetIPDirectedBroadcastReply) GetCrcString() string { func (*SwInterfaceSetIPDirectedBroadcastReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetIPDirectedBroadcastReply() api.Message { - return &SwInterfaceSetIPDirectedBroadcastReply{} -} // SwInterfaceEvent represents the VPP binary API message 'sw_interface_event'. -// Generated from 'interface.api.json', line 181: // // "sw_interface_event", // [ @@ -611,12 +574,8 @@ func (*SwInterfaceEvent) GetCrcString() string { func (*SwInterfaceEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewSwInterfaceEvent() api.Message { - return &SwInterfaceEvent{} -} // WantInterfaceEvents represents the VPP binary API message 'want_interface_events'. -// Generated from 'interface.api.json', line 215: // // "want_interface_events", // [ @@ -657,12 +616,8 @@ func (*WantInterfaceEvents) GetCrcString() string { func (*WantInterfaceEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantInterfaceEvents() api.Message { - return &WantInterfaceEvents{} -} // WantInterfaceEventsReply represents the VPP binary API message 'want_interface_events_reply'. -// Generated from 'interface.api.json', line 241: // // "want_interface_events_reply", // [ @@ -694,12 +649,8 @@ func (*WantInterfaceEventsReply) GetCrcString() string { func (*WantInterfaceEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantInterfaceEventsReply() api.Message { - return &WantInterfaceEventsReply{} -} // SwInterfaceDetails represents the VPP binary API message 'sw_interface_details'. -// Generated from 'interface.api.json', line 259: // // "sw_interface_details", // [ @@ -887,12 +838,8 @@ func (*SwInterfaceDetails) GetCrcString() string { func (*SwInterfaceDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceDetails() api.Message { - return &SwInterfaceDetails{} -} // SwInterfaceDump represents the VPP binary API message 'sw_interface_dump'. -// Generated from 'interface.api.json', line 403: // // "sw_interface_dump", // [ @@ -934,12 +881,8 @@ func (*SwInterfaceDump) GetCrcString() string { func (*SwInterfaceDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceDump() api.Message { - return &SwInterfaceDump{} -} // SwInterfaceAddDelAddress represents the VPP binary API message 'sw_interface_add_del_address'. -// Generated from 'interface.api.json', line 430: // // "sw_interface_add_del_address", // [ @@ -1001,12 +944,8 @@ func (*SwInterfaceAddDelAddress) GetCrcString() string { func (*SwInterfaceAddDelAddress) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceAddDelAddress() api.Message { - return &SwInterfaceAddDelAddress{} -} // SwInterfaceAddDelAddressReply represents the VPP binary API message 'sw_interface_add_del_address_reply'. -// Generated from 'interface.api.json', line 473: // // "sw_interface_add_del_address_reply", // [ @@ -1038,12 +977,8 @@ func (*SwInterfaceAddDelAddressReply) GetCrcString() string { func (*SwInterfaceAddDelAddressReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceAddDelAddressReply() api.Message { - return &SwInterfaceAddDelAddressReply{} -} // SwInterfaceSetTable represents the VPP binary API message 'sw_interface_set_table'. -// Generated from 'interface.api.json', line 491: // // "sw_interface_set_table", // [ @@ -1089,12 +1024,8 @@ func (*SwInterfaceSetTable) GetCrcString() string { func (*SwInterfaceSetTable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetTable() api.Message { - return &SwInterfaceSetTable{} -} // SwInterfaceSetTableReply represents the VPP binary API message 'sw_interface_set_table_reply'. -// Generated from 'interface.api.json', line 521: // // "sw_interface_set_table_reply", // [ @@ -1126,12 +1057,8 @@ func (*SwInterfaceSetTableReply) GetCrcString() string { func (*SwInterfaceSetTableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetTableReply() api.Message { - return &SwInterfaceSetTableReply{} -} // SwInterfaceGetTable represents the VPP binary API message 'sw_interface_get_table'. -// Generated from 'interface.api.json', line 539: // // "sw_interface_get_table", // [ @@ -1172,12 +1099,8 @@ func (*SwInterfaceGetTable) GetCrcString() string { func (*SwInterfaceGetTable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceGetTable() api.Message { - return &SwInterfaceGetTable{} -} // SwInterfaceGetTableReply represents the VPP binary API message 'sw_interface_get_table_reply'. -// Generated from 'interface.api.json', line 565: // // "sw_interface_get_table_reply", // [ @@ -1214,12 +1137,8 @@ func (*SwInterfaceGetTableReply) GetCrcString() string { func (*SwInterfaceGetTableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceGetTableReply() api.Message { - return &SwInterfaceGetTableReply{} -} // SwInterfaceSetUnnumbered represents the VPP binary API message 'sw_interface_set_unnumbered'. -// Generated from 'interface.api.json', line 587: // // "sw_interface_set_unnumbered", // [ @@ -1265,12 +1184,8 @@ func (*SwInterfaceSetUnnumbered) GetCrcString() string { func (*SwInterfaceSetUnnumbered) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetUnnumbered() api.Message { - return &SwInterfaceSetUnnumbered{} -} // SwInterfaceSetUnnumberedReply represents the VPP binary API message 'sw_interface_set_unnumbered_reply'. -// Generated from 'interface.api.json', line 617: // // "sw_interface_set_unnumbered_reply", // [ @@ -1302,12 +1217,8 @@ func (*SwInterfaceSetUnnumberedReply) GetCrcString() string { func (*SwInterfaceSetUnnumberedReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetUnnumberedReply() api.Message { - return &SwInterfaceSetUnnumberedReply{} -} // SwInterfaceClearStats represents the VPP binary API message 'sw_interface_clear_stats'. -// Generated from 'interface.api.json', line 635: // // "sw_interface_clear_stats", // [ @@ -1343,12 +1254,8 @@ func (*SwInterfaceClearStats) GetCrcString() string { func (*SwInterfaceClearStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceClearStats() api.Message { - return &SwInterfaceClearStats{} -} // SwInterfaceClearStatsReply represents the VPP binary API message 'sw_interface_clear_stats_reply'. -// Generated from 'interface.api.json', line 657: // // "sw_interface_clear_stats_reply", // [ @@ -1380,12 +1287,8 @@ func (*SwInterfaceClearStatsReply) GetCrcString() string { func (*SwInterfaceClearStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceClearStatsReply() api.Message { - return &SwInterfaceClearStatsReply{} -} // SwInterfaceTagAddDel represents the VPP binary API message 'sw_interface_tag_add_del'. -// Generated from 'interface.api.json', line 675: // // "sw_interface_tag_add_del", // [ @@ -1432,12 +1335,8 @@ func (*SwInterfaceTagAddDel) GetCrcString() string { func (*SwInterfaceTagAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceTagAddDel() api.Message { - return &SwInterfaceTagAddDel{} -} // SwInterfaceTagAddDelReply represents the VPP binary API message 'sw_interface_tag_add_del_reply'. -// Generated from 'interface.api.json', line 706: // // "sw_interface_tag_add_del_reply", // [ @@ -1469,12 +1368,8 @@ func (*SwInterfaceTagAddDelReply) GetCrcString() string { func (*SwInterfaceTagAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceTagAddDelReply() api.Message { - return &SwInterfaceTagAddDelReply{} -} // SwInterfaceSetMacAddress represents the VPP binary API message 'sw_interface_set_mac_address'. -// Generated from 'interface.api.json', line 724: // // "sw_interface_set_mac_address", // [ @@ -1516,12 +1411,8 @@ func (*SwInterfaceSetMacAddress) GetCrcString() string { func (*SwInterfaceSetMacAddress) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetMacAddress() api.Message { - return &SwInterfaceSetMacAddress{} -} // SwInterfaceSetMacAddressReply represents the VPP binary API message 'sw_interface_set_mac_address_reply'. -// Generated from 'interface.api.json', line 751: // // "sw_interface_set_mac_address_reply", // [ @@ -1553,12 +1444,8 @@ func (*SwInterfaceSetMacAddressReply) GetCrcString() string { func (*SwInterfaceSetMacAddressReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetMacAddressReply() api.Message { - return &SwInterfaceSetMacAddressReply{} -} // SwInterfaceGetMacAddress represents the VPP binary API message 'sw_interface_get_mac_address'. -// Generated from 'interface.api.json', line 769: // // "sw_interface_get_mac_address", // [ @@ -1594,12 +1481,8 @@ func (*SwInterfaceGetMacAddress) GetCrcString() string { func (*SwInterfaceGetMacAddress) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceGetMacAddress() api.Message { - return &SwInterfaceGetMacAddress{} -} // SwInterfaceGetMacAddressReply represents the VPP binary API message 'sw_interface_get_mac_address_reply'. -// Generated from 'interface.api.json', line 791: // // "sw_interface_get_mac_address_reply", // [ @@ -1637,12 +1520,8 @@ func (*SwInterfaceGetMacAddressReply) GetCrcString() string { func (*SwInterfaceGetMacAddressReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceGetMacAddressReply() api.Message { - return &SwInterfaceGetMacAddressReply{} -} // SwInterfaceSetRxMode represents the VPP binary API message 'sw_interface_set_rx_mode'. -// Generated from 'interface.api.json', line 814: // // "sw_interface_set_rx_mode", // [ @@ -1693,12 +1572,8 @@ func (*SwInterfaceSetRxMode) GetCrcString() string { func (*SwInterfaceSetRxMode) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetRxMode() api.Message { - return &SwInterfaceSetRxMode{} -} // SwInterfaceSetRxModeReply represents the VPP binary API message 'sw_interface_set_rx_mode_reply'. -// Generated from 'interface.api.json', line 848: // // "sw_interface_set_rx_mode_reply", // [ @@ -1730,12 +1605,182 @@ func (*SwInterfaceSetRxModeReply) GetCrcString() string { func (*SwInterfaceSetRxModeReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetRxModeReply() api.Message { - return &SwInterfaceSetRxModeReply{} + +// SwInterfaceSetRxPlacement represents the VPP binary API message 'sw_interface_set_rx_placement'. +// +// "sw_interface_set_rx_placement", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u32", +// "sw_if_index" +// ], +// [ +// "u32", +// "queue_id" +// ], +// [ +// "u32", +// "worker_id" +// ], +// [ +// "u8", +// "is_main" +// ], +// { +// "crc": "0x4ef4377d" +// } +// +type SwInterfaceSetRxPlacement struct { + SwIfIndex uint32 + QueueID uint32 + WorkerID uint32 + IsMain uint8 +} + +func (*SwInterfaceSetRxPlacement) GetMessageName() string { + return "sw_interface_set_rx_placement" +} +func (*SwInterfaceSetRxPlacement) GetCrcString() string { + return "4ef4377d" +} +func (*SwInterfaceSetRxPlacement) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// SwInterfaceSetRxPlacementReply represents the VPP binary API message 'sw_interface_set_rx_placement_reply'. +// +// "sw_interface_set_rx_placement_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "i32", +// "retval" +// ], +// { +// "crc": "0xe8d4e804" +// } +// +type SwInterfaceSetRxPlacementReply struct { + Retval int32 +} + +func (*SwInterfaceSetRxPlacementReply) GetMessageName() string { + return "sw_interface_set_rx_placement_reply" +} +func (*SwInterfaceSetRxPlacementReply) GetCrcString() string { + return "e8d4e804" +} +func (*SwInterfaceSetRxPlacementReply) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// SwInterfaceRxPlacementDump represents the VPP binary API message 'sw_interface_rx_placement_dump'. +// +// "sw_interface_rx_placement_dump", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u32", +// "sw_if_index" +// ], +// { +// "crc": "0x529cb13f" +// } +// +type SwInterfaceRxPlacementDump struct { + SwIfIndex uint32 +} + +func (*SwInterfaceRxPlacementDump) GetMessageName() string { + return "sw_interface_rx_placement_dump" +} +func (*SwInterfaceRxPlacementDump) GetCrcString() string { + return "529cb13f" +} +func (*SwInterfaceRxPlacementDump) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// SwInterfaceRxPlacementDetails represents the VPP binary API message 'sw_interface_rx_placement_details'. +// +// "sw_interface_rx_placement_details", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u32", +// "sw_if_index" +// ], +// [ +// "u32", +// "queue_id" +// ], +// [ +// "u32", +// "worker_id" +// ], +// [ +// "u8", +// "mode" +// ], +// { +// "crc": "0x0e9e33f4" +// } +// +type SwInterfaceRxPlacementDetails struct { + SwIfIndex uint32 + QueueID uint32 + WorkerID uint32 + Mode uint8 +} + +func (*SwInterfaceRxPlacementDetails) GetMessageName() string { + return "sw_interface_rx_placement_details" +} +func (*SwInterfaceRxPlacementDetails) GetCrcString() string { + return "0e9e33f4" +} +func (*SwInterfaceRxPlacementDetails) GetMessageType() api.MessageType { + return api.RequestMessage } // InterfaceNameRenumber represents the VPP binary API message 'interface_name_renumber'. -// Generated from 'interface.api.json', line 866: // // "interface_name_renumber", // [ @@ -1776,12 +1821,8 @@ func (*InterfaceNameRenumber) GetCrcString() string { func (*InterfaceNameRenumber) GetMessageType() api.MessageType { return api.RequestMessage } -func NewInterfaceNameRenumber() api.Message { - return &InterfaceNameRenumber{} -} // InterfaceNameRenumberReply represents the VPP binary API message 'interface_name_renumber_reply'. -// Generated from 'interface.api.json', line 892: // // "interface_name_renumber_reply", // [ @@ -1813,12 +1854,8 @@ func (*InterfaceNameRenumberReply) GetCrcString() string { func (*InterfaceNameRenumberReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewInterfaceNameRenumberReply() api.Message { - return &InterfaceNameRenumberReply{} -} // CreateSubif represents the VPP binary API message 'create_subif'. -// Generated from 'interface.api.json', line 910: // // "create_subif", // [ @@ -1909,12 +1946,8 @@ func (*CreateSubif) GetCrcString() string { func (*CreateSubif) GetMessageType() api.MessageType { return api.RequestMessage } -func NewCreateSubif() api.Message { - return &CreateSubif{} -} // CreateSubifReply represents the VPP binary API message 'create_subif_reply'. -// Generated from 'interface.api.json', line 976: // // "create_subif_reply", // [ @@ -1951,12 +1984,8 @@ func (*CreateSubifReply) GetCrcString() string { func (*CreateSubifReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewCreateSubifReply() api.Message { - return &CreateSubifReply{} -} // CreateVlanSubif represents the VPP binary API message 'create_vlan_subif'. -// Generated from 'interface.api.json', line 998: // // "create_vlan_subif", // [ @@ -1997,12 +2026,8 @@ func (*CreateVlanSubif) GetCrcString() string { func (*CreateVlanSubif) GetMessageType() api.MessageType { return api.RequestMessage } -func NewCreateVlanSubif() api.Message { - return &CreateVlanSubif{} -} // CreateVlanSubifReply represents the VPP binary API message 'create_vlan_subif_reply'. -// Generated from 'interface.api.json', line 1024: // // "create_vlan_subif_reply", // [ @@ -2039,12 +2064,8 @@ func (*CreateVlanSubifReply) GetCrcString() string { func (*CreateVlanSubifReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewCreateVlanSubifReply() api.Message { - return &CreateVlanSubifReply{} -} // DeleteSubif represents the VPP binary API message 'delete_subif'. -// Generated from 'interface.api.json', line 1046: // // "delete_subif", // [ @@ -2080,12 +2101,8 @@ func (*DeleteSubif) GetCrcString() string { func (*DeleteSubif) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDeleteSubif() api.Message { - return &DeleteSubif{} -} // DeleteSubifReply represents the VPP binary API message 'delete_subif_reply'. -// Generated from 'interface.api.json', line 1068: // // "delete_subif_reply", // [ @@ -2117,12 +2134,8 @@ func (*DeleteSubifReply) GetCrcString() string { func (*DeleteSubifReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDeleteSubifReply() api.Message { - return &DeleteSubifReply{} -} // CreateLoopback represents the VPP binary API message 'create_loopback'. -// Generated from 'interface.api.json', line 1086: // // "create_loopback", // [ @@ -2159,12 +2172,8 @@ func (*CreateLoopback) GetCrcString() string { func (*CreateLoopback) GetMessageType() api.MessageType { return api.RequestMessage } -func NewCreateLoopback() api.Message { - return &CreateLoopback{} -} // CreateLoopbackReply represents the VPP binary API message 'create_loopback_reply'. -// Generated from 'interface.api.json', line 1109: // // "create_loopback_reply", // [ @@ -2201,12 +2210,8 @@ func (*CreateLoopbackReply) GetCrcString() string { func (*CreateLoopbackReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewCreateLoopbackReply() api.Message { - return &CreateLoopbackReply{} -} // CreateLoopbackInstance represents the VPP binary API message 'create_loopback_instance'. -// Generated from 'interface.api.json', line 1131: // // "create_loopback_instance", // [ @@ -2253,12 +2258,8 @@ func (*CreateLoopbackInstance) GetCrcString() string { func (*CreateLoopbackInstance) GetMessageType() api.MessageType { return api.RequestMessage } -func NewCreateLoopbackInstance() api.Message { - return &CreateLoopbackInstance{} -} // CreateLoopbackInstanceReply represents the VPP binary API message 'create_loopback_instance_reply'. -// Generated from 'interface.api.json', line 1162: // // "create_loopback_instance_reply", // [ @@ -2295,12 +2296,8 @@ func (*CreateLoopbackInstanceReply) GetCrcString() string { func (*CreateLoopbackInstanceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewCreateLoopbackInstanceReply() api.Message { - return &CreateLoopbackInstanceReply{} -} // DeleteLoopback represents the VPP binary API message 'delete_loopback'. -// Generated from 'interface.api.json', line 1184: // // "delete_loopback", // [ @@ -2336,12 +2333,8 @@ func (*DeleteLoopback) GetCrcString() string { func (*DeleteLoopback) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDeleteLoopback() api.Message { - return &DeleteLoopback{} -} // DeleteLoopbackReply represents the VPP binary API message 'delete_loopback_reply'. -// Generated from 'interface.api.json', line 1206: // // "delete_loopback_reply", // [ @@ -2373,12 +2366,8 @@ func (*DeleteLoopbackReply) GetCrcString() string { func (*DeleteLoopbackReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDeleteLoopbackReply() api.Message { - return &DeleteLoopbackReply{} -} // CollectDetailedInterfaceStats represents the VPP binary API message 'collect_detailed_interface_stats'. -// Generated from 'interface.api.json', line 1224: // // "collect_detailed_interface_stats", // [ @@ -2419,12 +2408,8 @@ func (*CollectDetailedInterfaceStats) GetCrcString() string { func (*CollectDetailedInterfaceStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewCollectDetailedInterfaceStats() api.Message { - return &CollectDetailedInterfaceStats{} -} // CollectDetailedInterfaceStatsReply represents the VPP binary API message 'collect_detailed_interface_stats_reply'. -// Generated from 'interface.api.json', line 1250: // // "collect_detailed_interface_stats_reply", // [ @@ -2456,14 +2441,12 @@ func (*CollectDetailedInterfaceStatsReply) GetCrcString() string { func (*CollectDetailedInterfaceStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewCollectDetailedInterfaceStatsReply() api.Message { - return &CollectDetailedInterfaceStatsReply{} -} /* Services */ type Services interface { DumpSwInterface(*SwInterfaceDump) (*SwInterfaceDetails, error) + DumpSwInterfaceRxPlacement(*SwInterfaceRxPlacementDump) (*SwInterfaceRxPlacementDetails, error) CollectDetailedInterfaceStats(*CollectDetailedInterfaceStats) (*CollectDetailedInterfaceStatsReply, error) CreateLoopback(*CreateLoopback) (*CreateLoopbackReply, error) CreateLoopbackInstance(*CreateLoopbackInstance) (*CreateLoopbackInstanceReply, error) @@ -2482,6 +2465,7 @@ type Services interface { SwInterfaceSetMacAddress(*SwInterfaceSetMacAddress) (*SwInterfaceSetMacAddressReply, error) SwInterfaceSetMtu(*SwInterfaceSetMtu) (*SwInterfaceSetMtuReply, error) SwInterfaceSetRxMode(*SwInterfaceSetRxMode) (*SwInterfaceSetRxModeReply, error) + SwInterfaceSetRxPlacement(*SwInterfaceSetRxPlacement) (*SwInterfaceSetRxPlacementReply, error) SwInterfaceSetTable(*SwInterfaceSetTable) (*SwInterfaceSetTableReply, error) SwInterfaceSetUnnumbered(*SwInterfaceSetUnnumbered) (*SwInterfaceSetUnnumberedReply, error) SwInterfaceTagAddDel(*SwInterfaceTagAddDel) (*SwInterfaceTagAddDelReply, error) @@ -2520,6 +2504,10 @@ func init() { api.RegisterMessage((*SwInterfaceGetMacAddressReply)(nil), "interface.SwInterfaceGetMacAddressReply") api.RegisterMessage((*SwInterfaceSetRxMode)(nil), "interface.SwInterfaceSetRxMode") api.RegisterMessage((*SwInterfaceSetRxModeReply)(nil), "interface.SwInterfaceSetRxModeReply") + api.RegisterMessage((*SwInterfaceSetRxPlacement)(nil), "interface.SwInterfaceSetRxPlacement") + api.RegisterMessage((*SwInterfaceSetRxPlacementReply)(nil), "interface.SwInterfaceSetRxPlacementReply") + api.RegisterMessage((*SwInterfaceRxPlacementDump)(nil), "interface.SwInterfaceRxPlacementDump") + api.RegisterMessage((*SwInterfaceRxPlacementDetails)(nil), "interface.SwInterfaceRxPlacementDetails") api.RegisterMessage((*InterfaceNameRenumber)(nil), "interface.InterfaceNameRenumber") api.RegisterMessage((*InterfaceNameRenumberReply)(nil), "interface.InterfaceNameRenumberReply") api.RegisterMessage((*CreateSubif)(nil), "interface.CreateSubif") diff --git a/plugins/vpp/binapi/interfaces/pkgreflect.go b/plugins/vpp/binapi/interfaces/pkgreflect.go deleted file mode 100644 index 7f75cecba5..0000000000 --- a/plugins/vpp/binapi/interfaces/pkgreflect.go +++ /dev/null @@ -1,116 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package interfaces - -import "reflect" - -var Types = map[string]reflect.Type{ - "CollectDetailedInterfaceStats": reflect.TypeOf((*CollectDetailedInterfaceStats)(nil)).Elem(), - "CollectDetailedInterfaceStatsReply": reflect.TypeOf((*CollectDetailedInterfaceStatsReply)(nil)).Elem(), - "CreateLoopback": reflect.TypeOf((*CreateLoopback)(nil)).Elem(), - "CreateLoopbackInstance": reflect.TypeOf((*CreateLoopbackInstance)(nil)).Elem(), - "CreateLoopbackInstanceReply": reflect.TypeOf((*CreateLoopbackInstanceReply)(nil)).Elem(), - "CreateLoopbackReply": reflect.TypeOf((*CreateLoopbackReply)(nil)).Elem(), - "CreateSubif": reflect.TypeOf((*CreateSubif)(nil)).Elem(), - "CreateSubifReply": reflect.TypeOf((*CreateSubifReply)(nil)).Elem(), - "CreateVlanSubif": reflect.TypeOf((*CreateVlanSubif)(nil)).Elem(), - "CreateVlanSubifReply": reflect.TypeOf((*CreateVlanSubifReply)(nil)).Elem(), - "DeleteLoopback": reflect.TypeOf((*DeleteLoopback)(nil)).Elem(), - "DeleteLoopbackReply": reflect.TypeOf((*DeleteLoopbackReply)(nil)).Elem(), - "DeleteSubif": reflect.TypeOf((*DeleteSubif)(nil)).Elem(), - "DeleteSubifReply": reflect.TypeOf((*DeleteSubifReply)(nil)).Elem(), - "HwInterfaceSetMtu": reflect.TypeOf((*HwInterfaceSetMtu)(nil)).Elem(), - "HwInterfaceSetMtuReply": reflect.TypeOf((*HwInterfaceSetMtuReply)(nil)).Elem(), - "InterfaceNameRenumber": reflect.TypeOf((*InterfaceNameRenumber)(nil)).Elem(), - "InterfaceNameRenumberReply": reflect.TypeOf((*InterfaceNameRenumberReply)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SwInterfaceAddDelAddress": reflect.TypeOf((*SwInterfaceAddDelAddress)(nil)).Elem(), - "SwInterfaceAddDelAddressReply": reflect.TypeOf((*SwInterfaceAddDelAddressReply)(nil)).Elem(), - "SwInterfaceClearStats": reflect.TypeOf((*SwInterfaceClearStats)(nil)).Elem(), - "SwInterfaceClearStatsReply": reflect.TypeOf((*SwInterfaceClearStatsReply)(nil)).Elem(), - "SwInterfaceDetails": reflect.TypeOf((*SwInterfaceDetails)(nil)).Elem(), - "SwInterfaceDump": reflect.TypeOf((*SwInterfaceDump)(nil)).Elem(), - "SwInterfaceEvent": reflect.TypeOf((*SwInterfaceEvent)(nil)).Elem(), - "SwInterfaceGetMacAddress": reflect.TypeOf((*SwInterfaceGetMacAddress)(nil)).Elem(), - "SwInterfaceGetMacAddressReply": reflect.TypeOf((*SwInterfaceGetMacAddressReply)(nil)).Elem(), - "SwInterfaceGetTable": reflect.TypeOf((*SwInterfaceGetTable)(nil)).Elem(), - "SwInterfaceGetTableReply": reflect.TypeOf((*SwInterfaceGetTableReply)(nil)).Elem(), - "SwInterfaceSetFlags": reflect.TypeOf((*SwInterfaceSetFlags)(nil)).Elem(), - "SwInterfaceSetFlagsReply": reflect.TypeOf((*SwInterfaceSetFlagsReply)(nil)).Elem(), - "SwInterfaceSetIPDirectedBroadcast": reflect.TypeOf((*SwInterfaceSetIPDirectedBroadcast)(nil)).Elem(), - "SwInterfaceSetIPDirectedBroadcastReply": reflect.TypeOf((*SwInterfaceSetIPDirectedBroadcastReply)(nil)).Elem(), - "SwInterfaceSetMacAddress": reflect.TypeOf((*SwInterfaceSetMacAddress)(nil)).Elem(), - "SwInterfaceSetMacAddressReply": reflect.TypeOf((*SwInterfaceSetMacAddressReply)(nil)).Elem(), - "SwInterfaceSetMtu": reflect.TypeOf((*SwInterfaceSetMtu)(nil)).Elem(), - "SwInterfaceSetMtuReply": reflect.TypeOf((*SwInterfaceSetMtuReply)(nil)).Elem(), - "SwInterfaceSetRxMode": reflect.TypeOf((*SwInterfaceSetRxMode)(nil)).Elem(), - "SwInterfaceSetRxModeReply": reflect.TypeOf((*SwInterfaceSetRxModeReply)(nil)).Elem(), - "SwInterfaceSetTable": reflect.TypeOf((*SwInterfaceSetTable)(nil)).Elem(), - "SwInterfaceSetTableReply": reflect.TypeOf((*SwInterfaceSetTableReply)(nil)).Elem(), - "SwInterfaceSetUnnumbered": reflect.TypeOf((*SwInterfaceSetUnnumbered)(nil)).Elem(), - "SwInterfaceSetUnnumberedReply": reflect.TypeOf((*SwInterfaceSetUnnumberedReply)(nil)).Elem(), - "SwInterfaceTagAddDel": reflect.TypeOf((*SwInterfaceTagAddDel)(nil)).Elem(), - "SwInterfaceTagAddDelReply": reflect.TypeOf((*SwInterfaceTagAddDelReply)(nil)).Elem(), - "VlibCounter": reflect.TypeOf((*VlibCounter)(nil)).Elem(), - "VnetCombinedCounter": reflect.TypeOf((*VnetCombinedCounter)(nil)).Elem(), - "VnetSimpleCounter": reflect.TypeOf((*VnetSimpleCounter)(nil)).Elem(), - "WantInterfaceEvents": reflect.TypeOf((*WantInterfaceEvents)(nil)).Elem(), - "WantInterfaceEventsReply": reflect.TypeOf((*WantInterfaceEventsReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewCollectDetailedInterfaceStats": reflect.ValueOf(NewCollectDetailedInterfaceStats), - "NewCollectDetailedInterfaceStatsReply": reflect.ValueOf(NewCollectDetailedInterfaceStatsReply), - "NewCreateLoopback": reflect.ValueOf(NewCreateLoopback), - "NewCreateLoopbackInstance": reflect.ValueOf(NewCreateLoopbackInstance), - "NewCreateLoopbackInstanceReply": reflect.ValueOf(NewCreateLoopbackInstanceReply), - "NewCreateLoopbackReply": reflect.ValueOf(NewCreateLoopbackReply), - "NewCreateSubif": reflect.ValueOf(NewCreateSubif), - "NewCreateSubifReply": reflect.ValueOf(NewCreateSubifReply), - "NewCreateVlanSubif": reflect.ValueOf(NewCreateVlanSubif), - "NewCreateVlanSubifReply": reflect.ValueOf(NewCreateVlanSubifReply), - "NewDeleteLoopback": reflect.ValueOf(NewDeleteLoopback), - "NewDeleteLoopbackReply": reflect.ValueOf(NewDeleteLoopbackReply), - "NewDeleteSubif": reflect.ValueOf(NewDeleteSubif), - "NewDeleteSubifReply": reflect.ValueOf(NewDeleteSubifReply), - "NewHwInterfaceSetMtu": reflect.ValueOf(NewHwInterfaceSetMtu), - "NewHwInterfaceSetMtuReply": reflect.ValueOf(NewHwInterfaceSetMtuReply), - "NewInterfaceNameRenumber": reflect.ValueOf(NewInterfaceNameRenumber), - "NewInterfaceNameRenumberReply": reflect.ValueOf(NewInterfaceNameRenumberReply), - "NewSwInterfaceAddDelAddress": reflect.ValueOf(NewSwInterfaceAddDelAddress), - "NewSwInterfaceAddDelAddressReply": reflect.ValueOf(NewSwInterfaceAddDelAddressReply), - "NewSwInterfaceClearStats": reflect.ValueOf(NewSwInterfaceClearStats), - "NewSwInterfaceClearStatsReply": reflect.ValueOf(NewSwInterfaceClearStatsReply), - "NewSwInterfaceDetails": reflect.ValueOf(NewSwInterfaceDetails), - "NewSwInterfaceDump": reflect.ValueOf(NewSwInterfaceDump), - "NewSwInterfaceEvent": reflect.ValueOf(NewSwInterfaceEvent), - "NewSwInterfaceGetMacAddress": reflect.ValueOf(NewSwInterfaceGetMacAddress), - "NewSwInterfaceGetMacAddressReply": reflect.ValueOf(NewSwInterfaceGetMacAddressReply), - "NewSwInterfaceGetTable": reflect.ValueOf(NewSwInterfaceGetTable), - "NewSwInterfaceGetTableReply": reflect.ValueOf(NewSwInterfaceGetTableReply), - "NewSwInterfaceSetFlags": reflect.ValueOf(NewSwInterfaceSetFlags), - "NewSwInterfaceSetFlagsReply": reflect.ValueOf(NewSwInterfaceSetFlagsReply), - "NewSwInterfaceSetIPDirectedBroadcast": reflect.ValueOf(NewSwInterfaceSetIPDirectedBroadcast), - "NewSwInterfaceSetIPDirectedBroadcastReply": reflect.ValueOf(NewSwInterfaceSetIPDirectedBroadcastReply), - "NewSwInterfaceSetMacAddress": reflect.ValueOf(NewSwInterfaceSetMacAddress), - "NewSwInterfaceSetMacAddressReply": reflect.ValueOf(NewSwInterfaceSetMacAddressReply), - "NewSwInterfaceSetMtu": reflect.ValueOf(NewSwInterfaceSetMtu), - "NewSwInterfaceSetMtuReply": reflect.ValueOf(NewSwInterfaceSetMtuReply), - "NewSwInterfaceSetRxMode": reflect.ValueOf(NewSwInterfaceSetRxMode), - "NewSwInterfaceSetRxModeReply": reflect.ValueOf(NewSwInterfaceSetRxModeReply), - "NewSwInterfaceSetTable": reflect.ValueOf(NewSwInterfaceSetTable), - "NewSwInterfaceSetTableReply": reflect.ValueOf(NewSwInterfaceSetTableReply), - "NewSwInterfaceSetUnnumbered": reflect.ValueOf(NewSwInterfaceSetUnnumbered), - "NewSwInterfaceSetUnnumberedReply": reflect.ValueOf(NewSwInterfaceSetUnnumberedReply), - "NewSwInterfaceTagAddDel": reflect.ValueOf(NewSwInterfaceTagAddDel), - "NewSwInterfaceTagAddDelReply": reflect.ValueOf(NewSwInterfaceTagAddDelReply), - "NewWantInterfaceEvents": reflect.ValueOf(NewWantInterfaceEvents), - "NewWantInterfaceEventsReply": reflect.ValueOf(NewWantInterfaceEventsReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/ip/ip.ba.go b/plugins/vpp/binapi/ip/ip.ba.go index bb4d982263..24744bfe21 100644 --- a/plugins/vpp/binapi/ip/ip.ba.go +++ b/plugins/vpp/binapi/ip/ip.ba.go @@ -1,18 +1,16 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/ip.api.json +// source: /usr/share/vpp/api/ip.api.json /* -Package ip is a generated VPP binary API of the 'ip' VPP module. + Package ip is a generated from VPP binary API module 'ip'. -It is generated from this file: - ip.api.json + It contains following objects: + 87 messages + 10 types + 1 enum + 1 union + 42 services -It contains these VPP binary API objects: - 87 messages - 9 types - 1 enum - 1 union - 42 services */ package ip @@ -21,13 +19,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Enums */ // AddressFamily represents the VPP binary API enum 'address_family'. -// Generated from 'ip.api.json', line 2727: // // "address_family", // [ @@ -52,7 +50,6 @@ const ( /* Types */ // IP4Address represents the VPP binary API type 'ip4_address'. -// Generated from 'ip.api.json', line 2743: // // "ip4_address", // [ @@ -76,7 +73,6 @@ func (*IP4Address) GetCrcString() string { } // IP6Address represents the VPP binary API type 'ip6_address'. -// Generated from 'ip.api.json', line 2754: // // "ip6_address", // [ @@ -100,7 +96,6 @@ func (*IP6Address) GetCrcString() string { } // Address represents the VPP binary API type 'address'. -// Generated from 'ip.api.json', line 2765: // // "address", // [ @@ -128,7 +123,6 @@ func (*Address) GetCrcString() string { } // Prefix represents the VPP binary API type 'prefix'. -// Generated from 'ip.api.json', line 2779: // // "prefix", // [ @@ -156,7 +150,6 @@ func (*Prefix) GetCrcString() string { } // Mprefix represents the VPP binary API type 'mprefix'. -// Generated from 'ip.api.json', line 2793: // // "mprefix", // [ @@ -194,7 +187,6 @@ func (*Mprefix) GetCrcString() string { } // FibMplsLabel represents the VPP binary API type 'fib_mpls_label'. -// Generated from 'ip.api.json', line 2815: // // "fib_mpls_label", // [ @@ -232,7 +224,6 @@ func (*FibMplsLabel) GetCrcString() string { } // FibPath represents the VPP binary API type 'fib_path'. -// Generated from 'ip.api.json', line 2837: // // "fib_path", // [ @@ -351,8 +342,30 @@ func (*FibPath) GetCrcString() string { return "abe483ef" } +// MacAddress represents the VPP binary API type 'mac_address'. +// +// "mac_address", +// [ +// "u8", +// "bytes", +// 6 +// ], +// { +// "crc": "0xefdbdddc" +// } +// +type MacAddress struct { + Bytes []byte `struc:"[6]byte"` +} + +func (*MacAddress) GetTypeName() string { + return "mac_address" +} +func (*MacAddress) GetCrcString() string { + return "efdbdddc" +} + // IP6RaPrefixInfo represents the VPP binary API type 'ip6_ra_prefix_info'. -// Generated from 'ip.api.json', line 2925: // // "ip6_ra_prefix_info", // [ @@ -396,7 +409,6 @@ func (*IP6RaPrefixInfo) GetCrcString() string { } // ProxyArp represents the VPP binary API type 'proxy_arp'. -// Generated from 'ip.api.json', line 2952: // // "proxy_arp", // [ @@ -433,7 +445,6 @@ func (*ProxyArp) GetCrcString() string { /* Unions */ // AddressUnion represents the VPP binary API union 'address_union'. -// Generated from 'ip.api.json', line 2562: // // "address_union", // [ @@ -488,7 +499,6 @@ func (u *AddressUnion) GetIP6() (a IP6Address) { /* Messages */ // IPTableAddDel represents the VPP binary API message 'ip_table_add_del'. -// Generated from 'ip.api.json', line 4: // // "ip_table_add_del", // [ @@ -540,12 +550,8 @@ func (*IPTableAddDel) GetCrcString() string { func (*IPTableAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPTableAddDel() api.Message { - return &IPTableAddDel{} -} // IPTableAddDelReply represents the VPP binary API message 'ip_table_add_del_reply'. -// Generated from 'ip.api.json', line 39: // // "ip_table_add_del_reply", // [ @@ -577,12 +583,8 @@ func (*IPTableAddDelReply) GetCrcString() string { func (*IPTableAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPTableAddDelReply() api.Message { - return &IPTableAddDelReply{} -} // IPFibDump represents the VPP binary API message 'ip_fib_dump'. -// Generated from 'ip.api.json', line 57: // // "ip_fib_dump", // [ @@ -612,12 +614,8 @@ func (*IPFibDump) GetCrcString() string { func (*IPFibDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPFibDump() api.Message { - return &IPFibDump{} -} // IPFibDetails represents the VPP binary API message 'ip_fib_details'. -// Generated from 'ip.api.json', line 75: // // "ip_fib_details", // [ @@ -651,13 +649,17 @@ func NewIPFibDump() api.Message { // "count" // ], // [ +// "u32", +// "stats_index" +// ], +// [ // "vl_api_fib_path_t", // "path", // 0, // "count" // ], // { -// "crc": "0x99dfd73b" +// "crc": "0xf6a2fab3" // } // type IPFibDetails struct { @@ -666,6 +668,7 @@ type IPFibDetails struct { AddressLength uint8 Address []byte `struc:"[4]byte"` Count uint32 `struc:"sizeof=Path"` + StatsIndex uint32 Path []FibPath } @@ -673,17 +676,13 @@ func (*IPFibDetails) GetMessageName() string { return "ip_fib_details" } func (*IPFibDetails) GetCrcString() string { - return "99dfd73b" + return "f6a2fab3" } func (*IPFibDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPFibDetails() api.Message { - return &IPFibDetails{} -} // IP6FibDump represents the VPP binary API message 'ip6_fib_dump'. -// Generated from 'ip.api.json', line 117: // // "ip6_fib_dump", // [ @@ -713,12 +712,8 @@ func (*IP6FibDump) GetCrcString() string { func (*IP6FibDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIP6FibDump() api.Message { - return &IP6FibDump{} -} // IP6FibDetails represents the VPP binary API message 'ip6_fib_details'. -// Generated from 'ip.api.json', line 135: // // "ip6_fib_details", // [ @@ -752,13 +747,17 @@ func NewIP6FibDump() api.Message { // "count" // ], // [ +// "u32", +// "stats_index" +// ], +// [ // "vl_api_fib_path_t", // "path", // 0, // "count" // ], // { -// "crc": "0xabd0060e" +// "crc": "0xef11e94d" // } // type IP6FibDetails struct { @@ -767,6 +766,7 @@ type IP6FibDetails struct { AddressLength uint8 Address []byte `struc:"[16]byte"` Count uint32 `struc:"sizeof=Path"` + StatsIndex uint32 Path []FibPath } @@ -774,17 +774,13 @@ func (*IP6FibDetails) GetMessageName() string { return "ip6_fib_details" } func (*IP6FibDetails) GetCrcString() string { - return "abd0060e" + return "ef11e94d" } func (*IP6FibDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIP6FibDetails() api.Message { - return &IP6FibDetails{} -} // IPNeighborDump represents the VPP binary API message 'ip_neighbor_dump'. -// Generated from 'ip.api.json', line 177: // // "ip_neighbor_dump", // [ @@ -825,12 +821,8 @@ func (*IPNeighborDump) GetCrcString() string { func (*IPNeighborDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPNeighborDump() api.Message { - return &IPNeighborDump{} -} // IPNeighborDetails represents the VPP binary API message 'ip_neighbor_details'. -// Generated from 'ip.api.json', line 203: // // "ip_neighbor_details", // [ @@ -884,12 +876,8 @@ func (*IPNeighborDetails) GetCrcString() string { func (*IPNeighborDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPNeighborDetails() api.Message { - return &IPNeighborDetails{} -} // IPNeighborAddDel represents the VPP binary API message 'ip_neighbor_add_del'. -// Generated from 'ip.api.json', line 239: // // "ip_neighbor_add_del", // [ @@ -957,12 +945,8 @@ func (*IPNeighborAddDel) GetCrcString() string { func (*IPNeighborAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPNeighborAddDel() api.Message { - return &IPNeighborAddDel{} -} // IPNeighborAddDelReply represents the VPP binary API message 'ip_neighbor_add_del_reply'. -// Generated from 'ip.api.json', line 287: // // "ip_neighbor_add_del_reply", // [ @@ -994,12 +978,8 @@ func (*IPNeighborAddDelReply) GetCrcString() string { func (*IPNeighborAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPNeighborAddDelReply() api.Message { - return &IPNeighborAddDelReply{} -} // SetIPFlowHash represents the VPP binary API message 'set_ip_flow_hash'. -// Generated from 'ip.api.json', line 305: // // "set_ip_flow_hash", // [ @@ -1070,12 +1050,8 @@ func (*SetIPFlowHash) GetCrcString() string { func (*SetIPFlowHash) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSetIPFlowHash() api.Message { - return &SetIPFlowHash{} -} // SetIPFlowHashReply represents the VPP binary API message 'set_ip_flow_hash_reply'. -// Generated from 'ip.api.json', line 355: // // "set_ip_flow_hash_reply", // [ @@ -1107,12 +1083,8 @@ func (*SetIPFlowHashReply) GetCrcString() string { func (*SetIPFlowHashReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSetIPFlowHashReply() api.Message { - return &SetIPFlowHashReply{} -} // SwInterfaceIP6ndRaConfig represents the VPP binary API message 'sw_interface_ip6nd_ra_config'. -// Generated from 'ip.api.json', line 373: // // "sw_interface_ip6nd_ra_config", // [ @@ -1213,12 +1185,8 @@ func (*SwInterfaceIP6ndRaConfig) GetCrcString() string { func (*SwInterfaceIP6ndRaConfig) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceIP6ndRaConfig() api.Message { - return &SwInterfaceIP6ndRaConfig{} -} // SwInterfaceIP6ndRaConfigReply represents the VPP binary API message 'sw_interface_ip6nd_ra_config_reply'. -// Generated from 'ip.api.json', line 447: // // "sw_interface_ip6nd_ra_config_reply", // [ @@ -1250,12 +1218,8 @@ func (*SwInterfaceIP6ndRaConfigReply) GetCrcString() string { func (*SwInterfaceIP6ndRaConfigReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceIP6ndRaConfigReply() api.Message { - return &SwInterfaceIP6ndRaConfigReply{} -} // SwInterfaceIP6ndRaPrefix represents the VPP binary API message 'sw_interface_ip6nd_ra_prefix'. -// Generated from 'ip.api.json', line 465: // // "sw_interface_ip6nd_ra_prefix", // [ @@ -1342,12 +1306,8 @@ func (*SwInterfaceIP6ndRaPrefix) GetCrcString() string { func (*SwInterfaceIP6ndRaPrefix) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceIP6ndRaPrefix() api.Message { - return &SwInterfaceIP6ndRaPrefix{} -} // SwInterfaceIP6ndRaPrefixReply represents the VPP binary API message 'sw_interface_ip6nd_ra_prefix_reply'. -// Generated from 'ip.api.json', line 528: // // "sw_interface_ip6nd_ra_prefix_reply", // [ @@ -1379,12 +1339,8 @@ func (*SwInterfaceIP6ndRaPrefixReply) GetCrcString() string { func (*SwInterfaceIP6ndRaPrefixReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceIP6ndRaPrefixReply() api.Message { - return &SwInterfaceIP6ndRaPrefixReply{} -} // IP6ndProxyAddDel represents the VPP binary API message 'ip6nd_proxy_add_del'. -// Generated from 'ip.api.json', line 546: // // "ip6nd_proxy_add_del", // [ @@ -1431,12 +1387,8 @@ func (*IP6ndProxyAddDel) GetCrcString() string { func (*IP6ndProxyAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIP6ndProxyAddDel() api.Message { - return &IP6ndProxyAddDel{} -} // IP6ndProxyAddDelReply represents the VPP binary API message 'ip6nd_proxy_add_del_reply'. -// Generated from 'ip.api.json', line 577: // // "ip6nd_proxy_add_del_reply", // [ @@ -1468,12 +1420,8 @@ func (*IP6ndProxyAddDelReply) GetCrcString() string { func (*IP6ndProxyAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIP6ndProxyAddDelReply() api.Message { - return &IP6ndProxyAddDelReply{} -} // IP6ndProxyDetails represents the VPP binary API message 'ip6nd_proxy_details'. -// Generated from 'ip.api.json', line 595: // // "ip6nd_proxy_details", // [ @@ -1482,10 +1430,6 @@ func NewIP6ndProxyAddDelReply() api.Message { // ], // [ // "u32", -// "client_index" -// ], -// [ -// "u32", // "context" // ], // [ @@ -1498,7 +1442,7 @@ func NewIP6ndProxyAddDelReply() api.Message { // 16 // ], // { -// "crc": "0xd73bf1ab" +// "crc": "0x6a47c974" // } // type IP6ndProxyDetails struct { @@ -1510,17 +1454,13 @@ func (*IP6ndProxyDetails) GetMessageName() string { return "ip6nd_proxy_details" } func (*IP6ndProxyDetails) GetCrcString() string { - return "d73bf1ab" + return "6a47c974" } func (*IP6ndProxyDetails) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewIP6ndProxyDetails() api.Message { - return &IP6ndProxyDetails{} + return api.ReplyMessage } // IP6ndProxyDump represents the VPP binary API message 'ip6nd_proxy_dump'. -// Generated from 'ip.api.json', line 622: // // "ip6nd_proxy_dump", // [ @@ -1550,12 +1490,8 @@ func (*IP6ndProxyDump) GetCrcString() string { func (*IP6ndProxyDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIP6ndProxyDump() api.Message { - return &IP6ndProxyDump{} -} // IP6ndSendRouterSolicitation represents the VPP binary API message 'ip6nd_send_router_solicitation'. -// Generated from 'ip.api.json', line 640: // // "ip6nd_send_router_solicitation", // [ @@ -1616,12 +1552,8 @@ func (*IP6ndSendRouterSolicitation) GetCrcString() string { func (*IP6ndSendRouterSolicitation) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIP6ndSendRouterSolicitation() api.Message { - return &IP6ndSendRouterSolicitation{} -} // IP6ndSendRouterSolicitationReply represents the VPP binary API message 'ip6nd_send_router_solicitation_reply'. -// Generated from 'ip.api.json', line 682: // // "ip6nd_send_router_solicitation_reply", // [ @@ -1653,12 +1585,8 @@ func (*IP6ndSendRouterSolicitationReply) GetCrcString() string { func (*IP6ndSendRouterSolicitationReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIP6ndSendRouterSolicitationReply() api.Message { - return &IP6ndSendRouterSolicitationReply{} -} // SwInterfaceIP6EnableDisable represents the VPP binary API message 'sw_interface_ip6_enable_disable'. -// Generated from 'ip.api.json', line 700: // // "sw_interface_ip6_enable_disable", // [ @@ -1699,12 +1627,8 @@ func (*SwInterfaceIP6EnableDisable) GetCrcString() string { func (*SwInterfaceIP6EnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceIP6EnableDisable() api.Message { - return &SwInterfaceIP6EnableDisable{} -} // SwInterfaceIP6EnableDisableReply represents the VPP binary API message 'sw_interface_ip6_enable_disable_reply'. -// Generated from 'ip.api.json', line 726: // // "sw_interface_ip6_enable_disable_reply", // [ @@ -1736,12 +1660,8 @@ func (*SwInterfaceIP6EnableDisableReply) GetCrcString() string { func (*SwInterfaceIP6EnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceIP6EnableDisableReply() api.Message { - return &SwInterfaceIP6EnableDisableReply{} -} // SwInterfaceIP6SetLinkLocalAddress represents the VPP binary API message 'sw_interface_ip6_set_link_local_address'. -// Generated from 'ip.api.json', line 744: // // "sw_interface_ip6_set_link_local_address", // [ @@ -1783,12 +1703,8 @@ func (*SwInterfaceIP6SetLinkLocalAddress) GetCrcString() string { func (*SwInterfaceIP6SetLinkLocalAddress) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceIP6SetLinkLocalAddress() api.Message { - return &SwInterfaceIP6SetLinkLocalAddress{} -} // SwInterfaceIP6SetLinkLocalAddressReply represents the VPP binary API message 'sw_interface_ip6_set_link_local_address_reply'. -// Generated from 'ip.api.json', line 771: // // "sw_interface_ip6_set_link_local_address_reply", // [ @@ -1820,12 +1736,8 @@ func (*SwInterfaceIP6SetLinkLocalAddressReply) GetCrcString() string { func (*SwInterfaceIP6SetLinkLocalAddressReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceIP6SetLinkLocalAddressReply() api.Message { - return &SwInterfaceIP6SetLinkLocalAddressReply{} -} // IPAddDelRoute represents the VPP binary API message 'ip_add_del_route'. -// Generated from 'ip.api.json', line 789: // // "ip_add_del_route", // [ @@ -1995,12 +1907,8 @@ func (*IPAddDelRoute) GetCrcString() string { func (*IPAddDelRoute) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPAddDelRoute() api.Message { - return &IPAddDelRoute{} -} // IPAddDelRouteReply represents the VPP binary API message 'ip_add_del_route_reply'. -// Generated from 'ip.api.json', line 919: // // "ip_add_del_route_reply", // [ @@ -2015,29 +1923,30 @@ func NewIPAddDelRoute() api.Message { // "i32", // "retval" // ], +// [ +// "u32", +// "stats_index" +// ], // { -// "crc": "0xe8d4e804" +// "crc": "0x1992deab" // } // type IPAddDelRouteReply struct { - Retval int32 + Retval int32 + StatsIndex uint32 } func (*IPAddDelRouteReply) GetMessageName() string { return "ip_add_del_route_reply" } func (*IPAddDelRouteReply) GetCrcString() string { - return "e8d4e804" + return "1992deab" } func (*IPAddDelRouteReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPAddDelRouteReply() api.Message { - return &IPAddDelRouteReply{} -} // IPMrouteAddDel represents the VPP binary API message 'ip_mroute_add_del'. -// Generated from 'ip.api.json', line 937: // // "ip_mroute_add_del", // [ @@ -2141,12 +2050,8 @@ func (*IPMrouteAddDel) GetCrcString() string { func (*IPMrouteAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPMrouteAddDel() api.Message { - return &IPMrouteAddDel{} -} // IPMrouteAddDelReply represents the VPP binary API message 'ip_mroute_add_del_reply'. -// Generated from 'ip.api.json', line 1014: // // "ip_mroute_add_del_reply", // [ @@ -2178,12 +2083,8 @@ func (*IPMrouteAddDelReply) GetCrcString() string { func (*IPMrouteAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPMrouteAddDelReply() api.Message { - return &IPMrouteAddDelReply{} -} // IPMfibDump represents the VPP binary API message 'ip_mfib_dump'. -// Generated from 'ip.api.json', line 1032: // // "ip_mfib_dump", // [ @@ -2213,12 +2114,8 @@ func (*IPMfibDump) GetCrcString() string { func (*IPMfibDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPMfibDump() api.Message { - return &IPMfibDump{} -} // IPMfibDetails represents the VPP binary API message 'ip_mfib_details'. -// Generated from 'ip.api.json', line 1050: // // "ip_mfib_details", // [ @@ -2289,12 +2186,8 @@ func (*IPMfibDetails) GetCrcString() string { func (*IPMfibDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPMfibDetails() api.Message { - return &IPMfibDetails{} -} // IP6MfibDump represents the VPP binary API message 'ip6_mfib_dump'. -// Generated from 'ip.api.json', line 1100: // // "ip6_mfib_dump", // [ @@ -2324,12 +2217,8 @@ func (*IP6MfibDump) GetCrcString() string { func (*IP6MfibDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIP6MfibDump() api.Message { - return &IP6MfibDump{} -} // IP6MfibDetails represents the VPP binary API message 'ip6_mfib_details'. -// Generated from 'ip.api.json', line 1118: // // "ip6_mfib_details", // [ @@ -2390,12 +2279,8 @@ func (*IP6MfibDetails) GetCrcString() string { func (*IP6MfibDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIP6MfibDetails() api.Message { - return &IP6MfibDetails{} -} // IPAddressDetails represents the VPP binary API message 'ip_address_details'. -// Generated from 'ip.api.json', line 1160: // // "ip_address_details", // [ @@ -2404,10 +2289,6 @@ func NewIP6MfibDetails() api.Message { // ], // [ // "u32", -// "client_index" -// ], -// [ -// "u32", // "context" // ], // [ @@ -2428,7 +2309,7 @@ func NewIP6MfibDetails() api.Message { // "is_ipv6" // ], // { -// "crc": "0xbc7442f2" +// "crc": "0x9bc25966" // } // type IPAddressDetails struct { @@ -2442,17 +2323,13 @@ func (*IPAddressDetails) GetMessageName() string { return "ip_address_details" } func (*IPAddressDetails) GetCrcString() string { - return "bc7442f2" + return "9bc25966" } func (*IPAddressDetails) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewIPAddressDetails() api.Message { - return &IPAddressDetails{} + return api.ReplyMessage } // IPAddressDump represents the VPP binary API message 'ip_address_dump'. -// Generated from 'ip.api.json', line 1195: // // "ip_address_dump", // [ @@ -2493,12 +2370,8 @@ func (*IPAddressDump) GetCrcString() string { func (*IPAddressDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPAddressDump() api.Message { - return &IPAddressDump{} -} // IPUnnumberedDetails represents the VPP binary API message 'ip_unnumbered_details'. -// Generated from 'ip.api.json', line 1221: // // "ip_unnumbered_details", // [ @@ -2507,10 +2380,6 @@ func NewIPAddressDump() api.Message { // ], // [ // "u32", -// "client_index" -// ], -// [ -// "u32", // "context" // ], // [ @@ -2522,7 +2391,7 @@ func NewIPAddressDump() api.Message { // "ip_sw_if_index" // ], // { -// "crc": "0x05b717ca" +// "crc": "0xae694cf4" // } // type IPUnnumberedDetails struct { @@ -2534,17 +2403,13 @@ func (*IPUnnumberedDetails) GetMessageName() string { return "ip_unnumbered_details" } func (*IPUnnumberedDetails) GetCrcString() string { - return "05b717ca" + return "ae694cf4" } func (*IPUnnumberedDetails) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewIPUnnumberedDetails() api.Message { - return &IPUnnumberedDetails{} + return api.ReplyMessage } // IPUnnumberedDump represents the VPP binary API message 'ip_unnumbered_dump'. -// Generated from 'ip.api.json', line 1247: // // "ip_unnumbered_dump", // [ @@ -2580,12 +2445,8 @@ func (*IPUnnumberedDump) GetCrcString() string { func (*IPUnnumberedDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPUnnumberedDump() api.Message { - return &IPUnnumberedDump{} -} // IPDetails represents the VPP binary API message 'ip_details'. -// Generated from 'ip.api.json', line 1269: // // "ip_details", // [ @@ -2622,12 +2483,8 @@ func (*IPDetails) GetCrcString() string { func (*IPDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPDetails() api.Message { - return &IPDetails{} -} // IPDump represents the VPP binary API message 'ip_dump'. -// Generated from 'ip.api.json', line 1291: // // "ip_dump", // [ @@ -2663,12 +2520,8 @@ func (*IPDump) GetCrcString() string { func (*IPDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPDump() api.Message { - return &IPDump{} -} // MfibSignalDump represents the VPP binary API message 'mfib_signal_dump'. -// Generated from 'ip.api.json', line 1313: // // "mfib_signal_dump", // [ @@ -2698,12 +2551,8 @@ func (*MfibSignalDump) GetCrcString() string { func (*MfibSignalDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMfibSignalDump() api.Message { - return &MfibSignalDump{} -} // MfibSignalDetails represents the VPP binary API message 'mfib_signal_details'. -// Generated from 'ip.api.json', line 1331: // // "mfib_signal_details", // [ @@ -2712,10 +2561,6 @@ func NewMfibSignalDump() api.Message { // ], // [ // "u32", -// "client_index" -// ], -// [ -// "u32", // "context" // ], // [ @@ -2750,7 +2595,7 @@ func NewMfibSignalDump() api.Message { // 256 // ], // { -// "crc": "0x791bbeab" +// "crc": "0x3f5f03f5" // } // type MfibSignalDetails struct { @@ -2767,17 +2612,13 @@ func (*MfibSignalDetails) GetMessageName() string { return "mfib_signal_details" } func (*MfibSignalDetails) GetCrcString() string { - return "791bbeab" + return "3f5f03f5" } func (*MfibSignalDetails) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewMfibSignalDetails() api.Message { - return &MfibSignalDetails{} + return api.ReplyMessage } // IPPuntPolice represents the VPP binary API message 'ip_punt_police'. -// Generated from 'ip.api.json', line 1380: // // "ip_punt_police", // [ @@ -2823,12 +2664,8 @@ func (*IPPuntPolice) GetCrcString() string { func (*IPPuntPolice) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPPuntPolice() api.Message { - return &IPPuntPolice{} -} // IPPuntPoliceReply represents the VPP binary API message 'ip_punt_police_reply'. -// Generated from 'ip.api.json', line 1410: // // "ip_punt_police_reply", // [ @@ -2860,12 +2697,8 @@ func (*IPPuntPoliceReply) GetCrcString() string { func (*IPPuntPoliceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPPuntPoliceReply() api.Message { - return &IPPuntPoliceReply{} -} // IPPuntRedirect represents the VPP binary API message 'ip_punt_redirect'. -// Generated from 'ip.api.json', line 1428: // // "ip_punt_redirect", // [ @@ -2922,12 +2755,8 @@ func (*IPPuntRedirect) GetCrcString() string { func (*IPPuntRedirect) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPPuntRedirect() api.Message { - return &IPPuntRedirect{} -} // IPPuntRedirectReply represents the VPP binary API message 'ip_punt_redirect_reply'. -// Generated from 'ip.api.json', line 1467: // // "ip_punt_redirect_reply", // [ @@ -2959,12 +2788,8 @@ func (*IPPuntRedirectReply) GetCrcString() string { func (*IPPuntRedirectReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPPuntRedirectReply() api.Message { - return &IPPuntRedirectReply{} -} // IPContainerProxyAddDel represents the VPP binary API message 'ip_container_proxy_add_del'. -// Generated from 'ip.api.json', line 1485: // // "ip_container_proxy_add_del", // [ @@ -3021,12 +2846,8 @@ func (*IPContainerProxyAddDel) GetCrcString() string { func (*IPContainerProxyAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPContainerProxyAddDel() api.Message { - return &IPContainerProxyAddDel{} -} // IPContainerProxyAddDelReply represents the VPP binary API message 'ip_container_proxy_add_del_reply'. -// Generated from 'ip.api.json', line 1524: // // "ip_container_proxy_add_del_reply", // [ @@ -3058,12 +2879,8 @@ func (*IPContainerProxyAddDelReply) GetCrcString() string { func (*IPContainerProxyAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPContainerProxyAddDelReply() api.Message { - return &IPContainerProxyAddDelReply{} -} // IPSourceAndPortRangeCheckAddDel represents the VPP binary API message 'ip_source_and_port_range_check_add_del'. -// Generated from 'ip.api.json', line 1542: // // "ip_source_and_port_range_check_add_del", // [ @@ -3137,12 +2954,8 @@ func (*IPSourceAndPortRangeCheckAddDel) GetCrcString() string { func (*IPSourceAndPortRangeCheckAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPSourceAndPortRangeCheckAddDel() api.Message { - return &IPSourceAndPortRangeCheckAddDel{} -} // IPSourceAndPortRangeCheckAddDelReply represents the VPP binary API message 'ip_source_and_port_range_check_add_del_reply'. -// Generated from 'ip.api.json', line 1595: // // "ip_source_and_port_range_check_add_del_reply", // [ @@ -3174,12 +2987,8 @@ func (*IPSourceAndPortRangeCheckAddDelReply) GetCrcString() string { func (*IPSourceAndPortRangeCheckAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPSourceAndPortRangeCheckAddDelReply() api.Message { - return &IPSourceAndPortRangeCheckAddDelReply{} -} // IPSourceAndPortRangeCheckInterfaceAddDel represents the VPP binary API message 'ip_source_and_port_range_check_interface_add_del'. -// Generated from 'ip.api.json', line 1613: // // "ip_source_and_port_range_check_interface_add_del", // [ @@ -3240,12 +3049,8 @@ func (*IPSourceAndPortRangeCheckInterfaceAddDel) GetCrcString() string { func (*IPSourceAndPortRangeCheckInterfaceAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPSourceAndPortRangeCheckInterfaceAddDel() api.Message { - return &IPSourceAndPortRangeCheckInterfaceAddDel{} -} // IPSourceAndPortRangeCheckInterfaceAddDelReply represents the VPP binary API message 'ip_source_and_port_range_check_interface_add_del_reply'. -// Generated from 'ip.api.json', line 1655: // // "ip_source_and_port_range_check_interface_add_del_reply", // [ @@ -3277,12 +3082,8 @@ func (*IPSourceAndPortRangeCheckInterfaceAddDelReply) GetCrcString() string { func (*IPSourceAndPortRangeCheckInterfaceAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPSourceAndPortRangeCheckInterfaceAddDelReply() api.Message { - return &IPSourceAndPortRangeCheckInterfaceAddDelReply{} -} // IPScanNeighborEnableDisable represents the VPP binary API message 'ip_scan_neighbor_enable_disable'. -// Generated from 'ip.api.json', line 1673: // // "ip_scan_neighbor_enable_disable", // [ @@ -3343,12 +3144,8 @@ func (*IPScanNeighborEnableDisable) GetCrcString() string { func (*IPScanNeighborEnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPScanNeighborEnableDisable() api.Message { - return &IPScanNeighborEnableDisable{} -} // IPScanNeighborEnableDisableReply represents the VPP binary API message 'ip_scan_neighbor_enable_disable_reply'. -// Generated from 'ip.api.json', line 1715: // // "ip_scan_neighbor_enable_disable_reply", // [ @@ -3380,12 +3177,8 @@ func (*IPScanNeighborEnableDisableReply) GetCrcString() string { func (*IPScanNeighborEnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPScanNeighborEnableDisableReply() api.Message { - return &IPScanNeighborEnableDisableReply{} -} // IPProbeNeighbor represents the VPP binary API message 'ip_probe_neighbor'. -// Generated from 'ip.api.json', line 1733: // // "ip_probe_neighbor", // [ @@ -3432,12 +3225,8 @@ func (*IPProbeNeighbor) GetCrcString() string { func (*IPProbeNeighbor) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPProbeNeighbor() api.Message { - return &IPProbeNeighbor{} -} // IPProbeNeighborReply represents the VPP binary API message 'ip_probe_neighbor_reply'. -// Generated from 'ip.api.json', line 1764: // // "ip_probe_neighbor_reply", // [ @@ -3469,12 +3258,8 @@ func (*IPProbeNeighborReply) GetCrcString() string { func (*IPProbeNeighborReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPProbeNeighborReply() api.Message { - return &IPProbeNeighborReply{} -} // WantIP4ArpEvents represents the VPP binary API message 'want_ip4_arp_events'. -// Generated from 'ip.api.json', line 1782: // // "want_ip4_arp_events", // [ @@ -3520,12 +3305,8 @@ func (*WantIP4ArpEvents) GetCrcString() string { func (*WantIP4ArpEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP4ArpEvents() api.Message { - return &WantIP4ArpEvents{} -} // WantIP4ArpEventsReply represents the VPP binary API message 'want_ip4_arp_events_reply'. -// Generated from 'ip.api.json', line 1812: // // "want_ip4_arp_events_reply", // [ @@ -3557,12 +3338,8 @@ func (*WantIP4ArpEventsReply) GetCrcString() string { func (*WantIP4ArpEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP4ArpEventsReply() api.Message { - return &WantIP4ArpEventsReply{} -} // IP4ArpEvent represents the VPP binary API message 'ip4_arp_event'. -// Generated from 'ip.api.json', line 1830: // // "ip4_arp_event", // [ @@ -3615,12 +3392,8 @@ func (*IP4ArpEvent) GetCrcString() string { func (*IP4ArpEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewIP4ArpEvent() api.Message { - return &IP4ArpEvent{} -} // WantIP6NdEvents represents the VPP binary API message 'want_ip6_nd_events'. -// Generated from 'ip.api.json', line 1865: // // "want_ip6_nd_events", // [ @@ -3667,12 +3440,8 @@ func (*WantIP6NdEvents) GetCrcString() string { func (*WantIP6NdEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP6NdEvents() api.Message { - return &WantIP6NdEvents{} -} // WantIP6NdEventsReply represents the VPP binary API message 'want_ip6_nd_events_reply'. -// Generated from 'ip.api.json', line 1896: // // "want_ip6_nd_events_reply", // [ @@ -3704,12 +3473,8 @@ func (*WantIP6NdEventsReply) GetCrcString() string { func (*WantIP6NdEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP6NdEventsReply() api.Message { - return &WantIP6NdEventsReply{} -} // IP6NdEvent represents the VPP binary API message 'ip6_nd_event'. -// Generated from 'ip.api.json', line 1914: // // "ip6_nd_event", // [ @@ -3763,12 +3528,8 @@ func (*IP6NdEvent) GetCrcString() string { func (*IP6NdEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewIP6NdEvent() api.Message { - return &IP6NdEvent{} -} // WantIP6RaEvents represents the VPP binary API message 'want_ip6_ra_events'. -// Generated from 'ip.api.json', line 1950: // // "want_ip6_ra_events", // [ @@ -3809,12 +3570,8 @@ func (*WantIP6RaEvents) GetCrcString() string { func (*WantIP6RaEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP6RaEvents() api.Message { - return &WantIP6RaEvents{} -} // WantIP6RaEventsReply represents the VPP binary API message 'want_ip6_ra_events_reply'. -// Generated from 'ip.api.json', line 1976: // // "want_ip6_ra_events_reply", // [ @@ -3846,12 +3603,8 @@ func (*WantIP6RaEventsReply) GetCrcString() string { func (*WantIP6RaEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP6RaEventsReply() api.Message { - return &WantIP6RaEventsReply{} -} // IP6RaEvent represents the VPP binary API message 'ip6_ra_event'. -// Generated from 'ip.api.json', line 1994: // // "ip6_ra_event", // [ @@ -3931,12 +3684,8 @@ func (*IP6RaEvent) GetCrcString() string { func (*IP6RaEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewIP6RaEvent() api.Message { - return &IP6RaEvent{} -} // ProxyArpAddDel represents the VPP binary API message 'proxy_arp_add_del'. -// Generated from 'ip.api.json', line 2051: // // "proxy_arp_add_del", // [ @@ -3977,12 +3726,8 @@ func (*ProxyArpAddDel) GetCrcString() string { func (*ProxyArpAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewProxyArpAddDel() api.Message { - return &ProxyArpAddDel{} -} // ProxyArpAddDelReply represents the VPP binary API message 'proxy_arp_add_del_reply'. -// Generated from 'ip.api.json', line 2077: // // "proxy_arp_add_del_reply", // [ @@ -4014,12 +3759,8 @@ func (*ProxyArpAddDelReply) GetCrcString() string { func (*ProxyArpAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewProxyArpAddDelReply() api.Message { - return &ProxyArpAddDelReply{} -} // ProxyArpDump represents the VPP binary API message 'proxy_arp_dump'. -// Generated from 'ip.api.json', line 2095: // // "proxy_arp_dump", // [ @@ -4049,12 +3790,8 @@ func (*ProxyArpDump) GetCrcString() string { func (*ProxyArpDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewProxyArpDump() api.Message { - return &ProxyArpDump{} -} // ProxyArpDetails represents the VPP binary API message 'proxy_arp_details'. -// Generated from 'ip.api.json', line 2113: // // "proxy_arp_details", // [ @@ -4086,12 +3823,8 @@ func (*ProxyArpDetails) GetCrcString() string { func (*ProxyArpDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewProxyArpDetails() api.Message { - return &ProxyArpDetails{} -} // ProxyArpIntfcEnableDisable represents the VPP binary API message 'proxy_arp_intfc_enable_disable'. -// Generated from 'ip.api.json', line 2131: // // "proxy_arp_intfc_enable_disable", // [ @@ -4132,12 +3865,8 @@ func (*ProxyArpIntfcEnableDisable) GetCrcString() string { func (*ProxyArpIntfcEnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewProxyArpIntfcEnableDisable() api.Message { - return &ProxyArpIntfcEnableDisable{} -} // ProxyArpIntfcEnableDisableReply represents the VPP binary API message 'proxy_arp_intfc_enable_disable_reply'. -// Generated from 'ip.api.json', line 2157: // // "proxy_arp_intfc_enable_disable_reply", // [ @@ -4169,12 +3898,8 @@ func (*ProxyArpIntfcEnableDisableReply) GetCrcString() string { func (*ProxyArpIntfcEnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewProxyArpIntfcEnableDisableReply() api.Message { - return &ProxyArpIntfcEnableDisableReply{} -} // ProxyArpIntfcDump represents the VPP binary API message 'proxy_arp_intfc_dump'. -// Generated from 'ip.api.json', line 2175: // // "proxy_arp_intfc_dump", // [ @@ -4204,12 +3929,8 @@ func (*ProxyArpIntfcDump) GetCrcString() string { func (*ProxyArpIntfcDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewProxyArpIntfcDump() api.Message { - return &ProxyArpIntfcDump{} -} // ProxyArpIntfcDetails represents the VPP binary API message 'proxy_arp_intfc_details'. -// Generated from 'ip.api.json', line 2193: // // "proxy_arp_intfc_details", // [ @@ -4241,12 +3962,8 @@ func (*ProxyArpIntfcDetails) GetCrcString() string { func (*ProxyArpIntfcDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewProxyArpIntfcDetails() api.Message { - return &ProxyArpIntfcDetails{} -} // ResetFib represents the VPP binary API message 'reset_fib'. -// Generated from 'ip.api.json', line 2211: // // "reset_fib", // [ @@ -4287,12 +4004,8 @@ func (*ResetFib) GetCrcString() string { func (*ResetFib) GetMessageType() api.MessageType { return api.RequestMessage } -func NewResetFib() api.Message { - return &ResetFib{} -} // ResetFibReply represents the VPP binary API message 'reset_fib_reply'. -// Generated from 'ip.api.json', line 2237: // // "reset_fib_reply", // [ @@ -4324,12 +4037,8 @@ func (*ResetFibReply) GetCrcString() string { func (*ResetFibReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewResetFibReply() api.Message { - return &ResetFibReply{} -} // SetArpNeighborLimit represents the VPP binary API message 'set_arp_neighbor_limit'. -// Generated from 'ip.api.json', line 2255: // // "set_arp_neighbor_limit", // [ @@ -4370,12 +4079,8 @@ func (*SetArpNeighborLimit) GetCrcString() string { func (*SetArpNeighborLimit) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSetArpNeighborLimit() api.Message { - return &SetArpNeighborLimit{} -} // SetArpNeighborLimitReply represents the VPP binary API message 'set_arp_neighbor_limit_reply'. -// Generated from 'ip.api.json', line 2281: // // "set_arp_neighbor_limit_reply", // [ @@ -4407,12 +4112,8 @@ func (*SetArpNeighborLimitReply) GetCrcString() string { func (*SetArpNeighborLimitReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSetArpNeighborLimitReply() api.Message { - return &SetArpNeighborLimitReply{} -} // IoamEnable represents the VPP binary API message 'ioam_enable'. -// Generated from 'ip.api.json', line 2299: // // "ioam_enable", // [ @@ -4473,12 +4174,8 @@ func (*IoamEnable) GetCrcString() string { func (*IoamEnable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIoamEnable() api.Message { - return &IoamEnable{} -} // IoamEnableReply represents the VPP binary API message 'ioam_enable_reply'. -// Generated from 'ip.api.json', line 2341: // // "ioam_enable_reply", // [ @@ -4510,12 +4207,8 @@ func (*IoamEnableReply) GetCrcString() string { func (*IoamEnableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIoamEnableReply() api.Message { - return &IoamEnableReply{} -} // IoamDisable represents the VPP binary API message 'ioam_disable'. -// Generated from 'ip.api.json', line 2359: // // "ioam_disable", // [ @@ -4551,12 +4244,8 @@ func (*IoamDisable) GetCrcString() string { func (*IoamDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIoamDisable() api.Message { - return &IoamDisable{} -} // IoamDisableReply represents the VPP binary API message 'ioam_disable_reply'. -// Generated from 'ip.api.json', line 2381: // // "ioam_disable_reply", // [ @@ -4588,12 +4277,8 @@ func (*IoamDisableReply) GetCrcString() string { func (*IoamDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIoamDisableReply() api.Message { - return &IoamDisableReply{} -} // IPReassemblySet represents the VPP binary API message 'ip_reassembly_set'. -// Generated from 'ip.api.json', line 2399: // // "ip_reassembly_set", // [ @@ -4644,12 +4329,8 @@ func (*IPReassemblySet) GetCrcString() string { func (*IPReassemblySet) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPReassemblySet() api.Message { - return &IPReassemblySet{} -} // IPReassemblySetReply represents the VPP binary API message 'ip_reassembly_set_reply'. -// Generated from 'ip.api.json', line 2433: // // "ip_reassembly_set_reply", // [ @@ -4681,12 +4362,8 @@ func (*IPReassemblySetReply) GetCrcString() string { func (*IPReassemblySetReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPReassemblySetReply() api.Message { - return &IPReassemblySetReply{} -} // IPReassemblyGet represents the VPP binary API message 'ip_reassembly_get'. -// Generated from 'ip.api.json', line 2451: // // "ip_reassembly_get", // [ @@ -4722,12 +4399,8 @@ func (*IPReassemblyGet) GetCrcString() string { func (*IPReassemblyGet) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPReassemblyGet() api.Message { - return &IPReassemblyGet{} -} // IPReassemblyGetReply represents the VPP binary API message 'ip_reassembly_get_reply'. -// Generated from 'ip.api.json', line 2473: // // "ip_reassembly_get_reply", // [ @@ -4736,10 +4409,6 @@ func NewIPReassemblyGet() api.Message { // ], // [ // "u32", -// "client_index" -// ], -// [ -// "u32", // "context" // ], // [ @@ -4763,7 +4432,7 @@ func NewIPReassemblyGet() api.Message { // "is_ip6" // ], // { -// "crc": "0xd746fc57" +// "crc": "0x1f90afd1" // } // type IPReassemblyGetReply struct { @@ -4778,17 +4447,13 @@ func (*IPReassemblyGetReply) GetMessageName() string { return "ip_reassembly_get_reply" } func (*IPReassemblyGetReply) GetCrcString() string { - return "d746fc57" + return "1f90afd1" } func (*IPReassemblyGetReply) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewIPReassemblyGetReply() api.Message { - return &IPReassemblyGetReply{} + return api.ReplyMessage } // IPReassemblyEnableDisable represents the VPP binary API message 'ip_reassembly_enable_disable'. -// Generated from 'ip.api.json', line 2511: // // "ip_reassembly_enable_disable", // [ @@ -4834,12 +4499,8 @@ func (*IPReassemblyEnableDisable) GetCrcString() string { func (*IPReassemblyEnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIPReassemblyEnableDisable() api.Message { - return &IPReassemblyEnableDisable{} -} // IPReassemblyEnableDisableReply represents the VPP binary API message 'ip_reassembly_enable_disable_reply'. -// Generated from 'ip.api.json', line 2541: // // "ip_reassembly_enable_disable_reply", // [ @@ -4871,9 +4532,6 @@ func (*IPReassemblyEnableDisableReply) GetCrcString() string { func (*IPReassemblyEnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIPReassemblyEnableDisableReply() api.Message { - return &IPReassemblyEnableDisableReply{} -} /* Services */ diff --git a/plugins/vpp/binapi/ip/pkgreflect.go b/plugins/vpp/binapi/ip/pkgreflect.go deleted file mode 100644 index 6ea0aeb234..0000000000 --- a/plugins/vpp/binapi/ip/pkgreflect.go +++ /dev/null @@ -1,206 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package ip - -import "reflect" - -var Types = map[string]reflect.Type{ - "Address": reflect.TypeOf((*Address)(nil)).Elem(), - "AddressFamily": reflect.TypeOf((*AddressFamily)(nil)).Elem(), - "AddressUnion": reflect.TypeOf((*AddressUnion)(nil)).Elem(), - "FibMplsLabel": reflect.TypeOf((*FibMplsLabel)(nil)).Elem(), - "FibPath": reflect.TypeOf((*FibPath)(nil)).Elem(), - "IP4Address": reflect.TypeOf((*IP4Address)(nil)).Elem(), - "IP4ArpEvent": reflect.TypeOf((*IP4ArpEvent)(nil)).Elem(), - "IP6Address": reflect.TypeOf((*IP6Address)(nil)).Elem(), - "IP6FibDetails": reflect.TypeOf((*IP6FibDetails)(nil)).Elem(), - "IP6FibDump": reflect.TypeOf((*IP6FibDump)(nil)).Elem(), - "IP6MfibDetails": reflect.TypeOf((*IP6MfibDetails)(nil)).Elem(), - "IP6MfibDump": reflect.TypeOf((*IP6MfibDump)(nil)).Elem(), - "IP6NdEvent": reflect.TypeOf((*IP6NdEvent)(nil)).Elem(), - "IP6RaEvent": reflect.TypeOf((*IP6RaEvent)(nil)).Elem(), - "IP6RaPrefixInfo": reflect.TypeOf((*IP6RaPrefixInfo)(nil)).Elem(), - "IP6ndProxyAddDel": reflect.TypeOf((*IP6ndProxyAddDel)(nil)).Elem(), - "IP6ndProxyAddDelReply": reflect.TypeOf((*IP6ndProxyAddDelReply)(nil)).Elem(), - "IP6ndProxyDetails": reflect.TypeOf((*IP6ndProxyDetails)(nil)).Elem(), - "IP6ndProxyDump": reflect.TypeOf((*IP6ndProxyDump)(nil)).Elem(), - "IP6ndSendRouterSolicitation": reflect.TypeOf((*IP6ndSendRouterSolicitation)(nil)).Elem(), - "IP6ndSendRouterSolicitationReply": reflect.TypeOf((*IP6ndSendRouterSolicitationReply)(nil)).Elem(), - "IPAddDelRoute": reflect.TypeOf((*IPAddDelRoute)(nil)).Elem(), - "IPAddDelRouteReply": reflect.TypeOf((*IPAddDelRouteReply)(nil)).Elem(), - "IPAddressDetails": reflect.TypeOf((*IPAddressDetails)(nil)).Elem(), - "IPAddressDump": reflect.TypeOf((*IPAddressDump)(nil)).Elem(), - "IPContainerProxyAddDel": reflect.TypeOf((*IPContainerProxyAddDel)(nil)).Elem(), - "IPContainerProxyAddDelReply": reflect.TypeOf((*IPContainerProxyAddDelReply)(nil)).Elem(), - "IPDetails": reflect.TypeOf((*IPDetails)(nil)).Elem(), - "IPDump": reflect.TypeOf((*IPDump)(nil)).Elem(), - "IPFibDetails": reflect.TypeOf((*IPFibDetails)(nil)).Elem(), - "IPFibDump": reflect.TypeOf((*IPFibDump)(nil)).Elem(), - "IPMfibDetails": reflect.TypeOf((*IPMfibDetails)(nil)).Elem(), - "IPMfibDump": reflect.TypeOf((*IPMfibDump)(nil)).Elem(), - "IPMrouteAddDel": reflect.TypeOf((*IPMrouteAddDel)(nil)).Elem(), - "IPMrouteAddDelReply": reflect.TypeOf((*IPMrouteAddDelReply)(nil)).Elem(), - "IPNeighborAddDel": reflect.TypeOf((*IPNeighborAddDel)(nil)).Elem(), - "IPNeighborAddDelReply": reflect.TypeOf((*IPNeighborAddDelReply)(nil)).Elem(), - "IPNeighborDetails": reflect.TypeOf((*IPNeighborDetails)(nil)).Elem(), - "IPNeighborDump": reflect.TypeOf((*IPNeighborDump)(nil)).Elem(), - "IPProbeNeighbor": reflect.TypeOf((*IPProbeNeighbor)(nil)).Elem(), - "IPProbeNeighborReply": reflect.TypeOf((*IPProbeNeighborReply)(nil)).Elem(), - "IPPuntPolice": reflect.TypeOf((*IPPuntPolice)(nil)).Elem(), - "IPPuntPoliceReply": reflect.TypeOf((*IPPuntPoliceReply)(nil)).Elem(), - "IPPuntRedirect": reflect.TypeOf((*IPPuntRedirect)(nil)).Elem(), - "IPPuntRedirectReply": reflect.TypeOf((*IPPuntRedirectReply)(nil)).Elem(), - "IPReassemblyEnableDisable": reflect.TypeOf((*IPReassemblyEnableDisable)(nil)).Elem(), - "IPReassemblyEnableDisableReply": reflect.TypeOf((*IPReassemblyEnableDisableReply)(nil)).Elem(), - "IPReassemblyGet": reflect.TypeOf((*IPReassemblyGet)(nil)).Elem(), - "IPReassemblyGetReply": reflect.TypeOf((*IPReassemblyGetReply)(nil)).Elem(), - "IPReassemblySet": reflect.TypeOf((*IPReassemblySet)(nil)).Elem(), - "IPReassemblySetReply": reflect.TypeOf((*IPReassemblySetReply)(nil)).Elem(), - "IPScanNeighborEnableDisable": reflect.TypeOf((*IPScanNeighborEnableDisable)(nil)).Elem(), - "IPScanNeighborEnableDisableReply": reflect.TypeOf((*IPScanNeighborEnableDisableReply)(nil)).Elem(), - "IPSourceAndPortRangeCheckAddDel": reflect.TypeOf((*IPSourceAndPortRangeCheckAddDel)(nil)).Elem(), - "IPSourceAndPortRangeCheckAddDelReply": reflect.TypeOf((*IPSourceAndPortRangeCheckAddDelReply)(nil)).Elem(), - "IPSourceAndPortRangeCheckInterfaceAddDel": reflect.TypeOf((*IPSourceAndPortRangeCheckInterfaceAddDel)(nil)).Elem(), - "IPSourceAndPortRangeCheckInterfaceAddDelReply": reflect.TypeOf((*IPSourceAndPortRangeCheckInterfaceAddDelReply)(nil)).Elem(), - "IPTableAddDel": reflect.TypeOf((*IPTableAddDel)(nil)).Elem(), - "IPTableAddDelReply": reflect.TypeOf((*IPTableAddDelReply)(nil)).Elem(), - "IPUnnumberedDetails": reflect.TypeOf((*IPUnnumberedDetails)(nil)).Elem(), - "IPUnnumberedDump": reflect.TypeOf((*IPUnnumberedDump)(nil)).Elem(), - "IoamDisable": reflect.TypeOf((*IoamDisable)(nil)).Elem(), - "IoamDisableReply": reflect.TypeOf((*IoamDisableReply)(nil)).Elem(), - "IoamEnable": reflect.TypeOf((*IoamEnable)(nil)).Elem(), - "IoamEnableReply": reflect.TypeOf((*IoamEnableReply)(nil)).Elem(), - "MfibSignalDetails": reflect.TypeOf((*MfibSignalDetails)(nil)).Elem(), - "MfibSignalDump": reflect.TypeOf((*MfibSignalDump)(nil)).Elem(), - "Mprefix": reflect.TypeOf((*Mprefix)(nil)).Elem(), - "Prefix": reflect.TypeOf((*Prefix)(nil)).Elem(), - "ProxyArp": reflect.TypeOf((*ProxyArp)(nil)).Elem(), - "ProxyArpAddDel": reflect.TypeOf((*ProxyArpAddDel)(nil)).Elem(), - "ProxyArpAddDelReply": reflect.TypeOf((*ProxyArpAddDelReply)(nil)).Elem(), - "ProxyArpDetails": reflect.TypeOf((*ProxyArpDetails)(nil)).Elem(), - "ProxyArpDump": reflect.TypeOf((*ProxyArpDump)(nil)).Elem(), - "ProxyArpIntfcDetails": reflect.TypeOf((*ProxyArpIntfcDetails)(nil)).Elem(), - "ProxyArpIntfcDump": reflect.TypeOf((*ProxyArpIntfcDump)(nil)).Elem(), - "ProxyArpIntfcEnableDisable": reflect.TypeOf((*ProxyArpIntfcEnableDisable)(nil)).Elem(), - "ProxyArpIntfcEnableDisableReply": reflect.TypeOf((*ProxyArpIntfcEnableDisableReply)(nil)).Elem(), - "ResetFib": reflect.TypeOf((*ResetFib)(nil)).Elem(), - "ResetFibReply": reflect.TypeOf((*ResetFibReply)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SetArpNeighborLimit": reflect.TypeOf((*SetArpNeighborLimit)(nil)).Elem(), - "SetArpNeighborLimitReply": reflect.TypeOf((*SetArpNeighborLimitReply)(nil)).Elem(), - "SetIPFlowHash": reflect.TypeOf((*SetIPFlowHash)(nil)).Elem(), - "SetIPFlowHashReply": reflect.TypeOf((*SetIPFlowHashReply)(nil)).Elem(), - "SwInterfaceIP6EnableDisable": reflect.TypeOf((*SwInterfaceIP6EnableDisable)(nil)).Elem(), - "SwInterfaceIP6EnableDisableReply": reflect.TypeOf((*SwInterfaceIP6EnableDisableReply)(nil)).Elem(), - "SwInterfaceIP6SetLinkLocalAddress": reflect.TypeOf((*SwInterfaceIP6SetLinkLocalAddress)(nil)).Elem(), - "SwInterfaceIP6SetLinkLocalAddressReply": reflect.TypeOf((*SwInterfaceIP6SetLinkLocalAddressReply)(nil)).Elem(), - "SwInterfaceIP6ndRaConfig": reflect.TypeOf((*SwInterfaceIP6ndRaConfig)(nil)).Elem(), - "SwInterfaceIP6ndRaConfigReply": reflect.TypeOf((*SwInterfaceIP6ndRaConfigReply)(nil)).Elem(), - "SwInterfaceIP6ndRaPrefix": reflect.TypeOf((*SwInterfaceIP6ndRaPrefix)(nil)).Elem(), - "SwInterfaceIP6ndRaPrefixReply": reflect.TypeOf((*SwInterfaceIP6ndRaPrefixReply)(nil)).Elem(), - "WantIP4ArpEvents": reflect.TypeOf((*WantIP4ArpEvents)(nil)).Elem(), - "WantIP4ArpEventsReply": reflect.TypeOf((*WantIP4ArpEventsReply)(nil)).Elem(), - "WantIP6NdEvents": reflect.TypeOf((*WantIP6NdEvents)(nil)).Elem(), - "WantIP6NdEventsReply": reflect.TypeOf((*WantIP6NdEventsReply)(nil)).Elem(), - "WantIP6RaEvents": reflect.TypeOf((*WantIP6RaEvents)(nil)).Elem(), - "WantIP6RaEventsReply": reflect.TypeOf((*WantIP6RaEventsReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewIP4ArpEvent": reflect.ValueOf(NewIP4ArpEvent), - "NewIP6FibDetails": reflect.ValueOf(NewIP6FibDetails), - "NewIP6FibDump": reflect.ValueOf(NewIP6FibDump), - "NewIP6MfibDetails": reflect.ValueOf(NewIP6MfibDetails), - "NewIP6MfibDump": reflect.ValueOf(NewIP6MfibDump), - "NewIP6NdEvent": reflect.ValueOf(NewIP6NdEvent), - "NewIP6RaEvent": reflect.ValueOf(NewIP6RaEvent), - "NewIP6ndProxyAddDel": reflect.ValueOf(NewIP6ndProxyAddDel), - "NewIP6ndProxyAddDelReply": reflect.ValueOf(NewIP6ndProxyAddDelReply), - "NewIP6ndProxyDetails": reflect.ValueOf(NewIP6ndProxyDetails), - "NewIP6ndProxyDump": reflect.ValueOf(NewIP6ndProxyDump), - "NewIP6ndSendRouterSolicitation": reflect.ValueOf(NewIP6ndSendRouterSolicitation), - "NewIP6ndSendRouterSolicitationReply": reflect.ValueOf(NewIP6ndSendRouterSolicitationReply), - "NewIPAddDelRoute": reflect.ValueOf(NewIPAddDelRoute), - "NewIPAddDelRouteReply": reflect.ValueOf(NewIPAddDelRouteReply), - "NewIPAddressDetails": reflect.ValueOf(NewIPAddressDetails), - "NewIPAddressDump": reflect.ValueOf(NewIPAddressDump), - "NewIPContainerProxyAddDel": reflect.ValueOf(NewIPContainerProxyAddDel), - "NewIPContainerProxyAddDelReply": reflect.ValueOf(NewIPContainerProxyAddDelReply), - "NewIPDetails": reflect.ValueOf(NewIPDetails), - "NewIPDump": reflect.ValueOf(NewIPDump), - "NewIPFibDetails": reflect.ValueOf(NewIPFibDetails), - "NewIPFibDump": reflect.ValueOf(NewIPFibDump), - "NewIPMfibDetails": reflect.ValueOf(NewIPMfibDetails), - "NewIPMfibDump": reflect.ValueOf(NewIPMfibDump), - "NewIPMrouteAddDel": reflect.ValueOf(NewIPMrouteAddDel), - "NewIPMrouteAddDelReply": reflect.ValueOf(NewIPMrouteAddDelReply), - "NewIPNeighborAddDel": reflect.ValueOf(NewIPNeighborAddDel), - "NewIPNeighborAddDelReply": reflect.ValueOf(NewIPNeighborAddDelReply), - "NewIPNeighborDetails": reflect.ValueOf(NewIPNeighborDetails), - "NewIPNeighborDump": reflect.ValueOf(NewIPNeighborDump), - "NewIPProbeNeighbor": reflect.ValueOf(NewIPProbeNeighbor), - "NewIPProbeNeighborReply": reflect.ValueOf(NewIPProbeNeighborReply), - "NewIPPuntPolice": reflect.ValueOf(NewIPPuntPolice), - "NewIPPuntPoliceReply": reflect.ValueOf(NewIPPuntPoliceReply), - "NewIPPuntRedirect": reflect.ValueOf(NewIPPuntRedirect), - "NewIPPuntRedirectReply": reflect.ValueOf(NewIPPuntRedirectReply), - "NewIPReassemblyEnableDisable": reflect.ValueOf(NewIPReassemblyEnableDisable), - "NewIPReassemblyEnableDisableReply": reflect.ValueOf(NewIPReassemblyEnableDisableReply), - "NewIPReassemblyGet": reflect.ValueOf(NewIPReassemblyGet), - "NewIPReassemblyGetReply": reflect.ValueOf(NewIPReassemblyGetReply), - "NewIPReassemblySet": reflect.ValueOf(NewIPReassemblySet), - "NewIPReassemblySetReply": reflect.ValueOf(NewIPReassemblySetReply), - "NewIPScanNeighborEnableDisable": reflect.ValueOf(NewIPScanNeighborEnableDisable), - "NewIPScanNeighborEnableDisableReply": reflect.ValueOf(NewIPScanNeighborEnableDisableReply), - "NewIPSourceAndPortRangeCheckAddDel": reflect.ValueOf(NewIPSourceAndPortRangeCheckAddDel), - "NewIPSourceAndPortRangeCheckAddDelReply": reflect.ValueOf(NewIPSourceAndPortRangeCheckAddDelReply), - "NewIPSourceAndPortRangeCheckInterfaceAddDel": reflect.ValueOf(NewIPSourceAndPortRangeCheckInterfaceAddDel), - "NewIPSourceAndPortRangeCheckInterfaceAddDelReply": reflect.ValueOf(NewIPSourceAndPortRangeCheckInterfaceAddDelReply), - "NewIPTableAddDel": reflect.ValueOf(NewIPTableAddDel), - "NewIPTableAddDelReply": reflect.ValueOf(NewIPTableAddDelReply), - "NewIPUnnumberedDetails": reflect.ValueOf(NewIPUnnumberedDetails), - "NewIPUnnumberedDump": reflect.ValueOf(NewIPUnnumberedDump), - "NewIoamDisable": reflect.ValueOf(NewIoamDisable), - "NewIoamDisableReply": reflect.ValueOf(NewIoamDisableReply), - "NewIoamEnable": reflect.ValueOf(NewIoamEnable), - "NewIoamEnableReply": reflect.ValueOf(NewIoamEnableReply), - "NewMfibSignalDetails": reflect.ValueOf(NewMfibSignalDetails), - "NewMfibSignalDump": reflect.ValueOf(NewMfibSignalDump), - "NewProxyArpAddDel": reflect.ValueOf(NewProxyArpAddDel), - "NewProxyArpAddDelReply": reflect.ValueOf(NewProxyArpAddDelReply), - "NewProxyArpDetails": reflect.ValueOf(NewProxyArpDetails), - "NewProxyArpDump": reflect.ValueOf(NewProxyArpDump), - "NewProxyArpIntfcDetails": reflect.ValueOf(NewProxyArpIntfcDetails), - "NewProxyArpIntfcDump": reflect.ValueOf(NewProxyArpIntfcDump), - "NewProxyArpIntfcEnableDisable": reflect.ValueOf(NewProxyArpIntfcEnableDisable), - "NewProxyArpIntfcEnableDisableReply": reflect.ValueOf(NewProxyArpIntfcEnableDisableReply), - "NewResetFib": reflect.ValueOf(NewResetFib), - "NewResetFibReply": reflect.ValueOf(NewResetFibReply), - "NewSetArpNeighborLimit": reflect.ValueOf(NewSetArpNeighborLimit), - "NewSetArpNeighborLimitReply": reflect.ValueOf(NewSetArpNeighborLimitReply), - "NewSetIPFlowHash": reflect.ValueOf(NewSetIPFlowHash), - "NewSetIPFlowHashReply": reflect.ValueOf(NewSetIPFlowHashReply), - "NewSwInterfaceIP6EnableDisable": reflect.ValueOf(NewSwInterfaceIP6EnableDisable), - "NewSwInterfaceIP6EnableDisableReply": reflect.ValueOf(NewSwInterfaceIP6EnableDisableReply), - "NewSwInterfaceIP6SetLinkLocalAddress": reflect.ValueOf(NewSwInterfaceIP6SetLinkLocalAddress), - "NewSwInterfaceIP6SetLinkLocalAddressReply": reflect.ValueOf(NewSwInterfaceIP6SetLinkLocalAddressReply), - "NewSwInterfaceIP6ndRaConfig": reflect.ValueOf(NewSwInterfaceIP6ndRaConfig), - "NewSwInterfaceIP6ndRaConfigReply": reflect.ValueOf(NewSwInterfaceIP6ndRaConfigReply), - "NewSwInterfaceIP6ndRaPrefix": reflect.ValueOf(NewSwInterfaceIP6ndRaPrefix), - "NewSwInterfaceIP6ndRaPrefixReply": reflect.ValueOf(NewSwInterfaceIP6ndRaPrefixReply), - "NewWantIP4ArpEvents": reflect.ValueOf(NewWantIP4ArpEvents), - "NewWantIP4ArpEventsReply": reflect.ValueOf(NewWantIP4ArpEventsReply), - "NewWantIP6NdEvents": reflect.ValueOf(NewWantIP6NdEvents), - "NewWantIP6NdEventsReply": reflect.ValueOf(NewWantIP6NdEventsReply), - "NewWantIP6RaEvents": reflect.ValueOf(NewWantIP6RaEvents), - "NewWantIP6RaEventsReply": reflect.ValueOf(NewWantIP6RaEventsReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ - "ADDRESS_IP4": reflect.ValueOf(ADDRESS_IP4), - "ADDRESS_IP6": reflect.ValueOf(ADDRESS_IP6), -} - diff --git a/plugins/vpp/binapi/ipsec/ipsec.ba.go b/plugins/vpp/binapi/ipsec/ipsec.ba.go index 6f44f00676..6ffd2ad7f0 100644 --- a/plugins/vpp/binapi/ipsec/ipsec.ba.go +++ b/plugins/vpp/binapi/ipsec/ipsec.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/ipsec.api.json +// source: /usr/share/vpp/api/ipsec.api.json /* -Package ipsec is a generated VPP binary API of the 'ipsec' VPP module. + Package ipsec is a generated from VPP binary API module 'ipsec'. -It is generated from this file: - ipsec.api.json + It contains following objects: + 46 messages + 23 services -It contains these VPP binary API objects: - 46 messages - 23 services */ package ipsec @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // IpsecSpdAddDel represents the VPP binary API message 'ipsec_spd_add_del'. -// Generated from 'ipsec.api.json', line 4: // // "ipsec_spd_add_del", // [ @@ -65,12 +63,8 @@ func (*IpsecSpdAddDel) GetCrcString() string { func (*IpsecSpdAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecSpdAddDel() api.Message { - return &IpsecSpdAddDel{} -} // IpsecSpdAddDelReply represents the VPP binary API message 'ipsec_spd_add_del_reply'. -// Generated from 'ipsec.api.json', line 30: // // "ipsec_spd_add_del_reply", // [ @@ -102,12 +96,8 @@ func (*IpsecSpdAddDelReply) GetCrcString() string { func (*IpsecSpdAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecSpdAddDelReply() api.Message { - return &IpsecSpdAddDelReply{} -} // IpsecInterfaceAddDelSpd represents the VPP binary API message 'ipsec_interface_add_del_spd'. -// Generated from 'ipsec.api.json', line 48: // // "ipsec_interface_add_del_spd", // [ @@ -153,12 +143,8 @@ func (*IpsecInterfaceAddDelSpd) GetCrcString() string { func (*IpsecInterfaceAddDelSpd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecInterfaceAddDelSpd() api.Message { - return &IpsecInterfaceAddDelSpd{} -} // IpsecInterfaceAddDelSpdReply represents the VPP binary API message 'ipsec_interface_add_del_spd_reply'. -// Generated from 'ipsec.api.json', line 78: // // "ipsec_interface_add_del_spd_reply", // [ @@ -190,12 +176,8 @@ func (*IpsecInterfaceAddDelSpdReply) GetCrcString() string { func (*IpsecInterfaceAddDelSpdReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecInterfaceAddDelSpdReply() api.Message { - return &IpsecInterfaceAddDelSpdReply{} -} // IpsecSpdAddDelEntry represents the VPP binary API message 'ipsec_spd_add_del_entry'. -// Generated from 'ipsec.api.json', line 96: // // "ipsec_spd_add_del_entry", // [ @@ -315,12 +297,8 @@ func (*IpsecSpdAddDelEntry) GetCrcString() string { func (*IpsecSpdAddDelEntry) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecSpdAddDelEntry() api.Message { - return &IpsecSpdAddDelEntry{} -} // IpsecSpdAddDelEntryReply represents the VPP binary API message 'ipsec_spd_add_del_entry_reply'. -// Generated from 'ipsec.api.json', line 186: // // "ipsec_spd_add_del_entry_reply", // [ @@ -352,12 +330,8 @@ func (*IpsecSpdAddDelEntryReply) GetCrcString() string { func (*IpsecSpdAddDelEntryReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecSpdAddDelEntryReply() api.Message { - return &IpsecSpdAddDelEntryReply{} -} // IpsecSadAddDelEntry represents the VPP binary API message 'ipsec_sad_add_del_entry'. -// Generated from 'ipsec.api.json', line 204: // // "ipsec_sad_add_del_entry", // [ @@ -477,12 +451,8 @@ func (*IpsecSadAddDelEntry) GetCrcString() string { func (*IpsecSadAddDelEntry) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecSadAddDelEntry() api.Message { - return &IpsecSadAddDelEntry{} -} // IpsecSadAddDelEntryReply represents the VPP binary API message 'ipsec_sad_add_del_entry_reply'. -// Generated from 'ipsec.api.json', line 294: // // "ipsec_sad_add_del_entry_reply", // [ @@ -514,12 +484,8 @@ func (*IpsecSadAddDelEntryReply) GetCrcString() string { func (*IpsecSadAddDelEntryReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecSadAddDelEntryReply() api.Message { - return &IpsecSadAddDelEntryReply{} -} // IpsecSaSetKey represents the VPP binary API message 'ipsec_sa_set_key'. -// Generated from 'ipsec.api.json', line 312: // // "ipsec_sa_set_key", // [ @@ -577,12 +543,8 @@ func (*IpsecSaSetKey) GetCrcString() string { func (*IpsecSaSetKey) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecSaSetKey() api.Message { - return &IpsecSaSetKey{} -} // IpsecSaSetKeyReply represents the VPP binary API message 'ipsec_sa_set_key_reply'. -// Generated from 'ipsec.api.json', line 352: // // "ipsec_sa_set_key_reply", // [ @@ -614,12 +576,8 @@ func (*IpsecSaSetKeyReply) GetCrcString() string { func (*IpsecSaSetKeyReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecSaSetKeyReply() api.Message { - return &IpsecSaSetKeyReply{} -} // Ikev2ProfileAddDel represents the VPP binary API message 'ikev2_profile_add_del'. -// Generated from 'ipsec.api.json', line 370: // // "ikev2_profile_add_del", // [ @@ -661,12 +619,8 @@ func (*Ikev2ProfileAddDel) GetCrcString() string { func (*Ikev2ProfileAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2ProfileAddDel() api.Message { - return &Ikev2ProfileAddDel{} -} // Ikev2ProfileAddDelReply represents the VPP binary API message 'ikev2_profile_add_del_reply'. -// Generated from 'ipsec.api.json', line 397: // // "ikev2_profile_add_del_reply", // [ @@ -698,12 +652,8 @@ func (*Ikev2ProfileAddDelReply) GetCrcString() string { func (*Ikev2ProfileAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2ProfileAddDelReply() api.Message { - return &Ikev2ProfileAddDelReply{} -} // Ikev2ProfileSetAuth represents the VPP binary API message 'ikev2_profile_set_auth'. -// Generated from 'ipsec.api.json', line 415: // // "ikev2_profile_set_auth", // [ @@ -762,12 +712,8 @@ func (*Ikev2ProfileSetAuth) GetCrcString() string { func (*Ikev2ProfileSetAuth) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2ProfileSetAuth() api.Message { - return &Ikev2ProfileSetAuth{} -} // Ikev2ProfileSetAuthReply represents the VPP binary API message 'ikev2_profile_set_auth_reply'. -// Generated from 'ipsec.api.json', line 456: // // "ikev2_profile_set_auth_reply", // [ @@ -799,12 +745,8 @@ func (*Ikev2ProfileSetAuthReply) GetCrcString() string { func (*Ikev2ProfileSetAuthReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2ProfileSetAuthReply() api.Message { - return &Ikev2ProfileSetAuthReply{} -} // Ikev2ProfileSetID represents the VPP binary API message 'ikev2_profile_set_id'. -// Generated from 'ipsec.api.json', line 474: // // "ikev2_profile_set_id", // [ @@ -863,12 +805,8 @@ func (*Ikev2ProfileSetID) GetCrcString() string { func (*Ikev2ProfileSetID) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2ProfileSetID() api.Message { - return &Ikev2ProfileSetID{} -} // Ikev2ProfileSetIDReply represents the VPP binary API message 'ikev2_profile_set_id_reply'. -// Generated from 'ipsec.api.json', line 515: // // "ikev2_profile_set_id_reply", // [ @@ -900,12 +838,8 @@ func (*Ikev2ProfileSetIDReply) GetCrcString() string { func (*Ikev2ProfileSetIDReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2ProfileSetIDReply() api.Message { - return &Ikev2ProfileSetIDReply{} -} // Ikev2ProfileSetTs represents the VPP binary API message 'ikev2_profile_set_ts'. -// Generated from 'ipsec.api.json', line 533: // // "ikev2_profile_set_ts", // [ @@ -972,12 +906,8 @@ func (*Ikev2ProfileSetTs) GetCrcString() string { func (*Ikev2ProfileSetTs) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2ProfileSetTs() api.Message { - return &Ikev2ProfileSetTs{} -} // Ikev2ProfileSetTsReply represents the VPP binary API message 'ikev2_profile_set_ts_reply'. -// Generated from 'ipsec.api.json', line 580: // // "ikev2_profile_set_ts_reply", // [ @@ -1009,12 +939,8 @@ func (*Ikev2ProfileSetTsReply) GetCrcString() string { func (*Ikev2ProfileSetTsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2ProfileSetTsReply() api.Message { - return &Ikev2ProfileSetTsReply{} -} // Ikev2SetLocalKey represents the VPP binary API message 'ikev2_set_local_key'. -// Generated from 'ipsec.api.json', line 598: // // "ikev2_set_local_key", // [ @@ -1051,12 +977,8 @@ func (*Ikev2SetLocalKey) GetCrcString() string { func (*Ikev2SetLocalKey) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2SetLocalKey() api.Message { - return &Ikev2SetLocalKey{} -} // Ikev2SetLocalKeyReply represents the VPP binary API message 'ikev2_set_local_key_reply'. -// Generated from 'ipsec.api.json', line 621: // // "ikev2_set_local_key_reply", // [ @@ -1088,12 +1010,8 @@ func (*Ikev2SetLocalKeyReply) GetCrcString() string { func (*Ikev2SetLocalKeyReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2SetLocalKeyReply() api.Message { - return &Ikev2SetLocalKeyReply{} -} // Ikev2SetResponder represents the VPP binary API message 'ikev2_set_responder'. -// Generated from 'ipsec.api.json', line 639: // // "ikev2_set_responder", // [ @@ -1141,12 +1059,8 @@ func (*Ikev2SetResponder) GetCrcString() string { func (*Ikev2SetResponder) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2SetResponder() api.Message { - return &Ikev2SetResponder{} -} // Ikev2SetResponderReply represents the VPP binary API message 'ikev2_set_responder_reply'. -// Generated from 'ipsec.api.json', line 671: // // "ikev2_set_responder_reply", // [ @@ -1178,12 +1092,8 @@ func (*Ikev2SetResponderReply) GetCrcString() string { func (*Ikev2SetResponderReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2SetResponderReply() api.Message { - return &Ikev2SetResponderReply{} -} // Ikev2SetIkeTransforms represents the VPP binary API message 'ikev2_set_ike_transforms'. -// Generated from 'ipsec.api.json', line 689: // // "ikev2_set_ike_transforms", // [ @@ -1240,12 +1150,8 @@ func (*Ikev2SetIkeTransforms) GetCrcString() string { func (*Ikev2SetIkeTransforms) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2SetIkeTransforms() api.Message { - return &Ikev2SetIkeTransforms{} -} // Ikev2SetIkeTransformsReply represents the VPP binary API message 'ikev2_set_ike_transforms_reply'. -// Generated from 'ipsec.api.json', line 728: // // "ikev2_set_ike_transforms_reply", // [ @@ -1277,12 +1183,8 @@ func (*Ikev2SetIkeTransformsReply) GetCrcString() string { func (*Ikev2SetIkeTransformsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2SetIkeTransformsReply() api.Message { - return &Ikev2SetIkeTransformsReply{} -} // Ikev2SetEspTransforms represents the VPP binary API message 'ikev2_set_esp_transforms'. -// Generated from 'ipsec.api.json', line 746: // // "ikev2_set_esp_transforms", // [ @@ -1339,12 +1241,8 @@ func (*Ikev2SetEspTransforms) GetCrcString() string { func (*Ikev2SetEspTransforms) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2SetEspTransforms() api.Message { - return &Ikev2SetEspTransforms{} -} // Ikev2SetEspTransformsReply represents the VPP binary API message 'ikev2_set_esp_transforms_reply'. -// Generated from 'ipsec.api.json', line 785: // // "ikev2_set_esp_transforms_reply", // [ @@ -1376,12 +1274,8 @@ func (*Ikev2SetEspTransformsReply) GetCrcString() string { func (*Ikev2SetEspTransformsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2SetEspTransformsReply() api.Message { - return &Ikev2SetEspTransformsReply{} -} // Ikev2SetSaLifetime represents the VPP binary API message 'ikev2_set_sa_lifetime'. -// Generated from 'ipsec.api.json', line 803: // // "ikev2_set_sa_lifetime", // [ @@ -1438,12 +1332,8 @@ func (*Ikev2SetSaLifetime) GetCrcString() string { func (*Ikev2SetSaLifetime) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2SetSaLifetime() api.Message { - return &Ikev2SetSaLifetime{} -} // Ikev2SetSaLifetimeReply represents the VPP binary API message 'ikev2_set_sa_lifetime_reply'. -// Generated from 'ipsec.api.json', line 842: // // "ikev2_set_sa_lifetime_reply", // [ @@ -1475,12 +1365,8 @@ func (*Ikev2SetSaLifetimeReply) GetCrcString() string { func (*Ikev2SetSaLifetimeReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2SetSaLifetimeReply() api.Message { - return &Ikev2SetSaLifetimeReply{} -} // Ikev2InitiateSaInit represents the VPP binary API message 'ikev2_initiate_sa_init'. -// Generated from 'ipsec.api.json', line 860: // // "ikev2_initiate_sa_init", // [ @@ -1517,12 +1403,8 @@ func (*Ikev2InitiateSaInit) GetCrcString() string { func (*Ikev2InitiateSaInit) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2InitiateSaInit() api.Message { - return &Ikev2InitiateSaInit{} -} // Ikev2InitiateSaInitReply represents the VPP binary API message 'ikev2_initiate_sa_init_reply'. -// Generated from 'ipsec.api.json', line 883: // // "ikev2_initiate_sa_init_reply", // [ @@ -1554,12 +1436,8 @@ func (*Ikev2InitiateSaInitReply) GetCrcString() string { func (*Ikev2InitiateSaInitReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2InitiateSaInitReply() api.Message { - return &Ikev2InitiateSaInitReply{} -} // Ikev2InitiateDelIkeSa represents the VPP binary API message 'ikev2_initiate_del_ike_sa'. -// Generated from 'ipsec.api.json', line 901: // // "ikev2_initiate_del_ike_sa", // [ @@ -1595,12 +1473,8 @@ func (*Ikev2InitiateDelIkeSa) GetCrcString() string { func (*Ikev2InitiateDelIkeSa) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2InitiateDelIkeSa() api.Message { - return &Ikev2InitiateDelIkeSa{} -} // Ikev2InitiateDelIkeSaReply represents the VPP binary API message 'ikev2_initiate_del_ike_sa_reply'. -// Generated from 'ipsec.api.json', line 923: // // "ikev2_initiate_del_ike_sa_reply", // [ @@ -1632,12 +1506,8 @@ func (*Ikev2InitiateDelIkeSaReply) GetCrcString() string { func (*Ikev2InitiateDelIkeSaReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2InitiateDelIkeSaReply() api.Message { - return &Ikev2InitiateDelIkeSaReply{} -} // Ikev2InitiateDelChildSa represents the VPP binary API message 'ikev2_initiate_del_child_sa'. -// Generated from 'ipsec.api.json', line 941: // // "ikev2_initiate_del_child_sa", // [ @@ -1673,12 +1543,8 @@ func (*Ikev2InitiateDelChildSa) GetCrcString() string { func (*Ikev2InitiateDelChildSa) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2InitiateDelChildSa() api.Message { - return &Ikev2InitiateDelChildSa{} -} // Ikev2InitiateDelChildSaReply represents the VPP binary API message 'ikev2_initiate_del_child_sa_reply'. -// Generated from 'ipsec.api.json', line 963: // // "ikev2_initiate_del_child_sa_reply", // [ @@ -1710,12 +1576,8 @@ func (*Ikev2InitiateDelChildSaReply) GetCrcString() string { func (*Ikev2InitiateDelChildSaReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2InitiateDelChildSaReply() api.Message { - return &Ikev2InitiateDelChildSaReply{} -} // Ikev2InitiateRekeyChildSa represents the VPP binary API message 'ikev2_initiate_rekey_child_sa'. -// Generated from 'ipsec.api.json', line 981: // // "ikev2_initiate_rekey_child_sa", // [ @@ -1751,12 +1613,8 @@ func (*Ikev2InitiateRekeyChildSa) GetCrcString() string { func (*Ikev2InitiateRekeyChildSa) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIkev2InitiateRekeyChildSa() api.Message { - return &Ikev2InitiateRekeyChildSa{} -} // Ikev2InitiateRekeyChildSaReply represents the VPP binary API message 'ikev2_initiate_rekey_child_sa_reply'. -// Generated from 'ipsec.api.json', line 1003: // // "ikev2_initiate_rekey_child_sa_reply", // [ @@ -1788,12 +1646,8 @@ func (*Ikev2InitiateRekeyChildSaReply) GetCrcString() string { func (*Ikev2InitiateRekeyChildSaReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIkev2InitiateRekeyChildSaReply() api.Message { - return &Ikev2InitiateRekeyChildSaReply{} -} // IpsecSpdDump represents the VPP binary API message 'ipsec_spd_dump'. -// Generated from 'ipsec.api.json', line 1021: // // "ipsec_spd_dump", // [ @@ -1834,12 +1688,8 @@ func (*IpsecSpdDump) GetCrcString() string { func (*IpsecSpdDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecSpdDump() api.Message { - return &IpsecSpdDump{} -} // IpsecSpdDetails represents the VPP binary API message 'ipsec_spd_details'. -// Generated from 'ipsec.api.json', line 1047: // // "ipsec_spd_details", // [ @@ -1955,12 +1805,8 @@ func (*IpsecSpdDetails) GetCrcString() string { func (*IpsecSpdDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecSpdDetails() api.Message { - return &IpsecSpdDetails{} -} // IpsecTunnelIfAddDel represents the VPP binary API message 'ipsec_tunnel_if_add_del'. -// Generated from 'ipsec.api.json', line 1133: // // "ipsec_tunnel_if_add_del", // [ @@ -2092,12 +1938,8 @@ func (*IpsecTunnelIfAddDel) GetCrcString() string { func (*IpsecTunnelIfAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecTunnelIfAddDel() api.Message { - return &IpsecTunnelIfAddDel{} -} // IpsecTunnelIfAddDelReply represents the VPP binary API message 'ipsec_tunnel_if_add_del_reply'. -// Generated from 'ipsec.api.json', line 1233: // // "ipsec_tunnel_if_add_del_reply", // [ @@ -2134,12 +1976,8 @@ func (*IpsecTunnelIfAddDelReply) GetCrcString() string { func (*IpsecTunnelIfAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecTunnelIfAddDelReply() api.Message { - return &IpsecTunnelIfAddDelReply{} -} // IpsecSaDump represents the VPP binary API message 'ipsec_sa_dump'. -// Generated from 'ipsec.api.json', line 1255: // // "ipsec_sa_dump", // [ @@ -2175,12 +2013,8 @@ func (*IpsecSaDump) GetCrcString() string { func (*IpsecSaDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecSaDump() api.Message { - return &IpsecSaDump{} -} // IpsecSaDetails represents the VPP binary API message 'ipsec_sa_details'. -// Generated from 'ipsec.api.json', line 1277: // // "ipsec_sa_details", // [ @@ -2321,12 +2155,8 @@ func (*IpsecSaDetails) GetCrcString() string { func (*IpsecSaDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecSaDetails() api.Message { - return &IpsecSaDetails{} -} // IpsecTunnelIfSetKey represents the VPP binary API message 'ipsec_tunnel_if_set_key'. -// Generated from 'ipsec.api.json', line 1383: // // "ipsec_tunnel_if_set_key", // [ @@ -2383,12 +2213,8 @@ func (*IpsecTunnelIfSetKey) GetCrcString() string { func (*IpsecTunnelIfSetKey) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecTunnelIfSetKey() api.Message { - return &IpsecTunnelIfSetKey{} -} // IpsecTunnelIfSetKeyReply represents the VPP binary API message 'ipsec_tunnel_if_set_key_reply'. -// Generated from 'ipsec.api.json', line 1422: // // "ipsec_tunnel_if_set_key_reply", // [ @@ -2420,12 +2246,8 @@ func (*IpsecTunnelIfSetKeyReply) GetCrcString() string { func (*IpsecTunnelIfSetKeyReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecTunnelIfSetKeyReply() api.Message { - return &IpsecTunnelIfSetKeyReply{} -} // IpsecTunnelIfSetSa represents the VPP binary API message 'ipsec_tunnel_if_set_sa'. -// Generated from 'ipsec.api.json', line 1440: // // "ipsec_tunnel_if_set_sa", // [ @@ -2471,12 +2293,8 @@ func (*IpsecTunnelIfSetSa) GetCrcString() string { func (*IpsecTunnelIfSetSa) GetMessageType() api.MessageType { return api.RequestMessage } -func NewIpsecTunnelIfSetSa() api.Message { - return &IpsecTunnelIfSetSa{} -} // IpsecTunnelIfSetSaReply represents the VPP binary API message 'ipsec_tunnel_if_set_sa_reply'. -// Generated from 'ipsec.api.json', line 1470: // // "ipsec_tunnel_if_set_sa_reply", // [ @@ -2508,9 +2326,6 @@ func (*IpsecTunnelIfSetSaReply) GetCrcString() string { func (*IpsecTunnelIfSetSaReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewIpsecTunnelIfSetSaReply() api.Message { - return &IpsecTunnelIfSetSaReply{} -} /* Services */ diff --git a/plugins/vpp/binapi/ipsec/pkgreflect.go b/plugins/vpp/binapi/ipsec/pkgreflect.go deleted file mode 100644 index 8c08df99ca..0000000000 --- a/plugins/vpp/binapi/ipsec/pkgreflect.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package ipsec - -import "reflect" - -var Types = map[string]reflect.Type{ - "Ikev2InitiateDelChildSa": reflect.TypeOf((*Ikev2InitiateDelChildSa)(nil)).Elem(), - "Ikev2InitiateDelChildSaReply": reflect.TypeOf((*Ikev2InitiateDelChildSaReply)(nil)).Elem(), - "Ikev2InitiateDelIkeSa": reflect.TypeOf((*Ikev2InitiateDelIkeSa)(nil)).Elem(), - "Ikev2InitiateDelIkeSaReply": reflect.TypeOf((*Ikev2InitiateDelIkeSaReply)(nil)).Elem(), - "Ikev2InitiateRekeyChildSa": reflect.TypeOf((*Ikev2InitiateRekeyChildSa)(nil)).Elem(), - "Ikev2InitiateRekeyChildSaReply": reflect.TypeOf((*Ikev2InitiateRekeyChildSaReply)(nil)).Elem(), - "Ikev2InitiateSaInit": reflect.TypeOf((*Ikev2InitiateSaInit)(nil)).Elem(), - "Ikev2InitiateSaInitReply": reflect.TypeOf((*Ikev2InitiateSaInitReply)(nil)).Elem(), - "Ikev2ProfileAddDel": reflect.TypeOf((*Ikev2ProfileAddDel)(nil)).Elem(), - "Ikev2ProfileAddDelReply": reflect.TypeOf((*Ikev2ProfileAddDelReply)(nil)).Elem(), - "Ikev2ProfileSetAuth": reflect.TypeOf((*Ikev2ProfileSetAuth)(nil)).Elem(), - "Ikev2ProfileSetAuthReply": reflect.TypeOf((*Ikev2ProfileSetAuthReply)(nil)).Elem(), - "Ikev2ProfileSetID": reflect.TypeOf((*Ikev2ProfileSetID)(nil)).Elem(), - "Ikev2ProfileSetIDReply": reflect.TypeOf((*Ikev2ProfileSetIDReply)(nil)).Elem(), - "Ikev2ProfileSetTs": reflect.TypeOf((*Ikev2ProfileSetTs)(nil)).Elem(), - "Ikev2ProfileSetTsReply": reflect.TypeOf((*Ikev2ProfileSetTsReply)(nil)).Elem(), - "Ikev2SetEspTransforms": reflect.TypeOf((*Ikev2SetEspTransforms)(nil)).Elem(), - "Ikev2SetEspTransformsReply": reflect.TypeOf((*Ikev2SetEspTransformsReply)(nil)).Elem(), - "Ikev2SetIkeTransforms": reflect.TypeOf((*Ikev2SetIkeTransforms)(nil)).Elem(), - "Ikev2SetIkeTransformsReply": reflect.TypeOf((*Ikev2SetIkeTransformsReply)(nil)).Elem(), - "Ikev2SetLocalKey": reflect.TypeOf((*Ikev2SetLocalKey)(nil)).Elem(), - "Ikev2SetLocalKeyReply": reflect.TypeOf((*Ikev2SetLocalKeyReply)(nil)).Elem(), - "Ikev2SetResponder": reflect.TypeOf((*Ikev2SetResponder)(nil)).Elem(), - "Ikev2SetResponderReply": reflect.TypeOf((*Ikev2SetResponderReply)(nil)).Elem(), - "Ikev2SetSaLifetime": reflect.TypeOf((*Ikev2SetSaLifetime)(nil)).Elem(), - "Ikev2SetSaLifetimeReply": reflect.TypeOf((*Ikev2SetSaLifetimeReply)(nil)).Elem(), - "IpsecInterfaceAddDelSpd": reflect.TypeOf((*IpsecInterfaceAddDelSpd)(nil)).Elem(), - "IpsecInterfaceAddDelSpdReply": reflect.TypeOf((*IpsecInterfaceAddDelSpdReply)(nil)).Elem(), - "IpsecSaDetails": reflect.TypeOf((*IpsecSaDetails)(nil)).Elem(), - "IpsecSaDump": reflect.TypeOf((*IpsecSaDump)(nil)).Elem(), - "IpsecSaSetKey": reflect.TypeOf((*IpsecSaSetKey)(nil)).Elem(), - "IpsecSaSetKeyReply": reflect.TypeOf((*IpsecSaSetKeyReply)(nil)).Elem(), - "IpsecSadAddDelEntry": reflect.TypeOf((*IpsecSadAddDelEntry)(nil)).Elem(), - "IpsecSadAddDelEntryReply": reflect.TypeOf((*IpsecSadAddDelEntryReply)(nil)).Elem(), - "IpsecSpdAddDel": reflect.TypeOf((*IpsecSpdAddDel)(nil)).Elem(), - "IpsecSpdAddDelEntry": reflect.TypeOf((*IpsecSpdAddDelEntry)(nil)).Elem(), - "IpsecSpdAddDelEntryReply": reflect.TypeOf((*IpsecSpdAddDelEntryReply)(nil)).Elem(), - "IpsecSpdAddDelReply": reflect.TypeOf((*IpsecSpdAddDelReply)(nil)).Elem(), - "IpsecSpdDetails": reflect.TypeOf((*IpsecSpdDetails)(nil)).Elem(), - "IpsecSpdDump": reflect.TypeOf((*IpsecSpdDump)(nil)).Elem(), - "IpsecTunnelIfAddDel": reflect.TypeOf((*IpsecTunnelIfAddDel)(nil)).Elem(), - "IpsecTunnelIfAddDelReply": reflect.TypeOf((*IpsecTunnelIfAddDelReply)(nil)).Elem(), - "IpsecTunnelIfSetKey": reflect.TypeOf((*IpsecTunnelIfSetKey)(nil)).Elem(), - "IpsecTunnelIfSetKeyReply": reflect.TypeOf((*IpsecTunnelIfSetKeyReply)(nil)).Elem(), - "IpsecTunnelIfSetSa": reflect.TypeOf((*IpsecTunnelIfSetSa)(nil)).Elem(), - "IpsecTunnelIfSetSaReply": reflect.TypeOf((*IpsecTunnelIfSetSaReply)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewIkev2InitiateDelChildSa": reflect.ValueOf(NewIkev2InitiateDelChildSa), - "NewIkev2InitiateDelChildSaReply": reflect.ValueOf(NewIkev2InitiateDelChildSaReply), - "NewIkev2InitiateDelIkeSa": reflect.ValueOf(NewIkev2InitiateDelIkeSa), - "NewIkev2InitiateDelIkeSaReply": reflect.ValueOf(NewIkev2InitiateDelIkeSaReply), - "NewIkev2InitiateRekeyChildSa": reflect.ValueOf(NewIkev2InitiateRekeyChildSa), - "NewIkev2InitiateRekeyChildSaReply": reflect.ValueOf(NewIkev2InitiateRekeyChildSaReply), - "NewIkev2InitiateSaInit": reflect.ValueOf(NewIkev2InitiateSaInit), - "NewIkev2InitiateSaInitReply": reflect.ValueOf(NewIkev2InitiateSaInitReply), - "NewIkev2ProfileAddDel": reflect.ValueOf(NewIkev2ProfileAddDel), - "NewIkev2ProfileAddDelReply": reflect.ValueOf(NewIkev2ProfileAddDelReply), - "NewIkev2ProfileSetAuth": reflect.ValueOf(NewIkev2ProfileSetAuth), - "NewIkev2ProfileSetAuthReply": reflect.ValueOf(NewIkev2ProfileSetAuthReply), - "NewIkev2ProfileSetID": reflect.ValueOf(NewIkev2ProfileSetID), - "NewIkev2ProfileSetIDReply": reflect.ValueOf(NewIkev2ProfileSetIDReply), - "NewIkev2ProfileSetTs": reflect.ValueOf(NewIkev2ProfileSetTs), - "NewIkev2ProfileSetTsReply": reflect.ValueOf(NewIkev2ProfileSetTsReply), - "NewIkev2SetEspTransforms": reflect.ValueOf(NewIkev2SetEspTransforms), - "NewIkev2SetEspTransformsReply": reflect.ValueOf(NewIkev2SetEspTransformsReply), - "NewIkev2SetIkeTransforms": reflect.ValueOf(NewIkev2SetIkeTransforms), - "NewIkev2SetIkeTransformsReply": reflect.ValueOf(NewIkev2SetIkeTransformsReply), - "NewIkev2SetLocalKey": reflect.ValueOf(NewIkev2SetLocalKey), - "NewIkev2SetLocalKeyReply": reflect.ValueOf(NewIkev2SetLocalKeyReply), - "NewIkev2SetResponder": reflect.ValueOf(NewIkev2SetResponder), - "NewIkev2SetResponderReply": reflect.ValueOf(NewIkev2SetResponderReply), - "NewIkev2SetSaLifetime": reflect.ValueOf(NewIkev2SetSaLifetime), - "NewIkev2SetSaLifetimeReply": reflect.ValueOf(NewIkev2SetSaLifetimeReply), - "NewIpsecInterfaceAddDelSpd": reflect.ValueOf(NewIpsecInterfaceAddDelSpd), - "NewIpsecInterfaceAddDelSpdReply": reflect.ValueOf(NewIpsecInterfaceAddDelSpdReply), - "NewIpsecSaDetails": reflect.ValueOf(NewIpsecSaDetails), - "NewIpsecSaDump": reflect.ValueOf(NewIpsecSaDump), - "NewIpsecSaSetKey": reflect.ValueOf(NewIpsecSaSetKey), - "NewIpsecSaSetKeyReply": reflect.ValueOf(NewIpsecSaSetKeyReply), - "NewIpsecSadAddDelEntry": reflect.ValueOf(NewIpsecSadAddDelEntry), - "NewIpsecSadAddDelEntryReply": reflect.ValueOf(NewIpsecSadAddDelEntryReply), - "NewIpsecSpdAddDel": reflect.ValueOf(NewIpsecSpdAddDel), - "NewIpsecSpdAddDelEntry": reflect.ValueOf(NewIpsecSpdAddDelEntry), - "NewIpsecSpdAddDelEntryReply": reflect.ValueOf(NewIpsecSpdAddDelEntryReply), - "NewIpsecSpdAddDelReply": reflect.ValueOf(NewIpsecSpdAddDelReply), - "NewIpsecSpdDetails": reflect.ValueOf(NewIpsecSpdDetails), - "NewIpsecSpdDump": reflect.ValueOf(NewIpsecSpdDump), - "NewIpsecTunnelIfAddDel": reflect.ValueOf(NewIpsecTunnelIfAddDel), - "NewIpsecTunnelIfAddDelReply": reflect.ValueOf(NewIpsecTunnelIfAddDelReply), - "NewIpsecTunnelIfSetKey": reflect.ValueOf(NewIpsecTunnelIfSetKey), - "NewIpsecTunnelIfSetKeyReply": reflect.ValueOf(NewIpsecTunnelIfSetKeyReply), - "NewIpsecTunnelIfSetSa": reflect.ValueOf(NewIpsecTunnelIfSetSa), - "NewIpsecTunnelIfSetSaReply": reflect.ValueOf(NewIpsecTunnelIfSetSaReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/l2/l2.ba.go b/plugins/vpp/binapi/l2/l2.ba.go index bc8c890d29..7d1aef8575 100644 --- a/plugins/vpp/binapi/l2/l2.ba.go +++ b/plugins/vpp/binapi/l2/l2.ba.go @@ -1,16 +1,15 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/l2.api.json +// source: /usr/share/vpp/api/l2.api.json /* -Package l2 is a generated VPP binary API of the 'l2' VPP module. + Package l2 is a generated from VPP binary API module 'l2'. -It is generated from this file: - l2.api.json + It contains following objects: + 45 messages + 2 types + 2 enums + 22 services -It contains these VPP binary API objects: - 43 messages - 2 types - 21 services */ package l2 @@ -19,13 +18,79 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer +/* Enums */ + +// BdFlags represents the VPP binary API enum 'bd_flags'. +// +// "bd_flags", +// [ +// "BRIDGE_API_FLAG_LEARN", +// 1 +// ], +// [ +// "BRIDGE_API_FLAG_FWD", +// 2 +// ], +// [ +// "BRIDGE_API_FLAG_FLOOD", +// 4 +// ], +// [ +// "BRIDGE_API_FLAG_UU_FLOOD", +// 8 +// ], +// [ +// "BRIDGE_API_FLAG_ARP_TERM", +// 16 +// ], +// { +// "enumtype": "u32" +// } +// +type BdFlags uint32 + +const ( + BRIDGE_API_FLAG_LEARN BdFlags = 1 + BRIDGE_API_FLAG_FWD BdFlags = 2 + BRIDGE_API_FLAG_FLOOD BdFlags = 4 + BRIDGE_API_FLAG_UU_FLOOD BdFlags = 8 + BRIDGE_API_FLAG_ARP_TERM BdFlags = 16 +) + +// L2PortType represents the VPP binary API enum 'l2_port_type'. +// +// "l2_port_type", +// [ +// "L2_API_PORT_TYPE_NORMAL", +// 0 +// ], +// [ +// "L2_API_PORT_TYPE_BVI", +// 1 +// ], +// [ +// "L2_API_PORT_TYPE_UU_FWD", +// 2 +// ], +// { +// "enumtype": "u32" +// } +// +type L2PortType uint32 + +const ( + L2_API_PORT_TYPE_NORMAL L2PortType = 0 + L2_API_PORT_TYPE_BVI L2PortType = 1 + L2_API_PORT_TYPE_UU_FWD L2PortType = 2 +) + /* Types */ // MacEntry represents the VPP binary API type 'mac_entry'. -// Generated from 'l2.api.json', line 1206: // // "mac_entry", // [ @@ -64,7 +129,6 @@ func (*MacEntry) GetCrcString() string { } // BridgeDomainSwIf represents the VPP binary API type 'bridge_domain_sw_if'. -// Generated from 'l2.api.json', line 1229: // // "bridge_domain_sw_if", // [ @@ -99,7 +163,6 @@ func (*BridgeDomainSwIf) GetCrcString() string { /* Messages */ // L2XconnectDetails represents the VPP binary API message 'l2_xconnect_details'. -// Generated from 'l2.api.json', line 4: // // "l2_xconnect_details", // [ @@ -136,12 +199,8 @@ func (*L2XconnectDetails) GetCrcString() string { func (*L2XconnectDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2XconnectDetails() api.Message { - return &L2XconnectDetails{} -} // L2XconnectDump represents the VPP binary API message 'l2_xconnect_dump'. -// Generated from 'l2.api.json', line 26: // // "l2_xconnect_dump", // [ @@ -171,12 +230,8 @@ func (*L2XconnectDump) GetCrcString() string { func (*L2XconnectDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2XconnectDump() api.Message { - return &L2XconnectDump{} -} // L2FibTableDetails represents the VPP binary API message 'l2_fib_table_details'. -// Generated from 'l2.api.json', line 44: // // "l2_fib_table_details", // [ @@ -234,12 +289,8 @@ func (*L2FibTableDetails) GetCrcString() string { func (*L2FibTableDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2FibTableDetails() api.Message { - return &L2FibTableDetails{} -} // L2FibTableDump represents the VPP binary API message 'l2_fib_table_dump'. -// Generated from 'l2.api.json', line 83: // // "l2_fib_table_dump", // [ @@ -275,12 +326,8 @@ func (*L2FibTableDump) GetCrcString() string { func (*L2FibTableDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2FibTableDump() api.Message { - return &L2FibTableDump{} -} // L2FibClearTable represents the VPP binary API message 'l2_fib_clear_table'. -// Generated from 'l2.api.json', line 105: // // "l2_fib_clear_table", // [ @@ -310,12 +357,8 @@ func (*L2FibClearTable) GetCrcString() string { func (*L2FibClearTable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2FibClearTable() api.Message { - return &L2FibClearTable{} -} // L2FibClearTableReply represents the VPP binary API message 'l2_fib_clear_table_reply'. -// Generated from 'l2.api.json', line 123: // // "l2_fib_clear_table_reply", // [ @@ -347,12 +390,8 @@ func (*L2FibClearTableReply) GetCrcString() string { func (*L2FibClearTableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2FibClearTableReply() api.Message { - return &L2FibClearTableReply{} -} // L2fibFlushAll represents the VPP binary API message 'l2fib_flush_all'. -// Generated from 'l2.api.json', line 141: // // "l2fib_flush_all", // [ @@ -382,12 +421,8 @@ func (*L2fibFlushAll) GetCrcString() string { func (*L2fibFlushAll) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2fibFlushAll() api.Message { - return &L2fibFlushAll{} -} // L2fibFlushAllReply represents the VPP binary API message 'l2fib_flush_all_reply'. -// Generated from 'l2.api.json', line 159: // // "l2fib_flush_all_reply", // [ @@ -419,12 +454,8 @@ func (*L2fibFlushAllReply) GetCrcString() string { func (*L2fibFlushAllReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2fibFlushAllReply() api.Message { - return &L2fibFlushAllReply{} -} // L2fibFlushBd represents the VPP binary API message 'l2fib_flush_bd'. -// Generated from 'l2.api.json', line 177: // // "l2fib_flush_bd", // [ @@ -460,12 +491,8 @@ func (*L2fibFlushBd) GetCrcString() string { func (*L2fibFlushBd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2fibFlushBd() api.Message { - return &L2fibFlushBd{} -} // L2fibFlushBdReply represents the VPP binary API message 'l2fib_flush_bd_reply'. -// Generated from 'l2.api.json', line 199: // // "l2fib_flush_bd_reply", // [ @@ -497,12 +524,8 @@ func (*L2fibFlushBdReply) GetCrcString() string { func (*L2fibFlushBdReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2fibFlushBdReply() api.Message { - return &L2fibFlushBdReply{} -} // L2fibFlushInt represents the VPP binary API message 'l2fib_flush_int'. -// Generated from 'l2.api.json', line 217: // // "l2fib_flush_int", // [ @@ -538,12 +561,8 @@ func (*L2fibFlushInt) GetCrcString() string { func (*L2fibFlushInt) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2fibFlushInt() api.Message { - return &L2fibFlushInt{} -} // L2fibFlushIntReply represents the VPP binary API message 'l2fib_flush_int_reply'. -// Generated from 'l2.api.json', line 239: // // "l2fib_flush_int_reply", // [ @@ -575,12 +594,8 @@ func (*L2fibFlushIntReply) GetCrcString() string { func (*L2fibFlushIntReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2fibFlushIntReply() api.Message { - return &L2fibFlushIntReply{} -} // L2fibAddDel represents the VPP binary API message 'l2fib_add_del'. -// Generated from 'l2.api.json', line 257: // // "l2fib_add_del", // [ @@ -647,12 +662,8 @@ func (*L2fibAddDel) GetCrcString() string { func (*L2fibAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2fibAddDel() api.Message { - return &L2fibAddDel{} -} // L2fibAddDelReply represents the VPP binary API message 'l2fib_add_del_reply'. -// Generated from 'l2.api.json', line 304: // // "l2fib_add_del_reply", // [ @@ -684,12 +695,8 @@ func (*L2fibAddDelReply) GetCrcString() string { func (*L2fibAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2fibAddDelReply() api.Message { - return &L2fibAddDelReply{} -} // WantL2MacsEvents represents the VPP binary API message 'want_l2_macs_events'. -// Generated from 'l2.api.json', line 322: // // "want_l2_macs_events", // [ @@ -745,12 +752,8 @@ func (*WantL2MacsEvents) GetCrcString() string { func (*WantL2MacsEvents) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantL2MacsEvents() api.Message { - return &WantL2MacsEvents{} -} // WantL2MacsEventsReply represents the VPP binary API message 'want_l2_macs_events_reply'. -// Generated from 'l2.api.json', line 360: // // "want_l2_macs_events_reply", // [ @@ -782,12 +785,8 @@ func (*WantL2MacsEventsReply) GetCrcString() string { func (*WantL2MacsEventsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantL2MacsEventsReply() api.Message { - return &WantL2MacsEventsReply{} -} // L2MacsEvent represents the VPP binary API message 'l2_macs_event'. -// Generated from 'l2.api.json', line 378: // // "l2_macs_event", // [ @@ -831,12 +830,8 @@ func (*L2MacsEvent) GetCrcString() string { func (*L2MacsEvent) GetMessageType() api.MessageType { return api.EventMessage } -func NewL2MacsEvent() api.Message { - return &L2MacsEvent{} -} // L2Flags represents the VPP binary API message 'l2_flags'. -// Generated from 'l2.api.json', line 406: // // "l2_flags", // [ @@ -882,12 +877,8 @@ func (*L2Flags) GetCrcString() string { func (*L2Flags) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2Flags() api.Message { - return &L2Flags{} -} // L2FlagsReply represents the VPP binary API message 'l2_flags_reply'. -// Generated from 'l2.api.json', line 436: // // "l2_flags_reply", // [ @@ -924,12 +915,8 @@ func (*L2FlagsReply) GetCrcString() string { func (*L2FlagsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2FlagsReply() api.Message { - return &L2FlagsReply{} -} // BridgeDomainSetMacAge represents the VPP binary API message 'bridge_domain_set_mac_age'. -// Generated from 'l2.api.json', line 458: // // "bridge_domain_set_mac_age", // [ @@ -970,12 +957,8 @@ func (*BridgeDomainSetMacAge) GetCrcString() string { func (*BridgeDomainSetMacAge) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBridgeDomainSetMacAge() api.Message { - return &BridgeDomainSetMacAge{} -} // BridgeDomainSetMacAgeReply represents the VPP binary API message 'bridge_domain_set_mac_age_reply'. -// Generated from 'l2.api.json', line 484: // // "bridge_domain_set_mac_age_reply", // [ @@ -1007,12 +990,8 @@ func (*BridgeDomainSetMacAgeReply) GetCrcString() string { func (*BridgeDomainSetMacAgeReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBridgeDomainSetMacAgeReply() api.Message { - return &BridgeDomainSetMacAgeReply{} -} // BridgeDomainAddDel represents the VPP binary API message 'bridge_domain_add_del'. -// Generated from 'l2.api.json', line 502: // // "bridge_domain_add_del", // [ @@ -1089,12 +1068,8 @@ func (*BridgeDomainAddDel) GetCrcString() string { func (*BridgeDomainAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBridgeDomainAddDel() api.Message { - return &BridgeDomainAddDel{} -} // BridgeDomainAddDelReply represents the VPP binary API message 'bridge_domain_add_del_reply'. -// Generated from 'l2.api.json', line 557: // // "bridge_domain_add_del_reply", // [ @@ -1126,12 +1101,8 @@ func (*BridgeDomainAddDelReply) GetCrcString() string { func (*BridgeDomainAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBridgeDomainAddDelReply() api.Message { - return &BridgeDomainAddDelReply{} -} // BridgeDomainDump represents the VPP binary API message 'bridge_domain_dump'. -// Generated from 'l2.api.json', line 575: // // "bridge_domain_dump", // [ @@ -1167,12 +1138,8 @@ func (*BridgeDomainDump) GetCrcString() string { func (*BridgeDomainDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBridgeDomainDump() api.Message { - return &BridgeDomainDump{} -} // BridgeDomainDetails represents the VPP binary API message 'bridge_domain_details'. -// Generated from 'l2.api.json', line 597: // // "bridge_domain_details", // [ @@ -1222,6 +1189,10 @@ func NewBridgeDomainDump() api.Message { // ], // [ // "u32", +// "uu_fwd_sw_if_index" +// ], +// [ +// "u32", // "n_sw_ifs" // ], // [ @@ -1231,38 +1202,35 @@ func NewBridgeDomainDump() api.Message { // "n_sw_ifs" // ], // { -// "crc": "0x5527b45f" +// "crc": "0xb2134997" // } // type BridgeDomainDetails struct { - BdID uint32 - Flood uint8 - UuFlood uint8 - Forward uint8 - Learn uint8 - ArpTerm uint8 - MacAge uint8 - BdTag []byte `struc:"[64]byte"` - BviSwIfIndex uint32 - NSwIfs uint32 `struc:"sizeof=SwIfDetails"` - SwIfDetails []BridgeDomainSwIf + BdID uint32 + Flood uint8 + UuFlood uint8 + Forward uint8 + Learn uint8 + ArpTerm uint8 + MacAge uint8 + BdTag []byte `struc:"[64]byte"` + BviSwIfIndex uint32 + UuFwdSwIfIndex uint32 + NSwIfs uint32 `struc:"sizeof=SwIfDetails"` + SwIfDetails []BridgeDomainSwIf } func (*BridgeDomainDetails) GetMessageName() string { return "bridge_domain_details" } func (*BridgeDomainDetails) GetCrcString() string { - return "5527b45f" + return "b2134997" } func (*BridgeDomainDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBridgeDomainDetails() api.Message { - return &BridgeDomainDetails{} -} // BridgeFlags represents the VPP binary API message 'bridge_flags'. -// Generated from 'l2.api.json', line 658: // // "bridge_flags", // [ @@ -1286,34 +1254,30 @@ func NewBridgeDomainDetails() api.Message { // "is_set" // ], // [ -// "u32", -// "feature_bitmap" +// "vl_api_bd_flags_t", +// "flags" // ], // { -// "crc": "0x6b81f158" +// "crc": "0x8563d406" // } // type BridgeFlags struct { - BdID uint32 - IsSet uint8 - FeatureBitmap uint32 + BdID uint32 + IsSet uint8 + Flags BdFlags } func (*BridgeFlags) GetMessageName() string { return "bridge_flags" } func (*BridgeFlags) GetCrcString() string { - return "6b81f158" + return "8563d406" } func (*BridgeFlags) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBridgeFlags() api.Message { - return &BridgeFlags{} -} // BridgeFlagsReply represents the VPP binary API message 'bridge_flags_reply'. -// Generated from 'l2.api.json', line 688: // // "bridge_flags_reply", // [ @@ -1350,12 +1314,8 @@ func (*BridgeFlagsReply) GetCrcString() string { func (*BridgeFlagsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBridgeFlagsReply() api.Message { - return &BridgeFlagsReply{} -} // L2InterfaceVlanTagRewrite represents the VPP binary API message 'l2_interface_vlan_tag_rewrite'. -// Generated from 'l2.api.json', line 710: // // "l2_interface_vlan_tag_rewrite", // [ @@ -1411,12 +1371,8 @@ func (*L2InterfaceVlanTagRewrite) GetCrcString() string { func (*L2InterfaceVlanTagRewrite) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2InterfaceVlanTagRewrite() api.Message { - return &L2InterfaceVlanTagRewrite{} -} // L2InterfaceVlanTagRewriteReply represents the VPP binary API message 'l2_interface_vlan_tag_rewrite_reply'. -// Generated from 'l2.api.json', line 748: // // "l2_interface_vlan_tag_rewrite_reply", // [ @@ -1448,12 +1404,8 @@ func (*L2InterfaceVlanTagRewriteReply) GetCrcString() string { func (*L2InterfaceVlanTagRewriteReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2InterfaceVlanTagRewriteReply() api.Message { - return &L2InterfaceVlanTagRewriteReply{} -} // L2InterfacePbbTagRewrite represents the VPP binary API message 'l2_interface_pbb_tag_rewrite'. -// Generated from 'l2.api.json', line 766: // // "l2_interface_pbb_tag_rewrite", // [ @@ -1521,12 +1473,8 @@ func (*L2InterfacePbbTagRewrite) GetCrcString() string { func (*L2InterfacePbbTagRewrite) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2InterfacePbbTagRewrite() api.Message { - return &L2InterfacePbbTagRewrite{} -} // L2InterfacePbbTagRewriteReply represents the VPP binary API message 'l2_interface_pbb_tag_rewrite_reply'. -// Generated from 'l2.api.json', line 814: // // "l2_interface_pbb_tag_rewrite_reply", // [ @@ -1558,12 +1506,8 @@ func (*L2InterfacePbbTagRewriteReply) GetCrcString() string { func (*L2InterfacePbbTagRewriteReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2InterfacePbbTagRewriteReply() api.Message { - return &L2InterfacePbbTagRewriteReply{} -} // L2PatchAddDel represents the VPP binary API message 'l2_patch_add_del'. -// Generated from 'l2.api.json', line 832: // // "l2_patch_add_del", // [ @@ -1609,12 +1553,8 @@ func (*L2PatchAddDel) GetCrcString() string { func (*L2PatchAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2PatchAddDel() api.Message { - return &L2PatchAddDel{} -} // L2PatchAddDelReply represents the VPP binary API message 'l2_patch_add_del_reply'. -// Generated from 'l2.api.json', line 862: // // "l2_patch_add_del_reply", // [ @@ -1646,12 +1586,8 @@ func (*L2PatchAddDelReply) GetCrcString() string { func (*L2PatchAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2PatchAddDelReply() api.Message { - return &L2PatchAddDelReply{} -} // SwInterfaceSetL2Xconnect represents the VPP binary API message 'sw_interface_set_l2_xconnect'. -// Generated from 'l2.api.json', line 880: // // "sw_interface_set_l2_xconnect", // [ @@ -1697,12 +1633,8 @@ func (*SwInterfaceSetL2Xconnect) GetCrcString() string { func (*SwInterfaceSetL2Xconnect) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetL2Xconnect() api.Message { - return &SwInterfaceSetL2Xconnect{} -} // SwInterfaceSetL2XconnectReply represents the VPP binary API message 'sw_interface_set_l2_xconnect_reply'. -// Generated from 'l2.api.json', line 910: // // "sw_interface_set_l2_xconnect_reply", // [ @@ -1734,12 +1666,8 @@ func (*SwInterfaceSetL2XconnectReply) GetCrcString() string { func (*SwInterfaceSetL2XconnectReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetL2XconnectReply() api.Message { - return &SwInterfaceSetL2XconnectReply{} -} // SwInterfaceSetL2Bridge represents the VPP binary API message 'sw_interface_set_l2_bridge'. -// Generated from 'l2.api.json', line 928: // // "sw_interface_set_l2_bridge", // [ @@ -1763,26 +1691,26 @@ func NewSwInterfaceSetL2XconnectReply() api.Message { // "bd_id" // ], // [ -// "u8", -// "shg" +// "vl_api_l2_port_type_t", +// "port_type" // ], // [ // "u8", -// "bvi" +// "shg" // ], // [ // "u8", // "enable" // ], // { -// "crc": "0x95b4e4cf" +// "crc": "0x2af7795e" // } // type SwInterfaceSetL2Bridge struct { RxSwIfIndex uint32 BdID uint32 + PortType L2PortType Shg uint8 - Bvi uint8 Enable uint8 } @@ -1790,17 +1718,13 @@ func (*SwInterfaceSetL2Bridge) GetMessageName() string { return "sw_interface_set_l2_bridge" } func (*SwInterfaceSetL2Bridge) GetCrcString() string { - return "95b4e4cf" + return "2af7795e" } func (*SwInterfaceSetL2Bridge) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetL2Bridge() api.Message { - return &SwInterfaceSetL2Bridge{} -} // SwInterfaceSetL2BridgeReply represents the VPP binary API message 'sw_interface_set_l2_bridge_reply'. -// Generated from 'l2.api.json', line 966: // // "sw_interface_set_l2_bridge_reply", // [ @@ -1832,12 +1756,8 @@ func (*SwInterfaceSetL2BridgeReply) GetCrcString() string { func (*SwInterfaceSetL2BridgeReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetL2BridgeReply() api.Message { - return &SwInterfaceSetL2BridgeReply{} -} // BdIPMacAddDel represents the VPP binary API message 'bd_ip_mac_add_del'. -// Generated from 'l2.api.json', line 984: // // "bd_ip_mac_add_del", // [ @@ -1895,12 +1815,8 @@ func (*BdIPMacAddDel) GetCrcString() string { func (*BdIPMacAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBdIPMacAddDel() api.Message { - return &BdIPMacAddDel{} -} // BdIPMacAddDelReply represents the VPP binary API message 'bd_ip_mac_add_del_reply'. -// Generated from 'l2.api.json', line 1024: // // "bd_ip_mac_add_del_reply", // [ @@ -1932,12 +1848,95 @@ func (*BdIPMacAddDelReply) GetCrcString() string { func (*BdIPMacAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBdIPMacAddDelReply() api.Message { - return &BdIPMacAddDelReply{} + +// BdIPMacDetails represents the VPP binary API message 'bd_ip_mac_details'. +// +// "bd_ip_mac_details", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u32", +// "bd_id" +// ], +// [ +// "u8", +// "is_ipv6" +// ], +// [ +// "u8", +// "ip_address", +// 16 +// ], +// [ +// "u8", +// "mac_address", +// 6 +// ], +// { +// "crc": "0xd3184eda" +// } +// +type BdIPMacDetails struct { + BdID uint32 + IsIPv6 uint8 + IPAddress []byte `struc:"[16]byte"` + MacAddress []byte `struc:"[6]byte"` +} + +func (*BdIPMacDetails) GetMessageName() string { + return "bd_ip_mac_details" +} +func (*BdIPMacDetails) GetCrcString() string { + return "d3184eda" +} +func (*BdIPMacDetails) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// BdIPMacDump represents the VPP binary API message 'bd_ip_mac_dump'. +// +// "bd_ip_mac_dump", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u32", +// "bd_id" +// ], +// { +// "crc": "0xc25fdce6" +// } +// +type BdIPMacDump struct { + BdID uint32 +} + +func (*BdIPMacDump) GetMessageName() string { + return "bd_ip_mac_dump" +} +func (*BdIPMacDump) GetCrcString() string { + return "c25fdce6" +} +func (*BdIPMacDump) GetMessageType() api.MessageType { + return api.RequestMessage } // L2InterfaceEfpFilter represents the VPP binary API message 'l2_interface_efp_filter'. -// Generated from 'l2.api.json', line 1042: // // "l2_interface_efp_filter", // [ @@ -1978,12 +1977,8 @@ func (*L2InterfaceEfpFilter) GetCrcString() string { func (*L2InterfaceEfpFilter) GetMessageType() api.MessageType { return api.RequestMessage } -func NewL2InterfaceEfpFilter() api.Message { - return &L2InterfaceEfpFilter{} -} // L2InterfaceEfpFilterReply represents the VPP binary API message 'l2_interface_efp_filter_reply'. -// Generated from 'l2.api.json', line 1068: // // "l2_interface_efp_filter_reply", // [ @@ -2015,12 +2010,8 @@ func (*L2InterfaceEfpFilterReply) GetCrcString() string { func (*L2InterfaceEfpFilterReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewL2InterfaceEfpFilterReply() api.Message { - return &L2InterfaceEfpFilterReply{} -} // SwInterfaceSetVpath represents the VPP binary API message 'sw_interface_set_vpath'. -// Generated from 'l2.api.json', line 1086: // // "sw_interface_set_vpath", // [ @@ -2061,12 +2052,8 @@ func (*SwInterfaceSetVpath) GetCrcString() string { func (*SwInterfaceSetVpath) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetVpath() api.Message { - return &SwInterfaceSetVpath{} -} // SwInterfaceSetVpathReply represents the VPP binary API message 'sw_interface_set_vpath_reply'. -// Generated from 'l2.api.json', line 1112: // // "sw_interface_set_vpath_reply", // [ @@ -2098,13 +2085,11 @@ func (*SwInterfaceSetVpathReply) GetCrcString() string { func (*SwInterfaceSetVpathReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetVpathReply() api.Message { - return &SwInterfaceSetVpathReply{} -} /* Services */ type Services interface { + DumpBdIPMac(*BdIPMacDump) (*BdIPMacDetails, error) DumpBridgeDomain(*BridgeDomainDump) (*BridgeDomainDetails, error) DumpL2FibTable(*L2FibTableDump) (*L2FibTableDetails, error) DumpL2Xconnect(*L2XconnectDump) (*L2XconnectDetails, error) @@ -2168,6 +2153,8 @@ func init() { api.RegisterMessage((*SwInterfaceSetL2BridgeReply)(nil), "l2.SwInterfaceSetL2BridgeReply") api.RegisterMessage((*BdIPMacAddDel)(nil), "l2.BdIPMacAddDel") api.RegisterMessage((*BdIPMacAddDelReply)(nil), "l2.BdIPMacAddDelReply") + api.RegisterMessage((*BdIPMacDetails)(nil), "l2.BdIPMacDetails") + api.RegisterMessage((*BdIPMacDump)(nil), "l2.BdIPMacDump") api.RegisterMessage((*L2InterfaceEfpFilter)(nil), "l2.L2InterfaceEfpFilter") api.RegisterMessage((*L2InterfaceEfpFilterReply)(nil), "l2.L2InterfaceEfpFilterReply") api.RegisterMessage((*SwInterfaceSetVpath)(nil), "l2.SwInterfaceSetVpath") diff --git a/plugins/vpp/binapi/l2/pkgreflect.go b/plugins/vpp/binapi/l2/pkgreflect.go deleted file mode 100644 index a7bd49dae9..0000000000 --- a/plugins/vpp/binapi/l2/pkgreflect.go +++ /dev/null @@ -1,107 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package l2 - -import "reflect" - -var Types = map[string]reflect.Type{ - "BdIPMacAddDel": reflect.TypeOf((*BdIPMacAddDel)(nil)).Elem(), - "BdIPMacAddDelReply": reflect.TypeOf((*BdIPMacAddDelReply)(nil)).Elem(), - "BridgeDomainAddDel": reflect.TypeOf((*BridgeDomainAddDel)(nil)).Elem(), - "BridgeDomainAddDelReply": reflect.TypeOf((*BridgeDomainAddDelReply)(nil)).Elem(), - "BridgeDomainDetails": reflect.TypeOf((*BridgeDomainDetails)(nil)).Elem(), - "BridgeDomainDump": reflect.TypeOf((*BridgeDomainDump)(nil)).Elem(), - "BridgeDomainSetMacAge": reflect.TypeOf((*BridgeDomainSetMacAge)(nil)).Elem(), - "BridgeDomainSetMacAgeReply": reflect.TypeOf((*BridgeDomainSetMacAgeReply)(nil)).Elem(), - "BridgeDomainSwIf": reflect.TypeOf((*BridgeDomainSwIf)(nil)).Elem(), - "BridgeFlags": reflect.TypeOf((*BridgeFlags)(nil)).Elem(), - "BridgeFlagsReply": reflect.TypeOf((*BridgeFlagsReply)(nil)).Elem(), - "L2FibClearTable": reflect.TypeOf((*L2FibClearTable)(nil)).Elem(), - "L2FibClearTableReply": reflect.TypeOf((*L2FibClearTableReply)(nil)).Elem(), - "L2FibTableDetails": reflect.TypeOf((*L2FibTableDetails)(nil)).Elem(), - "L2FibTableDump": reflect.TypeOf((*L2FibTableDump)(nil)).Elem(), - "L2Flags": reflect.TypeOf((*L2Flags)(nil)).Elem(), - "L2FlagsReply": reflect.TypeOf((*L2FlagsReply)(nil)).Elem(), - "L2InterfaceEfpFilter": reflect.TypeOf((*L2InterfaceEfpFilter)(nil)).Elem(), - "L2InterfaceEfpFilterReply": reflect.TypeOf((*L2InterfaceEfpFilterReply)(nil)).Elem(), - "L2InterfacePbbTagRewrite": reflect.TypeOf((*L2InterfacePbbTagRewrite)(nil)).Elem(), - "L2InterfacePbbTagRewriteReply": reflect.TypeOf((*L2InterfacePbbTagRewriteReply)(nil)).Elem(), - "L2InterfaceVlanTagRewrite": reflect.TypeOf((*L2InterfaceVlanTagRewrite)(nil)).Elem(), - "L2InterfaceVlanTagRewriteReply": reflect.TypeOf((*L2InterfaceVlanTagRewriteReply)(nil)).Elem(), - "L2MacsEvent": reflect.TypeOf((*L2MacsEvent)(nil)).Elem(), - "L2PatchAddDel": reflect.TypeOf((*L2PatchAddDel)(nil)).Elem(), - "L2PatchAddDelReply": reflect.TypeOf((*L2PatchAddDelReply)(nil)).Elem(), - "L2XconnectDetails": reflect.TypeOf((*L2XconnectDetails)(nil)).Elem(), - "L2XconnectDump": reflect.TypeOf((*L2XconnectDump)(nil)).Elem(), - "L2fibAddDel": reflect.TypeOf((*L2fibAddDel)(nil)).Elem(), - "L2fibAddDelReply": reflect.TypeOf((*L2fibAddDelReply)(nil)).Elem(), - "L2fibFlushAll": reflect.TypeOf((*L2fibFlushAll)(nil)).Elem(), - "L2fibFlushAllReply": reflect.TypeOf((*L2fibFlushAllReply)(nil)).Elem(), - "L2fibFlushBd": reflect.TypeOf((*L2fibFlushBd)(nil)).Elem(), - "L2fibFlushBdReply": reflect.TypeOf((*L2fibFlushBdReply)(nil)).Elem(), - "L2fibFlushInt": reflect.TypeOf((*L2fibFlushInt)(nil)).Elem(), - "L2fibFlushIntReply": reflect.TypeOf((*L2fibFlushIntReply)(nil)).Elem(), - "MacEntry": reflect.TypeOf((*MacEntry)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SwInterfaceSetL2Bridge": reflect.TypeOf((*SwInterfaceSetL2Bridge)(nil)).Elem(), - "SwInterfaceSetL2BridgeReply": reflect.TypeOf((*SwInterfaceSetL2BridgeReply)(nil)).Elem(), - "SwInterfaceSetL2Xconnect": reflect.TypeOf((*SwInterfaceSetL2Xconnect)(nil)).Elem(), - "SwInterfaceSetL2XconnectReply": reflect.TypeOf((*SwInterfaceSetL2XconnectReply)(nil)).Elem(), - "SwInterfaceSetVpath": reflect.TypeOf((*SwInterfaceSetVpath)(nil)).Elem(), - "SwInterfaceSetVpathReply": reflect.TypeOf((*SwInterfaceSetVpathReply)(nil)).Elem(), - "WantL2MacsEvents": reflect.TypeOf((*WantL2MacsEvents)(nil)).Elem(), - "WantL2MacsEventsReply": reflect.TypeOf((*WantL2MacsEventsReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewBdIPMacAddDel": reflect.ValueOf(NewBdIPMacAddDel), - "NewBdIPMacAddDelReply": reflect.ValueOf(NewBdIPMacAddDelReply), - "NewBridgeDomainAddDel": reflect.ValueOf(NewBridgeDomainAddDel), - "NewBridgeDomainAddDelReply": reflect.ValueOf(NewBridgeDomainAddDelReply), - "NewBridgeDomainDetails": reflect.ValueOf(NewBridgeDomainDetails), - "NewBridgeDomainDump": reflect.ValueOf(NewBridgeDomainDump), - "NewBridgeDomainSetMacAge": reflect.ValueOf(NewBridgeDomainSetMacAge), - "NewBridgeDomainSetMacAgeReply": reflect.ValueOf(NewBridgeDomainSetMacAgeReply), - "NewBridgeFlags": reflect.ValueOf(NewBridgeFlags), - "NewBridgeFlagsReply": reflect.ValueOf(NewBridgeFlagsReply), - "NewL2FibClearTable": reflect.ValueOf(NewL2FibClearTable), - "NewL2FibClearTableReply": reflect.ValueOf(NewL2FibClearTableReply), - "NewL2FibTableDetails": reflect.ValueOf(NewL2FibTableDetails), - "NewL2FibTableDump": reflect.ValueOf(NewL2FibTableDump), - "NewL2Flags": reflect.ValueOf(NewL2Flags), - "NewL2FlagsReply": reflect.ValueOf(NewL2FlagsReply), - "NewL2InterfaceEfpFilter": reflect.ValueOf(NewL2InterfaceEfpFilter), - "NewL2InterfaceEfpFilterReply": reflect.ValueOf(NewL2InterfaceEfpFilterReply), - "NewL2InterfacePbbTagRewrite": reflect.ValueOf(NewL2InterfacePbbTagRewrite), - "NewL2InterfacePbbTagRewriteReply": reflect.ValueOf(NewL2InterfacePbbTagRewriteReply), - "NewL2InterfaceVlanTagRewrite": reflect.ValueOf(NewL2InterfaceVlanTagRewrite), - "NewL2InterfaceVlanTagRewriteReply": reflect.ValueOf(NewL2InterfaceVlanTagRewriteReply), - "NewL2MacsEvent": reflect.ValueOf(NewL2MacsEvent), - "NewL2PatchAddDel": reflect.ValueOf(NewL2PatchAddDel), - "NewL2PatchAddDelReply": reflect.ValueOf(NewL2PatchAddDelReply), - "NewL2XconnectDetails": reflect.ValueOf(NewL2XconnectDetails), - "NewL2XconnectDump": reflect.ValueOf(NewL2XconnectDump), - "NewL2fibAddDel": reflect.ValueOf(NewL2fibAddDel), - "NewL2fibAddDelReply": reflect.ValueOf(NewL2fibAddDelReply), - "NewL2fibFlushAll": reflect.ValueOf(NewL2fibFlushAll), - "NewL2fibFlushAllReply": reflect.ValueOf(NewL2fibFlushAllReply), - "NewL2fibFlushBd": reflect.ValueOf(NewL2fibFlushBd), - "NewL2fibFlushBdReply": reflect.ValueOf(NewL2fibFlushBdReply), - "NewL2fibFlushInt": reflect.ValueOf(NewL2fibFlushInt), - "NewL2fibFlushIntReply": reflect.ValueOf(NewL2fibFlushIntReply), - "NewSwInterfaceSetL2Bridge": reflect.ValueOf(NewSwInterfaceSetL2Bridge), - "NewSwInterfaceSetL2BridgeReply": reflect.ValueOf(NewSwInterfaceSetL2BridgeReply), - "NewSwInterfaceSetL2Xconnect": reflect.ValueOf(NewSwInterfaceSetL2Xconnect), - "NewSwInterfaceSetL2XconnectReply": reflect.ValueOf(NewSwInterfaceSetL2XconnectReply), - "NewSwInterfaceSetVpath": reflect.ValueOf(NewSwInterfaceSetVpath), - "NewSwInterfaceSetVpathReply": reflect.ValueOf(NewSwInterfaceSetVpathReply), - "NewWantL2MacsEvents": reflect.ValueOf(NewWantL2MacsEvents), - "NewWantL2MacsEventsReply": reflect.ValueOf(NewWantL2MacsEventsReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/memif/memif.ba.go b/plugins/vpp/binapi/memif/memif.ba.go index 9b0d7e4209..5aea86aad2 100644 --- a/plugins/vpp/binapi/memif/memif.ba.go +++ b/plugins/vpp/binapi/memif/memif.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/memif.api.json +// source: /usr/share/vpp/api/memif.api.json /* -Package memif is a generated VPP binary API of the 'memif' VPP module. + Package memif is a generated from VPP binary API module 'memif'. -It is generated from this file: - memif.api.json + It contains following objects: + 10 messages + 5 services -It contains these VPP binary API objects: - 10 messages - 5 services */ package memif @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // MemifSocketFilenameAddDel represents the VPP binary API message 'memif_socket_filename_add_del'. -// Generated from 'memif.api.json', line 4: // // "memif_socket_filename_add_del", // [ @@ -71,12 +69,8 @@ func (*MemifSocketFilenameAddDel) GetCrcString() string { func (*MemifSocketFilenameAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMemifSocketFilenameAddDel() api.Message { - return &MemifSocketFilenameAddDel{} -} // MemifSocketFilenameAddDelReply represents the VPP binary API message 'memif_socket_filename_add_del_reply'. -// Generated from 'memif.api.json', line 35: // // "memif_socket_filename_add_del_reply", // [ @@ -108,12 +102,8 @@ func (*MemifSocketFilenameAddDelReply) GetCrcString() string { func (*MemifSocketFilenameAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMemifSocketFilenameAddDelReply() api.Message { - return &MemifSocketFilenameAddDelReply{} -} // MemifCreate represents the VPP binary API message 'memif_create'. -// Generated from 'memif.api.json', line 53: // // "memif_create", // [ @@ -196,12 +186,8 @@ func (*MemifCreate) GetCrcString() string { func (*MemifCreate) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMemifCreate() api.Message { - return &MemifCreate{} -} // MemifCreateReply represents the VPP binary API message 'memif_create_reply'. -// Generated from 'memif.api.json', line 113: // // "memif_create_reply", // [ @@ -238,12 +224,8 @@ func (*MemifCreateReply) GetCrcString() string { func (*MemifCreateReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMemifCreateReply() api.Message { - return &MemifCreateReply{} -} // MemifDelete represents the VPP binary API message 'memif_delete'. -// Generated from 'memif.api.json', line 135: // // "memif_delete", // [ @@ -279,12 +261,8 @@ func (*MemifDelete) GetCrcString() string { func (*MemifDelete) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMemifDelete() api.Message { - return &MemifDelete{} -} // MemifDeleteReply represents the VPP binary API message 'memif_delete_reply'. -// Generated from 'memif.api.json', line 157: // // "memif_delete_reply", // [ @@ -316,12 +294,8 @@ func (*MemifDeleteReply) GetCrcString() string { func (*MemifDeleteReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMemifDeleteReply() api.Message { - return &MemifDeleteReply{} -} // MemifSocketFilenameDetails represents the VPP binary API message 'memif_socket_filename_details'. -// Generated from 'memif.api.json', line 175: // // "memif_socket_filename_details", // [ @@ -359,12 +333,8 @@ func (*MemifSocketFilenameDetails) GetCrcString() string { func (*MemifSocketFilenameDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMemifSocketFilenameDetails() api.Message { - return &MemifSocketFilenameDetails{} -} // MemifSocketFilenameDump represents the VPP binary API message 'memif_socket_filename_dump'. -// Generated from 'memif.api.json', line 198: // // "memif_socket_filename_dump", // [ @@ -394,12 +364,8 @@ func (*MemifSocketFilenameDump) GetCrcString() string { func (*MemifSocketFilenameDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMemifSocketFilenameDump() api.Message { - return &MemifSocketFilenameDump{} -} // MemifDetails represents the VPP binary API message 'memif_details'. -// Generated from 'memif.api.json', line 216: // // "memif_details", // [ @@ -483,12 +449,8 @@ func (*MemifDetails) GetCrcString() string { func (*MemifDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMemifDetails() api.Message { - return &MemifDetails{} -} // MemifDump represents the VPP binary API message 'memif_dump'. -// Generated from 'memif.api.json', line 276: // // "memif_dump", // [ @@ -518,9 +480,6 @@ func (*MemifDump) GetCrcString() string { func (*MemifDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMemifDump() api.Message { - return &MemifDump{} -} /* Services */ diff --git a/plugins/vpp/binapi/memif/pkgreflect.go b/plugins/vpp/binapi/memif/pkgreflect.go deleted file mode 100644 index a7715093b2..0000000000 --- a/plugins/vpp/binapi/memif/pkgreflect.go +++ /dev/null @@ -1,39 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package memif - -import "reflect" - -var Types = map[string]reflect.Type{ - "MemifCreate": reflect.TypeOf((*MemifCreate)(nil)).Elem(), - "MemifCreateReply": reflect.TypeOf((*MemifCreateReply)(nil)).Elem(), - "MemifDelete": reflect.TypeOf((*MemifDelete)(nil)).Elem(), - "MemifDeleteReply": reflect.TypeOf((*MemifDeleteReply)(nil)).Elem(), - "MemifDetails": reflect.TypeOf((*MemifDetails)(nil)).Elem(), - "MemifDump": reflect.TypeOf((*MemifDump)(nil)).Elem(), - "MemifSocketFilenameAddDel": reflect.TypeOf((*MemifSocketFilenameAddDel)(nil)).Elem(), - "MemifSocketFilenameAddDelReply": reflect.TypeOf((*MemifSocketFilenameAddDelReply)(nil)).Elem(), - "MemifSocketFilenameDetails": reflect.TypeOf((*MemifSocketFilenameDetails)(nil)).Elem(), - "MemifSocketFilenameDump": reflect.TypeOf((*MemifSocketFilenameDump)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewMemifCreate": reflect.ValueOf(NewMemifCreate), - "NewMemifCreateReply": reflect.ValueOf(NewMemifCreateReply), - "NewMemifDelete": reflect.ValueOf(NewMemifDelete), - "NewMemifDeleteReply": reflect.ValueOf(NewMemifDeleteReply), - "NewMemifDetails": reflect.ValueOf(NewMemifDetails), - "NewMemifDump": reflect.ValueOf(NewMemifDump), - "NewMemifSocketFilenameAddDel": reflect.ValueOf(NewMemifSocketFilenameAddDel), - "NewMemifSocketFilenameAddDelReply": reflect.ValueOf(NewMemifSocketFilenameAddDelReply), - "NewMemifSocketFilenameDetails": reflect.ValueOf(NewMemifSocketFilenameDetails), - "NewMemifSocketFilenameDump": reflect.ValueOf(NewMemifSocketFilenameDump), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/nat/nat.ba.go b/plugins/vpp/binapi/nat/nat.ba.go index 942719b482..5fd734c074 100644 --- a/plugins/vpp/binapi/nat/nat.ba.go +++ b/plugins/vpp/binapi/nat/nat.ba.go @@ -1,16 +1,14 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/nat.api.json +// source: /usr/share/vpp/api/nat.api.json /* -Package nat is a generated VPP binary API of the 'nat' VPP module. + Package nat is a generated from VPP binary API module 'nat'. -It is generated from this file: - nat.api.json + It contains following objects: + 120 messages + 1 type + 60 services -It contains these VPP binary API objects: - 116 messages - 1 type - 58 services */ package nat @@ -19,13 +17,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Types */ // Nat44LbAddrPort represents the VPP binary API type 'nat44_lb_addr_port'. -// Generated from 'nat.api.json', line 3416: // // "nat44_lb_addr_port", // [ @@ -66,7 +64,6 @@ func (*Nat44LbAddrPort) GetCrcString() string { /* Messages */ // NatControlPing represents the VPP binary API message 'nat_control_ping'. -// Generated from 'nat.api.json', line 4: // // "nat_control_ping", // [ @@ -96,12 +93,8 @@ func (*NatControlPing) GetCrcString() string { func (*NatControlPing) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatControlPing() api.Message { - return &NatControlPing{} -} // NatControlPingReply represents the VPP binary API message 'nat_control_ping_reply'. -// Generated from 'nat.api.json', line 22: // // "nat_control_ping_reply", // [ @@ -143,12 +136,8 @@ func (*NatControlPingReply) GetCrcString() string { func (*NatControlPingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatControlPingReply() api.Message { - return &NatControlPingReply{} -} // NatShowConfig represents the VPP binary API message 'nat_show_config'. -// Generated from 'nat.api.json', line 48: // // "nat_show_config", // [ @@ -178,12 +167,8 @@ func (*NatShowConfig) GetCrcString() string { func (*NatShowConfig) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatShowConfig() api.Message { - return &NatShowConfig{} -} // NatShowConfigReply represents the VPP binary API message 'nat_show_config_reply'. -// Generated from 'nat.api.json', line 66: // // "nat_show_config_reply", // [ @@ -211,6 +196,14 @@ func NewNatShowConfig() api.Message { // "deterministic" // ], // [ +// "u8", +// "endpoint_dependent" +// ], +// [ +// "u8", +// "out2in_dpo" +// ], +// [ // "u32", // "translation_buckets" // ], @@ -238,8 +231,28 @@ func NewNatShowConfig() api.Message { // "u32", // "inside_vrf_id" // ], +// [ +// "u8", +// "dslite_ce" +// ], +// [ +// "u32", +// "nat64_bib_buckets" +// ], +// [ +// "u32", +// "nat64_bib_memory_size" +// ], +// [ +// "u32", +// "nat64_st_buckets" +// ], +// [ +// "u32", +// "nat64_st_memory_size" +// ], // { -// "crc": "0x7685fc1c" +// "crc": "0xef8a2bbe" // } // type NatShowConfigReply struct { @@ -247,6 +260,8 @@ type NatShowConfigReply struct { StaticMappingOnly uint8 StaticMappingConnectionTracking uint8 Deterministic uint8 + EndpointDependent uint8 + Out2inDpo uint8 TranslationBuckets uint32 TranslationMemorySize uint32 UserBuckets uint32 @@ -254,23 +269,24 @@ type NatShowConfigReply struct { MaxTranslationsPerUser uint32 OutsideVrfID uint32 InsideVrfID uint32 + DsliteCe uint8 + Nat64BibBuckets uint32 + Nat64BibMemorySize uint32 + Nat64StBuckets uint32 + Nat64StMemorySize uint32 } func (*NatShowConfigReply) GetMessageName() string { return "nat_show_config_reply" } func (*NatShowConfigReply) GetCrcString() string { - return "7685fc1c" + return "ef8a2bbe" } func (*NatShowConfigReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatShowConfigReply() api.Message { - return &NatShowConfigReply{} -} // NatSetWorkers represents the VPP binary API message 'nat_set_workers'. -// Generated from 'nat.api.json', line 124: // // "nat_set_workers", // [ @@ -306,12 +322,8 @@ func (*NatSetWorkers) GetCrcString() string { func (*NatSetWorkers) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatSetWorkers() api.Message { - return &NatSetWorkers{} -} // NatSetWorkersReply represents the VPP binary API message 'nat_set_workers_reply'. -// Generated from 'nat.api.json', line 146: // // "nat_set_workers_reply", // [ @@ -343,12 +355,8 @@ func (*NatSetWorkersReply) GetCrcString() string { func (*NatSetWorkersReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatSetWorkersReply() api.Message { - return &NatSetWorkersReply{} -} // NatWorkerDump represents the VPP binary API message 'nat_worker_dump'. -// Generated from 'nat.api.json', line 164: // // "nat_worker_dump", // [ @@ -378,12 +386,8 @@ func (*NatWorkerDump) GetCrcString() string { func (*NatWorkerDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatWorkerDump() api.Message { - return &NatWorkerDump{} -} // NatWorkerDetails represents the VPP binary API message 'nat_worker_details'. -// Generated from 'nat.api.json', line 182: // // "nat_worker_details", // [ @@ -426,12 +430,8 @@ func (*NatWorkerDetails) GetCrcString() string { func (*NatWorkerDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatWorkerDetails() api.Message { - return &NatWorkerDetails{} -} // NatIpfixEnableDisable represents the VPP binary API message 'nat_ipfix_enable_disable'. -// Generated from 'nat.api.json', line 209: // // "nat_ipfix_enable_disable", // [ @@ -477,12 +477,8 @@ func (*NatIpfixEnableDisable) GetCrcString() string { func (*NatIpfixEnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatIpfixEnableDisable() api.Message { - return &NatIpfixEnableDisable{} -} // NatIpfixEnableDisableReply represents the VPP binary API message 'nat_ipfix_enable_disable_reply'. -// Generated from 'nat.api.json', line 239: // // "nat_ipfix_enable_disable_reply", // [ @@ -514,12 +510,8 @@ func (*NatIpfixEnableDisableReply) GetCrcString() string { func (*NatIpfixEnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatIpfixEnableDisableReply() api.Message { - return &NatIpfixEnableDisableReply{} -} // NatSetReass represents the VPP binary API message 'nat_set_reass'. -// Generated from 'nat.api.json', line 257: // // "nat_set_reass", // [ @@ -575,12 +567,8 @@ func (*NatSetReass) GetCrcString() string { func (*NatSetReass) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatSetReass() api.Message { - return &NatSetReass{} -} // NatSetReassReply represents the VPP binary API message 'nat_set_reass_reply'. -// Generated from 'nat.api.json', line 295: // // "nat_set_reass_reply", // [ @@ -612,12 +600,8 @@ func (*NatSetReassReply) GetCrcString() string { func (*NatSetReassReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatSetReassReply() api.Message { - return &NatSetReassReply{} -} // NatGetReass represents the VPP binary API message 'nat_get_reass'. -// Generated from 'nat.api.json', line 313: // // "nat_get_reass", // [ @@ -647,12 +631,8 @@ func (*NatGetReass) GetCrcString() string { func (*NatGetReass) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatGetReass() api.Message { - return &NatGetReass{} -} // NatGetReassReply represents the VPP binary API message 'nat_get_reass_reply'. -// Generated from 'nat.api.json', line 331: // // "nat_get_reass_reply", // [ @@ -724,12 +704,8 @@ func (*NatGetReassReply) GetCrcString() string { func (*NatGetReassReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatGetReassReply() api.Message { - return &NatGetReassReply{} -} // NatReassDump represents the VPP binary API message 'nat_reass_dump'. -// Generated from 'nat.api.json', line 381: // // "nat_reass_dump", // [ @@ -759,12 +735,8 @@ func (*NatReassDump) GetCrcString() string { func (*NatReassDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatReassDump() api.Message { - return &NatReassDump{} -} // NatReassDetails represents the VPP binary API message 'nat_reass_details'. -// Generated from 'nat.api.json', line 399: // // "nat_reass_details", // [ @@ -785,50 +757,553 @@ func NewNatReassDump() api.Message { // 16 // ], // [ -// "u8", -// "dst_addr", -// 16 +// "u8", +// "dst_addr", +// 16 +// ], +// [ +// "u32", +// "frag_id" +// ], +// [ +// "u8", +// "proto" +// ], +// [ +// "u8", +// "frag_n" +// ], +// { +// "crc": "0xee46e2d4" +// } +// +type NatReassDetails struct { + IsIP4 uint8 + SrcAddr []byte `struc:"[16]byte"` + DstAddr []byte `struc:"[16]byte"` + FragID uint32 + Proto uint8 + FragN uint8 +} + +func (*NatReassDetails) GetMessageName() string { + return "nat_reass_details" +} +func (*NatReassDetails) GetCrcString() string { + return "ee46e2d4" +} +func (*NatReassDetails) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// NatSetTimeouts represents the VPP binary API message 'nat_set_timeouts'. +// +// "nat_set_timeouts", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u32", +// "udp" +// ], +// [ +// "u32", +// "tcp_established" +// ], +// [ +// "u32", +// "tcp_transitory" +// ], +// [ +// "u32", +// "icmp" +// ], +// { +// "crc": "0xd4746b16" +// } +// +type NatSetTimeouts struct { + UDP uint32 + TCPEstablished uint32 + TCPTransitory uint32 + ICMP uint32 +} + +func (*NatSetTimeouts) GetMessageName() string { + return "nat_set_timeouts" +} +func (*NatSetTimeouts) GetCrcString() string { + return "d4746b16" +} +func (*NatSetTimeouts) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// NatSetTimeoutsReply represents the VPP binary API message 'nat_set_timeouts_reply'. +// +// "nat_set_timeouts_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "i32", +// "retval" +// ], +// { +// "crc": "0xe8d4e804" +// } +// +type NatSetTimeoutsReply struct { + Retval int32 +} + +func (*NatSetTimeoutsReply) GetMessageName() string { + return "nat_set_timeouts_reply" +} +func (*NatSetTimeoutsReply) GetCrcString() string { + return "e8d4e804" +} +func (*NatSetTimeoutsReply) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// NatGetTimeouts represents the VPP binary API message 'nat_get_timeouts'. +// +// "nat_get_timeouts", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// { +// "crc": "0x51077d14" +// } +// +type NatGetTimeouts struct{} + +func (*NatGetTimeouts) GetMessageName() string { + return "nat_get_timeouts" +} +func (*NatGetTimeouts) GetCrcString() string { + return "51077d14" +} +func (*NatGetTimeouts) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// NatGetTimeoutsReply represents the VPP binary API message 'nat_get_timeouts_reply'. +// +// "nat_get_timeouts_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "i32", +// "retval" +// ], +// [ +// "u32", +// "udp" +// ], +// [ +// "u32", +// "tcp_established" +// ], +// [ +// "u32", +// "tcp_transitory" +// ], +// [ +// "u32", +// "icmp" +// ], +// { +// "crc": "0x3c4df4e1" +// } +// +type NatGetTimeoutsReply struct { + Retval int32 + UDP uint32 + TCPEstablished uint32 + TCPTransitory uint32 + ICMP uint32 +} + +func (*NatGetTimeoutsReply) GetMessageName() string { + return "nat_get_timeouts_reply" +} +func (*NatGetTimeoutsReply) GetCrcString() string { + return "3c4df4e1" +} +func (*NatGetTimeoutsReply) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// NatSetAddrAndPortAllocAlg represents the VPP binary API message 'nat_set_addr_and_port_alloc_alg'. +// +// "nat_set_addr_and_port_alloc_alg", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u8", +// "alg" +// ], +// [ +// "u8", +// "psid_offset" +// ], +// [ +// "u8", +// "psid_length" +// ], +// [ +// "u16", +// "psid" +// ], +// [ +// "u16", +// "start_port" +// ], +// [ +// "u16", +// "end_port" +// ], +// { +// "crc": "0xdeeb746f" +// } +// +type NatSetAddrAndPortAllocAlg struct { + Alg uint8 + PsidOffset uint8 + PsidLength uint8 + Psid uint16 + StartPort uint16 + EndPort uint16 +} + +func (*NatSetAddrAndPortAllocAlg) GetMessageName() string { + return "nat_set_addr_and_port_alloc_alg" +} +func (*NatSetAddrAndPortAllocAlg) GetCrcString() string { + return "deeb746f" +} +func (*NatSetAddrAndPortAllocAlg) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// NatSetAddrAndPortAllocAlgReply represents the VPP binary API message 'nat_set_addr_and_port_alloc_alg_reply'. +// +// "nat_set_addr_and_port_alloc_alg_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "i32", +// "retval" +// ], +// { +// "crc": "0xe8d4e804" +// } +// +type NatSetAddrAndPortAllocAlgReply struct { + Retval int32 +} + +func (*NatSetAddrAndPortAllocAlgReply) GetMessageName() string { + return "nat_set_addr_and_port_alloc_alg_reply" +} +func (*NatSetAddrAndPortAllocAlgReply) GetCrcString() string { + return "e8d4e804" +} +func (*NatSetAddrAndPortAllocAlgReply) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// NatGetAddrAndPortAllocAlg represents the VPP binary API message 'nat_get_addr_and_port_alloc_alg'. +// +// "nat_get_addr_and_port_alloc_alg", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// { +// "crc": "0x51077d14" +// } +// +type NatGetAddrAndPortAllocAlg struct{} + +func (*NatGetAddrAndPortAllocAlg) GetMessageName() string { + return "nat_get_addr_and_port_alloc_alg" +} +func (*NatGetAddrAndPortAllocAlg) GetCrcString() string { + return "51077d14" +} +func (*NatGetAddrAndPortAllocAlg) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// NatGetAddrAndPortAllocAlgReply represents the VPP binary API message 'nat_get_addr_and_port_alloc_alg_reply'. +// +// "nat_get_addr_and_port_alloc_alg_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "i32", +// "retval" +// ], +// [ +// "u8", +// "alg" +// ], +// [ +// "u8", +// "psid_offset" +// ], +// [ +// "u8", +// "psid_length" +// ], +// [ +// "u16", +// "psid" +// ], +// [ +// "u16", +// "start_port" +// ], +// [ +// "u16", +// "end_port" +// ], +// { +// "crc": "0x3607a7d0" +// } +// +type NatGetAddrAndPortAllocAlgReply struct { + Retval int32 + Alg uint8 + PsidOffset uint8 + PsidLength uint8 + Psid uint16 + StartPort uint16 + EndPort uint16 +} + +func (*NatGetAddrAndPortAllocAlgReply) GetMessageName() string { + return "nat_get_addr_and_port_alloc_alg_reply" +} +func (*NatGetAddrAndPortAllocAlgReply) GetCrcString() string { + return "3607a7d0" +} +func (*NatGetAddrAndPortAllocAlgReply) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// NatSetMssClamping represents the VPP binary API message 'nat_set_mss_clamping'. +// +// "nat_set_mss_clamping", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u16", +// "mss_value" +// ], +// [ +// "u8", +// "enable" +// ], +// { +// "crc": "0x6a2472be" +// } +// +type NatSetMssClamping struct { + MssValue uint16 + Enable uint8 +} + +func (*NatSetMssClamping) GetMessageName() string { + return "nat_set_mss_clamping" +} +func (*NatSetMssClamping) GetCrcString() string { + return "6a2472be" +} +func (*NatSetMssClamping) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// NatSetMssClampingReply represents the VPP binary API message 'nat_set_mss_clamping_reply'. +// +// "nat_set_mss_clamping_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "i32", +// "retval" +// ], +// { +// "crc": "0xe8d4e804" +// } +// +type NatSetMssClampingReply struct { + Retval int32 +} + +func (*NatSetMssClampingReply) GetMessageName() string { + return "nat_set_mss_clamping_reply" +} +func (*NatSetMssClampingReply) GetCrcString() string { + return "e8d4e804" +} +func (*NatSetMssClampingReply) GetMessageType() api.MessageType { + return api.ReplyMessage +} + +// NatGetMssClamping represents the VPP binary API message 'nat_get_mss_clamping'. +// +// "nat_get_mss_clamping", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// { +// "crc": "0x51077d14" +// } +// +type NatGetMssClamping struct{} + +func (*NatGetMssClamping) GetMessageName() string { + return "nat_get_mss_clamping" +} +func (*NatGetMssClamping) GetCrcString() string { + return "51077d14" +} +func (*NatGetMssClamping) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// NatGetMssClampingReply represents the VPP binary API message 'nat_get_mss_clamping_reply'. +// +// "nat_get_mss_clamping_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" // ], // [ -// "u32", -// "frag_id" +// "i32", +// "retval" // ], // [ -// "u8", -// "proto" +// "u16", +// "mss_value" // ], // [ // "u8", -// "frag_n" +// "enable" // ], // { -// "crc": "0xee46e2d4" +// "crc": "0xf7bd89f5" // } // -type NatReassDetails struct { - IsIP4 uint8 - SrcAddr []byte `struc:"[16]byte"` - DstAddr []byte `struc:"[16]byte"` - FragID uint32 - Proto uint8 - FragN uint8 +type NatGetMssClampingReply struct { + Retval int32 + MssValue uint16 + Enable uint8 } -func (*NatReassDetails) GetMessageName() string { - return "nat_reass_details" +func (*NatGetMssClampingReply) GetMessageName() string { + return "nat_get_mss_clamping_reply" } -func (*NatReassDetails) GetCrcString() string { - return "ee46e2d4" +func (*NatGetMssClampingReply) GetCrcString() string { + return "f7bd89f5" } -func (*NatReassDetails) GetMessageType() api.MessageType { +func (*NatGetMssClampingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatReassDetails() api.Message { - return &NatReassDetails{} -} // Nat44AddDelAddressRange represents the VPP binary API message 'nat44_add_del_address_range'. -// Generated from 'nat.api.json', line 439: // // "nat44_add_del_address_range", // [ @@ -886,12 +1361,8 @@ func (*Nat44AddDelAddressRange) GetCrcString() string { func (*Nat44AddDelAddressRange) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44AddDelAddressRange() api.Message { - return &Nat44AddDelAddressRange{} -} // Nat44AddDelAddressRangeReply represents the VPP binary API message 'nat44_add_del_address_range_reply'. -// Generated from 'nat.api.json', line 479: // // "nat44_add_del_address_range_reply", // [ @@ -923,12 +1394,8 @@ func (*Nat44AddDelAddressRangeReply) GetCrcString() string { func (*Nat44AddDelAddressRangeReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44AddDelAddressRangeReply() api.Message { - return &Nat44AddDelAddressRangeReply{} -} // Nat44AddressDump represents the VPP binary API message 'nat44_address_dump'. -// Generated from 'nat.api.json', line 497: // // "nat44_address_dump", // [ @@ -958,12 +1425,8 @@ func (*Nat44AddressDump) GetCrcString() string { func (*Nat44AddressDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44AddressDump() api.Message { - return &Nat44AddressDump{} -} // Nat44AddressDetails represents the VPP binary API message 'nat44_address_details'. -// Generated from 'nat.api.json', line 515: // // "nat44_address_details", // [ @@ -1006,12 +1469,8 @@ func (*Nat44AddressDetails) GetCrcString() string { func (*Nat44AddressDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44AddressDetails() api.Message { - return &Nat44AddressDetails{} -} // Nat44InterfaceAddDelFeature represents the VPP binary API message 'nat44_interface_add_del_feature'. -// Generated from 'nat.api.json', line 542: // // "nat44_interface_add_del_feature", // [ @@ -1057,12 +1516,8 @@ func (*Nat44InterfaceAddDelFeature) GetCrcString() string { func (*Nat44InterfaceAddDelFeature) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44InterfaceAddDelFeature() api.Message { - return &Nat44InterfaceAddDelFeature{} -} // Nat44InterfaceAddDelFeatureReply represents the VPP binary API message 'nat44_interface_add_del_feature_reply'. -// Generated from 'nat.api.json', line 572: // // "nat44_interface_add_del_feature_reply", // [ @@ -1094,12 +1549,8 @@ func (*Nat44InterfaceAddDelFeatureReply) GetCrcString() string { func (*Nat44InterfaceAddDelFeatureReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44InterfaceAddDelFeatureReply() api.Message { - return &Nat44InterfaceAddDelFeatureReply{} -} // Nat44InterfaceDump represents the VPP binary API message 'nat44_interface_dump'. -// Generated from 'nat.api.json', line 590: // // "nat44_interface_dump", // [ @@ -1129,12 +1580,8 @@ func (*Nat44InterfaceDump) GetCrcString() string { func (*Nat44InterfaceDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44InterfaceDump() api.Message { - return &Nat44InterfaceDump{} -} // Nat44InterfaceDetails represents the VPP binary API message 'nat44_interface_details'. -// Generated from 'nat.api.json', line 608: // // "nat44_interface_details", // [ @@ -1171,12 +1618,8 @@ func (*Nat44InterfaceDetails) GetCrcString() string { func (*Nat44InterfaceDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44InterfaceDetails() api.Message { - return &Nat44InterfaceDetails{} -} // Nat44InterfaceAddDelOutputFeature represents the VPP binary API message 'nat44_interface_add_del_output_feature'. -// Generated from 'nat.api.json', line 630: // // "nat44_interface_add_del_output_feature", // [ @@ -1222,12 +1665,8 @@ func (*Nat44InterfaceAddDelOutputFeature) GetCrcString() string { func (*Nat44InterfaceAddDelOutputFeature) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44InterfaceAddDelOutputFeature() api.Message { - return &Nat44InterfaceAddDelOutputFeature{} -} // Nat44InterfaceAddDelOutputFeatureReply represents the VPP binary API message 'nat44_interface_add_del_output_feature_reply'. -// Generated from 'nat.api.json', line 660: // // "nat44_interface_add_del_output_feature_reply", // [ @@ -1259,12 +1698,8 @@ func (*Nat44InterfaceAddDelOutputFeatureReply) GetCrcString() string { func (*Nat44InterfaceAddDelOutputFeatureReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44InterfaceAddDelOutputFeatureReply() api.Message { - return &Nat44InterfaceAddDelOutputFeatureReply{} -} // Nat44InterfaceOutputFeatureDump represents the VPP binary API message 'nat44_interface_output_feature_dump'. -// Generated from 'nat.api.json', line 678: // // "nat44_interface_output_feature_dump", // [ @@ -1294,12 +1729,8 @@ func (*Nat44InterfaceOutputFeatureDump) GetCrcString() string { func (*Nat44InterfaceOutputFeatureDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44InterfaceOutputFeatureDump() api.Message { - return &Nat44InterfaceOutputFeatureDump{} -} // Nat44InterfaceOutputFeatureDetails represents the VPP binary API message 'nat44_interface_output_feature_details'. -// Generated from 'nat.api.json', line 696: // // "nat44_interface_output_feature_details", // [ @@ -1336,12 +1767,8 @@ func (*Nat44InterfaceOutputFeatureDetails) GetCrcString() string { func (*Nat44InterfaceOutputFeatureDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44InterfaceOutputFeatureDetails() api.Message { - return &Nat44InterfaceOutputFeatureDetails{} -} // Nat44AddDelStaticMapping represents the VPP binary API message 'nat44_add_del_static_mapping'. -// Generated from 'nat.api.json', line 718: // // "nat44_add_del_static_mapping", // [ @@ -1440,12 +1867,8 @@ func (*Nat44AddDelStaticMapping) GetCrcString() string { func (*Nat44AddDelStaticMapping) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44AddDelStaticMapping() api.Message { - return &Nat44AddDelStaticMapping{} -} // Nat44AddDelStaticMappingReply represents the VPP binary API message 'nat44_add_del_static_mapping_reply'. -// Generated from 'nat.api.json', line 791: // // "nat44_add_del_static_mapping_reply", // [ @@ -1477,12 +1900,8 @@ func (*Nat44AddDelStaticMappingReply) GetCrcString() string { func (*Nat44AddDelStaticMappingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44AddDelStaticMappingReply() api.Message { - return &Nat44AddDelStaticMappingReply{} -} // Nat44StaticMappingDump represents the VPP binary API message 'nat44_static_mapping_dump'. -// Generated from 'nat.api.json', line 809: // // "nat44_static_mapping_dump", // [ @@ -1512,12 +1931,8 @@ func (*Nat44StaticMappingDump) GetCrcString() string { func (*Nat44StaticMappingDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44StaticMappingDump() api.Message { - return &Nat44StaticMappingDump{} -} // Nat44StaticMappingDetails represents the VPP binary API message 'nat44_static_mapping_details'. -// Generated from 'nat.api.json', line 827: // // "nat44_static_mapping_details", // [ @@ -1607,12 +2022,8 @@ func (*Nat44StaticMappingDetails) GetCrcString() string { func (*Nat44StaticMappingDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44StaticMappingDetails() api.Message { - return &Nat44StaticMappingDetails{} -} // Nat44AddDelIdentityMapping represents the VPP binary API message 'nat44_add_del_identity_mapping'. -// Generated from 'nat.api.json', line 892: // // "nat44_add_del_identity_mapping", // [ @@ -1685,12 +2096,8 @@ func (*Nat44AddDelIdentityMapping) GetCrcString() string { func (*Nat44AddDelIdentityMapping) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44AddDelIdentityMapping() api.Message { - return &Nat44AddDelIdentityMapping{} -} // Nat44AddDelIdentityMappingReply represents the VPP binary API message 'nat44_add_del_identity_mapping_reply'. -// Generated from 'nat.api.json', line 944: // // "nat44_add_del_identity_mapping_reply", // [ @@ -1722,12 +2129,8 @@ func (*Nat44AddDelIdentityMappingReply) GetCrcString() string { func (*Nat44AddDelIdentityMappingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44AddDelIdentityMappingReply() api.Message { - return &Nat44AddDelIdentityMappingReply{} -} // Nat44IdentityMappingDump represents the VPP binary API message 'nat44_identity_mapping_dump'. -// Generated from 'nat.api.json', line 962: // // "nat44_identity_mapping_dump", // [ @@ -1757,12 +2160,8 @@ func (*Nat44IdentityMappingDump) GetCrcString() string { func (*Nat44IdentityMappingDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44IdentityMappingDump() api.Message { - return &Nat44IdentityMappingDump{} -} // Nat44IdentityMappingDetails represents the VPP binary API message 'nat44_identity_mapping_details'. -// Generated from 'nat.api.json', line 980: // // "nat44_identity_mapping_details", // [ @@ -1826,12 +2225,8 @@ func (*Nat44IdentityMappingDetails) GetCrcString() string { func (*Nat44IdentityMappingDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44IdentityMappingDetails() api.Message { - return &Nat44IdentityMappingDetails{} -} // Nat44AddDelInterfaceAddr represents the VPP binary API message 'nat44_add_del_interface_addr'. -// Generated from 'nat.api.json', line 1024: // // "nat44_add_del_interface_addr", // [ @@ -1877,12 +2272,8 @@ func (*Nat44AddDelInterfaceAddr) GetCrcString() string { func (*Nat44AddDelInterfaceAddr) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44AddDelInterfaceAddr() api.Message { - return &Nat44AddDelInterfaceAddr{} -} // Nat44AddDelInterfaceAddrReply represents the VPP binary API message 'nat44_add_del_interface_addr_reply'. -// Generated from 'nat.api.json', line 1054: // // "nat44_add_del_interface_addr_reply", // [ @@ -1914,12 +2305,8 @@ func (*Nat44AddDelInterfaceAddrReply) GetCrcString() string { func (*Nat44AddDelInterfaceAddrReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44AddDelInterfaceAddrReply() api.Message { - return &Nat44AddDelInterfaceAddrReply{} -} // Nat44InterfaceAddrDump represents the VPP binary API message 'nat44_interface_addr_dump'. -// Generated from 'nat.api.json', line 1072: // // "nat44_interface_addr_dump", // [ @@ -1949,12 +2336,8 @@ func (*Nat44InterfaceAddrDump) GetCrcString() string { func (*Nat44InterfaceAddrDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44InterfaceAddrDump() api.Message { - return &Nat44InterfaceAddrDump{} -} // Nat44InterfaceAddrDetails represents the VPP binary API message 'nat44_interface_addr_details'. -// Generated from 'nat.api.json', line 1090: // // "nat44_interface_addr_details", // [ @@ -1991,12 +2374,8 @@ func (*Nat44InterfaceAddrDetails) GetCrcString() string { func (*Nat44InterfaceAddrDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44InterfaceAddrDetails() api.Message { - return &Nat44InterfaceAddrDetails{} -} // Nat44UserDump represents the VPP binary API message 'nat44_user_dump'. -// Generated from 'nat.api.json', line 1112: // // "nat44_user_dump", // [ @@ -2026,12 +2405,8 @@ func (*Nat44UserDump) GetCrcString() string { func (*Nat44UserDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44UserDump() api.Message { - return &Nat44UserDump{} -} // Nat44UserDetails represents the VPP binary API message 'nat44_user_details'. -// Generated from 'nat.api.json', line 1130: // // "nat44_user_details", // [ @@ -2079,12 +2454,8 @@ func (*Nat44UserDetails) GetCrcString() string { func (*Nat44UserDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44UserDetails() api.Message { - return &Nat44UserDetails{} -} // Nat44UserSessionDump represents the VPP binary API message 'nat44_user_session_dump'. -// Generated from 'nat.api.json', line 1161: // // "nat44_user_session_dump", // [ @@ -2126,12 +2497,8 @@ func (*Nat44UserSessionDump) GetCrcString() string { func (*Nat44UserSessionDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44UserSessionDump() api.Message { - return &Nat44UserSessionDump{} -} // Nat44UserSessionDetails represents the VPP binary API message 'nat44_user_session_details'. -// Generated from 'nat.api.json', line 1188: // // "nat44_user_session_details", // [ @@ -2237,12 +2604,8 @@ func (*Nat44UserSessionDetails) GetCrcString() string { func (*Nat44UserSessionDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44UserSessionDetails() api.Message { - return &Nat44UserSessionDetails{} -} // Nat44AddDelLbStaticMapping represents the VPP binary API message 'nat44_add_del_lb_static_mapping'. -// Generated from 'nat.api.json', line 1266: // // "nat44_add_del_lb_static_mapping", // [ @@ -2292,6 +2655,10 @@ func NewNat44UserSessionDetails() api.Message { // 64 // ], // [ +// "u32", +// "affinity" +// ], +// [ // "u8", // "local_num" // ], @@ -2302,7 +2669,7 @@ func NewNat44UserSessionDetails() api.Message { // "local_num" // ], // { -// "crc": "0x532bc14c" +// "crc": "0x135f5f3a" // } // type Nat44AddDelLbStaticMapping struct { @@ -2314,7 +2681,8 @@ type Nat44AddDelLbStaticMapping struct { SelfTwiceNat uint8 Out2inOnly uint8 Tag []byte `struc:"[64]byte"` - LocalNum uint8 `struc:"sizeof=Locals"` + Affinity uint32 + LocalNum uint8 `struc:"sizeof=Locals"` Locals []Nat44LbAddrPort } @@ -2322,17 +2690,13 @@ func (*Nat44AddDelLbStaticMapping) GetMessageName() string { return "nat44_add_del_lb_static_mapping" } func (*Nat44AddDelLbStaticMapping) GetCrcString() string { - return "532bc14c" + return "135f5f3a" } func (*Nat44AddDelLbStaticMapping) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44AddDelLbStaticMapping() api.Message { - return &Nat44AddDelLbStaticMapping{} -} // Nat44AddDelLbStaticMappingReply represents the VPP binary API message 'nat44_add_del_lb_static_mapping_reply'. -// Generated from 'nat.api.json', line 1328: // // "nat44_add_del_lb_static_mapping_reply", // [ @@ -2364,12 +2728,8 @@ func (*Nat44AddDelLbStaticMappingReply) GetCrcString() string { func (*Nat44AddDelLbStaticMappingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44AddDelLbStaticMappingReply() api.Message { - return &Nat44AddDelLbStaticMappingReply{} -} // Nat44LbStaticMappingDump represents the VPP binary API message 'nat44_lb_static_mapping_dump'. -// Generated from 'nat.api.json', line 1346: // // "nat44_lb_static_mapping_dump", // [ @@ -2399,12 +2759,8 @@ func (*Nat44LbStaticMappingDump) GetCrcString() string { func (*Nat44LbStaticMappingDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44LbStaticMappingDump() api.Message { - return &Nat44LbStaticMappingDump{} -} // Nat44LbStaticMappingDetails represents the VPP binary API message 'nat44_lb_static_mapping_details'. -// Generated from 'nat.api.json', line 1364: // // "nat44_lb_static_mapping_details", // [ @@ -2446,6 +2802,10 @@ func NewNat44LbStaticMappingDump() api.Message { // 64 // ], // [ +// "u32", +// "affinity" +// ], +// [ // "u8", // "local_num" // ], @@ -2456,7 +2816,7 @@ func NewNat44LbStaticMappingDump() api.Message { // "local_num" // ], // { -// "crc": "0x6a287c74" +// "crc": "0xe5aba6bb" // } // type Nat44LbStaticMappingDetails struct { @@ -2467,7 +2827,8 @@ type Nat44LbStaticMappingDetails struct { SelfTwiceNat uint8 Out2inOnly uint8 Tag []byte `struc:"[64]byte"` - LocalNum uint8 `struc:"sizeof=Locals"` + Affinity uint32 + LocalNum uint8 `struc:"sizeof=Locals"` Locals []Nat44LbAddrPort } @@ -2475,17 +2836,13 @@ func (*Nat44LbStaticMappingDetails) GetMessageName() string { return "nat44_lb_static_mapping_details" } func (*Nat44LbStaticMappingDetails) GetCrcString() string { - return "6a287c74" + return "e5aba6bb" } func (*Nat44LbStaticMappingDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44LbStaticMappingDetails() api.Message { - return &Nat44LbStaticMappingDetails{} -} // Nat44DelSession represents the VPP binary API message 'nat44_del_session'. -// Generated from 'nat.api.json', line 1418: // // "nat44_del_session", // [ @@ -2558,12 +2915,8 @@ func (*Nat44DelSession) GetCrcString() string { func (*Nat44DelSession) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44DelSession() api.Message { - return &Nat44DelSession{} -} // Nat44DelSessionReply represents the VPP binary API message 'nat44_del_session_reply'. -// Generated from 'nat.api.json', line 1470: // // "nat44_del_session_reply", // [ @@ -2595,12 +2948,8 @@ func (*Nat44DelSessionReply) GetCrcString() string { func (*Nat44DelSessionReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44DelSessionReply() api.Message { - return &Nat44DelSessionReply{} -} // Nat44ForwardingEnableDisable represents the VPP binary API message 'nat44_forwarding_enable_disable'. -// Generated from 'nat.api.json', line 1488: // // "nat44_forwarding_enable_disable", // [ @@ -2636,12 +2985,8 @@ func (*Nat44ForwardingEnableDisable) GetCrcString() string { func (*Nat44ForwardingEnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44ForwardingEnableDisable() api.Message { - return &Nat44ForwardingEnableDisable{} -} // Nat44ForwardingEnableDisableReply represents the VPP binary API message 'nat44_forwarding_enable_disable_reply'. -// Generated from 'nat.api.json', line 1510: // // "nat44_forwarding_enable_disable_reply", // [ @@ -2673,12 +3018,8 @@ func (*Nat44ForwardingEnableDisableReply) GetCrcString() string { func (*Nat44ForwardingEnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44ForwardingEnableDisableReply() api.Message { - return &Nat44ForwardingEnableDisableReply{} -} // Nat44ForwardingIsEnabled represents the VPP binary API message 'nat44_forwarding_is_enabled'. -// Generated from 'nat.api.json', line 1528: // // "nat44_forwarding_is_enabled", // [ @@ -2708,12 +3049,8 @@ func (*Nat44ForwardingIsEnabled) GetCrcString() string { func (*Nat44ForwardingIsEnabled) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat44ForwardingIsEnabled() api.Message { - return &Nat44ForwardingIsEnabled{} -} // Nat44ForwardingIsEnabledReply represents the VPP binary API message 'nat44_forwarding_is_enabled_reply'. -// Generated from 'nat.api.json', line 1546: // // "nat44_forwarding_is_enabled_reply", // [ @@ -2745,12 +3082,8 @@ func (*Nat44ForwardingIsEnabledReply) GetCrcString() string { func (*Nat44ForwardingIsEnabledReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat44ForwardingIsEnabledReply() api.Message { - return &Nat44ForwardingIsEnabledReply{} -} // NatDetAddDelMap represents the VPP binary API message 'nat_det_add_del_map'. -// Generated from 'nat.api.json', line 1564: // // "nat_det_add_del_map", // [ @@ -2818,12 +3151,8 @@ func (*NatDetAddDelMap) GetCrcString() string { func (*NatDetAddDelMap) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatDetAddDelMap() api.Message { - return &NatDetAddDelMap{} -} // NatDetAddDelMapReply represents the VPP binary API message 'nat_det_add_del_map_reply'. -// Generated from 'nat.api.json', line 1612: // // "nat_det_add_del_map_reply", // [ @@ -2855,12 +3184,8 @@ func (*NatDetAddDelMapReply) GetCrcString() string { func (*NatDetAddDelMapReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatDetAddDelMapReply() api.Message { - return &NatDetAddDelMapReply{} -} // NatDetForward represents the VPP binary API message 'nat_det_forward'. -// Generated from 'nat.api.json', line 1630: // // "nat_det_forward", // [ @@ -2902,12 +3227,8 @@ func (*NatDetForward) GetCrcString() string { func (*NatDetForward) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatDetForward() api.Message { - return &NatDetForward{} -} // NatDetForwardReply represents the VPP binary API message 'nat_det_forward_reply'. -// Generated from 'nat.api.json', line 1657: // // "nat_det_forward_reply", // [ @@ -2955,12 +3276,8 @@ func (*NatDetForwardReply) GetCrcString() string { func (*NatDetForwardReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatDetForwardReply() api.Message { - return &NatDetForwardReply{} -} // NatDetReverse represents the VPP binary API message 'nat_det_reverse'. -// Generated from 'nat.api.json', line 1688: // // "nat_det_reverse", // [ @@ -3002,12 +3319,8 @@ func (*NatDetReverse) GetCrcString() string { func (*NatDetReverse) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatDetReverse() api.Message { - return &NatDetReverse{} -} // NatDetReverseReply represents the VPP binary API message 'nat_det_reverse_reply'. -// Generated from 'nat.api.json', line 1715: // // "nat_det_reverse_reply", // [ @@ -3047,219 +3360,13 @@ func (*NatDetReverseReply) GetMessageName() string { func (*NatDetReverseReply) GetCrcString() string { return "26139a2f" } -func (*NatDetReverseReply) GetMessageType() api.MessageType { - return api.ReplyMessage -} -func NewNatDetReverseReply() api.Message { - return &NatDetReverseReply{} -} - -// NatDetMapDump represents the VPP binary API message 'nat_det_map_dump'. -// Generated from 'nat.api.json', line 1742: -// -// "nat_det_map_dump", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "client_index" -// ], -// [ -// "u32", -// "context" -// ], -// { -// "crc": "0x51077d14" -// } -// -type NatDetMapDump struct{} - -func (*NatDetMapDump) GetMessageName() string { - return "nat_det_map_dump" -} -func (*NatDetMapDump) GetCrcString() string { - return "51077d14" -} -func (*NatDetMapDump) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewNatDetMapDump() api.Message { - return &NatDetMapDump{} -} - -// NatDetMapDetails represents the VPP binary API message 'nat_det_map_details'. -// Generated from 'nat.api.json', line 1760: -// -// "nat_det_map_details", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "context" -// ], -// [ -// "u8", -// "is_nat44" -// ], -// [ -// "u8", -// "in_addr", -// 16 -// ], -// [ -// "u8", -// "in_plen" -// ], -// [ -// "u8", -// "out_addr", -// 4 -// ], -// [ -// "u8", -// "out_plen" -// ], -// [ -// "u32", -// "sharing_ratio" -// ], -// [ -// "u16", -// "ports_per_host" -// ], -// [ -// "u32", -// "ses_num" -// ], -// { -// "crc": "0x886138a8" -// } -// -type NatDetMapDetails struct { - IsNat44 uint8 - InAddr []byte `struc:"[16]byte"` - InPlen uint8 - OutAddr []byte `struc:"[4]byte"` - OutPlen uint8 - SharingRatio uint32 - PortsPerHost uint16 - SesNum uint32 -} - -func (*NatDetMapDetails) GetMessageName() string { - return "nat_det_map_details" -} -func (*NatDetMapDetails) GetCrcString() string { - return "886138a8" -} -func (*NatDetMapDetails) GetMessageType() api.MessageType { - return api.ReplyMessage -} -func NewNatDetMapDetails() api.Message { - return &NatDetMapDetails{} -} - -// NatDetSetTimeouts represents the VPP binary API message 'nat_det_set_timeouts'. -// Generated from 'nat.api.json', line 1808: -// -// "nat_det_set_timeouts", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "client_index" -// ], -// [ -// "u32", -// "context" -// ], -// [ -// "u32", -// "udp" -// ], -// [ -// "u32", -// "tcp_established" -// ], -// [ -// "u32", -// "tcp_transitory" -// ], -// [ -// "u32", -// "icmp" -// ], -// { -// "crc": "0xd4746b16" -// } -// -type NatDetSetTimeouts struct { - UDP uint32 - TCPEstablished uint32 - TCPTransitory uint32 - ICMP uint32 -} - -func (*NatDetSetTimeouts) GetMessageName() string { - return "nat_det_set_timeouts" -} -func (*NatDetSetTimeouts) GetCrcString() string { - return "d4746b16" -} -func (*NatDetSetTimeouts) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewNatDetSetTimeouts() api.Message { - return &NatDetSetTimeouts{} -} - -// NatDetSetTimeoutsReply represents the VPP binary API message 'nat_det_set_timeouts_reply'. -// Generated from 'nat.api.json', line 1842: -// -// "nat_det_set_timeouts_reply", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "context" -// ], -// [ -// "i32", -// "retval" -// ], -// { -// "crc": "0xe8d4e804" -// } -// -type NatDetSetTimeoutsReply struct { - Retval int32 -} - -func (*NatDetSetTimeoutsReply) GetMessageName() string { - return "nat_det_set_timeouts_reply" -} -func (*NatDetSetTimeoutsReply) GetCrcString() string { - return "e8d4e804" -} -func (*NatDetSetTimeoutsReply) GetMessageType() api.MessageType { +func (*NatDetReverseReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatDetSetTimeoutsReply() api.Message { - return &NatDetSetTimeoutsReply{} -} -// NatDetGetTimeouts represents the VPP binary API message 'nat_det_get_timeouts'. -// Generated from 'nat.api.json', line 1860: +// NatDetMapDump represents the VPP binary API message 'nat_det_map_dump'. // -// "nat_det_get_timeouts", +// "nat_det_map_dump", // [ // "u16", // "_vl_msg_id" @@ -3276,25 +3383,21 @@ func NewNatDetSetTimeoutsReply() api.Message { // "crc": "0x51077d14" // } // -type NatDetGetTimeouts struct{} +type NatDetMapDump struct{} -func (*NatDetGetTimeouts) GetMessageName() string { - return "nat_det_get_timeouts" +func (*NatDetMapDump) GetMessageName() string { + return "nat_det_map_dump" } -func (*NatDetGetTimeouts) GetCrcString() string { +func (*NatDetMapDump) GetCrcString() string { return "51077d14" } -func (*NatDetGetTimeouts) GetMessageType() api.MessageType { +func (*NatDetMapDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatDetGetTimeouts() api.Message { - return &NatDetGetTimeouts{} -} -// NatDetGetTimeoutsReply represents the VPP binary API message 'nat_det_get_timeouts_reply'. -// Generated from 'nat.api.json', line 1878: +// NatDetMapDetails represents the VPP binary API message 'nat_det_map_details'. // -// "nat_det_get_timeouts_reply", +// "nat_det_map_details", // [ // "u16", // "_vl_msg_id" @@ -3304,52 +3407,65 @@ func NewNatDetGetTimeouts() api.Message { // "context" // ], // [ -// "i32", -// "retval" +// "u8", +// "is_nat44" // ], // [ -// "u32", -// "udp" +// "u8", +// "in_addr", +// 16 // ], // [ -// "u32", -// "tcp_established" +// "u8", +// "in_plen" +// ], +// [ +// "u8", +// "out_addr", +// 4 +// ], +// [ +// "u8", +// "out_plen" // ], // [ // "u32", -// "tcp_transitory" +// "sharing_ratio" +// ], +// [ +// "u16", +// "ports_per_host" // ], // [ // "u32", -// "icmp" +// "ses_num" // ], // { -// "crc": "0x3c4df4e1" +// "crc": "0x886138a8" // } // -type NatDetGetTimeoutsReply struct { - Retval int32 - UDP uint32 - TCPEstablished uint32 - TCPTransitory uint32 - ICMP uint32 +type NatDetMapDetails struct { + IsNat44 uint8 + InAddr []byte `struc:"[16]byte"` + InPlen uint8 + OutAddr []byte `struc:"[4]byte"` + OutPlen uint8 + SharingRatio uint32 + PortsPerHost uint16 + SesNum uint32 } -func (*NatDetGetTimeoutsReply) GetMessageName() string { - return "nat_det_get_timeouts_reply" +func (*NatDetMapDetails) GetMessageName() string { + return "nat_det_map_details" } -func (*NatDetGetTimeoutsReply) GetCrcString() string { - return "3c4df4e1" +func (*NatDetMapDetails) GetCrcString() string { + return "886138a8" } -func (*NatDetGetTimeoutsReply) GetMessageType() api.MessageType { +func (*NatDetMapDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatDetGetTimeoutsReply() api.Message { - return &NatDetGetTimeoutsReply{} -} // NatDetCloseSessionOut represents the VPP binary API message 'nat_det_close_session_out'. -// Generated from 'nat.api.json', line 1912: // // "nat_det_close_session_out", // [ @@ -3402,12 +3518,8 @@ func (*NatDetCloseSessionOut) GetCrcString() string { func (*NatDetCloseSessionOut) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatDetCloseSessionOut() api.Message { - return &NatDetCloseSessionOut{} -} // NatDetCloseSessionOutReply represents the VPP binary API message 'nat_det_close_session_out_reply'. -// Generated from 'nat.api.json', line 1948: // // "nat_det_close_session_out_reply", // [ @@ -3439,12 +3551,8 @@ func (*NatDetCloseSessionOutReply) GetCrcString() string { func (*NatDetCloseSessionOutReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatDetCloseSessionOutReply() api.Message { - return &NatDetCloseSessionOutReply{} -} // NatDetCloseSessionIn represents the VPP binary API message 'nat_det_close_session_in'. -// Generated from 'nat.api.json', line 1966: // // "nat_det_close_session_in", // [ @@ -3502,12 +3610,8 @@ func (*NatDetCloseSessionIn) GetCrcString() string { func (*NatDetCloseSessionIn) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatDetCloseSessionIn() api.Message { - return &NatDetCloseSessionIn{} -} // NatDetCloseSessionInReply represents the VPP binary API message 'nat_det_close_session_in_reply'. -// Generated from 'nat.api.json', line 2006: // // "nat_det_close_session_in_reply", // [ @@ -3539,12 +3643,8 @@ func (*NatDetCloseSessionInReply) GetCrcString() string { func (*NatDetCloseSessionInReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNatDetCloseSessionInReply() api.Message { - return &NatDetCloseSessionInReply{} -} // NatDetSessionDump represents the VPP binary API message 'nat_det_session_dump'. -// Generated from 'nat.api.json', line 2024: // // "nat_det_session_dump", // [ @@ -3586,12 +3686,8 @@ func (*NatDetSessionDump) GetCrcString() string { func (*NatDetSessionDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNatDetSessionDump() api.Message { - return &NatDetSessionDump{} -} // NatDetSessionDetails represents the VPP binary API message 'nat_det_session_details'. -// Generated from 'nat.api.json', line 2051: // // "nat_det_session_details", // [ @@ -3600,10 +3696,6 @@ func NewNatDetSessionDump() api.Message { // ], // [ // "u32", -// "client_index" -// ], -// [ -// "u32", // "context" // ], // [ @@ -3632,7 +3724,7 @@ func NewNatDetSessionDump() api.Message { // "expire" // ], // { -// "crc": "0x699b5164" +// "crc": "0xf620a631" // } // type NatDetSessionDetails struct { @@ -3648,17 +3740,13 @@ func (*NatDetSessionDetails) GetMessageName() string { return "nat_det_session_details" } func (*NatDetSessionDetails) GetCrcString() string { - return "699b5164" + return "f620a631" } func (*NatDetSessionDetails) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewNatDetSessionDetails() api.Message { - return &NatDetSessionDetails{} + return api.ReplyMessage } // Nat64AddDelPoolAddrRange represents the VPP binary API message 'nat64_add_del_pool_addr_range'. -// Generated from 'nat.api.json', line 2094: // // "nat64_add_del_pool_addr_range", // [ @@ -3711,12 +3799,8 @@ func (*Nat64AddDelPoolAddrRange) GetCrcString() string { func (*Nat64AddDelPoolAddrRange) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64AddDelPoolAddrRange() api.Message { - return &Nat64AddDelPoolAddrRange{} -} // Nat64AddDelPoolAddrRangeReply represents the VPP binary API message 'nat64_add_del_pool_addr_range_reply'. -// Generated from 'nat.api.json', line 2130: // // "nat64_add_del_pool_addr_range_reply", // [ @@ -3748,12 +3832,8 @@ func (*Nat64AddDelPoolAddrRangeReply) GetCrcString() string { func (*Nat64AddDelPoolAddrRangeReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64AddDelPoolAddrRangeReply() api.Message { - return &Nat64AddDelPoolAddrRangeReply{} -} // Nat64PoolAddrDump represents the VPP binary API message 'nat64_pool_addr_dump'. -// Generated from 'nat.api.json', line 2148: // // "nat64_pool_addr_dump", // [ @@ -3783,12 +3863,8 @@ func (*Nat64PoolAddrDump) GetCrcString() string { func (*Nat64PoolAddrDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64PoolAddrDump() api.Message { - return &Nat64PoolAddrDump{} -} // Nat64PoolAddrDetails represents the VPP binary API message 'nat64_pool_addr_details'. -// Generated from 'nat.api.json', line 2166: // // "nat64_pool_addr_details", // [ @@ -3826,12 +3902,8 @@ func (*Nat64PoolAddrDetails) GetCrcString() string { func (*Nat64PoolAddrDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64PoolAddrDetails() api.Message { - return &Nat64PoolAddrDetails{} -} // Nat64AddDelInterface represents the VPP binary API message 'nat64_add_del_interface'. -// Generated from 'nat.api.json', line 2189: // // "nat64_add_del_interface", // [ @@ -3877,12 +3949,8 @@ func (*Nat64AddDelInterface) GetCrcString() string { func (*Nat64AddDelInterface) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64AddDelInterface() api.Message { - return &Nat64AddDelInterface{} -} // Nat64AddDelInterfaceReply represents the VPP binary API message 'nat64_add_del_interface_reply'. -// Generated from 'nat.api.json', line 2219: // // "nat64_add_del_interface_reply", // [ @@ -3914,12 +3982,8 @@ func (*Nat64AddDelInterfaceReply) GetCrcString() string { func (*Nat64AddDelInterfaceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64AddDelInterfaceReply() api.Message { - return &Nat64AddDelInterfaceReply{} -} // Nat64InterfaceDump represents the VPP binary API message 'nat64_interface_dump'. -// Generated from 'nat.api.json', line 2237: // // "nat64_interface_dump", // [ @@ -3949,12 +4013,8 @@ func (*Nat64InterfaceDump) GetCrcString() string { func (*Nat64InterfaceDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64InterfaceDump() api.Message { - return &Nat64InterfaceDump{} -} // Nat64InterfaceDetails represents the VPP binary API message 'nat64_interface_details'. -// Generated from 'nat.api.json', line 2255: // // "nat64_interface_details", // [ @@ -3991,12 +4051,8 @@ func (*Nat64InterfaceDetails) GetCrcString() string { func (*Nat64InterfaceDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64InterfaceDetails() api.Message { - return &Nat64InterfaceDetails{} -} // Nat64AddDelStaticBib represents the VPP binary API message 'nat64_add_del_static_bib'. -// Generated from 'nat.api.json', line 2277: // // "nat64_add_del_static_bib", // [ @@ -4064,12 +4120,8 @@ func (*Nat64AddDelStaticBib) GetCrcString() string { func (*Nat64AddDelStaticBib) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64AddDelStaticBib() api.Message { - return &Nat64AddDelStaticBib{} -} // Nat64AddDelStaticBibReply represents the VPP binary API message 'nat64_add_del_static_bib_reply'. -// Generated from 'nat.api.json', line 2325: // // "nat64_add_del_static_bib_reply", // [ @@ -4101,12 +4153,8 @@ func (*Nat64AddDelStaticBibReply) GetCrcString() string { func (*Nat64AddDelStaticBibReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64AddDelStaticBibReply() api.Message { - return &Nat64AddDelStaticBibReply{} -} // Nat64BibDump represents the VPP binary API message 'nat64_bib_dump'. -// Generated from 'nat.api.json', line 2343: // // "nat64_bib_dump", // [ @@ -4142,12 +4190,8 @@ func (*Nat64BibDump) GetCrcString() string { func (*Nat64BibDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64BibDump() api.Message { - return &Nat64BibDump{} -} // Nat64BibDetails represents the VPP binary API message 'nat64_bib_details'. -// Generated from 'nat.api.json', line 2365: // // "nat64_bib_details", // [ @@ -4216,207 +4260,8 @@ func (*Nat64BibDetails) GetCrcString() string { func (*Nat64BibDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64BibDetails() api.Message { - return &Nat64BibDetails{} -} - -// Nat64SetTimeouts represents the VPP binary API message 'nat64_set_timeouts'. -// Generated from 'nat.api.json', line 2413: -// -// "nat64_set_timeouts", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "client_index" -// ], -// [ -// "u32", -// "context" -// ], -// [ -// "u32", -// "udp" -// ], -// [ -// "u32", -// "icmp" -// ], -// [ -// "u32", -// "tcp_trans" -// ], -// [ -// "u32", -// "tcp_est" -// ], -// [ -// "u32", -// "tcp_incoming_syn" -// ], -// { -// "crc": "0x1cc51cf1" -// } -// -type Nat64SetTimeouts struct { - UDP uint32 - ICMP uint32 - TCPTrans uint32 - TCPEst uint32 - TCPIncomingSyn uint32 -} - -func (*Nat64SetTimeouts) GetMessageName() string { - return "nat64_set_timeouts" -} -func (*Nat64SetTimeouts) GetCrcString() string { - return "1cc51cf1" -} -func (*Nat64SetTimeouts) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewNat64SetTimeouts() api.Message { - return &Nat64SetTimeouts{} -} - -// Nat64SetTimeoutsReply represents the VPP binary API message 'nat64_set_timeouts_reply'. -// Generated from 'nat.api.json', line 2451: -// -// "nat64_set_timeouts_reply", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "context" -// ], -// [ -// "i32", -// "retval" -// ], -// { -// "crc": "0xe8d4e804" -// } -// -type Nat64SetTimeoutsReply struct { - Retval int32 -} - -func (*Nat64SetTimeoutsReply) GetMessageName() string { - return "nat64_set_timeouts_reply" -} -func (*Nat64SetTimeoutsReply) GetCrcString() string { - return "e8d4e804" -} -func (*Nat64SetTimeoutsReply) GetMessageType() api.MessageType { - return api.ReplyMessage -} -func NewNat64SetTimeoutsReply() api.Message { - return &Nat64SetTimeoutsReply{} -} - -// Nat64GetTimeouts represents the VPP binary API message 'nat64_get_timeouts'. -// Generated from 'nat.api.json', line 2469: -// -// "nat64_get_timeouts", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "client_index" -// ], -// [ -// "u32", -// "context" -// ], -// { -// "crc": "0x51077d14" -// } -// -type Nat64GetTimeouts struct{} - -func (*Nat64GetTimeouts) GetMessageName() string { - return "nat64_get_timeouts" -} -func (*Nat64GetTimeouts) GetCrcString() string { - return "51077d14" -} -func (*Nat64GetTimeouts) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewNat64GetTimeouts() api.Message { - return &Nat64GetTimeouts{} -} - -// Nat64GetTimeoutsReply represents the VPP binary API message 'nat64_get_timeouts_reply'. -// Generated from 'nat.api.json', line 2487: -// -// "nat64_get_timeouts_reply", -// [ -// "u16", -// "_vl_msg_id" -// ], -// [ -// "u32", -// "context" -// ], -// [ -// "i32", -// "retval" -// ], -// [ -// "u32", -// "udp" -// ], -// [ -// "u32", -// "icmp" -// ], -// [ -// "u32", -// "tcp_trans" -// ], -// [ -// "u32", -// "tcp_est" -// ], -// [ -// "u32", -// "tcp_incoming_syn" -// ], -// { -// "crc": "0xcdd081d0" -// } -// -type Nat64GetTimeoutsReply struct { - Retval int32 - UDP uint32 - ICMP uint32 - TCPTrans uint32 - TCPEst uint32 - TCPIncomingSyn uint32 -} - -func (*Nat64GetTimeoutsReply) GetMessageName() string { - return "nat64_get_timeouts_reply" -} -func (*Nat64GetTimeoutsReply) GetCrcString() string { - return "cdd081d0" -} -func (*Nat64GetTimeoutsReply) GetMessageType() api.MessageType { - return api.ReplyMessage -} -func NewNat64GetTimeoutsReply() api.Message { - return &Nat64GetTimeoutsReply{} -} // Nat64StDump represents the VPP binary API message 'nat64_st_dump'. -// Generated from 'nat.api.json', line 2525: // // "nat64_st_dump", // [ @@ -4452,12 +4297,8 @@ func (*Nat64StDump) GetCrcString() string { func (*Nat64StDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64StDump() api.Message { - return &Nat64StDump{} -} // Nat64StDetails represents the VPP binary API message 'nat64_st_details'. -// Generated from 'nat.api.json', line 2547: // // "nat64_st_details", // [ @@ -4533,12 +4374,8 @@ func (*Nat64StDetails) GetCrcString() string { func (*Nat64StDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64StDetails() api.Message { - return &Nat64StDetails{} -} // Nat64AddDelPrefix represents the VPP binary API message 'nat64_add_del_prefix'. -// Generated from 'nat.api.json', line 2601: // // "nat64_add_del_prefix", // [ @@ -4590,12 +4427,8 @@ func (*Nat64AddDelPrefix) GetCrcString() string { func (*Nat64AddDelPrefix) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64AddDelPrefix() api.Message { - return &Nat64AddDelPrefix{} -} // Nat64AddDelPrefixReply represents the VPP binary API message 'nat64_add_del_prefix_reply'. -// Generated from 'nat.api.json', line 2636: // // "nat64_add_del_prefix_reply", // [ @@ -4627,12 +4460,8 @@ func (*Nat64AddDelPrefixReply) GetCrcString() string { func (*Nat64AddDelPrefixReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64AddDelPrefixReply() api.Message { - return &Nat64AddDelPrefixReply{} -} // Nat64PrefixDump represents the VPP binary API message 'nat64_prefix_dump'. -// Generated from 'nat.api.json', line 2654: // // "nat64_prefix_dump", // [ @@ -4662,12 +4491,8 @@ func (*Nat64PrefixDump) GetCrcString() string { func (*Nat64PrefixDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64PrefixDump() api.Message { - return &Nat64PrefixDump{} -} // Nat64PrefixDetails represents the VPP binary API message 'nat64_prefix_details'. -// Generated from 'nat.api.json', line 2672: // // "nat64_prefix_details", // [ @@ -4710,12 +4535,8 @@ func (*Nat64PrefixDetails) GetCrcString() string { func (*Nat64PrefixDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64PrefixDetails() api.Message { - return &Nat64PrefixDetails{} -} // Nat64AddDelInterfaceAddr represents the VPP binary API message 'nat64_add_del_interface_addr'. -// Generated from 'nat.api.json', line 2699: // // "nat64_add_del_interface_addr", // [ @@ -4761,12 +4582,8 @@ func (*Nat64AddDelInterfaceAddr) GetCrcString() string { func (*Nat64AddDelInterfaceAddr) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat64AddDelInterfaceAddr() api.Message { - return &Nat64AddDelInterfaceAddr{} -} // Nat64AddDelInterfaceAddrReply represents the VPP binary API message 'nat64_add_del_interface_addr_reply'. -// Generated from 'nat.api.json', line 2729: // // "nat64_add_del_interface_addr_reply", // [ @@ -4798,12 +4615,8 @@ func (*Nat64AddDelInterfaceAddrReply) GetCrcString() string { func (*Nat64AddDelInterfaceAddrReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat64AddDelInterfaceAddrReply() api.Message { - return &Nat64AddDelInterfaceAddrReply{} -} // DsliteAddDelPoolAddrRange represents the VPP binary API message 'dslite_add_del_pool_addr_range'. -// Generated from 'nat.api.json', line 2747: // // "dslite_add_del_pool_addr_range", // [ @@ -4851,12 +4664,8 @@ func (*DsliteAddDelPoolAddrRange) GetCrcString() string { func (*DsliteAddDelPoolAddrRange) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDsliteAddDelPoolAddrRange() api.Message { - return &DsliteAddDelPoolAddrRange{} -} // DsliteAddDelPoolAddrRangeReply represents the VPP binary API message 'dslite_add_del_pool_addr_range_reply'. -// Generated from 'nat.api.json', line 2779: // // "dslite_add_del_pool_addr_range_reply", // [ @@ -4888,12 +4697,8 @@ func (*DsliteAddDelPoolAddrRangeReply) GetCrcString() string { func (*DsliteAddDelPoolAddrRangeReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDsliteAddDelPoolAddrRangeReply() api.Message { - return &DsliteAddDelPoolAddrRangeReply{} -} // DsliteAddressDump represents the VPP binary API message 'dslite_address_dump'. -// Generated from 'nat.api.json', line 2797: // // "dslite_address_dump", // [ @@ -4923,12 +4728,8 @@ func (*DsliteAddressDump) GetCrcString() string { func (*DsliteAddressDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDsliteAddressDump() api.Message { - return &DsliteAddressDump{} -} // DsliteAddressDetails represents the VPP binary API message 'dslite_address_details'. -// Generated from 'nat.api.json', line 2815: // // "dslite_address_details", // [ @@ -4961,12 +4762,8 @@ func (*DsliteAddressDetails) GetCrcString() string { func (*DsliteAddressDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDsliteAddressDetails() api.Message { - return &DsliteAddressDetails{} -} // DsliteSetAftrAddr represents the VPP binary API message 'dslite_set_aftr_addr'. -// Generated from 'nat.api.json', line 2834: // // "dslite_set_aftr_addr", // [ @@ -5009,12 +4806,8 @@ func (*DsliteSetAftrAddr) GetCrcString() string { func (*DsliteSetAftrAddr) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDsliteSetAftrAddr() api.Message { - return &DsliteSetAftrAddr{} -} // DsliteSetAftrAddrReply represents the VPP binary API message 'dslite_set_aftr_addr_reply'. -// Generated from 'nat.api.json', line 2862: // // "dslite_set_aftr_addr_reply", // [ @@ -5046,12 +4839,8 @@ func (*DsliteSetAftrAddrReply) GetCrcString() string { func (*DsliteSetAftrAddrReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDsliteSetAftrAddrReply() api.Message { - return &DsliteSetAftrAddrReply{} -} // DsliteGetAftrAddr represents the VPP binary API message 'dslite_get_aftr_addr'. -// Generated from 'nat.api.json', line 2880: // // "dslite_get_aftr_addr", // [ @@ -5081,12 +4870,8 @@ func (*DsliteGetAftrAddr) GetCrcString() string { func (*DsliteGetAftrAddr) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDsliteGetAftrAddr() api.Message { - return &DsliteGetAftrAddr{} -} // DsliteGetAftrAddrReply represents the VPP binary API message 'dslite_get_aftr_addr_reply'. -// Generated from 'nat.api.json', line 2898: // // "dslite_get_aftr_addr_reply", // [ @@ -5130,12 +4915,8 @@ func (*DsliteGetAftrAddrReply) GetCrcString() string { func (*DsliteGetAftrAddrReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDsliteGetAftrAddrReply() api.Message { - return &DsliteGetAftrAddrReply{} -} // DsliteSetB4Addr represents the VPP binary API message 'dslite_set_b4_addr'. -// Generated from 'nat.api.json', line 2926: // // "dslite_set_b4_addr", // [ @@ -5178,12 +4959,8 @@ func (*DsliteSetB4Addr) GetCrcString() string { func (*DsliteSetB4Addr) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDsliteSetB4Addr() api.Message { - return &DsliteSetB4Addr{} -} // DsliteSetB4AddrReply represents the VPP binary API message 'dslite_set_b4_addr_reply'. -// Generated from 'nat.api.json', line 2954: // // "dslite_set_b4_addr_reply", // [ @@ -5215,12 +4992,8 @@ func (*DsliteSetB4AddrReply) GetCrcString() string { func (*DsliteSetB4AddrReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDsliteSetB4AddrReply() api.Message { - return &DsliteSetB4AddrReply{} -} // DsliteGetB4Addr represents the VPP binary API message 'dslite_get_b4_addr'. -// Generated from 'nat.api.json', line 2972: // // "dslite_get_b4_addr", // [ @@ -5250,12 +5023,8 @@ func (*DsliteGetB4Addr) GetCrcString() string { func (*DsliteGetB4Addr) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDsliteGetB4Addr() api.Message { - return &DsliteGetB4Addr{} -} // DsliteGetB4AddrReply represents the VPP binary API message 'dslite_get_b4_addr_reply'. -// Generated from 'nat.api.json', line 2990: // // "dslite_get_b4_addr_reply", // [ @@ -5299,12 +5068,8 @@ func (*DsliteGetB4AddrReply) GetCrcString() string { func (*DsliteGetB4AddrReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDsliteGetB4AddrReply() api.Message { - return &DsliteGetB4AddrReply{} -} // Nat66AddDelInterface represents the VPP binary API message 'nat66_add_del_interface'. -// Generated from 'nat.api.json', line 3018: // // "nat66_add_del_interface", // [ @@ -5350,12 +5115,8 @@ func (*Nat66AddDelInterface) GetCrcString() string { func (*Nat66AddDelInterface) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat66AddDelInterface() api.Message { - return &Nat66AddDelInterface{} -} // Nat66AddDelInterfaceReply represents the VPP binary API message 'nat66_add_del_interface_reply'. -// Generated from 'nat.api.json', line 3048: // // "nat66_add_del_interface_reply", // [ @@ -5387,12 +5148,8 @@ func (*Nat66AddDelInterfaceReply) GetCrcString() string { func (*Nat66AddDelInterfaceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat66AddDelInterfaceReply() api.Message { - return &Nat66AddDelInterfaceReply{} -} // Nat66InterfaceDump represents the VPP binary API message 'nat66_interface_dump'. -// Generated from 'nat.api.json', line 3066: // // "nat66_interface_dump", // [ @@ -5422,12 +5179,8 @@ func (*Nat66InterfaceDump) GetCrcString() string { func (*Nat66InterfaceDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat66InterfaceDump() api.Message { - return &Nat66InterfaceDump{} -} // Nat66InterfaceDetails represents the VPP binary API message 'nat66_interface_details'. -// Generated from 'nat.api.json', line 3084: // // "nat66_interface_details", // [ @@ -5464,12 +5217,8 @@ func (*Nat66InterfaceDetails) GetCrcString() string { func (*Nat66InterfaceDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat66InterfaceDetails() api.Message { - return &Nat66InterfaceDetails{} -} // Nat66AddDelStaticMapping represents the VPP binary API message 'nat66_add_del_static_mapping'. -// Generated from 'nat.api.json', line 3106: // // "nat66_add_del_static_mapping", // [ @@ -5522,12 +5271,8 @@ func (*Nat66AddDelStaticMapping) GetCrcString() string { func (*Nat66AddDelStaticMapping) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat66AddDelStaticMapping() api.Message { - return &Nat66AddDelStaticMapping{} -} // Nat66AddDelStaticMappingReply represents the VPP binary API message 'nat66_add_del_static_mapping_reply'. -// Generated from 'nat.api.json', line 3142: // // "nat66_add_del_static_mapping_reply", // [ @@ -5559,12 +5304,8 @@ func (*Nat66AddDelStaticMappingReply) GetCrcString() string { func (*Nat66AddDelStaticMappingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat66AddDelStaticMappingReply() api.Message { - return &Nat66AddDelStaticMappingReply{} -} // Nat66StaticMappingDump represents the VPP binary API message 'nat66_static_mapping_dump'. -// Generated from 'nat.api.json', line 3160: // // "nat66_static_mapping_dump", // [ @@ -5594,12 +5335,8 @@ func (*Nat66StaticMappingDump) GetCrcString() string { func (*Nat66StaticMappingDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewNat66StaticMappingDump() api.Message { - return &Nat66StaticMappingDump{} -} // Nat66StaticMappingDetails represents the VPP binary API message 'nat66_static_mapping_details'. -// Generated from 'nat.api.json', line 3178: // // "nat66_static_mapping_details", // [ @@ -5653,9 +5390,6 @@ func (*Nat66StaticMappingDetails) GetCrcString() string { func (*Nat66StaticMappingDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewNat66StaticMappingDetails() api.Message { - return &Nat66StaticMappingDetails{} -} /* Services */ @@ -5701,8 +5435,6 @@ type Services interface { Nat64AddDelPoolAddrRange(*Nat64AddDelPoolAddrRange) (*Nat64AddDelPoolAddrRangeReply, error) Nat64AddDelPrefix(*Nat64AddDelPrefix) (*Nat64AddDelPrefixReply, error) Nat64AddDelStaticBib(*Nat64AddDelStaticBib) (*Nat64AddDelStaticBibReply, error) - Nat64GetTimeouts(*Nat64GetTimeouts) (*Nat64GetTimeoutsReply, error) - Nat64SetTimeouts(*Nat64SetTimeouts) (*Nat64SetTimeoutsReply, error) Nat66AddDelInterface(*Nat66AddDelInterface) (*Nat66AddDelInterfaceReply, error) Nat66AddDelStaticMapping(*Nat66AddDelStaticMapping) (*Nat66AddDelStaticMappingReply, error) NatControlPing(*NatControlPing) (*NatControlPingReply, error) @@ -5710,12 +5442,16 @@ type Services interface { NatDetCloseSessionIn(*NatDetCloseSessionIn) (*NatDetCloseSessionInReply, error) NatDetCloseSessionOut(*NatDetCloseSessionOut) (*NatDetCloseSessionOutReply, error) NatDetForward(*NatDetForward) (*NatDetForwardReply, error) - NatDetGetTimeouts(*NatDetGetTimeouts) (*NatDetGetTimeoutsReply, error) NatDetReverse(*NatDetReverse) (*NatDetReverseReply, error) - NatDetSetTimeouts(*NatDetSetTimeouts) (*NatDetSetTimeoutsReply, error) + NatGetAddrAndPortAllocAlg(*NatGetAddrAndPortAllocAlg) (*NatGetAddrAndPortAllocAlgReply, error) + NatGetMssClamping(*NatGetMssClamping) (*NatGetMssClampingReply, error) NatGetReass(*NatGetReass) (*NatGetReassReply, error) + NatGetTimeouts(*NatGetTimeouts) (*NatGetTimeoutsReply, error) NatIpfixEnableDisable(*NatIpfixEnableDisable) (*NatIpfixEnableDisableReply, error) + NatSetAddrAndPortAllocAlg(*NatSetAddrAndPortAllocAlg) (*NatSetAddrAndPortAllocAlgReply, error) + NatSetMssClamping(*NatSetMssClamping) (*NatSetMssClampingReply, error) NatSetReass(*NatSetReass) (*NatSetReassReply, error) + NatSetTimeouts(*NatSetTimeouts) (*NatSetTimeoutsReply, error) NatSetWorkers(*NatSetWorkers) (*NatSetWorkersReply, error) NatShowConfig(*NatShowConfig) (*NatShowConfigReply, error) } @@ -5737,6 +5473,18 @@ func init() { api.RegisterMessage((*NatGetReassReply)(nil), "nat.NatGetReassReply") api.RegisterMessage((*NatReassDump)(nil), "nat.NatReassDump") api.RegisterMessage((*NatReassDetails)(nil), "nat.NatReassDetails") + api.RegisterMessage((*NatSetTimeouts)(nil), "nat.NatSetTimeouts") + api.RegisterMessage((*NatSetTimeoutsReply)(nil), "nat.NatSetTimeoutsReply") + api.RegisterMessage((*NatGetTimeouts)(nil), "nat.NatGetTimeouts") + api.RegisterMessage((*NatGetTimeoutsReply)(nil), "nat.NatGetTimeoutsReply") + api.RegisterMessage((*NatSetAddrAndPortAllocAlg)(nil), "nat.NatSetAddrAndPortAllocAlg") + api.RegisterMessage((*NatSetAddrAndPortAllocAlgReply)(nil), "nat.NatSetAddrAndPortAllocAlgReply") + api.RegisterMessage((*NatGetAddrAndPortAllocAlg)(nil), "nat.NatGetAddrAndPortAllocAlg") + api.RegisterMessage((*NatGetAddrAndPortAllocAlgReply)(nil), "nat.NatGetAddrAndPortAllocAlgReply") + api.RegisterMessage((*NatSetMssClamping)(nil), "nat.NatSetMssClamping") + api.RegisterMessage((*NatSetMssClampingReply)(nil), "nat.NatSetMssClampingReply") + api.RegisterMessage((*NatGetMssClamping)(nil), "nat.NatGetMssClamping") + api.RegisterMessage((*NatGetMssClampingReply)(nil), "nat.NatGetMssClampingReply") api.RegisterMessage((*Nat44AddDelAddressRange)(nil), "nat.Nat44AddDelAddressRange") api.RegisterMessage((*Nat44AddDelAddressRangeReply)(nil), "nat.Nat44AddDelAddressRangeReply") api.RegisterMessage((*Nat44AddressDump)(nil), "nat.Nat44AddressDump") @@ -5783,10 +5531,6 @@ func init() { api.RegisterMessage((*NatDetReverseReply)(nil), "nat.NatDetReverseReply") api.RegisterMessage((*NatDetMapDump)(nil), "nat.NatDetMapDump") api.RegisterMessage((*NatDetMapDetails)(nil), "nat.NatDetMapDetails") - api.RegisterMessage((*NatDetSetTimeouts)(nil), "nat.NatDetSetTimeouts") - api.RegisterMessage((*NatDetSetTimeoutsReply)(nil), "nat.NatDetSetTimeoutsReply") - api.RegisterMessage((*NatDetGetTimeouts)(nil), "nat.NatDetGetTimeouts") - api.RegisterMessage((*NatDetGetTimeoutsReply)(nil), "nat.NatDetGetTimeoutsReply") api.RegisterMessage((*NatDetCloseSessionOut)(nil), "nat.NatDetCloseSessionOut") api.RegisterMessage((*NatDetCloseSessionOutReply)(nil), "nat.NatDetCloseSessionOutReply") api.RegisterMessage((*NatDetCloseSessionIn)(nil), "nat.NatDetCloseSessionIn") @@ -5805,10 +5549,6 @@ func init() { api.RegisterMessage((*Nat64AddDelStaticBibReply)(nil), "nat.Nat64AddDelStaticBibReply") api.RegisterMessage((*Nat64BibDump)(nil), "nat.Nat64BibDump") api.RegisterMessage((*Nat64BibDetails)(nil), "nat.Nat64BibDetails") - api.RegisterMessage((*Nat64SetTimeouts)(nil), "nat.Nat64SetTimeouts") - api.RegisterMessage((*Nat64SetTimeoutsReply)(nil), "nat.Nat64SetTimeoutsReply") - api.RegisterMessage((*Nat64GetTimeouts)(nil), "nat.Nat64GetTimeouts") - api.RegisterMessage((*Nat64GetTimeoutsReply)(nil), "nat.Nat64GetTimeoutsReply") api.RegisterMessage((*Nat64StDump)(nil), "nat.Nat64StDump") api.RegisterMessage((*Nat64StDetails)(nil), "nat.Nat64StDetails") api.RegisterMessage((*Nat64AddDelPrefix)(nil), "nat.Nat64AddDelPrefix") diff --git a/plugins/vpp/binapi/nat/pkgreflect.go b/plugins/vpp/binapi/nat/pkgreflect.go deleted file mode 100644 index 9f48e5eba9..0000000000 --- a/plugins/vpp/binapi/nat/pkgreflect.go +++ /dev/null @@ -1,252 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package nat - -import "reflect" - -var Types = map[string]reflect.Type{ - "DsliteAddDelPoolAddrRange": reflect.TypeOf((*DsliteAddDelPoolAddrRange)(nil)).Elem(), - "DsliteAddDelPoolAddrRangeReply": reflect.TypeOf((*DsliteAddDelPoolAddrRangeReply)(nil)).Elem(), - "DsliteAddressDetails": reflect.TypeOf((*DsliteAddressDetails)(nil)).Elem(), - "DsliteAddressDump": reflect.TypeOf((*DsliteAddressDump)(nil)).Elem(), - "DsliteGetAftrAddr": reflect.TypeOf((*DsliteGetAftrAddr)(nil)).Elem(), - "DsliteGetAftrAddrReply": reflect.TypeOf((*DsliteGetAftrAddrReply)(nil)).Elem(), - "DsliteGetB4Addr": reflect.TypeOf((*DsliteGetB4Addr)(nil)).Elem(), - "DsliteGetB4AddrReply": reflect.TypeOf((*DsliteGetB4AddrReply)(nil)).Elem(), - "DsliteSetAftrAddr": reflect.TypeOf((*DsliteSetAftrAddr)(nil)).Elem(), - "DsliteSetAftrAddrReply": reflect.TypeOf((*DsliteSetAftrAddrReply)(nil)).Elem(), - "DsliteSetB4Addr": reflect.TypeOf((*DsliteSetB4Addr)(nil)).Elem(), - "DsliteSetB4AddrReply": reflect.TypeOf((*DsliteSetB4AddrReply)(nil)).Elem(), - "Nat44AddDelAddressRange": reflect.TypeOf((*Nat44AddDelAddressRange)(nil)).Elem(), - "Nat44AddDelAddressRangeReply": reflect.TypeOf((*Nat44AddDelAddressRangeReply)(nil)).Elem(), - "Nat44AddDelIdentityMapping": reflect.TypeOf((*Nat44AddDelIdentityMapping)(nil)).Elem(), - "Nat44AddDelIdentityMappingReply": reflect.TypeOf((*Nat44AddDelIdentityMappingReply)(nil)).Elem(), - "Nat44AddDelInterfaceAddr": reflect.TypeOf((*Nat44AddDelInterfaceAddr)(nil)).Elem(), - "Nat44AddDelInterfaceAddrReply": reflect.TypeOf((*Nat44AddDelInterfaceAddrReply)(nil)).Elem(), - "Nat44AddDelLbStaticMapping": reflect.TypeOf((*Nat44AddDelLbStaticMapping)(nil)).Elem(), - "Nat44AddDelLbStaticMappingReply": reflect.TypeOf((*Nat44AddDelLbStaticMappingReply)(nil)).Elem(), - "Nat44AddDelStaticMapping": reflect.TypeOf((*Nat44AddDelStaticMapping)(nil)).Elem(), - "Nat44AddDelStaticMappingReply": reflect.TypeOf((*Nat44AddDelStaticMappingReply)(nil)).Elem(), - "Nat44AddressDetails": reflect.TypeOf((*Nat44AddressDetails)(nil)).Elem(), - "Nat44AddressDump": reflect.TypeOf((*Nat44AddressDump)(nil)).Elem(), - "Nat44DelSession": reflect.TypeOf((*Nat44DelSession)(nil)).Elem(), - "Nat44DelSessionReply": reflect.TypeOf((*Nat44DelSessionReply)(nil)).Elem(), - "Nat44ForwardingEnableDisable": reflect.TypeOf((*Nat44ForwardingEnableDisable)(nil)).Elem(), - "Nat44ForwardingEnableDisableReply": reflect.TypeOf((*Nat44ForwardingEnableDisableReply)(nil)).Elem(), - "Nat44ForwardingIsEnabled": reflect.TypeOf((*Nat44ForwardingIsEnabled)(nil)).Elem(), - "Nat44ForwardingIsEnabledReply": reflect.TypeOf((*Nat44ForwardingIsEnabledReply)(nil)).Elem(), - "Nat44IdentityMappingDetails": reflect.TypeOf((*Nat44IdentityMappingDetails)(nil)).Elem(), - "Nat44IdentityMappingDump": reflect.TypeOf((*Nat44IdentityMappingDump)(nil)).Elem(), - "Nat44InterfaceAddDelFeature": reflect.TypeOf((*Nat44InterfaceAddDelFeature)(nil)).Elem(), - "Nat44InterfaceAddDelFeatureReply": reflect.TypeOf((*Nat44InterfaceAddDelFeatureReply)(nil)).Elem(), - "Nat44InterfaceAddDelOutputFeature": reflect.TypeOf((*Nat44InterfaceAddDelOutputFeature)(nil)).Elem(), - "Nat44InterfaceAddDelOutputFeatureReply": reflect.TypeOf((*Nat44InterfaceAddDelOutputFeatureReply)(nil)).Elem(), - "Nat44InterfaceAddrDetails": reflect.TypeOf((*Nat44InterfaceAddrDetails)(nil)).Elem(), - "Nat44InterfaceAddrDump": reflect.TypeOf((*Nat44InterfaceAddrDump)(nil)).Elem(), - "Nat44InterfaceDetails": reflect.TypeOf((*Nat44InterfaceDetails)(nil)).Elem(), - "Nat44InterfaceDump": reflect.TypeOf((*Nat44InterfaceDump)(nil)).Elem(), - "Nat44InterfaceOutputFeatureDetails": reflect.TypeOf((*Nat44InterfaceOutputFeatureDetails)(nil)).Elem(), - "Nat44InterfaceOutputFeatureDump": reflect.TypeOf((*Nat44InterfaceOutputFeatureDump)(nil)).Elem(), - "Nat44LbAddrPort": reflect.TypeOf((*Nat44LbAddrPort)(nil)).Elem(), - "Nat44LbStaticMappingDetails": reflect.TypeOf((*Nat44LbStaticMappingDetails)(nil)).Elem(), - "Nat44LbStaticMappingDump": reflect.TypeOf((*Nat44LbStaticMappingDump)(nil)).Elem(), - "Nat44StaticMappingDetails": reflect.TypeOf((*Nat44StaticMappingDetails)(nil)).Elem(), - "Nat44StaticMappingDump": reflect.TypeOf((*Nat44StaticMappingDump)(nil)).Elem(), - "Nat44UserDetails": reflect.TypeOf((*Nat44UserDetails)(nil)).Elem(), - "Nat44UserDump": reflect.TypeOf((*Nat44UserDump)(nil)).Elem(), - "Nat44UserSessionDetails": reflect.TypeOf((*Nat44UserSessionDetails)(nil)).Elem(), - "Nat44UserSessionDump": reflect.TypeOf((*Nat44UserSessionDump)(nil)).Elem(), - "Nat64AddDelInterface": reflect.TypeOf((*Nat64AddDelInterface)(nil)).Elem(), - "Nat64AddDelInterfaceAddr": reflect.TypeOf((*Nat64AddDelInterfaceAddr)(nil)).Elem(), - "Nat64AddDelInterfaceAddrReply": reflect.TypeOf((*Nat64AddDelInterfaceAddrReply)(nil)).Elem(), - "Nat64AddDelInterfaceReply": reflect.TypeOf((*Nat64AddDelInterfaceReply)(nil)).Elem(), - "Nat64AddDelPoolAddrRange": reflect.TypeOf((*Nat64AddDelPoolAddrRange)(nil)).Elem(), - "Nat64AddDelPoolAddrRangeReply": reflect.TypeOf((*Nat64AddDelPoolAddrRangeReply)(nil)).Elem(), - "Nat64AddDelPrefix": reflect.TypeOf((*Nat64AddDelPrefix)(nil)).Elem(), - "Nat64AddDelPrefixReply": reflect.TypeOf((*Nat64AddDelPrefixReply)(nil)).Elem(), - "Nat64AddDelStaticBib": reflect.TypeOf((*Nat64AddDelStaticBib)(nil)).Elem(), - "Nat64AddDelStaticBibReply": reflect.TypeOf((*Nat64AddDelStaticBibReply)(nil)).Elem(), - "Nat64BibDetails": reflect.TypeOf((*Nat64BibDetails)(nil)).Elem(), - "Nat64BibDump": reflect.TypeOf((*Nat64BibDump)(nil)).Elem(), - "Nat64GetTimeouts": reflect.TypeOf((*Nat64GetTimeouts)(nil)).Elem(), - "Nat64GetTimeoutsReply": reflect.TypeOf((*Nat64GetTimeoutsReply)(nil)).Elem(), - "Nat64InterfaceDetails": reflect.TypeOf((*Nat64InterfaceDetails)(nil)).Elem(), - "Nat64InterfaceDump": reflect.TypeOf((*Nat64InterfaceDump)(nil)).Elem(), - "Nat64PoolAddrDetails": reflect.TypeOf((*Nat64PoolAddrDetails)(nil)).Elem(), - "Nat64PoolAddrDump": reflect.TypeOf((*Nat64PoolAddrDump)(nil)).Elem(), - "Nat64PrefixDetails": reflect.TypeOf((*Nat64PrefixDetails)(nil)).Elem(), - "Nat64PrefixDump": reflect.TypeOf((*Nat64PrefixDump)(nil)).Elem(), - "Nat64SetTimeouts": reflect.TypeOf((*Nat64SetTimeouts)(nil)).Elem(), - "Nat64SetTimeoutsReply": reflect.TypeOf((*Nat64SetTimeoutsReply)(nil)).Elem(), - "Nat64StDetails": reflect.TypeOf((*Nat64StDetails)(nil)).Elem(), - "Nat64StDump": reflect.TypeOf((*Nat64StDump)(nil)).Elem(), - "Nat66AddDelInterface": reflect.TypeOf((*Nat66AddDelInterface)(nil)).Elem(), - "Nat66AddDelInterfaceReply": reflect.TypeOf((*Nat66AddDelInterfaceReply)(nil)).Elem(), - "Nat66AddDelStaticMapping": reflect.TypeOf((*Nat66AddDelStaticMapping)(nil)).Elem(), - "Nat66AddDelStaticMappingReply": reflect.TypeOf((*Nat66AddDelStaticMappingReply)(nil)).Elem(), - "Nat66InterfaceDetails": reflect.TypeOf((*Nat66InterfaceDetails)(nil)).Elem(), - "Nat66InterfaceDump": reflect.TypeOf((*Nat66InterfaceDump)(nil)).Elem(), - "Nat66StaticMappingDetails": reflect.TypeOf((*Nat66StaticMappingDetails)(nil)).Elem(), - "Nat66StaticMappingDump": reflect.TypeOf((*Nat66StaticMappingDump)(nil)).Elem(), - "NatControlPing": reflect.TypeOf((*NatControlPing)(nil)).Elem(), - "NatControlPingReply": reflect.TypeOf((*NatControlPingReply)(nil)).Elem(), - "NatDetAddDelMap": reflect.TypeOf((*NatDetAddDelMap)(nil)).Elem(), - "NatDetAddDelMapReply": reflect.TypeOf((*NatDetAddDelMapReply)(nil)).Elem(), - "NatDetCloseSessionIn": reflect.TypeOf((*NatDetCloseSessionIn)(nil)).Elem(), - "NatDetCloseSessionInReply": reflect.TypeOf((*NatDetCloseSessionInReply)(nil)).Elem(), - "NatDetCloseSessionOut": reflect.TypeOf((*NatDetCloseSessionOut)(nil)).Elem(), - "NatDetCloseSessionOutReply": reflect.TypeOf((*NatDetCloseSessionOutReply)(nil)).Elem(), - "NatDetForward": reflect.TypeOf((*NatDetForward)(nil)).Elem(), - "NatDetForwardReply": reflect.TypeOf((*NatDetForwardReply)(nil)).Elem(), - "NatDetGetTimeouts": reflect.TypeOf((*NatDetGetTimeouts)(nil)).Elem(), - "NatDetGetTimeoutsReply": reflect.TypeOf((*NatDetGetTimeoutsReply)(nil)).Elem(), - "NatDetMapDetails": reflect.TypeOf((*NatDetMapDetails)(nil)).Elem(), - "NatDetMapDump": reflect.TypeOf((*NatDetMapDump)(nil)).Elem(), - "NatDetReverse": reflect.TypeOf((*NatDetReverse)(nil)).Elem(), - "NatDetReverseReply": reflect.TypeOf((*NatDetReverseReply)(nil)).Elem(), - "NatDetSessionDetails": reflect.TypeOf((*NatDetSessionDetails)(nil)).Elem(), - "NatDetSessionDump": reflect.TypeOf((*NatDetSessionDump)(nil)).Elem(), - "NatDetSetTimeouts": reflect.TypeOf((*NatDetSetTimeouts)(nil)).Elem(), - "NatDetSetTimeoutsReply": reflect.TypeOf((*NatDetSetTimeoutsReply)(nil)).Elem(), - "NatGetReass": reflect.TypeOf((*NatGetReass)(nil)).Elem(), - "NatGetReassReply": reflect.TypeOf((*NatGetReassReply)(nil)).Elem(), - "NatIpfixEnableDisable": reflect.TypeOf((*NatIpfixEnableDisable)(nil)).Elem(), - "NatIpfixEnableDisableReply": reflect.TypeOf((*NatIpfixEnableDisableReply)(nil)).Elem(), - "NatReassDetails": reflect.TypeOf((*NatReassDetails)(nil)).Elem(), - "NatReassDump": reflect.TypeOf((*NatReassDump)(nil)).Elem(), - "NatSetReass": reflect.TypeOf((*NatSetReass)(nil)).Elem(), - "NatSetReassReply": reflect.TypeOf((*NatSetReassReply)(nil)).Elem(), - "NatSetWorkers": reflect.TypeOf((*NatSetWorkers)(nil)).Elem(), - "NatSetWorkersReply": reflect.TypeOf((*NatSetWorkersReply)(nil)).Elem(), - "NatShowConfig": reflect.TypeOf((*NatShowConfig)(nil)).Elem(), - "NatShowConfigReply": reflect.TypeOf((*NatShowConfigReply)(nil)).Elem(), - "NatWorkerDetails": reflect.TypeOf((*NatWorkerDetails)(nil)).Elem(), - "NatWorkerDump": reflect.TypeOf((*NatWorkerDump)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewDsliteAddDelPoolAddrRange": reflect.ValueOf(NewDsliteAddDelPoolAddrRange), - "NewDsliteAddDelPoolAddrRangeReply": reflect.ValueOf(NewDsliteAddDelPoolAddrRangeReply), - "NewDsliteAddressDetails": reflect.ValueOf(NewDsliteAddressDetails), - "NewDsliteAddressDump": reflect.ValueOf(NewDsliteAddressDump), - "NewDsliteGetAftrAddr": reflect.ValueOf(NewDsliteGetAftrAddr), - "NewDsliteGetAftrAddrReply": reflect.ValueOf(NewDsliteGetAftrAddrReply), - "NewDsliteGetB4Addr": reflect.ValueOf(NewDsliteGetB4Addr), - "NewDsliteGetB4AddrReply": reflect.ValueOf(NewDsliteGetB4AddrReply), - "NewDsliteSetAftrAddr": reflect.ValueOf(NewDsliteSetAftrAddr), - "NewDsliteSetAftrAddrReply": reflect.ValueOf(NewDsliteSetAftrAddrReply), - "NewDsliteSetB4Addr": reflect.ValueOf(NewDsliteSetB4Addr), - "NewDsliteSetB4AddrReply": reflect.ValueOf(NewDsliteSetB4AddrReply), - "NewNat44AddDelAddressRange": reflect.ValueOf(NewNat44AddDelAddressRange), - "NewNat44AddDelAddressRangeReply": reflect.ValueOf(NewNat44AddDelAddressRangeReply), - "NewNat44AddDelIdentityMapping": reflect.ValueOf(NewNat44AddDelIdentityMapping), - "NewNat44AddDelIdentityMappingReply": reflect.ValueOf(NewNat44AddDelIdentityMappingReply), - "NewNat44AddDelInterfaceAddr": reflect.ValueOf(NewNat44AddDelInterfaceAddr), - "NewNat44AddDelInterfaceAddrReply": reflect.ValueOf(NewNat44AddDelInterfaceAddrReply), - "NewNat44AddDelLbStaticMapping": reflect.ValueOf(NewNat44AddDelLbStaticMapping), - "NewNat44AddDelLbStaticMappingReply": reflect.ValueOf(NewNat44AddDelLbStaticMappingReply), - "NewNat44AddDelStaticMapping": reflect.ValueOf(NewNat44AddDelStaticMapping), - "NewNat44AddDelStaticMappingReply": reflect.ValueOf(NewNat44AddDelStaticMappingReply), - "NewNat44AddressDetails": reflect.ValueOf(NewNat44AddressDetails), - "NewNat44AddressDump": reflect.ValueOf(NewNat44AddressDump), - "NewNat44DelSession": reflect.ValueOf(NewNat44DelSession), - "NewNat44DelSessionReply": reflect.ValueOf(NewNat44DelSessionReply), - "NewNat44ForwardingEnableDisable": reflect.ValueOf(NewNat44ForwardingEnableDisable), - "NewNat44ForwardingEnableDisableReply": reflect.ValueOf(NewNat44ForwardingEnableDisableReply), - "NewNat44ForwardingIsEnabled": reflect.ValueOf(NewNat44ForwardingIsEnabled), - "NewNat44ForwardingIsEnabledReply": reflect.ValueOf(NewNat44ForwardingIsEnabledReply), - "NewNat44IdentityMappingDetails": reflect.ValueOf(NewNat44IdentityMappingDetails), - "NewNat44IdentityMappingDump": reflect.ValueOf(NewNat44IdentityMappingDump), - "NewNat44InterfaceAddDelFeature": reflect.ValueOf(NewNat44InterfaceAddDelFeature), - "NewNat44InterfaceAddDelFeatureReply": reflect.ValueOf(NewNat44InterfaceAddDelFeatureReply), - "NewNat44InterfaceAddDelOutputFeature": reflect.ValueOf(NewNat44InterfaceAddDelOutputFeature), - "NewNat44InterfaceAddDelOutputFeatureReply": reflect.ValueOf(NewNat44InterfaceAddDelOutputFeatureReply), - "NewNat44InterfaceAddrDetails": reflect.ValueOf(NewNat44InterfaceAddrDetails), - "NewNat44InterfaceAddrDump": reflect.ValueOf(NewNat44InterfaceAddrDump), - "NewNat44InterfaceDetails": reflect.ValueOf(NewNat44InterfaceDetails), - "NewNat44InterfaceDump": reflect.ValueOf(NewNat44InterfaceDump), - "NewNat44InterfaceOutputFeatureDetails": reflect.ValueOf(NewNat44InterfaceOutputFeatureDetails), - "NewNat44InterfaceOutputFeatureDump": reflect.ValueOf(NewNat44InterfaceOutputFeatureDump), - "NewNat44LbStaticMappingDetails": reflect.ValueOf(NewNat44LbStaticMappingDetails), - "NewNat44LbStaticMappingDump": reflect.ValueOf(NewNat44LbStaticMappingDump), - "NewNat44StaticMappingDetails": reflect.ValueOf(NewNat44StaticMappingDetails), - "NewNat44StaticMappingDump": reflect.ValueOf(NewNat44StaticMappingDump), - "NewNat44UserDetails": reflect.ValueOf(NewNat44UserDetails), - "NewNat44UserDump": reflect.ValueOf(NewNat44UserDump), - "NewNat44UserSessionDetails": reflect.ValueOf(NewNat44UserSessionDetails), - "NewNat44UserSessionDump": reflect.ValueOf(NewNat44UserSessionDump), - "NewNat64AddDelInterface": reflect.ValueOf(NewNat64AddDelInterface), - "NewNat64AddDelInterfaceAddr": reflect.ValueOf(NewNat64AddDelInterfaceAddr), - "NewNat64AddDelInterfaceAddrReply": reflect.ValueOf(NewNat64AddDelInterfaceAddrReply), - "NewNat64AddDelInterfaceReply": reflect.ValueOf(NewNat64AddDelInterfaceReply), - "NewNat64AddDelPoolAddrRange": reflect.ValueOf(NewNat64AddDelPoolAddrRange), - "NewNat64AddDelPoolAddrRangeReply": reflect.ValueOf(NewNat64AddDelPoolAddrRangeReply), - "NewNat64AddDelPrefix": reflect.ValueOf(NewNat64AddDelPrefix), - "NewNat64AddDelPrefixReply": reflect.ValueOf(NewNat64AddDelPrefixReply), - "NewNat64AddDelStaticBib": reflect.ValueOf(NewNat64AddDelStaticBib), - "NewNat64AddDelStaticBibReply": reflect.ValueOf(NewNat64AddDelStaticBibReply), - "NewNat64BibDetails": reflect.ValueOf(NewNat64BibDetails), - "NewNat64BibDump": reflect.ValueOf(NewNat64BibDump), - "NewNat64GetTimeouts": reflect.ValueOf(NewNat64GetTimeouts), - "NewNat64GetTimeoutsReply": reflect.ValueOf(NewNat64GetTimeoutsReply), - "NewNat64InterfaceDetails": reflect.ValueOf(NewNat64InterfaceDetails), - "NewNat64InterfaceDump": reflect.ValueOf(NewNat64InterfaceDump), - "NewNat64PoolAddrDetails": reflect.ValueOf(NewNat64PoolAddrDetails), - "NewNat64PoolAddrDump": reflect.ValueOf(NewNat64PoolAddrDump), - "NewNat64PrefixDetails": reflect.ValueOf(NewNat64PrefixDetails), - "NewNat64PrefixDump": reflect.ValueOf(NewNat64PrefixDump), - "NewNat64SetTimeouts": reflect.ValueOf(NewNat64SetTimeouts), - "NewNat64SetTimeoutsReply": reflect.ValueOf(NewNat64SetTimeoutsReply), - "NewNat64StDetails": reflect.ValueOf(NewNat64StDetails), - "NewNat64StDump": reflect.ValueOf(NewNat64StDump), - "NewNat66AddDelInterface": reflect.ValueOf(NewNat66AddDelInterface), - "NewNat66AddDelInterfaceReply": reflect.ValueOf(NewNat66AddDelInterfaceReply), - "NewNat66AddDelStaticMapping": reflect.ValueOf(NewNat66AddDelStaticMapping), - "NewNat66AddDelStaticMappingReply": reflect.ValueOf(NewNat66AddDelStaticMappingReply), - "NewNat66InterfaceDetails": reflect.ValueOf(NewNat66InterfaceDetails), - "NewNat66InterfaceDump": reflect.ValueOf(NewNat66InterfaceDump), - "NewNat66StaticMappingDetails": reflect.ValueOf(NewNat66StaticMappingDetails), - "NewNat66StaticMappingDump": reflect.ValueOf(NewNat66StaticMappingDump), - "NewNatControlPing": reflect.ValueOf(NewNatControlPing), - "NewNatControlPingReply": reflect.ValueOf(NewNatControlPingReply), - "NewNatDetAddDelMap": reflect.ValueOf(NewNatDetAddDelMap), - "NewNatDetAddDelMapReply": reflect.ValueOf(NewNatDetAddDelMapReply), - "NewNatDetCloseSessionIn": reflect.ValueOf(NewNatDetCloseSessionIn), - "NewNatDetCloseSessionInReply": reflect.ValueOf(NewNatDetCloseSessionInReply), - "NewNatDetCloseSessionOut": reflect.ValueOf(NewNatDetCloseSessionOut), - "NewNatDetCloseSessionOutReply": reflect.ValueOf(NewNatDetCloseSessionOutReply), - "NewNatDetForward": reflect.ValueOf(NewNatDetForward), - "NewNatDetForwardReply": reflect.ValueOf(NewNatDetForwardReply), - "NewNatDetGetTimeouts": reflect.ValueOf(NewNatDetGetTimeouts), - "NewNatDetGetTimeoutsReply": reflect.ValueOf(NewNatDetGetTimeoutsReply), - "NewNatDetMapDetails": reflect.ValueOf(NewNatDetMapDetails), - "NewNatDetMapDump": reflect.ValueOf(NewNatDetMapDump), - "NewNatDetReverse": reflect.ValueOf(NewNatDetReverse), - "NewNatDetReverseReply": reflect.ValueOf(NewNatDetReverseReply), - "NewNatDetSessionDetails": reflect.ValueOf(NewNatDetSessionDetails), - "NewNatDetSessionDump": reflect.ValueOf(NewNatDetSessionDump), - "NewNatDetSetTimeouts": reflect.ValueOf(NewNatDetSetTimeouts), - "NewNatDetSetTimeoutsReply": reflect.ValueOf(NewNatDetSetTimeoutsReply), - "NewNatGetReass": reflect.ValueOf(NewNatGetReass), - "NewNatGetReassReply": reflect.ValueOf(NewNatGetReassReply), - "NewNatIpfixEnableDisable": reflect.ValueOf(NewNatIpfixEnableDisable), - "NewNatIpfixEnableDisableReply": reflect.ValueOf(NewNatIpfixEnableDisableReply), - "NewNatReassDetails": reflect.ValueOf(NewNatReassDetails), - "NewNatReassDump": reflect.ValueOf(NewNatReassDump), - "NewNatSetReass": reflect.ValueOf(NewNatSetReass), - "NewNatSetReassReply": reflect.ValueOf(NewNatSetReassReply), - "NewNatSetWorkers": reflect.ValueOf(NewNatSetWorkers), - "NewNatSetWorkersReply": reflect.ValueOf(NewNatSetWorkersReply), - "NewNatShowConfig": reflect.ValueOf(NewNatShowConfig), - "NewNatShowConfigReply": reflect.ValueOf(NewNatShowConfigReply), - "NewNatWorkerDetails": reflect.ValueOf(NewNatWorkerDetails), - "NewNatWorkerDump": reflect.ValueOf(NewNatWorkerDump), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/session/pkgreflect.go b/plugins/vpp/binapi/session/pkgreflect.go deleted file mode 100644 index 83aea6c3b9..0000000000 --- a/plugins/vpp/binapi/session/pkgreflect.go +++ /dev/null @@ -1,103 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package session - -import "reflect" - -var Types = map[string]reflect.Type{ - "AcceptSession": reflect.TypeOf((*AcceptSession)(nil)).Elem(), - "AcceptSessionReply": reflect.TypeOf((*AcceptSessionReply)(nil)).Elem(), - "AppCutThroughRegistrationAdd": reflect.TypeOf((*AppCutThroughRegistrationAdd)(nil)).Elem(), - "AppCutThroughRegistrationAddReply": reflect.TypeOf((*AppCutThroughRegistrationAddReply)(nil)).Elem(), - "AppNamespaceAddDel": reflect.TypeOf((*AppNamespaceAddDel)(nil)).Elem(), - "AppNamespaceAddDelReply": reflect.TypeOf((*AppNamespaceAddDelReply)(nil)).Elem(), - "ApplicationAttach": reflect.TypeOf((*ApplicationAttach)(nil)).Elem(), - "ApplicationAttachReply": reflect.TypeOf((*ApplicationAttachReply)(nil)).Elem(), - "ApplicationDetach": reflect.TypeOf((*ApplicationDetach)(nil)).Elem(), - "ApplicationDetachReply": reflect.TypeOf((*ApplicationDetachReply)(nil)).Elem(), - "ApplicationTLSCertAdd": reflect.TypeOf((*ApplicationTLSCertAdd)(nil)).Elem(), - "ApplicationTLSCertAddReply": reflect.TypeOf((*ApplicationTLSCertAddReply)(nil)).Elem(), - "ApplicationTLSKeyAdd": reflect.TypeOf((*ApplicationTLSKeyAdd)(nil)).Elem(), - "ApplicationTLSKeyAddReply": reflect.TypeOf((*ApplicationTLSKeyAddReply)(nil)).Elem(), - "BindSock": reflect.TypeOf((*BindSock)(nil)).Elem(), - "BindSockReply": reflect.TypeOf((*BindSockReply)(nil)).Elem(), - "BindURI": reflect.TypeOf((*BindURI)(nil)).Elem(), - "BindURIReply": reflect.TypeOf((*BindURIReply)(nil)).Elem(), - "ConnectSession": reflect.TypeOf((*ConnectSession)(nil)).Elem(), - "ConnectSessionReply": reflect.TypeOf((*ConnectSessionReply)(nil)).Elem(), - "ConnectSock": reflect.TypeOf((*ConnectSock)(nil)).Elem(), - "ConnectSockReply": reflect.TypeOf((*ConnectSockReply)(nil)).Elem(), - "ConnectURI": reflect.TypeOf((*ConnectURI)(nil)).Elem(), - "ConnectURIReply": reflect.TypeOf((*ConnectURIReply)(nil)).Elem(), - "DisconnectSession": reflect.TypeOf((*DisconnectSession)(nil)).Elem(), - "DisconnectSessionReply": reflect.TypeOf((*DisconnectSessionReply)(nil)).Elem(), - "MapAnotherSegment": reflect.TypeOf((*MapAnotherSegment)(nil)).Elem(), - "MapAnotherSegmentReply": reflect.TypeOf((*MapAnotherSegmentReply)(nil)).Elem(), - "ResetSession": reflect.TypeOf((*ResetSession)(nil)).Elem(), - "ResetSessionReply": reflect.TypeOf((*ResetSessionReply)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SessionEnableDisable": reflect.TypeOf((*SessionEnableDisable)(nil)).Elem(), - "SessionEnableDisableReply": reflect.TypeOf((*SessionEnableDisableReply)(nil)).Elem(), - "SessionRuleAddDel": reflect.TypeOf((*SessionRuleAddDel)(nil)).Elem(), - "SessionRuleAddDelReply": reflect.TypeOf((*SessionRuleAddDelReply)(nil)).Elem(), - "SessionRulesDetails": reflect.TypeOf((*SessionRulesDetails)(nil)).Elem(), - "SessionRulesDump": reflect.TypeOf((*SessionRulesDump)(nil)).Elem(), - "UnbindSock": reflect.TypeOf((*UnbindSock)(nil)).Elem(), - "UnbindSockReply": reflect.TypeOf((*UnbindSockReply)(nil)).Elem(), - "UnbindURI": reflect.TypeOf((*UnbindURI)(nil)).Elem(), - "UnbindURIReply": reflect.TypeOf((*UnbindURIReply)(nil)).Elem(), - "UnmapSegment": reflect.TypeOf((*UnmapSegment)(nil)).Elem(), - "UnmapSegmentReply": reflect.TypeOf((*UnmapSegmentReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewAcceptSession": reflect.ValueOf(NewAcceptSession), - "NewAcceptSessionReply": reflect.ValueOf(NewAcceptSessionReply), - "NewAppCutThroughRegistrationAdd": reflect.ValueOf(NewAppCutThroughRegistrationAdd), - "NewAppCutThroughRegistrationAddReply": reflect.ValueOf(NewAppCutThroughRegistrationAddReply), - "NewAppNamespaceAddDel": reflect.ValueOf(NewAppNamespaceAddDel), - "NewAppNamespaceAddDelReply": reflect.ValueOf(NewAppNamespaceAddDelReply), - "NewApplicationAttach": reflect.ValueOf(NewApplicationAttach), - "NewApplicationAttachReply": reflect.ValueOf(NewApplicationAttachReply), - "NewApplicationDetach": reflect.ValueOf(NewApplicationDetach), - "NewApplicationDetachReply": reflect.ValueOf(NewApplicationDetachReply), - "NewApplicationTLSCertAdd": reflect.ValueOf(NewApplicationTLSCertAdd), - "NewApplicationTLSCertAddReply": reflect.ValueOf(NewApplicationTLSCertAddReply), - "NewApplicationTLSKeyAdd": reflect.ValueOf(NewApplicationTLSKeyAdd), - "NewApplicationTLSKeyAddReply": reflect.ValueOf(NewApplicationTLSKeyAddReply), - "NewBindSock": reflect.ValueOf(NewBindSock), - "NewBindSockReply": reflect.ValueOf(NewBindSockReply), - "NewBindURI": reflect.ValueOf(NewBindURI), - "NewBindURIReply": reflect.ValueOf(NewBindURIReply), - "NewConnectSession": reflect.ValueOf(NewConnectSession), - "NewConnectSessionReply": reflect.ValueOf(NewConnectSessionReply), - "NewConnectSock": reflect.ValueOf(NewConnectSock), - "NewConnectSockReply": reflect.ValueOf(NewConnectSockReply), - "NewConnectURI": reflect.ValueOf(NewConnectURI), - "NewConnectURIReply": reflect.ValueOf(NewConnectURIReply), - "NewDisconnectSession": reflect.ValueOf(NewDisconnectSession), - "NewDisconnectSessionReply": reflect.ValueOf(NewDisconnectSessionReply), - "NewMapAnotherSegment": reflect.ValueOf(NewMapAnotherSegment), - "NewMapAnotherSegmentReply": reflect.ValueOf(NewMapAnotherSegmentReply), - "NewResetSession": reflect.ValueOf(NewResetSession), - "NewResetSessionReply": reflect.ValueOf(NewResetSessionReply), - "NewSessionEnableDisable": reflect.ValueOf(NewSessionEnableDisable), - "NewSessionEnableDisableReply": reflect.ValueOf(NewSessionEnableDisableReply), - "NewSessionRuleAddDel": reflect.ValueOf(NewSessionRuleAddDel), - "NewSessionRuleAddDelReply": reflect.ValueOf(NewSessionRuleAddDelReply), - "NewSessionRulesDetails": reflect.ValueOf(NewSessionRulesDetails), - "NewSessionRulesDump": reflect.ValueOf(NewSessionRulesDump), - "NewUnbindSock": reflect.ValueOf(NewUnbindSock), - "NewUnbindSockReply": reflect.ValueOf(NewUnbindSockReply), - "NewUnbindURI": reflect.ValueOf(NewUnbindURI), - "NewUnbindURIReply": reflect.ValueOf(NewUnbindURIReply), - "NewUnmapSegment": reflect.ValueOf(NewUnmapSegment), - "NewUnmapSegmentReply": reflect.ValueOf(NewUnmapSegmentReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/session/session.ba.go b/plugins/vpp/binapi/session/session.ba.go index 5bbc41981f..d5f268c9e7 100644 --- a/plugins/vpp/binapi/session/session.ba.go +++ b/plugins/vpp/binapi/session/session.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/session.api.json +// source: /usr/share/vpp/api/session.api.json /* -Package session is a generated VPP binary API of the 'session' VPP module. + Package session is a generated from VPP binary API module 'session'. -It is generated from this file: - session.api.json + It contains following objects: + 44 messages + 22 services -It contains these VPP binary API objects: - 42 messages - 21 services */ package session @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // ApplicationAttach represents the VPP binary API message 'application_attach'. -// Generated from 'session.api.json', line 4: // // "application_attach", // [ @@ -77,12 +75,8 @@ func (*ApplicationAttach) GetCrcString() string { func (*ApplicationAttach) GetMessageType() api.MessageType { return api.RequestMessage } -func NewApplicationAttach() api.Message { - return &ApplicationAttach{} -} // ApplicationAttachReply represents the VPP binary API message 'application_attach_reply'. -// Generated from 'session.api.json', line 40: // // "application_attach_reply", // [ @@ -145,12 +139,8 @@ func (*ApplicationAttachReply) GetCrcString() string { func (*ApplicationAttachReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewApplicationAttachReply() api.Message { - return &ApplicationAttachReply{} -} // ApplicationTLSCertAdd represents the VPP binary API message 'application_tls_cert_add'. -// Generated from 'session.api.json', line 83: // // "application_tls_cert_add", // [ @@ -198,12 +188,8 @@ func (*ApplicationTLSCertAdd) GetCrcString() string { func (*ApplicationTLSCertAdd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewApplicationTLSCertAdd() api.Message { - return &ApplicationTLSCertAdd{} -} // ApplicationTLSCertAddReply represents the VPP binary API message 'application_tls_cert_add_reply'. -// Generated from 'session.api.json', line 115: // // "application_tls_cert_add_reply", // [ @@ -235,12 +221,8 @@ func (*ApplicationTLSCertAddReply) GetCrcString() string { func (*ApplicationTLSCertAddReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewApplicationTLSCertAddReply() api.Message { - return &ApplicationTLSCertAddReply{} -} // ApplicationTLSKeyAdd represents the VPP binary API message 'application_tls_key_add'. -// Generated from 'session.api.json', line 133: // // "application_tls_key_add", // [ @@ -288,12 +270,8 @@ func (*ApplicationTLSKeyAdd) GetCrcString() string { func (*ApplicationTLSKeyAdd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewApplicationTLSKeyAdd() api.Message { - return &ApplicationTLSKeyAdd{} -} // ApplicationTLSKeyAddReply represents the VPP binary API message 'application_tls_key_add_reply'. -// Generated from 'session.api.json', line 165: // // "application_tls_key_add_reply", // [ @@ -325,12 +303,8 @@ func (*ApplicationTLSKeyAddReply) GetCrcString() string { func (*ApplicationTLSKeyAddReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewApplicationTLSKeyAddReply() api.Message { - return &ApplicationTLSKeyAddReply{} -} // ApplicationDetach represents the VPP binary API message 'application_detach'. -// Generated from 'session.api.json', line 183: // // "application_detach", // [ @@ -360,12 +334,8 @@ func (*ApplicationDetach) GetCrcString() string { func (*ApplicationDetach) GetMessageType() api.MessageType { return api.RequestMessage } -func NewApplicationDetach() api.Message { - return &ApplicationDetach{} -} // ApplicationDetachReply represents the VPP binary API message 'application_detach_reply'. -// Generated from 'session.api.json', line 201: // // "application_detach_reply", // [ @@ -397,12 +367,8 @@ func (*ApplicationDetachReply) GetCrcString() string { func (*ApplicationDetachReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewApplicationDetachReply() api.Message { - return &ApplicationDetachReply{} -} // MapAnotherSegment represents the VPP binary API message 'map_another_segment'. -// Generated from 'session.api.json', line 219: // // "map_another_segment", // [ @@ -449,12 +415,8 @@ func (*MapAnotherSegment) GetCrcString() string { func (*MapAnotherSegment) GetMessageType() api.MessageType { return api.RequestMessage } -func NewMapAnotherSegment() api.Message { - return &MapAnotherSegment{} -} // MapAnotherSegmentReply represents the VPP binary API message 'map_another_segment_reply'. -// Generated from 'session.api.json', line 250: // // "map_another_segment_reply", // [ @@ -486,12 +448,8 @@ func (*MapAnotherSegmentReply) GetCrcString() string { func (*MapAnotherSegmentReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewMapAnotherSegmentReply() api.Message { - return &MapAnotherSegmentReply{} -} // UnmapSegment represents the VPP binary API message 'unmap_segment'. -// Generated from 'session.api.json', line 268: // // "unmap_segment", // [ @@ -528,12 +486,8 @@ func (*UnmapSegment) GetCrcString() string { func (*UnmapSegment) GetMessageType() api.MessageType { return api.RequestMessage } -func NewUnmapSegment() api.Message { - return &UnmapSegment{} -} // UnmapSegmentReply represents the VPP binary API message 'unmap_segment_reply'. -// Generated from 'session.api.json', line 291: // // "unmap_segment_reply", // [ @@ -565,12 +519,8 @@ func (*UnmapSegmentReply) GetCrcString() string { func (*UnmapSegmentReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewUnmapSegmentReply() api.Message { - return &UnmapSegmentReply{} -} // BindURI represents the VPP binary API message 'bind_uri'. -// Generated from 'session.api.json', line 309: // // "bind_uri", // [ @@ -612,12 +562,8 @@ func (*BindURI) GetCrcString() string { func (*BindURI) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBindURI() api.Message { - return &BindURI{} -} // BindURIReply represents the VPP binary API message 'bind_uri_reply'. -// Generated from 'session.api.json', line 336: // // "bind_uri_reply", // [ @@ -685,12 +631,8 @@ func (*BindURIReply) GetCrcString() string { func (*BindURIReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBindURIReply() api.Message { - return &BindURIReply{} -} // UnbindURI represents the VPP binary API message 'unbind_uri'. -// Generated from 'session.api.json', line 383: // // "unbind_uri", // [ @@ -727,12 +669,8 @@ func (*UnbindURI) GetCrcString() string { func (*UnbindURI) GetMessageType() api.MessageType { return api.RequestMessage } -func NewUnbindURI() api.Message { - return &UnbindURI{} -} // UnbindURIReply represents the VPP binary API message 'unbind_uri_reply'. -// Generated from 'session.api.json', line 406: // // "unbind_uri_reply", // [ @@ -764,12 +702,8 @@ func (*UnbindURIReply) GetCrcString() string { func (*UnbindURIReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewUnbindURIReply() api.Message { - return &UnbindURIReply{} -} // ConnectURI represents the VPP binary API message 'connect_uri'. -// Generated from 'session.api.json', line 424: // // "connect_uri", // [ @@ -817,12 +751,8 @@ func (*ConnectURI) GetCrcString() string { func (*ConnectURI) GetMessageType() api.MessageType { return api.RequestMessage } -func NewConnectURI() api.Message { - return &ConnectURI{} -} // ConnectURIReply represents the VPP binary API message 'connect_uri_reply'. -// Generated from 'session.api.json', line 456: // // "connect_uri_reply", // [ @@ -854,12 +784,8 @@ func (*ConnectURIReply) GetCrcString() string { func (*ConnectURIReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewConnectURIReply() api.Message { - return &ConnectURIReply{} -} // AcceptSession represents the VPP binary API message 'accept_session'. -// Generated from 'session.api.json', line 474: // // "accept_session", // [ @@ -936,12 +862,8 @@ func (*AcceptSession) GetCrcString() string { func (*AcceptSession) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAcceptSession() api.Message { - return &AcceptSession{} -} // AcceptSessionReply represents the VPP binary API message 'accept_session_reply'. -// Generated from 'session.api.json', line 529: // // "accept_session_reply", // [ @@ -978,12 +900,8 @@ func (*AcceptSessionReply) GetCrcString() string { func (*AcceptSessionReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAcceptSessionReply() api.Message { - return &AcceptSessionReply{} -} // DisconnectSession represents the VPP binary API message 'disconnect_session'. -// Generated from 'session.api.json', line 551: // // "disconnect_session", // [ @@ -1019,12 +937,8 @@ func (*DisconnectSession) GetCrcString() string { func (*DisconnectSession) GetMessageType() api.MessageType { return api.RequestMessage } -func NewDisconnectSession() api.Message { - return &DisconnectSession{} -} // DisconnectSessionReply represents the VPP binary API message 'disconnect_session_reply'. -// Generated from 'session.api.json', line 573: // // "disconnect_session_reply", // [ @@ -1061,12 +975,8 @@ func (*DisconnectSessionReply) GetCrcString() string { func (*DisconnectSessionReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewDisconnectSessionReply() api.Message { - return &DisconnectSessionReply{} -} // ResetSession represents the VPP binary API message 'reset_session'. -// Generated from 'session.api.json', line 595: // // "reset_session", // [ @@ -1102,12 +1012,8 @@ func (*ResetSession) GetCrcString() string { func (*ResetSession) GetMessageType() api.MessageType { return api.RequestMessage } -func NewResetSession() api.Message { - return &ResetSession{} -} // ResetSessionReply represents the VPP binary API message 'reset_session_reply'. -// Generated from 'session.api.json', line 617: // // "reset_session_reply", // [ @@ -1116,10 +1022,6 @@ func NewResetSession() api.Message { // ], // [ // "u32", -// "client_index" -// ], -// [ -// "u32", // "context" // ], // [ @@ -1131,7 +1033,7 @@ func NewResetSession() api.Message { // "handle" // ], // { -// "crc": "0xfaf37b87" +// "crc": "0xd6960a03" // } // type ResetSessionReply struct { @@ -1143,17 +1045,13 @@ func (*ResetSessionReply) GetMessageName() string { return "reset_session_reply" } func (*ResetSessionReply) GetCrcString() string { - return "faf37b87" + return "d6960a03" } func (*ResetSessionReply) GetMessageType() api.MessageType { - return api.RequestMessage -} -func NewResetSessionReply() api.Message { - return &ResetSessionReply{} + return api.ReplyMessage } // BindSock represents the VPP binary API message 'bind_sock'. -// Generated from 'session.api.json', line 643: // // "bind_sock", // [ @@ -1170,6 +1068,10 @@ func NewResetSessionReply() api.Message { // ], // [ // "u32", +// "wrk_index" +// ], +// [ +// "u32", // "vrf" // ], // [ @@ -1195,33 +1097,30 @@ func NewResetSessionReply() api.Message { // 16 // ], // { -// "crc": "0x6a6a40d0" +// "crc": "0x0394633f" // } // type BindSock struct { - Vrf uint32 - IsIP4 uint8 - IP []byte `struc:"[16]byte"` - Port uint16 - Proto uint8 - Options []uint64 `struc:"[16]uint64"` + WrkIndex uint32 + Vrf uint32 + IsIP4 uint8 + IP []byte `struc:"[16]byte"` + Port uint16 + Proto uint8 + Options []uint64 `struc:"[16]uint64"` } func (*BindSock) GetMessageName() string { return "bind_sock" } func (*BindSock) GetCrcString() string { - return "6a6a40d0" + return "0394633f" } func (*BindSock) GetMessageType() api.MessageType { return api.RequestMessage } -func NewBindSock() api.Message { - return &BindSock{} -} // UnbindSock represents the VPP binary API message 'unbind_sock'. -// Generated from 'session.api.json', line 687: // // "unbind_sock", // [ @@ -1237,32 +1136,33 @@ func NewBindSock() api.Message { // "context" // ], // [ +// "u32", +// "wrk_index" +// ], +// [ // "u64", // "handle" // ], // { -// "crc": "0x7279205b" +// "crc": "0x08880908" // } // type UnbindSock struct { - Handle uint64 + WrkIndex uint32 + Handle uint64 } func (*UnbindSock) GetMessageName() string { return "unbind_sock" } func (*UnbindSock) GetCrcString() string { - return "7279205b" + return "08880908" } func (*UnbindSock) GetMessageType() api.MessageType { return api.RequestMessage } -func NewUnbindSock() api.Message { - return &UnbindSock{} -} // UnbindSockReply represents the VPP binary API message 'unbind_sock_reply'. -// Generated from 'session.api.json', line 709: // // "unbind_sock_reply", // [ @@ -1294,12 +1194,8 @@ func (*UnbindSockReply) GetCrcString() string { func (*UnbindSockReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewUnbindSockReply() api.Message { - return &UnbindSockReply{} -} // ConnectSock represents the VPP binary API message 'connect_sock'. -// Generated from 'session.api.json', line 727: // // "connect_sock", // [ @@ -1315,6 +1211,10 @@ func NewUnbindSockReply() api.Message { // "context" // ], // [ +// "u32", +// "wrk_index" +// ], +// [ // "u64", // "client_queue_address" // ], @@ -1355,10 +1255,11 @@ func NewUnbindSockReply() api.Message { // "hostname_len" // ], // { -// "crc": "0x02c6e3c3" +// "crc": "0xa916aa77" // } // type ConnectSock struct { + WrkIndex uint32 ClientQueueAddress uint64 Options []uint64 `struc:"[16]uint64"` Vrf uint32 @@ -1374,17 +1275,13 @@ func (*ConnectSock) GetMessageName() string { return "connect_sock" } func (*ConnectSock) GetCrcString() string { - return "02c6e3c3" + return "a916aa77" } func (*ConnectSock) GetMessageType() api.MessageType { return api.RequestMessage } -func NewConnectSock() api.Message { - return &ConnectSock{} -} // ConnectSockReply represents the VPP binary API message 'connect_sock_reply'. -// Generated from 'session.api.json', line 785: // // "connect_sock_reply", // [ @@ -1416,12 +1313,8 @@ func (*ConnectSockReply) GetCrcString() string { func (*ConnectSockReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewConnectSockReply() api.Message { - return &ConnectSockReply{} -} // BindSockReply represents the VPP binary API message 'bind_sock_reply'. -// Generated from 'session.api.json', line 803: // // "bind_sock_reply", // [ @@ -1505,12 +1398,8 @@ func (*BindSockReply) GetCrcString() string { func (*BindSockReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewBindSockReply() api.Message { - return &BindSockReply{} -} // ConnectSession represents the VPP binary API message 'connect_session'. -// Generated from 'session.api.json', line 863: // // "connect_session", // [ @@ -1540,12 +1429,8 @@ func (*ConnectSession) GetCrcString() string { func (*ConnectSession) GetMessageType() api.MessageType { return api.RequestMessage } -func NewConnectSession() api.Message { - return &ConnectSession{} -} // ConnectSessionReply represents the VPP binary API message 'connect_session_reply'. -// Generated from 'session.api.json', line 881: // // "connect_session_reply", // [ @@ -1634,12 +1519,8 @@ func (*ConnectSessionReply) GetCrcString() string { func (*ConnectSessionReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewConnectSessionReply() api.Message { - return &ConnectSessionReply{} -} // AppCutThroughRegistrationAdd represents the VPP binary API message 'app_cut_through_registration_add'. -// Generated from 'session.api.json', line 945: // // "app_cut_through_registration_add", // [ @@ -1663,6 +1544,10 @@ func NewConnectSessionReply() api.Message { // "peer_evt_q_address" // ], // [ +// "u32", +// "wrk_index" +// ], +// [ // "u8", // "n_fds" // ], @@ -1671,12 +1556,13 @@ func NewConnectSessionReply() api.Message { // "fd_flags" // ], // { -// "crc": "0x75093c85" +// "crc": "0x6d73b1b9" // } // type AppCutThroughRegistrationAdd struct { EvtQAddress uint64 PeerEvtQAddress uint64 + WrkIndex uint32 NFds uint8 FdFlags uint8 } @@ -1685,17 +1571,13 @@ func (*AppCutThroughRegistrationAdd) GetMessageName() string { return "app_cut_through_registration_add" } func (*AppCutThroughRegistrationAdd) GetCrcString() string { - return "75093c85" + return "6d73b1b9" } func (*AppCutThroughRegistrationAdd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAppCutThroughRegistrationAdd() api.Message { - return &AppCutThroughRegistrationAdd{} -} // AppCutThroughRegistrationAddReply represents the VPP binary API message 'app_cut_through_registration_add_reply'. -// Generated from 'session.api.json', line 979: // // "app_cut_through_registration_add_reply", // [ @@ -1727,12 +1609,124 @@ func (*AppCutThroughRegistrationAddReply) GetCrcString() string { func (*AppCutThroughRegistrationAddReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAppCutThroughRegistrationAddReply() api.Message { - return &AppCutThroughRegistrationAddReply{} + +// AppWorkerAddDel represents the VPP binary API message 'app_worker_add_del'. +// +// "app_worker_add_del", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "client_index" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "u32", +// "app_api_index" +// ], +// [ +// "u32", +// "wrk_index" +// ], +// [ +// "u8", +// "is_add" +// ], +// { +// "crc": "0x8cd304f4" +// } +// +type AppWorkerAddDel struct { + AppAPIIndex uint32 + WrkIndex uint32 + IsAdd uint8 +} + +func (*AppWorkerAddDel) GetMessageName() string { + return "app_worker_add_del" +} +func (*AppWorkerAddDel) GetCrcString() string { + return "8cd304f4" +} +func (*AppWorkerAddDel) GetMessageType() api.MessageType { + return api.RequestMessage +} + +// AppWorkerAddDelReply represents the VPP binary API message 'app_worker_add_del_reply'. +// +// "app_worker_add_del_reply", +// [ +// "u16", +// "_vl_msg_id" +// ], +// [ +// "u32", +// "context" +// ], +// [ +// "i32", +// "retval" +// ], +// [ +// "u32", +// "wrk_index" +// ], +// [ +// "u64", +// "app_event_queue_address" +// ], +// [ +// "u8", +// "n_fds" +// ], +// [ +// "u8", +// "fd_flags" +// ], +// [ +// "u8", +// "segment_name_length" +// ], +// [ +// "u8", +// "segment_name", +// 128 +// ], +// [ +// "u8", +// "is_add" +// ], +// { +// "crc": "0xd5297212" +// } +// +type AppWorkerAddDelReply struct { + Retval int32 + WrkIndex uint32 + AppEventQueueAddress uint64 + NFds uint8 + FdFlags uint8 + SegmentNameLength uint8 + SegmentName []byte `struc:"[128]byte"` + IsAdd uint8 +} + +func (*AppWorkerAddDelReply) GetMessageName() string { + return "app_worker_add_del_reply" +} +func (*AppWorkerAddDelReply) GetCrcString() string { + return "d5297212" +} +func (*AppWorkerAddDelReply) GetMessageType() api.MessageType { + return api.ReplyMessage } // SessionEnableDisable represents the VPP binary API message 'session_enable_disable'. -// Generated from 'session.api.json', line 997: // // "session_enable_disable", // [ @@ -1768,12 +1762,8 @@ func (*SessionEnableDisable) GetCrcString() string { func (*SessionEnableDisable) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSessionEnableDisable() api.Message { - return &SessionEnableDisable{} -} // SessionEnableDisableReply represents the VPP binary API message 'session_enable_disable_reply'. -// Generated from 'session.api.json', line 1019: // // "session_enable_disable_reply", // [ @@ -1805,12 +1795,8 @@ func (*SessionEnableDisableReply) GetCrcString() string { func (*SessionEnableDisableReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSessionEnableDisableReply() api.Message { - return &SessionEnableDisableReply{} -} // AppNamespaceAddDel represents the VPP binary API message 'app_namespace_add_del'. -// Generated from 'session.api.json', line 1037: // // "app_namespace_add_del", // [ @@ -1872,12 +1858,8 @@ func (*AppNamespaceAddDel) GetCrcString() string { func (*AppNamespaceAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAppNamespaceAddDel() api.Message { - return &AppNamespaceAddDel{} -} // AppNamespaceAddDelReply represents the VPP binary API message 'app_namespace_add_del_reply'. -// Generated from 'session.api.json', line 1080: // // "app_namespace_add_del_reply", // [ @@ -1914,12 +1896,8 @@ func (*AppNamespaceAddDelReply) GetCrcString() string { func (*AppNamespaceAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAppNamespaceAddDelReply() api.Message { - return &AppNamespaceAddDelReply{} -} // SessionRuleAddDel represents the VPP binary API message 'session_rule_add_del'. -// Generated from 'session.api.json', line 1102: // // "session_rule_add_del", // [ @@ -2018,12 +1996,8 @@ func (*SessionRuleAddDel) GetCrcString() string { func (*SessionRuleAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSessionRuleAddDel() api.Message { - return &SessionRuleAddDel{} -} // SessionRuleAddDelReply represents the VPP binary API message 'session_rule_add_del_reply'. -// Generated from 'session.api.json', line 1175: // // "session_rule_add_del_reply", // [ @@ -2055,12 +2029,8 @@ func (*SessionRuleAddDelReply) GetCrcString() string { func (*SessionRuleAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSessionRuleAddDelReply() api.Message { - return &SessionRuleAddDelReply{} -} // SessionRulesDump represents the VPP binary API message 'session_rules_dump'. -// Generated from 'session.api.json', line 1193: // // "session_rules_dump", // [ @@ -2090,12 +2060,8 @@ func (*SessionRulesDump) GetCrcString() string { func (*SessionRulesDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSessionRulesDump() api.Message { - return &SessionRulesDump{} -} // SessionRulesDetails represents the VPP binary API message 'session_rules_details'. -// Generated from 'session.api.json', line 1211: // // "session_rules_details", // [ @@ -2185,9 +2151,6 @@ func (*SessionRulesDetails) GetCrcString() string { func (*SessionRulesDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSessionRulesDetails() api.Message { - return &SessionRulesDetails{} -} /* Services */ @@ -2196,6 +2159,7 @@ type Services interface { AcceptSession(*AcceptSession) (*AcceptSessionReply, error) AppCutThroughRegistrationAdd(*AppCutThroughRegistrationAdd) (*AppCutThroughRegistrationAddReply, error) AppNamespaceAddDel(*AppNamespaceAddDel) (*AppNamespaceAddDelReply, error) + AppWorkerAddDel(*AppWorkerAddDel) (*AppWorkerAddDelReply, error) ApplicationAttach(*ApplicationAttach) (*ApplicationAttachReply, error) ApplicationDetach(*ApplicationDetach) (*ApplicationDetachReply, error) ApplicationTLSCertAdd(*ApplicationTLSCertAdd) (*ApplicationTLSCertAddReply, error) @@ -2250,6 +2214,8 @@ func init() { api.RegisterMessage((*ConnectSessionReply)(nil), "session.ConnectSessionReply") api.RegisterMessage((*AppCutThroughRegistrationAdd)(nil), "session.AppCutThroughRegistrationAdd") api.RegisterMessage((*AppCutThroughRegistrationAddReply)(nil), "session.AppCutThroughRegistrationAddReply") + api.RegisterMessage((*AppWorkerAddDel)(nil), "session.AppWorkerAddDel") + api.RegisterMessage((*AppWorkerAddDelReply)(nil), "session.AppWorkerAddDelReply") api.RegisterMessage((*SessionEnableDisable)(nil), "session.SessionEnableDisable") api.RegisterMessage((*SessionEnableDisableReply)(nil), "session.SessionEnableDisableReply") api.RegisterMessage((*AppNamespaceAddDel)(nil), "session.AppNamespaceAddDel") diff --git a/plugins/vpp/binapi/sr/pkgreflect.go b/plugins/vpp/binapi/sr/pkgreflect.go deleted file mode 100644 index 02983ddb0b..0000000000 --- a/plugins/vpp/binapi/sr/pkgreflect.go +++ /dev/null @@ -1,58 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package sr - -import "reflect" - -var Types = map[string]reflect.Type{ - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SrIP6Address": reflect.TypeOf((*SrIP6Address)(nil)).Elem(), - "SrLocalsidAddDel": reflect.TypeOf((*SrLocalsidAddDel)(nil)).Elem(), - "SrLocalsidAddDelReply": reflect.TypeOf((*SrLocalsidAddDelReply)(nil)).Elem(), - "SrLocalsidsDetails": reflect.TypeOf((*SrLocalsidsDetails)(nil)).Elem(), - "SrLocalsidsDump": reflect.TypeOf((*SrLocalsidsDump)(nil)).Elem(), - "SrPoliciesDetails": reflect.TypeOf((*SrPoliciesDetails)(nil)).Elem(), - "SrPoliciesDump": reflect.TypeOf((*SrPoliciesDump)(nil)).Elem(), - "SrPolicyAdd": reflect.TypeOf((*SrPolicyAdd)(nil)).Elem(), - "SrPolicyAddReply": reflect.TypeOf((*SrPolicyAddReply)(nil)).Elem(), - "SrPolicyDel": reflect.TypeOf((*SrPolicyDel)(nil)).Elem(), - "SrPolicyDelReply": reflect.TypeOf((*SrPolicyDelReply)(nil)).Elem(), - "SrPolicyMod": reflect.TypeOf((*SrPolicyMod)(nil)).Elem(), - "SrPolicyModReply": reflect.TypeOf((*SrPolicyModReply)(nil)).Elem(), - "SrSetEncapSource": reflect.TypeOf((*SrSetEncapSource)(nil)).Elem(), - "SrSetEncapSourceReply": reflect.TypeOf((*SrSetEncapSourceReply)(nil)).Elem(), - "SrSteeringAddDel": reflect.TypeOf((*SrSteeringAddDel)(nil)).Elem(), - "SrSteeringAddDelReply": reflect.TypeOf((*SrSteeringAddDelReply)(nil)).Elem(), - "SrSteeringPolDetails": reflect.TypeOf((*SrSteeringPolDetails)(nil)).Elem(), - "SrSteeringPolDump": reflect.TypeOf((*SrSteeringPolDump)(nil)).Elem(), - "Srv6Sid": reflect.TypeOf((*Srv6Sid)(nil)).Elem(), - "Srv6SidList": reflect.TypeOf((*Srv6SidList)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewSrLocalsidAddDel": reflect.ValueOf(NewSrLocalsidAddDel), - "NewSrLocalsidAddDelReply": reflect.ValueOf(NewSrLocalsidAddDelReply), - "NewSrLocalsidsDetails": reflect.ValueOf(NewSrLocalsidsDetails), - "NewSrLocalsidsDump": reflect.ValueOf(NewSrLocalsidsDump), - "NewSrPoliciesDetails": reflect.ValueOf(NewSrPoliciesDetails), - "NewSrPoliciesDump": reflect.ValueOf(NewSrPoliciesDump), - "NewSrPolicyAdd": reflect.ValueOf(NewSrPolicyAdd), - "NewSrPolicyAddReply": reflect.ValueOf(NewSrPolicyAddReply), - "NewSrPolicyDel": reflect.ValueOf(NewSrPolicyDel), - "NewSrPolicyDelReply": reflect.ValueOf(NewSrPolicyDelReply), - "NewSrPolicyMod": reflect.ValueOf(NewSrPolicyMod), - "NewSrPolicyModReply": reflect.ValueOf(NewSrPolicyModReply), - "NewSrSetEncapSource": reflect.ValueOf(NewSrSetEncapSource), - "NewSrSetEncapSourceReply": reflect.ValueOf(NewSrSetEncapSourceReply), - "NewSrSteeringAddDel": reflect.ValueOf(NewSrSteeringAddDel), - "NewSrSteeringAddDelReply": reflect.ValueOf(NewSrSteeringAddDelReply), - "NewSrSteeringPolDetails": reflect.ValueOf(NewSrSteeringPolDetails), - "NewSrSteeringPolDump": reflect.ValueOf(NewSrSteeringPolDump), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/sr/sr.ba.go b/plugins/vpp/binapi/sr/sr.ba.go index 81b4f6c721..26de0c47b9 100644 --- a/plugins/vpp/binapi/sr/sr.ba.go +++ b/plugins/vpp/binapi/sr/sr.ba.go @@ -1,16 +1,14 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/sr.api.json +// source: /usr/share/vpp/api/sr.api.json /* -Package sr is a generated VPP binary API of the 'sr' VPP module. + Package sr is a generated from VPP binary API module 'sr'. -It is generated from this file: - sr.api.json + It contains following objects: + 18 messages + 3 types + 9 services -It contains these VPP binary API objects: - 18 messages - 3 types - 9 services */ package sr @@ -19,13 +17,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Types */ // Srv6Sid represents the VPP binary API type 'srv6_sid'. -// Generated from 'sr.api.json', line 577: // // "srv6_sid", // [ @@ -49,7 +47,6 @@ func (*Srv6Sid) GetCrcString() string { } // Srv6SidList represents the VPP binary API type 'srv6_sid_list'. -// Generated from 'sr.api.json', line 588: // // "srv6_sid_list", // [ @@ -83,7 +80,6 @@ func (*Srv6SidList) GetCrcString() string { } // SrIP6Address represents the VPP binary API type 'sr_ip6_address'. -// Generated from 'sr.api.json', line 607: // // "sr_ip6_address", // [ @@ -109,7 +105,6 @@ func (*SrIP6Address) GetCrcString() string { /* Messages */ // SrLocalsidAddDel represents the VPP binary API message 'sr_localsid_add_del'. -// Generated from 'sr.api.json', line 4: // // "sr_localsid_add_del", // [ @@ -187,12 +182,8 @@ func (*SrLocalsidAddDel) GetCrcString() string { func (*SrLocalsidAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrLocalsidAddDel() api.Message { - return &SrLocalsidAddDel{} -} // SrLocalsidAddDelReply represents the VPP binary API message 'sr_localsid_add_del_reply'. -// Generated from 'sr.api.json', line 60: // // "sr_localsid_add_del_reply", // [ @@ -224,12 +215,8 @@ func (*SrLocalsidAddDelReply) GetCrcString() string { func (*SrLocalsidAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrLocalsidAddDelReply() api.Message { - return &SrLocalsidAddDelReply{} -} // SrPolicyAdd represents the VPP binary API message 'sr_policy_add'. -// Generated from 'sr.api.json', line 78: // // "sr_policy_add", // [ @@ -291,12 +278,8 @@ func (*SrPolicyAdd) GetCrcString() string { func (*SrPolicyAdd) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrPolicyAdd() api.Message { - return &SrPolicyAdd{} -} // SrPolicyAddReply represents the VPP binary API message 'sr_policy_add_reply'. -// Generated from 'sr.api.json', line 121: // // "sr_policy_add_reply", // [ @@ -328,12 +311,8 @@ func (*SrPolicyAddReply) GetCrcString() string { func (*SrPolicyAddReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrPolicyAddReply() api.Message { - return &SrPolicyAddReply{} -} // SrPolicyMod represents the VPP binary API message 'sr_policy_mod'. -// Generated from 'sr.api.json', line 139: // // "sr_policy_mod", // [ @@ -400,12 +379,8 @@ func (*SrPolicyMod) GetCrcString() string { func (*SrPolicyMod) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrPolicyMod() api.Message { - return &SrPolicyMod{} -} // SrPolicyModReply represents the VPP binary API message 'sr_policy_mod_reply'. -// Generated from 'sr.api.json', line 186: // // "sr_policy_mod_reply", // [ @@ -437,12 +412,8 @@ func (*SrPolicyModReply) GetCrcString() string { func (*SrPolicyModReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrPolicyModReply() api.Message { - return &SrPolicyModReply{} -} // SrPolicyDel represents the VPP binary API message 'sr_policy_del'. -// Generated from 'sr.api.json', line 204: // // "sr_policy_del", // [ @@ -483,12 +454,8 @@ func (*SrPolicyDel) GetCrcString() string { func (*SrPolicyDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrPolicyDel() api.Message { - return &SrPolicyDel{} -} // SrPolicyDelReply represents the VPP binary API message 'sr_policy_del_reply'. -// Generated from 'sr.api.json', line 230: // // "sr_policy_del_reply", // [ @@ -520,12 +487,8 @@ func (*SrPolicyDelReply) GetCrcString() string { func (*SrPolicyDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrPolicyDelReply() api.Message { - return &SrPolicyDelReply{} -} // SrSetEncapSource represents the VPP binary API message 'sr_set_encap_source'. -// Generated from 'sr.api.json', line 248: // // "sr_set_encap_source", // [ @@ -562,12 +525,8 @@ func (*SrSetEncapSource) GetCrcString() string { func (*SrSetEncapSource) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrSetEncapSource() api.Message { - return &SrSetEncapSource{} -} // SrSetEncapSourceReply represents the VPP binary API message 'sr_set_encap_source_reply'. -// Generated from 'sr.api.json', line 271: // // "sr_set_encap_source_reply", // [ @@ -599,12 +558,8 @@ func (*SrSetEncapSourceReply) GetCrcString() string { func (*SrSetEncapSourceReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrSetEncapSourceReply() api.Message { - return &SrSetEncapSourceReply{} -} // SrSteeringAddDel represents the VPP binary API message 'sr_steering_add_del'. -// Generated from 'sr.api.json', line 289: // // "sr_steering_add_del", // [ @@ -677,12 +632,8 @@ func (*SrSteeringAddDel) GetCrcString() string { func (*SrSteeringAddDel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrSteeringAddDel() api.Message { - return &SrSteeringAddDel{} -} // SrSteeringAddDelReply represents the VPP binary API message 'sr_steering_add_del_reply'. -// Generated from 'sr.api.json', line 341: // // "sr_steering_add_del_reply", // [ @@ -714,12 +665,8 @@ func (*SrSteeringAddDelReply) GetCrcString() string { func (*SrSteeringAddDelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrSteeringAddDelReply() api.Message { - return &SrSteeringAddDelReply{} -} // SrLocalsidsDump represents the VPP binary API message 'sr_localsids_dump'. -// Generated from 'sr.api.json', line 359: // // "sr_localsids_dump", // [ @@ -749,12 +696,8 @@ func (*SrLocalsidsDump) GetCrcString() string { func (*SrLocalsidsDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrLocalsidsDump() api.Message { - return &SrLocalsidsDump{} -} // SrLocalsidsDetails represents the VPP binary API message 'sr_localsids_details'. -// Generated from 'sr.api.json', line 377: // // "sr_localsids_details", // [ @@ -823,12 +766,8 @@ func (*SrLocalsidsDetails) GetCrcString() string { func (*SrLocalsidsDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrLocalsidsDetails() api.Message { - return &SrLocalsidsDetails{} -} // SrPoliciesDump represents the VPP binary API message 'sr_policies_dump'. -// Generated from 'sr.api.json', line 425: // // "sr_policies_dump", // [ @@ -858,12 +797,8 @@ func (*SrPoliciesDump) GetCrcString() string { func (*SrPoliciesDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrPoliciesDump() api.Message { - return &SrPoliciesDump{} -} // SrPoliciesDetails represents the VPP binary API message 'sr_policies_details'. -// Generated from 'sr.api.json', line 443: // // "sr_policies_details", // [ @@ -922,12 +857,8 @@ func (*SrPoliciesDetails) GetCrcString() string { func (*SrPoliciesDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrPoliciesDetails() api.Message { - return &SrPoliciesDetails{} -} // SrSteeringPolDump represents the VPP binary API message 'sr_steering_pol_dump'. -// Generated from 'sr.api.json', line 483: // // "sr_steering_pol_dump", // [ @@ -957,12 +888,8 @@ func (*SrSteeringPolDump) GetCrcString() string { func (*SrSteeringPolDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSrSteeringPolDump() api.Message { - return &SrSteeringPolDump{} -} // SrSteeringPolDetails represents the VPP binary API message 'sr_steering_pol_details'. -// Generated from 'sr.api.json', line 501: // // "sr_steering_pol_details", // [ @@ -1020,9 +947,6 @@ func (*SrSteeringPolDetails) GetCrcString() string { func (*SrSteeringPolDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSrSteeringPolDetails() api.Message { - return &SrSteeringPolDetails{} -} /* Services */ diff --git a/plugins/vpp/binapi/stats/pkgreflect.go b/plugins/vpp/binapi/stats/pkgreflect.go deleted file mode 100644 index fb15fcdf52..0000000000 --- a/plugins/vpp/binapi/stats/pkgreflect.go +++ /dev/null @@ -1,117 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package stats - -import "reflect" - -var Types = map[string]reflect.Type{ - "BierNeighborCounter": reflect.TypeOf((*BierNeighborCounter)(nil)).Elem(), - "BierTableID": reflect.TypeOf((*BierTableID)(nil)).Elem(), - "FibMplsLabel": reflect.TypeOf((*FibMplsLabel)(nil)).Elem(), - "FibPath": reflect.TypeOf((*FibPath)(nil)).Elem(), - "IP4FibCounter": reflect.TypeOf((*IP4FibCounter)(nil)).Elem(), - "IP4MfibCounter": reflect.TypeOf((*IP4MfibCounter)(nil)).Elem(), - "IP4NbrCounter": reflect.TypeOf((*IP4NbrCounter)(nil)).Elem(), - "IP6FibCounter": reflect.TypeOf((*IP6FibCounter)(nil)).Elem(), - "IP6MfibCounter": reflect.TypeOf((*IP6MfibCounter)(nil)).Elem(), - "IP6NbrCounter": reflect.TypeOf((*IP6NbrCounter)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "StatsGetPollerDelay": reflect.TypeOf((*StatsGetPollerDelay)(nil)).Elem(), - "StatsGetPollerDelayReply": reflect.TypeOf((*StatsGetPollerDelayReply)(nil)).Elem(), - "UDPEncapCounter": reflect.TypeOf((*UDPEncapCounter)(nil)).Elem(), - "VlibCounter": reflect.TypeOf((*VlibCounter)(nil)).Elem(), - "VnetBierNeighborCounters": reflect.TypeOf((*VnetBierNeighborCounters)(nil)).Elem(), - "VnetCombinedCounter": reflect.TypeOf((*VnetCombinedCounter)(nil)).Elem(), - "VnetGetSummaryStats": reflect.TypeOf((*VnetGetSummaryStats)(nil)).Elem(), - "VnetGetSummaryStatsReply": reflect.TypeOf((*VnetGetSummaryStatsReply)(nil)).Elem(), - "VnetIP4FibCounters": reflect.TypeOf((*VnetIP4FibCounters)(nil)).Elem(), - "VnetIP4MfibCounters": reflect.TypeOf((*VnetIP4MfibCounters)(nil)).Elem(), - "VnetIP4NbrCounters": reflect.TypeOf((*VnetIP4NbrCounters)(nil)).Elem(), - "VnetIP6FibCounters": reflect.TypeOf((*VnetIP6FibCounters)(nil)).Elem(), - "VnetIP6MfibCounters": reflect.TypeOf((*VnetIP6MfibCounters)(nil)).Elem(), - "VnetIP6NbrCounters": reflect.TypeOf((*VnetIP6NbrCounters)(nil)).Elem(), - "VnetInterfaceCombinedCounters": reflect.TypeOf((*VnetInterfaceCombinedCounters)(nil)).Elem(), - "VnetInterfaceSimpleCounters": reflect.TypeOf((*VnetInterfaceSimpleCounters)(nil)).Elem(), - "VnetPerInterfaceCombinedCounters": reflect.TypeOf((*VnetPerInterfaceCombinedCounters)(nil)).Elem(), - "VnetPerInterfaceSimpleCounters": reflect.TypeOf((*VnetPerInterfaceSimpleCounters)(nil)).Elem(), - "VnetSimpleCounter": reflect.TypeOf((*VnetSimpleCounter)(nil)).Elem(), - "VnetUDPEncapCounters": reflect.TypeOf((*VnetUDPEncapCounters)(nil)).Elem(), - "WantBierNeighborStats": reflect.TypeOf((*WantBierNeighborStats)(nil)).Elem(), - "WantBierNeighborStatsReply": reflect.TypeOf((*WantBierNeighborStatsReply)(nil)).Elem(), - "WantIP4FibStats": reflect.TypeOf((*WantIP4FibStats)(nil)).Elem(), - "WantIP4FibStatsReply": reflect.TypeOf((*WantIP4FibStatsReply)(nil)).Elem(), - "WantIP4MfibStats": reflect.TypeOf((*WantIP4MfibStats)(nil)).Elem(), - "WantIP4MfibStatsReply": reflect.TypeOf((*WantIP4MfibStatsReply)(nil)).Elem(), - "WantIP4NbrStats": reflect.TypeOf((*WantIP4NbrStats)(nil)).Elem(), - "WantIP4NbrStatsReply": reflect.TypeOf((*WantIP4NbrStatsReply)(nil)).Elem(), - "WantIP6FibStats": reflect.TypeOf((*WantIP6FibStats)(nil)).Elem(), - "WantIP6FibStatsReply": reflect.TypeOf((*WantIP6FibStatsReply)(nil)).Elem(), - "WantIP6MfibStats": reflect.TypeOf((*WantIP6MfibStats)(nil)).Elem(), - "WantIP6MfibStatsReply": reflect.TypeOf((*WantIP6MfibStatsReply)(nil)).Elem(), - "WantIP6NbrStats": reflect.TypeOf((*WantIP6NbrStats)(nil)).Elem(), - "WantIP6NbrStatsReply": reflect.TypeOf((*WantIP6NbrStatsReply)(nil)).Elem(), - "WantInterfaceCombinedStats": reflect.TypeOf((*WantInterfaceCombinedStats)(nil)).Elem(), - "WantInterfaceCombinedStatsReply": reflect.TypeOf((*WantInterfaceCombinedStatsReply)(nil)).Elem(), - "WantInterfaceSimpleStats": reflect.TypeOf((*WantInterfaceSimpleStats)(nil)).Elem(), - "WantInterfaceSimpleStatsReply": reflect.TypeOf((*WantInterfaceSimpleStatsReply)(nil)).Elem(), - "WantPerInterfaceCombinedStats": reflect.TypeOf((*WantPerInterfaceCombinedStats)(nil)).Elem(), - "WantPerInterfaceCombinedStatsReply": reflect.TypeOf((*WantPerInterfaceCombinedStatsReply)(nil)).Elem(), - "WantPerInterfaceSimpleStats": reflect.TypeOf((*WantPerInterfaceSimpleStats)(nil)).Elem(), - "WantPerInterfaceSimpleStatsReply": reflect.TypeOf((*WantPerInterfaceSimpleStatsReply)(nil)).Elem(), - "WantStats": reflect.TypeOf((*WantStats)(nil)).Elem(), - "WantStatsReply": reflect.TypeOf((*WantStatsReply)(nil)).Elem(), - "WantUDPEncapStats": reflect.TypeOf((*WantUDPEncapStats)(nil)).Elem(), - "WantUDPEncapStatsReply": reflect.TypeOf((*WantUDPEncapStatsReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewStatsGetPollerDelay": reflect.ValueOf(NewStatsGetPollerDelay), - "NewStatsGetPollerDelayReply": reflect.ValueOf(NewStatsGetPollerDelayReply), - "NewVnetBierNeighborCounters": reflect.ValueOf(NewVnetBierNeighborCounters), - "NewVnetGetSummaryStats": reflect.ValueOf(NewVnetGetSummaryStats), - "NewVnetGetSummaryStatsReply": reflect.ValueOf(NewVnetGetSummaryStatsReply), - "NewVnetIP4FibCounters": reflect.ValueOf(NewVnetIP4FibCounters), - "NewVnetIP4MfibCounters": reflect.ValueOf(NewVnetIP4MfibCounters), - "NewVnetIP4NbrCounters": reflect.ValueOf(NewVnetIP4NbrCounters), - "NewVnetIP6FibCounters": reflect.ValueOf(NewVnetIP6FibCounters), - "NewVnetIP6MfibCounters": reflect.ValueOf(NewVnetIP6MfibCounters), - "NewVnetIP6NbrCounters": reflect.ValueOf(NewVnetIP6NbrCounters), - "NewVnetInterfaceCombinedCounters": reflect.ValueOf(NewVnetInterfaceCombinedCounters), - "NewVnetInterfaceSimpleCounters": reflect.ValueOf(NewVnetInterfaceSimpleCounters), - "NewVnetPerInterfaceCombinedCounters": reflect.ValueOf(NewVnetPerInterfaceCombinedCounters), - "NewVnetPerInterfaceSimpleCounters": reflect.ValueOf(NewVnetPerInterfaceSimpleCounters), - "NewVnetUDPEncapCounters": reflect.ValueOf(NewVnetUDPEncapCounters), - "NewWantBierNeighborStats": reflect.ValueOf(NewWantBierNeighborStats), - "NewWantBierNeighborStatsReply": reflect.ValueOf(NewWantBierNeighborStatsReply), - "NewWantIP4FibStats": reflect.ValueOf(NewWantIP4FibStats), - "NewWantIP4FibStatsReply": reflect.ValueOf(NewWantIP4FibStatsReply), - "NewWantIP4MfibStats": reflect.ValueOf(NewWantIP4MfibStats), - "NewWantIP4MfibStatsReply": reflect.ValueOf(NewWantIP4MfibStatsReply), - "NewWantIP4NbrStats": reflect.ValueOf(NewWantIP4NbrStats), - "NewWantIP4NbrStatsReply": reflect.ValueOf(NewWantIP4NbrStatsReply), - "NewWantIP6FibStats": reflect.ValueOf(NewWantIP6FibStats), - "NewWantIP6FibStatsReply": reflect.ValueOf(NewWantIP6FibStatsReply), - "NewWantIP6MfibStats": reflect.ValueOf(NewWantIP6MfibStats), - "NewWantIP6MfibStatsReply": reflect.ValueOf(NewWantIP6MfibStatsReply), - "NewWantIP6NbrStats": reflect.ValueOf(NewWantIP6NbrStats), - "NewWantIP6NbrStatsReply": reflect.ValueOf(NewWantIP6NbrStatsReply), - "NewWantInterfaceCombinedStats": reflect.ValueOf(NewWantInterfaceCombinedStats), - "NewWantInterfaceCombinedStatsReply": reflect.ValueOf(NewWantInterfaceCombinedStatsReply), - "NewWantInterfaceSimpleStats": reflect.ValueOf(NewWantInterfaceSimpleStats), - "NewWantInterfaceSimpleStatsReply": reflect.ValueOf(NewWantInterfaceSimpleStatsReply), - "NewWantPerInterfaceCombinedStats": reflect.ValueOf(NewWantPerInterfaceCombinedStats), - "NewWantPerInterfaceCombinedStatsReply": reflect.ValueOf(NewWantPerInterfaceCombinedStatsReply), - "NewWantPerInterfaceSimpleStats": reflect.ValueOf(NewWantPerInterfaceSimpleStats), - "NewWantPerInterfaceSimpleStatsReply": reflect.ValueOf(NewWantPerInterfaceSimpleStatsReply), - "NewWantStats": reflect.ValueOf(NewWantStats), - "NewWantStatsReply": reflect.ValueOf(NewWantStatsReply), - "NewWantUDPEncapStats": reflect.ValueOf(NewWantUDPEncapStats), - "NewWantUDPEncapStatsReply": reflect.ValueOf(NewWantUDPEncapStatsReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/stats/stats.ba.go b/plugins/vpp/binapi/stats/stats.ba.go index 1826493e3c..ba5f8f9add 100644 --- a/plugins/vpp/binapi/stats/stats.ba.go +++ b/plugins/vpp/binapi/stats/stats.ba.go @@ -1,16 +1,14 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/stats.api.json +// source: /usr/share/vpp/api/stats.api.json /* -Package stats is a generated VPP binary API of the 'stats' VPP module. + Package stats is a generated from VPP binary API module 'stats'. -It is generated from this file: - stats.api.json + It contains following objects: + 42 messages + 14 types + 15 services -It contains these VPP binary API objects: - 42 messages - 14 types - 15 services */ package stats @@ -19,13 +17,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Types */ // VlibCounter represents the VPP binary API type 'vlib_counter'. -// Generated from 'stats.api.json', line 1078: // // "vlib_counter", // [ @@ -53,7 +51,6 @@ func (*VlibCounter) GetCrcString() string { } // VnetCombinedCounter represents the VPP binary API type 'vnet_combined_counter'. -// Generated from 'stats.api.json', line 1092: // // "vnet_combined_counter", // [ @@ -156,7 +153,6 @@ func (*VnetCombinedCounter) GetCrcString() string { } // VnetSimpleCounter represents the VPP binary API type 'vnet_simple_counter'. -// Generated from 'stats.api.json', line 1166: // // "vnet_simple_counter", // [ @@ -224,7 +220,6 @@ func (*VnetSimpleCounter) GetCrcString() string { } // FibMplsLabel represents the VPP binary API type 'fib_mpls_label'. -// Generated from 'stats.api.json', line 1212: // // "fib_mpls_label", // [ @@ -262,7 +257,6 @@ func (*FibMplsLabel) GetCrcString() string { } // FibPath represents the VPP binary API type 'fib_path'. -// Generated from 'stats.api.json', line 1234: // // "fib_path", // [ @@ -382,7 +376,6 @@ func (*FibPath) GetCrcString() string { } // BierTableID represents the VPP binary API type 'bier_table_id'. -// Generated from 'stats.api.json', line 1322: // // "bier_table_id", // [ @@ -415,7 +408,6 @@ func (*BierTableID) GetCrcString() string { } // IP4FibCounter represents the VPP binary API type 'ip4_fib_counter'. -// Generated from 'stats.api.json', line 1340: // // "ip4_fib_counter", // [ @@ -453,7 +445,6 @@ func (*IP4FibCounter) GetCrcString() string { } // IP4MfibCounter represents the VPP binary API type 'ip4_mfib_counter'. -// Generated from 'stats.api.json', line 1362: // // "ip4_mfib_counter", // [ @@ -498,7 +489,6 @@ func (*IP4MfibCounter) GetCrcString() string { } // IP4NbrCounter represents the VPP binary API type 'ip4_nbr_counter'. -// Generated from 'stats.api.json', line 1390: // // "ip4_nbr_counter", // [ @@ -536,7 +526,6 @@ func (*IP4NbrCounter) GetCrcString() string { } // IP6FibCounter represents the VPP binary API type 'ip6_fib_counter'. -// Generated from 'stats.api.json', line 1412: // // "ip6_fib_counter", // [ @@ -575,7 +564,6 @@ func (*IP6FibCounter) GetCrcString() string { } // IP6MfibCounter represents the VPP binary API type 'ip6_mfib_counter'. -// Generated from 'stats.api.json', line 1435: // // "ip6_mfib_counter", // [ @@ -620,7 +608,6 @@ func (*IP6MfibCounter) GetCrcString() string { } // IP6NbrCounter represents the VPP binary API type 'ip6_nbr_counter'. -// Generated from 'stats.api.json', line 1463: // // "ip6_nbr_counter", // [ @@ -659,7 +646,6 @@ func (*IP6NbrCounter) GetCrcString() string { } // UDPEncapCounter represents the VPP binary API type 'udp_encap_counter'. -// Generated from 'stats.api.json', line 1486: // // "udp_encap_counter", // [ @@ -692,7 +678,6 @@ func (*UDPEncapCounter) GetCrcString() string { } // BierNeighborCounter represents the VPP binary API type 'bier_neighbor_counter'. -// Generated from 'stats.api.json', line 1504: // // "bier_neighbor_counter", // [ @@ -732,7 +717,6 @@ func (*BierNeighborCounter) GetCrcString() string { /* Messages */ // WantStats represents the VPP binary API message 'want_stats'. -// Generated from 'stats.api.json', line 4: // // "want_stats", // [ @@ -773,12 +757,8 @@ func (*WantStats) GetCrcString() string { func (*WantStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantStats() api.Message { - return &WantStats{} -} // WantStatsReply represents the VPP binary API message 'want_stats_reply'. -// Generated from 'stats.api.json', line 30: // // "want_stats_reply", // [ @@ -810,12 +790,8 @@ func (*WantStatsReply) GetCrcString() string { func (*WantStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantStatsReply() api.Message { - return &WantStatsReply{} -} // WantInterfaceSimpleStats represents the VPP binary API message 'want_interface_simple_stats'. -// Generated from 'stats.api.json', line 48: // // "want_interface_simple_stats", // [ @@ -856,12 +832,8 @@ func (*WantInterfaceSimpleStats) GetCrcString() string { func (*WantInterfaceSimpleStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantInterfaceSimpleStats() api.Message { - return &WantInterfaceSimpleStats{} -} // WantInterfaceSimpleStatsReply represents the VPP binary API message 'want_interface_simple_stats_reply'. -// Generated from 'stats.api.json', line 74: // // "want_interface_simple_stats_reply", // [ @@ -893,12 +865,8 @@ func (*WantInterfaceSimpleStatsReply) GetCrcString() string { func (*WantInterfaceSimpleStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantInterfaceSimpleStatsReply() api.Message { - return &WantInterfaceSimpleStatsReply{} -} // WantPerInterfaceSimpleStats represents the VPP binary API message 'want_per_interface_simple_stats'. -// Generated from 'stats.api.json', line 92: // // "want_per_interface_simple_stats", // [ @@ -951,12 +919,8 @@ func (*WantPerInterfaceSimpleStats) GetCrcString() string { func (*WantPerInterfaceSimpleStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantPerInterfaceSimpleStats() api.Message { - return &WantPerInterfaceSimpleStats{} -} // WantPerInterfaceSimpleStatsReply represents the VPP binary API message 'want_per_interface_simple_stats_reply'. -// Generated from 'stats.api.json', line 128: // // "want_per_interface_simple_stats_reply", // [ @@ -988,12 +952,8 @@ func (*WantPerInterfaceSimpleStatsReply) GetCrcString() string { func (*WantPerInterfaceSimpleStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantPerInterfaceSimpleStatsReply() api.Message { - return &WantPerInterfaceSimpleStatsReply{} -} // WantInterfaceCombinedStats represents the VPP binary API message 'want_interface_combined_stats'. -// Generated from 'stats.api.json', line 146: // // "want_interface_combined_stats", // [ @@ -1034,12 +994,8 @@ func (*WantInterfaceCombinedStats) GetCrcString() string { func (*WantInterfaceCombinedStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantInterfaceCombinedStats() api.Message { - return &WantInterfaceCombinedStats{} -} // WantInterfaceCombinedStatsReply represents the VPP binary API message 'want_interface_combined_stats_reply'. -// Generated from 'stats.api.json', line 172: // // "want_interface_combined_stats_reply", // [ @@ -1071,12 +1027,8 @@ func (*WantInterfaceCombinedStatsReply) GetCrcString() string { func (*WantInterfaceCombinedStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantInterfaceCombinedStatsReply() api.Message { - return &WantInterfaceCombinedStatsReply{} -} // WantPerInterfaceCombinedStats represents the VPP binary API message 'want_per_interface_combined_stats'. -// Generated from 'stats.api.json', line 190: // // "want_per_interface_combined_stats", // [ @@ -1129,12 +1081,8 @@ func (*WantPerInterfaceCombinedStats) GetCrcString() string { func (*WantPerInterfaceCombinedStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantPerInterfaceCombinedStats() api.Message { - return &WantPerInterfaceCombinedStats{} -} // WantPerInterfaceCombinedStatsReply represents the VPP binary API message 'want_per_interface_combined_stats_reply'. -// Generated from 'stats.api.json', line 226: // // "want_per_interface_combined_stats_reply", // [ @@ -1166,12 +1114,8 @@ func (*WantPerInterfaceCombinedStatsReply) GetCrcString() string { func (*WantPerInterfaceCombinedStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantPerInterfaceCombinedStatsReply() api.Message { - return &WantPerInterfaceCombinedStatsReply{} -} // WantIP4FibStats represents the VPP binary API message 'want_ip4_fib_stats'. -// Generated from 'stats.api.json', line 244: // // "want_ip4_fib_stats", // [ @@ -1212,12 +1156,8 @@ func (*WantIP4FibStats) GetCrcString() string { func (*WantIP4FibStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP4FibStats() api.Message { - return &WantIP4FibStats{} -} // WantIP4FibStatsReply represents the VPP binary API message 'want_ip4_fib_stats_reply'. -// Generated from 'stats.api.json', line 270: // // "want_ip4_fib_stats_reply", // [ @@ -1249,12 +1189,8 @@ func (*WantIP4FibStatsReply) GetCrcString() string { func (*WantIP4FibStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP4FibStatsReply() api.Message { - return &WantIP4FibStatsReply{} -} // WantIP6FibStats represents the VPP binary API message 'want_ip6_fib_stats'. -// Generated from 'stats.api.json', line 288: // // "want_ip6_fib_stats", // [ @@ -1295,12 +1231,8 @@ func (*WantIP6FibStats) GetCrcString() string { func (*WantIP6FibStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP6FibStats() api.Message { - return &WantIP6FibStats{} -} // WantIP6FibStatsReply represents the VPP binary API message 'want_ip6_fib_stats_reply'. -// Generated from 'stats.api.json', line 314: // // "want_ip6_fib_stats_reply", // [ @@ -1332,12 +1264,8 @@ func (*WantIP6FibStatsReply) GetCrcString() string { func (*WantIP6FibStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP6FibStatsReply() api.Message { - return &WantIP6FibStatsReply{} -} // WantIP4MfibStats represents the VPP binary API message 'want_ip4_mfib_stats'. -// Generated from 'stats.api.json', line 332: // // "want_ip4_mfib_stats", // [ @@ -1378,12 +1306,8 @@ func (*WantIP4MfibStats) GetCrcString() string { func (*WantIP4MfibStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP4MfibStats() api.Message { - return &WantIP4MfibStats{} -} // WantIP4MfibStatsReply represents the VPP binary API message 'want_ip4_mfib_stats_reply'. -// Generated from 'stats.api.json', line 358: // // "want_ip4_mfib_stats_reply", // [ @@ -1415,12 +1339,8 @@ func (*WantIP4MfibStatsReply) GetCrcString() string { func (*WantIP4MfibStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP4MfibStatsReply() api.Message { - return &WantIP4MfibStatsReply{} -} // WantIP6MfibStats represents the VPP binary API message 'want_ip6_mfib_stats'. -// Generated from 'stats.api.json', line 376: // // "want_ip6_mfib_stats", // [ @@ -1461,12 +1381,8 @@ func (*WantIP6MfibStats) GetCrcString() string { func (*WantIP6MfibStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP6MfibStats() api.Message { - return &WantIP6MfibStats{} -} // WantIP6MfibStatsReply represents the VPP binary API message 'want_ip6_mfib_stats_reply'. -// Generated from 'stats.api.json', line 402: // // "want_ip6_mfib_stats_reply", // [ @@ -1498,12 +1414,8 @@ func (*WantIP6MfibStatsReply) GetCrcString() string { func (*WantIP6MfibStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP6MfibStatsReply() api.Message { - return &WantIP6MfibStatsReply{} -} // WantIP4NbrStats represents the VPP binary API message 'want_ip4_nbr_stats'. -// Generated from 'stats.api.json', line 420: // // "want_ip4_nbr_stats", // [ @@ -1544,12 +1456,8 @@ func (*WantIP4NbrStats) GetCrcString() string { func (*WantIP4NbrStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP4NbrStats() api.Message { - return &WantIP4NbrStats{} -} // WantIP4NbrStatsReply represents the VPP binary API message 'want_ip4_nbr_stats_reply'. -// Generated from 'stats.api.json', line 446: // // "want_ip4_nbr_stats_reply", // [ @@ -1581,12 +1489,8 @@ func (*WantIP4NbrStatsReply) GetCrcString() string { func (*WantIP4NbrStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP4NbrStatsReply() api.Message { - return &WantIP4NbrStatsReply{} -} // WantIP6NbrStats represents the VPP binary API message 'want_ip6_nbr_stats'. -// Generated from 'stats.api.json', line 464: // // "want_ip6_nbr_stats", // [ @@ -1627,12 +1531,8 @@ func (*WantIP6NbrStats) GetCrcString() string { func (*WantIP6NbrStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantIP6NbrStats() api.Message { - return &WantIP6NbrStats{} -} // WantIP6NbrStatsReply represents the VPP binary API message 'want_ip6_nbr_stats_reply'. -// Generated from 'stats.api.json', line 490: // // "want_ip6_nbr_stats_reply", // [ @@ -1664,12 +1564,8 @@ func (*WantIP6NbrStatsReply) GetCrcString() string { func (*WantIP6NbrStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantIP6NbrStatsReply() api.Message { - return &WantIP6NbrStatsReply{} -} // VnetIP4FibCounters represents the VPP binary API message 'vnet_ip4_fib_counters'. -// Generated from 'stats.api.json', line 508: // // "vnet_ip4_fib_counters", // [ @@ -1709,12 +1605,8 @@ func (*VnetIP4FibCounters) GetCrcString() string { func (*VnetIP4FibCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetIP4FibCounters() api.Message { - return &VnetIP4FibCounters{} -} // VnetIP4MfibCounters represents the VPP binary API message 'vnet_ip4_mfib_counters'. -// Generated from 'stats.api.json', line 532: // // "vnet_ip4_mfib_counters", // [ @@ -1754,12 +1646,8 @@ func (*VnetIP4MfibCounters) GetCrcString() string { func (*VnetIP4MfibCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetIP4MfibCounters() api.Message { - return &VnetIP4MfibCounters{} -} // VnetIP4NbrCounters represents the VPP binary API message 'vnet_ip4_nbr_counters'. -// Generated from 'stats.api.json', line 556: // // "vnet_ip4_nbr_counters", // [ @@ -1804,12 +1692,8 @@ func (*VnetIP4NbrCounters) GetCrcString() string { func (*VnetIP4NbrCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetIP4NbrCounters() api.Message { - return &VnetIP4NbrCounters{} -} // VnetIP6FibCounters represents the VPP binary API message 'vnet_ip6_fib_counters'. -// Generated from 'stats.api.json', line 584: // // "vnet_ip6_fib_counters", // [ @@ -1849,12 +1733,8 @@ func (*VnetIP6FibCounters) GetCrcString() string { func (*VnetIP6FibCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetIP6FibCounters() api.Message { - return &VnetIP6FibCounters{} -} // VnetIP6MfibCounters represents the VPP binary API message 'vnet_ip6_mfib_counters'. -// Generated from 'stats.api.json', line 608: // // "vnet_ip6_mfib_counters", // [ @@ -1894,12 +1774,8 @@ func (*VnetIP6MfibCounters) GetCrcString() string { func (*VnetIP6MfibCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetIP6MfibCounters() api.Message { - return &VnetIP6MfibCounters{} -} // VnetIP6NbrCounters represents the VPP binary API message 'vnet_ip6_nbr_counters'. -// Generated from 'stats.api.json', line 632: // // "vnet_ip6_nbr_counters", // [ @@ -1944,12 +1820,8 @@ func (*VnetIP6NbrCounters) GetCrcString() string { func (*VnetIP6NbrCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetIP6NbrCounters() api.Message { - return &VnetIP6NbrCounters{} -} // VnetInterfaceSimpleCounters represents the VPP binary API message 'vnet_interface_simple_counters'. -// Generated from 'stats.api.json', line 660: // // "vnet_interface_simple_counters", // [ @@ -1994,12 +1866,8 @@ func (*VnetInterfaceSimpleCounters) GetCrcString() string { func (*VnetInterfaceSimpleCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetInterfaceSimpleCounters() api.Message { - return &VnetInterfaceSimpleCounters{} -} // VnetInterfaceCombinedCounters represents the VPP binary API message 'vnet_interface_combined_counters'. -// Generated from 'stats.api.json', line 688: // // "vnet_interface_combined_counters", // [ @@ -2044,12 +1912,8 @@ func (*VnetInterfaceCombinedCounters) GetCrcString() string { func (*VnetInterfaceCombinedCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetInterfaceCombinedCounters() api.Message { - return &VnetInterfaceCombinedCounters{} -} // VnetPerInterfaceSimpleCounters represents the VPP binary API message 'vnet_per_interface_simple_counters'. -// Generated from 'stats.api.json', line 716: // // "vnet_per_interface_simple_counters", // [ @@ -2089,12 +1953,8 @@ func (*VnetPerInterfaceSimpleCounters) GetCrcString() string { func (*VnetPerInterfaceSimpleCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetPerInterfaceSimpleCounters() api.Message { - return &VnetPerInterfaceSimpleCounters{} -} // VnetPerInterfaceCombinedCounters represents the VPP binary API message 'vnet_per_interface_combined_counters'. -// Generated from 'stats.api.json', line 740: // // "vnet_per_interface_combined_counters", // [ @@ -2134,12 +1994,8 @@ func (*VnetPerInterfaceCombinedCounters) GetCrcString() string { func (*VnetPerInterfaceCombinedCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetPerInterfaceCombinedCounters() api.Message { - return &VnetPerInterfaceCombinedCounters{} -} // VnetGetSummaryStats represents the VPP binary API message 'vnet_get_summary_stats'. -// Generated from 'stats.api.json', line 764: // // "vnet_get_summary_stats", // [ @@ -2169,12 +2025,8 @@ func (*VnetGetSummaryStats) GetCrcString() string { func (*VnetGetSummaryStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewVnetGetSummaryStats() api.Message { - return &VnetGetSummaryStats{} -} // VnetGetSummaryStatsReply represents the VPP binary API message 'vnet_get_summary_stats_reply'. -// Generated from 'stats.api.json', line 782: // // "vnet_get_summary_stats_reply", // [ @@ -2223,12 +2075,8 @@ func (*VnetGetSummaryStatsReply) GetCrcString() string { func (*VnetGetSummaryStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewVnetGetSummaryStatsReply() api.Message { - return &VnetGetSummaryStatsReply{} -} // StatsGetPollerDelay represents the VPP binary API message 'stats_get_poller_delay'. -// Generated from 'stats.api.json', line 814: // // "stats_get_poller_delay", // [ @@ -2258,12 +2106,8 @@ func (*StatsGetPollerDelay) GetCrcString() string { func (*StatsGetPollerDelay) GetMessageType() api.MessageType { return api.RequestMessage } -func NewStatsGetPollerDelay() api.Message { - return &StatsGetPollerDelay{} -} // StatsGetPollerDelayReply represents the VPP binary API message 'stats_get_poller_delay_reply'. -// Generated from 'stats.api.json', line 832: // // "stats_get_poller_delay_reply", // [ @@ -2300,12 +2144,8 @@ func (*StatsGetPollerDelayReply) GetCrcString() string { func (*StatsGetPollerDelayReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewStatsGetPollerDelayReply() api.Message { - return &StatsGetPollerDelayReply{} -} // WantUDPEncapStats represents the VPP binary API message 'want_udp_encap_stats'. -// Generated from 'stats.api.json', line 854: // // "want_udp_encap_stats", // [ @@ -2346,12 +2186,8 @@ func (*WantUDPEncapStats) GetCrcString() string { func (*WantUDPEncapStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantUDPEncapStats() api.Message { - return &WantUDPEncapStats{} -} // WantUDPEncapStatsReply represents the VPP binary API message 'want_udp_encap_stats_reply'. -// Generated from 'stats.api.json', line 880: // // "want_udp_encap_stats_reply", // [ @@ -2383,12 +2219,8 @@ func (*WantUDPEncapStatsReply) GetCrcString() string { func (*WantUDPEncapStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantUDPEncapStatsReply() api.Message { - return &WantUDPEncapStatsReply{} -} // VnetUDPEncapCounters represents the VPP binary API message 'vnet_udp_encap_counters'. -// Generated from 'stats.api.json', line 898: // // "vnet_udp_encap_counters", // [ @@ -2428,12 +2260,8 @@ func (*VnetUDPEncapCounters) GetCrcString() string { func (*VnetUDPEncapCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetUDPEncapCounters() api.Message { - return &VnetUDPEncapCounters{} -} // WantBierNeighborStats represents the VPP binary API message 'want_bier_neighbor_stats'. -// Generated from 'stats.api.json', line 922: // // "want_bier_neighbor_stats", // [ @@ -2474,12 +2302,8 @@ func (*WantBierNeighborStats) GetCrcString() string { func (*WantBierNeighborStats) GetMessageType() api.MessageType { return api.RequestMessage } -func NewWantBierNeighborStats() api.Message { - return &WantBierNeighborStats{} -} // WantBierNeighborStatsReply represents the VPP binary API message 'want_bier_neighbor_stats_reply'. -// Generated from 'stats.api.json', line 948: // // "want_bier_neighbor_stats_reply", // [ @@ -2511,12 +2335,8 @@ func (*WantBierNeighborStatsReply) GetCrcString() string { func (*WantBierNeighborStatsReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewWantBierNeighborStatsReply() api.Message { - return &WantBierNeighborStatsReply{} -} // VnetBierNeighborCounters represents the VPP binary API message 'vnet_bier_neighbor_counters'. -// Generated from 'stats.api.json', line 966: // // "vnet_bier_neighbor_counters", // [ @@ -2556,9 +2376,6 @@ func (*VnetBierNeighborCounters) GetCrcString() string { func (*VnetBierNeighborCounters) GetMessageType() api.MessageType { return api.OtherMessage } -func NewVnetBierNeighborCounters() api.Message { - return &VnetBierNeighborCounters{} -} /* Services */ diff --git a/plugins/vpp/binapi/stn/pkgreflect.go b/plugins/vpp/binapi/stn/pkgreflect.go deleted file mode 100644 index ce596e1ca6..0000000000 --- a/plugins/vpp/binapi/stn/pkgreflect.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package stn - -import "reflect" - -var Types = map[string]reflect.Type{ - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "StnAddDelRule": reflect.TypeOf((*StnAddDelRule)(nil)).Elem(), - "StnAddDelRuleReply": reflect.TypeOf((*StnAddDelRuleReply)(nil)).Elem(), - "StnRulesDetails": reflect.TypeOf((*StnRulesDetails)(nil)).Elem(), - "StnRulesDump": reflect.TypeOf((*StnRulesDump)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewStnAddDelRule": reflect.ValueOf(NewStnAddDelRule), - "NewStnAddDelRuleReply": reflect.ValueOf(NewStnAddDelRuleReply), - "NewStnRulesDetails": reflect.ValueOf(NewStnRulesDetails), - "NewStnRulesDump": reflect.ValueOf(NewStnRulesDump), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/stn/stn.ba.go b/plugins/vpp/binapi/stn/stn.ba.go index 7e2ea8cc07..7ba4def8ad 100644 --- a/plugins/vpp/binapi/stn/stn.ba.go +++ b/plugins/vpp/binapi/stn/stn.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/stn.api.json +// source: /usr/share/vpp/api/stn.api.json /* -Package stn is a generated VPP binary API of the 'stn' VPP module. + Package stn is a generated from VPP binary API module 'stn'. -It is generated from this file: - stn.api.json + It contains following objects: + 4 messages + 2 services -It contains these VPP binary API objects: - 4 messages - 2 services */ package stn @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // StnAddDelRule represents the VPP binary API message 'stn_add_del_rule'. -// Generated from 'stn.api.json', line 4: // // "stn_add_del_rule", // [ @@ -76,12 +74,8 @@ func (*StnAddDelRule) GetCrcString() string { func (*StnAddDelRule) GetMessageType() api.MessageType { return api.RequestMessage } -func NewStnAddDelRule() api.Message { - return &StnAddDelRule{} -} // StnAddDelRuleReply represents the VPP binary API message 'stn_add_del_rule_reply'. -// Generated from 'stn.api.json', line 39: // // "stn_add_del_rule_reply", // [ @@ -113,12 +107,8 @@ func (*StnAddDelRuleReply) GetCrcString() string { func (*StnAddDelRuleReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewStnAddDelRuleReply() api.Message { - return &StnAddDelRuleReply{} -} // StnRulesDump represents the VPP binary API message 'stn_rules_dump'. -// Generated from 'stn.api.json', line 57: // // "stn_rules_dump", // [ @@ -148,12 +138,8 @@ func (*StnRulesDump) GetCrcString() string { func (*StnRulesDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewStnRulesDump() api.Message { - return &StnRulesDump{} -} // StnRulesDetails represents the VPP binary API message 'stn_rules_details'. -// Generated from 'stn.api.json', line 75: // // "stn_rules_details", // [ @@ -196,9 +182,6 @@ func (*StnRulesDetails) GetCrcString() string { func (*StnRulesDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewStnRulesDetails() api.Message { - return &StnRulesDetails{} -} /* Services */ diff --git a/plugins/vpp/binapi/tap/pkgreflect.go b/plugins/vpp/binapi/tap/pkgreflect.go deleted file mode 100644 index 7843f9f934..0000000000 --- a/plugins/vpp/binapi/tap/pkgreflect.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package tap - -import "reflect" - -var Types = map[string]reflect.Type{ - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SwInterfaceTapDetails": reflect.TypeOf((*SwInterfaceTapDetails)(nil)).Elem(), - "SwInterfaceTapDump": reflect.TypeOf((*SwInterfaceTapDump)(nil)).Elem(), - "TapConnect": reflect.TypeOf((*TapConnect)(nil)).Elem(), - "TapConnectReply": reflect.TypeOf((*TapConnectReply)(nil)).Elem(), - "TapDelete": reflect.TypeOf((*TapDelete)(nil)).Elem(), - "TapDeleteReply": reflect.TypeOf((*TapDeleteReply)(nil)).Elem(), - "TapModify": reflect.TypeOf((*TapModify)(nil)).Elem(), - "TapModifyReply": reflect.TypeOf((*TapModifyReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewSwInterfaceTapDetails": reflect.ValueOf(NewSwInterfaceTapDetails), - "NewSwInterfaceTapDump": reflect.ValueOf(NewSwInterfaceTapDump), - "NewTapConnect": reflect.ValueOf(NewTapConnect), - "NewTapConnectReply": reflect.ValueOf(NewTapConnectReply), - "NewTapDelete": reflect.ValueOf(NewTapDelete), - "NewTapDeleteReply": reflect.ValueOf(NewTapDeleteReply), - "NewTapModify": reflect.ValueOf(NewTapModify), - "NewTapModifyReply": reflect.ValueOf(NewTapModifyReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/tap/tap.ba.go b/plugins/vpp/binapi/tap/tap.ba.go index 17c344eb81..6cde3f159c 100644 --- a/plugins/vpp/binapi/tap/tap.ba.go +++ b/plugins/vpp/binapi/tap/tap.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/tap.api.json +// source: /usr/share/vpp/api/tap.api.json /* -Package tap is a generated VPP binary API of the 'tap' VPP module. + Package tap is a generated from VPP binary API module 'tap'. -It is generated from this file: - tap.api.json + It contains following objects: + 8 messages + 4 services -It contains these VPP binary API objects: - 8 messages - 4 services */ package tap @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // TapConnect represents the VPP binary API message 'tap_connect'. -// Generated from 'tap.api.json', line 4: // // "tap_connect", // [ @@ -120,12 +118,8 @@ func (*TapConnect) GetCrcString() string { func (*TapConnect) GetMessageType() api.MessageType { return api.RequestMessage } -func NewTapConnect() api.Message { - return &TapConnect{} -} // TapConnectReply represents the VPP binary API message 'tap_connect_reply'. -// Generated from 'tap.api.json', line 75: // // "tap_connect_reply", // [ @@ -162,12 +156,8 @@ func (*TapConnectReply) GetCrcString() string { func (*TapConnectReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewTapConnectReply() api.Message { - return &TapConnectReply{} -} // TapModify represents the VPP binary API message 'tap_modify'. -// Generated from 'tap.api.json', line 97: // // "tap_modify", // [ @@ -230,12 +220,8 @@ func (*TapModify) GetCrcString() string { func (*TapModify) GetMessageType() api.MessageType { return api.RequestMessage } -func NewTapModify() api.Message { - return &TapModify{} -} // TapModifyReply represents the VPP binary API message 'tap_modify_reply'. -// Generated from 'tap.api.json', line 141: // // "tap_modify_reply", // [ @@ -272,12 +258,8 @@ func (*TapModifyReply) GetCrcString() string { func (*TapModifyReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewTapModifyReply() api.Message { - return &TapModifyReply{} -} // TapDelete represents the VPP binary API message 'tap_delete'. -// Generated from 'tap.api.json', line 163: // // "tap_delete", // [ @@ -313,12 +295,8 @@ func (*TapDelete) GetCrcString() string { func (*TapDelete) GetMessageType() api.MessageType { return api.RequestMessage } -func NewTapDelete() api.Message { - return &TapDelete{} -} // TapDeleteReply represents the VPP binary API message 'tap_delete_reply'. -// Generated from 'tap.api.json', line 185: // // "tap_delete_reply", // [ @@ -350,12 +328,8 @@ func (*TapDeleteReply) GetCrcString() string { func (*TapDeleteReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewTapDeleteReply() api.Message { - return &TapDeleteReply{} -} // SwInterfaceTapDump represents the VPP binary API message 'sw_interface_tap_dump'. -// Generated from 'tap.api.json', line 203: // // "sw_interface_tap_dump", // [ @@ -385,12 +359,8 @@ func (*SwInterfaceTapDump) GetCrcString() string { func (*SwInterfaceTapDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceTapDump() api.Message { - return &SwInterfaceTapDump{} -} // SwInterfaceTapDetails represents the VPP binary API message 'sw_interface_tap_details'. -// Generated from 'tap.api.json', line 221: // // "sw_interface_tap_details", // [ @@ -428,9 +398,6 @@ func (*SwInterfaceTapDetails) GetCrcString() string { func (*SwInterfaceTapDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceTapDetails() api.Message { - return &SwInterfaceTapDetails{} -} /* Services */ diff --git a/plugins/vpp/binapi/tapv2/pkgreflect.go b/plugins/vpp/binapi/tapv2/pkgreflect.go deleted file mode 100644 index d1bc760e37..0000000000 --- a/plugins/vpp/binapi/tapv2/pkgreflect.go +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package tapv2 - -import "reflect" - -var Types = map[string]reflect.Type{ - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SwInterfaceTapV2Details": reflect.TypeOf((*SwInterfaceTapV2Details)(nil)).Elem(), - "SwInterfaceTapV2Dump": reflect.TypeOf((*SwInterfaceTapV2Dump)(nil)).Elem(), - "TapCreateV2": reflect.TypeOf((*TapCreateV2)(nil)).Elem(), - "TapCreateV2Reply": reflect.TypeOf((*TapCreateV2Reply)(nil)).Elem(), - "TapDeleteV2": reflect.TypeOf((*TapDeleteV2)(nil)).Elem(), - "TapDeleteV2Reply": reflect.TypeOf((*TapDeleteV2Reply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewSwInterfaceTapV2Details": reflect.ValueOf(NewSwInterfaceTapV2Details), - "NewSwInterfaceTapV2Dump": reflect.ValueOf(NewSwInterfaceTapV2Dump), - "NewTapCreateV2": reflect.ValueOf(NewTapCreateV2), - "NewTapCreateV2Reply": reflect.ValueOf(NewTapCreateV2Reply), - "NewTapDeleteV2": reflect.ValueOf(NewTapDeleteV2), - "NewTapDeleteV2Reply": reflect.ValueOf(NewTapDeleteV2Reply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/tapv2/tapv2.ba.go b/plugins/vpp/binapi/tapv2/tapv2.ba.go index 4da3ae2d26..9d03d0653b 100644 --- a/plugins/vpp/binapi/tapv2/tapv2.ba.go +++ b/plugins/vpp/binapi/tapv2/tapv2.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/tapv2.api.json +// source: /usr/share/vpp/api/tapv2.api.json /* -Package tapv2 is a generated VPP binary API of the 'tapv2' VPP module. + Package tapv2 is a generated from VPP binary API module 'tapv2'. -It is generated from this file: - tapv2.api.json + It contains following objects: + 6 messages + 3 services -It contains these VPP binary API objects: - 6 messages - 3 services */ package tapv2 @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // TapCreateV2 represents the VPP binary API message 'tap_create_v2'. -// Generated from 'tapv2.api.json', line 4: // // "tap_create_v2", // [ @@ -185,12 +183,8 @@ func (*TapCreateV2) GetCrcString() string { func (*TapCreateV2) GetMessageType() api.MessageType { return api.RequestMessage } -func NewTapCreateV2() api.Message { - return &TapCreateV2{} -} // TapCreateV2Reply represents the VPP binary API message 'tap_create_v2_reply'. -// Generated from 'tapv2.api.json', line 128: // // "tap_create_v2_reply", // [ @@ -227,12 +221,8 @@ func (*TapCreateV2Reply) GetCrcString() string { func (*TapCreateV2Reply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewTapCreateV2Reply() api.Message { - return &TapCreateV2Reply{} -} // TapDeleteV2 represents the VPP binary API message 'tap_delete_v2'. -// Generated from 'tapv2.api.json', line 150: // // "tap_delete_v2", // [ @@ -268,12 +258,8 @@ func (*TapDeleteV2) GetCrcString() string { func (*TapDeleteV2) GetMessageType() api.MessageType { return api.RequestMessage } -func NewTapDeleteV2() api.Message { - return &TapDeleteV2{} -} // TapDeleteV2Reply represents the VPP binary API message 'tap_delete_v2_reply'. -// Generated from 'tapv2.api.json', line 172: // // "tap_delete_v2_reply", // [ @@ -305,12 +291,8 @@ func (*TapDeleteV2Reply) GetCrcString() string { func (*TapDeleteV2Reply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewTapDeleteV2Reply() api.Message { - return &TapDeleteV2Reply{} -} // SwInterfaceTapV2Dump represents the VPP binary API message 'sw_interface_tap_v2_dump'. -// Generated from 'tapv2.api.json', line 190: // // "sw_interface_tap_v2_dump", // [ @@ -340,12 +322,8 @@ func (*SwInterfaceTapV2Dump) GetCrcString() string { func (*SwInterfaceTapV2Dump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceTapV2Dump() api.Message { - return &SwInterfaceTapV2Dump{} -} // SwInterfaceTapV2Details represents the VPP binary API message 'sw_interface_tap_v2_details'. -// Generated from 'tapv2.api.json', line 208: // // "sw_interface_tap_v2_details", // [ @@ -444,9 +422,6 @@ func (*SwInterfaceTapV2Details) GetCrcString() string { func (*SwInterfaceTapV2Details) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceTapV2Details() api.Message { - return &SwInterfaceTapV2Details{} -} /* Services */ diff --git a/plugins/vpp/binapi/vpe/pkgreflect.go b/plugins/vpp/binapi/vpe/pkgreflect.go deleted file mode 100644 index 4058c07b90..0000000000 --- a/plugins/vpp/binapi/vpe/pkgreflect.go +++ /dev/null @@ -1,51 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package vpe - -import "reflect" - -var Types = map[string]reflect.Type{ - "AddNodeNext": reflect.TypeOf((*AddNodeNext)(nil)).Elem(), - "AddNodeNextReply": reflect.TypeOf((*AddNodeNextReply)(nil)).Elem(), - "Cli": reflect.TypeOf((*Cli)(nil)).Elem(), - "CliInband": reflect.TypeOf((*CliInband)(nil)).Elem(), - "CliInbandReply": reflect.TypeOf((*CliInbandReply)(nil)).Elem(), - "CliReply": reflect.TypeOf((*CliReply)(nil)).Elem(), - "ControlPing": reflect.TypeOf((*ControlPing)(nil)).Elem(), - "ControlPingReply": reflect.TypeOf((*ControlPingReply)(nil)).Elem(), - "GetNextIndex": reflect.TypeOf((*GetNextIndex)(nil)).Elem(), - "GetNextIndexReply": reflect.TypeOf((*GetNextIndexReply)(nil)).Elem(), - "GetNodeGraph": reflect.TypeOf((*GetNodeGraph)(nil)).Elem(), - "GetNodeGraphReply": reflect.TypeOf((*GetNodeGraphReply)(nil)).Elem(), - "GetNodeIndex": reflect.TypeOf((*GetNodeIndex)(nil)).Elem(), - "GetNodeIndexReply": reflect.TypeOf((*GetNodeIndexReply)(nil)).Elem(), - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "ShowVersion": reflect.TypeOf((*ShowVersion)(nil)).Elem(), - "ShowVersionReply": reflect.TypeOf((*ShowVersionReply)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewAddNodeNext": reflect.ValueOf(NewAddNodeNext), - "NewAddNodeNextReply": reflect.ValueOf(NewAddNodeNextReply), - "NewCli": reflect.ValueOf(NewCli), - "NewCliInband": reflect.ValueOf(NewCliInband), - "NewCliInbandReply": reflect.ValueOf(NewCliInbandReply), - "NewCliReply": reflect.ValueOf(NewCliReply), - "NewControlPing": reflect.ValueOf(NewControlPing), - "NewControlPingReply": reflect.ValueOf(NewControlPingReply), - "NewGetNextIndex": reflect.ValueOf(NewGetNextIndex), - "NewGetNextIndexReply": reflect.ValueOf(NewGetNextIndexReply), - "NewGetNodeGraph": reflect.ValueOf(NewGetNodeGraph), - "NewGetNodeGraphReply": reflect.ValueOf(NewGetNodeGraphReply), - "NewGetNodeIndex": reflect.ValueOf(NewGetNodeIndex), - "NewGetNodeIndexReply": reflect.ValueOf(NewGetNodeIndexReply), - "NewShowVersion": reflect.ValueOf(NewShowVersion), - "NewShowVersionReply": reflect.ValueOf(NewShowVersionReply), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/vpe/vpe.ba.go b/plugins/vpp/binapi/vpe/vpe.ba.go index 0a9d136569..739a8bccaf 100644 --- a/plugins/vpp/binapi/vpe/vpe.ba.go +++ b/plugins/vpp/binapi/vpe/vpe.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/vpe.api.json +// source: /usr/share/vpp/api/vpe.api.json /* -Package vpe is a generated VPP binary API of the 'vpe' VPP module. + Package vpe is a generated from VPP binary API module 'vpe'. -It is generated from this file: - vpe.api.json + It contains following objects: + 16 messages + 8 services -It contains these VPP binary API objects: - 16 messages - 8 services */ package vpe @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // ControlPing represents the VPP binary API message 'control_ping'. -// Generated from 'vpe.api.json', line 4: // // "control_ping", // [ @@ -54,12 +52,8 @@ func (*ControlPing) GetCrcString() string { func (*ControlPing) GetMessageType() api.MessageType { return api.RequestMessage } -func NewControlPing() api.Message { - return &ControlPing{} -} // ControlPingReply represents the VPP binary API message 'control_ping_reply'. -// Generated from 'vpe.api.json', line 22: // // "control_ping_reply", // [ @@ -101,12 +95,8 @@ func (*ControlPingReply) GetCrcString() string { func (*ControlPingReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewControlPingReply() api.Message { - return &ControlPingReply{} -} // Cli represents the VPP binary API message 'cli'. -// Generated from 'vpe.api.json', line 48: // // "cli", // [ @@ -142,12 +132,8 @@ func (*Cli) GetCrcString() string { func (*Cli) GetMessageType() api.MessageType { return api.RequestMessage } -func NewCli() api.Message { - return &Cli{} -} // CliInband represents the VPP binary API message 'cli_inband'. -// Generated from 'vpe.api.json', line 70: // // "cli_inband", // [ @@ -190,12 +176,8 @@ func (*CliInband) GetCrcString() string { func (*CliInband) GetMessageType() api.MessageType { return api.RequestMessage } -func NewCliInband() api.Message { - return &CliInband{} -} // CliReply represents the VPP binary API message 'cli_reply'. -// Generated from 'vpe.api.json', line 98: // // "cli_reply", // [ @@ -232,12 +214,8 @@ func (*CliReply) GetCrcString() string { func (*CliReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewCliReply() api.Message { - return &CliReply{} -} // CliInbandReply represents the VPP binary API message 'cli_inband_reply'. -// Generated from 'vpe.api.json', line 120: // // "cli_inband_reply", // [ @@ -281,12 +259,8 @@ func (*CliInbandReply) GetCrcString() string { func (*CliInbandReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewCliInbandReply() api.Message { - return &CliInbandReply{} -} // GetNodeIndex represents the VPP binary API message 'get_node_index'. -// Generated from 'vpe.api.json', line 148: // // "get_node_index", // [ @@ -323,12 +297,8 @@ func (*GetNodeIndex) GetCrcString() string { func (*GetNodeIndex) GetMessageType() api.MessageType { return api.RequestMessage } -func NewGetNodeIndex() api.Message { - return &GetNodeIndex{} -} // GetNodeIndexReply represents the VPP binary API message 'get_node_index_reply'. -// Generated from 'vpe.api.json', line 171: // // "get_node_index_reply", // [ @@ -365,12 +335,8 @@ func (*GetNodeIndexReply) GetCrcString() string { func (*GetNodeIndexReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewGetNodeIndexReply() api.Message { - return &GetNodeIndexReply{} -} // AddNodeNext represents the VPP binary API message 'add_node_next'. -// Generated from 'vpe.api.json', line 193: // // "add_node_next", // [ @@ -413,12 +379,8 @@ func (*AddNodeNext) GetCrcString() string { func (*AddNodeNext) GetMessageType() api.MessageType { return api.RequestMessage } -func NewAddNodeNext() api.Message { - return &AddNodeNext{} -} // AddNodeNextReply represents the VPP binary API message 'add_node_next_reply'. -// Generated from 'vpe.api.json', line 221: // // "add_node_next_reply", // [ @@ -455,12 +417,8 @@ func (*AddNodeNextReply) GetCrcString() string { func (*AddNodeNextReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewAddNodeNextReply() api.Message { - return &AddNodeNextReply{} -} // ShowVersion represents the VPP binary API message 'show_version'. -// Generated from 'vpe.api.json', line 243: // // "show_version", // [ @@ -490,12 +448,8 @@ func (*ShowVersion) GetCrcString() string { func (*ShowVersion) GetMessageType() api.MessageType { return api.RequestMessage } -func NewShowVersion() api.Message { - return &ShowVersion{} -} // ShowVersionReply represents the VPP binary API message 'show_version_reply'. -// Generated from 'vpe.api.json', line 261: // // "show_version_reply", // [ @@ -551,12 +505,8 @@ func (*ShowVersionReply) GetCrcString() string { func (*ShowVersionReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewShowVersionReply() api.Message { - return &ShowVersionReply{} -} // GetNodeGraph represents the VPP binary API message 'get_node_graph'. -// Generated from 'vpe.api.json', line 299: // // "get_node_graph", // [ @@ -586,12 +536,8 @@ func (*GetNodeGraph) GetCrcString() string { func (*GetNodeGraph) GetMessageType() api.MessageType { return api.RequestMessage } -func NewGetNodeGraph() api.Message { - return &GetNodeGraph{} -} // GetNodeGraphReply represents the VPP binary API message 'get_node_graph_reply'. -// Generated from 'vpe.api.json', line 317: // // "get_node_graph_reply", // [ @@ -628,12 +574,8 @@ func (*GetNodeGraphReply) GetCrcString() string { func (*GetNodeGraphReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewGetNodeGraphReply() api.Message { - return &GetNodeGraphReply{} -} // GetNextIndex represents the VPP binary API message 'get_next_index'. -// Generated from 'vpe.api.json', line 339: // // "get_next_index", // [ @@ -676,12 +618,8 @@ func (*GetNextIndex) GetCrcString() string { func (*GetNextIndex) GetMessageType() api.MessageType { return api.RequestMessage } -func NewGetNextIndex() api.Message { - return &GetNextIndex{} -} // GetNextIndexReply represents the VPP binary API message 'get_next_index_reply'. -// Generated from 'vpe.api.json', line 367: // // "get_next_index_reply", // [ @@ -718,9 +656,6 @@ func (*GetNextIndexReply) GetCrcString() string { func (*GetNextIndexReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewGetNextIndexReply() api.Message { - return &GetNextIndexReply{} -} /* Services */ diff --git a/plugins/vpp/binapi/vxlan/pkgreflect.go b/plugins/vpp/binapi/vxlan/pkgreflect.go deleted file mode 100644 index e0dd85918e..0000000000 --- a/plugins/vpp/binapi/vxlan/pkgreflect.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by github.com/ungerik/pkgreflect DO NOT EDIT. - -package vxlan - -import "reflect" - -var Types = map[string]reflect.Type{ - "Services": reflect.TypeOf((*Services)(nil)).Elem(), - "SwInterfaceSetVxlanBypass": reflect.TypeOf((*SwInterfaceSetVxlanBypass)(nil)).Elem(), - "SwInterfaceSetVxlanBypassReply": reflect.TypeOf((*SwInterfaceSetVxlanBypassReply)(nil)).Elem(), - "VxlanAddDelTunnel": reflect.TypeOf((*VxlanAddDelTunnel)(nil)).Elem(), - "VxlanAddDelTunnelReply": reflect.TypeOf((*VxlanAddDelTunnelReply)(nil)).Elem(), - "VxlanOffloadRx": reflect.TypeOf((*VxlanOffloadRx)(nil)).Elem(), - "VxlanOffloadRxReply": reflect.TypeOf((*VxlanOffloadRxReply)(nil)).Elem(), - "VxlanTunnelDetails": reflect.TypeOf((*VxlanTunnelDetails)(nil)).Elem(), - "VxlanTunnelDump": reflect.TypeOf((*VxlanTunnelDump)(nil)).Elem(), -} - -var Functions = map[string]reflect.Value{ - "NewSwInterfaceSetVxlanBypass": reflect.ValueOf(NewSwInterfaceSetVxlanBypass), - "NewSwInterfaceSetVxlanBypassReply": reflect.ValueOf(NewSwInterfaceSetVxlanBypassReply), - "NewVxlanAddDelTunnel": reflect.ValueOf(NewVxlanAddDelTunnel), - "NewVxlanAddDelTunnelReply": reflect.ValueOf(NewVxlanAddDelTunnelReply), - "NewVxlanOffloadRx": reflect.ValueOf(NewVxlanOffloadRx), - "NewVxlanOffloadRxReply": reflect.ValueOf(NewVxlanOffloadRxReply), - "NewVxlanTunnelDetails": reflect.ValueOf(NewVxlanTunnelDetails), - "NewVxlanTunnelDump": reflect.ValueOf(NewVxlanTunnelDump), -} - -var Variables = map[string]reflect.Value{ -} - -var Consts = map[string]reflect.Value{ -} - diff --git a/plugins/vpp/binapi/vxlan/vxlan.ba.go b/plugins/vpp/binapi/vxlan/vxlan.ba.go index e17e26c2c9..968f71a02c 100644 --- a/plugins/vpp/binapi/vxlan/vxlan.ba.go +++ b/plugins/vpp/binapi/vxlan/vxlan.ba.go @@ -1,15 +1,13 @@ // Code generated by GoVPP binapi-generator. DO NOT EDIT. -// source: /usr/share/vpp/api/vxlan.api.json +// source: /usr/share/vpp/api/vxlan.api.json /* -Package vxlan is a generated VPP binary API of the 'vxlan' VPP module. + Package vxlan is a generated from VPP binary API module 'vxlan'. -It is generated from this file: - vxlan.api.json + It contains following objects: + 8 messages + 4 services -It contains these VPP binary API objects: - 8 messages - 4 services */ package vxlan @@ -18,13 +16,13 @@ import "github.com/lunixbochs/struc" import "bytes" // Reference imports to suppress errors if they are not otherwise used. +var _ = api.RegisterMessage var _ = struc.Pack var _ = bytes.NewBuffer /* Messages */ // VxlanAddDelTunnel represents the VPP binary API message 'vxlan_add_del_tunnel'. -// Generated from 'vxlan.api.json', line 4: // // "vxlan_add_del_tunnel", // [ @@ -102,12 +100,8 @@ func (*VxlanAddDelTunnel) GetCrcString() string { func (*VxlanAddDelTunnel) GetMessageType() api.MessageType { return api.RequestMessage } -func NewVxlanAddDelTunnel() api.Message { - return &VxlanAddDelTunnel{} -} // VxlanAddDelTunnelReply represents the VPP binary API message 'vxlan_add_del_tunnel_reply'. -// Generated from 'vxlan.api.json', line 60: // // "vxlan_add_del_tunnel_reply", // [ @@ -144,12 +138,8 @@ func (*VxlanAddDelTunnelReply) GetCrcString() string { func (*VxlanAddDelTunnelReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewVxlanAddDelTunnelReply() api.Message { - return &VxlanAddDelTunnelReply{} -} // VxlanTunnelDump represents the VPP binary API message 'vxlan_tunnel_dump'. -// Generated from 'vxlan.api.json', line 82: // // "vxlan_tunnel_dump", // [ @@ -185,12 +175,8 @@ func (*VxlanTunnelDump) GetCrcString() string { func (*VxlanTunnelDump) GetMessageType() api.MessageType { return api.RequestMessage } -func NewVxlanTunnelDump() api.Message { - return &VxlanTunnelDump{} -} // VxlanTunnelDetails represents the VPP binary API message 'vxlan_tunnel_details'. -// Generated from 'vxlan.api.json', line 104: // // "vxlan_tunnel_details", // [ @@ -264,12 +250,8 @@ func (*VxlanTunnelDetails) GetCrcString() string { func (*VxlanTunnelDetails) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewVxlanTunnelDetails() api.Message { - return &VxlanTunnelDetails{} -} // SwInterfaceSetVxlanBypass represents the VPP binary API message 'sw_interface_set_vxlan_bypass'. -// Generated from 'vxlan.api.json', line 156: // // "sw_interface_set_vxlan_bypass", // [ @@ -315,12 +297,8 @@ func (*SwInterfaceSetVxlanBypass) GetCrcString() string { func (*SwInterfaceSetVxlanBypass) GetMessageType() api.MessageType { return api.RequestMessage } -func NewSwInterfaceSetVxlanBypass() api.Message { - return &SwInterfaceSetVxlanBypass{} -} // SwInterfaceSetVxlanBypassReply represents the VPP binary API message 'sw_interface_set_vxlan_bypass_reply'. -// Generated from 'vxlan.api.json', line 186: // // "sw_interface_set_vxlan_bypass_reply", // [ @@ -352,12 +330,8 @@ func (*SwInterfaceSetVxlanBypassReply) GetCrcString() string { func (*SwInterfaceSetVxlanBypassReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewSwInterfaceSetVxlanBypassReply() api.Message { - return &SwInterfaceSetVxlanBypassReply{} -} // VxlanOffloadRx represents the VPP binary API message 'vxlan_offload_rx'. -// Generated from 'vxlan.api.json', line 204: // // "vxlan_offload_rx", // [ @@ -403,12 +377,8 @@ func (*VxlanOffloadRx) GetCrcString() string { func (*VxlanOffloadRx) GetMessageType() api.MessageType { return api.RequestMessage } -func NewVxlanOffloadRx() api.Message { - return &VxlanOffloadRx{} -} // VxlanOffloadRxReply represents the VPP binary API message 'vxlan_offload_rx_reply'. -// Generated from 'vxlan.api.json', line 234: // // "vxlan_offload_rx_reply", // [ @@ -440,9 +410,6 @@ func (*VxlanOffloadRxReply) GetCrcString() string { func (*VxlanOffloadRxReply) GetMessageType() api.MessageType { return api.ReplyMessage } -func NewVxlanOffloadRxReply() api.Message { - return &VxlanOffloadRxReply{} -} /* Services */ diff --git a/plugins/vpp/data_change.go b/plugins/vpp/data_change.go index 1b1b925b2b..a18586ee37 100644 --- a/plugins/vpp/data_change.go +++ b/plugins/vpp/data_change.go @@ -17,7 +17,7 @@ package vpp import ( "strings" - "github.com/golang/protobuf/proto" + "github.com/gogo/protobuf/proto" "github.com/ligato/cn-infra/datasync" "github.com/ligato/vpp-agent/plugins/vpp/model/acl" "github.com/ligato/vpp-agent/plugins/vpp/model/bfd" @@ -38,7 +38,10 @@ func (plugin *Plugin) changePropagateRequest(dataChng datasync.ChangeEvent, call if strings.HasPrefix(key, interfaces.ErrorPrefix) || strings.HasPrefix(key, l2.BdErrPrefix) { return false, nil } - plugin.Log.Debug("Start processing change for key: ", key) + + plugin.Log.WithField("revision", dataChng.GetRevision()). + Debugf("Processing change for key: %q", key) + if strings.HasPrefix(key, acl.Prefix) { var value, prevValue acl.AccessLists_Acl if err := dataChng.GetValue(&value); err != nil { @@ -382,12 +385,15 @@ func (plugin *Plugin) dataChangeACL(diff bool, value *acl.AccessLists_Acl, prevV changeType datasync.Op) error { plugin.Log.Debug("dataChangeAcl ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.aclConfigurator.DeleteACL(prevValue) + err = plugin.aclConfigurator.DeleteACL(prevValue) } else if diff { - return plugin.aclConfigurator.ModifyACL(prevValue, value) + err = plugin.aclConfigurator.ModifyACL(prevValue, value) + } else { + err = plugin.aclConfigurator.ConfigureACL(value) } - return plugin.aclConfigurator.ConfigureACL(value) + return plugin.aclConfigurator.LogError(err) } // DataChangeIface propagates data change to the ifConfigurator. @@ -395,12 +401,15 @@ func (plugin *Plugin) dataChangeIface(diff bool, value *interfaces.Interfaces_In changeType datasync.Op) error { plugin.Log.Debug("dataChangeIface ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.ifConfigurator.DeleteVPPInterface(prevValue) + err = plugin.ifConfigurator.DeleteVPPInterface(prevValue) } else if diff { - return plugin.ifConfigurator.ModifyVPPInterface(value, prevValue) + err = plugin.ifConfigurator.ModifyVPPInterface(value, prevValue) + } else { + err = plugin.ifConfigurator.ConfigureVPPInterface(value) } - return plugin.ifConfigurator.ConfigureVPPInterface(value) + return plugin.ifConfigurator.LogError(err) } // DataChangeBfdSession propagates data change to the bfdConfigurator. @@ -408,12 +417,15 @@ func (plugin *Plugin) dataChangeBfdSession(diff bool, value *bfd.SingleHopBFD_Se changeType datasync.Op) error { plugin.Log.Debug("dataChangeBfdSession ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.bfdConfigurator.DeleteBfdSession(prevValue) + err = plugin.bfdConfigurator.DeleteBfdSession(prevValue) } else if diff { - return plugin.bfdConfigurator.ModifyBfdSession(prevValue, value) + err = plugin.bfdConfigurator.ModifyBfdSession(prevValue, value) + } else { + err = plugin.bfdConfigurator.ConfigureBfdSession(value) } - return plugin.bfdConfigurator.ConfigureBfdSession(value) + return plugin.bfdConfigurator.LogError(err) } // DataChangeBfdKey propagates data change to the bfdConfigurator. @@ -421,12 +433,15 @@ func (plugin *Plugin) dataChangeBfdKey(diff bool, value *bfd.SingleHopBFD_Key, p changeType datasync.Op) error { plugin.Log.Debug("dataChangeBfdKey ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.bfdConfigurator.DeleteBfdAuthKey(prevValue) + err = plugin.bfdConfigurator.DeleteBfdAuthKey(prevValue) } else if diff { - return plugin.bfdConfigurator.ModifyBfdAuthKey(prevValue, value) + err = plugin.bfdConfigurator.ModifyBfdAuthKey(prevValue, value) + } else { + err = plugin.bfdConfigurator.ConfigureBfdAuthKey(value) } - return plugin.bfdConfigurator.ConfigureBfdAuthKey(value) + return plugin.bfdConfigurator.LogError(err) } // DataChangeBfdEchoFunction propagates data change to the bfdConfigurator. @@ -434,12 +449,15 @@ func (plugin *Plugin) dataChangeBfdEchoFunction(diff bool, value *bfd.SingleHopB changeType datasync.Op) error { plugin.Log.Debug("dataChangeBfdEchoFunction ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.bfdConfigurator.DeleteBfdEchoFunction(prevValue) + err = plugin.bfdConfigurator.DeleteBfdEchoFunction(prevValue) } else if diff { - return plugin.bfdConfigurator.ModifyBfdEchoFunction(prevValue, value) + err = plugin.bfdConfigurator.ModifyBfdEchoFunction(prevValue, value) + } else { + err = plugin.bfdConfigurator.ConfigureBfdEchoFunction(value) } - return plugin.bfdConfigurator.ConfigureBfdEchoFunction(value) + return plugin.bfdConfigurator.LogError(err) } // dataChangeBD propagates data change to the bdConfigurator. @@ -447,12 +465,15 @@ func (plugin *Plugin) dataChangeBD(diff bool, value *l2.BridgeDomains_BridgeDoma changeType datasync.Op) error { plugin.Log.Debug("dataChangeBD ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.bdConfigurator.DeleteBridgeDomain(prevValue) + err = plugin.bdConfigurator.DeleteBridgeDomain(prevValue) } else if diff { - return plugin.bdConfigurator.ModifyBridgeDomain(value, prevValue) + err = plugin.bdConfigurator.ModifyBridgeDomain(value, prevValue) + } else { + err = plugin.bdConfigurator.ConfigureBridgeDomain(value) } - return plugin.bdConfigurator.ConfigureBridgeDomain(value) + return plugin.bdConfigurator.LogError(err) } // dataChangeFIB propagates data change to the fibConfigurator. @@ -473,13 +494,15 @@ func (plugin *Plugin) dataChangeXCon(diff bool, value *l2.XConnectPairs_XConnect changeType datasync.Op) error { plugin.Log.Debug("dataChangeXCon ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.xcConfigurator.DeleteXConnectPair(prevValue) + err = plugin.xcConfigurator.DeleteXConnectPair(prevValue) } else if diff { - return plugin.xcConfigurator.ModifyXConnectPair(value, prevValue) + err = plugin.xcConfigurator.ModifyXConnectPair(value, prevValue) + } else { + err = plugin.xcConfigurator.ConfigureXConnectPair(value) } - return plugin.xcConfigurator.ConfigureXConnectPair(value) - + return plugin.xcConfigurator.LogError(err) } // DataChangeStaticRoute propagates data change to the routeConfigurator. @@ -487,12 +510,15 @@ func (plugin *Plugin) dataChangeStaticRoute(diff bool, value *l3.StaticRoutes_Ro vrfFromKey string, changeType datasync.Op) error { plugin.Log.Debug("dataChangeStaticRoute ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.routeConfigurator.DeleteRoute(prevValue, vrfFromKey) + err = plugin.routeConfigurator.DeleteRoute(prevValue, vrfFromKey) } else if diff { - return plugin.routeConfigurator.ModifyRoute(value, prevValue, vrfFromKey) + err = plugin.routeConfigurator.ModifyRoute(value, prevValue, vrfFromKey) + } else { + err = plugin.routeConfigurator.ConfigureRoute(value, vrfFromKey) } - return plugin.routeConfigurator.ConfigureRoute(value, vrfFromKey) + return plugin.routeConfigurator.LogError(err) } // dataChangeARP propagates data change to the arpConfigurator @@ -500,12 +526,15 @@ func (plugin *Plugin) dataChangeARP(diff bool, value *l3.ArpTable_ArpEntry, prev changeType datasync.Op) error { plugin.Log.Debug("dataChangeARP diff=", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.arpConfigurator.DeleteArp(prevValue) + err = plugin.arpConfigurator.DeleteArp(prevValue) } else if diff { - return plugin.arpConfigurator.ChangeArp(value, prevValue) + err = plugin.arpConfigurator.ChangeArp(value, prevValue) + } else { + err = plugin.arpConfigurator.AddArp(value) } - return plugin.arpConfigurator.AddArp(value) + return plugin.arpConfigurator.LogError(err) } // dataChangeProxyARPInterface propagates data change to the arpConfigurator @@ -513,12 +542,15 @@ func (plugin *Plugin) dataChangeProxyARPInterface(diff bool, value, prevValue *l changeType datasync.Op) error { plugin.Log.Debug("dataChangeProxyARPInterface diff=", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.proxyArpConfigurator.DeleteInterface(prevValue) + err = plugin.proxyArpConfigurator.DeleteInterface(prevValue) } else if diff { - return plugin.proxyArpConfigurator.ModifyInterface(value, prevValue) + err = plugin.proxyArpConfigurator.ModifyInterface(value, prevValue) + } else { + err = plugin.proxyArpConfigurator.AddInterface(value) } - return plugin.proxyArpConfigurator.AddInterface(value) + return plugin.proxyArpConfigurator.LogError(err) } // dataChangeProxyARPRange propagates data change to the arpConfigurator @@ -526,22 +558,28 @@ func (plugin *Plugin) dataChangeProxyARPRange(diff bool, value, prevValue *l3.Pr changeType datasync.Op) error { plugin.Log.Debug("dataChangeProxyARPRange diff=", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.proxyArpConfigurator.DeleteRange(prevValue) + err = plugin.proxyArpConfigurator.DeleteRange(prevValue) } else if diff { - return plugin.proxyArpConfigurator.ModifyRange(value, prevValue) + err = plugin.proxyArpConfigurator.ModifyRange(value, prevValue) + } else { + err = plugin.proxyArpConfigurator.AddRange(value) } - return plugin.proxyArpConfigurator.AddRange(value) + return plugin.proxyArpConfigurator.LogError(err) } // dataChangeIPScanNeigh propagates data change to the ipNeighConfigurator func (plugin *Plugin) dataChangeIPScanNeigh(value *l3.IPScanNeighbor, changeType datasync.Op) error { + var err error if datasync.Delete == changeType { - return plugin.ipNeighConfigurator.Unset() + err = plugin.ipNeighConfigurator.Unset() + } else { + err = plugin.ipNeighConfigurator.Set(value) } - return plugin.ipNeighConfigurator.Set(value) + return plugin.ipNeighConfigurator.LogError(err) } // DataChangeStaticRoute propagates data change to the l4Configurator @@ -549,12 +587,15 @@ func (plugin *Plugin) dataChangeAppNamespace(diff bool, value *l4.AppNamespaces_ changeType datasync.Op) error { plugin.Log.Debug("dataChangeL4AppNamespace ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.appNsConfigurator.DeleteAppNamespace(prevValue) + err = plugin.appNsConfigurator.DeleteAppNamespace(prevValue) } else if diff { - return plugin.appNsConfigurator.ModifyAppNamespace(value, prevValue) + err = plugin.appNsConfigurator.ModifyAppNamespace(value, prevValue) + } else { + err = plugin.appNsConfigurator.ConfigureAppNamespace(value) } - return plugin.appNsConfigurator.ConfigureAppNamespace(value) + return plugin.appNsConfigurator.LogError(err) } // DataChangeL4Features propagates data change to the l4Configurator @@ -564,82 +605,103 @@ func (plugin *Plugin) dataChangeL4Features(value *l4.L4Features, prevValue *l4.L // diff and previous value is not important, features flag can be either set or not. // If removed, it is always set to false + var err error if datasync.Delete == changeType { - return plugin.appNsConfigurator.DeleteL4FeatureFlag() + err = plugin.appNsConfigurator.DeleteL4FeatureFlag() + } else { + err = plugin.appNsConfigurator.ConfigureL4FeatureFlag(value) } - return plugin.appNsConfigurator.ConfigureL4FeatureFlag(value) + return plugin.appNsConfigurator.LogError(err) } // DataChangeStnRule propagates data change to the stn configurator func (plugin *Plugin) dataChangeStnRule(diff bool, value *stn.STN_Rule, prevValue *stn.STN_Rule, changeType datasync.Op) error { plugin.Log.Debug("stnRuleChange diff->", diff, " changeType->", changeType, " value->", value, " prevValue->", prevValue) + var err error if datasync.Delete == changeType { - return plugin.stnConfigurator.Delete(prevValue) + err = plugin.stnConfigurator.Delete(prevValue) } else if diff { - return plugin.stnConfigurator.Modify(prevValue, value) + err = plugin.stnConfigurator.Modify(prevValue, value) + } else { + err = plugin.stnConfigurator.Add(value) } - return plugin.stnConfigurator.Add(value) + return plugin.stnConfigurator.LogError(err) } // dataChangeNatGlobal propagates data change to the nat configurator func (plugin *Plugin) dataChangeNatGlobal(diff bool, value, prevValue *nat.Nat44Global, changeType datasync.Op) error { plugin.Log.Debug("natGlobalChange diff->", diff, " changeType->", changeType, " value->", value, " prevValue->", prevValue) + var err error if datasync.Delete == changeType { - return plugin.natConfigurator.DeleteNatGlobalConfig(prevValue) + err = plugin.natConfigurator.DeleteNatGlobalConfig(prevValue) } else if diff { - return plugin.natConfigurator.ModifyNatGlobalConfig(prevValue, value) + err = plugin.natConfigurator.ModifyNatGlobalConfig(prevValue, value) + } else { + err = plugin.natConfigurator.SetNatGlobalConfig(value) } - return plugin.natConfigurator.SetNatGlobalConfig(value) + return plugin.natConfigurator.LogError(err) } // dataChangeSNat propagates data change to the nat configurator func (plugin *Plugin) dataChangeSNat(diff bool, value, prevValue *nat.Nat44SNat_SNatConfig, changeType datasync.Op) error { plugin.Log.Debug("sNatChange diff->", diff, " changeType->", changeType, " value->", value, " prevValue->", prevValue) + var err error if datasync.Delete == changeType { - return plugin.natConfigurator.DeleteSNat(prevValue) + err = plugin.natConfigurator.DeleteSNat(prevValue) } else if diff { - return plugin.natConfigurator.ModifySNat(prevValue, value) + err = plugin.natConfigurator.ModifySNat(prevValue, value) + } else { + err = plugin.natConfigurator.ConfigureSNat(value) } - return plugin.natConfigurator.ConfigureSNat(value) + return plugin.natConfigurator.LogError(err) } // dataChangeDNat propagates data change to the nat configurator func (plugin *Plugin) dataChangeDNat(diff bool, value, prevValue *nat.Nat44DNat_DNatConfig, changeType datasync.Op) error { plugin.Log.Debug("dNatChange diff->", diff, " changeType->", changeType, " value->", value, " prevValue->", prevValue) + var err error if datasync.Delete == changeType { - return plugin.natConfigurator.DeleteDNat(prevValue) + err = plugin.natConfigurator.DeleteDNat(prevValue) } else if diff { - return plugin.natConfigurator.ModifyDNat(prevValue, value) + err = plugin.natConfigurator.ModifyDNat(prevValue, value) + } else { + err = plugin.natConfigurator.ConfigureDNat(value) } - return plugin.natConfigurator.ConfigureDNat(value) + return plugin.natConfigurator.LogError(err) } // dataChangeIPSecSPD propagates data change to the IPSec configurator func (plugin *Plugin) dataChangeIPSecSPD(diff bool, value, prevValue *ipsec.SecurityPolicyDatabases_SPD, changeType datasync.Op) error { plugin.Log.Debug("dataChangeIPSecSPD diff->", diff, " changeType->", changeType, " value->", value, " prevValue->", prevValue) + var err error if datasync.Delete == changeType { - return plugin.ipSecConfigurator.DeleteSPD(prevValue) + err = plugin.ipSecConfigurator.DeleteSPD(prevValue) } else if diff { - return plugin.ipSecConfigurator.ModifySPD(prevValue, value) + err = plugin.ipSecConfigurator.ModifySPD(prevValue, value) + } else { + err = plugin.ipSecConfigurator.ConfigureSPD(value) } - return plugin.ipSecConfigurator.ConfigureSPD(value) + return plugin.ipSecConfigurator.LogError(err) } // dataChangeIPSecSA propagates data change to the IPSec configurator func (plugin *Plugin) dataChangeIPSecSA(diff bool, value, prevValue *ipsec.SecurityAssociations_SA, changeType datasync.Op) error { plugin.Log.Debug("dataChangeIPSecSA diff->", diff, " changeType->", changeType, " value->", value, " prevValue->", prevValue) + var err error if datasync.Delete == changeType { - return plugin.ipSecConfigurator.DeleteSA(prevValue) + err = plugin.ipSecConfigurator.DeleteSA(prevValue) } else if diff { - return plugin.ipSecConfigurator.ModifySA(prevValue, value) + err = plugin.ipSecConfigurator.ModifySA(prevValue, value) + } else { + err = plugin.ipSecConfigurator.ConfigureSA(value) } - return plugin.ipSecConfigurator.ConfigureSA(value) + return plugin.ipSecConfigurator.LogError(err) } // dataChangeIPSecTunnel propagates data change to the IPSec configurator @@ -657,43 +719,55 @@ func (plugin *Plugin) dataChangeIPSecTunnel(diff bool, value, prevValue *ipsec.T // DataChangeLocalSID handles change events from ETCD related to local SIDs func (plugin *Plugin) dataChangeLocalSID(diff bool, value *srv6.LocalSID, prevValue *srv6.LocalSID, changeType datasync.Op) error { plugin.Log.Debug("dataChangeLocalSIDs ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.srv6Configurator.DeleteLocalSID(prevValue) + err = plugin.srv6Configurator.DeleteLocalSID(prevValue) } else if diff { - return plugin.srv6Configurator.ModifyLocalSID(value, prevValue) + err = plugin.srv6Configurator.ModifyLocalSID(value, prevValue) + } else { + err = plugin.srv6Configurator.AddLocalSID(value) } - return plugin.srv6Configurator.AddLocalSID(value) + return plugin.srv6Configurator.LogError(err) } // dataChangePolicy handles change events from ETCD related to policies func (plugin *Plugin) dataChangePolicy(diff bool, value *srv6.Policy, prevValue *srv6.Policy, changeType datasync.Op) error { plugin.Log.Debug("dataChangePolicy ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.srv6Configurator.RemovePolicy(prevValue) + err = plugin.srv6Configurator.RemovePolicy(prevValue) } else if diff { - return plugin.srv6Configurator.ModifyPolicy(value, prevValue) + err = plugin.srv6Configurator.ModifyPolicy(value, prevValue) + } else { + err = plugin.srv6Configurator.AddPolicy(value) } - return plugin.srv6Configurator.AddPolicy(value) + return plugin.srv6Configurator.LogError(err) } // dataChangePolicySegment handles change events from ETCD related to policies segments func (plugin *Plugin) dataChangePolicySegment(segmentName string, diff bool, value *srv6.PolicySegment, prevValue *srv6.PolicySegment, changeType datasync.Op) error { plugin.Log.Debug("dataChangePolicySegment ", segmentName, " ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.srv6Configurator.RemovePolicySegment(segmentName, prevValue) + err = plugin.srv6Configurator.RemovePolicySegment(segmentName, prevValue) } else if diff { - return plugin.srv6Configurator.ModifyPolicySegment(segmentName, value, prevValue) + err = plugin.srv6Configurator.ModifyPolicySegment(segmentName, value, prevValue) + } else { + err = plugin.srv6Configurator.AddPolicySegment(segmentName, value) } - return plugin.srv6Configurator.AddPolicySegment(segmentName, value) + return plugin.srv6Configurator.LogError(err) } // dataChangeSteering handles change events from ETCD related to steering func (plugin *Plugin) dataChangeSteering(steeringName string, diff bool, value *srv6.Steering, prevValue *srv6.Steering, changeType datasync.Op) error { plugin.Log.Debug("dataChangeSteering ", steeringName, " ", diff, " ", changeType, " ", value, " ", prevValue) + var err error if datasync.Delete == changeType { - return plugin.srv6Configurator.RemoveSteering(steeringName, prevValue) + err = plugin.srv6Configurator.RemoveSteering(steeringName, prevValue) } else if diff { - return plugin.srv6Configurator.ModifySteering(steeringName, value, prevValue) + err = plugin.srv6Configurator.ModifySteering(steeringName, value, prevValue) + } else { + err = plugin.srv6Configurator.AddSteering(steeringName, value) } - return plugin.srv6Configurator.AddSteering(steeringName, value) + return plugin.srv6Configurator.LogError(err) } diff --git a/plugins/vpp/data_resync.go b/plugins/vpp/data_resync.go index 452c3c4d8f..9f322007a1 100644 --- a/plugins/vpp/data_resync.go +++ b/plugins/vpp/data_resync.go @@ -21,7 +21,6 @@ import ( "time" "github.com/ligato/cn-infra/datasync" - "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/plugins/vpp/model/acl" "github.com/ligato/vpp-agent/plugins/vpp/model/bfd" "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" @@ -161,33 +160,33 @@ func (plugin *Plugin) resyncConfig(req *DataResyncReq) error { var resyncErrs []error if !plugin.droppedFromResync(interfaces.Prefix) { - if errs := plugin.ifConfigurator.Resync(req.Interfaces); errs != nil { - resyncErrs = append(resyncErrs, errs...) + if err := plugin.ifConfigurator.Resync(req.Interfaces); err != nil { + resyncErrs = append(resyncErrs, plugin.ifConfigurator.LogError(err)) } } if !plugin.droppedFromResync(acl.Prefix) { if err := plugin.aclConfigurator.Resync(req.ACLs); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.aclConfigurator.LogError(err)) } } if !plugin.droppedFromResync(bfd.AuthKeysPrefix) { if err := plugin.bfdConfigurator.ResyncAuthKey(req.SingleHopBFDKey); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.bfdConfigurator.LogError(err)) } } if !plugin.droppedFromResync(bfd.SessionPrefix) { if err := plugin.bfdConfigurator.ResyncSession(req.SingleHopBFDSession); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.bfdConfigurator.LogError(err)) } } if !plugin.droppedFromResync(bfd.EchoFunctionPrefix) { if err := plugin.bfdConfigurator.ResyncEchoFunction(req.SingleHopBFDEcho); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.bfdConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l2.BdPrefix) { if err := plugin.bdConfigurator.Resync(req.BridgeDomains); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.bdConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l2.FibPrefix) { @@ -197,72 +196,72 @@ func (plugin *Plugin) resyncConfig(req *DataResyncReq) error { } if !plugin.droppedFromResync(l2.XConnectPrefix) { if err := plugin.xcConfigurator.Resync(req.XConnects); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.xcConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l3.RoutesPrefix) { if err := plugin.routeConfigurator.Resync(req.StaticRoutes); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.routeConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l3.ArpPrefix) { if err := plugin.arpConfigurator.Resync(req.ArpEntries); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.arpConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l3.ProxyARPInterfacePrefix) { if err := plugin.proxyArpConfigurator.ResyncInterfaces(req.ProxyArpInterfaces); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.proxyArpConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l3.ProxyARPRangePrefix) { if err := plugin.proxyArpConfigurator.ResyncRanges(req.ProxyArpRanges); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.proxyArpConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l3.IPScanNeighPrefix) { if err := plugin.ipNeighConfigurator.Resync(req.IPScanNeigh); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.ipNeighConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l4.FeaturesPrefix) { if err := plugin.appNsConfigurator.ResyncFeatures(req.L4Features); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.appNsConfigurator.LogError(err)) } } if !plugin.droppedFromResync(l4.NamespacesPrefix) { if err := plugin.appNsConfigurator.ResyncAppNs(req.AppNamespaces); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.appNsConfigurator.LogError(err)) } } if !plugin.droppedFromResync(stn.Prefix) { if err := plugin.stnConfigurator.Resync(req.StnRules); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.stnConfigurator.LogError(err)) } } if !plugin.droppedFromResync(nat.GlobalPrefix) { if err := plugin.natConfigurator.ResyncNatGlobal(req.Nat44Global); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.natConfigurator.LogError(err)) } } if !plugin.droppedFromResync(nat.SNatPrefix) { if err := plugin.natConfigurator.ResyncSNat(req.Nat44SNat); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.natConfigurator.LogError(err)) } } if !plugin.droppedFromResync(nat.DNatPrefix) { if err := plugin.natConfigurator.ResyncDNat(req.Nat44DNat); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.natConfigurator.LogError(err)) } } if !plugin.droppedFromResync(ipsec.KeyPrefix) { if err := plugin.ipSecConfigurator.Resync(req.IPSecSPDs, req.IPSecSAs, req.IPSecTunnels); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.ipSecConfigurator.LogError(err)) } } if !plugin.droppedFromResync(srv6.BasePrefix()) { if err := plugin.srv6Configurator.Resync(req.LocalSids, req.SrPolicies, req.SrPolicySegments, req.SrSteerings); err != nil { - resyncErrs = append(resyncErrs, err) + resyncErrs = append(resyncErrs, plugin.srv6Configurator.LogError(err)) } } // log errors if any @@ -277,75 +276,51 @@ func (plugin *Plugin) resyncConfig(req *DataResyncReq) error { func (plugin *Plugin) resyncParseEvent(resyncEv datasync.ResyncEvent) *DataResyncReq { req := NewDataResyncReq() - for key := range resyncEv.GetValues() { - plugin.Log.Debugf("Received RESYNC key %q", key) - } for key, resyncData := range resyncEv.GetValues() { + plugin.Log.Debugf("Received RESYNC key %q", key) if plugin.droppedFromResync(key) { continue } if strings.HasPrefix(key, acl.Prefix) { - numAcls := appendACLInterface(resyncData, req) - plugin.Log.Debug("Received RESYNC ACL values ", numAcls) + plugin.appendACLInterface(resyncData, req) } else if strings.HasPrefix(key, interfaces.Prefix) { - numInterfaces := appendResyncInterface(resyncData, req) - plugin.Log.Debug("Received RESYNC interface values ", numInterfaces) + plugin.appendResyncInterface(resyncData, req) } else if strings.HasPrefix(key, bfd.SessionPrefix) { - numBfdSession := resyncAppendBfdSession(resyncData, req) - plugin.Log.Debug("Received RESYNC BFD Session values ", numBfdSession) + plugin.resyncAppendBfdSession(resyncData, req) } else if strings.HasPrefix(key, bfd.AuthKeysPrefix) { - numBfdAuthKeys := resyncAppendBfdAuthKeys(resyncData, req) - plugin.Log.Debug("Received RESYNC BFD Auth Key values ", numBfdAuthKeys) + plugin.resyncAppendBfdAuthKeys(resyncData, req) } else if strings.HasPrefix(key, bfd.EchoFunctionPrefix) { - numBfdEchos := resyncAppendBfdEcho(resyncData, req) - plugin.Log.Debug("Received RESYNC BFD Echo values ", numBfdEchos) + plugin.resyncAppendBfdEcho(resyncData, req) } else if strings.HasPrefix(key, l2.BdPrefix) { - numBDs, numL2FIBs := resyncAppendBDs(resyncData, req) - plugin.Log.Debug("Received RESYNC BD values ", numBDs) - plugin.Log.Debug("Received RESYNC L2 FIB values ", numL2FIBs) + plugin.resyncAppendBDs(resyncData, req) } else if strings.HasPrefix(key, l2.XConnectPrefix) { - numXCons := resyncAppendXCons(resyncData, req) - plugin.Log.Debug("Received RESYNC XConnects values ", numXCons) + plugin.resyncAppendXCons(resyncData, req) } else if strings.HasPrefix(key, l3.VrfPrefix) { - numVRFs, numL3FIBs := resyncAppendVRFs(resyncData, req, plugin.Log) - plugin.Log.Debug("Received RESYNC VRF values ", numVRFs) - plugin.Log.Debug("Received RESYNC L3 FIB values ", numL3FIBs) + plugin.resyncAppendVRFs(resyncData, req) } else if strings.HasPrefix(key, l3.ArpPrefix) { - numARPs := resyncAppendARPs(resyncData, req, plugin.Log) - plugin.Log.Debug("Received RESYNC ARP values ", numARPs) + plugin.resyncAppendARPs(resyncData, req) } else if strings.HasPrefix(key, l3.ProxyARPInterfacePrefix) { - numARPs := resyncAppendProxyArpInterfaces(resyncData, req, plugin.Log) - plugin.Log.Debug("Received RESYNC proxy ARP interface values ", numARPs) + plugin.resyncAppendProxyArpInterfaces(resyncData, req) } else if strings.HasPrefix(key, l3.IPScanNeighPrefix) { - resyncAppendIPScanNeighs(resyncData, req) - plugin.Log.Debug("Received RESYNC IPScanNeigh") + plugin.resyncAppendIPScanNeighs(resyncData, req) } else if strings.HasPrefix(key, l3.ProxyARPRangePrefix) { - numARPs := resyncAppendProxyArpRanges(resyncData, req, plugin.Log) - plugin.Log.Debug("Received RESYNC proxy ARP range values ", numARPs) + plugin.resyncAppendProxyArpRanges(resyncData, req) } else if strings.HasPrefix(key, l4.FeaturesPrefix) { - resyncFeatures(resyncData, req) - plugin.Log.Debug("Received RESYNC AppNs feature flag") + plugin.resyncFeatures(resyncData, req) } else if strings.HasPrefix(key, l4.NamespacesPrefix) { - numAppNs := resyncAppendAppNs(resyncData, req) - plugin.Log.Debug("Received RESYNC AppNamespace values ", numAppNs) + plugin.resyncAppendAppNs(resyncData, req) } else if strings.HasPrefix(key, stn.Prefix) { - numStns := appendResyncStnRules(resyncData, req) - plugin.Log.Debug("Received RESYNC STN rules values ", numStns) + plugin.appendResyncStnRules(resyncData, req) } else if strings.HasPrefix(key, nat.GlobalPrefix) { - resyncNatGlobal(resyncData, req) - plugin.Log.Debug("Received RESYNC NAT global config") + plugin.resyncNatGlobal(resyncData, req) } else if strings.HasPrefix(key, nat.SNatPrefix) { - numSNats := appendResyncSNat(resyncData, req) - plugin.Log.Debug("Received RESYNC SNAT configs ", numSNats) + plugin.appendResyncSNat(resyncData, req) } else if strings.HasPrefix(key, nat.DNatPrefix) { - numDNats := appendResyncDNat(resyncData, req) - plugin.Log.Debug("Received RESYNC DNAT configs ", numDNats) + plugin.appendResyncDNat(resyncData, req) } else if strings.HasPrefix(key, ipsec.KeyPrefix) { - numIPSecs := appendResyncIPSec(resyncData, req) - plugin.Log.Debug("Received RESYNC IPSec configs ", numIPSecs) + plugin.appendResyncIPSec(resyncData, req) } else if strings.HasPrefix(key, srv6.BasePrefix()) { - numSRs := appendResyncSR(resyncData, req) - plugin.Log.Debug("Received RESYNC SR configs ", numSRs) + plugin.appendResyncSR(resyncData, req) } else { plugin.Log.Warnf("ignoring prefix %q by VPP standard plugins", key) } @@ -361,68 +336,95 @@ func (plugin *Plugin) droppedFromResync(key string) bool { return false } -func resyncAppendARPs(resyncData datasync.KeyValIterator, req *DataResyncReq, log logging.Logger) int { +func (plugin *Plugin) resyncAppendARPs(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if arpData, stop := resyncData.GetNext(); stop { break } else { entry := &l3.ArpTable_ArpEntry{} - if err := arpData.GetValue(entry); err == nil { - req.ArpEntries = append(req.ArpEntries, entry) - num++ + if err := arpData.GetValue(entry); err != nil { + plugin.Log.Errorf("error getting value of ARP: %v", err) + continue } + req.ArpEntries = append(req.ArpEntries, entry) + num++ + + plugin.Log.WithField("revision", arpData.GetRevision()). + Debugf("Processing resync for key: %q", arpData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC ARP values %d", num) } -func resyncAppendProxyArpInterfaces(resyncData datasync.KeyValIterator, req *DataResyncReq, log logging.Logger) int { +func (plugin *Plugin) resyncAppendProxyArpInterfaces(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if arpData, stop := resyncData.GetNext(); stop { break } else { entry := &l3.ProxyArpInterfaces_InterfaceList{} - if err := arpData.GetValue(entry); err == nil { - req.ProxyArpInterfaces = append(req.ProxyArpInterfaces, entry) - num++ + if err := arpData.GetValue(entry); err != nil { + plugin.Log.Errorf("error getting value of proxy ARP: %v", err) + continue } + req.ProxyArpInterfaces = append(req.ProxyArpInterfaces, entry) + num++ + + plugin.Log.WithField("revision", arpData.GetRevision()). + Debugf("Processing resync for key: %q", arpData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC proxy ARP values %d", num) } -func resyncAppendIPScanNeighs(resyncData datasync.KeyValIterator, req *DataResyncReq) { +func (plugin *Plugin) resyncAppendIPScanNeighs(resyncData datasync.KeyValIterator, req *DataResyncReq) { + num := 0 for { - arpData, stop := resyncData.GetNext() + ipScan, stop := resyncData.GetNext() if stop { break } entry := &l3.IPScanNeighbor{} - if err := arpData.GetValue(entry); err == nil { - req.IPScanNeigh = entry + if err := ipScan.GetValue(entry); err != nil { + plugin.Log.Errorf("error getting value of IP scan neigh: %v", err) + continue } + req.IPScanNeigh = entry + num++ + + plugin.Log.WithField("revision", ipScan.GetRevision()). + Debugf("Processing resync for key: %q", ipScan.GetKey()) } + + plugin.Log.Debugf("Received RESYNC IP scan neigh values %d", num) } -func resyncAppendProxyArpRanges(resyncData datasync.KeyValIterator, req *DataResyncReq, log logging.Logger) int { +func (plugin *Plugin) resyncAppendProxyArpRanges(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if arpData, stop := resyncData.GetNext(); stop { break } else { entry := &l3.ProxyArpRanges_RangeList{} - if err := arpData.GetValue(entry); err == nil { - req.ProxyArpRanges = append(req.ProxyArpRanges, entry) - num++ + if err := arpData.GetValue(entry); err != nil { + plugin.Log.Errorf("error getting value of proxy ARP ranges: %v", err) + continue } + req.ProxyArpRanges = append(req.ProxyArpRanges, entry) + num++ + + plugin.Log.WithField("revision", arpData.GetRevision()). + Debugf("Processing resync for key: %q", arpData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC proxy ARP ranges %d ", num) } -func resyncAppendL3FIB(fibData datasync.KeyVal, vrfIndex string, req *DataResyncReq, log logging.Logger) error { +func (plugin *Plugin) resyncAppendL3FIB(fibData datasync.KeyVal, vrfIndex string, req *DataResyncReq) error { route := &l3.StaticRoutes_Route{} err := fibData.GetValue(route) if err != nil { @@ -434,18 +436,20 @@ func resyncAppendL3FIB(fibData datasync.KeyVal, vrfIndex string, req *DataResync return err } if vrfIndex != strconv.Itoa(int(route.VrfId)) { - log.Warnf("Resync: VRF index from key (%v) and from config (%v) does not match, using value from the key", + plugin.Log.Warnf("Resync: VRF index from key (%v) and from config (%v) does not match, using value from the key", intVrfKeyIndex, route.VrfId) route.VrfId = uint32(intVrfKeyIndex) } - req.StaticRoutes = append(req.StaticRoutes, route) + + plugin.Log.WithField("revision", fibData.GetRevision()). + Debugf("Processing resync for key: %q", fibData.GetKey()) + return nil } -func resyncAppendVRFs(resyncData datasync.KeyValIterator, req *DataResyncReq, log logging.Logger) (numVRFs, numL3FIBs int) { - numVRFs = 0 - numL3FIBs = 0 +func (plugin *Plugin) resyncAppendVRFs(resyncData datasync.KeyValIterator, req *DataResyncReq) { + numL3FIBs := 0 for { if vrfData, stop := resyncData.GetNext(); stop { break @@ -453,46 +457,60 @@ func resyncAppendVRFs(resyncData datasync.KeyValIterator, req *DataResyncReq, lo key := vrfData.GetKey() fib, vrfIndex, _, _, _ := l3.ParseRouteKey(key) if fib { - err := resyncAppendL3FIB(vrfData, vrfIndex, req, log) - if err == nil { - numL3FIBs++ + if err := plugin.resyncAppendL3FIB(vrfData, vrfIndex, req); err != nil { + plugin.Log.Errorf("error resyncing L3FIB: %v", err) + continue } + numL3FIBs++ + + plugin.Log.WithField("revision", vrfData.GetRevision()). + Debugf("Processing resync for key: %q", vrfData.GetKey()) } else { - log.Warn("VRF RESYNC is not implemented") + plugin.Log.Warn("VRF RESYNC is not implemented") } } } - return numVRFs, numL3FIBs + + plugin.Log.Debugf("Received RESYNC L3 FIB values %d", numL3FIBs) } -func resyncAppendXCons(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) resyncAppendXCons(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if xConnectData, stop := resyncData.GetNext(); stop { break } else { value := &l2.XConnectPairs_XConnectPair{} - err := xConnectData.GetValue(value) - if err == nil { - req.XConnects = append(req.XConnects, value) - num++ + if err := xConnectData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of XConnect: %v", err) + continue } + req.XConnects = append(req.XConnects, value) + num++ + + plugin.Log.WithField("revision", xConnectData.GetRevision()). + Debugf("Processing resync for key: %q", xConnectData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC XConnects values %d", num) } -func resyncAppendL2FIB(fibData datasync.KeyVal, req *DataResyncReq) error { +func (plugin *Plugin) resyncAppendL2FIB(fibData datasync.KeyVal, req *DataResyncReq) error { value := &l2.FibTable_FibEntry{} - err := fibData.GetValue(value) - if err == nil { - req.FibTableEntries = append(req.FibTableEntries, value) + if err := fibData.GetValue(value); err != nil { + return fmt.Errorf("error getting value of L2FIB: %v", err) } - return err + req.FibTableEntries = append(req.FibTableEntries, value) + + plugin.Log.WithField("revision", fibData.GetRevision()). + Debugf("Processing resync for key: %q", fibData.GetKey()) + + return nil } -func resyncAppendBDs(resyncData datasync.KeyValIterator, req *DataResyncReq) (numBDs, numL2FIBs int) { - numBDs = 0 - numL2FIBs = 0 +func (plugin *Plugin) resyncAppendBDs(resyncData datasync.KeyValIterator, req *DataResyncReq) { + numBDs := 0 + numL2FIBs := 0 for { if bridgeDomainData, stop := resyncData.GetNext(); stop { break @@ -500,268 +518,367 @@ func resyncAppendBDs(resyncData datasync.KeyValIterator, req *DataResyncReq) (nu key := bridgeDomainData.GetKey() fib, _, _ := l2.ParseFibKey(key) if fib { - err := resyncAppendL2FIB(bridgeDomainData, req) - if err == nil { - numL2FIBs++ + if err := plugin.resyncAppendL2FIB(bridgeDomainData, req); err != nil { + plugin.Log.Errorf("error resyncing L2FIB: %v", err) + continue } + numL2FIBs++ + } else { value := &l2.BridgeDomains_BridgeDomain{} - err := bridgeDomainData.GetValue(value) - if err == nil { - req.BridgeDomains = append(req.BridgeDomains, value) - numBDs++ + if err := bridgeDomainData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of bridge domain: %v", err) + continue } + req.BridgeDomains = append(req.BridgeDomains, value) + numBDs++ + } + + plugin.Log.WithField("revision", bridgeDomainData.GetRevision()). + Debugf("Processing resync for key: %q", bridgeDomainData.GetKey()) } } - return numBDs, numL2FIBs + + plugin.Log.Debugf("Received RESYNC BD values %d", numBDs) + plugin.Log.Debugf("Received RESYNC L2 FIB values %d", numL2FIBs) } -func resyncAppendBfdEcho(resyncData datasync.KeyValIterator, req *DataResyncReq) int { - value := &bfd.SingleHopBFD_EchoFunction{} +func (plugin *Plugin) resyncAppendBfdEcho(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if bfdData, stop := resyncData.GetNext(); stop { break } else { - err := bfdData.GetValue(value) - if err == nil { - req.SingleHopBFDEcho = append(req.SingleHopBFDEcho, value) - num++ + bfdEcho := &bfd.SingleHopBFD_EchoFunction{} + if err := bfdData.GetValue(bfdEcho); err != nil { + plugin.Log.Errorf("error getting value of BFD echo function: %v", err) + continue } + req.SingleHopBFDEcho = append(req.SingleHopBFDEcho, bfdEcho) + num++ + + plugin.Log.WithField("revision", bfdData.GetRevision()). + Debugf("Processing resync for key: %q", bfdData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC BFD Echo values %d", num) } -func resyncAppendBfdAuthKeys(resyncData datasync.KeyValIterator, req *DataResyncReq) int { - value := &bfd.SingleHopBFD_Key{} +func (plugin *Plugin) resyncAppendBfdAuthKeys(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if bfdData, stop := resyncData.GetNext(); stop { break } else { - err := bfdData.GetValue(value) - if err == nil { - req.SingleHopBFDKey = append(req.SingleHopBFDKey, value) - num++ + bfdKey := &bfd.SingleHopBFD_Key{} + if err := bfdData.GetValue(bfdKey); err != nil { + plugin.Log.Errorf("error getting value of BFD auth key: %v", err) + continue } + req.SingleHopBFDKey = append(req.SingleHopBFDKey, bfdKey) + num++ + + plugin.Log.WithField("revision", bfdData.GetRevision()). + Debugf("Processing resync for key: %q", bfdData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC BFD auth keys %d", num) } -func resyncAppendBfdSession(resyncData datasync.KeyValIterator, req *DataResyncReq) int { - value := &bfd.SingleHopBFD_Session{} +func (plugin *Plugin) resyncAppendBfdSession(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if bfdData, stop := resyncData.GetNext(); stop { break } else { - err := bfdData.GetValue(value) - if err == nil { - req.SingleHopBFDSession = append(req.SingleHopBFDSession, value) - num++ + bfdSession := &bfd.SingleHopBFD_Session{} + if err := bfdData.GetValue(bfdSession); err != nil { + plugin.Log.Errorf("error getting value of BFD session: %v", err) + continue } + req.SingleHopBFDSession = append(req.SingleHopBFDSession, bfdSession) + num++ + + plugin.Log.WithField("revision", bfdData.GetRevision()). + Debugf("Processing resync for key: %q", bfdData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC BFD auth sessions %d", num) } -func appendACLInterface(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) appendACLInterface(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if data, stop := resyncData.GetNext(); stop { break } else { - value := &acl.AccessLists_Acl{} - err := data.GetValue(value) - if err == nil { - req.ACLs = append(req.ACLs, value) - num++ + aclData := &acl.AccessLists_Acl{} + if err := data.GetValue(aclData); err != nil { + plugin.Log.Errorf("error getting value of ACL: %v", err) + continue } + req.ACLs = append(req.ACLs, aclData) + num++ + + plugin.Log.WithField("revision", data.GetRevision()). + Debugf("Processing resync for key: %q", data.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC ACLs %d", num) } -func appendResyncInterface(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) appendResyncInterface(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if interfaceData, stop := resyncData.GetNext(); stop { break } else { - value := &interfaces.Interfaces_Interface{} - err := interfaceData.GetValue(value) - if err == nil { - req.Interfaces = append(req.Interfaces, value) - num++ + ifData := &interfaces.Interfaces_Interface{} + if err := interfaceData.GetValue(ifData); err != nil { + plugin.Log.Errorf("error getting value of interface: %v", err) + continue } + req.Interfaces = append(req.Interfaces, ifData) + num++ + + plugin.Log.WithField("revision", interfaceData.GetRevision()). + Debugf("Processing resync for key: %q", interfaceData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC interfaces %d", num) } -func resyncFeatures(resyncData datasync.KeyValIterator, req *DataResyncReq) { +func (plugin *Plugin) resyncFeatures(resyncData datasync.KeyValIterator, req *DataResyncReq) { + num := 0 for { appResyncData, stop := resyncData.GetNext() if stop { break } value := &l4.L4Features{} - err := appResyncData.GetValue(value) - if err == nil { - req.L4Features = value + if err := appResyncData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of L4 features: %v", err) + continue } + req.L4Features = value + num++ + + plugin.Log.WithField("revision", appResyncData.GetRevision()). + Debugf("Processing resync for key: %q", appResyncData.GetKey()) } + + plugin.Log.Debugf("Received RESYNC L4 features %d", num) } -func resyncAppendAppNs(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) resyncAppendAppNs(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if appResyncData, stop := resyncData.GetNext(); stop { break } else { value := &l4.AppNamespaces_AppNamespace{} - err := appResyncData.GetValue(value) - if err == nil { - req.AppNamespaces = append(req.AppNamespaces, value) - num++ + if err := appResyncData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of App namespaces: %v", err) + continue } + req.AppNamespaces = append(req.AppNamespaces, value) + num++ + + plugin.Log.WithField("revision", appResyncData.GetRevision()). + Debugf("Processing resync for key: %q", appResyncData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC app namespaces %d", num) } -func appendResyncStnRules(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) appendResyncStnRules(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if stnData, stop := resyncData.GetNext(); stop { break } else { value := &stn.STN_Rule{} - err := stnData.GetValue(value) - if err == nil { - req.StnRules = append(req.StnRules, value) - num++ + if err := stnData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of STN rules: %v", err) + continue } + req.StnRules = append(req.StnRules, value) + num++ + + plugin.Log.WithField("revision", stnData.GetRevision()). + Debugf("Processing resync for key: %q", stnData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC STN data %d", num) } -func resyncNatGlobal(resyncData datasync.KeyValIterator, req *DataResyncReq) { - natGlobalData, stop := resyncData.GetNext() - if stop { - return - } - value := &nat.Nat44Global{} - if err := natGlobalData.GetValue(value); err == nil { +func (plugin *Plugin) resyncNatGlobal(resyncData datasync.KeyValIterator, req *DataResyncReq) { + num := 0 + for { + natGlobalData, stop := resyncData.GetNext() + if stop { + break + } + value := &nat.Nat44Global{} + if err := natGlobalData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of NAT global: %v", err) + continue + } req.Nat44Global = value + num++ + + plugin.Log.WithField("revision", natGlobalData.GetRevision()). + Debugf("Processing resync for key: %q", natGlobalData.GetKey()) } + + plugin.Log.Debugf("Received RESYNC NAT global %d", num) } -func appendResyncSNat(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) appendResyncSNat(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if sNatData, stop := resyncData.GetNext(); stop { break } else { value := &nat.Nat44SNat_SNatConfig{} - err := sNatData.GetValue(value) - if err == nil { - req.Nat44SNat = append(req.Nat44SNat, value) - num++ + if err := sNatData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of SNAT: %v", err) + continue } + req.Nat44SNat = append(req.Nat44SNat, value) + num++ + + plugin.Log.WithField("revision", sNatData.GetRevision()). + Debugf("Processing resync for key: %q", sNatData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC SNAT global %d", num) } -func appendResyncDNat(resyncData datasync.KeyValIterator, req *DataResyncReq) int { +func (plugin *Plugin) appendResyncDNat(resyncData datasync.KeyValIterator, req *DataResyncReq) { num := 0 for { if dNatData, stop := resyncData.GetNext(); stop { break } else { value := &nat.Nat44DNat_DNatConfig{} - err := dNatData.GetValue(value) - if err == nil { - req.Nat44DNat = append(req.Nat44DNat, value) - num++ + if err := dNatData.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of DNAT: %v", err) + continue } + req.Nat44DNat = append(req.Nat44DNat, value) + num++ + + plugin.Log.WithField("revision", dNatData.GetRevision()). + Debugf("Processing resync for key: %q", dNatData.GetKey()) } } - return num + + plugin.Log.Debugf("Received RESYNC DNAT global %d", num) } -func appendResyncIPSec(resyncData datasync.KeyValIterator, req *DataResyncReq) (num int) { +func (plugin *Plugin) appendResyncIPSec(resyncData datasync.KeyValIterator, req *DataResyncReq) { + num := 0 for { if data, stop := resyncData.GetNext(); stop { break } else { if strings.HasPrefix(data.GetKey(), ipsec.KeyPrefixSPD) { value := &ipsec.SecurityPolicyDatabases_SPD{} - if err := data.GetValue(value); err == nil { - req.IPSecSPDs = append(req.IPSecSPDs, value) - num++ + if err := data.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of IPSec SPD: %v", err) + continue } + req.IPSecSPDs = append(req.IPSecSPDs, value) + num++ } else if strings.HasPrefix(data.GetKey(), ipsec.KeyPrefixSA) { value := &ipsec.SecurityAssociations_SA{} - if err := data.GetValue(value); err == nil { - req.IPSecSAs = append(req.IPSecSAs, value) - num++ + if err := data.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of IPSec SA: %v", err) + continue } + req.IPSecSAs = append(req.IPSecSAs, value) + num++ } else if strings.HasPrefix(data.GetKey(), ipsec.KeyPrefixTunnel) { value := &ipsec.TunnelInterfaces_Tunnel{} - if err := data.GetValue(value); err == nil { - req.IPSecTunnels = append(req.IPSecTunnels, value) - num++ + if err := data.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of IPSec tunnel: %v", err) + continue } + req.IPSecTunnels = append(req.IPSecTunnels, value) + num++ } + + plugin.Log.WithField("revision", data.GetRevision()). + Debugf("Processing resync for key: %q", data.GetKey()) } } - return + + plugin.Log.Debugf("Received RESYNC IPSec configs %d", num) } -func appendResyncSR(resyncData datasync.KeyValIterator, req *DataResyncReq) (num int) { +func (plugin *Plugin) appendResyncSR(resyncData datasync.KeyValIterator, req *DataResyncReq) { + num := 0 for { if data, stop := resyncData.GetNext(); stop { break } else { if strings.HasPrefix(data.GetKey(), srv6.LocalSIDPrefix()) { value := &srv6.LocalSID{} - if err := data.GetValue(value); err == nil { - req.LocalSids = append(req.LocalSids, value) - num++ + if err := data.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of SR sid: %v", err) + continue } + req.LocalSids = append(req.LocalSids, value) + num++ } else if strings.HasPrefix(data.GetKey(), srv6.PolicyPrefix()) { if srv6.IsPolicySegmentPrefix(data.GetKey()) { //Policy segment value := &srv6.PolicySegment{} - if err := data.GetValue(value); err == nil { - // TODO add proper error handling, everywhere around is missing handling of error case - if name, err := srv6.ParsePolicySegmentKey(data.GetKey()); err == nil { - req.SrPolicySegments = append(req.SrPolicySegments, &srplugin.NamedPolicySegment{Name: name, Segment: value}) - num++ - } + if err := data.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of SR policy segment: %v", err) + continue + } + if name, err := srv6.ParsePolicySegmentKey(data.GetKey()); err != nil { + plugin.Log.Errorf("failed to parse SR policy segment %s: %v", data.GetKey(), err) + continue + } else { + req.SrPolicySegments = append(req.SrPolicySegments, &srplugin.NamedPolicySegment{Name: name, Segment: value}) + num++ } } else { // Policy value := &srv6.Policy{} - if err := data.GetValue(value); err == nil { - req.SrPolicies = append(req.SrPolicies, value) - num++ + if err := data.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of SR policy: %v", err) + continue } + req.SrPolicies = append(req.SrPolicies, value) + num++ } } else if strings.HasPrefix(data.GetKey(), srv6.SteeringPrefix()) { value := &srv6.Steering{} - if err := data.GetValue(value); err == nil { - req.SrSteerings = append(req.SrSteerings, &srplugin.NamedSteering{Name: strings.TrimPrefix(data.GetKey(), srv6.SteeringPrefix()), Steering: value}) - num++ + if err := data.GetValue(value); err != nil { + plugin.Log.Errorf("error getting value of SR steering: %v", err) + continue } + req.SrSteerings = append(req.SrSteerings, &srplugin.NamedSteering{Name: strings.TrimPrefix(data.GetKey(), srv6.SteeringPrefix()), Steering: value}) + num++ } + + plugin.Log.WithField("revision", data.GetRevision()). + Debugf("Processing resync for key: %q", data.GetKey()) } } - return + + plugin.Log.Debugf("Received RESYNC SR configs %d", num) } // All registration for above channel select (it ensures proper order during initialization) are put here. diff --git a/plugins/vpp/ifplugin/afpacket_config.go b/plugins/vpp/ifplugin/afpacket_config.go index e01a59bf28..a426644377 100644 --- a/plugins/vpp/ifplugin/afpacket_config.go +++ b/plugins/vpp/ifplugin/afpacket_config.go @@ -15,8 +15,7 @@ package ifplugin import ( - "errors" - + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/vppcalls" @@ -46,8 +45,8 @@ type AfPacketConfig struct { } // GetAfPacketStatusByName looks for cached interface by its name and returns its state and data -func (plugin *AFPacketConfigurator) GetAfPacketStatusByName(name string) (exists, pending bool, ifData *intf.Interfaces_Interface) { - data, ok := plugin.afPacketByName[name] +func (c *AFPacketConfigurator) GetAfPacketStatusByName(name string) (exists, pending bool, ifData *intf.Interfaces_Interface) { + data, ok := c.afPacketByName[name] if data != nil { return ok, data.pending, data.config } @@ -55,8 +54,8 @@ func (plugin *AFPacketConfigurator) GetAfPacketStatusByName(name string) (exists } // GetAfPacketStatusByHost looks for cached interface by host interface and returns its state and data -func (plugin *AFPacketConfigurator) GetAfPacketStatusByHost(hostIf string) (exists, pending bool, ifData *intf.Interfaces_Interface) { - data, ok := plugin.afPacketByHostIf[hostIf] +func (c *AFPacketConfigurator) GetAfPacketStatusByHost(hostIf string) (exists, pending bool, ifData *intf.Interfaces_Interface) { + data, ok := c.afPacketByHostIf[hostIf] if data != nil { return ok, data.pending, data.config } @@ -64,163 +63,169 @@ func (plugin *AFPacketConfigurator) GetAfPacketStatusByHost(hostIf string) (exis } // GetHostInterfacesEntry looks for cached host interface and returns true if exists -func (plugin *AFPacketConfigurator) GetHostInterfacesEntry(hostIf string) bool { - _, ok := plugin.linuxHostInterfaces[hostIf] +func (c *AFPacketConfigurator) GetHostInterfacesEntry(hostIf string) bool { + _, ok := c.linuxHostInterfaces[hostIf] return ok } // Init members of AFPacketConfigurator. -func (plugin *AFPacketConfigurator) Init(logger logging.Logger, ifHandler vppcalls.IfVppAPI, linux interface{}, +func (c *AFPacketConfigurator) Init(logger logging.Logger, ifHandler vppcalls.IfVppAPI, linux interface{}, indexes ifaceidx.SwIfIndexRW) (err error) { - plugin.log = logger - plugin.log.Infof("Initializing AF-Packet configurator") + c.log = logger + c.log.Infof("Initializing AF-Packet configurator") // VPP API handler - plugin.ifHandler = ifHandler + c.ifHandler = ifHandler // Linux - plugin.linux = linux + c.linux = linux // Mappings - plugin.ifIndexes = indexes - plugin.afPacketByHostIf = make(map[string]*AfPacketConfig) - plugin.afPacketByName = make(map[string]*AfPacketConfig) - plugin.linuxHostInterfaces = make(map[string]struct{}) + c.ifIndexes = indexes + c.afPacketByHostIf = make(map[string]*AfPacketConfig) + c.afPacketByName = make(map[string]*AfPacketConfig) + c.linuxHostInterfaces = make(map[string]struct{}) return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *AFPacketConfigurator) clearMapping() { - plugin.afPacketByHostIf = make(map[string]*AfPacketConfig) - plugin.afPacketByName = make(map[string]*AfPacketConfig) +func (c *AFPacketConfigurator) clearMapping() { + c.afPacketByHostIf = make(map[string]*AfPacketConfig) + c.afPacketByName = make(map[string]*AfPacketConfig) } // ConfigureAfPacketInterface creates a new Afpacket interface or marks it as pending if the target host interface doesn't exist yet. -func (plugin *AFPacketConfigurator) ConfigureAfPacketInterface(afpacket *intf.Interfaces_Interface) (swIndex uint32, pending bool, err error) { +func (c *AFPacketConfigurator) ConfigureAfPacketInterface(afpacket *intf.Interfaces_Interface) (swIndex uint32, pending bool, err error) { if afpacket.Type != intf.InterfaceType_AF_PACKET_INTERFACE { - return 0, false, errors.New("expecting AfPacket interface") + return 0, false, errors.Errorf("expecting AfPacket-type interface, received %v", afpacket.Type) } - if plugin.linux != nil { - _, hostIfAvail := plugin.linuxHostInterfaces[afpacket.Afpacket.HostIfName] + if c.linux != nil { + _, hostIfAvail := c.linuxHostInterfaces[afpacket.Afpacket.HostIfName] if !hostIfAvail { - plugin.addToCache(afpacket, true) + c.addToCache(afpacket, true) return 0, true, nil } } - swIdx, err := plugin.ifHandler.AddAfPacketInterface(afpacket.Name, afpacket.PhysAddress, afpacket.Afpacket) + swIdx, err := c.ifHandler.AddAfPacketInterface(afpacket.Name, afpacket.PhysAddress, afpacket.Afpacket) if err != nil { - plugin.addToCache(afpacket, true) + c.addToCache(afpacket, true) return 0, true, err } - plugin.addToCache(afpacket, false) + c.addToCache(afpacket, false) // If the interface is not in pending state, register it - plugin.ifIndexes.RegisterName(afpacket.Name, swIdx, afpacket) + c.ifIndexes.RegisterName(afpacket.Name, swIdx, afpacket) + c.log.Debugf("Interface %s registered to mapping", afpacket.Name) return swIdx, false, nil } // ModifyAfPacketInterface updates the cache with afpacket configurations and tells InterfaceConfigurator if the interface // needs to be recreated for the changes to be applied. -func (plugin *AFPacketConfigurator) ModifyAfPacketInterface(newConfig *intf.Interfaces_Interface, +func (c *AFPacketConfigurator) ModifyAfPacketInterface(newConfig *intf.Interfaces_Interface, oldConfig *intf.Interfaces_Interface) (recreate bool, err error) { if oldConfig.Type != intf.InterfaceType_AF_PACKET_INTERFACE || newConfig.Type != intf.InterfaceType_AF_PACKET_INTERFACE { - return false, errors.New("expecting AfPacket interface") + return false, errors.Errorf("expecting AfPacket-type interface, received %v/%v", + oldConfig.Type, newConfig.Type) } - afpacket, found := plugin.afPacketByName[oldConfig.Name] + afpacket, found := c.afPacketByName[oldConfig.Name] if !found || afpacket.pending || (newConfig.Afpacket.HostIfName != oldConfig.Afpacket.HostIfName) { return true, nil } // rewrite cached configuration - plugin.addToCache(newConfig, false) + c.addToCache(newConfig, false) return false, nil } // DeleteAfPacketInterface removes Afpacket interface from VPP and from the cache. -func (plugin *AFPacketConfigurator) DeleteAfPacketInterface(afpacket *intf.Interfaces_Interface, ifIdx uint32) (err error) { +func (c *AFPacketConfigurator) DeleteAfPacketInterface(afpacket *intf.Interfaces_Interface, ifIdx uint32) (err error) { if afpacket.Type != intf.InterfaceType_AF_PACKET_INTERFACE { - return errors.New("expecting AfPacket interface") + return errors.Errorf("expecting AfPacket-type interface, received %v", afpacket.Type) } - config, found := plugin.afPacketByName[afpacket.Name] + config, found := c.afPacketByName[afpacket.Name] if !found || !config.pending { - err = plugin.ifHandler.DeleteAfPacketInterface(afpacket.Name, ifIdx, afpacket.GetAfpacket()) + err = c.ifHandler.DeleteAfPacketInterface(afpacket.Name, ifIdx, afpacket.GetAfpacket()) // unregister interface to let other plugins know that it is removed from the vpp - plugin.ifIndexes.UnregisterName(afpacket.Name) + c.ifIndexes.UnregisterName(afpacket.Name) + c.log.Debugf("Interface %s unregistered from mapping", afpacket.Name) } - plugin.removeFromCache(afpacket) + c.removeFromCache(afpacket) return err } // ResolveCreatedLinuxInterface reacts to a newly created Linux interface. -func (plugin *AFPacketConfigurator) ResolveCreatedLinuxInterface(interfaceName, hostIfName string, interfaceIndex uint32) *intf.Interfaces_Interface { - if plugin.linux == nil { - plugin.log.WithFields(logging.Fields{"ifName": interfaceName, "hostIfName": hostIfName}). - Warn("Unexpectedly learned about a new Linux interface") - return nil +func (c *AFPacketConfigurator) ResolveCreatedLinuxInterface(ifName, hostIfName string, ifIdx uint32) (*intf.Interfaces_Interface, error) { + if c.linux == nil { + c.log.Debugf("Registered linux interface %s not resolved, linux plugin disabled", ifName) + return nil, nil } - plugin.linuxHostInterfaces[hostIfName] = struct{}{} + c.linuxHostInterfaces[hostIfName] = struct{}{} + c.log.Debugf("Linux interface %s registered as host", hostIfName) - afpacket, found := plugin.afPacketByHostIf[hostIfName] + afpacket, found := c.afPacketByHostIf[hostIfName] if found { if !afpacket.pending { // this should not happen, log as warning - plugin.log.WithFields(logging.Fields{"ifName": interfaceName, "hostIfName": hostIfName}). - Warn("Re-creating already configured AFPacket interface") + c.log.Warn("Re-creating already configured AFPacket interface %s (host name: %s)", ifName, hostIfName) // remove the existing afpacket and let the interface configurator to re-create it - plugin.DeleteAfPacketInterface(afpacket.config, interfaceIndex) + if err := c.DeleteAfPacketInterface(afpacket.config, ifIdx); err != nil { + return nil, err + } } // afpacket is now free to get created - return afpacket.config + return afpacket.config, nil } - return nil // nothing to configure + return nil, nil // nothing to configure } // ResolveDeletedLinuxInterface reacts to a removed Linux interface. -func (plugin *AFPacketConfigurator) ResolveDeletedLinuxInterface(interfaceName, hostIfName string, ifIdx uint32) { - if plugin.linux == nil { - plugin.log.WithFields(logging.Fields{"ifName": interfaceName, "hostIfName": hostIfName}). - Warn("Unexpectedly learned about removed Linux interface") - return +func (c *AFPacketConfigurator) ResolveDeletedLinuxInterface(ifName, hostIfName string, ifIdx uint32) error { + if c.linux == nil { + c.log.Debugf("Unregistered linux interface %s not resolved, linux plugin disabled", ifName) + return nil } - delete(plugin.linuxHostInterfaces, hostIfName) + delete(c.linuxHostInterfaces, hostIfName) + c.log.Debugf("Linux interface %s unregistered as host", hostIfName) - afpacket, found := plugin.afPacketByHostIf[hostIfName] + afpacket, found := c.afPacketByHostIf[hostIfName] if found { // remove the interface and re-add as pending - if err := plugin.DeleteAfPacketInterface(afpacket.config, ifIdx); err != nil { - plugin.log.Errorf("Failed to remove af_packet interface %s (host name: %s)", interfaceName, hostIfName) - } else { - if _, _, err := plugin.ConfigureAfPacketInterface(afpacket.config); err != nil { - plugin.log.Errorf("Failed to configure af_packet interface %s (host name: %s)", interfaceName, hostIfName) - } + if err := c.DeleteAfPacketInterface(afpacket.config, ifIdx); err != nil { + return errors.Errorf("failed to remove af_packet interface %s (host name: %s): %v", + ifName, hostIfName, err) + } + if _, _, err := c.ConfigureAfPacketInterface(afpacket.config); err != nil { + return errors.Errorf("failed to configure af_packet interface %s (host name: %s): %v", + ifName, hostIfName, err) } } + return nil } // IsPendingAfPacket returns true if the given config belongs to pending Afpacket interface. -func (plugin *AFPacketConfigurator) IsPendingAfPacket(iface *intf.Interfaces_Interface) (pending bool) { - afpacket, found := plugin.afPacketByName[iface.Name] +func (c *AFPacketConfigurator) IsPendingAfPacket(iface *intf.Interfaces_Interface) (pending bool) { + afpacket, found := c.afPacketByName[iface.Name] return found && afpacket.pending } -func (plugin *AFPacketConfigurator) addToCache(afpacket *intf.Interfaces_Interface, pending bool) { +func (c *AFPacketConfigurator) addToCache(afpacket *intf.Interfaces_Interface, pending bool) { config := &AfPacketConfig{config: afpacket, pending: pending} - plugin.afPacketByHostIf[afpacket.Afpacket.HostIfName] = config - plugin.afPacketByName[afpacket.Name] = config - plugin.log.Debugf("Afpacket interface with name %v added to cache (hostIf: %s, pending: %t)", + c.afPacketByHostIf[afpacket.Afpacket.HostIfName] = config + c.afPacketByName[afpacket.Name] = config + c.log.Debugf("Afpacket interface with name %v added to cache (hostIf: %s, pending: %t)", afpacket.Name, afpacket.Afpacket.HostIfName, pending) } -func (plugin *AFPacketConfigurator) removeFromCache(afpacket *intf.Interfaces_Interface) { - delete(plugin.afPacketByName, afpacket.Name) - delete(plugin.afPacketByHostIf, afpacket.Afpacket.HostIfName) - plugin.log.Debugf("Afpacket interface with name %v removed from cache", afpacket.Name) +func (c *AFPacketConfigurator) removeFromCache(afpacket *intf.Interfaces_Interface) { + delete(c.afPacketByName, afpacket.Name) + delete(c.afPacketByHostIf, afpacket.Afpacket.HostIfName) + c.log.Debugf("Afpacket interface with name %v removed from cache", afpacket.Name) } diff --git a/plugins/vpp/ifplugin/afpacket_config_test.go b/plugins/vpp/ifplugin/afpacket_config_test.go index 407777941a..eb8dfd737f 100644 --- a/plugins/vpp/ifplugin/afpacket_config_test.go +++ b/plugins/vpp/ifplugin/afpacket_config_test.go @@ -338,7 +338,8 @@ func TestAfPacketNewLinuxInterfaceHostFound(t *testing.T) { _, pending, err := plugin.ConfigureAfPacketInterface(data) Expect(err).To(BeNil()) Expect(pending).To(BeTrue()) - config := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + config, err := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + Expect(err).To(BeNil()) Expect(config).ToNot(BeNil()) Expect(config.Afpacket.HostIfName).To(BeEquivalentTo("host1")) Expect(plugin.GetHostInterfacesEntry("host1")).To(BeTrue()) @@ -364,7 +365,8 @@ func TestAfPacketNewLinuxInterfaceHostNotPending(t *testing.T) { _, pending, err := plugin.ConfigureAfPacketInterface(data) Expect(err).To(BeNil()) Expect(pending).To(BeFalse()) - config := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + config, err := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + Expect(err).To(BeNil()) Expect(config).ToNot(BeNil()) Expect(config.Afpacket.HostIfName).To(BeEquivalentTo("host1")) Expect(plugin.GetHostInterfacesEntry("host1")).To(BeTrue()) @@ -378,7 +380,8 @@ func TestAfPacketNewLinuxInterfaceHostNotFound(t *testing.T) { Expect(plugin.GetHostInterfacesEntry("host1")).To(BeFalse()) // Test registered linux interface - config := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + config, err := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + Expect(err).To(BeNil()) Expect(config).To(BeNil()) Expect(plugin.GetHostInterfacesEntry("host1")).To(BeTrue()) } @@ -395,11 +398,12 @@ func TestAfPacketNewLinuxInterfaceNoLinux(t *testing.T) { swIfIndices := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "afpacket", nil)) // Configurator plugin := &ifplugin.AFPacketConfigurator{} - ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log, nil) + ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log) err := plugin.Init(log, ifHandler, nil, swIfIndices) Expect(err).To(BeNil()) // Test registered linux interface - config := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + config, err := plugin.ResolveCreatedLinuxInterface("host1", "host1", 1) + Expect(err).To(BeNil()) Expect(config).To(BeNil()) } @@ -452,7 +456,7 @@ func TestAfPacketDeleteLinuxInterfaceNoLinux(t *testing.T) { swIfIndices := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "afpacket", nil)) // Configurator plugin := &ifplugin.AFPacketConfigurator{} - ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log, nil) + ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log) err := plugin.Init(log, ifHandler, nil, swIfIndices) Expect(err).To(BeNil()) // Prepare @@ -506,7 +510,7 @@ func afPacketTestSetup(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.AFPacketCo swIfIndices := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "afpacket", nil)) // Configurator plugin := &ifplugin.AFPacketConfigurator{} - ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log, nil) + ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log) err := plugin.Init(log, ifHandler, struct{}{}, swIfIndices) Expect(err).To(BeNil()) diff --git a/plugins/vpp/ifplugin/bfd_config.go b/plugins/vpp/ifplugin/bfd_config.go index 9900c9a0d4..fc0ce3da51 100644 --- a/plugins/vpp/ifplugin/bfd_config.go +++ b/plugins/vpp/ifplugin/bfd_config.go @@ -14,17 +14,14 @@ package ifplugin -//go:generate protoc --proto_path=../model/bfd --gogo_out=../model/bfd ../model/bfd/bfd.proto - import ( - "fmt" "net" "strconv" "strings" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -44,7 +41,6 @@ type BFDConfigurator struct { ifIndexes ifaceidx.SwIfIndex bfdIDSeq uint32 - stopwatch *measure.Stopwatch // timer used to measure and store time // Base mappings sessionsIndexes idxvpp.NameToIdxRW keysIndexes idxvpp.NameToIdxRW @@ -57,83 +53,80 @@ type BFDConfigurator struct { } // Init members and channels -func (plugin *BFDConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *BFDConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-bfd-conf") - plugin.log.Infof("Initializing BFD configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("BFD-configurator", plugin.log) - } + c.log = logger.NewLogger("bfd-conf") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.sessionsIndexes = nametoidx.NewNameToIdx(plugin.log, "bfd_session_indexes", nil) - plugin.keysIndexes = nametoidx.NewNameToIdx(plugin.log, "bfd_auth_keys_indexes", nil) - plugin.echoFunctionIndex = nametoidx.NewNameToIdx(plugin.log, "bfd_echo_function_index", nil) + c.ifIndexes = swIfIndexes + c.sessionsIndexes = nametoidx.NewNameToIdx(c.log, "bfd_session_indexes", nil) + c.keysIndexes = nametoidx.NewNameToIdx(c.log, "bfd_auth_keys_indexes", nil) + c.echoFunctionIndex = nametoidx.NewNameToIdx(c.log, "bfd_echo_function_index", nil) // VPP channel - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handler - plugin.bfdHandler = vppcalls.NewBfdVppHandler(plugin.vppChan, plugin.ifIndexes, plugin.log, plugin.stopwatch) + c.bfdHandler = vppcalls.NewBfdVppHandler(c.vppChan, c.ifIndexes, c.log) + + c.log.Infof(" BFD configurator initialized") return nil } // Close GOVPP channel -func (plugin *BFDConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *BFDConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose BFD configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *BFDConfigurator) clearMapping() { - plugin.sessionsIndexes.Clear() - plugin.keysIndexes.Clear() - plugin.echoFunctionIndex.Clear() +func (c *BFDConfigurator) clearMapping() { + c.sessionsIndexes.Clear() + c.keysIndexes.Clear() + c.echoFunctionIndex.Clear() + + c.log.Debugf("BFD configurator mapping cleared") } // GetBfdSessionIndexes gives access to BFD session indexes -func (plugin *BFDConfigurator) GetBfdSessionIndexes() idxvpp.NameToIdxRW { - return plugin.sessionsIndexes +func (c *BFDConfigurator) GetBfdSessionIndexes() idxvpp.NameToIdxRW { + return c.sessionsIndexes } // GetBfdKeyIndexes gives access to BFD key indexes -func (plugin *BFDConfigurator) GetBfdKeyIndexes() idxvpp.NameToIdxRW { - return plugin.keysIndexes +func (c *BFDConfigurator) GetBfdKeyIndexes() idxvpp.NameToIdxRW { + return c.keysIndexes } // GetBfdEchoFunctionIndexes gives access to BFD echo function indexes -func (plugin *BFDConfigurator) GetBfdEchoFunctionIndexes() idxvpp.NameToIdxRW { - return plugin.echoFunctionIndex +func (c *BFDConfigurator) GetBfdEchoFunctionIndexes() idxvpp.NameToIdxRW { + return c.echoFunctionIndex } // ConfigureBfdSession configures bfd session (including authentication if exists). Provided interface has to contain // ip address defined in BFD as source -func (plugin *BFDConfigurator) ConfigureBfdSession(bfdInput *bfd.SingleHopBFD_Session) error { - plugin.log.Infof("Configuring BFD session for interface %v", bfdInput.Interface) - +func (c *BFDConfigurator) ConfigureBfdSession(bfdInput *bfd.SingleHopBFD_Session) error { // Verify interface presence - ifIdx, ifMeta, found := plugin.ifIndexes.LookupIdx(bfdInput.Interface) + ifIdx, ifMeta, found := c.ifIndexes.LookupIdx(bfdInput.Interface) if !found { - return fmt.Errorf("interface %v does not exist", bfdInput.Interface) + return errors.Errorf("interface %s does not exist", bfdInput.Interface) } // Check whether BFD contains source IP address if ifMeta == nil { - return fmt.Errorf("unable to get IP address data from interface %v", bfdInput.Interface) + return errors.Errorf("unable to get IP address data from interface %s", bfdInput.Interface) } var ipFound bool for _, ipAddr := range ifMeta.IpAddresses { // Remove suffix (BFD is not using it) ipWithMask := strings.Split(ipAddr, "/") if len(ipWithMask) == 0 { - return fmt.Errorf("incorrect IP address format %v", ipAddr) + return errors.Errorf("incorrect interface %s IP address %s format", bfdInput.Interface, ipAddr) } ipAddrWithoutMask := ipWithMask[0] // the first index is IP address if ipAddrWithoutMask == bfdInput.SourceAddress { @@ -142,46 +135,44 @@ func (plugin *BFDConfigurator) ConfigureBfdSession(bfdInput *bfd.SingleHopBFD_Se } } if !ipFound { - return fmt.Errorf("interface %v does not contain address %v required for BFD session", + return errors.Errorf("interface %s does not contain IP address %s required for BFD session", bfdInput.Interface, bfdInput.SourceAddress) } // Call vpp api - err := plugin.bfdHandler.AddBfdUDPSession(bfdInput, ifIdx, plugin.keysIndexes) + err := c.bfdHandler.AddBfdUDPSession(bfdInput, ifIdx, c.keysIndexes) if err != nil { - return fmt.Errorf("error while configuring BFD for interface %v", bfdInput.Interface) + return errors.Errorf("failed to configure BFD UDP session for interface %s: %v", bfdInput.Interface, err) } - plugin.sessionsIndexes.RegisterName(bfdInput.Interface, plugin.bfdIDSeq, nil) - plugin.log.Debugf("BFD session with interface %v registered. Idx: %v", bfdInput.Interface, plugin.bfdIDSeq) - plugin.bfdIDSeq++ + c.sessionsIndexes.RegisterName(bfdInput.Interface, c.bfdIDSeq, nil) + c.log.Debugf("BFD session for interface %s registered", bfdInput.Interface) + c.bfdIDSeq++ - plugin.log.Infof("BFD session for interface %v configured ", bfdInput.Interface) + c.log.Infof("BFD session for interface %s configured ", bfdInput.Interface) return nil } // ModifyBfdSession modifies BFD session fields. Source and destination IP address for old and new config has to be the // same. Authentication is NOT changed here, BFD modify bin api call does not support that -func (plugin *BFDConfigurator) ModifyBfdSession(oldBfdInput *bfd.SingleHopBFD_Session, newBfdInput *bfd.SingleHopBFD_Session) error { - plugin.log.Infof("Modifying BFD session for interface %v", newBfdInput.Interface) - +func (c *BFDConfigurator) ModifyBfdSession(oldBfdInput *bfd.SingleHopBFD_Session, newBfdInput *bfd.SingleHopBFD_Session) error { // Verify interface presence - ifIdx, ifMeta, found := plugin.ifIndexes.LookupIdx(newBfdInput.Interface) + ifIdx, ifMeta, found := c.ifIndexes.LookupIdx(newBfdInput.Interface) if !found { - return fmt.Errorf("interface %v does not exist", newBfdInput.Interface) + return errors.Errorf("interface %s does not exist", newBfdInput.Interface) } // Check whether BFD contains source IP address if ifMeta == nil { - return fmt.Errorf("unable to get IP address data from interface %v", newBfdInput.Interface) + return errors.Errorf("unable to get IP address data from interface %v", newBfdInput.Interface) } var ipFound bool for _, ipAddr := range ifMeta.IpAddresses { // Remove suffix ipWithMask := strings.Split(ipAddr, "/") if len(ipWithMask) == 0 { - return fmt.Errorf("incorrect IP address format %v", ipAddr) + return errors.Errorf("incorrect interface %s IP address %s format", newBfdInput.Interface, ipAddr) } ipAddrWithoutMask := ipWithMask[0] // the first index is IP address if ipAddrWithoutMask == newBfdInput.SourceAddress { @@ -190,222 +181,234 @@ func (plugin *BFDConfigurator) ModifyBfdSession(oldBfdInput *bfd.SingleHopBFD_Se } } if !ipFound { - return fmt.Errorf("interface %v does not contain address %v required for modified BFD session", + return errors.Errorf("interface %s does not contain IP address %s required for modified BFD session", newBfdInput.Interface, newBfdInput.SourceAddress) } // Find old BFD session - _, _, found = plugin.sessionsIndexes.LookupIdx(oldBfdInput.Interface) + _, _, found = c.sessionsIndexes.LookupIdx(oldBfdInput.Interface) if !found { - plugin.log.Printf("Previous BFD session does not exist, creating a new one for interface %v", newBfdInput.Interface) - err := plugin.bfdHandler.AddBfdUDPSession(newBfdInput, ifIdx, plugin.keysIndexes) + c.log.Warnf("Previous BFD session does not exist, creating a new one for interface %s", newBfdInput.Interface) + err := c.bfdHandler.AddBfdUDPSession(newBfdInput, ifIdx, c.keysIndexes) if err != nil { - return err + return errors.Errorf("failed to re-add BFD UDP session for interface %s: %v", newBfdInput.Interface, err) } - plugin.sessionsIndexes.RegisterName(newBfdInput.Interface, plugin.bfdIDSeq, nil) - plugin.bfdIDSeq++ + c.sessionsIndexes.RegisterName(newBfdInput.Interface, c.bfdIDSeq, nil) + c.log.Debugf("BFD session for interface %s registered", newBfdInput.Interface) + c.bfdIDSeq++ } else { // Compare source and destination addresses which cannot change if BFD session is modified // todo new BFD input should be compared to BFD data on the vpp, not the last change (old BFD data) if oldBfdInput.SourceAddress != newBfdInput.SourceAddress || oldBfdInput.DestinationAddress != newBfdInput.DestinationAddress { - return fmt.Errorf("unable to modify BFD session, adresses does not match. Odl session source: %v, dest: %v, new session source: %v, dest: %v", + return errors.Errorf("unable to modify BFD session, addresses do not match. Old session source: %s, dest: %s, new session source: %s, dest: %s", oldBfdInput.SourceAddress, oldBfdInput.DestinationAddress, newBfdInput.SourceAddress, newBfdInput.DestinationAddress) } - err := plugin.bfdHandler.ModifyBfdUDPSession(newBfdInput, plugin.ifIndexes) + err := c.bfdHandler.ModifyBfdUDPSession(newBfdInput, c.ifIndexes) if err != nil { - return err + return errors.Errorf("failed to modify BFD session for interface %s: %v", newBfdInput.Interface, err) } } - plugin.log.Infof("BFD session for interface %v modified ", newBfdInput.Interface) + c.log.Infof("Modified BFD session for interface %s", newBfdInput.Interface) return nil } // DeleteBfdSession removes BFD session -func (plugin *BFDConfigurator) DeleteBfdSession(bfdInput *bfd.SingleHopBFD_Session) error { - plugin.log.Info("Deleting BFD session") - - ifIndex, _, found := plugin.ifIndexes.LookupIdx(bfdInput.Interface) +func (c *BFDConfigurator) DeleteBfdSession(bfdInput *bfd.SingleHopBFD_Session) error { + ifIndex, _, found := c.ifIndexes.LookupIdx(bfdInput.Interface) if !found { - return fmt.Errorf("cannot remove BFD session, interface %s not found", bfdInput.Interface) + return errors.Errorf("cannot remove BFD session, interface %s not found", bfdInput.Interface) } - err := plugin.bfdHandler.DeleteBfdUDPSession(ifIndex, bfdInput.SourceAddress, bfdInput.DestinationAddress) + err := c.bfdHandler.DeleteBfdUDPSession(ifIndex, bfdInput.SourceAddress, bfdInput.DestinationAddress) if err != nil { - return fmt.Errorf("error while deleting BFD for interface %v", bfdInput.Interface) + return errors.Errorf("failed to remove BFD UDP session %s: %v", bfdInput.Interface, err) } - plugin.sessionsIndexes.UnregisterName(bfdInput.Interface) - plugin.log.Debugf("BFD session with interface %v unregistered", bfdInput.Interface) + c.sessionsIndexes.UnregisterName(bfdInput.Interface) + c.log.Debugf("BFD session for interface %v unregistered", bfdInput.Interface) + + c.log.Info("BFD session for interface %s removed", bfdInput.Interface) return nil } // ConfigureBfdAuthKey crates new authentication key which can be used for BFD session -func (plugin *BFDConfigurator) ConfigureBfdAuthKey(bfdAuthKey *bfd.SingleHopBFD_Key) error { - plugin.log.Infof("Configuring BFD authentication key with ID %v", bfdAuthKey.Id) - - err := plugin.bfdHandler.SetBfdUDPAuthenticationKey(bfdAuthKey) +func (c *BFDConfigurator) ConfigureBfdAuthKey(bfdAuthKey *bfd.SingleHopBFD_Key) error { + err := c.bfdHandler.SetBfdUDPAuthenticationKey(bfdAuthKey) if err != nil { - return fmt.Errorf("error while setting up BFD auth key with ID %v", bfdAuthKey.Id) + return errors.Errorf("failed to set BFD authentication key with name %s (ID %d): %v", + bfdAuthKey.Name, bfdAuthKey.Id, err) } authKeyIDAsString := AuthKeyIdentifier(bfdAuthKey.Id) - plugin.keysIndexes.RegisterName(authKeyIDAsString, plugin.bfdIDSeq, nil) - plugin.log.Debugf("BFD authentication key with id %v registered. Idx: %v", bfdAuthKey.Id, plugin.bfdIDSeq) - plugin.bfdIDSeq++ + c.keysIndexes.RegisterName(authKeyIDAsString, c.bfdIDSeq, nil) + c.log.Debugf("BFD authentication key with name %s (ID %d) registered", bfdAuthKey.Name, bfdAuthKey.Id) + c.bfdIDSeq++ - plugin.log.Infof("BFD authentication key with ID %v configured", bfdAuthKey.Id) + c.log.Infof("BFD authentication key with name %s (ID %d) configured", bfdAuthKey.Name, bfdAuthKey.Id) return nil } // ModifyBfdAuthKey modifies auth key fields. Key which is assigned to one or more BFD session cannot be modified -func (plugin *BFDConfigurator) ModifyBfdAuthKey(oldInput *bfd.SingleHopBFD_Key, newInput *bfd.SingleHopBFD_Key) error { - plugin.log.Infof("Modifying BFD auth key for ID %d", oldInput.Id) - +func (c *BFDConfigurator) ModifyBfdAuthKey(oldInput *bfd.SingleHopBFD_Key, newInput *bfd.SingleHopBFD_Key) error { // Check that this auth key is not used in any session - sessionList, err := plugin.bfdHandler.DumpBfdUDPSessionsWithID(newInput.Id) + sessionList, err := c.bfdHandler.DumpBfdUDPSessionsWithID(newInput.Id) if err != nil { - return fmt.Errorf("error while verifying authentication key usage. Id: %d: %v", oldInput.Id, err) + return errors.Errorf("error while verifying authentication key %s (ID: %d) usage: %v", + oldInput.Name, oldInput.Id, err) } if sessionList != nil && len(sessionList.Session) != 0 { // Authentication Key is used and cannot be removed directly for _, bfds := range sessionList.Session { sourceAddr := net.HardwareAddr(bfds.SourceAddress).String() destAddr := net.HardwareAddr(bfds.DestinationAddress).String() - ifIdx, _, found := plugin.ifIndexes.LookupIdx(bfds.Interface) + ifIdx, _, found := c.ifIndexes.LookupIdx(bfds.Interface) if !found { - plugin.log.Warnf("Modify BFD auth key: interface index for %s not found", bfds.Interface) + return errors.Errorf("Modify BFD auth key: interface index for %s not found in the mapping", + bfds.Interface) } - err := plugin.bfdHandler.DeleteBfdUDPSession(ifIdx, sourceAddr, destAddr) + err := c.bfdHandler.DeleteBfdUDPSession(ifIdx, sourceAddr, destAddr) if err != nil { - return err + return errors.Errorf("failed to remove BFD UDP session %s (temporary removal): %v", + bfds.Interface, err) } } - plugin.log.Debugf("%v session(s) temporary removed", len(sessionList.Session)) + c.log.Debugf("%d session(s) temporary removed while updating authentication keys", len(sessionList.Session)) } - err = plugin.bfdHandler.DeleteBfdUDPAuthenticationKey(oldInput) + err = c.bfdHandler.DeleteBfdUDPAuthenticationKey(oldInput) if err != nil { - return fmt.Errorf("error while removing BFD auth key with ID %d: %v", oldInput.Id, err) + return errors.Errorf("error while removing BFD auth key with name %s (ID %d): %v", + oldInput.Name, oldInput.Id, err) } - err = plugin.bfdHandler.SetBfdUDPAuthenticationKey(newInput) + err = c.bfdHandler.SetBfdUDPAuthenticationKey(newInput) if err != nil { - return fmt.Errorf("error while setting up BFD auth key with ID %d: %v", oldInput.Id, err) + return errors.Errorf("error while setting up BFD auth key with name %s (ID %d): %v", + oldInput.Name, oldInput.Id, err) } // Recreate BFD sessions if necessary if sessionList != nil && len(sessionList.Session) != 0 { for _, bfdSession := range sessionList.Session { - ifIdx, _, found := plugin.ifIndexes.LookupIdx(bfdSession.Interface) + ifIdx, _, found := c.ifIndexes.LookupIdx(bfdSession.Interface) if !found { - plugin.log.Warnf("Modify BFD auth key: interface index for %s not found", bfdSession.Interface) + return errors.Errorf("Modify BFD auth key: interface index for %s not found in the mapping", + bfdSession.Interface) } - err := plugin.bfdHandler.AddBfdUDPSession(bfdSession, ifIdx, plugin.keysIndexes) + err := c.bfdHandler.AddBfdUDPSession(bfdSession, ifIdx, c.keysIndexes) if err != nil { - return err + return errors.Errorf("failed to re-add BFD UDP session for interface %s: %v", + bfdSession.Interface, err) } } - plugin.log.Debugf("%v session(s) recreated", len(sessionList.Session)) + c.log.Debugf("%d session(s) recreated after authentication key update", len(sessionList.Session)) } + c.log.Infof("BFD authentication key with name %s (ID %d) modified", newInput.Name, newInput.Id) + return nil } // DeleteBfdAuthKey removes BFD authentication key but only if it is not used in any BFD session -func (plugin *BFDConfigurator) DeleteBfdAuthKey(bfdInput *bfd.SingleHopBFD_Key) error { - plugin.log.Info("Deleting BFD auth key") - +func (c *BFDConfigurator) DeleteBfdAuthKey(bfdInput *bfd.SingleHopBFD_Key) error { // Check that this auth key is not used in any session - sessionList, err := plugin.bfdHandler.DumpBfdUDPSessionsWithID(bfdInput.Id) + // TODO perhaps bfd session mapping can be used instead of dump + sessionList, err := c.bfdHandler.DumpBfdUDPSessionsWithID(bfdInput.Id) if err != nil { - return fmt.Errorf("error while verifying authentication key usage. Id: %v", bfdInput.Id) + return errors.Errorf("Delete BFD auth key %s (ID %d): failed to dump BFD sessions: %v", + bfdInput.Name, bfdInput.Id, err) } if sessionList != nil && len(sessionList.Session) != 0 { // Authentication Key is used and cannot be removed directly for _, bfds := range sessionList.Session { - ifIdx, _, found := plugin.ifIndexes.LookupIdx(bfds.Interface) + ifIdx, _, found := c.ifIndexes.LookupIdx(bfds.Interface) if !found { - plugin.log.Warnf("Delete BFD auth key: interface index for %s not found", bfds.Interface) + return errors.Errorf("Delete BFD auth key: interface index %s not found in the mapping", + bfds.Interface) } - err := plugin.bfdHandler.DeleteBfdUDPSession(ifIdx, bfds.SourceAddress, bfds.DestinationAddress) + err := c.bfdHandler.DeleteBfdUDPSession(ifIdx, bfds.SourceAddress, bfds.DestinationAddress) if err != nil { - return err + return errors.Errorf("failed to remove BFD UDP session %s: %v", bfds.Interface, err) } } - plugin.log.Debugf("%v session(s) temporary removed", len(sessionList.Session)) + c.log.Debugf("%d session(s) temporary removed", len(sessionList.Session)) } - err = plugin.bfdHandler.DeleteBfdUDPAuthenticationKey(bfdInput) + err = c.bfdHandler.DeleteBfdUDPAuthenticationKey(bfdInput) if err != nil { - return fmt.Errorf("error while removing BFD auth key with ID %v", bfdInput.Id) + return errors.Errorf("error while removing BFD auth key %s (ID %d): %v", bfdInput.Name, bfdInput.Id, err) } authKeyIDAsString := AuthKeyIdentifier(bfdInput.Id) - plugin.keysIndexes.UnregisterName(authKeyIDAsString) - plugin.log.Debugf("BFD authentication key with id %v unregistered", bfdInput.Id) + c.keysIndexes.UnregisterName(authKeyIDAsString) + c.log.Debugf("BFD authentication key %s (ID %d) unregistered", bfdInput.Name, bfdInput.Id) // Recreate BFD sessions if necessary if sessionList != nil && len(sessionList.Session) != 0 { for _, bfdSession := range sessionList.Session { - ifIdx, _, found := plugin.ifIndexes.LookupIdx(bfdSession.Interface) + ifIdx, _, found := c.ifIndexes.LookupIdx(bfdSession.Interface) if !found { - plugin.log.Warnf("Delete BFD auth key: interface index for %s not found", bfdSession.Interface) + return errors.Errorf("Delete BFD auth key: interface index for %s not found", bfdSession.Interface) } - err := plugin.bfdHandler.AddBfdUDPSession(bfdSession, ifIdx, plugin.keysIndexes) + err := c.bfdHandler.AddBfdUDPSession(bfdSession, ifIdx, c.keysIndexes) if err != nil { - return err + return errors.Errorf("failed to add BFD UDP session for interface %s: %v", + bfdSession.Interface, err) } } - plugin.log.Debugf("%v session(s) recreated", len(sessionList.Session)) + c.log.Debugf("%d session(s) recreated", len(sessionList.Session)) } return nil } // ConfigureBfdEchoFunction is used to setup BFD Echo function on existing interface -func (plugin *BFDConfigurator) ConfigureBfdEchoFunction(bfdInput *bfd.SingleHopBFD_EchoFunction) error { - plugin.log.Infof("Configuring BFD echo function for source interface %v", bfdInput.EchoSourceInterface) - +func (c *BFDConfigurator) ConfigureBfdEchoFunction(bfdInput *bfd.SingleHopBFD_EchoFunction) error { // Verify interface presence - _, _, found := plugin.ifIndexes.LookupIdx(bfdInput.EchoSourceInterface) + _, _, found := c.ifIndexes.LookupIdx(bfdInput.EchoSourceInterface) if !found { - return fmt.Errorf("interface %v does not exist", bfdInput.EchoSourceInterface) + return errors.Errorf("BFD echo function add: interface %s does not exist", bfdInput.EchoSourceInterface) } - err := plugin.bfdHandler.AddBfdEchoFunction(bfdInput, plugin.ifIndexes) + err := c.bfdHandler.AddBfdEchoFunction(bfdInput, c.ifIndexes) if err != nil { - return fmt.Errorf("error while setting up BFD echo source with interface %v", bfdInput.EchoSourceInterface) + return errors.Errorf("failed to set BFD echo source for interface %s: %v", + bfdInput.EchoSourceInterface, err) } - plugin.echoFunctionIndex.RegisterName(bfdInput.EchoSourceInterface, plugin.bfdIDSeq, nil) - plugin.log.Debugf("BFD echo function with interface %v registered. Idx: %v", bfdInput.EchoSourceInterface, plugin.bfdIDSeq) - plugin.bfdIDSeq++ + c.echoFunctionIndex.RegisterName(bfdInput.EchoSourceInterface, c.bfdIDSeq, nil) + c.log.Debugf("BFD echo function for interface %s registered", bfdInput.EchoSourceInterface) + c.bfdIDSeq++ - plugin.log.Infof("Echo source set to interface %v ", bfdInput.EchoSourceInterface) + c.log.Infof("BFD echo source set for interface %s ", bfdInput.EchoSourceInterface) return nil } // ModifyBfdEchoFunction handles echo function changes -func (plugin *BFDConfigurator) ModifyBfdEchoFunction(oldInput *bfd.SingleHopBFD_EchoFunction, newInput *bfd.SingleHopBFD_EchoFunction) error { - plugin.log.Debug("There is nothing to modify for BFD echo function") +func (c *BFDConfigurator) ModifyBfdEchoFunction(oldInput *bfd.SingleHopBFD_EchoFunction, newInput *bfd.SingleHopBFD_EchoFunction) error { + c.log.Warnf("There is nothing to modify for BFD echo function") // NO-OP + + /* todo: the reason is echo function uses interface name in key, so if interface is changed, the key changes (despite + there is 'name' field in the model which is currently unused). Maybe it would be better to use name in the key, + and change interface in modify as usually */ + return nil } // DeleteBfdEchoFunction removes BFD echo function -func (plugin *BFDConfigurator) DeleteBfdEchoFunction(bfdInput *bfd.SingleHopBFD_EchoFunction) error { - plugin.log.Info("Deleting BFD echo function") - - err := plugin.bfdHandler.DeleteBfdEchoFunction() +func (c *BFDConfigurator) DeleteBfdEchoFunction(bfdInput *bfd.SingleHopBFD_EchoFunction) error { + err := c.bfdHandler.DeleteBfdEchoFunction() if err != nil { - return fmt.Errorf("error while removing BFD echo source with interface %v", bfdInput.EchoSourceInterface) + return errors.Errorf("error while removing BFD echo source for interface %s: %v", + bfdInput.EchoSourceInterface, err) } - plugin.echoFunctionIndex.UnregisterName(bfdInput.EchoSourceInterface) - plugin.log.Debugf("BFD echo function with interface %v unregistered", bfdInput.EchoSourceInterface) + c.echoFunctionIndex.UnregisterName(bfdInput.EchoSourceInterface) + c.log.Debugf("BFD echo function for interface %s unregistered", bfdInput.EchoSourceInterface) - plugin.log.Info("Echo source unset") + c.log.Infof("Echo source unset (was set to %s)", bfdInput.EchoSourceInterface) return nil } @@ -414,3 +417,17 @@ func (plugin *BFDConfigurator) DeleteBfdEchoFunction(bfdInput *bfd.SingleHopBFD_ func AuthKeyIdentifier(id uint32) string { return strconv.Itoa(int(id)) } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *BFDConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/ifplugin/bfd_config_test.go b/plugins/vpp/ifplugin/bfd_config_test.go index 396f429eb2..ec0b39f235 100644 --- a/plugins/vpp/ifplugin/bfd_config_test.go +++ b/plugins/vpp/ifplugin/bfd_config_test.go @@ -15,14 +15,12 @@ package ifplugin_test import ( + "git.fd.io/govpp.git/core" "net" - "strings" "testing" "git.fd.io/govpp.git/adapter/mock" - "git.fd.io/govpp.git/core" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/logrus" "github.com/ligato/vpp-agent/idxvpp/nametoidx" bfd_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/bfd" "github.com/ligato/vpp-agent/plugins/vpp/binapi/vpe" @@ -351,21 +349,34 @@ func TestBfdConfiguratorModifyUnusedAuthKey(t *testing.T) { // Modify BFD authentication key which is used in session func TestBfdConfiguratorModifyUsedAuthKey(t *testing.T) { - var err error - // Setup - ctx, connection, plugin, _ := bfdTestSetup(t) + ctx, connection, plugin, swIfIdx := bfdTestSetup(t) defer bfdTestTeardown(connection, plugin) + // Reply handler - ctx.MockVpp.RegisterBinAPITypes(bfd_api.Types) - ctx.MockVpp.RegisterBinAPITypes(vpe.Types) - ctx.MockVpp.MockReplyHandler(bfdVppMockHandler(ctx.MockVpp)) + ctx.MockReplies([]*vppcallmock.HandleReplies{ + { + Name: (&bfd_api.BfdUDPSessionDump{}).GetMessageName(), + Ping: true, + Message: &bfd_api.BfdUDPSessionDetails{ + SwIfIndex: 1, + LocalAddr: net.ParseIP("10.0.0.1").To4(), + PeerAddr: net.ParseIP("10.0.0.2").To4(), + IsAuthenticated: 1, + BfdKeyID: 1, + }, + }, + }) + // Data oldData := getTestBfdAuthKey("key1", "secret", 1, 1, bfd.SingleHopBFD_Key_KEYED_SHA1) newData := getTestBfdAuthKey("key1", "secret", 1, 1, bfd.SingleHopBFD_Key_METICULOUS_KEYED_SHA1) + // Register + swIfIdx.RegisterName("if1", 1, nil) plugin.GetBfdKeyIndexes().RegisterName(ifplugin.AuthKeyIdentifier(oldData.Id), 1, nil) + // Test key modification - err = plugin.ModifyBfdAuthKey(oldData, newData) + err := plugin.ModifyBfdAuthKey(oldData, newData) Expect(err).To(BeNil()) } @@ -390,20 +401,33 @@ func TestBfdConfiguratorDeleteUnusedAuthKey(t *testing.T) { // Delete BFD authentication key which is used in session func TestBfdConfiguratorDeleteUsedAuthKey(t *testing.T) { - var err error - // Setup - ctx, connection, plugin, _ := bfdTestSetup(t) + ctx, connection, plugin, swIfIdx := bfdTestSetup(t) defer bfdTestTeardown(connection, plugin) + // Reply handler - ctx.MockVpp.RegisterBinAPITypes(bfd_api.Types) - ctx.MockVpp.RegisterBinAPITypes(vpe.Types) - ctx.MockVpp.MockReplyHandler(bfdVppMockHandler(ctx.MockVpp)) + ctx.MockReplies([]*vppcallmock.HandleReplies{ + { + Name: (&bfd_api.BfdUDPSessionDump{}).GetMessageName(), + Ping: true, + Message: &bfd_api.BfdUDPSessionDetails{ + SwIfIndex: 1, + LocalAddr: net.ParseIP("10.0.0.1").To4(), + PeerAddr: net.ParseIP("10.0.0.2").To4(), + IsAuthenticated: 1, + BfdKeyID: 1, + }, + }, + }) + // Data data := getTestBfdAuthKey("key1", "secret", 1, 1, bfd.SingleHopBFD_Key_KEYED_SHA1) + // Register + swIfIdx.RegisterName("if1", 1, nil) plugin.GetBfdKeyIndexes().RegisterName(ifplugin.AuthKeyIdentifier(data.Id), 1, nil) + // Test key modification - err = plugin.DeleteBfdAuthKey(data) + err := plugin.DeleteBfdAuthKey(data) Expect(err).To(BeNil()) } @@ -495,7 +519,7 @@ func TestBfdConfiguratorEchoFunctionDeleteError(t *testing.T) { func bfdTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *ifplugin.BFDConfigurator, ifaceidx.SwIfIndexRW) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -506,7 +530,7 @@ func bfdTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *ifplug swIfIndices := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "stn", nil)) // Configurator plugin := &ifplugin.BFDConfigurator{} - err = plugin.Init(log, connection, swIfIndices, true) + err = plugin.Init(log, connection, swIfIndices) Expect(err).To(BeNil()) return ctx, connection, plugin, swIfIndices @@ -519,46 +543,6 @@ func bfdTestTeardown(connection *core.Connection, plugin *ifplugin.BFDConfigurat logging.DefaultRegistry.ClearRegistry() } -func bfdVppMockHandler(vppMock *mock.VppAdapter) mock.ReplyHandler { - var sendControlPing bool - return func(request mock.MessageDTO) (reply []byte, msgID uint16, prepared bool) { - logrus.DefaultLogger().Errorf("recived request %v", request.MsgName) - if sendControlPing { - sendControlPing = false - data := &vpe.ControlPingReply{} - reply, err := vppMock.ReplyBytes(request, data) - Expect(err).To(BeNil()) - msgID, err := vppMock.GetMsgID(data.GetMessageName(), data.GetCrcString()) - Expect(err).To(BeNil()) - return reply, msgID, true - } - if strings.HasSuffix(request.MsgName, "_dump") { - // Send control ping after first iteration - sendControlPing = true - data := &bfd_api.BfdUDPSessionDetails{ - SwIfIndex: 1, - LocalAddr: net.ParseIP("10.0.0.1").To4(), - PeerAddr: net.ParseIP("10.0.0.2").To4(), - IsAuthenticated: 1, - BfdKeyID: 1, - } - reply, err := vppMock.ReplyBytes(request, data) - Expect(err).To(BeNil()) - msgID, err := vppMock.GetMsgID(data.GetMessageName(), data.GetCrcString()) - Expect(err).To(BeNil()) - return reply, msgID, true - } else { - if replyMsg, msgID, ok := vppMock.ReplyFor(request.MsgName); ok { - reply, err := vppMock.ReplyBytes(request, replyMsg) - Expect(err).To(BeNil()) - return reply, msgID, true - } - } - - return reply, 0, false - } -} - /* BFD Test Data */ func getTestBfdSession(ifName, srcAddr string) *bfd.SingleHopBFD_Session { diff --git a/plugins/vpp/ifplugin/data_resync.go b/plugins/vpp/ifplugin/data_resync.go index ae24ec8a79..b4abf5f9df 100644 --- a/plugins/vpp/ifplugin/data_resync.go +++ b/plugins/vpp/ifplugin/data_resync.go @@ -16,10 +16,11 @@ package ifplugin import ( "bytes" - "fmt" "net" "strings" + "github.com/go-errors/errors" + "github.com/gogo/protobuf/proto" "github.com/ligato/vpp-agent/plugins/vpp/model/bfd" intf "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" "github.com/ligato/vpp-agent/plugins/vpp/model/nat" @@ -38,30 +39,22 @@ const ifTempName = "temp-if-name" // 3. Untagged interfaces are correlated heuristically (mac address, ip addresses). If correlation // is found, interface is modified if needed and registered. // 4. All remaining NB interfaces are configured -func (plugin *InterfaceConfigurator) Resync(nbIfs []*intf.Interfaces_Interface) (errs []error) { - plugin.log.WithField("cfg", plugin).Debugf("RESYNC Interface begin for %v", nbIfs) - // Calculate and log interface resync - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *InterfaceConfigurator) Resync(nbIfs []*intf.Interfaces_Interface) error { // Re-initialize cache - if err := plugin.clearMapping(); err != nil { - return []error{err} + if err := c.clearMapping(); err != nil { + return err } - plugin.afPacketConfigurator.clearMapping() + c.afPacketConfigurator.clearMapping() var err error - if plugin.memifScCache, err = plugin.ifHandler.DumpMemifSocketDetails(); err != nil { - return []error{err} + if c.memifScCache, err = c.ifHandler.DumpMemifSocketDetails(); err != nil { + return errors.Errorf("interface resync error: failed to dump memif socket details: %v", err) } // Dump current state of the VPP interfaces - vppIfs, err := plugin.ifHandler.DumpInterfaces() + vppIfs, err := c.ifHandler.DumpInterfaces() if err != nil { - return []error{err} + return errors.Errorf("interface resync error: failed to dump interfaces: %v", err) } // Cache for untagged interfaces. All un-named interfaces have to be correlated @@ -71,14 +64,14 @@ func (plugin *InterfaceConfigurator) Resync(nbIfs []*intf.Interfaces_Interface) for vppIfIdx, vppIf := range vppIfs { if vppIfIdx == 0 { // Register local0 interface with zero index - if err := plugin.registerInterface(vppIf.Meta.InternalName, vppIfIdx, vppIf.Interface); err != nil { - errs = append(errs, err) + if err := c.registerInterface(vppIf.Meta.InternalName, vppIfIdx, vppIf.Interface); err != nil { + return errors.Errorf("interface resync error: %v", err) } continue } if vppIf.Interface.Name == "" { // If interface has no name, it is stored as unnamed and resolved later - plugin.log.Debugf("RESYNC interfaces: interface %v has no name (tag)", vppIfIdx) + c.log.Debugf("Interface resync: interface %v has no name (tag)", vppIfIdx) unnamedVppIfs[vppIfIdx] = vppIf.Interface continue } @@ -87,32 +80,32 @@ func (plugin *InterfaceConfigurator) Resync(nbIfs []*intf.Interfaces_Interface) if vppIf.Interface.Name == nbIf.Name { correlated = true // Register interface to mapping and VPP tag/index - if err := plugin.registerInterface(vppIf.Interface.Name, vppIfIdx, nbIf); err != nil { - errs = append(errs, err) + if err := c.registerInterface(vppIf.Interface.Name, vppIfIdx, nbIf); err != nil { + return errors.Errorf("interface resync error: %v", err) } // Calculate whether modification is needed - if plugin.isIfModified(nbIf, vppIf.Interface) { - plugin.log.Debugf("RESYNC interfaces: modifying interface %v", vppIf.Interface.Name) - if err = plugin.ModifyVPPInterface(nbIf, vppIf.Interface); err != nil { - plugin.log.Errorf("Error while modifying interface: %v", err) - errs = append(errs, err) + if c.isIfModified(nbIf, vppIf.Interface) { + c.log.Debugf("Interface resync: modifying interface %v", vppIf.Interface.Name) + if err = c.ModifyVPPInterface(nbIf, vppIf.Interface); err != nil { + return errors.Errorf("interface resync error: failed to modify interface %s: %v", + vppIf.Interface.Name, err) } } else { - plugin.log.Debugf("RESYNC interfaces: %v registered without additional changes", vppIf.Interface.Name) + c.log.Debugf("Interface resync: %s registered without additional changes", vppIf.Interface.Name) } break } } if !correlated { // Register interface before removal (to keep state consistent) - if err := plugin.registerInterface(vppIf.Interface.Name, vppIfIdx, vppIf.Interface); err != nil { - errs = append(errs, err) + if err := c.registerInterface(vppIf.Interface.Name, vppIfIdx, vppIf.Interface); err != nil { + return errors.Errorf("interface resync error: %v", err) } // VPP interface is obsolete and will be removed (un-configured if physical device) - plugin.log.Debugf("RESYNC interfaces: removing obsolete interface %v", vppIf.Interface.Name) - if err = plugin.deleteVPPInterface(vppIf.Interface, vppIfIdx); err != nil { - plugin.log.Errorf("Error while removing interface: %v", err) - errs = append(errs, err) + c.log.Debugf("RESYNC interfaces: removing obsolete interface %v", vppIf.Interface.Name) + if err = c.deleteVPPInterface(vppIf.Interface, vppIfIdx); err != nil { + return errors.Errorf("interface resync error: failed to remove interface %s: %v", + vppIf.Interface.Name, err) } } } @@ -123,12 +116,12 @@ func (plugin *InterfaceConfigurator) Resync(nbIfs []*intf.Interfaces_Interface) var correlatedIf *intf.Interfaces_Interface for _, nbIf := range nbIfs { // Already registered interfaces cannot be correlated again - _, _, found := plugin.swIfIndexes.LookupIdx(nbIf.Name) + _, _, found := c.swIfIndexes.LookupIdx(nbIf.Name) if found { continue } // Try to correlate heuristically - correlatedIf = plugin.correlateInterface(vppIf, nbIf) + correlatedIf = c.correlateInterface(vppIf, nbIf) if correlatedIf != nil { break } @@ -136,29 +129,29 @@ func (plugin *InterfaceConfigurator) Resync(nbIfs []*intf.Interfaces_Interface) if correlatedIf != nil { // Register interface - if err := plugin.registerInterface(correlatedIf.Name, vppIfIdx, correlatedIf); err != nil { - errs = append(errs, err) + if err := c.registerInterface(correlatedIf.Name, vppIfIdx, correlatedIf); err != nil { + return errors.Errorf("interface resync error: %v", err) } // Calculate whether modification is needed - if plugin.isIfModified(correlatedIf, vppIf) { - plugin.log.Debugf("RESYNC interfaces: modifying correlated interface %v", vppIf.Name) - if err = plugin.ModifyVPPInterface(correlatedIf, vppIf); err != nil { - plugin.log.Errorf("Error while modifying correlated interface: %v", err) - errs = append(errs, err) + if c.isIfModified(correlatedIf, vppIf) { + c.log.Debugf("Interface resync: modifying correlated interface %v", vppIf.Name) + if err = c.ModifyVPPInterface(correlatedIf, vppIf); err != nil { + return errors.Errorf("interface resync error: failed to modify correlated interface %s: %v", + vppIf.Name, err) } } else { - plugin.log.Debugf("RESYNC interfaces: correlated %v registered without additional changes", vppIf.Name) + c.log.Debugf("interface resync: correlated %v registered without additional changes", vppIf.Name) } } else { // Register interface with temporary name (will be unregistered during removal) - if err := plugin.registerInterface(ifTempName, vppIfIdx, vppIf); err != nil { - errs = append(errs, err) + if err := c.registerInterface(ifTempName, vppIfIdx, vppIf); err != nil { + return errors.Errorf("interface resync error: %v", err) } // VPP interface cannot be correlated and will be removed - plugin.log.Debugf("RESYNC interfaces: removing interface %v", vppIf.Name) - if err = plugin.deleteVPPInterface(vppIf, vppIfIdx); err != nil { - plugin.log.Errorf("Error while removing interface: %v", err) - errs = append(errs, err) + c.log.Debugf("Interface resync: removing interface %v", vppIf.Name) + if err = c.deleteVPPInterface(vppIf, vppIfIdx); err != nil { + return errors.Errorf("interface resync error: failed to remove interface %s: %v", + vppIf.Name, err) } } } @@ -166,46 +159,46 @@ func (plugin *InterfaceConfigurator) Resync(nbIfs []*intf.Interfaces_Interface) // Last step is to configure all new (not-yet-registered) interfaces for _, nbIf := range nbIfs { // If interface is registered, it was already processed - _, _, found := plugin.swIfIndexes.LookupIdx(nbIf.Name) + _, _, found := c.swIfIndexes.LookupIdx(nbIf.Name) if !found { - plugin.log.Debugf("RESYNC interfaces: configuring new interface %v", nbIf.Name) - if err := plugin.ConfigureVPPInterface(nbIf); err != nil { - plugin.log.Errorf("Error while configuring interface: %v", err) - errs = append(errs, err) + c.log.Debugf("Interface resync: configuring new interface %v", nbIf.Name) + if err := c.ConfigureVPPInterface(nbIf); err != nil { + return errors.Errorf("interface resync error: failed to configure interface %s: %v", + nbIf.Name, err) } } } // update the interfaces state data in memory - plugin.PropagateIfDetailsToStatus() + if err := c.propagateIfDetailsToStatus(); err != nil { + return errors.Errorf("interface resync error: %v", err) + } - plugin.log.WithField("cfg", plugin).Debug("RESYNC Interface end.") + c.log.Info("Interface resync done") - return + return nil } // VerifyVPPConfigPresence dumps VPP interface configuration on the vpp. If there are any interfaces configured (except // the local0), it returns false (do not interrupt the resto of the resync), otherwise returns true -func (plugin *InterfaceConfigurator) VerifyVPPConfigPresence(nbIfaces []*intf.Interfaces_Interface) bool { - plugin.log.WithField("cfg", plugin).Debug("RESYNC Interface begin.") +func (c *InterfaceConfigurator) VerifyVPPConfigPresence(nbIfaces []*intf.Interfaces_Interface) bool { // notify that the resync should be stopped var stop bool // Step 0: Dump actual state of the VPP - vppIfaces, err := plugin.ifHandler.DumpInterfaces() + vppIfaces, err := c.ifHandler.DumpInterfaces() if err != nil { + // Do not return error here return stop } - plugin.log.Infof("dumped %d interfaces", len(vppIfaces)) - // The strategy is optimize-cold-start, so look over all dumped VPP interfaces and check for the configured ones // (leave out the local0). If there are any other interfaces, return true (resync will continue). // If not, return a false flag which cancels the VPP resync operation. - plugin.log.Info("optimize-cold-start VPP resync strategy chosen, resolving...") + c.log.Info("optimize-cold-start VPP resync strategy chosen, resolving...") if len(vppIfaces) == 0 { stop = true - plugin.log.Infof("...VPP resync interrupted assuming there is no configuration on the VPP (no interface was found)") + c.log.Infof("...VPP resync interrupted assuming there is no configuration on the VPP (no interface was found)") return stop } // if interface exists, try to find local0 interface (index 0) @@ -213,36 +206,27 @@ func (plugin *InterfaceConfigurator) VerifyVPPConfigPresence(nbIfaces []*intf.In // in case local0 is the only interface on the vpp, stop the resync if len(vppIfaces) == 1 && ok { stop = true - plugin.log.Infof("...VPP resync interrupted assuming there is no configuration on the VPP (only local0 was found)") + c.log.Infof("...VPP resync interrupted assuming there is no configuration on the VPP (only local0 was found)") return stop } // otherwise continue normally - plugin.log.Infof("... VPP configuration found, continue with VPP resync") + c.log.Infof("... VPP configuration found, continue with VPP resync") return stop } // ResyncSession writes BFD sessions to the empty VPP -func (plugin *BFDConfigurator) ResyncSession(nbSessions []*bfd.SingleHopBFD_Session) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC BFD Session begin.") - // Calculate and log bfd resync - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *BFDConfigurator) ResyncSession(nbSessions []*bfd.SingleHopBFD_Session) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Dump all BFD vppSessions - vppBfdSessions, err := plugin.bfdHandler.DumpBfdSessions() + vppBfdSessions, err := c.bfdHandler.DumpBfdSessions() if err != nil { - return err + return errors.Errorf("BFD resync error: failed to dump BFD sessions: %v", err) } // Correlate existing BFD sessions from the VPP and NB config, configure new ones - var wasErr error for _, nbSession := range nbSessions { // look for configured session var found bool @@ -250,20 +234,18 @@ func (plugin *BFDConfigurator) ResyncSession(nbSessions []*bfd.SingleHopBFD_Sess // compare fixed fields if nbSession.Interface == vppSession.Interface && nbSession.SourceAddress == vppSession.SourceAddress && nbSession.DestinationAddress == vppSession.DestinationAddress { - plugin.log.Debugf("found configured BFD session for interface %v", nbSession.Interface) - plugin.sessionsIndexes.RegisterName(nbSession.Interface, plugin.bfdIDSeq, nil) - if err := plugin.ModifyBfdSession(vppSession, nbSession); err != nil { - plugin.log.Errorf("BFD resync: error modifying BFD session for interface %v: %v", nbSession.Interface, err) - wasErr = err + c.sessionsIndexes.RegisterName(nbSession.Interface, c.bfdIDSeq, nil) + if err := c.ModifyBfdSession(vppSession, nbSession); err != nil { + return errors.Errorf("BFD resync error: failed to modify BFD session %s: %v", + nbSession.Interface, err) } found = true } } if !found { // configure new BFD session - if err := plugin.ConfigureBfdSession(nbSession); err != nil { - plugin.log.Errorf("BFD resync: error creating a new BFD session for interface %v: %v", nbSession.Interface, err) - wasErr = err + if err := c.ConfigureBfdSession(nbSession); err != nil { + return errors.Errorf("BFD resync error: failed to create BFD session %s: %v", nbSession.Interface, err) } } } @@ -271,58 +253,47 @@ func (plugin *BFDConfigurator) ResyncSession(nbSessions []*bfd.SingleHopBFD_Sess // Remove old sessions for _, vppSession := range vppBfdSessions.Session { // remove every not-yet-registered session - _, _, found := plugin.sessionsIndexes.LookupIdx(vppSession.Interface) + _, _, found := c.sessionsIndexes.LookupIdx(vppSession.Interface) if !found { - if err := plugin.DeleteBfdSession(vppSession); err != nil { - plugin.log.Errorf("BFD resync: error removing BFD session for interface %v: %v", vppSession.Interface, err) - wasErr = err + if err := c.DeleteBfdSession(vppSession); err != nil { + return errors.Errorf("BFD resync error: failed to delete BFD session %s: %v", vppSession.Interface, err) } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC BFD Session end. ", wasErr) + c.log.Info("BFD session resync done") - return wasErr + return nil } // ResyncAuthKey writes BFD keys to the empty VPP -func (plugin *BFDConfigurator) ResyncAuthKey(nbKeys []*bfd.SingleHopBFD_Key) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC BFD Keys begin.") - // Calculate and log bfd resync - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *BFDConfigurator) ResyncAuthKey(nbKeys []*bfd.SingleHopBFD_Key) error { // lookup BFD auth keys - vppBfdKeys, err := plugin.bfdHandler.DumpBfdAuthKeys() + vppBfdKeys, err := c.bfdHandler.DumpBfdAuthKeys() if err != nil { - return err + return errors.Errorf("BFD resync error: failed to dump BFD authentication keys: %v", err) } // Correlate existing BFD keys from the VPP and NB config, configure new ones - var wasErr error for _, nbKey := range nbKeys { // look for configured keys var found bool for _, vppKey := range vppBfdKeys.AuthKeys { // compare key ID if nbKey.Id == vppKey.Id { - plugin.log.Debugf("found configured BFD auth key with ID %v", nbKey.Id) - plugin.keysIndexes.RegisterName(AuthKeyIdentifier(nbKey.Id), plugin.bfdIDSeq, nil) - if err := plugin.ModifyBfdAuthKey(vppKey, nbKey); err != nil { - plugin.log.Errorf("BFD resync: error modifying BFD auth key with ID %v: %v", nbKey.Id, err) - wasErr = err + c.keysIndexes.RegisterName(AuthKeyIdentifier(nbKey.Id), c.bfdIDSeq, nil) + if err := c.ModifyBfdAuthKey(vppKey, nbKey); err != nil { + return errors.Errorf("BFD resync error: failed to modify BFD authentication key %s (ID %d): %v", + nbKey.Name, nbKey.Id, err) } found = true } } if !found { // configure new BFD authentication key - if err := plugin.ConfigureBfdAuthKey(nbKey); err != nil { - plugin.log.Errorf("BFD resync: error creating a new BFD auth key with ID %v: %v", nbKey.Id, err) - wasErr = err + if err := c.ConfigureBfdAuthKey(nbKey); err != nil { + return errors.Errorf("BFD resync error: failed to configure BFD authentication key %s (ID %d): %v", + nbKey.Name, nbKey.Id, err) } } } @@ -330,24 +301,22 @@ func (plugin *BFDConfigurator) ResyncAuthKey(nbKeys []*bfd.SingleHopBFD_Key) err // Remove old keys for _, vppKey := range vppBfdKeys.AuthKeys { // remove every not-yet-registered keys - _, _, found := plugin.keysIndexes.LookupIdx(AuthKeyIdentifier(vppKey.Id)) + _, _, found := c.keysIndexes.LookupIdx(AuthKeyIdentifier(vppKey.Id)) if !found { - if err := plugin.DeleteBfdAuthKey(vppKey); err != nil { - plugin.log.Errorf("BFD resync: error removing BFD auth key with ID %v: %v", vppKey.Id, err) - wasErr = err + if err := c.DeleteBfdAuthKey(vppKey); err != nil { + return errors.Errorf("BFD resync error: failed to delete BFD authentication key %s (ID %d): %v", + vppKey.Name, vppKey.Id, err) } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC BFD Keys end. ", wasErr) + c.log.Info("BFD authentication key resync done") - return wasErr + return nil } // ResyncEchoFunction writes BFD echo function to the empty VPP -func (plugin *BFDConfigurator) ResyncEchoFunction(echoFunctions []*bfd.SingleHopBFD_EchoFunction) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC BFD Echo source begin.") - +func (c *BFDConfigurator) ResyncEchoFunction(echoFunctions []*bfd.SingleHopBFD_EchoFunction) error { if len(echoFunctions) == 0 { // Nothing to do here. Currently VPP does not support BFD echo dump so agent does not know // whether there is echo function already configured and cannot remove it @@ -356,31 +325,26 @@ func (plugin *BFDConfigurator) ResyncEchoFunction(echoFunctions []*bfd.SingleHop // Only one config can be used to set an echo source. If there are multiple configurations, // use the first one if len(echoFunctions) > 1 { - plugin.log.Warn("Multiple configurations of BFD echo function found. Setting up %v as source", + c.log.Warn("BFD resync: multiple configurations of BFD echo function found. Setting up %s as source", echoFunctions[0].EchoSourceInterface) } - if err := plugin.ConfigureBfdEchoFunction(echoFunctions[0]); err != nil { - return err + if err := c.ConfigureBfdEchoFunction(echoFunctions[0]); err != nil { + return errors.Errorf("BFD resync error: failed to set interface %s as BFD echo source: %v", + echoFunctions[0], err) } + c.log.Info("BFD echo function resync done") + return nil } // Resync writes stn rule to the the empty VPP -func (plugin *StnConfigurator) Resync(nbStnRules []*stn.STN_Rule) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC stn rules begin. ") - // Calculate and log stn rules resync - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *StnConfigurator) Resync(nbStnRules []*stn.STN_Rule) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Dump existing STN Rules - vppStnDetails, err := plugin.Dump() + vppStnDetails, err := c.Dump() if err != nil { return err } @@ -392,15 +356,15 @@ func (plugin *StnConfigurator) Resync(nbStnRules []*stn.STN_Rule) error { var vppStnIP net.IP var vppStnIPStr string - vppStnIfIdx, _, found := plugin.ifIndexes.LookupIdx(vppStnRule.Interface) + vppStnIfIdx, _, found := c.ifIndexes.LookupIdx(vppStnRule.Interface) if !found { // The rule is attached to non existing interface but it can be removed. If there is a similar // rule in NB config, it will be configured (or cached) - if err := plugin.stnHandler.DelStnRule(vppStnIfIdx, &vppStnIP); err != nil { - plugin.log.Error(err) + if err := c.stnHandler.DelStnRule(vppStnIfIdx, &vppStnIP); err != nil { + c.log.Error(err) wasErr = err } - plugin.log.Debugf("RESYNC STN: rule IP: %v ifIdx: %v removed due to missing interface, will be reconfigured if needed", + c.log.Debugf("RESYNC STN: rule IP: %v ifIdx: %v removed due to missing interface, will be reconfigured if needed", vppStnIPStr, vppStnIfIdx) continue } @@ -410,32 +374,32 @@ func (plugin *StnConfigurator) Resync(nbStnRules []*stn.STN_Rule) error { for _, nbStnRule := range nbStnRules { if nbStnRule.IpAddress == vppStnIPStr && nbStnRule.Interface == vppStnRule.Interface { // Register existing rule - plugin.indexSTNRule(nbStnRule, false) + c.indexSTNRule(nbStnRule, false) match = true } - plugin.log.Debugf("RESYNC STN: registered already existing rule %v", nbStnRule.RuleName) + c.log.Debugf("RESYNC STN: registered already existing rule %v", nbStnRule.RuleName) } // If STN rule does not exist, it is obsolete if !match { - if err := plugin.stnHandler.DelStnRule(vppStnIfIdx, &vppStnIP); err != nil { - plugin.log.Error(err) + if err := c.stnHandler.DelStnRule(vppStnIfIdx, &vppStnIP); err != nil { + c.log.Error(err) wasErr = err } - plugin.log.Debugf("RESYNC STN: rule IP: %v ifName: %v removed as obsolete", vppStnIPStr, vppStnRule.Interface) + c.log.Debugf("RESYNC STN: rule IP: %v ifName: %v removed as obsolete", vppStnIPStr, vppStnRule.Interface) } } // Configure missing rules for _, nbStnRule := range nbStnRules { identifier := StnIdentifier(nbStnRule.Interface) - _, _, found := plugin.allIndexes.LookupIdx(identifier) + _, _, found := c.allIndexes.LookupIdx(identifier) if !found { - if err := plugin.Add(nbStnRule); err != nil { - plugin.log.Error(err) + if err := c.Add(nbStnRule); err != nil { + c.log.Error(err) wasErr = err } - plugin.log.Debugf("RESYNC STN: rule %v added", nbStnRule.RuleName) + c.log.Debugf("RESYNC STN: rule %v added", nbStnRule.RuleName) } } @@ -443,34 +407,38 @@ func (plugin *StnConfigurator) Resync(nbStnRules []*stn.STN_Rule) error { } // ResyncNatGlobal writes NAT address pool config to the the empty VPP -func (plugin *NatConfigurator) ResyncNatGlobal(nbGlobal *nat.Nat44Global) error { - plugin.log.Debug("RESYNC nat global config.") - +func (c *NatConfigurator) ResyncNatGlobal(nbGlobal *nat.Nat44Global) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() - vppNatGlobal, err := plugin.natHandler.Nat44GlobalConfigDump() + vppNatGlobal, err := c.natHandler.Nat44GlobalConfigDump() if err != nil { - return fmt.Errorf("failed to dump NAT44 global config: %v", err) + return errors.Errorf("NAT resync error: failed to dump NAT44 global config: %v", err) } // Modify will made all the diffs needed (nothing if content is equal) - return plugin.ModifyNatGlobalConfig(vppNatGlobal, nbGlobal) + if err := c.ModifyNatGlobalConfig(vppNatGlobal, nbGlobal); err != nil { + return err + } + + c.log.Info("NAT global config resync done.") + + return nil } // ResyncSNat writes NAT static mapping config to the the empty VPP -func (plugin *NatConfigurator) ResyncSNat(sNatConf []*nat.Nat44SNat_SNatConfig) error { +func (c *NatConfigurator) ResyncSNat(sNatConf []*nat.Nat44SNat_SNatConfig) error { // todo SNAT not implemented yet, nothing to resync return nil } // ResyncDNat writes NAT static mapping config to the the empty VPP -func (plugin *NatConfigurator) ResyncDNat(nbDNatConfig []*nat.Nat44DNat_DNatConfig) error { - plugin.log.Debug("RESYNC DNAT config.") +func (c *NatConfigurator) ResyncDNat(nbDNatConfig []*nat.Nat44DNat_DNatConfig) error { + c.log.Debug("RESYNC DNAT config.") - vppDNatCfg, err := plugin.natHandler.Nat44DNatDump() + vppDNatCfg, err := c.natHandler.Nat44DNatDump() if err != nil { - return fmt.Errorf("failed to dump DNAT config: %v", err) + return errors.Errorf("NAT resync error: failed to dump NAT44 DNAT: %v", err) } if len(vppDNatCfg.DnatConfigs) == 0 { return nil @@ -483,96 +451,88 @@ func (plugin *NatConfigurator) ResyncDNat(nbDNatConfig []*nat.Nat44DNat_DNatConf continue } // Compare all VPP mappings with the NB, register existing ones - plugin.resolveMappings(nbDNat, &vppDNat.StMappings, &vppDNat.IdMappings) + c.resolveMappings(nbDNat, &vppDNat.StMappings, &vppDNat.IdMappings) // Configure all missing DNAT mappings for _, nbMapping := range nbDNat.StMappings { mappingIdentifier := GetStMappingIdentifier(nbMapping) - _, _, found := plugin.dNatStMappingIndexes.LookupIdx(mappingIdentifier) + _, _, found := c.dNatStMappingIndexes.LookupIdx(mappingIdentifier) if !found { // Configure missing mapping if len(nbMapping.LocalIps) == 1 { - if err := plugin.handleStaticMapping(nbMapping, "", true); err != nil { - plugin.log.Errorf("NAT44 resync: failed to configure static mapping: %v", err) - continue + if err := c.handleStaticMapping(nbMapping, "", true); err != nil { + return err } } else { - if err := plugin.handleStaticMappingLb(nbMapping, "", true); err != nil { - plugin.log.Errorf("NAT44 resync: failed to configure lb-static mapping: %v", err) - continue + if err := c.handleStaticMappingLb(nbMapping, "", true); err != nil { + return err } } // Register new DNAT mapping - plugin.dNatStMappingIndexes.RegisterName(mappingIdentifier, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ - plugin.log.Debugf("NAT44 resync: new (lb)static mapping %v configured", mappingIdentifier) + c.dNatStMappingIndexes.RegisterName(mappingIdentifier, c.natIndexSeq, nil) + c.natIndexSeq++ + c.log.Debugf("NAT44 resync: new (lb)static mapping %s registered", mappingIdentifier) } } // Configure all missing DNAT identity mappings for _, nbIDMapping := range nbDNat.IdMappings { mappingIdentifier := GetIDMappingIdentifier(nbIDMapping) - _, _, found := plugin.dNatIDMappingIndexes.LookupIdx(mappingIdentifier) + _, _, found := c.dNatIDMappingIndexes.LookupIdx(mappingIdentifier) if !found { // Configure missing mapping - if err := plugin.handleIdentityMapping(nbIDMapping, "", true); err != nil { - plugin.log.Errorf("NAT44 resync: failed to configure identity mapping: %v", err) - continue + if err := c.handleIdentityMapping(nbIDMapping, "", true); err != nil { + return err } // Register new DNAT mapping - plugin.dNatIDMappingIndexes.RegisterName(mappingIdentifier, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ - plugin.log.Debugf("NAT44 resync: new identity mapping %v configured", mappingIdentifier) + c.dNatIDMappingIndexes.RegisterName(mappingIdentifier, c.natIndexSeq, nil) + c.natIndexSeq++ + c.log.Debugf("NAT44 resync: new identity mapping %s registered", mappingIdentifier) } } // Remove obsolete mappings from DNAT for _, vppMapping := range vppDNat.StMappings { // Static mapping if len(vppMapping.LocalIps) == 1 { - - if err := plugin.handleStaticMapping(vppMapping, "", false); err != nil { - plugin.log.Errorf("NAT44 resync: failed to remove static mapping: %v", err) - continue + if err := c.handleStaticMapping(vppMapping, "", false); err != nil { + return err } } else { // Lb-static mapping - if err := plugin.handleStaticMappingLb(vppMapping, "", false); err != nil { - plugin.log.Errorf("NAT44 resync: failed to remove static mapping: %v", err) - continue + if err := c.handleStaticMappingLb(vppMapping, "", false); err != nil { + return err } } } for _, vppIDMapping := range vppDNat.IdMappings { // Identity mapping - if err := plugin.handleIdentityMapping(vppIDMapping, "", false); err != nil { - plugin.log.Errorf("NAT44 resync: failed to remove identity mapping: %v", err) - continue + if err := c.handleIdentityMapping(vppIDMapping, "", false); err != nil { + return err } } // At this point, the DNAT is completely configured and can be registered - plugin.dNatIndexes.RegisterName(nbDNat.Label, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ - plugin.log.Debugf("NAT44 resync: DNAT %v synced", nbDNat.Label) + c.dNatIndexes.RegisterName(nbDNat.Label, c.natIndexSeq, nil) + c.natIndexSeq++ + c.log.Debugf("NAT44 resync: DNAT %s synced", nbDNat.Label) } } // Remove obsolete DNAT configurations which are not registered for _, vppDNat := range vppDNatCfg.DnatConfigs { - _, _, found := plugin.dNatIndexes.LookupIdx(vppDNat.Label) + _, _, found := c.dNatIndexes.LookupIdx(vppDNat.Label) if !found { - if err := plugin.DeleteDNat(vppDNat); err != nil { - plugin.log.Errorf("NAT44 resync: failed to remove obsolete DNAT configuration: %v", vppDNat.Label) - continue + if err := c.DeleteDNat(vppDNat); err != nil { + return err } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC DNAT config done.") + c.log.Info("DNAT resync done.") return nil } // Looks for the same mapping in the VPP, register existing ones -func (plugin *NatConfigurator) resolveMappings(nbDNatConfig *nat.Nat44DNat_DNatConfig, +func (c *NatConfigurator) resolveMappings(nbDNatConfig *nat.Nat44DNat_DNatConfig, vppMappings *[]*nat.Nat44DNat_DNatConfig_StaticMapping, vppIDMappings *[]*nat.Nat44DNat_DNatConfig_IdentityMapping) { // Iterate over static mappings in NB DNAT config for _, nbMapping := range nbDNatConfig.StMappings { @@ -599,7 +559,7 @@ func (plugin *NatConfigurator) resolveMappings(nbDNatConfig *nat.Nat44DNat_DNatC for _, nbLocal := range nbMapping.LocalIps { var found bool for _, vppLocal := range vppLbMapping.LocalIps { - if *nbLocal == *vppLocal { + if proto.Equal(nbLocal, vppLocal) { found = true } } @@ -609,13 +569,13 @@ func (plugin *NatConfigurator) resolveMappings(nbDNatConfig *nat.Nat44DNat_DNatC } // At this point, the NB mapping matched the VPP one, so register it mappingIdentifier := GetStMappingIdentifier(nbMapping) - plugin.dNatStMappingIndexes.RegisterName(mappingIdentifier, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ + c.dNatStMappingIndexes.RegisterName(mappingIdentifier, c.natIndexSeq, nil) + c.natIndexSeq++ // Remove registered entry from vpp mapping (configurator knows which mappings were registered) dMappings := *vppMappings *vppMappings = append(dMappings[:vppIndex], dMappings[vppIndex+1:]...) - plugin.log.Debugf("NAT44 resync: lb-mapping %v already configured", mappingIdentifier) + c.log.Debugf("NAT44 resync: lb-mapping %v already configured", mappingIdentifier) } } else { // No load balancer @@ -638,24 +598,24 @@ func (plugin *NatConfigurator) resolveMappings(nbDNatConfig *nat.Nat44DNat_DNatC } // Compare Local IP/Port and probability addresses (there is only one local IP address in this case) if len(nbMapping.LocalIps) != 1 || len(vppMapping.LocalIps) != 1 { - plugin.log.Warnf("NAT44 resync: mapping without load balancer contains more than 1 local IP address") + c.log.Warnf("NAT44 resync: mapping without load balancer contains more than 1 local IP address") continue } nbLocal := nbMapping.LocalIps[0] vppLocal := vppMapping.LocalIps[0] - if *nbLocal != *vppLocal { + if !proto.Equal(nbLocal, vppLocal) { continue } // At this point, the NB mapping matched the VPP one, so register it mappingIdentifier := GetStMappingIdentifier(nbMapping) - plugin.dNatStMappingIndexes.RegisterName(mappingIdentifier, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ + c.dNatStMappingIndexes.RegisterName(mappingIdentifier, c.natIndexSeq, nil) + c.natIndexSeq++ // Remove registered entry from vpp mapping (so configurator knows which mappings were registered) dMappings := *vppMappings *vppMappings = append(dMappings[:vppIndex], dMappings[vppIndex+1:]...) - plugin.log.Debugf("NAT44 resync: mapping %v already configured", mappingIdentifier) + c.log.Debugf("NAT44 resync: mapping %v already configured", mappingIdentifier) } } } @@ -677,19 +637,19 @@ func (plugin *NatConfigurator) resolveMappings(nbDNatConfig *nat.Nat44DNat_DNatC // At this point, the NB mapping matched the VPP one, so register it mappingIdentifier := GetIDMappingIdentifier(nbIDMapping) - plugin.dNatIDMappingIndexes.RegisterName(mappingIdentifier, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ + c.dNatIDMappingIndexes.RegisterName(mappingIdentifier, c.natIndexSeq, nil) + c.natIndexSeq++ // Remove registered entry from vpp mapping (configurator knows which mappings were registered) dIDMappings := *vppIDMappings *vppIDMappings = append(dIDMappings[:vppIDIndex], dIDMappings[vppIDIndex+1:]...) - plugin.log.Debugf("NAT44 resync: identity mapping %v already configured", mappingIdentifier) + c.log.Debugf("NAT44 resync: identity mapping %v already configured", mappingIdentifier) } } } // Correlate interfaces according to MAC address, interface addresses -func (plugin *InterfaceConfigurator) correlateInterface(vppIf, nbIf *intf.Interfaces_Interface) *intf.Interfaces_Interface { +func (c *InterfaceConfigurator) correlateInterface(vppIf, nbIf *intf.Interfaces_Interface) *intf.Interfaces_Interface { // Correlate MAC address if nbIf.PhysAddress != "" { if nbIf.PhysAddress == vppIf.PhysAddress { @@ -706,12 +666,12 @@ func (plugin *InterfaceConfigurator) correlateInterface(vppIf, nbIf *intf.Interf for _, vppIP := range vppIf.IpAddresses { pNbIP, nbIPNet, err := net.ParseCIDR(nbIP) if err != nil { - plugin.log.Error(err) + c.log.Error(err) continue } pVppIP, vppIPNet, err := net.ParseCIDR(vppIP) if err != nil { - plugin.log.Error(err) + c.log.Error(err) continue } if nbIPNet.Mask.String() == vppIPNet.Mask.String() && bytes.Compare(pNbIP, pVppIP) == 0 { @@ -737,41 +697,41 @@ func (plugin *InterfaceConfigurator) correlateInterface(vppIf, nbIf *intf.Interf } // Compares two interfaces. If there is any difference, returns true, false otherwise -func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_Interface) bool { - plugin.log.Debugf("Interface RESYNC comparison started for interface %s", nbIf.Name) +func (c *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_Interface) bool { + c.log.Debugf("Interface RESYNC comparison started for interface %s", nbIf.Name) // Type if nbIf.Type != vppIf.Type { - plugin.log.Debugf("Interface RESYNC comparison: type changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: type changed (NB: %v, VPP: %v)", nbIf.Type, vppIf.Type) return true } // Enabled if nbIf.Enabled != vppIf.Enabled { - plugin.log.Debugf("Interface RESYNC comparison: enabled state changed (NB: %t, VPP: %t)", + c.log.Debugf("Interface RESYNC comparison: enabled state changed (NB: %t, VPP: %t)", nbIf.Enabled, vppIf.Enabled) return true } // VRF if nbIf.Vrf != vppIf.Vrf { - plugin.log.Debugf("Interface RESYNC comparison: VRF changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: VRF changed (NB: %d, VPP: %d)", nbIf.Vrf, vppIf.Vrf) return true } // Container IP address if nbIf.ContainerIpAddress != vppIf.ContainerIpAddress { - plugin.log.Debugf("Interface RESYNC comparison: container IP changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: container IP changed (NB: %s, VPP: %s)", nbIf.ContainerIpAddress, vppIf.ContainerIpAddress) return true } // DHCP setup if nbIf.SetDhcpClient != vppIf.SetDhcpClient { - plugin.log.Debugf("Interface RESYNC comparison: DHCP setup changed (NB: %t, VPP: %t)", + c.log.Debugf("Interface RESYNC comparison: DHCP setup changed (NB: %t, VPP: %t)", nbIf.SetDhcpClient, vppIf.SetDhcpClient) return true } - // MTU value (not valid for VxLAN) + // MTU value (not valid for VxLAN) if nbIf.Mtu != vppIf.Mtu && nbIf.Type != intf.InterfaceType_VXLAN_TUNNEL { - plugin.log.Debugf("Interface RESYNC comparison: MTU changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: MTU changed (NB: %d, VPP: %d)", nbIf.Mtu, vppIf.Mtu) return true } @@ -779,13 +739,30 @@ func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_I nbMac := strings.ToUpper(nbIf.PhysAddress) vppMac := strings.ToUpper(vppIf.PhysAddress) if nbMac != "" && nbMac != vppMac { - plugin.log.Debugf("Interface RESYNC comparison: Physical address changed (NB: %s, VPP: %s)", nbMac, vppMac) + c.log.Debugf("Interface RESYNC comparison: Physical address changed (NB: %s, VPP: %s)", nbMac, vppMac) return true } - // Unnumbered settings. If interface is unnumbered, do not compare ip addresses. - // todo dump unnumbered data - if nbIf.Unnumbered != nil { - plugin.log.Debugf("RESYNC interfaces: interface %s is unnumbered, result of the comparison may not be correct", nbIf.Name) + + // Check if NB or SB interface is unnumbered + if nbIf.Unnumbered != nil && nbIf.Unnumbered.IsUnnumbered { + if vppIf.Unnumbered == nil || (vppIf.Unnumbered != nil && !vppIf.Unnumbered.IsUnnumbered) { + c.log.Debugf("Interface RESYNC comparison: NB %s is unnumbered, VPP %s is not", nbMac, vppMac) + return true + } + } else { + // NB interface is not unnumbered, check VPP + if vppIf.Unnumbered != nil && vppIf.Unnumbered.IsUnnumbered { + c.log.Debugf("Interface RESYNC comparison: NB %s is not unnumbered, but VPP %s is", nbMac, vppMac) + return true + } + } + // If both of them are, check IP-interface. Otherwise, check IP addresses + if nbIf.Unnumbered != nil && nbIf.Unnumbered.IsUnnumbered { + if nbIf.Unnumbered.InterfaceWithIp != vppIf.Unnumbered.InterfaceWithIp { + c.log.Debugf("Interface RESYNC comparison: IP-unnumbered interface is different (NB: %s, VPP: %s)", + nbIf.Unnumbered.InterfaceWithIp, vppIf.Unnumbered.InterfaceWithIp) + return true + } vppIf.IpAddresses = nil } else { // Remove IPv6 link local addresses (default values) @@ -796,7 +773,7 @@ func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_I } // Compare IP address count if len(nbIf.IpAddresses) != len(vppIf.IpAddresses) { - plugin.log.Debugf("Interface RESYNC comparison: IP address count changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: IP address count changed (NB: %d, VPP: %d)", len(nbIf.IpAddresses), len(vppIf.IpAddresses)) return true } @@ -806,12 +783,12 @@ func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_I for _, vppIP := range vppIf.IpAddresses { pNbIP, nbIPNet, err := net.ParseCIDR(nbIP) if err != nil { - plugin.log.Error(err) + c.log.Error(err) continue } pVppIP, vppIPNet, err := net.ParseCIDR(vppIP) if err != nil { - plugin.log.Error(err) + c.log.Error(err) continue } if nbIPNet.Mask.String() == vppIPNet.Mask.String() && bytes.Compare(pNbIP, pVppIP) == 0 { @@ -820,35 +797,35 @@ func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_I } } if !ipFound { - plugin.log.Debugf("Interface RESYNC comparison: VPP interface %s does not contain IP %s", nbIf.Name, nbIP) + c.log.Debugf("Interface RESYNC comparison: VPP interface %s does not contain IP %s", nbIf.Name, nbIP) return true } } } // RxMode settings if nbIf.RxModeSettings == nil && vppIf.RxModeSettings != nil || nbIf.RxModeSettings != nil && vppIf.RxModeSettings == nil { - plugin.log.Debugf("Interface RESYNC comparison: RxModeSettings changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: RxModeSettings changed (NB: %v, VPP: %v)", nbIf.RxModeSettings, vppIf.RxModeSettings) return true } if nbIf.RxModeSettings != nil && vppIf.RxModeSettings != nil { // RxMode if nbIf.RxModeSettings.RxMode != vppIf.RxModeSettings.RxMode { - plugin.log.Debugf("Interface RESYNC comparison: RxMode changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: RxMode changed (NB: %v, VPP: %v)", nbIf.RxModeSettings.RxMode, vppIf.RxModeSettings.RxMode) return true } // QueueID if nbIf.RxModeSettings.QueueId != vppIf.RxModeSettings.QueueId { - plugin.log.Debugf("Interface RESYNC comparison: QueueID changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: QueueID changed (NB: %d, VPP: %d)", nbIf.RxModeSettings.QueueId, vppIf.RxModeSettings.QueueId) return true } // QueueIDValid if nbIf.RxModeSettings.QueueIdValid != vppIf.RxModeSettings.QueueIdValid { - plugin.log.Debugf("Interface RESYNC comparison: QueueIDValid changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: QueueIDValid changed (NB: %d, VPP: %d)", nbIf.RxModeSettings.QueueIdValid, vppIf.RxModeSettings.QueueIdValid) return true @@ -858,59 +835,59 @@ func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_I switch nbIf.Type { case intf.InterfaceType_AF_PACKET_INTERFACE: if nbIf.Afpacket == nil && vppIf.Afpacket != nil || nbIf.Afpacket != nil && vppIf.Afpacket == nil { - plugin.log.Debugf("Interface RESYNC comparison: AF-packet setup changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: AF-packet setup changed (NB: %v, VPP: %v)", nbIf.Afpacket, vppIf.Afpacket) return true } if nbIf.Afpacket != nil && vppIf.Afpacket != nil { // AF-packet host name if nbIf.Afpacket.HostIfName != vppIf.Afpacket.HostIfName { - plugin.log.Debugf("Interface RESYNC comparison: AF-packet host name changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: AF-packet host name changed (NB: %s, VPP: %s)", nbIf.Afpacket.HostIfName, vppIf.Afpacket.HostIfName) return true } } case intf.InterfaceType_MEMORY_INTERFACE: if nbIf.Memif == nil && vppIf.Memif != nil || nbIf.Memif != nil && vppIf.Memif == nil { - plugin.log.Debugf("Interface RESYNC comparison: memif setup changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: memif setup changed (NB: %v, VPP: %v)", nbIf.Memif, vppIf.Memif) return true } if nbIf.Memif != nil && vppIf.Memif != nil { // Memif ID if nbIf.Memif.Id != vppIf.Memif.Id { - plugin.log.Debugf("Interface RESYNC comparison: memif ID changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: memif ID changed (NB: %d, VPP: %d)", nbIf.Memif.Id, vppIf.Memif.Id) return true } // Memif socket if nbIf.Memif.SocketFilename != vppIf.Memif.SocketFilename { - plugin.log.Debugf("Interface RESYNC comparison: memif socket filename changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: memif socket filename changed (NB: %s, VPP: %s)", nbIf.Memif.SocketFilename, vppIf.Memif.SocketFilename) return true } // Master if nbIf.Memif.Master != vppIf.Memif.Master { - plugin.log.Debugf("Interface RESYNC comparison: memif master setup changed (NB: %t, VPP: %t)", + c.log.Debugf("Interface RESYNC comparison: memif master setup changed (NB: %t, VPP: %t)", nbIf.Memif.Master, vppIf.Memif.Master) return true } // Mode if nbIf.Memif.Mode != vppIf.Memif.Mode { - plugin.log.Debugf("Interface RESYNC comparison: memif mode setup changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: memif mode setup changed (NB: %v, VPP: %v)", nbIf.Memif.Mode, vppIf.Memif.Mode) return true } // Rx queues if nbIf.Memif.RxQueues != vppIf.Memif.RxQueues { - plugin.log.Debugf("Interface RESYNC comparison: RxQueues changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: RxQueues changed (NB: %d, VPP: %d)", nbIf.Memif.RxQueues, vppIf.Memif.RxQueues) return true } // Tx queues if nbIf.Memif.TxQueues != vppIf.Memif.TxQueues { - plugin.log.Debugf("Interface RESYNC comparison: TxQueues changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: TxQueues changed (NB: %d, VPP: %d)", nbIf.Memif.TxQueues, vppIf.Memif.TxQueues) return true } @@ -919,70 +896,70 @@ func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_I } case intf.InterfaceType_TAP_INTERFACE: if nbIf.Tap == nil && vppIf.Tap != nil || nbIf.Tap != nil && vppIf.Tap == nil { - plugin.log.Debugf("Interface RESYNC comparison: tap setup changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: tap setup changed (NB: %v, VPP: %v)", nbIf.Tap, vppIf.Tap) return true } if nbIf.Tap != nil && vppIf.Tap != nil { // Tap version if nbIf.Tap.Version == 2 && nbIf.Tap.Version != vppIf.Tap.Version { - plugin.log.Debugf("Interface RESYNC comparison: tap version changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: tap version changed (NB: %d, VPP: %d)", nbIf.Tap.Version, vppIf.Tap.Version) return true } // Namespace and host name if nbIf.Tap.Namespace != vppIf.Tap.Namespace { - plugin.log.Debugf("Interface RESYNC comparison: tap namespace changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: tap namespace changed (NB: %s, VPP: %s)", nbIf.Tap.Namespace, vppIf.Tap.Namespace) return true } // Namespace and host name if nbIf.Tap.HostIfName != vppIf.Tap.HostIfName { - plugin.log.Debugf("Interface RESYNC comparison: tap host name changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: tap host name changed (NB: %s, VPP: %s)", nbIf.Tap.HostIfName, vppIf.Tap.HostIfName) return true } // Rx ring size if nbIf.Tap.RxRingSize != nbIf.Tap.RxRingSize { - plugin.log.Debugf("Interface RESYNC comparison: tap Rx ring size changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: tap Rx ring size changed (NB: %d, VPP: %d)", nbIf.Tap.RxRingSize, vppIf.Tap.RxRingSize) return true } // Tx ring size if nbIf.Tap.TxRingSize != nbIf.Tap.TxRingSize { - plugin.log.Debugf("Interface RESYNC comparison: tap Tx ring size changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: tap Tx ring size changed (NB: %d, VPP: %d)", nbIf.Tap.TxRingSize, vppIf.Tap.TxRingSize) return true } } case intf.InterfaceType_VXLAN_TUNNEL: if nbIf.Vxlan == nil && vppIf.Vxlan != nil || nbIf.Vxlan != nil && vppIf.Vxlan == nil { - plugin.log.Debugf("Interface RESYNC comparison: VxLAN setup changed (NB: %v, VPP: %v)", + c.log.Debugf("Interface RESYNC comparison: VxLAN setup changed (NB: %v, VPP: %v)", nbIf.Vxlan, vppIf.Vxlan) return true } if nbIf.Vxlan != nil && vppIf.Vxlan != nil { // VxLAN Vni if nbIf.Vxlan.Vni != vppIf.Vxlan.Vni { - plugin.log.Debugf("Interface RESYNC comparison: VxLAN Vni changed (NB: %d, VPP: %d)", + c.log.Debugf("Interface RESYNC comparison: VxLAN Vni changed (NB: %d, VPP: %d)", nbIf.Vxlan.Vni, vppIf.Vxlan.Vni) return true } // VxLAN Src Address if nbIf.Vxlan.SrcAddress != vppIf.Vxlan.SrcAddress { - plugin.log.Debugf("Interface RESYNC comparison: VxLAN src address changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: VxLAN src address changed (NB: %s, VPP: %s)", nbIf.Vxlan.SrcAddress, vppIf.Vxlan.SrcAddress) return true } // VxLAN Dst Address if nbIf.Vxlan.DstAddress != vppIf.Vxlan.DstAddress { - plugin.log.Debugf("Interface RESYNC comparison: VxLAN dst address changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: VxLAN dst address changed (NB: %s, VPP: %s)", nbIf.Vxlan.DstAddress, vppIf.Vxlan.DstAddress) return true } // VxLAN Multicast if nbIf.Vxlan.Multicast != vppIf.Vxlan.Multicast { - plugin.log.Debugf("Interface RESYNC comparison: VxLAN multicast address changed (NB: %s, VPP: %s)", + c.log.Debugf("Interface RESYNC comparison: VxLAN multicast address changed (NB: %s, VPP: %s)", nbIf.Vxlan.Multicast, vppIf.Vxlan.Multicast) return true } @@ -994,18 +971,18 @@ func (plugin *InterfaceConfigurator) isIfModified(nbIf, vppIf *intf.Interfaces_I } // Register interface to mapping and add tag/index to the VPP -func (plugin *InterfaceConfigurator) registerInterface(ifName string, ifIdx uint32, ifData *intf.Interfaces_Interface) error { - plugin.swIfIndexes.RegisterName(ifName, ifIdx, ifData) - if err := plugin.ifHandler.SetInterfaceTag(ifName, ifIdx); err != nil { - return fmt.Errorf("error while adding interface tag %s, index %d: %v", ifName, ifIdx, err) +func (c *InterfaceConfigurator) registerInterface(ifName string, ifIdx uint32, ifData *intf.Interfaces_Interface) error { + c.swIfIndexes.RegisterName(ifName, ifIdx, ifData) + if err := c.ifHandler.SetInterfaceTag(ifName, ifIdx); err != nil { + return errors.Errorf("error while adding interface tag %s, index %d: %v", ifName, ifIdx, err) } // Add AF-packet type interface to local cache if ifData.Type == intf.InterfaceType_AF_PACKET_INTERFACE { - if plugin.linux != nil && plugin.afPacketConfigurator != nil && ifData.Afpacket != nil { + if c.linux != nil && c.afPacketConfigurator != nil && ifData.Afpacket != nil { // Interface is already present on the VPP so it cannot be marked as pending. - plugin.afPacketConfigurator.addToCache(ifData, false) + c.afPacketConfigurator.addToCache(ifData, false) } } - plugin.log.Debugf("RESYNC interfaces: registered interface %s (index %d)", ifName, ifIdx) + c.log.Debugf("RESYNC interfaces: registered interface %s (index %d)", ifName, ifIdx) return nil } diff --git a/plugins/vpp/ifplugin/data_resync_test.go b/plugins/vpp/ifplugin/data_resync_test.go index bc40e00ed7..a38f078b70 100644 --- a/plugins/vpp/ifplugin/data_resync_test.go +++ b/plugins/vpp/ifplugin/data_resync_test.go @@ -17,9 +17,10 @@ package ifplugin_test import ( "testing" + "git.fd.io/govpp.git/core" + "git.fd.io/govpp.git/adapter/mock" govppapi "git.fd.io/govpp.git/api" - govpp "git.fd.io/govpp.git/core" "github.com/ligato/cn-infra/logging" "github.com/ligato/cn-infra/logging/logrus" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -42,14 +43,14 @@ import ( // TODO: use configurator initializers from other files which do the same thing -func interfaceConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.InterfaceConfigurator, *govpp.Connection) { +func interfaceConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.InterfaceConfigurator, *core.Connection) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } - conn, err := govpp.Connect(ctx.MockVpp) + conn, err := core.Connect(ctx.MockVpp) Expect(err).To(BeNil()) // Test init @@ -58,26 +59,26 @@ func interfaceConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx ifVppNotifCh := make(chan govppapi.Message, 100) plugLog := logging.ForPlugin("tests") - err = plugin.Init(plugLog, conn, nil, ifVppNotifCh, 0, true) + err = plugin.Init(plugLog, conn, nil, ifVppNotifCh, 0) Expect(err).To(BeNil()) return ctx, plugin, conn } -func interfaceConfiguratorTestTeardown(plugin *ifplugin.InterfaceConfigurator, conn *govpp.Connection) { +func interfaceConfiguratorTestTeardown(plugin *ifplugin.InterfaceConfigurator, conn *core.Connection) { conn.Disconnect() Expect(plugin.Close()).To(BeNil()) logging.DefaultRegistry.ClearRegistry() } -func bfdConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.BFDConfigurator, *govpp.Connection, ifaceidx.SwIfIndexRW) { +func bfdConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.BFDConfigurator, *core.Connection, ifaceidx.SwIfIndexRW) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } - c, err := govpp.Connect(ctx.MockVpp) + c, err := core.Connect(ctx.MockVpp) Expect(err).To(BeNil()) // initialize index @@ -88,25 +89,25 @@ func bfdConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifp // Test init plugin := &ifplugin.BFDConfigurator{} - err = plugin.Init(logging.ForPlugin("test-log"), c, index, true) + err = plugin.Init(logging.ForPlugin("test-log"), c, index) Expect(err).To(BeNil()) return ctx, plugin, c, index } -func bfdConfiguratorTestTeardown(plugin *ifplugin.BFDConfigurator, conn *govpp.Connection) { +func bfdConfiguratorTestTeardown(plugin *ifplugin.BFDConfigurator, conn *core.Connection) { conn.Disconnect() Expect(plugin.Close()).To(BeNil()) logging.DefaultRegistry.ClearRegistry() } -func stnConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.StnConfigurator, *govpp.Connection) { +func stnConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.StnConfigurator, *core.Connection) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } - c, err := govpp.Connect(ctx.MockVpp) + c, err := core.Connect(ctx.MockVpp) Expect(err).To(BeNil()) // initialize index @@ -117,25 +118,25 @@ func stnConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifp // Test init plugin := &ifplugin.StnConfigurator{} - err = plugin.Init(logging.ForPlugin("test-log"), c, index, true) + err = plugin.Init(logging.ForPlugin("test-log"), c, index) Expect(err).To(BeNil()) return ctx, plugin, c } -func stnConfiguratorTestTeardown(plugin *ifplugin.StnConfigurator, conn *govpp.Connection) { +func stnConfiguratorTestTeardown(plugin *ifplugin.StnConfigurator, conn *core.Connection) { conn.Disconnect() Expect(plugin.Close()).To(BeNil()) logging.DefaultRegistry.ClearRegistry() } -func natConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.NatConfigurator, *govpp.Connection, ifaceidx.SwIfIndexRW) { +func natConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifplugin.NatConfigurator, *core.Connection, ifaceidx.SwIfIndexRW) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } - c, err := govpp.Connect(ctx.MockVpp) + c, err := core.Connect(ctx.MockVpp) Expect(err).To(BeNil()) // initialize index @@ -146,13 +147,13 @@ func natConfiguratorTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *ifp // Test init plugin := &ifplugin.NatConfigurator{} - err = plugin.Init(logging.ForPlugin("test-log"), c, index, true) + err = plugin.Init(logging.ForPlugin("test-log"), c, index) Expect(err).To(BeNil()) return ctx, plugin, c, index } -func natConfiguratorTestTeardown(plugin *ifplugin.NatConfigurator, conn *govpp.Connection) { +func natConfiguratorTestTeardown(plugin *ifplugin.NatConfigurator, conn *core.Connection) { conn.Disconnect() Expect(plugin.Close()).To(BeNil()) logging.DefaultRegistry.ClearRegistry() @@ -200,8 +201,8 @@ func TestDataResyncResync(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) Expect(plugin.IsSocketFilenameCached("testsocket")).To(BeTrue()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") @@ -252,8 +253,8 @@ func TestDataResyncResyncIdx0(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") Expect(found).To(BeTrue()) @@ -301,8 +302,8 @@ func TestDataResyncResyncSameName(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") Expect(found).To(BeTrue()) @@ -351,8 +352,8 @@ func TestDataResyncResyncUnnamed(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") Expect(found).To(BeTrue()) @@ -400,10 +401,9 @@ func TestDataResyncResyncUnnumbered(t *testing.T) { // Test intfaces := []*intf.Interfaces_Interface{ { - Name: "test", - Type: intf.InterfaceType_VXLAN_TUNNEL, - Enabled: true, - IpAddresses: []string{"192.168.0.1/24"}, + Name: "test", + Type: intf.InterfaceType_VXLAN_TUNNEL, + Enabled: true, Unnumbered: &intf.Interfaces_Interface_Unnumbered{ IsUnnumbered: true, InterfaceWithIp: "test", @@ -416,8 +416,8 @@ func TestDataResyncResyncUnnumbered(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") Expect(found).To(BeTrue()) @@ -480,8 +480,8 @@ func TestDataResyncResyncUnnumberedTap(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") Expect(found).To(BeTrue()) @@ -533,8 +533,8 @@ func TestDataResyncResyncUnnumberedAfPacket(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") Expect(found).To(BeTrue()) @@ -600,8 +600,8 @@ func TestDataResyncResyncUnnumberedMemif(t *testing.T) { }, } - errs := plugin.Resync(intfaces) - Expect(errs).To(BeEmpty()) + err := plugin.Resync(intfaces) + Expect(err).To(BeNil()) _, meta, found := plugin.GetSwIfIndexes().LookupIdx("test") Expect(found).To(BeTrue()) @@ -693,6 +693,236 @@ func TestDataResyncVerifyVPPConfigPresenceNegative(t *testing.T) { Expect(meta).To(BeNil()) } +func TestInterfaceModifyComparisonType(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + Type: intf.InterfaceType_TAP_INTERFACE, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + Type: intf.InterfaceType_MEMORY_INTERFACE, + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + vppIf.Type = intf.InterfaceType_TAP_INTERFACE + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonEnabled(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + Enabled: true, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + Enabled: false, + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + vppIf.Enabled = true + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonVrf(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + Vrf: 0, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + Vrf: 1, + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + vppIf.Vrf = 0 + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonContainerIP(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + ContainerIpAddress: "192.168.0.1", + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + ContainerIpAddress: "192.168.0.2", + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + vppIf.ContainerIpAddress = "192.168.0.1" + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonDHCP(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + SetDhcpClient: true, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + SetDhcpClient: false, + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + vppIf.SetDhcpClient = true + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonMtu(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + Mtu: 1000, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + Mtu: 1500, + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + // Not valid for VxLAN + nbIf.Type, vppIf.Type = intf.InterfaceType_VXLAN_TUNNEL, intf.InterfaceType_VXLAN_TUNNEL + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) + // Change to different type and same value + nbIf.Type, vppIf.Type = intf.InterfaceType_TAP_INTERFACE, intf.InterfaceType_TAP_INTERFACE + nbIf.Mtu, vppIf.Mtu = 1000, 1000 + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonMAC(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + PhysAddress: "00:00:00:00:00:01", + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + PhysAddress: "00:00:00:00:00:02", + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + // Do not compare if mac is not defined in NB + nbIf.PhysAddress = "" + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) + nbIf.PhysAddress, vppIf.PhysAddress = "00:00:00:00:00:01", "00:00:00:00:00:01" + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonUnnumbered(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + // Unnumbered set only for NB + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + Unnumbered: &intf.Interfaces_Interface_Unnumbered{ + IsUnnumbered: true, + }, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + } + + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + vppIf.Unnumbered = &intf.Interfaces_Interface_Unnumbered{ + IsUnnumbered: false, + } + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + + // Unnumbered set only for SB + nbIf.Unnumbered = nil + vppIf.Unnumbered.IsUnnumbered = true + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + nbIf.Unnumbered = &intf.Interfaces_Interface_Unnumbered{ + IsUnnumbered: false, + } + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + + // Unnumbered set to both + nbIf.Unnumbered.IsUnnumbered, vppIf.Unnumbered.IsUnnumbered = true, true + nbIf.Unnumbered.InterfaceWithIp, vppIf.Unnumbered.InterfaceWithIp = "unif1", "unif2" + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + nbIf.Unnumbered.InterfaceWithIp, vppIf.Unnumbered.InterfaceWithIp = "unif1", "unif1" + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonIPAddress(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + // Test IP count + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + IpAddresses: []string{"192.168.0.1/24", "192.168.0.2/24"}, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + IpAddresses: []string{"192.168.0.1/24"}, + } + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + + // Same count, different IP + vppIf.IpAddresses = []string{"192.168.0.1/24", "192.168.0.3/24"} + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + + // Equal case + vppIf.IpAddresses = []string{"192.168.0.1/24", "192.168.0.2/24"} + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) + + // IPv6 link local should not affect the result + vppIf.IpAddresses = []string{"192.168.0.1/24", "192.168.0.2/24", "fe80:0db8:85a3:0000:0000:8a2e:0370:7334"} + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + +func TestInterfaceModifyComparisonRxMode(t *testing.T) { + _, plugin, conn := interfaceConfiguratorTestInitialization(t) + defer interfaceConfiguratorTestTeardown(plugin, conn) + + nbIf := &intf.Interfaces_Interface{ + Name: "if1", + RxModeSettings: &intf.Interfaces_Interface_RxModeSettings{ + RxMode: intf.RxModeType_DEFAULT, + }, + } + vppIf := &intf.Interfaces_Interface{ + Name: "if2", + } + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + nbIf.RxModeSettings, vppIf.RxModeSettings = nil, &intf.Interfaces_Interface_RxModeSettings{ + RxMode: intf.RxModeType_DEFAULT, + } + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + + // RxMode + nbIf.RxModeSettings, vppIf.RxModeSettings = &intf.Interfaces_Interface_RxModeSettings{ + RxMode: intf.RxModeType_DEFAULT, + }, &intf.Interfaces_Interface_RxModeSettings{ + RxMode: intf.RxModeType_ADAPTIVE, + } + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeTrue()) + vppIf.RxModeSettings.RxMode = intf.RxModeType_DEFAULT + Expect(ifplugin.IsIfModified(plugin, nbIf, vppIf)).To(BeFalse()) +} + // Tests BFDConfigurator session resync func TestDataResyncResyncSession(t *testing.T) { ctx, plugin, conn, index := bfdConfiguratorTestInitialization(t) @@ -792,7 +1022,7 @@ func TestDataResyncResyncSessionSameData(t *testing.T) { // Tests BFDConfigurator authorization key resync func TestDataResyncResyncAuthKey(t *testing.T) { - ctx, plugin, conn, _ := bfdConfiguratorTestInitialization(t) + ctx, plugin, conn, swIfIdx := bfdConfiguratorTestInitialization(t) defer bfdConfiguratorTestTeardown(plugin, conn) ctx.MockReplies([]*vppcallmock.HandleReplies{ @@ -815,7 +1045,8 @@ func TestDataResyncResyncAuthKey(t *testing.T) { Message: &bfdApi.BfdAuthSetKeyReply{}, }, }) - + // Register + swIfIdx.RegisterName("if1", 0, nil) // Test authKey := []*bfd.SingleHopBFD_Key{ { @@ -1035,6 +1266,16 @@ func TestDataResyncResyncDNat(t *testing.T) { Tag: []byte("smap|lbstat|idmap"), ExternalAddr: []byte{192, 168, 10, 0}, ExternalPort: 88, + Locals: []natApi.Nat44LbAddrPort{ + { + Addr: []byte{192., 168, 10, 0}, + Port: 89, + }, + { + Addr: []byte{192., 168, 20, 0}, + Port: 90, + }, + }, }, }, { @@ -1178,8 +1419,19 @@ func TestDataResyncResyncDNatMultipleIPs(t *testing.T) { Name: (&natApi.Nat44LbStaticMappingDump{}).GetMessageName(), Ping: true, Message: &natApi.Nat44LbStaticMappingDetails{ - Protocol: 6, - Tag: []byte("smap|lbstat|idmap"), + ExternalPort: 25, + Protocol: 6, + Tag: []byte("smap|lbstat|idmap"), + Locals: []natApi.Nat44LbAddrPort{ + { + Addr: []byte{192., 168, 10, 0}, + Port: 89, + }, + { + Addr: []byte{192., 168, 20, 0}, + Port: 90, + }, + }, }, }, { diff --git a/plugins/vpp/ifplugin/export_test.go b/plugins/vpp/ifplugin/export_test.go index 854cecbbef..1467f0b7c5 100644 --- a/plugins/vpp/ifplugin/export_test.go +++ b/plugins/vpp/ifplugin/export_test.go @@ -14,10 +14,22 @@ package ifplugin -import "github.com/ligato/vpp-agent/plugins/vpp/model/nat" +import ( + "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" + "github.com/ligato/vpp-agent/plugins/vpp/model/nat" +) // Export for testing + +func PropagateIfDetailsToStatus(ifCfg *InterfaceConfigurator) error { + return ifCfg.propagateIfDetailsToStatus() +} + func ResolveMappings(natCfg *NatConfigurator, nbDNatConfig *nat.Nat44DNat_DNatConfig, vppMappings *[]*nat.Nat44DNat_DNatConfig_StaticMapping, vppIDMappings *[]*nat.Nat44DNat_DNatConfig_IdentityMapping) { natCfg.resolveMappings(nbDNatConfig, vppMappings, vppIDMappings) } + +func IsIfModified(ifCfg *InterfaceConfigurator, nbIf, vppIf *interfaces.Interfaces_Interface) bool { + return ifCfg.isIfModified(nbIf, vppIf) +} diff --git a/plugins/vpp/ifplugin/interface_config.go b/plugins/vpp/ifplugin/interface_config.go index 0858eb96c2..2e7fe72823 100644 --- a/plugins/vpp/ifplugin/interface_config.go +++ b/plugins/vpp/ifplugin/interface_config.go @@ -12,23 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/interfaces --gogo_out=../model/interfaces ../model/interfaces/interfaces.proto -//go:generate protoc --proto_path=../model/bfd --gogo_out=../model/bfd ../model/bfd/bfd.proto - // Package ifplugin implements the Interface plugin that handles management // of VPP interfaces. package ifplugin import ( "bytes" - "fmt" "net" "strings" - "time" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" + "github.com/gogo/protobuf/proto" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -50,8 +46,6 @@ type InterfaceConfigurator struct { linux interface{} // just flag if nil - stopwatch *measure.Stopwatch // timer used to measure and store time - swIfIndexes ifaceidx.SwIfIndexRW dhcpIndexes ifaceidx.DhcpIndexRW @@ -74,306 +68,253 @@ type InterfaceConfigurator struct { } // Init members (channels...) and start go routines -func (plugin *InterfaceConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, linux interface{}, - notifChan chan govppapi.Message, defaultMtu uint32, enableStopwatch bool) (err error) { +func (c *InterfaceConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, linux interface{}, + notifChan chan govppapi.Message, defaultMtu uint32) (err error) { // Logger - plugin.log = logger.NewLogger("-if-conf") - plugin.log.Debug("Initializing Interface configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("Interface-configurator", plugin.log) - } + c.log = logger.NewLogger("if-conf") // State notification channel - plugin.NotifChan = notifChan + c.NotifChan = notifChan // Config file data - plugin.defaultMtu = defaultMtu + c.defaultMtu = defaultMtu // VPP channel - if plugin.vppCh, err = goVppMux.NewAPIChannel(); err != nil { - return err + if c.vppCh, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handler - plugin.ifHandler = vppcalls.NewIfVppHandler(plugin.vppCh, plugin.log, plugin.stopwatch) + c.ifHandler = vppcalls.NewIfVppHandler(c.vppCh, c.log) // Mappings - plugin.swIfIndexes = ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(plugin.log, "sw_if_indexes", ifaceidx.IndexMetadata)) - plugin.dhcpIndexes = ifaceidx.NewDHCPIndex(nametoidx.NewNameToIdx(plugin.log, "dhcp_indices", ifaceidx.IndexDHCPMetadata)) - plugin.uIfaceCache = make(map[string]string) - plugin.vxlanMulticastCache = make(map[string]*intf.Interfaces_Interface) - plugin.memifScCache = make(map[string]uint32) + c.swIfIndexes = ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(c.log, "sw_if_indexes", ifaceidx.IndexMetadata)) + c.dhcpIndexes = ifaceidx.NewDHCPIndex(nametoidx.NewNameToIdx(c.log, "dhcp_indices", ifaceidx.IndexDHCPMetadata)) + c.uIfaceCache = make(map[string]string) + c.vxlanMulticastCache = make(map[string]*intf.Interfaces_Interface) + c.memifScCache = make(map[string]uint32) // Init AF-packet configurator - plugin.linux = linux - plugin.afPacketConfigurator = &AFPacketConfigurator{} - plugin.afPacketConfigurator.Init(plugin.log, plugin.ifHandler, plugin.linux, plugin.swIfIndexes) + c.linux = linux + c.afPacketConfigurator = &AFPacketConfigurator{} + c.afPacketConfigurator.Init(c.log, c.ifHandler, c.linux, c.swIfIndexes) // DHCP channel - plugin.DhcpChan = make(chan govppapi.Message, 1) - if _, err := plugin.vppCh.SubscribeNotification(plugin.DhcpChan, dhcp.NewDHCPComplEvent); err != nil { + c.DhcpChan = make(chan govppapi.Message, 1) + if _, err := c.vppCh.SubscribeNotification(c.DhcpChan, &dhcp.DHCPComplEvent{}); err != nil { return err } - go plugin.watchDHCPNotifications() + go c.watchDHCPNotifications() + + c.log.Info("Interface configurator initialized") return nil } // Close GOVPP channel -func (plugin *InterfaceConfigurator) Close() error { - return safeclose.Close(plugin.vppCh, plugin.DhcpChan) +func (c *InterfaceConfigurator) Close() error { + if err := safeclose.Close(c.vppCh, c.DhcpChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose interface configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *InterfaceConfigurator) clearMapping() error { - plugin.swIfIndexes.Clear() - plugin.dhcpIndexes.Clear() - plugin.uIfaceCache = make(map[string]string) - plugin.vxlanMulticastCache = make(map[string]*intf.Interfaces_Interface) - plugin.memifScCache = make(map[string]uint32) +func (c *InterfaceConfigurator) clearMapping() error { + c.swIfIndexes.Clear() + c.dhcpIndexes.Clear() + c.uIfaceCache = make(map[string]string) + c.vxlanMulticastCache = make(map[string]*intf.Interfaces_Interface) + c.memifScCache = make(map[string]uint32) + + c.log.Debugf("interface configurator mapping cleared") return nil } // GetSwIfIndexes exposes interface name-to-index mapping -func (plugin *InterfaceConfigurator) GetSwIfIndexes() ifaceidx.SwIfIndexRW { - return plugin.swIfIndexes +func (c *InterfaceConfigurator) GetSwIfIndexes() ifaceidx.SwIfIndexRW { + return c.swIfIndexes } // GetDHCPIndexes exposes DHCP name-to-index mapping -func (plugin *InterfaceConfigurator) GetDHCPIndexes() ifaceidx.DhcpIndexRW { - return plugin.dhcpIndexes +func (c *InterfaceConfigurator) GetDHCPIndexes() ifaceidx.DhcpIndexRW { + return c.dhcpIndexes } // IsSocketFilenameCached returns true if provided filename is presented in the cache -func (plugin *InterfaceConfigurator) IsSocketFilenameCached(filename string) bool { - _, ok := plugin.memifScCache[filename] +func (c *InterfaceConfigurator) IsSocketFilenameCached(filename string) bool { + _, ok := c.memifScCache[filename] return ok } // IsUnnumberedIfCached returns true if provided interface is cached as unconfigurabel unnubered interface -func (plugin *InterfaceConfigurator) IsUnnumberedIfCached(ifName string) bool { - _, ok := plugin.uIfaceCache[ifName] +func (c *InterfaceConfigurator) IsUnnumberedIfCached(ifName string) bool { + _, ok := c.uIfaceCache[ifName] return ok } // IsMulticastVxLanIfCached returns true if provided interface is cached as VxLAN with missing multicast interface -func (plugin *InterfaceConfigurator) IsMulticastVxLanIfCached(ifName string) bool { - _, ok := plugin.vxlanMulticastCache[ifName] +func (c *InterfaceConfigurator) IsMulticastVxLanIfCached(ifName string) bool { + _, ok := c.vxlanMulticastCache[ifName] return ok } -// PropagateIfDetailsToStatus looks up all VPP interfaces -func (plugin *InterfaceConfigurator) PropagateIfDetailsToStatus() error { - start := time.Now() - req := &interfaces.SwInterfaceDump{} - reqCtx := plugin.vppCh.SendMultiRequest(req) - - for { - msg := &interfaces.SwInterfaceDetails{} - stop, err := reqCtx.ReceiveReply(msg) - if stop { - break // break out of the loop - } - if err != nil { - plugin.log.Error(err) - return err - } - - _, _, found := plugin.swIfIndexes.LookupName(msg.SwIfIndex) - if !found { - plugin.log.Debugf("Unregistered interface %v with ID %v found on vpp", - string(bytes.SplitN(msg.InterfaceName, []byte{0x00}, 2)[0]), msg.SwIfIndex) - // Do not register unknown interface here, cuz it may cause inconsistencies in the ifplugin. - // All new interfaces should be registered during configuration - continue - } - - // Propagate interface state information to notification channel. - plugin.NotifChan <- msg - } - - // SwInterfaceSetFlags time - if plugin.stopwatch != nil { - timeLog := measure.GetTimeLog(interfaces.SwInterfaceSetFlags{}, plugin.stopwatch) - timeLog.LogTimeEntry(time.Since(start)) - } - - return nil -} - // ConfigureVPPInterface reacts to a new northbound VPP interface config by creating and configuring // the interface in the VPP network stack through the VPP binary API. -func (plugin *InterfaceConfigurator) ConfigureVPPInterface(iface *intf.Interfaces_Interface) (err error) { - plugin.log.Infof("Configuring new interface %v", iface.Name) - +func (c *InterfaceConfigurator) ConfigureVPPInterface(iface *intf.Interfaces_Interface) (err error) { var ifIdx uint32 switch iface.Type { case intf.InterfaceType_TAP_INTERFACE: - ifIdx, err = plugin.ifHandler.AddTapInterface(iface.Name, iface.Tap) + ifIdx, err = c.ifHandler.AddTapInterface(iface.Name, iface.Tap) case intf.InterfaceType_MEMORY_INTERFACE: var id uint32 // Memif socket id - id, err = plugin.resolveMemifSocketFilename(iface.Memif) - if err != nil { + if id, err = c.resolveMemifSocketFilename(iface.Memif); err != nil { return err } - ifIdx, err = plugin.ifHandler.AddMemifInterface(iface.Name, iface.Memif, id) + ifIdx, err = c.ifHandler.AddMemifInterface(iface.Name, iface.Memif, id) case intf.InterfaceType_VXLAN_TUNNEL: // VxLAN multicast interface. Interrupt the processing if there is an error or interface was cached - multicastIfIdx, cached, err := plugin.getVxLanMulticast(iface) + multicastIfIdx, cached, err := c.getVxLanMulticast(iface) if err != nil || cached { return err } - ifIdx, err = plugin.ifHandler.AddVxLanTunnel(iface.Name, iface.Vrf, multicastIfIdx, iface.Vxlan) + ifIdx, err = c.ifHandler.AddVxLanTunnel(iface.Name, iface.Vrf, multicastIfIdx, iface.Vxlan) case intf.InterfaceType_SOFTWARE_LOOPBACK: - ifIdx, err = plugin.ifHandler.AddLoopbackInterface(iface.Name) + ifIdx, err = c.ifHandler.AddLoopbackInterface(iface.Name) case intf.InterfaceType_ETHERNET_CSMACD: var exists bool - if ifIdx, _, exists = plugin.swIfIndexes.LookupIdx(iface.Name); !exists { - plugin.log.Warnf("It is not yet supported to add (whitelist) a new physical interface") + if ifIdx, _, exists = c.swIfIndexes.LookupIdx(iface.Name); !exists { + c.log.Warnf("It is not yet supported to add (whitelist) a new physical interface") return nil } case intf.InterfaceType_AF_PACKET_INTERFACE: var pending bool - if ifIdx, pending, err = plugin.afPacketConfigurator.ConfigureAfPacketInterface(iface); err != nil { + if ifIdx, pending, err = c.afPacketConfigurator.ConfigureAfPacketInterface(iface); err != nil { return err } if pending { - plugin.log.Debugf("interface %+v cannot be created yet and will be configured later", iface) + c.log.Debugf("Af-packet interface %s cannot be created yet and will be configured later", iface) return nil } } if err != nil { - plugin.log.Error(err) return err } - var errs []error - // Rx-mode - if err := plugin.configRxModeForInterface(iface, ifIdx); err != nil { - errs = append(errs, err) + if err := c.configRxModeForInterface(iface, ifIdx); err != nil { + return err } // Rx-placement TODO: simplify implementation for rx placement when the binary api call will be available (remove dump) if iface.RxPlacementSettings != nil { // Required in order to get vpp internal name. Must be called from here, calling in vppcalls causes // import cycle - ifMap, err := plugin.ifHandler.DumpInterfaces() + ifMap, err := c.ifHandler.DumpInterfaces() if err != nil { - return err + return errors.Errorf("failed to dump interfaces: %v", err) } ifData, ok := ifMap[ifIdx] if !ok || ifData == nil { - return fmt.Errorf("set rx-placement failed, no data available for interface index %d", ifIdx) + return errors.Errorf("set rx-placement failed, no data available for interface index %d", ifIdx) } - if err := plugin.ifHandler.SetRxPlacement(ifData.Meta.InternalName, iface.RxPlacementSettings); err != nil { - errs = append(errs, err) + if err := c.ifHandler.SetRxPlacement(ifData.Meta.SwIfIndex, iface.RxPlacementSettings); err != nil { + return errors.Errorf("failed to set rx-placement for interface %s: %v", ifData.Interface.Name, err) } } // MAC address (optional, for af-packet is configured in different way) if iface.PhysAddress != "" && iface.Type != intf.InterfaceType_AF_PACKET_INTERFACE { - if err := plugin.ifHandler.SetInterfaceMac(ifIdx, iface.PhysAddress); err != nil { - errs = append(errs, err) + if err := c.ifHandler.SetInterfaceMac(ifIdx, iface.PhysAddress); err != nil { + return errors.Errorf("failed to set MAC address %s to interface %s: %v", + iface.PhysAddress, iface.Name, err) } } // DHCP client if iface.SetDhcpClient { - if err := plugin.ifHandler.SetInterfaceAsDHCPClient(ifIdx, iface.Name); err != nil { - errs = append(errs, err) - } else { - plugin.log.Debugf("Interface %v set as DHCP client", iface.Name) + if err := c.ifHandler.SetInterfaceAsDHCPClient(ifIdx, iface.Name); err != nil { + return errors.Errorf("failed to set interface %s as DHCP client", iface.Name) } } // Get IP addresses IPAddrs, err := addrs.StrAddrsToStruct(iface.IpAddresses) if err != nil { - return err + return errors.Errorf("failed to convert %s IP address list to IPNet structures: %v", iface.Name, err) } // VRF (optional, unavailable for VxLAN interfaces), has to be done before IP addresses are configured if iface.Type != intf.InterfaceType_VXLAN_TUNNEL { // Configured separately for IPv4/IPv6 - isIPv4, isIPv6 := plugin.getIPAddressVersions(IPAddrs) + isIPv4, isIPv6 := getIPAddressVersions(IPAddrs) if isIPv4 { - if err := plugin.ifHandler.SetInterfaceVrf(ifIdx, iface.Vrf); err != nil { - errs = append(errs, err) + if err := c.ifHandler.SetInterfaceVrf(ifIdx, iface.Vrf); err != nil { + return errors.Errorf("failed to set interface %s as IPv4 VRF %d: %v", iface.Name, iface.Vrf, err) } } if isIPv6 { - if err := plugin.ifHandler.SetInterfaceVrfIPv6(ifIdx, iface.Vrf); err != nil { - errs = append(errs, err) + if err := c.ifHandler.SetInterfaceVrfIPv6(ifIdx, iface.Vrf); err != nil { + return errors.Errorf("failed to set interface %s as IPv6 VRF %d: %v", iface.Name, iface.Vrf, err) } } } // Configure IP addresses or unnumbered config - if err := plugin.configureIPAddresses(iface.Name, ifIdx, IPAddrs, iface.Unnumbered); err != nil { - errs = append(errs, err) + if err := c.configureIPAddresses(iface.Name, ifIdx, IPAddrs, iface.Unnumbered); err != nil { + return err } // configure container IP address if iface.ContainerIpAddress != "" { - if err := plugin.ifHandler.AddContainerIP(ifIdx, iface.ContainerIpAddress); err != nil { - errs = append(errs, err) - } else { - plugin.log.WithFields(logging.Fields{"IPaddr": iface.ContainerIpAddress, "ifIdx": ifIdx}). - Debug("Container IP address added") + if err := c.ifHandler.AddContainerIP(ifIdx, iface.ContainerIpAddress); err != nil { + return errors.Errorf("failed to add container IP address %s to interface %s: %v", + iface.ContainerIpAddress, iface.Name, err) } } // configure mtu. Prefer value in interface config, otherwise set default value if defined if iface.Type != intf.InterfaceType_VXLAN_TUNNEL { mtuToConfigure := iface.Mtu - if mtuToConfigure == 0 && plugin.defaultMtu != 0 { - mtuToConfigure = plugin.defaultMtu + if mtuToConfigure == 0 && c.defaultMtu != 0 { + mtuToConfigure = c.defaultMtu } if mtuToConfigure != 0 { iface.Mtu = mtuToConfigure - if err := plugin.ifHandler.SetInterfaceMtu(ifIdx, mtuToConfigure); err != nil { - errs = append(errs, err) + if err := c.ifHandler.SetInterfaceMtu(ifIdx, mtuToConfigure); err != nil { + return errors.Errorf("failed to set MTU %d to interface %s: %v", mtuToConfigure, iface.Name, err) } } } // register name to idx mapping if it is not an af_packet interface type (it is registered in ConfigureAfPacketInterface if needed) if iface.Type != intf.InterfaceType_AF_PACKET_INTERFACE { - plugin.swIfIndexes.RegisterName(iface.Name, ifIdx, iface) + c.swIfIndexes.RegisterName(iface.Name, ifIdx, iface) + c.log.Debugf("Interface %s registered to interface mapping", iface.Name) } - l := plugin.log.WithFields(logging.Fields{"ifName": iface.Name, "ifIdx": ifIdx}) - l.Debug("Configured interface") - // set interface up if enabled // NOTE: needs to be called after RegisterName, otherwise interface up/down notification won't map to a valid interface if iface.Enabled { - if err := plugin.ifHandler.InterfaceAdminUp(ifIdx); err != nil { - l.Warnf("setting interface up failed: %v", err) - errs = append(errs, err) - return fmt.Errorf("found %d errors: %v", len(errs), errs) + if err := c.ifHandler.InterfaceAdminUp(ifIdx); err != nil { + return errors.Errorf("failed to set interface %s up: %v", iface.Name, err) } } // load interface state data for newly added interface (no way to filter by swIfIndex, need to dump all of them) - plugin.PropagateIfDetailsToStatus() - - l.Info("Interface configuration done") + if err := c.propagateIfDetailsToStatus(); err != nil { + return err + } // Check whether there is no VxLAN interface waiting on created one as a multicast - if err := plugin.resolveCachedVxLANMulticasts(iface.Name); err != nil { - errs = append(errs, err) + if err := c.resolveCachedVxLANMulticasts(iface.Name); err != nil { + return err } - // TODO: use some error aggregator - if errs != nil { - return fmt.Errorf("found %d errors: %v", len(errs), errs) - } + c.log.Infof("Interface %s configured", iface.Name) + return nil } @@ -393,365 +334,319 @@ Interfaces - supported modes: * ethernet csmad - P * af packet - PIA */ -func (plugin *InterfaceConfigurator) configRxModeForInterface(iface *intf.Interfaces_Interface, ifIdx uint32) error { +func (c *InterfaceConfigurator) configRxModeForInterface(iface *intf.Interfaces_Interface, ifIdx uint32) error { rxModeSettings := iface.RxModeSettings if rxModeSettings != nil { switch iface.Type { case intf.InterfaceType_ETHERNET_CSMACD: if rxModeSettings.RxMode == intf.RxModeType_POLLING { - return plugin.configRxMode(iface, ifIdx, rxModeSettings) + return c.configRxMode(iface, ifIdx, rxModeSettings) } default: - return plugin.configRxMode(iface, ifIdx, rxModeSettings) + return c.configRxMode(iface, ifIdx, rxModeSettings) } } return nil } -/** -Call specific vpp API method for setting rx-mode -*/ -func (plugin *InterfaceConfigurator) configRxMode(iface *intf.Interfaces_Interface, ifIdx uint32, rxModeSettings *intf.Interfaces_Interface_RxModeSettings) error { - err := plugin.ifHandler.SetRxMode(ifIdx, rxModeSettings) - plugin.log.WithFields(logging.Fields{"ifName": iface.Name, "rxMode": rxModeSettings.RxMode}). - Debug("RX-mode configuration for ", iface.Type, ".") - return err +// Call specific vpp API method for setting rx-mode +func (c *InterfaceConfigurator) configRxMode(iface *intf.Interfaces_Interface, ifIdx uint32, rxModeSettings *intf.Interfaces_Interface_RxModeSettings) error { + if err := c.ifHandler.SetRxMode(ifIdx, rxModeSettings); err != nil { + return errors.Errorf("failed to set Rx-mode for interface %s: %v", iface.Name, err) + } + return nil } -func (plugin *InterfaceConfigurator) configureIPAddresses(ifName string, ifIdx uint32, addresses []*net.IPNet, unnumbered *intf.Interfaces_Interface_Unnumbered) error { +func (c *InterfaceConfigurator) configureIPAddresses(ifName string, ifIdx uint32, addresses []*net.IPNet, unnumbered *intf.Interfaces_Interface_Unnumbered) error { if unnumbered != nil && unnumbered.IsUnnumbered { ifWithIP := unnumbered.InterfaceWithIp if ifWithIP == "" { - return fmt.Errorf("unnubered interface %s has no interface with IP address set", ifName) + return errors.Errorf("unnubered interface %s has no interface with IP address set", ifName) } - ifIdxIP, _, found := plugin.swIfIndexes.LookupIdx(ifWithIP) + ifIdxIP, _, found := c.swIfIndexes.LookupIdx(ifWithIP) if !found { // cache not-configurable interface - plugin.uIfaceCache[ifName] = ifWithIP - plugin.log.Debugf("unnubered interface %s requires IP address from non-existing %v, moved to cache", ifName, ifWithIP) + c.uIfaceCache[ifName] = ifWithIP + c.log.Debugf("unnubered interface %s moved to cache (requires IP address from non-existing %s)", ifName, ifWithIP) return nil } // Set interface as un-numbered - if err := plugin.ifHandler.SetUnnumberedIP(ifIdx, ifIdxIP); err != nil { - return err - } - plugin.log.WithFields(logging.Fields{"un-numberedIface": ifIdx, "ifIdxIP": ifIdxIP}).Debug("Interface set as un-numbered") - - // just log - if len(addresses) != 0 { - plugin.log.Warnf("Interface %v set as un-numbered contains IP address(es)", ifName, addresses) + if err := c.ifHandler.SetUnnumberedIP(ifIdx, ifIdxIP); err != nil { + return errors.Errorf("failed to set interface %v as unnumbered for %v: %v", ifName, ifIdxIP, err) } } // configure optional ip address - var wasErr error for _, address := range addresses { - if err := plugin.ifHandler.AddInterfaceIP(ifIdx, address); err != nil { - plugin.log.Errorf("adding interface IP address failed: %v", err) - wasErr = err + if err := c.ifHandler.AddInterfaceIP(ifIdx, address); err != nil { + return errors.Errorf("adding IP address %v to interface %v failed: %v", address, ifName, err) } } // with ip address configured, the interface can be used as a source for un-numbered interfaces (if any) - if err := plugin.resolveDependentUnnumberedInterfaces(ifName, ifIdx); err != nil { - wasErr = err + if err := c.resolveDependentUnnumberedInterfaces(ifName, ifIdx); err != nil { + return err } - return wasErr + return nil } -func (plugin *InterfaceConfigurator) removeIPAddresses(ifIdx uint32, addresses []*net.IPNet, unnumbered *intf.Interfaces_Interface_Unnumbered) error { +func (c *InterfaceConfigurator) removeIPAddresses(ifIdx uint32, addresses []*net.IPNet, unnumbered *intf.Interfaces_Interface_Unnumbered) error { if unnumbered != nil && unnumbered.IsUnnumbered { // Set interface as un-numbered - if err := plugin.ifHandler.UnsetUnnumberedIP(ifIdx); err != nil { - return err + if err := c.ifHandler.UnsetUnnumberedIP(ifIdx); err != nil { + return errors.Errorf("faield to unset unnumbered IP for interface %d: %v", ifIdx, err) } } // delete IP Addresses - var wasErr error for _, addr := range addresses { - err := plugin.ifHandler.DelInterfaceIP(ifIdx, addr) + err := c.ifHandler.DelInterfaceIP(ifIdx, addr) if err != nil { - plugin.log.Errorf("deleting IP address failed: %v", err) - wasErr = err - } else { - plugin.log.Debug("deleted IP addr %v", addr) + return errors.Errorf("deleting IP address %s from interface %d failed: %v", addr, ifIdx, err) } } - return wasErr + return nil } // Iterate over all un-numbered interfaces in cache (which could not be configured before) and find all interfaces // dependent on the provided one -func (plugin *InterfaceConfigurator) resolveDependentUnnumberedInterfaces(ifNameIP string, ifIdxIP uint32) error { - plugin.log.Debugf("Looking up unnumbered interfaces dependent on %v", ifNameIP) - var wasErr error - for uIface, ifWithIP := range plugin.uIfaceCache { +func (c *InterfaceConfigurator) resolveDependentUnnumberedInterfaces(ifNameIP string, ifIdxIP uint32) error { + for uIface, ifWithIP := range c.uIfaceCache { if ifWithIP == ifNameIP { // find index of the dependent interface - uIdx, _, found := plugin.swIfIndexes.LookupIdx(uIface) + uIdx, _, found := c.swIfIndexes.LookupIdx(uIface) if !found { - plugin.log.Debugf("Unnumbered interface %v not found, removing from cache", uIface) - delete(plugin.uIfaceCache, uIface) + delete(c.uIfaceCache, uIface) + c.log.Debugf("Unnumbered interface %s removed from cache (not found)", uIface) continue } - if err := plugin.ifHandler.SetUnnumberedIP(uIdx, ifIdxIP); err != nil { - plugin.log.Errorf("setting unnumbered IP failed: %v", err) - wasErr = err - } else { - plugin.log.WithFields(logging.Fields{"un-numberedIface": uIdx, "ifIdxIP": ifIdxIP}).Debug("Interface set as un-numbered") + if err := c.ifHandler.SetUnnumberedIP(uIdx, ifIdxIP); err != nil { + return errors.Errorf("setting unnumbered IP %v for interface %v (%v) failed: %v", ifIdxIP, uIface, uIdx, err) } - delete(plugin.uIfaceCache, uIface) + delete(c.uIfaceCache, uIface) + c.log.Debugf("Unnumbered interface %s set and removed from cache", uIface) } } - return wasErr + return nil } // ModifyVPPInterface applies changes in the NB configuration of a VPP interface into the running VPP // through the VPP binary API. -func (plugin *InterfaceConfigurator) ModifyVPPInterface(newConfig *intf.Interfaces_Interface, +func (c *InterfaceConfigurator) ModifyVPPInterface(newConfig *intf.Interfaces_Interface, oldConfig *intf.Interfaces_Interface) error { - plugin.log.Infof("Modifying Interface %v", newConfig.Name) // Recreate pending Af-packet - if newConfig.Type == intf.InterfaceType_AF_PACKET_INTERFACE && plugin.afPacketConfigurator.IsPendingAfPacket(oldConfig) { - return plugin.recreateVPPInterface(newConfig, oldConfig, 0) + if newConfig.Type == intf.InterfaceType_AF_PACKET_INTERFACE && c.afPacketConfigurator.IsPendingAfPacket(oldConfig) { + return c.recreateVPPInterface(newConfig, oldConfig, 0) } // Re-create cached VxLAN if newConfig.Type == intf.InterfaceType_VXLAN_TUNNEL { - if _, ok := plugin.vxlanMulticastCache[newConfig.Name]; ok { - delete(plugin.vxlanMulticastCache, newConfig.Name) - return plugin.ConfigureVPPInterface(newConfig) + if _, ok := c.vxlanMulticastCache[newConfig.Name]; ok { + delete(c.vxlanMulticastCache, newConfig.Name) + c.log.Debugf("Interface %s removed from VxLAN multicast cache, will be configured", newConfig.Name) + return c.ConfigureVPPInterface(newConfig) } } - // lookup index - ifIdx, meta, found := plugin.swIfIndexes.LookupIdx(newConfig.Name) - + // Lookup index. If not found, create interface a a new on. + ifIdx, meta, found := c.swIfIndexes.LookupIdx(newConfig.Name) if !found { - plugin.log.WithFields(logging.Fields{"ifName": newConfig.Name}).Debug("Mapping for interface name not found.") - return nil + c.log.Warnf("Modify interface %s: index was not found in the mapping, creating as a new one", newConfig.Name) + return c.ConfigureVPPInterface(newConfig) } - if err := plugin.modifyVPPInterface(newConfig, oldConfig, ifIdx, meta.Type); err != nil { + if err := c.modifyVPPInterface(newConfig, oldConfig, ifIdx, meta.Type); err != nil { return err } - plugin.log.Infof("Interface %v modified", newConfig.Name) + c.log.Infof("Interface %s modified", newConfig.Name) return nil } // ModifyVPPInterface applies changes in the NB configuration of a VPP interface into the running VPP // through the VPP binary API. -func (plugin *InterfaceConfigurator) modifyVPPInterface(newConfig *intf.Interfaces_Interface, oldConfig *intf.Interfaces_Interface, +func (c *InterfaceConfigurator) modifyVPPInterface(newConfig, oldConfig *intf.Interfaces_Interface, ifIdx uint32, ifaceType intf.InterfaceType) (err error) { - plugin.log.WithFields(logging.Fields{"ifname": oldConfig.Name, "swIfIndex": ifIdx}). - Debug("modifyVPPInterface begin") - switch ifaceType { case intf.InterfaceType_TAP_INTERFACE: - if !plugin.canTapBeModifWithoutDelete(newConfig.Tap, oldConfig.Tap) { - err := plugin.recreateVPPInterface(newConfig, oldConfig, ifIdx) - plugin.log.WithFields(logging.Fields{"ifName": newConfig.Name, "ifIdx": ifIdx}). - Debug("modifyVPPInterface end. ", err) - return err + if !c.canTapBeModifWithoutDelete(newConfig.Tap, oldConfig.Tap) { + return c.recreateVPPInterface(newConfig, oldConfig, ifIdx) } case intf.InterfaceType_MEMORY_INTERFACE: - if !plugin.canMemifBeModifWithoutDelete(newConfig.Memif, oldConfig.Memif) { - err := plugin.recreateVPPInterface(newConfig, oldConfig, ifIdx) - plugin.log.WithFields(logging.Fields{"ifName": newConfig.Name, "ifIdx": ifIdx}). - Debug("modifyVPPInterface end. ", err) - return err + if !c.canMemifBeModifWithoutDelete(newConfig.Memif, oldConfig.Memif) { + return c.recreateVPPInterface(newConfig, oldConfig, ifIdx) } case intf.InterfaceType_VXLAN_TUNNEL: - if !plugin.canVxlanBeModifWithoutDelete(newConfig.Vxlan, oldConfig.Vxlan) || + if !c.canVxlanBeModifWithoutDelete(newConfig.Vxlan, oldConfig.Vxlan) || oldConfig.Vrf != newConfig.Vrf { - err := plugin.recreateVPPInterface(newConfig, oldConfig, ifIdx) - plugin.log.WithFields(logging.Fields{"ifName": newConfig.Name, "ifIdx": ifIdx}). - Debug("modifyVPPInterface end. ", err) - return err + return c.recreateVPPInterface(newConfig, oldConfig, ifIdx) } case intf.InterfaceType_AF_PACKET_INTERFACE: - recreate, err := plugin.afPacketConfigurator.ModifyAfPacketInterface(newConfig, oldConfig) - if err != nil || recreate { - if err == nil { - err = plugin.recreateVPPInterface(newConfig, oldConfig, ifIdx) - } - plugin.log.WithFields(logging.Fields{"ifName": newConfig.Name, "ifIdx": ifIdx}). - Debug("modifyVPPInterface end. ", err) + recreate, err := c.afPacketConfigurator.ModifyAfPacketInterface(newConfig, oldConfig) + if err != nil { return err } + if recreate { + return c.recreateVPPInterface(newConfig, oldConfig, ifIdx) + } case intf.InterfaceType_SOFTWARE_LOOPBACK: case intf.InterfaceType_ETHERNET_CSMACD: } - var wasError error - // rx mode + // Rx-mode if !(oldConfig.RxModeSettings == nil && newConfig.RxModeSettings == nil) { - wasError = plugin.modifyRxModeForInterfaces(oldConfig, newConfig, ifIdx) + if err := c.modifyRxModeForInterfaces(oldConfig, newConfig, ifIdx); err != nil { + return err + } } - // rx placement + // Rx-placement if newConfig.RxPlacementSettings != nil { // Required in order to get vpp internal name. Must be called from here, calling in vppcalls causes // import cycle - ifMap, err := plugin.ifHandler.DumpInterfaces() + ifMap, err := c.ifHandler.DumpInterfaces() if err != nil { - return err + return errors.Errorf("failed to dump interfaces: %v", err) } ifData, ok := ifMap[ifIdx] if !ok || ifData == nil { - return fmt.Errorf("set rx-placement for new config failed, no data available for interface index %d", ifIdx) + return errors.Errorf("set rx-placement for new config failed, no data available for interface index %d", ifIdx) } - if err := plugin.ifHandler.SetRxPlacement(ifData.Meta.InternalName, newConfig.RxPlacementSettings); err != nil { - wasError = err + if err := c.ifHandler.SetRxPlacement(ifData.Meta.SwIfIndex, newConfig.RxPlacementSettings); err != nil { + return errors.Errorf("failed to set rx-placement for interface %s: %v", newConfig.Name, err) } } - // admin status + // Admin status if newConfig.Enabled != oldConfig.Enabled { if newConfig.Enabled { - err = plugin.ifHandler.InterfaceAdminUp(ifIdx) + if err = c.ifHandler.InterfaceAdminUp(ifIdx); err != nil { + return errors.Errorf("failed to set interface %s up: %v", newConfig.Name, err) + } } else { - err = plugin.ifHandler.InterfaceAdminDown(ifIdx) - } - if nil != err { - wasError = err + if err = c.ifHandler.InterfaceAdminDown(ifIdx); err != nil { + return errors.Errorf("failed to set interface %s down: %v", newConfig.Name, err) + } } } - // configure new mac address if set (and only if it was changed) + // Configure new mac address if set (and only if it was changed) if newConfig.PhysAddress != "" && newConfig.PhysAddress != oldConfig.PhysAddress { - if err := plugin.ifHandler.SetInterfaceMac(ifIdx, newConfig.PhysAddress); err != nil { - plugin.log.Errorf("setting interface MAC address failed: %v", err) - wasError = err + if err := c.ifHandler.SetInterfaceMac(ifIdx, newConfig.PhysAddress); err != nil { + return errors.Errorf("setting interface %s MAC address %s failed: %v", + newConfig.Name, newConfig.PhysAddress, err) } } - // reconfigure DHCP + // Reconfigure DHCP if oldConfig.SetDhcpClient != newConfig.SetDhcpClient { if newConfig.SetDhcpClient { - if err := plugin.ifHandler.SetInterfaceAsDHCPClient(ifIdx, newConfig.Name); err != nil { - plugin.log.Error(err) - wasError = err - } else { - plugin.log.Debugf("Interface %v set as DHCP client", newConfig.Name) + if err := c.ifHandler.SetInterfaceAsDHCPClient(ifIdx, newConfig.Name); err != nil { + return errors.Errorf("failed to set interface %s as DHCP client: %v", newConfig.Name, err) } } else { - if err := plugin.ifHandler.UnsetInterfaceAsDHCPClient(ifIdx, newConfig.Name); err != nil { - plugin.log.Error(err) - wasError = err - } else { - // Remove from dhcp mapping - plugin.dhcpIndexes.UnregisterName(newConfig.Name) - plugin.log.Debugf("Interface %v unset as DHCP client", oldConfig.Name) + if err := c.ifHandler.UnsetInterfaceAsDHCPClient(ifIdx, newConfig.Name); err != nil { + return errors.Errorf("failed to unset interface %s as DHCP client: %v", newConfig.Name, err) } + // Remove from DHCP mapping + c.dhcpIndexes.UnregisterName(newConfig.Name) + c.log.Debugf("Interface %s unregistered as DHCP client", oldConfig.Name) } } - // ip address + // Ip addresses newAddrs, err := addrs.StrAddrsToStruct(newConfig.IpAddresses) if err != nil { - return err + return errors.Errorf("failed to convert %s IP address list to IPNet structures: %v", newConfig.Name, err) } - oldAddrs, err := addrs.StrAddrsToStruct(oldConfig.IpAddresses) if err != nil { - return err + return errors.Errorf("failed to convert %s IP address list to IPNet structures: %v", oldConfig.Name, err) } // Reconfigure VRF if ifaceType != intf.InterfaceType_VXLAN_TUNNEL { - plugin.log.Debugf("VRF changed: %v -> %v", oldConfig.Vrf, newConfig.Vrf) - - // interface must not have IP when setting VRF - if err := plugin.removeIPAddresses(ifIdx, oldAddrs, oldConfig.Unnumbered); err != nil { - plugin.log.Error(err) - wasError = err + // Interface must not have IP when setting VRF + if err := c.removeIPAddresses(ifIdx, oldAddrs, oldConfig.Unnumbered); err != nil { + return err } // Get VRF IP version using new list of addresses. During modify, interface VRF IP version // should be updated as well. - isIPv4, isIPv6 := plugin.getIPAddressVersions(newAddrs) + isIPv4, isIPv6 := getIPAddressVersions(newAddrs) if isIPv4 { - if err := plugin.ifHandler.SetInterfaceVrf(ifIdx, newConfig.Vrf); err != nil { - plugin.log.Error(err) - wasError = err + if err := c.ifHandler.SetInterfaceVrf(ifIdx, newConfig.Vrf); err != nil { + return errors.Errorf("failed to set IPv4 VRF %d for interface %s: %v", + newConfig.Vrf, newConfig.Name, err) } } if isIPv6 { - if err := plugin.ifHandler.SetInterfaceVrfIPv6(ifIdx, newConfig.Vrf); err != nil { - plugin.log.Error(err) - wasError = err + if err := c.ifHandler.SetInterfaceVrfIPv6(ifIdx, newConfig.Vrf); err != nil { + return errors.Errorf("failed to set IPv6 VRF %d for interface %s: %v", + newConfig.Vrf, newConfig.Name, err) } } - if err = plugin.configureIPAddresses(newConfig.Name, ifIdx, newAddrs, newConfig.Unnumbered); err != nil { - plugin.log.Error(err) - wasError = err + if err = c.configureIPAddresses(newConfig.Name, ifIdx, newAddrs, newConfig.Unnumbered); err != nil { + return err } } - // container ip address + // Container ip address if newConfig.ContainerIpAddress != oldConfig.ContainerIpAddress { - plugin.log.WithFields(logging.Fields{"ifIdx": ifIdx, "ip_new": newConfig.ContainerIpAddress, "ip_old": oldConfig.ContainerIpAddress}). - Debug("Container IP address modification.") - if err := plugin.ifHandler.AddContainerIP(ifIdx, newConfig.ContainerIpAddress); err != nil { - plugin.log.WithFields(logging.Fields{"newIP": newConfig.ContainerIpAddress, "oldIP": oldConfig.ContainerIpAddress, "ifIdx": ifIdx}). - Errorf("adding container IP failed: %v", err) - wasError = err + if err := c.ifHandler.AddContainerIP(ifIdx, newConfig.ContainerIpAddress); err != nil { + return errors.Errorf("failed to add container IP %s to interface %s: %v", + newConfig.ContainerIpAddress, newConfig.Name, err) } } // Set MTU if changed in interface config if newConfig.Mtu != 0 && newConfig.Mtu != oldConfig.Mtu { - if err := plugin.ifHandler.SetInterfaceMtu(ifIdx, newConfig.Mtu); err != nil { - wasError = err + if err := c.ifHandler.SetInterfaceMtu(ifIdx, newConfig.Mtu); err != nil { + return errors.Errorf("failed to set MTU to interface %s: %v", newConfig.Name, err) } - } else if newConfig.Mtu == 0 && plugin.defaultMtu != 0 { - if err := plugin.ifHandler.SetInterfaceMtu(ifIdx, plugin.defaultMtu); err != nil { - wasError = err + } else if newConfig.Mtu == 0 && c.defaultMtu != 0 { + if err := c.ifHandler.SetInterfaceMtu(ifIdx, c.defaultMtu); err != nil { + return errors.Errorf("failed to set MTU to interface %s: %v", newConfig.Name, err) } } - plugin.swIfIndexes.UpdateMetadata(newConfig.Name, newConfig) - plugin.log.WithFields(logging.Fields{"ifName": newConfig.Name, "ifIdx": ifIdx}).Info("Modified interface") + c.swIfIndexes.UpdateMetadata(newConfig.Name, newConfig) + c.log.Debugf("Metadata updated in interface mapping for %s", newConfig.Name) - return wasError + return nil } /** Modify rx-mode on specified VPP interface */ -func (plugin *InterfaceConfigurator) modifyRxModeForInterfaces(oldIntf *intf.Interfaces_Interface, newIntf *intf.Interfaces_Interface, - ifIdx uint32) error { +func (c *InterfaceConfigurator) modifyRxModeForInterfaces(oldIntf, newIntf *intf.Interfaces_Interface, ifIdx uint32) error { oldRx := oldIntf.RxModeSettings newRx := newIntf.RxModeSettings - if oldRx == nil && newRx != nil || oldRx != nil && newRx == nil || *oldRx != *newRx { + if oldRx == nil && newRx != nil || oldRx != nil && newRx == nil || !proto.Equal(oldRx, newRx) { // If new rx mode is nil, value is reset to default version (differs for interface types) switch newIntf.Type { case intf.InterfaceType_ETHERNET_CSMACD: if newRx == nil { - return plugin.modifyRxMode(newIntf.Name, ifIdx, &intf.Interfaces_Interface_RxModeSettings{RxMode: intf.RxModeType_POLLING}) + return c.modifyRxMode(newIntf.Name, ifIdx, &intf.Interfaces_Interface_RxModeSettings{RxMode: intf.RxModeType_POLLING}) } else if newRx.RxMode != intf.RxModeType_POLLING { - return fmt.Errorf("attempt to set unsupported rx-mode %s on Ethernet interface %s", newRx.RxMode, newIntf.Name) + return errors.Errorf("attempt to set unsupported rx-mode %s to Ethernet interface %s", newRx.RxMode, newIntf.Name) } case intf.InterfaceType_AF_PACKET_INTERFACE: if newRx == nil { - return plugin.modifyRxMode(newIntf.Name, ifIdx, &intf.Interfaces_Interface_RxModeSettings{RxMode: intf.RxModeType_INTERRUPT}) + return c.modifyRxMode(newIntf.Name, ifIdx, &intf.Interfaces_Interface_RxModeSettings{RxMode: intf.RxModeType_INTERRUPT}) } default: // All the other interface types if newRx == nil { - return plugin.modifyRxMode(newIntf.Name, ifIdx, &intf.Interfaces_Interface_RxModeSettings{RxMode: intf.RxModeType_DEFAULT}) + return c.modifyRxMode(newIntf.Name, ifIdx, &intf.Interfaces_Interface_RxModeSettings{RxMode: intf.RxModeType_DEFAULT}) } } - - return plugin.modifyRxMode(newIntf.Name, ifIdx, newRx) + return c.modifyRxMode(newIntf.Name, ifIdx, newRx) } return nil @@ -760,113 +655,105 @@ func (plugin *InterfaceConfigurator) modifyRxModeForInterfaces(oldIntf *intf.Int /** Direct call of vpp api to change rx-mode of specified interface */ -func (plugin *InterfaceConfigurator) modifyRxMode(ifName string, ifIdx uint32, rxMode *intf.Interfaces_Interface_RxModeSettings) error { - err := plugin.ifHandler.SetRxMode(ifIdx, rxMode) - plugin.log.Debugf("RX-mode for %s set to %v", ifName, rxMode.RxMode) - return err +func (c *InterfaceConfigurator) modifyRxMode(ifName string, ifIdx uint32, rxMode *intf.Interfaces_Interface_RxModeSettings) error { + if err := c.ifHandler.SetRxMode(ifIdx, rxMode); err != nil { + return errors.Errorf("failed to set rx-mode for interface %s: %v", ifName, err) + } + return nil } // recreateVPPInterface removes and creates an interface from scratch. -func (plugin *InterfaceConfigurator) recreateVPPInterface(newConfig *intf.Interfaces_Interface, - oldConfig *intf.Interfaces_Interface, ifIdx uint32) (wasError error) { - var err error +func (c *InterfaceConfigurator) recreateVPPInterface(newConfig *intf.Interfaces_Interface, + oldConfig *intf.Interfaces_Interface, ifIdx uint32) error { if oldConfig.Type == intf.InterfaceType_AF_PACKET_INTERFACE { - err = plugin.afPacketConfigurator.DeleteAfPacketInterface(oldConfig, ifIdx) + if err := c.afPacketConfigurator.DeleteAfPacketInterface(oldConfig, ifIdx); err != nil { + return err + } } else { - err = plugin.deleteVPPInterface(oldConfig, ifIdx) - } - if err != nil { - return err + if err := c.deleteVPPInterface(oldConfig, ifIdx); err != nil { + return err + } } - return plugin.ConfigureVPPInterface(newConfig) + return c.ConfigureVPPInterface(newConfig) } // DeleteVPPInterface reacts to a removed NB configuration of a VPP interface. // It results in the interface being removed from VPP. -func (plugin *InterfaceConfigurator) DeleteVPPInterface(iface *intf.Interfaces_Interface) (wasError error) { - plugin.log.Infof("Removing interface %v", iface.Name) - +func (c *InterfaceConfigurator) DeleteVPPInterface(iface *intf.Interfaces_Interface) error { // Remove VxLAN from cache if exists if iface.Type == intf.InterfaceType_VXLAN_TUNNEL { - if _, ok := plugin.vxlanMulticastCache[iface.Name]; ok { - delete(plugin.vxlanMulticastCache, iface.Name) - return + if _, ok := c.vxlanMulticastCache[iface.Name]; ok { + delete(c.vxlanMulticastCache, iface.Name) + c.log.Debugf("Interface %s removed from VxLAN multicast cache, will be removed", iface.Name) + return nil } } - if plugin.afPacketConfigurator.IsPendingAfPacket(iface) { - ifIdx, _, found := plugin.afPacketConfigurator.ifIndexes.LookupIdx(iface.Name) + if c.afPacketConfigurator.IsPendingAfPacket(iface) { + ifIdx, _, found := c.afPacketConfigurator.ifIndexes.LookupIdx(iface.Name) if !found { - return fmt.Errorf("cannot remove af packet interface %v, index not available from mapping", iface.Name) + // Just remove from cache + c.afPacketConfigurator.removeFromCache(iface) + return nil } - return plugin.afPacketConfigurator.DeleteAfPacketInterface(iface, ifIdx) + + return c.afPacketConfigurator.DeleteAfPacketInterface(iface, ifIdx) } // unregister name to init mapping (following triggers notifications for all subscribers, skip physical interfaces) if iface.Type != intf.InterfaceType_ETHERNET_CSMACD { - ifIdx, prev, found := plugin.swIfIndexes.UnregisterName(iface.Name) + ifIdx, prev, found := c.swIfIndexes.UnregisterName(iface.Name) if !found { - plugin.log.WithField("ifname", iface.Name).Debug("Unable to find index for interface to be deleted.") - return nil + return errors.Errorf("Unable to find interface %s in the mapping", iface.Name) } + c.log.Debugf("Interface %s unregistered from interface mapping", iface.Name) // delete from unnumbered map (if the interface is present) - delete(plugin.uIfaceCache, iface.Name) + delete(c.uIfaceCache, iface.Name) + c.log.Debugf("Unnumbered interface %s removed from cache (will be removed)", iface.Name) - if err := plugin.deleteVPPInterface(prev, ifIdx); err != nil { + if err := c.deleteVPPInterface(prev, ifIdx); err != nil { return err } } else { // Find index of the Physical interface and un-configure it - ifIdx, prev, found := plugin.swIfIndexes.LookupIdx(iface.Name) + ifIdx, prev, found := c.swIfIndexes.LookupIdx(iface.Name) if !found { - plugin.log.WithField("ifname", iface.Name).Debug("Unable to find index for interface to be deleted.") - return nil + return errors.Errorf("unable to find index for physical interface %s, cannot delete", iface.Name) } - if err := plugin.deleteVPPInterface(prev, ifIdx); err != nil { + if err := c.deleteVPPInterface(prev, ifIdx); err != nil { return err } } - plugin.log.Infof("Interface %v removed", iface.Name) + c.log.Infof("Interface %v removed", iface.Name) - return wasError + return nil } -func (plugin *InterfaceConfigurator) deleteVPPInterface(oldConfig *intf.Interfaces_Interface, ifIdx uint32) (wasError error) { - plugin.log.WithFields(logging.Fields{"ifname": oldConfig.Name, "swIfIndex": ifIdx}). - Debug("deleteVPPInterface begin") - +func (c *InterfaceConfigurator) deleteVPPInterface(oldConfig *intf.Interfaces_Interface, ifIdx uint32) error { // Skip setting interface to ADMIN_DOWN unless the type AF_PACKET_INTERFACE if oldConfig.Type != intf.InterfaceType_AF_PACKET_INTERFACE { - plugin.log.Infof("Setting interface %v down", oldConfig.Name) - // Let's try to do following even if previously error occurred - if err := plugin.ifHandler.InterfaceAdminDown(ifIdx); err != nil { - plugin.log.Errorf("Setting interface down failed: %v", err) - wasError = err + if err := c.ifHandler.InterfaceAdminDown(ifIdx); err != nil { + return errors.Errorf("failed to set interface %s down: %v", oldConfig.Name, err) } } // Remove DHCP if it was set if oldConfig.SetDhcpClient { - if err := plugin.ifHandler.UnsetInterfaceAsDHCPClient(ifIdx, oldConfig.Name); err != nil { - plugin.log.Error(err) - wasError = err + if err := c.ifHandler.UnsetInterfaceAsDHCPClient(ifIdx, oldConfig.Name); err != nil { + return errors.Errorf("failed to unset interface %s as DHCP client: %v", oldConfig.Name, err) } - // Remove from dhcp mapping - plugin.dhcpIndexes.UnregisterName(oldConfig.Name) - plugin.log.Debugf("Interface %v unset as DHCP client", oldConfig.Name) + // Remove from DHCP mapping + c.dhcpIndexes.UnregisterName(oldConfig.Name) + c.log.Debugf("Interface %v unregistered as DHCP client", oldConfig.Name) } - // let's try to do following even if previously error occurred if oldConfig.ContainerIpAddress != "" { - if err := plugin.ifHandler.DelContainerIP(ifIdx, oldConfig.ContainerIpAddress); err != nil { - plugin.log.Error(err) - wasError = err - } else { - plugin.log.WithFields(logging.Fields{"IPaddr": oldConfig.ContainerIpAddress, "ifIdx": ifIdx}). - Debug("Container IP address deleted") + if err := c.ifHandler.DelContainerIP(ifIdx, oldConfig.ContainerIpAddress); err != nil { + return errors.Errorf("failed to delete container IP %s from interface %s: %v", + oldConfig.ContainerIpAddress, oldConfig.Name, err) } } @@ -874,120 +761,130 @@ func (plugin *InterfaceConfigurator) deleteVPPInterface(oldConfig *intf.Interfac if strings.HasPrefix(oldIP, "fe80") { // TODO: skip link local addresses (possible workaround for af_packet) oldConfig.IpAddresses = append(oldConfig.IpAddresses[:i], oldConfig.IpAddresses[i+1:]...) + c.log.Debugf("delete vpp interface %s: link local address %s skipped", oldConfig.Name, oldIP) } } oldAddrs, err := addrs.StrAddrsToStruct(oldConfig.IpAddresses) if err != nil { - plugin.log.WithFields(logging.Fields{"ifname": oldConfig.Name, "swIfIndex": ifIdx}). - Debug("deleteVPPInterface end ", err) - return err + return errors.Errorf("failed to convert %s IP address list to IPNet structures: %v", oldConfig.Name, err) } for _, oldAddr := range oldAddrs { - if err := plugin.ifHandler.DelInterfaceIP(ifIdx, oldAddr); err != nil { - plugin.log.Errorf("deleting interface IP address failed: %v", err) - wasError = err + if err := c.ifHandler.DelInterfaceIP(ifIdx, oldAddr); err != nil { + return errors.Errorf("failed to remove IP address %s from interface %s: %v", + oldAddr, oldConfig.Name, err) } } - plugin.log.Info("IP addrs removed") - // let's try to do following even if previously error occurred switch oldConfig.Type { case intf.InterfaceType_TAP_INTERFACE: - err = plugin.ifHandler.DeleteTapInterface(oldConfig.Name, ifIdx, oldConfig.Tap.Version) + err = c.ifHandler.DeleteTapInterface(oldConfig.Name, ifIdx, oldConfig.Tap.Version) case intf.InterfaceType_MEMORY_INTERFACE: - err = plugin.ifHandler.DeleteMemifInterface(oldConfig.Name, ifIdx) + err = c.ifHandler.DeleteMemifInterface(oldConfig.Name, ifIdx) case intf.InterfaceType_VXLAN_TUNNEL: - err = plugin.ifHandler.DeleteVxLanTunnel(oldConfig.Name, ifIdx, oldConfig.Vrf, oldConfig.GetVxlan()) + err = c.ifHandler.DeleteVxLanTunnel(oldConfig.Name, ifIdx, oldConfig.Vrf, oldConfig.GetVxlan()) case intf.InterfaceType_SOFTWARE_LOOPBACK: - err = plugin.ifHandler.DeleteLoopbackInterface(oldConfig.Name, ifIdx) + err = c.ifHandler.DeleteLoopbackInterface(oldConfig.Name, ifIdx) case intf.InterfaceType_ETHERNET_CSMACD: - plugin.log.Debugf("Interface removal skipped: cannot remove (blacklist) physical interface") // Not an error + c.log.Debugf("Interface removal skipped: cannot remove (blacklist) physical interface") // Not an error return nil case intf.InterfaceType_AF_PACKET_INTERFACE: - err = plugin.afPacketConfigurator.DeleteAfPacketInterface(oldConfig, ifIdx) + err = c.afPacketConfigurator.DeleteAfPacketInterface(oldConfig, ifIdx) } if err != nil { - wasError = err + return errors.Errorf("failed to remove interface %s, index %d: %v", oldConfig.Name, ifIdx, err) } - plugin.log.WithFields(logging.Fields{"ifname": oldConfig.Name, "swIfIndex": ifIdx}). - Debug("deleteVPPInterface end ", err) - - return wasError + return nil } // ResolveCreatedLinuxInterface reacts to a newly created Linux interface. -func (plugin *InterfaceConfigurator) ResolveCreatedLinuxInterface(interfaceName, hostIfName string, interfaceIndex uint32) { - plugin.log.WithFields(logging.Fields{"ifName": interfaceName, "hostIfName": hostIfName, "ifIdx": interfaceIndex}).Info("New Linux interface was created") - - pendingAfpacket := plugin.afPacketConfigurator.ResolveCreatedLinuxInterface(interfaceName, hostIfName, interfaceIndex) +func (c *InterfaceConfigurator) ResolveCreatedLinuxInterface(ifName, hostIfName string, ifIdx uint32) error { + pendingAfpacket, err := c.afPacketConfigurator.ResolveCreatedLinuxInterface(ifName, hostIfName, ifIdx) + if err != nil { + return err + } if pendingAfpacket != nil { - // there is a pending afpacket that can be now configured - if err := plugin.ConfigureVPPInterface(pendingAfpacket); err != nil { - plugin.log.Error(err) - } + // there is a pending af-packet that can be now configured + return c.ConfigureVPPInterface(pendingAfpacket) } + return nil } // ResolveDeletedLinuxInterface reacts to a removed Linux interface. -func (plugin *InterfaceConfigurator) ResolveDeletedLinuxInterface(interfaceName, hostIfName string, ifIdx uint32) { - plugin.log.WithFields(logging.Fields{"ifName": interfaceName, "hostIfName": hostIfName}).Info("Linux interface was deleted") - - plugin.afPacketConfigurator.ResolveDeletedLinuxInterface(interfaceName, hostIfName, ifIdx) +func (c *InterfaceConfigurator) ResolveDeletedLinuxInterface(ifName, hostIfName string, ifIdx uint32) error { + return c.afPacketConfigurator.ResolveDeletedLinuxInterface(ifName, hostIfName, ifIdx) } -// Returns two flags, whether provided list of addresses contains IPv4 and/or IPv6 type addresses -func (plugin *InterfaceConfigurator) getIPAddressVersions(ipAddrs []*net.IPNet) (isIPv4, isIPv6 bool) { - for _, ip := range ipAddrs { - if ip.IP.To4() != nil { - isIPv4 = true - } else { - isIPv6 = true +// PropagateIfDetailsToStatus looks up all VPP interfaces +func (c *InterfaceConfigurator) propagateIfDetailsToStatus() error { + req := &interfaces.SwInterfaceDump{} + reqCtx := c.vppCh.SendMultiRequest(req) + + for { + msg := &interfaces.SwInterfaceDetails{} + stop, err := reqCtx.ReceiveReply(msg) + if stop { + break } + if err != nil { + return errors.Errorf("failed to receive interface dump details: %v", err) + } + + _, _, found := c.swIfIndexes.LookupName(msg.SwIfIndex) + if !found { + c.log.Warnf("Unregistered interface %v with ID %v found on vpp", + string(bytes.SplitN(msg.InterfaceName, []byte{0x00}, 2)[0]), msg.SwIfIndex) + // Do not register unknown interface here, cuz it may cause inconsistencies in the ifplugin. + // All new interfaces should be registered during configuration + continue + } + + // Propagate interface state information to notification channel. + c.NotifChan <- msg } - return + return nil } // returns memif socket filename ID. Registers it if does not exists yet -func (plugin *InterfaceConfigurator) resolveMemifSocketFilename(memifIf *intf.Interfaces_Interface_Memif) (uint32, error) { +func (c *InterfaceConfigurator) resolveMemifSocketFilename(memifIf *intf.Interfaces_Interface_Memif) (uint32, error) { if memifIf.SocketFilename == "" { - return 0, fmt.Errorf("memif configuration does not contain socket file name") + return 0, errors.Errorf("memif configuration does not contain socket file name") } - registeredID, ok := plugin.memifScCache[memifIf.SocketFilename] + registeredID, ok := c.memifScCache[memifIf.SocketFilename] if !ok { // Register new socket. ID is generated (default filename ID is 0, first is ID 1, second ID 2, etc) - registeredID = uint32(len(plugin.memifScCache)) - err := plugin.ifHandler.RegisterMemifSocketFilename([]byte(memifIf.SocketFilename), registeredID) + registeredID = uint32(len(c.memifScCache)) + err := c.ifHandler.RegisterMemifSocketFilename([]byte(memifIf.SocketFilename), registeredID) if err != nil { - return 0, fmt.Errorf("error registering socket file name %s (ID %d): %v", memifIf.SocketFilename, registeredID, err) + return 0, errors.Errorf("error registering socket file name %s (ID %d): %v", memifIf.SocketFilename, registeredID, err) } - plugin.memifScCache[memifIf.SocketFilename] = registeredID - plugin.log.Debugf("Memif socket filename %s registered under ID %d", memifIf.SocketFilename, registeredID) + c.memifScCache[memifIf.SocketFilename] = registeredID + c.log.Debugf("Memif socket filename %s registered under ID %d", memifIf.SocketFilename, registeredID) } return registeredID, nil } // Returns VxLAN multicast interface index if set and exists. Returns index of the interface an whether the vxlan was cached. -func (plugin *InterfaceConfigurator) getVxLanMulticast(vxlan *intf.Interfaces_Interface) (ifIdx uint32, cached bool, err error) { +func (c *InterfaceConfigurator) getVxLanMulticast(vxlan *intf.Interfaces_Interface) (ifIdx uint32, cached bool, err error) { if vxlan.Vxlan == nil { - plugin.log.Debugf("VxLAN multicast: no data available for %s", vxlan.Name) + c.log.Debugf("VxLAN multicast: no data available for %s", vxlan.Name) return 0, false, nil } if vxlan.Vxlan.Multicast == "" { - plugin.log.Debugf("VxLAN %s has no multicast interface defined", vxlan.Name) + c.log.Debugf("VxLAN %s has no multicast interface defined", vxlan.Name) return 0, false, nil } - mcIfIdx, mcIf, found := plugin.swIfIndexes.LookupIdx(vxlan.Vxlan.Multicast) + mcIfIdx, mcIf, found := c.swIfIndexes.LookupIdx(vxlan.Vxlan.Multicast) if !found { - plugin.log.Infof("multicast interface %s not found, %s is cached", vxlan.Vxlan.Multicast, vxlan.Name) - plugin.vxlanMulticastCache[vxlan.Name] = vxlan + c.vxlanMulticastCache[vxlan.Name] = vxlan + c.log.Debugf("multicast interface %s not found, cached", vxlan.Vxlan.Multicast, vxlan.Name) return 0, true, nil } // Check wheteher at least one of the addresses is from multicast range if len(mcIf.IpAddresses) == 0 { - return 0, false, fmt.Errorf("VxLAN %s refers to multicast interface %s which does not have any IP address", + return 0, false, errors.Errorf("VxLAN %s refers to multicast interface %s which does not have any IP address", vxlan.Name, mcIf.Name) } var IPVerified bool @@ -996,7 +893,7 @@ func (plugin *InterfaceConfigurator) getVxLanMulticast(vxlan *intf.Interfaces_In IPVerified = net.ParseIP(mcIfAddrWithoutMask).IsMulticast() if IPVerified { if vxlan.Vxlan.DstAddress != mcIfAddr { - plugin.log.Warn("VxLAN %s contains destination address %s which will be replaced with multicast %s", + c.log.Warn("VxLAN %s contains destination address %s which will be replaced with multicast %s", vxlan.Name, vxlan.Vxlan.DstAddress, mcIfAddr) } vxlan.Vxlan.DstAddress = mcIfAddrWithoutMask @@ -1004,7 +901,7 @@ func (plugin *InterfaceConfigurator) getVxLanMulticast(vxlan *intf.Interfaces_In } } if !IPVerified { - return 0, false, fmt.Errorf("VxLAN %s refers to multicast interface %s which does not have multicast IP address", + return 0, false, errors.Errorf("VxLAN %s refers to multicast interface %s which does not have multicast IP address", vxlan.Name, mcIf.Name) } @@ -1012,12 +909,14 @@ func (plugin *InterfaceConfigurator) getVxLanMulticast(vxlan *intf.Interfaces_In } // Look over cached VxLAN multicast interfaces and configure them if possible -func (plugin *InterfaceConfigurator) resolveCachedVxLANMulticasts(createdIfName string) error { - for vxlanName, vxlan := range plugin.vxlanMulticastCache { +func (c *InterfaceConfigurator) resolveCachedVxLANMulticasts(createdIfName string) error { + for vxlanName, vxlan := range c.vxlanMulticastCache { if vxlan.Vxlan.Multicast == createdIfName { - delete(plugin.vxlanMulticastCache, vxlanName) - if err := plugin.ConfigureVPPInterface(vxlan); err != nil { - return err + delete(c.vxlanMulticastCache, vxlanName) + c.log.Debugf("Interface %s removed from VxLAN multicast cache, will be configured", vxlanName) + if err := c.ConfigureVPPInterface(vxlan); err != nil { + return errors.Errorf("failed to configure VPP interface %s as VxLAN multicast: %v", + createdIfName, err) } } } @@ -1025,35 +924,37 @@ func (plugin *InterfaceConfigurator) resolveCachedVxLANMulticasts(createdIfName return nil } -func (plugin *InterfaceConfigurator) canMemifBeModifWithoutDelete(newConfig *intf.Interfaces_Interface_Memif, oldConfig *intf.Interfaces_Interface_Memif) bool { +func (c *InterfaceConfigurator) canMemifBeModifWithoutDelete(newConfig *intf.Interfaces_Interface_Memif, oldConfig *intf.Interfaces_Interface_Memif) bool { if newConfig == nil || oldConfig == nil { return true } - if *newConfig != *oldConfig { - plugin.log.Warnf("Difference between new & old config causing recreation of memif, old: '%+v' new: '%+v'", oldConfig, newConfig) + if !proto.Equal(newConfig, oldConfig) { + c.log.Debug("Difference between new & old config causing recreation of memif") return false } return true } -func (plugin *InterfaceConfigurator) canVxlanBeModifWithoutDelete(newConfig *intf.Interfaces_Interface_Vxlan, oldConfig *intf.Interfaces_Interface_Vxlan) bool { +func (c *InterfaceConfigurator) canVxlanBeModifWithoutDelete(newConfig *intf.Interfaces_Interface_Vxlan, oldConfig *intf.Interfaces_Interface_Vxlan) bool { if newConfig == nil || oldConfig == nil { return true } - if *newConfig != *oldConfig { + if !proto.Equal(newConfig, oldConfig) { + c.log.Debug("Difference between new & old config causing recreation of VxLAN") return false } return true } -func (plugin *InterfaceConfigurator) canTapBeModifWithoutDelete(newConfig *intf.Interfaces_Interface_Tap, oldConfig *intf.Interfaces_Interface_Tap) bool { +func (c *InterfaceConfigurator) canTapBeModifWithoutDelete(newConfig *intf.Interfaces_Interface_Tap, oldConfig *intf.Interfaces_Interface_Tap) bool { if newConfig == nil || oldConfig == nil { return true } - if *newConfig != *oldConfig { + if !proto.Equal(newConfig, oldConfig) { + c.log.Debug("Difference between new & old config causing recreation of tap") return false } @@ -1061,12 +962,12 @@ func (plugin *InterfaceConfigurator) canTapBeModifWithoutDelete(newConfig *intf. } // watch and process DHCP notifications. DHCP configuration is registered to dhcp mapping for every interface -func (plugin *InterfaceConfigurator) watchDHCPNotifications() { - plugin.log.Debug("Started watcher on DHCP notifications") +func (c *InterfaceConfigurator) watchDHCPNotifications() { + c.log.Debug("Started watcher on DHCP notifications") for { select { - case notification := <-plugin.DhcpChan: + case notification := <-c.DhcpChan: switch dhcpNotif := notification.(type) { case *dhcp.DHCPComplEvent: var ipAddr, rIPAddr net.IP = dhcpNotif.Lease.HostAddress, dhcpNotif.Lease.RouterAddress @@ -1083,16 +984,16 @@ func (plugin *InterfaceConfigurator) watchDHCPNotifications() { rIPStr = rIPAddr[:4].To4().String() } - plugin.log.Debugf("DHCP assigned %v to interface %q (router address %v)", ipStr, name, rIPStr) + c.log.Debugf("DHCP assigned %v to interface %q (router address %v)", ipStr, name, rIPStr) - ifIdx, _, found := plugin.swIfIndexes.LookupIdx(name) + ifIdx, _, found := c.swIfIndexes.LookupIdx(name) if !found { - plugin.log.Warnf("Expected interface %v not found in the mapping", name) + c.log.Warnf("Expected interface %v not found in the mapping", name) continue } // Register DHCP config - plugin.dhcpIndexes.RegisterName(name, ifIdx, &ifaceidx.DHCPSettings{ + c.dhcpIndexes.RegisterName(name, ifIdx, &ifaceidx.DHCPSettings{ IfName: name, IsIPv6: func(isIPv6 uint8) bool { if isIPv6 == 1 { @@ -1105,16 +1006,35 @@ func (plugin *InterfaceConfigurator) watchDHCPNotifications() { PhysAddress: hwAddr.String(), RouterAddress: rIPStr, }) + c.log.Debugf("Interface %s registered as DHCP client", name) + } + } + } +} - plugin.log.Debugf("Registered dhcp metadata for interface %v", name) +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *InterfaceConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} - _, _, found = plugin.dhcpIndexes.LookupIdx(name) - if found { - plugin.log.Debugf("Name %q is registered", name) - } else { - plugin.log.Debugf("Name %q is NOT registered", name) - } - } +// Returns two flags, whether provided list of addresses contains IPv4 and/or IPv6 type addresses +func getIPAddressVersions(ipAddrs []*net.IPNet) (isIPv4, isIPv6 bool) { + for _, ip := range ipAddrs { + if ip.IP.To4() != nil { + isIPv4 = true + } else { + isIPv6 = true } } + + return } diff --git a/plugins/vpp/ifplugin/interface_config_test.go b/plugins/vpp/ifplugin/interface_config_test.go index d0d5e05da8..ec034596bb 100644 --- a/plugins/vpp/ifplugin/interface_config_test.go +++ b/plugins/vpp/ifplugin/interface_config_test.go @@ -19,9 +19,10 @@ import ( "testing" "time" + "git.fd.io/govpp.git/core" + "git.fd.io/govpp.git/adapter/mock" govppapi "git.fd.io/govpp.git/api" - govpp "git.fd.io/govpp.git/core" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/plugins/vpp/binapi/af_packet" dhcp_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/dhcp" @@ -127,7 +128,7 @@ func TestInterfaceConfiguratorPropagateIfDetailsToStatus(t *testing.T) { }() // Test notifications - Expect(plugin.PropagateIfDetailsToStatus()).To(Succeed()) + Expect(ifplugin.PropagateIfDetailsToStatus(plugin)).To(Succeed()) // This blocks until the result is sent Eventually(done).Should(Receive(Equal(1))) } @@ -461,6 +462,7 @@ func TestInterfacesConfigureVxLANWithMulticastError(t *testing.T) { ctx.MockVpp.MockReply(&ip.IPContainerProxyAddDelReply{}) ctx.MockVpp.MockReply(&interfaces.HwInterfaceSetMtuReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) + ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) // Data data := getTestInterface("if1", if_api.InterfaceType_VXLAN_TUNNEL, []string{"10.0.0.1/24"}, false, "", 0) multicast := getTestInterface("multicastIf", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"20.0.0.1/24"}, false, "", 0) @@ -488,6 +490,7 @@ func TestInterfacesConfigureVxLANWithMulticastIPError(t *testing.T) { ctx.MockVpp.MockReply(&ip.IPContainerProxyAddDelReply{}) ctx.MockVpp.MockReply(&interfaces.HwInterfaceSetMtuReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) + ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) // Data data := getTestInterface("if1", if_api.InterfaceType_VXLAN_TUNNEL, []string{"10.0.0.1/24"}, false, "", 0) multicast := getTestInterface("multicastIf", if_api.InterfaceType_SOFTWARE_LOOPBACK, nil, false, "", 0) @@ -621,7 +624,7 @@ func TestInterfacesConfigureAfPacketPending(t *testing.T) { } // Configure new interface and tests error propagation during configuration -func TestInterfacesConfigureInterfaceErrors(t *testing.T) { +func TestInterfacesConfigureInterfaceLoopbackError(t *testing.T) { var err error // Setup ctx, connection, plugin := ifTestSetup(t) @@ -630,38 +633,161 @@ func TestInterfacesConfigureInterfaceErrors(t *testing.T) { ctx.MockVpp.MockReply(&interfaces.CreateLoopbackReply{ SwIfIndex: 1, }) + // Data + data := getTestInterface("if1", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"10.0.0.1/24"}, false, "46:06:18:DB:05:3A", 1500) + data.RxModeSettings = getTestRxModeSettings(if_api.RxModeType_POLLING) + // Test configure TAP + err = plugin.ConfigureVPPInterface(data) + Expect(err).ToNot(BeNil()) + _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) + Expect(found).To(BeFalse()) +} + +// Configure new interface and tests error propagation during configuration +func TestInterfacesConfigureInterfaceRxModeError(t *testing.T) { + var err error + // Setup + ctx, connection, plugin := ifTestSetup(t) + defer ifTestTeardown(connection, plugin) + // Reply set + ctx.MockVpp.MockReply(&interfaces.CreateLoopbackReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetRxModeReply{ Retval: 1, // Simulate Rx mode error }) + // Data + data := getTestInterface("if1", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"10.0.0.1/24"}, false, "46:06:18:DB:05:3A", 1500) + data.RxModeSettings = getTestRxModeSettings(if_api.RxModeType_POLLING) + // Test configure TAP + err = plugin.ConfigureVPPInterface(data) + Expect(err).ToNot(BeNil()) + _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) + Expect(found).To(BeFalse()) +} + +// Configure new interface and tests error propagation during configuration +func TestInterfacesConfigureInterfaceMacError(t *testing.T) { + var err error + // Setup + ctx, connection, plugin := ifTestSetup(t) + defer ifTestTeardown(connection, plugin) + // Reply set + ctx.MockVpp.MockReply(&interfaces.CreateLoopbackReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetRxModeReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetMacAddressReply{ Retval: 1, // Simulate MAC error }) + // Data + data := getTestInterface("if1", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"10.0.0.1/24"}, false, "46:06:18:DB:05:3A", 1500) + data.RxModeSettings = getTestRxModeSettings(if_api.RxModeType_POLLING) + // Test configure TAP + err = plugin.ConfigureVPPInterface(data) + Expect(err).ToNot(BeNil()) + _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) + Expect(found).To(BeFalse()) +} + +// Configure new interface and tests error propagation during configuration +func TestInterfacesConfigureInterfaceVrfError(t *testing.T) { + var err error + // Setup + ctx, connection, plugin := ifTestSetup(t) + defer ifTestTeardown(connection, plugin) + // Reply set + ctx.MockVpp.MockReply(&interfaces.CreateLoopbackReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetRxModeReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetMacAddressReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetTableReply{ Retval: 1, // Interface VRF error }) + // Data + data := getTestInterface("if1", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"10.0.0.1/24"}, false, "46:06:18:DB:05:3A", 1500) + data.RxModeSettings = getTestRxModeSettings(if_api.RxModeType_POLLING) + // Test configure TAP + err = plugin.ConfigureVPPInterface(data) + Expect(err).ToNot(BeNil()) + _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) + Expect(found).To(BeFalse()) +} + +// Configure new interface and tests error propagation during configuration +func TestInterfacesConfigureInterfaceIPAddressError(t *testing.T) { + var err error + // Setup + ctx, connection, plugin := ifTestSetup(t) + defer ifTestTeardown(connection, plugin) + // Reply set + ctx.MockVpp.MockReply(&interfaces.CreateLoopbackReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetRxModeReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetMacAddressReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetTableReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{ Retval: 1, // IP address error }) + // Data + data := getTestInterface("if1", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"10.0.0.1/24"}, false, "46:06:18:DB:05:3A", 1500) + data.RxModeSettings = getTestRxModeSettings(if_api.RxModeType_POLLING) + // Test configure TAP + err = plugin.ConfigureVPPInterface(data) + Expect(err).ToNot(BeNil()) + _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) + Expect(found).To(BeFalse()) +} + +// Configure new interface and tests error propagation during configuration +func TestInterfacesConfigureInterfaceContainerIPAddressError(t *testing.T) { + var err error + // Setup + ctx, connection, plugin := ifTestSetup(t) + defer ifTestTeardown(connection, plugin) + // Reply set + ctx.MockVpp.MockReply(&interfaces.CreateLoopbackReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetRxModeReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetMacAddressReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetTableReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) ctx.MockVpp.MockReply(&ip.IPContainerProxyAddDelReply{ Retval: 1, // Container IP error }) + // Data + data := getTestInterface("if1", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"10.0.0.1/24"}, false, "46:06:18:DB:05:3A", 1500) + data.RxModeSettings = getTestRxModeSettings(if_api.RxModeType_POLLING) + // Test configure TAP + err = plugin.ConfigureVPPInterface(data) + Expect(err).ToNot(BeNil()) + _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) + Expect(found).To(BeFalse()) +} + +// Configure new interface and tests error propagation during configuration +func TestInterfacesConfigureInterfaceMtuError(t *testing.T) { + var err error + // Setup + ctx, connection, plugin := ifTestSetup(t) + defer ifTestTeardown(connection, plugin) + // Reply set + ctx.MockVpp.MockReply(&interfaces.CreateLoopbackReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetRxModeReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetMacAddressReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetTableReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) + ctx.MockVpp.MockReply(&ip.IPContainerProxyAddDelReply{}) ctx.MockVpp.MockReply(&interfaces.HwInterfaceSetMtuReply{ Retval: 1, // MTU error }) - ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) - ctx.MockVpp.MockReply() // Do not propagate interface details - ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) // Break status propagation // Data data := getTestInterface("if1", if_api.InterfaceType_SOFTWARE_LOOPBACK, []string{"10.0.0.1/24"}, false, "46:06:18:DB:05:3A", 1500) data.RxModeSettings = getTestRxModeSettings(if_api.RxModeType_POLLING) // Test configure TAP err = plugin.ConfigureVPPInterface(data) Expect(err).ToNot(BeNil()) - Expect(err.Error()).To(ContainSubstring("found 6 errors")) - _, meta, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) - Expect(found).To(BeTrue()) - Expect(meta).ToNot(BeNil()) + _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) + Expect(found).To(BeFalse()) } // Configure new interface and tests admin up error @@ -1281,6 +1407,7 @@ func TestInterfacesDeleteEthernetInterface(t *testing.T) { ctx, connection, plugin := ifTestSetup(t) defer ifTestTeardown(connection, plugin) // Reply set + ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) ctx.MockVpp.MockReply(&ip.IPContainerProxyAddDelReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) // Data @@ -1300,21 +1427,15 @@ func TestInterfacesDeleteAfPacketInterface(t *testing.T) { ctx, connection, plugin := ifTestSetup(t) defer ifTestTeardown(connection, plugin) // Reply set - ctx.MockVpp.MockReply(&af_packet.AfPacketCreateReply{}) // Create - ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) - ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetTableReply{}) - ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) - ctx.MockVpp.MockReply(&interfaces.HwInterfaceSetMtuReply{}) - ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) - ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) // Delete - ctx.MockVpp.MockReply(&ip.IPContainerProxyAddDelReply{}) - ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) // Delete ctx.MockVpp.MockReply(&af_packet.AfPacketDeleteReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) // Data data := getTestAfPacket("if1", []string{"10.0.0.1/24"}, "host1") // Register hosts plugin.ResolveCreatedLinuxInterface("host1", "host1", 2) + // Register af-packet + plugin.GetSwIfIndexes().RegisterName(data.Name, 1, data) // Test delete err = plugin.DeleteVPPInterface(data) Expect(err).To(BeNil()) @@ -1334,7 +1455,10 @@ func TestInterfacesDeletePendingAfPacketInterface(t *testing.T) { ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) ctx.MockVpp.MockReply(&interfaces.HwInterfaceSetMtuReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) + ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceSetFlagsReply{}) // Delete + ctx.MockVpp.MockReply(&af_packet.AfPacketDeleteReply{}) + ctx.MockVpp.MockReply(&interfaces.SwInterfaceTagAddDelReply{}) ctx.MockVpp.MockReply(&ip.IPContainerProxyAddDelReply{}) ctx.MockVpp.MockReply(&interfaces.SwInterfaceAddDelAddressReply{}) ctx.MockVpp.MockReply(&af_packet.AfPacketDeleteReply{}) @@ -1347,7 +1471,9 @@ func TestInterfacesDeletePendingAfPacketInterface(t *testing.T) { err = plugin.ConfigureVPPInterface(data) Expect(err).To(BeNil()) _, _, found := plugin.GetSwIfIndexes().LookupIdx(data.Name) - plugin.ResolveDeletedLinuxInterface("host1", "host1", 2) + Expect(found).To(BeTrue()) + err = plugin.ResolveDeletedLinuxInterface("host1", "host1", 2) + Expect(err).To(BeNil()) err = plugin.DeleteVPPInterface(data) Expect(err).To(BeNil()) _, _, found = plugin.GetSwIfIndexes().LookupIdx(data.Name) @@ -1389,13 +1515,13 @@ func TestModifyRxMode(t *testing.T) { /* Interface Test Setup */ -func ifTestSetup(t *testing.T) (*vppcallmock.TestCtx, *govpp.Connection, *ifplugin.InterfaceConfigurator) { +func ifTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *ifplugin.InterfaceConfigurator) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } - connection, err := govpp.Connect(ctx.MockVpp) + connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) // Logger @@ -1405,13 +1531,13 @@ func ifTestSetup(t *testing.T) (*vppcallmock.TestCtx, *govpp.Connection, *ifplug // Configurator plugin := &ifplugin.InterfaceConfigurator{} notifChan := make(chan govppapi.Message, 5) - err = plugin.Init(log, connection, 1, notifChan, 1500, true) + err = plugin.Init(log, connection, 1, notifChan, 1500) Expect(err).To(BeNil()) return ctx, connection, plugin } -func ifTestTeardown(connection *govpp.Connection, plugin *ifplugin.InterfaceConfigurator) { +func ifTestTeardown(connection *core.Connection, plugin *ifplugin.InterfaceConfigurator) { connection.Disconnect() err := plugin.Close() Expect(err).To(BeNil()) diff --git a/plugins/vpp/ifplugin/interface_state.go b/plugins/vpp/ifplugin/interface_state.go index 6333ab87bc..0353626c4c 100644 --- a/plugins/vpp/ifplugin/interface_state.go +++ b/plugins/vpp/ifplugin/interface_state.go @@ -17,13 +17,13 @@ package ifplugin import ( "bytes" "context" - "fmt" "net" "os" "sync" "time" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -73,9 +73,9 @@ type InterfaceStateUpdater struct { access sync.Mutex // lock for the state data map vppCh govppapi.Channel - vppNotifSubs *govppapi.NotifSubscription - vppCountersSubs *govppapi.NotifSubscription - vppCombinedCountersSubs *govppapi.NotifSubscription + vppNotifSubs govppapi.SubscriptionCtx + vppCountersSubs govppapi.SubscriptionCtx + vppCombinedCountersSubs govppapi.SubscriptionCtx notifChan chan govppapi.Message swIdxChan chan ifaceidx.SwIfIdxDto @@ -84,237 +84,229 @@ type InterfaceStateUpdater struct { } // Init members (channels, maps...) and start go routines -func (plugin *InterfaceStateUpdater) Init(ctx context.Context, logger logging.PluginLogger, goVppMux govppmux.API, +func (c *InterfaceStateUpdater) Init(ctx context.Context, logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, notifChan chan govppapi.Message, publishIfState func(notification *intf.InterfaceNotification)) (err error) { // Logger - plugin.log = logger.NewLogger("-if-state") - plugin.log.Info("Initializing InterfaceStateUpdater") + c.log = logger.NewLogger("if-state") // Mappings - plugin.swIfIndexes = swIfIndexes + c.swIfIndexes = swIfIndexes - plugin.publishIfState = publishIfState - plugin.ifState = make(map[uint32]*intf.InterfacesState_Interface) + c.publishIfState = publishIfState + c.ifState = make(map[uint32]*intf.InterfacesState_Interface) // VPP channel - plugin.vppCh, err = goVppMux.NewAPIChannel() + c.vppCh, err = goVppMux.NewAPIChannel() if err != nil { - return err + return errors.Errorf("failed to create API channel: %v", err) } - plugin.swIdxChan = make(chan ifaceidx.SwIfIdxDto, 100) - swIfIndexes.WatchNameToIdx("ifplugin_ifstate", plugin.swIdxChan) - plugin.notifChan = notifChan + c.swIdxChan = make(chan ifaceidx.SwIfIdxDto, 100) + swIfIndexes.WatchNameToIdx("ifplugin_ifstate", c.swIdxChan) + c.notifChan = notifChan // Create child context var childCtx context.Context - childCtx, plugin.cancel = context.WithCancel(ctx) + childCtx, c.cancel = context.WithCancel(ctx) // Watch for incoming notifications - go plugin.watchVPPNotifications(childCtx) + go c.watchVPPNotifications(childCtx) + + c.log.Info("Interface state updater initialized") return nil } // AfterInit subscribes for watching VPP notifications on previously initialized channel -func (plugin *InterfaceStateUpdater) AfterInit() (err error) { - plugin.subscribeVPPNotifications() - +func (c *InterfaceStateUpdater) AfterInit() error { + err := c.subscribeVPPNotifications() + if err != nil { + return err + } return nil } // subscribeVPPNotifications subscribes for interface state notifications from VPP. -func (plugin *InterfaceStateUpdater) subscribeVPPNotifications() error { +func (c *InterfaceStateUpdater) subscribeVPPNotifications() error { var err error - // subscribe for receiving SwInterfaceEvents notifications - plugin.vppNotifSubs, err = plugin.vppCh.SubscribeNotification(plugin.notifChan, interfaces.NewSwInterfaceEvent) - if err != nil { - return err + if c.vppNotifSubs, err = c.vppCh.SubscribeNotification(c.notifChan, &interfaces.SwInterfaceEvent{}); err != nil { + return errors.Errorf("failed to subscribe VPP notification (sw_interface_event): %v", err) } // subscribe for receiving VnetInterfaceSimpleCounters notifications - plugin.vppCountersSubs, err = plugin.vppCh.SubscribeNotification(plugin.notifChan, stats.NewVnetInterfaceSimpleCounters) - if err != nil { - return err + if c.vppCountersSubs, err = c.vppCh.SubscribeNotification(c.notifChan, &stats.VnetInterfaceSimpleCounters{}); err != nil { + return errors.Errorf("failed to subscribe VPP notification (vnet_interface_simple_counters): %v", err) } // subscribe for receiving VnetInterfaceCombinedCounters notifications - plugin.vppCombinedCountersSubs, err = plugin.vppCh.SubscribeNotification(plugin.notifChan, stats.NewVnetInterfaceCombinedCounters) - if err != nil { - return err + if c.vppCombinedCountersSubs, err = c.vppCh.SubscribeNotification(c.notifChan, &stats.VnetInterfaceCombinedCounters{}); err != nil { + return errors.Errorf("failed to subscribe VPP notification (vnet_interface_combined_counters): %v", err) } - wantInterfaceEventsReply := &interfaces.WantInterfaceEventsReply{} + wantIfEventsReply := &interfaces.WantInterfaceEventsReply{} // enable interface state notifications from VPP - err = plugin.vppCh.SendRequest(&interfaces.WantInterfaceEvents{ + err = c.vppCh.SendRequest(&interfaces.WantInterfaceEvents{ PID: uint32(os.Getpid()), EnableDisable: 1, - }).ReceiveReply(wantInterfaceEventsReply) - plugin.log.Debug("wantInterfaceEventsReply: ", wantInterfaceEventsReply, " ", err) + }).ReceiveReply(wantIfEventsReply) if err != nil { - return err + return errors.Errorf("failed to get interface events: %v", err) } - if wantInterfaceEventsReply.Retval != 0 { - return fmt.Errorf(fmt.Sprintf("wantStatsReply=%d", wantInterfaceEventsReply.Retval)) + if wantIfEventsReply.Retval != 0 { + return errors.Errorf("%s returned %d", wantIfEventsReply.GetMessageName(), wantIfEventsReply.Retval) } wantStatsReply := &stats.WantStatsReply{} // enable interface counters notifications from VPP - err = plugin.vppCh.SendRequest(&stats.WantStats{ + err = c.vppCh.SendRequest(&stats.WantStats{ PID: uint32(os.Getpid()), EnableDisable: 1, }).ReceiveReply(wantStatsReply) - plugin.log.Debug("wantStatsReply: ", wantStatsReply, " ", err) if err != nil { - return err + return errors.Errorf("failed to get interface events: %v", err) } if wantStatsReply.Retval != 0 { - return fmt.Errorf(fmt.Sprintf("wantStatsReply=%d", wantStatsReply.Retval)) + return errors.Errorf("%s returned %d", wantStatsReply.GetMessageName(), wantStatsReply.Retval) } return nil } // Close unsubscribes from interface state notifications from VPP & GOVPP channel -func (plugin *InterfaceStateUpdater) Close() error { - plugin.cancel() - plugin.wg.Wait() +func (c *InterfaceStateUpdater) Close() error { + c.cancel() + c.wg.Wait() - if plugin.vppNotifSubs != nil { - plugin.vppCh.UnsubscribeNotification(plugin.vppNotifSubs) + if c.vppNotifSubs != nil { + if err := c.vppNotifSubs.Unsubscribe(); err != nil { + return c.LogError(errors.Errorf("failed to unsubscribe interface state notification on close: %v", err)) + } } - if plugin.vppCountersSubs != nil { - plugin.vppCh.UnsubscribeNotification(plugin.vppCountersSubs) + if c.vppCountersSubs != nil { + if err := c.vppCountersSubs.Unsubscribe(); err != nil { + return c.LogError(errors.Errorf("failed to unsubscribe interface state counters on close: %v", err)) + } } - if plugin.vppCombinedCountersSubs != nil { - plugin.vppCh.UnsubscribeNotification(plugin.vppCombinedCountersSubs) + if c.vppCombinedCountersSubs != nil { + if err := c.vppCombinedCountersSubs.Unsubscribe(); err != nil { + return c.LogError(errors.Errorf("failed to unsubscribe interface state combined counters on close: %v", err)) + } } - return safeclose.Close(plugin.vppCh) + if err := safeclose.Close(c.vppCh); err != nil { + return c.LogError(errors.Errorf("failed to safe close interface state: %v", err)) + } + + return nil } // watchVPPNotifications watches for delivery of notifications from VPP. -func (plugin *InterfaceStateUpdater) watchVPPNotifications(ctx context.Context) { - plugin.wg.Add(1) - defer plugin.wg.Done() +func (c *InterfaceStateUpdater) watchVPPNotifications(ctx context.Context) { + c.wg.Add(1) + defer c.wg.Done() - if plugin.notifChan != nil { - plugin.log.Info("watchVPPNotifications starting") + if c.notifChan != nil { + c.log.Debug("Interface state VPP notification watcher started") } else { - plugin.log.Error("watchVPPNotifications will not start") + c.log.Warn("Interface state VPP notification does not start: the channel c nil") return } for { select { - case msg := <-plugin.notifChan: + case msg := <-c.notifChan: switch notif := msg.(type) { case *interfaces.SwInterfaceEvent: - plugin.processIfStateNotification(notif) + c.processIfStateNotification(notif) case *stats.VnetInterfaceSimpleCounters: - plugin.processIfCounterNotification(notif) + c.processIfCounterNotification(notif) case *stats.VnetInterfaceCombinedCounters: - plugin.processIfCombinedCounterNotification(notif) + c.processIfCombinedCounterNotification(notif) case *interfaces.SwInterfaceDetails: - plugin.updateIfStateDetails(notif) + c.updateIfStateDetails(notif) default: - plugin.log.Debugf("Ignoring unknown VPP notification: %s %+v", + c.log.Debugf("Ignoring unknown VPP notification: %s, %v", msg.GetMessageName(), msg) } - case swIdxDto := <-plugin.swIdxChan: + case swIdxDto := <-c.swIdxChan: if swIdxDto.Del { - plugin.setIfStateDeleted(swIdxDto.Idx, swIdxDto.Name) + c.setIfStateDeleted(swIdxDto.Idx, swIdxDto.Name) } swIdxDto.Done() case <-ctx.Done(): // stop watching for notifications + c.log.Debug("Interface state VPP notification watcher stopped") return } } } // processIfStateNotification process a VPP state notification. -func (plugin *InterfaceStateUpdater) processIfStateNotification(notif *interfaces.SwInterfaceEvent) { - //plugin.access.Lock() not needed because of channel synchronization - //defer plugin.access.Unlock() - +func (c *InterfaceStateUpdater) processIfStateNotification(notif *interfaces.SwInterfaceEvent) { // update and return if state data - ifState, found, err := plugin.updateIfStateFlags(notif) + ifState, found := c.updateIfStateFlags(notif) if !found { - plugin.log.WithField("swIfIndex", notif.SwIfIndex). - Debug("processIfStateNotification but the swIfIndex is not event registered") return } - if err != nil { - plugin.log.Warn(err) - return - } - - plugin.log.WithFields(logging.Fields{"ifName": ifState.Name, "swIfIndex": notif.SwIfIndex, "AdminUpDown": notif.AdminUpDown, - "LinkUpDown": notif.LinkUpDown, "Deleted": notif.Deleted}).Debug("Interface state change notification.") + c.log.Debugf("Interface state notification for %s (Idx %d)", ifState.Name, ifState.IfIndex) // store data in ETCD - plugin.publishIfState(&intf.InterfaceNotification{ + c.publishIfState(&intf.InterfaceNotification{ Type: intf.InterfaceNotification_UPDOWN, State: ifState}) } // getIfStateData returns interface state data structure for the specified interface index and interface name. // NOTE: plugin.ifStateData needs to be locked when calling this function! -func (plugin *InterfaceStateUpdater) getIfStateData(swIfIndex uint32, ifName string) ( - *intf.InterfacesState_Interface, bool, error) { +func (c *InterfaceStateUpdater) getIfStateData(swIfIndex uint32, ifName string) (*intf.InterfacesState_Interface, bool) { - ifState, ok := plugin.ifState[swIfIndex] + ifState, ok := c.ifState[swIfIndex] - // check also if the provided logical name is the same as the one associated + // check also if the provided logical name c the same as the one associated // with swIfIndex, because swIfIndexes might be reused if ok && ifState.Name == ifName { - return ifState, true, nil + return ifState, true } - return nil, false, nil + return nil, false } // getIfStateDataWLookup returns interface state data structure for the specified interface index (creates it if it does not exist). // NOTE: plugin.ifStateData needs to be locked when calling this function! -func (plugin *InterfaceStateUpdater) getIfStateDataWLookup(swIfIndex uint32) ( - *intf.InterfacesState_Interface, bool, error) { - ifName, _, found := plugin.swIfIndexes.LookupName(swIfIndex) - +func (c *InterfaceStateUpdater) getIfStateDataWLookup(ifIdx uint32) ( + *intf.InterfacesState_Interface, bool) { + ifName, _, found := c.swIfIndexes.LookupName(ifIdx) if !found { - return nil, found, nil + c.log.Debugf("Interface state data structure lookup for %d interrupted, not registered yet", ifIdx) + return nil, found } - ifState, found, err := plugin.getIfStateData(swIfIndex, ifName) - + ifState, found := c.getIfStateData(ifIdx, ifName) if !found { ifState = &intf.InterfacesState_Interface{ - IfIndex: swIfIndex, + IfIndex: ifIdx, Name: ifName, Statistics: &intf.InterfacesState_Interface_Statistics{}, } - plugin.ifState[swIfIndex] = ifState + c.ifState[ifIdx] = ifState found = true } - return ifState, found, err + return ifState, found } // updateIfStateFlags updates the interface state data in memory from provided VPP flags message and returns updated state data. // NOTE: plugin.ifStateData needs to be locked when calling this function! -func (plugin *InterfaceStateUpdater) updateIfStateFlags(vppMsg *interfaces.SwInterfaceEvent) ( - iface *intf.InterfacesState_Interface, found bool, err error) { +func (c *InterfaceStateUpdater) updateIfStateFlags(vppMsg *interfaces.SwInterfaceEvent) ( + iface *intf.InterfacesState_Interface, found bool) { - ifState, found, err := plugin.getIfStateDataWLookup(vppMsg.SwIfIndex) + ifState, found := c.getIfStateDataWLookup(vppMsg.SwIfIndex) if !found { - return nil, false, err - } - if err != nil { - return nil, false, err + return nil, false } ifState.LastChange = time.Now().Unix() @@ -333,51 +325,47 @@ func (plugin *InterfaceStateUpdater) updateIfStateFlags(vppMsg *interfaces.SwInt ifState.OperStatus = intf.InterfacesState_Interface_DOWN } } - return ifState, true, nil + return ifState, true } // processIfCounterNotification processes a VPP (simple) counter message. -func (plugin *InterfaceStateUpdater) processIfCounterNotification(counter *stats.VnetInterfaceSimpleCounters) { - plugin.access.Lock() - defer plugin.access.Unlock() +func (c *InterfaceStateUpdater) processIfCounterNotification(counter *stats.VnetInterfaceSimpleCounters) { + c.access.Lock() + defer c.access.Unlock() for i := uint32(0); i < counter.Count; i++ { swIfIndex := counter.FirstSwIfIndex + i - ifState, found, err := plugin.getIfStateDataWLookup(swIfIndex) + ifState, found := c.getIfStateDataWLookup(swIfIndex) if !found { continue } - if err != nil { - plugin.log.Warn(err) - continue - } - stats := ifState.Statistics + ifStats := ifState.Statistics packets := counter.Data[i] switch counterType(counter.VnetCounterType) { case Drop: - stats.DropPackets = packets + ifStats.DropPackets = packets case Punt: - stats.PuntPackets = packets + ifStats.PuntPackets = packets case IPv4: - stats.Ipv4Packets = packets + ifStats.Ipv4Packets = packets case IPv6: - stats.Ipv6Packets = packets + ifStats.Ipv6Packets = packets case RxNoBuf: - stats.InNobufPackets = packets + ifStats.InNobufPackets = packets case RxMiss: - stats.InMissPackets = packets + ifStats.InMissPackets = packets case RxError: - stats.InErrorPackets = packets + ifStats.InErrorPackets = packets case TxError: - stats.OutErrorPackets = packets + ifStats.OutErrorPackets = packets } } } // processIfCombinedCounterNotification processes a VPP message with combined counters. -func (plugin *InterfaceStateUpdater) processIfCombinedCounterNotification(counter *stats.VnetInterfaceCombinedCounters) { - plugin.access.Lock() - defer plugin.access.Unlock() +func (c *InterfaceStateUpdater) processIfCombinedCounterNotification(counter *stats.VnetInterfaceCombinedCounters) { + c.access.Lock() + defer c.access.Unlock() if counter.VnetCounterType > Tx { // TODO: process other types of combined counters (RX/TX for unicast/multicast/broadcast) @@ -387,47 +375,36 @@ func (plugin *InterfaceStateUpdater) processIfCombinedCounterNotification(counte var save bool for i := uint32(0); i < counter.Count; i++ { swIfIndex := counter.FirstSwIfIndex + i - ifState, found, err := plugin.getIfStateDataWLookup(swIfIndex) + ifState, found := c.getIfStateDataWLookup(swIfIndex) if !found { continue } - if err != nil { - plugin.log.Warn(err) - continue - } - stats := ifState.Statistics + ifStats := ifState.Statistics if combinedCounterType(counter.VnetCounterType) == Rx { - stats.InPackets = counter.Data[i].Packets - stats.InBytes = counter.Data[i].Bytes + ifStats.InPackets = counter.Data[i].Packets + ifStats.InBytes = counter.Data[i].Bytes } else if combinedCounterType(counter.VnetCounterType) == Tx { - stats.OutPackets = counter.Data[i].Packets - stats.OutBytes = counter.Data[i].Bytes + ifStats.OutPackets = counter.Data[i].Packets + ifStats.OutBytes = counter.Data[i].Bytes save = true } } if save { // store counters of all interfaces into ETCD - for _, counter := range plugin.ifState { - //plugin.deps.DB.Put(intf.InterfaceStateKey(c.Name), counter) - plugin.publishIfState(&intf.InterfaceNotification{ + for _, counter := range c.ifState { + c.publishIfState(&intf.InterfaceNotification{ Type: intf.InterfaceNotification_UPDOWN, State: counter}) } } } // updateIfStateDetails updates the interface state data in memory from provided VPP details message. -func (plugin *InterfaceStateUpdater) updateIfStateDetails(ifDetails *interfaces.SwInterfaceDetails) { - plugin.access.Lock() - defer plugin.access.Unlock() +func (c *InterfaceStateUpdater) updateIfStateDetails(ifDetails *interfaces.SwInterfaceDetails) { + c.access.Lock() + defer c.access.Unlock() - ifState, found, err := plugin.getIfStateDataWLookup(ifDetails.SwIfIndex) + ifState, found := c.getIfStateDataWLookup(ifDetails.SwIfIndex) if !found { - plugin.log.WithField("swIfIndex", ifDetails.SwIfIndex). - Debug("updateIfStateDetails but the swIfIndex is not event registered") - return - } - if err != nil { - plugin.log.Warn(err) return } @@ -476,23 +453,17 @@ func (plugin *InterfaceStateUpdater) updateIfStateDetails(ifDetails *interfaces. ifState.Duplex = intf.InterfacesState_Interface_UNKNOWN_DUPLEX } - plugin.publishIfState(&intf.InterfaceNotification{ + c.publishIfState(&intf.InterfaceNotification{ Type: intf.InterfaceNotification_UNKNOWN, State: ifState}) } // setIfStateDeleted marks the interface as deleted in the state data structure in memory. -func (plugin *InterfaceStateUpdater) setIfStateDeleted(swIfIndex uint32, ifName string) { - plugin.access.Lock() - defer plugin.access.Unlock() +func (c *InterfaceStateUpdater) setIfStateDeleted(swIfIndex uint32, ifName string) { + c.access.Lock() + defer c.access.Unlock() - ifState, found, err := plugin.getIfStateData(swIfIndex, ifName) + ifState, found := c.getIfStateData(swIfIndex, ifName) if !found { - plugin.log.WithField("swIfIndex", swIfIndex). - Debug("notification delete but the swIfIndex is not event registered") - return - } - if err != nil { - plugin.log.Warn(err) return } ifState.AdminStatus = intf.InterfacesState_Interface_DELETED @@ -500,6 +471,20 @@ func (plugin *InterfaceStateUpdater) setIfStateDeleted(swIfIndex uint32, ifName ifState.LastChange = time.Now().Unix() // this can be post-processed by multiple plugins - plugin.publishIfState(&intf.InterfaceNotification{ + c.publishIfState(&intf.InterfaceNotification{ Type: intf.InterfaceNotification_UNKNOWN, State: ifState}) } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *InterfaceStateUpdater) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/ifplugin/interface_state_test.go b/plugins/vpp/ifplugin/interface_state_test.go index 81bfa14ff8..ed1328e4f8 100644 --- a/plugins/vpp/ifplugin/interface_state_test.go +++ b/plugins/vpp/ifplugin/interface_state_test.go @@ -18,9 +18,10 @@ import ( "net" "testing" + "git.fd.io/govpp.git/core" + "git.fd.io/govpp.git/adapter/mock" govppapi "git.fd.io/govpp.git/api" - govpp "git.fd.io/govpp.git/core" "github.com/ligato/cn-infra/logging" "github.com/ligato/cn-infra/logging/logrus" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -34,9 +35,8 @@ import ( "golang.org/x/net/context" ) -func testPluginDataInitialization(t *testing.T) (*govpp.Connection, ifaceidx.SwIfIndexRW, *ifplugin.InterfaceStateUpdater, - chan govppapi.Message, chan *intf.InterfaceNotification, -) { +func testPluginDataInitialization(t *testing.T) (*core.Connection, ifaceidx.SwIfIndexRW, *ifplugin.InterfaceStateUpdater, + chan govppapi.Message, chan *intf.InterfaceNotification) { RegisterTestingT(t) // Initialize notification channel @@ -59,10 +59,16 @@ func testPluginDataInitialization(t *testing.T) (*govpp.Connection, ifaceidx.SwI ctx, _ := context.WithCancel(context.Background()) // Create connection - mockCtx := &vppcallmock.TestCtx{MockVpp: &mock.VppAdapter{}} - connection, err := govpp.Connect(mockCtx.MockVpp) + mockCtx := &vppcallmock.TestCtx{ + MockVpp: mock.NewVppAdapter(), + } + connection, err := core.Connect(mockCtx.MockVpp) Expect(err).To(BeNil()) + // Prepare Init VPP replies + mockCtx.MockVpp.MockReply(&interfaces.WantInterfaceEventsReply{}) + mockCtx.MockVpp.MockReply(&stats.WantStatsReply{}) + // Create plugin logger pluginLogger := logging.ForPlugin("testname") @@ -76,7 +82,7 @@ func testPluginDataInitialization(t *testing.T) (*govpp.Connection, ifaceidx.SwI return connection, index, ifPlugin, notifChan, publishChan } -func testPluginDataTeardown(plugin *ifplugin.InterfaceStateUpdater, connection *govpp.Connection) { +func testPluginDataTeardown(plugin *ifplugin.InterfaceStateUpdater, connection *core.Connection) { connection.Disconnect() Expect(plugin.Close()).To(BeNil()) logging.DefaultRegistry.ClearRegistry() diff --git a/plugins/vpp/ifplugin/nat_config.go b/plugins/vpp/ifplugin/nat_config.go index 45fb1cc67b..0318e3b2ea 100644 --- a/plugins/vpp/ifplugin/nat_config.go +++ b/plugins/vpp/ifplugin/nat_config.go @@ -12,20 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/nat --gogo_out=../model/nat ../model/nat/nat.proto - package ifplugin import ( - "bytes" - "fmt" "net" "strconv" "strings" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" + "github.com/gogo/protobuf/proto" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -37,9 +34,6 @@ import ( // Mapping labels const ( - static = "|static|" - staticLb = "|staticLb|" - identity = "|identity|" dummyTag = "dummy-tag" // used for deletion where tag is not needed ) @@ -87,393 +81,350 @@ type NatConfigurator struct { // VPP API handler natHandler vppcalls.NatVppAPI - - stopwatch *measure.Stopwatch } // Init NAT configurator -func (plugin *NatConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, ifIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *NatConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, ifIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-nat-conf") - plugin.log.Debug("Initializing NAT configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("NAT-configurator", plugin.log) - } + c.log = logger.NewLogger("nat-conf") // Mappings - plugin.ifIndexes = ifIndexes - plugin.sNatIndexes = nametoidx.NewNameToIdx(plugin.log, "snat-indices", nil) - plugin.sNatMappingIndexes = nametoidx.NewNameToIdx(plugin.log, "snat-mapping-indices", nil) - plugin.dNatIndexes = nametoidx.NewNameToIdx(plugin.log, "dnat-indices", nil) - plugin.dNatStMappingIndexes = nametoidx.NewNameToIdx(plugin.log, "dnat-st-mapping-indices", nil) - plugin.dNatIDMappingIndexes = nametoidx.NewNameToIdx(plugin.log, "dnat-id-mapping-indices", nil) - plugin.notEnabledIfs = make(map[string]*nat.Nat44Global_NatInterface) - plugin.notDisabledIfs = make(map[string]*nat.Nat44Global_NatInterface) - plugin.natIndexSeq, plugin.natMappingTagSeq = 1, 1 + c.ifIndexes = ifIndexes + c.sNatIndexes = nametoidx.NewNameToIdx(c.log, "snat-indices", nil) + c.sNatMappingIndexes = nametoidx.NewNameToIdx(c.log, "snat-mapping-indices", nil) + c.dNatIndexes = nametoidx.NewNameToIdx(c.log, "dnat-indices", nil) + c.dNatStMappingIndexes = nametoidx.NewNameToIdx(c.log, "dnat-st-mapping-indices", nil) + c.dNatIDMappingIndexes = nametoidx.NewNameToIdx(c.log, "dnat-id-mapping-indices", nil) + c.notEnabledIfs = make(map[string]*nat.Nat44Global_NatInterface) + c.notDisabledIfs = make(map[string]*nat.Nat44Global_NatInterface) + c.natIndexSeq, c.natMappingTagSeq = 1, 1 // Init VPP API channel - if plugin.vppChan, err = goVppMux.NewAPIChannel(); err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } - if plugin.vppDumpChan, err = goVppMux.NewAPIChannel(); err != nil { - return err + if c.vppDumpChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create dump API channel: %v", err) } // VPP API handler - plugin.natHandler = vppcalls.NewNatVppHandler(plugin.vppChan, plugin.vppDumpChan, plugin.ifIndexes, - plugin.log, plugin.stopwatch) + c.natHandler = vppcalls.NewNatVppHandler(c.vppChan, c.vppDumpChan, c.ifIndexes, c.log) + + c.log.Info("NAT configurator initialized") return nil } // Close used resources -func (plugin *NatConfigurator) Close() error { - return safeclose.Close(plugin.vppChan, plugin.vppDumpChan) +func (c *NatConfigurator) Close() error { + if err := safeclose.Close(c.vppChan, c.vppDumpChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose NAT configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *NatConfigurator) clearMapping() { - plugin.sNatIndexes.Clear() - plugin.sNatMappingIndexes.Clear() - plugin.dNatIndexes.Clear() - plugin.dNatStMappingIndexes.Clear() - plugin.dNatIDMappingIndexes.Clear() - plugin.notEnabledIfs = make(map[string]*nat.Nat44Global_NatInterface) - plugin.notDisabledIfs = make(map[string]*nat.Nat44Global_NatInterface) +func (c *NatConfigurator) clearMapping() { + c.sNatIndexes.Clear() + c.sNatMappingIndexes.Clear() + c.dNatIndexes.Clear() + c.dNatStMappingIndexes.Clear() + c.dNatIDMappingIndexes.Clear() + c.notEnabledIfs = make(map[string]*nat.Nat44Global_NatInterface) + c.notDisabledIfs = make(map[string]*nat.Nat44Global_NatInterface) + + c.log.Debugf("NAT configurator mapping cleared") } // GetGlobalNat makes current global nat accessible -func (plugin *NatConfigurator) GetGlobalNat() *nat.Nat44Global { - return plugin.globalNAT +func (c *NatConfigurator) GetGlobalNat() *nat.Nat44Global { + return c.globalNAT } // IsInNotEnabledIfCache checks if interface is present in 'notEnabledIfs' cache -func (plugin *NatConfigurator) IsInNotEnabledIfCache(ifName string) bool { - _, ok := plugin.notEnabledIfs[ifName] +func (c *NatConfigurator) IsInNotEnabledIfCache(ifName string) bool { + _, ok := c.notEnabledIfs[ifName] return ok } // IsInNotDisabledIfCache checks if interface is present in 'notDisabledIfs' cache -func (plugin *NatConfigurator) IsInNotDisabledIfCache(ifName string) bool { - _, ok := plugin.notDisabledIfs[ifName] +func (c *NatConfigurator) IsInNotDisabledIfCache(ifName string) bool { + _, ok := c.notDisabledIfs[ifName] return ok } // IsDNatLabelRegistered checks if interface is present in 'notDisabledIfs' cache -func (plugin *NatConfigurator) IsDNatLabelRegistered(label string) bool { - _, _, found := plugin.dNatIndexes.LookupIdx(label) +func (c *NatConfigurator) IsDNatLabelRegistered(label string) bool { + _, _, found := c.dNatIndexes.LookupIdx(label) return found } // IsDNatLabelStMappingRegistered checks if DNAT static mapping with provided id is registered -func (plugin *NatConfigurator) IsDNatLabelStMappingRegistered(id string) bool { - _, _, found := plugin.dNatStMappingIndexes.LookupIdx(id) +func (c *NatConfigurator) IsDNatLabelStMappingRegistered(id string) bool { + _, _, found := c.dNatStMappingIndexes.LookupIdx(id) return found } // IsDNatLabelIDMappingRegistered checks if DNAT identity mapping with provided id is registered -func (plugin *NatConfigurator) IsDNatLabelIDMappingRegistered(id string) bool { - _, _, found := plugin.dNatIDMappingIndexes.LookupIdx(id) +func (c *NatConfigurator) IsDNatLabelIDMappingRegistered(id string) bool { + _, _, found := c.dNatIDMappingIndexes.LookupIdx(id) return found } // SetNatGlobalConfig configures common setup for all NAT use cases -func (plugin *NatConfigurator) SetNatGlobalConfig(config *nat.Nat44Global) error { - plugin.log.Info("Setting up NAT global config") - +func (c *NatConfigurator) SetNatGlobalConfig(config *nat.Nat44Global) error { // Store global NAT configuration (serves as cache) - plugin.globalNAT = config + c.globalNAT = config // Forwarding - if err := plugin.natHandler.SetNat44Forwarding(config.Forwarding); err != nil { - return err - } - if config.Forwarding { - plugin.log.Debugf("NAT forwarding enabled") - } else { - plugin.log.Debugf("NAT forwarding disabled") + if err := c.natHandler.SetNat44Forwarding(config.Forwarding); err != nil { + return errors.Errorf("failed to set NAT44 forwarding to %t: %d", config.Forwarding, err) } // Inside/outside interfaces if len(config.NatInterfaces) > 0 { - if err := plugin.enableNatInterfaces(config.NatInterfaces); err != nil { + if err := c.enableNatInterfaces(config.NatInterfaces); err != nil { return err } - } else { - plugin.log.Debug("No NAT interfaces to configure") } - if err := plugin.addAddressPool(config.AddressPools); err != nil { + if err := c.addAddressPool(config.AddressPools); err != nil { return err } // Virtual reassembly IPv4 if config.VirtualReassemblyIpv4 != nil { - if err := plugin.natHandler.SetVirtualReassemblyIPv4(config.VirtualReassemblyIpv4); err != nil { - return err + if err := c.natHandler.SetVirtualReassemblyIPv4(config.VirtualReassemblyIpv4); err != nil { + return errors.Errorf("failed to set NAT virtual reassembly for IPv4: %v", err) } - plugin.log.Debug("Nat virtual reassembly set for IPv4") } // Virtual reassembly IPv6 if config.VirtualReassemblyIpv6 != nil { - if err := plugin.natHandler.SetVirtualReassemblyIPv6(config.VirtualReassemblyIpv6); err != nil { - return err + if err := c.natHandler.SetVirtualReassemblyIPv6(config.VirtualReassemblyIpv6); err != nil { + return errors.Errorf("failed to set NAT virtual reassembly for IPv6: %v", err) } - plugin.log.Debug("Nat virtual reassembly set for IPv6") } - plugin.log.Debug("Setting up NAT global config done") + c.log.Info("Setting up NAT global config done") return nil } // ModifyNatGlobalConfig modifies common setup for all NAT use cases -func (plugin *NatConfigurator) ModifyNatGlobalConfig(oldConfig, newConfig *nat.Nat44Global) (err error) { - plugin.log.Info("Modifying NAT global config") - +func (c *NatConfigurator) ModifyNatGlobalConfig(oldConfig, newConfig *nat.Nat44Global) (err error) { // Replace global NAT config - plugin.globalNAT = newConfig + c.globalNAT = newConfig // Forwarding if oldConfig.Forwarding != newConfig.Forwarding { - if err := plugin.natHandler.SetNat44Forwarding(newConfig.Forwarding); err != nil { - return err + if err := c.natHandler.SetNat44Forwarding(newConfig.Forwarding); err != nil { + return errors.Errorf("failed to set NAT44 forwarding to %t: %d", newConfig.Forwarding, err) } } // Inside/outside interfaces toSetIn, toSetOut, toUnsetIn, toUnsetOut := diffInterfaces(oldConfig.NatInterfaces, newConfig.NatInterfaces) - if err := plugin.disableNatInterfaces(toUnsetIn); err != nil { + if err := c.disableNatInterfaces(toUnsetIn); err != nil { return err } - if err := plugin.disableNatInterfaces(toUnsetOut); err != nil { + if err := c.disableNatInterfaces(toUnsetOut); err != nil { return err } - if err := plugin.enableNatInterfaces(toSetIn); err != nil { + if err := c.enableNatInterfaces(toSetIn); err != nil { return err } - if err := plugin.enableNatInterfaces(toSetOut); err != nil { + if err := c.enableNatInterfaces(toSetOut); err != nil { return err } // Address pool toAdd, toRemove := diffAddressPools(oldConfig.AddressPools, newConfig.AddressPools) - if err := plugin.delAddressPool(toRemove); err != nil { + if err := c.delAddressPool(toRemove); err != nil { return err } - if err := plugin.addAddressPool(toAdd); err != nil { + if err := c.addAddressPool(toAdd); err != nil { return err } // Virtual reassembly IPv4 if toConfigure := isVirtualReassModified(oldConfig.VirtualReassemblyIpv4, newConfig.VirtualReassemblyIpv4); toConfigure != nil { - if err := plugin.natHandler.SetVirtualReassemblyIPv4(toConfigure); err != nil { - return err + if err := c.natHandler.SetVirtualReassemblyIPv4(toConfigure); err != nil { + return errors.Errorf("failed to set NAT virtual reassembly for IPv4: %v", err) } - plugin.log.Debug("Nat virtual reassembly modified for IPv4") } // Virtual reassembly IPv6 if toConfigure := isVirtualReassModified(oldConfig.VirtualReassemblyIpv6, newConfig.VirtualReassemblyIpv6); toConfigure != nil { - if err := plugin.natHandler.SetVirtualReassemblyIPv6(toConfigure); err != nil { - return err + if err := c.natHandler.SetVirtualReassemblyIPv6(toConfigure); err != nil { + return errors.Errorf("failed to set NAT virtual reassembly for IPv6: %v", err) } - plugin.log.Debug("Nat virtual reassembly modified for IPv6") } + c.log.Info("NAT global config modified") + return nil } // DeleteNatGlobalConfig removes common setup for all NAT use cases -func (plugin *NatConfigurator) DeleteNatGlobalConfig(config *nat.Nat44Global) (err error) { - plugin.log.Info("Deleting NAT global config") - +func (c *NatConfigurator) DeleteNatGlobalConfig(config *nat.Nat44Global) (err error) { // Remove global NAT config - plugin.globalNAT = nil + c.globalNAT = nil // Inside/outside interfaces if len(config.NatInterfaces) > 0 { - if err := plugin.disableNatInterfaces(config.NatInterfaces); err != nil { + if err := c.disableNatInterfaces(config.NatInterfaces); err != nil { return err } } // Address pools if len(config.AddressPools) > 0 { - if err := plugin.delAddressPool(config.AddressPools); err != nil { + if err := c.delAddressPool(config.AddressPools); err != nil { return err } } // Reset virtual reassembly to default - if err := plugin.natHandler.SetVirtualReassemblyIPv4(getDefaultVr()); err != nil { - return err + if err := c.natHandler.SetVirtualReassemblyIPv4(getDefaultVr()); err != nil { + return errors.Errorf("failed to reset NAT virtual reassembly for IPv4 to default: %v", err) } - if err := plugin.natHandler.SetVirtualReassemblyIPv6(getDefaultVr()); err != nil { - return err + if err := c.natHandler.SetVirtualReassemblyIPv6(getDefaultVr()); err != nil { + return errors.Errorf("failed to reset NAT virtual reassembly for IPv4 to default: %v", err) } - plugin.log.Debug("Deleting NAT global config done") + c.log.Info("NAT global config removed") return nil } // ConfigureSNat configures new SNAT setup -func (plugin *NatConfigurator) ConfigureSNat(sNat *nat.Nat44SNat_SNatConfig) error { - plugin.log.Warn("SNAT CREATE not implemented") +func (c *NatConfigurator) ConfigureSNat(sNat *nat.Nat44SNat_SNatConfig) error { + c.log.Warn("SNAT CREATE not implemented") return nil } // ModifySNat modifies existing SNAT setup -func (plugin *NatConfigurator) ModifySNat(oldSNat, newSNat *nat.Nat44SNat_SNatConfig) error { - plugin.log.Warn("SNAT MODIFY not implemented") +func (c *NatConfigurator) ModifySNat(oldSNat, newSNat *nat.Nat44SNat_SNatConfig) error { + c.log.Warn("SNAT MODIFY not implemented") return nil } // DeleteSNat removes existing SNAT setup -func (plugin *NatConfigurator) DeleteSNat(sNat *nat.Nat44SNat_SNatConfig) error { - plugin.log.Warn("SNAT DELETE not implemented") +func (c *NatConfigurator) DeleteSNat(sNat *nat.Nat44SNat_SNatConfig) error { + c.log.Warn("SNAT DELETE not implemented") return nil } // ConfigureDNat configures new DNAT setup -func (plugin *NatConfigurator) ConfigureDNat(dNat *nat.Nat44DNat_DNatConfig) error { - plugin.log.Infof("Configuring DNAT with label %v", dNat.Label) - - var wasErr error - +func (c *NatConfigurator) ConfigureDNat(dNat *nat.Nat44DNat_DNatConfig) error { // Resolve static mapping - if err := plugin.configureStaticMappings(dNat.Label, dNat.StMappings); err != nil { - wasErr = err - plugin.log.Errorf("Failed to configure static mapping for DNAT %s: %v", dNat.Label, err) + if err := c.configureStaticMappings(dNat.Label, dNat.StMappings); err != nil { + return err } // Resolve identity mapping - if err := plugin.configureIdentityMappings(dNat.Label, dNat.IdMappings); err != nil { - wasErr = err - plugin.log.Errorf("Failed to configure identity mapping for DNAT %s: %v", dNat.Label, err) + if err := c.configureIdentityMappings(dNat.Label, dNat.IdMappings); err != nil { + return err } // Register DNAT configuration - plugin.dNatIndexes.RegisterName(dNat.Label, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ - plugin.log.Debugf("DNAT configuration registered (label: %v)", dNat.Label) + c.dNatIndexes.RegisterName(dNat.Label, c.natIndexSeq, nil) + c.natIndexSeq++ + c.log.Debugf("DNAT configuration registered (label: %v)", dNat.Label) - plugin.log.Infof("DNAT %v configuration done", dNat.Label) + c.log.Infof("DNAT %s configured", dNat.Label) - return wasErr + return nil } // ModifyDNat modifies existing DNAT setup -func (plugin *NatConfigurator) ModifyDNat(oldDNat, newDNat *nat.Nat44DNat_DNatConfig) error { - plugin.log.Infof("Modifying DNAT with label %v", newDNat.Label) - - var wasErr error - +func (c *NatConfigurator) ModifyDNat(oldDNat, newDNat *nat.Nat44DNat_DNatConfig) error { // Static mappings - stmToAdd, stmToRemove := plugin.diffStatic(oldDNat.StMappings, newDNat.StMappings) + stmToAdd, stmToRemove := c.diffStatic(oldDNat.StMappings, newDNat.StMappings) - if err := plugin.unconfigureStaticMappings(stmToRemove); err != nil { - wasErr = err - plugin.log.Errorf("Failed to remove static mapping from DNAT %s: %v", newDNat.Label, err) + if err := c.unconfigureStaticMappings(stmToRemove); err != nil { + return err } - if err := plugin.configureStaticMappings(newDNat.Label, stmToAdd); err != nil { - wasErr = err - plugin.log.Errorf("Failed to configure static mapping for DNAT %s: %v", newDNat.Label, err) + if err := c.configureStaticMappings(newDNat.Label, stmToAdd); err != nil { + return err } // Identity mappings - idToAdd, idToRemove := plugin.diffIdentity(oldDNat.IdMappings, newDNat.IdMappings) + idToAdd, idToRemove := c.diffIdentity(oldDNat.IdMappings, newDNat.IdMappings) - if err := plugin.unconfigureIdentityMappings(idToRemove); err != nil { - wasErr = err - plugin.log.Errorf("Failed to remove identity mapping from DNAT %s: %v", newDNat.Label, err) + if err := c.unconfigureIdentityMappings(idToRemove); err != nil { + return err } - if err := plugin.configureIdentityMappings(newDNat.Label, idToAdd); err != nil { - wasErr = err - plugin.log.Errorf("Failed to configure identity mapping for DNAT %s: %v", newDNat.Label, err) + if err := c.configureIdentityMappings(newDNat.Label, idToAdd); err != nil { + return err } - plugin.log.Infof("DNAT %v modification done", newDNat.Label) + c.log.Infof("DNAT %s modification done", newDNat.Label) - return wasErr + return nil } // DeleteDNat removes existing DNAT setup -func (plugin *NatConfigurator) DeleteDNat(dNat *nat.Nat44DNat_DNatConfig) error { - plugin.log.Infof("Deleting DNAT with label %v", dNat.Label) - - var wasErr error - +func (c *NatConfigurator) DeleteDNat(dNat *nat.Nat44DNat_DNatConfig) error { // In delete case, vpp-agent attempts to reconstruct every static mapping entry and remove it from the VPP - if err := plugin.unconfigureStaticMappings(dNat.StMappings); err != nil { - wasErr = err - plugin.log.Errorf("Failed to remove static mapping from DNAT %s: %v", dNat.Label, err) + if err := c.unconfigureStaticMappings(dNat.StMappings); err != nil { + return err } // Do the same also for identity apping - if err := plugin.unconfigureIdentityMappings(dNat.IdMappings); err != nil { - wasErr = err - plugin.log.Errorf("Failed to remove identity mapping from DNAT %s: %v", dNat.Label, err) + if err := c.unconfigureIdentityMappings(dNat.IdMappings); err != nil { + return err } // Unregister DNAT configuration - plugin.dNatIndexes.UnregisterName(dNat.Label) - plugin.log.Debugf("DNAT configuration unregistered (label: %v)", dNat.Label) + c.dNatIndexes.UnregisterName(dNat.Label) + c.log.Debugf("DNAT configuration unregistered (label: %v)", dNat.Label) - plugin.log.Infof("DNAT %v removal done", dNat.Label) + c.log.Infof("DNAT %v removed", dNat.Label) - return wasErr + return nil } // ResolveCreatedInterface looks for cache of interfaces which should be enabled or disabled // for NAT -func (plugin *NatConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { - plugin.log.Debugf("NAT configurator: resolving registered interface %s", ifName) - - var wasErr error - +func (c *NatConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { // Check for interfaces which should be enabled var enabledIf []*nat.Nat44Global_NatInterface - for cachedName, data := range plugin.notEnabledIfs { + for cachedName, data := range c.notEnabledIfs { if cachedName == ifName { - delete(plugin.notEnabledIfs, cachedName) - if err := plugin.enableNatInterfaces(append(enabledIf, data)); err != nil { - plugin.log.Error(err) - wasErr = err + delete(c.notEnabledIfs, cachedName) + c.log.Debugf("interface %s removed from not-enabled-for-NAT cache", ifName) + if err := c.enableNatInterfaces(append(enabledIf, data)); err != nil { + return errors.Errorf("failed to enable cached interface %s for NAT: %v", ifName, err) } } } // Check for interfaces which could be disabled var disabledIf []*nat.Nat44Global_NatInterface - for cachedName, data := range plugin.notDisabledIfs { + for cachedName, data := range c.notDisabledIfs { if cachedName == ifName { - delete(plugin.notDisabledIfs, cachedName) - if err := plugin.disableNatInterfaces(append(disabledIf, data)); err != nil { - plugin.log.Error(err) - wasErr = err + delete(c.notDisabledIfs, cachedName) + c.log.Debugf("interface %s removed from not-disabled-for-NAT cache", ifName) + if err := c.disableNatInterfaces(append(disabledIf, data)); err != nil { + return errors.Errorf("failed to disable cached interface %s for NAT: %v", ifName, err) } } } - return wasErr + return nil } // ResolveDeletedInterface handles removed interface from NAT perspective -func (plugin *NatConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { - plugin.log.Debugf("NAT configurator: resolving deleted interface %s", ifName) - +func (c *NatConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { // Check global NAT for interfaces - if plugin.globalNAT != nil { - for _, natIf := range plugin.globalNAT.NatInterfaces { + if c.globalNAT != nil { + for _, natIf := range c.globalNAT.NatInterfaces { if natIf.Name == ifName { // This interface was removed and it is not possible to determine its state, so agent handles it as // not enabled - plugin.notEnabledIfs[natIf.Name] = natIf + c.notEnabledIfs[natIf.Name] = natIf + c.log.Debugf("unregistered interface %s added to not-enabled-for-NAT cache", ifName) return nil } } @@ -483,141 +434,113 @@ func (plugin *NatConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint } // DumpNatGlobal returns the current NAT44 global config -func (plugin *NatConfigurator) DumpNatGlobal() (*nat.Nat44Global, error) { - return plugin.natHandler.Nat44GlobalConfigDump() +func (c *NatConfigurator) DumpNatGlobal() (*nat.Nat44Global, error) { + return c.natHandler.Nat44GlobalConfigDump() } // DumpNatDNat returns the current NAT44 DNAT config -func (plugin *NatConfigurator) DumpNatDNat() (*nat.Nat44DNat, error) { - return plugin.natHandler.Nat44DNatDump() +func (c *NatConfigurator) DumpNatDNat() (*nat.Nat44DNat, error) { + return c.natHandler.Nat44DNatDump() } // enables set of interfaces as inside/outside in NAT -func (plugin *NatConfigurator) enableNatInterfaces(natInterfaces []*nat.Nat44Global_NatInterface) (err error) { +func (c *NatConfigurator) enableNatInterfaces(natInterfaces []*nat.Nat44Global_NatInterface) error { for _, natInterface := range natInterfaces { - ifIdx, _, found := plugin.ifIndexes.LookupIdx(natInterface.Name) + ifIdx, _, found := c.ifIndexes.LookupIdx(natInterface.Name) if !found { - plugin.log.Debugf("Interface %v missing, cannot enable NAT", natInterface.Name) - plugin.notEnabledIfs[natInterface.Name] = natInterface // cache interface + c.notEnabledIfs[natInterface.Name] = natInterface // cache interface + c.log.Debugf("Interface %s missing, cannot enable it for NAT yet, cached", natInterface.Name) } else { if natInterface.OutputFeature { // enable nat interface and output feature - if err = plugin.natHandler.EnableNat44InterfaceOutput(ifIdx, natInterface.IsInside); err != nil { - return - } - if natInterface.IsInside { - plugin.log.Debugf("Interface %v output-feature enabled for NAT as inside", natInterface.Name) - } else { - plugin.log.Debugf("Interface %v output-feature enabled for NAT as outside", natInterface.Name) + if err := c.natHandler.EnableNat44InterfaceOutput(ifIdx, natInterface.IsInside); err != nil { + return errors.Errorf("failed to enable interface %s for NAT44 as output feature: %v", + natInterface.Name, err) } } else { // enable interface only - if err = plugin.natHandler.EnableNat44Interface(ifIdx, natInterface.IsInside); err != nil { - return - } - if natInterface.IsInside { - plugin.log.Debugf("Interface %v enabled for NAT as inside", natInterface.Name) - } else { - plugin.log.Debugf("Interface %v enabled for NAT as outside", natInterface.Name) + if err := c.natHandler.EnableNat44Interface(ifIdx, natInterface.IsInside); err != nil { + return errors.Errorf("failed to enable interface %s for NAT44: %v", natInterface.Name, err) } } } } - return + return nil } // disables set of interfaces in NAT -func (plugin *NatConfigurator) disableNatInterfaces(natInterfaces []*nat.Nat44Global_NatInterface) (err error) { +func (c *NatConfigurator) disableNatInterfaces(natInterfaces []*nat.Nat44Global_NatInterface) error { for _, natInterface := range natInterfaces { // Check if interface is not in the cache - for ifName := range plugin.notEnabledIfs { + for ifName := range c.notEnabledIfs { if ifName == natInterface.Name { - delete(plugin.notEnabledIfs, ifName) + delete(c.notEnabledIfs, ifName) } } // Check if interface exists - ifIdx, _, found := plugin.ifIndexes.LookupIdx(natInterface.Name) + ifIdx, _, found := c.ifIndexes.LookupIdx(natInterface.Name) if !found { - plugin.log.Debugf("Interface %v missing, cannot disable NAT", natInterface) - plugin.notDisabledIfs[natInterface.Name] = natInterface // cache interface + c.notDisabledIfs[natInterface.Name] = natInterface // cache interface + c.log.Debugf("Interface %s missing, cannot disable it for NAT yet, cached", natInterface.Name) } else { if natInterface.OutputFeature { // disable nat interface and output feature - if err = plugin.natHandler.DisableNat44InterfaceOutput(ifIdx, natInterface.IsInside); err != nil { - return - } - if natInterface.IsInside { - plugin.log.Debugf("Interface %v output-feature disabled for NAT as inside", natInterface.Name) - } else { - plugin.log.Debugf("Interface %v output-feature disabled for NAT as outside", natInterface.Name) + if err := c.natHandler.DisableNat44InterfaceOutput(ifIdx, natInterface.IsInside); err != nil { + return errors.Errorf("failed to disable NAT44 interface %s as output feature: %v", + natInterface.Name, err) } } else { // disable interface - if err = plugin.natHandler.DisableNat44Interface(ifIdx, natInterface.IsInside); err != nil { - return - } - if natInterface.IsInside { - plugin.log.Debugf("Interface %v disabled for NAT as inside", natInterface) - } else { - plugin.log.Debugf("Interface %v disabled for NAT as outside", natInterface) + if err := c.natHandler.DisableNat44Interface(ifIdx, natInterface.IsInside); err != nil { + return errors.Errorf("failed to disable NAT44 interface %s: %v", natInterface.Name, err) } } } } - return + return nil } // Configures NAT address pool. If an address pool cannot is invalid and cannot be configured, it is skipped. -func (plugin *NatConfigurator) addAddressPool(addressPools []*nat.Nat44Global_AddressPool) (err error) { - var wasErr error +func (c *NatConfigurator) addAddressPool(addressPools []*nat.Nat44Global_AddressPool) (err error) { for _, addressPool := range addressPools { if addressPool.FirstSrcAddress == "" && addressPool.LastSrcAddress == "" { - err := fmt.Errorf("invalid address pool config, no IP address provided") - plugin.log.Error(err) - wasErr = err - continue + return errors.Errorf("failed to add address pool: invalid config, no IP address provided") } var firstIP []byte var lastIP []byte if addressPool.FirstSrcAddress != "" { firstIP = net.ParseIP(addressPool.FirstSrcAddress).To4() if firstIP == nil { - err := fmt.Errorf("unable to parse IP address %v", addressPool.FirstSrcAddress) - plugin.log.Error(err) - wasErr = err - continue + return errors.Errorf("failed to add address pool: unable to parse IP address %s", + addressPool.FirstSrcAddress) } } if addressPool.LastSrcAddress != "" { lastIP = net.ParseIP(addressPool.LastSrcAddress).To4() if lastIP == nil { - err := fmt.Errorf("unable to parse IP address %v", addressPool.LastSrcAddress) - plugin.log.Error(err) - wasErr = err - continue + return errors.Errorf("failed to add address pool: unable to parse IP address %s", + addressPool.LastSrcAddress) } } // Both fields have to be set, at least at the same value if only one of them is set if firstIP == nil { firstIP = lastIP } else if lastIP == nil { - lastIP = firstIP + lastIP = firstIP // Matthew 20:16 } - if err = plugin.natHandler.AddNat44AddressPool(firstIP, lastIP, addressPool.VrfId, addressPool.TwiceNat); err != nil { - plugin.log.Error(err) - wasErr = err + if err = c.natHandler.AddNat44AddressPool(firstIP, lastIP, addressPool.VrfId, addressPool.TwiceNat); err != nil { + return errors.Errorf("failed to add NAT44 address pool %s - %s: %v", firstIP, lastIP, err) } } - return wasErr + return nil } // Removes NAT address pool. Invalid address pool configuration is skipped with warning, configurator assumes that // such a data could not be configured to the vpp. -func (plugin *NatConfigurator) delAddressPool(addressPools []*nat.Nat44Global_AddressPool) (err error) { - var wasErr error +func (c *NatConfigurator) delAddressPool(addressPools []*nat.Nat44Global_AddressPool) error { for _, addressPool := range addressPools { if addressPool.FirstSrcAddress == "" && addressPool.LastSrcAddress == "" { // No address pool to remove @@ -629,7 +552,7 @@ func (plugin *NatConfigurator) delAddressPool(addressPools []*nat.Nat44Global_Ad firstIP = net.ParseIP(addressPool.FirstSrcAddress).To4() if firstIP == nil { // Do not return error here - plugin.log.Warnf("First address pool IP %s cannot be parsed and removed, skipping", + c.log.Warnf("First NAT44 address pool IP %s cannot be parsed and removed, skipping", addressPool.FirstSrcAddress) continue } @@ -638,7 +561,7 @@ func (plugin *NatConfigurator) delAddressPool(addressPools []*nat.Nat44Global_Ad lastIP = net.ParseIP(addressPool.LastSrcAddress).To4() if lastIP == nil { // Do not return error here - plugin.log.Warnf("Last address pool IP %s cannot be parsed and removed, skipping", + c.log.Warnf("Last NAT44 address pool IP %s cannot be parsed and removed, skipping", addressPool.LastSrcAddress) continue } @@ -651,101 +574,83 @@ func (plugin *NatConfigurator) delAddressPool(addressPools []*nat.Nat44Global_Ad } // remove address pool - if err = plugin.natHandler.DelNat44AddressPool(firstIP, lastIP, addressPool.VrfId, addressPool.TwiceNat); err != nil { - plugin.log.Error(err) - wasErr = err + if err := c.natHandler.DelNat44AddressPool(firstIP, lastIP, addressPool.VrfId, addressPool.TwiceNat); err != nil { + errors.Errorf("failed to delete NAT44 address pool %s - %s: %v", firstIP, lastIP, err) } } - return wasErr + return nil } // configures a list of static mappings for provided label -func (plugin *NatConfigurator) configureStaticMappings(label string, mappings []*nat.Nat44DNat_DNatConfig_StaticMapping) error { - var wasErr error +func (c *NatConfigurator) configureStaticMappings(label string, mappings []*nat.Nat44DNat_DNatConfig_StaticMapping) error { for _, mappingEntry := range mappings { - var tag string localIPList := mappingEntry.LocalIps if len(localIPList) == 0 { - wasErr = fmt.Errorf("cannot configure DNAT static mapping: no local address provided") - plugin.log.Error(wasErr) - continue + return errors.Errorf("cannot configure DNAT static mapping %s: no local address provided", label) } else if len(localIPList) == 1 { // Case without load balance (one local address) - tag = plugin.getMappingTag(label, static) - if err := plugin.handleStaticMapping(mappingEntry, tag, true); err != nil { - wasErr = fmt.Errorf("DNAT static mapping configuration failed: %v", err) - plugin.log.Error(wasErr) - continue + if err := c.handleStaticMapping(mappingEntry, label, true); err != nil { + return err } } else { // Case with load balance (more local addresses) - tag = plugin.getMappingTag(label, staticLb) - if err := plugin.handleStaticMappingLb(mappingEntry, tag, true); err != nil { - wasErr = fmt.Errorf("DNAT static lb-mapping configuration failed: %v", err) - plugin.log.Error(wasErr) - continue + if err := c.handleStaticMappingLb(mappingEntry, label, true); err != nil { + return err } } // Register DNAT static mapping mappingIdentifier := GetStMappingIdentifier(mappingEntry) - plugin.dNatStMappingIndexes.RegisterName(mappingIdentifier, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ - - plugin.log.Debugf("DNAT static (lb)mapping configured (ID: %s, Tag: %s)", mappingIdentifier, tag) + c.dNatStMappingIndexes.RegisterName(mappingIdentifier, c.natIndexSeq, nil) + c.natIndexSeq++ + c.log.Debugf("DNAT static (lb) mapping registered (ID: %s, Tag: %s)", mappingIdentifier, label) } - return wasErr + return nil } // removes static mappings from configuration with provided label -func (plugin *NatConfigurator) unconfigureStaticMappings(mappings []*nat.Nat44DNat_DNatConfig_StaticMapping) error { - var wasErr error +func (c *NatConfigurator) unconfigureStaticMappings(mappings []*nat.Nat44DNat_DNatConfig_StaticMapping) error { for mappingIdx, mappingEntry := range mappings { localIPList := mappingEntry.LocalIps if len(localIPList) == 0 { - plugin.log.Warnf("DNAT mapping %v has not local IPs, cannot remove it", mappingIdx) + c.log.Warnf("DNAT mapping %s has not local IPs, cannot remove it", mappingIdx) continue } else if len(localIPList) == 1 { // Case without load balance (one local address) - if err := plugin.handleStaticMapping(mappingEntry, dummyTag, false); err != nil { - wasErr = fmt.Errorf("DNAT mapping removal failed: %v", err) - plugin.log.Error(wasErr) - continue + if err := c.handleStaticMapping(mappingEntry, dummyTag, false); err != nil { + return err } } else { // Case with load balance (more local addresses) - if err := plugin.handleStaticMappingLb(mappingEntry, dummyTag, false); err != nil { - wasErr = fmt.Errorf("DNAT lb-mapping removal failed: %v", err) - plugin.log.Error(wasErr) - continue + if err := c.handleStaticMappingLb(mappingEntry, dummyTag, false); err != nil { + return err } } // Unregister DNAT mapping mappingIdentifier := GetStMappingIdentifier(mappingEntry) - plugin.dNatStMappingIndexes.UnregisterName(mappingIdentifier) - - plugin.log.Debugf("DNAT lb-mapping un-configured (ID %v)", mappingIdentifier) + c.dNatStMappingIndexes.UnregisterName(mappingIdentifier) + c.log.Debugf("DNAT lb-mapping unregistered (ID %v)", mappingIdentifier) } - return wasErr + return nil } // configures single static mapping entry with load balancer -func (plugin *NatConfigurator) handleStaticMappingLb(staticMappingLb *nat.Nat44DNat_DNatConfig_StaticMapping, tag string, add bool) (err error) { +func (c *NatConfigurator) handleStaticMappingLb(staticMappingLb *nat.Nat44DNat_DNatConfig_StaticMapping, tag string, add bool) (err error) { // Validate tag if tag == dummyTag && add { - plugin.log.Warn("Static mapping will be configured with generic tag") + c.log.Warn("Static mapping will be configured with generic tag") } // Parse external IP address exIPAddrByte := net.ParseIP(staticMappingLb.ExternalIp).To4() if exIPAddrByte == nil { - return fmt.Errorf("cannot configure DNAT mapping: unable to parse external IP %v", staticMappingLb.ExternalIp) + return errors.Errorf("cannot configure DNAT lb static mapping: unable to parse external IP %s", exIPAddrByte.String()) } // In this case, external port is required if staticMappingLb.ExternalPort == 0 { - return fmt.Errorf("cannot configure DNAT mapping: external port is not set") + return errors.Errorf("cannot configure DNAT lb static mapping: external port is not set") } // Address mapping with load balancer @@ -753,30 +658,36 @@ func (plugin *NatConfigurator) handleStaticMappingLb(staticMappingLb *nat.Nat44D Tag: tag, ExternalIP: exIPAddrByte, ExternalPort: uint16(staticMappingLb.ExternalPort), - Protocol: getProtocol(staticMappingLb.Protocol, plugin.log), - LocalIPs: getLocalIPs(staticMappingLb.LocalIps, plugin.log), + Protocol: getProtocol(staticMappingLb.Protocol, c.log), + LocalIPs: getLocalIPs(staticMappingLb.LocalIps, c.log), TwiceNat: staticMappingLb.TwiceNat == nat.TwiceNatMode_ENABLED, SelfTwiceNat: staticMappingLb.TwiceNat == nat.TwiceNatMode_SELF, } if len(ctx.LocalIPs) == 0 { - return fmt.Errorf("cannot configure DNAT mapping: no local IP was successfully parsed") + return errors.Errorf("cannot configure DNAT mapping: no local IP was successfully parsed") } if add { - return plugin.natHandler.AddNat44StaticMappingLb(ctx) + if err := c.natHandler.AddNat44StaticMappingLb(ctx); err != nil { + return errors.Errorf("failed to add NAT44 lb static mapping: %v", err) + } + } else { + if err := c.natHandler.DelNat44StaticMappingLb(ctx); err != nil { + return errors.Errorf("failed to delete NAT44 static mapping: %v", err) + } } - return plugin.natHandler.DelNat44StaticMappingLb(ctx) + return nil } // handler for single static mapping entry -func (plugin *NatConfigurator) handleStaticMapping(staticMapping *nat.Nat44DNat_DNatConfig_StaticMapping, tag string, add bool) (err error) { +func (c *NatConfigurator) handleStaticMapping(staticMapping *nat.Nat44DNat_DNatConfig_StaticMapping, tag string, add bool) (err error) { var ifIdx uint32 = 0xffffffff // default value - means no external interface is set - var exIPAddr []byte + var exIPAddr net.IP // Validate tag if tag == dummyTag && add { - plugin.log.Warn("Static mapping will be configured with generic tag") + c.log.Warn("Static mapping will be configured with generic tag") } // Parse local IP address and port @@ -784,22 +695,23 @@ func (plugin *NatConfigurator) handleStaticMapping(staticMapping *nat.Nat44DNat_ lcPort := staticMapping.LocalIps[0].LocalPort lcVrf := staticMapping.LocalIps[0].VrfId if lcIPAddr == nil { - return fmt.Errorf("cannot configure DNAT mapping: unable to parse local IP %v", lcIPAddr) + return errors.Errorf("cannot configure DNAT static mapping: unable to parse local IP %s", lcIPAddr.String()) } // Check external interface (prioritized over external IP) if staticMapping.ExternalInterface != "" { // Check external interface var found bool - ifIdx, _, found = plugin.ifIndexes.LookupIdx(staticMapping.ExternalInterface) + ifIdx, _, found = c.ifIndexes.LookupIdx(staticMapping.ExternalInterface) if !found { - return fmt.Errorf("required external interface %v is missing", staticMapping.ExternalInterface) + return errors.Errorf("cannot configure DNAT static mapping: required external interface %s is missing", + staticMapping.ExternalInterface) } } else { // Parse external IP address exIPAddr = net.ParseIP(staticMapping.ExternalIp).To4() if exIPAddr == nil { - return fmt.Errorf("cannot configure DNAT mapping: unable to parse external IP %v", exIPAddr) + return errors.Errorf("cannot configure DNAT static mapping: unable to parse external IP %s", exIPAddr.String()) } } @@ -818,89 +730,85 @@ func (plugin *NatConfigurator) handleStaticMapping(staticMapping *nat.Nat44DNat_ ExternalIP: exIPAddr, ExternalPort: uint16(staticMapping.ExternalPort), ExternalIfIdx: ifIdx, - Protocol: getProtocol(staticMapping.Protocol, plugin.log), + Protocol: getProtocol(staticMapping.Protocol, c.log), Vrf: lcVrf, TwiceNat: staticMapping.TwiceNat == nat.TwiceNatMode_ENABLED, SelfTwiceNat: staticMapping.TwiceNat == nat.TwiceNatMode_SELF, } if add { - return plugin.natHandler.AddNat44StaticMapping(ctx) + if err := c.natHandler.AddNat44StaticMapping(ctx); err != nil { + return errors.Errorf("failed to add NAT44 static mapping: %v", err) + } + } else { + if err := c.natHandler.DelNat44StaticMapping(ctx); err != nil { + return errors.Errorf("failed to delete NAT44 static mapping: %v", err) + } } - return plugin.natHandler.DelNat44StaticMapping(ctx) + return nil } // configures a list of identity mappings with label -func (plugin *NatConfigurator) configureIdentityMappings(label string, mappings []*nat.Nat44DNat_DNatConfig_IdentityMapping) error { - var wasErr error +func (c *NatConfigurator) configureIdentityMappings(label string, mappings []*nat.Nat44DNat_DNatConfig_IdentityMapping) error { for _, idMapping := range mappings { if idMapping.IpAddress == "" && idMapping.AddressedInterface == "" { - wasErr = fmt.Errorf("cannot configure DNAT identity mapping: no IP address or interface provided") - plugin.log.Error(wasErr) - continue + return errors.Errorf("cannot configure DNAT %s identity mapping: no IP address or interface provided", label) } // Case without load balance (one local address) - tag := plugin.getMappingTag(label, identity) - if err := plugin.handleIdentityMapping(idMapping, tag, true); err != nil { - wasErr = err - plugin.log.Error(err) - continue + if err := c.handleIdentityMapping(idMapping, label, true); err != nil { + return err } // Register DNAT identity mapping mappingIdentifier := GetIDMappingIdentifier(idMapping) - plugin.dNatIDMappingIndexes.RegisterName(mappingIdentifier, plugin.natIndexSeq, nil) - plugin.natIndexSeq++ - - plugin.log.Debugf("DNAT identity mapping configured (ID: %s, Tag: %s)", mappingIdentifier, tag) + c.dNatIDMappingIndexes.RegisterName(mappingIdentifier, c.natIndexSeq, nil) + c.natIndexSeq++ + c.log.Debugf("DNAT identity mapping registered (ID: %s, Tag: %s)", mappingIdentifier, label) } - return wasErr + return nil } // removes identity mappings from configuration with provided label -func (plugin *NatConfigurator) unconfigureIdentityMappings(mappings []*nat.Nat44DNat_DNatConfig_IdentityMapping) error { +func (c *NatConfigurator) unconfigureIdentityMappings(mappings []*nat.Nat44DNat_DNatConfig_IdentityMapping) error { var wasErr error for mappingIdx, idMapping := range mappings { if idMapping.IpAddress == "" && idMapping.AddressedInterface == "" { - wasErr = fmt.Errorf("cannot remove DNAT %v identity mapping: no IP address or interface provided", mappingIdx) - plugin.log.Error(wasErr) - continue + return errors.Errorf("cannot configure DNAT identity mapping %d: no IP address or interface provided", + mappingIdx) } - if err := plugin.handleIdentityMapping(idMapping, dummyTag, false); err != nil { - wasErr = err - plugin.log.Error(err) - continue + if err := c.handleIdentityMapping(idMapping, dummyTag, false); err != nil { + return err } // Unregister DNAT identity mapping mappingIdentifier := GetIDMappingIdentifier(idMapping) - plugin.dNatIDMappingIndexes.UnregisterName(mappingIdentifier) - plugin.natIndexSeq++ - - plugin.log.Debugf("DNAT identity (lb)mapping un-configured (ID: %v)", mappingIdentifier) + c.dNatIDMappingIndexes.UnregisterName(mappingIdentifier) + c.natIndexSeq++ + c.log.Debugf("DNAT identity mapping unregistered (ID: %v)", mappingIdentifier) } return wasErr } // handler for single identity mapping entry -func (plugin *NatConfigurator) handleIdentityMapping(idMapping *nat.Nat44DNat_DNatConfig_IdentityMapping, tag string, isAdd bool) (err error) { +func (c *NatConfigurator) handleIdentityMapping(idMapping *nat.Nat44DNat_DNatConfig_IdentityMapping, tag string, isAdd bool) (err error) { // Verify interface if exists var ifIdx uint32 if idMapping.AddressedInterface != "" { var found bool - ifIdx, _, found = plugin.ifIndexes.LookupIdx(idMapping.AddressedInterface) + ifIdx, _, found = c.ifIndexes.LookupIdx(idMapping.AddressedInterface) if !found { // TODO: use cache to configure later - return fmt.Errorf("identity mapping config: provided interface %v does not exist", idMapping.AddressedInterface) + return errors.Errorf("failed to configure identity mapping: provided interface %s does not exist", + idMapping.AddressedInterface) } } // Identity mapping (common fields) ctx := &vppcalls.IdentityMappingContext{ Tag: tag, - Protocol: getProtocol(idMapping.Protocol, plugin.log), + Protocol: getProtocol(idMapping.Protocol, c.log), Port: uint16(idMapping.Port), IfIdx: ifIdx, Vrf: idMapping.VrfId, @@ -910,7 +818,7 @@ func (plugin *NatConfigurator) handleIdentityMapping(idMapping *nat.Nat44DNat_DN // Case with IP (optionally port). Verify and parse input IP/port parsedIP := net.ParseIP(idMapping.IpAddress).To4() if parsedIP == nil { - return fmt.Errorf("unable to parse IP address %v", idMapping.IpAddress) + return errors.Errorf("failed to configure identity mapping: unable to parse IP address %s", idMapping.IpAddress) } // Add IP address to context ctx.IPAddress = parsedIP @@ -918,9 +826,15 @@ func (plugin *NatConfigurator) handleIdentityMapping(idMapping *nat.Nat44DNat_DN // Configure/remove identity mapping if isAdd { - return plugin.natHandler.AddNat44IdentityMapping(ctx) + if err := c.natHandler.AddNat44IdentityMapping(ctx); err != nil { + return errors.Errorf("failed to add NAT44 identity mapping: %v", err) + } + } else { + if err := c.natHandler.DelNat44IdentityMapping(ctx); err != nil { + return errors.Errorf("failed to remove NAT44 identity mapping: %v", err) + } } - return plugin.natHandler.DelNat44IdentityMapping(ctx) + return nil } // looks for new and obsolete IN interfaces @@ -1014,7 +928,7 @@ func diffAddressPools(oldAPs, newAPs []*nat.Nat44Global_AddressPool) (toAdd, toR } // returns a list of static mappings to add/remove -func (plugin *NatConfigurator) diffStatic(oldMappings, newMappings []*nat.Nat44DNat_DNatConfig_StaticMapping) (toAdd, toRemove []*nat.Nat44DNat_DNatConfig_StaticMapping) { +func (c *NatConfigurator) diffStatic(oldMappings, newMappings []*nat.Nat44DNat_DNatConfig_StaticMapping) (toAdd, toRemove []*nat.Nat44DNat_DNatConfig_StaticMapping) { // Find missing mappings for _, newMap := range newMappings { var found bool @@ -1029,7 +943,7 @@ func (plugin *NatConfigurator) diffStatic(oldMappings, newMappings []*nat.Nat44D continue } // Local IPs - if !plugin.compareLocalIPs(oldMap.LocalIps, newMap.LocalIps) { + if !c.compareLocalIPs(oldMap.LocalIps, newMap.LocalIps) { continue } found = true @@ -1052,7 +966,7 @@ func (plugin *NatConfigurator) diffStatic(oldMappings, newMappings []*nat.Nat44D continue } // Local IPs - if !plugin.compareLocalIPs(oldMap.LocalIps, newMap.LocalIps) { + if !c.compareLocalIPs(oldMap.LocalIps, newMap.LocalIps) { continue } found = true @@ -1066,7 +980,7 @@ func (plugin *NatConfigurator) diffStatic(oldMappings, newMappings []*nat.Nat44D } // returns a list of identity mappings to add/remove -func (plugin *NatConfigurator) diffIdentity(oldMappings, newMappings []*nat.Nat44DNat_DNatConfig_IdentityMapping) (toAdd, toRemove []*nat.Nat44DNat_DNatConfig_IdentityMapping) { +func (c *NatConfigurator) diffIdentity(oldMappings, newMappings []*nat.Nat44DNat_DNatConfig_IdentityMapping) (toAdd, toRemove []*nat.Nat44DNat_DNatConfig_IdentityMapping) { // Find missing mappings for _, newMap := range newMappings { var found bool @@ -1113,7 +1027,7 @@ func (plugin *NatConfigurator) diffIdentity(oldMappings, newMappings []*nat.Nat4 // if no changes are needed func isVirtualReassModified(oldReass, newReass *nat.Nat44Global_VirtualReassembly) *nat.Nat44Global_VirtualReassembly { // If new value is set while the old value does not exist, or it is different, return new value to configure - if newReass != nil && (oldReass == nil || *oldReass != *newReass) { + if newReass != nil && (oldReass == nil || !proto.Equal(oldReass, newReass)) { return newReass } // If old value was set but new is not, return default @@ -1123,8 +1037,8 @@ func isVirtualReassModified(oldReass, newReass *nat.Nat44Global_VirtualReassembl return nil } -// comapares two lists of Local IP addresses, returns true if lists are equal, false otherwise -func (plugin *NatConfigurator) compareLocalIPs(oldIPs, newIPs []*nat.Nat44DNat_DNatConfig_StaticMapping_LocalIP) bool { +// compares two lists of Local IP addresses, returns true if lists are equal, false otherwise +func (c *NatConfigurator) compareLocalIPs(oldIPs, newIPs []*nat.Nat44DNat_DNatConfig_StaticMapping_LocalIP) bool { if len(oldIPs) != len(newIPs) { return false } @@ -1202,17 +1116,6 @@ func GetIDMappingIdentifier(mapping *nat.Nat44DNat_DNatConfig_IdentityMapping) s return extIP + "-" + mapping.AddressedInterface + "-" + strconv.Itoa(int(mapping.VrfId)) } -// returns unique mapping tag -func (plugin *NatConfigurator) getMappingTag(label, mType string) string { - var buffer bytes.Buffer - buffer.WriteString(label) - buffer.WriteString(mType) - buffer.WriteString(strconv.Itoa(int(plugin.natMappingTagSeq))) - plugin.natMappingTagSeq++ - - return buffer.String() -} - // getDefaultVr returns default nat virtual reassembly configuration. func getDefaultVr() *nat.Nat44Global_VirtualReassembly { return &nat.Nat44Global_VirtualReassembly{ @@ -1222,3 +1125,17 @@ func getDefaultVr() *nat.Nat44Global_VirtualReassembly { DropFrag: false, } } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *NatConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/ifplugin/nat_config_test.go b/plugins/vpp/ifplugin/nat_config_test.go index 75743d98cf..04b4460810 100644 --- a/plugins/vpp/ifplugin/nat_config_test.go +++ b/plugins/vpp/ifplugin/nat_config_test.go @@ -17,8 +17,9 @@ package ifplugin_test import ( "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" nat_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/nat" @@ -644,7 +645,7 @@ func TestNatConfiguratorDNatStaticMappingNoLocalIPError(t *testing.T) { // Test configure DNAT without local IPs err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) } // Configure DNAT static mapping using external IP @@ -726,7 +727,7 @@ func TestNatConfiguratorDNatStaticMappingInvalidLocalAddressError(t *testing.T) // Test configure DNAT with invalid local IP err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetStMappingIdentifier(data.StMappings[0]) Expect(plugin.IsDNatLabelStMappingRegistered(id)).To(BeFalse()) } @@ -745,7 +746,7 @@ func TestNatConfiguratorDNatStaticMappingInvalidExternalAddressError(t *testing. // Test configure DNAT with invalid external IP err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetStMappingIdentifier(data.StMappings[0]) Expect(plugin.IsDNatLabelStMappingRegistered(id)).To(BeFalse()) } @@ -764,7 +765,7 @@ func TestNatConfiguratorDNatStaticMappingMissingInterfaceError(t *testing.T) { // Test configure DNAT with missing external interface err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetStMappingIdentifier(data.StMappings[0]) Expect(plugin.IsDNatLabelStMappingRegistered(id)).To(BeFalse()) } @@ -827,7 +828,7 @@ func TestNatConfiguratorDNatStaticMappingLbInvalidLocalError(t *testing.T) { // Test configure DNAT static mapping with load balancer with invalid local IP err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetStMappingIdentifier(data.StMappings[0]) Expect(plugin.IsDNatLabelStMappingRegistered(id)).To(BeFalse()) } @@ -847,7 +848,7 @@ func TestNatConfiguratorDNatStaticMappingLbMissingExternalPortError(t *testing.T // Test configure static mapping with load balancer with missing external port err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetStMappingIdentifier(data.StMappings[0]) Expect(plugin.IsDNatLabelStMappingRegistered(id)).To(BeFalse()) } @@ -867,7 +868,7 @@ func TestNatConfiguratorDNatStaticMappingLbInvalidExternalIPError(t *testing.T) // Test DNAT static mapping invalid external IP err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetStMappingIdentifier(data.StMappings[0]) Expect(plugin.IsDNatLabelStMappingRegistered(id)).To(BeFalse()) } @@ -927,7 +928,7 @@ func TestNatConfiguratorDNatIdentityMappingMissingInterfaceError(t *testing.T) { // Test identity mapping with address interface while interface is not registered err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetIDMappingIdentifier(data.IdMappings[0]) Expect(plugin.IsDNatLabelIDMappingRegistered(id)).To(BeFalse()) } @@ -945,7 +946,7 @@ func TestNatConfiguratorDNatIdentityMappingInvalidIPError(t *testing.T) { // Test identity mapping with invalid IP err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetIDMappingIdentifier(data.IdMappings[0]) Expect(plugin.IsDNatLabelIDMappingRegistered(id)).To(BeFalse()) } @@ -963,7 +964,7 @@ func TestNatConfiguratorDNatIdentityMappingNoInterfaceAndIPError(t *testing.T) { // Test identity mapping without interface and IP err := plugin.ConfigureDNat(data) Expect(err).ToNot(BeNil()) - Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeTrue()) + Expect(plugin.IsDNatLabelRegistered(data.Label)).To(BeFalse()) id := ifplugin.GetIDMappingIdentifier(data.IdMappings[0]) Expect(plugin.IsDNatLabelIDMappingRegistered(id)).To(BeFalse()) } @@ -1201,7 +1202,7 @@ func natTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *ifplug RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -1215,7 +1216,7 @@ func natTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *ifplug // Configurator plugin := &ifplugin.NatConfigurator{} - err = plugin.Init(log, connection, swIfIndices, true) + err = plugin.Init(log, connection, swIfIndices) Expect(err).To(BeNil()) return ctx, connection, plugin, swIfIndices diff --git a/plugins/vpp/ifplugin/stn_config.go b/plugins/vpp/ifplugin/stn_config.go index 13b2f0d2ff..3dd2dfe961 100644 --- a/plugins/vpp/ifplugin/stn_config.go +++ b/plugins/vpp/ifplugin/stn_config.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/stn --gogo_out=../model/stn ../model/stn/stn.proto - package ifplugin import ( @@ -22,8 +20,8 @@ import ( "strings" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -48,197 +46,187 @@ type StnConfigurator struct { vppChan govppapi.Channel // VPP API handler stnHandler vppcalls.StnVppAPI - // Stopwatch - stopwatch *measure.Stopwatch } // IndexExistsFor returns true if there is and mapping entry for provided name -func (plugin *StnConfigurator) IndexExistsFor(name string) bool { - _, _, found := plugin.allIndexes.LookupIdx(name) +func (c *StnConfigurator) IndexExistsFor(name string) bool { + _, _, found := c.allIndexes.LookupIdx(name) return found } // UnstoredIndexExistsFor returns true if there is and mapping entry for provided name -func (plugin *StnConfigurator) UnstoredIndexExistsFor(name string) bool { - _, _, found := plugin.unstoredIndexes.LookupIdx(name) +func (c *StnConfigurator) UnstoredIndexExistsFor(name string) bool { + _, _, found := c.unstoredIndexes.LookupIdx(name) return found } // Init initializes STN configurator -func (plugin *StnConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, ifIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *StnConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, ifIndexes ifaceidx.SwIfIndex) (err error) { // Init logger - plugin.log = logger.NewLogger("-stn-conf") - plugin.log.Debug("Initializing STN configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("STN-configurator", plugin.log) - } + c.log = logger.NewLogger("stn-conf") // Init VPP API channel - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // Init indexes - plugin.ifIndexes = ifIndexes - plugin.allIndexes = nametoidx.NewNameToIdx(plugin.log, "stn-all-indexes", nil) - plugin.unstoredIndexes = nametoidx.NewNameToIdx(plugin.log, "stn-unstored-indexes", nil) - plugin.allIndexesSeq, plugin.unstoredIndexSeq = 1, 1 + c.ifIndexes = ifIndexes + c.allIndexes = nametoidx.NewNameToIdx(c.log, "stn-all-indexes", nil) + c.unstoredIndexes = nametoidx.NewNameToIdx(c.log, "stn-unstored-indexes", nil) + c.allIndexesSeq, c.unstoredIndexSeq = 1, 1 // VPP API handler - plugin.stnHandler = vppcalls.NewStnVppHandler(plugin.vppChan, plugin.ifIndexes, plugin.log, plugin.stopwatch) + c.stnHandler = vppcalls.NewStnVppHandler(c.vppChan, c.ifIndexes, c.log) + + c.log.Info("STN configurator initialized") return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *StnConfigurator) clearMapping() { - plugin.allIndexes.Clear() - plugin.unstoredIndexes.Clear() +func (c *StnConfigurator) clearMapping() { + c.allIndexes.Clear() + c.unstoredIndexes.Clear() } // ResolveDeletedInterface resolves when interface is deleted. If there exist a rule for this interface // the rule will be deleted also. -func (plugin *StnConfigurator) ResolveDeletedInterface(interfaceName string) { - plugin.log.Debugf("STN plugin: resolving deleted interface: %v", interfaceName) - if rule := plugin.ruleFromIndex(interfaceName, true); rule != nil { - plugin.Delete(rule) +func (c *StnConfigurator) ResolveDeletedInterface(interfaceName string) error { + if rule := c.ruleFromIndex(interfaceName, true); rule != nil { + if err := c.Delete(rule); err != nil { + return err + } } + return nil } // ResolveCreatedInterface will check rules and if there is one waiting for interfaces it will be written // into VPP. -func (plugin *StnConfigurator) ResolveCreatedInterface(interfaceName string) { - plugin.log.Debugf("STN plugin: resolving created interface: %v", interfaceName) - if rule := plugin.ruleFromIndex(interfaceName, false); rule != nil { - if err := plugin.Add(rule); err == nil { - plugin.unstoredIndexes.UnregisterName(StnIdentifier(interfaceName)) +func (c *StnConfigurator) ResolveCreatedInterface(interfaceName string) error { + if rule := c.ruleFromIndex(interfaceName, false); rule != nil { + if err := c.Add(rule); err == nil { + c.unstoredIndexes.UnregisterName(StnIdentifier(interfaceName)) + c.log.Debugf("STN rule %s unregistered", rule.RuleName) + } else { + return err } } + return nil } // Add create a new STN rule. -func (plugin *StnConfigurator) Add(rule *modelStn.STN_Rule) error { - plugin.log.Infof("Configuring new STN rule %v", rule) - +func (c *StnConfigurator) Add(rule *modelStn.STN_Rule) error { // Check stn data - stnRule, doVPPCall, err := plugin.checkStn(rule, plugin.ifIndexes) + stnRule, doVPPCall, err := c.checkStn(rule, c.ifIndexes) if err != nil { return err } if !doVPPCall { - plugin.log.Debugf("There is no interface for rule: %+v. Waiting for interface.", rule.Interface) - plugin.indexSTNRule(rule, true) + c.log.Debugf("There is no interface for rule: %v. Waiting for interface.", rule.Interface) + c.indexSTNRule(rule, true) } else { - plugin.log.Debugf("adding STN rule: %+v", rule) // Create and register new stn - if err := plugin.stnHandler.AddStnRule(stnRule.IfaceIdx, &stnRule.IPAddress); err != nil { - return err + if err := c.stnHandler.AddStnRule(stnRule.IfaceIdx, &stnRule.IPAddress); err != nil { + return errors.Errorf("failed to add STN rule %s: %v", rule.RuleName, err) } - plugin.indexSTNRule(rule, false) + c.indexSTNRule(rule, false) - plugin.log.Infof("STN rule %v configured", rule) + c.log.Infof("STN rule %s configured", rule.RuleName) } return nil } // Delete removes STN rule. -func (plugin *StnConfigurator) Delete(rule *modelStn.STN_Rule) error { - plugin.log.Infof("Removing STN rule on if: %v with IP: %v", rule.Interface, rule.IpAddress) +func (c *StnConfigurator) Delete(rule *modelStn.STN_Rule) error { // Check stn data - stnRule, _, err := plugin.checkStn(rule, plugin.ifIndexes) - + stnRule, _, err := c.checkStn(rule, c.ifIndexes) if err != nil { return err } - if withoutIf, _ := plugin.removeRuleFromIndex(rule.Interface); withoutIf { - plugin.log.Debug("STN rule was not stored into VPP, removed only from indexes.") + if withoutIf, _ := c.removeRuleFromIndex(rule.Interface); withoutIf { + c.log.Debug("STN rule was not stored into VPP, removed only from indexes.") return nil } - plugin.log.Debugf("STN rule: %+v was stored in VPP, trying to delete it. %+v", stnRule) // Remove rule - if err := plugin.stnHandler.DelStnRule(stnRule.IfaceIdx, &stnRule.IPAddress); err != nil { - return err + if err := c.stnHandler.DelStnRule(stnRule.IfaceIdx, &stnRule.IPAddress); err != nil { + return errors.Errorf("failed to delete STN rule %s: %v", rule.RuleName, err) } - plugin.log.Infof("STN rule %v removed", rule) + c.log.Infof("STN rule %s removed", rule.RuleName) return nil } // Modify configured rule. -func (plugin *StnConfigurator) Modify(ruleOld *modelStn.STN_Rule, ruleNew *modelStn.STN_Rule) error { - plugin.log.Infof("Modifying STN %v", ruleNew) - +func (c *StnConfigurator) Modify(ruleOld *modelStn.STN_Rule, ruleNew *modelStn.STN_Rule) error { if ruleOld == nil { - return fmt.Errorf("old stn rule is null") + return errors.Errorf("failed to modify STN rule, provided old value is nil") } if ruleNew == nil { - return fmt.Errorf("new stn rule is null") + return errors.Errorf("failed to modify STN rule, provided new value is nil") } - if err := plugin.Delete(ruleOld); err != nil { + if err := c.Delete(ruleOld); err != nil { return err } - if err := plugin.Add(ruleNew); err != nil { + if err := c.Add(ruleNew); err != nil { return err } - plugin.log.Infof("STN rule %v modified", ruleNew) + c.log.Infof("STN rule %s modified", ruleNew.RuleName) return nil } // Dump STN rules configured on the VPP -func (plugin *StnConfigurator) Dump() (*vppcalls.StnDetails, error) { - stnDetails, err := plugin.stnHandler.DumpStnRules() +func (c *StnConfigurator) Dump() (*vppcalls.StnDetails, error) { + stnDetails, err := c.stnHandler.DumpStnRules() if err != nil { - return nil, err + return nil, errors.Errorf("failed to dump STN rules: %v", err) } - plugin.log.Debugf("found %d configured STN rules", len(stnDetails.Rules)) return stnDetails, nil } // Close GOVPP channel. -func (plugin *StnConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *StnConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose STN configurator: %v", err)) + } + return nil } // checkStn will check the rule raw data and change it to internal data structure. // In case the rule contains a interface that doesn't exist yet, rule is stored into index map. -func (plugin *StnConfigurator) checkStn(stnInput *modelStn.STN_Rule, index ifaceidx.SwIfIndex) (stnRule *vppcalls.StnRule, doVPPCall bool, err error) { - plugin.log.Debugf("Checking stn rule: %+v", stnInput) +func (c *StnConfigurator) checkStn(stnInput *modelStn.STN_Rule, index ifaceidx.SwIfIndex) (stnRule *vppcalls.StnRule, doVPPCall bool, err error) { + c.log.Debugf("Checking stn rule: %+v", stnInput) if stnInput == nil { - err = fmt.Errorf("STN input is empty") - return + return nil, false, errors.Errorf("failed to add STN rule, input is empty") } if stnInput.Interface == "" { - err = fmt.Errorf("STN input does not contain interface") - return + return nil, false, errors.Errorf("failed to add STN rule %s, no interface provided", + stnInput.RuleName) } if stnInput.IpAddress == "" { - err = fmt.Errorf("STN input does not contain IP") - return + return nil, false, errors.Errorf("failed to add STN rule %s, no IP address provided", + stnInput.RuleName) } ipWithMask := strings.Split(stnInput.IpAddress, "/") if len(ipWithMask) > 1 { - plugin.log.Debugf("STN rule %v IP address mask is ignored", stnInput.RuleName) + c.log.Debugf("STN rule %s IP address %s mask is ignored", stnInput.RuleName, stnInput.IpAddress) stnInput.IpAddress = ipWithMask[0] } parsedIP := net.ParseIP(stnInput.IpAddress) if parsedIP == nil { - err = fmt.Errorf("unable to parse IP %v", stnInput.IpAddress) - return + return nil, false, errors.Errorf("failed to create STN rule %s, unable to parse IP %s", + stnInput.RuleName, stnInput.IpAddress) } ifName := stnInput.Interface @@ -255,23 +243,26 @@ func (plugin *StnConfigurator) checkStn(stnInput *modelStn.STN_Rule, index iface return } -func (plugin *StnConfigurator) indexSTNRule(rule *modelStn.STN_Rule, withoutIface bool) { +func (c *StnConfigurator) indexSTNRule(rule *modelStn.STN_Rule, withoutIface bool) { idx := StnIdentifier(rule.Interface) if withoutIface { - plugin.unstoredIndexes.RegisterName(idx, plugin.unstoredIndexSeq, rule) - plugin.unstoredIndexSeq++ + c.unstoredIndexes.RegisterName(idx, c.unstoredIndexSeq, rule) + c.unstoredIndexSeq++ + c.log.Debugf("STN rule %s cached to unstored", rule.RuleName) } - plugin.allIndexes.RegisterName(idx, plugin.allIndexesSeq, rule) - plugin.allIndexesSeq++ + c.allIndexes.RegisterName(idx, c.allIndexesSeq, rule) + c.allIndexesSeq++ + c.log.Debugf("STN rule %s registered to all", rule.RuleName) } -func (plugin *StnConfigurator) removeRuleFromIndex(iface string) (withoutIface bool, rule *modelStn.STN_Rule) { +func (c *StnConfigurator) removeRuleFromIndex(iface string) (withoutIface bool, rule *modelStn.STN_Rule) { idx := StnIdentifier(iface) // Removing rule from main index - _, ruleIface, exists := plugin.allIndexes.LookupIdx(idx) + _, ruleIface, exists := c.allIndexes.LookupIdx(idx) if exists { - plugin.allIndexes.UnregisterName(idx) + c.allIndexes.UnregisterName(idx) + c.log.Debugf("STN rule %d unregistered from all", idx) stnRule, ok := ruleIface.(*modelStn.STN_Rule) if ok { rule = stnRule @@ -279,33 +270,32 @@ func (plugin *StnConfigurator) removeRuleFromIndex(iface string) (withoutIface b } // Removing rule from not stored rules index - _, _, existsWithout := plugin.unstoredIndexes.LookupIdx(idx) + _, _, existsWithout := c.unstoredIndexes.LookupIdx(idx) if existsWithout { withoutIface = true - plugin.unstoredIndexes.UnregisterName(idx) + c.unstoredIndexes.UnregisterName(idx) + c.log.Debugf("STN rule %s unregistered from unstored", rule.RuleName) } return } -func (plugin *StnConfigurator) ruleFromIndex(iface string, fromAllRules bool) (rule *modelStn.STN_Rule) { +func (c *StnConfigurator) ruleFromIndex(iface string, fromAllRules bool) (rule *modelStn.STN_Rule) { idx := StnIdentifier(iface) var ruleIface interface{} var exists bool if !fromAllRules { - _, ruleIface, exists = plugin.unstoredIndexes.LookupIdx(idx) + _, ruleIface, exists = c.unstoredIndexes.LookupIdx(idx) } else { - _, ruleIface, exists = plugin.allIndexes.LookupIdx(idx) + _, ruleIface, exists = c.allIndexes.LookupIdx(idx) } - plugin.log.Debugf("Rule exists: %+v returned rule: %+v", exists, &ruleIface) if exists { stnRule, ok := ruleIface.(*modelStn.STN_Rule) if ok { rule = stnRule } - plugin.log.Debugf("Getting rule: %+v", stnRule) } return @@ -315,3 +305,17 @@ func (plugin *StnConfigurator) ruleFromIndex(iface string, fromAllRules bool) (r func StnIdentifier(iface string) string { return fmt.Sprintf("stn-iface-%v", iface) } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *StnConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/ifplugin/stn_config_test.go b/plugins/vpp/ifplugin/stn_config_test.go index 495fd06aa7..d9df818c7b 100644 --- a/plugins/vpp/ifplugin/stn_config_test.go +++ b/plugins/vpp/ifplugin/stn_config_test.go @@ -18,8 +18,9 @@ import ( "net" "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" stn_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/stn" @@ -392,7 +393,7 @@ func TestStnConfiguratorResolveDeletedInterface(t *testing.T) { func stnTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *ifplugin.StnConfigurator, ifaceidx.SwIfIndexRW) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -403,7 +404,7 @@ func stnTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *ifplug swIfIndices := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "stn", nil)) // Configurator plugin := &ifplugin.StnConfigurator{} - err = plugin.Init(log, connection, swIfIndices, true) + err = plugin.Init(log, connection, swIfIndices) Expect(err).To(BeNil()) return ctx, connection, plugin, swIfIndices diff --git a/plugins/vpp/ifplugin/vppcalls/admin_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/admin_vppcalls.go index 439f513256..a154c5127d 100644 --- a/plugins/vpp/ifplugin/vppcalls/admin_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/admin_vppcalls.go @@ -16,7 +16,6 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" ) @@ -42,10 +41,6 @@ func (h *IfVppHandler) RemoveInterfaceTag(tag string, ifIdx uint32) error { } func (h *IfVppHandler) interfaceSetFlags(ifIdx uint32, adminUp bool) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceSetFlagsReply{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &interfaces.SwInterfaceSetFlags{ SwIfIndex: ifIdx, AdminUpDown: boolToUint(adminUp), @@ -62,10 +57,6 @@ func (h *IfVppHandler) interfaceSetFlags(ifIdx uint32, adminUp bool) error { } func (h *IfVppHandler) handleInterfaceTag(tag string, ifIdx uint32, isAdd bool) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceTagAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &interfaces.SwInterfaceTagAddDel{ Tag: []byte(tag), IsAdd: boolToUint(isAdd), diff --git a/plugins/vpp/ifplugin/vppcalls/admin_vppcalls_test.go b/plugins/vpp/ifplugin/vppcalls/admin_vppcalls_test.go index c7821cd715..0976374675 100644 --- a/plugins/vpp/ifplugin/vppcalls/admin_vppcalls_test.go +++ b/plugins/vpp/ifplugin/vppcalls/admin_vppcalls_test.go @@ -175,6 +175,6 @@ func TestInterfaceRemoveTagRetval(t *testing.T) { func ifTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.IfVppAPI) { ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") - ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log, nil) + ifHandler := vppcalls.NewIfVppHandler(ctx.MockChannel, log) return ctx, ifHandler } diff --git a/plugins/vpp/ifplugin/vppcalls/afpacket_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/afpacket_vppcalls.go index 711b1c25f4..eed6152562 100644 --- a/plugins/vpp/ifplugin/vppcalls/afpacket_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/afpacket_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/af_packet" intf "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" @@ -25,10 +24,6 @@ import ( // AddAfPacketInterface implements AfPacket handler. func (h *IfVppHandler) AddAfPacketInterface(ifName string, hwAddr string, afPacketIntf *intf.Interfaces_Interface_Afpacket) (swIndex uint32, err error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(af_packet.AfPacketCreate{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &af_packet.AfPacketCreate{ HostIfName: []byte(afPacketIntf.HostIfName), } @@ -54,10 +49,6 @@ func (h *IfVppHandler) AddAfPacketInterface(ifName string, hwAddr string, afPack // DeleteAfPacketInterface implements AfPacket handler. func (h *IfVppHandler) DeleteAfPacketInterface(ifName string, idx uint32, afPacketIntf *intf.Interfaces_Interface_Afpacket) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(af_packet.AfPacketDelete{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &af_packet.AfPacketDelete{ HostIfName: []byte(afPacketIntf.HostIfName), } diff --git a/plugins/vpp/ifplugin/vppcalls/api_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/api_vppcalls.go index 8da71cd786..c1dbd6f480 100644 --- a/plugins/vpp/ifplugin/vppcalls/api_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/api_vppcalls.go @@ -19,7 +19,6 @@ import ( "git.fd.io/govpp.git/api" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/idxvpp" bfd_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/bfd" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" @@ -89,7 +88,7 @@ type IfVppWrite interface { // SetRxMode calls SwInterfaceSetRxMode bin SetRxMode(ifIdx uint32, rxModeSettings *interfaces.Interfaces_Interface_RxModeSettings) error // SetRxPlacement configures rx-placement for interface - SetRxPlacement(vppInternalName string, rxPlacement *interfaces.Interfaces_Interface_RxPlacementSettings) error + SetRxPlacement(ifIdx uint32, rxPlacement *interfaces.Interfaces_Interface_RxPlacementSettings) error // CreateVrf checks if VRF exists and creates it if not CreateVrf(vrfID uint32) error // CreateVrfIPv6 checks if IPv6 VRF exists and creates it if not @@ -232,14 +231,12 @@ type StnVppRead interface { // IfVppHandler is accessor for interface-related vppcalls methods type IfVppHandler struct { - stopwatch *measure.Stopwatch callsChannel api.Channel log logging.Logger } // BfdVppHandler is accessor for BFD-related vppcalls methods type BfdVppHandler struct { - stopwatch *measure.Stopwatch callsChannel api.Channel ifIndexes ifaceidx.SwIfIndex log logging.Logger @@ -247,7 +244,6 @@ type BfdVppHandler struct { // NatVppHandler is accessor for NAT-related vppcalls methods type NatVppHandler struct { - stopwatch *measure.Stopwatch callsChannel api.Channel dumpChannel api.Channel ifIndexes ifaceidx.SwIfIndex @@ -256,48 +252,43 @@ type NatVppHandler struct { // StnVppHandler is accessor for STN-related vppcalls methods type StnVppHandler struct { - stopwatch *measure.Stopwatch ifIndexes ifaceidx.SwIfIndex callsChannel api.Channel log logging.Logger } // NewIfVppHandler creates new instance of interface vppcalls handler -func NewIfVppHandler(callsChan api.Channel, log logging.Logger, stopwatch *measure.Stopwatch) *IfVppHandler { +func NewIfVppHandler(callsChan api.Channel, log logging.Logger) *IfVppHandler { return &IfVppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, log: log, } } // NewBfdVppHandler creates new instance of BFD vppcalls handler -func NewBfdVppHandler(callsChan api.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *BfdVppHandler { +func NewBfdVppHandler(callsChan api.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *BfdVppHandler { return &BfdVppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, log: log, } } // NewNatVppHandler creates new instance of NAT vppcalls handler -func NewNatVppHandler(callsChan, dumpChan api.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *NatVppHandler { +func NewNatVppHandler(callsChan, dumpChan api.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *NatVppHandler { return &NatVppHandler{ callsChannel: callsChan, dumpChannel: dumpChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, log: log, } } // NewStnVppHandler creates new instance of STN vppcalls handler -func NewStnVppHandler(callsChan api.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *StnVppHandler { +func NewStnVppHandler(callsChan api.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *StnVppHandler { return &StnVppHandler{ callsChannel: callsChan, ifIndexes: ifIndexes, - stopwatch: stopwatch, log: log, } } diff --git a/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls.go index f8ecf5d868..8fc2785969 100644 --- a/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls.go @@ -18,7 +18,6 @@ import ( "fmt" "net" "strconv" - "time" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/vpp-agent/idxvpp" @@ -28,11 +27,7 @@ import ( ) // AddBfdUDPSession implements BFD handler. -func (handler *BfdVppHandler) AddBfdUDPSession(bfdSess *bfd.SingleHopBFD_Session, ifIdx uint32, bfdKeyIndexes idxvpp.NameToIdx) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdUDPAdd{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) AddBfdUDPSession(bfdSess *bfd.SingleHopBFD_Session, ifIdx uint32, bfdKeyIndexes idxvpp.NameToIdx) error { req := &bfd_api.BfdUDPAdd{ SwIfIndex: ifIdx, DesiredMinTx: bfdSess.DesiredMinTxInterval, @@ -64,14 +59,14 @@ func (handler *BfdVppHandler) AddBfdUDPSession(bfdSess *bfd.SingleHopBFD_Session // Authentication if bfdSess.Authentication != nil { keyID := strconv.Itoa(int(bfdSess.Authentication.KeyId)) - handler.log.Infof("Setting up authentication with index %v", keyID) + h.log.Infof("Setting up authentication with index %v", keyID) _, _, found := bfdKeyIndexes.LookupIdx(keyID) if found { req.IsAuthenticated = 1 req.BfdKeyID = uint8(bfdSess.Authentication.KeyId) req.ConfKeyID = bfdSess.Authentication.AdvertisedKeyId } else { - handler.log.Infof("Authentication key %v not found", bfdSess.Authentication.KeyId) + h.log.Infof("Authentication key %v not found", bfdSess.Authentication.KeyId) req.IsAuthenticated = 0 } } else { @@ -79,7 +74,7 @@ func (handler *BfdVppHandler) AddBfdUDPSession(bfdSess *bfd.SingleHopBFD_Session } reply := &bfd_api.BfdUDPAddReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -89,11 +84,7 @@ func (handler *BfdVppHandler) AddBfdUDPSession(bfdSess *bfd.SingleHopBFD_Session } // AddBfdUDPSessionFromDetails implements BFD handler. -func (handler *BfdVppHandler) AddBfdUDPSessionFromDetails(bfdSess *bfd_api.BfdUDPSessionDetails, bfdKeyIndexes idxvpp.NameToIdx) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdUDPAdd{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) AddBfdUDPSessionFromDetails(bfdSess *bfd_api.BfdUDPSessionDetails, bfdKeyIndexes idxvpp.NameToIdx) error { req := &bfd_api.BfdUDPAdd{ SwIfIndex: bfdSess.SwIfIndex, DesiredMinTx: bfdSess.DesiredMinTx, @@ -107,14 +98,14 @@ func (handler *BfdVppHandler) AddBfdUDPSessionFromDetails(bfdSess *bfd_api.BfdUD // Authentication if bfdSess.IsAuthenticated != 0 { keyID := string(bfdSess.BfdKeyID) - handler.log.Infof("Setting up authentication with index %v", keyID) + h.log.Infof("Setting up authentication with index %v", keyID) _, _, found := bfdKeyIndexes.LookupIdx(keyID) if found { req.IsAuthenticated = 1 req.BfdKeyID = bfdSess.BfdKeyID req.ConfKeyID = bfdSess.ConfKeyID } else { - handler.log.Infof("Authentication key %v not found", bfdSess.BfdKeyID) + h.log.Infof("Authentication key %v not found", bfdSess.BfdKeyID) req.IsAuthenticated = 0 } } else { @@ -122,7 +113,7 @@ func (handler *BfdVppHandler) AddBfdUDPSessionFromDetails(bfdSess *bfd_api.BfdUD } reply := &bfd_api.BfdUDPAddReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -132,11 +123,7 @@ func (handler *BfdVppHandler) AddBfdUDPSessionFromDetails(bfdSess *bfd_api.BfdUD } // ModifyBfdUDPSession implements BFD handler. -func (handler *BfdVppHandler) ModifyBfdUDPSession(bfdSess *bfd.SingleHopBFD_Session, swIfIndexes ifaceidx.SwIfIndex) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdUDPMod{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) ModifyBfdUDPSession(bfdSess *bfd.SingleHopBFD_Session, swIfIndexes ifaceidx.SwIfIndex) error { // Find the interface ifIdx, _, found := swIfIndexes.LookupIdx(bfdSess.Interface) if !found { @@ -172,7 +159,7 @@ func (handler *BfdVppHandler) ModifyBfdUDPSession(bfdSess *bfd.SingleHopBFD_Sess } reply := &bfd_api.BfdUDPModReply{} - if err = handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err = h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -182,11 +169,7 @@ func (handler *BfdVppHandler) ModifyBfdUDPSession(bfdSess *bfd.SingleHopBFD_Sess } // DeleteBfdUDPSession implements BFD handler. -func (handler *BfdVppHandler) DeleteBfdUDPSession(ifIndex uint32, sourceAddress string, destAddress string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdUDPDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) DeleteBfdUDPSession(ifIndex uint32, sourceAddress string, destAddress string) error { req := &bfd_api.BfdUDPDel{ SwIfIndex: ifIndex, LocalAddr: net.ParseIP(sourceAddress).To4(), @@ -195,7 +178,7 @@ func (handler *BfdVppHandler) DeleteBfdUDPSession(ifIndex uint32, sourceAddress } reply := &bfd_api.BfdUDPDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -205,11 +188,7 @@ func (handler *BfdVppHandler) DeleteBfdUDPSession(ifIndex uint32, sourceAddress } // SetBfdUDPAuthenticationKey implements BFD handler. -func (handler *BfdVppHandler) SetBfdUDPAuthenticationKey(bfdKey *bfd.SingleHopBFD_Key) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdAuthSetKey{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) SetBfdUDPAuthenticationKey(bfdKey *bfd.SingleHopBFD_Key) error { // Convert authentication according to RFC5880. var authentication uint8 if bfdKey.AuthenticationType == 0 { @@ -217,7 +196,7 @@ func (handler *BfdVppHandler) SetBfdUDPAuthenticationKey(bfdKey *bfd.SingleHopBF } else if bfdKey.AuthenticationType == 1 { authentication = 5 // Meticulous keyed SHA1 } else { - handler.log.Warnf("Provided authentication type not supported, setting up SHA1") + h.log.Warnf("Provided authentication type not supported, setting up SHA1") authentication = 4 } @@ -229,7 +208,7 @@ func (handler *BfdVppHandler) SetBfdUDPAuthenticationKey(bfdKey *bfd.SingleHopBF } reply := &bfd_api.BfdAuthSetKeyReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -239,17 +218,13 @@ func (handler *BfdVppHandler) SetBfdUDPAuthenticationKey(bfdKey *bfd.SingleHopBF } // DeleteBfdUDPAuthenticationKey implements BFD handler. -func (handler *BfdVppHandler) DeleteBfdUDPAuthenticationKey(bfdKey *bfd.SingleHopBFD_Key) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdAuthDelKey{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) DeleteBfdUDPAuthenticationKey(bfdKey *bfd.SingleHopBFD_Key) error { req := &bfd_api.BfdAuthDelKey{ ConfKeyID: bfdKey.Id, } reply := &bfd_api.BfdAuthDelKeyReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -259,11 +234,7 @@ func (handler *BfdVppHandler) DeleteBfdUDPAuthenticationKey(bfdKey *bfd.SingleHo } // AddBfdEchoFunction implements BFD handler. -func (handler *BfdVppHandler) AddBfdEchoFunction(bfdInput *bfd.SingleHopBFD_EchoFunction, swIfIndexes ifaceidx.SwIfIndex) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdUDPSetEchoSource{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) AddBfdEchoFunction(bfdInput *bfd.SingleHopBFD_EchoFunction, swIfIndexes ifaceidx.SwIfIndex) error { // Verify the interface presence. ifIdx, _, found := swIfIndexes.LookupIdx(bfdInput.EchoSourceInterface) if !found { @@ -275,7 +246,7 @@ func (handler *BfdVppHandler) AddBfdEchoFunction(bfdInput *bfd.SingleHopBFD_Echo } reply := &bfd_api.BfdUDPSetEchoSourceReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -285,16 +256,12 @@ func (handler *BfdVppHandler) AddBfdEchoFunction(bfdInput *bfd.SingleHopBFD_Echo } // DeleteBfdEchoFunction implements BFD handler. -func (handler *BfdVppHandler) DeleteBfdEchoFunction() error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfd_api.BfdUDPDelEchoSource{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) DeleteBfdEchoFunction() error { // Prepare the message. req := &bfd_api.BfdUDPDelEchoSource{} reply := &bfd_api.BfdUDPDelEchoSourceReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) diff --git a/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls_test.go b/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls_test.go index 858f9a06e3..84126b8feb 100644 --- a/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls_test.go +++ b/plugins/vpp/ifplugin/vppcalls/bfd_vppcalls_test.go @@ -842,6 +842,6 @@ func bfdTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.BfdVppAPI, iface ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "bfd-if-idx", nil)) - bfdHandler := vppcalls.NewBfdVppHandler(ctx.MockChannel, ifIndexes, log, nil) + bfdHandler := vppcalls.NewBfdVppHandler(ctx.MockChannel, ifIndexes, log,) return ctx, bfdHandler, ifIndexes } diff --git a/plugins/vpp/ifplugin/vppcalls/dhcp_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/dhcp_vppcalls.go index 0a9664b588..dbb1e1b9f2 100644 --- a/plugins/vpp/ifplugin/vppcalls/dhcp_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/dhcp_vppcalls.go @@ -16,16 +16,11 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/dhcp" ) func (h *IfVppHandler) handleInterfaceDHCP(ifIdx uint32, hostName string, isAdd bool) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(dhcp.DHCPClientConfig{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &dhcp.DHCPClientConfig{ IsAdd: boolToUint(isAdd), Client: dhcp.DHCPClient{ diff --git a/plugins/vpp/ifplugin/vppcalls/dump_bfd_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/dump_bfd_vppcalls.go index bb300ddbc1..3d8e96df1a 100644 --- a/plugins/vpp/ifplugin/vppcalls/dump_bfd_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/dump_bfd_vppcalls.go @@ -16,7 +16,6 @@ package vppcalls import ( "net" - "time" bfdapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/bfd" "github.com/ligato/vpp-agent/plugins/vpp/model/bfd" @@ -35,12 +34,12 @@ type BfdMeta struct { } // DumpBfdSingleHop implements BFD handler. -func (handler *BfdVppHandler) DumpBfdSingleHop() (*BfdDetails, error) { - sessionDetails, err := handler.DumpBfdSessions() +func (h *BfdVppHandler) DumpBfdSingleHop() (*BfdDetails, error) { + sessionDetails, err := h.DumpBfdSessions() if err != nil { return nil, err } - keyDetails, err := handler.DumpBfdAuthKeys() + keyDetails, err := h.DumpBfdAuthKeys() if err != nil { return nil, err } @@ -69,18 +68,14 @@ type BfdSessionMeta struct { } // DumpBfdSessions implements BFD handler. -func (handler *BfdVppHandler) DumpBfdSessions() (*BfdSessionDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfdapi.BfdUDPSessionDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) DumpBfdSessions() (*BfdSessionDetails, error) { var sessions []*bfd.SingleHopBFD_Session meta := &BfdSessionMeta{ SessionIfToIdx: make(map[uint32]string), } req := &bfdapi.BfdUDPSessionDump{} - sessionsRequest := handler.callsChannel.SendMultiRequest(req) + sessionsRequest := h.callsChannel.SendMultiRequest(req) for { sessionDetails := &bfdapi.BfdUDPSessionDetails{} @@ -92,9 +87,9 @@ func (handler *BfdVppHandler) DumpBfdSessions() (*BfdSessionDetails, error) { return nil, err } - ifName, _, exists := handler.ifIndexes.LookupName(sessionDetails.SwIfIndex) + ifName, _, exists := h.ifIndexes.LookupName(sessionDetails.SwIfIndex) if !exists { - handler.log.Warnf("BFD session dump: interface name not found for index %d", sessionDetails.SwIfIndex) + h.log.Warnf("BFD session dump: interface name not found for index %d", sessionDetails.SwIfIndex) } var srcAddr, dstAddr net.IP = sessionDetails.LocalAddr, sessionDetails.PeerAddr @@ -122,8 +117,8 @@ func (handler *BfdVppHandler) DumpBfdSessions() (*BfdSessionDetails, error) { } // DumpBfdUDPSessionsWithID implements BFD handler. -func (handler *BfdVppHandler) DumpBfdUDPSessionsWithID(authKeyIndex uint32) (*BfdSessionDetails, error) { - details, err := handler.DumpBfdSessions() +func (h *BfdVppHandler) DumpBfdUDPSessionsWithID(authKeyIndex uint32) (*BfdSessionDetails, error) { + details, err := h.DumpBfdSessions() if err != nil || len(details.Session) == 0 { return nil, err } @@ -152,18 +147,14 @@ type BfdAuthKeyMeta struct { } // DumpBfdAuthKeys implements BFD handler. -func (handler *BfdVppHandler) DumpBfdAuthKeys() (*BfdAuthKeyDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bfdapi.BfdAuthKeysDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BfdVppHandler) DumpBfdAuthKeys() (*BfdAuthKeyDetails, error) { var authKeys []*bfd.SingleHopBFD_Key meta := &BfdAuthKeyMeta{ KeyIDToUseCount: make(map[uint32]uint32), } req := &bfdapi.BfdAuthKeysDump{} - keysRequest := handler.callsChannel.SendMultiRequest(req) + keysRequest := h.callsChannel.SendMultiRequest(req) for { keyDetails := &bfdapi.BfdAuthKeysDetails{} diff --git a/plugins/vpp/ifplugin/vppcalls/dump_interface_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/dump_interface_vppcalls.go index 33373f27d8..42b6430dee 100644 --- a/plugins/vpp/ifplugin/vppcalls/dump_interface_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/dump_interface_vppcalls.go @@ -19,9 +19,7 @@ import ( "fmt" "net" "strings" - "time" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/plugins/vpp/binapi/dhcp" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" @@ -96,7 +94,6 @@ func (h *IfVppHandler) DumpInterfacesByType(reqType ifnb.InterfaceType) (map[uin // DumpInterfaces implements interface handler. func (h *IfVppHandler) DumpInterfaces() (map[uint32]*InterfaceDetails, error) { - start := time.Now() // map for the resulting interfaces ifs := make(map[uint32]*InterfaceDetails) @@ -149,13 +146,17 @@ func (h *IfVppHandler) DumpInterfaces() (map[uint32]*InterfaceDetails, error) { if err != nil { return nil, fmt.Errorf("failed to dump interface DHCP clients: %v", err) } + // Get unnumbered interfaces + unnumbered, err := h.dumpUnnumberedDetails() + if err != nil { + return nil, fmt.Errorf("failed to dump unnumbered interfaces: %v", err) + } // Get vrf for every interface and fill DHCP if set for _, ifData := range ifs { // VRF vrf, err := h.GetInterfaceVrf(ifData.Meta.SwIfIndex) if err != nil { - h.log.Warnf("Interface dump: failed to get VRF from interface %d: %v", ifData.Meta.SwIfIndex, err) - continue + return nil, fmt.Errorf("interface dump: failed to get VRF from interface %d: %v", ifData.Meta.SwIfIndex, err) } ifData.Interface.Vrf = vrf // DHCP @@ -164,22 +165,30 @@ func (h *IfVppHandler) DumpInterfaces() (map[uint32]*InterfaceDetails, error) { ifData.Interface.SetDhcpClient = true ifData.Meta.Dhcp = dhcpData } + // Unnumbered + ifWithIPIdx, ok := unnumbered[ifData.Meta.SwIfIndex] + if ok { + // Find unnumbered interface + var ifWithIPName string + ifWithIP, ok := ifs[ifWithIPIdx] + if ok { + ifWithIPName = ifWithIP.Interface.Name + } else { + h.log.Debugf("cannot find name of the ip-interface for unnumbered %s", ifData.Interface.Name) + ifWithIPName = "" + } + ifData.Interface.Unnumbered = &ifnb.Interfaces_Interface_Unnumbered{ + IsUnnumbered: true, + InterfaceWithIp: ifWithIPName, + } + } } - h.log.Debugf("dumped %d interfaces", len(ifs)) - - // SwInterfaceDump time - timeLog := measure.GetTimeLog(interfaces.SwInterfaceDump{}, h.stopwatch) - if timeLog != nil { - timeLog.LogTimeEntry(time.Since(start)) - } - - timeLog = measure.GetTimeLog(ip.IPAddressDump{}, h.stopwatch) - err = h.dumpIPAddressDetails(ifs, 0, timeLog) + err = h.dumpIPAddressDetails(ifs, 0) if err != nil { return nil, err } - err = h.dumpIPAddressDetails(ifs, 1, timeLog) + err = h.dumpIPAddressDetails(ifs, 1) if err != nil { return nil, err } @@ -204,11 +213,6 @@ func (h *IfVppHandler) DumpInterfaces() (map[uint32]*InterfaceDetails, error) { // DumpMemifSocketDetails implements interface handler. func (h *IfVppHandler) DumpMemifSocketDetails() (map[string]uint32, error) { - // MemifSocketFilenameDump time measurement - defer func(t time.Time) { - h.stopwatch.TimeLog(memif.MemifSocketFilenameDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - memifSocketMap := make(map[string]uint32) reqCtx := h.callsChannel.SendMultiRequest(&memif.MemifSocketFilenameDump{}) @@ -232,12 +236,9 @@ func (h *IfVppHandler) DumpMemifSocketDetails() (map[string]uint32, error) { } // dumpIPAddressDetails dumps IP address details of interfaces from VPP and fills them into the provided interface map. -func (h *IfVppHandler) dumpIPAddressDetails(ifs map[uint32]*InterfaceDetails, isIPv6 uint8, timeLog measure.StopWatchEntry) error { +func (h *IfVppHandler) dumpIPAddressDetails(ifs map[uint32]*InterfaceDetails, isIPv6 uint8) error { // Dump IP addresses of each interface. for idx := range ifs { - // IPAddressDetails time measurement - start := time.Now() - reqCtx := h.callsChannel.SendMultiRequest(&ip.IPAddressDump{ SwIfIndex: idx, IsIPv6: isIPv6, @@ -253,11 +254,6 @@ func (h *IfVppHandler) dumpIPAddressDetails(ifs map[uint32]*InterfaceDetails, is } h.processIPDetails(ifs, ipDetails) } - - // IPAddressDump time - if timeLog != nil { - timeLog.LogTimeEntry(time.Since(start)) - } } return nil @@ -288,11 +284,6 @@ func fillAFPacketDetails(ifs map[uint32]*InterfaceDetails, swIfIndex uint32, ifN // dumpMemifDetails dumps memif interface details from VPP and fills them into the provided interface map. func (h *IfVppHandler) dumpMemifDetails(ifs map[uint32]*InterfaceDetails) error { - // MemifDetails time measurement - defer func(t time.Time) { - h.stopwatch.TimeLog(memif.MemifDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - // Dump all memif sockets memifSocketMap, err := h.DumpMemifSocketDetails() if err != nil { @@ -340,11 +331,6 @@ func (h *IfVppHandler) dumpMemifDetails(ifs map[uint32]*InterfaceDetails) error // dumpTapDetails dumps tap interface details from VPP and fills them into the provided interface map. func (h *IfVppHandler) dumpTapDetails(ifs map[uint32]*InterfaceDetails) error { - // SwInterfaceTapDump time measurement - defer func(t time.Time) { - h.stopwatch.TimeLog(tap.SwInterfaceTapDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - // Original TAP. reqCtx := h.callsChannel.SendMultiRequest(&tap.SwInterfaceTapDump{}) for { @@ -396,11 +382,6 @@ func (h *IfVppHandler) dumpTapDetails(ifs map[uint32]*InterfaceDetails) error { // dumpVxlanDetails dumps VXLAN interface details from VPP and fills them into the provided interface map. func (h *IfVppHandler) dumpVxlanDetails(ifs map[uint32]*InterfaceDetails) error { - // VxlanTunnelDump time measurement - defer func(t time.Time) { - h.stopwatch.TimeLog(vxlan.VxlanTunnelDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - reqCtx := h.callsChannel.SendMultiRequest(&vxlan.VxlanTunnelDump{SwIfIndex: ^uint32(0)}) for { vxlanDetails := &vxlan.VxlanTunnelDetails{} @@ -445,10 +426,6 @@ func (h *IfVppHandler) dumpVxlanDetails(ifs map[uint32]*InterfaceDetails) error // dumpDhcpClients returns a slice of DhcpMeta with all interfaces and other DHCP-related information available func (h *IfVppHandler) dumpDhcpClients() (map[uint32]*Dhcp, error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(dhcp.DHCPClientDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - dhcpData := make(map[uint32]*Dhcp) reqCtx := h.callsChannel.SendMultiRequest(&dhcp.DHCPClientDump{}) @@ -506,6 +483,29 @@ func (h *IfVppHandler) dumpDhcpClients() (map[uint32]*Dhcp, error) { return dhcpData, nil } +// dumpUnnumberedDetails returns a map of unnumbered interface indexes, every with interface index of element with IP +func (h *IfVppHandler) dumpUnnumberedDetails() (map[uint32]uint32, error) { + unIfMap := make(map[uint32]uint32) // unnumbered/ip-interface + reqCtx := h.callsChannel.SendMultiRequest(&ip.IPUnnumberedDump{ + SwIfIndex: ^uint32(0), + }) + + for { + unDetails := &ip.IPUnnumberedDetails{} + last, err := reqCtx.ReceiveReply(unDetails) + if last { + break + } + if err != nil { + return nil, err + } + + unIfMap[unDetails.SwIfIndex] = unDetails.IPSwIfIndex + } + + return unIfMap, nil +} + // guessInterfaceType attempts to guess the correct interface type from its internal name (as given by VPP). // This is required mainly for those interface types, that do not provide dump binary API, // such as loopback of af_packet. diff --git a/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls.go index a238924538..9b006977d5 100644 --- a/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls.go @@ -19,7 +19,6 @@ import ( "fmt" "net" "strings" - "time" bin_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/nat" "github.com/ligato/vpp-agent/plugins/vpp/model/nat" @@ -33,12 +32,12 @@ type Nat44Details struct { } // Nat44Dump implements NAT handler. -func (handler *NatVppHandler) Nat44Dump() (*Nat44Details, error) { - global, err := handler.Nat44GlobalConfigDump() +func (h *NatVppHandler) Nat44Dump() (*Nat44Details, error) { + global, err := h.Nat44GlobalConfigDump() if err != nil { return nil, err } - dNat, err := handler.Nat44DNatDump() + dNat, err := h.Nat44DNatDump() if err != nil { return nil, err } @@ -49,26 +48,26 @@ func (handler *NatVppHandler) Nat44Dump() (*Nat44Details, error) { } // Nat44GlobalConfigDump implements NAT handler. -func (handler *NatVppHandler) Nat44GlobalConfigDump() (*nat.Nat44Global, error) { - handler.log.Debug("dumping Nat44Global") +func (h *NatVppHandler) Nat44GlobalConfigDump() (*nat.Nat44Global, error) { + h.log.Debug("dumping Nat44Global") // Dump all necessary data to reconstruct global NAT configuration - isEnabled, err := handler.isNat44ForwardingEnabled() + isEnabled, err := h.isNat44ForwardingEnabled() if err != nil { return nil, err } - natInterfaces, err := handler.Nat44InterfaceDump() + natInterfaces, err := h.Nat44InterfaceDump() if err != nil { return nil, err } - natOutputFeature, err := handler.nat44InterfaceOutputFeatureDump() + natOutputFeature, err := h.nat44InterfaceOutputFeatureDump() if err != nil { return nil, err } - natAddressPools, err := handler.nat44AddressDump() + natAddressPools, err := h.nat44AddressDump() if err != nil { return nil, err } - vrIPv4, vrIPv6, err := handler.virtualReassemblyDump() + vrIPv4, vrIPv6, err := h.virtualReassemblyDump() if err != nil { return nil, err } @@ -90,7 +89,7 @@ func (handler *NatVppHandler) Nat44GlobalConfigDump() (*nat.Nat44Global, error) }) } - handler.log.Debug("dumped Nat44Global") + h.log.Debug("dumped Nat44Global") // Set fields return &nat.Nat44Global{ @@ -103,38 +102,38 @@ func (handler *NatVppHandler) Nat44GlobalConfigDump() (*nat.Nat44Global, error) } // Nat44DNatDump implements NAT handler. -func (handler *NatVppHandler) Nat44DNatDump() (*nat.Nat44DNat, error) { +func (h *NatVppHandler) Nat44DNatDump() (*nat.Nat44DNat, error) { // List od DNAT configs var dNatCfgs []*nat.Nat44DNat_DNatConfig - handler.log.Debug("dumping DNat") + h.log.Debug("dumping DNat") // Static mappings - natStMappings, err := handler.nat44StaticMappingDump() + natStMappings, err := h.nat44StaticMappingDump() if err != nil { return nil, fmt.Errorf("failed to dump NAT44 static mappings: %v", err) } for tag, data := range natStMappings { - handler.processDNatData(tag, data, &dNatCfgs) + h.processDNatData(tag, data, &dNatCfgs) } // Static mappings with load balancer - natStLbMappings, err := handler.nat44StaticMappingLbDump() + natStLbMappings, err := h.nat44StaticMappingLbDump() if err != nil { return nil, fmt.Errorf("failed to dump NAT44 static mappings with load balancer: %v", err) } for tag, data := range natStLbMappings { - handler.processDNatData(tag, data, &dNatCfgs) + h.processDNatData(tag, data, &dNatCfgs) } // Identity mappings - natIDMappings, err := handler.nat44IdentityMappingDump() + natIDMappings, err := h.nat44IdentityMappingDump() if err != nil { return nil, fmt.Errorf("failed to dump NAT44 identity mappings: %v", err) } for tag, data := range natIDMappings { - handler.processDNatData(tag, data, &dNatCfgs) + h.processDNatData(tag, data, &dNatCfgs) } - handler.log.Debugf("dumped %d NAT44DNat configs", len(dNatCfgs)) + h.log.Debugf("dumped %d NAT44DNat configs", len(dNatCfgs)) return &nat.Nat44DNat{ DnatConfigs: dNatCfgs, @@ -142,13 +141,9 @@ func (handler *NatVppHandler) Nat44DNatDump() (*nat.Nat44DNat, error) { } // nat44AddressDump returns a list of NAT44 address pools configured in the VPP -func (handler *NatVppHandler) nat44AddressDump() (addresses []*nat.Nat44Global_AddressPool, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.Nat44AddressDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) nat44AddressDump() (addresses []*nat.Nat44Global_AddressPool, err error) { req := &bin_api.Nat44AddressDump{} - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &bin_api.Nat44AddressDetails{} @@ -169,21 +164,17 @@ func (handler *NatVppHandler) nat44AddressDump() (addresses []*nat.Nat44Global_A }) } - handler.log.Debugf("NAT44 address pool dump complete, found %d entries", len(addresses)) + h.log.Debugf("NAT44 address pool dump complete, found %d entries", len(addresses)) return } // virtualReassemblyDump returns current NAT44 virtual-reassembly configuration. The output config may be nil. -func (handler *NatVppHandler) virtualReassemblyDump() (vrIPv4 *nat.Nat44Global_VirtualReassembly, vrIPv6 *nat.Nat44Global_VirtualReassembly, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.NatGetReass{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) virtualReassemblyDump() (vrIPv4 *nat.Nat44Global_VirtualReassembly, vrIPv6 *nat.Nat44Global_VirtualReassembly, err error) { req := &bin_api.NatGetReass{} reply := &bin_api.NatGetReassReply{} - if err := handler.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { return nil, nil, fmt.Errorf("failed to get NAT44 virtual reassembly configuration: %v", err) } if reply.Retval != 0 { @@ -207,14 +198,10 @@ func (handler *NatVppHandler) virtualReassemblyDump() (vrIPv4 *nat.Nat44Global_V } // nat44StaticMappingDump returns a map of static mapping tag/data pairs -func (handler *NatVppHandler) nat44StaticMappingDump() (entries map[string]*nat.Nat44DNat_DNatConfig_StaticMapping, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.Nat44StaticMappingDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) nat44StaticMappingDump() (entries map[string]*nat.Nat44DNat_DNatConfig_StaticMapping, err error) { entries = make(map[string]*nat.Nat44DNat_DNatConfig_StaticMapping) req := &bin_api.Nat44StaticMappingDump{} - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &bin_api.Nat44StaticMappingDetails{} @@ -235,9 +222,9 @@ func (handler *NatVppHandler) nat44StaticMappingDump() (entries map[string]*nat. // Fill data (value) entries[tag] = &nat.Nat44DNat_DNatConfig_StaticMapping{ ExternalInterface: func(ifIdx uint32) string { - ifName, _, found := handler.ifIndexes.LookupName(ifIdx) + ifName, _, found := h.ifIndexes.LookupName(ifIdx) if !found && ifIdx != ^uint32(0) { - handler.log.Warnf("Interface with index %v not found in the mapping", ifIdx) + h.log.Warnf("Interface with index %v not found in the mapping", ifIdx) } return ifName }(msg.ExternalSwIfIndex), @@ -248,25 +235,21 @@ func (handler *NatVppHandler) nat44StaticMappingDump() (entries map[string]*nat. LocalIp: lcIPAddress.To4().String(), LocalPort: uint32(msg.LocalPort), }), - Protocol: handler.getProtocol(msg.Protocol), - TwiceNat: handler.getTwiceNatMode(msg.TwiceNat, msg.SelfTwiceNat), + Protocol: h.getProtocol(msg.Protocol), + TwiceNat: h.getTwiceNatMode(msg.TwiceNat, msg.SelfTwiceNat), } } - handler.log.Debugf("NAT44 static mapping dump complete, found %d entries", len(entries)) + h.log.Debugf("NAT44 static mapping dump complete, found %d entries", len(entries)) return entries, nil } // nat44StaticMappingLbDump returns a map of static mapping tag/data pairs with load balancer -func (handler *NatVppHandler) nat44StaticMappingLbDump() (entries map[string]*nat.Nat44DNat_DNatConfig_StaticMapping, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.Nat44LbStaticMappingDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) nat44StaticMappingLbDump() (entries map[string]*nat.Nat44DNat_DNatConfig_StaticMapping, err error) { entries = make(map[string]*nat.Nat44DNat_DNatConfig_StaticMapping) req := &bin_api.Nat44LbStaticMappingDump{} - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &bin_api.Nat44LbStaticMappingDetails{} @@ -298,25 +281,21 @@ func (handler *NatVppHandler) nat44StaticMappingLbDump() (entries map[string]*na ExternalIp: exIPAddress.To4().String(), ExternalPort: uint32(msg.ExternalPort), LocalIps: locals, - Protocol: handler.getProtocol(msg.Protocol), - TwiceNat: handler.getTwiceNatMode(msg.TwiceNat, msg.SelfTwiceNat), + Protocol: h.getProtocol(msg.Protocol), + TwiceNat: h.getTwiceNatMode(msg.TwiceNat, msg.SelfTwiceNat), } } - handler.log.Debugf("NAT44 lb-static mapping dump complete, found %d entries", len(entries)) + h.log.Debugf("NAT44 lb-static mapping dump complete, found %d entries", len(entries)) return entries, nil } // nat44IdentityMappingDump returns a map of identity mapping tag/data pairs -func (handler *NatVppHandler) nat44IdentityMappingDump() (entries map[string]*nat.Nat44DNat_DNatConfig_IdentityMapping, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.Nat44IdentityMappingDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) nat44IdentityMappingDump() (entries map[string]*nat.Nat44DNat_DNatConfig_IdentityMapping, err error) { entries = make(map[string]*nat.Nat44DNat_DNatConfig_IdentityMapping) req := &bin_api.Nat44IdentityMappingDump{} - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &bin_api.Nat44IdentityMappingDetails{} @@ -337,31 +316,27 @@ func (handler *NatVppHandler) nat44IdentityMappingDump() (entries map[string]*na entries[tag] = &nat.Nat44DNat_DNatConfig_IdentityMapping{ VrfId: msg.VrfID, AddressedInterface: func(ifIdx uint32) string { - ifName, _, found := handler.ifIndexes.LookupName(ifIdx) + ifName, _, found := h.ifIndexes.LookupName(ifIdx) if !found && ifIdx != 0xffffffff { - handler.log.Warnf("Interface with index %v not found in the mapping", ifIdx) + h.log.Warnf("Interface with index %v not found in the mapping", ifIdx) } return ifName }(msg.SwIfIndex), IpAddress: ipAddress.To4().String(), Port: uint32(msg.Port), - Protocol: handler.getProtocol(msg.Protocol), + Protocol: h.getProtocol(msg.Protocol), } } - handler.log.Debugf("NAT44 identity mapping dump complete, found %d entries", len(entries)) + h.log.Debugf("NAT44 identity mapping dump complete, found %d entries", len(entries)) return entries, nil } // Nat44InterfaceDump implements NAT handler. -func (handler *NatVppHandler) Nat44InterfaceDump() (interfaces []*nat.Nat44Global_NatInterface, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.Nat44InterfaceDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) Nat44InterfaceDump() (interfaces []*nat.Nat44Global_NatInterface, err error) { req := &bin_api.Nat44InterfaceDump{} - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &bin_api.Nat44InterfaceDetails{} @@ -374,9 +349,9 @@ func (handler *NatVppHandler) Nat44InterfaceDump() (interfaces []*nat.Nat44Globa } // Find interface name - ifName, _, found := handler.ifIndexes.LookupName(msg.SwIfIndex) + ifName, _, found := h.ifIndexes.LookupName(msg.SwIfIndex) if !found { - handler.log.Warnf("Interface with index %d not found in the mapping", msg.SwIfIndex) + h.log.Warnf("Interface with index %d not found in the mapping", msg.SwIfIndex) continue } @@ -394,19 +369,15 @@ func (handler *NatVppHandler) Nat44InterfaceDump() (interfaces []*nat.Nat44Globa } } - handler.log.Debugf("NAT44 interface dump complete, found %d entries", len(interfaces)) + h.log.Debugf("NAT44 interface dump complete, found %d entries", len(interfaces)) return } // nat44InterfaceOutputFeatureDump returns a list of interfaces with output feature set -func (handler *NatVppHandler) nat44InterfaceOutputFeatureDump() (ifaces []*nat.Nat44Global_NatInterface, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.Nat44InterfaceOutputFeatureDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) nat44InterfaceOutputFeatureDump() (ifaces []*nat.Nat44Global_NatInterface, err error) { req := &bin_api.Nat44InterfaceOutputFeatureDump{} - reqContext := handler.dumpChannel.SendMultiRequest(req) + reqContext := h.dumpChannel.SendMultiRequest(req) for { msg := &bin_api.Nat44InterfaceOutputFeatureDetails{} @@ -419,9 +390,9 @@ func (handler *NatVppHandler) nat44InterfaceOutputFeatureDump() (ifaces []*nat.N } // Find interface name - ifName, _, found := handler.ifIndexes.LookupName(msg.SwIfIndex) + ifName, _, found := h.ifIndexes.LookupName(msg.SwIfIndex) if !found { - handler.log.Warnf("Interface with index %d not found in the mapping", msg.SwIfIndex) + h.log.Warnf("Interface with index %d not found in the mapping", msg.SwIfIndex) continue } @@ -432,37 +403,33 @@ func (handler *NatVppHandler) nat44InterfaceOutputFeatureDump() (ifaces []*nat.N }) } - handler.log.Debugf("NAT44 interface with output feature dump complete, found %d entries", len(ifaces)) + h.log.Debugf("NAT44 interface with output feature dump complete, found %d entries", len(ifaces)) return ifaces, nil } // Nat44IsForwardingEnabled returns a list of interfaces enabled for NAT44 -func (handler *NatVppHandler) isNat44ForwardingEnabled() (isEnabled bool, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(bin_api.Nat44ForwardingIsEnabled{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) isNat44ForwardingEnabled() (isEnabled bool, err error) { req := &bin_api.Nat44ForwardingIsEnabled{} reply := &bin_api.Nat44ForwardingIsEnabledReply{} - if err := handler.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.dumpChannel.SendRequest(req).ReceiveReply(reply); err != nil { return false, fmt.Errorf("failed to dump forwarding: %v", err) } isEnabled = uintToBool(reply.Enabled) - handler.log.Debugf("NAT44 forwarding dump complete, is enabled: %v", isEnabled) + h.log.Debugf("NAT44 forwarding dump complete, is enabled: %v", isEnabled) return isEnabled, nil } // Common function can process all static and identity mappings -func (handler *NatVppHandler) processDNatData(tag string, data interface{}, dNatCfgs *[]*nat.Nat44DNat_DNatConfig) { +func (h *NatVppHandler) processDNatData(tag string, data interface{}, dNatCfgs *[]*nat.Nat44DNat_DNatConfig) { if tag == "" { - handler.log.Errorf("Cannot process DNAT config without tag") + h.log.Errorf("Cannot process DNAT config without tag") return } - label := handler.getDnatLabel(tag) + label := h.getDnatLabel(tag) // Look for DNAT config using tag var dNat *nat.Nat44DNat_DNatConfig @@ -480,22 +447,22 @@ func (handler *NatVppHandler) processDNatData(tag string, data interface{}, dNat IdMappings: make([]*nat.Nat44DNat_DNatConfig_IdentityMapping, 0), } *dNatCfgs = append(*dNatCfgs, dNat) - handler.log.Debugf("Created new DNAT configuration %s", label) + h.log.Debugf("Created new DNAT configuration %s", label) } // Add data to config switch mapping := data.(type) { case *nat.Nat44DNat_DNatConfig_StaticMapping: - handler.log.Debugf("Static mapping added to DNAT %s", label) + h.log.Debugf("Static mapping added to DNAT %s", label) dNat.StMappings = append(dNat.StMappings, mapping) case *nat.Nat44DNat_DNatConfig_IdentityMapping: - handler.log.Debugf("Identity mapping added to DNAT %s", label) + h.log.Debugf("Identity mapping added to DNAT %s", label) dNat.IdMappings = append(dNat.IdMappings, mapping) } } // returns NAT numeric representation of provided protocol value -func (handler *NatVppHandler) getProtocol(protocol uint8) (proto nat.Protocol) { +func (h *NatVppHandler) getProtocol(protocol uint8) (proto nat.Protocol) { switch protocol { case TCP: return nat.Protocol_TCP @@ -504,15 +471,15 @@ func (handler *NatVppHandler) getProtocol(protocol uint8) (proto nat.Protocol) { case ICMP: return nat.Protocol_ICMP default: - handler.log.Warnf("Unknown protocol %v", protocol) + h.log.Warnf("Unknown protocol %v", protocol) return 0 } } -func (handler *NatVppHandler) getTwiceNatMode(twiceNat, selfTwiceNat uint8) nat.TwiceNatMode { +func (h *NatVppHandler) getTwiceNatMode(twiceNat, selfTwiceNat uint8) nat.TwiceNatMode { if twiceNat > 0 { if selfTwiceNat > 0 { - handler.log.Warnf("Both TwiceNAT and self-TwiceNAT are enabled") + h.log.Warnf("Both TwiceNAT and self-TwiceNAT are enabled") return 0 } return nat.TwiceNatMode_ENABLED @@ -531,15 +498,15 @@ func uintToBool(value uint8) bool { } // Obtain DNAT label from provided tag -func (handler *NatVppHandler) getDnatLabel(tag string) (label string) { +func (h *NatVppHandler) getDnatLabel(tag string) (label string) { parts := strings.Split(tag, "|") // Tag should be in format label|mappingType|index if len(parts) == 0 { - handler.log.Errorf("Unable to obtain DNAT label, incorrect mapping tag format: '%s'", tag) + h.log.Errorf("Unable to obtain DNAT label, incorrect mapping tag format: '%s'", tag) return } if len(parts) != 3 { - handler.log.Warnf("Mapping tag has unexpected format: %s. Resolved DNAT label may not be correct", tag) + h.log.Warnf("Mapping tag has unexpected format: %s. Resolved DNAT label may not be correct", tag) } return parts[0] } diff --git a/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls_test.go b/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls_test.go index f891c38f0f..162f8ec5f4 100644 --- a/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls_test.go +++ b/plugins/vpp/ifplugin/vppcalls/dump_nat_vppcalls_test.go @@ -87,6 +87,6 @@ func natTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.NatVppAPI, iface ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "test-sw_if_indexes", ifaceidx.IndexMetadata)) - natHandler := vppcalls.NewNatVppHandler(ctx.MockChannel, ctx.MockChannel, swIfIndexes, log, nil) + natHandler := vppcalls.NewNatVppHandler(ctx.MockChannel, ctx.MockChannel, swIfIndexes, log,) return ctx, natHandler, swIfIndexes } diff --git a/plugins/vpp/ifplugin/vppcalls/dump_stn_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/dump_stn_vppcalls.go index e3cbb77496..c5b6f8329a 100644 --- a/plugins/vpp/ifplugin/vppcalls/dump_stn_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/dump_stn_vppcalls.go @@ -15,11 +15,8 @@ package vppcalls import ( - "time" - - "net" - "fmt" + "net" stnapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/stn" "github.com/ligato/vpp-agent/plugins/vpp/model/stn" @@ -37,18 +34,14 @@ type StnMeta struct { } // DumpStnRules implements STN handler. -func (handler *StnVppHandler) DumpStnRules() (rules *StnDetails, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(stnapi.StnRulesDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *StnVppHandler) DumpStnRules() (rules *StnDetails, err error) { var ruleList []*stn.STN_Rule meta := &StnMeta{ IfNameToIdx: make(map[uint32]string), } req := &stnapi.StnRulesDump{} - reqCtx := handler.callsChannel.SendMultiRequest(req) + reqCtx := h.callsChannel.SendMultiRequest(req) for { msg := &stnapi.StnRulesDetails{} stop, err := reqCtx.ReceiveReply(msg) @@ -58,9 +51,9 @@ func (handler *StnVppHandler) DumpStnRules() (rules *StnDetails, err error) { if err != nil { return nil, err } - ifName, _, found := handler.ifIndexes.LookupName(msg.SwIfIndex) + ifName, _, found := h.ifIndexes.LookupName(msg.SwIfIndex) if !found { - handler.log.Warnf("STN dump: name not found for interface %d", msg.SwIfIndex) + h.log.Warnf("STN dump: name not found for interface %d", msg.SwIfIndex) } var stnStrIP string diff --git a/plugins/vpp/ifplugin/vppcalls/ip_container_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/ip_container_vppcalls.go index 4ef1941cbb..9389968420 100644 --- a/plugins/vpp/ifplugin/vppcalls/ip_container_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/ip_container_vppcalls.go @@ -16,7 +16,6 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" @@ -28,10 +27,6 @@ const ( ) func (h *IfVppHandler) sendAndLogMessageForVpp(ifIdx uint32, addr string, isAdd uint8) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(ip.IPContainerProxyAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &ip.IPContainerProxyAddDel{ SwIfIndex: ifIdx, IsAdd: isAdd, diff --git a/plugins/vpp/ifplugin/vppcalls/ip_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/ip_vppcalls.go index 988ec6286a..eabcbae721 100644 --- a/plugins/vpp/ifplugin/vppcalls/ip_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/ip_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" @@ -29,10 +28,6 @@ const ( ) func (h *IfVppHandler) addDelInterfaceIP(ifIdx uint32, addr *net.IPNet, isAdd uint8) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceAddDelAddress{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &interfaces.SwInterfaceAddDelAddress{ SwIfIndex: ifIdx, IsAdd: isAdd, @@ -79,10 +74,6 @@ const ( ) func (h *IfVppHandler) setUnsetUnnumberedIP(uIfIdx uint32, ifIdxWithIP uint32, isAdd uint8) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceSetUnnumbered{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - // Prepare the message. req := &interfaces.SwInterfaceSetUnnumbered{ SwIfIndex: ifIdxWithIP, diff --git a/plugins/vpp/ifplugin/vppcalls/loopback_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/loopback_vppcalls.go index a7893f7fa7..89c2fd7562 100644 --- a/plugins/vpp/ifplugin/vppcalls/loopback_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/loopback_vppcalls.go @@ -16,17 +16,12 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" ) // AddLoopbackInterface implements interface handler. func (h *IfVppHandler) AddLoopbackInterface(ifName string) (swIndex uint32, err error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.CreateLoopback{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &interfaces.CreateLoopback{} reply := &interfaces.CreateLoopbackReply{} @@ -41,10 +36,6 @@ func (h *IfVppHandler) AddLoopbackInterface(ifName string) (swIndex uint32, err // DeleteLoopbackInterface implements interface handler. func (h *IfVppHandler) DeleteLoopbackInterface(ifName string, idx uint32) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.DeleteLoopback{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - // Prepare the message. req := &interfaces.DeleteLoopback{ SwIfIndex: idx, diff --git a/plugins/vpp/ifplugin/vppcalls/mac_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/mac_vppcalls.go index 196ba47ce3..ed179fb160 100644 --- a/plugins/vpp/ifplugin/vppcalls/mac_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/mac_vppcalls.go @@ -17,17 +17,12 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" ) // SetInterfaceMac implements interface handler. func (h *IfVppHandler) SetInterfaceMac(ifIdx uint32, macAddress string) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceSetMacAddress{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - mac, err := net.ParseMAC(macAddress) if err != nil { return err diff --git a/plugins/vpp/ifplugin/vppcalls/memif_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/memif_vppcalls.go index 181b8859d4..3bd33bb051 100644 --- a/plugins/vpp/ifplugin/vppcalls/memif_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/memif_vppcalls.go @@ -16,7 +16,6 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/memif" intf "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" @@ -24,10 +23,6 @@ import ( // AddMemifInterface implements interface handler. func (h *IfVppHandler) AddMemifInterface(ifName string, memIface *intf.Interfaces_Interface_Memif, socketID uint32) (swIdx uint32, err error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(memif.MemifCreate{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &memif.MemifCreate{ ID: memIface.Id, Mode: uint8(memIface.Mode), @@ -63,10 +58,6 @@ func (h *IfVppHandler) AddMemifInterface(ifName string, memIface *intf.Interface // DeleteMemifInterface implements interface handler. func (h *IfVppHandler) DeleteMemifInterface(ifName string, idx uint32) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(memif.MemifDelete{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &memif.MemifDelete{ SwIfIndex: idx, } @@ -83,10 +74,6 @@ func (h *IfVppHandler) DeleteMemifInterface(ifName string, idx uint32) error { // RegisterMemifSocketFilename implements interface handler. func (h *IfVppHandler) RegisterMemifSocketFilename(filename []byte, id uint32) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(memif.MemifSocketFilenameAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &memif.MemifSocketFilenameAddDel{ SocketFilename: filename, SocketID: id, diff --git a/plugins/vpp/ifplugin/vppcalls/mtu_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/mtu_vppcalls.go index 22f470de16..7ecad7afad 100644 --- a/plugins/vpp/ifplugin/vppcalls/mtu_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/mtu_vppcalls.go @@ -16,17 +16,12 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" ) // SetInterfaceMtu implements interface handler. func (h *IfVppHandler) SetInterfaceMtu(ifIdx uint32, mtu uint32) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.HwInterfaceSetMtu{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &interfaces.HwInterfaceSetMtu{ SwIfIndex: ifIdx, Mtu: uint16(mtu), diff --git a/plugins/vpp/ifplugin/vppcalls/nat_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/nat_vppcalls.go index d4d8c7ed24..dff285b304 100644 --- a/plugins/vpp/ifplugin/vppcalls/nat_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/nat_vppcalls.go @@ -16,7 +16,8 @@ package vppcalls import ( "fmt" - "time" + + "github.com/go-errors/errors" "github.com/ligato/vpp-agent/plugins/vpp/binapi/nat" nat2 "github.com/ligato/vpp-agent/plugins/vpp/model/nat" @@ -29,8 +30,12 @@ const ( UDP uint8 = 17 ) -// NoInterface is sw-if-idx which means 'no interface' -const NoInterface uint32 = 0xffffffff +const ( + // NoInterface is sw-if-idx which means 'no interface' + NoInterface uint32 = 0xffffffff + // Maximal length of tag + maxTagLen = 64 +) // StaticMappingContext groups common fields required for static mapping type StaticMappingContext struct { @@ -78,17 +83,13 @@ type LocalLbAddress struct { } // SetNat44Forwarding implements NAT handler. -func (handler *NatVppHandler) SetNat44Forwarding(enableFwd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.Nat44ForwardingEnableDisable{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) SetNat44Forwarding(enableFwd bool) error { req := &nat.Nat44ForwardingEnableDisable{ Enable: boolToUint(enableFwd), } reply := &nat.Nat44ForwardingEnableDisableReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -98,11 +99,7 @@ func (handler *NatVppHandler) SetNat44Forwarding(enableFwd bool) error { } // Calls VPP binary API to set/unset interface as NAT -func (handler *NatVppHandler) handleNat44Interface(ifIdx uint32, isInside, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.Nat44InterfaceAddDelFeature{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) handleNat44Interface(ifIdx uint32, isInside, isAdd bool) error { req := &nat.Nat44InterfaceAddDelFeature{ SwIfIndex: ifIdx, IsInside: boolToUint(isInside), @@ -110,7 +107,7 @@ func (handler *NatVppHandler) handleNat44Interface(ifIdx uint32, isInside, isAdd } reply := &nat.Nat44InterfaceAddDelFeatureReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -120,11 +117,7 @@ func (handler *NatVppHandler) handleNat44Interface(ifIdx uint32, isInside, isAdd } // Calls VPP binary API to set/unset interface as NAT with output feature -func (handler *NatVppHandler) handleNat44InterfaceOutputFeature(ifIdx uint32, isInside, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.Nat44InterfaceAddDelOutputFeature{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) handleNat44InterfaceOutputFeature(ifIdx uint32, isInside, isAdd bool) error { req := &nat.Nat44InterfaceAddDelOutputFeature{ SwIfIndex: ifIdx, IsInside: boolToUint(isInside), @@ -132,7 +125,7 @@ func (handler *NatVppHandler) handleNat44InterfaceOutputFeature(ifIdx uint32, is } reply := &nat.Nat44InterfaceAddDelOutputFeatureReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -142,11 +135,7 @@ func (handler *NatVppHandler) handleNat44InterfaceOutputFeature(ifIdx uint32, is } // Calls VPP binary API to add/remove address pool -func (handler *NatVppHandler) handleNat44AddressPool(first, last []byte, vrf uint32, twiceNat, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.Nat44AddDelAddressRange{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) handleNat44AddressPool(first, last []byte, vrf uint32, twiceNat, isAdd bool) error { req := &nat.Nat44AddDelAddressRange{ FirstIPAddress: first, LastIPAddress: last, @@ -156,7 +145,7 @@ func (handler *NatVppHandler) handleNat44AddressPool(first, last []byte, vrf uin } reply := &nat.Nat44AddDelAddressRangeReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -166,11 +155,7 @@ func (handler *NatVppHandler) handleNat44AddressPool(first, last []byte, vrf uin } // Calls VPP binary API to setup NAT virtual reassembly -func (handler *NatVppHandler) handleNat44VirtualReassembly(timeout, maxReass, maxFrag uint32, dropFrag, isIpv6 bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.NatSetReass{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *NatVppHandler) handleNat44VirtualReassembly(timeout, maxReass, maxFrag uint32, dropFrag, isIpv6 bool) error { req := &nat.NatSetReass{ Timeout: timeout, MaxReass: uint16(maxReass), @@ -180,7 +165,7 @@ func (handler *NatVppHandler) handleNat44VirtualReassembly(timeout, maxReass, ma } reply := &nat.NatSetReassReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -190,10 +175,10 @@ func (handler *NatVppHandler) handleNat44VirtualReassembly(timeout, maxReass, ma } // Calls VPP binary API to add/remove static mapping -func (handler *NatVppHandler) handleNat44StaticMapping(ctx *StaticMappingContext, isAdd, addrOnly bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.Nat44AddDelStaticMapping{}).LogTimeEntry(time.Since(t)) - }(time.Now()) +func (h *NatVppHandler) handleNat44StaticMapping(ctx *StaticMappingContext, isAdd, addrOnly bool) error { + if err := checkTagLength(ctx.Tag); err != nil { + return err + } req := &nat.Nat44AddDelStaticMapping{ Tag: []byte(ctx.Tag), @@ -217,7 +202,7 @@ func (handler *NatVppHandler) handleNat44StaticMapping(ctx *StaticMappingContext } reply := &nat.Nat44AddDelStaticMappingReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -227,10 +212,10 @@ func (handler *NatVppHandler) handleNat44StaticMapping(ctx *StaticMappingContext } // Calls VPP binary API to add/remove static mapping with load balancer -func (handler *NatVppHandler) handleNat44StaticMappingLb(ctx *StaticMappingLbContext, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.Nat44AddDelLbStaticMapping{}).LogTimeEntry(time.Since(t)) - }(time.Now()) +func (h *NatVppHandler) handleNat44StaticMappingLb(ctx *StaticMappingLbContext, isAdd bool) error { + if err := checkTagLength(ctx.Tag); err != nil { + return err + } // Transform local IP/Ports var localAddrPorts []nat.Nat44LbAddrPort @@ -258,7 +243,7 @@ func (handler *NatVppHandler) handleNat44StaticMappingLb(ctx *StaticMappingLbCon } reply := &nat.Nat44AddDelLbStaticMappingReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -268,10 +253,10 @@ func (handler *NatVppHandler) handleNat44StaticMappingLb(ctx *StaticMappingLbCon } // Calls VPP binary API to add/remove identity mapping -func (handler *NatVppHandler) handleNat44IdentityMapping(ctx *IdentityMappingContext, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(nat.Nat44AddDelIdentityMapping{}).LogTimeEntry(time.Since(t)) - }(time.Now()) +func (h *NatVppHandler) handleNat44IdentityMapping(ctx *IdentityMappingContext, isAdd bool) error { + if err := checkTagLength(ctx.Tag); err != nil { + return err + } req := &nat.Nat44AddDelIdentityMapping{ Tag: []byte(ctx.Tag), @@ -296,7 +281,7 @@ func (handler *NatVppHandler) handleNat44IdentityMapping(ctx *IdentityMappingCon } reply := &nat.Nat44AddDelIdentityMappingReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -305,78 +290,87 @@ func (handler *NatVppHandler) handleNat44IdentityMapping(ctx *IdentityMappingCon return nil } +// checkTagLength serves as a validator for static/identity mapping tag length +func checkTagLength(tag string) error { + if len(tag) > maxTagLen { + return errors.Errorf("load-balanced static mapping label '%s' has %d bytes, max allowed is %d", + tag, len(tag), maxTagLen) + } + return nil +} + // EnableNat44Interface implements NAT handler. -func (handler *NatVppHandler) EnableNat44Interface(ifIdx uint32, isInside bool) error { - return handler.handleNat44Interface(ifIdx, isInside, true) +func (h *NatVppHandler) EnableNat44Interface(ifIdx uint32, isInside bool) error { + return h.handleNat44Interface(ifIdx, isInside, true) } // DisableNat44Interface implements NAT handler. -func (handler *NatVppHandler) DisableNat44Interface(ifIdx uint32, isInside bool) error { - return handler.handleNat44Interface(ifIdx, isInside, false) +func (h *NatVppHandler) DisableNat44Interface(ifIdx uint32, isInside bool) error { + return h.handleNat44Interface(ifIdx, isInside, false) } // EnableNat44InterfaceOutput implements NAT handler. -func (handler *NatVppHandler) EnableNat44InterfaceOutput(ifIdx uint32, isInside bool) error { - return handler.handleNat44InterfaceOutputFeature(ifIdx, isInside, true) +func (h *NatVppHandler) EnableNat44InterfaceOutput(ifIdx uint32, isInside bool) error { + return h.handleNat44InterfaceOutputFeature(ifIdx, isInside, true) } // DisableNat44InterfaceOutput implements NAT handler. -func (handler *NatVppHandler) DisableNat44InterfaceOutput(ifIdx uint32, isInside bool) error { - return handler.handleNat44InterfaceOutputFeature(ifIdx, isInside, false) +func (h *NatVppHandler) DisableNat44InterfaceOutput(ifIdx uint32, isInside bool) error { + return h.handleNat44InterfaceOutputFeature(ifIdx, isInside, false) } // AddNat44AddressPool implements NAT handler. -func (handler *NatVppHandler) AddNat44AddressPool(first, last []byte, vrf uint32, twiceNat bool) error { - return handler.handleNat44AddressPool(first, last, vrf, twiceNat, true) +func (h *NatVppHandler) AddNat44AddressPool(first, last []byte, vrf uint32, twiceNat bool) error { + return h.handleNat44AddressPool(first, last, vrf, twiceNat, true) } // DelNat44AddressPool implements NAT handler. -func (handler *NatVppHandler) DelNat44AddressPool(first, last []byte, vrf uint32, twiceNat bool) error { - return handler.handleNat44AddressPool(first, last, vrf, twiceNat, false) +func (h *NatVppHandler) DelNat44AddressPool(first, last []byte, vrf uint32, twiceNat bool) error { + return h.handleNat44AddressPool(first, last, vrf, twiceNat, false) } // SetVirtualReassemblyIPv4 implements NAT handler. -func (handler *NatVppHandler) SetVirtualReassemblyIPv4(vrCfg *nat2.Nat44Global_VirtualReassembly) error { - return handler.handleNat44VirtualReassembly(vrCfg.Timeout, vrCfg.MaxReass, vrCfg.MaxFrag, vrCfg.DropFrag, false) +func (h *NatVppHandler) SetVirtualReassemblyIPv4(vrCfg *nat2.Nat44Global_VirtualReassembly) error { + return h.handleNat44VirtualReassembly(vrCfg.Timeout, vrCfg.MaxReass, vrCfg.MaxFrag, vrCfg.DropFrag, false) } // SetVirtualReassemblyIPv6 implements NAT handler. -func (handler *NatVppHandler) SetVirtualReassemblyIPv6(vrCfg *nat2.Nat44Global_VirtualReassembly) error { - return handler.handleNat44VirtualReassembly(vrCfg.Timeout, vrCfg.MaxReass, vrCfg.MaxFrag, vrCfg.DropFrag, true) +func (h *NatVppHandler) SetVirtualReassemblyIPv6(vrCfg *nat2.Nat44Global_VirtualReassembly) error { + return h.handleNat44VirtualReassembly(vrCfg.Timeout, vrCfg.MaxReass, vrCfg.MaxFrag, vrCfg.DropFrag, true) } // AddNat44IdentityMapping implements NAT handler. -func (handler *NatVppHandler) AddNat44IdentityMapping(ctx *IdentityMappingContext) error { - return handler.handleNat44IdentityMapping(ctx, true) +func (h *NatVppHandler) AddNat44IdentityMapping(ctx *IdentityMappingContext) error { + return h.handleNat44IdentityMapping(ctx, true) } // DelNat44IdentityMapping implements NAT handler. -func (handler *NatVppHandler) DelNat44IdentityMapping(ctx *IdentityMappingContext) error { - return handler.handleNat44IdentityMapping(ctx, false) +func (h *NatVppHandler) DelNat44IdentityMapping(ctx *IdentityMappingContext) error { + return h.handleNat44IdentityMapping(ctx, false) } // AddNat44StaticMapping implements NAT handler. -func (handler *NatVppHandler) AddNat44StaticMapping(ctx *StaticMappingContext) error { +func (h *NatVppHandler) AddNat44StaticMapping(ctx *StaticMappingContext) error { if ctx.AddressOnly { - return handler.handleNat44StaticMapping(ctx, true, true) + return h.handleNat44StaticMapping(ctx, true, true) } - return handler.handleNat44StaticMapping(ctx, true, false) + return h.handleNat44StaticMapping(ctx, true, false) } // DelNat44StaticMapping implements NAT handler. -func (handler *NatVppHandler) DelNat44StaticMapping(ctx *StaticMappingContext) error { +func (h *NatVppHandler) DelNat44StaticMapping(ctx *StaticMappingContext) error { if ctx.AddressOnly { - return handler.handleNat44StaticMapping(ctx, false, true) + return h.handleNat44StaticMapping(ctx, false, true) } - return handler.handleNat44StaticMapping(ctx, false, false) + return h.handleNat44StaticMapping(ctx, false, false) } // AddNat44StaticMappingLb implements NAT handler. -func (handler *NatVppHandler) AddNat44StaticMappingLb(ctx *StaticMappingLbContext) error { - return handler.handleNat44StaticMappingLb(ctx, true) +func (h *NatVppHandler) AddNat44StaticMappingLb(ctx *StaticMappingLbContext) error { + return h.handleNat44StaticMappingLb(ctx, true) } // DelNat44StaticMappingLb implements NAT handler. -func (handler *NatVppHandler) DelNat44StaticMappingLb(ctx *StaticMappingLbContext) error { - return handler.handleNat44StaticMappingLb(ctx, false) +func (h *NatVppHandler) DelNat44StaticMappingLb(ctx *StaticMappingLbContext) error { + return h.handleNat44StaticMappingLb(ctx, false) } diff --git a/plugins/vpp/ifplugin/vppcalls/nat_vppcalls_test.go b/plugins/vpp/ifplugin/vppcalls/nat_vppcalls_test.go index 57f6d97244..5bbd239308 100644 --- a/plugins/vpp/ifplugin/vppcalls/nat_vppcalls_test.go +++ b/plugins/vpp/ifplugin/vppcalls/nat_vppcalls_test.go @@ -783,6 +783,69 @@ func TestDelNat44IdentityMapping(t *testing.T) { Expect(msg.Protocol).To(BeEquivalentTo(16)) } +func TestNat44MappingLongTag(t *testing.T) { + ctx, natHandler, _ := natTestSetup(t) + defer ctx.TeardownTestCtx() + + normalTag := "normalTag" + longTag := "some-weird-tag-which-is-much-longer-than-allowed-sixty-four-bytes" + + localIP1 := net.ParseIP("10.0.0.1").To4() + localIP2 := net.ParseIP("20.0.0.1").To4() + externalIP := net.ParseIP("10.0.0.2").To4() + + // No other data are required + smCtx := &vppcalls.StaticMappingContext{ + Tag: normalTag, + AddressOnly: false, + LocalIP: localIP1, + ExternalIP: externalIP, + } + smLbCtx := &vppcalls.StaticMappingLbContext{ + Tag: normalTag, + LocalIPs: localIPs(localIP1, localIP2), + ExternalIP: externalIP, + ExternalPort: 8080, + Protocol: 16, + TwiceNat: true, + } + imCtx := &vppcalls.IdentityMappingContext{ + Tag: normalTag, + IPAddress: localIP1, + Protocol: 16, + Vrf: 1, + IfIdx: 1, + } + + // 1. test + ctx.MockVpp.MockReply(&nat.Nat44AddDelStaticMappingReply{}) + ctx.MockVpp.MockReply(&nat.Nat44AddDelLbStaticMappingReply{}) + ctx.MockVpp.MockReply(&nat.Nat44AddDelIdentityMappingReply{}) + // 2. test + ctx.MockVpp.MockReply(&nat.Nat44AddDelStaticMappingReply{}) + ctx.MockVpp.MockReply(&nat.Nat44AddDelLbStaticMappingReply{}) + ctx.MockVpp.MockReply(&nat.Nat44AddDelIdentityMappingReply{}) + + // Successful scenario (to ensure there is no other error) + err := natHandler.AddNat44StaticMapping(smCtx) + Expect(err).To(BeNil()) + err = natHandler.AddNat44StaticMappingLb(smLbCtx) + Expect(err).To(BeNil()) + err = natHandler.AddNat44IdentityMapping(imCtx) + Expect(err).To(BeNil()) + + // Replace tags and test again + smCtx.Tag = longTag + smLbCtx.Tag = longTag + imCtx.Tag = longTag + err = natHandler.AddNat44StaticMapping(smCtx) + Expect(err).ToNot(BeNil()) + err = natHandler.AddNat44StaticMappingLb(smLbCtx) + Expect(err).ToNot(BeNil()) + err = natHandler.AddNat44IdentityMapping(imCtx) + Expect(err).ToNot(BeNil()) +} + func localIPs(addr1, addr2 []byte) []*vppcalls.LocalLbAddress { return []*vppcalls.LocalLbAddress{ { diff --git a/plugins/vpp/ifplugin/vppcalls/rx_mode_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/rx_mode_vppcalls.go index 20e12fb1b6..385669c4fc 100644 --- a/plugins/vpp/ifplugin/vppcalls/rx_mode_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/rx_mode_vppcalls.go @@ -16,7 +16,6 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" intf "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" @@ -24,10 +23,6 @@ import ( // SetRxMode implements interface handler. func (h *IfVppHandler) SetRxMode(ifIdx uint32, rxModeSettings *intf.Interfaces_Interface_RxModeSettings) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceSetRxMode{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &interfaces.SwInterfaceSetRxMode{ SwIfIndex: ifIdx, Mode: uint8(rxModeSettings.RxMode), diff --git a/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls.go index d6fa42a49b..2d74b030c9 100644 --- a/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls.go @@ -16,42 +16,26 @@ package vppcalls import ( "fmt" - "strconv" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/vpe" intf "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" ) // SetRxPlacement implements interface handler. -func (h *IfVppHandler) SetRxPlacement(vppInternalName string, rxPlacement *intf.Interfaces_Interface_RxPlacementSettings) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceSetRxMode{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - queue := strconv.Itoa(int(rxPlacement.Queue)) - worker := strconv.Itoa(int(rxPlacement.Worker)) - - command := "set interface rx-placement " + vppInternalName + " queue " + queue + " worker " + worker - - h.log.Warnf("Setting rx-placement commnad %s", command) - - // TODO: binary api call for rx-placement is not available - req := &vpe.CliInband{ - Length: uint32(len(command)), - Cmd: []byte(command), +func (h *IfVppHandler) SetRxPlacement(ifIdx uint32, rxPlacement *intf.Interfaces_Interface_RxPlacementSettings) error { + req := &interfaces.SwInterfaceSetRxPlacement{ + SwIfIndex: ifIdx, + QueueID: rxPlacement.Queue, + WorkerID: rxPlacement.Worker, + IsMain: boolToUint(rxPlacement.IsMain), } - reply := &vpe.CliInbandReply{} + reply := &interfaces.SwInterfaceSetRxPlacementReply{} if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) } - if reply.Length > 0 { - return fmt.Errorf("rx-placement setup replied with %s", string(reply.Reply)) - } return nil } diff --git a/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls_test.go b/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls_test.go index 9b53cc5ce2..2f41df4458 100644 --- a/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls_test.go +++ b/plugins/vpp/ifplugin/vppcalls/rx_placement_vppcalls_test.go @@ -17,7 +17,8 @@ package vppcalls_test import ( "testing" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/vpe" + ifApi "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" + "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" . "github.com/onsi/gomega" ) @@ -26,48 +27,31 @@ func TestSetRxPlacement(t *testing.T) { ctx, ifHandler := ifTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&vpe.CliInbandReply{}) + ctx.MockVpp.MockReply(&ifApi.SwInterfaceSetRxPlacementReply{}) - err := ifHandler.SetRxPlacement("if-internal", &interfaces.Interfaces_Interface_RxPlacementSettings{ + err := ifHandler.SetRxPlacement(1, &interfaces.Interfaces_Interface_RxPlacementSettings{ Queue: 1, Worker: 2, + IsMain: true, }) - expMsg := "set interface rx-placement if-internal queue 1 worker 2" - expMsgLen := len(expMsg) - Expect(err).To(BeNil()) - vppMsg, ok := ctx.MockChannel.Msg.(*vpe.CliInband) + vppMsg, ok := ctx.MockChannel.Msg.(*ifApi.SwInterfaceSetRxPlacement) Expect(ok).To(BeTrue()) - Expect(vppMsg.Cmd).To(BeEquivalentTo([]byte(expMsg))) - Expect(vppMsg.Length).To(BeEquivalentTo(uint32(expMsgLen))) + Expect(vppMsg.QueueID).To(BeEquivalentTo(1)) + Expect(vppMsg.WorkerID).To(BeEquivalentTo(uint32(2))) + Expect(vppMsg.IsMain).To(BeEquivalentTo(uint32(1))) } func TestSetRxPlacementRetval(t *testing.T) { ctx, ifHandler := ifTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&vpe.CliInbandReply{ + ctx.MockVpp.MockReply(&ifApi.SwInterfaceSetRxPlacementReply{ Retval: 1, }) - err := ifHandler.SetRxPlacement("if-internal", &interfaces.Interfaces_Interface_RxPlacementSettings{ - Queue: 1, - Worker: 2, - }) - - Expect(err).ToNot(BeNil()) -} - -func TestSetRxPlacementReply(t *testing.T) { - ctx, ifHandler := ifTestSetup(t) - defer ctx.TeardownTestCtx() - - ctx.MockVpp.MockReply(&vpe.CliInbandReply{ - Reply: []byte("dummy-reply"), - }) - - err := ifHandler.SetRxPlacement("if-internal", &interfaces.Interfaces_Interface_RxPlacementSettings{ + err := ifHandler.SetRxPlacement(1, &interfaces.Interfaces_Interface_RxPlacementSettings{ Queue: 1, Worker: 2, }) @@ -79,9 +63,9 @@ func TestSetRxPlacementError(t *testing.T) { ctx, ifHandler := ifTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&vpe.CliInband{}) + ctx.MockVpp.MockReply(&ifApi.SwInterfaceSetRxPlacement{}) - err := ifHandler.SetRxPlacement("if-internal", &interfaces.Interfaces_Interface_RxPlacementSettings{ + err := ifHandler.SetRxPlacement(1, &interfaces.Interfaces_Interface_RxPlacementSettings{ Queue: 1, Worker: 2, }) diff --git a/plugins/vpp/ifplugin/vppcalls/stn_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/stn_vppcalls.go index 20769557ec..4c2410326f 100644 --- a/plugins/vpp/ifplugin/vppcalls/stn_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/stn_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/vpp-agent/plugins/vpp/binapi/stn" @@ -29,11 +28,7 @@ type StnRule struct { IfaceIdx uint32 } -func (handler *StnVppHandler) addDelStnRule(ifIdx uint32, addr *net.IP, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(stn.StnAddDelRule{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *StnVppHandler) addDelStnRule(ifIdx uint32, addr *net.IP, isAdd bool) error { // prepare the message req := &stn.StnAddDelRule{ SwIfIndex: ifIdx, @@ -53,7 +48,7 @@ func (handler *StnVppHandler) addDelStnRule(ifIdx uint32, addr *net.IP, isAdd bo } reply := &stn.StnAddDelRuleReply{} - if err = handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err = h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -64,12 +59,12 @@ func (handler *StnVppHandler) addDelStnRule(ifIdx uint32, addr *net.IP, isAdd bo } // AddStnRule implements STN handler. -func (handler *StnVppHandler) AddStnRule(ifIdx uint32, addr *net.IP) error { - return handler.addDelStnRule(ifIdx, addr, true) +func (h *StnVppHandler) AddStnRule(ifIdx uint32, addr *net.IP) error { + return h.addDelStnRule(ifIdx, addr, true) } // DelStnRule implements STN handler. -func (handler *StnVppHandler) DelStnRule(ifIdx uint32, addr *net.IP) error { - return handler.addDelStnRule(ifIdx, addr, false) +func (h *StnVppHandler) DelStnRule(ifIdx uint32, addr *net.IP) error { + return h.addDelStnRule(ifIdx, addr, false) } diff --git a/plugins/vpp/ifplugin/vppcalls/stn_vppcalls_test.go b/plugins/vpp/ifplugin/vppcalls/stn_vppcalls_test.go index e493ff7247..2816f82035 100644 --- a/plugins/vpp/ifplugin/vppcalls/stn_vppcalls_test.go +++ b/plugins/vpp/ifplugin/vppcalls/stn_vppcalls_test.go @@ -119,6 +119,6 @@ func TestDelStnRule(t *testing.T) { func stnTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.StnVppAPI) { ctx := vppcallmock.SetupTestCtx(t) ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "stn-if-idx", nil)) - stnHandler := vppcalls.NewStnVppHandler(ctx.MockChannel, ifIndexes, logrus.DefaultLogger(), nil) + stnHandler := vppcalls.NewStnVppHandler(ctx.MockChannel, ifIndexes, logrus.DefaultLogger()) return ctx, stnHandler } diff --git a/plugins/vpp/ifplugin/vppcalls/tap_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/tap_vppcalls.go index 256be811bf..1b09944593 100644 --- a/plugins/vpp/ifplugin/vppcalls/tap_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/tap_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( "errors" "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/tap" "github.com/ligato/vpp-agent/plugins/vpp/binapi/tapv2" @@ -26,10 +25,6 @@ import ( // AddTapInterface implements interface handler. func (h *IfVppHandler) AddTapInterface(ifName string, tapIf *interfaces.Interfaces_Interface_Tap) (swIfIdx uint32, err error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(tap.TapConnect{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - if tapIf == nil || tapIf.HostIfName == "" { return 0, errors.New("host interface name was not provided for the TAP interface") } @@ -83,10 +78,6 @@ func (h *IfVppHandler) AddTapInterface(ifName string, tapIf *interfaces.Interfac // DeleteTapInterface implements interface handler. func (h *IfVppHandler) DeleteTapInterface(ifName string, idx uint32, version uint32) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(tap.TapDelete{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - var ( err error retval int32 diff --git a/plugins/vpp/ifplugin/vppcalls/vrf_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/vrf_vppcalls.go index 71a2b5edff..d5fc4b6d7f 100644 --- a/plugins/vpp/ifplugin/vppcalls/vrf_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/vrf_vppcalls.go @@ -17,8 +17,6 @@ package vppcalls import ( "fmt" - "time" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" ) @@ -86,10 +84,6 @@ func (h *IfVppHandler) createVrfIfNeeded(vrfID uint32, isIPv6 bool) error { // Interface is set to VRF table. Table IP version has to be defined. func (h *IfVppHandler) setInterfaceVrf(ifIdx, vrfID uint32, isIPv6 bool) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceSetTable{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - if err := h.createVrfIfNeeded(vrfID, isIPv6); err != nil { return fmt.Errorf("creating VRF failed: %v", err) } @@ -107,17 +101,13 @@ func (h *IfVppHandler) setInterfaceVrf(ifIdx, vrfID uint32, isIPv6 bool) error { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) } - h.log.Debugf("Interface %s set to VRF %d", ifIdx, vrfID) + h.log.Debugf("Interface %d set to VRF %d", ifIdx, vrfID) return nil } // Returns VRF ID for provided interface. func (h *IfVppHandler) getInterfaceVrf(ifIdx uint32, isIPv6 bool) (vrfID uint32, err error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(interfaces.SwInterfaceGetTable{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &interfaces.SwInterfaceGetTable{ SwIfIndex: ifIdx, IsIPv6: boolToUint(isIPv6), @@ -135,10 +125,6 @@ func (h *IfVppHandler) getInterfaceVrf(ifIdx uint32, isIPv6 bool) (vrfID uint32, // Returns all IPv4 VRF tables func (h *IfVppHandler) dumpVrfTables() (map[uint32][]*ip.IPFibDetails, error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(ip.IPFibDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - fibs := map[uint32][]*ip.IPFibDetails{} reqCtx := h.callsChannel.SendMultiRequest(&ip.IPFibDump{}) for { @@ -160,10 +146,6 @@ func (h *IfVppHandler) dumpVrfTables() (map[uint32][]*ip.IPFibDetails, error) { // Returns all IPv6 VRF tables func (h *IfVppHandler) dumpVrfTablesIPv6() (map[uint32][]*ip.IP6FibDetails, error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(ip.IP6FibDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - fibs := map[uint32][]*ip.IP6FibDetails{} reqCtx := h.callsChannel.SendMultiRequest(&ip.IP6FibDump{}) for { @@ -185,10 +167,6 @@ func (h *IfVppHandler) dumpVrfTablesIPv6() (map[uint32][]*ip.IP6FibDetails, erro // Creates new VRF table with provided ID and for desired IP version func (h *IfVppHandler) vppAddIPTable(vrfID uint32, isIPv6 bool) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(ip.IPTableAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &ip.IPTableAddDel{ TableID: vrfID, IsIPv6: boolToUint(isIPv6), diff --git a/plugins/vpp/ifplugin/vppcalls/vxlan_vppcalls.go b/plugins/vpp/ifplugin/vppcalls/vxlan_vppcalls.go index 6fe674a826..7b07beb06d 100644 --- a/plugins/vpp/ifplugin/vppcalls/vxlan_vppcalls.go +++ b/plugins/vpp/ifplugin/vppcalls/vxlan_vppcalls.go @@ -17,17 +17,12 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/vxlan" intf "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" ) func (h *IfVppHandler) addDelVxLanTunnel(vxLan *intf.Interfaces_Interface_Vxlan, vrf, multicastIf uint32, isAdd bool) (swIdx uint32, err error) { - defer func(t time.Time) { - h.stopwatch.TimeLog(vxlan.VxlanAddDelTunnel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - // this is temporary fix to solve creation of VRF table for VxLAN if err := h.CreateVrf(vrf); err != nil { return 0, err diff --git a/plugins/vpp/ipsecplugin/data_resync.go b/plugins/vpp/ipsecplugin/data_resync.go index eb9e459b62..8527852ed7 100644 --- a/plugins/vpp/ipsecplugin/data_resync.go +++ b/plugins/vpp/ipsecplugin/data_resync.go @@ -14,43 +14,35 @@ package ipsecplugin -import "github.com/ligato/vpp-agent/plugins/vpp/model/ipsec" +import ( + "github.com/go-errors/errors" + "github.com/ligato/vpp-agent/plugins/vpp/model/ipsec" +) // Resync writes missing IPSec configs to the VPP and removes obsolete ones. -func (plugin *IPSecConfigurator) Resync(spds []*ipsec.SecurityPolicyDatabases_SPD, sas []*ipsec.SecurityAssociations_SA, tunnels []*ipsec.TunnelInterfaces_Tunnel) error { - plugin.log.Debug("RESYNC IPSec begin.") - - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - - plugin.clearMapping() +func (c *IPSecConfigurator) Resync(spds []*ipsec.SecurityPolicyDatabases_SPD, sas []*ipsec.SecurityAssociations_SA, tunnels []*ipsec.TunnelInterfaces_Tunnel) error { + c.clearMapping() // TODO: dump existing configuration from VPP for _, sa := range sas { - if err := plugin.ConfigureSA(sa); err != nil { - plugin.log.Error(err) - continue + if err := c.ConfigureSA(sa); err != nil { + return errors.Errorf("IPSec resync error: failed to configure SA %v: %v", sa.Name, err) } } for _, spd := range spds { - if err := plugin.ConfigureSPD(spd); err != nil { - plugin.log.Error(err) - continue + if err := c.ConfigureSPD(spd); err != nil { + return errors.Errorf("IPSec resync error: failed to configure SPD %v: %v", spd.Name, err) } } for _, tunnel := range tunnels { - if err := plugin.ConfigureTunnel(tunnel); err != nil { - plugin.log.Error(err) - continue + if err := c.ConfigureTunnel(tunnel); err != nil { + return errors.Errorf("IPSec resync error: failed to configure tunnel interface %v: %v", tunnel.Name, err) } } - plugin.log.Debug("RESYNC IPSec end.") + c.log.Debug("IPSec resync done") return nil } diff --git a/plugins/vpp/ipsecplugin/ipsec_config.go b/plugins/vpp/ipsecplugin/ipsec_config.go index 20f073c546..b75027296d 100644 --- a/plugins/vpp/ipsecplugin/ipsec_config.go +++ b/plugins/vpp/ipsecplugin/ipsec_config.go @@ -12,15 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/ipsec --gogo_out=../model/ipsec ../model/ipsec/ipsec.proto - // Package ipsecplugin implements the IPSec plugin that handles management of IPSec for VPP. package ipsecplugin import ( govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp" @@ -65,392 +63,381 @@ type IPSecConfigurator struct { // VPP API handlers ifHandler iface_vppcalls.IfVppAPI ipSecHandler vppcalls.IPSecVppAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init members (channels...) and start go routines -func (plugin *IPSecConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndexRW, - enableStopwatch bool) (err error) { +func (c *IPSecConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndexRW) (err error) { // Logger - plugin.log = logger.NewLogger("-ipsec-plugin") - plugin.log.Debug("Initializing IPSec configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("IPSec-configurator", plugin.log) - } + c.log = logger.NewLogger("ipsec-plugin") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.spdIndexes = ipsecidx.NewSPDIndex(nametoidx.NewNameToIdx(plugin.log, "ipsec_spd_indexes", nil)) - plugin.cachedSpdIndexes = ipsecidx.NewSPDIndex(nametoidx.NewNameToIdx(plugin.log, "ipsec_cached_spd_indexes", nil)) - plugin.saIndexes = nametoidx.NewNameToIdx(plugin.log, "ipsec_sa_indexes", ifaceidx.IndexMetadata) - plugin.spdIndexSeq = 1 - plugin.saIndexSeq = 1 + c.ifIndexes = swIfIndexes + c.spdIndexes = ipsecidx.NewSPDIndex(nametoidx.NewNameToIdx(c.log, "ipsec_spd_indexes", nil)) + c.cachedSpdIndexes = ipsecidx.NewSPDIndex(nametoidx.NewNameToIdx(c.log, "ipsec_cached_spd_indexes", nil)) + c.saIndexes = nametoidx.NewNameToIdx(c.log, "ipsec_sa_indexes", ifaceidx.IndexMetadata) + c.spdIndexSeq = 1 + c.saIndexSeq = 1 // VPP channel - plugin.vppCh, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppCh, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handlers - plugin.ifHandler = iface_vppcalls.NewIfVppHandler(plugin.vppCh, plugin.log, plugin.stopwatch) - plugin.ipSecHandler = vppcalls.NewIPsecVppHandler(plugin.vppCh, plugin.ifIndexes, plugin.spdIndexes, plugin.log, plugin.stopwatch) + c.ifHandler = iface_vppcalls.NewIfVppHandler(c.vppCh, c.log) + c.ipSecHandler = vppcalls.NewIPsecVppHandler(c.vppCh, c.ifIndexes, c.spdIndexes, c.log) + + c.log.Debug("IPSec configurator initialized") return nil } // Close GOVPP channel -func (plugin *IPSecConfigurator) Close() error { - return safeclose.Close(plugin.vppCh) +func (c *IPSecConfigurator) Close() error { + if err := safeclose.Close(c.vppCh); err != nil { + c.LogError(errors.Errorf("failed to safeclose IPSec configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *IPSecConfigurator) clearMapping() { - plugin.spdIndexes.Clear() - plugin.cachedSpdIndexes.Clear() - plugin.saIndexes.Clear() +func (c *IPSecConfigurator) clearMapping() { + c.spdIndexes.Clear() + c.cachedSpdIndexes.Clear() + c.saIndexes.Clear() + + c.log.Debugf("IPSec configurator mapping cleared") } // GetSaIndexes returns security association indexes -func (plugin *IPSecConfigurator) GetSaIndexes() idxvpp.NameToIdxRW { - return plugin.saIndexes +func (c *IPSecConfigurator) GetSaIndexes() idxvpp.NameToIdxRW { + return c.saIndexes } // GetSpdIndexes returns security policy database indexes -func (plugin *IPSecConfigurator) GetSpdIndexes() ipsecidx.SPDIndex { - return plugin.spdIndexes +func (c *IPSecConfigurator) GetSpdIndexes() ipsecidx.SPDIndex { + return c.spdIndexes } // ConfigureSPD configures Security Policy Database in VPP -func (plugin *IPSecConfigurator) ConfigureSPD(spd *ipsec.SecurityPolicyDatabases_SPD) error { - plugin.log.Debugf("Configuring SPD %v", spd.Name) - - spdID := plugin.spdIndexSeq - plugin.spdIndexSeq++ +func (c *IPSecConfigurator) ConfigureSPD(spd *ipsec.SecurityPolicyDatabases_SPD) error { + spdID := c.spdIndexSeq + c.spdIndexSeq++ for _, entry := range spd.PolicyEntries { if entry.Sa != "" { - if _, _, exists := plugin.saIndexes.LookupIdx(entry.Sa); !exists { - plugin.log.Warnf("SA %q for SPD %q not found, caching SPD configuration", entry.Sa, spd.Name) - plugin.cachedSpdIndexes.RegisterName(spd.Name, spdID, spd) + if _, _, exists := c.saIndexes.LookupIdx(entry.Sa); !exists { + c.cachedSpdIndexes.RegisterName(spd.Name, spdID, spd) + c.log.Debugf("SA %q for SPD %q not found, SPD configuration cached", entry.Sa, spd.Name) return nil } } } - return plugin.configureSPD(spdID, spd) -} + if err := c.configureSPD(spdID, spd); err != nil { + return err + } -func (plugin *IPSecConfigurator) configureSPD(spdID uint32, spd *ipsec.SecurityPolicyDatabases_SPD) error { - plugin.log.Debugf("configuring SPD %v (%d)", spd.Name, spdID) + c.log.Debugf("SPD %s configured", spd.Name) - if err := plugin.ipSecHandler.AddSPD(spdID); err != nil { - return err + return nil +} + +func (c *IPSecConfigurator) configureSPD(spdID uint32, spd *ipsec.SecurityPolicyDatabases_SPD) error { + if err := c.ipSecHandler.AddSPD(spdID); err != nil { + return errors.Errorf("failed to add SPD with ID %d: %v", spdID, err) } - plugin.spdIndexes.RegisterName(spd.Name, spdID, spd) - plugin.log.Infof("Registered SPD %v (%d)", spd.Name, spdID) + c.spdIndexes.RegisterName(spd.Name, spdID, spd) + c.log.Debugf("Registered SPD %s (%d)", spd.Name, spdID) for _, iface := range spd.Interfaces { - plugin.log.Debugf("Assigning SPD to interface %v", iface) - - swIfIdx, _, exists := plugin.ifIndexes.LookupIdx(iface.Name) + swIfIdx, _, exists := c.ifIndexes.LookupIdx(iface.Name) if !exists { - plugin.log.Infof("Interface %q for SPD %q not found, caching assignment of interface to SPD", iface.Name, spd.Name) - plugin.cacheSPDInterfaceAssignment(spdID, iface.Name) + c.cacheSPDInterfaceAssignment(spdID, iface.Name) + c.log.Debugf("Interface %q for SPD %q not found, assignment of interface to SPD cached", iface.Name, spd.Name) continue } - if err := plugin.ipSecHandler.InterfaceAddSPD(spdID, swIfIdx); err != nil { - plugin.log.Errorf("assigning interface to SPD failed: %v", err) - continue + if err := c.ipSecHandler.InterfaceAddSPD(spdID, swIfIdx); err != nil { + return errors.Errorf("failed to assign interface %d to SPD %d: %v", swIfIdx, spdID, err) } - - plugin.log.Infof("Assigned SPD %q to interface %q", spd.Name, iface.Name) } for _, entry := range spd.PolicyEntries { - plugin.log.Infof("Adding SPD policy entry %v", entry) - var saID uint32 if entry.Sa != "" { var exists bool - if saID, _, exists = plugin.saIndexes.LookupIdx(entry.Sa); !exists { - plugin.log.Warnf("SA %q for SPD %q not found, skipping SPD policy entry configuration", entry.Sa, spd.Name) + if saID, _, exists = c.saIndexes.LookupIdx(entry.Sa); !exists { + c.log.Debugf("SA %q for SPD %q not found, skipping SPD policy entry configuration", entry.Sa, spd.Name) continue } } - if err := plugin.ipSecHandler.AddSPDEntry(spdID, saID, entry); err != nil { - plugin.log.Errorf("adding SPD policy entry failed: %v", err) - continue + if err := c.ipSecHandler.AddSPDEntry(spdID, saID, entry); err != nil { + return errors.Errorf("failed to add SPD %d entry: %v", saID, err) } - - plugin.log.Infof("Added SPD policy entry") } - plugin.log.Infof("Configured SPD %v", spd.Name) + c.log.Infof("Configured SPD %v", spd.Name) return nil } // ModifySPD modifies Security Policy Database in VPP -func (plugin *IPSecConfigurator) ModifySPD(oldSpd *ipsec.SecurityPolicyDatabases_SPD, newSpd *ipsec.SecurityPolicyDatabases_SPD) error { - plugin.log.Debugf("Modifying SPD %v", oldSpd.Name) - - if err := plugin.DeleteSPD(oldSpd); err != nil { - plugin.log.Error("deleting old SPD failed:", err) - return err +func (c *IPSecConfigurator) ModifySPD(oldSpd, newSpd *ipsec.SecurityPolicyDatabases_SPD) error { + if err := c.DeleteSPD(oldSpd); err != nil { + return errors.Errorf("failed to modify SPD %v, error while removing old entry: %v", oldSpd.Name, err) } - if err := plugin.ConfigureSPD(newSpd); err != nil { - plugin.log.Error("configuring new SPD failed:", err) - return err + if err := c.ConfigureSPD(newSpd); err != nil { + return errors.Errorf("failed to modify SPD %v, error while adding new entry: %v", oldSpd.Name, err) } + c.log.Debugf("SPD %s modified", oldSpd.Name) + return nil } // DeleteSPD deletes Security Policy Database in VPP -func (plugin *IPSecConfigurator) DeleteSPD(oldSpd *ipsec.SecurityPolicyDatabases_SPD) error { - plugin.log.Debugf("Deleting SPD %v", oldSpd.Name) - - if spdID, _, found := plugin.cachedSpdIndexes.LookupIdx(oldSpd.Name); found { - plugin.log.Debugf("removing cached SPD %v", spdID) - plugin.cachedSpdIndexes.UnregisterName(oldSpd.Name) +func (c *IPSecConfigurator) DeleteSPD(oldSpd *ipsec.SecurityPolicyDatabases_SPD) error { + if spdID, _, found := c.cachedSpdIndexes.LookupIdx(oldSpd.Name); found { + c.cachedSpdIndexes.UnregisterName(oldSpd.Name) + c.log.Debugf("Cached SPD %d removed", spdID) return nil } - spdID, _, exists := plugin.spdIndexes.LookupIdx(oldSpd.Name) + spdID, _, exists := c.spdIndexes.LookupIdx(oldSpd.Name) if !exists { - plugin.log.Warnf("SPD %q not found", oldSpd.Name) - return nil + return errors.Errorf("cannot remove SPD %s, entry not found in the mapping", oldSpd.Name) } - if err := plugin.ipSecHandler.DelSPD(spdID); err != nil { - return err + if err := c.ipSecHandler.DelSPD(spdID); err != nil { + return errors.Errorf("failed to remove SPD %d: %v", spdID, err) } // remove cache entries related to the SPD - for i, entry := range plugin.spdIfCache { + for i, entry := range c.spdIfCache { if entry.spdID == spdID { - plugin.log.Debugf("Removing cache entry for assignment of SPD %q to interface %q", entry.spdID, entry.ifaceName) - plugin.spdIfCache = append(plugin.spdIfCache[:i], plugin.spdIfCache[i+1:]...) + c.spdIfCache = append(c.spdIfCache[:i], c.spdIfCache[i+1:]...) + c.log.Debugf("Removed cache entry for assignment of SPD %q to interface %q", entry.spdID, entry.ifaceName) } } - plugin.spdIndexes.UnregisterName(oldSpd.Name) - plugin.log.Infof("Deleted SPD %v", oldSpd.Name) + c.spdIndexes.UnregisterName(oldSpd.Name) + c.log.Debugf("SPD %s unregistered", oldSpd.Name) + + c.log.Infof("Deleted SPD %v", oldSpd.Name) return nil } // ConfigureSA configures Security Association in VPP -func (plugin *IPSecConfigurator) ConfigureSA(sa *ipsec.SecurityAssociations_SA) error { - plugin.log.Debugf("Configuring SA %v", sa.Name) - - saID := plugin.saIndexSeq - plugin.saIndexSeq++ +func (c *IPSecConfigurator) ConfigureSA(sa *ipsec.SecurityAssociations_SA) error { + saID := c.saIndexSeq + c.saIndexSeq++ - if err := plugin.ipSecHandler.AddSAEntry(saID, sa); err != nil { - return err + if err := c.ipSecHandler.AddSAEntry(saID, sa); err != nil { + return errors.Errorf("failed to add sA %d: %v", saID, err) } - plugin.saIndexes.RegisterName(sa.Name, saID, nil) - plugin.log.Infof("Registered SA %v (%d)", sa.Name, saID) + c.saIndexes.RegisterName(sa.Name, saID, nil) + c.log.Debugf("Registered SA %v (%d)", sa.Name, saID) - for _, cached := range plugin.cachedSpdIndexes.LookupBySA(sa.Name) { + for _, cached := range c.cachedSpdIndexes.LookupBySA(sa.Name) { for _, entry := range cached.SPD.PolicyEntries { if entry.Sa != "" { - if _, _, exists := plugin.saIndexes.LookupIdx(entry.Sa); !exists { - plugin.log.Warnf("SA %q for SPD %q not found, keeping SPD in cache", entry.Sa, cached.SPD.Name) + if _, _, exists := c.saIndexes.LookupIdx(entry.Sa); !exists { + c.log.Debugf("SA %q for SPD %q not found, keeping SPD in cache", entry.Sa, cached.SPD.Name) return nil } } } - if err := plugin.configureSPD(cached.SpdID, cached.SPD); err != nil { - plugin.log.Errorf("configuring cached SPD failed: %v", err) - } else { - plugin.cachedSpdIndexes.UnregisterName(cached.SPD.Name) + if err := c.configureSPD(cached.SpdID, cached.SPD); err != nil { + return errors.Errorf("failed to configure SPD %s", cached.SPD.Name) } + c.cachedSpdIndexes.UnregisterName(cached.SPD.Name) + c.log.Debugf("SPD %s unregistered from cache", cached.SPD.Name) } + c.log.Infof("SA %v configured", sa.Name) + return nil } // ModifySA modifies Security Association in VPP -func (plugin *IPSecConfigurator) ModifySA(oldSa *ipsec.SecurityAssociations_SA, newSa *ipsec.SecurityAssociations_SA) error { - plugin.log.Debugf("Modifying SA %v", oldSa.Name) - +func (c *IPSecConfigurator) ModifySA(oldSa *ipsec.SecurityAssociations_SA, newSa *ipsec.SecurityAssociations_SA) error { // TODO: check if only keys change and use IpsecSaSetKey vpp call - if err := plugin.DeleteSA(oldSa); err != nil { - plugin.log.Error("deleting old SPD failed:", err) - return err + if err := c.DeleteSA(oldSa); err != nil { + return errors.Errorf("failed to delete SA %s: %v", oldSa.Name, err) } - if err := plugin.ConfigureSA(newSa); err != nil { - plugin.log.Error("configuring new SPD failed:", err) - return err + if err := c.ConfigureSA(newSa); err != nil { + return errors.Errorf("failed to configure SA %s: %v", newSa.Name, err) } + c.log.Debugf("SA %s modified", oldSa.Name) + return nil } // DeleteSA deletes Security Association in VPP -func (plugin *IPSecConfigurator) DeleteSA(oldSa *ipsec.SecurityAssociations_SA) error { - plugin.log.Debugf("Deleting SA %v", oldSa.Name) - - saID, _, exists := plugin.saIndexes.LookupIdx(oldSa.Name) +func (c *IPSecConfigurator) DeleteSA(oldSa *ipsec.SecurityAssociations_SA) error { + saID, _, exists := c.saIndexes.LookupIdx(oldSa.Name) if !exists { - plugin.log.Warnf("SA %q not found", oldSa.Name) - return nil + return errors.Errorf("cannot delete SA %s, not found in the mapping", oldSa.Name) } - for _, entry := range plugin.spdIndexes.LookupBySA(oldSa.Name) { - if err := plugin.DeleteSPD(entry.SPD); err != nil { - plugin.log.Errorf("deleting SPD to be cached failed: %v", err) - continue + for _, entry := range c.spdIndexes.LookupBySA(oldSa.Name) { + if err := c.DeleteSPD(entry.SPD); err != nil { + return errors.Errorf("attempt to remove SPD %v in order to cache it failed: %v", entry.SPD.Name, err) } - plugin.cachedSpdIndexes.RegisterName(entry.SPD.Name, entry.SpdID, entry.SPD) - plugin.log.Warnf("caching SPD %v due removed SA %v", entry.SPD.Name, oldSa.Name) + c.cachedSpdIndexes.RegisterName(entry.SPD.Name, entry.SpdID, entry.SPD) + c.log.Debugf("caching SPD %s due removed SA %s", entry.SPD.Name, oldSa.Name) } - if err := plugin.ipSecHandler.DelSAEntry(saID, oldSa); err != nil { - return err + if err := c.ipSecHandler.DelSAEntry(saID, oldSa); err != nil { + return errors.Errorf("failed to remove SA %d: %v", saID, err) } - plugin.saIndexes.UnregisterName(oldSa.Name) - plugin.log.Infof("Deleted SA %v", oldSa.Name) + c.saIndexes.UnregisterName(oldSa.Name) + c.log.Debugf("SA %s unregistered", oldSa.Name) + + c.log.Infof("SA %s deleted", oldSa.Name) return nil } // ConfigureTunnel configures Tunnel interface in VPP -func (plugin *IPSecConfigurator) ConfigureTunnel(tunnel *ipsec.TunnelInterfaces_Tunnel) error { - plugin.log.Debugf("Configuring Tunnel %v", tunnel.Name) - - ifIdx, err := plugin.ipSecHandler.AddTunnelInterface(tunnel) +func (c *IPSecConfigurator) ConfigureTunnel(tunnel *ipsec.TunnelInterfaces_Tunnel) error { + ifIdx, err := c.ipSecHandler.AddTunnelInterface(tunnel) if err != nil { - return err + return errors.Errorf("failed to add IPSec tunnel interface %s: %v", tunnel.Name, err) } - // Register with necessary metadta info - plugin.ifIndexes.RegisterName(tunnel.Name, ifIdx, &interfaces.Interfaces_Interface{ + // Register with necessary metadata info + c.ifIndexes.RegisterName(tunnel.Name, ifIdx, &interfaces.Interfaces_Interface{ Name: tunnel.Name, Enabled: tunnel.Enabled, IpAddresses: tunnel.IpAddresses, Vrf: tunnel.Vrf, }) - plugin.log.Infof("Registered Tunnel %v (%d)", tunnel.Name, ifIdx) + c.log.Debugf("Registered tunnel %s (%d)", tunnel.Name, ifIdx) - if err := plugin.ifHandler.SetInterfaceVrf(ifIdx, tunnel.Vrf); err != nil { - return err + if err := c.ifHandler.SetInterfaceVrf(ifIdx, tunnel.Vrf); err != nil { + return errors.Errorf("failed to set VRF %d to tunnel interface %s: %v", tunnel.Vrf, tunnel.Name, err) } ipAddrs, err := addrs.StrAddrsToStruct(tunnel.IpAddresses) if err != nil { - return err + return errors.Errorf("failed to parse IP Addresses %s: %v", tunnel.IpAddresses, err) } for _, ip := range ipAddrs { - if err := plugin.ifHandler.AddInterfaceIP(ifIdx, ip); err != nil { - plugin.log.Errorf("adding interface IP address failed: %v", err) - return err + if err := c.ifHandler.AddInterfaceIP(ifIdx, ip); err != nil { + return errors.Errorf("failed to add IP addresses %s to tunnel interface %s: %v", + tunnel.IpAddresses, tunnel.Name, err) } } if tunnel.Enabled { - if err := plugin.ifHandler.InterfaceAdminUp(ifIdx); err != nil { - plugin.log.Debugf("setting interface up failed: %v", err) - return err + if err := c.ifHandler.InterfaceAdminUp(ifIdx); err != nil { + return errors.Errorf("failed to set interface %s admin status up: %v", + tunnel.Name, err) } } + c.log.Infof("IPSec %s tunnel configured", tunnel.Name) + return nil } // ModifyTunnel modifies Tunnel interface in VPP -func (plugin *IPSecConfigurator) ModifyTunnel(oldTunnel *ipsec.TunnelInterfaces_Tunnel, newTunnel *ipsec.TunnelInterfaces_Tunnel) error { - plugin.log.Debugf("Modifying Tunnel %v", oldTunnel.Name) - - if err := plugin.DeleteTunnel(oldTunnel); err != nil { - plugin.log.Error("deleting old Tunnel failed:", err) - return err +func (c *IPSecConfigurator) ModifyTunnel(oldTunnel, newTunnel *ipsec.TunnelInterfaces_Tunnel) error { + if err := c.DeleteTunnel(oldTunnel); err != nil { + return errors.Errorf("failed to remove modified tunnel interface %s: %v", oldTunnel.Name, err) } - if err := plugin.ConfigureTunnel(newTunnel); err != nil { - plugin.log.Error("configuring new Tunnel failed:", err) - return err + if err := c.ConfigureTunnel(newTunnel); err != nil { + return errors.Errorf("failed to configure modified tunnel interface %s: %v", oldTunnel.Name, err) } + c.log.Infof("IPSec Tunnel %s modified", oldTunnel.Name) + return nil } // DeleteTunnel deletes Tunnel interface in VPP -func (plugin *IPSecConfigurator) DeleteTunnel(oldTunnel *ipsec.TunnelInterfaces_Tunnel) error { - plugin.log.Debugf("Deleting Tunnel %v", oldTunnel.Name) - - ifIdx, _, exists := plugin.ifIndexes.LookupIdx(oldTunnel.Name) +func (c *IPSecConfigurator) DeleteTunnel(oldTunnel *ipsec.TunnelInterfaces_Tunnel) error { + ifIdx, _, exists := c.ifIndexes.LookupIdx(oldTunnel.Name) if !exists { - plugin.log.Warnf("Tunnel %q not found", oldTunnel.Name) - return nil + return errors.Errorf("cannot delete IPSec tunnel interface %s, not found in the mapping", oldTunnel.Name) } - if err := plugin.ipSecHandler.DelTunnelInterface(ifIdx, oldTunnel); err != nil { - return err + if err := c.ipSecHandler.DelTunnelInterface(ifIdx, oldTunnel); err != nil { + return errors.Errorf("failed to delete tunnel interface %s: %v", oldTunnel.Name, err) } - plugin.ifIndexes.UnregisterName(oldTunnel.Name) - plugin.log.Infof("Deleted Tunnel %v", oldTunnel.Name) + c.ifIndexes.UnregisterName(oldTunnel.Name) + c.log.Debugf("tunnel interface %s unregistered", oldTunnel.Name) + + c.log.Infof("Tunnel %s removed", oldTunnel.Name) return nil } // ResolveCreatedInterface is responsible for reconfiguring cached assignments -func (plugin *IPSecConfigurator) ResolveCreatedInterface(ifName string, swIfIdx uint32) { - for i, entry := range plugin.spdIfCache { +func (c *IPSecConfigurator) ResolveCreatedInterface(ifName string, swIfIdx uint32) error { + for i, entry := range c.spdIfCache { if entry.ifaceName == ifName { - plugin.log.Infof("Assigning SPD %v to interface %q", entry.spdID, ifName) - // TODO: loop through stored deletes, this is now needed because old assignment might still exist - if err := plugin.ipSecHandler.InterfaceDelSPD(entry.spdID, swIfIdx); err != nil { - plugin.log.Errorf("unassigning interface from SPD failed: %v", err) - } else { - plugin.log.Infof("Unassigned SPD %v from interface %q", entry.spdID, ifName) + if err := c.ipSecHandler.InterfaceDelSPD(entry.spdID, swIfIdx); err != nil { + // Do not return error here + c.log.Errorf("un-assigning interface from SPD failed: %v", err) } - if err := plugin.ipSecHandler.InterfaceAddSPD(entry.spdID, swIfIdx); err != nil { - plugin.log.Errorf("assigning interface to SPD failed: %v", err) - continue - } else { - plugin.log.Infof("Assigned SPD %v to interface %q", entry.spdID, entry.ifaceName) + if err := c.ipSecHandler.InterfaceAddSPD(entry.spdID, swIfIdx); err != nil { + return errors.Errorf("failed to assign interface %s to SPD %d: %v", ifName, entry.spdID, err) } - plugin.spdIfCache = append(plugin.spdIfCache[:i], plugin.spdIfCache[i+1:]...) + c.log.Debugf("interface %s assigned to the SPD %d", ifName, entry.spdID) + c.spdIfCache = append(c.spdIfCache[:i], c.spdIfCache[i+1:]...) + c.log.Debugf("interface %s removed from SPD cache", ifName) } } + + return nil } // ResolveDeletedInterface is responsible for caching assignments for future reconfiguration -func (plugin *IPSecConfigurator) ResolveDeletedInterface(ifName string, swIfIdx uint32) { - for _, assign := range plugin.spdIndexes.LookupByInterface(ifName) { - plugin.log.Infof("Unassigning SPD %v from interface %q", assign.SpdID, ifName) - +func (c *IPSecConfigurator) ResolveDeletedInterface(ifName string, swIfIdx uint32) error { + for _, assign := range c.spdIndexes.LookupByInterface(ifName) { // TODO: just store this for future, because this will fail since swIfIdx no longer exists - if err := plugin.ipSecHandler.InterfaceDelSPD(assign.SpdID, swIfIdx); err != nil { - plugin.log.Errorf("unassigning interface from SPD failed: %v", err) - } else { - plugin.log.Infof("Unassigned SPD %v from interface %q", assign.SpdID, ifName) + if err := c.ipSecHandler.InterfaceDelSPD(assign.SpdID, swIfIdx); err != nil { + // Do not return error here + c.log.Errorf("un-assigning interface from SPD failed: %v", err) } - plugin.cacheSPDInterfaceAssignment(assign.SpdID, ifName) + c.cacheSPDInterfaceAssignment(assign.SpdID, ifName) } + + return nil } -func (plugin *IPSecConfigurator) cacheSPDInterfaceAssignment(spdID uint32, ifaceName string) { - plugin.log.Debugf("caching SPD %v interface assignment to %v", spdID, ifaceName) - plugin.spdIfCache = append(plugin.spdIfCache, SPDIfCacheEntry{ +func (c *IPSecConfigurator) cacheSPDInterfaceAssignment(spdID uint32, ifaceName string) { + c.log.Debugf("caching SPD %v interface assignment to %v", spdID, ifaceName) + c.spdIfCache = append(c.spdIfCache, SPDIfCacheEntry{ ifaceName: ifaceName, spdID: spdID, }) } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *IPSecConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/ipsecplugin/vppcalls/api_vppcalls.go b/plugins/vpp/ipsecplugin/vppcalls/api_vppcalls.go index 2e6dcb3729..b81f9ee744 100644 --- a/plugins/vpp/ipsecplugin/vppcalls/api_vppcalls.go +++ b/plugins/vpp/ipsecplugin/vppcalls/api_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( govppapi "git.fd.io/govpp.git/api" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/vpp/ipsecplugin/ipsecidx" "github.com/ligato/vpp-agent/plugins/vpp/model/ipsec" @@ -67,7 +66,6 @@ type IPSecVPPRead interface { // IPSecVppHandler is accessor for IPsec-related vppcalls methods type IPSecVppHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel ifIndexes ifaceidx.SwIfIndex spdIndexes ipsecidx.SPDIndex // TODO workaround in order to be able to dump at least spds configurator knows about @@ -76,10 +74,9 @@ type IPSecVppHandler struct { // NewIPsecVppHandler creates new instance of IPsec vppcalls handler func NewIPsecVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, spdIndexes ipsecidx.SPDIndex, - log logging.Logger, stopwatch *measure.Stopwatch) *IPSecVppHandler { + log logging.Logger) *IPSecVppHandler { return &IPSecVppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, spdIndexes: spdIndexes, log: log, diff --git a/plugins/vpp/ipsecplugin/vppcalls/dump_vppcalls.go b/plugins/vpp/ipsecplugin/vppcalls/dump_vppcalls.go index 060bb40d13..be4a52727d 100644 --- a/plugins/vpp/ipsecplugin/vppcalls/dump_vppcalls.go +++ b/plugins/vpp/ipsecplugin/vppcalls/dump_vppcalls.go @@ -15,12 +15,10 @@ package vppcalls import ( - "net" - "strconv" - "time" - ipsecapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/ipsec" "github.com/ligato/vpp-agent/plugins/vpp/model/ipsec" + "net" + "strconv" ) // IPSecSaDetails holds security association with VPP metadata @@ -44,17 +42,13 @@ type IPSecSaMeta struct { } // DumpIPSecSA implements IPSec handler. -func (handler *IPSecVppHandler) DumpIPSecSA() (saList []*IPSecSaDetails, err error) { - return handler.DumpIPSecSAWithIndex(^uint32(0)) // Get everything +func (h *IPSecVppHandler) DumpIPSecSA() (saList []*IPSecSaDetails, err error) { + return h.DumpIPSecSAWithIndex(^uint32(0)) // Get everything } // DumpIPSecSAWithIndex implements IPSec handler. -func (handler *IPSecVppHandler) DumpIPSecSAWithIndex(saID uint32) (saList []*IPSecSaDetails, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsecapi.IpsecSaDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - saDetails, err := handler.dumpSecurityAssociations(saID) +func (h *IPSecVppHandler) DumpIPSecSAWithIndex(saID uint32) (saList []*IPSecSaDetails, err error) { + saDetails, err := h.dumpSecurityAssociations(saID) if err != nil { return nil, err } @@ -120,12 +114,8 @@ type IPSecTunnelMeta struct { } // DumpIPSecTunnelInterfaces implements IPSec handler. -func (handler *IPSecVppHandler) DumpIPSecTunnelInterfaces() (tun []*IPSecTunnelInterfaceDetails, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsecapi.IpsecSaDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - saDetails, err := handler.dumpSecurityAssociations(^uint32(0)) +func (h *IPSecVppHandler) DumpIPSecTunnelInterfaces() (tun []*IPSecTunnelInterfaceDetails, err error) { + saDetails, err := h.dumpSecurityAssociations(^uint32(0)) if err != nil { return nil, err } @@ -137,13 +127,13 @@ func (handler *IPSecVppHandler) DumpIPSecTunnelInterfaces() (tun []*IPSecTunnelI } // Interface - ifName, ifData, found := handler.ifIndexes.LookupName(saData.SwIfIndex) + ifName, ifData, found := h.ifIndexes.LookupName(saData.SwIfIndex) if !found { - handler.log.Warnf("IPSec SA dump: interface name not found for %d", saData.SwIfIndex) + h.log.Warnf("IPSec SA dump: interface name not found for %d", saData.SwIfIndex) continue } if ifData == nil { - handler.log.Warnf("IPSec SA dump: interface %s has no metadata", ifName) + h.log.Warnf("IPSec SA dump: interface %s has no metadata", ifName) continue } @@ -204,19 +194,15 @@ type SpdMeta struct { } // DumpIPSecSPD implements IPSec handler. -func (handler *IPSecVppHandler) DumpIPSecSPD() (spdList []*IPSecSpdDetails, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsecapi.IpsecSpdDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *IPSecVppHandler) DumpIPSecSPD() (spdList []*IPSecSpdDetails, err error) { metadata := &IPSecSpdMeta{ SpdMeta: make(map[string]*SpdMeta), } // TODO IPSec SPD dump request requires SPD ID, otherwise it returns nothing. There is currently no way // to dump all SPDs available on the VPP, so let's dump at least the ones configurator knows about. - for _, spdName := range handler.spdIndexes.GetMapping().ListNames() { - spdIdx, _, found := handler.spdIndexes.LookupIdx(spdName) + for _, spdName := range h.spdIndexes.GetMapping().ListNames() { + spdIdx, _, found := h.spdIndexes.LookupIdx(spdName) if !found { // Shouldn't happen, call the police or something continue @@ -228,7 +214,7 @@ func (handler *IPSecVppHandler) DumpIPSecSPD() (spdList []*IPSecSpdDetails, err SpdID: spdIdx, SaID: ^uint32(0), } - requestCtx := handler.callsChannel.SendMultiRequest(req) + requestCtx := h.callsChannel.SendMultiRequest(req) // Policy association index, used to generate SA name var paIdx int @@ -299,15 +285,11 @@ func (handler *IPSecVppHandler) DumpIPSecSPD() (spdList []*IPSecSpdDetails, err } // Get all security association (used also for tunnel interfaces) in binary api format -func (handler *IPSecVppHandler) dumpSecurityAssociations(saID uint32) (saList []*ipsecapi.IpsecSaDetails, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsecapi.IpsecSaDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *IPSecVppHandler) dumpSecurityAssociations(saID uint32) (saList []*ipsecapi.IpsecSaDetails, err error) { req := &ipsecapi.IpsecSaDump{ SaID: saID, } - requestCtx := handler.callsChannel.SendMultiRequest(req) + requestCtx := h.callsChannel.SendMultiRequest(req) for { saDetails := &ipsecapi.IpsecSaDetails{} diff --git a/plugins/vpp/ipsecplugin/vppcalls/ipsec_vppcalls.go b/plugins/vpp/ipsecplugin/vppcalls/ipsec_vppcalls.go index 049255e0bb..fee6f39b51 100644 --- a/plugins/vpp/ipsecplugin/vppcalls/ipsec_vppcalls.go +++ b/plugins/vpp/ipsecplugin/vppcalls/ipsec_vppcalls.go @@ -18,18 +18,13 @@ import ( "encoding/hex" "fmt" "net" - "time" "github.com/ligato/cn-infra/utils/addrs" ipsec_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/ipsec" "github.com/ligato/vpp-agent/plugins/vpp/model/ipsec" ) -func (handler *IPSecVppHandler) tunnelIfAddDel(tunnel *ipsec.TunnelInterfaces_Tunnel, isAdd bool) (uint32, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsec_api.IpsecTunnelIfAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *IPSecVppHandler) tunnelIfAddDel(tunnel *ipsec.TunnelInterfaces_Tunnel, isAdd bool) (uint32, error) { localCryptoKey, err := hex.DecodeString(tunnel.LocalCryptoKey) if err != nil { return 0, err @@ -68,7 +63,7 @@ func (handler *IPSecVppHandler) tunnelIfAddDel(tunnel *ipsec.TunnelInterfaces_Tu } reply := &ipsec_api.IpsecTunnelIfAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return 0, err } else if reply.Retval != 0 { return 0, fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -78,29 +73,25 @@ func (handler *IPSecVppHandler) tunnelIfAddDel(tunnel *ipsec.TunnelInterfaces_Tu } // AddTunnelInterface implements IPSec handler. -func (handler *IPSecVppHandler) AddTunnelInterface(tunnel *ipsec.TunnelInterfaces_Tunnel) (uint32, error) { - return handler.tunnelIfAddDel(tunnel, true) +func (h *IPSecVppHandler) AddTunnelInterface(tunnel *ipsec.TunnelInterfaces_Tunnel) (uint32, error) { + return h.tunnelIfAddDel(tunnel, true) } // DelTunnelInterface implements IPSec handler. -func (handler *IPSecVppHandler) DelTunnelInterface(ifIdx uint32, tunnel *ipsec.TunnelInterfaces_Tunnel) error { +func (h *IPSecVppHandler) DelTunnelInterface(ifIdx uint32, tunnel *ipsec.TunnelInterfaces_Tunnel) error { // Note: ifIdx is not used now, tunnel shiould be matched based on paramters - _, err := handler.tunnelIfAddDel(tunnel, false) + _, err := h.tunnelIfAddDel(tunnel, false) return err } -func (handler *IPSecVppHandler) spdAddDel(spdID uint32, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsec_api.IpsecSpdAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *IPSecVppHandler) spdAddDel(spdID uint32, isAdd bool) error { req := &ipsec_api.IpsecSpdAddDel{ IsAdd: boolToUint(isAdd), SpdID: spdID, } reply := &ipsec_api.IpsecSpdAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -110,20 +101,16 @@ func (handler *IPSecVppHandler) spdAddDel(spdID uint32, isAdd bool) error { } // AddSPD implements IPSec handler. -func (handler *IPSecVppHandler) AddSPD(spdID uint32) error { - return handler.spdAddDel(spdID, true) +func (h *IPSecVppHandler) AddSPD(spdID uint32) error { + return h.spdAddDel(spdID, true) } // DelSPD implements IPSec handler. -func (handler *IPSecVppHandler) DelSPD(spdID uint32) error { - return handler.spdAddDel(spdID, false) +func (h *IPSecVppHandler) DelSPD(spdID uint32) error { + return h.spdAddDel(spdID, false) } -func (handler *IPSecVppHandler) interfaceAddDelSpd(spdID, swIfIdx uint32, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsec_api.IpsecInterfaceAddDelSpd{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *IPSecVppHandler) interfaceAddDelSpd(spdID, swIfIdx uint32, isAdd bool) error { req := &ipsec_api.IpsecInterfaceAddDelSpd{ IsAdd: boolToUint(isAdd), SwIfIndex: swIfIdx, @@ -131,7 +118,7 @@ func (handler *IPSecVppHandler) interfaceAddDelSpd(spdID, swIfIdx uint32, isAdd } reply := &ipsec_api.IpsecInterfaceAddDelSpdReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -141,20 +128,16 @@ func (handler *IPSecVppHandler) interfaceAddDelSpd(spdID, swIfIdx uint32, isAdd } // InterfaceAddSPD implements IPSec handler. -func (handler *IPSecVppHandler) InterfaceAddSPD(spdID, swIfIdx uint32) error { - return handler.interfaceAddDelSpd(spdID, swIfIdx, true) +func (h *IPSecVppHandler) InterfaceAddSPD(spdID, swIfIdx uint32) error { + return h.interfaceAddDelSpd(spdID, swIfIdx, true) } // InterfaceDelSPD implements IPSec handler. -func (handler *IPSecVppHandler) InterfaceDelSPD(spdID, swIfIdx uint32) error { - return handler.interfaceAddDelSpd(spdID, swIfIdx, false) +func (h *IPSecVppHandler) InterfaceDelSPD(spdID, swIfIdx uint32) error { + return h.interfaceAddDelSpd(spdID, swIfIdx, false) } -func (handler *IPSecVppHandler) spdAddDelEntry(spdID, saID uint32, spd *ipsec.SecurityPolicyDatabases_SPD_PolicyEntry, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsec_api.IpsecSpdAddDelEntry{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *IPSecVppHandler) spdAddDelEntry(spdID, saID uint32, spd *ipsec.SecurityPolicyDatabases_SPD_PolicyEntry, isAdd bool) error { req := &ipsec_api.IpsecSpdAddDelEntry{ IsAdd: boolToUint(isAdd), SpdID: spdID, @@ -200,7 +183,7 @@ func (handler *IPSecVppHandler) spdAddDelEntry(spdID, saID uint32, spd *ipsec.Se } reply := &ipsec_api.IpsecSpdAddDelEntryReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -210,20 +193,16 @@ func (handler *IPSecVppHandler) spdAddDelEntry(spdID, saID uint32, spd *ipsec.Se } // AddSPDEntry implements IPSec handler. -func (handler *IPSecVppHandler) AddSPDEntry(spdID, saID uint32, spd *ipsec.SecurityPolicyDatabases_SPD_PolicyEntry) error { - return handler.spdAddDelEntry(spdID, saID, spd, true) +func (h *IPSecVppHandler) AddSPDEntry(spdID, saID uint32, spd *ipsec.SecurityPolicyDatabases_SPD_PolicyEntry) error { + return h.spdAddDelEntry(spdID, saID, spd, true) } // DelSPDEntry implements IPSec handler. -func (handler *IPSecVppHandler) DelSPDEntry(spdID, saID uint32, spd *ipsec.SecurityPolicyDatabases_SPD_PolicyEntry) error { - return handler.spdAddDelEntry(spdID, saID, spd, false) +func (h *IPSecVppHandler) DelSPDEntry(spdID, saID uint32, spd *ipsec.SecurityPolicyDatabases_SPD_PolicyEntry) error { + return h.spdAddDelEntry(spdID, saID, spd, false) } -func (handler *IPSecVppHandler) sadAddDelEntry(saID uint32, sa *ipsec.SecurityAssociations_SA, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ipsec_api.IpsecSadAddDelEntry{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *IPSecVppHandler) sadAddDelEntry(saID uint32, sa *ipsec.SecurityAssociations_SA, isAdd bool) error { cryptoKey, err := hex.DecodeString(sa.CryptoKey) if err != nil { return err @@ -266,7 +245,7 @@ func (handler *IPSecVppHandler) sadAddDelEntry(saID uint32, sa *ipsec.SecurityAs } reply := &ipsec_api.IpsecSadAddDelEntryReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -276,13 +255,13 @@ func (handler *IPSecVppHandler) sadAddDelEntry(saID uint32, sa *ipsec.SecurityAs } // AddSAEntry implements IPSec handler. -func (handler *IPSecVppHandler) AddSAEntry(saID uint32, sa *ipsec.SecurityAssociations_SA) error { - return handler.sadAddDelEntry(saID, sa, true) +func (h *IPSecVppHandler) AddSAEntry(saID uint32, sa *ipsec.SecurityAssociations_SA) error { + return h.sadAddDelEntry(saID, sa, true) } // DelSAEntry implements IPSec handler. -func (handler *IPSecVppHandler) DelSAEntry(saID uint32, sa *ipsec.SecurityAssociations_SA) error { - return handler.sadAddDelEntry(saID, sa, false) +func (h *IPSecVppHandler) DelSAEntry(saID uint32, sa *ipsec.SecurityAssociations_SA) error { + return h.sadAddDelEntry(saID, sa, false) } func boolToUint(value bool) uint8 { diff --git a/plugins/vpp/l2plugin/bd_config.go b/plugins/vpp/l2plugin/bd_config.go index 462d0576bc..4d946994fc 100644 --- a/plugins/vpp/l2plugin/bd_config.go +++ b/plugins/vpp/l2plugin/bd_config.go @@ -12,17 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/l2 --gogo_out=../model/l2 ../model/l2/l2.proto - // Package l2plugin implements the L2 plugin that handles Bridge Domains and L2 FIBs. package l2plugin import ( - "fmt" - govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -58,9 +54,6 @@ type BDConfigurator struct { // VPP API handlers ifHandler ifvppcalls.IfVppAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // BridgeDomainStateMessage is message with bridge domain state + bridge domain name (since a state message does not @@ -71,78 +64,73 @@ type BridgeDomainStateMessage struct { } // GetBdIndexes exposes interface name-to-index mapping -func (plugin *BDConfigurator) GetBdIndexes() l2idx.BDIndexRW { - return plugin.bdIndexes +func (c *BDConfigurator) GetBdIndexes() l2idx.BDIndexRW { + return c.bdIndexes } // Init members (channels...) and start go routines. -func (plugin *BDConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - notificationChannel chan BridgeDomainStateMessage, enableStopwatch bool) (err error) { +func (c *BDConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, + notificationChannel chan BridgeDomainStateMessage) (err error) { // Logger - plugin.log = logger.NewLogger("-l2-bd-conf") - plugin.log.Debug("Initializing L2 Bridge domains configurator") + c.log = logger.NewLogger("l2-bd-conf") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.bdIndexes = l2idx.NewBDIndex(nametoidx.NewNameToIdx(plugin.log, "bd_indexes", l2idx.IndexMetadata)) - plugin.bdIDSeq = 1 - plugin.regIfCounter = 1 + c.ifIndexes = swIfIndexes + c.bdIndexes = l2idx.NewBDIndex(nametoidx.NewNameToIdx(c.log, "bd_indexes", l2idx.IndexMetadata)) + c.bdIDSeq = 1 + c.regIfCounter = 1 // VPP channel - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // Init notification channel. - plugin.notificationChan = notificationChannel - - // Stopwatch - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("BDConfigurator", plugin.log) - } + c.notificationChan = notificationChannel // VPP API handlers - plugin.ifHandler = ifvppcalls.NewIfVppHandler(plugin.vppChan, plugin.log, plugin.stopwatch) - plugin.bdHandler = vppcalls.NewBridgeDomainVppHandler(plugin.vppChan, plugin.ifIndexes, plugin.log, plugin.stopwatch) + c.ifHandler = ifvppcalls.NewIfVppHandler(c.vppChan, c.log) + c.bdHandler = vppcalls.NewBridgeDomainVppHandler(c.vppChan, c.ifIndexes, c.log) + + c.log.Debug("L2 Bridge domains configurator initialized") return nil } // Close GOVPP channel. -func (plugin *BDConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *BDConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose L2 bridge domain configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *BDConfigurator) clearMapping() { - plugin.bdIndexes.Clear() +func (c *BDConfigurator) clearMapping() { + c.bdIndexes.Clear() } // ConfigureBridgeDomain handles the creation of new bridge domain including interfaces, ARP termination // entries and pushes status update notification. -func (plugin *BDConfigurator) ConfigureBridgeDomain(bdConfig *l2.BridgeDomains_BridgeDomain) error { - plugin.log.Println("Configuring VPP Bridge Domain", bdConfig.Name) - - isValid, _ := plugin.vppValidateBridgeDomainBVI(bdConfig, nil) +func (c *BDConfigurator) ConfigureBridgeDomain(bdConfig *l2.BridgeDomains_BridgeDomain) error { + isValid, _ := c.vppValidateBridgeDomainBVI(bdConfig, nil) if !isValid { - return nil + return errors.Errorf("New bridge domain %s configuration is invalid", bdConfig.Name) } // Set index of the new bridge domain and increment global index. - bdIdx := plugin.bdIDSeq - plugin.bdIDSeq++ + bdIdx := c.bdIDSeq + c.bdIDSeq++ // Create bridge domain with respective index. - if err := plugin.bdHandler.VppAddBridgeDomain(bdIdx, bdConfig); err != nil { - plugin.log.Errorf("adding bridge domain %v failed: %v", bdConfig.Name, err) - return err + if err := c.bdHandler.VppAddBridgeDomain(bdIdx, bdConfig); err != nil { + return errors.Errorf("failed to configure bridge domain %s: %v", bdConfig.Name, err) } // Find all interfaces belonging to this bridge domain and set them up. - configuredIfs, err := plugin.bdHandler.SetInterfacesToBridgeDomain(bdConfig.Name, bdIdx, bdConfig.Interfaces, plugin.ifIndexes) + configuredIfs, err := c.bdHandler.SetInterfacesToBridgeDomain(bdConfig.Name, bdIdx, bdConfig.Interfaces, c.ifIndexes) if err != nil { - return err + return errors.Errorf("failed to set interfaces to bridge domain %s: %v", bdConfig.Name, err) } // Resolve ARP termination table entries. @@ -150,131 +138,133 @@ func (plugin *BDConfigurator) ConfigureBridgeDomain(bdConfig *l2.BridgeDomains_B if arpTerminationTable != nil && len(arpTerminationTable) != 0 { arpTable := bdConfig.ArpTerminationTable for _, arpEntry := range arpTable { - err := plugin.bdHandler.VppAddArpTerminationTableEntry(bdIdx, arpEntry.PhysAddress, arpEntry.IpAddress) - if err != nil { - plugin.log.Error(err) + if err := c.bdHandler.VppAddArpTerminationTableEntry(bdIdx, arpEntry.PhysAddress, arpEntry.IpAddress); err != nil { + return errors.Errorf("failed to add ARP termination table entry (MAC %v) to bridge domain %s: %v", + arpEntry.PhysAddress, bdConfig.Name, err) } } - } else { - plugin.log.WithField("Bridge domain name", bdConfig.Name).Debug("No ARP termination entries to set") } // Register created bridge domain. - plugin.bdIndexes.RegisterName(bdConfig.Name, bdIdx, l2idx.NewBDMetadata(bdConfig, configuredIfs)) - plugin.log.WithFields(logging.Fields{"Name": bdConfig.Name, "Index": bdIdx}).Debug("Bridge domain registered") + c.bdIndexes.RegisterName(bdConfig.Name, bdIdx, l2idx.NewBDMetadata(bdConfig, configuredIfs)) + c.log.Debugf("Bridge domain %s registered", bdConfig.Name) // Push to bridge domain state. - errLookup := plugin.PropagateBdDetailsToStatus(bdIdx, bdConfig.Name) - if errLookup != nil { - plugin.log.WithField("bdName", bdConfig.Name).Error(errLookup) + if errLookup := c.propagateBdDetailsToStatus(bdIdx, bdConfig.Name); errLookup != nil { return errLookup } - plugin.log.WithFields(logging.Fields{"bdIdx": bdIdx}). - Infof("Bridge domain %v configured", bdConfig.Name) + c.log.Infof("Bridge domain %s configured (ID: %d)", bdConfig.Name, bdIdx) return nil } // ModifyBridgeDomain processes the NB config and propagates it to bin api calls. -func (plugin *BDConfigurator) ModifyBridgeDomain(newBdConfig *l2.BridgeDomains_BridgeDomain, oldBdConfig *l2.BridgeDomains_BridgeDomain) error { - plugin.log.Infof("Modifying VPP bridge domain %v", newBdConfig.Name) - +func (c *BDConfigurator) ModifyBridgeDomain(newBdConfig, oldBdConfig *l2.BridgeDomains_BridgeDomain) error { // Validate updated config. - isValid, recreate := plugin.vppValidateBridgeDomainBVI(newBdConfig, oldBdConfig) + isValid, recreate := c.vppValidateBridgeDomainBVI(newBdConfig, oldBdConfig) if !isValid { - return nil + return errors.Errorf("Modified bridge domain %s configuration is invalid", newBdConfig.Name) } // In case bridge domain params changed, it needs to be recreated if recreate { - if err := plugin.DeleteBridgeDomain(oldBdConfig); err != nil { - return err + if err := c.DeleteBridgeDomain(oldBdConfig); err != nil { + return errors.Errorf("bridge domain %s recreate error: %v", oldBdConfig.Name, err) } - if err := plugin.ConfigureBridgeDomain(newBdConfig); err != nil { - return err + if err := c.ConfigureBridgeDomain(newBdConfig); err != nil { + return errors.Errorf("bridge domain %s recreate error: %v", newBdConfig.Name, err) } - plugin.log.Infof("Bridge domain %v modify done.", newBdConfig.Name) + c.log.Infof("Bridge domain %v modify done.", newBdConfig.Name) return nil } // Modify without recreation - bdIdx, bdMeta, found := plugin.bdIndexes.LookupIdx(oldBdConfig.Name) + bdIdx, bdMeta, found := c.bdIndexes.LookupIdx(oldBdConfig.Name) if !found { // If old config is missing, the diff cannot be done. Bridge domain will be created as a new one. This // case should NOT happen, it means that the agent's state is inconsistent. - plugin.log.Warnf("Bridge domain %v modify failed due to missing old configuration, will be created as a new one", + c.log.Warnf("Bridge domain %v modify failed due to missing old configuration, will be created as a new one", newBdConfig.Name) - return plugin.ConfigureBridgeDomain(newBdConfig) + return c.ConfigureBridgeDomain(newBdConfig) } // Update interfaces. - toSet, toUnset := plugin.calculateIfaceDiff(newBdConfig.Interfaces, oldBdConfig.Interfaces) - unConfIfs, err := plugin.bdHandler.UnsetInterfacesFromBridgeDomain(newBdConfig.Name, bdIdx, toUnset, plugin.ifIndexes) + toSet, toUnset := c.calculateIfaceDiff(newBdConfig.Interfaces, oldBdConfig.Interfaces) + unConfIfs, err := c.bdHandler.UnsetInterfacesFromBridgeDomain(newBdConfig.Name, bdIdx, toUnset, c.ifIndexes) if err != nil { - return err + return errors.Errorf("failed to unset interfaces from modified bridge domain %s: %v", newBdConfig.Name, err) } - newConfIfs, err := plugin.bdHandler.SetInterfacesToBridgeDomain(newBdConfig.Name, bdIdx, toSet, plugin.ifIndexes) + newConfIfs, err := c.bdHandler.SetInterfacesToBridgeDomain(newBdConfig.Name, bdIdx, toSet, c.ifIndexes) if err != nil { - return err + return errors.Errorf("failed to set interfaces to modified bridge domain %s: %v", newBdConfig.Name, err) } // Refresh configured interfaces - configuredIfs := plugin.reckonInterfaces(bdMeta.ConfiguredInterfaces, newConfIfs, unConfIfs) + configuredIfs := reckonInterfaces(bdMeta.ConfiguredInterfaces, newConfIfs, unConfIfs) // Update ARP termination table. - toAdd, toRemove := plugin.calculateARPDiff(newBdConfig.ArpTerminationTable, oldBdConfig.ArpTerminationTable) + toAdd, toRemove := calculateARPDiff(newBdConfig.ArpTerminationTable, oldBdConfig.ArpTerminationTable) for _, entry := range toAdd { - plugin.bdHandler.VppAddArpTerminationTableEntry(bdIdx, entry.PhysAddress, entry.IpAddress) + if err := c.bdHandler.VppAddArpTerminationTableEntry(bdIdx, entry.PhysAddress, entry.IpAddress); err != nil { + return errors.Errorf("failed to set ARP termination (MAC %s) to bridge domain %s: %v", + entry.PhysAddress, newBdConfig.Name, err) + } } for _, entry := range toRemove { - plugin.bdHandler.VppRemoveArpTerminationTableEntry(bdIdx, entry.PhysAddress, entry.IpAddress) + if err := c.bdHandler.VppRemoveArpTerminationTableEntry(bdIdx, entry.PhysAddress, entry.IpAddress); err != nil { + return errors.Errorf("failed to remove ARP termination (MAC %s) to bridge domain %s: %v", + entry.PhysAddress, newBdConfig.Name, err) + } } // Push change to bridge domain state. - errLookup := plugin.PropagateBdDetailsToStatus(bdIdx, newBdConfig.Name) - if errLookup != nil { - plugin.log.WithField("bdName", newBdConfig.Name).Error(errLookup) + if errLookup := c.propagateBdDetailsToStatus(bdIdx, newBdConfig.Name); errLookup != nil { return errLookup } // Update bridge domain's registered metadata - if success := plugin.bdIndexes.UpdateMetadata(newBdConfig.Name, l2idx.NewBDMetadata(newBdConfig, configuredIfs)); !success { - plugin.log.Errorf("Failed to update metadata for bridge domain %s", newBdConfig.Name) + c.log.Debugf("Updating bridge domain %s mapping metadata", newBdConfig.Name) + if success := c.bdIndexes.UpdateMetadata(newBdConfig.Name, l2idx.NewBDMetadata(newBdConfig, configuredIfs)); !success { + c.log.Errorf("Failed to update metadata for bridge domain %s", newBdConfig.Name) } + c.log.Infof("Bridge domain %s modified", newBdConfig.Name) + return nil } // DeleteBridgeDomain processes the NB config and propagates it to bin api calls. -func (plugin *BDConfigurator) DeleteBridgeDomain(bdConfig *l2.BridgeDomains_BridgeDomain) error { - plugin.log.Infof("Deleting bridge domain %v", bdConfig.Name) - - bdIdx, _, found := plugin.bdIndexes.LookupIdx(bdConfig.Name) +func (c *BDConfigurator) DeleteBridgeDomain(bdConfig *l2.BridgeDomains_BridgeDomain) error { + bdIdx, _, found := c.bdIndexes.LookupIdx(bdConfig.Name) if !found { - plugin.log.WithField("bdName", bdConfig.Name).Debug("Unable to find index for bridge domain to be deleted.") - return nil + return errors.Errorf("cannot remove bridge domain %s, index not found in the mapping", bdConfig.Name) + } + + if err := c.deleteBridgeDomain(bdConfig, bdIdx); err != nil { + return errors.Errorf("failed to remove bridge domain %s: %v", bdConfig.Name, err) } - return plugin.deleteBridgeDomain(bdConfig, bdIdx) + c.log.Infof("Bridge domain %s deleted", bdConfig.Name) + + return nil } -func (plugin *BDConfigurator) deleteBridgeDomain(bdConfig *l2.BridgeDomains_BridgeDomain, bdIdx uint32) error { +func (c *BDConfigurator) deleteBridgeDomain(bdConfig *l2.BridgeDomains_BridgeDomain, bdIdx uint32) error { // Unmap all interfaces from removed bridge domain. - if _, err := plugin.bdHandler.UnsetInterfacesFromBridgeDomain(bdConfig.Name, bdIdx, bdConfig.Interfaces, plugin.ifIndexes); err != nil { - plugin.log.Error(err) // Try to remove bridge domain anyway + if _, err := c.bdHandler.UnsetInterfacesFromBridgeDomain(bdConfig.Name, bdIdx, bdConfig.Interfaces, c.ifIndexes); err != nil { + c.log.Error(err) // Do not return, try to remove bridge domain anyway } - if err := plugin.bdHandler.VppDeleteBridgeDomain(bdIdx); err != nil { - return err + if err := c.bdHandler.VppDeleteBridgeDomain(bdIdx); err != nil { + return errors.Errorf("failed to remove bridge domain %s: %v", bdConfig, err) } - plugin.bdIndexes.UnregisterName(bdConfig.Name) - plugin.log.WithFields(logging.Fields{"bdIdx": bdIdx}). - Debugf("Bridge domain %v removed", bdConfig.Name) + c.bdIndexes.UnregisterName(bdConfig.Name) + c.log.Debugf("Bridge domain %s unregistered", bdConfig.Name) // Update bridge domain state. - if err := plugin.PropagateBdDetailsToStatus(bdIdx, bdConfig.Name); err != nil { + if err := c.propagateBdDetailsToStatus(bdIdx, bdConfig.Name); err != nil { return err } @@ -282,11 +272,9 @@ func (plugin *BDConfigurator) deleteBridgeDomain(bdConfig *l2.BridgeDomains_Brid } // PropagateBdDetailsToStatus looks for existing VPP bridge domain state and propagates it to the etcd bd state. -func (plugin *BDConfigurator) PropagateBdDetailsToStatus(bdID uint32, bdName string) error { +func (c *BDConfigurator) propagateBdDetailsToStatus(bdID uint32, bdName string) error { stateMsg := BridgeDomainStateMessage{} - var wasError error - - _, _, found := plugin.bdIndexes.LookupName(bdID) + _, _, found := c.bdIndexes.LookupName(bdID) if !found { // If bridge domain does not exist in mapping, the lookup treats it as a removed bridge domain, // and ID in message is set to 0. Name has to be passed further in order @@ -300,46 +288,52 @@ func (plugin *BDConfigurator) PropagateBdDetailsToStatus(bdID uint32, bdName str req := &l2ba.BridgeDomainDump{ BdID: bdID, } - reqContext := plugin.vppChan.SendRequest(req) + reqContext := c.vppChan.SendRequest(req) msg := &l2ba.BridgeDomainDetails{} - err := reqContext.ReceiveReply(msg) - if err != nil { - wasError = err + if err := reqContext.ReceiveReply(msg); err != nil { + return errors.Errorf("BD status propagation: failed to dump bridge domains: %s", err) } stateMsg.Message = msg stateMsg.Name = bdName } // Propagate bridge domain state information to the bridge domain state updater. - plugin.notificationChan <- stateMsg + c.notificationChan <- stateMsg - return wasError + return nil } // ResolveCreatedInterface looks for bridge domain this interface is assigned to and sets it up. -func (plugin *BDConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { - plugin.log.Infof("Assigning new interface %v to bridge domain", ifName) +func (c *BDConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { // Find bridge domain where the interface should be assigned - bdIdx, bd, bdIf, found := plugin.bdIndexes.LookupBdForInterface(ifName) + bdIdx, bd, bdIf, found := c.bdIndexes.LookupBdForInterface(ifName) if !found { - plugin.log.Debugf("Interface %s does not belong to any bridge domain", ifName) return nil } - var bdIfs []*l2.BridgeDomains_BridgeDomain_Interfaces // Single-value - configuredIf, err := plugin.bdHandler.SetInterfacesToBridgeDomain(bd.Name, bdIdx, append(bdIfs, bdIf), plugin.ifIndexes) + configuredIf, err := c.bdHandler.SetInterfaceToBridgeDomain(bd.Name, bdIdx, bdIf, c.ifIndexes) if err != nil { - return fmt.Errorf("error while assigning interface %s to bridge domain %s", ifName, bd.Name) + return errors.Errorf("error while assigning registered interface %s to bridge domain %s: %v", + ifName, bd.Name, err) } - // Refresh metadata - configuredIfs, found := plugin.bdIndexes.LookupConfiguredIfsForBd(bd.Name) + // Refresh metadata. Skip if resolved interface already exists + _, bdMeta, found := c.bdIndexes.LookupIdx(bd.Name) if !found { - return fmt.Errorf("unable to get list of configured interfaces from %s", configuredIfs) + return errors.Errorf("unable to get list of configured interfaces from %s", bd.Name) + } + var isUpdated bool + for _, metaIf := range bdMeta.ConfiguredInterfaces { + if metaIf == configuredIf { + isUpdated = true + } + } + if !isUpdated { + c.bdIndexes.UpdateMetadata(bd.Name, l2idx.NewBDMetadata(bd, append(bdMeta.ConfiguredInterfaces, configuredIf))) + c.log.Debugf("Bridge domain %s metadata updated", bd.Name) } - plugin.bdIndexes.UpdateMetadata(bd.Name, l2idx.NewBDMetadata(bd, append(configuredIfs, configuredIf...))) // Push to bridge domain state. - if err := plugin.PropagateBdDetailsToStatus(bdIdx, bd.Name); err != nil { + if err := c.propagateBdDetailsToStatus(bdIdx, bd.Name); err != nil { return err } @@ -347,29 +341,28 @@ func (plugin *BDConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint3 } // ResolveDeletedInterface is called by VPP if an interface is removed. -func (plugin *BDConfigurator) ResolveDeletedInterface(ifName string) error { - plugin.log.Infof("Remove deleted interface %v from bridge domain", ifName) +func (c *BDConfigurator) ResolveDeletedInterface(ifName string) error { // Find bridge domain the interface should be removed from - bdIdx, bd, _, found := plugin.bdIndexes.LookupBdForInterface(ifName) + bdIdx, bd, _, found := c.bdIndexes.LookupBdForInterface(ifName) if !found { - plugin.log.Debugf("Interface %s does not belong to any bridge domain", ifName) return nil } // If interface belonging to a bridge domain is removed, VPP handles internal bridge domain update itself. // However, the etcd operational state and bridge domain metadata still needs to be updated to reflect changed VPP state. - configuredIfs, found := plugin.bdIndexes.LookupConfiguredIfsForBd(bd.Name) + _, bdMeta, found := c.bdIndexes.LookupIdx(bd.Name) if !found { - return fmt.Errorf("unable to get list of configured interfaces from %s", configuredIfs) + return errors.Errorf("unable to get list of configured interfaces for bridge domain %v", bd.Name) } - for i, configuredIf := range configuredIfs { + for i, configuredIf := range bdMeta.ConfiguredInterfaces { if configuredIf == ifName { - configuredIfs = append(configuredIfs[:i], configuredIfs[i+1:]...) + bdMeta.ConfiguredInterfaces = append(bdMeta.ConfiguredInterfaces[:i], bdMeta.ConfiguredInterfaces[i+1:]...) break } } - plugin.bdIndexes.UpdateMetadata(bd.Name, l2idx.NewBDMetadata(bd, configuredIfs)) - err := plugin.PropagateBdDetailsToStatus(bdIdx, bd.Name) + c.bdIndexes.UpdateMetadata(bd.Name, l2idx.NewBDMetadata(bd, bdMeta.ConfiguredInterfaces)) + c.log.Debugf("Bridge domain %s metadata updated", bd.Name) + err := c.propagateBdDetailsToStatus(bdIdx, bd.Name) if err != nil { return err } @@ -378,14 +371,13 @@ func (plugin *BDConfigurator) ResolveDeletedInterface(ifName string) error { } // The goal of the validation is to ensure that bridge domain does not contain more than one BVI interface -func (plugin *BDConfigurator) vppValidateBridgeDomainBVI(newBdConfig, oldBdConfig *l2.BridgeDomains_BridgeDomain) (bool, bool) { - recreate := plugin.calculateBdParamsDiff(newBdConfig, oldBdConfig) +func (c *BDConfigurator) vppValidateBridgeDomainBVI(newBdConfig, oldBdConfig *l2.BridgeDomains_BridgeDomain) (bool, bool) { + recreate := calculateBdParamsDiff(newBdConfig, oldBdConfig) if recreate { - plugin.log.Debugf("Bridge domain %v base params changed, will be recreated", newBdConfig.Name) + c.log.Debugf("Bridge domain %s base params changed, needs to be recreated", newBdConfig.Name) } - if len(newBdConfig.Interfaces) == 0 { - plugin.log.Warnf("Bridge domain %v does not contain any interface", newBdConfig.Name) + c.log.Debugf("Bridge domain %s does not contain any interface", newBdConfig.Name) return true, recreate } var bviCount int @@ -395,18 +387,18 @@ func (plugin *BDConfigurator) vppValidateBridgeDomainBVI(newBdConfig, oldBdConfi } } if bviCount == 0 { - plugin.log.Debugf("Bridge domain %v does not contain any bvi interface", newBdConfig.Name) + c.log.Debugf("Bridge domain %s does not contain any bvi interface", newBdConfig.Name) return true, recreate } else if bviCount == 1 { return true, recreate } else { - plugin.log.Warnf("Bridge domain %v contains more than one BVI interface. Correct it and create/modify bridge domain again", newBdConfig.Name) + c.log.Warnf("Bridge domain %s contains more than one BVI interface", newBdConfig.Name) return false, recreate } } // Compares all base bridge domain params. Returns true if there is a difference, false otherwise. -func (plugin *BDConfigurator) calculateBdParamsDiff(newBdConfig, oldBdConfig *l2.BridgeDomains_BridgeDomain) bool { +func calculateBdParamsDiff(newBdConfig, oldBdConfig *l2.BridgeDomains_BridgeDomain) bool { if oldBdConfig == nil { // nothing to compare return false @@ -442,7 +434,7 @@ func (plugin *BDConfigurator) calculateBdParamsDiff(newBdConfig, oldBdConfig *l2 // * all new interfaces added to bridge domain // * interface which was a BVI before // * interface which will be the new BVI -func (plugin *BDConfigurator) calculateIfaceDiff(newIfaces, oldIfaces []*l2.BridgeDomains_BridgeDomain_Interfaces) (toSet, toUnset []*l2.BridgeDomains_BridgeDomain_Interfaces) { +func (c *BDConfigurator) calculateIfaceDiff(newIfaces, oldIfaces []*l2.BridgeDomains_BridgeDomain_Interfaces) (toSet, toUnset []*l2.BridgeDomains_BridgeDomain_Interfaces) { // Find BVI interfaces (it may not be configured) var oldBVI, newBVI *l2.BridgeDomains_BridgeDomain_Interfaces for _, newIface := range newIfaces { @@ -525,7 +517,7 @@ func (plugin *BDConfigurator) calculateIfaceDiff(newIfaces, oldIfaces []*l2.Brid // - added is a list of new configured interfaces // - removed is a list of un-configured interfaces // Note: resulting list of interfaces may NOT correspond with the one in bridge domain configuration. -func (plugin *BDConfigurator) reckonInterfaces(current []string, added []string, removed []string) []string { +func reckonInterfaces(current []string, added []string, removed []string) []string { for _, delItem := range removed { for i, currItem := range current { if currItem == delItem { @@ -538,7 +530,7 @@ func (plugin *BDConfigurator) reckonInterfaces(current []string, added []string, } // resolve diff of ARP entries -func (plugin *BDConfigurator) calculateARPDiff(newARPs, oldARPs []*l2.BridgeDomains_BridgeDomain_ArpTerminationEntry) (toAdd, toRemove []*l2.BridgeDomains_BridgeDomain_ArpTerminationEntry) { +func calculateARPDiff(newARPs, oldARPs []*l2.BridgeDomains_BridgeDomain_ArpTerminationEntry) (toAdd, toRemove []*l2.BridgeDomains_BridgeDomain_ArpTerminationEntry) { // Resolve ARPs to add for _, newARP := range newARPs { var exists bool @@ -566,3 +558,17 @@ func (plugin *BDConfigurator) calculateARPDiff(newARPs, oldARPs []*l2.BridgeDoma return toAdd, toRemove } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *BDConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/l2plugin/bd_config_test.go b/plugins/vpp/l2plugin/bd_config_test.go index c2c4963655..c772d9acc1 100644 --- a/plugins/vpp/l2plugin/bd_config_test.go +++ b/plugins/vpp/l2plugin/bd_config_test.go @@ -17,8 +17,9 @@ package l2plugin_test import ( "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/cn-infra/logging/logrus" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -48,7 +49,9 @@ func bdConfigTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *core.Conne Expect(names).To(BeEmpty()) // Create connection - mockCtx := &vppcallmock.TestCtx{MockVpp: &mock.VppAdapter{}} + mockCtx := &vppcallmock.TestCtx{ + MockVpp: mock.NewVppAdapter(), + } connection, err := core.Connect(mockCtx.MockVpp) Expect(err).To(BeNil()) @@ -57,7 +60,7 @@ func bdConfigTestInitialization(t *testing.T) (*vppcallmock.TestCtx, *core.Conne // Test initialization bdConfiguratorPlugin := &l2plugin.BDConfigurator{} - err = bdConfiguratorPlugin.Init(pluginLogger, connection, swIfIndex, notifChan, false) + err = bdConfiguratorPlugin.Init(pluginLogger, connection, swIfIndex, notifChan) Expect(err).To(BeNil()) return mockCtx, connection, swIfIndex, notifChan, bdConfiguratorPlugin @@ -118,11 +121,14 @@ func TestBDConfigurator_ModifyBridgeDomainRecreate(t *testing.T) { ctx, conn, _, _, plugin := bdConfigTestInitialization(t) defer bdConfigTeardown(conn, plugin) + ctx.MockVpp.MockReply(&l22.BridgeDomainAddDelReply{}) ctx.MockVpp.MockReply(&l22.BridgeDomainAddDelReply{}) ctx.MockVpp.MockReply(&l22.BdIPMacAddDelReply{}) ctx.MockVpp.MockReply(&l22.BridgeDomainDetails{}) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) + plugin.GetBdIndexes().RegisterName("test", 2, nil) + err := plugin.ModifyBridgeDomain(&l2.BridgeDomains_BridgeDomain{ Name: "test", Flood: false, @@ -249,7 +255,7 @@ func TestBDConfigurator_ModifyBridgeDomainFound(t *testing.T) { ctx, conn, _, _, plugin := bdConfigTestInitialization(t) defer bdConfigTeardown(conn, plugin) - ctx.MockVpp.MockReply(&l22.BridgeDomainAddDelReply{}) + ctx.MockVpp.MockReply(&l22.BdIPMacAddDelReply{}) ctx.MockVpp.MockReply(&l22.BdIPMacAddDelReply{}) ctx.MockVpp.MockReply(&l22.BridgeDomainDetails{}) ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) @@ -458,6 +464,46 @@ func TestBDConfigurator_ResolveCreatedInterfaceFound(t *testing.T) { Expect(meta.ConfiguredInterfaces[0]).To(Equal("test")) } +// Tests checks that calling Resolve twice with the same interface registers it to the metadata only once +func TestBDConfigurator_ResolveCreatedInterfaceDuplicated(t *testing.T) { + ctx, conn, ifIndexes, _, plugin := bdConfigTestInitialization(t) + defer bdConfigTeardown(conn, plugin) + + // Register bridge domain (as created) + plugin.GetBdIndexes().RegisterName("bd1", 1, &l2idx.BdMetadata{ + BridgeDomain: &l2.BridgeDomains_BridgeDomain{ + Name: "bd1", + Interfaces: []*l2.BridgeDomains_BridgeDomain_Interfaces{ + { + Name: "if1", + }, + }, + }, + }) + + // Register interface (as created) + ifIndexes.RegisterName("if1", 1, nil) // Meta is not needed + + ctx.MockVpp.MockReply(&l22.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l22.BridgeDomainDetails{}) + ctx.MockVpp.MockReply(&l22.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l22.BridgeDomainDetails{}) + + // 1) + err := plugin.ResolveCreatedInterface("if1", 1) + Expect(err).To(BeNil()) + _, meta, found := plugin.GetBdIndexes().LookupIdx("bd1") + Expect(found).To(BeTrue()) + Expect(meta.ConfiguredInterfaces).To(HaveLen(1)) + + // 2) + err = plugin.ResolveCreatedInterface("if1", 1) + Expect(err).To(BeNil()) + _, meta, found = plugin.GetBdIndexes().LookupIdx("bd1") + Expect(found).To(BeTrue()) + Expect(meta.ConfiguredInterfaces).To(HaveLen(1)) +} + // Tests resolving of deleted interface (not found) func TestBDConfigurator_ResolveDeletedInterfaceNotFound(t *testing.T) { _, conn, _, _, plugin := bdConfigTestInitialization(t) @@ -708,7 +754,7 @@ func TestBDConfigurator_TwoBVI(t *testing.T) { } err := plugin.ConfigureBridgeDomain(bdData) - Expect(err).To(BeNil()) + Expect(err).ToNot(BeNil()) // Check for missing index after failed creation _, _, found := plugin.GetBdIndexes().LookupIdx("bd1") diff --git a/plugins/vpp/l2plugin/bd_state.go b/plugins/vpp/l2plugin/bd_state.go index 3b2495a562..4bcac9335d 100644 --- a/plugins/vpp/l2plugin/bd_state.go +++ b/plugins/vpp/l2plugin/bd_state.go @@ -20,6 +20,7 @@ import ( "time" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/plugins/govppmux" l2_api "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" @@ -52,80 +53,86 @@ type BridgeDomainStateUpdater struct { vppCh govppapi.Channel // Notification subscriptions - vppNotifSubs *govppapi.NotifSubscription - vppCountersSubs *govppapi.NotifSubscription - vppCombinedCountersSubs *govppapi.NotifSubscription + vppNotifSubs govppapi.SubscriptionCtx + vppCountersSubs govppapi.SubscriptionCtx + vppCombinedCountersSubs govppapi.SubscriptionCtx notificationChan chan BridgeDomainStateMessage // Injected, do not close here bdIdxChan chan l2idx.BdChangeDto } // Init bridge domain state updater. -func (plugin *BridgeDomainStateUpdater) Init(ctx context.Context, logger logging.PluginLogger, goVppMux govppmux.API, bdIndexes l2idx.BDIndex, swIfIndexes ifaceidx.SwIfIndex, +func (c *BridgeDomainStateUpdater) Init(ctx context.Context, logger logging.PluginLogger, goVppMux govppmux.API, bdIndexes l2idx.BDIndex, swIfIndexes ifaceidx.SwIfIndex, notificationChan chan BridgeDomainStateMessage, publishBdState func(notification *BridgeDomainStateNotification)) (err error) { // Logger - plugin.log = logger.NewLogger("-l2-bd-state") - plugin.log.Info("Initializing BridgeDomainStateUpdater") + c.log = logger.NewLogger("l2-bd-state") // Mappings - plugin.bdIndexes = bdIndexes - plugin.ifIndexes = swIfIndexes + c.bdIndexes = bdIndexes + c.ifIndexes = swIfIndexes // State publisher - plugin.notificationChan = notificationChan - plugin.publishBdState = publishBdState - plugin.bdState = make(map[uint32]*l2.BridgeDomainState_BridgeDomain) + c.notificationChan = notificationChan + c.publishBdState = publishBdState + c.bdState = make(map[uint32]*l2.BridgeDomainState_BridgeDomain) // VPP channel - plugin.vppCh, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppCh, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // Name-to-index watcher - plugin.bdIdxChan = make(chan l2idx.BdChangeDto, 100) - bdIndexes.WatchNameToIdx("bdplugin_bdstate", plugin.bdIdxChan) + c.bdIdxChan = make(chan l2idx.BdChangeDto, 100) + bdIndexes.WatchNameToIdx("bdplugin_bdstate", c.bdIdxChan) var childCtx context.Context - childCtx, plugin.cancel = context.WithCancel(ctx) + childCtx, c.cancel = context.WithCancel(ctx) // Bridge domain notification watcher - go plugin.watchVPPNotifications(childCtx) + go c.watchVPPNotifications(childCtx) + + c.log.Info("Initializing bridge domain state updater") return nil } // watchVPPNotifications watches for delivery of notifications from VPP. -func (plugin *BridgeDomainStateUpdater) watchVPPNotifications(ctx context.Context) { - plugin.wg.Add(1) - defer plugin.wg.Done() +func (c *BridgeDomainStateUpdater) watchVPPNotifications(ctx context.Context) { + c.wg.Add(1) + defer c.wg.Done() - if plugin.notificationChan != nil { - plugin.log.Info("watchVPPNotifications for bridge domain state started") + if c.notificationChan != nil { + c.log.Debugf("bridge domain state updater started to watch VPP notification") } else { - plugin.log.Error("failed to start watchVPPNotifications for bridge domain state") + c.LogError(errors.Errorf("bridge domain state updater failed to start watching VPP notifications")) return } for { select { - case notif, ok := <-plugin.notificationChan: + case notif, ok := <-c.notificationChan: if !ok { continue } bdName := notif.Name switch msg := notif.Message.(type) { case *l2_api.BridgeDomainDetails: - bdState := plugin.processBridgeDomainDetailsNotification(msg, bdName) + bdState, err := c.processBridgeDomainDetailsNotification(msg, bdName) + if err != nil { + // Log error but continue watching + c.LogError(errors.Errorf("bridge domain state updater failed to process notification for %s: %v", + bdName, err)) + continue + } if bdState != nil { - plugin.publishBdState(&BridgeDomainStateNotification{ + c.publishBdState(&BridgeDomainStateNotification{ State: bdState, }) } default: - plugin.log.Debugf("L2Plugin: Ignoring unknown VPP notification: %v", msg) + c.log.Debugf("L2Plugin: Ignoring unknown VPP notification: %v", msg) } - case bdIdxDto := <-plugin.bdIdxChan: + case bdIdxDto := <-c.bdIdxChan: bdIdxDto.Done() case <-ctx.Done(): @@ -135,28 +142,26 @@ func (plugin *BridgeDomainStateUpdater) watchVPPNotifications(ctx context.Contex } } -func (plugin *BridgeDomainStateUpdater) processBridgeDomainDetailsNotification(msg *l2_api.BridgeDomainDetails, name string) *l2.BridgeDomainState_BridgeDomain { +func (c *BridgeDomainStateUpdater) processBridgeDomainDetailsNotification(msg *l2_api.BridgeDomainDetails, name string) (*l2.BridgeDomainState_BridgeDomain, error) { bdState := &l2.BridgeDomainState_BridgeDomain{} // Delete case. if msg.BdID == 0 { if name == "" { - plugin.log.Debugf("invalid bridge domain received: %+v", msg) - return bdState + return nil, errors.Errorf("failed to process bridge domain notification: invalid data") } // Mark index to 0 to be removed, but pass name so that the key can be constructed. bdState.Index = 0 bdState.InternalName = name - return bdState + return bdState, nil } bdState.Index = msg.BdID - name, _, found := plugin.bdIndexes.LookupName(msg.BdID) + name, _, found := c.bdIndexes.LookupName(msg.BdID) if !found { - plugin.log.Warnf("bridge domain index not found, index %v is not in the mapping", msg.BdID) - return bdState + return nil, errors.Errorf("failed to process bridge domain notification: not found in the mapping") } bdState.InternalName = name bdState.InterfaceCount = msg.NSwIfs - name, _, found = plugin.ifIndexes.LookupName(msg.BviSwIfIndex) + name, _, found = c.ifIndexes.LookupName(msg.BviSwIfIndex) if found { bdState.BviInterface = name bdState.BviInterfaceIndex = msg.BviSwIfIndex @@ -164,19 +169,19 @@ func (plugin *BridgeDomainStateUpdater) processBridgeDomainDetailsNotification(m bdState.BviInterface = "not_set" } bdState.L2Params = getBridgeDomainStateParams(msg) - bdState.Interfaces = plugin.getBridgeDomainInterfaces(msg) + bdState.Interfaces = c.getBridgeDomainInterfaces(msg) bdState.LastChange = time.Now().Unix() - return bdState + return bdState, nil } -func (plugin *BridgeDomainStateUpdater) getBridgeDomainInterfaces(msg *l2_api.BridgeDomainDetails) []*l2.BridgeDomainState_BridgeDomain_Interfaces { +func (c *BridgeDomainStateUpdater) getBridgeDomainInterfaces(msg *l2_api.BridgeDomainDetails) []*l2.BridgeDomainState_BridgeDomain_Interfaces { var bdStateInterfaces []*l2.BridgeDomainState_BridgeDomain_Interfaces for _, swIfaceDetails := range msg.SwIfDetails { bdIfaceState := &l2.BridgeDomainState_BridgeDomain_Interfaces{} - name, _, found := plugin.ifIndexes.LookupName(swIfaceDetails.SwIfIndex) + name, _, found := c.ifIndexes.LookupName(swIfaceDetails.SwIfIndex) if !found { - plugin.log.Debugf("Interface name with index %v not found for bridge domain status", swIfaceDetails.SwIfIndex) + c.log.Warnf("Interface name with index %d not found for bridge domain status", swIfaceDetails.SwIfIndex) bdIfaceState.Name = "unknown" } else { bdIfaceState.Name = name @@ -205,3 +210,17 @@ func intToBool(num uint8) bool { } return false } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *BridgeDomainStateUpdater) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/l2plugin/bd_state_test.go b/plugins/vpp/l2plugin/bd_state_test.go index 3cc87c399d..b2ec4acbfb 100644 --- a/plugins/vpp/l2plugin/bd_state_test.go +++ b/plugins/vpp/l2plugin/bd_state_test.go @@ -17,8 +17,9 @@ package l2plugin_test import ( "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/cn-infra/logging/logrus" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -66,7 +67,9 @@ func bdStateTestInitialization(t *testing.T) (*l2plugin.BridgeDomainStateUpdater ctx, _ := context.WithCancel(context.Background()) // Create connection - mockCtx := &vppcallmock.TestCtx{MockVpp: &mock.VppAdapter{}} + mockCtx := &vppcallmock.TestCtx{ + MockVpp: mock.NewVppAdapter(), + } connection, err := core.Connect(mockCtx.MockVpp) Expect(err).To(BeNil()) @@ -118,7 +121,7 @@ func TestBridgeDomainStateUpdater_watchVppNotificationsZeroNoName(t *testing.T) var notif *l2plugin.BridgeDomainStateNotification - Eventually(publishChan).Should(Receive(¬if)) + Eventually(publishChan).ShouldNot(Receive(¬if)) } // Tests notification processing in bridge domain state updater diff --git a/plugins/vpp/l2plugin/data_resync.go b/plugins/vpp/l2plugin/data_resync.go index 7777763434..ec46688ae2 100644 --- a/plugins/vpp/l2plugin/data_resync.go +++ b/plugins/vpp/l2plugin/data_resync.go @@ -17,31 +17,23 @@ package l2plugin import ( "strings" + "github.com/go-errors/errors" "github.com/ligato/vpp-agent/plugins/vpp/l2plugin/l2idx" "github.com/ligato/vpp-agent/plugins/vpp/model/l2" ) // Resync writes missing BDs to the VPP and removes obsolete ones. -func (plugin *BDConfigurator) Resync(nbBDs []*l2.BridgeDomains_BridgeDomain) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC BDs begin.") - // Calculate and log bd resync. - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *BDConfigurator) Resync(nbBDs []*l2.BridgeDomains_BridgeDomain) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Dump current state of the VPP bridge domains - vppBDs, err := plugin.bdHandler.DumpBridgeDomains() + vppBDs, err := c.bdHandler.DumpBridgeDomains() if err != nil { - return err + return errors.Errorf("bridge domain resyc error: failed to dump bridge domains: %v", err) } // Correlate with NB config - var wasErr error for vppBDIdx, vppBD := range vppBDs { // tag is bridge domain name (unique identifier) tag := vppBD.Bd.Name @@ -53,19 +45,16 @@ func (plugin *BDConfigurator) Resync(nbBDs []*l2.BridgeDomains_BridgeDomain) err break } } - // NB config does not exist, VPP bridge domain is obsolete if nbBD == nil { - if err := plugin.deleteBridgeDomain(&l2.BridgeDomains_BridgeDomain{ + if err := c.deleteBridgeDomain(&l2.BridgeDomains_BridgeDomain{ Name: tag, }, vppBDIdx); err != nil { - plugin.log.Error(err) - continue + return errors.Errorf("bridge domain resync error: failed to remove bridge domain %s: %v", tag, err) } - plugin.log.Debugf("RESYNC bridge domain: obsolete config %v (ID %v) removed", tag, vppBDIdx) } else { // Bridge domain exists, validate - valid, recreate := plugin.vppValidateBridgeDomainBVI(nbBD, &l2.BridgeDomains_BridgeDomain{ + valid, recreate := c.vppValidateBridgeDomainBVI(nbBD, &l2.BridgeDomains_BridgeDomain{ Name: tag, Learn: vppBD.Bd.Learn, Flood: vppBD.Bd.Flood, @@ -75,32 +64,26 @@ func (plugin *BDConfigurator) Resync(nbBDs []*l2.BridgeDomains_BridgeDomain) err MacAge: vppBD.Bd.MacAge, }) if !valid { - plugin.log.Errorf("RESYNC bridge domain: new config %v is invalid", nbBD.Name) - continue + return errors.Errorf("bridge domain resync error: bridge domain %s config is invalid", tag) } if recreate { // Internal bridge domain parameters changed, cannot be modified and will be recreated - if err := plugin.deleteBridgeDomain(&l2.BridgeDomains_BridgeDomain{ + if err := c.deleteBridgeDomain(&l2.BridgeDomains_BridgeDomain{ Name: tag, }, vppBDIdx); err != nil { - plugin.log.Error(err) - continue + return errors.Errorf("bridge domain resync error: failed to remove bridge domain %s: %v", tag, err) } - if err := plugin.ConfigureBridgeDomain(nbBD); err != nil { - plugin.log.Error(err) - continue + if err := c.ConfigureBridgeDomain(nbBD); err != nil { + return errors.Errorf("bridge domain resync error: failed to create bridge domain %s: %v", tag, err) } - plugin.log.Debugf("RESYNC bridge domains: config %v recreated", nbBD.Name) continue } // todo currently it is not possible to dump interfaces. In order to prevent BD removal, unset all available interfaces // Dump all interfaces - interfaceMap, err := plugin.ifHandler.DumpInterfaces() + interfaceMap, err := c.ifHandler.DumpInterfaces() if err != nil { - plugin.log.Error(err) - wasErr = err - continue + return errors.Errorf("bridge domain resync error: failed to dump interfaces: %v", err) } // Prepare a list of interface objects with proper name var interfacesToUnset []*l2.BridgeDomains_BridgeDomain_Interfaces @@ -111,69 +94,59 @@ func (plugin *BDConfigurator) Resync(nbBDs []*l2.BridgeDomains_BridgeDomain) err } // Remove interfaces from bridge domain. Attempt to unset interface which does not belong to the bridge domain // does not cause an error - if _, err := plugin.bdHandler.UnsetInterfacesFromBridgeDomain(nbBD.Name, vppBDIdx, interfacesToUnset, plugin.ifIndexes); err != nil { - return err + if _, err := c.bdHandler.UnsetInterfacesFromBridgeDomain(nbBD.Name, vppBDIdx, interfacesToUnset, c.ifIndexes); err != nil { + return errors.Errorf("bridge domain resync error: failed to unset interfaces from bridge domain %s: %v", + nbBD.Name, err) } // Set all new interfaces to the bridge domain // todo there is no need to calculate diff from configured interfaces, because currently all available interfaces are set here - configuredIfs, err := plugin.bdHandler.SetInterfacesToBridgeDomain(nbBD.Name, vppBDIdx, nbBD.Interfaces, plugin.ifIndexes) + configuredIfs, err := c.bdHandler.SetInterfacesToBridgeDomain(nbBD.Name, vppBDIdx, nbBD.Interfaces, c.ifIndexes) if err != nil { - return err + return errors.Errorf("bridge domain resync error: failed to set interfaces from bridge domain %s: %v", + nbBD.Name, err) } // todo VPP does not support ARP dump, they can be only added at this time // Resolve new ARP entries for _, arpEntry := range nbBD.ArpTerminationTable { - if err := plugin.bdHandler.VppAddArpTerminationTableEntry(vppBDIdx, arpEntry.PhysAddress, arpEntry.IpAddress); err != nil { - plugin.log.Error(err) - wasErr = err + if err := c.bdHandler.VppAddArpTerminationTableEntry(vppBDIdx, arpEntry.PhysAddress, arpEntry.IpAddress); err != nil { + return errors.Errorf("bridge domain resync error: failed to add arp termination entry (MAC %s) to bridge domain %s: %v", + arpEntry.PhysAddress, nbBD.Name, err) } } // Register bridge domain - plugin.bdIndexes.RegisterName(nbBD.Name, plugin.bdIDSeq, l2idx.NewBDMetadata(nbBD, configuredIfs)) - plugin.bdIDSeq++ - - plugin.log.Debugf("RESYNC Bridge domain: config %v (ID %v) modified", tag, vppBDIdx) + c.bdIndexes.RegisterName(nbBD.Name, c.bdIDSeq, l2idx.NewBDMetadata(nbBD, configuredIfs)) + c.bdIDSeq++ + c.log.Debugf("Bridge domain resync: %s registered", tag) } } // Configure new bridge domains for _, newBD := range nbBDs { - _, _, found := plugin.bdIndexes.LookupIdx(newBD.Name) + _, _, found := c.bdIndexes.LookupIdx(newBD.Name) if !found { - if err := plugin.ConfigureBridgeDomain(newBD); err != nil { - plugin.log.Error(err) - continue + if err := c.ConfigureBridgeDomain(newBD); err != nil { + return errors.Errorf("bridge domain resync error: failed to configure %s: %v", newBD.Name, err) } - plugin.log.Debugf("RESYNC bridge domains: new config %v added", newBD.Name) } } - return wasErr + return nil } // Resync writes missing FIBs to the VPP and removes obsolete ones. -func (plugin *FIBConfigurator) Resync(nbFIBs []*l2.FibTable_FibEntry) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC FIBs begin.") - // Calculate and log fib resync. - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *FIBConfigurator) Resync(nbFIBs []*l2.FibTable_FibEntry) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Get all FIB entries configured on the VPP - vppFIBs, err := plugin.fibHandler.DumpFIBTableEntries() + vppFIBs, err := c.fibHandler.DumpFIBTableEntries() if err != nil { - return err + return errors.Errorf("FIB resync error: failed to dump FIB table: %v", err) } // Correlate existing config with the NB - var wasErr error for vppFIBmac, vppFIBdata := range vppFIBs { exists, meta := func(nbFIBs []*l2.FibTable_FibEntry) (bool, *l2.FibTable_FibEntry) { for _, nbFIB := range nbFIBs { @@ -182,7 +155,7 @@ func (plugin *FIBConfigurator) Resync(nbFIBs []*l2.FibTable_FibEntry) error { continue } // Bridge domain - bdIdx, _, found := plugin.bdIndexes.LookupIdx(nbFIB.BridgeDomain) + bdIdx, _, found := c.bdIndexes.LookupIdx(nbFIB.BridgeDomain) if !found || vppFIBdata.Meta.BdID != bdIdx { continue } @@ -191,7 +164,7 @@ func (plugin *FIBConfigurator) Resync(nbFIBs []*l2.FibTable_FibEntry) error { continue } // Interface - swIdx, _, found := plugin.ifIndexes.LookupIdx(nbFIB.OutgoingInterface) + swIdx, _, found := c.ifIndexes.LookupIdx(nbFIB.OutgoingInterface) if !found || vppFIBdata.Meta.IfIdx != swIdx { continue } @@ -207,107 +180,104 @@ func (plugin *FIBConfigurator) Resync(nbFIBs []*l2.FibTable_FibEntry) error { // Register existing entries, Remove entries missing in NB config (except non-static) if exists { - plugin.fibIndexes.RegisterName(vppFIBmac, plugin.fibIndexSeq, meta) - plugin.fibIndexSeq++ + c.fibIndexes.RegisterName(vppFIBmac, c.fibIndexSeq, meta) + c.fibIndexSeq++ } else if vppFIBdata.Fib.StaticConfig { // Get appropriate interface/bridge domain names - ifIdx, _, ifFound := plugin.ifIndexes.LookupName(vppFIBdata.Meta.IfIdx) - bdIdx, _, bdFound := plugin.bdIndexes.LookupName(vppFIBdata.Meta.BdID) + ifIdx, _, ifFound := c.ifIndexes.LookupName(vppFIBdata.Meta.IfIdx) + bdIdx, _, bdFound := c.bdIndexes.LookupName(vppFIBdata.Meta.BdID) if !ifFound || !bdFound { // FIB entry cannot be removed without these informations and // it should be removed by the VPP continue } - plugin.Delete(&l2.FibTable_FibEntry{ + if err := c.Delete(&l2.FibTable_FibEntry{ PhysAddress: vppFIBmac, OutgoingInterface: ifIdx, BridgeDomain: bdIdx, }, func(callbackErr error) { if callbackErr != nil { - wasErr = callbackErr + c.log.Error(callbackErr) } - }) - + }); err != nil { + return errors.Errorf("FIB resync error: failed to remove entry %s: %v", vppFIBmac, err) + } } } // Configure all unregistered FIB entries from NB config for _, nbFIB := range nbFIBs { - _, _, found := plugin.fibIndexes.LookupIdx(nbFIB.PhysAddress) + _, _, found := c.fibIndexes.LookupIdx(nbFIB.PhysAddress) if !found { - plugin.Add(nbFIB, func(callbackErr error) { + if err := c.Add(nbFIB, func(callbackErr error) { if callbackErr != nil { - wasErr = callbackErr + c.log.Error(callbackErr) } - }) + }); err != nil { + return errors.Errorf("FIB resync error: failed to add entry %s: %v", nbFIB.PhysAddress, err) + } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC FIBs end.") + c.log.Info("FIB resync done") - return wasErr + return nil } // Resync writes missing XCons to the VPP and removes obsolete ones. -func (plugin *XConnectConfigurator) Resync(nbXConns []*l2.XConnectPairs_XConnectPair) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC XConnect begin.") - // Calculate and log xConnect resync. - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *XConnectConfigurator) Resync(nbXConns []*l2.XConnectPairs_XConnectPair) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Read cross connects from the VPP - vppXConns, err := plugin.xcHandler.DumpXConnectPairs() + vppXConns, err := c.xcHandler.DumpXConnectPairs() if err != nil { - return err + return errors.Errorf("XConnect resync error: failed to dump XConnect data: %v", err) } // Correlate with NB config - var wasErr error for _, vppXConn := range vppXConns { var existsInNB bool var rxIfName, txIfName string for _, nbXConn := range nbXConns { // Find receive and transmit interface - rxIfName, _, rxIfFound := plugin.ifIndexes.LookupName(vppXConn.Meta.ReceiveInterfaceSwIfIdx) - txIfName, _, txIfFound := plugin.ifIndexes.LookupName(vppXConn.Meta.TransmitInterfaceSwIfIdx) + rxIfName, _, rxIfFound := c.ifIndexes.LookupName(vppXConn.Meta.ReceiveInterfaceSwIfIdx) + txIfName, _, txIfFound := c.ifIndexes.LookupName(vppXConn.Meta.TransmitInterfaceSwIfIdx) if !rxIfFound || !txIfFound { continue } if rxIfName == nbXConn.ReceiveInterface && txIfName == nbXConn.TransmitInterface { // NB XConnect correlated with VPP - plugin.xcIndexes.RegisterName(nbXConn.ReceiveInterface, plugin.xcIndexSeq, nbXConn) - plugin.xcIndexSeq++ + c.xcIndexes.RegisterName(nbXConn.ReceiveInterface, c.xcIndexSeq, nbXConn) + c.xcIndexSeq++ + c.log.Debugf("XConnect resync: %s registered", nbXConn.ReceiveInterface) existsInNB = true } } if !existsInNB { - if err := plugin.DeleteXConnectPair(&l2.XConnectPairs_XConnectPair{ + if err := c.DeleteXConnectPair(&l2.XConnectPairs_XConnectPair{ ReceiveInterface: rxIfName, TransmitInterface: txIfName, }); err != nil { - wasErr = err + return errors.Errorf("XConnect resync error: failed to remove XConnect %s-%s: %v", + rxIfName, txIfName, err) } } } // Configure new XConnect pairs for _, nbXConn := range nbXConns { - _, _, found := plugin.xcIndexes.LookupIdx(nbXConn.ReceiveInterface) + _, _, found := c.xcIndexes.LookupIdx(nbXConn.ReceiveInterface) if !found { - if err := plugin.ConfigureXConnectPair(nbXConn); err != nil { - wasErr = err + if err := c.ConfigureXConnectPair(nbXConn); err != nil { + return errors.Errorf("XConnect resync error: failed to configure XConnect %s-%s: %v", + nbXConn.ReceiveInterface, nbXConn.TransmitInterface, err) } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC XConnect end. ", wasErr) + c.log.Debug("XConnect resync done") - return wasErr + return nil } diff --git a/plugins/vpp/l2plugin/fib_config.go b/plugins/vpp/l2plugin/fib_config.go index 7222c457b7..6ce37b04bd 100644 --- a/plugins/vpp/l2plugin/fib_config.go +++ b/plugins/vpp/l2plugin/fib_config.go @@ -15,11 +15,9 @@ package l2plugin import ( - "fmt" - govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -51,210 +49,222 @@ type FIBConfigurator struct { // VPP channels syncChannel govppapi.Channel asyncChannel govppapi.Channel - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init goroutines, mappings, channels.. -func (plugin *FIBConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - bdIndexes l2idx.BDIndex, enableStopwatch bool) (err error) { +func (c *FIBConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, + bdIndexes l2idx.BDIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-l2-fib-conf") - plugin.log.Debug("Initializing L2 Bridge domains") - - // Stopwatch - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("FIBConfigurator", plugin.log) - } + c.log = logger.NewLogger("l2-fib-conf") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.bdIndexes = bdIndexes - plugin.fibIndexes = l2idx.NewFIBIndex(nametoidx.NewNameToIdx(plugin.log, "fib_indexes", nil)) - plugin.addCacheIndexes = l2idx.NewFIBIndex(nametoidx.NewNameToIdx(plugin.log, "fib_add_indexes", nil)) - plugin.delCacheIndexes = l2idx.NewFIBIndex(nametoidx.NewNameToIdx(plugin.log, "fib_del_indexes", nil)) - plugin.fibIndexSeq = 1 + c.ifIndexes = swIfIndexes + c.bdIndexes = bdIndexes + c.fibIndexes = l2idx.NewFIBIndex(nametoidx.NewNameToIdx(c.log, "fib_indexes", nil)) + c.addCacheIndexes = l2idx.NewFIBIndex(nametoidx.NewNameToIdx(c.log, "fib_add_indexes", nil)) + c.delCacheIndexes = l2idx.NewFIBIndex(nametoidx.NewNameToIdx(c.log, "fib_del_indexes", nil)) + c.fibIndexSeq = 1 // VPP channels - plugin.syncChannel, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.syncChannel, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create sync API channel: %v", err) } - plugin.asyncChannel, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.asyncChannel, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create async API channel: %v", err) } // VPP calls helper object - plugin.fibHandler = vppcalls.NewFibVppHandler(plugin.syncChannel, plugin.asyncChannel, plugin.ifIndexes, - plugin.bdIndexes, plugin.log, plugin.stopwatch) + c.fibHandler = vppcalls.NewFibVppHandler(c.syncChannel, c.asyncChannel, c.ifIndexes, c.bdIndexes, c.log) // FIB reply watcher - go plugin.fibHandler.WatchFIBReplies() + go c.fibHandler.WatchFIBReplies() + + c.log.Info("L2 FIB configurator initialized") return nil } // Close vpp channel. -func (plugin *FIBConfigurator) Close() error { - return safeclose.Close(plugin.syncChannel, plugin.asyncChannel) +func (c *FIBConfigurator) Close() error { + if err := safeclose.Close(c.syncChannel, c.asyncChannel); err != nil { + c.LogError(errors.Errorf("failed to safeclose FIB configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *FIBConfigurator) clearMapping() { - plugin.fibIndexes.Clear() - plugin.addCacheIndexes.Clear() - plugin.delCacheIndexes.Clear() +func (c *FIBConfigurator) clearMapping() { + c.fibIndexes.Clear() + c.addCacheIndexes.Clear() + c.delCacheIndexes.Clear() + c.log.Debugf("FIB configurator mapping cleared") } // GetFibIndexes returns FIB memory indexes -func (plugin *FIBConfigurator) GetFibIndexes() l2idx.FIBIndexRW { - return plugin.fibIndexes +func (c *FIBConfigurator) GetFibIndexes() l2idx.FIBIndexRW { + return c.fibIndexes } // GetFibAddCacheIndexes returns FIB memory 'add' cache indexes, for testing purpose -func (plugin *FIBConfigurator) GetFibAddCacheIndexes() l2idx.FIBIndexRW { - return plugin.addCacheIndexes +func (c *FIBConfigurator) GetFibAddCacheIndexes() l2idx.FIBIndexRW { + return c.addCacheIndexes } // GetFibDelCacheIndexes returns FIB memory 'del' cache indexes, for testing purpose -func (plugin *FIBConfigurator) GetFibDelCacheIndexes() l2idx.FIBIndexRW { - return plugin.delCacheIndexes +func (c *FIBConfigurator) GetFibDelCacheIndexes() l2idx.FIBIndexRW { + return c.delCacheIndexes } // Add configures provided FIB input. Every entry has to contain info about MAC address, interface, and bridge domain. // If interface or bridge domain is missing or interface is not a part of the bridge domain, FIB data is cached // and recalled if particular entity is registered/updated. -func (plugin *FIBConfigurator) Add(fib *l2.FibTable_FibEntry, callback func(error)) error { - plugin.log.Infof("Configuring new FIB table entry with MAC %v", fib.PhysAddress) - +func (c *FIBConfigurator) Add(fib *l2.FibTable_FibEntry, callback func(error)) error { if fib.PhysAddress == "" { - return fmt.Errorf("no mac address in FIB entry %s", fib) + return errors.Errorf("failed to configure FIB entry, no MAC address defined") } if fib.BridgeDomain == "" { - return fmt.Errorf("no bridge domain in FIB entry %s", fib) + return errors.Errorf("failed to configure FIB entry (MAC %s), no bridge domain defined", fib.PhysAddress) } // Remove FIB from (del) cache if it's there - _, _, exists := plugin.delCacheIndexes.UnregisterName(fib.PhysAddress) + _, _, exists := c.delCacheIndexes.UnregisterName(fib.PhysAddress) if exists { - plugin.log.Debugf("FIB entry %s was removed from (del) cache before configuration") + c.log.Debugf("FIB entry %s was removed from (del) cache before configuration", fib.PhysAddress) } // Validate required items and move to (add) cache if something's missing - cached, ifIdx, bdIdx := plugin.validateFibRequirements(fib, true) + cached, ifIdx, bdIdx := c.validateFibRequirements(fib, true) if cached { return nil } - plugin.log.Debugf("Configuring FIB entry %s for bridge domain %s and interface %s", fib.PhysAddress, bdIdx, ifIdx) - return plugin.fibHandler.Add(fib.PhysAddress, bdIdx, ifIdx, fib.BridgedVirtualInterface, fib.StaticConfig, + if err := c.fibHandler.Add(fib.PhysAddress, bdIdx, ifIdx, fib.BridgedVirtualInterface, fib.StaticConfig, func(err error) { - // Register - plugin.fibIndexes.RegisterName(fib.PhysAddress, plugin.fibIndexSeq, fib) - plugin.log.Debugf("Fib entry with MAC %v registered", fib.PhysAddress) - plugin.fibIndexSeq++ + if err != nil { + c.log.Errorf("FIB %s callback error: %v", fib.PhysAddress, err) + } else { + // Register + c.fibIndexes.RegisterName(fib.PhysAddress, c.fibIndexSeq, fib) + c.log.Debugf("Fib entry with MAC %s registered", fib.PhysAddress) + c.fibIndexSeq++ + } callback(err) - }) + }); err != nil { + return errors.Errorf("failed to add FIB entry with MAC %s: %v", fib.PhysAddress, err) + } + + c.log.Infof("FIB table entry with MAC %s configured", fib.PhysAddress) + + return nil } // Modify provides changes for FIB entry. Old fib entry is removed (if possible) and a new one is registered // if all the conditions are fulfilled (interface and bridge domain presence), otherwise new configuration is cached. -func (plugin *FIBConfigurator) Modify(oldFib *l2.FibTable_FibEntry, +func (c *FIBConfigurator) Modify(oldFib *l2.FibTable_FibEntry, newFib *l2.FibTable_FibEntry, callback func(error)) error { - plugin.log.Infof("Modifying FIB table entry with MAC %s", newFib.PhysAddress) - // Remove FIB from (add) cache if present - _, _, exists := plugin.addCacheIndexes.UnregisterName(oldFib.PhysAddress) + _, _, exists := c.addCacheIndexes.UnregisterName(oldFib.PhysAddress) if exists { - plugin.log.Debugf("Modified FIB %s removed from (add) cache", oldFib.PhysAddress) + c.log.Debugf("Modified FIB %s removed from (add) cache", oldFib.PhysAddress) } // Remove an old entry if possible - oldIfIdx, _, ifFound := plugin.ifIndexes.LookupIdx(oldFib.OutgoingInterface) + oldIfIdx, _, ifFound := c.ifIndexes.LookupIdx(oldFib.OutgoingInterface) if !ifFound { - plugin.log.Debugf("FIB %s cannot be removed now, interface %s no longer exists", + c.log.Debugf("FIB %s cannot be removed now, interface %s no longer exists", oldFib.PhysAddress, oldFib.OutgoingInterface) } else { - oldBdIdx, _, bdFound := plugin.bdIndexes.LookupIdx(oldFib.BridgeDomain) + oldBdIdx, _, bdFound := c.bdIndexes.LookupIdx(oldFib.BridgeDomain) if !bdFound { - plugin.log.Debugf("FIB %s cannot be removed, bridge domain %s no longer exists", + c.log.Debugf("FIB %s cannot be removed, bridge domain %s no longer exists", oldFib.PhysAddress, oldFib.BridgeDomain) } else { - if err := plugin.fibHandler.Delete(oldFib.PhysAddress, oldBdIdx, oldIfIdx, func(err error) { - plugin.fibIndexes.UnregisterName(oldFib.PhysAddress) + if err := c.fibHandler.Delete(oldFib.PhysAddress, oldBdIdx, oldIfIdx, func(err error) { + c.fibIndexes.UnregisterName(oldFib.PhysAddress) + c.log.Debugf("FIB %s unregistered", oldFib.PhysAddress) callback(err) }); err != nil { - // Log error but continue - plugin.log.Errorf("FIB modify: failed to remove entry %s", oldFib.PhysAddress) + return errors.Errorf("failed to delete FIB entry %s: %v", oldFib.PhysAddress, err) } - plugin.addCacheIndexes.UnregisterName(oldFib.PhysAddress) + c.addCacheIndexes.UnregisterName(oldFib.PhysAddress) + c.log.Debugf("FIB %s unregistered from (add) cache", oldFib.PhysAddress) } } - cached, ifIdx, bdIdx := plugin.validateFibRequirements(newFib, true) + cached, ifIdx, bdIdx := c.validateFibRequirements(newFib, true) if cached { return nil } - return plugin.fibHandler.Add(newFib.PhysAddress, bdIdx, ifIdx, newFib.BridgedVirtualInterface, newFib.StaticConfig, + if err := c.fibHandler.Add(newFib.PhysAddress, bdIdx, ifIdx, newFib.BridgedVirtualInterface, newFib.StaticConfig, func(err error) { - plugin.fibIndexes.RegisterName(oldFib.PhysAddress, plugin.fibIndexSeq, newFib) - plugin.fibIndexSeq++ + if err != nil { + c.log.Errorf("FIB %s callback error: %v", newFib.PhysAddress, err) + } else { + // Register + c.fibIndexes.RegisterName(newFib.PhysAddress, c.fibIndexSeq, newFib) + c.log.Debugf("Fib entry with MAC %s registered", newFib.PhysAddress) + c.fibIndexSeq++ + } callback(err) - }) + }); err != nil { + return errors.Errorf("failed to create FIB entry %s: %v", oldFib.PhysAddress, err) + } + + c.log.Infof("FIB table entry with MAC %s modified", newFib.PhysAddress) + + return nil } // Delete removes FIB table entry. The request to be successful, both interface and bridge domain indices // have to be available. Request does nothing without this info. If interface (or bridge domain) was removed before, // provided FIB data is just unregistered and agent assumes, that VPP removed FIB entry itself. -func (plugin *FIBConfigurator) Delete(fib *l2.FibTable_FibEntry, callback func(error)) error { - plugin.log.Infof("Deleting FIB table entry with MAC %s", fib.PhysAddress) - +func (c *FIBConfigurator) Delete(fib *l2.FibTable_FibEntry, callback func(error)) error { // Check if FIB is in cache (add). In such a case, just remove it. - _, _, exists := plugin.addCacheIndexes.UnregisterName(fib.PhysAddress) + _, _, exists := c.addCacheIndexes.UnregisterName(fib.PhysAddress) if exists { + c.log.Infof("FIB %s does not exist, unregistered from (add) cache", fib.PhysAddress) return nil } // Check whether the FIB can be actually removed - cached, ifIdx, bdIdx := plugin.validateFibRequirements(fib, false) + cached, ifIdx, bdIdx := c.validateFibRequirements(fib, false) if cached { return nil } // Unregister from (del) cache and from indexes - plugin.delCacheIndexes.UnregisterName(fib.PhysAddress) - plugin.fibIndexes.UnregisterName(fib.PhysAddress) - plugin.log.Debugf("FIB %s removed from mappings", fib.PhysAddress) + c.delCacheIndexes.UnregisterName(fib.PhysAddress) + c.log.Debugf("FIB %s unregistered from (del) cache", fib.PhysAddress) + c.fibIndexes.UnregisterName(fib.PhysAddress) + c.log.Debugf("FIB %s removed from mapping", fib.PhysAddress) - return plugin.fibHandler.Delete(fib.PhysAddress, bdIdx, ifIdx, func(err error) { + if err := c.fibHandler.Delete(fib.PhysAddress, bdIdx, ifIdx, func(err error) { callback(err) - }) + }); err != nil { + return errors.Errorf("failed to delete FIB entry %s: %v", fib.PhysAddress, err) + } + + c.log.Infof("FIB table entry with MAC %s removed", fib.PhysAddress) + + return nil } // ResolveCreatedInterface uses FIB cache to additionally configure any FIB entries for this interface. Bridge domain // is checked for existence. If resolution is successful, new FIB entry is configured, registered and removed from cache. -func (plugin *FIBConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32, callback func(error)) error { - plugin.log.Infof("FIB configurator: resolving registered interface %s", ifName) - - if err := plugin.resolveRegisteredItem(callback); err != nil { +func (c *FIBConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32, callback func(error)) error { + if err := c.resolveRegisteredItem(callback); err != nil { return err } - - plugin.log.Infof("FIB: resolution of created interface %s is done", ifName) return nil } // ResolveDeletedInterface handles removed interface. In that case, FIB entry remains on the VPP but it is not possible // to delete it. -func (plugin *FIBConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32, callback func(error)) error { - plugin.log.Infof("FIB configurator: resolving unregistered interface %s", ifName) - - count := plugin.resolveUnRegisteredItem(ifName, "") +func (c *FIBConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32, callback func(error)) error { + count := c.resolveUnRegisteredItem(ifName, "") - plugin.log.Infof("%d FIB entries belongs to removed interface %s. These FIBs cannot be deleted or changed while interface is missing", + c.log.Debugf("%d FIB entries belongs to removed interface %s. These FIBs cannot be deleted or changed while interface is missing", count, ifName) return nil @@ -263,40 +273,30 @@ func (plugin *FIBConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint // ResolveCreatedBridgeDomain uses FIB cache to configure any FIB entries for this bridge domain. // Required interface is checked for existence. If resolution is successful, new FIB entry is configured, // registered and removed from cache. -func (plugin *FIBConfigurator) ResolveCreatedBridgeDomain(bdName string, bdID uint32, callback func(error)) error { - plugin.log.Infof("FIB configurator: resolving registered bridge domain %s", bdName) - - if err := plugin.resolveRegisteredItem(callback); err != nil { +func (c *FIBConfigurator) ResolveCreatedBridgeDomain(bdName string, bdID uint32, callback func(error)) error { + if err := c.resolveRegisteredItem(callback); err != nil { return err } - - plugin.log.Infof("FIB: resolution of created bridge domain %s is done", bdName) return nil } // ResolveUpdatedBridgeDomain handles case where metadata of bridge domain are updated. If interface-bridge domain pair // required for a FIB entry was not bound together, but it was changed in the bridge domain later, FIB is resolved and // eventually configred here. -func (plugin *FIBConfigurator) ResolveUpdatedBridgeDomain(bdName string, bdID uint32, callback func(error)) error { - plugin.log.Infof("FIB configurator: resolving updated bridge domain %s", bdName) - +func (c *FIBConfigurator) ResolveUpdatedBridgeDomain(bdName string, bdID uint32, callback func(error)) error { // Updated bridge domain is resolved the same as new (metadata were changed) - if err := plugin.resolveRegisteredItem(callback); err != nil { + if err := c.resolveRegisteredItem(callback); err != nil { return err } - - plugin.log.Infof("FIB: resolution of updated bridge domain %s is done", bdName) return nil } // ResolveDeletedBridgeDomain handles removed bridge domain. In that case, FIB entry remains on the VPP but it is not possible // to delete it. -func (plugin *FIBConfigurator) ResolveDeletedBridgeDomain(bdName string, bdID uint32, callback func(error)) error { - plugin.log.Infof("FIB configurator: resolving unregistered bridge domain %s", bdName) +func (c *FIBConfigurator) ResolveDeletedBridgeDomain(bdName string, bdID uint32, callback func(error)) error { + count := c.resolveUnRegisteredItem("", bdName) - count := plugin.resolveUnRegisteredItem("", bdName) - - plugin.log.Infof("%d FIB entries belongs to removed bridge domain %s. These FIBs cannot be deleted or changed while bridge domain is missing", + c.log.Debugf("%d FIB entries belongs to removed bridge domain %s. These FIBs cannot be deleted or changed while bridge domain is missing", count, bdName) return nil @@ -304,67 +304,72 @@ func (plugin *FIBConfigurator) ResolveDeletedBridgeDomain(bdName string, bdID ui // Common method called in either interface was created or bridge domain was created or updated. It tries to // validate every 'add' or 'del' cached entry and configure/un-configure entries which are now possible -func (plugin *FIBConfigurator) resolveRegisteredItem(callback func(error)) error { - var wasErr error +func (c *FIBConfigurator) resolveRegisteredItem(callback func(error)) error { // First, remove FIBs which cannot be removed due to missing interface - for _, cachedFibID := range plugin.delCacheIndexes.GetMapping().ListNames() { - _, fibData, found := plugin.delCacheIndexes.LookupIdx(cachedFibID) + for _, cachedFibID := range c.delCacheIndexes.GetMapping().ListNames() { + _, fibData, found := c.delCacheIndexes.LookupIdx(cachedFibID) if !found || fibData == nil { // Should not happen continue } // Re-validate FIB, configure or keep cached - cached, ifIdx, bdIdx := plugin.validateFibRequirements(fibData, false) + cached, ifIdx, bdIdx := c.validateFibRequirements(fibData, false) if cached { continue } - if err := plugin.fibHandler.Delete(cachedFibID, bdIdx, ifIdx, func(err error) { - plugin.log.Debugf("Deleting cached obsolete FIB %s", cachedFibID) + if err := c.fibHandler.Delete(cachedFibID, bdIdx, ifIdx, func(err error) { // Handle registration - plugin.fibIndexes.UnregisterName(cachedFibID) + c.fibIndexes.UnregisterName(cachedFibID) + c.log.Debugf("Obsolete FIB %s unregistered", cachedFibID) callback(err) }); err != nil { - plugin.log.Error(err) - wasErr = err + return errors.Errorf("failed to remove obsolete FIB %s: %v", cachedFibID, err) } - plugin.delCacheIndexes.UnregisterName(cachedFibID) - plugin.log.Debugf("FIB %s removed from 'del' cache", cachedFibID) + c.delCacheIndexes.UnregisterName(cachedFibID) + c.log.Debugf("FIB %s removed from (del) cache", cachedFibID) + + c.log.Infof("Cached FIB %s removed", cachedFibID) } // Configure un-configurable FIBs - for _, cachedFibID := range plugin.addCacheIndexes.GetMapping().ListNames() { - _, fibData, found := plugin.addCacheIndexes.LookupIdx(cachedFibID) + for _, cachedFibID := range c.addCacheIndexes.GetMapping().ListNames() { + _, fibData, found := c.addCacheIndexes.LookupIdx(cachedFibID) if !found || fibData == nil { // Should not happen continue } // Re-validate FIB, configure or keep cached - cached, ifIdx, bdIdx := plugin.validateFibRequirements(fibData, true) + cached, ifIdx, bdIdx := c.validateFibRequirements(fibData, true) if cached { continue } - if err := plugin.fibHandler.Add(cachedFibID, bdIdx, ifIdx, fibData.BridgedVirtualInterface, fibData.StaticConfig, func(err error) { - plugin.log.Infof("Configuring cached FIB %s", cachedFibID) - // Handle registration - plugin.fibIndexes.RegisterName(cachedFibID, plugin.fibIndexSeq, fibData) - plugin.fibIndexSeq++ + if err := c.fibHandler.Add(cachedFibID, bdIdx, ifIdx, fibData.BridgedVirtualInterface, fibData.StaticConfig, func(err error) { + if err != nil { + c.log.Errorf("FIB %s callback error: %v", cachedFibID, err) + } else { + // Register + c.fibIndexes.RegisterName(cachedFibID, c.fibIndexSeq, fibData) + c.log.Debugf("Fib entry with MAC %s registered", cachedFibID) + c.fibIndexSeq++ + } callback(err) }); err != nil { - plugin.log.Error(err) - wasErr = err + return errors.Errorf("failed to add FIB %s: %v", cachedFibID, err) } - plugin.addCacheIndexes.UnregisterName(cachedFibID) - plugin.log.Debugf("FIB %s removed from 'add' cache", cachedFibID) + c.addCacheIndexes.UnregisterName(cachedFibID) + c.log.Debugf("FIB %s removed from (add) cache", cachedFibID) + + c.log.Infof("Cached FIB %s added", cachedFibID) } - return wasErr + return nil } // Just informative method which returns a count of entries affected by change -func (plugin *FIBConfigurator) resolveUnRegisteredItem(ifName, bdName string) int { +func (c *FIBConfigurator) resolveUnRegisteredItem(ifName, bdName string) int { var counter int - for _, fib := range plugin.fibIndexes.GetMapping().ListNames() { - _, meta, found := plugin.fibIndexes.LookupIdx(fib) + for _, fib := range c.fibIndexes.GetMapping().ListNames() { + _, meta, found := c.fibIndexes.LookupIdx(fib) if !found || meta == nil { // Should not happen continue @@ -384,26 +389,27 @@ func (plugin *FIBConfigurator) resolveUnRegisteredItem(ifName, bdName string) in return counter } -func (plugin *FIBConfigurator) validateFibRequirements(fib *l2.FibTable_FibEntry, add bool) (cached bool, ifIdx, bdIdx uint32) { +func (c *FIBConfigurator) validateFibRequirements(fib *l2.FibTable_FibEntry, add bool) (cached bool, ifIdx, bdIdx uint32) { var ifFound, bdFound, tied bool // Check interface presence - ifIdx, _, ifFound = plugin.ifIndexes.LookupIdx(fib.OutgoingInterface) + ifIdx, _, ifFound = c.ifIndexes.LookupIdx(fib.OutgoingInterface) if !ifFound { - plugin.log.Infof("FIB entry %s is configured for interface %s which does not exists", + c.log.Debugf("FIB entry %s is configured for interface %s which does not exists", fib.PhysAddress, fib.OutgoingInterface) } // Check bridge domain presence - bdIdx, _, bdFound = plugin.bdIndexes.LookupIdx(fib.BridgeDomain) + var bdMeta *l2idx.BdMetadata + bdIdx, bdMeta, bdFound = c.bdIndexes.LookupIdx(fib.BridgeDomain) if !bdFound { - plugin.log.Infof("FIB entry %s is configured for bridge domain %s which does not exists", + c.log.Debugf("FIB entry %s is configured for bridge domain %s which does not exists", fib.PhysAddress, fib.BridgeDomain) } // Check that interface is tied with bridge domain. If interfaces are not found, metadata do not exists. // They can be updated later, configurator will handle it, but they should not be missing - if bdInterfaces, found := plugin.bdIndexes.LookupConfiguredIfsForBd(fib.BridgeDomain); found { - for _, configured := range bdInterfaces { + if bdMeta != nil { + for _, configured := range bdMeta.ConfiguredInterfaces { if configured == fib.OutgoingInterface { tied = true break @@ -415,23 +421,25 @@ func (plugin *FIBConfigurator) validateFibRequirements(fib *l2.FibTable_FibEntry if !bdFound || !ifFound || !tied { if add { // FIB table entry is cached and will be configured again when all required items are available - _, _, found := plugin.addCacheIndexes.LookupIdx(fib.PhysAddress) + _, _, found := c.addCacheIndexes.LookupIdx(fib.PhysAddress) if !found { - plugin.addCacheIndexes.RegisterName(fib.PhysAddress, plugin.fibIndexSeq, fib) - plugin.log.Debugf("FIB entry with name %s added to cache (add)", fib.PhysAddress) - plugin.fibIndexSeq++ + c.addCacheIndexes.RegisterName(fib.PhysAddress, c.fibIndexSeq, fib) + c.log.Debugf("FIB entry with name %s added to cache (add)", fib.PhysAddress) + c.fibIndexSeq++ } else { - plugin.addCacheIndexes.UpdateMetadata(fib.PhysAddress, fib) + c.addCacheIndexes.UpdateMetadata(fib.PhysAddress, fib) + c.log.Debugf("FIB entry %s metadata updated", fib.PhysAddress) } } else { // FIB table entry is cached and will be removed again when all required items are available - _, _, found := plugin.delCacheIndexes.LookupIdx(fib.PhysAddress) + _, _, found := c.delCacheIndexes.LookupIdx(fib.PhysAddress) if !found { - plugin.delCacheIndexes.RegisterName(fib.PhysAddress, plugin.fibIndexSeq, fib) - plugin.log.Debugf("FIB entry with name %s added to cache (del)", fib.PhysAddress) - plugin.fibIndexSeq++ + c.delCacheIndexes.RegisterName(fib.PhysAddress, c.fibIndexSeq, fib) + c.log.Debugf("FIB entry with name %s added to cache (del)", fib.PhysAddress) + c.fibIndexSeq++ } else { - plugin.delCacheIndexes.UpdateMetadata(fib.PhysAddress, fib) + c.delCacheIndexes.UpdateMetadata(fib.PhysAddress, fib) + c.log.Debugf("FIB entry %s metadata updated", fib.PhysAddress) } } cached = true @@ -439,3 +447,17 @@ func (plugin *FIBConfigurator) validateFibRequirements(fib *l2.FibTable_FibEntry return } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *FIBConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/l2plugin/fib_config_test.go b/plugins/vpp/l2plugin/fib_config_test.go index d03282330d..b050373085 100644 --- a/plugins/vpp/l2plugin/fib_config_test.go +++ b/plugins/vpp/l2plugin/fib_config_test.go @@ -19,8 +19,9 @@ import ( "testing" "time" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" l2Api "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" @@ -1102,7 +1103,7 @@ func blockingResolveUpdatedBridgeDomain(plugin *l2plugin.FIBConfigurator, bdName func fibTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l2plugin.FIBConfigurator, ifaceidx.SwIfIndexRW, l2idx.BDIndexRW) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -1114,7 +1115,7 @@ func fibTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l2plug bdIndexes := l2idx.NewBDIndex(nametoidx.NewNameToIdx(log, "fib-bd", nil)) // Configurator plugin := &l2plugin.FIBConfigurator{} - err = plugin.Init(logging.ForPlugin("test-log"), connection, swIfIndexes, bdIndexes, false) + err = plugin.Init(logging.ForPlugin("test-log"), connection, swIfIndexes, bdIndexes) Expect(err).To(BeNil()) return ctx, connection, plugin, swIfIndexes, bdIndexes diff --git a/plugins/vpp/l2plugin/l2idx/bd_index.go b/plugins/vpp/l2plugin/l2idx/bd_index.go index 7631437da2..26323f67d0 100644 --- a/plugins/vpp/l2plugin/l2idx/bd_index.go +++ b/plugins/vpp/l2plugin/l2idx/bd_index.go @@ -34,9 +34,6 @@ type BDIndex interface { // LookupBdForInterface looks up for bridge domain the interface belongs to LookupBdForInterface(ifName string) (bdIdx uint32, bd *l2.BridgeDomains_BridgeDomain, bdIf *l2.BridgeDomains_BridgeDomain_Interfaces, exists bool) - // LookupConfiguredIfsForBd return a list of configured interfaces for bridge domain - LookupConfiguredIfsForBd(bdName string) ([]string, bool) - // WatchNameToIdx allows to subscribe for watching changes in bdIndex mapping WatchNameToIdx(subscriber string, pluginChannel chan BdChangeDto) } @@ -176,19 +173,6 @@ func (bdi *bdIndex) LookupBdForInterface(ifName string) (bdIdx uint32, bd *l2.Br return bdIdx, bd, nil, false } -// LookupConfiguredIfsForBd returns a list of configured interfaces stored in metadata -func (bdi *bdIndex) LookupConfiguredIfsForBd(bdName string) ([]string, bool) { - _, meta, exists := bdi.mapping.LookupIdx(bdName) - if !exists || meta == nil { - return nil, false - } - bdMeta := castBdMetadata(meta) - if bdMeta == nil { - return nil, false - } - return bdMeta.ConfiguredInterfaces, true -} - // WatchNameToIdx allows to subscribe for watching changes in bdIndex mapping. func (bdi *bdIndex) WatchNameToIdx(subscriber string, pluginChannel chan BdChangeDto) { ch := make(chan idxvpp.NameToIdxDto) diff --git a/plugins/vpp/l2plugin/l2idx/bd_index_test.go b/plugins/vpp/l2plugin/l2idx/bd_index_test.go index de9fe5b66b..fab66b46a1 100644 --- a/plugins/vpp/l2plugin/l2idx/bd_index_test.go +++ b/plugins/vpp/l2plugin/l2idx/bd_index_test.go @@ -356,24 +356,24 @@ func TestLookupConfiguredIfsForBd(t *testing.T) { } // Return correct list of configured interfaces for every bridge domain - configured, exists := bdIndex.LookupConfiguredIfsForBd(bdName0) + _, bdMeta, exists := bdIndex.LookupIdx(bdName0) Expect(exists).To(BeTrue()) - Expect(configured).To(HaveLen(2)) - Expect(configured).To(ContainElement(ifaceAName)) - Expect(configured).To(ContainElement(ifaceBName)) + Expect(bdMeta.ConfiguredInterfaces).To(HaveLen(2)) + Expect(bdMeta.ConfiguredInterfaces).To(ContainElement(ifaceAName)) + Expect(bdMeta.ConfiguredInterfaces).To(ContainElement(ifaceBName)) - configured, exists = bdIndex.LookupConfiguredIfsForBd(bdName1) + _, bdMeta, exists = bdIndex.LookupIdx(bdName1) Expect(exists).To(BeTrue()) - Expect(configured).To(HaveLen(1)) - Expect(configured).To(ContainElement(ifaceCName)) + Expect(bdMeta.ConfiguredInterfaces).To(HaveLen(1)) + Expect(bdMeta.ConfiguredInterfaces).To(ContainElement(ifaceCName)) - configured, exists = bdIndex.LookupConfiguredIfsForBd(bdName2) - Expect(exists).To(BeFalse()) - Expect(configured).To(BeNil()) + _, bdMeta, exists = bdIndex.LookupIdx(bdName2) + Expect(exists).To(BeTrue()) + Expect(bdMeta).To(BeNil()) - configured, exists = bdIndex.LookupConfiguredIfsForBd("") + _, bdMeta, exists = bdIndex.LookupIdx("") Expect(exists).To(BeFalse()) - Expect(configured).To(BeNil()) + Expect(bdMeta).To(BeNil()) } func TestWatchNameToIdx(t *testing.T) { diff --git a/plugins/vpp/l2plugin/vppcalls/api_vppcalls.go b/plugins/vpp/l2plugin/vppcalls/api_vppcalls.go index cb2cb69624..97ca3c23be 100644 --- a/plugins/vpp/l2plugin/vppcalls/api_vppcalls.go +++ b/plugins/vpp/l2plugin/vppcalls/api_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( govppapi "git.fd.io/govpp.git/api" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/vpp/l2plugin/l2idx" "github.com/ligato/vpp-agent/plugins/vpp/model/l2" @@ -35,6 +34,9 @@ type BridgeDomainVppWrite interface { VppAddBridgeDomain(bdIdx uint32, bd *l2.BridgeDomains_BridgeDomain) error // VppDeleteBridgeDomain removes existing bridge domain. VppDeleteBridgeDomain(bdIdx uint32) error + // SetInterfaceToBridgeDomain sets single interface to bridge domain. Interface name is returned if configured. + SetInterfaceToBridgeDomain(bdName string, bdIdx uint32, bdIf *l2.BridgeDomains_BridgeDomain_Interfaces, + swIfIndices ifaceidx.SwIfIndex) (iface string, wasErr error) // SetInterfacesToBridgeDomain attempts to set all provided interfaces to bridge domain. It returns a list of interfaces // which were successfully set. SetInterfacesToBridgeDomain(bdName string, bdIdx uint32, bdIfs []*l2.BridgeDomains_BridgeDomain_Interfaces, @@ -110,7 +112,6 @@ type XConnectVppRead interface { // BridgeDomainVppHandler is accessor for bridge domain-related vppcalls methods type BridgeDomainVppHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel ifIndexes ifaceidx.SwIfIndex log logging.Logger @@ -118,7 +119,6 @@ type BridgeDomainVppHandler struct { // FibVppHandler is accessor for FIB-related vppcalls methods type FibVppHandler struct { - stopwatch *measure.Stopwatch syncCallsChannel govppapi.Channel asyncCallsChannel govppapi.Channel requestChan chan *FibLogicalReq @@ -129,17 +129,15 @@ type FibVppHandler struct { // XConnectVppHandler is accessor for cross-connect-related vppcalls methods type XConnectVppHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel ifIndexes ifaceidx.SwIfIndex log logging.Logger } // NewBridgeDomainVppHandler creates new instance of bridge domain vppcalls handler -func NewBridgeDomainVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *BridgeDomainVppHandler { +func NewBridgeDomainVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *BridgeDomainVppHandler { return &BridgeDomainVppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, log: log, } @@ -147,12 +145,11 @@ func NewBridgeDomainVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.Sw // NewFibVppHandler creates new instance of FIB vppcalls handler func NewFibVppHandler(syncChan, asyncChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, bdIndexes l2idx.BDIndex, - log logging.Logger, stopwatch *measure.Stopwatch) *FibVppHandler { + log logging.Logger) *FibVppHandler { return &FibVppHandler{ syncCallsChannel: syncChan, asyncCallsChannel: asyncChan, requestChan: make(chan *FibLogicalReq), - stopwatch: stopwatch, ifIndexes: ifIndexes, bdIndexes: bdIndexes, log: log, @@ -160,10 +157,9 @@ func NewFibVppHandler(syncChan, asyncChan govppapi.Channel, ifIndexes ifaceidx.S } // NewXConnectVppHandler creates new instance of cross connect vppcalls handler -func NewXConnectVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *XConnectVppHandler { +func NewXConnectVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *XConnectVppHandler { return &XConnectVppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, log: log, } diff --git a/plugins/vpp/l2plugin/vppcalls/arp_term_vppcalls.go b/plugins/vpp/l2plugin/vppcalls/arp_term_vppcalls.go index 59cac9bdb4..cf35a687a6 100644 --- a/plugins/vpp/l2plugin/vppcalls/arp_term_vppcalls.go +++ b/plugins/vpp/l2plugin/vppcalls/arp_term_vppcalls.go @@ -17,18 +17,13 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/cn-infra/logging" "github.com/ligato/cn-infra/utils/addrs" l2ba "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" ) -func (handler *BridgeDomainVppHandler) callBdIPMacAddDel(isAdd bool, bdID uint32, mac string, ip string) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.BdIPMacAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BridgeDomainVppHandler) callBdIPMacAddDel(isAdd bool, bdID uint32, mac string, ip string) error { req := &l2ba.BdIPMacAddDel{ BdID: bdID, IsAdd: boolToUint(isAdd), @@ -54,7 +49,7 @@ func (handler *BridgeDomainVppHandler) callBdIPMacAddDel(isAdd bool, bdID uint32 } reply := &l2ba.BdIPMacAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -64,29 +59,29 @@ func (handler *BridgeDomainVppHandler) callBdIPMacAddDel(isAdd bool, bdID uint32 } // VppAddArpTerminationTableEntry implements bridge domain handler. -func (handler *BridgeDomainVppHandler) VppAddArpTerminationTableEntry(bdID uint32, mac string, ip string) error { - handler.log.Info("Adding ARP termination entry") +func (h *BridgeDomainVppHandler) VppAddArpTerminationTableEntry(bdID uint32, mac string, ip string) error { + h.log.Info("Adding ARP termination entry") - err := handler.callBdIPMacAddDel(true, bdID, mac, ip) + err := h.callBdIPMacAddDel(true, bdID, mac, ip) if err != nil { return err } - handler.log.WithFields(logging.Fields{"bdID": bdID, "MAC": mac, "IP": ip}).Debug("ARP termination entry added") + h.log.WithFields(logging.Fields{"bdID": bdID, "MAC": mac, "IP": ip}).Debug("ARP termination entry added") return nil } // VppRemoveArpTerminationTableEntry implements bridge domain handler. -func (handler *BridgeDomainVppHandler) VppRemoveArpTerminationTableEntry(bdID uint32, mac string, ip string) error { - handler.log.Info("Removing ARP termination entry") +func (h *BridgeDomainVppHandler) VppRemoveArpTerminationTableEntry(bdID uint32, mac string, ip string) error { + h.log.Info("Removing ARP termination entry") - err := handler.callBdIPMacAddDel(false, bdID, mac, ip) + err := h.callBdIPMacAddDel(false, bdID, mac, ip) if err != nil { return err } - handler.log.WithFields(logging.Fields{"bdID": bdID, "MAC": mac, "IP": ip}).Debug("ARP termination entry removed") + h.log.WithFields(logging.Fields{"bdID": bdID, "MAC": mac, "IP": ip}).Debug("ARP termination entry removed") return nil } diff --git a/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls.go b/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls.go index bcc0fee197..ef81ac9eb8 100644 --- a/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls.go +++ b/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls.go @@ -16,18 +16,13 @@ package vppcalls import ( "fmt" - "time" l2ba "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" "github.com/ligato/vpp-agent/plugins/vpp/model/l2" ) // VppAddBridgeDomain implements bridge domain handler. -func (handler *BridgeDomainVppHandler) VppAddBridgeDomain(bdIdx uint32, bd *l2.BridgeDomains_BridgeDomain) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.BridgeDomainAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BridgeDomainVppHandler) VppAddBridgeDomain(bdIdx uint32, bd *l2.BridgeDomains_BridgeDomain) error { req := &l2ba.BridgeDomainAddDel{ IsAdd: 1, BdID: bdIdx, @@ -41,7 +36,7 @@ func (handler *BridgeDomainVppHandler) VppAddBridgeDomain(bdIdx uint32, bd *l2.B } reply := &l2ba.BridgeDomainAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -51,18 +46,14 @@ func (handler *BridgeDomainVppHandler) VppAddBridgeDomain(bdIdx uint32, bd *l2.B } // VppDeleteBridgeDomain implements bridge domain handler. -func (handler *BridgeDomainVppHandler) VppDeleteBridgeDomain(bdIdx uint32) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.BridgeDomainAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BridgeDomainVppHandler) VppDeleteBridgeDomain(bdIdx uint32) error { req := &l2ba.BridgeDomainAddDel{ IsAdd: 0, BdID: bdIdx, } reply := &l2ba.BridgeDomainAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) diff --git a/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls_test.go b/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls_test.go index 216ae53c92..b49818c593 100644 --- a/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls_test.go +++ b/plugins/vpp/l2plugin/vppcalls/bridge_domain_vppcalls_test.go @@ -139,6 +139,6 @@ func bdTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.BridgeDomainVppAP ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") ifIndex := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "bd-test-ifidx", nil)) - bdHandler := vppcalls.NewBridgeDomainVppHandler(ctx.MockChannel, ifIndex, log, nil) + bdHandler := vppcalls.NewBridgeDomainVppHandler(ctx.MockChannel, ifIndex, log) return ctx, bdHandler, ifIndex } diff --git a/plugins/vpp/l2plugin/vppcalls/dump_vppcalls.go b/plugins/vpp/l2plugin/vppcalls/dump_vppcalls.go index 15996896d1..b36871e5e8 100644 --- a/plugins/vpp/l2plugin/vppcalls/dump_vppcalls.go +++ b/plugins/vpp/l2plugin/vppcalls/dump_vppcalls.go @@ -17,7 +17,8 @@ package vppcalls import ( "bytes" "net" - "time" + + "github.com/go-errors/errors" l2ba "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" l2nb "github.com/ligato/vpp-agent/plugins/vpp/model/l2" @@ -37,16 +38,18 @@ type BridgeDomainMeta struct { } // DumpBridgeDomains implements bridge domain handler. -func (handler *BridgeDomainVppHandler) DumpBridgeDomains() (map[uint32]*BridgeDomainDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.BridgeDomainDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) +func (h *BridgeDomainVppHandler) DumpBridgeDomains() (map[uint32]*BridgeDomainDetails, error) { + // At first prepare bridge domain ARP termination table which needs to be dumped separately + bdArpTab, err := h.dumpBridgeDomainMacTable() + if err != nil { + return nil, errors.Errorf("failed to dump arp termination table: %v", err) + } // map for the resulting BDs bds := make(map[uint32]*BridgeDomainDetails) // First, dump all interfaces to create initial data. - reqCtx := handler.callsChannel.SendMultiRequest(&l2ba.BridgeDomainDump{BdID: ^uint32(0)}) + reqCtx := h.callsChannel.SendMultiRequest(&l2ba.BridgeDomainDump{BdID: ^uint32(0)}) for { bdDetails := &l2ba.BridgeDomainDetails{} @@ -75,11 +78,11 @@ func (handler *BridgeDomainVppHandler) DumpBridgeDomains() (map[uint32]*BridgeDo }, } - // bridge domain interfaces and metadata + // Bridge domain interfaces and metadata for _, iface := range bdDetails.SwIfDetails { - ifName, _, exists := handler.ifIndexes.LookupName(iface.SwIfIndex) + ifName, _, exists := h.ifIndexes.LookupName(iface.SwIfIndex) if !exists { - handler.log.Warnf("Bridge domain dump: interface name for index %d not found", iface.SwIfIndex) + h.log.Warnf("Bridge domain dump: interface name for index %d not found", iface.SwIfIndex) continue } // Bvi @@ -96,20 +99,21 @@ func (handler *BridgeDomainVppHandler) DumpBridgeDomains() (map[uint32]*BridgeDo SplitHorizonGroup: uint32(iface.Shg), }) } + // Add ARP termination entries + arpTable, ok := bdArpTab[bdDetails.BdID] + if ok { + bds[bdDetails.BdID].Bd.ArpTerminationTable = arpTable + } } return bds, nil } // DumpBridgeDomainIDs implements bridge domain handler. -func (handler *BridgeDomainVppHandler) DumpBridgeDomainIDs() ([]uint32, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.BridgeDomainDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *BridgeDomainVppHandler) DumpBridgeDomainIDs() ([]uint32, error) { req := &l2ba.BridgeDomainDump{BdID: ^uint32(0)} var activeDomains []uint32 - reqCtx := handler.callsChannel.SendMultiRequest(req) + reqCtx := h.callsChannel.SendMultiRequest(req) for { msg := &l2ba.BridgeDomainDetails{} stop, err := reqCtx.ReceiveReply(msg) @@ -125,6 +129,44 @@ func (handler *BridgeDomainVppHandler) DumpBridgeDomainIDs() ([]uint32, error) { return activeDomains, nil } +// Reads ARP termination table from all bridge domains. Result is then added to bridge domains. +func (h *BridgeDomainVppHandler) dumpBridgeDomainMacTable() (map[uint32][]*l2nb.BridgeDomains_BridgeDomain_ArpTerminationEntry, error) { + bdArpTable := make(map[uint32][]*l2nb.BridgeDomains_BridgeDomain_ArpTerminationEntry) + req := &l2ba.BdIPMacDump{BdID: ^uint32(0)} + + reqCtx := h.callsChannel.SendMultiRequest(req) + for { + msg := &l2ba.BdIPMacDetails{} + stop, err := reqCtx.ReceiveReply(msg) + if err != nil { + return nil, err + } + if stop { + break + } + + // Prepare ARP entry + arpEntry := &l2nb.BridgeDomains_BridgeDomain_ArpTerminationEntry{} + var ipAddr net.IP = msg.IPAddress + if uintToBool(msg.IsIPv6) { + arpEntry.IpAddress = ipAddr.To16().String() + } else { + arpEntry.IpAddress = ipAddr[:4].To4().String() + } + arpEntry.PhysAddress = net.HardwareAddr(msg.MacAddress).String() + + // Add ARP entry to result map + arpEntries, ok := bdArpTable[msg.BdID] + if ok { + arpEntries = append(arpEntries, arpEntry) + } else { + bdArpTable[msg.BdID] = append(bdArpTable[msg.BdID], arpEntry) + } + } + + return bdArpTable, nil +} + // FibTableDetails is the wrapper structure for the FIB table entry northbound API structure. type FibTableDetails struct { Fib *l2nb.FibTable_FibEntry `json:"fib"` @@ -138,15 +180,11 @@ type FibMeta struct { } // DumpFIBTableEntries implements fib handler. -func (handler *FibVppHandler) DumpFIBTableEntries() (map[string]*FibTableDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.L2FibTableDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *FibVppHandler) DumpFIBTableEntries() (map[string]*FibTableDetails, error) { // map for the resulting FIBs fibs := make(map[string]*FibTableDetails) - reqCtx := handler.syncCallsChannel.SendMultiRequest(&l2ba.L2FibTableDump{BdID: ^uint32(0)}) + reqCtx := h.syncCallsChannel.SendMultiRequest(&l2ba.L2FibTableDump{BdID: ^uint32(0)}) for { fibDetails := &l2ba.L2FibTableDetails{} stop, err := reqCtx.ReceiveReply(fibDetails) @@ -166,14 +204,14 @@ func (handler *FibVppHandler) DumpFIBTableEntries() (map[string]*FibTableDetails } // Interface name - ifName, _, exists := handler.ifIndexes.LookupName(fibDetails.SwIfIndex) + ifName, _, exists := h.ifIndexes.LookupName(fibDetails.SwIfIndex) if !exists { - handler.log.Warnf("FIB dump: interface name for index %s not found", fibDetails.SwIfIndex) + h.log.Warnf("FIB dump: interface name for index %d not found", fibDetails.SwIfIndex) } // Bridge domain name - bdName, _, exists := handler.bdIndexes.LookupName(fibDetails.BdID) + bdName, _, exists := h.bdIndexes.LookupName(fibDetails.BdID) if !exists { - handler.log.Warnf("FIB dump: bridge domain name for index %s not found", fibDetails.BdID) + h.log.Warnf("FIB dump: bridge domain name for index %d not found", fibDetails.BdID) } fibs[mac] = &FibTableDetails{ @@ -208,15 +246,11 @@ type XcMeta struct { } // DumpXConnectPairs implements xconnect handler. -func (handler *XConnectVppHandler) DumpXConnectPairs() (map[uint32]*XConnectDetails, error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.L2XconnectDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *XConnectVppHandler) DumpXConnectPairs() (map[uint32]*XConnectDetails, error) { // map for the resulting xconnect pairs xpairs := make(map[uint32]*XConnectDetails) - reqCtx := handler.callsChannel.SendMultiRequest(&l2ba.L2XconnectDump{}) + reqCtx := h.callsChannel.SendMultiRequest(&l2ba.L2XconnectDump{}) for { pairs := &l2ba.L2XconnectDetails{} stop, err := reqCtx.ReceiveReply(pairs) @@ -228,13 +262,13 @@ func (handler *XConnectVppHandler) DumpXConnectPairs() (map[uint32]*XConnectDeta } // Find interface names - rxIfaceName, _, exists := handler.ifIndexes.LookupName(pairs.RxSwIfIndex) + rxIfaceName, _, exists := h.ifIndexes.LookupName(pairs.RxSwIfIndex) if !exists { - handler.log.Warnf("XConnect dump: rx interface name for index %s not found", pairs.RxSwIfIndex) + h.log.Warnf("XConnect dump: rx interface name for index %d not found", pairs.RxSwIfIndex) } - txIfaceName, _, exists := handler.ifIndexes.LookupName(pairs.TxSwIfIndex) + txIfaceName, _, exists := h.ifIndexes.LookupName(pairs.TxSwIfIndex) if !exists { - handler.log.Warnf("XConnect dump: tx interface name for index %s not found", pairs.TxSwIfIndex) + h.log.Warnf("XConnect dump: tx interface name for index %d not found", pairs.TxSwIfIndex) } xpairs[pairs.RxSwIfIndex] = &XConnectDetails{ @@ -251,3 +285,10 @@ func (handler *XConnectVppHandler) DumpXConnectPairs() (map[uint32]*XConnectDeta return xpairs, nil } + +func uintToBool(value uint8) bool { + if value == 0 { + return false + } + return true +} diff --git a/plugins/vpp/l2plugin/vppcalls/dump_vppcalls_test.go b/plugins/vpp/l2plugin/vppcalls/dump_vppcalls_test.go index 1a0dee48f8..57c4be00a4 100644 --- a/plugins/vpp/l2plugin/vppcalls/dump_vppcalls_test.go +++ b/plugins/vpp/l2plugin/vppcalls/dump_vppcalls_test.go @@ -22,6 +22,7 @@ import ( "github.com/ligato/vpp-agent/plugins/vpp/binapi/vpe" "github.com/ligato/vpp-agent/plugins/vpp/l2plugin/vppcalls" l2nb "github.com/ligato/vpp-agent/plugins/vpp/model/l2" + "github.com/ligato/vpp-agent/tests/vppcallmock" . "github.com/onsi/gomega" ) @@ -87,6 +88,12 @@ var testDataOutMessage = []*vppcalls.BridgeDomainDetails{ Name: "if3", }, }, + ArpTerminationTable: []*l2nb.BridgeDomains_BridgeDomain_ArpTerminationEntry{ + { + IpAddress: "192.168.0.1", + PhysAddress: "aa:aa:aa:aa:aa:aa", + }, + }, }, Meta: &vppcalls.BridgeDomainMeta{ BdID: 5, @@ -123,8 +130,6 @@ func TestDumpBridgeDomainIDs(t *testing.T) { Expect(err).Should(HaveOccurred()) } -// Scenario: -// - 2 bridge domains + 1 default in VPP // TestDumpBridgeDomains tests DumpBridgeDomains method func TestDumpBridgeDomains(t *testing.T) { ctx, bdHandler, ifIndexes := bdTestSetup(t) @@ -132,16 +137,61 @@ func TestDumpBridgeDomains(t *testing.T) { ifIndexes.RegisterName("if1", 5, nil) ifIndexes.RegisterName("if2", 7, nil) - ifIndexes.RegisterName("if3", 8, nil) - ctx.MockVpp.MockReply(testDataInMessagesBDs...) - ctx.MockVpp.MockReply(&vpe.ControlPingReply{}) + ctx.MockReplies([]*vppcallmock.HandleReplies{ + { + Name: (&l2ba.BdIPMacDump{}).GetMessageName(), + Ping: true, + Message: &l2ba.BdIPMacDetails{}, + }, + { + Name: (&l2ba.BridgeDomainDump{}).GetMessageName(), + Ping: true, + Message: testDataInMessagesBDs[0], + }, + }) bridgeDomains, err := bdHandler.DumpBridgeDomains() Expect(err).To(BeNil()) - Expect(bridgeDomains).To(HaveLen(2)) + Expect(bridgeDomains).To(HaveLen(1)) Expect(bridgeDomains[4]).To(Equal(testDataOutMessage[0])) + + ctx.MockVpp.MockReply(&l2ba.BridgeDomainAddDelReply{}) + _, err = bdHandler.DumpBridgeDomains() + Expect(err).Should(HaveOccurred()) +} + +// TestDumpBridgeDomains tests DumpBridgeDomains method +func TestDumpBridgeDomainsWithARP(t *testing.T) { + ctx, bdHandler, ifIndexes := bdTestSetup(t) + defer ctx.TeardownTestCtx() + + ifIndexes.RegisterName("if1", 5, nil) + ifIndexes.RegisterName("if3", 8, nil) + + ctx.MockReplies([]*vppcallmock.HandleReplies{ + { + Name: (&l2ba.BdIPMacDump{}).GetMessageName(), + Ping: true, + Message: &l2ba.BdIPMacDetails{ + BdID: 5, + IsIPv6: 0, + IPAddress: []byte{192, 168, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + MacAddress: []byte{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, + }, + }, + { + Name: (&l2ba.BridgeDomainDump{}).GetMessageName(), + Ping: true, + Message: testDataInMessagesBDs[1], + }, + }) + + bridgeDomains, err := bdHandler.DumpBridgeDomains() + + Expect(err).To(BeNil()) + Expect(bridgeDomains).To(HaveLen(1)) Expect(bridgeDomains[5]).To(Equal(testDataOutMessage[1])) ctx.MockVpp.MockReply(&l2ba.BridgeDomainAddDelReply{}) diff --git a/plugins/vpp/l2plugin/vppcalls/interface_vppcalls.go b/plugins/vpp/l2plugin/vppcalls/interface_vppcalls.go index 7d9a99f5bd..6eca783593 100644 --- a/plugins/vpp/l2plugin/vppcalls/interface_vppcalls.go +++ b/plugins/vpp/l2plugin/vppcalls/interface_vppcalls.go @@ -16,7 +16,8 @@ package vppcalls import ( "fmt" - "time" + + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" l2ba "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" @@ -24,47 +25,46 @@ import ( "github.com/ligato/vpp-agent/plugins/vpp/model/l2" ) -// SetInterfacesToBridgeDomain implements bridge domain handler. -func (handler *BridgeDomainVppHandler) SetInterfacesToBridgeDomain(bdName string, bdIdx uint32, bdIfs []*l2.BridgeDomains_BridgeDomain_Interfaces, - swIfIndices ifaceidx.SwIfIndex) (ifs []string, wasErr error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.SwInterfaceSetL2Bridge{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - if len(bdIfs) == 0 { - handler.log.Debugf("Bridge domain %v has no new interface to set", bdName) - return nil, nil +// SetInterfaceToBridgeDomain implements bridge domain handler. Returns an interface configured to the BD. +func (h *BridgeDomainVppHandler) SetInterfaceToBridgeDomain(bdName string, bdIdx uint32, bdIf *l2.BridgeDomains_BridgeDomain_Interfaces, + swIfIndices ifaceidx.SwIfIndex) (string, error) { + // Verify that interface exists, otherwise skip it. + ifIdx, _, found := swIfIndices.LookupIdx(bdIf.Name) + if !found { + h.log.Debugf("Required bridge domain %s interface %s not found", bdName, bdIf.Name) + return "", nil } + if err := h.addDelInterfaceToBridgeDomain(bdName, bdIdx, bdIf, ifIdx, true); err != nil { + return "", err + } + h.log.WithFields(logging.Fields{"Interface": bdIf.Name, "BD": bdName}).Debug("Interface set to bridge domain") + + return bdIf.Name, nil +} +// SetInterfacesToBridgeDomain implements bridge domain handler. Returns a list of interfaces configured to the BD. +func (h *BridgeDomainVppHandler) SetInterfacesToBridgeDomain(bdName string, bdIdx uint32, bdIfs []*l2.BridgeDomains_BridgeDomain_Interfaces, + swIfIndices ifaceidx.SwIfIndex) ([]string, error) { + + var ifs []string for _, bdIf := range bdIfs { - // Verify that interface exists, otherwise skip it. - ifIdx, _, found := swIfIndices.LookupIdx(bdIf.Name) - if !found { - handler.log.Debugf("Required bridge domain %v interface %v not found", bdName, bdIf.Name) - continue + iface, err := h.SetInterfaceToBridgeDomain(bdName, bdIdx, bdIf, swIfIndices) + if err != nil { + return nil, err } - if err := handler.addDelInterfaceToBridgeDomain(bdName, bdIdx, bdIf, ifIdx, true); err != nil { - wasErr = err - handler.log.Error(wasErr) - } else { - handler.log.WithFields(logging.Fields{"Interface": bdIf.Name, "BD": bdName}).Debug("Interface set to bridge domain") - ifs = append(ifs, bdIf.Name) + if iface != "" { + ifs = append(ifs, iface) } } - return ifs, wasErr + return ifs, nil } -// UnsetInterfacesFromBridgeDomain implements bridge domain handler. -func (handler *BridgeDomainVppHandler) UnsetInterfacesFromBridgeDomain(bdName string, bdIdx uint32, bdIfs []*l2.BridgeDomains_BridgeDomain_Interfaces, +// UnsetInterfacesFromBridgeDomain implements bridge domain handler. Returns a list of interfaces removed from the BD. +func (h *BridgeDomainVppHandler) UnsetInterfacesFromBridgeDomain(bdName string, bdIdx uint32, bdIfs []*l2.BridgeDomains_BridgeDomain_Interfaces, swIfIndices ifaceidx.SwIfIndex) (ifs []string, wasErr error) { - - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.SwInterfaceSetL2Bridge{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - if len(bdIfs) == 0 { - handler.log.Debugf("Bridge domain %v has no obsolete interface to unset", bdName) + h.log.Debugf("Bridge domain %s has no obsolete interface to unset", bdName) return nil, nil } @@ -72,22 +72,22 @@ func (handler *BridgeDomainVppHandler) UnsetInterfacesFromBridgeDomain(bdName st // Verify that interface exists, otherwise skip it. ifIdx, _, found := swIfIndices.LookupIdx(bdIf.Name) if !found { - handler.log.Debugf("Required bridge domain %v interface %v not found", bdName, bdIf.Name) + h.log.Debugf("Required bridge domain %s interface %s not found", bdName, bdIf.Name) + // The interface still needs to be added to the list as un-configured + ifs = append(ifs, bdIf.Name) continue } - if err := handler.addDelInterfaceToBridgeDomain(bdName, bdIdx, bdIf, ifIdx, false); err != nil { - wasErr = err - handler.log.Error(wasErr) - } else { - handler.log.WithFields(logging.Fields{"Interface": bdIf.Name, "BD": bdName}).Debug("Interface unset from bridge domain") - ifs = append(ifs, bdIf.Name) + if err := h.addDelInterfaceToBridgeDomain(bdName, bdIdx, bdIf, ifIdx, false); err != nil { + return nil, errors.Errorf("failed to remove interface %s from bridge domain %s: %v", bdIf.Name, bdName, err) } + h.log.WithFields(logging.Fields{"Interface": bdIf.Name, "BD": bdName}).Debug("Interface unset from bridge domain") + ifs = append(ifs, bdIf.Name) } return ifs, wasErr } -func (handler *BridgeDomainVppHandler) addDelInterfaceToBridgeDomain(bdName string, bdIdx uint32, bdIf *l2.BridgeDomains_BridgeDomain_Interfaces, +func (h *BridgeDomainVppHandler) addDelInterfaceToBridgeDomain(bdName string, bdIdx uint32, bdIf *l2.BridgeDomains_BridgeDomain_Interfaces, ifIdx uint32, add bool) error { req := &l2ba.SwInterfaceSetL2Bridge{ BdID: bdIdx, @@ -97,15 +97,15 @@ func (handler *BridgeDomainVppHandler) addDelInterfaceToBridgeDomain(bdName stri } // Set as BVI. if bdIf.BridgedVirtualInterface { - req.Bvi = 1 - handler.log.Debugf("Interface %v set as BVI", bdIf.Name) + req.PortType = l2ba.L2_API_PORT_TYPE_BVI + h.log.Debugf("Interface %v set as BVI", bdIf.Name) } reply := &l2ba.SwInterfaceSetL2BridgeReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { - return fmt.Errorf("error while assigning/removing interface %v to bd %v: %v", bdIf.Name, bdName, err) + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + return fmt.Errorf("error while assigning/removing interface %s to bd %s: %v", bdIf.Name, bdName, err) } else if reply.Retval != 0 { - return fmt.Errorf("%s returned %d while assigning/removing interface %v (idx %v) to bd %v", + return fmt.Errorf("%s returned %d while assigning/removing interface %s (idx %d) to bd %s", reply.GetMessageName(), reply.Retval, bdIf.Name, ifIdx, bdName) } diff --git a/plugins/vpp/l2plugin/vppcalls/interface_vppcalls_test.go b/plugins/vpp/l2plugin/vppcalls/interface_vppcalls_test.go index 8d82635e52..71892ab1d8 100644 --- a/plugins/vpp/l2plugin/vppcalls/interface_vppcalls_test.go +++ b/plugins/vpp/l2plugin/vppcalls/interface_vppcalls_test.go @@ -19,7 +19,7 @@ import ( "github.com/ligato/cn-infra/logging/logrus" "github.com/ligato/vpp-agent/idxvpp/nametoidx" - l2Api "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" + l2ba "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/vpp/model/l2" . "github.com/onsi/gomega" @@ -29,9 +29,9 @@ func TestSetInterfacesToBridgeDomain(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "bd", nil)) swIfIndexes.RegisterName("if1", 1, nil) // Metadata are not required for test purpose @@ -59,15 +59,15 @@ func TestSetInterfacesToBridgeDomain(t *testing.T) { Expect(err).To(BeNil()) Expect(len(ctx.MockChannel.Msgs)).To(BeEquivalentTo(3)) for i, msg := range ctx.MockChannel.Msgs { - var bvi uint8 + portType := l2ba.L2_API_PORT_TYPE_NORMAL if i == 0 { - bvi = 1 + portType = l2ba.L2_API_PORT_TYPE_BVI } - Expect(msg).To(Equal(&l2Api.SwInterfaceSetL2Bridge{ + Expect(msg).To(Equal(&l2ba.SwInterfaceSetL2Bridge{ RxSwIfIndex: uint32(i + 1), BdID: 1, Shg: uint8(i), - Bvi: bvi, + PortType: portType, Enable: 1, })) } @@ -92,8 +92,8 @@ func TestSetInterfacesToBridgeDomainMissingInterface(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "bd", nil)) swIfIndexes.RegisterName("if1", 1, nil) // Metadata are not required for test purpose @@ -117,7 +117,7 @@ func TestSetInterfacesToBridgeDomainError(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2Bridge{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2Bridge{}) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "bd", nil)) swIfIndexes.RegisterName("if1", 1, nil) // Metadata are not required for test purpose @@ -136,7 +136,7 @@ func TestSetInterfacesToBridgeDomainRetval(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{ + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{ Retval: 1, }) @@ -157,9 +157,9 @@ func TestUnsetInterfacesFromBridgeDomain(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "bd", nil)) swIfIndexes.RegisterName("if1", 1, nil) // Metadata are not required for test purpose @@ -184,7 +184,7 @@ func TestUnsetInterfacesFromBridgeDomain(t *testing.T) { Expect(err).To(BeNil()) Expect(len(ctx.MockChannel.Msgs)).To(BeEquivalentTo(3)) for i, msg := range ctx.MockChannel.Msgs { - Expect(msg).To(Equal(&l2Api.SwInterfaceSetL2Bridge{ + Expect(msg).To(Equal(&l2ba.SwInterfaceSetL2Bridge{ RxSwIfIndex: uint32(i + 1), BdID: 1, Shg: uint8(i), @@ -212,8 +212,8 @@ func TestUnsetInterfacesFromBridgeDomainMissingInterface(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{}) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "bd", nil)) swIfIndexes.RegisterName("if1", 1, nil) // Metadata are not required for test purpose @@ -230,14 +230,15 @@ func TestUnsetInterfacesFromBridgeDomainMissingInterface(t *testing.T) { Expect(err).To(BeNil()) Expect(len(ctx.MockChannel.Msgs)).To(BeEquivalentTo(1)) - Expect(configured).To(HaveLen(1)) + // Both must be marked as un-configured + Expect(configured).To(HaveLen(2)) } func TestUnsetInterfacesFromBridgeDomainError(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2Bridge{}) + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2Bridge{}) swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "bd", nil)) swIfIndexes.RegisterName("if1", 1, nil) // Metadata are not required for test purpose @@ -256,7 +257,7 @@ func TestUnsetInterfacesFromBridgeDomainRetval(t *testing.T) { ctx, bdHandler, _ := bdTestSetup(t) defer ctx.TeardownTestCtx() - ctx.MockVpp.MockReply(&l2Api.SwInterfaceSetL2BridgeReply{ + ctx.MockVpp.MockReply(&l2ba.SwInterfaceSetL2BridgeReply{ Retval: 1, }) diff --git a/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls.go b/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls.go index 9825c250bd..5b8466a365 100644 --- a/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls.go +++ b/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/cn-infra/logging" l2ba "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" @@ -36,10 +35,10 @@ type FibLogicalReq struct { } // Add implements fib handler. -func (handler *FibVppHandler) Add(mac string, bdID uint32, ifIdx uint32, bvi bool, static bool, callback func(error)) error { - handler.log.Debug("Adding L2 FIB table entry, mac: ", mac) +func (h *FibVppHandler) Add(mac string, bdID uint32, ifIdx uint32, bvi bool, static bool, callback func(error)) error { + h.log.Debug("Adding L2 FIB table entry, mac: ", mac) - handler.requestChan <- &FibLogicalReq{ + h.requestChan <- &FibLogicalReq{ IsAdd: true, MAC: mac, BDIdx: bdID, @@ -52,10 +51,10 @@ func (handler *FibVppHandler) Add(mac string, bdID uint32, ifIdx uint32, bvi boo } // Delete implements fib handler. -func (handler *FibVppHandler) Delete(mac string, bdID uint32, ifIdx uint32, callback func(error)) error { - handler.log.Debug("Removing L2 fib table entry, mac: ", mac) +func (h *FibVppHandler) Delete(mac string, bdID uint32, ifIdx uint32, callback func(error)) error { + h.log.Debug("Removing L2 fib table entry, mac: ", mac) - handler.requestChan <- &FibLogicalReq{ + h.requestChan <- &FibLogicalReq{ IsAdd: false, MAC: mac, BDIdx: bdID, @@ -66,17 +65,17 @@ func (handler *FibVppHandler) Delete(mac string, bdID uint32, ifIdx uint32, call } // WatchFIBReplies implements fib handler. -func (handler *FibVppHandler) WatchFIBReplies() { +func (h *FibVppHandler) WatchFIBReplies() { for { select { - case r := <-handler.requestChan: - handler.log.Debug("VPP L2FIB request: ", r) - err := handler.l2fibAddDel(r.MAC, r.BDIdx, r.SwIfIdx, r.BVI, r.Static, r.IsAdd) + case r := <-h.requestChan: + h.log.Debug("VPP L2FIB request: ", r) + err := h.l2fibAddDel(r.MAC, r.BDIdx, r.SwIfIdx, r.BVI, r.Static, r.IsAdd) if err != nil { - handler.log.WithFields(logging.Fields{"mac": r.MAC, "bdIdx": r.BDIdx}). + h.log.WithFields(logging.Fields{"mac": r.MAC, "ifIdx": r.SwIfIdx, "bdIdx": r.BDIdx}). Error("Static fib entry add/delete failed:", err) } else { - handler.log.WithFields(logging.Fields{"mac": r.MAC, "bdIdx": r.BDIdx}). + h.log.WithFields(logging.Fields{"mac": r.MAC, "ifIdx": r.SwIfIdx, "bdIdx": r.BDIdx}). Debug("Static fib entry added/deleted.") } r.callback(err) @@ -84,11 +83,7 @@ func (handler *FibVppHandler) WatchFIBReplies() { } } -func (handler *FibVppHandler) l2fibAddDel(macstr string, bdIdx, swIfIdx uint32, bvi, static, isAdd bool) (err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.L2fibAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *FibVppHandler) l2fibAddDel(macstr string, bdIdx, swIfIdx uint32, bvi, static, isAdd bool) (err error) { var mac []byte if macstr != "" { mac, err = net.ParseMAC(macstr) @@ -107,7 +102,7 @@ func (handler *FibVppHandler) l2fibAddDel(macstr string, bdIdx, swIfIdx uint32, } reply := &l2ba.L2fibAddDelReply{} - if err := handler.asyncCallsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.asyncCallsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) diff --git a/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls_test.go b/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls_test.go index 8892d64e3a..ff12a0d447 100644 --- a/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls_test.go +++ b/plugins/vpp/l2plugin/vppcalls/l2fib_vppcalls_test.go @@ -195,6 +195,6 @@ func fibTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.FibVppAPI, iface logger := logrus.NewLogger("test-log") ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logger, "fib-if-idx", nil)) bdIndexes := l2idx.NewBDIndex(nametoidx.NewNameToIdx(logger, "fib-bd-idx", nil)) - fibHandler := vppcalls.NewFibVppHandler(ctx.MockChannel, ctx.MockChannel, ifIndexes, bdIndexes, logger, nil) + fibHandler := vppcalls.NewFibVppHandler(ctx.MockChannel, ctx.MockChannel, ifIndexes, bdIndexes, logger) return ctx, fibHandler, ifIndexes, bdIndexes } diff --git a/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls.go b/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls.go index e00314ce85..720e188b32 100644 --- a/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls.go +++ b/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls.go @@ -16,26 +16,21 @@ package vppcalls import ( "fmt" - "time" l2ba "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" ) // AddL2XConnect implements xconnect handler. -func (handler *XConnectVppHandler) AddL2XConnect(rxIfIdx uint32, txIfIdx uint32) error { - return handler.addDelXConnect(rxIfIdx, txIfIdx, true) +func (h *XConnectVppHandler) AddL2XConnect(rxIfIdx uint32, txIfIdx uint32) error { + return h.addDelXConnect(rxIfIdx, txIfIdx, true) } // DeleteL2XConnect implements xconnect handler. -func (handler *XConnectVppHandler) DeleteL2XConnect(rxIfIdx uint32, txIfIdx uint32) error { - return handler.addDelXConnect(rxIfIdx, txIfIdx, false) +func (h *XConnectVppHandler) DeleteL2XConnect(rxIfIdx uint32, txIfIdx uint32) error { + return h.addDelXConnect(rxIfIdx, txIfIdx, false) } -func (handler *XConnectVppHandler) addDelXConnect(rxIfaceIdx uint32, txIfaceIdx uint32, enable bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l2ba.SwInterfaceSetL2Xconnect{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *XConnectVppHandler) addDelXConnect(rxIfaceIdx uint32, txIfaceIdx uint32, enable bool) error { req := &l2ba.SwInterfaceSetL2Xconnect{ Enable: boolToUint(enable), TxSwIfIndex: txIfaceIdx, @@ -43,7 +38,7 @@ func (handler *XConnectVppHandler) addDelXConnect(rxIfaceIdx uint32, txIfaceIdx } reply := &l2ba.SwInterfaceSetL2XconnectReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) diff --git a/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls_test.go b/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls_test.go index 8aef72b514..2736a4a36a 100644 --- a/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls_test.go +++ b/plugins/vpp/l2plugin/vppcalls/xconnect_vppcalls_test.go @@ -145,6 +145,6 @@ func xcTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.XConnectVppAPI, i ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "xc-if-idx", nil)) - xcHandler := vppcalls.NewXConnectVppHandler(ctx.MockChannel, ifIndexes, log, nil) + xcHandler := vppcalls.NewXConnectVppHandler(ctx.MockChannel, ifIndexes, log) return ctx, xcHandler, ifIndexes } diff --git a/plugins/vpp/l2plugin/xconnect_config.go b/plugins/vpp/l2plugin/xconnect_config.go index bdfd5a6afd..a9d76d640b 100644 --- a/plugins/vpp/l2plugin/xconnect_config.go +++ b/plugins/vpp/l2plugin/xconnect_config.go @@ -15,11 +15,9 @@ package l2plugin import ( - "fmt" - govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -42,240 +40,240 @@ type XConnectConfigurator struct { vppChan govppapi.Channel xcHandler vppcalls.XConnectVppAPI - stopwatch *measure.Stopwatch // Timer used to measure and store time } // Init essential configurator fields. -func (plugin *XConnectConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *XConnectConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-xc-conf") - plugin.log.Info("Initializing L2 xConnect configurator") - - // Stopwatch - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("XCConfigurator", plugin.log) - } + c.log = logger.NewLogger("xc-conf") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.xcIndexes = l2idx.NewXcIndex(nametoidx.NewNameToIdx(plugin.log, "xc-indexes", nil)) - plugin.xcAddCacheIndexes = l2idx.NewXcIndex(nametoidx.NewNameToIdx(plugin.log, "xc-add-cache-indexes", nil)) - plugin.xcDelCacheIndexes = l2idx.NewXcIndex(nametoidx.NewNameToIdx(plugin.log, "xc-del-cache-indexes", nil)) - plugin.xcIndexSeq = 1 + c.ifIndexes = swIfIndexes + c.xcIndexes = l2idx.NewXcIndex(nametoidx.NewNameToIdx(c.log, "xc-indexes", nil)) + c.xcAddCacheIndexes = l2idx.NewXcIndex(nametoidx.NewNameToIdx(c.log, "xc-add-cache-indexes", nil)) + c.xcDelCacheIndexes = l2idx.NewXcIndex(nametoidx.NewNameToIdx(c.log, "xc-del-cache-indexes", nil)) + c.xcIndexSeq = 1 // VPP channel - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + errors.Errorf("failed to create API channel: %v", err) } // Cross-connect VPP API handler - plugin.xcHandler = vppcalls.NewXConnectVppHandler(plugin.vppChan, plugin.ifIndexes, plugin.log, plugin.stopwatch) + c.xcHandler = vppcalls.NewXConnectVppHandler(c.vppChan, c.ifIndexes, c.log) + + c.log.Info("L2 XConnect configurator initialized") return nil } // Close govpp channel. -func (plugin *XConnectConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *XConnectConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + c.LogError(errors.Errorf("failed to safeclose XConnect configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *XConnectConfigurator) clearMapping() { - plugin.xcIndexes.Clear() - plugin.xcAddCacheIndexes.Clear() - plugin.xcDelCacheIndexes.Clear() +func (c *XConnectConfigurator) clearMapping() { + c.xcIndexes.Clear() + c.xcAddCacheIndexes.Clear() + c.xcDelCacheIndexes.Clear() + c.log.Debugf("XConnect configurator mapping cleared") } // GetXcIndexes returns cross connect memory indexes -func (plugin *XConnectConfigurator) GetXcIndexes() l2idx.XcIndexRW { - return plugin.xcIndexes +func (c *XConnectConfigurator) GetXcIndexes() l2idx.XcIndexRW { + return c.xcIndexes } // GetXcAddCache returns cross connect 'add' cache (test purposes) -func (plugin *XConnectConfigurator) GetXcAddCache() l2idx.XcIndexRW { - return plugin.xcAddCacheIndexes +func (c *XConnectConfigurator) GetXcAddCache() l2idx.XcIndexRW { + return c.xcAddCacheIndexes } // GetXcDelCache returns cross connect 'del' cache (test purposes) -func (plugin *XConnectConfigurator) GetXcDelCache() l2idx.XcIndexRW { - return plugin.xcDelCacheIndexes +func (c *XConnectConfigurator) GetXcDelCache() l2idx.XcIndexRW { + return c.xcDelCacheIndexes } // ConfigureXConnectPair adds new cross connect pair -func (plugin *XConnectConfigurator) ConfigureXConnectPair(xc *l2.XConnectPairs_XConnectPair) error { - plugin.log.Infof("Configuring L2 xConnect pair %s-%s", xc.ReceiveInterface, xc.TransmitInterface) - if err := plugin.validateConfig(xc); err != nil { - return err +func (c *XConnectConfigurator) ConfigureXConnectPair(xc *l2.XConnectPairs_XConnectPair) error { + if err := c.validateConfig(xc); err != nil { + return errors.Errorf("failed to configure XConnect %s-%s, config is invalid: %v", + xc.ReceiveInterface, xc.TransmitInterface, err) } // Verify interface presence, eventually store cross connect to cache if either is missing - rxIfIdx, _, rxFound := plugin.ifIndexes.LookupIdx(xc.ReceiveInterface) - if !rxFound { - plugin.log.Debugf("XC Add: Receive interface %s not found.", xc.ReceiveInterface) - } - txIfIdx, _, txFound := plugin.ifIndexes.LookupIdx(xc.TransmitInterface) - if !txFound { - plugin.log.Debugf("XC Add: Transmit interface %s not found.", xc.TransmitInterface) - } + rxIfIdx, _, rxFound := c.ifIndexes.LookupIdx(xc.ReceiveInterface) + txIfIdx, _, txFound := c.ifIndexes.LookupIdx(xc.TransmitInterface) if !rxFound || !txFound { - plugin.putOrUpdateCache(xc, true) + c.putOrUpdateCache(xc, true) return nil } // XConnect can be configured now - if err := plugin.xcHandler.AddL2XConnect(rxIfIdx, txIfIdx); err != nil { - plugin.log.Errorf("Adding l2xConnect failed: %v", err) - return err + if err := c.xcHandler.AddL2XConnect(rxIfIdx, txIfIdx); err != nil { + return errors.Errorf("failed to add L2 XConnect %v-%v: %v", rxIfIdx, txIfIdx, err) } // Unregister from 'del' cache in case it is present - plugin.xcDelCacheIndexes.UnregisterName(xc.ReceiveInterface) + c.xcDelCacheIndexes.UnregisterName(xc.ReceiveInterface) + c.log.Debugf("XConnect %s-%s removed from (del) cache", rxIfIdx, txIfIdx) // Register - plugin.xcIndexes.RegisterName(xc.ReceiveInterface, plugin.xcIndexSeq, xc) - plugin.xcIndexSeq++ - plugin.log.Infof("L2 xConnect pair %s-%s configured", xc.ReceiveInterface, xc.TransmitInterface) + c.xcIndexes.RegisterName(xc.ReceiveInterface, c.xcIndexSeq, xc) + c.xcIndexSeq++ + c.log.Debugf("XConnect %s-%s registered", rxIfIdx, txIfIdx) + + c.log.Infof("L2 XConnect pair %s-%s configured", xc.ReceiveInterface, xc.TransmitInterface) return nil } // ModifyXConnectPair modifies cross connect pair (its transmit interface). Old entry is replaced. -func (plugin *XConnectConfigurator) ModifyXConnectPair(newXc, oldXc *l2.XConnectPairs_XConnectPair) error { - plugin.log.Infof("Modifying L2 xConnect pair %s-%s", oldXc.ReceiveInterface, oldXc.TransmitInterface) - if err := plugin.validateConfig(newXc); err != nil { +func (c *XConnectConfigurator) ModifyXConnectPair(newXc, oldXc *l2.XConnectPairs_XConnectPair) error { + if err := c.validateConfig(newXc); err != nil { return err } // Verify receive interface presence - rxIfIdx, _, rxFound := plugin.ifIndexes.LookupIdx(newXc.ReceiveInterface) + rxIfIdx, _, rxFound := c.ifIndexes.LookupIdx(newXc.ReceiveInterface) if !rxFound { - plugin.log.Debugf("XC Modify: Receive interface %s not found.", newXc.ReceiveInterface) - plugin.putOrUpdateCache(newXc, true) - plugin.xcIndexes.UnregisterName(oldXc.ReceiveInterface) + c.putOrUpdateCache(newXc, true) + c.xcIndexes.UnregisterName(oldXc.ReceiveInterface) + c.log.Debugf("XC Modify: Receive interface %s not found, unregistered.", newXc.ReceiveInterface) // Can return, without receive interface the entry cannot exist return nil } // Verify transmit interface - txIfIdx, _, txFound := plugin.ifIndexes.LookupIdx(newXc.TransmitInterface) + txIfIdx, _, txFound := c.ifIndexes.LookupIdx(newXc.TransmitInterface) if !txFound { - plugin.log.Debugf("XC Modify: Transmit interface %s not found.", newXc.TransmitInterface) - plugin.putOrUpdateCache(newXc, true) + c.putOrUpdateCache(newXc, true) // If new transmit interface is missing and XConnect cannot be updated now, configurator can try to remove old // entry, so the VPP output won't be confusing - oldTxIfIdx, _, oldTxFound := plugin.ifIndexes.LookupIdx(oldXc.TransmitInterface) + oldTxIfIdx, _, oldTxFound := c.ifIndexes.LookupIdx(oldXc.TransmitInterface) if !oldTxFound { return nil // Nothing more can be done } - plugin.log.Debugf("Removing obsolete l2xConnect %s-%s", oldXc.ReceiveInterface, oldXc.TransmitInterface) - if err := plugin.xcHandler.DeleteL2XConnect(rxIfIdx, oldTxIfIdx); err != nil { - plugin.log.Errorf("Deleted obsolete l2xConnect failed: %v", err) - return err + c.log.Debugf("XC Modify: Removing obsolete l2 XConnect %s-%s", oldXc.ReceiveInterface, oldXc.TransmitInterface) + if err := c.xcHandler.DeleteL2XConnect(rxIfIdx, oldTxIfIdx); err != nil { + return errors.Errorf("failed to remove obsolete L2 XConnect %s-%s: %v", + oldXc.ReceiveInterface, oldXc.TransmitInterface, err) } - plugin.xcIndexes.UnregisterName(oldXc.ReceiveInterface) + c.xcIndexes.UnregisterName(oldXc.ReceiveInterface) + c.log.Debugf("XConnect %s-%s unregistered", rxIfIdx, txIfIdx) return nil } // Replace existing entry - if err := plugin.xcHandler.AddL2XConnect(rxIfIdx, txIfIdx); err != nil { - plugin.log.Errorf("Replacing l2xConnect failed: %v", err) + if err := c.xcHandler.AddL2XConnect(rxIfIdx, txIfIdx); err != nil { + c.log.Errorf("Replacing l2 XConnect failed: %v", err) return err } - plugin.xcIndexes.RegisterName(newXc.ReceiveInterface, plugin.xcIndexSeq, newXc) - plugin.xcIndexSeq++ - plugin.log.Debugf("Modifying XConnect: new entry %s-%s added", newXc.ReceiveInterface, newXc.TransmitInterface) + c.xcIndexes.RegisterName(newXc.ReceiveInterface, c.xcIndexSeq, newXc) + c.xcIndexSeq++ + c.log.Debugf("Modifying XConnect: new entry %s-%s added", newXc.ReceiveInterface, newXc.TransmitInterface) + + c.log.Infof("L2 XConnect pair (rx: %s) modified", newXc.ReceiveInterface) return nil } // DeleteXConnectPair removes XConnect if possible. Note: Xconnect pair cannot be removed if any interface is missing. -func (plugin *XConnectConfigurator) DeleteXConnectPair(xc *l2.XConnectPairs_XConnectPair) error { - plugin.log.Infof("Removing L2 xConnect pair %s-%s", xc.ReceiveInterface, xc.TransmitInterface) - if err := plugin.validateConfig(xc); err != nil { +func (c *XConnectConfigurator) DeleteXConnectPair(xc *l2.XConnectPairs_XConnectPair) error { + if err := c.validateConfig(xc); err != nil { return err } // If receive interface is missing, XConnect entry is not configured on the VPP. - rxIfIdx, _, rxFound := plugin.ifIndexes.LookupIdx(xc.ReceiveInterface) + rxIfIdx, _, rxFound := c.ifIndexes.LookupIdx(xc.ReceiveInterface) if !rxFound { - plugin.log.Debugf("XC Del: Receive interface %s not found.", xc.ReceiveInterface) + c.log.Debugf("XC Del: Receive interface %s not found.", xc.ReceiveInterface) // Remove from all caches - plugin.xcIndexes.UnregisterName(xc.ReceiveInterface) - plugin.xcAddCacheIndexes.UnregisterName(xc.ReceiveInterface) - plugin.xcDelCacheIndexes.UnregisterName(xc.ReceiveInterface) + c.xcIndexes.UnregisterName(xc.ReceiveInterface) + c.xcAddCacheIndexes.UnregisterName(xc.ReceiveInterface) + c.xcDelCacheIndexes.UnregisterName(xc.ReceiveInterface) + c.log.Debugf("XC Del: %s unregistered from (add) cache, (del) cache and mapping.", xc.ReceiveInterface) return nil } // Verify transmit interface. If it is missing, XConnect cannot be removed and will be put to cache for deleted // interfaces - txIfIdx, _, txFound := plugin.ifIndexes.LookupIdx(xc.TransmitInterface) + txIfIdx, _, txFound := c.ifIndexes.LookupIdx(xc.TransmitInterface) if !txFound { - plugin.log.Debugf("XC Del: Transmit interface %s for XConnect %s not found.", + c.log.Debugf("XC Del: Transmit interface %s for XConnect %s not found.", xc.TransmitInterface, xc.ReceiveInterface) - plugin.putOrUpdateCache(xc, false) + c.putOrUpdateCache(xc, false) // Remove from other caches - plugin.xcIndexes.UnregisterName(xc.ReceiveInterface) - plugin.xcAddCacheIndexes.UnregisterName(xc.ReceiveInterface) + c.xcIndexes.UnregisterName(xc.ReceiveInterface) + c.xcAddCacheIndexes.UnregisterName(xc.ReceiveInterface) + c.log.Debugf("XC Del: %s unregistered from mapping and (add) cache", xc.ReceiveInterface) return nil } // XConnect can be removed now - if err := plugin.xcHandler.DeleteL2XConnect(rxIfIdx, txIfIdx); err != nil { - plugin.log.Errorf("Removing l2xConnect failed: %v", err) - return err + if err := c.xcHandler.DeleteL2XConnect(rxIfIdx, txIfIdx); err != nil { + return errors.Errorf("failed to remove XConnect pair %v-%v: %v", rxIfIdx, txIfIdx, err) } // Unregister - plugin.xcIndexes.UnregisterName(xc.ReceiveInterface) - plugin.log.Infof("L2 xConnect pair %s-%s removed", xc.ReceiveInterface, xc.TransmitInterface) + c.xcIndexes.UnregisterName(xc.ReceiveInterface) + c.log.Debugf("XConnect pair %s-%s removed from mapping", rxIfIdx, txIfIdx) + + c.log.Infof("L2 XConnect pair %s-%s removed", xc.ReceiveInterface, xc.TransmitInterface) return nil } // ResolveCreatedInterface resolves XConnects waiting for an interface. -func (plugin *XConnectConfigurator) ResolveCreatedInterface(ifName string) error { - plugin.log.Debugf("XConnect configurator: resolving created interface %s", ifName) - var wasErr error +func (c *XConnectConfigurator) ResolveCreatedInterface(ifName string) error { // XConnects waiting to be configured - for _, xcRxIf := range plugin.xcAddCacheIndexes.GetMapping().ListNames() { - _, xc, _ := plugin.xcAddCacheIndexes.LookupIdx(xcRxIf) + for _, xcRxIf := range c.xcAddCacheIndexes.GetMapping().ListNames() { + _, xc, _ := c.xcAddCacheIndexes.LookupIdx(xcRxIf) if xc == nil { - plugin.log.Errorf("XConnect entry %s has no metadata", xcRxIf) - continue + return errors.Errorf("failed to process registered interface %s: XC entry %s has no metadata", + ifName, xcRxIf) } if xc.TransmitInterface == ifName || xc.ReceiveInterface == ifName { - plugin.xcAddCacheIndexes.UnregisterName(xcRxIf) - if err := plugin.ConfigureXConnectPair(xc); err != nil { - plugin.log.Error(err) - wasErr = err + if _, _, found := c.xcAddCacheIndexes.UnregisterName(xcRxIf); found { + c.log.Debugf("XConnect %s unregistered from (add) cache", xcRxIf) + } + if err := c.ConfigureXConnectPair(xc); err != nil { + return errors.Errorf("failed to add new XConnect %s with registered interface %s: %v", + xc.ReceiveInterface, ifName, err) } } } // XConnects waiting for removal - for _, xcRxIf := range plugin.xcDelCacheIndexes.GetMapping().ListNames() { - _, xc, _ := plugin.xcDelCacheIndexes.LookupIdx(xcRxIf) + for _, xcRxIf := range c.xcDelCacheIndexes.GetMapping().ListNames() { + _, xc, _ := c.xcDelCacheIndexes.LookupIdx(xcRxIf) if xc == nil { - plugin.log.Errorf("XConnect entry %s has no metadata", xcRxIf) - continue + return errors.Errorf("failed to process registered interface %s: XC entry %s has no metadata", + ifName, xcRxIf) } if xc.TransmitInterface == ifName || xc.ReceiveInterface == ifName { - plugin.xcDelCacheIndexes.UnregisterName(xcRxIf) - if err := plugin.DeleteXConnectPair(xc); err != nil { - plugin.log.Error(err) - wasErr = err + if _, _, found := c.xcDelCacheIndexes.UnregisterName(xcRxIf); found { + c.log.Debugf("XConnect %s unregistered from (del) cache", xcRxIf) + } + if err := c.DeleteXConnectPair(xc); err != nil { + return errors.Errorf("failed to delete XConnect %s with registered interface %s: %v", + xc.ReceiveInterface, ifName, err) } } } - return wasErr + return nil } // ResolveDeletedInterface resolves XConnects using deleted interface // If deleted interface is a received interface, the XConnect was removed by the VPP // If deleted interface is a transmit interface, it will get flag 'DELETED' in VPP, but the entry will be kept -func (plugin *XConnectConfigurator) ResolveDeletedInterface(ifName string) error { - plugin.log.Debugf("XConnect configurator: resolving deleted interface %s", ifName) - for _, xcRxIf := range plugin.xcIndexes.GetMapping().ListNames() { - _, xc, _ := plugin.xcIndexes.LookupIdx(xcRxIf) +func (c *XConnectConfigurator) ResolveDeletedInterface(ifName string) error { + for _, xcRxIf := range c.xcIndexes.GetMapping().ListNames() { + _, xc, _ := c.xcIndexes.LookupIdx(xcRxIf) if xc == nil { - plugin.log.Errorf("XConnect entry %s has no metadata", xcRxIf) - continue + return errors.Errorf("failed to process unregistered interface %s: XC entry %s has no metadata", + ifName, xcRxIf) } if xc.ReceiveInterface == ifName { - plugin.xcIndexes.UnregisterName(xc.ReceiveInterface) - plugin.xcAddCacheIndexes.RegisterName(xc.ReceiveInterface, plugin.xcIndexSeq, xc) - plugin.xcIndexSeq++ + if _, _, found := c.xcIndexes.UnregisterName(xc.ReceiveInterface); found { + c.log.Debugf("XConnect %s unregistered from mapping", xcRxIf) + } + c.xcAddCacheIndexes.RegisterName(xc.ReceiveInterface, c.xcIndexSeq, xc) + c.xcIndexSeq++ + c.log.Debugf("XConnect %s registered to (add) cache", xcRxIf) continue } // Nothing to do for transmit @@ -285,34 +283,52 @@ func (plugin *XConnectConfigurator) ResolveDeletedInterface(ifName string) error } // Add XConnect to 'add' or 'del' cache, or just update metadata -func (plugin *XConnectConfigurator) putOrUpdateCache(xc *l2.XConnectPairs_XConnectPair, cacheTypeAdd bool) { +func (c *XConnectConfigurator) putOrUpdateCache(xc *l2.XConnectPairs_XConnectPair, cacheTypeAdd bool) { if cacheTypeAdd { - if _, _, found := plugin.xcAddCacheIndexes.LookupIdx(xc.ReceiveInterface); found { - plugin.xcAddCacheIndexes.UpdateMetadata(xc.ReceiveInterface, xc) + if _, _, found := c.xcAddCacheIndexes.LookupIdx(xc.ReceiveInterface); found { + c.xcAddCacheIndexes.UpdateMetadata(xc.ReceiveInterface, xc) + c.log.Debugf("XConnect %s-%s cached (add) medatada updated", xc.ReceiveInterface, xc.TransmitInterface) } else { - plugin.xcAddCacheIndexes.RegisterName(xc.ReceiveInterface, plugin.xcIndexSeq, xc) - plugin.xcIndexSeq++ + c.xcAddCacheIndexes.RegisterName(xc.ReceiveInterface, c.xcIndexSeq, xc) + c.xcIndexSeq++ + c.log.Debugf("XConnect %s-%s registered to (add) cache", xc.ReceiveInterface, xc.TransmitInterface) } } else { - if _, _, found := plugin.xcDelCacheIndexes.LookupIdx(xc.ReceiveInterface); found { - plugin.xcDelCacheIndexes.UpdateMetadata(xc.ReceiveInterface, xc) + if _, _, found := c.xcDelCacheIndexes.LookupIdx(xc.ReceiveInterface); found { + c.xcDelCacheIndexes.UpdateMetadata(xc.ReceiveInterface, xc) + c.log.Debugf("XConnect %s-%s cached (del) medatada updated", xc.ReceiveInterface, xc.TransmitInterface) } else { - plugin.xcDelCacheIndexes.RegisterName(xc.ReceiveInterface, plugin.xcIndexSeq, xc) - plugin.xcIndexSeq++ + c.xcDelCacheIndexes.RegisterName(xc.ReceiveInterface, c.xcIndexSeq, xc) + c.xcIndexSeq++ + c.log.Debugf("XConnect %s-%s registered to (del) cache", xc.ReceiveInterface, xc.TransmitInterface) } } } -func (plugin *XConnectConfigurator) validateConfig(xc *l2.XConnectPairs_XConnectPair) error { +func (c *XConnectConfigurator) validateConfig(xc *l2.XConnectPairs_XConnectPair) error { if xc.ReceiveInterface == "" { - return fmt.Errorf("invalid XConnect configuration, receive interface is not set") + return errors.Errorf("invalid XConnect configuration, receive interface is not set") } if xc.TransmitInterface == "" { - return fmt.Errorf("invalid XConnect configuration, transmit interface is not set") + return errors.Errorf("invalid XConnect configuration, transmit interface is not set") } if xc.ReceiveInterface == xc.TransmitInterface { - return fmt.Errorf("invalid XConnect configuration, recevie interface is the same as transmit (%s)", + return errors.Errorf("invalid XConnect configuration, recevie interface is the same as transmit (%s)", xc.ReceiveInterface) } return nil } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *XConnectConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/l2plugin/xconnect_config_test.go b/plugins/vpp/l2plugin/xconnect_config_test.go index 88d2c60e4a..8e23362877 100644 --- a/plugins/vpp/l2plugin/xconnect_config_test.go +++ b/plugins/vpp/l2plugin/xconnect_config_test.go @@ -17,8 +17,9 @@ package l2plugin_test import ( "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" l2api "github.com/ligato/vpp-agent/plugins/vpp/binapi/l2" @@ -594,7 +595,7 @@ func TestConfigureXConnectPairResolveDeletedRcInterface(t *testing.T) { func xcTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l2plugin.XConnectConfigurator, ifaceidx.SwIfIndexRW) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -605,7 +606,7 @@ func xcTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l2plugi swIfIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "xc-if", nil)) // Configurator plugin := &l2plugin.XConnectConfigurator{} - err = plugin.Init(log, connection, swIfIndexes, false) + err = plugin.Init(log, connection, swIfIndexes) Expect(err).To(BeNil()) return ctx, connection, plugin, swIfIndexes diff --git a/plugins/vpp/l3plugin/arp_config.go b/plugins/vpp/l3plugin/arp_config.go index da4f37de20..8c9bdc18f3 100644 --- a/plugins/vpp/l3plugin/arp_config.go +++ b/plugins/vpp/l3plugin/arp_config.go @@ -19,8 +19,8 @@ import ( "net" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -54,67 +54,62 @@ type ArpConfigurator struct { vppChan govppapi.Channel // VPP API handler arpHandler vppcalls.ArpVppAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init initializes ARP configurator -func (plugin *ArpConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *ArpConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-l3-arp-conf") - plugin.log.Debug("Initializing ARP configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("ARP-configurator", plugin.log) - } + c.log = logger.NewLogger("l3-arp-conf") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.arpIndexes = l3idx.NewARPIndex(nametoidx.NewNameToIdx(plugin.log, "arp_indexes", nil)) - plugin.arpCache = l3idx.NewARPIndex(nametoidx.NewNameToIdx(plugin.log, "arp_cache", nil)) - plugin.arpDeleted = l3idx.NewARPIndex(nametoidx.NewNameToIdx(plugin.log, "arp_unnasigned", nil)) - plugin.arpIndexSeq = 1 + c.ifIndexes = swIfIndexes + c.arpIndexes = l3idx.NewARPIndex(nametoidx.NewNameToIdx(c.log, "arp_indexes", nil)) + c.arpCache = l3idx.NewARPIndex(nametoidx.NewNameToIdx(c.log, "arp_cache", nil)) + c.arpDeleted = l3idx.NewARPIndex(nametoidx.NewNameToIdx(c.log, "arp_unnasigned", nil)) + c.arpIndexSeq = 1 // VPP channel - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handler - plugin.arpHandler = vppcalls.NewArpVppHandler(plugin.vppChan, plugin.ifIndexes, plugin.log, plugin.stopwatch) + c.arpHandler = vppcalls.NewArpVppHandler(c.vppChan, c.ifIndexes, c.log) + + c.log.Info("VPP ARP configurator initialized") return nil } // Close GOVPP channel -func (plugin *ArpConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *ArpConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose VPP ARP configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *ArpConfigurator) clearMapping() { - plugin.arpIndexes.Clear() - plugin.arpCache.Clear() - plugin.arpDeleted.Clear() +func (c *ArpConfigurator) clearMapping() { + c.arpIndexes.Clear() + c.arpCache.Clear() + c.arpDeleted.Clear() + c.log.Debugf("VPP ARP configurator mapping cleared") } // GetArpIndexes exposes arpIndexes mapping -func (plugin *ArpConfigurator) GetArpIndexes() l3idx.ARPIndexRW { - return plugin.arpIndexes +func (c *ArpConfigurator) GetArpIndexes() l3idx.ARPIndexRW { + return c.arpIndexes } // GetArpCache exposes list of cached ARP entries (present in ETCD but not in VPP) -func (plugin *ArpConfigurator) GetArpCache() l3idx.ARPIndexRW { - return plugin.arpCache +func (c *ArpConfigurator) GetArpCache() l3idx.ARPIndexRW { + return c.arpCache } // GetArpDeleted exposes arppDeleted mapping (unsuccessfully deleted ARP entries) -func (plugin *ArpConfigurator) GetArpDeleted() l3idx.ARPIndexRW { - return plugin.arpDeleted +func (c *ArpConfigurator) GetArpDeleted() l3idx.ARPIndexRW { + return c.arpDeleted } // Creates unique identifier which serves as a name in name to index mapping @@ -123,102 +118,96 @@ func arpIdentifier(iface, ip, mac string) string { } // AddArp processes the NB config and propagates it to bin api call -func (plugin *ArpConfigurator) AddArp(entry *l3.ArpTable_ArpEntry) error { - plugin.log.Infof("Configuring new ARP entry %v", *entry) - - if !isValidARP(entry, plugin.log) { - return fmt.Errorf("cannot configure ARP, provided data is not valid") +func (c *ArpConfigurator) AddArp(entry *l3.ArpTable_ArpEntry) error { + if err := isValidARP(entry, c.log); err != nil { + return err } arpID := arpIdentifier(entry.Interface, entry.PhysAddress, entry.IpAddress) // look for ARP in list of deleted ARPs - _, _, exists := plugin.arpDeleted.UnregisterName(arpID) + _, _, exists := c.arpDeleted.UnregisterName(arpID) if exists { - plugin.log.Debugf("ARP entry %v recreated", arpID) + c.log.Debugf("ARP entry %v unregistered from (del) cache", arpID) } // verify interface presence - ifIndex, _, exists := plugin.ifIndexes.LookupIdx(entry.Interface) + ifIndex, _, exists := c.ifIndexes.LookupIdx(entry.Interface) if !exists { // Store ARP entry to cache - plugin.log.Debugf("Interface %v required by ARP entry not found, moving to cache", entry.Interface) - plugin.arpCache.RegisterName(arpID, plugin.arpIndexSeq, entry) - plugin.arpIndexSeq++ + c.arpCache.RegisterName(arpID, c.arpIndexSeq, entry) + c.log.Debugf("ARP %S stored to cache, interface %s not found", arpID, entry.Interface) + c.arpIndexSeq++ return nil } // Transform arp data arp, err := transformArp(entry, ifIndex) if err != nil { - return err + return errors.Errorf("failed to transform ARP entry %s", arpID) } if arp == nil { return nil } - plugin.log.Debugf("adding ARP: %+v", *arp) // Create and register new arp entry - if err = plugin.arpHandler.VppAddArp(arp); err != nil { - return err + if err = c.arpHandler.VppAddArp(arp); err != nil { + return errors.Errorf("failed to configure VPP ARP %s: %v", arpID, err) } // Register configured ARP - plugin.arpIndexes.RegisterName(arpID, plugin.arpIndexSeq, entry) - plugin.arpIndexSeq++ - plugin.log.Debugf("ARP entry %v registered", arpID) + c.arpIndexes.RegisterName(arpID, c.arpIndexSeq, entry) + c.arpIndexSeq++ + c.log.Debugf("ARP entry %s registered", arpID) - plugin.log.Infof("ARP entry %v configured", arpID) + c.log.Infof("ARP entry %s configured", arpID) return nil } // ChangeArp processes the NB config and propagates it to bin api call -func (plugin *ArpConfigurator) ChangeArp(entry *l3.ArpTable_ArpEntry, prevEntry *l3.ArpTable_ArpEntry) error { - plugin.log.Infof("Modifying ARP entry %v to %v", *prevEntry, *entry) - - if err := plugin.DeleteArp(prevEntry); err != nil { - return err +func (c *ArpConfigurator) ChangeArp(entry *l3.ArpTable_ArpEntry, prevEntry *l3.ArpTable_ArpEntry) error { + if err := c.DeleteArp(prevEntry); err != nil { + return errors.Errorf("failed to delete ARP entry (MAC %s): %v", entry.PhysAddress, err) } - if err := plugin.AddArp(entry); err != nil { - return err + if err := c.AddArp(entry); err != nil { + return errors.Errorf("failed to add ARP entry (MAC %s): %v", entry.PhysAddress, err) } - plugin.log.Infof("ARP entry %v modified to %v", *prevEntry, *entry) + c.log.Infof("VPP ARP entry ( MAC %s) modified", entry.PhysAddress, *entry) return nil } // DeleteArp processes the NB config and propagates it to bin api call -func (plugin *ArpConfigurator) DeleteArp(entry *l3.ArpTable_ArpEntry) error { - plugin.log.Infof("Removing ARP entry %v", *entry) - - if !isValidARP(entry, plugin.log) { +func (c *ArpConfigurator) DeleteArp(entry *l3.ArpTable_ArpEntry) error { + if err := isValidARP(entry, c.log); err != nil { // Note: such an ARP cannot be configured either, so it should not happen - return fmt.Errorf("cannot remove ARP, provided data is not valid") + return err } // ARP entry identifier arpID := arpIdentifier(entry.Interface, entry.PhysAddress, entry.IpAddress) // Check if ARP entry is not just cached - _, _, found := plugin.arpCache.LookupIdx(arpID) + _, _, found := c.arpCache.LookupIdx(arpID) if found { - plugin.log.Debugf("ARP entry %v found in cache, removed", arpID) - plugin.arpCache.UnregisterName(arpID) + c.arpCache.UnregisterName(arpID) + c.log.Debugf("ARP entry %s found in cache, removed", arpID) // Cached ARP is not configured on the VPP, return return nil } // Check interface presence - ifIndex, _, exists := plugin.ifIndexes.LookupIdx(entry.Interface) + ifIndex, _, exists := c.ifIndexes.LookupIdx(entry.Interface) if !exists { // ARP entry cannot be removed without interface. Since the data are // no longer in the ETCD, agent need to remember the state and remove // entry when possible - plugin.log.Infof("Cannot remove ARP entry %v due to missing interface, will be removed when possible", - entry.Interface) - plugin.arpIndexes.UnregisterName(arpID) - plugin.arpDeleted.RegisterName(arpID, plugin.arpIndexSeq, entry) - plugin.arpIndexSeq++ + c.log.Debugf("Cannot remove ARP entry %s due to missing interface %s, will be removed when possible", + arpID, entry.Interface) + c.arpIndexes.UnregisterName(arpID) + c.arpDeleted.RegisterName(arpID, c.arpIndexSeq, entry) + c.log.Debugf("ARP entry %s removed from mapping and added to (del) cache", arpID) + c.arpIndexSeq++ return nil } @@ -226,67 +215,62 @@ func (plugin *ArpConfigurator) DeleteArp(entry *l3.ArpTable_ArpEntry) error { // Transform arp data arp, err := transformArp(entry, ifIndex) if err != nil { - return err + return errors.Errorf("failed to transform ARP entry %s: %v", arpID, err) } if arp == nil { return nil } - plugin.log.Debugf("deleting ARP: %+v", arp) // Delete and un-register new arp - if err = plugin.arpHandler.VppDelArp(arp); err != nil { - return err - } - _, _, found = plugin.arpIndexes.UnregisterName(arpID) - if found { - plugin.log.Infof("ARP entry %v unregistered", arpID) - } else { - plugin.log.Warnf("Un-register failed, ARP entry %v not found", arpID) + if err = c.arpHandler.VppDelArp(arp); err != nil { + return errors.Errorf("failed to delete VPP ARP %s: %v", arpID, err) } + c.arpIndexes.UnregisterName(arpID) + c.log.Debugf("ARP entry %v unregistered", arpID) + + c.log.Infof("ARP entry %v removed", arpID) - plugin.log.Infof("ARP entry %v removed", arpID) return nil } // ResolveCreatedInterface handles case when new interface appears in the config -func (plugin *ArpConfigurator) ResolveCreatedInterface(interfaceName string) error { - plugin.log.Debugf("ARP configurator: resolving new interface %v", interfaceName) +func (c *ArpConfigurator) ResolveCreatedInterface(ifName string) error { // find all entries which can be resolved - entriesToAdd := plugin.arpCache.LookupNamesByInterface(interfaceName) - entriesToRemove := plugin.arpDeleted.LookupNamesByInterface(interfaceName) + entriesToAdd := c.arpCache.LookupNamesByInterface(ifName) + entriesToRemove := c.arpDeleted.LookupNamesByInterface(ifName) // Configure all cached ARP entriesToAdd which can be configured for _, entry := range entriesToAdd { // ARP entry identifier. Every entry in cache was already validated arpID := arpIdentifier(entry.Interface, entry.PhysAddress, entry.IpAddress) - if err := plugin.AddArp(entry); err != nil { - return err + if err := c.AddArp(entry); err != nil { + return errors.Errorf("failed to add VPP ARP entry %s with registered interface %s: %v", + arpID, ifName, err) } // remove from cache - plugin.arpCache.UnregisterName(arpID) - plugin.log.Infof("Previously un-configurable ARP entry %v is now configured", arpID) + c.arpCache.UnregisterName(arpID) + c.log.Debugf("Cached ARP %s was configured and unregistered from cache", arpID) } // Remove all entries which should not be configured for _, entry := range entriesToRemove { arpID := arpIdentifier(entry.Interface, entry.PhysAddress, entry.IpAddress) - if err := plugin.DeleteArp(entry); err != nil { - return err + if err := c.DeleteArp(entry); err != nil { + return errors.Errorf("failed to delete VPP ARP entry %s with registered interface %s: %v", + arpID, ifName, err) } // remove from list of deleted - plugin.arpDeleted.UnregisterName(arpID) - plugin.log.Infof("Deprecated ARP entry %v was removed", arpID) + c.arpDeleted.UnregisterName(arpID) + c.log.Debugf("Cached ARP %s was removed and unregistered from (del) cache", arpID) } return nil } // ResolveDeletedInterface handles case when interface is removed from the config -func (plugin *ArpConfigurator) ResolveDeletedInterface(interfaceName string, interfaceIdx uint32) error { - plugin.log.Debugf("ARP configurator: resolving deleted interface %v", interfaceName) - +func (c *ArpConfigurator) ResolveDeletedInterface(interfaceName string, interfaceIdx uint32) error { // Since the interface does not exist, all related ARP entries are 'un-assigned' on the VPP // but they cannot be removed using binary API. Nothing to do here. @@ -294,25 +278,22 @@ func (plugin *ArpConfigurator) ResolveDeletedInterface(interfaceName string, int } // Verify ARP entry contains all required fields -func isValidARP(arpInput *l3.ArpTable_ArpEntry, log logging.Logger) bool { +func isValidARP(arpInput *l3.ArpTable_ArpEntry, log logging.Logger) error { if arpInput == nil { log.Info("ARP input is empty") - return false + return errors.Errorf("ARP invalid: input is empty") + } + if arpInput.PhysAddress == "" { + return errors.Errorf("ARP invalid: no MAC address provided") } if arpInput.Interface == "" { - log.Info("ARP input does not contain interface") - return false + return errors.Errorf("ARP (MAC %s) invalid: no interface provided", arpInput.PhysAddress) } if arpInput.IpAddress == "" { - log.Info("ARP input does not contain IP") - return false - } - if arpInput.PhysAddress == "" { - log.Info("ARP input does not contain MAC") - return false + return errors.Errorf("ARP (MAC %s) invalid: no IP address provided", arpInput.PhysAddress) } - return true + return nil } // transformArp converts raw entry data to ARP object @@ -326,3 +307,17 @@ func transformArp(arpInput *l3.ArpTable_ArpEntry, ifIndex uint32) (*vppcalls.Arp } return arp, nil } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *ArpConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/l3plugin/arp_config_test.go b/plugins/vpp/l3plugin/arp_config_test.go index 8d15d38cfa..41f8393be7 100644 --- a/plugins/vpp/l3plugin/arp_config_test.go +++ b/plugins/vpp/l3plugin/arp_config_test.go @@ -17,8 +17,9 @@ package l3plugin_test import ( "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" @@ -289,7 +290,7 @@ func TestArpResolveDeletedInterface(t *testing.T) { func arpTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l3plugin.ArpConfigurator, ifaceidx.SwIfIndex) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -297,7 +298,7 @@ func arpTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l3plug plugin := &l3plugin.ArpConfigurator{} ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logging.ForPlugin("test-log"), "l3-plugin", nil)) - err = plugin.Init(logging.ForPlugin("test-log"), connection, ifIndexes, false) + err = plugin.Init(logging.ForPlugin("test-log"), connection, ifIndexes) Expect(err).To(BeNil()) return ctx, connection, plugin, ifIndexes diff --git a/plugins/vpp/l3plugin/arp_proxy_config.go b/plugins/vpp/l3plugin/arp_proxy_config.go index 52a05db5d7..508f4b690c 100644 --- a/plugins/vpp/l3plugin/arp_proxy_config.go +++ b/plugins/vpp/l3plugin/arp_proxy_config.go @@ -15,13 +15,12 @@ package l3plugin import ( - "fmt" "net" "strings" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -53,336 +52,287 @@ type ProxyArpConfigurator struct { vppChan govppapi.Channel // VPP API channel pArpHandler vppcalls.ProxyArpVppAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init VPP channel and vppcalls handler -func (plugin *ProxyArpConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *ProxyArpConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-l3-proxy-arp-conf") - plugin.log.Debugf("Initializing proxy ARP configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("ARP-proxy-configurator", plugin.log) - } + c.log = logger.NewLogger("l3-proxy-arp-conf") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.pArpIfIndexes = nametoidx.NewNameToIdx(plugin.log, "proxyarp_if_indices", nil) - plugin.pArpRngIndexes = nametoidx.NewNameToIdx(plugin.log, "proxyarp_rng_indices", nil) - plugin.pArpIndexSeq = 1 + c.ifIndexes = swIfIndexes + c.pArpIfIndexes = nametoidx.NewNameToIdx(c.log, "proxyarp_if_indices", nil) + c.pArpRngIndexes = nametoidx.NewNameToIdx(c.log, "proxyarp_rng_indices", nil) + c.pArpIndexSeq = 1 // VPP channel - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handler - plugin.pArpHandler = vppcalls.NewProxyArpVppHandler(plugin.vppChan, plugin.ifIndexes, plugin.log, plugin.stopwatch) + c.pArpHandler = vppcalls.NewProxyArpVppHandler(c.vppChan, c.ifIndexes, c.log) + + c.log.Info("Proxy ARP configurator initialized") return nil } // Close VPP channel -func (plugin *ProxyArpConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *ProxyArpConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose Proxy ARP configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *ProxyArpConfigurator) clearMapping() { - plugin.pArpIfIndexes.Clear() - plugin.pArpRngIndexes.Clear() +func (c *ProxyArpConfigurator) clearMapping() { + c.pArpIfIndexes.Clear() + c.pArpRngIndexes.Clear() + c.log.Debugf("Proxy ARP configurator mapping cleared") } // GetArpIfIndexes exposes list of proxy ARP interface indexes -func (plugin *ProxyArpConfigurator) GetArpIfIndexes() idxvpp.NameToIdxRW { - return plugin.pArpIfIndexes +func (c *ProxyArpConfigurator) GetArpIfIndexes() idxvpp.NameToIdxRW { + return c.pArpIfIndexes } // GetArpRngIndexes exposes list of proxy ARP range indexes -func (plugin *ProxyArpConfigurator) GetArpRngIndexes() idxvpp.NameToIdxRW { - return plugin.pArpRngIndexes +func (c *ProxyArpConfigurator) GetArpRngIndexes() idxvpp.NameToIdxRW { + return c.pArpRngIndexes } // GetArpIfCache exposes list of cached ARP interfaces -func (plugin *ProxyArpConfigurator) GetArpIfCache() []string { - return plugin.pArpIfCache +func (c *ProxyArpConfigurator) GetArpIfCache() []string { + return c.pArpIfCache } // AddInterface implements proxy arp handler. -func (plugin *ProxyArpConfigurator) AddInterface(pArpIf *l3.ProxyArpInterfaces_InterfaceList) error { - plugin.log.Infof("Enabling interfaces from proxy ARP config %s", pArpIf.Label) - +func (c *ProxyArpConfigurator) AddInterface(pArpIf *l3.ProxyArpInterfaces_InterfaceList) error { for _, proxyArpIf := range pArpIf.Interfaces { ifName := proxyArpIf.Name if ifName == "" { - err := fmt.Errorf("proxy ARP interface not set") - plugin.log.Error(err) - return err + return errors.Errorf("proxy ARP %s interface name not set", pArpIf.Label) } // Check interface, cache if does not exist - ifIdx, _, found := plugin.ifIndexes.LookupIdx(ifName) + ifIdx, _, found := c.ifIndexes.LookupIdx(ifName) if !found { - plugin.log.Debugf("Interface %s does not exist, moving to cache", ifName) - plugin.pArpIfCache = append(plugin.pArpIfCache, ifName) + c.pArpIfCache = append(c.pArpIfCache, ifName) + c.log.Debugf("Interface %s does not exist, moving to cache", ifName) continue } // Call VPP API to enable interface for proxy ARP - if err := plugin.pArpHandler.EnableProxyArpInterface(ifIdx); err == nil { - plugin.log.Debugf("Interface %s enabled for proxy ARP", ifName) - } else { - err := fmt.Errorf("enabling interface %s for proxy ARP failed: %v", ifName, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.EnableProxyArpInterface(ifIdx); err != nil { + return errors.Errorf("enabling interface %s for proxy ARP failed: %v", ifName, err) } } // Register - plugin.pArpIfIndexes.RegisterName(pArpIf.Label, plugin.pArpIndexSeq, nil) - plugin.pArpIndexSeq++ - plugin.log.Debugf("Proxy ARP interface configuration %s registered", pArpIf.Label) + c.pArpIfIndexes.RegisterName(pArpIf.Label, c.pArpIndexSeq, nil) + c.pArpIndexSeq++ + c.log.Debugf("Proxy ARP configuration %s registered", pArpIf.Label) + + c.log.Infof("Interfaces enabled for proxy ARP config %s", pArpIf.Label) return nil } // ModifyInterface does nothing -func (plugin *ProxyArpConfigurator) ModifyInterface(newPArpIf, oldPArpIf *l3.ProxyArpInterfaces_InterfaceList) error { - plugin.log.Infof("Modifying proxy ARP interface configuration %s", newPArpIf.Label) - - toEnable, toDisable := plugin.calculateIfDiff(newPArpIf.Interfaces, oldPArpIf.Interfaces) +func (c *ProxyArpConfigurator) ModifyInterface(newPArpIf, oldPArpIf *l3.ProxyArpInterfaces_InterfaceList) error { + toEnable, toDisable := calculateIfDiff(newPArpIf.Interfaces, oldPArpIf.Interfaces) // Disable obsolete interfaces for _, ifName := range toDisable { // Check cache - for idx, cachedIf := range plugin.pArpIfCache { + for idx, cachedIf := range c.pArpIfCache { if cachedIf == ifName { - plugin.pArpIfCache = append(plugin.pArpIfCache[:idx], plugin.pArpIfCache[idx+1:]...) - plugin.log.Debugf("Proxy ARP interface %s removed from cache", ifName) + c.pArpIfCache = append(c.pArpIfCache[:idx], c.pArpIfCache[idx+1:]...) + c.log.Debugf("Proxy ARP interface %s removed from cache", ifName) continue } } - ifIdx, _, found := plugin.ifIndexes.LookupIdx(ifName) + ifIdx, _, found := c.ifIndexes.LookupIdx(ifName) // If interface is not found, there is nothing to do if found { - if err := plugin.pArpHandler.DisableProxyArpInterface(ifIdx); err == nil { - plugin.log.Debugf("Interface %s disabled for proxy ARP", ifName) - } else { - err = fmt.Errorf("disabling interface %s for proxy ARP failed: %v", ifName, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.DisableProxyArpInterface(ifIdx); err != nil { + return errors.Errorf("failed to disable interface %s for proxy ARP: %v", ifName, err) } } } // Enable new interfaces for _, ifName := range toEnable { // Put to cache if interface is missing - ifIdx, _, found := plugin.ifIndexes.LookupIdx(ifName) + ifIdx, _, found := c.ifIndexes.LookupIdx(ifName) if !found { - plugin.log.Debugf("Interface %s does not exist, moving to cache", ifName) - plugin.pArpIfCache = append(plugin.pArpIfCache, ifName) + c.pArpIfCache = append(c.pArpIfCache, ifName) + c.log.Debugf("Interface %s does not exist, moving to cache", ifName) continue } // Configure - if err := plugin.pArpHandler.EnableProxyArpInterface(ifIdx); err == nil { - plugin.log.Debugf("Interface %s enabled for proxy ARP", ifName) - } else { - err := fmt.Errorf("enabling interface %s for proxy ARP failed: %v", ifName, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.EnableProxyArpInterface(ifIdx); err != nil { + return errors.Errorf("failed to enable interface %s for proxy ARP: %v", ifName, err) } } - plugin.log.Debugf("Proxy ARP interface config %s modification done", newPArpIf.Label) + c.log.Infof("Modifying proxy ARP interface configuration %s", newPArpIf.Label) + return nil } // DeleteInterface disables proxy ARP interface or removes it from cache -func (plugin *ProxyArpConfigurator) DeleteInterface(pArpIf *l3.ProxyArpInterfaces_InterfaceList) error { - plugin.log.Infof("Disabling interfaces from proxy ARP config %s", pArpIf.Label) - +func (c *ProxyArpConfigurator) DeleteInterface(pArpIf *l3.ProxyArpInterfaces_InterfaceList) error { ProxyArpIfLoop: for _, proxyArpIf := range pArpIf.Interfaces { ifName := proxyArpIf.Name // Check if interface is cached - for idx, cachedIf := range plugin.pArpIfCache { + for idx, cachedIf := range c.pArpIfCache { if cachedIf == ifName { - plugin.pArpIfCache = append(plugin.pArpIfCache[:idx], plugin.pArpIfCache[idx+1:]...) - plugin.log.Debugf("Proxy ARP interface %s removed from cache", ifName) + c.pArpIfCache = append(c.pArpIfCache[:idx], c.pArpIfCache[idx+1:]...) + c.log.Debugf("Proxy ARP interface %s removed from cache", ifName) continue ProxyArpIfLoop } } // Look for interface - ifIdx, _, found := plugin.ifIndexes.LookupIdx(ifName) + ifIdx, _, found := c.ifIndexes.LookupIdx(ifName) if !found { // Interface does not exist, nothing more to do continue } // Call VPP API to disable interface for proxy ARP - if err := plugin.pArpHandler.DisableProxyArpInterface(ifIdx); err == nil { - plugin.log.Debugf("Interface %s disabled for proxy ARP", ifName) - } else { - err = fmt.Errorf("disabling interface %s for proxy ARP failed: %v", ifName, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.DisableProxyArpInterface(ifIdx); err != nil { + return errors.Errorf("failed to enable interface %s for proxy ARP: %v", ifName, err) } } // Un-register - plugin.pArpIfIndexes.UnregisterName(pArpIf.Label) - plugin.log.Debugf("Proxy ARP interface config %s un-registered", pArpIf.Label) + c.pArpIfIndexes.UnregisterName(pArpIf.Label) + c.log.Debugf("Proxy ARP interface config %s unregistered", pArpIf.Label) + + c.log.Infof("Disabling interfaces from proxy ARP config %s", pArpIf.Label) + return nil } // AddRange configures new IP range for proxy ARP -func (plugin *ProxyArpConfigurator) AddRange(pArpRng *l3.ProxyArpRanges_RangeList) error { - plugin.log.Infof("Setting up proxy ARP IP range config %s", pArpRng.Label) - +func (c *ProxyArpConfigurator) AddRange(pArpRng *l3.ProxyArpRanges_RangeList) error { for _, proxyArpRange := range pArpRng.Ranges { // Prune addresses - firstIP, err := plugin.pruneIP(proxyArpRange.FirstIp) + firstIP, err := c.pruneIP(proxyArpRange.FirstIp) if err != nil { - plugin.log.Error(err) return err } - lastIP, err := plugin.pruneIP(proxyArpRange.LastIp) + lastIP, err := c.pruneIP(proxyArpRange.LastIp) if err != nil { - plugin.log.Error(err) return err } // Convert to byte representation bFirstIP := net.ParseIP(firstIP).To4() bLastIP := net.ParseIP(lastIP).To4() // Call VPP API to configure IP range for proxy ARP - if err := plugin.pArpHandler.AddProxyArpRange(bFirstIP, bLastIP); err == nil { - plugin.log.Debugf("Address range %s - %s configured for proxy ARP", firstIP, lastIP) - } else { - err := fmt.Errorf("failed to configure proxy ARP address range %s - %s: %v", firstIP, lastIP, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.AddProxyArpRange(bFirstIP, bLastIP); err != nil { + return errors.Errorf("failed to configure proxy ARP address range %s - %s: %v", firstIP, lastIP, err) } } // Register - plugin.pArpRngIndexes.RegisterName(pArpRng.Label, plugin.pArpIndexSeq, nil) - plugin.pArpIndexSeq++ - plugin.log.Debugf("Proxy ARP range config %s registered", pArpRng.Label) + c.pArpRngIndexes.RegisterName(pArpRng.Label, c.pArpIndexSeq, nil) + c.pArpIndexSeq++ + c.log.Debugf("Proxy ARP range config %s registered", pArpRng.Label) + + c.log.Infof("Proxy ARP IP range config %s set", pArpRng.Label) + return nil } // ModifyRange does nothing -func (plugin *ProxyArpConfigurator) ModifyRange(newPArpRng, oldPArpRng *l3.ProxyArpRanges_RangeList) error { - plugin.log.Infof("Modifying proxy ARP range config %s", oldPArpRng.Label) - - toAdd, toDelete := plugin.calculateRngDiff(newPArpRng.Ranges, oldPArpRng.Ranges) +func (c *ProxyArpConfigurator) ModifyRange(newPArpRng, oldPArpRng *l3.ProxyArpRanges_RangeList) error { + toAdd, toDelete := calculateRngDiff(newPArpRng.Ranges, oldPArpRng.Ranges) // Remove old ranges for _, rng := range toDelete { // Prune - firstIP, err := plugin.pruneIP(rng.FirstIp) + firstIP, err := c.pruneIP(rng.FirstIp) if err != nil { - plugin.log.Error(err) return err } - lastIP, err := plugin.pruneIP(rng.LastIp) + lastIP, err := c.pruneIP(rng.LastIp) if err != nil { - plugin.log.Error(err) return err } // Convert to byte representation bFirstIP := net.ParseIP(firstIP).To4() bLastIP := net.ParseIP(lastIP).To4() // Call VPP API to configure IP range for proxy ARP - if err := plugin.pArpHandler.DeleteProxyArpRange(bFirstIP, bLastIP); err == nil { - plugin.log.Debugf("Address range %s - %s removed from proxy ARP setup", firstIP, lastIP) - } else { - err = fmt.Errorf("failed to remove proxy ARP address range %s - %s: %v", firstIP, lastIP, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.DeleteProxyArpRange(bFirstIP, bLastIP); err != nil { + return errors.Errorf("failed to remove proxy ARP address range %s - %s: %v", firstIP, lastIP, err) } } // Add new ranges for _, rng := range toAdd { // Prune addresses - firstIP, err := plugin.pruneIP(rng.FirstIp) + firstIP, err := c.pruneIP(rng.FirstIp) if err != nil { - plugin.log.Error(err) return err } - lastIP, err := plugin.pruneIP(rng.LastIp) + lastIP, err := c.pruneIP(rng.LastIp) if err != nil { - plugin.log.Error(err) return err } // Convert to byte representation bFirstIP := net.ParseIP(firstIP).To4() bLastIP := net.ParseIP(lastIP).To4() // Call VPP API to configure IP range for proxy ARP - if err := plugin.pArpHandler.AddProxyArpRange(bFirstIP, bLastIP); err == nil { - plugin.log.Debugf("Address range %s - %s configured for proxy ARP", firstIP, lastIP) - } else { - err := fmt.Errorf("failed to configure proxy ARP address range %s - %s: %v", firstIP, lastIP, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.AddProxyArpRange(bFirstIP, bLastIP); err != nil { + return errors.Errorf("failed to configure proxy ARP address range %s - %s: %v", firstIP, lastIP, err) } } - plugin.log.Debugf("Proxy ARP range config %s modification done", newPArpRng.Label) + c.log.Infof("Proxy ARP range config %s modified", oldPArpRng.Label) + return nil } // DeleteRange implements proxy arp handler. -func (plugin *ProxyArpConfigurator) DeleteRange(pArpRng *l3.ProxyArpRanges_RangeList) error { - plugin.log.Infof("Removing proxy ARP IP range config %s", pArpRng.Label) - +func (c *ProxyArpConfigurator) DeleteRange(pArpRng *l3.ProxyArpRanges_RangeList) error { for _, proxyArpRange := range pArpRng.Ranges { // Prune addresses - firstIP, err := plugin.pruneIP(proxyArpRange.FirstIp) + firstIP, err := c.pruneIP(proxyArpRange.FirstIp) if err != nil { - plugin.log.Error(err) return err } - lastIP, err := plugin.pruneIP(proxyArpRange.LastIp) + lastIP, err := c.pruneIP(proxyArpRange.LastIp) if err != nil { - plugin.log.Error(err) return err } // Convert to byte representation bFirstIP := net.ParseIP(firstIP).To4() bLastIP := net.ParseIP(lastIP).To4() // Call VPP API to configure IP range for proxy ARP - if err := plugin.pArpHandler.DeleteProxyArpRange(bFirstIP, bLastIP); err == nil { - plugin.log.Debugf("Address range %s - %s removed from proxy ARP setup", firstIP, lastIP) - } else { - err = fmt.Errorf("failed to remove proxy ARP address range %s - %s: %v", firstIP, lastIP, err) - plugin.log.Error(err) - return err + if err := c.pArpHandler.DeleteProxyArpRange(bFirstIP, bLastIP); err != nil { + return errors.Errorf("failed to remove proxy ARP address range %s - %s: %v", firstIP, lastIP, err) } } // Un-register - plugin.pArpRngIndexes.UnregisterName(pArpRng.Label) - plugin.log.Debugf("Proxy ARP range config %s un-registered", pArpRng.Label) + c.pArpRngIndexes.UnregisterName(pArpRng.Label) + c.log.Debugf("Proxy ARP range config %s unregistered", pArpRng.Label) + + c.log.Infof("Proxy ARP IP range config %s removed", pArpRng.Label) + return nil } // ResolveCreatedInterface handles new registered interface for proxy ARP -func (plugin *ProxyArpConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { - plugin.log.Debugf("Proxy ARP: handling new interface %s", ifName) - +func (c *ProxyArpConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { // Look for interface in cache - for idx, cachedIf := range plugin.pArpIfCache { + for idx, cachedIf := range c.pArpIfCache { if cachedIf == ifName { // Configure cached interface - if err := plugin.pArpHandler.EnableProxyArpInterface(ifIdx); err != nil { - plugin.log.Error(err) - return err + if err := c.pArpHandler.EnableProxyArpInterface(ifIdx); err != nil { + return errors.Errorf("failed to enable registered interface %s for proxy ARP: %v", ifName, err) } // Remove from cache - plugin.pArpIfCache = append(plugin.pArpIfCache[:idx], plugin.pArpIfCache[idx+1:]...) - plugin.log.Debugf("Proxy ARP interface %s configured and removed from cache", ifName) + c.pArpIfCache = append(c.pArpIfCache[:idx], c.pArpIfCache[idx+1:]...) + c.log.Debugf("Registered interface %s configured for Proxy ARP and removed from cache", ifName) return nil } } @@ -391,35 +341,33 @@ func (plugin *ProxyArpConfigurator) ResolveCreatedInterface(ifName string, ifIdx } // ResolveDeletedInterface handles new registered interface for proxy ARP -func (plugin *ProxyArpConfigurator) ResolveDeletedInterface(ifName string) error { - plugin.log.Debugf("Proxy ARP: handling removed interface %s", ifName) - +func (c *ProxyArpConfigurator) ResolveDeletedInterface(ifName string) error { // Check if interface was enabled for proxy ARP - _, _, found := plugin.pArpIfIndexes.LookupIdx(ifName) + _, _, found := c.pArpIfIndexes.LookupIdx(ifName) if found { // Put interface to cache (no need to call delete) - plugin.pArpIfCache = append(plugin.pArpIfCache, ifName) - plugin.log.Debugf("Removed interface %s was configured for proxy ARP, added to cache", ifName) + c.pArpIfCache = append(c.pArpIfCache, ifName) + c.log.Debugf("Unregistered interface %s removed from proxy ARP cache", ifName) } return nil } // Remove IP mask if set -func (plugin *ProxyArpConfigurator) pruneIP(ip string) (string, error) { +func (c *ProxyArpConfigurator) pruneIP(ip string) (string, error) { ipParts := strings.Split(ip, "/") if len(ipParts) == 1 { return ipParts[0], nil } if len(ipParts) == 2 { - plugin.log.Warnf("Proxy ARP range: removing unnecessary mask from IP address %s", ip) + c.log.Warnf("Proxy ARP range: removing unnecessary mask from IP address %s", ip) return ipParts[0], nil } - return ip, fmt.Errorf("proxy ARP range: invalid IP address format: %s", ip) + return ip, errors.Errorf("proxy ARP range: invalid IP address format: %s", ip) } // Calculate difference between old and new interfaces -func (plugin *ProxyArpConfigurator) calculateIfDiff(newIfs, oldIfs []*l3.ProxyArpInterfaces_InterfaceList_Interface) (toEnable, toDisable []string) { +func calculateIfDiff(newIfs, oldIfs []*l3.ProxyArpInterfaces_InterfaceList_Interface) (toEnable, toDisable []string) { // Find missing new interfaces for _, newIf := range newIfs { var found bool @@ -448,7 +396,7 @@ func (plugin *ProxyArpConfigurator) calculateIfDiff(newIfs, oldIfs []*l3.ProxyAr } // Calculate difference between old and new ranges -func (plugin *ProxyArpConfigurator) calculateRngDiff(newRngs, oldRngs []*l3.ProxyArpRanges_RangeList_Range) (toAdd, toDelete []*l3.ProxyArpRanges_RangeList_Range) { +func calculateRngDiff(newRngs, oldRngs []*l3.ProxyArpRanges_RangeList_Range) (toAdd, toDelete []*l3.ProxyArpRanges_RangeList_Range) { // Find missing ranges for _, newRng := range newRngs { var found bool @@ -474,5 +422,18 @@ func (plugin *ProxyArpConfigurator) calculateRngDiff(newRngs, oldRngs []*l3.Prox } } return +} +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *ProxyArpConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err } diff --git a/plugins/vpp/l3plugin/arp_proxy_config_test.go b/plugins/vpp/l3plugin/arp_proxy_config_test.go index d56f46e743..bcfc6a6479 100644 --- a/plugins/vpp/l3plugin/arp_proxy_config_test.go +++ b/plugins/vpp/l3plugin/arp_proxy_config_test.go @@ -17,8 +17,9 @@ package l3plugin_test import ( "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" @@ -404,7 +405,7 @@ func TestArpProxyResolveDeletedInterface(t *testing.T) { func proxyarpTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l3plugin.ProxyArpConfigurator, ifaceidx.SwIfIndex) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -412,7 +413,7 @@ func proxyarpTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l plugin := &l3plugin.ProxyArpConfigurator{} ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logging.ForPlugin("test-log"), "l3-plugin", nil)) - err = plugin.Init(logging.ForPlugin("test-log"), connection, ifIndexes, false) + err = plugin.Init(logging.ForPlugin("test-log"), connection, ifIndexes) Expect(err).To(BeNil()) return ctx, connection, plugin, ifIndexes diff --git a/plugins/vpp/l3plugin/data_resync.go b/plugins/vpp/l3plugin/data_resync.go index 56caa596ff..e84ee50f43 100644 --- a/plugins/vpp/l3plugin/data_resync.go +++ b/plugins/vpp/l3plugin/data_resync.go @@ -19,43 +19,35 @@ import ( "net" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/vpp-agent/plugins/vpp/l3plugin/vppcalls" "github.com/ligato/vpp-agent/plugins/vpp/model/l3" ) // Resync configures the VPP static routes. -func (plugin *RouteConfigurator) Resync(nbRoutes []*l3.StaticRoutes_Route) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC routes begin. ") - // Calculate and log route resync. - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *RouteConfigurator) Resync(nbRoutes []*l3.StaticRoutes_Route) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Retrieve VPP route configuration - vppRouteDetails, err := plugin.rtHandler.DumpStaticRoutes() + vppRouteDetails, err := c.rtHandler.DumpStaticRoutes() if err != nil { - return err + return errors.Errorf("failed to dump VPP routes: %v", err) } - plugin.log.Debugf("Found %d routes configured on the VPP", len(vppRouteDetails)) // Correlate NB and VPP configuration for _, nbRoute := range nbRoutes { nbRouteID := routeIdentifier(nbRoute.VrfId, nbRoute.DstIpAddr, nbRoute.NextHopAddr) - nbIfIdx, _, found := plugin.ifIndexes.LookupIdx(nbRoute.OutgoingInterface) + nbIfIdx, _, found := c.ifIndexes.LookupIdx(nbRoute.OutgoingInterface) if !found { if nbRoute.Type == l3.StaticRoutes_Route_INTER_VRF { // expected by inter VRF-routes nbIfIdx = vppcalls.NextHopOutgoingIfUnset } else { - plugin.log.Debugf("RESYNC routes: outgoing interface not found for %s", nbRouteID) - plugin.rtCachedIndexes.RegisterName(nbRouteID, plugin.rtIndexSeq, nbRoute) - plugin.rtIndexSeq++ + c.rtCachedIndexes.RegisterName(nbRouteID, c.rtIndexSeq, nbRoute) + c.log.Debugf("VPP route resync: outgoing interface not found for %s, cached", nbRouteID) + c.rtIndexSeq++ continue } } @@ -70,71 +62,70 @@ func (plugin *RouteConfigurator) Resync(nbRoutes []*l3.StaticRoutes_Route) error } vppRoute := vppRouteDetail.Route vppRouteID := routeIdentifier(vppRoute.VrfId, vppRoute.DstIpAddr, vppRoute.NextHopAddr) - plugin.log.Debugf("RESYNC routes: comparing %s and %s", nbRouteID, vppRouteID) + c.log.Debugf("VPP route resync: comparing %s and %s", nbRouteID, vppRouteID) if int32(vppRoute.Type) != int32(nbRoute.Type) { - plugin.log.Debugf("RESYNC routes: route type is different (NB: %d, VPP %d)", + c.log.Debugf("VPP route resync: route type is different (NB: %d, VPP %d)", nbRoute.Type, vppRoute.Type) continue } if vppRoute.OutgoingInterface != nbRoute.OutgoingInterface { - plugin.log.Debugf("RESYNC routes: interface index is different (NB: %d, VPP %d)", + c.log.Debugf("VPP route resync: interface index is different (NB: %d, VPP %d)", nbIfIdx, vppRoute.OutgoingInterface) continue } if vppRoute.DstIpAddr != nbRoute.DstIpAddr { - plugin.log.Debugf("RESYNC routes: dst address is different (NB: %s, VPP %s)", + c.log.Debugf("VPP route resync: dst address is different (NB: %s, VPP %s)", nbRoute.DstIpAddr, vppRoute.DstIpAddr) continue } if vppRoute.VrfId != nbRoute.VrfId { - plugin.log.Debugf("RESYNC routes: VRF ID is different (NB: %d, VPP %d)", + c.log.Debugf("VPP route resync: VRF ID is different (NB: %d, VPP %d)", nbRoute.VrfId, vppRoute.VrfId) continue } if vppRoute.Weight != nbRoute.Weight { - plugin.log.Debugf("RESYNC routes: weight is different (NB: %d, VPP %d)", + c.log.Debugf("VPP route resync: weight is different (NB: %d, VPP %d)", nbRoute.Weight, vppRoute.Weight) continue } if vppRoute.Preference != nbRoute.Preference { - plugin.log.Debugf("RESYNC routes: preference is different (NB: %d, VPP %d)", + c.log.Debugf("VPP route resync: preference is different (NB: %d, VPP %d)", nbRoute.Preference, vppRoute.Preference) continue } // Set zero address in correct format if not defined if nbRoute.NextHopAddr == "" { - nbRoute.NextHopAddr = plugin.fillEmptyNextHop(nbRoute.DstIpAddr) + if nbRoute.NextHopAddr, err = c.fillEmptyNextHop(nbRoute.DstIpAddr); err != nil { + return err + } } if vppRoute.NextHopAddr != nbRoute.NextHopAddr { - plugin.log.Debugf("RESYNC routes: next hop address is different (NB: %s, VPP %s)", + c.log.Debugf("VPP route resync routes: next hop address is different (NB: %s, VPP %s)", nbRoute.NextHopAddr, vppRoute.NextHopAddr) continue } if vppRoute.ViaVrfId != nbRoute.ViaVrfId { - plugin.log.Debugf("RESYNC routes: via VRF ID is different (NB: %d, VPP %d)", + c.log.Debugf("VPP route resync: via VRF ID is different (NB: %d, VPP %d)", nbRoute.ViaVrfId, vppRoute.ViaVrfId) continue } // Register existing routes - plugin.rtIndexes.RegisterName(nbRouteID, plugin.rtIndexSeq, nbRoute) - plugin.rtIndexSeq++ - plugin.log.Debugf("RESYNC routes: route %s registered without additional changes", nbRouteID) + c.rtIndexes.RegisterName(nbRouteID, c.rtIndexSeq, nbRoute) + c.rtIndexSeq++ + c.log.Debugf("VPP route resync: route %s registered without additional changes", nbRouteID) break } } // Add missing route configuration - var wasError error for _, nbRoute := range nbRoutes { routeID := routeIdentifier(nbRoute.VrfId, nbRoute.DstIpAddr, nbRoute.NextHopAddr) - _, _, found := plugin.rtIndexes.LookupIdx(routeID) + _, _, found := c.rtIndexes.LookupIdx(routeID) if !found { // create new route if does not exist yet. VRF ID is already validated at this point. - if err := plugin.ConfigureRoute(nbRoute, fmt.Sprintf("%d", nbRoute.VrfId)); err != nil { - plugin.log.Error(err) - wasError = err + if err := c.ConfigureRoute(nbRoute, fmt.Sprintf("%d", nbRoute.VrfId)); err != nil { + return errors.Errorf("VPP route resync error: failed to configure route %s: %v", routeID, err) } - plugin.log.Debugf("RESYNC routes: route %s was configured", routeID) } } @@ -143,22 +134,22 @@ func (plugin *RouteConfigurator) Resync(nbRoutes []*l3.StaticRoutes_Route) error if routeMayBeRemoved(vppRoute) { route := vppRoute.Route routeID := routeIdentifier(route.VrfId, route.DstIpAddr, route.NextHopAddr) - _, _, found := plugin.rtIndexes.LookupIdx(routeID) + _, _, found := c.rtIndexes.LookupIdx(routeID) if !found { // Register before removal - plugin.rtIndexes.RegisterName(routeID, plugin.rtIndexSeq, route) - plugin.rtIndexSeq++ - if err := plugin.DeleteRoute(route, fmt.Sprintf("%d", route.VrfId)); err != nil { - plugin.log.Error(err) - wasError = err + c.rtIndexes.RegisterName(routeID, c.rtIndexSeq, route) + c.rtIndexSeq++ + c.log.Debugf("Route %s registered before removal", routeID) + if err := c.DeleteRoute(route, fmt.Sprintf("%d", route.VrfId)); err != nil { + return errors.Errorf("VPP route resync error: failed to remove route %s: %v", routeID, err) } - plugin.log.Debugf("RESYNC routes: vpp route %s removed", routeID) + c.log.Debugf("VPP route resync: vpp route %s removed", routeID) } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC routes end. ", wasError) - return wasError + c.log.Debugf("VPP route resync done") + return nil } // Following rules are currently applied: @@ -175,103 +166,80 @@ func routeMayBeRemoved(route *vppcalls.RouteDetails) bool { } // Resync confgures the empty VPP (overwrites the arp entries) -func (plugin *ArpConfigurator) Resync(arpEntries []*l3.ArpTable_ArpEntry) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC arp begin. ") - // Calculate and log arp resync - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *ArpConfigurator) Resync(arpEntries []*l3.ArpTable_ArpEntry) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() + + // todo dump arp - var wasError error if len(arpEntries) > 0 { for _, entry := range arpEntries { - wasError = plugin.AddArp(entry) + if err := c.AddArp(entry); err != nil { + return errors.Errorf("ARP resync error: failed to configure ARP (MAC %s): %v", + entry.PhysAddress, err) + } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC arp end. ", wasError) + c.log.Info("VPP ARP resync done") return nil } // ResyncInterfaces confgures the empty VPP (overwrites the proxy arp entries) -func (plugin *ProxyArpConfigurator) ResyncInterfaces(nbProxyArpIfs []*l3.ProxyArpInterfaces_InterfaceList) error { - plugin.log.Debug("RESYNC proxy ARP interfaces begin. ") - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *ProxyArpConfigurator) ResyncInterfaces(nbProxyArpIfs []*l3.ProxyArpInterfaces_InterfaceList) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // Todo: dump proxy arp - var wasError error if len(nbProxyArpIfs) > 0 { for _, entry := range nbProxyArpIfs { - wasError = plugin.AddInterface(entry) + if err := c.AddInterface(entry); err != nil { + return errors.Errorf("Proxy ARP interface resync error: failed to add interfaces to %s: %v", + entry.Label, err) + } } } - plugin.log.Debug("RESYNC proxy ARP interface end. ", wasError) + c.log.Info("Proxy ARP interface resync done") return nil } // ResyncRanges confgures the empty VPP (overwrites the proxy arp ranges) -func (plugin *ProxyArpConfigurator) ResyncRanges(nbProxyArpRanges []*l3.ProxyArpRanges_RangeList) error { - plugin.log.Debug("RESYNC proxy ARP ranges begin. ") - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *ProxyArpConfigurator) ResyncRanges(nbProxyArpRanges []*l3.ProxyArpRanges_RangeList) error { // Todo: dump proxy arp - var wasError error if len(nbProxyArpRanges) > 0 { for _, entry := range nbProxyArpRanges { - wasError = plugin.AddRange(entry) + if err := c.AddRange(entry); err != nil { + return errors.Errorf("Proxy ARP range resync error: failed to set range to %s: %v", + entry.Label, err) + } } } - plugin.log.Debug("RESYNC proxy ARP ranges end. ", wasError) + c.log.Info("Proxy ARP interface resync done") return nil } // Resync configures the empty VPP (adds IP scan neigh config) -func (p *IPNeighConfigurator) Resync(config *l3.IPScanNeighbor) error { - p.log.Debug("RESYNC IP neighbor begin. ") - defer func() { - if p.stopwatch != nil { - p.stopwatch.PrintLog() - } - }() - - var wasError error - if err := p.Set(config); err != nil { - return err +func (c *IPNeighConfigurator) Resync(config *l3.IPScanNeighbor) error { + if err := c.Set(config); err != nil { + return errors.Errorf("failed to set IP scan neighbor: %v", err) } - p.log.Debug("RESYNC IP neighbor end. ", wasError) + c.log.Info("IP scan neighbor resync done") return nil } // Takes route destination address used to derive IP version and returns zero IP without mask -func (plugin *RouteConfigurator) fillEmptyNextHop(dstIP string) string { +func (c *RouteConfigurator) fillEmptyNextHop(dstIP string) (string, error) { _, isIPv6, err := addrs.ParseIPWithPrefix(dstIP) if err != nil { - plugin.log.Errorf("route resync error: failed to parse IP address %s", dstIP) - return "" + return "", errors.Errorf("route resync error: failed to parse IP address %s: %v", dstIP, err) } if isIPv6 { - return net.IPv6zero.String() + return net.IPv6zero.String(), nil } - return net.IPv4zero.String() + return net.IPv4zero.String(), nil } diff --git a/plugins/vpp/l3plugin/ip_neigh_config.go b/plugins/vpp/l3plugin/ip_neigh_config.go index e780ac6c49..9f9e77bb68 100644 --- a/plugins/vpp/l3plugin/ip_neigh_config.go +++ b/plugins/vpp/l3plugin/ip_neigh_config.go @@ -16,8 +16,8 @@ package l3plugin import ( govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/plugins/govppmux" "github.com/ligato/vpp-agent/plugins/vpp/l3plugin/vppcalls" @@ -35,61 +35,69 @@ type IPNeighConfigurator struct { vppChan govppapi.Channel // VPP API channel ipNeighHandler vppcalls.IPNeighVppAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init VPP channel and vppcalls handler -func (p *IPNeighConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, enableStopwatch bool) (err error) { +func (c *IPNeighConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API) (err error) { // Logger - p.log = logger.NewLogger("-l3-ip-neigh-conf") - p.log.Debugf("Initializing proxy ARP configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - p.stopwatch = measure.NewStopwatch("IPScan-Neigh-configurator", p.log) - } + c.log = logger.NewLogger("l3-ip-neigh-conf") + c.log.Debugf("Initializing proxy ARP configurator") // VPP channel - p.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handler - p.ipNeighHandler = vppcalls.NewIPNeighVppHandler(p.vppChan, p.log, p.stopwatch) + c.ipNeighHandler = vppcalls.NewIPNeighVppHandler(c.vppChan, c.log) return nil } // Close VPP channel -func (p *IPNeighConfigurator) Close() error { - return safeclose.Close(p.vppChan) +func (c *IPNeighConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose IP neighbor configurator: %v", err)) + } + return nil } // Set puts desired IP scan neighbor configuration to the VPP -func (p *IPNeighConfigurator) Set(config *l3.IPScanNeighbor) error { - if err := p.ipNeighHandler.SetIPScanNeighbor(config); err != nil { - return err +func (c *IPNeighConfigurator) Set(config *l3.IPScanNeighbor) error { + if err := c.ipNeighHandler.SetIPScanNeighbor(config); err != nil { + return errors.Errorf("failed to set IP neighbor: %v", err) } - p.log.Debugf("IP scan neighbor set to %v", config.Mode) + c.log.Infof("IP scan neighbor set to %v", config.Mode) return nil } // Unset returns IP scan neighbor configuration to default -func (p *IPNeighConfigurator) Unset() error { +func (c *IPNeighConfigurator) Unset() error { defaultCfg := &l3.IPScanNeighbor{ Mode: l3.IPScanNeighbor_DISABLED, } - if err := p.ipNeighHandler.SetIPScanNeighbor(defaultCfg); err != nil { - return err + if err := c.ipNeighHandler.SetIPScanNeighbor(defaultCfg); err != nil { + return errors.Errorf("failed to set IP neighbor to default: %v", err) } - p.log.Debug("IP scan neighbor set to default") + c.log.Info("IP scan neighbor set to default") return nil } + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *IPNeighConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} diff --git a/plugins/vpp/l3plugin/route_config.go b/plugins/vpp/l3plugin/route_config.go index b4abaa8869..4aef82a026 100644 --- a/plugins/vpp/l3plugin/route_config.go +++ b/plugins/vpp/l3plugin/route_config.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/l3 --gogo_out=../model/l3 ../model/l3/l3.proto - // Package l3plugin implements the L3 plugin that handles L3 FIBs. package l3plugin @@ -26,8 +24,9 @@ import ( "sort" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" + "github.com/gogo/protobuf/proto" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -78,61 +77,56 @@ type RouteConfigurator struct { // VPP API handlers ifHandler ifvppcalls.IfVppWrite rtHandler vppcalls.RouteVppAPI - - // Timer used to measure and store time - stopwatch *measure.Stopwatch } // Init members (channels...) and start go routines. -func (plugin *RouteConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *RouteConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-l3-route-conf") - plugin.log.Debug("Initializing L3 Route configurator") - - // Configurator-wide stopwatch instance - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("Route-configurator", plugin.log) - } + c.log = logger.NewLogger("l3-route-conf") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.rtIndexes = l3idx.NewRouteIndex(nametoidx.NewNameToIdx(plugin.log, "route_indexes", nil)) - plugin.rtCachedIndexes = l3idx.NewRouteIndex(nametoidx.NewNameToIdx(plugin.log, "route_cached_indexes", nil)) - plugin.rtIndexSeq = 1 + c.ifIndexes = swIfIndexes + c.rtIndexes = l3idx.NewRouteIndex(nametoidx.NewNameToIdx(c.log, "route_indexes", nil)) + c.rtCachedIndexes = l3idx.NewRouteIndex(nametoidx.NewNameToIdx(c.log, "route_cached_indexes", nil)) + c.rtIndexSeq = 1 // VPP channel - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handlers - plugin.ifHandler = ifvppcalls.NewIfVppHandler(plugin.vppChan, plugin.log, plugin.stopwatch) - plugin.rtHandler = vppcalls.NewRouteVppHandler(plugin.vppChan, plugin.ifIndexes, plugin.log, plugin.stopwatch) + c.ifHandler = ifvppcalls.NewIfVppHandler(c.vppChan, c.log) + c.rtHandler = vppcalls.NewRouteVppHandler(c.vppChan, c.ifIndexes, c.log) + + c.log.Debug("L3 Route configurator initialized") return nil } // GetRouteIndexes exposes rtIndexes mapping -func (plugin *RouteConfigurator) GetRouteIndexes() l3idx.RouteIndex { - return plugin.rtIndexes +func (c *RouteConfigurator) GetRouteIndexes() l3idx.RouteIndex { + return c.rtIndexes } // GetCachedRouteIndexes exposes rtCachedIndexes mapping -func (plugin *RouteConfigurator) GetCachedRouteIndexes() l3idx.RouteIndex { - return plugin.rtCachedIndexes +func (c *RouteConfigurator) GetCachedRouteIndexes() l3idx.RouteIndex { + return c.rtCachedIndexes } // Close GOVPP channel. -func (plugin *RouteConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *RouteConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose VPP route configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *RouteConfigurator) clearMapping() { - plugin.rtIndexes.Clear() - plugin.rtCachedIndexes.Clear() +func (c *RouteConfigurator) clearMapping() { + c.rtIndexes.Clear() + c.rtCachedIndexes.Clear() + c.log.Debugf("VPP ARP configurator mapping cleared") } // Create unique identifier which serves as a name in name-to-index mapping. @@ -144,180 +138,173 @@ func routeIdentifier(vrf uint32, destination string, nextHop string) string { } // ConfigureRoute processes the NB config and propagates it to bin api calls. -func (plugin *RouteConfigurator) ConfigureRoute(route *l3.StaticRoutes_Route, vrfFromKey string) error { - plugin.log.Infof("Configuring new route %v -> %v", route.DstIpAddr, route.NextHopAddr) +func (c *RouteConfigurator) ConfigureRoute(route *l3.StaticRoutes_Route, vrfFromKey string) error { // Validate VRF index from key and it's value in data. - if err := plugin.validateVrfFromKey(route, vrfFromKey); err != nil { + if err := c.validateVrfFromKey(route, vrfFromKey); err != nil { return err } routeID := routeIdentifier(route.VrfId, route.DstIpAddr, route.NextHopAddr) - swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, plugin.ifIndexes) + swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, c.ifIndexes) if err != nil { - plugin.rtCachedIndexes.RegisterName(routeID, plugin.rtIndexSeq, route) - plugin.rtIndexSeq++ - plugin.log.Debugf("Route %v registered to cache", routeID) + c.rtCachedIndexes.RegisterName(routeID, c.rtIndexSeq, route) + c.rtIndexSeq++ + c.log.Debugf("Route %v registered to cache", routeID) return nil } // Check mandatory destination address if route.DstIpAddr == "" { - return fmt.Errorf("route %v does not contain destination address", routeID) + return errors.Errorf("route %s does not contain destination address", routeID) } // Create new route. - err = plugin.rtHandler.VppAddRoute(plugin.ifHandler, route, swIdx) + err = c.rtHandler.VppAddRoute(c.ifHandler, route, swIdx) if err != nil { - return err + return errors.Errorf("failed to add VPP route %s: %v", routeID, err) } // Register configured route - _, _, routeExists := plugin.rtIndexes.LookupIdx(routeID) + _, _, routeExists := c.rtIndexes.LookupIdx(routeID) if !routeExists { - plugin.rtIndexes.RegisterName(routeID, plugin.rtIndexSeq, route) - plugin.rtIndexSeq++ - plugin.log.Infof("Route %v registered", routeID) + c.rtIndexes.RegisterName(routeID, c.rtIndexSeq, route) + c.rtIndexSeq++ + c.log.Infof("Route %v registered", routeID) } - plugin.log.Infof("Route %v -> %v configured", route.DstIpAddr, route.NextHopAddr) + c.log.Infof("Route %v -> %v configured", route.DstIpAddr, route.NextHopAddr) return nil } // ModifyRoute processes the NB config and propagates it to bin api calls. -func (plugin *RouteConfigurator) ModifyRoute(newConfig *l3.StaticRoutes_Route, oldConfig *l3.StaticRoutes_Route, vrfFromKey string) error { - plugin.log.Infof("Modifying route %v -> %v", oldConfig.DstIpAddr, oldConfig.NextHopAddr) - +func (c *RouteConfigurator) ModifyRoute(newConfig *l3.StaticRoutes_Route, oldConfig *l3.StaticRoutes_Route, vrfFromKey string) error { routeID := routeIdentifier(oldConfig.VrfId, oldConfig.DstIpAddr, oldConfig.NextHopAddr) if newConfig.OutgoingInterface != "" { - _, _, existsNewOutgoing := plugin.ifIndexes.LookupIdx(newConfig.OutgoingInterface) + _, _, existsNewOutgoing := c.ifIndexes.LookupIdx(newConfig.OutgoingInterface) newrouteID := routeIdentifier(newConfig.VrfId, newConfig.DstIpAddr, newConfig.NextHopAddr) if existsNewOutgoing { - plugin.log.Debugf("Route %s unregistered from cache", newrouteID) - plugin.rtCachedIndexes.UnregisterName(newrouteID) + c.rtCachedIndexes.UnregisterName(newrouteID) + c.log.Debugf("Route %s unregistered from cache", newrouteID) } else { - if routeIdx, _, isCached := plugin.rtCachedIndexes.LookupIdx(routeID); isCached { - plugin.rtCachedIndexes.RegisterName(newrouteID, routeIdx, newConfig) + if routeIdx, _, isCached := c.rtCachedIndexes.LookupIdx(routeID); isCached { + c.rtCachedIndexes.RegisterName(newrouteID, routeIdx, newConfig) + c.log.Debugf("Route %s registered to cache", newrouteID) } else { - plugin.rtCachedIndexes.RegisterName(newrouteID, plugin.rtIndexSeq, newConfig) - plugin.rtIndexSeq++ + c.rtCachedIndexes.RegisterName(newrouteID, c.rtIndexSeq, newConfig) + c.rtIndexSeq++ + c.log.Debugf("Route %s registered to cache", newrouteID) } } } - if err := plugin.deleteOldRoute(oldConfig, vrfFromKey); err != nil { + if err := c.deleteOldRoute(oldConfig, vrfFromKey); err != nil { return err } - if err := plugin.addNewRoute(newConfig, vrfFromKey); err != nil { + if err := c.addNewRoute(newConfig, vrfFromKey); err != nil { return err } - plugin.log.Infof("Route %v -> %v modified", oldConfig.DstIpAddr, oldConfig.NextHopAddr) + c.log.Infof("Route %s -> %s modified", oldConfig.DstIpAddr, oldConfig.NextHopAddr) return nil } -func (plugin *RouteConfigurator) deleteOldRoute(route *l3.StaticRoutes_Route, vrfFromKey string) error { +func (c *RouteConfigurator) deleteOldRoute(route *l3.StaticRoutes_Route, vrfFromKey string) error { // Check if route entry is not just cached routeID := routeIdentifier(route.VrfId, route.DstIpAddr, route.NextHopAddr) - _, _, found := plugin.rtCachedIndexes.LookupIdx(routeID) + _, _, found := c.rtCachedIndexes.LookupIdx(routeID) if found { - plugin.log.Debugf("Route entry %v found in cache, removed", routeID) - plugin.rtCachedIndexes.UnregisterName(routeID) + c.rtCachedIndexes.UnregisterName(routeID) + c.log.Debugf("Route entry %v found in cache, removed", routeID) // Cached route is not configured on the VPP, return return nil } - swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, plugin.ifIndexes) + swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, c.ifIndexes) if err != nil { return err } // Validate old cachedRoute data Vrf. - if err := plugin.validateVrfFromKey(route, vrfFromKey); err != nil { + if err := c.validateVrfFromKey(route, vrfFromKey); err != nil { return err } // Remove and unregister old route. - if err := plugin.rtHandler.VppDelRoute(route, swIdx); err != nil { - return err + if err := c.rtHandler.VppDelRoute(route, swIdx); err != nil { + return errors.Errorf("failed to delete VPP route %s: %v", routeID, err) } - _, _, found = plugin.rtIndexes.UnregisterName(routeID) + _, _, found = c.rtIndexes.UnregisterName(routeID) if found { - plugin.log.Infof("Old route %v unregistered", routeID) - } else { - plugin.log.Warnf("Unregister failed, old route %v not found", routeID) + c.log.Infof("Old route %s unregistered", routeID) } return nil } -func (plugin *RouteConfigurator) addNewRoute(route *l3.StaticRoutes_Route, vrfFromKey string) error { +func (c *RouteConfigurator) addNewRoute(route *l3.StaticRoutes_Route, vrfFromKey string) error { // Validate new route data Vrf. - if err := plugin.validateVrfFromKey(route, vrfFromKey); err != nil { + if err := c.validateVrfFromKey(route, vrfFromKey); err != nil { return err } - swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, plugin.ifIndexes) + swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, c.ifIndexes) if err != nil { return err } + routeID := routeIdentifier(route.VrfId, route.DstIpAddr, route.NextHopAddr) + // Create and register new route. - if err = plugin.rtHandler.VppAddRoute(plugin.ifHandler, route, swIdx); err != nil { - return err + if err = c.rtHandler.VppAddRoute(c.ifHandler, route, swIdx); err != nil { + return errors.Errorf("failed to add VPP route %s: %v", routeID, err) } + c.rtIndexes.RegisterName(routeID, c.rtIndexSeq, route) + c.rtIndexSeq++ + c.log.Debugf("New route %v registered", routeID) - routeID := routeIdentifier(route.VrfId, route.DstIpAddr, route.NextHopAddr) - plugin.rtIndexes.RegisterName(routeID, plugin.rtIndexSeq, route) - plugin.rtIndexSeq++ - - plugin.log.Infof("New route %v registered", routeID) return nil } // DeleteRoute processes the NB config and propagates it to bin api calls. -func (plugin *RouteConfigurator) DeleteRoute(route *l3.StaticRoutes_Route, vrfFromKey string) (wasError error) { - plugin.log.Infof("Removing route %v -> %v", route.DstIpAddr, route.NextHopAddr) - +func (c *RouteConfigurator) DeleteRoute(route *l3.StaticRoutes_Route, vrfFromKey string) (wasError error) { // Validate VRF index from key and it's value in data. - if err := plugin.validateVrfFromKey(route, vrfFromKey); err != nil { + if err := c.validateVrfFromKey(route, vrfFromKey); err != nil { return err } // Check if route entry is not just cached routeID := routeIdentifier(route.VrfId, route.DstIpAddr, route.NextHopAddr) - _, _, found := plugin.rtCachedIndexes.LookupIdx(routeID) + _, _, found := c.rtCachedIndexes.LookupIdx(routeID) if found { - plugin.log.Debugf("Route entry %v found in cache, removed", routeID) - plugin.rtCachedIndexes.UnregisterName(routeID) + c.rtCachedIndexes.UnregisterName(routeID) + c.log.Debugf("Route entry %v found in cache, removed", routeID) // Cached route is not configured on the VPP, return return nil } - swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, plugin.ifIndexes) + swIdx, err := resolveInterfaceSwIndex(route.OutgoingInterface, c.ifIndexes) if err != nil { return err } // Remove and unregister route. - if err := plugin.rtHandler.VppDelRoute(route, swIdx); err != nil { - return err + if err := c.rtHandler.VppDelRoute(route, swIdx); err != nil { + return errors.Errorf("failed to delete VPP route %s: %v", routeID, err) } routeIdentifier := routeIdentifier(route.VrfId, route.DstIpAddr, route.NextHopAddr) - _, _, found = plugin.rtIndexes.UnregisterName(routeIdentifier) + _, _, found = c.rtIndexes.UnregisterName(routeIdentifier) if found { - plugin.log.Infof("Route %v unregistered", routeIdentifier) - } else { - plugin.log.Warnf("Unregister failed, route %v not found", routeIdentifier) + c.log.Infof("Route %v unregistered", routeIdentifier) } - plugin.log.Infof("Route %v -> %v removed", route.DstIpAddr, route.NextHopAddr) + c.log.Infof("Route %v -> %v removed", route.DstIpAddr, route.NextHopAddr) return nil } // DiffRoutes calculates route diff from two sets of routes and returns routes to be added and removed -func (plugin *RouteConfigurator) DiffRoutes(new, old []*l3.StaticRoutes_Route) (toBeDeleted, toBeAdded []*l3.StaticRoutes_Route) { +func (c *RouteConfigurator) DiffRoutes(new, old []*l3.StaticRoutes_Route) (toBeDeleted, toBeAdded []*l3.StaticRoutes_Route) { oldSorted, newSorted := SortedRoutes(old), SortedRoutes(new) sort.Sort(newSorted) sort.Sort(oldSorted) @@ -325,7 +312,7 @@ func (plugin *RouteConfigurator) DiffRoutes(new, old []*l3.StaticRoutes_Route) ( // Compare. i, j := 0, 0 for i < len(newSorted) && j < len(oldSorted) { - if *newSorted[i] == *oldSorted[j] { + if proto.Equal(newSorted[i], oldSorted[j]) { i++ j++ } else { @@ -350,54 +337,48 @@ func (plugin *RouteConfigurator) DiffRoutes(new, old []*l3.StaticRoutes_Route) ( } // ResolveCreatedInterface is responsible for reconfiguring cached routes and then from removing them from route cache -func (plugin *RouteConfigurator) ResolveCreatedInterface(ifName string, swIdx uint32) { - routesWithIndex := plugin.rtCachedIndexes.LookupRouteAndIDByOutgoingIfc(ifName) +func (c *RouteConfigurator) ResolveCreatedInterface(ifName string, swIdx uint32) error { + routesWithIndex := c.rtCachedIndexes.LookupRouteAndIDByOutgoingIfc(ifName) if len(routesWithIndex) == 0 { - return + return nil } - plugin.log.Infof("Route configurator: resolving new interface %v for %d routes", ifName, len(routesWithIndex)) for _, routeWithIndex := range routesWithIndex { route := routeWithIndex.Route - plugin.log.WithFields(logging.Fields{ - "ifName": ifName, - "swIdx": swIdx, - "vrfID": route.VrfId, - "dstIPAddr": route.DstIpAddr, - }).Debug("Remove routes from route cache - outgoing interface was added.") vrf := strconv.FormatUint(uint64(route.VrfId), 10) - if err := plugin.recreateRoute(route, vrf); err != nil { - plugin.log.Errorf("Error recreating interface %s: %v", ifName, err) + if err := c.recreateRoute(route, vrf); err != nil { + return errors.Errorf("Error recreating route %s with interface %s: %v", + routeWithIndex.RouteID, ifName, err) } - plugin.rtCachedIndexes.UnregisterName(routeWithIndex.RouteID) + c.rtCachedIndexes.UnregisterName(routeWithIndex.RouteID) + c.log.Debugf("Route %s removed from cache", routeWithIndex.RouteID) } + + return nil } // ResolveDeletedInterface is responsible for moving routes of deleted interface to cache -func (plugin *RouteConfigurator) ResolveDeletedInterface(ifName string, swIdx uint32) { - routesWithIndex := plugin.rtIndexes.LookupRouteAndIDByOutgoingIfc(ifName) +func (c *RouteConfigurator) ResolveDeletedInterface(ifName string, swIdx uint32) error { + routesWithIndex := c.rtIndexes.LookupRouteAndIDByOutgoingIfc(ifName) if len(routesWithIndex) == 0 { - return + return nil } - plugin.log.Debugf("Route configurator: resolving deleted interface %v for %d routes", ifName, len(routesWithIndex)) for _, routeWithIndex := range routesWithIndex { route := routeWithIndex.Route - plugin.log.WithFields(logging.Fields{ - "ifName": ifName, - "swIdx": swIdx, - "vrfID": route.VrfId, - "dstIPAddr": route.DstIpAddr, - }).Debug("Add routes to route cache - outgoing interface was deleted.") - plugin.moveRouteToCache(route) + if err := c.moveRouteToCache(route); err != nil { + return err + } } + + return nil } -func (plugin *RouteConfigurator) validateVrfFromKey(config *l3.StaticRoutes_Route, vrfFromKey string) error { +func (c *RouteConfigurator) validateVrfFromKey(config *l3.StaticRoutes_Route, vrfFromKey string) error { intVrfFromKey, err := strconv.Atoi(vrfFromKey) if intVrfFromKey != int(config.VrfId) { if err != nil { - return err + return errors.Errorf("failed to validate route VRF value from key: %v", err) } - plugin.log.Warnf("VRF index from key (%v) and from config (%v) does not match, using value from the key", + c.log.Warnf("VRF index from key (%v) and from config (%v) does not match, using value from the key", intVrfFromKey, config.VrfId) config.VrfId = uint32(intVrfFromKey) } @@ -415,25 +396,23 @@ It is neither possible to recreate interface and then create route. It is only possible to recreate interface, delete old associated routes (like clean old mess) and then add them again. */ -func (plugin *RouteConfigurator) recreateRoute(route *l3.StaticRoutes_Route, vrf string) error { - if err := plugin.DeleteRoute(route, vrf); err != nil { - return nil +func (c *RouteConfigurator) recreateRoute(route *l3.StaticRoutes_Route, vrf string) error { + if err := c.DeleteRoute(route, vrf); err != nil { + return errors.Errorf("failed to remove route which should be recreated: %v", err) } - return plugin.ConfigureRoute(route, vrf) + return c.ConfigureRoute(route, vrf) } -func (plugin *RouteConfigurator) moveRouteToCache(config *l3.StaticRoutes_Route) (wasError error) { +func (c *RouteConfigurator) moveRouteToCache(config *l3.StaticRoutes_Route) (wasError error) { routeID := routeIdentifier(config.VrfId, config.DstIpAddr, config.NextHopAddr) - _, _, found := plugin.rtIndexes.UnregisterName(routeID) + _, _, found := c.rtIndexes.UnregisterName(routeID) if found { - plugin.log.Infof("Route %v unregistered", routeID) - } else { - plugin.log.Warnf("Unregister failed, route %v not found", routeID) + c.log.Infof("Route %v unregistered", routeID) } - plugin.log.Infof("Route %s registrated in cache", routeID) - plugin.rtCachedIndexes.RegisterName(routeID, plugin.rtIndexSeq, config) - plugin.rtIndexSeq++ + c.rtCachedIndexes.RegisterName(routeID, c.rtIndexSeq, config) + c.rtIndexSeq++ + c.log.Debugf("Route %s registered to cache", routeID) return nil } @@ -444,7 +423,7 @@ func resolveInterfaceSwIndex(ifName string, index ifaceidx.SwIfIndex) (uint32, e var exists bool ifIndex, _, exists = index.LookupIdx(ifName) if !exists { - return ifIndex, fmt.Errorf("route outgoing interface %v not found", ifName) + return ifIndex, errors.Errorf("route outgoing interface %s not found", ifName) } } return ifIndex, nil @@ -473,5 +452,18 @@ func lessRoute(a, b *l3.StaticRoutes_Route) bool { return a.Preference < b.Preference } return a.Weight < b.Weight +} +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *RouteConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err } diff --git a/plugins/vpp/l3plugin/route_config_test.go b/plugins/vpp/l3plugin/route_config_test.go index 594a7774b2..eb717656be 100644 --- a/plugins/vpp/l3plugin/route_config_test.go +++ b/plugins/vpp/l3plugin/route_config_test.go @@ -17,8 +17,9 @@ package l3plugin_test import ( "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" @@ -383,7 +384,7 @@ func TestResolveDeletedRoute(t *testing.T) { func routeTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l3plugin.RouteConfigurator, ifaceidx.SwIfIndex) { RegisterTestingT(t) ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -391,7 +392,7 @@ func routeTestSetup(t *testing.T) (*vppcallmock.TestCtx, *core.Connection, *l3pl plugin := &l3plugin.RouteConfigurator{} ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logging.ForPlugin("test-log"), "l3-plugin", nil)) - err = plugin.Init(logging.ForPlugin("test-log"), connection, ifIndexes, false) + err = plugin.Init(logging.ForPlugin("test-log"), connection, ifIndexes) Expect(err).To(BeNil()) return ctx, connection, plugin, ifIndexes diff --git a/plugins/vpp/l3plugin/vppcalls/api_vppcalls.go b/plugins/vpp/l3plugin/vppcalls/api_vppcalls.go index a6b10f703e..827bbb1dba 100644 --- a/plugins/vpp/l3plugin/vppcalls/api_vppcalls.go +++ b/plugins/vpp/l3plugin/vppcalls/api_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( govppapi "git.fd.io/govpp.git/api" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/vppcalls" "github.com/ligato/vpp-agent/plugins/vpp/model/l3" @@ -97,7 +96,6 @@ type IPNeighVppAPI interface { // ArpVppHandler is accessor for ARP-related vppcalls methods type ArpVppHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel ifIndexes ifaceidx.SwIfIndex log logging.Logger @@ -105,7 +103,6 @@ type ArpVppHandler struct { // ProxyArpVppHandler is accessor for proxy ARP-related vppcalls methods type ProxyArpVppHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel ifIndexes ifaceidx.SwIfIndex log logging.Logger @@ -113,7 +110,6 @@ type ProxyArpVppHandler struct { // RouteHandler is accessor for route-related vppcalls methods type RouteHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel ifIndexes ifaceidx.SwIfIndex log logging.Logger @@ -121,46 +117,41 @@ type RouteHandler struct { // IPNeighHandler is accessor for ip-neighbor-related vppcalls methods type IPNeighHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel log logging.Logger } // NewArpVppHandler creates new instance of IPsec vppcalls handler -func NewArpVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *ArpVppHandler { +func NewArpVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *ArpVppHandler { return &ArpVppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, log: log, } } // NewProxyArpVppHandler creates new instance of proxy ARP vppcalls handler -func NewProxyArpVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *ProxyArpVppHandler { +func NewProxyArpVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *ProxyArpVppHandler { return &ProxyArpVppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, log: log, } } // NewRouteVppHandler creates new instance of route vppcalls handler -func NewRouteVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger, stopwatch *measure.Stopwatch) *RouteHandler { +func NewRouteVppHandler(callsChan govppapi.Channel, ifIndexes ifaceidx.SwIfIndex, log logging.Logger) *RouteHandler { return &RouteHandler{ callsChannel: callsChan, - stopwatch: stopwatch, ifIndexes: ifIndexes, log: log, } } // NewIPNeighVppHandler creates new instance of ip neighbor vppcalls handler -func NewIPNeighVppHandler(callsChan govppapi.Channel, log logging.Logger, stopwatch *measure.Stopwatch) *IPNeighHandler { +func NewIPNeighVppHandler(callsChan govppapi.Channel, log logging.Logger) *IPNeighHandler { return &IPNeighHandler{ callsChannel: callsChan, - stopwatch: stopwatch, log: log, } } diff --git a/plugins/vpp/l3plugin/vppcalls/arp_dump.go b/plugins/vpp/l3plugin/vppcalls/arp_dump.go index f2b1e597b4..5c9bbfb4bc 100644 --- a/plugins/vpp/l3plugin/vppcalls/arp_dump.go +++ b/plugins/vpp/l3plugin/vppcalls/arp_dump.go @@ -17,7 +17,6 @@ package vppcalls import ( "fmt" "net" - "time" l3binapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" "github.com/ligato/vpp-agent/plugins/vpp/model/l3" @@ -35,16 +34,9 @@ type ArpMeta struct { } // DumpArpEntries implements arp handler. -func (handler *ArpVppHandler) DumpArpEntries() ([]*ArpDetails, error) { - // ArpDump time measurement - defer func(t time.Time) { - handler.stopwatch.TimeLog(l3binapi.IPNeighborDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ArpVppHandler) DumpArpEntries() ([]*ArpDetails, error) { var entries []*ArpDetails - - // Dump ARPs. - reqCtx := handler.callsChannel.SendMultiRequest(&l3binapi.IPNeighborDump{ + reqCtx := h.callsChannel.SendMultiRequest(&l3binapi.IPNeighborDump{ SwIfIndex: 0xffffffff, // Send multirequest to get all ARP entries }) @@ -55,14 +47,14 @@ func (handler *ArpVppHandler) DumpArpEntries() ([]*ArpDetails, error) { break } if err != nil { - handler.log.Error(err) + h.log.Error(err) return nil, err } // ARP interface - ifName, _, exists := handler.ifIndexes.LookupName(arpDetails.SwIfIndex) + ifName, _, exists := h.ifIndexes.LookupName(arpDetails.SwIfIndex) if !exists { - handler.log.Warnf("ARP dump: interface name not found for index %d", arpDetails.SwIfIndex) + h.log.Warnf("ARP dump: interface name not found for index %d", arpDetails.SwIfIndex) } // IP & MAC address var ip, mac string diff --git a/plugins/vpp/l3plugin/vppcalls/arp_vppcalls.go b/plugins/vpp/l3plugin/vppcalls/arp_vppcalls.go index 405cf07459..228e932200 100644 --- a/plugins/vpp/l3plugin/vppcalls/arp_vppcalls.go +++ b/plugins/vpp/l3plugin/vppcalls/arp_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( "fmt" "net" - "time" "github.com/ligato/cn-infra/utils/addrs" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" @@ -32,11 +31,7 @@ type ArpEntry struct { } // vppAddDelArp adds or removes ARP entry according to provided input -func (handler *ArpVppHandler) vppAddDelArp(entry *ArpEntry, delete bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ip.IPNeighborAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ArpVppHandler) vppAddDelArp(entry *ArpEntry, delete bool) error { req := &ip.IPNeighborAddDel{ SwIfIndex: entry.Interface, IsNoAdjFib: 1, @@ -71,7 +66,7 @@ func (handler *ArpVppHandler) vppAddDelArp(entry *ArpEntry, delete bool) error { reply := &ip.IPNeighborAddDelReply{} // Send message - if err = handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err = h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) @@ -81,11 +76,11 @@ func (handler *ArpVppHandler) vppAddDelArp(entry *ArpEntry, delete bool) error { } // VppAddArp implements arp handler. -func (handler *ArpVppHandler) VppAddArp(entry *ArpEntry) error { - return handler.vppAddDelArp(entry, false) +func (h *ArpVppHandler) VppAddArp(entry *ArpEntry) error { + return h.vppAddDelArp(entry, false) } // VppDelArp implements arp handler. -func (handler *ArpVppHandler) VppDelArp(entry *ArpEntry) error { - return handler.vppAddDelArp(entry, true) +func (h *ArpVppHandler) VppDelArp(entry *ArpEntry) error { + return h.vppAddDelArp(entry, true) } diff --git a/plugins/vpp/l3plugin/vppcalls/arp_vppcalls_test.go b/plugins/vpp/l3plugin/vppcalls/arp_vppcalls_test.go index c862a8db60..cd7f4c426a 100644 --- a/plugins/vpp/l3plugin/vppcalls/arp_vppcalls_test.go +++ b/plugins/vpp/l3plugin/vppcalls/arp_vppcalls_test.go @@ -81,6 +81,6 @@ func arpTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.ArpVppAPI) { ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "arp-if-idx", nil)) - arpHandler := vppcalls.NewArpVppHandler(ctx.MockChannel, ifIndexes, log, nil) + arpHandler := vppcalls.NewArpVppHandler(ctx.MockChannel, ifIndexes, log) return ctx, arpHandler } diff --git a/plugins/vpp/l3plugin/vppcalls/ipneigh_vppcalls.go b/plugins/vpp/l3plugin/vppcalls/ipneigh_vppcalls.go index b6c445792f..99c3b039b7 100644 --- a/plugins/vpp/l3plugin/vppcalls/ipneigh_vppcalls.go +++ b/plugins/vpp/l3plugin/vppcalls/ipneigh_vppcalls.go @@ -16,7 +16,6 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" "github.com/ligato/vpp-agent/plugins/vpp/model/l3" @@ -24,10 +23,6 @@ import ( // SetIPScanNeighbor implements ip neigh handler. func (h *IPNeighHandler) SetIPScanNeighbor(data *l3.IPScanNeighbor) error { - defer func(t time.Time) { - h.stopwatch.TimeLog(ip.IPScanNeighborEnableDisable{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &ip.IPScanNeighborEnableDisable{ Mode: uint8(data.Mode), ScanInterval: uint8(data.ScanInterval), diff --git a/plugins/vpp/l3plugin/vppcalls/proxyarp_dump.go b/plugins/vpp/l3plugin/vppcalls/proxyarp_dump.go index baa4821a61..6266d7b17b 100644 --- a/plugins/vpp/l3plugin/vppcalls/proxyarp_dump.go +++ b/plugins/vpp/l3plugin/vppcalls/proxyarp_dump.go @@ -17,7 +17,6 @@ package vppcalls import ( "fmt" "net" - "time" l3binapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" "github.com/ligato/vpp-agent/plugins/vpp/model/l3" @@ -29,14 +28,8 @@ type ProxyArpRangesDetails struct { } // DumpProxyArpRanges implements proxy arp handler. -func (handler *ProxyArpVppHandler) DumpProxyArpRanges() (pArpRngs []*ProxyArpRangesDetails, err error) { - // ArpDump time measurement - defer func(t time.Time) { - handler.stopwatch.TimeLog(l3binapi.ProxyArpDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - // Dump proxy ARP rages - reqCtx := handler.callsChannel.SendMultiRequest(&l3binapi.ProxyArpDump{}) +func (h *ProxyArpVppHandler) DumpProxyArpRanges() (pArpRngs []*ProxyArpRangesDetails, err error) { + reqCtx := h.callsChannel.SendMultiRequest(&l3binapi.ProxyArpDump{}) for { proxyArpDetails := &l3binapi.ProxyArpDetails{} @@ -45,7 +38,7 @@ func (handler *ProxyArpVppHandler) DumpProxyArpRanges() (pArpRngs []*ProxyArpRan break } if err != nil { - handler.log.Error(err) + h.log.Error(err) return nil, err } @@ -72,13 +65,8 @@ type ProxyArpInterfaceMeta struct { } // DumpProxyArpInterfaces implements proxy arp handler. -func (handler *ProxyArpVppHandler) DumpProxyArpInterfaces() (pArpIfs []*ProxyArpInterfaceDetails, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(l3binapi.ProxyArpIntfcDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - // Dump proxy ARP interfaces - reqCtx := handler.callsChannel.SendMultiRequest(&l3binapi.ProxyArpIntfcDump{}) +func (h *ProxyArpVppHandler) DumpProxyArpInterfaces() (pArpIfs []*ProxyArpInterfaceDetails, err error) { + reqCtx := h.callsChannel.SendMultiRequest(&l3binapi.ProxyArpIntfcDump{}) for { proxyArpDetails := &l3binapi.ProxyArpIntfcDetails{} @@ -87,14 +75,14 @@ func (handler *ProxyArpVppHandler) DumpProxyArpInterfaces() (pArpIfs []*ProxyArp break } if err != nil { - handler.log.Error(err) + h.log.Error(err) return nil, err } // Interface - ifName, _, exists := handler.ifIndexes.LookupName(proxyArpDetails.SwIfIndex) + ifName, _, exists := h.ifIndexes.LookupName(proxyArpDetails.SwIfIndex) if !exists { - handler.log.Warnf("Proxy ARP interface dump: missing name for interface index %d", proxyArpDetails.SwIfIndex) + h.log.Warnf("Proxy ARP interface dump: missing name for interface index %d", proxyArpDetails.SwIfIndex) } // Create entry diff --git a/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls.go b/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls.go index fab2e6fc6e..54211ef8b6 100644 --- a/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls.go +++ b/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls.go @@ -16,37 +16,32 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" ) // EnableProxyArpInterface implements proxy arp handler. -func (handler *ProxyArpVppHandler) EnableProxyArpInterface(swIfIdx uint32) error { - return handler.vppAddDelProxyArpInterface(swIfIdx, true) +func (h *ProxyArpVppHandler) EnableProxyArpInterface(swIfIdx uint32) error { + return h.vppAddDelProxyArpInterface(swIfIdx, true) } // DisableProxyArpInterface implements proxy arp handler. -func (handler *ProxyArpVppHandler) DisableProxyArpInterface(swIfIdx uint32) error { - return handler.vppAddDelProxyArpInterface(swIfIdx, false) +func (h *ProxyArpVppHandler) DisableProxyArpInterface(swIfIdx uint32) error { + return h.vppAddDelProxyArpInterface(swIfIdx, false) } // AddProxyArpRange implements proxy arp handler. -func (handler *ProxyArpVppHandler) AddProxyArpRange(firstIP, lastIP []byte) error { - return handler.vppAddDelProxyArpRange(firstIP, lastIP, true) +func (h *ProxyArpVppHandler) AddProxyArpRange(firstIP, lastIP []byte) error { + return h.vppAddDelProxyArpRange(firstIP, lastIP, true) } // DeleteProxyArpRange implements proxy arp handler. -func (handler *ProxyArpVppHandler) DeleteProxyArpRange(firstIP, lastIP []byte) error { - return handler.vppAddDelProxyArpRange(firstIP, lastIP, false) +func (h *ProxyArpVppHandler) DeleteProxyArpRange(firstIP, lastIP []byte) error { + return h.vppAddDelProxyArpRange(firstIP, lastIP, false) } // vppAddDelProxyArpInterface adds or removes proxy ARP interface entry according to provided input -func (handler *ProxyArpVppHandler) vppAddDelProxyArpInterface(swIfIdx uint32, enable bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ip.ProxyArpIntfcEnableDisable{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ProxyArpVppHandler) vppAddDelProxyArpInterface(swIfIdx uint32, enable bool) error { req := &ip.ProxyArpIntfcEnableDisable{} if enable { req.EnableDisable = 1 @@ -57,24 +52,20 @@ func (handler *ProxyArpVppHandler) vppAddDelProxyArpInterface(swIfIdx uint32, en // Send message reply := &ip.ProxyArpIntfcEnableDisableReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) } - handler.log.Debugf("interface %v enabled for proxy arp: %v", req.SwIfIndex, enable) + h.log.Debugf("interface %v enabled for proxy arp: %v", req.SwIfIndex, enable) return nil } // vppAddDelProxyArpRange adds or removes proxy ARP range according to provided input -func (handler *ProxyArpVppHandler) vppAddDelProxyArpRange(firstIP, lastIP []byte, isAdd bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ip.ProxyArpAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *ProxyArpVppHandler) vppAddDelProxyArpRange(firstIP, lastIP []byte, isAdd bool) error { req := &ip.ProxyArpAddDel{} if isAdd { req.IsAdd = 1 @@ -88,13 +79,13 @@ func (handler *ProxyArpVppHandler) vppAddDelProxyArpRange(firstIP, lastIP []byte reply := &ip.ProxyArpAddDelReply{} // Send message - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %d", reply.GetMessageName(), reply.Retval) } - handler.log.Debugf("proxy arp range: %v - %v added: %v", req.Proxy.LowAddress, req.Proxy.HiAddress, isAdd) + h.log.Debugf("proxy arp range: %v - %v added: %v", req.Proxy.LowAddress, req.Proxy.HiAddress, isAdd) return nil } diff --git a/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls_test.go b/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls_test.go index bf40f8b325..c53013b6f1 100644 --- a/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls_test.go +++ b/plugins/vpp/l3plugin/vppcalls/proxyarp_vppcalls_test.go @@ -66,7 +66,7 @@ func pArpTestSetup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.ArpVppAPI, vppc ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "proxy-arp-if-idx", nil)) - arpHandler := vppcalls.NewArpVppHandler(ctx.MockChannel, ifIndexes, log, nil) - pArpHandler := vppcalls.NewProxyArpVppHandler(ctx.MockChannel, ifIndexes, log, nil) + arpHandler := vppcalls.NewArpVppHandler(ctx.MockChannel, ifIndexes, log) + pArpHandler := vppcalls.NewProxyArpVppHandler(ctx.MockChannel, ifIndexes, log) return ctx, arpHandler, pArpHandler } diff --git a/plugins/vpp/l3plugin/vppcalls/route_dump.go b/plugins/vpp/l3plugin/vppcalls/route_dump.go index 532882a3d1..1ecbd457dd 100644 --- a/plugins/vpp/l3plugin/vppcalls/route_dump.go +++ b/plugins/vpp/l3plugin/vppcalls/route_dump.go @@ -18,7 +18,6 @@ import ( "bytes" "fmt" "net" - "time" l3binapi "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" "github.com/ligato/vpp-agent/plugins/vpp/model/l3" @@ -51,16 +50,10 @@ type RouteMeta struct { } // DumpStaticRoutes implements route handler. -func (handler *RouteHandler) DumpStaticRoutes() ([]*RouteDetails, error) { - // IPFibDump time measurement - defer func(t time.Time) { - handler.stopwatch.TimeLog(l3binapi.IPFibDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *RouteHandler) DumpStaticRoutes() ([]*RouteDetails, error) { var routes []*RouteDetails - // Dump IPv4 l3 FIB. - reqCtx := handler.callsChannel.SendMultiRequest(&l3binapi.IPFibDump{}) + reqCtx := h.callsChannel.SendMultiRequest(&l3binapi.IPFibDump{}) for { fibDetails := &l3binapi.IPFibDetails{} stop, err := reqCtx.ReceiveReply(fibDetails) @@ -70,7 +63,7 @@ func (handler *RouteHandler) DumpStaticRoutes() ([]*RouteDetails, error) { if err != nil { return nil, err } - ipv4Route, err := handler.dumpStaticRouteIPv4Details(fibDetails) + ipv4Route, err := h.dumpStaticRouteIPv4Details(fibDetails) if err != nil { return nil, err } @@ -78,7 +71,7 @@ func (handler *RouteHandler) DumpStaticRoutes() ([]*RouteDetails, error) { } // Dump IPv6 l3 FIB. - reqCtx = handler.callsChannel.SendMultiRequest(&l3binapi.IP6FibDump{}) + reqCtx = h.callsChannel.SendMultiRequest(&l3binapi.IP6FibDump{}) for { fibDetails := &l3binapi.IP6FibDetails{} stop, err := reqCtx.ReceiveReply(fibDetails) @@ -88,7 +81,7 @@ func (handler *RouteHandler) DumpStaticRoutes() ([]*RouteDetails, error) { if err != nil { return nil, err } - ipv6Route, err := handler.dumpStaticRouteIPv6Details(fibDetails) + ipv6Route, err := h.dumpStaticRouteIPv6Details(fibDetails) if err != nil { return nil, err } @@ -98,17 +91,17 @@ func (handler *RouteHandler) DumpStaticRoutes() ([]*RouteDetails, error) { return routes, nil } -func (handler *RouteHandler) dumpStaticRouteIPv4Details(fibDetails *l3binapi.IPFibDetails) ([]*RouteDetails, error) { - return handler.dumpStaticRouteIPDetails(fibDetails.TableID, fibDetails.TableName, fibDetails.Address, fibDetails.AddressLength, fibDetails.Path, false) +func (h *RouteHandler) dumpStaticRouteIPv4Details(fibDetails *l3binapi.IPFibDetails) ([]*RouteDetails, error) { + return h.dumpStaticRouteIPDetails(fibDetails.TableID, fibDetails.TableName, fibDetails.Address, fibDetails.AddressLength, fibDetails.Path, false) } -func (handler *RouteHandler) dumpStaticRouteIPv6Details(fibDetails *l3binapi.IP6FibDetails) ([]*RouteDetails, error) { - return handler.dumpStaticRouteIPDetails(fibDetails.TableID, fibDetails.TableName, fibDetails.Address, fibDetails.AddressLength, fibDetails.Path, true) +func (h *RouteHandler) dumpStaticRouteIPv6Details(fibDetails *l3binapi.IP6FibDetails) ([]*RouteDetails, error) { + return h.dumpStaticRouteIPDetails(fibDetails.TableID, fibDetails.TableName, fibDetails.Address, fibDetails.AddressLength, fibDetails.Path, true) } // dumpStaticRouteIPDetails processes static route details and returns a route objects. Number of routes returned // depends on size of path list. -func (handler *RouteHandler) dumpStaticRouteIPDetails(tableID uint32, tableName []byte, address []byte, prefixLen uint8, paths []l3binapi.FibPath, ipv6 bool) ([]*RouteDetails, error) { +func (h *RouteHandler) dumpStaticRouteIPDetails(tableID uint32, tableName []byte, address []byte, prefixLen uint8, paths []l3binapi.FibPath, ipv6 bool) ([]*RouteDetails, error) { // Common fields for every route path (destination IP, VRF) var dstIP string if ipv6 { @@ -133,12 +126,12 @@ func (handler *RouteHandler) dumpStaticRouteIPDetails(tableID uint32, tableName // Route type (if via VRF is used) var routeType l3.StaticRoutes_Route_RouteType var viaVrfID uint32 - if path.SwIfIndex == NextHopOutgoingIfUnset && path.TableID != tableID { - // outgoing interface not specified and path table id not equal to route table id = inter-VRF route + if uintToBool(path.IsDrop) { + routeType = l3.StaticRoutes_Route_DROP + } else if path.SwIfIndex == NextHopOutgoingIfUnset && path.TableID != tableID { + // outgoing interface not specified and path table is not equal to route table id = inter-VRF route routeType = l3.StaticRoutes_Route_INTER_VRF viaVrfID = path.TableID - } else if uintToBool(path.IsDrop) { - routeType = l3.StaticRoutes_Route_DROP } else { routeType = l3.StaticRoutes_Route_INTRA_VRF // default } @@ -146,11 +139,13 @@ func (handler *RouteHandler) dumpStaticRouteIPDetails(tableID uint32, tableName // Outgoing interface var ifName string var ifIdx uint32 - if path.SwIfIndex != ^uint32(0) { + if path.SwIfIndex == NextHopOutgoingIfUnset { + ifIdx = NextHopOutgoingIfUnset + } else { var exists bool ifIdx = path.SwIfIndex - if ifName, _, exists = handler.ifIndexes.LookupName(path.SwIfIndex); !exists { - handler.log.Warnf("Static route dump: interface name for index %d not found", path.SwIfIndex) + if ifName, _, exists = h.ifIndexes.LookupName(path.SwIfIndex); !exists { + h.log.Warnf("Static route dump: interface name for index %d not found", path.SwIfIndex) } } @@ -192,7 +187,7 @@ func (handler *RouteHandler) dumpStaticRouteIPDetails(tableID uint32, tableName } } else { // Return route without path fields, but this is not a valid configuration - handler.log.Warnf("Route with destination IP %s (VRF %d) has no path specified", dstIP, tableID) + h.log.Warnf("Route with destination IP %s (VRF %d) has no path specified", dstIP, tableID) route := &l3.StaticRoutes_Route{ Type: l3.StaticRoutes_Route_INTRA_VRF, // default VrfId: tableID, diff --git a/plugins/vpp/l3plugin/vppcalls/route_dump_test.go b/plugins/vpp/l3plugin/vppcalls/route_dump_test.go index ff12ca4ca5..7a74f9f268 100644 --- a/plugins/vpp/l3plugin/vppcalls/route_dump_test.go +++ b/plugins/vpp/l3plugin/vppcalls/route_dump_test.go @@ -30,7 +30,7 @@ import ( func TestDumpStaticRoutes(t *testing.T) { ctx := vppcallmock.SetupTestCtx(t) ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(logrus.DefaultLogger(), "rt-dump-if-idx", nil)) - l3handler := NewRouteVppHandler(ctx.MockChannel, ifIndexes, logrus.DefaultLogger(), nil) + l3handler := NewRouteVppHandler(ctx.MockChannel, ifIndexes, logrus.DefaultLogger()) defer ctx.TeardownTestCtx() ifIndexes.RegisterName("if1", 2, nil) diff --git a/plugins/vpp/l3plugin/vppcalls/route_vppcalls.go b/plugins/vpp/l3plugin/vppcalls/route_vppcalls.go index a052b314ae..2f9d41f63f 100644 --- a/plugins/vpp/l3plugin/vppcalls/route_vppcalls.go +++ b/plugins/vpp/l3plugin/vppcalls/route_vppcalls.go @@ -16,8 +16,6 @@ package vppcalls import ( "fmt" - "time" - "net" "github.com/ligato/cn-infra/utils/addrs" @@ -41,11 +39,7 @@ const ( ) // vppAddDelRoute adds or removes route, according to provided input. Every route has to contain VRF ID (default is 0). -func (handler *RouteHandler) vppAddDelRoute(route *l3.StaticRoutes_Route, rtIfIdx uint32, delete bool) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(ip.IPAddDelRoute{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *RouteHandler) vppAddDelRoute(route *l3.StaticRoutes_Route, rtIfIdx uint32, delete bool) error { req := &ip.IPAddDelRoute{} if delete { req.IsAdd = 0 @@ -94,7 +88,7 @@ func (handler *RouteHandler) vppAddDelRoute(route *l3.StaticRoutes_Route, rtIfId // Send message reply := &ip.IPAddDelRouteReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { @@ -105,7 +99,7 @@ func (handler *RouteHandler) vppAddDelRoute(route *l3.StaticRoutes_Route, rtIfId } // VppAddRoute implements route handler. -func (handler *RouteHandler) VppAddRoute(ifHandler ifvppcalls.IfVppWrite, route *l3.StaticRoutes_Route, rtIfIdx uint32) error { +func (h *RouteHandler) VppAddRoute(ifHandler ifvppcalls.IfVppWrite, route *l3.StaticRoutes_Route, rtIfIdx uint32) error { // Evaluate route IP version _, isIPv6, err := addrs.ParseIPWithPrefix(route.DstIpAddr) if err != nil { @@ -133,10 +127,10 @@ func (handler *RouteHandler) VppAddRoute(ifHandler ifvppcalls.IfVppWrite, route } } } - return handler.vppAddDelRoute(route, rtIfIdx, false) + return h.vppAddDelRoute(route, rtIfIdx, false) } // VppDelRoute implements route handler. -func (handler *RouteHandler) VppDelRoute(route *l3.StaticRoutes_Route, rtIfIdx uint32) error { - return handler.vppAddDelRoute(route, rtIfIdx, true) +func (h *RouteHandler) VppDelRoute(route *l3.StaticRoutes_Route, rtIfIdx uint32) error { + return h.vppAddDelRoute(route, rtIfIdx, true) } diff --git a/plugins/vpp/l3plugin/vppcalls/route_vppcalls_test.go b/plugins/vpp/l3plugin/vppcalls/route_vppcalls_test.go index 62a5765c85..936c48ff1b 100644 --- a/plugins/vpp/l3plugin/vppcalls/route_vppcalls_test.go +++ b/plugins/vpp/l3plugin/vppcalls/route_vppcalls_test.go @@ -80,8 +80,8 @@ func TestDeleteRoute(t *testing.T) { func routeTestSetup(t *testing.T) (*vppcallmock.TestCtx, ifvppcalls.IfVppAPI, vppcalls.RouteVppAPI) { ctx := vppcallmock.SetupTestCtx(t) log := logrus.NewLogger("test-log") - ifHandler := ifvppcalls.NewIfVppHandler(ctx.MockChannel, log, nil) + ifHandler := ifvppcalls.NewIfVppHandler(ctx.MockChannel, log) ifIndexes := ifaceidx.NewSwIfIndex(nametoidx.NewNameToIdx(log, "rt-if-idx", nil)) - rtHandler := vppcalls.NewRouteVppHandler(ctx.MockChannel, ifIndexes, log, nil) + rtHandler := vppcalls.NewRouteVppHandler(ctx.MockChannel, ifIndexes, log) return ctx, ifHandler, rtHandler } diff --git a/plugins/vpp/l4plugin/appns_config.go b/plugins/vpp/l4plugin/appns_config.go index 18d25091d8..be2ad45fd2 100644 --- a/plugins/vpp/l4plugin/appns_config.go +++ b/plugins/vpp/l4plugin/appns_config.go @@ -12,16 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/l4 --gogo_out=../model/l4 ../model/l4/l4.proto - package l4plugin import ( - "fmt" - govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/govppmux" @@ -51,234 +47,232 @@ type AppNsConfigurator struct { // VPP API handler l4Handler vppcalls.L4VppAPI - stopwatch *measure.Stopwatch - // Feature flag - internal state whether the L4 features are enabled or disabled l4ftEnabled bool } // Init members (channels...) and start go routines -func (plugin *AppNsConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool) (err error) { +func (c *AppNsConfigurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex) (err error) { // Logger - plugin.log = logger.NewLogger("-l4-plugin") - plugin.log.Debugf("Initializing L4 configurator") + c.log = logger.NewLogger("l4-plugin") // Mappings - plugin.ifIndexes = swIfIndexes - plugin.appNsIndexes = nsidx.NewAppNsIndex(nametoidx.NewNameToIdx(plugin.log, "namespace_indexes", nil)) - plugin.appNsCached = nsidx.NewAppNsIndex(nametoidx.NewNameToIdx(plugin.log, "not_configured_namespace_indexes", nil)) - plugin.appNsIdxSeq = 1 - - // Stopwatch - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("AppNsConfigurator", plugin.log) - } + c.ifIndexes = swIfIndexes + c.appNsIndexes = nsidx.NewAppNsIndex(nametoidx.NewNameToIdx(c.log, "namespace_indexes", nil)) + c.appNsCached = nsidx.NewAppNsIndex(nametoidx.NewNameToIdx(c.log, "not_configured_namespace_indexes", nil)) + c.appNsIdxSeq = 1 // VPP channels - if plugin.vppChan, err = goVppMux.NewAPIChannel(); err != nil { - return err + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handler - plugin.l4Handler = vppcalls.NewL4VppHandler(plugin.vppChan, plugin.log, plugin.stopwatch) + c.l4Handler = vppcalls.NewL4VppHandler(c.vppChan, c.log) + + c.log.Debugf("L4 configurator initialized") return nil } // Close members, channels -func (plugin *AppNsConfigurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *AppNsConfigurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose l4 configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *AppNsConfigurator) clearMapping() { - plugin.appNsIndexes.Clear() - plugin.appNsCached.Clear() +func (c *AppNsConfigurator) clearMapping() { + c.appNsIndexes.Clear() + c.appNsCached.Clear() + c.log.Debugf("l4 configurator mapping cleared") } // GetAppNsIndexes returns application namespace memory indexes -func (plugin *AppNsConfigurator) GetAppNsIndexes() nsidx.AppNsIndexRW { - return plugin.appNsIndexes +func (c *AppNsConfigurator) GetAppNsIndexes() nsidx.AppNsIndexRW { + return c.appNsIndexes } // ConfigureL4FeatureFlag process the NB Features config and propagates it to bin api calls -func (plugin *AppNsConfigurator) ConfigureL4FeatureFlag(features *l4.L4Features) error { - plugin.log.Info("Setting up L4 features") - +func (c *AppNsConfigurator) ConfigureL4FeatureFlag(features *l4.L4Features) error { if features.Enabled { - if err := plugin.configureL4FeatureFlag(); err != nil { + if err := c.configureL4FeatureFlag(); err != nil { return err } - return plugin.resolveCachedNamespaces() + return c.resolveCachedNamespaces() } - return plugin.DeleteL4FeatureFlag() + c.DeleteL4FeatureFlag() + + return nil } // configureL4FeatureFlag process the NB Features config and propagates it to bin api calls -func (plugin *AppNsConfigurator) configureL4FeatureFlag() error { - plugin.log.Info("Configuring L4 features") - - if err := plugin.l4Handler.EnableL4Features(); err != nil { - plugin.log.Errorf("Enabling L4 features failed: %v", err) - return err +func (c *AppNsConfigurator) configureL4FeatureFlag() error { + if err := c.l4Handler.EnableL4Features(); err != nil { + return errors.Errorf("failed to enable L4 features: %v", err) } - plugin.l4ftEnabled = true - plugin.log.Infof("L4 features enabled") + c.l4ftEnabled = true + c.log.Infof("L4 features enabled") return nil } // DeleteL4FeatureFlag process the NB Features config and propagates it to bin api calls -func (plugin *AppNsConfigurator) DeleteL4FeatureFlag() error { - plugin.log.Info("Removing L4 features") - - if err := plugin.l4Handler.DisableL4Features(); err != nil { - plugin.log.Errorf("Disabling L4 features failed: %v", err) - return err +func (c *AppNsConfigurator) DeleteL4FeatureFlag() error { + if err := c.l4Handler.DisableL4Features(); err != nil { + return errors.Errorf("failed to disable L4 features: %v", err) } - plugin.l4ftEnabled = false - plugin.log.Infof("L4 features disabled") + c.l4ftEnabled = false + c.log.Infof("L4 features disabled") return nil } // ConfigureAppNamespace process the NB AppNamespace config and propagates it to bin api calls -func (plugin *AppNsConfigurator) ConfigureAppNamespace(ns *l4.AppNamespaces_AppNamespace) error { - plugin.log.Infof("Configuring new AppNamespace with ID %v", ns.NamespaceId) - +func (c *AppNsConfigurator) ConfigureAppNamespace(ns *l4.AppNamespaces_AppNamespace) error { // Validate data if ns.Interface == "" { - return fmt.Errorf("application namespace %v does not contain interface", ns.NamespaceId) + return errors.Errorf("application namespace %s does not contain interface", ns.NamespaceId) } // Check whether L4 l4ftEnabled are enabled. If not, all namespaces created earlier are added to cache - if !plugin.l4ftEnabled { - plugin.appNsCached.RegisterName(ns.NamespaceId, plugin.appNsIdxSeq, ns) - plugin.appNsIdxSeq++ - plugin.log.Infof("Unable to configure application namespace %v due to disabled L4 features, moving to cache", ns.NamespaceId) + if !c.l4ftEnabled { + c.appNsCached.RegisterName(ns.NamespaceId, c.appNsIdxSeq, ns) + c.appNsIdxSeq++ + c.log.Debugf("cannot configure application namespace %s: L4 features are disabled, moved to cache", + ns.NamespaceId) return nil } // Find interface. If not found, add to cache for not configured namespaces - ifIdx, _, found := plugin.ifIndexes.LookupIdx(ns.Interface) + ifIdx, _, found := c.ifIndexes.LookupIdx(ns.Interface) if !found { - plugin.appNsCached.RegisterName(ns.NamespaceId, plugin.appNsIdxSeq, ns) - plugin.appNsIdxSeq++ - plugin.log.Infof("Unable to configure application namespace %v due to missing interface, moving to cache", ns.NamespaceId) + c.appNsCached.RegisterName(ns.NamespaceId, c.appNsIdxSeq, ns) + c.appNsIdxSeq++ + c.log.Infof("cannot configure application namespace %s: interface %s is missing", + ns.NamespaceId, ns.Interface) return nil } - return plugin.configureAppNamespace(ns, ifIdx) + if err := c.configureAppNamespace(ns, ifIdx); err != nil { + return err + } + + c.log.Info("application namespace %s configured", ns.NamespaceId) + + return nil } // ModifyAppNamespace process the NB AppNamespace config and propagates it to bin api calls -func (plugin *AppNsConfigurator) ModifyAppNamespace(newNs *l4.AppNamespaces_AppNamespace, oldNs *l4.AppNamespaces_AppNamespace) error { - plugin.log.Infof("Modifying AppNamespace with ID %v", newNs.NamespaceId) - +func (c *AppNsConfigurator) ModifyAppNamespace(newNs *l4.AppNamespaces_AppNamespace, oldNs *l4.AppNamespaces_AppNamespace) error { // Validate data if newNs.Interface == "" { - return fmt.Errorf("modified application namespace %v does not contain interface", newNs.NamespaceId) + return errors.Errorf("modified application namespace %s does not contain interface", newNs.NamespaceId) } // At first, unregister the old configuration from both mappings (if exists) - plugin.appNsIndexes.UnregisterName(oldNs.NamespaceId) - plugin.appNsCached.UnregisterName(oldNs.NamespaceId) + c.appNsIndexes.UnregisterName(oldNs.NamespaceId) + c.appNsCached.UnregisterName(oldNs.NamespaceId) + c.log.Debugf("application namespace %s removed from index map and cache", oldNs.NamespaceId) // Check whether L4 l4ftEnabled are enabled. If not, all namespaces created earlier are added to cache - if !plugin.l4ftEnabled { - plugin.appNsCached.RegisterName(newNs.NamespaceId, plugin.appNsIdxSeq, newNs) - plugin.log.Infof("Unable to modify application namespace %v due to disabled L4 features, moving to cache", newNs.NamespaceId) - plugin.appNsIdxSeq++ + if !c.l4ftEnabled { + c.appNsCached.RegisterName(newNs.NamespaceId, c.appNsIdxSeq, newNs) + c.appNsIdxSeq++ + c.log.Debugf("cannot modify application namespace %s: L4 features are disabled, moved to cache", + newNs.NamespaceId) return nil } // Check interface - ifIdx, _, found := plugin.ifIndexes.LookupIdx(newNs.Interface) + ifIdx, _, found := c.ifIndexes.LookupIdx(newNs.Interface) if !found { - plugin.appNsCached.RegisterName(newNs.NamespaceId, plugin.appNsIdxSeq, newNs) - plugin.log.Infof("Unable to modify application namespace %v due to missing interface, moving to cache", newNs.NamespaceId) - plugin.appNsIdxSeq++ + c.appNsCached.RegisterName(newNs.NamespaceId, c.appNsIdxSeq, newNs) + c.appNsIdxSeq++ + c.log.Infof("cannot modify application namespace %s: interface %s is missing", + newNs.NamespaceId, newNs.Interface) return nil } // TODO: remove namespace - return plugin.configureAppNamespace(newNs, ifIdx) + if err := c.configureAppNamespace(newNs, ifIdx); err != nil { + return err + } + + c.log.Info("application namespace %s modified", newNs.NamespaceId) + + return nil } // DeleteAppNamespace process the NB AppNamespace config and propagates it to bin api calls. This case is not currently // supported by VPP -func (plugin *AppNsConfigurator) DeleteAppNamespace(ns *l4.AppNamespaces_AppNamespace) error { +func (c *AppNsConfigurator) DeleteAppNamespace(ns *l4.AppNamespaces_AppNamespace) error { // TODO: implement - plugin.log.Warn("AppNamespace removal not supported by the VPP") + c.log.Warn("cannot remove application namespace %s: unsupported", ns.NamespaceId) return nil } // ResolveCreatedInterface looks for application namespace this interface is assigned to and configures them -func (plugin *AppNsConfigurator) ResolveCreatedInterface(interfaceName string, interfaceIndex uint32) error { +func (c *AppNsConfigurator) ResolveCreatedInterface(ifName string, ifIdx uint32) error { // If L4 features are not enabled, skip (and keep all in cache) - if !plugin.l4ftEnabled { + if !c.l4ftEnabled { return nil } // Search mapping for unregistered application namespaces using the new interface - cachedAppNs := plugin.appNsCached.LookupNamesByInterface(interfaceName) + cachedAppNs := c.appNsCached.LookupNamesByInterface(ifName) if len(cachedAppNs) == 0 { return nil } - var wasErr error - plugin.log.Infof("L4 configurator: resolving new interface %v for %d app namespaces", interfaceName, len(cachedAppNs)) - for _, appNamespace := range cachedAppNs { - if err := plugin.configureAppNamespace(appNamespace, interfaceIndex); err != nil { - plugin.log.Errorf("configuring app namespace %v failed: %v", appNamespace, err) - wasErr = err + for _, appNs := range cachedAppNs { + if err := c.configureAppNamespace(appNs, ifIdx); err != nil { + return errors.Errorf("failed to configure application namespace %s with registered interface %s: %v", + appNs.NamespaceId, ifName, err) } // Remove from cache - plugin.appNsCached.UnregisterName(appNamespace.NamespaceId) + c.appNsCached.UnregisterName(appNs.NamespaceId) + c.log.Debugf("application namespace %s removed from cache", appNs.NamespaceId) } - return wasErr + return nil } // ResolveDeletedInterface looks for application namespace this interface is assigned to and removes -func (plugin *AppNsConfigurator) ResolveDeletedInterface(interfaceName string, interfaceIndex uint32) error { - +func (c *AppNsConfigurator) ResolveDeletedInterface(ifName string, ifIdx uint32) error { // Search mapping for configured application namespaces using the new interface - cachedAppNs := plugin.appNsIndexes.LookupNamesByInterface(interfaceName) + cachedAppNs := c.appNsIndexes.LookupNamesByInterface(ifName) if len(cachedAppNs) == 0 { return nil } - plugin.log.Infof("L4 configurator: resolving deleted interface %v for %d app namespaces", interfaceName, len(cachedAppNs)) - for _, appNamespace := range cachedAppNs { + for _, appNs := range cachedAppNs { // TODO: remove namespace. Also check whether it can be done while L4Features are disabled // Unregister from configured namespaces mapping - plugin.appNsIndexes.UnregisterName(appNamespace.NamespaceId) + c.appNsIndexes.UnregisterName(appNs.NamespaceId) // Add to un-configured. If the interface will be recreated, all namespaces are configured back - plugin.appNsCached.RegisterName(appNamespace.NamespaceId, plugin.appNsIdxSeq, appNamespace) - plugin.appNsIdxSeq++ + c.appNsCached.RegisterName(appNs.NamespaceId, c.appNsIdxSeq, appNs) + c.log.Debugf("application namespace %s removed from mapping and added to cache (unregistered interface %s)", + appNs.NamespaceId, ifName) + c.appNsIdxSeq++ } return nil } -func (plugin *AppNsConfigurator) configureAppNamespace(ns *l4.AppNamespaces_AppNamespace, ifIdx uint32) error { +func (c *AppNsConfigurator) configureAppNamespace(ns *l4.AppNamespaces_AppNamespace, ifIdx uint32) error { // Namespace ID nsID := []byte(ns.NamespaceId) - plugin.log.Debugf("Adding App Namespace %v to interface %v", ns.NamespaceId, ifIdx) - - appNsIdx, err := plugin.l4Handler.AddAppNamespace(ns.Secret, ifIdx, ns.Ipv4FibId, ns.Ipv6FibId, nsID) + appNsIdx, err := c.l4Handler.AddAppNamespace(ns.Secret, ifIdx, ns.Ipv4FibId, ns.Ipv6FibId, nsID) if err != nil { - return err + return errors.Errorf("failed to add application namespace %s: %v", ns.NamespaceId, err) } // register namespace - plugin.appNsIndexes.RegisterName(ns.NamespaceId, appNsIdx, ns) - plugin.log.Debugf("Application namespace %v registered", ns.NamespaceId) - - plugin.log.WithFields(logging.Fields{"appNsIdx": appNsIdx}). - Debugf("AppNamespace %v configured", ns.NamespaceId) + c.appNsIndexes.RegisterName(ns.NamespaceId, appNsIdx, ns) + c.log.Debugf("Application namespace %s registered", ns.NamespaceId) return nil } @@ -287,36 +281,48 @@ func (plugin *AppNsConfigurator) configureAppNamespace(ns *l4.AppNamespaces_AppN // - the required interface was missing // - the L4 features were disabled // Namespaces skipped due to the second case are configured here -func (plugin *AppNsConfigurator) resolveCachedNamespaces() error { - cachedAppNs := plugin.appNsCached.ListNames() +func (c *AppNsConfigurator) resolveCachedNamespaces() error { + cachedAppNs := c.appNsCached.ListNames() if len(cachedAppNs) == 0 { return nil } - plugin.log.Infof("Configuring %d cached namespaces after L4 features were enabled", len(cachedAppNs)) + c.log.Debugf("Configuring %d cached namespaces after L4 features were enabled", len(cachedAppNs)) // Scan all registered indexes in mapping for un-configured application namespaces - var wasErr error for _, name := range cachedAppNs { - _, ns, found := plugin.appNsCached.LookupIdx(name) + _, ns, found := c.appNsCached.LookupIdx(name) if !found { continue } // Check interface. If still missing, continue (keep namespace in cache) - ifIdx, _, found := plugin.ifIndexes.LookupIdx(ns.Interface) + ifIdx, _, found := c.ifIndexes.LookupIdx(ns.Interface) if !found { - plugin.log.Infof("Unable to configure application namespace %v due to missing interface, keeping in cache", ns.NamespaceId) continue } - if err := plugin.configureAppNamespace(ns, ifIdx); err != nil { - plugin.log.Errorf("configuring app namespace %v failed: %v", ns, err) - wasErr = err - } else { - // AppNamespace was configured, remove from cache - plugin.appNsCached.UnregisterName(ns.NamespaceId) + if err := c.configureAppNamespace(ns, ifIdx); err != nil { + return err } + // AppNamespace was configured, remove from cache + c.appNsCached.UnregisterName(ns.NamespaceId) + c.log.Debugf("Application namespace %s unregistered from cache", ns.NamespaceId) + } + + return nil +} + +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *AppNsConfigurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) } - return wasErr + return err } diff --git a/plugins/vpp/l4plugin/data_resync.go b/plugins/vpp/l4plugin/data_resync.go index 9f97c0a426..6bedbcd906 100644 --- a/plugins/vpp/l4plugin/data_resync.go +++ b/plugins/vpp/l4plugin/data_resync.go @@ -15,56 +15,36 @@ package l4plugin import ( + "github.com/go-errors/errors" "github.com/ligato/vpp-agent/plugins/vpp/model/l4" ) // ResyncAppNs configures app namespaces to the empty VPP -func (plugin *AppNsConfigurator) ResyncAppNs(appNamespaces []*l4.AppNamespaces_AppNamespace) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC application namespaces begin. ") - - // Calculate and log application namespaces resync - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - +func (c *AppNsConfigurator) ResyncAppNs(appNamespaces []*l4.AppNamespaces_AppNamespace) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() - var wasError error if len(appNamespaces) > 0 { for _, appNs := range appNamespaces { - if err := plugin.ConfigureAppNamespace(appNs); err != nil { - plugin.log.Error(err) - wasError = err + if err := c.ConfigureAppNamespace(appNs); err != nil { + return errors.Errorf("app-ns resync error: failed to configure application namespace %s: %v", + appNs.NamespaceId, err) } } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC application namespaces end.") + c.log.Info("Application namespace resync done.") - return wasError + return nil } -// ResyncFeatures sets initital L4Features flag -func (plugin *AppNsConfigurator) ResyncFeatures(l4Features *l4.L4Features) error { - plugin.log.WithField("cfg", plugin).Debug("RESYNC L4Features begin. ") - - // Calculate and log L4Features resync - defer func() { - if plugin.stopwatch != nil { - plugin.stopwatch.PrintLog() - } - }() - - var wasError error +// ResyncFeatures sets initial L4Features flag +func (c *AppNsConfigurator) ResyncFeatures(l4Features *l4.L4Features) error { if l4Features != nil { - if err := plugin.ConfigureL4FeatureFlag(l4Features); err != nil { - plugin.log.Error(err) - wasError = err + if err := c.ConfigureL4FeatureFlag(l4Features); err != nil { + return errors.Errorf("app-ns resync error: failed to configure L4: %v", err) } } - plugin.log.WithField("cfg", plugin).Debug("RESYNC L4Features end.") + c.log.Info("L4 features resync done.") - return wasError + return nil } diff --git a/plugins/vpp/l4plugin/vppcalls/api_vppcalls.go b/plugins/vpp/l4plugin/vppcalls/api_vppcalls.go index 0cc4f2f5ed..35bf41cc5e 100644 --- a/plugins/vpp/l4plugin/vppcalls/api_vppcalls.go +++ b/plugins/vpp/l4plugin/vppcalls/api_vppcalls.go @@ -17,7 +17,6 @@ package vppcalls import ( govppapi "git.fd.io/govpp.git/api" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" ) // L4VppAPI provides methods for managing L4 layer configuration @@ -44,16 +43,14 @@ type L4VppRead interface { // L4VppHandler is accessor for l4-related vppcalls methods type L4VppHandler struct { - stopwatch *measure.Stopwatch callsChannel govppapi.Channel log logging.Logger } // NewL4VppHandler creates new instance of L4 vppcalls handler -func NewL4VppHandler(callsChan govppapi.Channel, log logging.Logger, stopwatch *measure.Stopwatch) *L4VppHandler { +func NewL4VppHandler(callsChan govppapi.Channel, log logging.Logger) *L4VppHandler { return &L4VppHandler{ callsChannel: callsChan, - stopwatch: stopwatch, log: log, } } diff --git a/plugins/vpp/l4plugin/vppcalls/app_namespace_vppcalls.go b/plugins/vpp/l4plugin/vppcalls/app_namespace_vppcalls.go index 4fed32d4c0..cd39deb1b1 100644 --- a/plugins/vpp/l4plugin/vppcalls/app_namespace_vppcalls.go +++ b/plugins/vpp/l4plugin/vppcalls/app_namespace_vppcalls.go @@ -16,17 +16,12 @@ package vppcalls import ( "fmt" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/session" ) // AddAppNamespace adds app namespace. -func (handler *L4VppHandler) AddAppNamespace(secret uint64, swIfIdx, ip4FibID, ip6FibID uint32, id []byte) (appNsIdx uint32, err error) { - defer func(t time.Time) { - handler.stopwatch.TimeLog(session.AppNamespaceAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *L4VppHandler) AddAppNamespace(secret uint64, swIfIdx, ip4FibID, ip6FibID uint32, id []byte) (appNsIdx uint32, err error) { req := &session.AppNamespaceAddDel{ SwIfIndex: swIfIdx, Secret: secret, @@ -37,7 +32,7 @@ func (handler *L4VppHandler) AddAppNamespace(secret uint64, swIfIdx, ip4FibID, i } reply := &session.AppNamespaceAddDelReply{} - if err = handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err = h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return 0, err } else if reply.Retval != 0 { return 0, fmt.Errorf("%s returned %v", reply.GetMessageName(), reply.Retval) diff --git a/plugins/vpp/l4plugin/vppcalls/dump_vppcalls.go b/plugins/vpp/l4plugin/vppcalls/dump_vppcalls.go index 761715ed17..319fec1d87 100644 --- a/plugins/vpp/l4plugin/vppcalls/dump_vppcalls.go +++ b/plugins/vpp/l4plugin/vppcalls/dump_vppcalls.go @@ -18,7 +18,6 @@ import ( "bytes" "fmt" "net" - "time" "github.com/ligato/vpp-agent/plugins/vpp/binapi/session" ) @@ -37,16 +36,10 @@ type SessionDetails struct { } // DumpL4Config implements L4VppRead. -func (handler *L4VppHandler) DumpL4Config() ([]*SessionDetails, error) { - // ArpDump time measurement - defer func(t time.Time) { - handler.stopwatch.TimeLog(session.SessionRulesDump{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *L4VppHandler) DumpL4Config() ([]*SessionDetails, error) { var appNsDetails []*SessionDetails - // Dump ARPs. - reqCtx := handler.callsChannel.SendMultiRequest(&session.SessionRulesDump{}) + reqCtx := h.callsChannel.SendMultiRequest(&session.SessionRulesDump{}) for { sessions := &session.SessionRulesDetails{} @@ -55,7 +48,7 @@ func (handler *L4VppHandler) DumpL4Config() ([]*SessionDetails, error) { break } if err != nil { - handler.log.Error(err) + h.log.Error(err) return nil, err } diff --git a/plugins/vpp/l4plugin/vppcalls/features_vppcalls.go b/plugins/vpp/l4plugin/vppcalls/features_vppcalls.go index e81eac167c..d513861760 100644 --- a/plugins/vpp/l4plugin/vppcalls/features_vppcalls.go +++ b/plugins/vpp/l4plugin/vppcalls/features_vppcalls.go @@ -21,13 +21,13 @@ import ( ) // EnableL4Features enables L4 features. -func (handler *L4VppHandler) EnableL4Features() error { +func (h *L4VppHandler) EnableL4Features() error { req := &session.SessionEnableDisable{ IsEnable: 1, } reply := &session.SessionEnableDisableReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %v", reply.GetMessageName(), reply.Retval) @@ -37,13 +37,13 @@ func (handler *L4VppHandler) EnableL4Features() error { } // DisableL4Features disables L4 features. -func (handler *L4VppHandler) DisableL4Features() error { +func (h *L4VppHandler) DisableL4Features() error { req := &session.SessionEnableDisable{ IsEnable: 0, } reply := &session.SessionEnableDisableReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } else if reply.Retval != 0 { return fmt.Errorf("%s returned %v", reply.GetMessageName(), reply.Retval) diff --git a/plugins/vpp/model/acl/acl.pb.go b/plugins/vpp/model/acl/acl.pb.go index 9b107b183d..c6b301a904 100644 --- a/plugins/vpp/model/acl/acl.pb.go +++ b/plugins/vpp/model/acl/acl.pb.go @@ -1,15 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: acl.proto -/* -Package acl is a generated protocol buffer package. - -It is generated from these files: - acl.proto - -It has these top-level messages: - AccessLists -*/ package acl import proto "github.com/gogo/protobuf/proto" @@ -49,18 +40,42 @@ var AclAction_value = map[string]int32{ func (x AclAction) String() string { return proto.EnumName(AclAction_name, int32(x)) } -func (AclAction) EnumDescriptor() ([]byte, []int) { return fileDescriptorAcl, []int{0} } +func (AclAction) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_acl_700e6e99ae46a356, []int{0} +} // This is a top level container for Access Control Lists. // It can have one or more Access Control Lists. type AccessLists struct { - Acls []*AccessLists_Acl `protobuf:"bytes,1,rep,name=acls" json:"acls,omitempty"` + Acls []*AccessLists_Acl `protobuf:"bytes,1,rep,name=acls" json:"acls,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *AccessLists) Reset() { *m = AccessLists{} } -func (m *AccessLists) String() string { return proto.CompactTextString(m) } -func (*AccessLists) ProtoMessage() {} -func (*AccessLists) Descriptor() ([]byte, []int) { return fileDescriptorAcl, []int{0} } +func (m *AccessLists) Reset() { *m = AccessLists{} } +func (m *AccessLists) String() string { return proto.CompactTextString(m) } +func (*AccessLists) ProtoMessage() {} +func (*AccessLists) Descriptor() ([]byte, []int) { + return fileDescriptor_acl_700e6e99ae46a356, []int{0} +} +func (m *AccessLists) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists.Unmarshal(m, b) +} +func (m *AccessLists) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists.Marshal(b, m, deterministic) +} +func (dst *AccessLists) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists.Merge(dst, src) +} +func (m *AccessLists) XXX_Size() int { + return xxx_messageInfo_AccessLists.Size(m) +} +func (m *AccessLists) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists proto.InternalMessageInfo func (m *AccessLists) GetAcls() []*AccessLists_Acl { if m != nil { @@ -77,13 +92,35 @@ type AccessLists_Acl struct { AclName string `protobuf:"bytes,1,opt,name=acl_name,json=aclName,proto3" json:"acl_name,omitempty"` Rules []*AccessLists_Acl_Rule `protobuf:"bytes,2,rep,name=rules" json:"rules,omitempty"` // The set of interfaces that has assigned this ACL on ingres or egress. - Interfaces *AccessLists_Acl_Interfaces `protobuf:"bytes,3,opt,name=interfaces" json:"interfaces,omitempty"` + Interfaces *AccessLists_Acl_Interfaces `protobuf:"bytes,3,opt,name=interfaces" json:"interfaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *AccessLists_Acl) Reset() { *m = AccessLists_Acl{} } -func (m *AccessLists_Acl) String() string { return proto.CompactTextString(m) } -func (*AccessLists_Acl) ProtoMessage() {} -func (*AccessLists_Acl) Descriptor() ([]byte, []int) { return fileDescriptorAcl, []int{0, 0} } +func (m *AccessLists_Acl) Reset() { *m = AccessLists_Acl{} } +func (m *AccessLists_Acl) String() string { return proto.CompactTextString(m) } +func (*AccessLists_Acl) ProtoMessage() {} +func (*AccessLists_Acl) Descriptor() ([]byte, []int) { + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0} +} +func (m *AccessLists_Acl) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl.Unmarshal(m, b) +} +func (m *AccessLists_Acl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl.Merge(dst, src) +} +func (m *AccessLists_Acl) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl.Size(m) +} +func (m *AccessLists_Acl) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl proto.InternalMessageInfo func (m *AccessLists_Acl) GetAclName() string { if m != nil { @@ -117,14 +154,36 @@ type AccessLists_Acl_Rule struct { // A unique name identifying this Access List Entry (Rule) RuleName string `protobuf:"bytes,1,opt,name=rule_name,json=ruleName,proto3" json:"rule_name,omitempty"` // Action for this Access List Rule - AclAction AclAction `protobuf:"varint,2,opt,name=acl_action,json=aclAction,proto3,enum=acl.AclAction" json:"acl_action,omitempty"` - Match *AccessLists_Acl_Rule_Match `protobuf:"bytes,3,opt,name=match" json:"match,omitempty"` + AclAction AclAction `protobuf:"varint,2,opt,name=acl_action,json=aclAction,proto3,enum=acl.AclAction" json:"acl_action,omitempty"` + Match *AccessLists_Acl_Rule_Match `protobuf:"bytes,3,opt,name=match" json:"match,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessLists_Acl_Rule) Reset() { *m = AccessLists_Acl_Rule{} } +func (m *AccessLists_Acl_Rule) String() string { return proto.CompactTextString(m) } +func (*AccessLists_Acl_Rule) ProtoMessage() {} +func (*AccessLists_Acl_Rule) Descriptor() ([]byte, []int) { + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0} +} +func (m *AccessLists_Acl_Rule) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule.Merge(dst, src) +} +func (m *AccessLists_Acl_Rule) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule.Size(m) +} +func (m *AccessLists_Acl_Rule) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule.DiscardUnknown(m) } -func (m *AccessLists_Acl_Rule) Reset() { *m = AccessLists_Acl_Rule{} } -func (m *AccessLists_Acl_Rule) String() string { return proto.CompactTextString(m) } -func (*AccessLists_Acl_Rule) ProtoMessage() {} -func (*AccessLists_Acl_Rule) Descriptor() ([]byte, []int) { return fileDescriptorAcl, []int{0, 0, 0} } +var xxx_messageInfo_AccessLists_Acl_Rule proto.InternalMessageInfo func (m *AccessLists_Acl_Rule) GetRuleName() string { if m != nil { @@ -149,16 +208,36 @@ func (m *AccessLists_Acl_Rule) GetMatch() *AccessLists_Acl_Rule_Match { // Definitions for match criteria for this Access List Rule type AccessLists_Acl_Rule_Match struct { - IpRule *AccessLists_Acl_Rule_Match_IpRule `protobuf:"bytes,1,opt,name=ip_rule,json=ipRule" json:"ip_rule,omitempty"` - MacipRule *AccessLists_Acl_Rule_Match_MacIpRule `protobuf:"bytes,2,opt,name=macip_rule,json=macipRule" json:"macip_rule,omitempty"` + IpRule *AccessLists_Acl_Rule_Match_IpRule `protobuf:"bytes,1,opt,name=ip_rule,json=ipRule" json:"ip_rule,omitempty"` + MacipRule *AccessLists_Acl_Rule_Match_MacIpRule `protobuf:"bytes,2,opt,name=macip_rule,json=macipRule" json:"macip_rule,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match) Reset() { *m = AccessLists_Acl_Rule_Match{} } func (m *AccessLists_Acl_Rule_Match) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Rule_Match) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0} +} +func (m *AccessLists_Acl_Rule_Match) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match.Merge(dst, src) } +func (m *AccessLists_Acl_Rule_Match) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match.Size(m) +} +func (m *AccessLists_Acl_Rule_Match) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl_Rule_Match proto.InternalMessageInfo func (m *AccessLists_Acl_Rule_Match) GetIpRule() *AccessLists_Acl_Rule_Match_IpRule { if m != nil { @@ -182,19 +261,39 @@ func (m *AccessLists_Acl_Rule_Match) GetMacipRule() *AccessLists_Acl_Rule_Match_ // * UDP (port range) // * TCP (port range, flags mask, flags value) type AccessLists_Acl_Rule_Match_IpRule struct { - Ip *AccessLists_Acl_Rule_Match_IpRule_Ip `protobuf:"bytes,1,opt,name=ip" json:"ip,omitempty"` - Icmp *AccessLists_Acl_Rule_Match_IpRule_Icmp `protobuf:"bytes,2,opt,name=icmp" json:"icmp,omitempty"` - Tcp *AccessLists_Acl_Rule_Match_IpRule_Tcp `protobuf:"bytes,3,opt,name=tcp" json:"tcp,omitempty"` - Udp *AccessLists_Acl_Rule_Match_IpRule_Udp `protobuf:"bytes,4,opt,name=udp" json:"udp,omitempty"` + Ip *AccessLists_Acl_Rule_Match_IpRule_Ip `protobuf:"bytes,1,opt,name=ip" json:"ip,omitempty"` + Icmp *AccessLists_Acl_Rule_Match_IpRule_Icmp `protobuf:"bytes,2,opt,name=icmp" json:"icmp,omitempty"` + Tcp *AccessLists_Acl_Rule_Match_IpRule_Tcp `protobuf:"bytes,3,opt,name=tcp" json:"tcp,omitempty"` + Udp *AccessLists_Acl_Rule_Match_IpRule_Udp `protobuf:"bytes,4,opt,name=udp" json:"udp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_IpRule) Reset() { *m = AccessLists_Acl_Rule_Match_IpRule{} } func (m *AccessLists_Acl_Rule_Match_IpRule) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Rule_Match_IpRule) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_IpRule) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 0} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 0} +} +func (m *AccessLists_Acl_Rule_Match_IpRule) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match_IpRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_IpRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule.Merge(dst, src) +} +func (m *AccessLists_Acl_Rule_Match_IpRule) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule.Size(m) +} +func (m *AccessLists_Acl_Rule_Match_IpRule) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule.DiscardUnknown(m) } +var xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule proto.InternalMessageInfo + func (m *AccessLists_Acl_Rule_Match_IpRule) GetIp() *AccessLists_Acl_Rule_Match_IpRule_Ip { if m != nil { return m.Ip @@ -228,15 +327,35 @@ type AccessLists_Acl_Rule_Match_IpRule_Ip struct { // Destination IPv4/IPv6 network address (/) DestinationNetwork string `protobuf:"bytes,1,opt,name=destination_network,json=destinationNetwork,proto3" json:"destination_network,omitempty"` // Destination IPv4/IPv6 network address (/) - SourceNetwork string `protobuf:"bytes,2,opt,name=source_network,json=sourceNetwork,proto3" json:"source_network,omitempty"` + SourceNetwork string `protobuf:"bytes,2,opt,name=source_network,json=sourceNetwork,proto3" json:"source_network,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_IpRule_Ip) Reset() { *m = AccessLists_Acl_Rule_Match_IpRule_Ip{} } func (m *AccessLists_Acl_Rule_Match_IpRule_Ip) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Rule_Match_IpRule_Ip) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_IpRule_Ip) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 0, 0} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 0, 0} +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Ip) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Ip.Unmarshal(m, b) } +func (m *AccessLists_Acl_Rule_Match_IpRule_Ip) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Ip.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_IpRule_Ip) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Ip.Merge(dst, src) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Ip) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Ip.Size(m) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Ip) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Ip.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Ip proto.InternalMessageInfo func (m *AccessLists_Acl_Rule_Match_IpRule_Ip) GetDestinationNetwork() string { if m != nil { @@ -256,8 +375,11 @@ type AccessLists_Acl_Rule_Match_IpRule_Icmp struct { // ICMPv6 flag, if false ICMPv4 will be used Icmpv6 bool `protobuf:"varint,1,opt,name=icmpv6,proto3" json:"icmpv6,omitempty"` // Inclusive range representing icmp codes to be used. - IcmpCodeRange *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range `protobuf:"bytes,2,opt,name=icmp_code_range,json=icmpCodeRange" json:"icmp_code_range,omitempty"` - IcmpTypeRange *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range `protobuf:"bytes,3,opt,name=icmp_type_range,json=icmpTypeRange" json:"icmp_type_range,omitempty"` + IcmpCodeRange *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range `protobuf:"bytes,2,opt,name=icmp_code_range,json=icmpCodeRange" json:"icmp_code_range,omitempty"` + IcmpTypeRange *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range `protobuf:"bytes,3,opt,name=icmp_type_range,json=icmpTypeRange" json:"icmp_type_range,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) Reset() { @@ -266,8 +388,25 @@ func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) Reset() { func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Rule_Match_IpRule_Icmp) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_IpRule_Icmp) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 0, 1} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 0, 1} } +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_IpRule_Icmp) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp.Merge(dst, src) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp.Size(m) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp proto.InternalMessageInfo func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp) GetIcmpv6() bool { if m != nil { @@ -294,7 +433,10 @@ type AccessLists_Acl_Rule_Match_IpRule_Icmp_Range struct { // Lower boundary for range First uint32 `protobuf:"varint,1,opt,name=first,proto3" json:"first,omitempty"` // Upper boundary for range - Last uint32 `protobuf:"varint,2,opt,name=last,proto3" json:"last,omitempty"` + Last uint32 `protobuf:"varint,2,opt,name=last,proto3" json:"last,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) Reset() { @@ -305,9 +447,26 @@ func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) String() string { } func (*AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 0, 1, 0} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 0, 1, 0} +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp_Range.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp_Range.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp_Range.Merge(dst, src) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp_Range.Size(m) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp_Range.DiscardUnknown(m) } +var xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Icmp_Range proto.InternalMessageInfo + func (m *AccessLists_Acl_Rule_Match_IpRule_Icmp_Range) GetFirst() uint32 { if m != nil { return m.First @@ -329,7 +488,10 @@ type AccessLists_Acl_Rule_Match_IpRule_PortRange struct { LowerPort uint32 `protobuf:"varint,1,opt,name=lower_port,json=lowerPort,proto3" json:"lower_port,omitempty"` // Upper boundary for port. If existing, the upper port must // be greater or equal to lower-port - UpperPort uint32 `protobuf:"varint,2,opt,name=upper_port,json=upperPort,proto3" json:"upper_port,omitempty"` + UpperPort uint32 `protobuf:"varint,2,opt,name=upper_port,json=upperPort,proto3" json:"upper_port,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_IpRule_PortRange) Reset() { @@ -340,8 +502,25 @@ func (m *AccessLists_Acl_Rule_Match_IpRule_PortRange) String() string { } func (*AccessLists_Acl_Rule_Match_IpRule_PortRange) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_IpRule_PortRange) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 0, 2} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 0, 2} +} +func (m *AccessLists_Acl_Rule_Match_IpRule_PortRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_PortRange.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_PortRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_PortRange.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_IpRule_PortRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_PortRange.Merge(dst, src) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_PortRange) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_PortRange.Size(m) } +func (m *AccessLists_Acl_Rule_Match_IpRule_PortRange) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_PortRange.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_PortRange proto.InternalMessageInfo func (m *AccessLists_Acl_Rule_Match_IpRule_PortRange) GetLowerPort() uint32 { if m != nil { @@ -367,15 +546,35 @@ type AccessLists_Acl_Rule_Match_IpRule_Tcp struct { // Binary value for tcp flags to match. MSB order (FIN at position 0). // Before tcp-flags-value is compared with tcp flags field of the packet being matched, // tcp-flags-mask is applied to packet field value. - TcpFlagsValue uint32 `protobuf:"varint,4,opt,name=tcp_flags_value,json=tcpFlagsValue,proto3" json:"tcp_flags_value,omitempty"` + TcpFlagsValue uint32 `protobuf:"varint,4,opt,name=tcp_flags_value,json=tcpFlagsValue,proto3" json:"tcp_flags_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) Reset() { *m = AccessLists_Acl_Rule_Match_IpRule_Tcp{} } func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Rule_Match_IpRule_Tcp) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_IpRule_Tcp) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 0, 3} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 0, 3} +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Tcp.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Tcp.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_IpRule_Tcp) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Tcp.Merge(dst, src) } +func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Tcp.Size(m) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Tcp.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Tcp proto.InternalMessageInfo func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) GetDestinationPortRange() *AccessLists_Acl_Rule_Match_IpRule_PortRange { if m != nil { @@ -408,14 +607,34 @@ func (m *AccessLists_Acl_Rule_Match_IpRule_Tcp) GetTcpFlagsValue() uint32 { type AccessLists_Acl_Rule_Match_IpRule_Udp struct { DestinationPortRange *AccessLists_Acl_Rule_Match_IpRule_PortRange `protobuf:"bytes,1,opt,name=destination_port_range,json=destinationPortRange" json:"destination_port_range,omitempty"` SourcePortRange *AccessLists_Acl_Rule_Match_IpRule_PortRange `protobuf:"bytes,2,opt,name=source_port_range,json=sourcePortRange" json:"source_port_range,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_IpRule_Udp) Reset() { *m = AccessLists_Acl_Rule_Match_IpRule_Udp{} } func (m *AccessLists_Acl_Rule_Match_IpRule_Udp) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Rule_Match_IpRule_Udp) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_IpRule_Udp) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 0, 4} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 0, 4} +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Udp) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Udp.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Udp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Udp.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_IpRule_Udp) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Udp.Merge(dst, src) } +func (m *AccessLists_Acl_Rule_Match_IpRule_Udp) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Udp.Size(m) +} +func (m *AccessLists_Acl_Rule_Match_IpRule_Udp) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Udp.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl_Rule_Match_IpRule_Udp proto.InternalMessageInfo func (m *AccessLists_Acl_Rule_Match_IpRule_Udp) GetDestinationPortRange() *AccessLists_Acl_Rule_Match_IpRule_PortRange { if m != nil { @@ -443,16 +662,36 @@ type AccessLists_Acl_Rule_Match_MacIpRule struct { // Source MAC address mask. // Applied as logical AND with source mac address field of the packet being matched, // before it is compared with source-mac-address. - SourceMacAddressMask string `protobuf:"bytes,4,opt,name=source_mac_address_mask,json=sourceMacAddressMask,proto3" json:"source_mac_address_mask,omitempty"` + SourceMacAddressMask string `protobuf:"bytes,4,opt,name=source_mac_address_mask,json=sourceMacAddressMask,proto3" json:"source_mac_address_mask,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Rule_Match_MacIpRule) Reset() { *m = AccessLists_Acl_Rule_Match_MacIpRule{} } func (m *AccessLists_Acl_Rule_Match_MacIpRule) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Rule_Match_MacIpRule) ProtoMessage() {} func (*AccessLists_Acl_Rule_Match_MacIpRule) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 0, 0, 1} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 0, 0, 1} +} +func (m *AccessLists_Acl_Rule_Match_MacIpRule) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_MacIpRule.Unmarshal(m, b) +} +func (m *AccessLists_Acl_Rule_Match_MacIpRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_MacIpRule.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Rule_Match_MacIpRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Rule_Match_MacIpRule.Merge(dst, src) +} +func (m *AccessLists_Acl_Rule_Match_MacIpRule) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Rule_Match_MacIpRule.Size(m) +} +func (m *AccessLists_Acl_Rule_Match_MacIpRule) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Rule_Match_MacIpRule.DiscardUnknown(m) } +var xxx_messageInfo_AccessLists_Acl_Rule_Match_MacIpRule proto.InternalMessageInfo + func (m *AccessLists_Acl_Rule_Match_MacIpRule) GetSourceAddress() string { if m != nil { return m.SourceAddress @@ -482,16 +721,36 @@ func (m *AccessLists_Acl_Rule_Match_MacIpRule) GetSourceMacAddressMask() string } type AccessLists_Acl_Interfaces struct { - Egress []string `protobuf:"bytes,1,rep,name=egress" json:"egress,omitempty"` - Ingress []string `protobuf:"bytes,2,rep,name=ingress" json:"ingress,omitempty"` + Egress []string `protobuf:"bytes,1,rep,name=egress" json:"egress,omitempty"` + Ingress []string `protobuf:"bytes,2,rep,name=ingress" json:"ingress,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessLists_Acl_Interfaces) Reset() { *m = AccessLists_Acl_Interfaces{} } func (m *AccessLists_Acl_Interfaces) String() string { return proto.CompactTextString(m) } func (*AccessLists_Acl_Interfaces) ProtoMessage() {} func (*AccessLists_Acl_Interfaces) Descriptor() ([]byte, []int) { - return fileDescriptorAcl, []int{0, 0, 1} + return fileDescriptor_acl_700e6e99ae46a356, []int{0, 0, 1} +} +func (m *AccessLists_Acl_Interfaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccessLists_Acl_Interfaces.Unmarshal(m, b) } +func (m *AccessLists_Acl_Interfaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccessLists_Acl_Interfaces.Marshal(b, m, deterministic) +} +func (dst *AccessLists_Acl_Interfaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessLists_Acl_Interfaces.Merge(dst, src) +} +func (m *AccessLists_Acl_Interfaces) XXX_Size() int { + return xxx_messageInfo_AccessLists_Acl_Interfaces.Size(m) +} +func (m *AccessLists_Acl_Interfaces) XXX_DiscardUnknown() { + xxx_messageInfo_AccessLists_Acl_Interfaces.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessLists_Acl_Interfaces proto.InternalMessageInfo func (m *AccessLists_Acl_Interfaces) GetEgress() []string { if m != nil { @@ -509,24 +768,24 @@ func (m *AccessLists_Acl_Interfaces) GetIngress() []string { func init() { proto.RegisterType((*AccessLists)(nil), "acl.AccessLists") - proto.RegisterType((*AccessLists_Acl)(nil), "acl.AccessLists.ACL") - proto.RegisterType((*AccessLists_Acl_Rule)(nil), "acl.AccessLists.ACL.Rule") - proto.RegisterType((*AccessLists_Acl_Rule_Match)(nil), "acl.AccessLists.ACL.Rule.Match") - proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule)(nil), "acl.AccessLists.ACL.Rule.Match.IpRule") - proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Ip)(nil), "acl.AccessLists.ACL.Rule.Match.IpRule.Ip") - proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Icmp)(nil), "acl.AccessLists.ACL.Rule.Match.IpRule.Icmp") - proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Icmp_Range)(nil), "acl.AccessLists.ACL.Rule.Match.IpRule.Icmp.Range") - proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_PortRange)(nil), "acl.AccessLists.ACL.Rule.Match.IpRule.PortRange") - proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Tcp)(nil), "acl.AccessLists.ACL.Rule.Match.IpRule.Tcp") - proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Udp)(nil), "acl.AccessLists.ACL.Rule.Match.IpRule.Udp") - proto.RegisterType((*AccessLists_Acl_Rule_Match_MacIpRule)(nil), "acl.AccessLists.ACL.Rule.Match.MacIpRule") - proto.RegisterType((*AccessLists_Acl_Interfaces)(nil), "acl.AccessLists.ACL.Interfaces") + proto.RegisterType((*AccessLists_Acl)(nil), "acl.AccessLists.Acl") + proto.RegisterType((*AccessLists_Acl_Rule)(nil), "acl.AccessLists.Acl.Rule") + proto.RegisterType((*AccessLists_Acl_Rule_Match)(nil), "acl.AccessLists.Acl.Rule.Match") + proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule)(nil), "acl.AccessLists.Acl.Rule.Match.IpRule") + proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Ip)(nil), "acl.AccessLists.Acl.Rule.Match.IpRule.Ip") + proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Icmp)(nil), "acl.AccessLists.Acl.Rule.Match.IpRule.Icmp") + proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Icmp_Range)(nil), "acl.AccessLists.Acl.Rule.Match.IpRule.Icmp.Range") + proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_PortRange)(nil), "acl.AccessLists.Acl.Rule.Match.IpRule.PortRange") + proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Tcp)(nil), "acl.AccessLists.Acl.Rule.Match.IpRule.Tcp") + proto.RegisterType((*AccessLists_Acl_Rule_Match_IpRule_Udp)(nil), "acl.AccessLists.Acl.Rule.Match.IpRule.Udp") + proto.RegisterType((*AccessLists_Acl_Rule_Match_MacIpRule)(nil), "acl.AccessLists.Acl.Rule.Match.MacIpRule") + proto.RegisterType((*AccessLists_Acl_Interfaces)(nil), "acl.AccessLists.Acl.Interfaces") proto.RegisterEnum("acl.AclAction", AclAction_name, AclAction_value) } -func init() { proto.RegisterFile("acl.proto", fileDescriptorAcl) } +func init() { proto.RegisterFile("acl.proto", fileDescriptor_acl_700e6e99ae46a356) } -var fileDescriptorAcl = []byte{ +var fileDescriptor_acl_700e6e99ae46a356 = []byte{ // 779 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x55, 0xdd, 0x6e, 0xe3, 0x44, 0x14, 0x26, 0xb6, 0xf3, 0xe3, 0x93, 0x75, 0x12, 0x66, 0xc3, 0x92, 0x35, 0x42, 0x44, 0x08, 0x56, diff --git a/plugins/vpp/model/bfd/bfd.pb.go b/plugins/vpp/model/bfd/bfd.pb.go index a513200e13..ca4075e411 100644 --- a/plugins/vpp/model/bfd/bfd.pb.go +++ b/plugins/vpp/model/bfd/bfd.pb.go @@ -1,18 +1,11 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: bfd.proto -/* -Package bfd is a generated protocol buffer package. +package bfd +/* Package bfd provides data model to single-hop UDP transport BFD based on RFC 5880 and RFC 5881. - -It is generated from these files: - bfd.proto - -It has these top-level messages: - SingleHopBFD */ -package bfd import proto "github.com/gogo/protobuf/proto" import fmt "fmt" @@ -49,19 +42,41 @@ func (x SingleHopBFD_Key_AuthenticationType) String() string { return proto.EnumName(SingleHopBFD_Key_AuthenticationType_name, int32(x)) } func (SingleHopBFD_Key_AuthenticationType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorBfd, []int{0, 1, 0} + return fileDescriptor_bfd_3513382b1705aae1, []int{0, 1, 0} } type SingleHopBFD struct { - Sessions []*SingleHopBFD_Session `protobuf:"bytes,1,rep,name=sessions" json:"sessions,omitempty"` - Keys []*SingleHopBFD_Key `protobuf:"bytes,2,rep,name=keys" json:"keys,omitempty"` - EchoFunction *SingleHopBFD_EchoFunction `protobuf:"bytes,3,opt,name=echo_function,json=echoFunction" json:"echo_function,omitempty"` + Sessions []*SingleHopBFD_Session `protobuf:"bytes,1,rep,name=sessions" json:"sessions,omitempty"` + Keys []*SingleHopBFD_Key `protobuf:"bytes,2,rep,name=keys" json:"keys,omitempty"` + EchoFunction *SingleHopBFD_EchoFunction `protobuf:"bytes,3,opt,name=echo_function,json=echoFunction" json:"echo_function,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SingleHopBFD) Reset() { *m = SingleHopBFD{} } +func (m *SingleHopBFD) String() string { return proto.CompactTextString(m) } +func (*SingleHopBFD) ProtoMessage() {} +func (*SingleHopBFD) Descriptor() ([]byte, []int) { + return fileDescriptor_bfd_3513382b1705aae1, []int{0} +} +func (m *SingleHopBFD) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SingleHopBFD.Unmarshal(m, b) +} +func (m *SingleHopBFD) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SingleHopBFD.Marshal(b, m, deterministic) +} +func (dst *SingleHopBFD) XXX_Merge(src proto.Message) { + xxx_messageInfo_SingleHopBFD.Merge(dst, src) +} +func (m *SingleHopBFD) XXX_Size() int { + return xxx_messageInfo_SingleHopBFD.Size(m) +} +func (m *SingleHopBFD) XXX_DiscardUnknown() { + xxx_messageInfo_SingleHopBFD.DiscardUnknown(m) } -func (m *SingleHopBFD) Reset() { *m = SingleHopBFD{} } -func (m *SingleHopBFD) String() string { return proto.CompactTextString(m) } -func (*SingleHopBFD) ProtoMessage() {} -func (*SingleHopBFD) Descriptor() ([]byte, []int) { return fileDescriptorBfd, []int{0} } +var xxx_messageInfo_SingleHopBFD proto.InternalMessageInfo func (m *SingleHopBFD) GetSessions() []*SingleHopBFD_Session { if m != nil { @@ -93,12 +108,34 @@ type SingleHopBFD_Session struct { RequiredMinRxInterval uint32 `protobuf:"varint,9,opt,name=required_min_rx_interval,json=requiredMinRxInterval,proto3" json:"required_min_rx_interval,omitempty"` DetectMultiplier uint32 `protobuf:"varint,10,opt,name=detect_multiplier,json=detectMultiplier,proto3" json:"detect_multiplier,omitempty"` Authentication *SingleHopBFD_Session_Authentication `protobuf:"bytes,11,opt,name=authentication" json:"authentication,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SingleHopBFD_Session) Reset() { *m = SingleHopBFD_Session{} } +func (m *SingleHopBFD_Session) String() string { return proto.CompactTextString(m) } +func (*SingleHopBFD_Session) ProtoMessage() {} +func (*SingleHopBFD_Session) Descriptor() ([]byte, []int) { + return fileDescriptor_bfd_3513382b1705aae1, []int{0, 0} +} +func (m *SingleHopBFD_Session) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SingleHopBFD_Session.Unmarshal(m, b) +} +func (m *SingleHopBFD_Session) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SingleHopBFD_Session.Marshal(b, m, deterministic) +} +func (dst *SingleHopBFD_Session) XXX_Merge(src proto.Message) { + xxx_messageInfo_SingleHopBFD_Session.Merge(dst, src) +} +func (m *SingleHopBFD_Session) XXX_Size() int { + return xxx_messageInfo_SingleHopBFD_Session.Size(m) +} +func (m *SingleHopBFD_Session) XXX_DiscardUnknown() { + xxx_messageInfo_SingleHopBFD_Session.DiscardUnknown(m) } -func (m *SingleHopBFD_Session) Reset() { *m = SingleHopBFD_Session{} } -func (m *SingleHopBFD_Session) String() string { return proto.CompactTextString(m) } -func (*SingleHopBFD_Session) ProtoMessage() {} -func (*SingleHopBFD_Session) Descriptor() ([]byte, []int) { return fileDescriptorBfd, []int{0, 0} } +var xxx_messageInfo_SingleHopBFD_Session proto.InternalMessageInfo func (m *SingleHopBFD_Session) GetInterface() string { if m != nil { @@ -157,17 +194,37 @@ func (m *SingleHopBFD_Session) GetAuthentication() *SingleHopBFD_Session_Authent } type SingleHopBFD_Session_Authentication struct { - KeyId uint32 `protobuf:"varint,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` - AdvertisedKeyId uint32 `protobuf:"varint,2,opt,name=advertised_key_id,json=advertisedKeyId,proto3" json:"advertised_key_id,omitempty"` + KeyId uint32 `protobuf:"varint,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + AdvertisedKeyId uint32 `protobuf:"varint,2,opt,name=advertised_key_id,json=advertisedKeyId,proto3" json:"advertised_key_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SingleHopBFD_Session_Authentication) Reset() { *m = SingleHopBFD_Session_Authentication{} } func (m *SingleHopBFD_Session_Authentication) String() string { return proto.CompactTextString(m) } func (*SingleHopBFD_Session_Authentication) ProtoMessage() {} func (*SingleHopBFD_Session_Authentication) Descriptor() ([]byte, []int) { - return fileDescriptorBfd, []int{0, 0, 0} + return fileDescriptor_bfd_3513382b1705aae1, []int{0, 0, 0} +} +func (m *SingleHopBFD_Session_Authentication) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SingleHopBFD_Session_Authentication.Unmarshal(m, b) +} +func (m *SingleHopBFD_Session_Authentication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SingleHopBFD_Session_Authentication.Marshal(b, m, deterministic) +} +func (dst *SingleHopBFD_Session_Authentication) XXX_Merge(src proto.Message) { + xxx_messageInfo_SingleHopBFD_Session_Authentication.Merge(dst, src) +} +func (m *SingleHopBFD_Session_Authentication) XXX_Size() int { + return xxx_messageInfo_SingleHopBFD_Session_Authentication.Size(m) +} +func (m *SingleHopBFD_Session_Authentication) XXX_DiscardUnknown() { + xxx_messageInfo_SingleHopBFD_Session_Authentication.DiscardUnknown(m) } +var xxx_messageInfo_SingleHopBFD_Session_Authentication proto.InternalMessageInfo + func (m *SingleHopBFD_Session_Authentication) GetKeyId() uint32 { if m != nil { return m.KeyId @@ -183,17 +240,39 @@ func (m *SingleHopBFD_Session_Authentication) GetAdvertisedKeyId() uint32 { } type SingleHopBFD_Key struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - AuthKeyIndex uint32 `protobuf:"varint,2,opt,name=auth_key_index,json=authKeyIndex,proto3" json:"auth_key_index,omitempty"` - Id uint32 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` - AuthenticationType SingleHopBFD_Key_AuthenticationType `protobuf:"varint,4,opt,name=authentication_type,json=authenticationType,proto3,enum=bfd.SingleHopBFD_Key_AuthenticationType" json:"authentication_type,omitempty"` - Secret string `protobuf:"bytes,5,opt,name=secret,proto3" json:"secret,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + AuthKeyIndex uint32 `protobuf:"varint,2,opt,name=auth_key_index,json=authKeyIndex,proto3" json:"auth_key_index,omitempty"` + Id uint32 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` + AuthenticationType SingleHopBFD_Key_AuthenticationType `protobuf:"varint,4,opt,name=authentication_type,json=authenticationType,proto3,enum=bfd.SingleHopBFD_Key_AuthenticationType" json:"authentication_type,omitempty"` + Secret string `protobuf:"bytes,5,opt,name=secret,proto3" json:"secret,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SingleHopBFD_Key) Reset() { *m = SingleHopBFD_Key{} } +func (m *SingleHopBFD_Key) String() string { return proto.CompactTextString(m) } +func (*SingleHopBFD_Key) ProtoMessage() {} +func (*SingleHopBFD_Key) Descriptor() ([]byte, []int) { + return fileDescriptor_bfd_3513382b1705aae1, []int{0, 1} +} +func (m *SingleHopBFD_Key) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SingleHopBFD_Key.Unmarshal(m, b) +} +func (m *SingleHopBFD_Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SingleHopBFD_Key.Marshal(b, m, deterministic) +} +func (dst *SingleHopBFD_Key) XXX_Merge(src proto.Message) { + xxx_messageInfo_SingleHopBFD_Key.Merge(dst, src) +} +func (m *SingleHopBFD_Key) XXX_Size() int { + return xxx_messageInfo_SingleHopBFD_Key.Size(m) +} +func (m *SingleHopBFD_Key) XXX_DiscardUnknown() { + xxx_messageInfo_SingleHopBFD_Key.DiscardUnknown(m) } -func (m *SingleHopBFD_Key) Reset() { *m = SingleHopBFD_Key{} } -func (m *SingleHopBFD_Key) String() string { return proto.CompactTextString(m) } -func (*SingleHopBFD_Key) ProtoMessage() {} -func (*SingleHopBFD_Key) Descriptor() ([]byte, []int) { return fileDescriptorBfd, []int{0, 1} } +var xxx_messageInfo_SingleHopBFD_Key proto.InternalMessageInfo func (m *SingleHopBFD_Key) GetName() string { if m != nil { @@ -231,14 +310,36 @@ func (m *SingleHopBFD_Key) GetSecret() string { } type SingleHopBFD_EchoFunction struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - EchoSourceInterface string `protobuf:"bytes,2,opt,name=echo_source_interface,json=echoSourceInterface,proto3" json:"echo_source_interface,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + EchoSourceInterface string `protobuf:"bytes,2,opt,name=echo_source_interface,json=echoSourceInterface,proto3" json:"echo_source_interface,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SingleHopBFD_EchoFunction) Reset() { *m = SingleHopBFD_EchoFunction{} } +func (m *SingleHopBFD_EchoFunction) String() string { return proto.CompactTextString(m) } +func (*SingleHopBFD_EchoFunction) ProtoMessage() {} +func (*SingleHopBFD_EchoFunction) Descriptor() ([]byte, []int) { + return fileDescriptor_bfd_3513382b1705aae1, []int{0, 2} +} +func (m *SingleHopBFD_EchoFunction) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SingleHopBFD_EchoFunction.Unmarshal(m, b) +} +func (m *SingleHopBFD_EchoFunction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SingleHopBFD_EchoFunction.Marshal(b, m, deterministic) +} +func (dst *SingleHopBFD_EchoFunction) XXX_Merge(src proto.Message) { + xxx_messageInfo_SingleHopBFD_EchoFunction.Merge(dst, src) +} +func (m *SingleHopBFD_EchoFunction) XXX_Size() int { + return xxx_messageInfo_SingleHopBFD_EchoFunction.Size(m) +} +func (m *SingleHopBFD_EchoFunction) XXX_DiscardUnknown() { + xxx_messageInfo_SingleHopBFD_EchoFunction.DiscardUnknown(m) } -func (m *SingleHopBFD_EchoFunction) Reset() { *m = SingleHopBFD_EchoFunction{} } -func (m *SingleHopBFD_EchoFunction) String() string { return proto.CompactTextString(m) } -func (*SingleHopBFD_EchoFunction) ProtoMessage() {} -func (*SingleHopBFD_EchoFunction) Descriptor() ([]byte, []int) { return fileDescriptorBfd, []int{0, 2} } +var xxx_messageInfo_SingleHopBFD_EchoFunction proto.InternalMessageInfo func (m *SingleHopBFD_EchoFunction) GetName() string { if m != nil { @@ -263,9 +364,9 @@ func init() { proto.RegisterEnum("bfd.SingleHopBFD_Key_AuthenticationType", SingleHopBFD_Key_AuthenticationType_name, SingleHopBFD_Key_AuthenticationType_value) } -func init() { proto.RegisterFile("bfd.proto", fileDescriptorBfd) } +func init() { proto.RegisterFile("bfd.proto", fileDescriptor_bfd_3513382b1705aae1) } -var fileDescriptorBfd = []byte{ +var fileDescriptor_bfd_3513382b1705aae1 = []byte{ // 547 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xd1, 0x6e, 0xda, 0x4c, 0x10, 0x85, 0x7f, 0x9b, 0x24, 0x84, 0x09, 0xf8, 0x4f, 0x26, 0xa5, 0x75, 0x50, 0x55, 0xa1, 0xa8, diff --git a/plugins/vpp/model/gen.go b/plugins/vpp/model/gen.go new file mode 100644 index 0000000000..4665e36c6b --- /dev/null +++ b/plugins/vpp/model/gen.go @@ -0,0 +1,27 @@ +// Copyright (c) 2018 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 protoc --proto_path=acl --gogo_out=acl acl/acl.proto +//go:generate protoc --proto_path=bfd --gogo_out=bfd bfd/bfd.proto +//go:generate protoc --proto_path=interfaces --gogo_out=interfaces interfaces/interfaces.proto +//go:generate protoc --proto_path=ipsec --gogo_out=ipsec ipsec/ipsec.proto +//go:generate protoc --proto_path=l2 --gogo_out=l2 l2/l2.proto +//go:generate protoc --proto_path=l3 --gogo_out=l3 l3/l3.proto +//go:generate protoc --proto_path=l4 --gogo_out=l4 l4/l4.proto +//go:generate protoc --proto_path=nat --gogo_out=nat nat.proto +//go:generate protoc --proto_path=rpc --proto_path=$GOPATH/src --gogo_out=plugins=grpc:rpc rpc/rpc.proto +//go:generate protoc --proto_path=srv6 --gogo_out=srv6 srv6/srv6.proto +//go:generate protoc --proto_path=stn --gogo_out=stn stn/stn.proto + +package model diff --git a/plugins/vpp/model/interfaces/interfaces.pb.go b/plugins/vpp/model/interfaces/interfaces.pb.go index 39939cf978..d340691502 100644 --- a/plugins/vpp/model/interfaces/interfaces.pb.go +++ b/plugins/vpp/model/interfaces/interfaces.pb.go @@ -1,18 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: interfaces.proto -/* -Package interfaces is a generated protocol buffer package. - -It is generated from these files: - interfaces.proto - -It has these top-level messages: - Interfaces - InterfacesState - InterfaceNotification - InterfaceErrors -*/ package interfaces import proto "github.com/gogo/protobuf/proto" @@ -61,7 +49,9 @@ var InterfaceType_value = map[string]int32{ func (x InterfaceType) String() string { return proto.EnumName(InterfaceType_name, int32(x)) } -func (InterfaceType) EnumDescriptor() ([]byte, []int) { return fileDescriptorInterfaces, []int{0} } +func (InterfaceType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0} +} // from vpp/build-root/install-vpp-native/vpp/include/vnet/interface.h type RxModeType int32 @@ -92,7 +82,9 @@ var RxModeType_value = map[string]int32{ func (x RxModeType) String() string { return proto.EnumName(RxModeType_name, int32(x)) } -func (RxModeType) EnumDescriptor() ([]byte, []int) { return fileDescriptorInterfaces, []int{1} } +func (RxModeType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{1} +} type Interfaces_Interface_Memif_MemifMode int32 @@ -117,7 +109,7 @@ func (x Interfaces_Interface_Memif_MemifMode) String() string { return proto.EnumName(Interfaces_Interface_Memif_MemifMode_name, int32(x)) } func (Interfaces_Interface_Memif_MemifMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 3, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 3, 0} } type InterfacesState_Interface_Status int32 @@ -146,7 +138,7 @@ func (x InterfacesState_Interface_Status) String() string { return proto.EnumName(InterfacesState_Interface_Status_name, int32(x)) } func (InterfacesState_Interface_Status) EnumDescriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{1, 0, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{1, 0, 0} } type InterfacesState_Interface_Duplex int32 @@ -172,7 +164,7 @@ func (x InterfacesState_Interface_Duplex) String() string { return proto.EnumName(InterfacesState_Interface_Duplex_name, int32(x)) } func (InterfacesState_Interface_Duplex) EnumDescriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{1, 0, 1} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{1, 0, 1} } type InterfaceNotification_NotifType int32 @@ -198,17 +190,39 @@ func (x InterfaceNotification_NotifType) String() string { return proto.EnumName(InterfaceNotification_NotifType_name, int32(x)) } func (InterfaceNotification_NotifType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{2, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{2, 0} } type Interfaces struct { - Interfaces []*Interfaces_Interface `protobuf:"bytes,1,rep,name=interfaces" json:"interfaces,omitempty"` + Interfaces []*Interfaces_Interface `protobuf:"bytes,1,rep,name=interfaces" json:"interfaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Interfaces) Reset() { *m = Interfaces{} } +func (m *Interfaces) String() string { return proto.CompactTextString(m) } +func (*Interfaces) ProtoMessage() {} +func (*Interfaces) Descriptor() ([]byte, []int) { + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0} +} +func (m *Interfaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces.Unmarshal(m, b) +} +func (m *Interfaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces.Marshal(b, m, deterministic) +} +func (dst *Interfaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces.Merge(dst, src) +} +func (m *Interfaces) XXX_Size() int { + return xxx_messageInfo_Interfaces.Size(m) +} +func (m *Interfaces) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces.DiscardUnknown(m) } -func (m *Interfaces) Reset() { *m = Interfaces{} } -func (m *Interfaces) String() string { return proto.CompactTextString(m) } -func (*Interfaces) ProtoMessage() {} -func (*Interfaces) Descriptor() ([]byte, []int) { return fileDescriptorInterfaces, []int{0} } +var xxx_messageInfo_Interfaces proto.InternalMessageInfo func (m *Interfaces) GetInterfaces() []*Interfaces_Interface { if m != nil { @@ -228,23 +242,43 @@ type Interfaces_Interface struct { ContainerIpAddress string `protobuf:"bytes,8,opt,name=container_ip_address,json=containerIpAddress,proto3" json:"container_ip_address,omitempty"` SetDhcpClient bool `protobuf:"varint,9,opt,name=set_dhcp_client,json=setDhcpClient,proto3" json:"set_dhcp_client,omitempty"` // Required format is "ipAddress/ipPrefix" - IpAddresses []string `protobuf:"bytes,10,rep,name=ip_addresses,json=ipAddresses" json:"ip_addresses,omitempty"` - Unnumbered *Interfaces_Interface_Unnumbered `protobuf:"bytes,11,opt,name=unnumbered" json:"unnumbered,omitempty"` - RxModeSettings *Interfaces_Interface_RxModeSettings `protobuf:"bytes,12,opt,name=rx_mode_settings,json=rxModeSettings" json:"rx_mode_settings,omitempty"` - RxPlacementSettings *Interfaces_Interface_RxPlacementSettings `protobuf:"bytes,13,opt,name=rx_placement_settings,json=rxPlacementSettings" json:"rx_placement_settings,omitempty"` - Memif *Interfaces_Interface_Memif `protobuf:"bytes,101,opt,name=memif" json:"memif,omitempty"` - Vxlan *Interfaces_Interface_Vxlan `protobuf:"bytes,102,opt,name=vxlan" json:"vxlan,omitempty"` - Afpacket *Interfaces_Interface_Afpacket `protobuf:"bytes,103,opt,name=afpacket" json:"afpacket,omitempty"` - Tap *Interfaces_Interface_Tap `protobuf:"bytes,104,opt,name=tap" json:"tap,omitempty"` + IpAddresses []string `protobuf:"bytes,10,rep,name=ip_addresses,json=ipAddresses" json:"ip_addresses,omitempty"` + Unnumbered *Interfaces_Interface_Unnumbered `protobuf:"bytes,11,opt,name=unnumbered" json:"unnumbered,omitempty"` + RxModeSettings *Interfaces_Interface_RxModeSettings `protobuf:"bytes,12,opt,name=rx_mode_settings,json=rxModeSettings" json:"rx_mode_settings,omitempty"` + RxPlacementSettings *Interfaces_Interface_RxPlacementSettings `protobuf:"bytes,13,opt,name=rx_placement_settings,json=rxPlacementSettings" json:"rx_placement_settings,omitempty"` + Memif *Interfaces_Interface_Memif `protobuf:"bytes,101,opt,name=memif" json:"memif,omitempty"` + Vxlan *Interfaces_Interface_Vxlan `protobuf:"bytes,102,opt,name=vxlan" json:"vxlan,omitempty"` + Afpacket *Interfaces_Interface_Afpacket `protobuf:"bytes,103,opt,name=afpacket" json:"afpacket,omitempty"` + Tap *Interfaces_Interface_Tap `protobuf:"bytes,104,opt,name=tap" json:"tap,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface) Reset() { *m = Interfaces_Interface{} } func (m *Interfaces_Interface) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface) ProtoMessage() {} func (*Interfaces_Interface) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0} +} +func (m *Interfaces_Interface) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface.Unmarshal(m, b) +} +func (m *Interfaces_Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface.Merge(dst, src) +} +func (m *Interfaces_Interface) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface.Size(m) +} +func (m *Interfaces_Interface) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface.DiscardUnknown(m) } +var xxx_messageInfo_Interfaces_Interface proto.InternalMessageInfo + func (m *Interfaces_Interface) GetName() string { if m != nil { return m.Name @@ -365,16 +399,36 @@ func (m *Interfaces_Interface) GetTap() *Interfaces_Interface_Tap { } type Interfaces_Interface_Unnumbered struct { - IsUnnumbered bool `protobuf:"varint,1,opt,name=is_unnumbered,json=isUnnumbered,proto3" json:"is_unnumbered,omitempty"` - InterfaceWithIp string `protobuf:"bytes,2,opt,name=interface_with_ip,json=interfaceWithIp,proto3" json:"interface_with_ip,omitempty"` + IsUnnumbered bool `protobuf:"varint,1,opt,name=is_unnumbered,json=isUnnumbered,proto3" json:"is_unnumbered,omitempty"` + InterfaceWithIp string `protobuf:"bytes,2,opt,name=interface_with_ip,json=interfaceWithIp,proto3" json:"interface_with_ip,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface_Unnumbered) Reset() { *m = Interfaces_Interface_Unnumbered{} } func (m *Interfaces_Interface_Unnumbered) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface_Unnumbered) ProtoMessage() {} func (*Interfaces_Interface_Unnumbered) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 0} +} +func (m *Interfaces_Interface_Unnumbered) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface_Unnumbered.Unmarshal(m, b) +} +func (m *Interfaces_Interface_Unnumbered) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface_Unnumbered.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface_Unnumbered) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface_Unnumbered.Merge(dst, src) } +func (m *Interfaces_Interface_Unnumbered) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface_Unnumbered.Size(m) +} +func (m *Interfaces_Interface_Unnumbered) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface_Unnumbered.DiscardUnknown(m) +} + +var xxx_messageInfo_Interfaces_Interface_Unnumbered proto.InternalMessageInfo func (m *Interfaces_Interface_Unnumbered) GetIsUnnumbered() bool { if m != nil { @@ -391,17 +445,37 @@ func (m *Interfaces_Interface_Unnumbered) GetInterfaceWithIp() string { } type Interfaces_Interface_RxModeSettings struct { - RxMode RxModeType `protobuf:"varint,1,opt,name=rx_mode,json=rxMode,proto3,enum=interfaces.RxModeType" json:"rx_mode,omitempty"` - QueueId uint32 `protobuf:"varint,2,opt,name=queue_id,json=queueId,proto3" json:"queue_id,omitempty"` - QueueIdValid uint32 `protobuf:"varint,3,opt,name=queue_id_valid,json=queueIdValid,proto3" json:"queue_id_valid,omitempty"` + RxMode RxModeType `protobuf:"varint,1,opt,name=rx_mode,json=rxMode,proto3,enum=interfaces.RxModeType" json:"rx_mode,omitempty"` + QueueId uint32 `protobuf:"varint,2,opt,name=queue_id,json=queueId,proto3" json:"queue_id,omitempty"` + QueueIdValid uint32 `protobuf:"varint,3,opt,name=queue_id_valid,json=queueIdValid,proto3" json:"queue_id_valid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface_RxModeSettings) Reset() { *m = Interfaces_Interface_RxModeSettings{} } func (m *Interfaces_Interface_RxModeSettings) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface_RxModeSettings) ProtoMessage() {} func (*Interfaces_Interface_RxModeSettings) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 1} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 1} } +func (m *Interfaces_Interface_RxModeSettings) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface_RxModeSettings.Unmarshal(m, b) +} +func (m *Interfaces_Interface_RxModeSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface_RxModeSettings.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface_RxModeSettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface_RxModeSettings.Merge(dst, src) +} +func (m *Interfaces_Interface_RxModeSettings) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface_RxModeSettings.Size(m) +} +func (m *Interfaces_Interface_RxModeSettings) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface_RxModeSettings.DiscardUnknown(m) +} + +var xxx_messageInfo_Interfaces_Interface_RxModeSettings proto.InternalMessageInfo func (m *Interfaces_Interface_RxModeSettings) GetRxMode() RxModeType { if m != nil { @@ -425,8 +499,12 @@ func (m *Interfaces_Interface_RxModeSettings) GetQueueIdValid() uint32 { } type Interfaces_Interface_RxPlacementSettings struct { - Queue uint32 `protobuf:"varint,1,opt,name=queue,proto3" json:"queue,omitempty"` - Worker uint32 `protobuf:"varint,2,opt,name=worker,proto3" json:"worker,omitempty"` + Queue uint32 `protobuf:"varint,1,opt,name=queue,proto3" json:"queue,omitempty"` + Worker uint32 `protobuf:"varint,2,opt,name=worker,proto3" json:"worker,omitempty"` + IsMain bool `protobuf:"varint,3,opt,name=is_main,json=isMain,proto3" json:"is_main,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface_RxPlacementSettings) Reset() { @@ -435,8 +513,25 @@ func (m *Interfaces_Interface_RxPlacementSettings) Reset() { func (m *Interfaces_Interface_RxPlacementSettings) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface_RxPlacementSettings) ProtoMessage() {} func (*Interfaces_Interface_RxPlacementSettings) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 2} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 2} } +func (m *Interfaces_Interface_RxPlacementSettings) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface_RxPlacementSettings.Unmarshal(m, b) +} +func (m *Interfaces_Interface_RxPlacementSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface_RxPlacementSettings.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface_RxPlacementSettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface_RxPlacementSettings.Merge(dst, src) +} +func (m *Interfaces_Interface_RxPlacementSettings) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface_RxPlacementSettings.Size(m) +} +func (m *Interfaces_Interface_RxPlacementSettings) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface_RxPlacementSettings.DiscardUnknown(m) +} + +var xxx_messageInfo_Interfaces_Interface_RxPlacementSettings proto.InternalMessageInfo func (m *Interfaces_Interface_RxPlacementSettings) GetQueue() uint32 { if m != nil { @@ -452,25 +547,52 @@ func (m *Interfaces_Interface_RxPlacementSettings) GetWorker() uint32 { return 0 } +func (m *Interfaces_Interface_RxPlacementSettings) GetIsMain() bool { + if m != nil { + return m.IsMain + } + return false +} + type Interfaces_Interface_Memif struct { - Master bool `protobuf:"varint,1,opt,name=master,proto3" json:"master,omitempty"` - Mode Interfaces_Interface_Memif_MemifMode `protobuf:"varint,2,opt,name=mode,proto3,enum=interfaces.Interfaces_Interface_Memif_MemifMode" json:"mode,omitempty"` - Id uint32 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` - SocketFilename string `protobuf:"bytes,4,opt,name=socket_filename,json=socketFilename,proto3" json:"socket_filename,omitempty"` - Secret string `protobuf:"bytes,5,opt,name=secret,proto3" json:"secret,omitempty"` - RingSize uint32 `protobuf:"varint,6,opt,name=ring_size,json=ringSize,proto3" json:"ring_size,omitempty"` - BufferSize uint32 `protobuf:"varint,7,opt,name=buffer_size,json=bufferSize,proto3" json:"buffer_size,omitempty"` - RxQueues uint32 `protobuf:"varint,8,opt,name=rx_queues,json=rxQueues,proto3" json:"rx_queues,omitempty"` - TxQueues uint32 `protobuf:"varint,9,opt,name=tx_queues,json=txQueues,proto3" json:"tx_queues,omitempty"` + Master bool `protobuf:"varint,1,opt,name=master,proto3" json:"master,omitempty"` + Mode Interfaces_Interface_Memif_MemifMode `protobuf:"varint,2,opt,name=mode,proto3,enum=interfaces.Interfaces_Interface_Memif_MemifMode" json:"mode,omitempty"` + Id uint32 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` + SocketFilename string `protobuf:"bytes,4,opt,name=socket_filename,json=socketFilename,proto3" json:"socket_filename,omitempty"` + Secret string `protobuf:"bytes,5,opt,name=secret,proto3" json:"secret,omitempty"` + RingSize uint32 `protobuf:"varint,6,opt,name=ring_size,json=ringSize,proto3" json:"ring_size,omitempty"` + BufferSize uint32 `protobuf:"varint,7,opt,name=buffer_size,json=bufferSize,proto3" json:"buffer_size,omitempty"` + RxQueues uint32 `protobuf:"varint,8,opt,name=rx_queues,json=rxQueues,proto3" json:"rx_queues,omitempty"` + TxQueues uint32 `protobuf:"varint,9,opt,name=tx_queues,json=txQueues,proto3" json:"tx_queues,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface_Memif) Reset() { *m = Interfaces_Interface_Memif{} } func (m *Interfaces_Interface_Memif) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface_Memif) ProtoMessage() {} func (*Interfaces_Interface_Memif) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 3} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 3} +} +func (m *Interfaces_Interface_Memif) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface_Memif.Unmarshal(m, b) +} +func (m *Interfaces_Interface_Memif) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface_Memif.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface_Memif) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface_Memif.Merge(dst, src) +} +func (m *Interfaces_Interface_Memif) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface_Memif.Size(m) +} +func (m *Interfaces_Interface_Memif) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface_Memif.DiscardUnknown(m) } +var xxx_messageInfo_Interfaces_Interface_Memif proto.InternalMessageInfo + func (m *Interfaces_Interface_Memif) GetMaster() bool { if m != nil { return m.Master @@ -535,18 +657,38 @@ func (m *Interfaces_Interface_Memif) GetTxQueues() uint32 { } type Interfaces_Interface_Vxlan struct { - SrcAddress string `protobuf:"bytes,1,opt,name=src_address,json=srcAddress,proto3" json:"src_address,omitempty"` - DstAddress string `protobuf:"bytes,2,opt,name=dst_address,json=dstAddress,proto3" json:"dst_address,omitempty"` - Vni uint32 `protobuf:"varint,3,opt,name=vni,proto3" json:"vni,omitempty"` - Multicast string `protobuf:"bytes,4,opt,name=multicast,proto3" json:"multicast,omitempty"` + SrcAddress string `protobuf:"bytes,1,opt,name=src_address,json=srcAddress,proto3" json:"src_address,omitempty"` + DstAddress string `protobuf:"bytes,2,opt,name=dst_address,json=dstAddress,proto3" json:"dst_address,omitempty"` + Vni uint32 `protobuf:"varint,3,opt,name=vni,proto3" json:"vni,omitempty"` + Multicast string `protobuf:"bytes,4,opt,name=multicast,proto3" json:"multicast,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface_Vxlan) Reset() { *m = Interfaces_Interface_Vxlan{} } func (m *Interfaces_Interface_Vxlan) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface_Vxlan) ProtoMessage() {} func (*Interfaces_Interface_Vxlan) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 4} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 4} +} +func (m *Interfaces_Interface_Vxlan) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface_Vxlan.Unmarshal(m, b) +} +func (m *Interfaces_Interface_Vxlan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface_Vxlan.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface_Vxlan) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface_Vxlan.Merge(dst, src) +} +func (m *Interfaces_Interface_Vxlan) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface_Vxlan.Size(m) } +func (m *Interfaces_Interface_Vxlan) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface_Vxlan.DiscardUnknown(m) +} + +var xxx_messageInfo_Interfaces_Interface_Vxlan proto.InternalMessageInfo func (m *Interfaces_Interface_Vxlan) GetSrcAddress() string { if m != nil { @@ -577,15 +719,35 @@ func (m *Interfaces_Interface_Vxlan) GetMulticast() string { } type Interfaces_Interface_Afpacket struct { - HostIfName string `protobuf:"bytes,1,opt,name=host_if_name,json=hostIfName,proto3" json:"host_if_name,omitempty"` + HostIfName string `protobuf:"bytes,1,opt,name=host_if_name,json=hostIfName,proto3" json:"host_if_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface_Afpacket) Reset() { *m = Interfaces_Interface_Afpacket{} } func (m *Interfaces_Interface_Afpacket) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface_Afpacket) ProtoMessage() {} func (*Interfaces_Interface_Afpacket) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 5} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 5} +} +func (m *Interfaces_Interface_Afpacket) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface_Afpacket.Unmarshal(m, b) +} +func (m *Interfaces_Interface_Afpacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface_Afpacket.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface_Afpacket) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface_Afpacket.Merge(dst, src) +} +func (m *Interfaces_Interface_Afpacket) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface_Afpacket.Size(m) } +func (m *Interfaces_Interface_Afpacket) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface_Afpacket.DiscardUnknown(m) +} + +var xxx_messageInfo_Interfaces_Interface_Afpacket proto.InternalMessageInfo func (m *Interfaces_Interface_Afpacket) GetHostIfName() string { if m != nil { @@ -595,20 +757,40 @@ func (m *Interfaces_Interface_Afpacket) GetHostIfName() string { } type Interfaces_Interface_Tap struct { - Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` - HostIfName string `protobuf:"bytes,2,opt,name=host_if_name,json=hostIfName,proto3" json:"host_if_name,omitempty"` - Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` - RxRingSize uint32 `protobuf:"varint,4,opt,name=rx_ring_size,json=rxRingSize,proto3" json:"rx_ring_size,omitempty"` - TxRingSize uint32 `protobuf:"varint,5,opt,name=tx_ring_size,json=txRingSize,proto3" json:"tx_ring_size,omitempty"` + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + HostIfName string `protobuf:"bytes,2,opt,name=host_if_name,json=hostIfName,proto3" json:"host_if_name,omitempty"` + Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` + RxRingSize uint32 `protobuf:"varint,4,opt,name=rx_ring_size,json=rxRingSize,proto3" json:"rx_ring_size,omitempty"` + TxRingSize uint32 `protobuf:"varint,5,opt,name=tx_ring_size,json=txRingSize,proto3" json:"tx_ring_size,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Interfaces_Interface_Tap) Reset() { *m = Interfaces_Interface_Tap{} } func (m *Interfaces_Interface_Tap) String() string { return proto.CompactTextString(m) } func (*Interfaces_Interface_Tap) ProtoMessage() {} func (*Interfaces_Interface_Tap) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{0, 0, 6} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{0, 0, 6} +} +func (m *Interfaces_Interface_Tap) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Interfaces_Interface_Tap.Unmarshal(m, b) +} +func (m *Interfaces_Interface_Tap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Interfaces_Interface_Tap.Marshal(b, m, deterministic) +} +func (dst *Interfaces_Interface_Tap) XXX_Merge(src proto.Message) { + xxx_messageInfo_Interfaces_Interface_Tap.Merge(dst, src) +} +func (m *Interfaces_Interface_Tap) XXX_Size() int { + return xxx_messageInfo_Interfaces_Interface_Tap.Size(m) +} +func (m *Interfaces_Interface_Tap) XXX_DiscardUnknown() { + xxx_messageInfo_Interfaces_Interface_Tap.DiscardUnknown(m) } +var xxx_messageInfo_Interfaces_Interface_Tap proto.InternalMessageInfo + func (m *Interfaces_Interface_Tap) GetVersion() uint32 { if m != nil { return m.Version @@ -645,13 +827,35 @@ func (m *Interfaces_Interface_Tap) GetTxRingSize() uint32 { } type InterfacesState struct { - Interfaces []*InterfacesState_Interface `protobuf:"bytes,1,rep,name=interfaces" json:"interfaces,omitempty"` + Interfaces []*InterfacesState_Interface `protobuf:"bytes,1,rep,name=interfaces" json:"interfaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *InterfacesState) Reset() { *m = InterfacesState{} } -func (m *InterfacesState) String() string { return proto.CompactTextString(m) } -func (*InterfacesState) ProtoMessage() {} -func (*InterfacesState) Descriptor() ([]byte, []int) { return fileDescriptorInterfaces, []int{1} } +func (m *InterfacesState) Reset() { *m = InterfacesState{} } +func (m *InterfacesState) String() string { return proto.CompactTextString(m) } +func (*InterfacesState) ProtoMessage() {} +func (*InterfacesState) Descriptor() ([]byte, []int) { + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{1} +} +func (m *InterfacesState) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InterfacesState.Unmarshal(m, b) +} +func (m *InterfacesState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InterfacesState.Marshal(b, m, deterministic) +} +func (dst *InterfacesState) XXX_Merge(src proto.Message) { + xxx_messageInfo_InterfacesState.Merge(dst, src) +} +func (m *InterfacesState) XXX_Size() int { + return xxx_messageInfo_InterfacesState.Size(m) +} +func (m *InterfacesState) XXX_DiscardUnknown() { + xxx_messageInfo_InterfacesState.DiscardUnknown(m) +} + +var xxx_messageInfo_InterfacesState proto.InternalMessageInfo func (m *InterfacesState) GetInterfaces() []*InterfacesState_Interface { if m != nil { @@ -661,26 +865,46 @@ func (m *InterfacesState) GetInterfaces() []*InterfacesState_Interface { } type InterfacesState_Interface struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - InternalName string `protobuf:"bytes,2,opt,name=internal_name,json=internalName,proto3" json:"internal_name,omitempty"` - Type InterfaceType `protobuf:"varint,3,opt,name=type,proto3,enum=interfaces.InterfaceType" json:"type,omitempty"` - IfIndex uint32 `protobuf:"varint,4,opt,name=if_index,json=ifIndex,proto3" json:"if_index,omitempty"` - AdminStatus InterfacesState_Interface_Status `protobuf:"varint,5,opt,name=admin_status,json=adminStatus,proto3,enum=interfaces.InterfacesState_Interface_Status" json:"admin_status,omitempty"` - OperStatus InterfacesState_Interface_Status `protobuf:"varint,6,opt,name=oper_status,json=operStatus,proto3,enum=interfaces.InterfacesState_Interface_Status" json:"oper_status,omitempty"` - LastChange int64 `protobuf:"varint,7,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` - PhysAddress string `protobuf:"bytes,8,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` - Speed uint64 `protobuf:"varint,9,opt,name=speed,proto3" json:"speed,omitempty"` - Mtu uint32 `protobuf:"varint,10,opt,name=mtu,proto3" json:"mtu,omitempty"` - Duplex InterfacesState_Interface_Duplex `protobuf:"varint,11,opt,name=duplex,proto3,enum=interfaces.InterfacesState_Interface_Duplex" json:"duplex,omitempty"` - Statistics *InterfacesState_Interface_Statistics `protobuf:"bytes,100,opt,name=statistics" json:"statistics,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + InternalName string `protobuf:"bytes,2,opt,name=internal_name,json=internalName,proto3" json:"internal_name,omitempty"` + Type InterfaceType `protobuf:"varint,3,opt,name=type,proto3,enum=interfaces.InterfaceType" json:"type,omitempty"` + IfIndex uint32 `protobuf:"varint,4,opt,name=if_index,json=ifIndex,proto3" json:"if_index,omitempty"` + AdminStatus InterfacesState_Interface_Status `protobuf:"varint,5,opt,name=admin_status,json=adminStatus,proto3,enum=interfaces.InterfacesState_Interface_Status" json:"admin_status,omitempty"` + OperStatus InterfacesState_Interface_Status `protobuf:"varint,6,opt,name=oper_status,json=operStatus,proto3,enum=interfaces.InterfacesState_Interface_Status" json:"oper_status,omitempty"` + LastChange int64 `protobuf:"varint,7,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` + PhysAddress string `protobuf:"bytes,8,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` + Speed uint64 `protobuf:"varint,9,opt,name=speed,proto3" json:"speed,omitempty"` + Mtu uint32 `protobuf:"varint,10,opt,name=mtu,proto3" json:"mtu,omitempty"` + Duplex InterfacesState_Interface_Duplex `protobuf:"varint,11,opt,name=duplex,proto3,enum=interfaces.InterfacesState_Interface_Duplex" json:"duplex,omitempty"` + Statistics *InterfacesState_Interface_Statistics `protobuf:"bytes,100,opt,name=statistics" json:"statistics,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *InterfacesState_Interface) Reset() { *m = InterfacesState_Interface{} } func (m *InterfacesState_Interface) String() string { return proto.CompactTextString(m) } func (*InterfacesState_Interface) ProtoMessage() {} func (*InterfacesState_Interface) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{1, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{1, 0} +} +func (m *InterfacesState_Interface) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InterfacesState_Interface.Unmarshal(m, b) +} +func (m *InterfacesState_Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InterfacesState_Interface.Marshal(b, m, deterministic) +} +func (dst *InterfacesState_Interface) XXX_Merge(src proto.Message) { + xxx_messageInfo_InterfacesState_Interface.Merge(dst, src) } +func (m *InterfacesState_Interface) XXX_Size() int { + return xxx_messageInfo_InterfacesState_Interface.Size(m) +} +func (m *InterfacesState_Interface) XXX_DiscardUnknown() { + xxx_messageInfo_InterfacesState_Interface.DiscardUnknown(m) +} + +var xxx_messageInfo_InterfacesState_Interface proto.InternalMessageInfo func (m *InterfacesState_Interface) GetName() string { if m != nil { @@ -767,26 +991,46 @@ func (m *InterfacesState_Interface) GetStatistics() *InterfacesState_Interface_S } type InterfacesState_Interface_Statistics struct { - InPackets uint64 `protobuf:"varint,1,opt,name=in_packets,json=inPackets,proto3" json:"in_packets,omitempty"` - InBytes uint64 `protobuf:"varint,2,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"` - OutPackets uint64 `protobuf:"varint,3,opt,name=out_packets,json=outPackets,proto3" json:"out_packets,omitempty"` - OutBytes uint64 `protobuf:"varint,4,opt,name=out_bytes,json=outBytes,proto3" json:"out_bytes,omitempty"` - DropPackets uint64 `protobuf:"varint,5,opt,name=drop_packets,json=dropPackets,proto3" json:"drop_packets,omitempty"` - PuntPackets uint64 `protobuf:"varint,6,opt,name=punt_packets,json=puntPackets,proto3" json:"punt_packets,omitempty"` - Ipv4Packets uint64 `protobuf:"varint,7,opt,name=ipv4_packets,json=ipv4Packets,proto3" json:"ipv4_packets,omitempty"` - Ipv6Packets uint64 `protobuf:"varint,8,opt,name=ipv6_packets,json=ipv6Packets,proto3" json:"ipv6_packets,omitempty"` - InNobufPackets uint64 `protobuf:"varint,9,opt,name=in_nobuf_packets,json=inNobufPackets,proto3" json:"in_nobuf_packets,omitempty"` - InMissPackets uint64 `protobuf:"varint,10,opt,name=in_miss_packets,json=inMissPackets,proto3" json:"in_miss_packets,omitempty"` - InErrorPackets uint64 `protobuf:"varint,11,opt,name=in_error_packets,json=inErrorPackets,proto3" json:"in_error_packets,omitempty"` - OutErrorPackets uint64 `protobuf:"varint,12,opt,name=out_error_packets,json=outErrorPackets,proto3" json:"out_error_packets,omitempty"` + InPackets uint64 `protobuf:"varint,1,opt,name=in_packets,json=inPackets,proto3" json:"in_packets,omitempty"` + InBytes uint64 `protobuf:"varint,2,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"` + OutPackets uint64 `protobuf:"varint,3,opt,name=out_packets,json=outPackets,proto3" json:"out_packets,omitempty"` + OutBytes uint64 `protobuf:"varint,4,opt,name=out_bytes,json=outBytes,proto3" json:"out_bytes,omitempty"` + DropPackets uint64 `protobuf:"varint,5,opt,name=drop_packets,json=dropPackets,proto3" json:"drop_packets,omitempty"` + PuntPackets uint64 `protobuf:"varint,6,opt,name=punt_packets,json=puntPackets,proto3" json:"punt_packets,omitempty"` + Ipv4Packets uint64 `protobuf:"varint,7,opt,name=ipv4_packets,json=ipv4Packets,proto3" json:"ipv4_packets,omitempty"` + Ipv6Packets uint64 `protobuf:"varint,8,opt,name=ipv6_packets,json=ipv6Packets,proto3" json:"ipv6_packets,omitempty"` + InNobufPackets uint64 `protobuf:"varint,9,opt,name=in_nobuf_packets,json=inNobufPackets,proto3" json:"in_nobuf_packets,omitempty"` + InMissPackets uint64 `protobuf:"varint,10,opt,name=in_miss_packets,json=inMissPackets,proto3" json:"in_miss_packets,omitempty"` + InErrorPackets uint64 `protobuf:"varint,11,opt,name=in_error_packets,json=inErrorPackets,proto3" json:"in_error_packets,omitempty"` + OutErrorPackets uint64 `protobuf:"varint,12,opt,name=out_error_packets,json=outErrorPackets,proto3" json:"out_error_packets,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *InterfacesState_Interface_Statistics) Reset() { *m = InterfacesState_Interface_Statistics{} } func (m *InterfacesState_Interface_Statistics) String() string { return proto.CompactTextString(m) } func (*InterfacesState_Interface_Statistics) ProtoMessage() {} func (*InterfacesState_Interface_Statistics) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{1, 0, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{1, 0, 0} } +func (m *InterfacesState_Interface_Statistics) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InterfacesState_Interface_Statistics.Unmarshal(m, b) +} +func (m *InterfacesState_Interface_Statistics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InterfacesState_Interface_Statistics.Marshal(b, m, deterministic) +} +func (dst *InterfacesState_Interface_Statistics) XXX_Merge(src proto.Message) { + xxx_messageInfo_InterfacesState_Interface_Statistics.Merge(dst, src) +} +func (m *InterfacesState_Interface_Statistics) XXX_Size() int { + return xxx_messageInfo_InterfacesState_Interface_Statistics.Size(m) +} +func (m *InterfacesState_Interface_Statistics) XXX_DiscardUnknown() { + xxx_messageInfo_InterfacesState_Interface_Statistics.DiscardUnknown(m) +} + +var xxx_messageInfo_InterfacesState_Interface_Statistics proto.InternalMessageInfo func (m *InterfacesState_Interface_Statistics) GetInPackets() uint64 { if m != nil { @@ -873,14 +1117,36 @@ func (m *InterfacesState_Interface_Statistics) GetOutErrorPackets() uint64 { } type InterfaceNotification struct { - Type InterfaceNotification_NotifType `protobuf:"varint,1,opt,name=Type,proto3,enum=interfaces.InterfaceNotification_NotifType" json:"Type,omitempty"` - State *InterfacesState_Interface `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` + Type InterfaceNotification_NotifType `protobuf:"varint,1,opt,name=Type,json=type,proto3,enum=interfaces.InterfaceNotification_NotifType" json:"Type,omitempty"` + State *InterfacesState_Interface `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *InterfaceNotification) Reset() { *m = InterfaceNotification{} } -func (m *InterfaceNotification) String() string { return proto.CompactTextString(m) } -func (*InterfaceNotification) ProtoMessage() {} -func (*InterfaceNotification) Descriptor() ([]byte, []int) { return fileDescriptorInterfaces, []int{2} } +func (m *InterfaceNotification) Reset() { *m = InterfaceNotification{} } +func (m *InterfaceNotification) String() string { return proto.CompactTextString(m) } +func (*InterfaceNotification) ProtoMessage() {} +func (*InterfaceNotification) Descriptor() ([]byte, []int) { + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{2} +} +func (m *InterfaceNotification) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InterfaceNotification.Unmarshal(m, b) +} +func (m *InterfaceNotification) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InterfaceNotification.Marshal(b, m, deterministic) +} +func (dst *InterfaceNotification) XXX_Merge(src proto.Message) { + xxx_messageInfo_InterfaceNotification.Merge(dst, src) +} +func (m *InterfaceNotification) XXX_Size() int { + return xxx_messageInfo_InterfaceNotification.Size(m) +} +func (m *InterfaceNotification) XXX_DiscardUnknown() { + xxx_messageInfo_InterfaceNotification.DiscardUnknown(m) +} + +var xxx_messageInfo_InterfaceNotification proto.InternalMessageInfo func (m *InterfaceNotification) GetType() InterfaceNotification_NotifType { if m != nil { @@ -897,13 +1163,35 @@ func (m *InterfaceNotification) GetState() *InterfacesState_Interface { } type InterfaceErrors struct { - Interfaces []*InterfaceErrors_Interface `protobuf:"bytes,1,rep,name=interfaces" json:"interfaces,omitempty"` + Interfaces []*InterfaceErrors_Interface `protobuf:"bytes,1,rep,name=interfaces" json:"interfaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InterfaceErrors) Reset() { *m = InterfaceErrors{} } +func (m *InterfaceErrors) String() string { return proto.CompactTextString(m) } +func (*InterfaceErrors) ProtoMessage() {} +func (*InterfaceErrors) Descriptor() ([]byte, []int) { + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{3} +} +func (m *InterfaceErrors) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InterfaceErrors.Unmarshal(m, b) +} +func (m *InterfaceErrors) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InterfaceErrors.Marshal(b, m, deterministic) +} +func (dst *InterfaceErrors) XXX_Merge(src proto.Message) { + xxx_messageInfo_InterfaceErrors.Merge(dst, src) +} +func (m *InterfaceErrors) XXX_Size() int { + return xxx_messageInfo_InterfaceErrors.Size(m) +} +func (m *InterfaceErrors) XXX_DiscardUnknown() { + xxx_messageInfo_InterfaceErrors.DiscardUnknown(m) } -func (m *InterfaceErrors) Reset() { *m = InterfaceErrors{} } -func (m *InterfaceErrors) String() string { return proto.CompactTextString(m) } -func (*InterfaceErrors) ProtoMessage() {} -func (*InterfaceErrors) Descriptor() ([]byte, []int) { return fileDescriptorInterfaces, []int{3} } +var xxx_messageInfo_InterfaceErrors proto.InternalMessageInfo func (m *InterfaceErrors) GetInterfaces() []*InterfaceErrors_Interface { if m != nil { @@ -913,16 +1201,36 @@ func (m *InterfaceErrors) GetInterfaces() []*InterfaceErrors_Interface { } type InterfaceErrors_Interface struct { - InterfaceName string `protobuf:"bytes,1,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"` - ErrorData []*InterfaceErrors_Interface_ErrorData `protobuf:"bytes,2,rep,name=error_data,json=errorData" json:"error_data,omitempty"` + InterfaceName string `protobuf:"bytes,1,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"` + ErrorData []*InterfaceErrors_Interface_ErrorData `protobuf:"bytes,2,rep,name=error_data,json=errorData" json:"error_data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *InterfaceErrors_Interface) Reset() { *m = InterfaceErrors_Interface{} } func (m *InterfaceErrors_Interface) String() string { return proto.CompactTextString(m) } func (*InterfaceErrors_Interface) ProtoMessage() {} func (*InterfaceErrors_Interface) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{3, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{3, 0} +} +func (m *InterfaceErrors_Interface) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InterfaceErrors_Interface.Unmarshal(m, b) +} +func (m *InterfaceErrors_Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InterfaceErrors_Interface.Marshal(b, m, deterministic) +} +func (dst *InterfaceErrors_Interface) XXX_Merge(src proto.Message) { + xxx_messageInfo_InterfaceErrors_Interface.Merge(dst, src) } +func (m *InterfaceErrors_Interface) XXX_Size() int { + return xxx_messageInfo_InterfaceErrors_Interface.Size(m) +} +func (m *InterfaceErrors_Interface) XXX_DiscardUnknown() { + xxx_messageInfo_InterfaceErrors_Interface.DiscardUnknown(m) +} + +var xxx_messageInfo_InterfaceErrors_Interface proto.InternalMessageInfo func (m *InterfaceErrors_Interface) GetInterfaceName() string { if m != nil { @@ -939,17 +1247,37 @@ func (m *InterfaceErrors_Interface) GetErrorData() []*InterfaceErrors_Interface_ } type InterfaceErrors_Interface_ErrorData struct { - ChangeType string `protobuf:"bytes,1,opt,name=change_type,json=changeType,proto3" json:"change_type,omitempty"` - ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` - LastChange int64 `protobuf:"varint,3,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` + ChangeType string `protobuf:"bytes,1,opt,name=change_type,json=changeType,proto3" json:"change_type,omitempty"` + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + LastChange int64 `protobuf:"varint,3,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *InterfaceErrors_Interface_ErrorData) Reset() { *m = InterfaceErrors_Interface_ErrorData{} } func (m *InterfaceErrors_Interface_ErrorData) String() string { return proto.CompactTextString(m) } func (*InterfaceErrors_Interface_ErrorData) ProtoMessage() {} func (*InterfaceErrors_Interface_ErrorData) Descriptor() ([]byte, []int) { - return fileDescriptorInterfaces, []int{3, 0, 0} + return fileDescriptor_interfaces_d8d30348f2c6c08e, []int{3, 0, 0} } +func (m *InterfaceErrors_Interface_ErrorData) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InterfaceErrors_Interface_ErrorData.Unmarshal(m, b) +} +func (m *InterfaceErrors_Interface_ErrorData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InterfaceErrors_Interface_ErrorData.Marshal(b, m, deterministic) +} +func (dst *InterfaceErrors_Interface_ErrorData) XXX_Merge(src proto.Message) { + xxx_messageInfo_InterfaceErrors_Interface_ErrorData.Merge(dst, src) +} +func (m *InterfaceErrors_Interface_ErrorData) XXX_Size() int { + return xxx_messageInfo_InterfaceErrors_Interface_ErrorData.Size(m) +} +func (m *InterfaceErrors_Interface_ErrorData) XXX_DiscardUnknown() { + xxx_messageInfo_InterfaceErrors_Interface_ErrorData.DiscardUnknown(m) +} + +var xxx_messageInfo_InterfaceErrors_Interface_ErrorData proto.InternalMessageInfo func (m *InterfaceErrors_Interface_ErrorData) GetChangeType() string { if m != nil { @@ -997,112 +1325,113 @@ func init() { proto.RegisterEnum("interfaces.InterfaceNotification_NotifType", InterfaceNotification_NotifType_name, InterfaceNotification_NotifType_value) } -func init() { proto.RegisterFile("interfaces.proto", fileDescriptorInterfaces) } - -var fileDescriptorInterfaces = []byte{ - // 1650 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4d, 0x93, 0xdb, 0xb6, - 0x19, 0x36, 0xf5, 0xad, 0x57, 0x5f, 0x34, 0x6c, 0xa7, 0xb4, 0xd2, 0x8e, 0x95, 0x4d, 0xe2, 0x6e, - 0xdd, 0x74, 0xed, 0xd9, 0x66, 0x7c, 0x49, 0x67, 0x5a, 0x45, 0xe2, 0x36, 0xaa, 0xb5, 0x92, 0x0a, - 0x51, 0x76, 0x72, 0xe8, 0x60, 0xb8, 0x24, 0xb4, 0xc2, 0x44, 0x22, 0x59, 0x02, 0xda, 0x68, 0x73, - 0xec, 0xad, 0xa7, 0xfe, 0x88, 0xfe, 0x88, 0xe6, 0x2f, 0xf4, 0xd8, 0x7b, 0x4f, 0xfd, 0x11, 0x3d, - 0x77, 0x00, 0x90, 0x14, 0xd7, 0xde, 0xcc, 0xca, 0xbd, 0x68, 0x88, 0xe7, 0x7d, 0x9e, 0x07, 0x5f, - 0x2f, 0x5e, 0x40, 0x60, 0xb2, 0x40, 0xd0, 0x78, 0xe9, 0x7a, 0x94, 0x9f, 0x44, 0x71, 0x28, 0x42, - 0x04, 0x7b, 0xe4, 0xe8, 0xaf, 0x1d, 0x80, 0x51, 0xd6, 0x44, 0xbf, 0x83, 0x5c, 0xd0, 0x32, 0x7a, - 0xc5, 0xe3, 0xc6, 0x69, 0xef, 0x24, 0xe7, 0x30, 0xba, 0xe5, 0x13, 0xe7, 0x34, 0xdd, 0x1f, 0xda, - 0x50, 0xcf, 0x22, 0x08, 0x41, 0x29, 0x70, 0x37, 0xd4, 0x32, 0x7a, 0xc6, 0x71, 0x1d, 0xab, 0x6f, - 0xd4, 0x83, 0x86, 0x4f, 0xb9, 0x17, 0xb3, 0x48, 0xb0, 0x30, 0xb0, 0x0a, 0x2a, 0x94, 0x87, 0xd0, - 0xaf, 0xa0, 0x24, 0xae, 0x23, 0x6a, 0x15, 0x7b, 0xc6, 0x71, 0xfb, 0xf4, 0xf1, 0xad, 0xfd, 0x3b, - 0xd7, 0x11, 0xc5, 0x8a, 0x86, 0x2c, 0xa8, 0xd2, 0xc0, 0xbd, 0x58, 0x53, 0xdf, 0x2a, 0xf5, 0x8c, - 0xe3, 0x1a, 0x4e, 0x9b, 0xe8, 0x23, 0x68, 0x46, 0xab, 0x6b, 0x4e, 0x5c, 0xdf, 0x8f, 0x29, 0xe7, - 0x56, 0x59, 0xf7, 0x25, 0xb1, 0xbe, 0x86, 0x90, 0x09, 0xc5, 0x8d, 0xd8, 0x5a, 0x95, 0x9e, 0x71, - 0xdc, 0xc2, 0xf2, 0x53, 0x22, 0x57, 0xf1, 0xd2, 0xaa, 0x6a, 0xe4, 0x2a, 0x5e, 0xa2, 0x17, 0xf0, - 0xd0, 0x0b, 0x03, 0xe1, 0xb2, 0x80, 0xc6, 0x84, 0x45, 0x99, 0x5d, 0x4d, 0xd9, 0xa1, 0x2c, 0x36, - 0x8a, 0x52, 0xd7, 0xa7, 0xd0, 0xe1, 0x54, 0x10, 0x7f, 0xe5, 0x45, 0xc4, 0x5b, 0x33, 0x1a, 0x08, - 0xab, 0xae, 0x86, 0xd6, 0xe2, 0x54, 0x0c, 0x57, 0x5e, 0x34, 0x50, 0xa0, 0x1c, 0xe0, 0xde, 0x8f, - 0x72, 0x0b, 0x7a, 0x45, 0x39, 0x40, 0x96, 0x1a, 0x51, 0x8e, 0x5e, 0x01, 0x6c, 0x83, 0x60, 0xbb, - 0xb9, 0xa0, 0x31, 0xf5, 0xad, 0x46, 0xcf, 0x38, 0x6e, 0x9c, 0xfe, 0xf2, 0xae, 0x2d, 0x39, 0x59, - 0x64, 0x12, 0x9c, 0x93, 0xa3, 0x6f, 0xc0, 0x8c, 0x77, 0x64, 0x13, 0xfa, 0x94, 0x70, 0x2a, 0x04, - 0x0b, 0x2e, 0xb9, 0xd5, 0x54, 0x96, 0xcf, 0xef, 0xb4, 0xc4, 0xbb, 0xf3, 0xd0, 0xa7, 0xf3, 0x44, - 0x86, 0xdb, 0xf1, 0x8d, 0x36, 0x5a, 0xc1, 0xa3, 0x78, 0x47, 0xa2, 0xb5, 0xeb, 0xd1, 0x0d, 0x0d, - 0xc4, 0xde, 0xbf, 0xa5, 0xfc, 0x3f, 0x3f, 0xc0, 0x7f, 0x96, 0x8a, 0xb3, 0x4e, 0x1e, 0xc4, 0xef, - 0x82, 0xe8, 0x37, 0x50, 0xde, 0xd0, 0x0d, 0x5b, 0x5a, 0x54, 0x39, 0x3f, 0xbd, 0xd3, 0xf9, 0x5c, - 0xb2, 0xb1, 0x16, 0x49, 0xf5, 0xd5, 0x6e, 0xed, 0x06, 0xd6, 0xf2, 0x40, 0xf5, 0x6b, 0xc9, 0xc6, - 0x5a, 0x84, 0x6c, 0xa8, 0xb9, 0xcb, 0xc8, 0xf5, 0xbe, 0xa5, 0xc2, 0xba, 0x54, 0x06, 0xbf, 0xb8, - 0xd3, 0xa0, 0x9f, 0x08, 0x70, 0x26, 0x45, 0x2f, 0xa1, 0x28, 0xdc, 0xc8, 0x5a, 0x29, 0x87, 0x4f, - 0xee, 0x74, 0x70, 0xdc, 0x08, 0x4b, 0x41, 0xf7, 0x4f, 0x00, 0xfb, 0x9d, 0x45, 0x1f, 0x43, 0x8b, - 0x71, 0x92, 0xcb, 0x0e, 0x43, 0xe5, 0x58, 0x93, 0xf1, 0x1c, 0xe9, 0x19, 0xdc, 0xcf, 0xec, 0xc9, - 0x77, 0x4c, 0xac, 0x08, 0x8b, 0x92, 0x43, 0xd7, 0xc9, 0x02, 0x6f, 0x98, 0x58, 0x8d, 0xa2, 0xee, - 0x5f, 0x0c, 0x68, 0xdf, 0xdc, 0x66, 0xf4, 0x1c, 0xaa, 0x49, 0xc6, 0x28, 0xf7, 0xf6, 0xe9, 0x07, - 0xf9, 0xd1, 0x6a, 0xb2, 0x3a, 0x8b, 0x15, 0x9d, 0x0f, 0xe8, 0x31, 0xd4, 0xfe, 0xbc, 0xa5, 0x5b, - 0x4a, 0x98, 0xaf, 0xba, 0x69, 0xe1, 0xaa, 0x6a, 0x8f, 0x7c, 0xf4, 0x09, 0xb4, 0xd3, 0x10, 0xb9, - 0x72, 0xd7, 0xcc, 0x57, 0x27, 0xbc, 0x85, 0x9b, 0x09, 0xe1, 0xb5, 0xc4, 0xba, 0x03, 0x78, 0x70, - 0x4b, 0x2a, 0xa0, 0x87, 0x50, 0x56, 0x34, 0x35, 0x8c, 0x16, 0xd6, 0x0d, 0xf4, 0x01, 0x54, 0xbe, - 0x0b, 0xe3, 0x6f, 0x69, 0x9c, 0xf4, 0x95, 0xb4, 0xba, 0xff, 0x29, 0x40, 0x59, 0x6d, 0xbb, 0x64, - 0x6c, 0x5c, 0x2e, 0x68, 0x9c, 0xac, 0x4e, 0xd2, 0x42, 0x43, 0x28, 0xa9, 0x59, 0x15, 0xd4, 0xac, - 0x5e, 0x1c, 0x96, 0x44, 0xfa, 0x57, 0xce, 0x13, 0x2b, 0x35, 0x6a, 0x43, 0x21, 0x9b, 0x46, 0x81, - 0xf9, 0xe8, 0xe7, 0xd0, 0xe1, 0xa1, 0xdc, 0x62, 0xb2, 0x64, 0x6b, 0xaa, 0x6a, 0x5f, 0x49, 0xad, - 0x75, 0x5b, 0xc3, 0x67, 0x09, 0x2a, 0x87, 0xc5, 0xa9, 0x17, 0x53, 0x91, 0x14, 0xa5, 0xa4, 0x85, - 0x3e, 0x84, 0x7a, 0xcc, 0x82, 0x4b, 0xc2, 0xd9, 0xf7, 0x34, 0xa9, 0x4a, 0x35, 0x09, 0xcc, 0xd9, - 0xf7, 0x14, 0x3d, 0x81, 0xc6, 0xc5, 0x76, 0xb9, 0xa4, 0xb1, 0x0e, 0xeb, 0x12, 0x05, 0x1a, 0x52, - 0x04, 0xa9, 0xde, 0x11, 0xb5, 0x34, 0xba, 0x3c, 0x49, 0xf5, 0xee, 0x8f, 0xaa, 0x2d, 0x83, 0x22, - 0x0b, 0xd6, 0x75, 0x50, 0x24, 0xc1, 0xa3, 0x53, 0xa8, 0x67, 0x73, 0x43, 0x4d, 0xa8, 0xd9, 0xce, - 0x57, 0x36, 0x9e, 0xd8, 0x8e, 0x79, 0x0f, 0x55, 0xa0, 0x30, 0x9a, 0x99, 0x06, 0xea, 0x40, 0x63, - 0xb6, 0x98, 0x38, 0x64, 0x34, 0xf9, 0x83, 0x3d, 0x70, 0xcc, 0x42, 0xf7, 0x1a, 0xca, 0xea, 0x70, - 0xc8, 0x71, 0xf1, 0xd8, 0xcb, 0xea, 0xa2, 0xae, 0xf6, 0xc0, 0x63, 0x2f, 0xad, 0x87, 0x4f, 0xa0, - 0xe1, 0x73, 0x91, 0x11, 0x74, 0xfa, 0x81, 0xcf, 0x45, 0xae, 0x0c, 0x5f, 0x05, 0x2c, 0x59, 0x48, - 0xf9, 0x89, 0x7e, 0x0a, 0xf5, 0xcd, 0x76, 0x2d, 0x98, 0xe7, 0x72, 0x91, 0xac, 0xe1, 0x1e, 0xe8, - 0x7e, 0x06, 0xb5, 0xf4, 0x58, 0xa1, 0x1e, 0x34, 0x57, 0x21, 0x17, 0x84, 0x2d, 0x49, 0xee, 0xb2, - 0x01, 0x89, 0x8d, 0x96, 0x13, 0x77, 0x43, 0xbb, 0x7f, 0x37, 0xa0, 0xe8, 0xb8, 0x91, 0xbc, 0x29, - 0xae, 0x68, 0xcc, 0xe5, 0xb5, 0xa3, 0xb3, 0x28, 0x6d, 0xbe, 0xe3, 0x51, 0x78, 0xdb, 0x43, 0x8e, - 0x47, 0x46, 0x78, 0xe4, 0x7a, 0xfa, 0x66, 0xaa, 0xe3, 0x3d, 0x20, 0xf5, 0xf1, 0x8e, 0xec, 0x77, - 0xae, 0xa4, 0xb7, 0x26, 0xde, 0xe1, 0x74, 0xef, 0x7a, 0xd0, 0x14, 0x79, 0x46, 0x59, 0x33, 0x44, - 0xc6, 0x38, 0xfa, 0x47, 0x1d, 0x3a, 0xfb, 0xd4, 0x9b, 0x0b, 0x57, 0x50, 0x64, 0xdf, 0x72, 0x21, - 0x7f, 0x7a, 0x7b, 0xae, 0x2a, 0xc1, 0x8f, 0xdc, 0xca, 0xff, 0xae, 0xdd, 0x75, 0x2b, 0xcb, 0x5a, - 0x22, 0x09, 0x81, 0xbb, 0xce, 0xaf, 0x40, 0x33, 0x05, 0xd5, 0x1a, 0xbc, 0xe7, 0xc5, 0xfc, 0x18, - 0x6a, 0x6c, 0x49, 0x58, 0xe0, 0xd3, 0x5d, 0xb2, 0x20, 0x55, 0xb6, 0x1c, 0xc9, 0x26, 0x9a, 0x42, - 0xd3, 0xf5, 0x37, 0x2c, 0x20, 0x5c, 0xb8, 0x62, 0xab, 0x6f, 0xe6, 0xf6, 0xe9, 0x67, 0x07, 0xcd, - 0xec, 0x64, 0xae, 0x34, 0xb8, 0xa1, 0x1c, 0x74, 0x03, 0x9d, 0x43, 0x23, 0x8c, 0xe4, 0xc1, 0xd0, - 0x7e, 0x95, 0xff, 0xc3, 0x0f, 0xa4, 0x41, 0x62, 0xf7, 0x04, 0x1a, 0x6b, 0x97, 0x0b, 0xe2, 0xad, - 0xdc, 0xe0, 0x52, 0x9f, 0xb4, 0x22, 0x06, 0x09, 0x0d, 0x14, 0xf2, 0xce, 0xd3, 0xa2, 0xf6, 0xee, - 0xd3, 0xe2, 0x21, 0x94, 0x79, 0x44, 0xa9, 0xaf, 0xce, 0x5a, 0x09, 0xeb, 0x46, 0xfa, 0xe0, 0x80, - 0xfd, 0x83, 0x63, 0x08, 0x15, 0x7f, 0x1b, 0xad, 0xe9, 0x4e, 0xdd, 0xee, 0x07, 0x8f, 0x7a, 0xa8, - 0x34, 0x38, 0xd1, 0xa2, 0x19, 0x80, 0x9c, 0x3b, 0xe3, 0x82, 0x79, 0xdc, 0xf2, 0xd5, 0xcd, 0xf2, - 0xe2, 0xf0, 0xf9, 0x6b, 0x1d, 0xce, 0x79, 0x74, 0x7f, 0x28, 0x02, 0xec, 0x43, 0xe8, 0x67, 0x32, - 0x15, 0x89, 0x3e, 0x73, 0xfa, 0x8c, 0x97, 0x70, 0x9d, 0x05, 0x33, 0x0d, 0xa8, 0xcd, 0x0e, 0xc8, - 0xc5, 0xb5, 0xa0, 0xfa, 0x7c, 0x97, 0x70, 0x95, 0x05, 0x5f, 0xca, 0xa6, 0x5c, 0xcc, 0x70, 0x2b, - 0x32, 0x69, 0x51, 0x45, 0x21, 0xdc, 0x8a, 0x54, 0xfb, 0x21, 0xd4, 0x25, 0x41, 0x8b, 0x4b, 0x2a, - 0x5c, 0x0b, 0xb7, 0x42, 0xab, 0x3f, 0x82, 0xa6, 0x1f, 0x87, 0x51, 0x26, 0x2f, 0xab, 0x78, 0x43, - 0x62, 0xa9, 0x5e, 0x6e, 0xc6, 0x36, 0xd8, 0xf7, 0x50, 0xd1, 0x14, 0x89, 0xe5, 0x28, 0x2c, 0xba, - 0xfa, 0x3c, 0xa3, 0x54, 0x35, 0x45, 0x62, 0x37, 0x29, 0x2f, 0x33, 0x4a, 0x2d, 0xa3, 0xbc, 0x4c, - 0x29, 0xc7, 0xf2, 0x39, 0x4d, 0x82, 0xf0, 0x62, 0xbb, 0xcc, 0x68, 0x7a, 0x77, 0xdb, 0x2c, 0x98, - 0x48, 0x38, 0x65, 0x3e, 0x85, 0x0e, 0x0b, 0xc8, 0x86, 0x71, 0x9e, 0x11, 0x41, 0x11, 0x5b, 0x2c, - 0x38, 0x67, 0x9c, 0xdf, 0x74, 0xa4, 0x71, 0x1c, 0xc6, 0x19, 0xb1, 0x91, 0x3a, 0xda, 0x12, 0x4e, - 0x99, 0xcf, 0xe0, 0xbe, 0x5c, 0xa4, 0x9b, 0xd4, 0xa6, 0xa2, 0x76, 0xc2, 0xad, 0xc8, 0x73, 0x8f, - 0xbe, 0x80, 0x4a, 0x92, 0xc8, 0x08, 0xda, 0x8b, 0xc9, 0xab, 0xc9, 0xf4, 0xcd, 0x84, 0xcc, 0x9d, - 0xbe, 0xb3, 0x98, 0xeb, 0x82, 0xbe, 0x90, 0x05, 0xbd, 0x06, 0xa5, 0xe1, 0xf4, 0xcd, 0xc4, 0x2c, - 0xa0, 0x06, 0x54, 0x87, 0xf6, 0xd8, 0x76, 0xec, 0xa1, 0x59, 0x3c, 0x7a, 0x01, 0x15, 0x9d, 0x5b, - 0x79, 0xf1, 0x70, 0x31, 0x1b, 0xdb, 0x5f, 0x9b, 0xf7, 0xa4, 0xe8, 0xab, 0xfe, 0xf8, 0x4c, 0xcb, - 0xcf, 0x16, 0xe3, 0xb1, 0x59, 0x38, 0xfa, 0xa7, 0x01, 0x8f, 0xb2, 0x74, 0x9a, 0x84, 0x82, 0x2d, - 0x99, 0xe7, 0xaa, 0xa7, 0xfc, 0x6f, 0xa1, 0x24, 0x0b, 0x42, 0xf2, 0x76, 0xb8, 0xfd, 0xdd, 0x9a, - 0x17, 0x9c, 0xa8, 0x86, 0xae, 0x21, 0xf2, 0x17, 0x7d, 0x01, 0x65, 0x99, 0x92, 0xba, 0x1e, 0x1d, - 0x5c, 0xfb, 0xb4, 0x46, 0x5e, 0x6a, 0x99, 0x9f, 0x9c, 0x63, 0x32, 0x19, 0xf3, 0x1e, 0x02, 0xa8, - 0x2c, 0x66, 0x6a, 0xf2, 0x86, 0xbc, 0xed, 0x06, 0xd3, 0xc5, 0xc4, 0xb1, 0xf1, 0xdc, 0x2c, 0x1c, - 0xfd, 0xab, 0x90, 0xab, 0xc2, 0x6a, 0x51, 0xf9, 0x7b, 0x54, 0x61, 0x2d, 0xf8, 0x91, 0x2a, 0xfc, - 0x5f, 0x23, 0x5f, 0x85, 0x3f, 0x85, 0xf6, 0xfe, 0x61, 0x96, 0xab, 0xc7, 0xad, 0x0c, 0x55, 0x35, - 0x77, 0x02, 0xa0, 0xb7, 0xdc, 0x77, 0x85, 0x6b, 0x15, 0x54, 0xdf, 0xcf, 0x0f, 0xea, 0xfb, 0x44, - 0x01, 0x43, 0x57, 0xb8, 0xb8, 0x4e, 0xd3, 0xcf, 0x6e, 0x0c, 0xf5, 0x0c, 0x97, 0x27, 0x53, 0x57, - 0x38, 0x22, 0xd2, 0x5d, 0xaa, 0x63, 0xd0, 0x90, 0x5a, 0xb4, 0x8f, 0xa1, 0xa5, 0x7b, 0xdf, 0x50, - 0xce, 0xdd, 0xcb, 0xec, 0x5a, 0x50, 0xe0, 0xb9, 0xc6, 0xde, 0x2e, 0x96, 0xc5, 0xb7, 0x8b, 0xe5, - 0xb3, 0xbf, 0x19, 0xd0, 0xba, 0x71, 0x41, 0xa0, 0x47, 0x70, 0x7f, 0x3e, 0x3d, 0x73, 0xde, 0xf4, - 0xb1, 0x4d, 0xc6, 0xd3, 0xe9, 0xec, 0xcb, 0xfe, 0xe0, 0x95, 0x79, 0x0f, 0x3d, 0x80, 0x4e, 0xfa, - 0xf0, 0x20, 0x83, 0xf9, 0x79, 0x7f, 0x30, 0x34, 0x0d, 0xf4, 0x10, 0xcc, 0x73, 0xfb, 0x7c, 0x8a, - 0xbf, 0x21, 0x23, 0xb9, 0x49, 0x67, 0xfd, 0x81, 0x6d, 0x16, 0xd0, 0x7d, 0x68, 0x39, 0xfd, 0x59, - 0x0e, 0x2a, 0xa2, 0x9f, 0xc0, 0x83, 0xfe, 0x19, 0x99, 0xf5, 0x07, 0xaf, 0x6c, 0x27, 0x17, 0x28, - 0x21, 0x13, 0x9a, 0xaf, 0xbf, 0x1e, 0xf7, 0x27, 0xc4, 0x59, 0x4c, 0x26, 0xf6, 0xd8, 0x2c, 0x3f, - 0x9b, 0x01, 0xec, 0xdf, 0xae, 0x37, 0x53, 0xa3, 0x01, 0xd5, 0xd9, 0x74, 0x3c, 0x1e, 0x4d, 0x7e, - 0x6f, 0x1a, 0xa8, 0x05, 0x75, 0x65, 0x84, 0x17, 0x33, 0xc7, 0x2c, 0xc8, 0x54, 0xe9, 0x0f, 0xfb, - 0x33, 0x67, 0xf4, 0x5a, 0xf6, 0xa7, 0x4e, 0xcd, 0x59, 0x7f, 0x31, 0x76, 0xcc, 0xd2, 0x45, 0x45, - 0xfd, 0xb9, 0xfe, 0xf5, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xec, 0x10, 0x72, 0x70, 0x0f, +func init() { proto.RegisterFile("interfaces.proto", fileDescriptor_interfaces_d8d30348f2c6c08e) } + +var fileDescriptor_interfaces_d8d30348f2c6c08e = []byte{ + // 1666 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x92, 0xdb, 0xb6, + 0x15, 0x36, 0xf5, 0xaf, 0xa3, 0x3f, 0x1a, 0xb6, 0x13, 0x5a, 0x69, 0xc7, 0xca, 0x26, 0x71, 0xb7, + 0x6e, 0xba, 0xf6, 0x6c, 0x33, 0xbe, 0x49, 0x67, 0x5a, 0x45, 0xe2, 0x36, 0xaa, 0xf5, 0x57, 0x88, + 0xb2, 0x93, 0x99, 0x76, 0x30, 0x5c, 0x12, 0x5a, 0x61, 0x22, 0x91, 0x2c, 0x01, 0x6d, 0xb4, 0xb9, + 0xec, 0x0b, 0xf4, 0x1d, 0xda, 0x87, 0x68, 0x5f, 0xa1, 0x97, 0xb9, 0xef, 0x55, 0x1f, 0xa2, 0xd7, + 0x1d, 0x00, 0x24, 0xc5, 0xb5, 0x37, 0xb3, 0x9b, 0xde, 0xec, 0x08, 0xdf, 0xf9, 0xbe, 0x0f, 0x04, + 0x70, 0x70, 0x0e, 0x16, 0x4c, 0x16, 0x08, 0x1a, 0xaf, 0x5c, 0x8f, 0xf2, 0x93, 0x28, 0x0e, 0x45, + 0x88, 0xe0, 0x80, 0x1c, 0xfd, 0xad, 0x03, 0x30, 0xca, 0x86, 0xe8, 0xb7, 0x90, 0x0b, 0x5a, 0x46, + 0xaf, 0x78, 0xdc, 0x38, 0xed, 0x9d, 0xe4, 0x1c, 0x46, 0x37, 0xfc, 0xc4, 0x39, 0x4d, 0xf7, 0xfb, + 0x36, 0xd4, 0xb3, 0x08, 0x42, 0x50, 0x0a, 0xdc, 0x2d, 0xb5, 0x8c, 0x9e, 0x71, 0x5c, 0xc7, 0xea, + 0x37, 0xea, 0x41, 0xc3, 0xa7, 0xdc, 0x8b, 0x59, 0x24, 0x58, 0x18, 0x58, 0x05, 0x15, 0xca, 0x43, + 0xe8, 0x97, 0x50, 0x12, 0x57, 0x11, 0xb5, 0x8a, 0x3d, 0xe3, 0xb8, 0x7d, 0xfa, 0xf8, 0xc6, 0xf9, + 0x9d, 0xab, 0x88, 0x62, 0x45, 0x43, 0x16, 0x54, 0x69, 0xe0, 0x9e, 0x6f, 0xa8, 0x6f, 0x95, 0x7a, + 0xc6, 0x71, 0x0d, 0xa7, 0x43, 0xf4, 0x21, 0x34, 0xa3, 0xf5, 0x15, 0x27, 0xae, 0xef, 0xc7, 0x94, + 0x73, 0xab, 0xac, 0xe7, 0x92, 0x58, 0x5f, 0x43, 0xc8, 0x84, 0xe2, 0x56, 0xec, 0xac, 0x4a, 0xcf, + 0x38, 0x6e, 0x61, 0xf9, 0x53, 0x22, 0x97, 0xf1, 0xca, 0xaa, 0x6a, 0xe4, 0x32, 0x5e, 0xa1, 0x17, + 0xf0, 0xd0, 0x0b, 0x03, 0xe1, 0xb2, 0x80, 0xc6, 0x84, 0x45, 0x99, 0x5d, 0x4d, 0xd9, 0xa1, 0x2c, + 0x36, 0x8a, 0x52, 0xd7, 0xa7, 0xd0, 0xe1, 0x54, 0x10, 0x7f, 0xed, 0x45, 0xc4, 0xdb, 0x30, 0x1a, + 0x08, 0xab, 0xae, 0x3e, 0xad, 0xc5, 0xa9, 0x18, 0xae, 0xbd, 0x68, 0xa0, 0x40, 0xf9, 0x81, 0x07, + 0x3f, 0xca, 0x2d, 0xe8, 0x15, 0xe5, 0x07, 0xb2, 0xd4, 0x88, 0x72, 0xf4, 0x0a, 0x60, 0x17, 0x04, + 0xbb, 0xed, 0x39, 0x8d, 0xa9, 0x6f, 0x35, 0x7a, 0xc6, 0x71, 0xe3, 0xf4, 0x17, 0xb7, 0x1d, 0xc9, + 0xc9, 0x32, 0x93, 0xe0, 0x9c, 0x1c, 0x7d, 0x0d, 0x66, 0xbc, 0x27, 0xdb, 0xd0, 0xa7, 0x84, 0x53, + 0x21, 0x58, 0x70, 0xc1, 0xad, 0xa6, 0xb2, 0x7c, 0x7e, 0xab, 0x25, 0xde, 0x4f, 0x42, 0x9f, 0x2e, + 0x12, 0x19, 0x6e, 0xc7, 0xd7, 0xc6, 0x68, 0x0d, 0x8f, 0xe2, 0x3d, 0x89, 0x36, 0xae, 0x47, 0xb7, + 0x34, 0x10, 0x07, 0xff, 0x96, 0xf2, 0xff, 0xec, 0x0e, 0xfe, 0xf3, 0x54, 0x9c, 0x4d, 0xf2, 0x20, + 0x7e, 0x17, 0x44, 0xbf, 0x86, 0xf2, 0x96, 0x6e, 0xd9, 0xca, 0xa2, 0xca, 0xf9, 0xe9, 0xad, 0xce, + 0x13, 0xc9, 0xc6, 0x5a, 0x24, 0xd5, 0x97, 0xfb, 0x8d, 0x1b, 0x58, 0xab, 0x3b, 0xaa, 0x5f, 0x4b, + 0x36, 0xd6, 0x22, 0x64, 0x43, 0xcd, 0x5d, 0x45, 0xae, 0xf7, 0x0d, 0x15, 0xd6, 0x85, 0x32, 0xf8, + 0xf9, 0xad, 0x06, 0xfd, 0x44, 0x80, 0x33, 0x29, 0x7a, 0x09, 0x45, 0xe1, 0x46, 0xd6, 0x5a, 0x39, + 0x7c, 0x7c, 0xab, 0x83, 0xe3, 0x46, 0x58, 0x0a, 0xba, 0x7f, 0x02, 0x38, 0x9c, 0x2c, 0xfa, 0x08, + 0x5a, 0x8c, 0x93, 0x5c, 0x76, 0x18, 0x2a, 0xc7, 0x9a, 0x8c, 0xe7, 0x48, 0xcf, 0xe0, 0x7e, 0x66, + 0x4f, 0xbe, 0x65, 0x62, 0x4d, 0x58, 0x94, 0x5c, 0xba, 0x4e, 0x16, 0x78, 0xc3, 0xc4, 0x7a, 0x14, + 0x75, 0xff, 0x62, 0x40, 0xfb, 0xfa, 0x31, 0xa3, 0xe7, 0x50, 0x4d, 0x32, 0x46, 0xb9, 0xb7, 0x4f, + 0xdf, 0xcb, 0x7f, 0xad, 0x26, 0xab, 0xbb, 0x58, 0xd1, 0xf9, 0x80, 0x1e, 0x43, 0xed, 0xcf, 0x3b, + 0xba, 0xa3, 0x84, 0xf9, 0x6a, 0x9a, 0x16, 0xae, 0xaa, 0xf1, 0xc8, 0x47, 0x1f, 0x43, 0x3b, 0x0d, + 0x91, 0x4b, 0x77, 0xc3, 0x7c, 0x75, 0xc3, 0x5b, 0xb8, 0x99, 0x10, 0x5e, 0x4b, 0xac, 0xfb, 0x47, + 0x78, 0x70, 0x43, 0x2a, 0xa0, 0x87, 0x50, 0x56, 0x34, 0xf5, 0x19, 0x2d, 0xac, 0x07, 0xe8, 0x3d, + 0xa8, 0x7c, 0x1b, 0xc6, 0xdf, 0xd0, 0x38, 0x99, 0x2b, 0x19, 0xa1, 0xf7, 0xa1, 0xca, 0x38, 0xd9, + 0xba, 0x2c, 0x50, 0x73, 0xd4, 0x70, 0x85, 0xf1, 0x89, 0xcb, 0x82, 0xee, 0x7f, 0x0a, 0x50, 0x56, + 0xf9, 0x20, 0xa5, 0x5b, 0x97, 0x0b, 0x1a, 0x27, 0xdb, 0x96, 0x8c, 0xd0, 0x10, 0x4a, 0x6a, 0xb9, + 0x05, 0xb5, 0xdc, 0x17, 0x77, 0xcb, 0x2e, 0xfd, 0x57, 0x6e, 0x00, 0x56, 0x6a, 0xd4, 0x86, 0x42, + 0xb6, 0xbe, 0x02, 0xf3, 0xd1, 0xcf, 0xa0, 0xc3, 0x43, 0x79, 0xf6, 0x64, 0xc5, 0x36, 0x54, 0x15, + 0xc5, 0x92, 0x3a, 0x84, 0xb6, 0x86, 0xcf, 0x12, 0x54, 0x7e, 0x16, 0xa7, 0x5e, 0x4c, 0x45, 0x52, + 0xad, 0x92, 0x11, 0xfa, 0x00, 0xea, 0x31, 0x0b, 0x2e, 0x08, 0x67, 0xdf, 0xd1, 0xa4, 0x5c, 0xd5, + 0x24, 0xb0, 0x60, 0xdf, 0x51, 0xf4, 0x04, 0x1a, 0xe7, 0xbb, 0xd5, 0x8a, 0xc6, 0x3a, 0xac, 0x6b, + 0x17, 0x68, 0x48, 0x11, 0xa4, 0x7a, 0x4f, 0xd4, 0x9e, 0xe9, 0xba, 0x25, 0xd5, 0xfb, 0x3f, 0xa8, + 0xb1, 0x0c, 0x8a, 0x2c, 0x58, 0xd7, 0x41, 0x91, 0x04, 0x8f, 0x4e, 0xa1, 0x9e, 0xad, 0x0d, 0x35, + 0xa1, 0x66, 0x3b, 0x5f, 0xda, 0x78, 0x6a, 0x3b, 0xe6, 0x3d, 0x54, 0x81, 0xc2, 0x68, 0x6e, 0x1a, + 0xa8, 0x03, 0x8d, 0xf9, 0x72, 0xea, 0x90, 0xd1, 0xf4, 0xf7, 0xf6, 0xc0, 0x31, 0x0b, 0xdd, 0x2b, + 0x28, 0xab, 0x5b, 0x23, 0xbf, 0x8b, 0xc7, 0x5e, 0x56, 0x30, 0x75, 0x1b, 0x00, 0x1e, 0x7b, 0x69, + 0xa1, 0x7c, 0x02, 0x0d, 0x9f, 0x8b, 0x8c, 0xa0, 0xf3, 0x12, 0x7c, 0x2e, 0x72, 0xf5, 0xf9, 0x32, + 0x60, 0xc9, 0x46, 0xca, 0x9f, 0xe8, 0x27, 0x50, 0xdf, 0xee, 0x36, 0x82, 0x79, 0x2e, 0x17, 0xc9, + 0x1e, 0x1e, 0x80, 0xee, 0xa7, 0x50, 0x4b, 0xef, 0x1b, 0xea, 0x41, 0x73, 0x1d, 0x72, 0x41, 0xd8, + 0x8a, 0xe4, 0xba, 0x10, 0x48, 0x6c, 0xb4, 0x9a, 0xba, 0x5b, 0xda, 0xfd, 0xbb, 0x01, 0x45, 0xc7, + 0x8d, 0x64, 0x0b, 0xb9, 0xa4, 0x31, 0x97, 0xfd, 0x48, 0xa7, 0x57, 0x3a, 0x7c, 0xc7, 0xa3, 0xf0, + 0xb6, 0x87, 0xfc, 0x1e, 0x19, 0xe1, 0x91, 0xeb, 0xe9, 0x96, 0x55, 0xc7, 0x07, 0x40, 0xea, 0xe3, + 0x3d, 0x39, 0x9c, 0x5c, 0x49, 0x1f, 0x4d, 0xbc, 0xc7, 0xe9, 0xd9, 0xf5, 0xa0, 0x29, 0xf2, 0x8c, + 0xb2, 0x66, 0x88, 0x8c, 0x71, 0xf4, 0x8f, 0x3a, 0x74, 0x0e, 0xa9, 0xb7, 0x10, 0xae, 0xa0, 0xc8, + 0xbe, 0xa1, 0x53, 0x7f, 0x72, 0x73, 0xae, 0x2a, 0xc1, 0x0f, 0xb4, 0xeb, 0x7f, 0xd7, 0x6e, 0x6b, + 0xd7, 0xb2, 0xc8, 0x48, 0x42, 0xe0, 0x6e, 0xf2, 0x3b, 0xd0, 0x4c, 0x41, 0xb5, 0x07, 0x3f, 0xb2, + 0x63, 0x3f, 0x86, 0x1a, 0x5b, 0x11, 0x16, 0xf8, 0x74, 0x9f, 0x6c, 0x48, 0x95, 0xad, 0x46, 0x72, + 0x88, 0x66, 0xd0, 0x74, 0xfd, 0x2d, 0x0b, 0x08, 0x17, 0xae, 0xd8, 0xe9, 0x96, 0xdd, 0x3e, 0xfd, + 0xf4, 0x4e, 0x2b, 0x3b, 0x59, 0x28, 0x0d, 0x6e, 0x28, 0x07, 0x3d, 0x40, 0x13, 0x68, 0x84, 0x91, + 0xbc, 0x18, 0xda, 0xaf, 0xf2, 0x7f, 0xf8, 0x81, 0x34, 0x48, 0xec, 0x9e, 0x40, 0x63, 0xe3, 0x72, + 0x41, 0xbc, 0xb5, 0x1b, 0x5c, 0xe8, 0x9b, 0x56, 0xc4, 0x20, 0xa1, 0x81, 0x42, 0xde, 0x79, 0x73, + 0xd4, 0xde, 0x7d, 0x73, 0x3c, 0x84, 0x32, 0x8f, 0x28, 0xf5, 0xd5, 0x5d, 0x2b, 0x61, 0x3d, 0x48, + 0x5f, 0x22, 0x70, 0x78, 0x89, 0x0c, 0xa1, 0xe2, 0xef, 0xa2, 0x0d, 0xdd, 0xab, 0xb6, 0x7f, 0xe7, + 0xaf, 0x1e, 0x2a, 0x0d, 0x4e, 0xb4, 0x68, 0x0e, 0x20, 0xd7, 0xce, 0xb8, 0x60, 0x1e, 0xb7, 0x7c, + 0xd5, 0x72, 0x5e, 0xdc, 0x7d, 0xfd, 0x5a, 0x87, 0x73, 0x1e, 0xdd, 0x7f, 0x16, 0x01, 0x0e, 0x21, + 0xf4, 0x53, 0x99, 0x8a, 0x44, 0xdf, 0x39, 0x7d, 0xc7, 0x4b, 0xb8, 0xce, 0x82, 0xb9, 0x06, 0xd4, + 0x61, 0x07, 0xe4, 0xfc, 0x4a, 0x50, 0x7d, 0xbf, 0x4b, 0xb8, 0xca, 0x82, 0x2f, 0xe4, 0x50, 0x6e, + 0x66, 0xb8, 0x13, 0x99, 0xb4, 0xa8, 0xa2, 0x10, 0xee, 0x44, 0xaa, 0xfd, 0x00, 0xea, 0x92, 0xa0, + 0xc5, 0x25, 0x15, 0xae, 0x85, 0x3b, 0xa1, 0xd5, 0x1f, 0x42, 0xd3, 0x8f, 0xc3, 0x28, 0x93, 0x97, + 0x55, 0xbc, 0x21, 0xb1, 0x54, 0x2f, 0x0f, 0x63, 0x17, 0x1c, 0x66, 0xa8, 0x68, 0x8a, 0xc4, 0x72, + 0x14, 0x16, 0x5d, 0x7e, 0x96, 0x51, 0xaa, 0x9a, 0x22, 0xb1, 0xeb, 0x94, 0x97, 0x19, 0xa5, 0x96, + 0x51, 0x5e, 0xa6, 0x94, 0x63, 0xf9, 0xce, 0x26, 0x41, 0x78, 0xbe, 0x5b, 0x65, 0x34, 0x7d, 0xba, + 0x6d, 0x16, 0x4c, 0x25, 0x9c, 0x32, 0x9f, 0x42, 0x87, 0x05, 0x64, 0xcb, 0x38, 0xcf, 0x88, 0xa0, + 0x88, 0x2d, 0x16, 0x4c, 0x18, 0xe7, 0xd7, 0x1d, 0x69, 0x1c, 0x87, 0x71, 0x46, 0x6c, 0xa4, 0x8e, + 0xb6, 0x84, 0x53, 0xe6, 0x33, 0xb8, 0x2f, 0x37, 0xe9, 0x3a, 0xb5, 0xa9, 0xa8, 0x9d, 0x70, 0x27, + 0xf2, 0xdc, 0xa3, 0xcf, 0xa1, 0x92, 0x24, 0x32, 0x82, 0xf6, 0x72, 0xfa, 0x6a, 0x3a, 0x7b, 0x33, + 0x25, 0x0b, 0xa7, 0xef, 0x2c, 0x17, 0xba, 0xa0, 0x2f, 0x65, 0x41, 0xaf, 0x41, 0x69, 0x38, 0x7b, + 0x33, 0x35, 0x0b, 0xa8, 0x01, 0xd5, 0xa1, 0x3d, 0xb6, 0x1d, 0x7b, 0x68, 0x16, 0x8f, 0x5e, 0x40, + 0x45, 0xe7, 0x56, 0x5e, 0x3c, 0x5c, 0xce, 0xc7, 0xf6, 0x57, 0xe6, 0x3d, 0x29, 0xfa, 0xb2, 0x3f, + 0x3e, 0xd3, 0xf2, 0xb3, 0xe5, 0x78, 0x6c, 0x16, 0x8e, 0xfe, 0x65, 0xc0, 0xa3, 0x2c, 0x9d, 0xa6, + 0xa1, 0x60, 0x2b, 0xe6, 0xb9, 0xea, 0x8d, 0xff, 0x1b, 0x28, 0xc9, 0x82, 0x90, 0x3c, 0x2a, 0x6e, + 0x7e, 0xd0, 0xe6, 0x05, 0x27, 0x6a, 0x90, 0xab, 0x21, 0x9f, 0x43, 0x59, 0xa6, 0xa4, 0xae, 0x47, + 0x77, 0xae, 0x7d, 0x5a, 0x23, 0x9b, 0x5a, 0xe6, 0x27, 0xd7, 0x98, 0x2c, 0xc6, 0xbc, 0x87, 0x00, + 0x2a, 0xcb, 0xb9, 0x5a, 0xbc, 0x21, 0xbb, 0xdd, 0x60, 0xb6, 0x9c, 0x3a, 0x36, 0x5e, 0x98, 0x85, + 0xa3, 0xef, 0x0b, 0xb9, 0x2a, 0xac, 0x36, 0x95, 0xff, 0x88, 0x2a, 0xac, 0x05, 0x3f, 0x50, 0x85, + 0xff, 0x6b, 0xe4, 0xab, 0xf0, 0x27, 0xd0, 0x3e, 0xbc, 0xd8, 0x72, 0xf5, 0xb8, 0x95, 0xa1, 0xaa, + 0xe6, 0x4e, 0x01, 0xf4, 0x91, 0xfb, 0xae, 0x70, 0xad, 0x82, 0x9a, 0xfb, 0xf9, 0x9d, 0xe6, 0x3e, + 0x51, 0xc0, 0xd0, 0x15, 0x2e, 0xae, 0xd3, 0xf4, 0x67, 0x37, 0x86, 0x7a, 0x86, 0xcb, 0x9b, 0xa9, + 0x2b, 0x1c, 0x11, 0xe9, 0x29, 0xd5, 0x31, 0x68, 0x48, 0x6d, 0xda, 0x47, 0xd0, 0xd2, 0xb3, 0x6f, + 0x29, 0xe7, 0xee, 0x45, 0xd6, 0x16, 0x14, 0x38, 0xd1, 0xd8, 0xdb, 0xc5, 0xb2, 0xf8, 0x76, 0xb1, + 0x7c, 0xf6, 0x57, 0x03, 0x5a, 0xd7, 0x1a, 0x04, 0x7a, 0x04, 0xf7, 0x17, 0xb3, 0x33, 0xe7, 0x4d, + 0x1f, 0xdb, 0x64, 0x3c, 0x9b, 0xcd, 0xbf, 0xe8, 0x0f, 0x5e, 0x99, 0xf7, 0xd0, 0x03, 0xe8, 0xa4, + 0x0f, 0x0f, 0x32, 0x58, 0x4c, 0xfa, 0x83, 0xa1, 0x69, 0xa0, 0x87, 0x60, 0x4e, 0xec, 0xc9, 0x0c, + 0x7f, 0x4d, 0x46, 0xf2, 0x90, 0xce, 0xfa, 0x03, 0xdb, 0x2c, 0xa0, 0xfb, 0xd0, 0x72, 0xfa, 0xf3, + 0x1c, 0x54, 0x44, 0xef, 0xc3, 0x83, 0xfe, 0x19, 0x99, 0xf7, 0x07, 0xaf, 0x6c, 0x27, 0x17, 0x28, + 0x21, 0x13, 0x9a, 0xaf, 0xbf, 0x1a, 0xf7, 0xa7, 0xc4, 0x59, 0x4e, 0xa7, 0xf6, 0xd8, 0x2c, 0x3f, + 0x9b, 0x03, 0x1c, 0x1e, 0xb5, 0xd7, 0x53, 0xa3, 0x01, 0xd5, 0xf9, 0x6c, 0x3c, 0x1e, 0x4d, 0x7f, + 0x67, 0x1a, 0xa8, 0x05, 0x75, 0x65, 0x84, 0x97, 0x73, 0xc7, 0x2c, 0xc8, 0x54, 0xe9, 0x0f, 0xfb, + 0x73, 0x67, 0xf4, 0x5a, 0xce, 0xa7, 0x6e, 0xcd, 0x59, 0x7f, 0x39, 0x76, 0xcc, 0xd2, 0x79, 0x45, + 0xfd, 0xd7, 0xfd, 0xab, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x83, 0xae, 0x20, 0xf6, 0x89, 0x0f, 0x00, 0x00, } diff --git a/plugins/vpp/model/interfaces/interfaces.proto b/plugins/vpp/model/interfaces/interfaces.proto index 10883e1de1..a1a0761ca4 100644 --- a/plugins/vpp/model/interfaces/interfaces.proto +++ b/plugins/vpp/model/interfaces/interfaces.proto @@ -51,6 +51,7 @@ message Interfaces { message RxPlacementSettings { uint32 queue = 1; uint32 worker = 2; + bool is_main = 3; } RxPlacementSettings rx_placement_settings = 13; diff --git a/plugins/vpp/model/ipsec/ipsec.pb.go b/plugins/vpp/model/ipsec/ipsec.pb.go index 0e95a2b945..c812a0b83b 100644 --- a/plugins/vpp/model/ipsec/ipsec.pb.go +++ b/plugins/vpp/model/ipsec/ipsec.pb.go @@ -1,18 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: ipsec.proto -/* -Package ipsec is a generated protocol buffer package. - -It is generated from these files: - ipsec.proto - -It has these top-level messages: - TunnelInterfaces - SecurityPolicyDatabases - SecurityAssociations - ResyncRequest -*/ package ipsec import proto "github.com/gogo/protobuf/proto" @@ -56,7 +44,9 @@ var CryptoAlgorithm_value = map[string]int32{ func (x CryptoAlgorithm) String() string { return proto.EnumName(CryptoAlgorithm_name, int32(x)) } -func (CryptoAlgorithm) EnumDescriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{0} } +func (CryptoAlgorithm) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{0} +} // Cryptographic algorithm for authentication type IntegAlgorithm int32 @@ -93,7 +83,9 @@ var IntegAlgorithm_value = map[string]int32{ func (x IntegAlgorithm) String() string { return proto.EnumName(IntegAlgorithm_name, int32(x)) } -func (IntegAlgorithm) EnumDescriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{1} } +func (IntegAlgorithm) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{1} +} // Policy action type SecurityPolicyDatabases_SPD_PolicyEntry_Action int32 @@ -120,7 +112,7 @@ func (x SecurityPolicyDatabases_SPD_PolicyEntry_Action) String() string { return proto.EnumName(SecurityPolicyDatabases_SPD_PolicyEntry_Action_name, int32(x)) } func (SecurityPolicyDatabases_SPD_PolicyEntry_Action) EnumDescriptor() ([]byte, []int) { - return fileDescriptorIpsec, []int{1, 0, 1, 0} + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{1, 0, 1, 0} } // IPSec protocol @@ -144,18 +136,40 @@ func (x SecurityAssociations_SA_IPSecProtocol) String() string { return proto.EnumName(SecurityAssociations_SA_IPSecProtocol_name, int32(x)) } func (SecurityAssociations_SA_IPSecProtocol) EnumDescriptor() ([]byte, []int) { - return fileDescriptorIpsec, []int{2, 0, 0} + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{2, 0, 0} } // Tunnel Interfaces type TunnelInterfaces struct { - Tunnels []*TunnelInterfaces_Tunnel `protobuf:"bytes,1,rep,name=tunnels" json:"tunnels,omitempty"` + Tunnels []*TunnelInterfaces_Tunnel `protobuf:"bytes,1,rep,name=tunnels" json:"tunnels,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TunnelInterfaces) Reset() { *m = TunnelInterfaces{} } +func (m *TunnelInterfaces) String() string { return proto.CompactTextString(m) } +func (*TunnelInterfaces) ProtoMessage() {} +func (*TunnelInterfaces) Descriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{0} +} +func (m *TunnelInterfaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TunnelInterfaces.Unmarshal(m, b) +} +func (m *TunnelInterfaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TunnelInterfaces.Marshal(b, m, deterministic) +} +func (dst *TunnelInterfaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_TunnelInterfaces.Merge(dst, src) +} +func (m *TunnelInterfaces) XXX_Size() int { + return xxx_messageInfo_TunnelInterfaces.Size(m) +} +func (m *TunnelInterfaces) XXX_DiscardUnknown() { + xxx_messageInfo_TunnelInterfaces.DiscardUnknown(m) } -func (m *TunnelInterfaces) Reset() { *m = TunnelInterfaces{} } -func (m *TunnelInterfaces) String() string { return proto.CompactTextString(m) } -func (*TunnelInterfaces) ProtoMessage() {} -func (*TunnelInterfaces) Descriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{0} } +var xxx_messageInfo_TunnelInterfaces proto.InternalMessageInfo func (m *TunnelInterfaces) GetTunnels() []*TunnelInterfaces_Tunnel { if m != nil { @@ -179,15 +193,37 @@ type TunnelInterfaces_Tunnel struct { LocalIntegKey string `protobuf:"bytes,12,opt,name=local_integ_key,json=localIntegKey,proto3" json:"local_integ_key,omitempty"` RemoteIntegKey string `protobuf:"bytes,13,opt,name=remote_integ_key,json=remoteIntegKey,proto3" json:"remote_integ_key,omitempty"` // Extra fields related to interface - Enabled bool `protobuf:"varint,100,opt,name=enabled,proto3" json:"enabled,omitempty"` - IpAddresses []string `protobuf:"bytes,101,rep,name=ip_addresses,json=ipAddresses" json:"ip_addresses,omitempty"` - Vrf uint32 `protobuf:"varint,102,opt,name=vrf,proto3" json:"vrf,omitempty"` + Enabled bool `protobuf:"varint,100,opt,name=enabled,proto3" json:"enabled,omitempty"` + IpAddresses []string `protobuf:"bytes,101,rep,name=ip_addresses,json=ipAddresses" json:"ip_addresses,omitempty"` + Vrf uint32 `protobuf:"varint,102,opt,name=vrf,proto3" json:"vrf,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TunnelInterfaces_Tunnel) Reset() { *m = TunnelInterfaces_Tunnel{} } +func (m *TunnelInterfaces_Tunnel) String() string { return proto.CompactTextString(m) } +func (*TunnelInterfaces_Tunnel) ProtoMessage() {} +func (*TunnelInterfaces_Tunnel) Descriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{0, 0} +} +func (m *TunnelInterfaces_Tunnel) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TunnelInterfaces_Tunnel.Unmarshal(m, b) +} +func (m *TunnelInterfaces_Tunnel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TunnelInterfaces_Tunnel.Marshal(b, m, deterministic) +} +func (dst *TunnelInterfaces_Tunnel) XXX_Merge(src proto.Message) { + xxx_messageInfo_TunnelInterfaces_Tunnel.Merge(dst, src) +} +func (m *TunnelInterfaces_Tunnel) XXX_Size() int { + return xxx_messageInfo_TunnelInterfaces_Tunnel.Size(m) +} +func (m *TunnelInterfaces_Tunnel) XXX_DiscardUnknown() { + xxx_messageInfo_TunnelInterfaces_Tunnel.DiscardUnknown(m) } -func (m *TunnelInterfaces_Tunnel) Reset() { *m = TunnelInterfaces_Tunnel{} } -func (m *TunnelInterfaces_Tunnel) String() string { return proto.CompactTextString(m) } -func (*TunnelInterfaces_Tunnel) ProtoMessage() {} -func (*TunnelInterfaces_Tunnel) Descriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{0, 0} } +var xxx_messageInfo_TunnelInterfaces_Tunnel proto.InternalMessageInfo func (m *TunnelInterfaces_Tunnel) GetName() string { if m != nil { @@ -303,13 +339,35 @@ func (m *TunnelInterfaces_Tunnel) GetVrf() uint32 { // Security Policy Database (SPD) type SecurityPolicyDatabases struct { - Spds []*SecurityPolicyDatabases_SPD `protobuf:"bytes,1,rep,name=spds" json:"spds,omitempty"` + Spds []*SecurityPolicyDatabases_SPD `protobuf:"bytes,1,rep,name=spds" json:"spds,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *SecurityPolicyDatabases) Reset() { *m = SecurityPolicyDatabases{} } -func (m *SecurityPolicyDatabases) String() string { return proto.CompactTextString(m) } -func (*SecurityPolicyDatabases) ProtoMessage() {} -func (*SecurityPolicyDatabases) Descriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{1} } +func (m *SecurityPolicyDatabases) Reset() { *m = SecurityPolicyDatabases{} } +func (m *SecurityPolicyDatabases) String() string { return proto.CompactTextString(m) } +func (*SecurityPolicyDatabases) ProtoMessage() {} +func (*SecurityPolicyDatabases) Descriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{1} +} +func (m *SecurityPolicyDatabases) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SecurityPolicyDatabases.Unmarshal(m, b) +} +func (m *SecurityPolicyDatabases) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SecurityPolicyDatabases.Marshal(b, m, deterministic) +} +func (dst *SecurityPolicyDatabases) XXX_Merge(src proto.Message) { + xxx_messageInfo_SecurityPolicyDatabases.Merge(dst, src) +} +func (m *SecurityPolicyDatabases) XXX_Size() int { + return xxx_messageInfo_SecurityPolicyDatabases.Size(m) +} +func (m *SecurityPolicyDatabases) XXX_DiscardUnknown() { + xxx_messageInfo_SecurityPolicyDatabases.DiscardUnknown(m) +} + +var xxx_messageInfo_SecurityPolicyDatabases proto.InternalMessageInfo func (m *SecurityPolicyDatabases) GetSpds() []*SecurityPolicyDatabases_SPD { if m != nil { @@ -319,18 +377,38 @@ func (m *SecurityPolicyDatabases) GetSpds() []*SecurityPolicyDatabases_SPD { } type SecurityPolicyDatabases_SPD struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Interfaces []*SecurityPolicyDatabases_SPD_Interface `protobuf:"bytes,2,rep,name=interfaces" json:"interfaces,omitempty"` - PolicyEntries []*SecurityPolicyDatabases_SPD_PolicyEntry `protobuf:"bytes,3,rep,name=policy_entries,json=policyEntries" json:"policy_entries,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Interfaces []*SecurityPolicyDatabases_SPD_Interface `protobuf:"bytes,2,rep,name=interfaces" json:"interfaces,omitempty"` + PolicyEntries []*SecurityPolicyDatabases_SPD_PolicyEntry `protobuf:"bytes,3,rep,name=policy_entries,json=policyEntries" json:"policy_entries,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SecurityPolicyDatabases_SPD) Reset() { *m = SecurityPolicyDatabases_SPD{} } func (m *SecurityPolicyDatabases_SPD) String() string { return proto.CompactTextString(m) } func (*SecurityPolicyDatabases_SPD) ProtoMessage() {} func (*SecurityPolicyDatabases_SPD) Descriptor() ([]byte, []int) { - return fileDescriptorIpsec, []int{1, 0} + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{1, 0} +} +func (m *SecurityPolicyDatabases_SPD) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SecurityPolicyDatabases_SPD.Unmarshal(m, b) +} +func (m *SecurityPolicyDatabases_SPD) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SecurityPolicyDatabases_SPD.Marshal(b, m, deterministic) +} +func (dst *SecurityPolicyDatabases_SPD) XXX_Merge(src proto.Message) { + xxx_messageInfo_SecurityPolicyDatabases_SPD.Merge(dst, src) +} +func (m *SecurityPolicyDatabases_SPD) XXX_Size() int { + return xxx_messageInfo_SecurityPolicyDatabases_SPD.Size(m) +} +func (m *SecurityPolicyDatabases_SPD) XXX_DiscardUnknown() { + xxx_messageInfo_SecurityPolicyDatabases_SPD.DiscardUnknown(m) } +var xxx_messageInfo_SecurityPolicyDatabases_SPD proto.InternalMessageInfo + func (m *SecurityPolicyDatabases_SPD) GetName() string { if m != nil { return m.Name @@ -354,16 +432,36 @@ func (m *SecurityPolicyDatabases_SPD) GetPolicyEntries() []*SecurityPolicyDataba // Interface type SecurityPolicyDatabases_SPD_Interface struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SecurityPolicyDatabases_SPD_Interface) Reset() { *m = SecurityPolicyDatabases_SPD_Interface{} } func (m *SecurityPolicyDatabases_SPD_Interface) String() string { return proto.CompactTextString(m) } func (*SecurityPolicyDatabases_SPD_Interface) ProtoMessage() {} func (*SecurityPolicyDatabases_SPD_Interface) Descriptor() ([]byte, []int) { - return fileDescriptorIpsec, []int{1, 0, 0} + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{1, 0, 0} +} +func (m *SecurityPolicyDatabases_SPD_Interface) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SecurityPolicyDatabases_SPD_Interface.Unmarshal(m, b) +} +func (m *SecurityPolicyDatabases_SPD_Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SecurityPolicyDatabases_SPD_Interface.Marshal(b, m, deterministic) +} +func (dst *SecurityPolicyDatabases_SPD_Interface) XXX_Merge(src proto.Message) { + xxx_messageInfo_SecurityPolicyDatabases_SPD_Interface.Merge(dst, src) +} +func (m *SecurityPolicyDatabases_SPD_Interface) XXX_Size() int { + return xxx_messageInfo_SecurityPolicyDatabases_SPD_Interface.Size(m) +} +func (m *SecurityPolicyDatabases_SPD_Interface) XXX_DiscardUnknown() { + xxx_messageInfo_SecurityPolicyDatabases_SPD_Interface.DiscardUnknown(m) } +var xxx_messageInfo_SecurityPolicyDatabases_SPD_Interface proto.InternalMessageInfo + func (m *SecurityPolicyDatabases_SPD_Interface) GetName() string { if m != nil { return m.Name @@ -373,19 +471,22 @@ func (m *SecurityPolicyDatabases_SPD_Interface) GetName() string { // Policy Entry type SecurityPolicyDatabases_SPD_PolicyEntry struct { - Sa string `protobuf:"bytes,1,opt,name=sa,proto3" json:"sa,omitempty"` - Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"` - IsOutbound bool `protobuf:"varint,3,opt,name=is_outbound,json=isOutbound,proto3" json:"is_outbound,omitempty"` - RemoteAddrStart string `protobuf:"bytes,4,opt,name=remote_addr_start,json=remoteAddrStart,proto3" json:"remote_addr_start,omitempty"` - RemoteAddrStop string `protobuf:"bytes,5,opt,name=remote_addr_stop,json=remoteAddrStop,proto3" json:"remote_addr_stop,omitempty"` - LocalAddrStart string `protobuf:"bytes,6,opt,name=local_addr_start,json=localAddrStart,proto3" json:"local_addr_start,omitempty"` - LocalAddrStop string `protobuf:"bytes,7,opt,name=local_addr_stop,json=localAddrStop,proto3" json:"local_addr_stop,omitempty"` - Protocol uint32 `protobuf:"varint,8,opt,name=protocol,proto3" json:"protocol,omitempty"` - RemotePortStart uint32 `protobuf:"varint,9,opt,name=remote_port_start,json=remotePortStart,proto3" json:"remote_port_start,omitempty"` - RemotePortStop uint32 `protobuf:"varint,10,opt,name=remote_port_stop,json=remotePortStop,proto3" json:"remote_port_stop,omitempty"` - LocalPortStart uint32 `protobuf:"varint,11,opt,name=local_port_start,json=localPortStart,proto3" json:"local_port_start,omitempty"` - LocalPortStop uint32 `protobuf:"varint,12,opt,name=local_port_stop,json=localPortStop,proto3" json:"local_port_stop,omitempty"` - Action SecurityPolicyDatabases_SPD_PolicyEntry_Action `protobuf:"varint,13,opt,name=action,proto3,enum=ipsec.SecurityPolicyDatabases_SPD_PolicyEntry_Action" json:"action,omitempty"` + Sa string `protobuf:"bytes,1,opt,name=sa,proto3" json:"sa,omitempty"` + Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"` + IsOutbound bool `protobuf:"varint,3,opt,name=is_outbound,json=isOutbound,proto3" json:"is_outbound,omitempty"` + RemoteAddrStart string `protobuf:"bytes,4,opt,name=remote_addr_start,json=remoteAddrStart,proto3" json:"remote_addr_start,omitempty"` + RemoteAddrStop string `protobuf:"bytes,5,opt,name=remote_addr_stop,json=remoteAddrStop,proto3" json:"remote_addr_stop,omitempty"` + LocalAddrStart string `protobuf:"bytes,6,opt,name=local_addr_start,json=localAddrStart,proto3" json:"local_addr_start,omitempty"` + LocalAddrStop string `protobuf:"bytes,7,opt,name=local_addr_stop,json=localAddrStop,proto3" json:"local_addr_stop,omitempty"` + Protocol uint32 `protobuf:"varint,8,opt,name=protocol,proto3" json:"protocol,omitempty"` + RemotePortStart uint32 `protobuf:"varint,9,opt,name=remote_port_start,json=remotePortStart,proto3" json:"remote_port_start,omitempty"` + RemotePortStop uint32 `protobuf:"varint,10,opt,name=remote_port_stop,json=remotePortStop,proto3" json:"remote_port_stop,omitempty"` + LocalPortStart uint32 `protobuf:"varint,11,opt,name=local_port_start,json=localPortStart,proto3" json:"local_port_start,omitempty"` + LocalPortStop uint32 `protobuf:"varint,12,opt,name=local_port_stop,json=localPortStop,proto3" json:"local_port_stop,omitempty"` + Action SecurityPolicyDatabases_SPD_PolicyEntry_Action `protobuf:"varint,13,opt,name=action,proto3,enum=ipsec.SecurityPolicyDatabases_SPD_PolicyEntry_Action" json:"action,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SecurityPolicyDatabases_SPD_PolicyEntry) Reset() { @@ -394,9 +495,26 @@ func (m *SecurityPolicyDatabases_SPD_PolicyEntry) Reset() { func (m *SecurityPolicyDatabases_SPD_PolicyEntry) String() string { return proto.CompactTextString(m) } func (*SecurityPolicyDatabases_SPD_PolicyEntry) ProtoMessage() {} func (*SecurityPolicyDatabases_SPD_PolicyEntry) Descriptor() ([]byte, []int) { - return fileDescriptorIpsec, []int{1, 0, 1} + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{1, 0, 1} +} +func (m *SecurityPolicyDatabases_SPD_PolicyEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SecurityPolicyDatabases_SPD_PolicyEntry.Unmarshal(m, b) +} +func (m *SecurityPolicyDatabases_SPD_PolicyEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SecurityPolicyDatabases_SPD_PolicyEntry.Marshal(b, m, deterministic) +} +func (dst *SecurityPolicyDatabases_SPD_PolicyEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_SecurityPolicyDatabases_SPD_PolicyEntry.Merge(dst, src) +} +func (m *SecurityPolicyDatabases_SPD_PolicyEntry) XXX_Size() int { + return xxx_messageInfo_SecurityPolicyDatabases_SPD_PolicyEntry.Size(m) +} +func (m *SecurityPolicyDatabases_SPD_PolicyEntry) XXX_DiscardUnknown() { + xxx_messageInfo_SecurityPolicyDatabases_SPD_PolicyEntry.DiscardUnknown(m) } +var xxx_messageInfo_SecurityPolicyDatabases_SPD_PolicyEntry proto.InternalMessageInfo + func (m *SecurityPolicyDatabases_SPD_PolicyEntry) GetSa() string { if m != nil { return m.Sa @@ -490,13 +608,35 @@ func (m *SecurityPolicyDatabases_SPD_PolicyEntry) GetAction() SecurityPolicyData // Security Association (SA) type SecurityAssociations struct { - Sas []*SecurityAssociations_SA `protobuf:"bytes,1,rep,name=sas" json:"sas,omitempty"` + Sas []*SecurityAssociations_SA `protobuf:"bytes,1,rep,name=sas" json:"sas,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SecurityAssociations) Reset() { *m = SecurityAssociations{} } +func (m *SecurityAssociations) String() string { return proto.CompactTextString(m) } +func (*SecurityAssociations) ProtoMessage() {} +func (*SecurityAssociations) Descriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{2} +} +func (m *SecurityAssociations) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SecurityAssociations.Unmarshal(m, b) +} +func (m *SecurityAssociations) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SecurityAssociations.Marshal(b, m, deterministic) +} +func (dst *SecurityAssociations) XXX_Merge(src proto.Message) { + xxx_messageInfo_SecurityAssociations.Merge(dst, src) +} +func (m *SecurityAssociations) XXX_Size() int { + return xxx_messageInfo_SecurityAssociations.Size(m) +} +func (m *SecurityAssociations) XXX_DiscardUnknown() { + xxx_messageInfo_SecurityAssociations.DiscardUnknown(m) } -func (m *SecurityAssociations) Reset() { *m = SecurityAssociations{} } -func (m *SecurityAssociations) String() string { return proto.CompactTextString(m) } -func (*SecurityAssociations) ProtoMessage() {} -func (*SecurityAssociations) Descriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{2} } +var xxx_messageInfo_SecurityAssociations proto.InternalMessageInfo func (m *SecurityAssociations) GetSas() []*SecurityAssociations_SA { if m != nil { @@ -506,24 +646,46 @@ func (m *SecurityAssociations) GetSas() []*SecurityAssociations_SA { } type SecurityAssociations_SA struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Spi uint32 `protobuf:"varint,2,opt,name=spi,proto3" json:"spi,omitempty"` - Protocol SecurityAssociations_SA_IPSecProtocol `protobuf:"varint,3,opt,name=protocol,proto3,enum=ipsec.SecurityAssociations_SA_IPSecProtocol" json:"protocol,omitempty"` - CryptoAlg CryptoAlgorithm `protobuf:"varint,4,opt,name=crypto_alg,json=cryptoAlg,proto3,enum=ipsec.CryptoAlgorithm" json:"crypto_alg,omitempty"` - CryptoKey string `protobuf:"bytes,5,opt,name=crypto_key,json=cryptoKey,proto3" json:"crypto_key,omitempty"` - IntegAlg IntegAlgorithm `protobuf:"varint,6,opt,name=integ_alg,json=integAlg,proto3,enum=ipsec.IntegAlgorithm" json:"integ_alg,omitempty"` - IntegKey string `protobuf:"bytes,7,opt,name=integ_key,json=integKey,proto3" json:"integ_key,omitempty"` - UseEsn bool `protobuf:"varint,8,opt,name=use_esn,json=useEsn,proto3" json:"use_esn,omitempty"` - UseAntiReplay bool `protobuf:"varint,9,opt,name=use_anti_replay,json=useAntiReplay,proto3" json:"use_anti_replay,omitempty"` - TunnelSrcAddr string `protobuf:"bytes,10,opt,name=tunnel_src_addr,json=tunnelSrcAddr,proto3" json:"tunnel_src_addr,omitempty"` - TunnelDstAddr string `protobuf:"bytes,11,opt,name=tunnel_dst_addr,json=tunnelDstAddr,proto3" json:"tunnel_dst_addr,omitempty"` - EnableUdpEncap bool `protobuf:"varint,12,opt,name=enable_udp_encap,json=enableUdpEncap,proto3" json:"enable_udp_encap,omitempty"` -} - -func (m *SecurityAssociations_SA) Reset() { *m = SecurityAssociations_SA{} } -func (m *SecurityAssociations_SA) String() string { return proto.CompactTextString(m) } -func (*SecurityAssociations_SA) ProtoMessage() {} -func (*SecurityAssociations_SA) Descriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{2, 0} } + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Spi uint32 `protobuf:"varint,2,opt,name=spi,proto3" json:"spi,omitempty"` + Protocol SecurityAssociations_SA_IPSecProtocol `protobuf:"varint,3,opt,name=protocol,proto3,enum=ipsec.SecurityAssociations_SA_IPSecProtocol" json:"protocol,omitempty"` + CryptoAlg CryptoAlgorithm `protobuf:"varint,4,opt,name=crypto_alg,json=cryptoAlg,proto3,enum=ipsec.CryptoAlgorithm" json:"crypto_alg,omitempty"` + CryptoKey string `protobuf:"bytes,5,opt,name=crypto_key,json=cryptoKey,proto3" json:"crypto_key,omitempty"` + IntegAlg IntegAlgorithm `protobuf:"varint,6,opt,name=integ_alg,json=integAlg,proto3,enum=ipsec.IntegAlgorithm" json:"integ_alg,omitempty"` + IntegKey string `protobuf:"bytes,7,opt,name=integ_key,json=integKey,proto3" json:"integ_key,omitempty"` + UseEsn bool `protobuf:"varint,8,opt,name=use_esn,json=useEsn,proto3" json:"use_esn,omitempty"` + UseAntiReplay bool `protobuf:"varint,9,opt,name=use_anti_replay,json=useAntiReplay,proto3" json:"use_anti_replay,omitempty"` + TunnelSrcAddr string `protobuf:"bytes,10,opt,name=tunnel_src_addr,json=tunnelSrcAddr,proto3" json:"tunnel_src_addr,omitempty"` + TunnelDstAddr string `protobuf:"bytes,11,opt,name=tunnel_dst_addr,json=tunnelDstAddr,proto3" json:"tunnel_dst_addr,omitempty"` + EnableUdpEncap bool `protobuf:"varint,12,opt,name=enable_udp_encap,json=enableUdpEncap,proto3" json:"enable_udp_encap,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SecurityAssociations_SA) Reset() { *m = SecurityAssociations_SA{} } +func (m *SecurityAssociations_SA) String() string { return proto.CompactTextString(m) } +func (*SecurityAssociations_SA) ProtoMessage() {} +func (*SecurityAssociations_SA) Descriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{2, 0} +} +func (m *SecurityAssociations_SA) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SecurityAssociations_SA.Unmarshal(m, b) +} +func (m *SecurityAssociations_SA) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SecurityAssociations_SA.Marshal(b, m, deterministic) +} +func (dst *SecurityAssociations_SA) XXX_Merge(src proto.Message) { + xxx_messageInfo_SecurityAssociations_SA.Merge(dst, src) +} +func (m *SecurityAssociations_SA) XXX_Size() int { + return xxx_messageInfo_SecurityAssociations_SA.Size(m) +} +func (m *SecurityAssociations_SA) XXX_DiscardUnknown() { + xxx_messageInfo_SecurityAssociations_SA.DiscardUnknown(m) +} + +var xxx_messageInfo_SecurityAssociations_SA proto.InternalMessageInfo func (m *SecurityAssociations_SA) GetName() string { if m != nil { @@ -610,15 +772,37 @@ func (m *SecurityAssociations_SA) GetEnableUdpEncap() bool { } type ResyncRequest struct { - Tunnels []*TunnelInterfaces_Tunnel `protobuf:"bytes,1,rep,name=tunnels" json:"tunnels,omitempty"` - Spds []*SecurityPolicyDatabases_SPD `protobuf:"bytes,2,rep,name=spds" json:"spds,omitempty"` - Sas []*SecurityAssociations_SA `protobuf:"bytes,3,rep,name=sas" json:"sas,omitempty"` + Tunnels []*TunnelInterfaces_Tunnel `protobuf:"bytes,1,rep,name=tunnels" json:"tunnels,omitempty"` + Spds []*SecurityPolicyDatabases_SPD `protobuf:"bytes,2,rep,name=spds" json:"spds,omitempty"` + Sas []*SecurityAssociations_SA `protobuf:"bytes,3,rep,name=sas" json:"sas,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ResyncRequest) Reset() { *m = ResyncRequest{} } +func (m *ResyncRequest) String() string { return proto.CompactTextString(m) } +func (*ResyncRequest) ProtoMessage() {} +func (*ResyncRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ipsec_d451fe8770ade8e1, []int{3} +} +func (m *ResyncRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ResyncRequest.Unmarshal(m, b) +} +func (m *ResyncRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ResyncRequest.Marshal(b, m, deterministic) +} +func (dst *ResyncRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResyncRequest.Merge(dst, src) +} +func (m *ResyncRequest) XXX_Size() int { + return xxx_messageInfo_ResyncRequest.Size(m) +} +func (m *ResyncRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ResyncRequest.DiscardUnknown(m) } -func (m *ResyncRequest) Reset() { *m = ResyncRequest{} } -func (m *ResyncRequest) String() string { return proto.CompactTextString(m) } -func (*ResyncRequest) ProtoMessage() {} -func (*ResyncRequest) Descriptor() ([]byte, []int) { return fileDescriptorIpsec, []int{3} } +var xxx_messageInfo_ResyncRequest proto.InternalMessageInfo func (m *ResyncRequest) GetTunnels() []*TunnelInterfaces_Tunnel { if m != nil { @@ -657,9 +841,9 @@ func init() { proto.RegisterEnum("ipsec.SecurityAssociations_SA_IPSecProtocol", SecurityAssociations_SA_IPSecProtocol_name, SecurityAssociations_SA_IPSecProtocol_value) } -func init() { proto.RegisterFile("ipsec.proto", fileDescriptorIpsec) } +func init() { proto.RegisterFile("ipsec.proto", fileDescriptor_ipsec_d451fe8770ade8e1) } -var fileDescriptorIpsec = []byte{ +var fileDescriptor_ipsec_d451fe8770ade8e1 = []byte{ // 1058 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0xe3, 0x44, 0x14, 0x6e, 0xe2, 0xd4, 0x49, 0x4e, 0xea, 0xd4, 0x8c, 0x80, 0x35, 0x59, 0x2d, 0x1b, 0x72, 0xb1, diff --git a/plugins/vpp/model/l2/l2.pb.go b/plugins/vpp/model/l2/l2.pb.go index 5cf3c75880..c03f225343 100644 --- a/plugins/vpp/model/l2/l2.pb.go +++ b/plugins/vpp/model/l2/l2.pb.go @@ -1,19 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: l2.proto -/* -Package l2 is a generated protocol buffer package. - -It is generated from these files: - l2.proto - -It has these top-level messages: - BridgeDomains - FibTable - XConnectPairs - BridgeDomainState - BridgeDomainErrors -*/ package l2 import proto "github.com/gogo/protobuf/proto" @@ -51,17 +38,39 @@ func (x FibTable_FibEntry_Action) String() string { return proto.EnumName(FibTable_FibEntry_Action_name, int32(x)) } func (FibTable_FibEntry_Action) EnumDescriptor() ([]byte, []int) { - return fileDescriptorL2, []int{1, 0, 0} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{1, 0, 0} } type BridgeDomains struct { - BridgeDomains []*BridgeDomains_BridgeDomain `protobuf:"bytes,1,rep,name=bridge_domains,json=bridgeDomains" json:"bridge_domains,omitempty"` + BridgeDomains []*BridgeDomains_BridgeDomain `protobuf:"bytes,1,rep,name=bridge_domains,json=bridgeDomains" json:"bridge_domains,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *BridgeDomains) Reset() { *m = BridgeDomains{} } -func (m *BridgeDomains) String() string { return proto.CompactTextString(m) } -func (*BridgeDomains) ProtoMessage() {} -func (*BridgeDomains) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{0} } +func (m *BridgeDomains) Reset() { *m = BridgeDomains{} } +func (m *BridgeDomains) String() string { return proto.CompactTextString(m) } +func (*BridgeDomains) ProtoMessage() {} +func (*BridgeDomains) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{0} +} +func (m *BridgeDomains) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomains.Unmarshal(m, b) +} +func (m *BridgeDomains) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomains.Marshal(b, m, deterministic) +} +func (dst *BridgeDomains) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomains.Merge(dst, src) +} +func (m *BridgeDomains) XXX_Size() int { + return xxx_messageInfo_BridgeDomains.Size(m) +} +func (m *BridgeDomains) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomains.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomains proto.InternalMessageInfo func (m *BridgeDomains) GetBridgeDomains() []*BridgeDomains_BridgeDomain { if m != nil { @@ -71,21 +80,43 @@ func (m *BridgeDomains) GetBridgeDomains() []*BridgeDomains_BridgeDomain { } type BridgeDomains_BridgeDomain struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Flood bool `protobuf:"varint,2,opt,name=flood,proto3" json:"flood,omitempty"` - UnknownUnicastFlood bool `protobuf:"varint,3,opt,name=unknown_unicast_flood,json=unknownUnicastFlood,proto3" json:"unknown_unicast_flood,omitempty"` - Forward bool `protobuf:"varint,4,opt,name=forward,proto3" json:"forward,omitempty"` - Learn bool `protobuf:"varint,5,opt,name=learn,proto3" json:"learn,omitempty"` - ArpTermination bool `protobuf:"varint,6,opt,name=arp_termination,json=arpTermination,proto3" json:"arp_termination,omitempty"` - MacAge uint32 `protobuf:"varint,7,opt,name=mac_age,json=macAge,proto3" json:"mac_age,omitempty"` - Interfaces []*BridgeDomains_BridgeDomain_Interfaces `protobuf:"bytes,100,rep,name=interfaces" json:"interfaces,omitempty"` - ArpTerminationTable []*BridgeDomains_BridgeDomain_ArpTerminationEntry `protobuf:"bytes,102,rep,name=arp_termination_table,json=arpTerminationTable" json:"arp_termination_table,omitempty"` -} - -func (m *BridgeDomains_BridgeDomain) Reset() { *m = BridgeDomains_BridgeDomain{} } -func (m *BridgeDomains_BridgeDomain) String() string { return proto.CompactTextString(m) } -func (*BridgeDomains_BridgeDomain) ProtoMessage() {} -func (*BridgeDomains_BridgeDomain) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{0, 0} } + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Flood bool `protobuf:"varint,2,opt,name=flood,proto3" json:"flood,omitempty"` + UnknownUnicastFlood bool `protobuf:"varint,3,opt,name=unknown_unicast_flood,json=unknownUnicastFlood,proto3" json:"unknown_unicast_flood,omitempty"` + Forward bool `protobuf:"varint,4,opt,name=forward,proto3" json:"forward,omitempty"` + Learn bool `protobuf:"varint,5,opt,name=learn,proto3" json:"learn,omitempty"` + ArpTermination bool `protobuf:"varint,6,opt,name=arp_termination,json=arpTermination,proto3" json:"arp_termination,omitempty"` + MacAge uint32 `protobuf:"varint,7,opt,name=mac_age,json=macAge,proto3" json:"mac_age,omitempty"` + Interfaces []*BridgeDomains_BridgeDomain_Interfaces `protobuf:"bytes,100,rep,name=interfaces" json:"interfaces,omitempty"` + ArpTerminationTable []*BridgeDomains_BridgeDomain_ArpTerminationEntry `protobuf:"bytes,102,rep,name=arp_termination_table,json=arpTerminationTable" json:"arp_termination_table,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BridgeDomains_BridgeDomain) Reset() { *m = BridgeDomains_BridgeDomain{} } +func (m *BridgeDomains_BridgeDomain) String() string { return proto.CompactTextString(m) } +func (*BridgeDomains_BridgeDomain) ProtoMessage() {} +func (*BridgeDomains_BridgeDomain) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{0, 0} +} +func (m *BridgeDomains_BridgeDomain) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomains_BridgeDomain.Unmarshal(m, b) +} +func (m *BridgeDomains_BridgeDomain) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomains_BridgeDomain.Marshal(b, m, deterministic) +} +func (dst *BridgeDomains_BridgeDomain) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomains_BridgeDomain.Merge(dst, src) +} +func (m *BridgeDomains_BridgeDomain) XXX_Size() int { + return xxx_messageInfo_BridgeDomains_BridgeDomain.Size(m) +} +func (m *BridgeDomains_BridgeDomain) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomains_BridgeDomain.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomains_BridgeDomain proto.InternalMessageInfo func (m *BridgeDomains_BridgeDomain) GetName() string { if m != nil { @@ -151,17 +182,37 @@ func (m *BridgeDomains_BridgeDomain) GetArpTerminationTable() []*BridgeDomains_B } type BridgeDomains_BridgeDomain_Interfaces struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - BridgedVirtualInterface bool `protobuf:"varint,2,opt,name=bridged_virtual_interface,json=bridgedVirtualInterface,proto3" json:"bridged_virtual_interface,omitempty"` - SplitHorizonGroup uint32 `protobuf:"varint,3,opt,name=split_horizon_group,json=splitHorizonGroup,proto3" json:"split_horizon_group,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + BridgedVirtualInterface bool `protobuf:"varint,2,opt,name=bridged_virtual_interface,json=bridgedVirtualInterface,proto3" json:"bridged_virtual_interface,omitempty"` + SplitHorizonGroup uint32 `protobuf:"varint,3,opt,name=split_horizon_group,json=splitHorizonGroup,proto3" json:"split_horizon_group,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BridgeDomains_BridgeDomain_Interfaces) Reset() { *m = BridgeDomains_BridgeDomain_Interfaces{} } func (m *BridgeDomains_BridgeDomain_Interfaces) String() string { return proto.CompactTextString(m) } func (*BridgeDomains_BridgeDomain_Interfaces) ProtoMessage() {} func (*BridgeDomains_BridgeDomain_Interfaces) Descriptor() ([]byte, []int) { - return fileDescriptorL2, []int{0, 0, 0} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{0, 0, 0} +} +func (m *BridgeDomains_BridgeDomain_Interfaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomains_BridgeDomain_Interfaces.Unmarshal(m, b) +} +func (m *BridgeDomains_BridgeDomain_Interfaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomains_BridgeDomain_Interfaces.Marshal(b, m, deterministic) +} +func (dst *BridgeDomains_BridgeDomain_Interfaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomains_BridgeDomain_Interfaces.Merge(dst, src) } +func (m *BridgeDomains_BridgeDomain_Interfaces) XXX_Size() int { + return xxx_messageInfo_BridgeDomains_BridgeDomain_Interfaces.Size(m) +} +func (m *BridgeDomains_BridgeDomain_Interfaces) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomains_BridgeDomain_Interfaces.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomains_BridgeDomain_Interfaces proto.InternalMessageInfo func (m *BridgeDomains_BridgeDomain_Interfaces) GetName() string { if m != nil { @@ -185,8 +236,11 @@ func (m *BridgeDomains_BridgeDomain_Interfaces) GetSplitHorizonGroup() uint32 { } type BridgeDomains_BridgeDomain_ArpTerminationEntry struct { - IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - PhysAddress string `protobuf:"bytes,2,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` + IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + PhysAddress string `protobuf:"bytes,2,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) Reset() { @@ -197,9 +251,26 @@ func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) String() string { } func (*BridgeDomains_BridgeDomain_ArpTerminationEntry) ProtoMessage() {} func (*BridgeDomains_BridgeDomain_ArpTerminationEntry) Descriptor() ([]byte, []int) { - return fileDescriptorL2, []int{0, 0, 1} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{0, 0, 1} +} +func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomains_BridgeDomain_ArpTerminationEntry.Unmarshal(m, b) +} +func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomains_BridgeDomain_ArpTerminationEntry.Marshal(b, m, deterministic) +} +func (dst *BridgeDomains_BridgeDomain_ArpTerminationEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomains_BridgeDomain_ArpTerminationEntry.Merge(dst, src) +} +func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) XXX_Size() int { + return xxx_messageInfo_BridgeDomains_BridgeDomain_ArpTerminationEntry.Size(m) +} +func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomains_BridgeDomain_ArpTerminationEntry.DiscardUnknown(m) } +var xxx_messageInfo_BridgeDomains_BridgeDomain_ArpTerminationEntry proto.InternalMessageInfo + func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) GetIpAddress() string { if m != nil { return m.IpAddress @@ -215,13 +286,35 @@ func (m *BridgeDomains_BridgeDomain_ArpTerminationEntry) GetPhysAddress() string } type FibTable struct { - FibTableEntries []*FibTable_FibEntry `protobuf:"bytes,100,rep,name=fib_table_entries,json=fibTableEntries" json:"fib_table_entries,omitempty"` + FibTableEntries []*FibTable_FibEntry `protobuf:"bytes,100,rep,name=fib_table_entries,json=fibTableEntries" json:"fib_table_entries,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *FibTable) Reset() { *m = FibTable{} } -func (m *FibTable) String() string { return proto.CompactTextString(m) } -func (*FibTable) ProtoMessage() {} -func (*FibTable) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{1} } +func (m *FibTable) Reset() { *m = FibTable{} } +func (m *FibTable) String() string { return proto.CompactTextString(m) } +func (*FibTable) ProtoMessage() {} +func (*FibTable) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{1} +} +func (m *FibTable) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FibTable.Unmarshal(m, b) +} +func (m *FibTable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FibTable.Marshal(b, m, deterministic) +} +func (dst *FibTable) XXX_Merge(src proto.Message) { + xxx_messageInfo_FibTable.Merge(dst, src) +} +func (m *FibTable) XXX_Size() int { + return xxx_messageInfo_FibTable.Size(m) +} +func (m *FibTable) XXX_DiscardUnknown() { + xxx_messageInfo_FibTable.DiscardUnknown(m) +} + +var xxx_messageInfo_FibTable proto.InternalMessageInfo func (m *FibTable) GetFibTableEntries() []*FibTable_FibEntry { if m != nil { @@ -237,12 +330,34 @@ type FibTable_FibEntry struct { OutgoingInterface string `protobuf:"bytes,4,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` StaticConfig bool `protobuf:"varint,5,opt,name=static_config,json=staticConfig,proto3" json:"static_config,omitempty"` BridgedVirtualInterface bool `protobuf:"varint,6,opt,name=bridged_virtual_interface,json=bridgedVirtualInterface,proto3" json:"bridged_virtual_interface,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *FibTable_FibEntry) Reset() { *m = FibTable_FibEntry{} } -func (m *FibTable_FibEntry) String() string { return proto.CompactTextString(m) } -func (*FibTable_FibEntry) ProtoMessage() {} -func (*FibTable_FibEntry) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{1, 0} } +func (m *FibTable_FibEntry) Reset() { *m = FibTable_FibEntry{} } +func (m *FibTable_FibEntry) String() string { return proto.CompactTextString(m) } +func (*FibTable_FibEntry) ProtoMessage() {} +func (*FibTable_FibEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{1, 0} +} +func (m *FibTable_FibEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FibTable_FibEntry.Unmarshal(m, b) +} +func (m *FibTable_FibEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FibTable_FibEntry.Marshal(b, m, deterministic) +} +func (dst *FibTable_FibEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_FibTable_FibEntry.Merge(dst, src) +} +func (m *FibTable_FibEntry) XXX_Size() int { + return xxx_messageInfo_FibTable_FibEntry.Size(m) +} +func (m *FibTable_FibEntry) XXX_DiscardUnknown() { + xxx_messageInfo_FibTable_FibEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_FibTable_FibEntry proto.InternalMessageInfo func (m *FibTable_FibEntry) GetPhysAddress() string { if m != nil { @@ -287,13 +402,35 @@ func (m *FibTable_FibEntry) GetBridgedVirtualInterface() bool { } type XConnectPairs struct { - XConnectPairs []*XConnectPairs_XConnectPair `protobuf:"bytes,100,rep,name=x_connect_pairs,json=xConnectPairs" json:"x_connect_pairs,omitempty"` + XConnectPairs []*XConnectPairs_XConnectPair `protobuf:"bytes,100,rep,name=x_connect_pairs,json=xConnectPairs" json:"x_connect_pairs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *XConnectPairs) Reset() { *m = XConnectPairs{} } +func (m *XConnectPairs) String() string { return proto.CompactTextString(m) } +func (*XConnectPairs) ProtoMessage() {} +func (*XConnectPairs) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{2} +} +func (m *XConnectPairs) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_XConnectPairs.Unmarshal(m, b) +} +func (m *XConnectPairs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_XConnectPairs.Marshal(b, m, deterministic) +} +func (dst *XConnectPairs) XXX_Merge(src proto.Message) { + xxx_messageInfo_XConnectPairs.Merge(dst, src) +} +func (m *XConnectPairs) XXX_Size() int { + return xxx_messageInfo_XConnectPairs.Size(m) +} +func (m *XConnectPairs) XXX_DiscardUnknown() { + xxx_messageInfo_XConnectPairs.DiscardUnknown(m) } -func (m *XConnectPairs) Reset() { *m = XConnectPairs{} } -func (m *XConnectPairs) String() string { return proto.CompactTextString(m) } -func (*XConnectPairs) ProtoMessage() {} -func (*XConnectPairs) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{2} } +var xxx_messageInfo_XConnectPairs proto.InternalMessageInfo func (m *XConnectPairs) GetXConnectPairs() []*XConnectPairs_XConnectPair { if m != nil { @@ -303,14 +440,36 @@ func (m *XConnectPairs) GetXConnectPairs() []*XConnectPairs_XConnectPair { } type XConnectPairs_XConnectPair struct { - ReceiveInterface string `protobuf:"bytes,2,opt,name=receive_interface,json=receiveInterface,proto3" json:"receive_interface,omitempty"` - TransmitInterface string `protobuf:"bytes,3,opt,name=transmit_interface,json=transmitInterface,proto3" json:"transmit_interface,omitempty"` + ReceiveInterface string `protobuf:"bytes,2,opt,name=receive_interface,json=receiveInterface,proto3" json:"receive_interface,omitempty"` + TransmitInterface string `protobuf:"bytes,3,opt,name=transmit_interface,json=transmitInterface,proto3" json:"transmit_interface,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *XConnectPairs_XConnectPair) Reset() { *m = XConnectPairs_XConnectPair{} } +func (m *XConnectPairs_XConnectPair) String() string { return proto.CompactTextString(m) } +func (*XConnectPairs_XConnectPair) ProtoMessage() {} +func (*XConnectPairs_XConnectPair) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{2, 0} +} +func (m *XConnectPairs_XConnectPair) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_XConnectPairs_XConnectPair.Unmarshal(m, b) +} +func (m *XConnectPairs_XConnectPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_XConnectPairs_XConnectPair.Marshal(b, m, deterministic) +} +func (dst *XConnectPairs_XConnectPair) XXX_Merge(src proto.Message) { + xxx_messageInfo_XConnectPairs_XConnectPair.Merge(dst, src) +} +func (m *XConnectPairs_XConnectPair) XXX_Size() int { + return xxx_messageInfo_XConnectPairs_XConnectPair.Size(m) +} +func (m *XConnectPairs_XConnectPair) XXX_DiscardUnknown() { + xxx_messageInfo_XConnectPairs_XConnectPair.DiscardUnknown(m) } -func (m *XConnectPairs_XConnectPair) Reset() { *m = XConnectPairs_XConnectPair{} } -func (m *XConnectPairs_XConnectPair) String() string { return proto.CompactTextString(m) } -func (*XConnectPairs_XConnectPair) ProtoMessage() {} -func (*XConnectPairs_XConnectPair) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{2, 0} } +var xxx_messageInfo_XConnectPairs_XConnectPair proto.InternalMessageInfo func (m *XConnectPairs_XConnectPair) GetReceiveInterface() string { if m != nil { @@ -327,13 +486,35 @@ func (m *XConnectPairs_XConnectPair) GetTransmitInterface() string { } type BridgeDomainState struct { - BridgeDomains []*BridgeDomainState_BridgeDomain `protobuf:"bytes,100,rep,name=bridge_domains,json=bridgeDomains" json:"bridge_domains,omitempty"` + BridgeDomains []*BridgeDomainState_BridgeDomain `protobuf:"bytes,100,rep,name=bridge_domains,json=bridgeDomains" json:"bridge_domains,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BridgeDomainState) Reset() { *m = BridgeDomainState{} } +func (m *BridgeDomainState) String() string { return proto.CompactTextString(m) } +func (*BridgeDomainState) ProtoMessage() {} +func (*BridgeDomainState) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{3} +} +func (m *BridgeDomainState) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomainState.Unmarshal(m, b) +} +func (m *BridgeDomainState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomainState.Marshal(b, m, deterministic) +} +func (dst *BridgeDomainState) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomainState.Merge(dst, src) +} +func (m *BridgeDomainState) XXX_Size() int { + return xxx_messageInfo_BridgeDomainState.Size(m) +} +func (m *BridgeDomainState) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomainState.DiscardUnknown(m) } -func (m *BridgeDomainState) Reset() { *m = BridgeDomainState{} } -func (m *BridgeDomainState) String() string { return proto.CompactTextString(m) } -func (*BridgeDomainState) ProtoMessage() {} -func (*BridgeDomainState) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{3} } +var xxx_messageInfo_BridgeDomainState proto.InternalMessageInfo func (m *BridgeDomainState) GetBridgeDomains() []*BridgeDomainState_BridgeDomain { if m != nil { @@ -343,22 +524,42 @@ func (m *BridgeDomainState) GetBridgeDomains() []*BridgeDomainState_BridgeDomain } type BridgeDomainState_BridgeDomain struct { - Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` - InternalName string `protobuf:"bytes,2,opt,name=internal_name,json=internalName,proto3" json:"internal_name,omitempty"` - BviInterface string `protobuf:"bytes,3,opt,name=bvi_interface,json=bviInterface,proto3" json:"bvi_interface,omitempty"` - BviInterfaceIndex uint32 `protobuf:"varint,4,opt,name=bvi_interface_index,json=bviInterfaceIndex,proto3" json:"bvi_interface_index,omitempty"` - InterfaceCount uint32 `protobuf:"varint,5,opt,name=interface_count,json=interfaceCount,proto3" json:"interface_count,omitempty"` - LastChange int64 `protobuf:"varint,6,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` - L2Params *BridgeDomainState_BridgeDomain_L2Params `protobuf:"bytes,100,opt,name=l2_params,json=l2Params" json:"l2_params,omitempty"` - Interfaces []*BridgeDomainState_BridgeDomain_Interfaces `protobuf:"bytes,101,rep,name=interfaces" json:"interfaces,omitempty"` + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + InternalName string `protobuf:"bytes,2,opt,name=internal_name,json=internalName,proto3" json:"internal_name,omitempty"` + BviInterface string `protobuf:"bytes,3,opt,name=bvi_interface,json=bviInterface,proto3" json:"bvi_interface,omitempty"` + BviInterfaceIndex uint32 `protobuf:"varint,4,opt,name=bvi_interface_index,json=bviInterfaceIndex,proto3" json:"bvi_interface_index,omitempty"` + InterfaceCount uint32 `protobuf:"varint,5,opt,name=interface_count,json=interfaceCount,proto3" json:"interface_count,omitempty"` + LastChange int64 `protobuf:"varint,6,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` + L2Params *BridgeDomainState_BridgeDomain_L2Params `protobuf:"bytes,100,opt,name=l2_params,json=l2Params" json:"l2_params,omitempty"` + Interfaces []*BridgeDomainState_BridgeDomain_Interfaces `protobuf:"bytes,101,rep,name=interfaces" json:"interfaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BridgeDomainState_BridgeDomain) Reset() { *m = BridgeDomainState_BridgeDomain{} } func (m *BridgeDomainState_BridgeDomain) String() string { return proto.CompactTextString(m) } func (*BridgeDomainState_BridgeDomain) ProtoMessage() {} func (*BridgeDomainState_BridgeDomain) Descriptor() ([]byte, []int) { - return fileDescriptorL2, []int{3, 0} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{3, 0} } +func (m *BridgeDomainState_BridgeDomain) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomainState_BridgeDomain.Unmarshal(m, b) +} +func (m *BridgeDomainState_BridgeDomain) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomainState_BridgeDomain.Marshal(b, m, deterministic) +} +func (dst *BridgeDomainState_BridgeDomain) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomainState_BridgeDomain.Merge(dst, src) +} +func (m *BridgeDomainState_BridgeDomain) XXX_Size() int { + return xxx_messageInfo_BridgeDomainState_BridgeDomain.Size(m) +} +func (m *BridgeDomainState_BridgeDomain) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomainState_BridgeDomain.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomainState_BridgeDomain proto.InternalMessageInfo func (m *BridgeDomainState_BridgeDomain) GetIndex() uint32 { if m != nil { @@ -417,12 +618,15 @@ func (m *BridgeDomainState_BridgeDomain) GetInterfaces() []*BridgeDomainState_Br } type BridgeDomainState_BridgeDomain_L2Params struct { - Flood bool `protobuf:"varint,1,opt,name=flood,proto3" json:"flood,omitempty"` - UnknownUnicastFlood bool `protobuf:"varint,2,opt,name=unknown_unicast_flood,json=unknownUnicastFlood,proto3" json:"unknown_unicast_flood,omitempty"` - Forward bool `protobuf:"varint,3,opt,name=forward,proto3" json:"forward,omitempty"` - Learn bool `protobuf:"varint,4,opt,name=learn,proto3" json:"learn,omitempty"` - ArpTermination bool `protobuf:"varint,5,opt,name=arp_termination,json=arpTermination,proto3" json:"arp_termination,omitempty"` - MacAge uint32 `protobuf:"varint,6,opt,name=mac_age,json=macAge,proto3" json:"mac_age,omitempty"` + Flood bool `protobuf:"varint,1,opt,name=flood,proto3" json:"flood,omitempty"` + UnknownUnicastFlood bool `protobuf:"varint,2,opt,name=unknown_unicast_flood,json=unknownUnicastFlood,proto3" json:"unknown_unicast_flood,omitempty"` + Forward bool `protobuf:"varint,3,opt,name=forward,proto3" json:"forward,omitempty"` + Learn bool `protobuf:"varint,4,opt,name=learn,proto3" json:"learn,omitempty"` + ArpTermination bool `protobuf:"varint,5,opt,name=arp_termination,json=arpTermination,proto3" json:"arp_termination,omitempty"` + MacAge uint32 `protobuf:"varint,6,opt,name=mac_age,json=macAge,proto3" json:"mac_age,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BridgeDomainState_BridgeDomain_L2Params) Reset() { @@ -431,8 +635,25 @@ func (m *BridgeDomainState_BridgeDomain_L2Params) Reset() { func (m *BridgeDomainState_BridgeDomain_L2Params) String() string { return proto.CompactTextString(m) } func (*BridgeDomainState_BridgeDomain_L2Params) ProtoMessage() {} func (*BridgeDomainState_BridgeDomain_L2Params) Descriptor() ([]byte, []int) { - return fileDescriptorL2, []int{3, 0, 0} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{3, 0, 0} } +func (m *BridgeDomainState_BridgeDomain_L2Params) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomainState_BridgeDomain_L2Params.Unmarshal(m, b) +} +func (m *BridgeDomainState_BridgeDomain_L2Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomainState_BridgeDomain_L2Params.Marshal(b, m, deterministic) +} +func (dst *BridgeDomainState_BridgeDomain_L2Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomainState_BridgeDomain_L2Params.Merge(dst, src) +} +func (m *BridgeDomainState_BridgeDomain_L2Params) XXX_Size() int { + return xxx_messageInfo_BridgeDomainState_BridgeDomain_L2Params.Size(m) +} +func (m *BridgeDomainState_BridgeDomain_L2Params) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomainState_BridgeDomain_L2Params.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomainState_BridgeDomain_L2Params proto.InternalMessageInfo func (m *BridgeDomainState_BridgeDomain_L2Params) GetFlood() bool { if m != nil { @@ -477,9 +698,12 @@ func (m *BridgeDomainState_BridgeDomain_L2Params) GetMacAge() uint32 { } type BridgeDomainState_BridgeDomain_Interfaces struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - SwIfIndex uint32 `protobuf:"varint,2,opt,name=sw_if_index,json=swIfIndex,proto3" json:"sw_if_index,omitempty"` - SplitHorizonGroup uint32 `protobuf:"varint,3,opt,name=split_horizon_group,json=splitHorizonGroup,proto3" json:"split_horizon_group,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + SwIfIndex uint32 `protobuf:"varint,2,opt,name=sw_if_index,json=swIfIndex,proto3" json:"sw_if_index,omitempty"` + SplitHorizonGroup uint32 `protobuf:"varint,3,opt,name=split_horizon_group,json=splitHorizonGroup,proto3" json:"split_horizon_group,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BridgeDomainState_BridgeDomain_Interfaces) Reset() { @@ -488,8 +712,25 @@ func (m *BridgeDomainState_BridgeDomain_Interfaces) Reset() { func (m *BridgeDomainState_BridgeDomain_Interfaces) String() string { return proto.CompactTextString(m) } func (*BridgeDomainState_BridgeDomain_Interfaces) ProtoMessage() {} func (*BridgeDomainState_BridgeDomain_Interfaces) Descriptor() ([]byte, []int) { - return fileDescriptorL2, []int{3, 0, 1} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{3, 0, 1} } +func (m *BridgeDomainState_BridgeDomain_Interfaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomainState_BridgeDomain_Interfaces.Unmarshal(m, b) +} +func (m *BridgeDomainState_BridgeDomain_Interfaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomainState_BridgeDomain_Interfaces.Marshal(b, m, deterministic) +} +func (dst *BridgeDomainState_BridgeDomain_Interfaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomainState_BridgeDomain_Interfaces.Merge(dst, src) +} +func (m *BridgeDomainState_BridgeDomain_Interfaces) XXX_Size() int { + return xxx_messageInfo_BridgeDomainState_BridgeDomain_Interfaces.Size(m) +} +func (m *BridgeDomainState_BridgeDomain_Interfaces) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomainState_BridgeDomain_Interfaces.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomainState_BridgeDomain_Interfaces proto.InternalMessageInfo func (m *BridgeDomainState_BridgeDomain_Interfaces) GetName() string { if m != nil { @@ -513,13 +754,35 @@ func (m *BridgeDomainState_BridgeDomain_Interfaces) GetSplitHorizonGroup() uint3 } type BridgeDomainErrors struct { - BridgeDomain []*BridgeDomainErrors_BridgeDomain `protobuf:"bytes,1,rep,name=bridge_domain,json=bridgeDomain" json:"bridge_domain,omitempty"` + BridgeDomain []*BridgeDomainErrors_BridgeDomain `protobuf:"bytes,1,rep,name=bridge_domain,json=bridgeDomain" json:"bridge_domain,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BridgeDomainErrors) Reset() { *m = BridgeDomainErrors{} } +func (m *BridgeDomainErrors) String() string { return proto.CompactTextString(m) } +func (*BridgeDomainErrors) ProtoMessage() {} +func (*BridgeDomainErrors) Descriptor() ([]byte, []int) { + return fileDescriptor_l2_4bbbea60c5faa02d, []int{4} +} +func (m *BridgeDomainErrors) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomainErrors.Unmarshal(m, b) +} +func (m *BridgeDomainErrors) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomainErrors.Marshal(b, m, deterministic) +} +func (dst *BridgeDomainErrors) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomainErrors.Merge(dst, src) +} +func (m *BridgeDomainErrors) XXX_Size() int { + return xxx_messageInfo_BridgeDomainErrors.Size(m) +} +func (m *BridgeDomainErrors) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomainErrors.DiscardUnknown(m) } -func (m *BridgeDomainErrors) Reset() { *m = BridgeDomainErrors{} } -func (m *BridgeDomainErrors) String() string { return proto.CompactTextString(m) } -func (*BridgeDomainErrors) ProtoMessage() {} -func (*BridgeDomainErrors) Descriptor() ([]byte, []int) { return fileDescriptorL2, []int{4} } +var xxx_messageInfo_BridgeDomainErrors proto.InternalMessageInfo func (m *BridgeDomainErrors) GetBridgeDomain() []*BridgeDomainErrors_BridgeDomain { if m != nil { @@ -529,16 +792,36 @@ func (m *BridgeDomainErrors) GetBridgeDomain() []*BridgeDomainErrors_BridgeDomai } type BridgeDomainErrors_BridgeDomain struct { - BdName string `protobuf:"bytes,1,opt,name=bd_name,json=bdName,proto3" json:"bd_name,omitempty"` - ErrorData []*BridgeDomainErrors_BridgeDomain_ErrorData `protobuf:"bytes,2,rep,name=error_data,json=errorData" json:"error_data,omitempty"` + BdName string `protobuf:"bytes,1,opt,name=bd_name,json=bdName,proto3" json:"bd_name,omitempty"` + ErrorData []*BridgeDomainErrors_BridgeDomain_ErrorData `protobuf:"bytes,2,rep,name=error_data,json=errorData" json:"error_data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BridgeDomainErrors_BridgeDomain) Reset() { *m = BridgeDomainErrors_BridgeDomain{} } func (m *BridgeDomainErrors_BridgeDomain) String() string { return proto.CompactTextString(m) } func (*BridgeDomainErrors_BridgeDomain) ProtoMessage() {} func (*BridgeDomainErrors_BridgeDomain) Descriptor() ([]byte, []int) { - return fileDescriptorL2, []int{4, 0} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{4, 0} } +func (m *BridgeDomainErrors_BridgeDomain) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomainErrors_BridgeDomain.Unmarshal(m, b) +} +func (m *BridgeDomainErrors_BridgeDomain) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomainErrors_BridgeDomain.Marshal(b, m, deterministic) +} +func (dst *BridgeDomainErrors_BridgeDomain) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomainErrors_BridgeDomain.Merge(dst, src) +} +func (m *BridgeDomainErrors_BridgeDomain) XXX_Size() int { + return xxx_messageInfo_BridgeDomainErrors_BridgeDomain.Size(m) +} +func (m *BridgeDomainErrors_BridgeDomain) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomainErrors_BridgeDomain.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomainErrors_BridgeDomain proto.InternalMessageInfo func (m *BridgeDomainErrors_BridgeDomain) GetBdName() string { if m != nil { @@ -555,9 +838,12 @@ func (m *BridgeDomainErrors_BridgeDomain) GetErrorData() []*BridgeDomainErrors_B } type BridgeDomainErrors_BridgeDomain_ErrorData struct { - ChangeType string `protobuf:"bytes,2,opt,name=change_type,json=changeType,proto3" json:"change_type,omitempty"` - ErrorMessage string `protobuf:"bytes,3,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` - LastChange int64 `protobuf:"varint,4,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` + ChangeType string `protobuf:"bytes,2,opt,name=change_type,json=changeType,proto3" json:"change_type,omitempty"` + ErrorMessage string `protobuf:"bytes,3,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + LastChange int64 `protobuf:"varint,4,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BridgeDomainErrors_BridgeDomain_ErrorData) Reset() { @@ -566,8 +852,25 @@ func (m *BridgeDomainErrors_BridgeDomain_ErrorData) Reset() { func (m *BridgeDomainErrors_BridgeDomain_ErrorData) String() string { return proto.CompactTextString(m) } func (*BridgeDomainErrors_BridgeDomain_ErrorData) ProtoMessage() {} func (*BridgeDomainErrors_BridgeDomain_ErrorData) Descriptor() ([]byte, []int) { - return fileDescriptorL2, []int{4, 0, 0} + return fileDescriptor_l2_4bbbea60c5faa02d, []int{4, 0, 0} } +func (m *BridgeDomainErrors_BridgeDomain_ErrorData) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BridgeDomainErrors_BridgeDomain_ErrorData.Unmarshal(m, b) +} +func (m *BridgeDomainErrors_BridgeDomain_ErrorData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BridgeDomainErrors_BridgeDomain_ErrorData.Marshal(b, m, deterministic) +} +func (dst *BridgeDomainErrors_BridgeDomain_ErrorData) XXX_Merge(src proto.Message) { + xxx_messageInfo_BridgeDomainErrors_BridgeDomain_ErrorData.Merge(dst, src) +} +func (m *BridgeDomainErrors_BridgeDomain_ErrorData) XXX_Size() int { + return xxx_messageInfo_BridgeDomainErrors_BridgeDomain_ErrorData.Size(m) +} +func (m *BridgeDomainErrors_BridgeDomain_ErrorData) XXX_DiscardUnknown() { + xxx_messageInfo_BridgeDomainErrors_BridgeDomain_ErrorData.DiscardUnknown(m) +} + +var xxx_messageInfo_BridgeDomainErrors_BridgeDomain_ErrorData proto.InternalMessageInfo func (m *BridgeDomainErrors_BridgeDomain_ErrorData) GetChangeType() string { if m != nil { @@ -609,9 +912,9 @@ func init() { proto.RegisterEnum("l2.FibTable_FibEntry_Action", FibTable_FibEntry_Action_name, FibTable_FibEntry_Action_value) } -func init() { proto.RegisterFile("l2.proto", fileDescriptorL2) } +func init() { proto.RegisterFile("l2.proto", fileDescriptor_l2_4bbbea60c5faa02d) } -var fileDescriptorL2 = []byte{ +var fileDescriptor_l2_4bbbea60c5faa02d = []byte{ // 973 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcd, 0x72, 0xe3, 0x44, 0x10, 0x46, 0xfe, 0x77, 0xdb, 0x4a, 0xe2, 0xc9, 0xa6, 0x22, 0x5c, 0xb0, 0x1b, 0x9c, 0xc3, 0x9a, diff --git a/plugins/vpp/model/l3/l3.pb.go b/plugins/vpp/model/l3/l3.pb.go index 057b3c9960..3030831235 100644 --- a/plugins/vpp/model/l3/l3.pb.go +++ b/plugins/vpp/model/l3/l3.pb.go @@ -1,20 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: l3.proto -/* -Package l3 is a generated protocol buffer package. - -It is generated from these files: - l3.proto - -It has these top-level messages: - StaticRoutes - ArpTable - ProxyArpRanges - ProxyArpInterfaces - STNTable - IPScanNeighbor -*/ package l3 import proto "github.com/gogo/protobuf/proto" @@ -55,7 +41,7 @@ func (x StaticRoutes_Route_RouteType) String() string { return proto.EnumName(StaticRoutes_Route_RouteType_name, int32(x)) } func (StaticRoutes_Route_RouteType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorL3, []int{0, 0, 0} + return fileDescriptor_l3_3f0db3548c262ee3, []int{0, 0, 0} } type IPScanNeighbor_Mode int32 @@ -83,17 +69,41 @@ var IPScanNeighbor_Mode_value = map[string]int32{ func (x IPScanNeighbor_Mode) String() string { return proto.EnumName(IPScanNeighbor_Mode_name, int32(x)) } -func (IPScanNeighbor_Mode) EnumDescriptor() ([]byte, []int) { return fileDescriptorL3, []int{5, 0} } +func (IPScanNeighbor_Mode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{5, 0} +} // Static routes type StaticRoutes struct { - Routes []*StaticRoutes_Route `protobuf:"bytes,1,rep,name=routes" json:"routes,omitempty"` + Routes []*StaticRoutes_Route `protobuf:"bytes,1,rep,name=routes" json:"routes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StaticRoutes) Reset() { *m = StaticRoutes{} } +func (m *StaticRoutes) String() string { return proto.CompactTextString(m) } +func (*StaticRoutes) ProtoMessage() {} +func (*StaticRoutes) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{0} +} +func (m *StaticRoutes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StaticRoutes.Unmarshal(m, b) +} +func (m *StaticRoutes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StaticRoutes.Marshal(b, m, deterministic) +} +func (dst *StaticRoutes) XXX_Merge(src proto.Message) { + xxx_messageInfo_StaticRoutes.Merge(dst, src) +} +func (m *StaticRoutes) XXX_Size() int { + return xxx_messageInfo_StaticRoutes.Size(m) +} +func (m *StaticRoutes) XXX_DiscardUnknown() { + xxx_messageInfo_StaticRoutes.DiscardUnknown(m) } -func (m *StaticRoutes) Reset() { *m = StaticRoutes{} } -func (m *StaticRoutes) String() string { return proto.CompactTextString(m) } -func (*StaticRoutes) ProtoMessage() {} -func (*StaticRoutes) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{0} } +var xxx_messageInfo_StaticRoutes proto.InternalMessageInfo func (m *StaticRoutes) GetRoutes() []*StaticRoutes_Route { if m != nil { @@ -112,13 +122,35 @@ type StaticRoutes_Route struct { Weight uint32 `protobuf:"varint,6,opt,name=weight,proto3" json:"weight,omitempty"` Preference uint32 `protobuf:"varint,7,opt,name=preference,proto3" json:"preference,omitempty"` // (a poor man's primary and backup) - ViaVrfId uint32 `protobuf:"varint,8,opt,name=via_vrf_id,json=viaVrfId,proto3" json:"via_vrf_id,omitempty"` + ViaVrfId uint32 `protobuf:"varint,8,opt,name=via_vrf_id,json=viaVrfId,proto3" json:"via_vrf_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *StaticRoutes_Route) Reset() { *m = StaticRoutes_Route{} } -func (m *StaticRoutes_Route) String() string { return proto.CompactTextString(m) } -func (*StaticRoutes_Route) ProtoMessage() {} -func (*StaticRoutes_Route) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{0, 0} } +func (m *StaticRoutes_Route) Reset() { *m = StaticRoutes_Route{} } +func (m *StaticRoutes_Route) String() string { return proto.CompactTextString(m) } +func (*StaticRoutes_Route) ProtoMessage() {} +func (*StaticRoutes_Route) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{0, 0} +} +func (m *StaticRoutes_Route) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StaticRoutes_Route.Unmarshal(m, b) +} +func (m *StaticRoutes_Route) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StaticRoutes_Route.Marshal(b, m, deterministic) +} +func (dst *StaticRoutes_Route) XXX_Merge(src proto.Message) { + xxx_messageInfo_StaticRoutes_Route.Merge(dst, src) +} +func (m *StaticRoutes_Route) XXX_Size() int { + return xxx_messageInfo_StaticRoutes_Route.Size(m) +} +func (m *StaticRoutes_Route) XXX_DiscardUnknown() { + xxx_messageInfo_StaticRoutes_Route.DiscardUnknown(m) +} + +var xxx_messageInfo_StaticRoutes_Route proto.InternalMessageInfo func (m *StaticRoutes_Route) GetType() StaticRoutes_Route_RouteType { if m != nil { @@ -185,13 +217,35 @@ func (m *StaticRoutes_Route) GetViaVrfId() uint32 { // IP ARP entries type ArpTable struct { - ArpEntries []*ArpTable_ArpEntry `protobuf:"bytes,1,rep,name=arp_entries,json=arpEntries" json:"arp_entries,omitempty"` + ArpEntries []*ArpTable_ArpEntry `protobuf:"bytes,1,rep,name=arp_entries,json=arpEntries" json:"arp_entries,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *ArpTable) Reset() { *m = ArpTable{} } -func (m *ArpTable) String() string { return proto.CompactTextString(m) } -func (*ArpTable) ProtoMessage() {} -func (*ArpTable) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{1} } +func (m *ArpTable) Reset() { *m = ArpTable{} } +func (m *ArpTable) String() string { return proto.CompactTextString(m) } +func (*ArpTable) ProtoMessage() {} +func (*ArpTable) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{1} +} +func (m *ArpTable) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ArpTable.Unmarshal(m, b) +} +func (m *ArpTable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ArpTable.Marshal(b, m, deterministic) +} +func (dst *ArpTable) XXX_Merge(src proto.Message) { + xxx_messageInfo_ArpTable.Merge(dst, src) +} +func (m *ArpTable) XXX_Size() int { + return xxx_messageInfo_ArpTable.Size(m) +} +func (m *ArpTable) XXX_DiscardUnknown() { + xxx_messageInfo_ArpTable.DiscardUnknown(m) +} + +var xxx_messageInfo_ArpTable proto.InternalMessageInfo func (m *ArpTable) GetArpEntries() []*ArpTable_ArpEntry { if m != nil { @@ -201,16 +255,38 @@ func (m *ArpTable) GetArpEntries() []*ArpTable_ArpEntry { } type ArpTable_ArpEntry struct { - Interface string `protobuf:"bytes,1,opt,name=interface,proto3" json:"interface,omitempty"` - IpAddress string `protobuf:"bytes,2,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - PhysAddress string `protobuf:"bytes,3,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` - Static bool `protobuf:"varint,4,opt,name=static,proto3" json:"static,omitempty"` + Interface string `protobuf:"bytes,1,opt,name=interface,proto3" json:"interface,omitempty"` + IpAddress string `protobuf:"bytes,2,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + PhysAddress string `protobuf:"bytes,3,opt,name=phys_address,json=physAddress,proto3" json:"phys_address,omitempty"` + Static bool `protobuf:"varint,4,opt,name=static,proto3" json:"static,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *ArpTable_ArpEntry) Reset() { *m = ArpTable_ArpEntry{} } -func (m *ArpTable_ArpEntry) String() string { return proto.CompactTextString(m) } -func (*ArpTable_ArpEntry) ProtoMessage() {} -func (*ArpTable_ArpEntry) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{1, 0} } +func (m *ArpTable_ArpEntry) Reset() { *m = ArpTable_ArpEntry{} } +func (m *ArpTable_ArpEntry) String() string { return proto.CompactTextString(m) } +func (*ArpTable_ArpEntry) ProtoMessage() {} +func (*ArpTable_ArpEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{1, 0} +} +func (m *ArpTable_ArpEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ArpTable_ArpEntry.Unmarshal(m, b) +} +func (m *ArpTable_ArpEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ArpTable_ArpEntry.Marshal(b, m, deterministic) +} +func (dst *ArpTable_ArpEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_ArpTable_ArpEntry.Merge(dst, src) +} +func (m *ArpTable_ArpEntry) XXX_Size() int { + return xxx_messageInfo_ArpTable_ArpEntry.Size(m) +} +func (m *ArpTable_ArpEntry) XXX_DiscardUnknown() { + xxx_messageInfo_ArpTable_ArpEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_ArpTable_ArpEntry proto.InternalMessageInfo func (m *ArpTable_ArpEntry) GetInterface() string { if m != nil { @@ -242,13 +318,35 @@ func (m *ArpTable_ArpEntry) GetStatic() bool { // Proxy ARP ranges type ProxyArpRanges struct { - RangeLists []*ProxyArpRanges_RangeList `protobuf:"bytes,1,rep,name=range_lists,json=rangeLists" json:"range_lists,omitempty"` + RangeLists []*ProxyArpRanges_RangeList `protobuf:"bytes,1,rep,name=range_lists,json=rangeLists" json:"range_lists,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ProxyArpRanges) Reset() { *m = ProxyArpRanges{} } +func (m *ProxyArpRanges) String() string { return proto.CompactTextString(m) } +func (*ProxyArpRanges) ProtoMessage() {} +func (*ProxyArpRanges) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{2} +} +func (m *ProxyArpRanges) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProxyArpRanges.Unmarshal(m, b) +} +func (m *ProxyArpRanges) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProxyArpRanges.Marshal(b, m, deterministic) +} +func (dst *ProxyArpRanges) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProxyArpRanges.Merge(dst, src) +} +func (m *ProxyArpRanges) XXX_Size() int { + return xxx_messageInfo_ProxyArpRanges.Size(m) +} +func (m *ProxyArpRanges) XXX_DiscardUnknown() { + xxx_messageInfo_ProxyArpRanges.DiscardUnknown(m) } -func (m *ProxyArpRanges) Reset() { *m = ProxyArpRanges{} } -func (m *ProxyArpRanges) String() string { return proto.CompactTextString(m) } -func (*ProxyArpRanges) ProtoMessage() {} -func (*ProxyArpRanges) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{2} } +var xxx_messageInfo_ProxyArpRanges proto.InternalMessageInfo func (m *ProxyArpRanges) GetRangeLists() []*ProxyArpRanges_RangeList { if m != nil { @@ -258,14 +356,36 @@ func (m *ProxyArpRanges) GetRangeLists() []*ProxyArpRanges_RangeList { } type ProxyArpRanges_RangeList struct { - Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` - Ranges []*ProxyArpRanges_RangeList_Range `protobuf:"bytes,2,rep,name=ranges" json:"ranges,omitempty"` + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + Ranges []*ProxyArpRanges_RangeList_Range `protobuf:"bytes,2,rep,name=ranges" json:"ranges,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *ProxyArpRanges_RangeList) Reset() { *m = ProxyArpRanges_RangeList{} } -func (m *ProxyArpRanges_RangeList) String() string { return proto.CompactTextString(m) } -func (*ProxyArpRanges_RangeList) ProtoMessage() {} -func (*ProxyArpRanges_RangeList) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{2, 0} } +func (m *ProxyArpRanges_RangeList) Reset() { *m = ProxyArpRanges_RangeList{} } +func (m *ProxyArpRanges_RangeList) String() string { return proto.CompactTextString(m) } +func (*ProxyArpRanges_RangeList) ProtoMessage() {} +func (*ProxyArpRanges_RangeList) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{2, 0} +} +func (m *ProxyArpRanges_RangeList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProxyArpRanges_RangeList.Unmarshal(m, b) +} +func (m *ProxyArpRanges_RangeList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProxyArpRanges_RangeList.Marshal(b, m, deterministic) +} +func (dst *ProxyArpRanges_RangeList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProxyArpRanges_RangeList.Merge(dst, src) +} +func (m *ProxyArpRanges_RangeList) XXX_Size() int { + return xxx_messageInfo_ProxyArpRanges_RangeList.Size(m) +} +func (m *ProxyArpRanges_RangeList) XXX_DiscardUnknown() { + xxx_messageInfo_ProxyArpRanges_RangeList.DiscardUnknown(m) +} + +var xxx_messageInfo_ProxyArpRanges_RangeList proto.InternalMessageInfo func (m *ProxyArpRanges_RangeList) GetLabel() string { if m != nil { @@ -282,17 +402,37 @@ func (m *ProxyArpRanges_RangeList) GetRanges() []*ProxyArpRanges_RangeList_Range } type ProxyArpRanges_RangeList_Range struct { - FirstIp string `protobuf:"bytes,1,opt,name=first_ip,json=firstIp,proto3" json:"first_ip,omitempty"` - LastIp string `protobuf:"bytes,2,opt,name=last_ip,json=lastIp,proto3" json:"last_ip,omitempty"` + FirstIp string `protobuf:"bytes,1,opt,name=first_ip,json=firstIp,proto3" json:"first_ip,omitempty"` + LastIp string `protobuf:"bytes,2,opt,name=last_ip,json=lastIp,proto3" json:"last_ip,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ProxyArpRanges_RangeList_Range) Reset() { *m = ProxyArpRanges_RangeList_Range{} } func (m *ProxyArpRanges_RangeList_Range) String() string { return proto.CompactTextString(m) } func (*ProxyArpRanges_RangeList_Range) ProtoMessage() {} func (*ProxyArpRanges_RangeList_Range) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{2, 0, 0} + return fileDescriptor_l3_3f0db3548c262ee3, []int{2, 0, 0} +} +func (m *ProxyArpRanges_RangeList_Range) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProxyArpRanges_RangeList_Range.Unmarshal(m, b) +} +func (m *ProxyArpRanges_RangeList_Range) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProxyArpRanges_RangeList_Range.Marshal(b, m, deterministic) +} +func (dst *ProxyArpRanges_RangeList_Range) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProxyArpRanges_RangeList_Range.Merge(dst, src) +} +func (m *ProxyArpRanges_RangeList_Range) XXX_Size() int { + return xxx_messageInfo_ProxyArpRanges_RangeList_Range.Size(m) +} +func (m *ProxyArpRanges_RangeList_Range) XXX_DiscardUnknown() { + xxx_messageInfo_ProxyArpRanges_RangeList_Range.DiscardUnknown(m) } +var xxx_messageInfo_ProxyArpRanges_RangeList_Range proto.InternalMessageInfo + func (m *ProxyArpRanges_RangeList_Range) GetFirstIp() string { if m != nil { return m.FirstIp @@ -309,13 +449,35 @@ func (m *ProxyArpRanges_RangeList_Range) GetLastIp() string { // Proxy ARP interfaces type ProxyArpInterfaces struct { - InterfaceLists []*ProxyArpInterfaces_InterfaceList `protobuf:"bytes,1,rep,name=interface_lists,json=interfaceLists" json:"interface_lists,omitempty"` + InterfaceLists []*ProxyArpInterfaces_InterfaceList `protobuf:"bytes,1,rep,name=interface_lists,json=interfaceLists" json:"interface_lists,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ProxyArpInterfaces) Reset() { *m = ProxyArpInterfaces{} } +func (m *ProxyArpInterfaces) String() string { return proto.CompactTextString(m) } +func (*ProxyArpInterfaces) ProtoMessage() {} +func (*ProxyArpInterfaces) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{3} +} +func (m *ProxyArpInterfaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProxyArpInterfaces.Unmarshal(m, b) +} +func (m *ProxyArpInterfaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProxyArpInterfaces.Marshal(b, m, deterministic) +} +func (dst *ProxyArpInterfaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProxyArpInterfaces.Merge(dst, src) +} +func (m *ProxyArpInterfaces) XXX_Size() int { + return xxx_messageInfo_ProxyArpInterfaces.Size(m) +} +func (m *ProxyArpInterfaces) XXX_DiscardUnknown() { + xxx_messageInfo_ProxyArpInterfaces.DiscardUnknown(m) } -func (m *ProxyArpInterfaces) Reset() { *m = ProxyArpInterfaces{} } -func (m *ProxyArpInterfaces) String() string { return proto.CompactTextString(m) } -func (*ProxyArpInterfaces) ProtoMessage() {} -func (*ProxyArpInterfaces) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{3} } +var xxx_messageInfo_ProxyArpInterfaces proto.InternalMessageInfo func (m *ProxyArpInterfaces) GetInterfaceLists() []*ProxyArpInterfaces_InterfaceList { if m != nil { @@ -325,16 +487,36 @@ func (m *ProxyArpInterfaces) GetInterfaceLists() []*ProxyArpInterfaces_Interface } type ProxyArpInterfaces_InterfaceList struct { - Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` - Interfaces []*ProxyArpInterfaces_InterfaceList_Interface `protobuf:"bytes,2,rep,name=interfaces" json:"interfaces,omitempty"` + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + Interfaces []*ProxyArpInterfaces_InterfaceList_Interface `protobuf:"bytes,2,rep,name=interfaces" json:"interfaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ProxyArpInterfaces_InterfaceList) Reset() { *m = ProxyArpInterfaces_InterfaceList{} } func (m *ProxyArpInterfaces_InterfaceList) String() string { return proto.CompactTextString(m) } func (*ProxyArpInterfaces_InterfaceList) ProtoMessage() {} func (*ProxyArpInterfaces_InterfaceList) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{3, 0} + return fileDescriptor_l3_3f0db3548c262ee3, []int{3, 0} } +func (m *ProxyArpInterfaces_InterfaceList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProxyArpInterfaces_InterfaceList.Unmarshal(m, b) +} +func (m *ProxyArpInterfaces_InterfaceList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProxyArpInterfaces_InterfaceList.Marshal(b, m, deterministic) +} +func (dst *ProxyArpInterfaces_InterfaceList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProxyArpInterfaces_InterfaceList.Merge(dst, src) +} +func (m *ProxyArpInterfaces_InterfaceList) XXX_Size() int { + return xxx_messageInfo_ProxyArpInterfaces_InterfaceList.Size(m) +} +func (m *ProxyArpInterfaces_InterfaceList) XXX_DiscardUnknown() { + xxx_messageInfo_ProxyArpInterfaces_InterfaceList.DiscardUnknown(m) +} + +var xxx_messageInfo_ProxyArpInterfaces_InterfaceList proto.InternalMessageInfo func (m *ProxyArpInterfaces_InterfaceList) GetLabel() string { if m != nil { @@ -351,7 +533,10 @@ func (m *ProxyArpInterfaces_InterfaceList) GetInterfaces() []*ProxyArpInterfaces } type ProxyArpInterfaces_InterfaceList_Interface struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ProxyArpInterfaces_InterfaceList_Interface) Reset() { @@ -362,9 +547,26 @@ func (m *ProxyArpInterfaces_InterfaceList_Interface) String() string { } func (*ProxyArpInterfaces_InterfaceList_Interface) ProtoMessage() {} func (*ProxyArpInterfaces_InterfaceList_Interface) Descriptor() ([]byte, []int) { - return fileDescriptorL3, []int{3, 0, 0} + return fileDescriptor_l3_3f0db3548c262ee3, []int{3, 0, 0} +} +func (m *ProxyArpInterfaces_InterfaceList_Interface) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProxyArpInterfaces_InterfaceList_Interface.Unmarshal(m, b) +} +func (m *ProxyArpInterfaces_InterfaceList_Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProxyArpInterfaces_InterfaceList_Interface.Marshal(b, m, deterministic) +} +func (dst *ProxyArpInterfaces_InterfaceList_Interface) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProxyArpInterfaces_InterfaceList_Interface.Merge(dst, src) +} +func (m *ProxyArpInterfaces_InterfaceList_Interface) XXX_Size() int { + return xxx_messageInfo_ProxyArpInterfaces_InterfaceList_Interface.Size(m) +} +func (m *ProxyArpInterfaces_InterfaceList_Interface) XXX_DiscardUnknown() { + xxx_messageInfo_ProxyArpInterfaces_InterfaceList_Interface.DiscardUnknown(m) } +var xxx_messageInfo_ProxyArpInterfaces_InterfaceList_Interface proto.InternalMessageInfo + func (m *ProxyArpInterfaces_InterfaceList_Interface) GetName() string { if m != nil { return m.Name @@ -374,13 +576,35 @@ func (m *ProxyArpInterfaces_InterfaceList_Interface) GetName() string { // STN (Steal The NIC) feature table type STNTable struct { - StnEntries []*STNTable_STNTableEntry `protobuf:"bytes,1,rep,name=stn_entries,json=stnEntries" json:"stn_entries,omitempty"` + StnEntries []*STNTable_STNTableEntry `protobuf:"bytes,1,rep,name=stn_entries,json=stnEntries" json:"stn_entries,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *STNTable) Reset() { *m = STNTable{} } -func (m *STNTable) String() string { return proto.CompactTextString(m) } -func (*STNTable) ProtoMessage() {} -func (*STNTable) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{4} } +func (m *STNTable) Reset() { *m = STNTable{} } +func (m *STNTable) String() string { return proto.CompactTextString(m) } +func (*STNTable) ProtoMessage() {} +func (*STNTable) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{4} +} +func (m *STNTable) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_STNTable.Unmarshal(m, b) +} +func (m *STNTable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_STNTable.Marshal(b, m, deterministic) +} +func (dst *STNTable) XXX_Merge(src proto.Message) { + xxx_messageInfo_STNTable.Merge(dst, src) +} +func (m *STNTable) XXX_Size() int { + return xxx_messageInfo_STNTable.Size(m) +} +func (m *STNTable) XXX_DiscardUnknown() { + xxx_messageInfo_STNTable.DiscardUnknown(m) +} + +var xxx_messageInfo_STNTable proto.InternalMessageInfo func (m *STNTable) GetStnEntries() []*STNTable_STNTableEntry { if m != nil { @@ -390,14 +614,36 @@ func (m *STNTable) GetStnEntries() []*STNTable_STNTableEntry { } type STNTable_STNTableEntry struct { - IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - Interface string `protobuf:"bytes,2,opt,name=interface,proto3" json:"interface,omitempty"` + IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + Interface string `protobuf:"bytes,2,opt,name=interface,proto3" json:"interface,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *STNTable_STNTableEntry) Reset() { *m = STNTable_STNTableEntry{} } +func (m *STNTable_STNTableEntry) String() string { return proto.CompactTextString(m) } +func (*STNTable_STNTableEntry) ProtoMessage() {} +func (*STNTable_STNTableEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{4, 0} +} +func (m *STNTable_STNTableEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_STNTable_STNTableEntry.Unmarshal(m, b) +} +func (m *STNTable_STNTableEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_STNTable_STNTableEntry.Marshal(b, m, deterministic) +} +func (dst *STNTable_STNTableEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_STNTable_STNTableEntry.Merge(dst, src) +} +func (m *STNTable_STNTableEntry) XXX_Size() int { + return xxx_messageInfo_STNTable_STNTableEntry.Size(m) +} +func (m *STNTable_STNTableEntry) XXX_DiscardUnknown() { + xxx_messageInfo_STNTable_STNTableEntry.DiscardUnknown(m) } -func (m *STNTable_STNTableEntry) Reset() { *m = STNTable_STNTableEntry{} } -func (m *STNTable_STNTableEntry) String() string { return proto.CompactTextString(m) } -func (*STNTable_STNTableEntry) ProtoMessage() {} -func (*STNTable_STNTableEntry) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{4, 0} } +var xxx_messageInfo_STNTable_STNTableEntry proto.InternalMessageInfo func (m *STNTable_STNTableEntry) GetIpAddress() string { if m != nil { @@ -415,18 +661,40 @@ func (m *STNTable_STNTableEntry) GetInterface() string { // Enables/disables IP neighbor scanning type IPScanNeighbor struct { - Mode IPScanNeighbor_Mode `protobuf:"varint,1,opt,name=mode,proto3,enum=l3.IPScanNeighbor_Mode" json:"mode,omitempty"` - ScanInterval uint32 `protobuf:"varint,2,opt,name=scan_interval,json=scanInterval,proto3" json:"scan_interval,omitempty"` - MaxProcTime uint32 `protobuf:"varint,3,opt,name=max_proc_time,json=maxProcTime,proto3" json:"max_proc_time,omitempty"` - MaxUpdate uint32 `protobuf:"varint,4,opt,name=max_update,json=maxUpdate,proto3" json:"max_update,omitempty"` - ScanIntDelay uint32 `protobuf:"varint,5,opt,name=scan_int_delay,json=scanIntDelay,proto3" json:"scan_int_delay,omitempty"` - StaleThreshold uint32 `protobuf:"varint,6,opt,name=stale_threshold,json=staleThreshold,proto3" json:"stale_threshold,omitempty"` + Mode IPScanNeighbor_Mode `protobuf:"varint,1,opt,name=mode,proto3,enum=l3.IPScanNeighbor_Mode" json:"mode,omitempty"` + ScanInterval uint32 `protobuf:"varint,2,opt,name=scan_interval,json=scanInterval,proto3" json:"scan_interval,omitempty"` + MaxProcTime uint32 `protobuf:"varint,3,opt,name=max_proc_time,json=maxProcTime,proto3" json:"max_proc_time,omitempty"` + MaxUpdate uint32 `protobuf:"varint,4,opt,name=max_update,json=maxUpdate,proto3" json:"max_update,omitempty"` + ScanIntDelay uint32 `protobuf:"varint,5,opt,name=scan_int_delay,json=scanIntDelay,proto3" json:"scan_int_delay,omitempty"` + StaleThreshold uint32 `protobuf:"varint,6,opt,name=stale_threshold,json=staleThreshold,proto3" json:"stale_threshold,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IPScanNeighbor) Reset() { *m = IPScanNeighbor{} } +func (m *IPScanNeighbor) String() string { return proto.CompactTextString(m) } +func (*IPScanNeighbor) ProtoMessage() {} +func (*IPScanNeighbor) Descriptor() ([]byte, []int) { + return fileDescriptor_l3_3f0db3548c262ee3, []int{5} +} +func (m *IPScanNeighbor) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IPScanNeighbor.Unmarshal(m, b) +} +func (m *IPScanNeighbor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IPScanNeighbor.Marshal(b, m, deterministic) +} +func (dst *IPScanNeighbor) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPScanNeighbor.Merge(dst, src) +} +func (m *IPScanNeighbor) XXX_Size() int { + return xxx_messageInfo_IPScanNeighbor.Size(m) +} +func (m *IPScanNeighbor) XXX_DiscardUnknown() { + xxx_messageInfo_IPScanNeighbor.DiscardUnknown(m) } -func (m *IPScanNeighbor) Reset() { *m = IPScanNeighbor{} } -func (m *IPScanNeighbor) String() string { return proto.CompactTextString(m) } -func (*IPScanNeighbor) ProtoMessage() {} -func (*IPScanNeighbor) Descriptor() ([]byte, []int) { return fileDescriptorL3, []int{5} } +var xxx_messageInfo_IPScanNeighbor proto.InternalMessageInfo func (m *IPScanNeighbor) GetMode() IPScanNeighbor_Mode { if m != nil { @@ -488,9 +756,9 @@ func init() { proto.RegisterEnum("l3.IPScanNeighbor_Mode", IPScanNeighbor_Mode_name, IPScanNeighbor_Mode_value) } -func init() { proto.RegisterFile("l3.proto", fileDescriptorL3) } +func init() { proto.RegisterFile("l3.proto", fileDescriptor_l3_3f0db3548c262ee3) } -var fileDescriptorL3 = []byte{ +var fileDescriptor_l3_3f0db3548c262ee3 = []byte{ // 826 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcd, 0x8e, 0xe3, 0x44, 0x10, 0x5e, 0x67, 0x12, 0x8f, 0x5d, 0x1e, 0x67, 0x43, 0x8b, 0x9d, 0x35, 0xd1, 0xb0, 0x04, 0xb3, diff --git a/plugins/vpp/model/l4/l4.pb.go b/plugins/vpp/model/l4/l4.pb.go index 978855c398..78da736007 100644 --- a/plugins/vpp/model/l4/l4.pb.go +++ b/plugins/vpp/model/l4/l4.pb.go @@ -1,16 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: l4.proto -/* -Package l4 is a generated protocol buffer package. - -It is generated from these files: - l4.proto - -It has these top-level messages: - L4Features - AppNamespaces -*/ package l4 import proto "github.com/gogo/protobuf/proto" @@ -30,13 +20,35 @@ const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package // Layer 4 VPP features settings type L4Features struct { - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *L4Features) Reset() { *m = L4Features{} } +func (m *L4Features) String() string { return proto.CompactTextString(m) } +func (*L4Features) ProtoMessage() {} +func (*L4Features) Descriptor() ([]byte, []int) { + return fileDescriptor_l4_3288b4ffe3b5800c, []int{0} +} +func (m *L4Features) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_L4Features.Unmarshal(m, b) +} +func (m *L4Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_L4Features.Marshal(b, m, deterministic) +} +func (dst *L4Features) XXX_Merge(src proto.Message) { + xxx_messageInfo_L4Features.Merge(dst, src) +} +func (m *L4Features) XXX_Size() int { + return xxx_messageInfo_L4Features.Size(m) +} +func (m *L4Features) XXX_DiscardUnknown() { + xxx_messageInfo_L4Features.DiscardUnknown(m) } -func (m *L4Features) Reset() { *m = L4Features{} } -func (m *L4Features) String() string { return proto.CompactTextString(m) } -func (*L4Features) ProtoMessage() {} -func (*L4Features) Descriptor() ([]byte, []int) { return fileDescriptorL4, []int{0} } +var xxx_messageInfo_L4Features proto.InternalMessageInfo func (m *L4Features) GetEnabled() bool { if m != nil { @@ -47,13 +59,35 @@ func (m *L4Features) GetEnabled() bool { // Application namespaces type AppNamespaces struct { - AppNamespaces []*AppNamespaces_AppNamespace `protobuf:"bytes,100,rep,name=app_namespaces,json=appNamespaces" json:"app_namespaces,omitempty"` + AppNamespaces []*AppNamespaces_AppNamespace `protobuf:"bytes,100,rep,name=app_namespaces,json=appNamespaces" json:"app_namespaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *AppNamespaces) Reset() { *m = AppNamespaces{} } -func (m *AppNamespaces) String() string { return proto.CompactTextString(m) } -func (*AppNamespaces) ProtoMessage() {} -func (*AppNamespaces) Descriptor() ([]byte, []int) { return fileDescriptorL4, []int{1} } +func (m *AppNamespaces) Reset() { *m = AppNamespaces{} } +func (m *AppNamespaces) String() string { return proto.CompactTextString(m) } +func (*AppNamespaces) ProtoMessage() {} +func (*AppNamespaces) Descriptor() ([]byte, []int) { + return fileDescriptor_l4_3288b4ffe3b5800c, []int{1} +} +func (m *AppNamespaces) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AppNamespaces.Unmarshal(m, b) +} +func (m *AppNamespaces) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AppNamespaces.Marshal(b, m, deterministic) +} +func (dst *AppNamespaces) XXX_Merge(src proto.Message) { + xxx_messageInfo_AppNamespaces.Merge(dst, src) +} +func (m *AppNamespaces) XXX_Size() int { + return xxx_messageInfo_AppNamespaces.Size(m) +} +func (m *AppNamespaces) XXX_DiscardUnknown() { + xxx_messageInfo_AppNamespaces.DiscardUnknown(m) +} + +var xxx_messageInfo_AppNamespaces proto.InternalMessageInfo func (m *AppNamespaces) GetAppNamespaces() []*AppNamespaces_AppNamespace { if m != nil { @@ -63,17 +97,39 @@ func (m *AppNamespaces) GetAppNamespaces() []*AppNamespaces_AppNamespace { } type AppNamespaces_AppNamespace struct { - NamespaceId string `protobuf:"bytes,1,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` - Secret uint64 `protobuf:"varint,2,opt,name=secret,proto3" json:"secret,omitempty"` - Interface string `protobuf:"bytes,3,opt,name=interface,proto3" json:"interface,omitempty"` - Ipv4FibId uint32 `protobuf:"varint,4,opt,name=ipv4_fib_id,json=ipv4FibId,proto3" json:"ipv4_fib_id,omitempty"` - Ipv6FibId uint32 `protobuf:"varint,6,opt,name=ipv6_fib_id,json=ipv6FibId,proto3" json:"ipv6_fib_id,omitempty"` + NamespaceId string `protobuf:"bytes,1,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` + Secret uint64 `protobuf:"varint,2,opt,name=secret,proto3" json:"secret,omitempty"` + Interface string `protobuf:"bytes,3,opt,name=interface,proto3" json:"interface,omitempty"` + Ipv4FibId uint32 `protobuf:"varint,4,opt,name=ipv4_fib_id,json=ipv4FibId,proto3" json:"ipv4_fib_id,omitempty"` + Ipv6FibId uint32 `protobuf:"varint,6,opt,name=ipv6_fib_id,json=ipv6FibId,proto3" json:"ipv6_fib_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AppNamespaces_AppNamespace) Reset() { *m = AppNamespaces_AppNamespace{} } +func (m *AppNamespaces_AppNamespace) String() string { return proto.CompactTextString(m) } +func (*AppNamespaces_AppNamespace) ProtoMessage() {} +func (*AppNamespaces_AppNamespace) Descriptor() ([]byte, []int) { + return fileDescriptor_l4_3288b4ffe3b5800c, []int{1, 0} +} +func (m *AppNamespaces_AppNamespace) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AppNamespaces_AppNamespace.Unmarshal(m, b) +} +func (m *AppNamespaces_AppNamespace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AppNamespaces_AppNamespace.Marshal(b, m, deterministic) +} +func (dst *AppNamespaces_AppNamespace) XXX_Merge(src proto.Message) { + xxx_messageInfo_AppNamespaces_AppNamespace.Merge(dst, src) +} +func (m *AppNamespaces_AppNamespace) XXX_Size() int { + return xxx_messageInfo_AppNamespaces_AppNamespace.Size(m) +} +func (m *AppNamespaces_AppNamespace) XXX_DiscardUnknown() { + xxx_messageInfo_AppNamespaces_AppNamespace.DiscardUnknown(m) } -func (m *AppNamespaces_AppNamespace) Reset() { *m = AppNamespaces_AppNamespace{} } -func (m *AppNamespaces_AppNamespace) String() string { return proto.CompactTextString(m) } -func (*AppNamespaces_AppNamespace) ProtoMessage() {} -func (*AppNamespaces_AppNamespace) Descriptor() ([]byte, []int) { return fileDescriptorL4, []int{1, 0} } +var xxx_messageInfo_AppNamespaces_AppNamespace proto.InternalMessageInfo func (m *AppNamespaces_AppNamespace) GetNamespaceId() string { if m != nil { @@ -116,9 +172,9 @@ func init() { proto.RegisterType((*AppNamespaces_AppNamespace)(nil), "l4.AppNamespaces.AppNamespace") } -func init() { proto.RegisterFile("l4.proto", fileDescriptorL4) } +func init() { proto.RegisterFile("l4.proto", fileDescriptor_l4_3288b4ffe3b5800c) } -var fileDescriptorL4 = []byte{ +var fileDescriptor_l4_3288b4ffe3b5800c = []byte{ // 228 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xc8, 0x31, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xca, 0x31, 0x51, 0x52, 0xe3, 0xe2, 0xf2, 0x31, 0x71, 0x4b, diff --git a/plugins/vpp/model/nat/nat.pb.go b/plugins/vpp/model/nat/nat.pb.go index bcc4e53dd9..2017b420ee 100644 --- a/plugins/vpp/model/nat/nat.pb.go +++ b/plugins/vpp/model/nat/nat.pb.go @@ -1,17 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: nat.proto -/* -Package nat is a generated protocol buffer package. - -It is generated from these files: - nat.proto - -It has these top-level messages: - Nat44Global - Nat44SNat - Nat44DNat -*/ package nat import proto "github.com/gogo/protobuf/proto" @@ -51,7 +40,9 @@ var Protocol_value = map[string]int32{ func (x Protocol) String() string { return proto.EnumName(Protocol_name, int32(x)) } -func (Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorNat, []int{0} } +func (Protocol) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{0} +} type TwiceNatMode int32 @@ -75,7 +66,9 @@ var TwiceNatMode_value = map[string]int32{ func (x TwiceNatMode) String() string { return proto.EnumName(TwiceNatMode_name, int32(x)) } -func (TwiceNatMode) EnumDescriptor() ([]byte, []int) { return fileDescriptorNat, []int{1} } +func (TwiceNatMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{1} +} // NAT44 global config type Nat44Global struct { @@ -84,12 +77,34 @@ type Nat44Global struct { AddressPools []*Nat44Global_AddressPool `protobuf:"bytes,5,rep,name=address_pools,json=addressPools" json:"address_pools,omitempty"` VirtualReassemblyIpv4 *Nat44Global_VirtualReassembly `protobuf:"bytes,6,opt,name=virtual_reassembly_ipv4,json=virtualReassemblyIpv4" json:"virtual_reassembly_ipv4,omitempty"` VirtualReassemblyIpv6 *Nat44Global_VirtualReassembly `protobuf:"bytes,7,opt,name=virtual_reassembly_ipv6,json=virtualReassemblyIpv6" json:"virtual_reassembly_ipv6,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Nat44Global) Reset() { *m = Nat44Global{} } +func (m *Nat44Global) String() string { return proto.CompactTextString(m) } +func (*Nat44Global) ProtoMessage() {} +func (*Nat44Global) Descriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{0} +} +func (m *Nat44Global) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44Global.Unmarshal(m, b) +} +func (m *Nat44Global) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44Global.Marshal(b, m, deterministic) +} +func (dst *Nat44Global) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44Global.Merge(dst, src) +} +func (m *Nat44Global) XXX_Size() int { + return xxx_messageInfo_Nat44Global.Size(m) +} +func (m *Nat44Global) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44Global.DiscardUnknown(m) } -func (m *Nat44Global) Reset() { *m = Nat44Global{} } -func (m *Nat44Global) String() string { return proto.CompactTextString(m) } -func (*Nat44Global) ProtoMessage() {} -func (*Nat44Global) Descriptor() ([]byte, []int) { return fileDescriptorNat, []int{0} } +var xxx_messageInfo_Nat44Global proto.InternalMessageInfo func (m *Nat44Global) GetForwarding() bool { if m != nil { @@ -127,15 +142,37 @@ func (m *Nat44Global) GetVirtualReassemblyIpv6() *Nat44Global_VirtualReassembly } type Nat44Global_NatInterface struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - IsInside bool `protobuf:"varint,2,opt,name=is_inside,json=isInside,proto3" json:"is_inside,omitempty"` - OutputFeature bool `protobuf:"varint,3,opt,name=output_feature,json=outputFeature,proto3" json:"output_feature,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + IsInside bool `protobuf:"varint,2,opt,name=is_inside,json=isInside,proto3" json:"is_inside,omitempty"` + OutputFeature bool `protobuf:"varint,3,opt,name=output_feature,json=outputFeature,proto3" json:"output_feature,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Nat44Global_NatInterface) Reset() { *m = Nat44Global_NatInterface{} } +func (m *Nat44Global_NatInterface) String() string { return proto.CompactTextString(m) } +func (*Nat44Global_NatInterface) ProtoMessage() {} +func (*Nat44Global_NatInterface) Descriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{0, 0} +} +func (m *Nat44Global_NatInterface) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44Global_NatInterface.Unmarshal(m, b) +} +func (m *Nat44Global_NatInterface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44Global_NatInterface.Marshal(b, m, deterministic) +} +func (dst *Nat44Global_NatInterface) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44Global_NatInterface.Merge(dst, src) +} +func (m *Nat44Global_NatInterface) XXX_Size() int { + return xxx_messageInfo_Nat44Global_NatInterface.Size(m) +} +func (m *Nat44Global_NatInterface) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44Global_NatInterface.DiscardUnknown(m) } -func (m *Nat44Global_NatInterface) Reset() { *m = Nat44Global_NatInterface{} } -func (m *Nat44Global_NatInterface) String() string { return proto.CompactTextString(m) } -func (*Nat44Global_NatInterface) ProtoMessage() {} -func (*Nat44Global_NatInterface) Descriptor() ([]byte, []int) { return fileDescriptorNat, []int{0, 0} } +var xxx_messageInfo_Nat44Global_NatInterface proto.InternalMessageInfo func (m *Nat44Global_NatInterface) GetName() string { if m != nil { @@ -159,16 +196,38 @@ func (m *Nat44Global_NatInterface) GetOutputFeature() bool { } type Nat44Global_AddressPool struct { - FirstSrcAddress string `protobuf:"bytes,1,opt,name=first_src_address,json=firstSrcAddress,proto3" json:"first_src_address,omitempty"` - LastSrcAddress string `protobuf:"bytes,2,opt,name=last_src_address,json=lastSrcAddress,proto3" json:"last_src_address,omitempty"` - VrfId uint32 `protobuf:"varint,3,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"` - TwiceNat bool `protobuf:"varint,4,opt,name=twice_nat,json=twiceNat,proto3" json:"twice_nat,omitempty"` + FirstSrcAddress string `protobuf:"bytes,1,opt,name=first_src_address,json=firstSrcAddress,proto3" json:"first_src_address,omitempty"` + LastSrcAddress string `protobuf:"bytes,2,opt,name=last_src_address,json=lastSrcAddress,proto3" json:"last_src_address,omitempty"` + VrfId uint32 `protobuf:"varint,3,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"` + TwiceNat bool `protobuf:"varint,4,opt,name=twice_nat,json=twiceNat,proto3" json:"twice_nat,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *Nat44Global_AddressPool) Reset() { *m = Nat44Global_AddressPool{} } -func (m *Nat44Global_AddressPool) String() string { return proto.CompactTextString(m) } -func (*Nat44Global_AddressPool) ProtoMessage() {} -func (*Nat44Global_AddressPool) Descriptor() ([]byte, []int) { return fileDescriptorNat, []int{0, 1} } +func (m *Nat44Global_AddressPool) Reset() { *m = Nat44Global_AddressPool{} } +func (m *Nat44Global_AddressPool) String() string { return proto.CompactTextString(m) } +func (*Nat44Global_AddressPool) ProtoMessage() {} +func (*Nat44Global_AddressPool) Descriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{0, 1} +} +func (m *Nat44Global_AddressPool) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44Global_AddressPool.Unmarshal(m, b) +} +func (m *Nat44Global_AddressPool) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44Global_AddressPool.Marshal(b, m, deterministic) +} +func (dst *Nat44Global_AddressPool) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44Global_AddressPool.Merge(dst, src) +} +func (m *Nat44Global_AddressPool) XXX_Size() int { + return xxx_messageInfo_Nat44Global_AddressPool.Size(m) +} +func (m *Nat44Global_AddressPool) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44Global_AddressPool.DiscardUnknown(m) +} + +var xxx_messageInfo_Nat44Global_AddressPool proto.InternalMessageInfo func (m *Nat44Global_AddressPool) GetFirstSrcAddress() string { if m != nil { @@ -199,19 +258,39 @@ func (m *Nat44Global_AddressPool) GetTwiceNat() bool { } type Nat44Global_VirtualReassembly struct { - Timeout uint32 `protobuf:"varint,1,opt,name=timeout,proto3" json:"timeout,omitempty"` - MaxReass uint32 `protobuf:"varint,2,opt,name=max_reass,json=maxReass,proto3" json:"max_reass,omitempty"` - MaxFrag uint32 `protobuf:"varint,3,opt,name=max_frag,json=maxFrag,proto3" json:"max_frag,omitempty"` - DropFrag bool `protobuf:"varint,4,opt,name=drop_frag,json=dropFrag,proto3" json:"drop_frag,omitempty"` + Timeout uint32 `protobuf:"varint,1,opt,name=timeout,proto3" json:"timeout,omitempty"` + MaxReass uint32 `protobuf:"varint,2,opt,name=max_reass,json=maxReass,proto3" json:"max_reass,omitempty"` + MaxFrag uint32 `protobuf:"varint,3,opt,name=max_frag,json=maxFrag,proto3" json:"max_frag,omitempty"` + DropFrag bool `protobuf:"varint,4,opt,name=drop_frag,json=dropFrag,proto3" json:"drop_frag,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Nat44Global_VirtualReassembly) Reset() { *m = Nat44Global_VirtualReassembly{} } func (m *Nat44Global_VirtualReassembly) String() string { return proto.CompactTextString(m) } func (*Nat44Global_VirtualReassembly) ProtoMessage() {} func (*Nat44Global_VirtualReassembly) Descriptor() ([]byte, []int) { - return fileDescriptorNat, []int{0, 2} + return fileDescriptor_nat_35c2c3d9aa286b77, []int{0, 2} +} +func (m *Nat44Global_VirtualReassembly) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44Global_VirtualReassembly.Unmarshal(m, b) +} +func (m *Nat44Global_VirtualReassembly) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44Global_VirtualReassembly.Marshal(b, m, deterministic) +} +func (dst *Nat44Global_VirtualReassembly) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44Global_VirtualReassembly.Merge(dst, src) +} +func (m *Nat44Global_VirtualReassembly) XXX_Size() int { + return xxx_messageInfo_Nat44Global_VirtualReassembly.Size(m) +} +func (m *Nat44Global_VirtualReassembly) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44Global_VirtualReassembly.DiscardUnknown(m) } +var xxx_messageInfo_Nat44Global_VirtualReassembly proto.InternalMessageInfo + func (m *Nat44Global_VirtualReassembly) GetTimeout() uint32 { if m != nil { return m.Timeout @@ -242,13 +321,35 @@ func (m *Nat44Global_VirtualReassembly) GetDropFrag() bool { // Many-to-one (SNAT) setup type Nat44SNat struct { - SnatConfigs []*Nat44SNat_SNatConfig `protobuf:"bytes,1,rep,name=snat_configs,json=snatConfigs" json:"snat_configs,omitempty"` + SnatConfigs []*Nat44SNat_SNatConfig `protobuf:"bytes,1,rep,name=snat_configs,json=snatConfigs" json:"snat_configs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *Nat44SNat) Reset() { *m = Nat44SNat{} } -func (m *Nat44SNat) String() string { return proto.CompactTextString(m) } -func (*Nat44SNat) ProtoMessage() {} -func (*Nat44SNat) Descriptor() ([]byte, []int) { return fileDescriptorNat, []int{1} } +func (m *Nat44SNat) Reset() { *m = Nat44SNat{} } +func (m *Nat44SNat) String() string { return proto.CompactTextString(m) } +func (*Nat44SNat) ProtoMessage() {} +func (*Nat44SNat) Descriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{1} +} +func (m *Nat44SNat) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44SNat.Unmarshal(m, b) +} +func (m *Nat44SNat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44SNat.Marshal(b, m, deterministic) +} +func (dst *Nat44SNat) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44SNat.Merge(dst, src) +} +func (m *Nat44SNat) XXX_Size() int { + return xxx_messageInfo_Nat44SNat.Size(m) +} +func (m *Nat44SNat) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44SNat.DiscardUnknown(m) +} + +var xxx_messageInfo_Nat44SNat proto.InternalMessageInfo func (m *Nat44SNat) GetSnatConfigs() []*Nat44SNat_SNatConfig { if m != nil { @@ -258,13 +359,35 @@ func (m *Nat44SNat) GetSnatConfigs() []*Nat44SNat_SNatConfig { } type Nat44SNat_SNatConfig struct { - Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *Nat44SNat_SNatConfig) Reset() { *m = Nat44SNat_SNatConfig{} } -func (m *Nat44SNat_SNatConfig) String() string { return proto.CompactTextString(m) } -func (*Nat44SNat_SNatConfig) ProtoMessage() {} -func (*Nat44SNat_SNatConfig) Descriptor() ([]byte, []int) { return fileDescriptorNat, []int{1, 0} } +func (m *Nat44SNat_SNatConfig) Reset() { *m = Nat44SNat_SNatConfig{} } +func (m *Nat44SNat_SNatConfig) String() string { return proto.CompactTextString(m) } +func (*Nat44SNat_SNatConfig) ProtoMessage() {} +func (*Nat44SNat_SNatConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{1, 0} +} +func (m *Nat44SNat_SNatConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44SNat_SNatConfig.Unmarshal(m, b) +} +func (m *Nat44SNat_SNatConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44SNat_SNatConfig.Marshal(b, m, deterministic) +} +func (dst *Nat44SNat_SNatConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44SNat_SNatConfig.Merge(dst, src) +} +func (m *Nat44SNat_SNatConfig) XXX_Size() int { + return xxx_messageInfo_Nat44SNat_SNatConfig.Size(m) +} +func (m *Nat44SNat_SNatConfig) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44SNat_SNatConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_Nat44SNat_SNatConfig proto.InternalMessageInfo func (m *Nat44SNat_SNatConfig) GetLabel() string { if m != nil { @@ -275,13 +398,35 @@ func (m *Nat44SNat_SNatConfig) GetLabel() string { // One-to-many (DNAT) setup type Nat44DNat struct { - DnatConfigs []*Nat44DNat_DNatConfig `protobuf:"bytes,1,rep,name=dnat_configs,json=dnatConfigs" json:"dnat_configs,omitempty"` + DnatConfigs []*Nat44DNat_DNatConfig `protobuf:"bytes,1,rep,name=dnat_configs,json=dnatConfigs" json:"dnat_configs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *Nat44DNat) Reset() { *m = Nat44DNat{} } -func (m *Nat44DNat) String() string { return proto.CompactTextString(m) } -func (*Nat44DNat) ProtoMessage() {} -func (*Nat44DNat) Descriptor() ([]byte, []int) { return fileDescriptorNat, []int{2} } +func (m *Nat44DNat) Reset() { *m = Nat44DNat{} } +func (m *Nat44DNat) String() string { return proto.CompactTextString(m) } +func (*Nat44DNat) ProtoMessage() {} +func (*Nat44DNat) Descriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{2} +} +func (m *Nat44DNat) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44DNat.Unmarshal(m, b) +} +func (m *Nat44DNat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44DNat.Marshal(b, m, deterministic) +} +func (dst *Nat44DNat) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44DNat.Merge(dst, src) +} +func (m *Nat44DNat) XXX_Size() int { + return xxx_messageInfo_Nat44DNat.Size(m) +} +func (m *Nat44DNat) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44DNat.DiscardUnknown(m) +} + +var xxx_messageInfo_Nat44DNat proto.InternalMessageInfo func (m *Nat44DNat) GetDnatConfigs() []*Nat44DNat_DNatConfig { if m != nil { @@ -291,15 +436,37 @@ func (m *Nat44DNat) GetDnatConfigs() []*Nat44DNat_DNatConfig { } type Nat44DNat_DNatConfig struct { - Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` - StMappings []*Nat44DNat_DNatConfig_StaticMapping `protobuf:"bytes,4,rep,name=st_mappings,json=stMappings" json:"st_mappings,omitempty"` - IdMappings []*Nat44DNat_DNatConfig_IdentityMapping `protobuf:"bytes,6,rep,name=id_mappings,json=idMappings" json:"id_mappings,omitempty"` + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + StMappings []*Nat44DNat_DNatConfig_StaticMapping `protobuf:"bytes,4,rep,name=st_mappings,json=stMappings" json:"st_mappings,omitempty"` + IdMappings []*Nat44DNat_DNatConfig_IdentityMapping `protobuf:"bytes,6,rep,name=id_mappings,json=idMappings" json:"id_mappings,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Nat44DNat_DNatConfig) Reset() { *m = Nat44DNat_DNatConfig{} } +func (m *Nat44DNat_DNatConfig) String() string { return proto.CompactTextString(m) } +func (*Nat44DNat_DNatConfig) ProtoMessage() {} +func (*Nat44DNat_DNatConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_nat_35c2c3d9aa286b77, []int{2, 0} +} +func (m *Nat44DNat_DNatConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44DNat_DNatConfig.Unmarshal(m, b) +} +func (m *Nat44DNat_DNatConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44DNat_DNatConfig.Marshal(b, m, deterministic) +} +func (dst *Nat44DNat_DNatConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44DNat_DNatConfig.Merge(dst, src) +} +func (m *Nat44DNat_DNatConfig) XXX_Size() int { + return xxx_messageInfo_Nat44DNat_DNatConfig.Size(m) +} +func (m *Nat44DNat_DNatConfig) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44DNat_DNatConfig.DiscardUnknown(m) } -func (m *Nat44DNat_DNatConfig) Reset() { *m = Nat44DNat_DNatConfig{} } -func (m *Nat44DNat_DNatConfig) String() string { return proto.CompactTextString(m) } -func (*Nat44DNat_DNatConfig) ProtoMessage() {} -func (*Nat44DNat_DNatConfig) Descriptor() ([]byte, []int) { return fileDescriptorNat, []int{2, 0} } +var xxx_messageInfo_Nat44DNat_DNatConfig proto.InternalMessageInfo func (m *Nat44DNat_DNatConfig) GetLabel() string { if m != nil { @@ -323,20 +490,40 @@ func (m *Nat44DNat_DNatConfig) GetIdMappings() []*Nat44DNat_DNatConfig_IdentityM } type Nat44DNat_DNatConfig_StaticMapping struct { - ExternalInterface string `protobuf:"bytes,2,opt,name=external_interface,json=externalInterface,proto3" json:"external_interface,omitempty"` - ExternalIp string `protobuf:"bytes,3,opt,name=external_ip,json=externalIp,proto3" json:"external_ip,omitempty"` - ExternalPort uint32 `protobuf:"varint,4,opt,name=external_port,json=externalPort,proto3" json:"external_port,omitempty"` - LocalIps []*Nat44DNat_DNatConfig_StaticMapping_LocalIP `protobuf:"bytes,5,rep,name=local_ips,json=localIps" json:"local_ips,omitempty"` - Protocol Protocol `protobuf:"varint,6,opt,name=protocol,proto3,enum=nat.Protocol" json:"protocol,omitempty"` - TwiceNat TwiceNatMode `protobuf:"varint,7,opt,name=twice_nat,json=twiceNat,proto3,enum=nat.TwiceNatMode" json:"twice_nat,omitempty"` + ExternalInterface string `protobuf:"bytes,2,opt,name=external_interface,json=externalInterface,proto3" json:"external_interface,omitempty"` + ExternalIp string `protobuf:"bytes,3,opt,name=external_ip,json=externalIp,proto3" json:"external_ip,omitempty"` + ExternalPort uint32 `protobuf:"varint,4,opt,name=external_port,json=externalPort,proto3" json:"external_port,omitempty"` + LocalIps []*Nat44DNat_DNatConfig_StaticMapping_LocalIP `protobuf:"bytes,5,rep,name=local_ips,json=localIps" json:"local_ips,omitempty"` + Protocol Protocol `protobuf:"varint,6,opt,name=protocol,proto3,enum=nat.Protocol" json:"protocol,omitempty"` + TwiceNat TwiceNatMode `protobuf:"varint,7,opt,name=twice_nat,json=twiceNat,proto3,enum=nat.TwiceNatMode" json:"twice_nat,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Nat44DNat_DNatConfig_StaticMapping) Reset() { *m = Nat44DNat_DNatConfig_StaticMapping{} } func (m *Nat44DNat_DNatConfig_StaticMapping) String() string { return proto.CompactTextString(m) } func (*Nat44DNat_DNatConfig_StaticMapping) ProtoMessage() {} func (*Nat44DNat_DNatConfig_StaticMapping) Descriptor() ([]byte, []int) { - return fileDescriptorNat, []int{2, 0, 0} + return fileDescriptor_nat_35c2c3d9aa286b77, []int{2, 0, 0} +} +func (m *Nat44DNat_DNatConfig_StaticMapping) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping.Unmarshal(m, b) +} +func (m *Nat44DNat_DNatConfig_StaticMapping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping.Marshal(b, m, deterministic) +} +func (dst *Nat44DNat_DNatConfig_StaticMapping) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping.Merge(dst, src) +} +func (m *Nat44DNat_DNatConfig_StaticMapping) XXX_Size() int { + return xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping.Size(m) } +func (m *Nat44DNat_DNatConfig_StaticMapping) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping.DiscardUnknown(m) +} + +var xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping proto.InternalMessageInfo func (m *Nat44DNat_DNatConfig_StaticMapping) GetExternalInterface() string { if m != nil { @@ -381,10 +568,13 @@ func (m *Nat44DNat_DNatConfig_StaticMapping) GetTwiceNat() TwiceNatMode { } type Nat44DNat_DNatConfig_StaticMapping_LocalIP struct { - VrfId uint32 `protobuf:"varint,4,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"` - LocalIp string `protobuf:"bytes,1,opt,name=local_ip,json=localIp,proto3" json:"local_ip,omitempty"` - LocalPort uint32 `protobuf:"varint,3,opt,name=local_port,json=localPort,proto3" json:"local_port,omitempty"` - Probability uint32 `protobuf:"varint,2,opt,name=probability,proto3" json:"probability,omitempty"` + VrfId uint32 `protobuf:"varint,4,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"` + LocalIp string `protobuf:"bytes,1,opt,name=local_ip,json=localIp,proto3" json:"local_ip,omitempty"` + LocalPort uint32 `protobuf:"varint,3,opt,name=local_port,json=localPort,proto3" json:"local_port,omitempty"` + Probability uint32 `protobuf:"varint,2,opt,name=probability,proto3" json:"probability,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) Reset() { @@ -395,8 +585,25 @@ func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) String() string { } func (*Nat44DNat_DNatConfig_StaticMapping_LocalIP) ProtoMessage() {} func (*Nat44DNat_DNatConfig_StaticMapping_LocalIP) Descriptor() ([]byte, []int) { - return fileDescriptorNat, []int{2, 0, 0, 0} + return fileDescriptor_nat_35c2c3d9aa286b77, []int{2, 0, 0, 0} +} +func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping_LocalIP.Unmarshal(m, b) +} +func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping_LocalIP.Marshal(b, m, deterministic) +} +func (dst *Nat44DNat_DNatConfig_StaticMapping_LocalIP) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping_LocalIP.Merge(dst, src) } +func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) XXX_Size() int { + return xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping_LocalIP.Size(m) +} +func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping_LocalIP.DiscardUnknown(m) +} + +var xxx_messageInfo_Nat44DNat_DNatConfig_StaticMapping_LocalIP proto.InternalMessageInfo func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) GetVrfId() uint32 { if m != nil { @@ -427,19 +634,39 @@ func (m *Nat44DNat_DNatConfig_StaticMapping_LocalIP) GetProbability() uint32 { } type Nat44DNat_DNatConfig_IdentityMapping struct { - VrfId uint32 `protobuf:"varint,1,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"` - AddressedInterface string `protobuf:"bytes,2,opt,name=addressed_interface,json=addressedInterface,proto3" json:"addressed_interface,omitempty"` - IpAddress string `protobuf:"bytes,3,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - Port uint32 `protobuf:"varint,4,opt,name=port,proto3" json:"port,omitempty"` - Protocol Protocol `protobuf:"varint,5,opt,name=protocol,proto3,enum=nat.Protocol" json:"protocol,omitempty"` + VrfId uint32 `protobuf:"varint,1,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"` + AddressedInterface string `protobuf:"bytes,2,opt,name=addressed_interface,json=addressedInterface,proto3" json:"addressed_interface,omitempty"` + IpAddress string `protobuf:"bytes,3,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + Port uint32 `protobuf:"varint,4,opt,name=port,proto3" json:"port,omitempty"` + Protocol Protocol `protobuf:"varint,5,opt,name=protocol,proto3,enum=nat.Protocol" json:"protocol,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Nat44DNat_DNatConfig_IdentityMapping) Reset() { *m = Nat44DNat_DNatConfig_IdentityMapping{} } func (m *Nat44DNat_DNatConfig_IdentityMapping) String() string { return proto.CompactTextString(m) } func (*Nat44DNat_DNatConfig_IdentityMapping) ProtoMessage() {} func (*Nat44DNat_DNatConfig_IdentityMapping) Descriptor() ([]byte, []int) { - return fileDescriptorNat, []int{2, 0, 1} + return fileDescriptor_nat_35c2c3d9aa286b77, []int{2, 0, 1} +} +func (m *Nat44DNat_DNatConfig_IdentityMapping) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nat44DNat_DNatConfig_IdentityMapping.Unmarshal(m, b) +} +func (m *Nat44DNat_DNatConfig_IdentityMapping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nat44DNat_DNatConfig_IdentityMapping.Marshal(b, m, deterministic) } +func (dst *Nat44DNat_DNatConfig_IdentityMapping) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nat44DNat_DNatConfig_IdentityMapping.Merge(dst, src) +} +func (m *Nat44DNat_DNatConfig_IdentityMapping) XXX_Size() int { + return xxx_messageInfo_Nat44DNat_DNatConfig_IdentityMapping.Size(m) +} +func (m *Nat44DNat_DNatConfig_IdentityMapping) XXX_DiscardUnknown() { + xxx_messageInfo_Nat44DNat_DNatConfig_IdentityMapping.DiscardUnknown(m) +} + +var xxx_messageInfo_Nat44DNat_DNatConfig_IdentityMapping proto.InternalMessageInfo func (m *Nat44DNat_DNatConfig_IdentityMapping) GetVrfId() uint32 { if m != nil { @@ -492,9 +719,9 @@ func init() { proto.RegisterEnum("nat.TwiceNatMode", TwiceNatMode_name, TwiceNatMode_value) } -func init() { proto.RegisterFile("nat.proto", fileDescriptorNat) } +func init() { proto.RegisterFile("nat.proto", fileDescriptor_nat_35c2c3d9aa286b77) } -var fileDescriptorNat = []byte{ +var fileDescriptor_nat_35c2c3d9aa286b77 = []byte{ // 846 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4f, 0x6f, 0xe3, 0x44, 0x14, 0x5f, 0x37, 0xff, 0x9c, 0xe7, 0xb8, 0x9b, 0x0e, 0xac, 0x70, 0x03, 0x85, 0x28, 0x08, 0xc8, diff --git a/plugins/vpp/model/rpc/rpc.pb.go b/plugins/vpp/model/rpc/rpc.pb.go index 5286de2d2d..691ba80511 100644 --- a/plugins/vpp/model/rpc/rpc.pb.go +++ b/plugins/vpp/model/rpc/rpc.pb.go @@ -1,25 +1,13 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: rpc.proto -/* -Package rpc is a generated protocol buffer package. - -It is generated from these files: - rpc.proto - -It has these top-level messages: - DataRequest - NotificationRequest - PutResponse - DelResponse - ResyncResponse - NotificationsResponse -*/ package rpc import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" +import interfaces1 "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" +import l31 "github.com/ligato/vpp-agent/plugins/linux/model/l3" import acl "github.com/ligato/vpp-agent/plugins/vpp/model/acl" import bfd "github.com/ligato/vpp-agent/plugins/vpp/model/bfd" import interfaces "github.com/ligato/vpp-agent/plugins/vpp/model/interfaces" @@ -28,13 +16,9 @@ import l3 "github.com/ligato/vpp-agent/plugins/vpp/model/l3" import l4 "github.com/ligato/vpp-agent/plugins/vpp/model/l4" import nat "github.com/ligato/vpp-agent/plugins/vpp/model/nat" import stn "github.com/ligato/vpp-agent/plugins/vpp/model/stn" -import interfaces1 "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" -import l31 "github.com/ligato/vpp-agent/plugins/linux/model/l3" -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -69,15 +53,37 @@ type DataRequest struct { NatGlobal *nat.Nat44Global `protobuf:"bytes,71,opt,name=NatGlobal" json:"NatGlobal,omitempty"` DNATs []*nat.Nat44DNat_DNatConfig `protobuf:"bytes,72,rep,name=DNATs" json:"DNATs,omitempty"` // Linuxplugin - LinuxInterfaces []*interfaces1.LinuxInterfaces_Interface `protobuf:"bytes,80,rep,name=LinuxInterfaces" json:"LinuxInterfaces,omitempty"` - LinuxArpEntries []*l31.LinuxStaticArpEntries_ArpEntry `protobuf:"bytes,90,rep,name=LinuxArpEntries" json:"LinuxArpEntries,omitempty"` - LinuxRoutes []*l31.LinuxStaticRoutes_Route `protobuf:"bytes,91,rep,name=LinuxRoutes" json:"LinuxRoutes,omitempty"` + LinuxInterfaces []*interfaces1.LinuxInterfaces_Interface `protobuf:"bytes,80,rep,name=LinuxInterfaces" json:"LinuxInterfaces,omitempty"` + LinuxArpEntries []*l31.LinuxStaticArpEntries_ArpEntry `protobuf:"bytes,90,rep,name=LinuxArpEntries" json:"LinuxArpEntries,omitempty"` + LinuxRoutes []*l31.LinuxStaticRoutes_Route `protobuf:"bytes,91,rep,name=LinuxRoutes" json:"LinuxRoutes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DataRequest) Reset() { *m = DataRequest{} } +func (m *DataRequest) String() string { return proto.CompactTextString(m) } +func (*DataRequest) ProtoMessage() {} +func (*DataRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_rpc_4797542838a6c8ba, []int{0} +} +func (m *DataRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DataRequest.Unmarshal(m, b) +} +func (m *DataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DataRequest.Marshal(b, m, deterministic) +} +func (dst *DataRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DataRequest.Merge(dst, src) +} +func (m *DataRequest) XXX_Size() int { + return xxx_messageInfo_DataRequest.Size(m) +} +func (m *DataRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DataRequest.DiscardUnknown(m) } -func (m *DataRequest) Reset() { *m = DataRequest{} } -func (m *DataRequest) String() string { return proto.CompactTextString(m) } -func (*DataRequest) ProtoMessage() {} -func (*DataRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{0} } +var xxx_messageInfo_DataRequest proto.InternalMessageInfo func (m *DataRequest) GetAccessLists() []*acl.AccessLists_Acl { if m != nil { @@ -222,13 +228,35 @@ func (m *DataRequest) GetLinuxRoutes() []*l31.LinuxStaticRoutes_Route { // NotificationRequest represent a notification request which contains index of next required // message type NotificationRequest struct { - Idx uint32 `protobuf:"varint,1,opt,name=idx,proto3" json:"idx,omitempty"` + Idx uint32 `protobuf:"varint,1,opt,name=idx,proto3" json:"idx,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *NotificationRequest) Reset() { *m = NotificationRequest{} } -func (m *NotificationRequest) String() string { return proto.CompactTextString(m) } -func (*NotificationRequest) ProtoMessage() {} -func (*NotificationRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1} } +func (m *NotificationRequest) Reset() { *m = NotificationRequest{} } +func (m *NotificationRequest) String() string { return proto.CompactTextString(m) } +func (*NotificationRequest) ProtoMessage() {} +func (*NotificationRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_rpc_4797542838a6c8ba, []int{1} +} +func (m *NotificationRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NotificationRequest.Unmarshal(m, b) +} +func (m *NotificationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NotificationRequest.Marshal(b, m, deterministic) +} +func (dst *NotificationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_NotificationRequest.Merge(dst, src) +} +func (m *NotificationRequest) XXX_Size() int { + return xxx_messageInfo_NotificationRequest.Size(m) +} +func (m *NotificationRequest) XXX_DiscardUnknown() { + xxx_messageInfo_NotificationRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_NotificationRequest proto.InternalMessageInfo func (m *NotificationRequest) GetIdx() uint32 { if m != nil { @@ -239,43 +267,131 @@ func (m *NotificationRequest) GetIdx() uint32 { // Response to data change 'put' type PutResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PutResponse) Reset() { *m = PutResponse{} } +func (m *PutResponse) String() string { return proto.CompactTextString(m) } +func (*PutResponse) ProtoMessage() {} +func (*PutResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_rpc_4797542838a6c8ba, []int{2} +} +func (m *PutResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PutResponse.Unmarshal(m, b) +} +func (m *PutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PutResponse.Marshal(b, m, deterministic) +} +func (dst *PutResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PutResponse.Merge(dst, src) +} +func (m *PutResponse) XXX_Size() int { + return xxx_messageInfo_PutResponse.Size(m) +} +func (m *PutResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PutResponse.DiscardUnknown(m) } -func (m *PutResponse) Reset() { *m = PutResponse{} } -func (m *PutResponse) String() string { return proto.CompactTextString(m) } -func (*PutResponse) ProtoMessage() {} -func (*PutResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{2} } +var xxx_messageInfo_PutResponse proto.InternalMessageInfo // Response to data change 'del' type DelResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DelResponse) Reset() { *m = DelResponse{} } +func (m *DelResponse) String() string { return proto.CompactTextString(m) } +func (*DelResponse) ProtoMessage() {} +func (*DelResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_rpc_4797542838a6c8ba, []int{3} +} +func (m *DelResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DelResponse.Unmarshal(m, b) +} +func (m *DelResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DelResponse.Marshal(b, m, deterministic) +} +func (dst *DelResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DelResponse.Merge(dst, src) +} +func (m *DelResponse) XXX_Size() int { + return xxx_messageInfo_DelResponse.Size(m) +} +func (m *DelResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DelResponse.DiscardUnknown(m) } -func (m *DelResponse) Reset() { *m = DelResponse{} } -func (m *DelResponse) String() string { return proto.CompactTextString(m) } -func (*DelResponse) ProtoMessage() {} -func (*DelResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{3} } +var xxx_messageInfo_DelResponse proto.InternalMessageInfo // Response to data resync type ResyncResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *ResyncResponse) Reset() { *m = ResyncResponse{} } -func (m *ResyncResponse) String() string { return proto.CompactTextString(m) } -func (*ResyncResponse) ProtoMessage() {} -func (*ResyncResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{4} } +func (m *ResyncResponse) Reset() { *m = ResyncResponse{} } +func (m *ResyncResponse) String() string { return proto.CompactTextString(m) } +func (*ResyncResponse) ProtoMessage() {} +func (*ResyncResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_rpc_4797542838a6c8ba, []int{4} +} +func (m *ResyncResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ResyncResponse.Unmarshal(m, b) +} +func (m *ResyncResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ResyncResponse.Marshal(b, m, deterministic) +} +func (dst *ResyncResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResyncResponse.Merge(dst, src) +} +func (m *ResyncResponse) XXX_Size() int { + return xxx_messageInfo_ResyncResponse.Size(m) +} +func (m *ResyncResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ResyncResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ResyncResponse proto.InternalMessageInfo // Response to notification request 'get'. Returns indexed notification. type NotificationsResponse struct { // Index of following notification NextIdx uint32 `protobuf:"varint,1,opt,name=nextIdx,proto3" json:"nextIdx,omitempty"` // Notification data - NIf *interfaces.InterfaceNotification `protobuf:"bytes,2,opt,name=nIf" json:"nIf,omitempty"` + NIf *interfaces.InterfaceNotification `protobuf:"bytes,2,opt,name=nIf" json:"nIf,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NotificationsResponse) Reset() { *m = NotificationsResponse{} } +func (m *NotificationsResponse) String() string { return proto.CompactTextString(m) } +func (*NotificationsResponse) ProtoMessage() {} +func (*NotificationsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_rpc_4797542838a6c8ba, []int{5} +} +func (m *NotificationsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NotificationsResponse.Unmarshal(m, b) +} +func (m *NotificationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NotificationsResponse.Marshal(b, m, deterministic) +} +func (dst *NotificationsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_NotificationsResponse.Merge(dst, src) +} +func (m *NotificationsResponse) XXX_Size() int { + return xxx_messageInfo_NotificationsResponse.Size(m) +} +func (m *NotificationsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_NotificationsResponse.DiscardUnknown(m) } -func (m *NotificationsResponse) Reset() { *m = NotificationsResponse{} } -func (m *NotificationsResponse) String() string { return proto.CompactTextString(m) } -func (*NotificationsResponse) ProtoMessage() {} -func (*NotificationsResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{5} } +var xxx_messageInfo_NotificationsResponse proto.InternalMessageInfo func (m *NotificationsResponse) GetNextIdx() uint32 { if m != nil { @@ -327,7 +443,7 @@ func NewDataChangeServiceClient(cc *grpc.ClientConn) DataChangeServiceClient { func (c *dataChangeServiceClient) Put(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*PutResponse, error) { out := new(PutResponse) - err := grpc.Invoke(ctx, "/rpc.DataChangeService/Put", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/rpc.DataChangeService/Put", in, out, opts...) if err != nil { return nil, err } @@ -336,7 +452,7 @@ func (c *dataChangeServiceClient) Put(ctx context.Context, in *DataRequest, opts func (c *dataChangeServiceClient) Del(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*DelResponse, error) { out := new(DelResponse) - err := grpc.Invoke(ctx, "/rpc.DataChangeService/Del", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/rpc.DataChangeService/Del", in, out, opts...) if err != nil { return nil, err } @@ -426,7 +542,7 @@ func NewDataResyncServiceClient(cc *grpc.ClientConn) DataResyncServiceClient { func (c *dataResyncServiceClient) Resync(ctx context.Context, in *DataRequest, opts ...grpc.CallOption) (*ResyncResponse, error) { out := new(ResyncResponse) - err := grpc.Invoke(ctx, "/rpc.DataResyncService/Resync", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/rpc.DataResyncService/Resync", in, out, opts...) if err != nil { return nil, err } @@ -491,7 +607,7 @@ func NewNotificationServiceClient(cc *grpc.ClientConn) NotificationServiceClient } func (c *notificationServiceClient) Get(ctx context.Context, in *NotificationRequest, opts ...grpc.CallOption) (NotificationService_GetClient, error) { - stream, err := grpc.NewClientStream(ctx, &_NotificationService_serviceDesc.Streams[0], c.cc, "/rpc.NotificationService/Get", opts...) + stream, err := c.cc.NewStream(ctx, &_NotificationService_serviceDesc.Streams[0], "/rpc.NotificationService/Get", opts...) if err != nil { return nil, err } @@ -568,9 +684,9 @@ var _NotificationService_serviceDesc = grpc.ServiceDesc{ Metadata: "rpc.proto", } -func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } +func init() { proto.RegisterFile("rpc.proto", fileDescriptor_rpc_4797542838a6c8ba) } -var fileDescriptorRpc = []byte{ +var fileDescriptor_rpc_4797542838a6c8ba = []byte{ // 879 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x51, 0x6f, 0x23, 0x35, 0x10, 0x56, 0x09, 0x77, 0xd0, 0x09, 0xed, 0x15, 0xdf, 0x15, 0x99, 0x82, 0x4a, 0xa9, 0x40, 0xb4, diff --git a/plugins/vpp/model/srv6/srv6.pb.go b/plugins/vpp/model/srv6/srv6.pb.go index 4cb8be8f0a..ae5a23ef75 100644 --- a/plugins/vpp/model/srv6/srv6.pb.go +++ b/plugins/vpp/model/srv6/srv6.pb.go @@ -1,18 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: srv6.proto -/* -Package srv6 is a generated protocol buffer package. - -It is generated from these files: - srv6.proto - -It has these top-level messages: - LocalSID - Policy - PolicySegment - Steering -*/ package srv6 import proto "github.com/gogo/protobuf/proto" @@ -34,20 +22,42 @@ type LocalSID struct { Sid string `protobuf:"bytes,1,opt,name=sid,proto3" json:"sid,omitempty"` FibTableId uint32 `protobuf:"varint,2,opt,name=fib_table_id,json=fibTableId,proto3" json:"fib_table_id,omitempty"` // Configuration for end functions (all end functions are mutually exclusive) - BaseEndFunction *LocalSID_End `protobuf:"bytes,3,opt,name=base_end_function,json=baseEndFunction" json:"base_end_function,omitempty"` - EndFunction_X *LocalSID_EndX `protobuf:"bytes,4,opt,name=end_function_X,json=endFunctionX" json:"end_function_X,omitempty"` - EndFunction_T *LocalSID_EndT `protobuf:"bytes,5,opt,name=end_function_T,json=endFunctionT" json:"end_function_T,omitempty"` - EndFunction_DX2 *LocalSID_EndDX2 `protobuf:"bytes,6,opt,name=end_function_DX2,json=endFunctionDX2" json:"end_function_DX2,omitempty"` - EndFunction_DX4 *LocalSID_EndDX4 `protobuf:"bytes,7,opt,name=end_function_DX4,json=endFunctionDX4" json:"end_function_DX4,omitempty"` - EndFunction_DX6 *LocalSID_EndDX6 `protobuf:"bytes,8,opt,name=end_function_DX6,json=endFunctionDX6" json:"end_function_DX6,omitempty"` - EndFunction_DT4 *LocalSID_EndDT4 `protobuf:"bytes,9,opt,name=end_function_DT4,json=endFunctionDT4" json:"end_function_DT4,omitempty"` - EndFunction_DT6 *LocalSID_EndDT6 `protobuf:"bytes,10,opt,name=end_function_DT6,json=endFunctionDT6" json:"end_function_DT6,omitempty"` + BaseEndFunction *LocalSID_End `protobuf:"bytes,3,opt,name=base_end_function,json=baseEndFunction" json:"base_end_function,omitempty"` + EndFunction_X *LocalSID_EndX `protobuf:"bytes,4,opt,name=end_function_X,json=endFunctionX" json:"end_function_X,omitempty"` + EndFunction_T *LocalSID_EndT `protobuf:"bytes,5,opt,name=end_function_T,json=endFunctionT" json:"end_function_T,omitempty"` + EndFunction_DX2 *LocalSID_EndDX2 `protobuf:"bytes,6,opt,name=end_function_DX2,json=endFunctionDX2" json:"end_function_DX2,omitempty"` + EndFunction_DX4 *LocalSID_EndDX4 `protobuf:"bytes,7,opt,name=end_function_DX4,json=endFunctionDX4" json:"end_function_DX4,omitempty"` + EndFunction_DX6 *LocalSID_EndDX6 `protobuf:"bytes,8,opt,name=end_function_DX6,json=endFunctionDX6" json:"end_function_DX6,omitempty"` + EndFunction_DT4 *LocalSID_EndDT4 `protobuf:"bytes,9,opt,name=end_function_DT4,json=endFunctionDT4" json:"end_function_DT4,omitempty"` + EndFunction_DT6 *LocalSID_EndDT6 `protobuf:"bytes,10,opt,name=end_function_DT6,json=endFunctionDT6" json:"end_function_DT6,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *LocalSID) Reset() { *m = LocalSID{} } -func (m *LocalSID) String() string { return proto.CompactTextString(m) } -func (*LocalSID) ProtoMessage() {} -func (*LocalSID) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0} } +func (m *LocalSID) Reset() { *m = LocalSID{} } +func (m *LocalSID) String() string { return proto.CompactTextString(m) } +func (*LocalSID) ProtoMessage() {} +func (*LocalSID) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0} +} +func (m *LocalSID) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID.Unmarshal(m, b) +} +func (m *LocalSID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID.Marshal(b, m, deterministic) +} +func (dst *LocalSID) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID.Merge(dst, src) +} +func (m *LocalSID) XXX_Size() int { + return xxx_messageInfo_LocalSID.Size(m) +} +func (m *LocalSID) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID.DiscardUnknown(m) +} + +var xxx_messageInfo_LocalSID proto.InternalMessageInfo func (m *LocalSID) GetSid() string { if m != nil { @@ -121,13 +131,35 @@ func (m *LocalSID) GetEndFunction_DT6() *LocalSID_EndDT6 { // End function behavior of simple endpoint type LocalSID_End struct { - Psp bool `protobuf:"varint,1,opt,name=psp,proto3" json:"psp,omitempty"` + Psp bool `protobuf:"varint,1,opt,name=psp,proto3" json:"psp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *LocalSID_End) Reset() { *m = LocalSID_End{} } -func (m *LocalSID_End) String() string { return proto.CompactTextString(m) } -func (*LocalSID_End) ProtoMessage() {} -func (*LocalSID_End) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 0} } +func (m *LocalSID_End) Reset() { *m = LocalSID_End{} } +func (m *LocalSID_End) String() string { return proto.CompactTextString(m) } +func (*LocalSID_End) ProtoMessage() {} +func (*LocalSID_End) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 0} +} +func (m *LocalSID_End) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_End.Unmarshal(m, b) +} +func (m *LocalSID_End) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_End.Marshal(b, m, deterministic) +} +func (dst *LocalSID_End) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_End.Merge(dst, src) +} +func (m *LocalSID_End) XXX_Size() int { + return xxx_messageInfo_LocalSID_End.Size(m) +} +func (m *LocalSID_End) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_End.DiscardUnknown(m) +} + +var xxx_messageInfo_LocalSID_End proto.InternalMessageInfo func (m *LocalSID_End) GetPsp() bool { if m != nil { @@ -138,15 +170,37 @@ func (m *LocalSID_End) GetPsp() bool { // End function behavior of endpoint with Layer-3 cross-connect type LocalSID_EndX struct { - Psp bool `protobuf:"varint,1,opt,name=psp,proto3" json:"psp,omitempty"` - OutgoingInterface string `protobuf:"bytes,2,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` - NextHop string `protobuf:"bytes,3,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + Psp bool `protobuf:"varint,1,opt,name=psp,proto3" json:"psp,omitempty"` + OutgoingInterface string `protobuf:"bytes,2,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` + NextHop string `protobuf:"bytes,3,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LocalSID_EndX) Reset() { *m = LocalSID_EndX{} } +func (m *LocalSID_EndX) String() string { return proto.CompactTextString(m) } +func (*LocalSID_EndX) ProtoMessage() {} +func (*LocalSID_EndX) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 1} +} +func (m *LocalSID_EndX) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_EndX.Unmarshal(m, b) +} +func (m *LocalSID_EndX) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_EndX.Marshal(b, m, deterministic) +} +func (dst *LocalSID_EndX) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_EndX.Merge(dst, src) +} +func (m *LocalSID_EndX) XXX_Size() int { + return xxx_messageInfo_LocalSID_EndX.Size(m) +} +func (m *LocalSID_EndX) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_EndX.DiscardUnknown(m) } -func (m *LocalSID_EndX) Reset() { *m = LocalSID_EndX{} } -func (m *LocalSID_EndX) String() string { return proto.CompactTextString(m) } -func (*LocalSID_EndX) ProtoMessage() {} -func (*LocalSID_EndX) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 1} } +var xxx_messageInfo_LocalSID_EndX proto.InternalMessageInfo func (m *LocalSID_EndX) GetPsp() bool { if m != nil { @@ -171,13 +225,35 @@ func (m *LocalSID_EndX) GetNextHop() string { // End function behavior of endpoint with specific IPv6 table lookup type LocalSID_EndT struct { - Psp bool `protobuf:"varint,1,opt,name=psp,proto3" json:"psp,omitempty"` + Psp bool `protobuf:"varint,1,opt,name=psp,proto3" json:"psp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *LocalSID_EndT) Reset() { *m = LocalSID_EndT{} } -func (m *LocalSID_EndT) String() string { return proto.CompactTextString(m) } -func (*LocalSID_EndT) ProtoMessage() {} -func (*LocalSID_EndT) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 2} } +func (m *LocalSID_EndT) Reset() { *m = LocalSID_EndT{} } +func (m *LocalSID_EndT) String() string { return proto.CompactTextString(m) } +func (*LocalSID_EndT) ProtoMessage() {} +func (*LocalSID_EndT) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 2} +} +func (m *LocalSID_EndT) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_EndT.Unmarshal(m, b) +} +func (m *LocalSID_EndT) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_EndT.Marshal(b, m, deterministic) +} +func (dst *LocalSID_EndT) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_EndT.Merge(dst, src) +} +func (m *LocalSID_EndT) XXX_Size() int { + return xxx_messageInfo_LocalSID_EndT.Size(m) +} +func (m *LocalSID_EndT) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_EndT.DiscardUnknown(m) +} + +var xxx_messageInfo_LocalSID_EndT proto.InternalMessageInfo func (m *LocalSID_EndT) GetPsp() bool { if m != nil { @@ -188,15 +264,37 @@ func (m *LocalSID_EndT) GetPsp() bool { // End function nehavior of endpoint with decapsulation and Layer-2 cross-connect (or DX2 with egress VLAN rewrite when VLAN notzero - not supported this variant yet) type LocalSID_EndDX2 struct { - VlanTag uint32 `protobuf:"varint,1,opt,name=vlan_tag,json=vlanTag,proto3" json:"vlan_tag,omitempty"` - OutgoingInterface string `protobuf:"bytes,2,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` - NextHop string `protobuf:"bytes,3,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + VlanTag uint32 `protobuf:"varint,1,opt,name=vlan_tag,json=vlanTag,proto3" json:"vlan_tag,omitempty"` + OutgoingInterface string `protobuf:"bytes,2,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` + NextHop string `protobuf:"bytes,3,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LocalSID_EndDX2) Reset() { *m = LocalSID_EndDX2{} } +func (m *LocalSID_EndDX2) String() string { return proto.CompactTextString(m) } +func (*LocalSID_EndDX2) ProtoMessage() {} +func (*LocalSID_EndDX2) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 3} +} +func (m *LocalSID_EndDX2) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_EndDX2.Unmarshal(m, b) +} +func (m *LocalSID_EndDX2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_EndDX2.Marshal(b, m, deterministic) +} +func (dst *LocalSID_EndDX2) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_EndDX2.Merge(dst, src) +} +func (m *LocalSID_EndDX2) XXX_Size() int { + return xxx_messageInfo_LocalSID_EndDX2.Size(m) +} +func (m *LocalSID_EndDX2) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_EndDX2.DiscardUnknown(m) } -func (m *LocalSID_EndDX2) Reset() { *m = LocalSID_EndDX2{} } -func (m *LocalSID_EndDX2) String() string { return proto.CompactTextString(m) } -func (*LocalSID_EndDX2) ProtoMessage() {} -func (*LocalSID_EndDX2) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 3} } +var xxx_messageInfo_LocalSID_EndDX2 proto.InternalMessageInfo func (m *LocalSID_EndDX2) GetVlanTag() uint32 { if m != nil { @@ -221,14 +319,36 @@ func (m *LocalSID_EndDX2) GetNextHop() string { // End function behavior of endpoint with decapsulation and IPv4 cross-connect type LocalSID_EndDX4 struct { - OutgoingInterface string `protobuf:"bytes,1,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` - NextHop string `protobuf:"bytes,2,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + OutgoingInterface string `protobuf:"bytes,1,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` + NextHop string `protobuf:"bytes,2,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LocalSID_EndDX4) Reset() { *m = LocalSID_EndDX4{} } +func (m *LocalSID_EndDX4) String() string { return proto.CompactTextString(m) } +func (*LocalSID_EndDX4) ProtoMessage() {} +func (*LocalSID_EndDX4) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 4} +} +func (m *LocalSID_EndDX4) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_EndDX4.Unmarshal(m, b) +} +func (m *LocalSID_EndDX4) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_EndDX4.Marshal(b, m, deterministic) +} +func (dst *LocalSID_EndDX4) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_EndDX4.Merge(dst, src) +} +func (m *LocalSID_EndDX4) XXX_Size() int { + return xxx_messageInfo_LocalSID_EndDX4.Size(m) +} +func (m *LocalSID_EndDX4) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_EndDX4.DiscardUnknown(m) } -func (m *LocalSID_EndDX4) Reset() { *m = LocalSID_EndDX4{} } -func (m *LocalSID_EndDX4) String() string { return proto.CompactTextString(m) } -func (*LocalSID_EndDX4) ProtoMessage() {} -func (*LocalSID_EndDX4) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 4} } +var xxx_messageInfo_LocalSID_EndDX4 proto.InternalMessageInfo func (m *LocalSID_EndDX4) GetOutgoingInterface() string { if m != nil { @@ -246,14 +366,36 @@ func (m *LocalSID_EndDX4) GetNextHop() string { // End function behavior of endpoint with decapsulation and IPv6 cross-connect type LocalSID_EndDX6 struct { - OutgoingInterface string `protobuf:"bytes,1,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` - NextHop string `protobuf:"bytes,2,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + OutgoingInterface string `protobuf:"bytes,1,opt,name=outgoing_interface,json=outgoingInterface,proto3" json:"outgoing_interface,omitempty"` + NextHop string `protobuf:"bytes,2,opt,name=next_hop,json=nextHop,proto3" json:"next_hop,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LocalSID_EndDX6) Reset() { *m = LocalSID_EndDX6{} } +func (m *LocalSID_EndDX6) String() string { return proto.CompactTextString(m) } +func (*LocalSID_EndDX6) ProtoMessage() {} +func (*LocalSID_EndDX6) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 5} +} +func (m *LocalSID_EndDX6) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_EndDX6.Unmarshal(m, b) +} +func (m *LocalSID_EndDX6) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_EndDX6.Marshal(b, m, deterministic) +} +func (dst *LocalSID_EndDX6) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_EndDX6.Merge(dst, src) +} +func (m *LocalSID_EndDX6) XXX_Size() int { + return xxx_messageInfo_LocalSID_EndDX6.Size(m) +} +func (m *LocalSID_EndDX6) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_EndDX6.DiscardUnknown(m) } -func (m *LocalSID_EndDX6) Reset() { *m = LocalSID_EndDX6{} } -func (m *LocalSID_EndDX6) String() string { return proto.CompactTextString(m) } -func (*LocalSID_EndDX6) ProtoMessage() {} -func (*LocalSID_EndDX6) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 5} } +var xxx_messageInfo_LocalSID_EndDX6 proto.InternalMessageInfo func (m *LocalSID_EndDX6) GetOutgoingInterface() string { if m != nil { @@ -271,34 +413,100 @@ func (m *LocalSID_EndDX6) GetNextHop() string { // End function behavior of endpoint with decapsulation and specific IPv4 table lookup type LocalSID_EndDT4 struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *LocalSID_EndDT4) Reset() { *m = LocalSID_EndDT4{} } -func (m *LocalSID_EndDT4) String() string { return proto.CompactTextString(m) } -func (*LocalSID_EndDT4) ProtoMessage() {} -func (*LocalSID_EndDT4) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 6} } +func (m *LocalSID_EndDT4) Reset() { *m = LocalSID_EndDT4{} } +func (m *LocalSID_EndDT4) String() string { return proto.CompactTextString(m) } +func (*LocalSID_EndDT4) ProtoMessage() {} +func (*LocalSID_EndDT4) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 6} +} +func (m *LocalSID_EndDT4) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_EndDT4.Unmarshal(m, b) +} +func (m *LocalSID_EndDT4) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_EndDT4.Marshal(b, m, deterministic) +} +func (dst *LocalSID_EndDT4) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_EndDT4.Merge(dst, src) +} +func (m *LocalSID_EndDT4) XXX_Size() int { + return xxx_messageInfo_LocalSID_EndDT4.Size(m) +} +func (m *LocalSID_EndDT4) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_EndDT4.DiscardUnknown(m) +} + +var xxx_messageInfo_LocalSID_EndDT4 proto.InternalMessageInfo // End function behavior of endpoint with decapsulation and specific IPv6 table lookup type LocalSID_EndDT6 struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *LocalSID_EndDT6) Reset() { *m = LocalSID_EndDT6{} } -func (m *LocalSID_EndDT6) String() string { return proto.CompactTextString(m) } -func (*LocalSID_EndDT6) ProtoMessage() {} -func (*LocalSID_EndDT6) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{0, 7} } +func (m *LocalSID_EndDT6) Reset() { *m = LocalSID_EndDT6{} } +func (m *LocalSID_EndDT6) String() string { return proto.CompactTextString(m) } +func (*LocalSID_EndDT6) ProtoMessage() {} +func (*LocalSID_EndDT6) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{0, 7} +} +func (m *LocalSID_EndDT6) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LocalSID_EndDT6.Unmarshal(m, b) +} +func (m *LocalSID_EndDT6) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LocalSID_EndDT6.Marshal(b, m, deterministic) +} +func (dst *LocalSID_EndDT6) XXX_Merge(src proto.Message) { + xxx_messageInfo_LocalSID_EndDT6.Merge(dst, src) +} +func (m *LocalSID_EndDT6) XXX_Size() int { + return xxx_messageInfo_LocalSID_EndDT6.Size(m) +} +func (m *LocalSID_EndDT6) XXX_DiscardUnknown() { + xxx_messageInfo_LocalSID_EndDT6.DiscardUnknown(m) +} + +var xxx_messageInfo_LocalSID_EndDT6 proto.InternalMessageInfo // Model for SRv6 policy (policy without at least one policy segment is only cached in ligato and not written to VPP) type Policy struct { - Bsid string `protobuf:"bytes,1,opt,name=bsid,proto3" json:"bsid,omitempty"` - FibTableId uint32 `protobuf:"varint,2,opt,name=fib_table_id,json=fibTableId,proto3" json:"fib_table_id,omitempty"` - SrhEncapsulation bool `protobuf:"varint,3,opt,name=srh_encapsulation,json=srhEncapsulation,proto3" json:"srh_encapsulation,omitempty"` - SprayBehaviour bool `protobuf:"varint,4,opt,name=spray_behaviour,json=sprayBehaviour,proto3" json:"spray_behaviour,omitempty"` + Bsid string `protobuf:"bytes,1,opt,name=bsid,proto3" json:"bsid,omitempty"` + FibTableId uint32 `protobuf:"varint,2,opt,name=fib_table_id,json=fibTableId,proto3" json:"fib_table_id,omitempty"` + SrhEncapsulation bool `protobuf:"varint,3,opt,name=srh_encapsulation,json=srhEncapsulation,proto3" json:"srh_encapsulation,omitempty"` + SprayBehaviour bool `protobuf:"varint,4,opt,name=spray_behaviour,json=sprayBehaviour,proto3" json:"spray_behaviour,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Policy) Reset() { *m = Policy{} } +func (m *Policy) String() string { return proto.CompactTextString(m) } +func (*Policy) ProtoMessage() {} +func (*Policy) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{1} +} +func (m *Policy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Policy.Unmarshal(m, b) +} +func (m *Policy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Policy.Marshal(b, m, deterministic) +} +func (dst *Policy) XXX_Merge(src proto.Message) { + xxx_messageInfo_Policy.Merge(dst, src) +} +func (m *Policy) XXX_Size() int { + return xxx_messageInfo_Policy.Size(m) +} +func (m *Policy) XXX_DiscardUnknown() { + xxx_messageInfo_Policy.DiscardUnknown(m) } -func (m *Policy) Reset() { *m = Policy{} } -func (m *Policy) String() string { return proto.CompactTextString(m) } -func (*Policy) ProtoMessage() {} -func (*Policy) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{1} } +var xxx_messageInfo_Policy proto.InternalMessageInfo func (m *Policy) GetBsid() string { if m != nil { @@ -330,15 +538,37 @@ func (m *Policy) GetSprayBehaviour() bool { // Model for segment of SRv6 policy (etcd key for segment has as prefix the etcd key for policy where it belongs) type PolicySegment struct { - PolicyBsid string `protobuf:"bytes,1,opt,name=policy_bsid,json=policyBsid,proto3" json:"policy_bsid,omitempty"` - Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` - Segments []string `protobuf:"bytes,3,rep,name=segments" json:"segments,omitempty"` + PolicyBsid string `protobuf:"bytes,1,opt,name=policy_bsid,json=policyBsid,proto3" json:"policy_bsid,omitempty"` + Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` + Segments []string `protobuf:"bytes,3,rep,name=segments" json:"segments,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *PolicySegment) Reset() { *m = PolicySegment{} } -func (m *PolicySegment) String() string { return proto.CompactTextString(m) } -func (*PolicySegment) ProtoMessage() {} -func (*PolicySegment) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{2} } +func (m *PolicySegment) Reset() { *m = PolicySegment{} } +func (m *PolicySegment) String() string { return proto.CompactTextString(m) } +func (*PolicySegment) ProtoMessage() {} +func (*PolicySegment) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{2} +} +func (m *PolicySegment) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PolicySegment.Unmarshal(m, b) +} +func (m *PolicySegment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PolicySegment.Marshal(b, m, deterministic) +} +func (dst *PolicySegment) XXX_Merge(src proto.Message) { + xxx_messageInfo_PolicySegment.Merge(dst, src) +} +func (m *PolicySegment) XXX_Size() int { + return xxx_messageInfo_PolicySegment.Size(m) +} +func (m *PolicySegment) XXX_DiscardUnknown() { + xxx_messageInfo_PolicySegment.DiscardUnknown(m) +} + +var xxx_messageInfo_PolicySegment proto.InternalMessageInfo func (m *PolicySegment) GetPolicyBsid() string { if m != nil { @@ -366,14 +596,36 @@ type Steering struct { PolicyBsid string `protobuf:"bytes,1,opt,name=policy_bsid,json=policyBsid,proto3" json:"policy_bsid,omitempty"` PolicyIndex uint32 `protobuf:"varint,2,opt,name=policy_index,json=policyIndex,proto3" json:"policy_index,omitempty"` // Traffic configuration (all traffic messages are mutual exclusive) - L2Traffic *Steering_L2Traffic `protobuf:"bytes,3,opt,name=l2_traffic,json=l2Traffic" json:"l2_traffic,omitempty"` - L3Traffic *Steering_L3Traffic `protobuf:"bytes,4,opt,name=l3_traffic,json=l3Traffic" json:"l3_traffic,omitempty"` + L2Traffic *Steering_L2Traffic `protobuf:"bytes,3,opt,name=l2_traffic,json=l2Traffic" json:"l2_traffic,omitempty"` + L3Traffic *Steering_L3Traffic `protobuf:"bytes,4,opt,name=l3_traffic,json=l3Traffic" json:"l3_traffic,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Steering) Reset() { *m = Steering{} } +func (m *Steering) String() string { return proto.CompactTextString(m) } +func (*Steering) ProtoMessage() {} +func (*Steering) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{3} +} +func (m *Steering) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Steering.Unmarshal(m, b) +} +func (m *Steering) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Steering.Marshal(b, m, deterministic) +} +func (dst *Steering) XXX_Merge(src proto.Message) { + xxx_messageInfo_Steering.Merge(dst, src) +} +func (m *Steering) XXX_Size() int { + return xxx_messageInfo_Steering.Size(m) +} +func (m *Steering) XXX_DiscardUnknown() { + xxx_messageInfo_Steering.DiscardUnknown(m) } -func (m *Steering) Reset() { *m = Steering{} } -func (m *Steering) String() string { return proto.CompactTextString(m) } -func (*Steering) ProtoMessage() {} -func (*Steering) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{3} } +var xxx_messageInfo_Steering proto.InternalMessageInfo func (m *Steering) GetPolicyBsid() string { if m != nil { @@ -404,13 +656,35 @@ func (m *Steering) GetL3Traffic() *Steering_L3Traffic { } type Steering_L2Traffic struct { - InterfaceName string `protobuf:"bytes,1,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"` + InterfaceName string `protobuf:"bytes,1,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Steering_L2Traffic) Reset() { *m = Steering_L2Traffic{} } +func (m *Steering_L2Traffic) String() string { return proto.CompactTextString(m) } +func (*Steering_L2Traffic) ProtoMessage() {} +func (*Steering_L2Traffic) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{3, 0} +} +func (m *Steering_L2Traffic) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Steering_L2Traffic.Unmarshal(m, b) +} +func (m *Steering_L2Traffic) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Steering_L2Traffic.Marshal(b, m, deterministic) +} +func (dst *Steering_L2Traffic) XXX_Merge(src proto.Message) { + xxx_messageInfo_Steering_L2Traffic.Merge(dst, src) +} +func (m *Steering_L2Traffic) XXX_Size() int { + return xxx_messageInfo_Steering_L2Traffic.Size(m) +} +func (m *Steering_L2Traffic) XXX_DiscardUnknown() { + xxx_messageInfo_Steering_L2Traffic.DiscardUnknown(m) } -func (m *Steering_L2Traffic) Reset() { *m = Steering_L2Traffic{} } -func (m *Steering_L2Traffic) String() string { return proto.CompactTextString(m) } -func (*Steering_L2Traffic) ProtoMessage() {} -func (*Steering_L2Traffic) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{3, 0} } +var xxx_messageInfo_Steering_L2Traffic proto.InternalMessageInfo func (m *Steering_L2Traffic) GetInterfaceName() string { if m != nil { @@ -420,14 +694,36 @@ func (m *Steering_L2Traffic) GetInterfaceName() string { } type Steering_L3Traffic struct { - FibTableId uint32 `protobuf:"varint,1,opt,name=fib_table_id,json=fibTableId,proto3" json:"fib_table_id,omitempty"` - PrefixAddress string `protobuf:"bytes,2,opt,name=prefix_address,json=prefixAddress,proto3" json:"prefix_address,omitempty"` + FibTableId uint32 `protobuf:"varint,1,opt,name=fib_table_id,json=fibTableId,proto3" json:"fib_table_id,omitempty"` + PrefixAddress string `protobuf:"bytes,2,opt,name=prefix_address,json=prefixAddress,proto3" json:"prefix_address,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Steering_L3Traffic) Reset() { *m = Steering_L3Traffic{} } +func (m *Steering_L3Traffic) String() string { return proto.CompactTextString(m) } +func (*Steering_L3Traffic) ProtoMessage() {} +func (*Steering_L3Traffic) Descriptor() ([]byte, []int) { + return fileDescriptor_srv6_b35bd010c3b9f84d, []int{3, 1} +} +func (m *Steering_L3Traffic) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Steering_L3Traffic.Unmarshal(m, b) +} +func (m *Steering_L3Traffic) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Steering_L3Traffic.Marshal(b, m, deterministic) +} +func (dst *Steering_L3Traffic) XXX_Merge(src proto.Message) { + xxx_messageInfo_Steering_L3Traffic.Merge(dst, src) +} +func (m *Steering_L3Traffic) XXX_Size() int { + return xxx_messageInfo_Steering_L3Traffic.Size(m) +} +func (m *Steering_L3Traffic) XXX_DiscardUnknown() { + xxx_messageInfo_Steering_L3Traffic.DiscardUnknown(m) } -func (m *Steering_L3Traffic) Reset() { *m = Steering_L3Traffic{} } -func (m *Steering_L3Traffic) String() string { return proto.CompactTextString(m) } -func (*Steering_L3Traffic) ProtoMessage() {} -func (*Steering_L3Traffic) Descriptor() ([]byte, []int) { return fileDescriptorSrv6, []int{3, 1} } +var xxx_messageInfo_Steering_L3Traffic proto.InternalMessageInfo func (m *Steering_L3Traffic) GetFibTableId() uint32 { if m != nil { @@ -460,9 +756,9 @@ func init() { proto.RegisterType((*Steering_L3Traffic)(nil), "srv6.Steering.L3Traffic") } -func init() { proto.RegisterFile("srv6.proto", fileDescriptorSrv6) } +func init() { proto.RegisterFile("srv6.proto", fileDescriptor_srv6_b35bd010c3b9f84d) } -var fileDescriptorSrv6 = []byte{ +var fileDescriptor_srv6_b35bd010c3b9f84d = []byte{ // 626 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0xcf, 0x6e, 0xd3, 0x40, 0x10, 0xc6, 0xe5, 0x26, 0x24, 0xf6, 0xb4, 0x49, 0xdb, 0x45, 0x80, 0xc9, 0x85, 0x10, 0xa9, 0x22, diff --git a/plugins/vpp/model/stn/stn.pb.go b/plugins/vpp/model/stn/stn.pb.go index 802e4349cd..4248d73bb8 100644 --- a/plugins/vpp/model/stn/stn.pb.go +++ b/plugins/vpp/model/stn/stn.pb.go @@ -1,15 +1,6 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: stn.proto -/* -Package stn is a generated protocol buffer package. - -It is generated from these files: - stn.proto - -It has these top-level messages: - STN -*/ package stn import proto "github.com/gogo/protobuf/proto" @@ -28,13 +19,35 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package type STN struct { - Rules []*STN_Rule `protobuf:"bytes,1,rep,name=rules" json:"rules,omitempty"` + Rules []*STN_Rule `protobuf:"bytes,1,rep,name=rules" json:"rules,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *STN) Reset() { *m = STN{} } +func (m *STN) String() string { return proto.CompactTextString(m) } +func (*STN) ProtoMessage() {} +func (*STN) Descriptor() ([]byte, []int) { + return fileDescriptor_stn_0bc0f61bd7e72bf0, []int{0} +} +func (m *STN) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_STN.Unmarshal(m, b) +} +func (m *STN) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_STN.Marshal(b, m, deterministic) +} +func (dst *STN) XXX_Merge(src proto.Message) { + xxx_messageInfo_STN.Merge(dst, src) +} +func (m *STN) XXX_Size() int { + return xxx_messageInfo_STN.Size(m) +} +func (m *STN) XXX_DiscardUnknown() { + xxx_messageInfo_STN.DiscardUnknown(m) } -func (m *STN) Reset() { *m = STN{} } -func (m *STN) String() string { return proto.CompactTextString(m) } -func (*STN) ProtoMessage() {} -func (*STN) Descriptor() ([]byte, []int) { return fileDescriptorStn, []int{0} } +var xxx_messageInfo_STN proto.InternalMessageInfo func (m *STN) GetRules() []*STN_Rule { if m != nil { @@ -44,15 +57,37 @@ func (m *STN) GetRules() []*STN_Rule { } type STN_Rule struct { - RuleName string `protobuf:"bytes,3,opt,name=rule_name,json=ruleName,proto3" json:"rule_name,omitempty"` - IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - Interface string `protobuf:"bytes,2,opt,name=interface,proto3" json:"interface,omitempty"` + RuleName string `protobuf:"bytes,3,opt,name=rule_name,json=ruleName,proto3" json:"rule_name,omitempty"` + IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + Interface string `protobuf:"bytes,2,opt,name=interface,proto3" json:"interface,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *STN_Rule) Reset() { *m = STN_Rule{} } +func (m *STN_Rule) String() string { return proto.CompactTextString(m) } +func (*STN_Rule) ProtoMessage() {} +func (*STN_Rule) Descriptor() ([]byte, []int) { + return fileDescriptor_stn_0bc0f61bd7e72bf0, []int{0, 0} +} +func (m *STN_Rule) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_STN_Rule.Unmarshal(m, b) +} +func (m *STN_Rule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_STN_Rule.Marshal(b, m, deterministic) +} +func (dst *STN_Rule) XXX_Merge(src proto.Message) { + xxx_messageInfo_STN_Rule.Merge(dst, src) +} +func (m *STN_Rule) XXX_Size() int { + return xxx_messageInfo_STN_Rule.Size(m) +} +func (m *STN_Rule) XXX_DiscardUnknown() { + xxx_messageInfo_STN_Rule.DiscardUnknown(m) } -func (m *STN_Rule) Reset() { *m = STN_Rule{} } -func (m *STN_Rule) String() string { return proto.CompactTextString(m) } -func (*STN_Rule) ProtoMessage() {} -func (*STN_Rule) Descriptor() ([]byte, []int) { return fileDescriptorStn, []int{0, 0} } +var xxx_messageInfo_STN_Rule proto.InternalMessageInfo func (m *STN_Rule) GetRuleName() string { if m != nil { @@ -80,9 +115,9 @@ func init() { proto.RegisterType((*STN_Rule)(nil), "stn.STN.Rule") } -func init() { proto.RegisterFile("stn.proto", fileDescriptorStn) } +func init() { proto.RegisterFile("stn.proto", fileDescriptor_stn_0bc0f61bd7e72bf0) } -var fileDescriptorStn = []byte{ +var fileDescriptor_stn_0bc0f61bd7e72bf0 = []byte{ // 156 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2c, 0x2e, 0xc9, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2e, 0x2e, 0xc9, 0x53, 0xea, 0x61, 0xe4, 0x62, 0x0e, diff --git a/plugins/vpp/plugin_impl_vpp.go b/plugins/vpp/plugin_impl_vpp.go index 6951e19c9c..ff8fc8ada4 100644 --- a/plugins/vpp/plugin_impl_vpp.go +++ b/plugins/vpp/plugin_impl_vpp.go @@ -129,9 +129,8 @@ type Plugin struct { omittedPrefixes []string // list of keys which won't be resynced // From config file - enableStopwatch bool - ifMtu uint32 - resyncStrategy string + ifMtu uint32 + resyncStrategy string // Common statusCheckReg bool @@ -161,7 +160,6 @@ type Deps struct { // Config holds the vpp-plugin configuration. type Config struct { Mtu uint32 `json:"mtu"` - Stopwatch bool `json:"stopwatch"` Strategy string `json:"strategy"` StatusPublishers []string `json:"status-publishers"` } @@ -416,8 +414,8 @@ func (plugin *Plugin) initIF(ctx context.Context) error { // Interface configurator plugin.ifVppNotifChan = make(chan govppapi.Message, 100) plugin.ifConfigurator = &ifplugin.InterfaceConfigurator{} - if err := plugin.ifConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.Linux, plugin.ifVppNotifChan, plugin.ifMtu, plugin.enableStopwatch); err != nil { - return err + if err := plugin.ifConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.Linux, plugin.ifVppNotifChan, plugin.ifMtu); err != nil { + return plugin.ifConfigurator.LogError(err) } plugin.Log.Debug("ifConfigurator Initialized") @@ -428,35 +426,37 @@ func (plugin *Plugin) initIF(ctx context.Context) error { } // Interface state updater plugin.ifStateUpdater = &ifplugin.InterfaceStateUpdater{} - plugin.ifStateUpdater.Init(ctx, plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.ifVppNotifChan, func(state *intf.InterfaceNotification) { + if err := plugin.ifStateUpdater.Init(ctx, plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.ifVppNotifChan, func(state *intf.InterfaceNotification) { select { case plugin.ifStateChan <- state: // OK default: plugin.Log.Debug("Unable to send to the ifStateNotifications channel - channel buffer full.") } - }) + }); err != nil { + return plugin.ifStateUpdater.LogError(err) + } plugin.Log.Debug("ifStateUpdater Initialized") // BFD configurator plugin.bfdConfigurator = &ifplugin.BFDConfigurator{} - if err := plugin.bfdConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.bfdConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.bfdConfigurator.LogError(err) } plugin.Log.Debug("bfdConfigurator Initialized") // STN configurator plugin.stnConfigurator = &ifplugin.StnConfigurator{} - if err := plugin.stnConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.stnConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.stnConfigurator.LogError(err) } plugin.Log.Debug("stnConfigurator Initialized") // NAT configurator plugin.natConfigurator = &ifplugin.NatConfigurator{} - if err := plugin.natConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.natConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.natConfigurator.LogError(err) } plugin.Log.Debug("natConfigurator Initialized") @@ -468,8 +468,8 @@ func (plugin *Plugin) initIPSec(ctx context.Context) (err error) { // IPSec configurator plugin.ipSecConfigurator = &ipsecplugin.IPSecConfigurator{} - if err = plugin.ipSecConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err = plugin.ipSecConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.ipSecConfigurator.LogError(err) } plugin.Log.Debug("ipSecConfigurator Initialized") @@ -481,9 +481,9 @@ func (plugin *Plugin) initACL(ctx context.Context) error { // ACL configurator plugin.aclConfigurator = &aclplugin.ACLConfigurator{} - err := plugin.aclConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch) + err := plugin.aclConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes) if err != nil { - return err + return plugin.aclConfigurator.LogError(err) } plugin.Log.Debug("aclConfigurator Initialized") @@ -496,9 +496,9 @@ func (plugin *Plugin) initL2(ctx context.Context) error { // Bridge domain configurator plugin.bdVppNotifChan = make(chan l2plugin.BridgeDomainStateMessage, 100) plugin.bdConfigurator = &l2plugin.BDConfigurator{} - err := plugin.bdConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.bdVppNotifChan, plugin.enableStopwatch) + err := plugin.bdConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.bdVppNotifChan) if err != nil { - return err + return plugin.bdConfigurator.LogError(err) } plugin.Log.Debug("bdConfigurator Initialized") @@ -516,20 +516,20 @@ func (plugin *Plugin) initL2(ctx context.Context) error { plugin.Log.Debug("Unable to send to the bdState channel: buffer is full.") } }); err != nil { - return err + return plugin.bdStateUpdater.LogError(err) } // L2 FIB configurator plugin.fibConfigurator = &l2plugin.FIBConfigurator{} - if err := plugin.fibConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.bdIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.fibConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.bdIndexes); err != nil { + return plugin.fibConfigurator.LogError(err) } plugin.Log.Debug("fibConfigurator Initialized") // L2 cross connect plugin.xcConfigurator = &l2plugin.XConnectConfigurator{} - if err := plugin.xcConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.xcConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.xcConfigurator.LogError(err) } plugin.Log.Debug("xcConfigurator Initialized") @@ -541,29 +541,29 @@ func (plugin *Plugin) initL3(ctx context.Context) error { // ARP configurator plugin.arpConfigurator = &l3plugin.ArpConfigurator{} - if err := plugin.arpConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.arpConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.arpConfigurator.LogError(err) } plugin.Log.Debug("arpConfigurator Initialized") // Proxy ARP configurator plugin.proxyArpConfigurator = &l3plugin.ProxyArpConfigurator{} - if err := plugin.proxyArpConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.proxyArpConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.proxyArpConfigurator.LogError(err) } plugin.Log.Debug("proxyArpConfigurator Initialized") // Route configurator plugin.routeConfigurator = &l3plugin.RouteConfigurator{} - if err := plugin.routeConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.routeConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.routeConfigurator.LogError(err) } plugin.Log.Debug("routeConfigurator Initialized") // IP neighbor configurator plugin.ipNeighConfigurator = &l3plugin.IPNeighConfigurator{} - if err := plugin.ipNeighConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.enableStopwatch); err != nil { - return err + if err := plugin.ipNeighConfigurator.Init(plugin.Log, plugin.GoVppmux); err != nil { + return plugin.ipNeighConfigurator.LogError(err) } plugin.Log.Debug("ipNeighConfigurator Initialized") @@ -575,8 +575,8 @@ func (plugin *Plugin) initL4(ctx context.Context) error { // Application namespace configurator plugin.appNsConfigurator = &l4plugin.AppNsConfigurator{} - if err := plugin.appNsConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch); err != nil { - return err + if err := plugin.appNsConfigurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes); err != nil { + return plugin.appNsConfigurator.LogError(err) } plugin.Log.Debug("l4Configurator Initialized") @@ -588,8 +588,8 @@ func (plugin *Plugin) initSR(ctx context.Context) (err error) { // Init SR configurator plugin.srv6Configurator = &srplugin.SRv6Configurator{} - if err := plugin.srv6Configurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, plugin.enableStopwatch, nil); err != nil { - return err + if err := plugin.srv6Configurator.Init(plugin.Log, plugin.GoVppmux, plugin.swIfIndexes, nil); err != nil { + return plugin.srv6Configurator.LogError(err) } plugin.Log.Debug("SRConfigurator Initialized") @@ -597,7 +597,7 @@ func (plugin *Plugin) initSR(ctx context.Context) (err error) { } func (plugin *Plugin) initErrorHandler() error { - ehLogger := plugin.Log.NewLogger("-error-handler") + ehLogger := plugin.Log.NewLogger("error-handler") plugin.errorIndexes = nametoidx.NewNameToIdx(ehLogger, "error_indexes", nil) // Init mapping index @@ -627,18 +627,10 @@ func (plugin *Plugin) fromConfigFile() { plugin.ifMtu = config.Mtu plugin.Log.Infof("Default MTU set to %v", plugin.ifMtu) } - - if config.Stopwatch { - plugin.enableStopwatch = true - plugin.Log.Info("stopwatch enabled for VPP plugins") - } else { - plugin.Log.Info("stopwatch disabled VPP plugins") - } // return skip (if set) or value from config plugin.resyncStrategy = plugin.resolveResyncStrategy(config.Strategy) plugin.Log.Infof("VPP resync strategy is set to %v", plugin.resyncStrategy) } else { - plugin.Log.Infof("stopwatch disabled for %v", plugin.PluginName) // return skip (if set) or full plugin.resyncStrategy = plugin.resolveResyncStrategy(fullResync) plugin.Log.Infof("VPP resync strategy config not found, set to %v", plugin.resyncStrategy) diff --git a/plugins/vpp/rpc/services.go b/plugins/vpp/rpc/services.go index 7c11b9d5d6..45640c3c27 100644 --- a/plugins/vpp/rpc/services.go +++ b/plugins/vpp/rpc/services.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/rpc --proto_path=$GOPATH/src --gogo_out=plugins=grpc:../model/rpc ../model/rpc/rpc.proto - package rpc import ( @@ -64,15 +62,8 @@ func (plugin *Plugin) Init() error { // Notification service (represents GRPC client) plugin.notifSvc.log = plugin.Log.NewLogger("notifSvc") - return nil -} - -// AfterInit registers all GRPC services in vppscv package -// (be sure that defaultvppplugins are completely initialized). -func (plugin *Plugin) AfterInit() error { - if plugin.GRPCServer == nil { - return nil - } + // Register all GRPC services if server is available. Register needs to be done + // before 'ListenAndServe' is called in GRPC plugin grpcServer := plugin.GRPCServer.GetServer() if grpcServer != nil { rpc.RegisterDataChangeServiceServer(grpcServer, &plugin.changeVppSvc) diff --git a/plugins/vpp/srplugin/data_resync.go b/plugins/vpp/srplugin/data_resync.go index 25855196fe..f0b28348b3 100644 --- a/plugins/vpp/srplugin/data_resync.go +++ b/plugins/vpp/srplugin/data_resync.go @@ -15,6 +15,7 @@ package srplugin import ( + "github.com/go-errors/errors" "github.com/ligato/vpp-agent/plugins/vpp/model/srv6" ) @@ -32,42 +33,36 @@ type NamedSteering struct { } // Resync writes missing segment routing configs to the VPP and removes obsolete ones. -func (plugin *SRv6Configurator) Resync(localSids []*srv6.LocalSID, policies []*srv6.Policy, namedSegments []*NamedPolicySegment, namedSteerings []*NamedSteering) error { - plugin.log.Debug("RESYNC SR begin.") - +func (c *SRv6Configurator) Resync(localSids []*srv6.LocalSID, policies []*srv6.Policy, namedSegments []*NamedPolicySegment, namedSteerings []*NamedSteering) error { // Re-initialize cache - plugin.clearMapping() + c.clearMapping() // TODO: dump existing configuration from VPP, compare it with etcd and change vpp according to etcd (now is handled only case when VPP is clean, i.e. from starting) for _, localsid := range localSids { - if err := plugin.AddLocalSID(localsid); err != nil { - plugin.log.Error(err) - continue + if err := c.AddLocalSID(localsid); err != nil { + return errors.Errorf("sr resync error: failed to add local sid %s: %v", localsid, err) } } for _, policy := range policies { - if err := plugin.AddPolicy(policy); err != nil { - plugin.log.Error(err) - continue + if err := c.AddPolicy(policy); err != nil { + return errors.Errorf("sr resync error: failed to add policy %s: %v", policy.GetBsid(), err) } } for _, namedSegment := range namedSegments { - if err := plugin.AddPolicySegment(namedSegment.Name, namedSegment.Segment); err != nil { - plugin.log.Error(err) - continue + if err := c.AddPolicySegment(namedSegment.Name, namedSegment.Segment); err != nil { + return errors.Errorf("sr resync error: failed to add policy segment %s: %v", namedSegment.Name, err) } } for _, namedSteering := range namedSteerings { - if err := plugin.AddSteering(namedSteering.Name, namedSteering.Steering); err != nil { - plugin.log.Error(err) - continue + if err := c.AddSteering(namedSteering.Name, namedSteering.Steering); err != nil { + return errors.Errorf("sr resync error: failed to add steering %s: %v", namedSteering.Name, err) } } - plugin.log.Debug("RESYNC SR end.") + c.log.Info("Segment routing resync done") return nil } diff --git a/plugins/vpp/srplugin/srv6_config.go b/plugins/vpp/srplugin/srv6_config.go index 3d521e1903..c0555fb1a4 100644 --- a/plugins/vpp/srplugin/srv6_config.go +++ b/plugins/vpp/srplugin/srv6_config.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate protoc --proto_path=../model/srv6 --gogo_out=../model/srv6 ../model/srv6/srv6.proto - package srplugin import ( @@ -23,8 +21,8 @@ import ( "strings" govppapi "git.fd.io/govpp.git/api" + "github.com/go-errors/errors" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/cn-infra/utils/safeclose" "github.com/ligato/vpp-agent/idxvpp" "github.com/ligato/vpp-agent/idxvpp/nametoidx" @@ -61,370 +59,437 @@ type SRv6Configurator struct { policyIndexes idxvpp.NameToIdxRW // Mapping between policy bsid and index inside VPP policySegmentIndexSeq *gaplessSequence policySegmentIndexes idxvpp.NameToIdxRW // Mapping between policy segment name as defined in ETCD key and index inside VPP - - // stopwatch - stopwatch *measure.Stopwatch } // Init members -func (plugin *SRv6Configurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, - enableStopwatch bool, srHandler vppcalls.SRv6VppAPI) (err error) { +func (c *SRv6Configurator) Init(logger logging.PluginLogger, goVppMux govppmux.API, swIfIndexes ifaceidx.SwIfIndex, + srHandler vppcalls.SRv6VppAPI) (err error) { // Logger - plugin.log = logger.NewLogger("-sr-plugin") + c.log = logger.NewLogger("sr-plugin") // NewAPIChannel returns a new API channel for communication with VPP via govpp core. // It uses default buffer sizes for the request and reply Go channels. - plugin.vppChan, err = goVppMux.NewAPIChannel() - if err != nil { - return - } - - // Init stopwatch - if enableStopwatch { - plugin.stopwatch = measure.NewStopwatch("SRConfigurator", plugin.log) + if c.vppChan, err = goVppMux.NewAPIChannel(); err != nil { + return errors.Errorf("failed to create API channel: %v", err) } // VPP API handler if srHandler != nil { - plugin.srHandler = srHandler + c.srHandler = srHandler } else { - plugin.srHandler = vppcalls.NewSRv6VppHandler(plugin.vppChan, plugin.log, plugin.stopwatch) + c.srHandler = vppcalls.NewSRv6VppHandler(c.vppChan, c.log) } // Interface indexes - plugin.swIfIndexes = swIfIndexes + c.swIfIndexes = swIfIndexes // Create caches - plugin.policyCache = cache.NewPolicyCache(plugin.log) - plugin.policySegmentsCache = cache.NewPolicySegmentCache(plugin.log) - plugin.steeringCache = cache.NewSteeringCache(plugin.log) - plugin.createdPolicies = make(map[string]struct{}) + c.policyCache = cache.NewPolicyCache(c.log) + c.policySegmentsCache = cache.NewPolicySegmentCache(c.log) + c.steeringCache = cache.NewSteeringCache(c.log) + c.createdPolicies = make(map[string]struct{}) // Create indexes - plugin.policySegmentIndexSeq = newSequence() - plugin.policySegmentIndexes = nametoidx.NewNameToIdx(plugin.log, "policy-segment-indexes", nil) - plugin.policyIndexSeq = newSequence() - plugin.policyIndexes = nametoidx.NewNameToIdx(plugin.log, "policy-indexes", nil) + c.policySegmentIndexSeq = newSequence() + c.policySegmentIndexes = nametoidx.NewNameToIdx(c.log, "policy-segment-indexes", nil) + c.policyIndexSeq = newSequence() + c.policyIndexes = nametoidx.NewNameToIdx(c.log, "policy-indexes", nil) + + c.log.Info("Segment routing configurator initialized") return } // Close closes GOVPP channel -func (plugin *SRv6Configurator) Close() error { - return safeclose.Close(plugin.vppChan) +func (c *SRv6Configurator) Close() error { + if err := safeclose.Close(c.vppChan); err != nil { + return c.LogError(errors.Errorf("failed to safeclose segment routing configurator: %v", err)) + } + return nil } // clearMapping prepares all in-memory-mappings and other cache fields. All previous cached entries are removed. -func (plugin *SRv6Configurator) clearMapping() { +func (c *SRv6Configurator) clearMapping() { // Clear caches - plugin.policyCache = cache.NewPolicyCache(plugin.log) - plugin.policySegmentsCache = cache.NewPolicySegmentCache(plugin.log) - plugin.steeringCache = cache.NewSteeringCache(plugin.log) - plugin.createdPolicies = make(map[string]struct{}) + c.policyCache = cache.NewPolicyCache(c.log) + c.policySegmentsCache = cache.NewPolicySegmentCache(c.log) + c.steeringCache = cache.NewSteeringCache(c.log) + c.createdPolicies = make(map[string]struct{}) // Clear indexes - plugin.policySegmentIndexSeq = newSequence() - plugin.policySegmentIndexes.Clear() - plugin.policyIndexSeq = newSequence() - plugin.policyIndexes.Clear() + c.policySegmentIndexSeq = newSequence() + c.policySegmentIndexes.Clear() + c.policyIndexSeq = newSequence() + c.policyIndexes.Clear() + + c.log.Debugf("segment routing configurator mapping cleared") } // AddLocalSID adds new Local SID into VPP using VPP's binary api -func (plugin *SRv6Configurator) AddLocalSID(value *srv6.LocalSID) error { +func (c *SRv6Configurator) AddLocalSID(value *srv6.LocalSID) error { sid, err := ParseIPv6(value.GetSid()) if err != nil { - return fmt.Errorf("sid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse local sid %s, should be a valid ipv6 address: %v", + value.GetSid(), err) + } + if err := c.srHandler.AddLocalSid(sid, value, c.swIfIndexes); err != nil { + return errors.Errorf("failed to add local sid %s: %v", sid.String(), err) } - return plugin.srHandler.AddLocalSid(sid, value, plugin.swIfIndexes) + c.log.Infof("Local sid %s added", value.GetSid()) + + return nil } // DeleteLocalSID removes Local SID from VPP using VPP's binary api -func (plugin *SRv6Configurator) DeleteLocalSID(value *srv6.LocalSID) error { +func (c *SRv6Configurator) DeleteLocalSID(value *srv6.LocalSID) error { sid, err := ParseIPv6(value.GetSid()) if err != nil { - return fmt.Errorf("sid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse local sid %s, should be a valid ipv6 address: %v", + value.GetSid(), err) + } + if err := c.srHandler.DeleteLocalSid(sid); err != nil { + return errors.Errorf("failed to delete local sid %s: %v", sid.String(), err) } - return plugin.srHandler.DeleteLocalSid(sid) + c.log.Infof("Local sid %s removed", value.GetSid()) + + return nil } // ModifyLocalSID modifies Local SID from to in VPP using VPP's binary api -func (plugin *SRv6Configurator) ModifyLocalSID(value *srv6.LocalSID, prevValue *srv6.LocalSID) error { - err := plugin.DeleteLocalSID(prevValue) +func (c *SRv6Configurator) ModifyLocalSID(value *srv6.LocalSID, prevValue *srv6.LocalSID) error { + err := c.DeleteLocalSID(prevValue) if err != nil { - return fmt.Errorf("can't delete old version of Local SID: %v", err) + return errors.Errorf("local sid modify: failed to delete old version of Local SID %s: %v", prevValue.Sid, err) } - err = plugin.AddLocalSID(value) + err = c.AddLocalSID(value) if err != nil { - return fmt.Errorf("can't apply new version of Local SID: %v", err) + return errors.Errorf("local sid modify: failed to apply new version of Local SID %s: %v", value.Sid, err) } + c.log.Infof("Sid %s modified", value.GetSid()) + return nil } // AddPolicy adds new policy into VPP using VPP's binary api -func (plugin *SRv6Configurator) AddPolicy(policy *srv6.Policy) error { +func (c *SRv6Configurator) AddPolicy(policy *srv6.Policy) error { bsid, err := ParseIPv6(policy.GetBsid()) if err != nil { - return fmt.Errorf("bsid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse bsid %s, should be a valid ipv6 address: %v", + policy.GetBsid(), err) } - plugin.policyCache.Put(bsid, policy) - segments, segmentNames := plugin.policySegmentsCache.LookupByPolicy(bsid) + c.policyCache.Put(bsid, policy) + segments, segmentNames := c.policySegmentsCache.LookupByPolicy(bsid) if len(segments) == 0 { - plugin.log.Debugf("addition of policy (%v) postponed until first policy segment is defined for it", bsid.String()) + c.log.Debugf("addition of policy (%v) postponed until first policy segment is defined for it", bsid.String()) return nil } - plugin.addPolicyToIndexes(bsid) - plugin.addSegmentToIndexes(bsid, segmentNames[0]) - err = plugin.srHandler.AddPolicy(bsid, policy, segments[0]) + c.addPolicyToIndexes(bsid) + c.addSegmentToIndexes(bsid, segmentNames[0]) + err = c.srHandler.AddPolicy(bsid, policy, segments[0]) if err != nil { - return fmt.Errorf("can't write policy (%v) with first segment (%v): %v", bsid, segments[0].Segments, err) + return errors.Errorf("failed to write policy %s with first segment %s: %v", + bsid.String(), segments[0].Segments, err) } - plugin.createdPolicies[bsid.String()] = struct{}{} // write into Set that policy was successfully created + c.createdPolicies[bsid.String()] = struct{}{} // write into Set that policy was successfully created if len(segments) > 1 { for i, segment := range segments[1:] { - err = plugin.AddPolicySegment(segmentNames[i], segment) + err = c.AddPolicySegment(segmentNames[i], segment) if err != nil { - return fmt.Errorf("can't apply subsequent policy segment (%v) to policy (%v): %v", segment.Segments, bsid.String(), err) + return errors.Errorf("faield to apply subsequent policy segment %s to policy %s: %v", + segment.Segments, bsid.String(), err) } } } // adding policy dependent steerings - idx, _, _ := plugin.policyIndexes.LookupIdx(bsid.String()) - steerings, steeringNames := plugin.lookupSteeringByPolicy(bsid, idx) + idx, _, _ := c.policyIndexes.LookupIdx(bsid.String()) + steerings, steeringNames := c.lookupSteeringByPolicy(bsid, idx) for i, steering := range steerings { - if err := plugin.AddSteering(steeringNames[i], steering); err != nil { - return fmt.Errorf("can't create steering by creating policy referenced by steering: %v", err) + if err := c.AddSteering(steeringNames[i], steering); err != nil { + return fmt.Errorf("failed to create steering %s by creating policy referenced by steering: %v", + steeringNames[i], err) } } + + c.log.Infof("Policy with bsid %s added", policy.Bsid) + return nil } -func (plugin *SRv6Configurator) lookupSteeringByPolicy(bsid srv6.SID, index uint32) ([]*srv6.Steering, []string) { +func (c *SRv6Configurator) lookupSteeringByPolicy(bsid srv6.SID, index uint32) ([]*srv6.Steering, []string) { // union search by bsid and policy index - steerings1, steeringNames1 := plugin.steeringCache.LookupByPolicyBSID(bsid) - steerings2, steeringNames2 := plugin.steeringCache.LookupByPolicyIndex(index) + steerings1, steeringNames1 := c.steeringCache.LookupByPolicyBSID(bsid) + steerings2, steeringNames2 := c.steeringCache.LookupByPolicyIndex(index) steerings1 = append(steerings1, steerings2...) steeringNames1 = append(steeringNames1, steeringNames2...) return steerings1, steeringNames1 } // RemovePolicy removes policy from VPP using VPP's binary api -func (plugin *SRv6Configurator) RemovePolicy(policy *srv6.Policy) error { +func (c *SRv6Configurator) RemovePolicy(policy *srv6.Policy) error { bsid, err := ParseIPv6(policy.GetBsid()) if err != nil { - return fmt.Errorf("bsid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse bsid %s, should be a valid ipv6 address: %v", + policy.GetBsid(), err) } // adding policy dependent steerings - idx, _, _ := plugin.policyIndexes.LookupIdx(bsid.String()) - steerings, steeringNames := plugin.lookupSteeringByPolicy(bsid, idx) + idx, _, _ := c.policyIndexes.LookupIdx(bsid.String()) + steerings, steeringNames := c.lookupSteeringByPolicy(bsid, idx) for i, steering := range steerings { - if err := plugin.RemoveSteering(steeringNames[i], steering); err != nil { - return fmt.Errorf("can't remove steering in process of removing policy referenced by steering: %v", err) + if err := c.RemoveSteering(steeringNames[i], steering); err != nil { + return errors.Errorf("failed to remove steering %s in process of removing policy referenced by steering: %v", + steeringNames[i], err) } } - plugin.policyCache.Delete(bsid) - plugin.policyIndexes.UnregisterName(bsid.String()) - delete(plugin.createdPolicies, bsid.String()) - _, segmentNames := plugin.policySegmentsCache.LookupByPolicy(bsid) + c.policyCache.Delete(bsid) + c.policyIndexes.UnregisterName(bsid.String()) + c.log.Debugf("policy %s removed from cache and mapping", policy.Bsid) + delete(c.createdPolicies, bsid.String()) + _, segmentNames := c.policySegmentsCache.LookupByPolicy(bsid) for _, segmentName := range segmentNames { - plugin.policySegmentsCache.Delete(bsid, segmentName) - index, _, exists := plugin.policySegmentIndexes.UnregisterName(plugin.uniquePolicySegmentName(bsid, segmentName)) + c.policySegmentsCache.Delete(bsid, segmentName) + index, _, exists := c.policySegmentIndexes.UnregisterName(c.uniquePolicySegmentName(bsid, segmentName)) + c.log.Debugf("policy segment %s removed from cache and mapping", policy.Bsid) if exists { - plugin.policySegmentIndexSeq.delete(index) + c.policySegmentIndexSeq.delete(index) } } - return plugin.srHandler.DeletePolicy(bsid) // expecting that policy delete will also delete policy segments in vpp + if err := c.srHandler.DeletePolicy(bsid); err != nil { // expecting that policy delete will also delete policy segments in vpp + return errors.Errorf("failed to delete policy %s: %v", + bsid.String(), err) + } + + return nil } // ModifyPolicy modifies policy in VPP using VPP's binary api -func (plugin *SRv6Configurator) ModifyPolicy(value *srv6.Policy, prevValue *srv6.Policy) error { +func (c *SRv6Configurator) ModifyPolicy(value *srv6.Policy, prevValue *srv6.Policy) error { bsid, err := ParseIPv6(value.GetBsid()) if err != nil { - return fmt.Errorf("bsid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse modified bsid %s, should be a valid ipv6 address: %v", + value.GetBsid(), err) } - segments, segmentNames := plugin.policySegmentsCache.LookupByPolicy(bsid) - err = plugin.RemovePolicy(prevValue) + segments, segmentNames := c.policySegmentsCache.LookupByPolicy(bsid) + err = c.RemovePolicy(prevValue) if err != nil { - return fmt.Errorf("can't delete old version of Policy: %v", err) + return err } - err = plugin.AddPolicy(value) + err = c.AddPolicy(value) if err != nil { - return fmt.Errorf("can't apply new version of Policy: %v", err) + return err } for i, segment := range segments { - err = plugin.AddPolicySegment(segmentNames[i], segment) + err = c.AddPolicySegment(segmentNames[i], segment) if err != nil { - return fmt.Errorf("can't apply segment %v (%v) as part of policy modification: %v", segmentNames[i], segment.Segments, err) + return errors.Errorf("can't apply segment %s (%s) as part of policy modification: %v", segmentNames[i], segment.Segments, err) } } return nil } // AddPolicySegment adds policy segment with name into referenced policy in VPP using VPP's binary api. -func (plugin *SRv6Configurator) AddPolicySegment(segmentName string, policySegment *srv6.PolicySegment) error { +func (c *SRv6Configurator) AddPolicySegment(segmentName string, policySegment *srv6.PolicySegment) error { bsid, err := ParseIPv6(policySegment.GetPolicyBsid()) if err != nil { - return fmt.Errorf("policy bsid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse bsid %s, should be a valid ipv6 address: %v", + policySegment.GetPolicyBsid(), err) } - plugin.policySegmentsCache.Put(bsid, segmentName, policySegment) - policy, exists := plugin.policyCache.GetValue(bsid) + c.policySegmentsCache.Put(bsid, segmentName, policySegment) + policy, exists := c.policyCache.GetValue(bsid) if !exists { - plugin.log.Debugf("addition of policy segment (%v) postponed until policy with %v bsid is created", policySegment.GetSegments(), bsid.String()) + c.log.Debugf("addition of policy segment (%v) postponed until policy with %s bsid is created", + policySegment.GetSegments(), bsid.String()) return nil } - segments, _ := plugin.policySegmentsCache.LookupByPolicy(bsid) + segments, _ := c.policySegmentsCache.LookupByPolicy(bsid) if len(segments) <= 1 { - if _, alreadyCreated := plugin.createdPolicies[bsid.String()]; alreadyCreated { - // last segment got deleted in etcd, but policy with last segment stays in VPP, and we want add another segment - // -> we must remove old policy with last segment from VPP to add it again with new segment - err := plugin.RemovePolicy(policy) + if _, alreadyCreated := c.createdPolicies[bsid.String()]; alreadyCreated { + // last segment got deleted in etcd, but policy with last segment stays in VPP, and we want to add another segment + // -> we must remove the old policy with last segment from the VPP to add it again with the new segment + err := c.RemovePolicy(policy) if err != nil { - return fmt.Errorf("can't delete Policy (with previously deleted last policy segment) to recreated it with new policy segment: %v", err) + return errors.Errorf("can't delete Policy (with previously deleted last policy segment) to recreated it with new policy segment: %v", err) } - plugin.policySegmentsCache.Put(bsid, segmentName, policySegment) // got deleted in policy removal + c.policySegmentsCache.Put(bsid, segmentName, policySegment) // got deleted in policy removal } - return plugin.AddPolicy(policy) + return c.AddPolicy(policy) } // FIXME there is no API contract saying what happens to VPP indexes if addition fails (also different fail code can rollback or not rollback indexes) => no way how to handle this without being dependent on internal implementation inside VPP and that is just very fragile -> API should tell this but it doesn't! - plugin.addSegmentToIndexes(bsid, segmentName) - return plugin.srHandler.AddPolicySegment(bsid, policy, policySegment) + c.addSegmentToIndexes(bsid, segmentName) + if err := c.srHandler.AddPolicySegment(bsid, policy, policySegment); err != nil { + return errors.Errorf("failed to add policy segment %s: %v", bsid, err) + } + + return nil } // RemovePolicySegment removes policy segment with name from referenced policy in VPP using // VPP's binary api. In case of last policy segment in policy, policy segment is not removed, because policy can't exists // in VPP without policy segment. Instead it is postponed until policy removal or addition of another policy segment happen. -func (plugin *SRv6Configurator) RemovePolicySegment(segmentName string, policySegment *srv6.PolicySegment) error { +func (c *SRv6Configurator) RemovePolicySegment(segmentName string, policySegment *srv6.PolicySegment) error { bsid, err := ParseIPv6(policySegment.GetPolicyBsid()) if err != nil { - return fmt.Errorf("policy bsid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse bsid %s, should be a valid ipv6 address: %v", + policySegment.GetPolicyBsid(), err) } - plugin.policySegmentsCache.Delete(bsid, segmentName) - index, _, exists := plugin.policySegmentIndexes.UnregisterName(plugin.uniquePolicySegmentName(bsid, segmentName)) + c.policySegmentsCache.Delete(bsid, segmentName) + index, _, exists := c.policySegmentIndexes.UnregisterName(c.uniquePolicySegmentName(bsid, segmentName)) - siblings, _ := plugin.policySegmentsCache.LookupByPolicy(bsid) // sibling segments in the same policy - if len(siblings) == 0 { // last segment for policy - plugin.log.Debugf("removal of policy segment (%v) postponed until policy with %v bsid is deleted", policySegment.GetSegments(), bsid.String()) + siblings, _ := c.policySegmentsCache.LookupByPolicy(bsid) // sibling segments in the same policy + if len(siblings) == 0 { // last segment for policy + c.log.Debugf("removal of policy segment (%v) postponed until policy with %s bsid is deleted", policySegment.GetSegments(), bsid.String()) return nil } // removing not-last segment if !exists { - return fmt.Errorf("can't find index of policy segment %v in policy with bsid %v", policySegment.Segments, bsid) + return errors.Errorf("can't find index of policy segment %s in policy with bsid %s", policySegment.Segments, bsid) } - policy, exists := plugin.policyCache.GetValue(bsid) + policy, exists := c.policyCache.GetValue(bsid) if !exists { - return fmt.Errorf("can't find policy with bsid %v", bsid) + return errors.Errorf("can't find policy with bsid %s", bsid) } // FIXME there is no API contract saying what happens to VPP indexes if removal fails (also different fail code can rollback or not rollback indexes) => no way how to handle this without being dependent on internal implementation inside VPP and that is just very fragile -> API should tell this but it doesn't! - plugin.policySegmentIndexSeq.delete(index) - return plugin.srHandler.DeletePolicySegment(bsid, policy, policySegment, index) + c.policySegmentIndexSeq.delete(index) + if err := c.srHandler.DeletePolicySegment(bsid, policy, policySegment, index); err != nil { + return errors.Errorf("failed to delete policy segment %s: %v", bsid, err) + } + + return nil } // ModifyPolicySegment modifies existing policy segment with name from to in referenced policy. -func (plugin *SRv6Configurator) ModifyPolicySegment(segmentName string, value *srv6.PolicySegment, prevValue *srv6.PolicySegment) error { +func (c *SRv6Configurator) ModifyPolicySegment(segmentName string, value *srv6.PolicySegment, prevValue *srv6.PolicySegment) error { bsid, err := ParseIPv6(value.GetPolicyBsid()) if err != nil { - return fmt.Errorf("policy bsid should be valid ipv6 address: %v", err) + return errors.Errorf("failed to parse modified bsid %s, should be a valid ipv6 address: %v", + value.GetPolicyBsid(), err) } - segments, _ := plugin.policySegmentsCache.LookupByPolicy(bsid) + segments, _ := c.policySegmentsCache.LookupByPolicy(bsid) if len(segments) <= 1 { // last segment in policy can't be removed without removing policy itself - policy, exists := plugin.policyCache.GetValue(bsid) + policy, exists := c.policyCache.GetValue(bsid) if !exists { - return fmt.Errorf("can't find Policy in cache when updating last policy segment in policy") + return errors.Errorf("can't find Policy in cache when updating last policy segment in policy") } - err := plugin.RemovePolicy(policy) + err := c.RemovePolicy(policy) if err != nil { - return fmt.Errorf("can't delete Policy as part of removing old version of last policy segment in policy: %v", err) + return errors.Errorf("can't delete Policy as part of removing old version of last policy segment in policy: %v", err) } - err = plugin.AddPolicy(policy) + err = c.AddPolicy(policy) if err != nil { - return fmt.Errorf("can't add Policy as part of adding new version of last policy segment in policy: %v", err) + return errors.Errorf("can't add Policy as part of adding new version of last policy segment in policy: %v", err) } - err = plugin.AddPolicySegment(segmentName, value) + err = c.AddPolicySegment(segmentName, value) if err != nil { - return fmt.Errorf("can't apply new version of last Policy segment: %v", err) + return errors.Errorf("can't apply new version of last Policy segment: %v", err) } return nil } - err = plugin.RemovePolicySegment(segmentName, prevValue) + err = c.RemovePolicySegment(segmentName, prevValue) if err != nil { - return fmt.Errorf("can't delete old version of Policy segment: %v", err) + return errors.Errorf("can't delete old version of Policy segment: %v", err) } - err = plugin.AddPolicySegment(segmentName, value) + err = c.AddPolicySegment(segmentName, value) if err != nil { - return fmt.Errorf("can't apply new version of Policy segment: %v", err) + return errors.Errorf("can't apply new version of Policy segment: %v", err) } return nil } -func (plugin *SRv6Configurator) addSegmentToIndexes(bsid srv6.SID, segmentName string) { - plugin.policySegmentIndexes.RegisterName(plugin.uniquePolicySegmentName(bsid, segmentName), plugin.policySegmentIndexSeq.nextID(), nil) +func (c *SRv6Configurator) addSegmentToIndexes(bsid srv6.SID, segmentName string) { + c.policySegmentIndexes.RegisterName(c.uniquePolicySegmentName(bsid, segmentName), c.policySegmentIndexSeq.nextID(), nil) + c.log.Debugf("policy segment with bsid %s registered", bsid.String()) } -func (plugin *SRv6Configurator) addPolicyToIndexes(bsid srv6.SID) { - plugin.policyIndexes.RegisterName(bsid.String(), plugin.policyIndexSeq.nextID(), nil) +func (c *SRv6Configurator) addPolicyToIndexes(bsid srv6.SID) { + c.policyIndexes.RegisterName(bsid.String(), c.policyIndexSeq.nextID(), nil) + c.log.Debugf("policy with bsid %s registered", bsid.String()) } -func (plugin *SRv6Configurator) uniquePolicySegmentName(bsid srv6.SID, segmentName string) string { +func (c *SRv6Configurator) uniquePolicySegmentName(bsid srv6.SID, segmentName string) string { return bsid.String() + srv6.EtcdKeyPathDelimiter + segmentName } // AddSteering adds new steering into VPP using VPP's binary api -func (plugin *SRv6Configurator) AddSteering(name string, steering *srv6.Steering) error { - plugin.steeringCache.Put(name, steering) +func (c *SRv6Configurator) AddSteering(name string, steering *srv6.Steering) error { + c.steeringCache.Put(name, steering) bsidStr := steering.PolicyBsid if len(strings.Trim(steering.PolicyBsid, " ")) == 0 { // policy defined by index var exists bool - bsidStr, _, exists = plugin.policyIndexes.LookupName(steering.PolicyIndex) + bsidStr, _, exists = c.policyIndexes.LookupName(steering.PolicyIndex) if !exists { - plugin.log.Debugf("addition of steering (index %v) postponed until referenced policy is defined", steering.PolicyIndex) + c.log.Debugf("addition of steering (index %d) postponed until referenced policy is defined", steering.PolicyIndex) return nil } } // policy defined by BSID (or index defined converted to BSID defined) bsid, err := ParseIPv6(bsidStr) if err != nil { - return fmt.Errorf("can't parse policy BSID string ('%v') into IPv6 address", steering.PolicyBsid) + return errors.Errorf("failed to parse modified bsid %s, should be a valid ipv6 address: %v", + steering.GetPolicyBsid(), err) } - if _, exists := plugin.policyCache.GetValue(bsid); !exists { - plugin.log.Debugf("addition of steering (bsid %v) postponed until referenced policy is defined", name) + if _, exists := c.policyCache.GetValue(bsid); !exists { + c.log.Debugf("addition of steering (bsid %s) postponed until referenced policy is defined", name) return nil } - return plugin.srHandler.AddSteering(steering, plugin.swIfIndexes) + if err := c.srHandler.AddSteering(steering, c.swIfIndexes); err != nil { + return errors.Errorf("failed to add steering %s: %v", name, err) + } + + return nil } // RemoveSteering removes steering from VPP using VPP's binary api -func (plugin *SRv6Configurator) RemoveSteering(name string, steering *srv6.Steering) error { - plugin.steeringCache.Delete(name) - return plugin.srHandler.RemoveSteering(steering, plugin.swIfIndexes) +func (c *SRv6Configurator) RemoveSteering(name string, steering *srv6.Steering) error { + c.steeringCache.Delete(name) + c.log.Debugf("steering %s removed from cache", name) + if err := c.srHandler.RemoveSteering(steering, c.swIfIndexes); err != nil { + return errors.Errorf("failed to remove steering %s: %v", name, err) + } + + return nil } // ModifySteering modifies existing steering in VPP using VPP's binary api -func (plugin *SRv6Configurator) ModifySteering(name string, value *srv6.Steering, prevValue *srv6.Steering) error { - err := plugin.RemoveSteering(name, prevValue) +func (c *SRv6Configurator) ModifySteering(name string, value *srv6.Steering, prevValue *srv6.Steering) error { + err := c.RemoveSteering(name, prevValue) if err != nil { - return fmt.Errorf("can't delete old version of steering %v: %v", name, err) + return errors.Errorf("modify steering: failed to remove old value %s: %v", name, err) } - err = plugin.AddSteering(name, value) + err = c.AddSteering(name, value) if err != nil { - return fmt.Errorf("can't apply new version of steering %v: %v", name, err) + return errors.Errorf("modify steering: failed to apply new value %s: %v", name, err) } return nil } +// LogError prints error if not nil, including stack trace. The same value is also returned, so it can be easily propagated further +func (c *SRv6Configurator) LogError(err error) error { + if err == nil { + return nil + } + switch err.(type) { + case *errors.Error: + c.log.WithField("logger", c.log).Errorf(string(err.Error() + "\n" + string(err.(*errors.Error).Stack()))) + default: + c.log.Error(err) + } + return err +} + // ParseIPv6 parses string to IPv6 address (including IPv4 address converted to IPv6 address) func ParseIPv6(str string) (net.IP, error) { ip := net.ParseIP(str) if ip == nil { - return nil, fmt.Errorf(" %q is not ip address", str) + return nil, errors.Errorf(" %q is not ip address", str) } ipv6 := ip.To16() if ipv6 == nil { - return nil, fmt.Errorf(" %q is not ipv6 address", str) + return nil, errors.Errorf(" %q is not ipv6 address", str) } return ipv6, nil } diff --git a/plugins/vpp/srplugin/srv6_config_test.go b/plugins/vpp/srplugin/srv6_config_test.go index 28b2c136f6..60326c55a6 100644 --- a/plugins/vpp/srplugin/srv6_config_test.go +++ b/plugins/vpp/srplugin/srv6_config_test.go @@ -18,8 +18,9 @@ import ( "fmt" "testing" - "git.fd.io/govpp.git/adapter/mock" "git.fd.io/govpp.git/core" + + "git.fd.io/govpp.git/adapter/mock" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/idxvpp/nametoidx" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" @@ -655,7 +656,7 @@ func TestAddSteering(t *testing.T) { VerifyAfterAddSteering: func(steering *srv6.Steering, err error, fakeVPPCalls *SRv6Calls) { Expect(err).To(BeNil()) state := fakeVPPCalls.SteeringState() - _, exists := state[*steering] + _, exists := state[steering.PolicyBsid] Expect(exists).To(BeTrue()) }, }, @@ -668,7 +669,7 @@ func TestAddSteering(t *testing.T) { }, VerifyAfterAddPolicy: func(steering *srv6.Steering, fakeVPPCalls *SRv6Calls) { state := fakeVPPCalls.SteeringState() - _, exists := state[*steering] + _, exists := state[steering.PolicyBsid] Expect(exists).To(BeTrue()) }, }, @@ -681,7 +682,7 @@ func TestAddSteering(t *testing.T) { VerifyAfterAddSteering: func(steering *srv6.Steering, err error, fakeVPPCalls *SRv6Calls) { Expect(err).To(BeNil()) state := fakeVPPCalls.SteeringState() - _, exists := state[*steering] + _, exists := state[steering.PolicyBsid] Expect(exists).To(BeTrue()) }, }, @@ -695,7 +696,7 @@ func TestAddSteering(t *testing.T) { }, VerifyAfterAddPolicy: func(steering *srv6.Steering, fakeVPPCalls *SRv6Calls) { state := fakeVPPCalls.SteeringState() - _, exists := state[*steering] + _, exists := state[steering.PolicyBsid] Expect(exists).To(BeTrue()) }, }, @@ -830,7 +831,7 @@ func TestModifySteering(t *testing.T) { Verify: func(steering *srv6.Steering, err error, fakeVPPCalls *SRv6Calls) { Expect(err).To(BeNil()) state := fakeVPPCalls.SteeringState() - _, exists := state[*steering] + _, exists := state[steering.PolicyBsid] Expect(exists).To(BeTrue()) }, }, @@ -899,7 +900,7 @@ func srv6TestSetup(t *testing.T) (*srplugin.SRv6Configurator, *SRv6Calls, *core. RegisterTestingT(t) // connection ctx := &vppcallmock.TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } connection, err := core.Connect(ctx.MockVpp) Expect(err).ShouldNot(HaveOccurred()) @@ -911,7 +912,7 @@ func srv6TestSetup(t *testing.T) (*srplugin.SRv6Configurator, *SRv6Calls, *core. // Configurator fakeVPPCalls := NewSRv6Calls() configurator := &srplugin.SRv6Configurator{} - err = configurator.Init(log, connection, swIndex, false, fakeVPPCalls) + err = configurator.Init(log, connection, swIndex, fakeVPPCalls) Expect(err).To(BeNil()) return configurator, fakeVPPCalls, connection diff --git a/plugins/vpp/srplugin/srv6calls_test.go b/plugins/vpp/srplugin/srv6calls_test.go index aced6cdd4e..e0bf6cc17f 100644 --- a/plugins/vpp/srplugin/srv6calls_test.go +++ b/plugins/vpp/srplugin/srv6calls_test.go @@ -30,8 +30,8 @@ type SRv6Calls struct { localSidState map[string]*srv6.LocalSID policiesState map[string]*PolicyState nextPolicyIndex uint32 - policiesIdxs map[uint32]string // index to bsid - steeringState map[srv6.Steering]struct{} // set of steerings + policiesIdxs map[uint32]string // index to bsid + steeringState map[string]struct{} // set of steerings } // PolicyState is holder for one policy and its segments @@ -46,7 +46,7 @@ func NewSRv6Calls() *SRv6Calls { localSidState: make(map[string]*srv6.LocalSID, 0), policiesState: make(map[string]*PolicyState, 0), policiesIdxs: make(map[uint32]string, 0), - steeringState: make(map[srv6.Steering]struct{}, 0), + steeringState: make(map[string]struct{}, 0), } } @@ -67,7 +67,7 @@ func (fake *SRv6Calls) PoliciesState() map[string]*PolicyState { } // SteeringState provides current state of steerings as changed by calls to SRv6Calls fake -func (fake *SRv6Calls) SteeringState() map[srv6.Steering]struct{} { +func (fake *SRv6Calls) SteeringState() map[string]struct{} { return fake.steeringState } @@ -217,7 +217,7 @@ func (fake *SRv6Calls) AddSteering(steering *srv6.Steering, swIfIndex ifaceidx.S if _, exists := fake.policiesState[bsidStr]; !exists { return fmt.Errorf("can't find policy for bsid %v (adding steering proces)", bsidStr) } - fake.steeringState[*steering] = struct{}{} + fake.steeringState[steering.PolicyBsid] = struct{}{} return nil } @@ -226,6 +226,6 @@ func (fake *SRv6Calls) RemoveSteering(steering *srv6.Steering, swIfIndex ifaceid if _, ok := fake.failCall.(RemoveSteeringFuncCall); ok { return fake.failError } - delete(fake.steeringState, *steering) + delete(fake.steeringState, steering.PolicyBsid) return nil } diff --git a/plugins/vpp/srplugin/vppcalls/api_vppcalls.go b/plugins/vpp/srplugin/vppcalls/api_vppcalls.go index 487764a47a..04376c4806 100644 --- a/plugins/vpp/srplugin/vppcalls/api_vppcalls.go +++ b/plugins/vpp/srplugin/vppcalls/api_vppcalls.go @@ -19,7 +19,6 @@ import ( govppapi "git.fd.io/govpp.git/api" "github.com/ligato/cn-infra/logging" - "github.com/ligato/cn-infra/logging/measure" "github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx" "github.com/ligato/vpp-agent/plugins/vpp/model/srv6" ) @@ -61,14 +60,12 @@ type SRv6VPPRead interface { type SRv6VppHandler struct { log logging.Logger callsChannel govppapi.Channel - stopwatch *measure.Stopwatch } // NewSRv6VppHandler creates new instance of SRv6 vppcalls handler -func NewSRv6VppHandler(vppChan govppapi.Channel, log logging.Logger, stopwatch *measure.Stopwatch) *SRv6VppHandler { +func NewSRv6VppHandler(vppChan govppapi.Channel, log logging.Logger) *SRv6VppHandler { return &SRv6VppHandler{ callsChannel: vppChan, log: log, - stopwatch: stopwatch, } } diff --git a/plugins/vpp/srplugin/vppcalls/srv6.go b/plugins/vpp/srplugin/vppcalls/srv6.go index 2f6d809077..dea76bdbce 100644 --- a/plugins/vpp/srplugin/vppcalls/srv6.go +++ b/plugins/vpp/srplugin/vppcalls/srv6.go @@ -18,7 +18,6 @@ import ( "fmt" "net" "strings" - "time" "github.com/ligato/cn-infra/logging" "github.com/ligato/vpp-agent/plugins/vpp/binapi/sr" @@ -57,55 +56,51 @@ const ( ) // AddLocalSid adds local sid given by and into VPP -func (handler *SRv6VppHandler) AddLocalSid(sidAddr net.IP, localSID *srv6.LocalSID, swIfIndex ifaceidx.SwIfIndex) error { - return handler.addDelLocalSid(false, sidAddr, localSID, swIfIndex) +func (h *SRv6VppHandler) AddLocalSid(sidAddr net.IP, localSID *srv6.LocalSID, swIfIndex ifaceidx.SwIfIndex) error { + return h.addDelLocalSid(false, sidAddr, localSID, swIfIndex) } // DeleteLocalSid delets local sid given by in VPP -func (handler *SRv6VppHandler) DeleteLocalSid(sidAddr net.IP) error { - return handler.addDelLocalSid(true, sidAddr, nil, nil) +func (h *SRv6VppHandler) DeleteLocalSid(sidAddr net.IP) error { + return h.addDelLocalSid(true, sidAddr, nil, nil) } -func (handler *SRv6VppHandler) addDelLocalSid(deletion bool, sidAddr net.IP, localSID *srv6.LocalSID, swIfIndex ifaceidx.SwIfIndex) error { - handler.log.WithFields(logging.Fields{"localSID": sidAddr, "delete": deletion, "FIB table ID": handler.fibTableID(localSID), "end function": handler.endFunction(localSID)}). +func (h *SRv6VppHandler) addDelLocalSid(deletion bool, sidAddr net.IP, localSID *srv6.LocalSID, swIfIndex ifaceidx.SwIfIndex) error { + h.log.WithFields(logging.Fields{"localSID": sidAddr, "delete": deletion, "FIB table ID": h.fibTableID(localSID), "end function": h.endFunction(localSID)}). Debug("Adding/deleting Local SID", sidAddr) - defer func(t time.Time) { - handler.stopwatch.TimeLog(sr.SrLocalsidAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - req := &sr.SrLocalsidAddDel{ IsDel: boolToUint(deletion), Localsid: sr.Srv6Sid{Addr: []byte(sidAddr)}, } if !deletion { req.FibTable = localSID.FibTableId // where to install localsid entry - if err := handler.writeEndFunction(req, sidAddr, localSID, swIfIndex); err != nil { + if err := h.writeEndFunction(req, sidAddr, localSID, swIfIndex); err != nil { return err } } reply := &sr.SrLocalsidAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { return fmt.Errorf("vpp call %q returned: %d", reply.GetMessageName(), reply.Retval) } - handler.log.WithFields(logging.Fields{"localSID": sidAddr, "delete": deletion, "FIB table ID": handler.fibTableID(localSID), "end function": handler.endFunction(localSID)}). + h.log.WithFields(logging.Fields{"localSID": sidAddr, "delete": deletion, "FIB table ID": h.fibTableID(localSID), "end function": h.endFunction(localSID)}). Debug("Added/deleted Local SID ", sidAddr) return nil } -func (handler *SRv6VppHandler) fibTableID(localSID *srv6.LocalSID) string { +func (h *SRv6VppHandler) fibTableID(localSID *srv6.LocalSID) string { if localSID != nil { return string(localSID.FibTableId) } return "" } -func (handler *SRv6VppHandler) endFunction(localSID *srv6.LocalSID) string { +func (h *SRv6VppHandler) endFunction(localSID *srv6.LocalSID) string { if localSID == nil { return "" } else if localSID.BaseEndFunction != nil { @@ -128,7 +123,7 @@ func (handler *SRv6VppHandler) endFunction(localSID *srv6.LocalSID) string { return "unknown end function" } -func (handler *SRv6VppHandler) writeEndFunction(req *sr.SrLocalsidAddDel, sidAddr net.IP, localSID *srv6.LocalSID, swIfIndex ifaceidx.SwIfIndex) error { +func (h *SRv6VppHandler) writeEndFunction(req *sr.SrLocalsidAddDel, sidAddr net.IP, localSID *srv6.LocalSID, swIfIndex ifaceidx.SwIfIndex) error { if localSID.BaseEndFunction != nil { req.Behavior = BehaviorEnd req.EndPsp = boolToUint(localSID.BaseEndFunction.Psp) @@ -208,12 +203,8 @@ func (handler *SRv6VppHandler) writeEndFunction(req *sr.SrLocalsidAddDel, sidAdd } // SetEncapsSourceAddress sets for SRv6 in VPP the source address used for encapsulated packet -func (handler *SRv6VppHandler) SetEncapsSourceAddress(address string) error { - handler.log.Debugf("Configuring encapsulation source address to address %v", address) - defer func(t time.Time) { - handler.stopwatch.TimeLog(sr.SrSetEncapSource{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *SRv6VppHandler) SetEncapsSourceAddress(address string) error { + h.log.Debugf("Configuring encapsulation source address to address %v", address) ipAddress, err := parseIPv6(address) if err != nil { return err @@ -223,27 +214,23 @@ func (handler *SRv6VppHandler) SetEncapsSourceAddress(address string) error { } reply := &sr.SrSetEncapSourceReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { return fmt.Errorf("vpp call %q returned: %d", reply.GetMessageName(), reply.Retval) } - handler.log.WithFields(logging.Fields{"Encapsulation source address": address}). + h.log.WithFields(logging.Fields{"Encapsulation source address": address}). Debug("Encapsulation source address configured.") return nil } // AddPolicy adds SRv6 policy given by identified ,initial segment for policy and other policy settings in -func (handler *SRv6VppHandler) AddPolicy(bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment) error { - handler.log.Debugf("Adding SR policy with binding SID %v and list of next SIDs %v", bindingSid, policySegment.Segments) - defer func(t time.Time) { - handler.stopwatch.TimeLog(sr.SrPolicyAdd{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - sids, err := handler.convertPolicySegment(policySegment) +func (h *SRv6VppHandler) AddPolicy(bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment) error { + h.log.Debugf("Adding SR policy with binding SID %v and list of next SIDs %v", bindingSid, policySegment.Segments) + sids, err := h.convertPolicySegment(policySegment) if err != nil { return err } @@ -257,74 +244,66 @@ func (handler *SRv6VppHandler) AddPolicy(bindingSid net.IP, policy *srv6.Policy, } reply := &sr.SrPolicyAddReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { return fmt.Errorf("vpp call %q returned: %d", reply.GetMessageName(), reply.Retval) } - handler.log.WithFields(logging.Fields{"binding SID": bindingSid, "list of next SIDs": policySegment.Segments}). + h.log.WithFields(logging.Fields{"binding SID": bindingSid, "list of next SIDs": policySegment.Segments}). Debug("SR policy added") return nil } // DeletePolicy deletes SRv6 policy given by binding SID -func (handler *SRv6VppHandler) DeletePolicy(bindingSid net.IP) error { - handler.log.Debugf("Deleting SR policy with binding SID %v ", bindingSid) - defer func(t time.Time) { - handler.stopwatch.TimeLog(sr.SrPolicyDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *SRv6VppHandler) DeletePolicy(bindingSid net.IP) error { + h.log.Debugf("Deleting SR policy with binding SID %v ", bindingSid) req := &sr.SrPolicyDel{ BsidAddr: sr.Srv6Sid{Addr: []byte(bindingSid)}, // TODO add ability to define policy also by index (SrPolicyIndex) } reply := &sr.SrPolicyDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { return fmt.Errorf("vpp call %q returned: %d", reply.GetMessageName(), reply.Retval) } - handler.log.WithFields(logging.Fields{"binding SID": bindingSid}). + h.log.WithFields(logging.Fields{"binding SID": bindingSid}). Debug("SR policy deleted") return nil } // AddPolicySegment adds segment to SRv6 policy that has policy BSID -func (handler *SRv6VppHandler) AddPolicySegment(bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment) error { - handler.log.Debugf("Adding segment %v to SR policy with binding SID %v", policySegment.Segments, bindingSid) - err := handler.modPolicy(AddSRList, bindingSid, policy, policySegment, 0) +func (h *SRv6VppHandler) AddPolicySegment(bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment) error { + h.log.Debugf("Adding segment %v to SR policy with binding SID %v", policySegment.Segments, bindingSid) + err := h.modPolicy(AddSRList, bindingSid, policy, policySegment, 0) if err == nil { - handler.log.WithFields(logging.Fields{"binding SID": bindingSid, "list of next SIDs": policySegment.Segments}). + h.log.WithFields(logging.Fields{"binding SID": bindingSid, "list of next SIDs": policySegment.Segments}). Debug("SR policy modified(added another segment list)") } return err } // DeletePolicySegment removes segment (with segment index ) from SRv6 policy that has policy BSID -func (handler *SRv6VppHandler) DeletePolicySegment(bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment, +func (h *SRv6VppHandler) DeletePolicySegment(bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment, segmentIndex uint32) error { - handler.log.Debugf("Removing segment %v (index %v) from SR policy with binding SID %v", policySegment.Segments, segmentIndex, bindingSid) - err := handler.modPolicy(DeleteSRList, bindingSid, policy, policySegment, segmentIndex) + h.log.Debugf("Removing segment %v (index %v) from SR policy with binding SID %v", policySegment.Segments, segmentIndex, bindingSid) + err := h.modPolicy(DeleteSRList, bindingSid, policy, policySegment, segmentIndex) if err == nil { - handler.log.WithFields(logging.Fields{"binding SID": bindingSid, "list of next SIDs": policySegment.Segments, "segmentIndex": segmentIndex}). + h.log.WithFields(logging.Fields{"binding SID": bindingSid, "list of next SIDs": policySegment.Segments, "segmentIndex": segmentIndex}). Debug("SR policy modified(removed segment list)") } return err } -func (handler *SRv6VppHandler) modPolicy(operation uint8, bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment, +func (h *SRv6VppHandler) modPolicy(operation uint8, bindingSid net.IP, policy *srv6.Policy, policySegment *srv6.PolicySegment, segmentIndex uint32) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(sr.SrPolicyMod{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - - sids, err := handler.convertPolicySegment(policySegment) + sids, err := h.convertPolicySegment(policySegment) if err != nil { return err } @@ -341,7 +320,7 @@ func (handler *SRv6VppHandler) modPolicy(operation uint8, bindingSid net.IP, pol reply := &sr.SrPolicyModReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { @@ -350,7 +329,7 @@ func (handler *SRv6VppHandler) modPolicy(operation uint8, bindingSid net.IP, pol return nil } -func (handler *SRv6VppHandler) convertPolicySegment(policySegment *srv6.PolicySegment) (*sr.Srv6SidList, error) { +func (h *SRv6VppHandler) convertPolicySegment(policySegment *srv6.PolicySegment) (*sr.Srv6SidList, error) { var segments []sr.Srv6Sid for _, sid := range policySegment.Segments { // parse to IPv6 address @@ -374,20 +353,16 @@ func (handler *SRv6VppHandler) convertPolicySegment(policySegment *srv6.PolicySe } // AddSteering sets in VPP steering into SRv6 policy. -func (handler *SRv6VppHandler) AddSteering(steering *srv6.Steering, swIfIndex ifaceidx.SwIfIndex) error { - return handler.addDelSteering(false, steering, swIfIndex) +func (h *SRv6VppHandler) AddSteering(steering *srv6.Steering, swIfIndex ifaceidx.SwIfIndex) error { + return h.addDelSteering(false, steering, swIfIndex) } // RemoveSteering removes in VPP steering into SRv6 policy. -func (handler *SRv6VppHandler) RemoveSteering(steering *srv6.Steering, swIfIndex ifaceidx.SwIfIndex) error { - return handler.addDelSteering(true, steering, swIfIndex) +func (h *SRv6VppHandler) RemoveSteering(steering *srv6.Steering, swIfIndex ifaceidx.SwIfIndex) error { + return h.addDelSteering(true, steering, swIfIndex) } -func (handler *SRv6VppHandler) addDelSteering(delete bool, steering *srv6.Steering, swIfIndex ifaceidx.SwIfIndex) error { - defer func(t time.Time) { - handler.stopwatch.TimeLog(sr.SrSteeringAddDel{}).LogTimeEntry(time.Since(t)) - }(time.Now()) - +func (h *SRv6VppHandler) addDelSteering(delete bool, steering *srv6.Steering, swIfIndex ifaceidx.SwIfIndex) error { // defining operation strings for logging operationProgressing, operationFinished := "Adding", "Added" if delete { @@ -396,10 +371,10 @@ func (handler *SRv6VppHandler) addDelSteering(delete bool, steering *srv6.Steeri // logging info about operation with steering if steering.L3Traffic != nil { - handler.log.Debugf("%v steering for l3 traffic with destination %v to SR policy (binding SID %v, policy index %v)", + h.log.Debugf("%v steering for l3 traffic with destination %v to SR policy (binding SID %v, policy index %v)", operationProgressing, steering.L3Traffic.PrefixAddress, steering.PolicyBsid, steering.PolicyIndex) } else { - handler.log.Debugf("%v steering for l2 traffic from interface %v to SR policy (binding SID %v, policy index %v)", + h.log.Debugf("%v steering for l2 traffic from interface %v to SR policy (binding SID %v, policy index %v)", operationProgressing, steering.L2Traffic.InterfaceName, steering.PolicyBsid, steering.PolicyIndex) } @@ -451,14 +426,14 @@ func (handler *SRv6VppHandler) addDelSteering(delete bool, steering *srv6.Steeri } reply := &sr.SrSteeringAddDelReply{} - if err := handler.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { + if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { return err } if reply.Retval != 0 { return fmt.Errorf("vpp call %q returned: %d", reply.GetMessageName(), reply.Retval) } - handler.log.WithFields(logging.Fields{"steer type": steerType, "L3 prefix address bytes": prefixAddr, + h.log.WithFields(logging.Fields{"steer type": steerType, "L3 prefix address bytes": prefixAddr, "L2 interface index": intIndex, "policy binding SID": bsidAddr, "policy index": steering.PolicyIndex}). Debugf("%v steering to SR policy ", operationFinished) diff --git a/plugins/vpp/srplugin/vppcalls/srv6_test.go b/plugins/vpp/srplugin/vppcalls/srv6_test.go index 2848e53ac7..9b39cb2423 100644 --- a/plugins/vpp/srplugin/vppcalls/srv6_test.go +++ b/plugins/vpp/srplugin/vppcalls/srv6_test.go @@ -919,7 +919,7 @@ func testAddRemoveSteering(t *testing.T, removal bool) { func setup(t *testing.T) (*vppcallmock.TestCtx, vppcalls.SRv6VppAPI) { ctx := vppcallmock.SetupTestCtx(t) - vppCalls := vppcalls.NewSRv6VppHandler(ctx.MockChannel, logrus.DefaultLogger(), nil) + vppCalls := vppcalls.NewSRv6VppHandler(ctx.MockChannel, logrus.DefaultLogger()) return ctx, vppCalls } diff --git a/plugins/vpp/vpp-plugin.conf b/plugins/vpp/vpp-plugin.conf index f10ad2e04c..494593a86d 100644 --- a/plugins/vpp/vpp-plugin.conf +++ b/plugins/vpp/vpp-plugin.conf @@ -5,10 +5,6 @@ # interface configuration is preferred). mtu: 0 -# Enable or disable feature to measure binary API call duration. Measured time is shown directly in log (info level). -# Measurement is taken also for certain procedures, like resync of plugin startup. Turned off by default. -stopwatch: false - # VPP plugin resync strategy. Available options are [full] and [optimize]. Full strategy is default, and always performs # the resync, optimize can be used for cold start; it looks for interface configuration looking for interfaces. If there # is none, VPP is considered empty and resync is skipped. diff --git a/plugins/vpp/watch_events.go b/plugins/vpp/watch_events.go index 79fbf48eeb..919a99ac92 100644 --- a/plugins/vpp/watch_events.go +++ b/plugins/vpp/watch_events.go @@ -145,40 +145,82 @@ func (plugin *Plugin) onChangeEvent(e datasync.ChangeEvent) { } func (plugin *Plugin) onVppIfaceEvent(e ifaceidx.SwIfIdxDto) { - if !e.IsDelete() { - // Keep order. - plugin.aclConfigurator.ResolveCreatedInterface(e.Name, e.Idx) - plugin.arpConfigurator.ResolveCreatedInterface(e.Name) - plugin.proxyArpConfigurator.ResolveCreatedInterface(e.Name, e.Idx) - plugin.bdConfigurator.ResolveCreatedInterface(e.Name, e.Idx) - plugin.fibConfigurator.ResolveCreatedInterface(e.Name, e.Idx, func(err error) { + if e.IsDelete() { + if err := plugin.aclConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.aclConfigurator.LogError(err) + } + if err := plugin.arpConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.arpConfigurator.LogError(err) + } + if err := plugin.proxyArpConfigurator.ResolveDeletedInterface(e.Name); err != nil { + plugin.proxyArpConfigurator.LogError(err) + } + if err := plugin.bdConfigurator.ResolveDeletedInterface(e.Name); err != nil { + plugin.bdConfigurator.LogError(err) + } + plugin.fibConfigurator.ResolveDeletedInterface(e.Name, e.Idx, func(err error) { if err != nil { - plugin.Log.Error(err) + plugin.fibConfigurator.LogError(err) } }) - plugin.xcConfigurator.ResolveCreatedInterface(e.Name) - plugin.appNsConfigurator.ResolveCreatedInterface(e.Name, e.Idx) - plugin.stnConfigurator.ResolveCreatedInterface(e.Name) - plugin.routeConfigurator.ResolveCreatedInterface(e.Name, e.Idx) - plugin.natConfigurator.ResolveCreatedInterface(e.Name, e.Idx) - plugin.ipSecConfigurator.ResolveCreatedInterface(e.Name, e.Idx) + if err := plugin.xcConfigurator.ResolveDeletedInterface(e.Name); err != nil { + plugin.xcConfigurator.LogError(err) + } + if err := plugin.appNsConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.appNsConfigurator.LogError(err) + } + if err := plugin.stnConfigurator.ResolveDeletedInterface(e.Name); err != nil { + plugin.stnConfigurator.LogError(err) + } + if err := plugin.routeConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.routeConfigurator.LogError(err) + } + if err := plugin.natConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.natConfigurator.LogError(err) + } + if err := plugin.ipSecConfigurator.ResolveDeletedInterface(e.Name, e.Idx); err != nil { + plugin.ipSecConfigurator.LogError(err) + } // TODO propagate error + } else if e.IsUpdate() { + // Nothing to do here } else { - plugin.aclConfigurator.ResolveDeletedInterface(e.Name, e.Idx) - plugin.arpConfigurator.ResolveDeletedInterface(e.Name, e.Idx) - plugin.proxyArpConfigurator.ResolveDeletedInterface(e.Name) - plugin.bdConfigurator.ResolveDeletedInterface(e.Name) // TODO: e.Idx to not process data events - plugin.fibConfigurator.ResolveDeletedInterface(e.Name, e.Idx, func(err error) { + // Keep order. + if err := plugin.aclConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.aclConfigurator.LogError(err) + } + if err := plugin.arpConfigurator.ResolveCreatedInterface(e.Name); err != nil { + plugin.arpConfigurator.LogError(err) + } + if err := plugin.proxyArpConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.proxyArpConfigurator.LogError(err) + } + if err := plugin.bdConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.bdConfigurator.LogError(err) + } + plugin.fibConfigurator.ResolveCreatedInterface(e.Name, e.Idx, func(err error) { if err != nil { - plugin.Log.Error(err) + plugin.fibConfigurator.LogError(err) } }) - plugin.xcConfigurator.ResolveDeletedInterface(e.Name) - plugin.appNsConfigurator.ResolveDeletedInterface(e.Name, e.Idx) - plugin.stnConfigurator.ResolveDeletedInterface(e.Name) - plugin.routeConfigurator.ResolveDeletedInterface(e.Name, e.Idx) - plugin.natConfigurator.ResolveDeletedInterface(e.Name, e.Idx) - plugin.ipSecConfigurator.ResolveDeletedInterface(e.Name, e.Idx) + if err := plugin.xcConfigurator.ResolveCreatedInterface(e.Name); err != nil { + plugin.xcConfigurator.LogError(err) + } + if err := plugin.appNsConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.appNsConfigurator.LogError(err) + } + if err := plugin.stnConfigurator.ResolveCreatedInterface(e.Name); err != nil { + plugin.stnConfigurator.LogError(err) + } + if err := plugin.routeConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.routeConfigurator.LogError(err) + } + if err := plugin.natConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.natConfigurator.LogError(err) + } + if err := plugin.ipSecConfigurator.ResolveCreatedInterface(e.Name, e.Idx); err != nil { + plugin.ipSecConfigurator.LogError(err) + } // TODO propagate error } e.Done() @@ -189,13 +231,13 @@ func (plugin *Plugin) onLinuxIfaceEvent(e linux_ifaceidx.LinuxIfIndexDto) { if e.Metadata != nil && e.Metadata.Data != nil && e.Metadata.Data.HostIfName != "" { hostIfName = e.Metadata.Data.HostIfName } + var err error if !e.IsDelete() { - plugin.ifConfigurator.ResolveCreatedLinuxInterface(e.Name, hostIfName, e.Idx) - // TODO propagate error + err = plugin.ifConfigurator.ResolveCreatedLinuxInterface(e.Name, hostIfName, e.Idx) } else { - plugin.ifConfigurator.ResolveDeletedLinuxInterface(e.Name, hostIfName, e.Idx) - // TODO propagate error + err = plugin.ifConfigurator.ResolveDeletedLinuxInterface(e.Name, hostIfName, e.Idx) } + plugin.ifConfigurator.LogError(err) e.Done() } @@ -203,21 +245,21 @@ func (plugin *Plugin) onVppBdEvent(e l2idx.BdChangeDto) { if e.IsDelete() { plugin.fibConfigurator.ResolveDeletedBridgeDomain(e.Name, e.Idx, func(err error) { if err != nil { - plugin.Log.Error(err) + plugin.fibConfigurator.LogError(err) } }) // TODO propagate error } else if e.IsUpdate() { plugin.fibConfigurator.ResolveUpdatedBridgeDomain(e.Name, e.Idx, func(err error) { if err != nil { - plugin.Log.Error(err) + plugin.fibConfigurator.LogError(err) } }) // TODO propagate error } else { plugin.fibConfigurator.ResolveCreatedBridgeDomain(e.Name, e.Idx, func(err error) { if err != nil { - plugin.Log.Error(err) + plugin.fibConfigurator.LogError(err) } }) // TODO propagate error diff --git a/tests/linuxmock/namespace_mock.go b/tests/linuxmock/namespace_mock.go index 00bf7976ac..a51ead6648 100644 --- a/tests/linuxmock/namespace_mock.go +++ b/tests/linuxmock/namespace_mock.go @@ -4,6 +4,7 @@ import ( "github.com/ligato/vpp-agent/plugins/linux/model/interfaces" "github.com/ligato/vpp-agent/plugins/linux/model/l3" "github.com/ligato/vpp-agent/plugins/linux/nsplugin" + "github.com/vishvananda/netns" ) // NamespacePluginMock allows to mock namespace plugin methods to manage namespaces and microservices @@ -67,6 +68,22 @@ func (mock *NamespacePluginMock) getReturnValues(name string) (response []interf /* Mocked netlink handler methods */ //todo define other +// GetOrCreateNamespace implements NsManagement. +func (mock *NamespacePluginMock) GetOrCreateNamespace(ns *nsplugin.Namespace) (netns.NsHandle, error) { + items := mock.getReturnValues("GetOrCreateNamespace") + if len(items) == 1 { + switch typed := items[0].(type) { + case netns.NsHandle: + return typed, nil + case error: + return 0, typed + } + } else if len(items) == 2 { + return items[0].(netns.NsHandle), items[1].(error) + } + return 0, nil +} + // IsNamespaceAvailable implements NsManagement. func (mock *NamespacePluginMock) IsNamespaceAvailable(ns *interfaces.LinuxInterfaces_Interface_Namespace) bool { items := mock.getReturnValues("IsNamespaceAvailable") @@ -105,20 +122,20 @@ func (mock *NamespacePluginMock) SwitchToNamespace(nsMgmtCtx *nsplugin.Namespace return func() {}, nil } -// SetInterfaceNamespace implements NsManagement. -func (mock *NamespacePluginMock) SetInterfaceNamespace(ctx *nsplugin.NamespaceMgmtCtx, ifName string, namespace *interfaces.LinuxInterfaces_Interface_Namespace) error { - items := mock.getReturnValues("SetInterfaceNamespace") +// GetConfigNamespace implements NsManagement. +func (mock *NamespacePluginMock) GetConfigNamespace() *interfaces.LinuxInterfaces_Interface_Namespace { + items := mock.getReturnValues("GetConfigNamespace") if len(items) >= 1 { - return items[0].(error) + return items[0].(*interfaces.LinuxInterfaces_Interface_Namespace) } return nil } -// GetConfigNamespace implements NsManagement. -func (mock *NamespacePluginMock) GetConfigNamespace() *interfaces.LinuxInterfaces_Interface_Namespace { - items := mock.getReturnValues("GetConfigNamespace") +// ConvertMicroserviceNsToPidNs implements NsManagement +func (mock *NamespacePluginMock) ConvertMicroserviceNsToPidNs(msLabel string) (pidNs *nsplugin.Namespace) { + items := mock.getReturnValues("ConvertMicroserviceNsToPidNs") if len(items) >= 1 { - return items[0].(*interfaces.LinuxInterfaces_Interface_Namespace) + return items[0].(*nsplugin.Namespace) } return nil } diff --git a/tests/linuxmock/netlink_if_handler_mock.go b/tests/linuxmock/netlink_if_handler_mock.go index fd0dc489d5..a800222f39 100644 --- a/tests/linuxmock/netlink_if_handler_mock.go +++ b/tests/linuxmock/netlink_if_handler_mock.go @@ -17,7 +17,8 @@ package linuxmock import ( "net" - "github.com/ligato/cn-infra/logging/measure" + "github.com/ligato/vpp-agent/plugins/linux/ifplugin/linuxcalls" + "github.com/vishvananda/netlink" ) @@ -303,5 +304,12 @@ func (mock *IfNetlinkHandlerMock) GetInterfaceByName(ifName string) (*net.Interf return nil, nil } -// SetStopwatch sets stopwatch. -func (mock *IfNetlinkHandlerMock) SetStopwatch(stopwatch *measure.Stopwatch) {} +// DumpInterfaces does not return a value +func (mock *IfNetlinkHandlerMock) DumpInterfaces() ([]*linuxcalls.LinuxInterfaceDetails, error) { + return nil, nil +} + +// DumpInterfaceStatistics does not return a value +func (mock *IfNetlinkHandlerMock) DumpInterfaceStatistics() ([]*linuxcalls.LinuxInterfaceStatistics, error) { + return nil, nil +} diff --git a/tests/linuxmock/netlink_l3_handler_mock.go b/tests/linuxmock/netlink_l3_handler_mock.go index b6929c4333..0822f6c6ed 100644 --- a/tests/linuxmock/netlink_l3_handler_mock.go +++ b/tests/linuxmock/netlink_l3_handler_mock.go @@ -15,7 +15,7 @@ package linuxmock import ( - "github.com/ligato/cn-infra/logging/measure" + "github.com/ligato/vpp-agent/plugins/linux/l3plugin/linuxcalls" "github.com/vishvananda/netlink" ) @@ -150,5 +150,28 @@ func (mock *L3NetlinkHandlerMock) DelStaticRoute(name string, route *netlink.Rou return nil } -// SetStopwatch implements . -func (mock *L3NetlinkHandlerMock) SetStopwatch(stopwatch *measure.Stopwatch) {} +// GetStaticRoutes implements NetlinkAPI. +func (mock *L3NetlinkHandlerMock) GetStaticRoutes(link netlink.Link, family int) ([]netlink.Route, error) { + items := mock.getReturnValues("GetStaticRoutes") + if len(items) == 1 { + switch typed := items[0].(type) { + case []netlink.Route: + return typed, nil + case error: + return nil, typed + } + } else if len(items) == 2 { + return items[0].([]netlink.Route), items[1].(error) + } + return nil, nil +} + +// DumpArpEntries does not return a value +func (mock *L3NetlinkHandlerMock) DumpArpEntries() ([]*linuxcalls.LinuxArpDetails, error) { + return nil, nil +} + +// DumpRoutes does not return a value +func (mock *L3NetlinkHandlerMock) DumpRoutes() ([]*linuxcalls.LinuxRouteDetails, error) { + return nil, nil +} diff --git a/tests/robot/libraries/SshCommons.robot b/tests/robot/libraries/SshCommons.robot index 6be4a49b35..4430c80b2c 100644 --- a/tests/robot/libraries/SshCommons.robot +++ b/tests/robot/libraries/SshCommons.robot @@ -8,13 +8,16 @@ Open_Ssh_Connection_Kube [Documentation] Create SSH connection to \{ip} aliased as \${name} and log in using \${user} and \${pswd} (or rsa). ... Log to output file. The new connection is left active. BuiltIn.Log_Many ${name} ${ip} ${user} ${pswd} + ${time} = DateTime.Get_Current_Date ${connection}= Open Connection ${ip} alias=${name} timeout=${SSH_TIMEOUT} #${out} = BuiltIn.Run_Keyword_If """${pswd}""" != "rsa_id" SSHLibrary.Login ${user} ${pswd} #${out2} = BuiltIn.Run_Keyword_If """${pswd}""" == "rsa_id" SSHLibrary.Login_With_Public_Key ${user} %{HOME}/.ssh/id_rsa any + OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${name}.log ${time}${\n}*** Command: Login${\n} ${out} = BuiltIn.Run_Keyword_If """${pswd}""" != "rsa_id" Login ${user} ${pswd} ${out2} = BuiltIn.Run_Keyword_If """${pswd}""" == "rsa_id" SSHLibrary.Login_With_Public_Key ${user} %{HOME}/.ssh/id_rsa any - BuiltIn.Run_Keyword_If """${out}""" != "None" OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${name}.log *** Command: Login${\n}${out}${\n} - BuiltIn.Run_Keyword_If """${out2}""" != "None" OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${name}.log *** Command: Login${\n}${out2}${\n} + ${time} = DateTime.Get_Current_Date + BuiltIn.Run_Keyword_If """${out}""" != "None" OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${name}.log ${time}${\n}*** Response1: ${out}${\n} + BuiltIn.Run_Keyword_If """${out2}""" != "None" OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${name}.log ${time}${\n}*** Response2: {out2}${\n} [Return] ${connection} Switch_And_Execute_With_Copied_File @@ -95,10 +98,13 @@ Append_Command_Log Builtin.Log_Many ${command} ${output} ${stderr} ${rc} ${connection} = SSHLibrary.Get_Connection ${time} = DateTime.Get_Current_Date + OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${connection.alias}.log ${time}${\n}*** Command: ${command}${\n} + OperatingSystem.Append_To_File ${RESULTS_FOLDER_SUITE}/output_${connection.alias}.log ${time}${\n}*** Command: ${command}${\n} ${output_length} = BuiltIn.Get_Length ${output} ${if_output} = BuiltIn.Set_Variable_If ${output_length} ${output}${\n} ${EMPTY} ${stderr_length} = Builtin.Get_Length ${stderr} ${if_stderr} = BuiltIn.Set_Variable_If ${stderr_length} *** Stderr: ${stderr}${\n} ${EMPTY} ${if_rc} = BuiltIn.Set_Variable_If """${rc}""" *** Return code: ${rc}${\n} ${EMPTY} - OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${connection.alias}.log ${time}${\n}*** Command: ${command}${\n}${if_stderr}${if_rc}${if_output} - OperatingSystem.Append_To_File ${RESULTS_FOLDER_SUITE}/output_${connection.alias}.log ${time}${\n}*** Command: ${command}${\n}${if_stderr}${if_rc}${if_output} \ No newline at end of file + ${time} = DateTime.Get_Current_Date + OperatingSystem.Append_To_File ${RESULTS_FOLDER}/output_${connection.alias}.log ${time}${\n}*** Response: ${if_stderr}${if_rc}${if_output} + OperatingSystem.Append_To_File ${RESULTS_FOLDER_SUITE}/output_${connection.alias}.log ${time}${\n}*** Response: ${if_stderr}${if_rc}${if_output} \ No newline at end of file diff --git a/tests/robot/libraries/common_setup-teardown.robot b/tests/robot/libraries/common_setup-teardown.robot index 8fa3a72762..b14e117147 100644 --- a/tests/robot/libraries/common_setup-teardown.robot +++ b/tests/robot/libraries/common_setup-teardown.robot @@ -3,7 +3,7 @@ *** Settings *** Library String Library RequestsLibrary -Library SSHLibrary timeout=60s +Library SSHLibrary timeout=15s loglevel=TRACE Resource ssh.robot *** Keywords *** diff --git a/tests/robot/libraries/configurations.robot b/tests/robot/libraries/configurations.robot index 71dc247a67..e3b4b4a021 100644 --- a/tests/robot/libraries/configurations.robot +++ b/tests/robot/libraries/configurations.robot @@ -70,4 +70,16 @@ Configure Environment 6 Execute On Machine docker ${DOCKER_COMMAND} images Execute On Machine docker ${DOCKER_COMMAND} ps -as Start SFC Controller Container With Own Config ${sfc_conf} + Sleep ${SYNC_SLEEP} + +Configure Environment 7 + [Documentation] Setup environment with 1 vpp and 3 vpp nodes (same as conf 4 but without sfc_setup) + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Add Agent Node node_1 + Add Agent Node node_2 + Add Agent Node node_3 + Execute In Container agent_vpp_1 echo $MICROSERVICE_LABEL + Execute In Container agent_vpp_1 ls -al + Execute On Machine docker ${DOCKER_COMMAND} images + Execute On Machine docker ${DOCKER_COMMAND} ps -as Sleep ${SYNC_SLEEP} \ No newline at end of file diff --git a/tests/robot/libraries/docker.robot b/tests/robot/libraries/docker.robot index a0a63135c0..0d6d47a3f1 100644 --- a/tests/robot/libraries/docker.robot +++ b/tests/robot/libraries/docker.robot @@ -3,7 +3,7 @@ *** Settings *** Library Collections Library RequestsLibrary -Library SSHLibrary timeout=60s +Library SSHLibrary timeout=15s loglevel=TRACE Library DateTime *** Variables *** @@ -12,35 +12,67 @@ ${timeout_etcd}= 30s *** Keywords *** Add Agent Node [Arguments] ${node} - Log Many ${node} Open SSH Connection ${node} ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} - Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} --sysctl net.ipv6.conf.all.disable_ipv6=0 -it -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${${node}_DOCKER_IMAGE} + Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -e KAFKA_CONFIG=disabled --sysctl net.ipv6.conf.all.disable_ipv6=0 -it -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${${node}_DOCKER_IMAGE} bash #Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -it -p ${${node}_PING_HOST_PORT}:${${node}_PING_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${${node}_DOCKER_IMAGE} Write To Machine ${node} ${DOCKER_COMMAND} start ${node} Append To List ${NODES} ${node} Create Session ${node} http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' Set Suite Variable ${${node}_HOSTNAME} ${hostname} - Log List ${NODES} Add Agent Node Again [Arguments] ${node} - Log Many ${node} Open SSH Connection ${node}_again ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} - Execute On Machine ${node}_again ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} --sysctl net.ipv6.conf.all.disable_ipv6=0 -it -p ${${node}_AGAIN_REST_API_HOST_PORT}:${${node}_AGAIN_REST_API_PORT} --name ${node}_again ${${node}_DOCKER_IMAGE} + Execute On Machine ${node}_again ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -e KAFKA_CONFIG=disabled --sysctl net.ipv6.conf.all.disable_ipv6=0 -it -p ${${node}_AGAIN_REST_API_HOST_PORT}:${${node}_AGAIN_REST_API_PORT} --name ${node}_again ${${node}_DOCKER_IMAGE} bash #Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -it -p ${${node}_PING_HOST_PORT}:${${node}_PING_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${${node}_DOCKER_IMAGE} Write To Machine ${node}_again ${DOCKER_COMMAND} start ${node}_again Append To List ${NODES} ${node}_again Create Session ${node}_again http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' Set Suite Variable ${${node}_again_HOSTNAME} ${hostname} - Log List ${NODES} + +Add Agent Node With Kafka + [Arguments] ${node} + Open SSH Connection ${node} ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} + Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} --sysctl net.ipv6.conf.all.disable_ipv6=0 -it -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${${node}_DOCKER_IMAGE} bash + #Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -it -p ${${node}_PING_HOST_PORT}:${${node}_PING_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${${node}_DOCKER_IMAGE} + Write To Machine ${node} ${DOCKER_COMMAND} start ${node} + Append To List ${NODES} ${node} + Create Session ${node} http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} + ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' + Set Suite Variable ${${node}_HOSTNAME} ${hostname} + +Add Agent Node With Kafka Again + [Arguments] ${node} + Open SSH Connection ${node}_again ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} + Execute On Machine ${node}_again ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} --sysctl net.ipv6.conf.all.disable_ipv6=0 -it -p ${${node}_AGAIN_REST_API_HOST_PORT}:${${node}_AGAIN_REST_API_PORT} --name ${node}_again ${${node}_DOCKER_IMAGE} bash + #Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -it -p ${${node}_PING_HOST_PORT}:${${node}_PING_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${${node}_DOCKER_IMAGE} + Write To Machine ${node}_again ${DOCKER_COMMAND} start ${node}_again + Append To List ${NODES} ${node}_again + Create Session ${node}_again http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} + ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' + Set Suite Variable ${${node}_again_HOSTNAME} ${hostname} + Add Agent VPP Node [Arguments] ${node} ${vswitch}=${FALSE} - Log Many ${node} ${vswitch} ${add_params}= Set Variable If ${vswitch} --pid=host -v "/var/run/docker.sock:/var/run/docker.sock" ${EMPTY} - Log ${add_params} + Open SSH Connection ${node} ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} + Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -e KAFKA_CONFIG=disabled -e VPP_STATUS_PUBLISHERS=etcd -e INITIAL_LOGLVL=debug --sysctl net.ipv6.conf.all.disable_ipv6=0 -it --privileged -v "${VPP_AGENT_HOST_MEMIF_SOCKET_FOLDER}:${${node}_MEMIF_SOCKET_FOLDER}" -v "${DOCKER_SOCKET_FOLDER}:${${node}_SOCKET_FOLDER}" -p ${${node}_VPP_HOST_PORT}:${${node}_VPP_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${add_params} ${${node}_DOCKER_IMAGE} + Write To Machine ${node} ${DOCKER_COMMAND} start ${node} + Append To List ${NODES} ${node} + Open SSH Connection ${node}_term ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} + Open SSH Connection ${node}_vat ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} + vpp_term: Open VPP Terminal ${node} + vat_term: Open VAT Terminal ${node} + Create Session ${node} http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} + ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' + Set Suite Variable ${${node}_HOSTNAME} ${hostname} + +Add Agent VPP Node With Kafka + [Arguments] ${node} ${vswitch}=${FALSE} + ${add_params}= Set Variable If ${vswitch} --pid=host -v "/var/run/docker.sock:/var/run/docker.sock" ${EMPTY} Open SSH Connection ${node} ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -e VPP_STATUS_PUBLISHERS=etcd -e INITIAL_LOGLVL=debug --sysctl net.ipv6.conf.all.disable_ipv6=0 -it --privileged -v "${VPP_AGENT_HOST_MEMIF_SOCKET_FOLDER}:${${node}_MEMIF_SOCKET_FOLDER}" -v "${DOCKER_SOCKET_FOLDER}:${${node}_SOCKET_FOLDER}" -p ${${node}_VPP_HOST_PORT}:${${node}_VPP_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${add_params} ${${node}_DOCKER_IMAGE} Write To Machine ${node} ${DOCKER_COMMAND} start ${node} @@ -52,13 +84,12 @@ Add Agent VPP Node Create Session ${node} http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' Set Suite Variable ${${node}_HOSTNAME} ${hostname} - Log List ${NODES} + Add Agent Libmemif Node [Arguments] ${node} - Log Many ${node} Open SSH Connection ${node} ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} - Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} --sysctl net.ipv6.conf.all.disable_ipv6=0 -it --privileged -v "${VPP_AGENT_HOST_MEMIF_SOCKET_FOLDER}:${${node}_MEMIF_SOCKET_FOLDER}" --name ${node} ${${node}_DOCKER_IMAGE} /bin/bash + Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -e KAFKA_CONFIG=disabled --sysctl net.ipv6.conf.all.disable_ipv6=0 -it --privileged -v "${VPP_AGENT_HOST_MEMIF_SOCKET_FOLDER}:${${node}_MEMIF_SOCKET_FOLDER}" --name ${node} ${${node}_DOCKER_IMAGE} /bin/bash Write To Machine ${node} ${DOCKER_COMMAND} start ${node} Append To List ${NODES} ${node} #${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' @@ -67,23 +98,17 @@ Add Agent Libmemif Node Set Suite Variable ${${node}_HOSTNAME} ${hostname} Open SSH Connection ${node}_lmterm ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} lmterm: Open LM Terminal ${node} - Log List ${NODES} - Add Agent VPP Node With Physical Int [Arguments] ${node} ${int_nums} ${vswitch}=${FALSE} - Log Many ${node} ${int_nums} ${vswitch} ${add_params}= Set Variable If ${vswitch} --pid=host -v "/var/run/docker.sock:/var/run/docker.sock" ${EMPTY} - Log ${add_params} Open SSH Connection ${node} ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} - Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} --sysctl net.ipv6.conf.all.disable_ipv6=0 -it --privileged -v "${DOCKER_SOCKET_FOLDER}:${${node}_SOCKET_FOLDER}" -p ${${node}_VPP_HOST_PORT}:${${node}_VPP_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${add_params} ${${node}_DOCKER_IMAGE} + Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -e KAFKA_CONFIG=disabled --sysctl net.ipv6.conf.all.disable_ipv6=0 -it --privileged -v "${DOCKER_SOCKET_FOLDER}:${${node}_SOCKET_FOLDER}" -p ${${node}_VPP_HOST_PORT}:${${node}_VPP_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${add_params} ${${node}_DOCKER_IMAGE} ${devs}= Set Variable ${EMPTY} :FOR ${int_num} IN @{int_nums} \ ${devs}= Set Variable ${devs}${\n}dev ${DOCKER_PHYSICAL_INT_${int_num}} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/vpp_physical_int.conf - Log Many ${data} ${devs} ${data}= Replace Variables ${data} - Log ${data} Create File ${RESULTS_FOLDER}/vpp-${node}.conf ${data} Create File ${RESULTS_FOLDER_SUITE}/vpp-${node}.conf ${data} Execute On Machine ${node} ${DOCKER_COMMAND} cp ${EXECDIR}/${RESULTS_FOLDER}/vpp-${node}.conf ${node}:${VPP_CONF_PATH} @@ -97,27 +122,22 @@ Add Agent VPP Node With Physical Int Create Session ${node} http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' Set Suite Variable ${${node}_HOSTNAME} ${hostname} - Log List ${NODES} Remove All Nodes - Log List ${NODES} :FOR ${id} IN @{NODES} \ Remove Node ${id} Execute On Machine docker ${DOCKER_COMMAND} ps -as Remove All VPP Nodes - Log List ${NODES} :FOR ${id} IN @{NODES} \ Run Keyword If "vpp" in "${id}" Remove Node ${id} Execute On Machine docker ${DOCKER_COMMAND} ps -as Remove Node [Arguments] ${node} - Log ${node} ${log}= Execute On Machine docker ${DOCKER_COMMAND} logs --details -t ${node} log=false Append To File ${RESULTS_FOLDER}/output_${node}_container_agent.log ${log} Append To File ${RESULTS_FOLDER_SUITE}/output_${node}_container_agent.log ${log} - Log ${node} Output Switch Connection ${node} Close Connection Run Keyword If "vpp" in "${node}" Remove VPP Connections ${node} @@ -127,31 +147,25 @@ Remove Node Remove VPP Connections [Arguments] ${node} - Log ${node} - Log ${node}_term Output Switch Connection ${node}_term Close Connection - Log ${node}_vat Output Switch Connection ${node}_vat Close Connection Remove LM Connections [Arguments] ${node} - Log ${node} - Log ${node}_lmterm Output Switch Connection ${node}_lmterm Close Connection Check ETCD Running ${out}= Write To Machine docker ${DOCKER_COMMAND} exec -it etcd etcdctl version - Log Many ${out} Should Contain ${out} etcdctl version: [Return] ${out} Start ETCD Server Open SSH Connection etcd ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} Execute On Machine etcd ${ETCD_SERVER_CREATE} - Write To Machine etcd ${DOCKER_COMMAND} start -i etcd + ${out}= Write To Machine Until String etcd ${DOCKER_COMMAND} start -i etcd etcdmain: ready to serve client requests # ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec etcd bash -c 'echo $HOSTNAME' # etcd nema bash, preto dame hostname natvrdo ${hostname}= Set Variable etcd @@ -160,82 +174,75 @@ Start ETCD Server Stop ETCD Server Execute On Machine docker ${ETCD_SERVER_DESTROY} - Log etcd Output Execute In Container [Arguments] ${container} ${command} - Log Many ${container} ${command} Switch Connection docker ${currdate}= Get Current Date + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} ${out} ${stderr} ${rc}= Execute Command ${DOCKER_COMMAND} exec ${container} ${command} return_stderr=True return_rc=True - Log ${out} - Log ${stderr} - Log ${rc} ${status}= Run Keyword And Return Status Should be Empty ${stderr} Run Keyword If ${status}==False Log One or more error occured during execution of a command ${command} in container ${container} level=WARN - Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n}*** - Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n}*** + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Response: ${out}${\n}*** + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Response: ${out}${\n}*** Run Keyword If ${status}==False Append To File ${RESULTS_FOLDER}/output_${container}.log *** Error: ${stderr}${\n} Run Keyword If ${status}==False Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Error: ${stderr}${\n} [Return] ${out} Execute In Container Background [Arguments] ${container} ${command} - Log Many ${container} ${command} Switch Connection docker ${currdate}= Get Current Date + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} ${out} ${stderr}= Execute Command ${DOCKER_COMMAND} exec -d ${container} ${command} return_stderr=True - Log ${out} - Log ${stderr} ${status}= Run Keyword And Return Status Should be Empty ${stderr} Run Keyword If ${status}==False Log One or more error occured during execution of a command ${command} in container ${container} level=WARN - Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n} - Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n} + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Response: ${out}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} response: ${out}${\n} Run Keyword If ${status}==False Append To File ${RESULTS_FOLDER}/output_${container}.log *** Error: ${stderr}${\n} Run Keyword If ${status}==False Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Error: ${stderr}${\n} [Return] ${out} Write To Container Until Prompt - [Arguments] ${container} ${command} ${prompt}=root@ ${delay}=${SSH_READ_DELAY} - [Documentation] *Write Container ${container} ${command}* - ... Writing ${command} to connection with name ${container} and reading until prompt - ... Output log is added to container output log - Log Many ${container} ${command} ${prompt} ${delay} - Switch Connection ${container} - ${currdate}= Get Current Date - Write ${command} - ${out}= Read Until ${prompt}${${container}_HOSTNAME} - Log ${out} - ${out2}= Read delay=${delay} - Log ${out2} - Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} - Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} - [Return] ${out}${out2} + [Arguments] ${container} ${command} ${prompt}=root@ ${delay}=${SSH_READ_DELAY} + [Documentation] *Write Container ${container} ${command}* + ... Writing ${command} to connection with name ${container} and reading until prompt + ... Output log is added to container output log + Switch Connection ${container} + ${currdate}= Get Current Date + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} + Write ${command} + ${out}= Read Until ${prompt}${${container}_HOSTNAME} loglevel=TRACE + ${out2}= Read loglevel=TRACE delay=${delay} + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Response: ${out}${out2}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Response: ${out}${out2}${\n} + [Return] ${out}${out2} Write Command to Container - [Arguments] ${container} ${command} ${delay}=${SSH_READ_DELAY} - [Documentation] *Write Container ${container} ${command}* - ... Writing ${command} to connection with name ${container} and reading output - ... Output log is added to container output log - Log Many ${container} ${command} ${delay} - Switch Connection ${container} - ${currdate}= Get Current Date - ${written}= Write ${command} - Log ${written} - ${out}= Read delay=${delay} - Should Not Contain ${out} ${written} # Was consumed from the output - ${out2}= Read delay=${delay} - Log ${out2} - Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} - Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} - [Return] ${out}${out2} + [Arguments] ${container} ${command} ${delay}=${SSH_READ_DELAY} + [Documentation] *Write Container ${container} ${command}* + ... Writing ${command} to connection with name ${container} and reading output + ... Output log is added to container output log + Switch Connection ${container} + ${currdate}= Get Current Date + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Command: ${command}${\n} + ${written}= Write ${command} + ${out}= Read loglevel=TRACE delay=${delay} + Should Not Contain ${out} ${written} # Was consumed from the output + ${out2}= Read loglevel=TRACE delay=${delay} + Append To File ${RESULTS_FOLDER}/output_${container}.log *** Time:${currdate} Response: ${out}${out2}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${container}.log *** Time:${currdate} Response: ${out}${out2}${\n} + [Return] ${out}${out2} Start Dev Container [Arguments] ${command}=bash - Log ${command} Open SSH Connection dev ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} - Execute On Machine dev ${DOCKER_COMMAND} create -it --name dev --privileged ${DEV_IMAGE} ${command} + Execute On Machine dev ${DOCKER_COMMAND} create -it --name dev -e KAFKA_CONFIG=disabled --privileged ${DEV_IMAGE} ${command} Write To Machine dev ${DOCKER_COMMAND} start -i dev Switch Connection dev Set Client Configuration timeout=600s @@ -244,7 +251,6 @@ Start Dev Container Stop Dev Container Execute On Machine docker ${DOCKER_COMMAND} rm -f dev - Log dev Output Update Agent In Dev Container Write To Container Until Prompt dev cd $GOPATH/src/gitlab.cisco.com/ctao/vnf-agent @@ -261,11 +267,9 @@ Start Kafka Server Stop Kafka Server Execute On Machine docker ${KAFKA_SERVER_DESTROY} - Log kafka Output Start VPP Ctl Container [Arguments] ${command}=bash - Log ${command} Open SSH Connection vpp_agent_ctl ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} Execute On Machine vpp_agent_ctl ${DOCKER_COMMAND} create -it --name vpp_agent_ctl ${VPP_AGENT_CTL_IMAGE_NAME} ${command} Write To Machine vpp_agent_ctl ${DOCKER_COMMAND} start -i vpp_agent_ctl @@ -274,11 +278,9 @@ Start VPP Ctl Container Stop VPP Ctl Container Execute On Machine docker ${DOCKER_COMMAND} rm -f vpp_agent_ctl - Log vpp_agent_ctl Output Start SFC Controller Container With Own Config [Arguments] ${config} - Log ${config} Open SSH Connection sfc_controller ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} Execute On Machine sfc_controller ${DOCKER_COMMAND} create -it --name sfc_controller ${SFC_CONTROLLER_IMAGE_NAME} SSHLibrary.Put_file ${DATA_FOLDER}/${config} /tmp/ @@ -290,4 +292,3 @@ Start SFC Controller Container With Own Config Stop SFC Controller Container Execute On Machine docker ${DOCKER_COMMAND} rm -f sfc_controller - Log sfc_controller Output diff --git a/tests/robot/libraries/kubernetes/KubeSetup.robot b/tests/robot/libraries/kubernetes/KubeSetup.robot index 38ba44438c..4c9bbc8965 100644 --- a/tests/robot/libraries/kubernetes/KubeSetup.robot +++ b/tests/robot/libraries/kubernetes/KubeSetup.robot @@ -1,6 +1,6 @@ *** Settings *** Library OperatingSystem -Library SSHLibrary timeout=60s +Library SSHLibrary timeout=15s loglevel=TRACE Resource ../setup-teardown.robot Resource ../SshCommons.robot Documentation Contains keywords used to setup and teardown Kubernetes tests. diff --git a/tests/robot/libraries/kubernetes/KubeTestOperations.robot b/tests/robot/libraries/kubernetes/KubeTestOperations.robot index 0abe9c08af..5d1aa374b9 100644 --- a/tests/robot/libraries/kubernetes/KubeTestOperations.robot +++ b/tests/robot/libraries/kubernetes/KubeTestOperations.robot @@ -25,14 +25,12 @@ Trigger Pod Restart - VPP SIGSEGV [Arguments] ${pod_name} BuiltIn.Log ${pod_name} ${stdout} = Run Command In Pod pkill --signal 11 -f /usr/bin/vpp ${pod_name} - log ${stdout} Trigger Pod Restart - Pod Deletion [Documentation] Trigger a pod restart by deleting the pod using kubectl. [Arguments] ${ssh_session} ${pod_name} ${vswitch}=${FALSE} BuiltIn.Log Many ${ssh_session} ${pod_name} ${vswitch} ${stdout} = Switch_And_Execute_Command ${ssh_session} kubectl delete pod ${pod_name} - log ${stdout} Wait Until Keyword Succeeds 20sec 1sec KubeEnv.Verify_Pod_Not_Terminating ${ssh_session} ${pod_name} Run Keyword If ${vswitch} Get Vswitch Pod Name ${ssh_session} @@ -43,7 +41,6 @@ Ping Until Success - Unix Ping [Timeout] ${timeout} BuiltIn.Log Many ${source_pod_name} ${destination_ip} ${timeout} ${stdout} = Run Command In Pod /bin/bash -c "until ping -c1 -w1 ${destination_ip} &>/dev/null; do :; done" ${source_pod_name} - log ${stdout} Ping Until Success - VPP Ping [Documentation] Repeatedly execute ping from the named pod's VPP until @@ -122,7 +119,6 @@ Scale Pod Restart - Pod Deletion [Documentation] Trigger pod restart in scale test scenario. Restart ... the first pod of the specified type in each bridge segment. [Arguments] ${pod_type} - Log Many ${topology} ${pod_type} :FOR ${bridge_segment} IN @{topology} \ Trigger Pod Restart - Pod Deletion ${testbed_connection} ${bridge_segment["${pod_type}"][0]["name"]} @@ -130,7 +126,6 @@ Scale Pod Restart - VPP SIGSEGV [Documentation] Trigger pod restart in scale test scenario. Restart ... the first pod of the specified type in each bridge segment. [Arguments] ${pod_type} - Log Many ${topology} ${pod_type} :FOR ${bridge_segment} IN @{topology} \ Trigger Pod Restart - VPP SIGSEGV ${bridge_segment["${pod_type}"][0]["name"]} @@ -138,7 +133,6 @@ Scale Wait For Reconnect - Unix Ping [Documentation] Run "Ping Until Success" sequentially for each pod ... restarted in scale test scenario. [Arguments] ${timeout_per_bridge}=120s - Log Many ${topology} ${timeout_per_bridge} :FOR ${bridge_segment} IN @{topology} \ Ping Until Success - Unix Ping ${bridge_segment["novpp"][0]["name"]} ${bridge_segment["vnf"][0]["ip"]} ${timeout_per_bridge} @@ -146,6 +140,5 @@ Scale Wait For Reconnect - VPP Ping [Documentation] Run "Ping Until Success" sequentially for each pod ... restarted in scale test scenario. [Arguments] ${timeout_per_bridge}=120s - Log Many ${topology} ${timeout_per_bridge} :FOR ${bridge_segment} IN @{topology} \ Ping Until Success - VPP Ping ${bridge_segment["vnf"][0]["name"]} ${bridge_segment["novpp"][0]["ip"]} ${timeout_per_bridge} diff --git a/tests/robot/libraries/linux.robot b/tests/robot/libraries/linux.robot index ebf70cd77b..b2f67a5be7 100644 --- a/tests/robot/libraries/linux.robot +++ b/tests/robot/libraries/linux.robot @@ -12,29 +12,22 @@ ${TCPPING}= nc -zv *** Keywords *** linux: Get Linux Interfaces [Arguments] ${node} - Log ${node} ${out}= Execute In Container ${node} ip a - Log ${out} ${ints}= Parse Linux Interfaces ${out} - Log ${ints} [Return] ${ints} linux: Check Veth Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} ${desired_state} ${veth_config}= vpp_ctl: Get Linux Interface Config As Json ${node} ${name} ${peer}= Set Variable ${veth_config["veth"]["peer_if_name"]} - Log ${peer} ${ints}= linux: Get Linux Interfaces ${node} ${actual_state}= Pick Linux Interface ${ints} ${name}\@${peer} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} linux: Check Interface Presence [Arguments] ${node} ${mac} ${status}=${TRUE} [Documentation] Checking if specified interface with mac exists in linux - Log Many ${node} ${mac} ${status} ${ints}= linux: Get Linux Interfaces ${node} ${result}= Check Linux Interface Presence ${ints} ${mac} Should Be Equal ${result} ${status} @@ -42,51 +35,42 @@ linux: Check Interface Presence linux: Check Interface With IP Presence [Arguments] ${node} ${mac} ${ip} ${status}=${TRUE} [Documentation] Checking if specified interface with mac and ip exists in linux - Log Many ${node} ${mac} ${ip} ${status} ${ints}= linux: Get Linux Interfaces ${node} ${result}= Check Linux Interface IP Presence ${ints} ${mac} ${ip} Should Be Equal ${result} ${status} linux: Interface Is Created [Arguments] ${node} ${mac} - Log Many ${node} ${mac} Wait Until Keyword Succeeds ${interface_timeout} 3s linux: Check Interface Presence ${node} ${mac} linux: Interface With IP Is Created [Arguments] ${node} ${mac} ${ipv4} - Log Many ${node} ${mac} ${ipv4} Wait Until Keyword Succeeds ${interface_timeout} 3s linux: Check Interface With IP Presence ${node} ${mac} ${ipv4} linux: Interface Is Deleted [Arguments] ${node} ${mac} - Log Many ${node} ${mac} Wait Until Keyword Succeeds ${interface_timeout} 3s linux: Check Interface Presence ${node} ${mac} ${FALSE} linux: Interface With IP Is Deleted [Arguments] ${node} ${mac} ${ipv4} - Log Many ${node} ${mac} ${ipv4} Wait Until Keyword Succeeds ${interface_timeout} 3s linux: Check Interface With IP Presence ${node} ${mac} ${ipv4} ${FALSE} linux: Interface Exists [Arguments] ${node} ${mac} - Log Many ${node} ${mac} linux: Check Interface Presence ${node} ${mac} linux: Interface Not Exists [Arguments] ${node} ${mac} - Log Many ${node} ${mac} linux: Check Interface Presence ${node} ${mac} ${FALSE} linux: Check Ping [Arguments] ${node} ${ip} - Log Many ${node} ${ip} ${out}= Execute In Container ${node} ping -c 5 ${ip} Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss linux: Check Ping6 [Arguments] ${node} ${ip} - Log Many ${node} ${ip} ${out}= Execute In Container ${node} ping6 -c 5 ${ip} Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss @@ -94,18 +78,15 @@ linux: Check Ping6 linux: Run TCP Ping Server On Node [Arguments] ${node} ${port} [Documentation] Run TCP PingServer as listener on node ${node} - Log Many ${node} ${port} ${out}= Execute In Container Background ${node} ${PINGSERVER_TCP} ${port} linux: Run UDP Ping Server On Node [Arguments] ${node} ${port} [Documentation] Run UDP PingServer as listener on node ${node} - Log Many ${node} ${port} ${out}= Execute In Container Background ${node} ${PINGSERVER_UDP} ${port} linux: TCPPing [Arguments] ${node} ${ip} ${port} - Log Many ${node} ${ip} ${port} #${out}= Execute In Container ${node} ${TCPPING} ${ip} ${port} #${out}= Write To Container Until Prompt ${node} ${TCPPING} ${ip} ${port} ${out}= Write Command to Container ${node} ${TCPPING} ${ip} ${port} @@ -114,7 +95,6 @@ linux: TCPPing linux: TCPPingNot [Arguments] ${node} ${ip} ${port} - Log Many ${node} ${ip} ${port} #${out}= Execute In Container ${node} ${TCPPING} ${ip} ${port} #${out}= Write To Container Until Prompt ${node} ${TCPPING} ${ip} ${port} ${out}= Write Command to Container ${node} ${TCPPING} ${ip} ${port} @@ -123,7 +103,6 @@ linux: TCPPingNot linux: UDPPing [Arguments] ${node} ${ip} ${port} - Log Many ${node} ${ip} ${port} #${out}= Execute In Container ${node} ${UDPPING} ${ip} ${port} #${out}= Write To Container Until Prompt ${node} ${UDPPING} ${ip} ${port} ${out}= Write Command to Container ${node} ${UDPPING} ${ip} ${port} @@ -132,7 +111,6 @@ linux: UDPPing linux: UDPPingNot [Arguments] ${node} ${ip} ${port} - Log Many ${node} ${ip} ${port} #${out}= Execute In Container ${node} ${UDPPING} ${ip} ${port} #${out}= Write To Container Until Prompt ${node} ${UDPPING} ${ip} ${port} ${out}= Write Command to Container ${node} ${UDPPING} ${ip} ${port} @@ -141,24 +119,18 @@ linux: UDPPingNot linux: Check Processes on Node [Arguments] ${node} - Log ${node} ${out}= Execute In Container ${node} ps aux linux: Set Host TAP Interface [Arguments] ${node} ${host_if_name} ${ip} ${prefix} - Log Many ${node} ${host_if_name} ${ip} ${prefix} ${out}= Execute In Container ${node} ip link set dev ${host_if_name} up - Log ${out} ${out}= Execute In Container ${node} ip addr add ${ip}/${prefix} dev ${host_if_name} - Log ${out} linux: Add Route [Arguments] ${node} ${destination_ip} ${prefix} ${next_hop_ip} - Log Many ${node} ${destination_ip} ${prefix} ${next_hop_ip} Execute In Container ${node} ip route add ${destination_ip}/${prefix} via ${next_hop_ip} linux: Delete Route [Arguments] ${node} ${destination_ip} ${prefix} ${next_hop_ip} - Log Many ${node} ${destination_ip} ${prefix} ${next_hop_ip} Execute In Container ${node} ip route del ${destination_ip}/${prefix} via ${next_hop_ip} diff --git a/tests/robot/libraries/lm_term.robot b/tests/robot/libraries/lm_term.robot index 53908131e3..cce6b17025 100644 --- a/tests/robot/libraries/lm_term.robot +++ b/tests/robot/libraries/lm_term.robot @@ -13,21 +13,17 @@ ${terminal_timeout}= 30s lmterm: Open LM Terminal [Arguments] ${node} [Documentation] Attaching to already running Libmemif App on node ${node} - Log Many ${node} #lmterm: Issue Command ${node}_lmterm ${DOCKER_COMMAND} attach ${node} Write To Machine ${node}_lmterm ${DOCKER_COMMAND} exec -it ${node} bash -c './.libs/icmpr-epoll' lmterm: Issue Command [Arguments] ${node} ${command} - Log Many ${node} ${command} ${node}_lmterm ${out}= Write To Machine ${node}_lmterm ${command} - Log ${out} # Should Contain ${out} ${${node}_VPP_TERM_PROMPT} [Return] ${out} lmterm: Exit VPP Terminal [Arguments] ${node} - Log Many ${node} ${node}_lmterm ${ctrl_p} Evaluate chr(int(16)) ${ctrl_q} Evaluate chr(int(17)) ${command}= Set Variable ${ctrl_p} ${ctrl_q} diff --git a/tests/robot/libraries/pretty_keywords.robot b/tests/robot/libraries/pretty_keywords.robot index b2c66ec3ea..64254f09d1 100644 --- a/tests/robot/libraries/pretty_keywords.robot +++ b/tests/robot/libraries/pretty_keywords.robot @@ -10,175 +10,115 @@ Ping On ${node} With IP ${ip}, Source ${source} vpp_term: Check Ping Within Interface ${node} ${ip} ${source} Create Loopback Interface ${name} On ${node} With Ip ${ip}/${prefix} And Mac ${mac} - Log Many ${name} ${node} ${ip} ${prefix} ${mac} vpp_ctl: Put Loopback Interface With IP ${node} ${name} ${mac} ${ip} ${prefix} Create Loopback Interface ${name} On ${node} With Mac ${mac} - Log Many ${name} ${node} ${mac} vpp_ctl: Put Loopback Interface ${node} ${name} ${mac} Create Loopback Interface ${name} On ${node} With VRF ${vrf}, Ip ${ip}/${prefix} And Mac ${mac} - Log Many ${name} ${node} ${ip} ${prefix} ${mac} ${vrf} vpp_ctl: Put Loopback Interface With IP ${node} ${name} ${mac} ${ip} ${prefix} vrf=${vrf} Create ${type} ${name} On ${node} With MAC ${mac}, Key ${key} And ${sock} Socket - Log Many ${type} ${name} ${node} ${mac} ${key} ${sock} ${type}= Set Variable if "${type}"=="Master" true false - Log Many ${type} vpp_ctl: put memif interface ${node} ${name} ${mac} ${type} ${key} ${sock} Create ${type} ${name} On ${node} With IP ${ip}, MAC ${mac}, Key ${key} And ${socket} Socket - Log Many ${type} ${name} ${node} ${ip} ${key} ${socket} ${type}= Set Variable if "${type}"=="Master" true false - Log Many ${type} ${out}= vpp_ctl: Put Memif Interface With IP ${node} ${name} ${mac} ${type} ${key} ${ip} socket=${socket} - Log Many ${out} Create ${type} ${name} On ${node} With Vrf ${vrf}, IP ${ip}, MAC ${mac}, Key ${key} And ${socket} Socket - Log Many ${type} ${name} ${node} ${ip} ${key} ${vrf} ${socket} ${type}= Set Variable if "${type}"=="Master" true false - Log Many ${type} ${out}= vpp_ctl: Put Memif Interface With IP ${node} ${name} ${mac} ${type} ${key} ${ip} socket=${socket} vrf=${vrf} - Log Many ${out} Create Tap Interface ${name} On ${node} With Vrf ${vrf}, IP ${ip}, MAC ${mac} And HostIfName ${host_if_name} - Log Many ${name} ${node} ${ip} ${vrf} ${out}= vpp_ctl: Put TAP Interface With IP ${node} ${name} ${mac} ${ip} ${host_if_name} vrf=${vrf} - Log Many ${out} Create Bridge Domain ${name} with Autolearn On ${node} With Interfaces ${interfaces} - Log Many ${name} ${node} ${interfaces} @{ints}= Split String ${interfaces} separator=,${space} - Log Many @{ints} vpp_ctl: put bridge domain ${node} ${name} ${ints} Create Bridge Domain ${name} Without Autolearn On ${node} With Interfaces ${interfaces} - Log Many ${name} ${node} ${interfaces} @{ints}= Split String ${interfaces} separator=,${space} - Log Many @{ints} vpp_ctl: put bridge domain ${node} ${name} ${ints} unicast=false learn=false Create Route On ${node} With IP ${ip}/${prefix} With Next Hop ${next_hop} And Vrf Id ${id} - Log Many ${node} ${ip} ${prefix} ${next_hop} ${id} ${data}= OperatingSystem.Get File ${CURDIR}/../../robot/resources/static_route.json - Log Many ${data} ${data}= replace variables ${data} - Log Many ${data} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/vrf/${id}/fib/${ip}/${prefix}/${next_hop} - Log Many ${uri} ${out}= vpp_ctl: Put Json ${uri} ${data} - Log Many ${out} Create Route On ${node} With IP ${ip}/${prefix} With Next Hop VRF ${next_hop_vrf} From Vrf Id ${id} And Type ${type} - Log Many ${node} ${ip} ${prefix} ${next_hop_vrf} ${id} ${type} ${data}= OperatingSystem.Get File ${CURDIR}/../../robot/resources/route_to_other_vrf.json - Log Many ${data} ${data}= replace variables ${data} - Log Many ${data} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/vrf/${id}/fib/${ip}/${prefix} - Log Many ${uri} ${out}= vpp_ctl: Put Json ${uri} ${data} - Log Many ${out} Delete IPsec On ${node} With Prefix ${prefix} And Name ${name} - Log Many ${node} ${prefix} ${name} vpp_ctl: Delete IPsec ${node} ${prefix} ${name} Create VXLan ${name} From ${src_ip} To ${dst_ip} With Vni ${vni} On ${node} - Log Many ${name} ${src_ip} ${dst_ip} ${vni} ${node} vpp_ctl: Put VXLan Interface ${node} ${name} ${src_ip} ${dst_ip} ${vni} Delete Routes On ${node} And Vrf Id ${id} - Log Many ${node} ${id} vpp_ctl: Delete routes ${node} ${id} Remove Interface ${name} On ${node} - Log Many ${name} ${node} vpp_ctl: Delete VPP Interface ${node} ${name} Remove Bridge Domain ${name} On ${node} - Log Many ${name} ${node} vpp_ctl: Delete Bridge Domain ${node} ${name} Add fib entry for ${mac} in ${name} over ${outgoing} on ${node} - Log Many ${mac} ${name} ${outgoing} ${node} vpp_ctl: Put Static Fib Entry ${node} ${name} ${mac} ${outgoing} Command: ${cmd} should ${expected} - Log Many ${cmd} ${expected} ${out}= Run Keyword And Ignore Error ${cmd} - Log Many @{out} Should Be Equal @{out}[0] ${expected} ignore_case=True [Return] ${out} IP Fib Table ${id} On ${node} Should Be Empty - Log many ${node} ${id} ${out}= vpp_term: Show IP Fib Table ${node} ${id} - log many ${out} Should Be Equal ${out} vpp#${SPACE} IP6 Fib Table ${id} On ${node} Should Be Empty - Log many ${node} ${id} ${out}= vpp_term: Show IP6 Fib Table ${node} ${id} - log many ${out} Should Be Equal ${out} vpp#${SPACE} IP Fib Table ${id} On ${node} Should Not Be Empty - Log many ${node} ${id} ${out}= vpp_term: Show IP Fib Table ${node} ${id} - log many ${out} Should Not Be Equal ${out} vpp#${SPACE} IP Fib Table ${id} On ${node} Should Contain Route With IP ${ip}/${prefix} - Log many ${node} ${id} ${out}= vpp_term: Show IP Fib Table ${node} ${id} - log many ${out} Should Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip4-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip4\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] IP Fib Table ${id} On ${node} Should Not Contain Route With IP ${ip}/${prefix} - Log many ${node} ${id} ${out}= vpp_term: Show IP Fib Table ${node} ${id} - log many ${out} Should Not Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip4-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip4\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] IP6 Fib Table ${id} On ${node} Should Contain Route With IP ${ip}/${prefix} - Log many ${node} ${id} ${out}= vpp_term: Show IP6 Fib Table ${node} ${id} - log many ${out} Should Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip6-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip6\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] IP6 Fib Table ${id} On ${node} Should Not Contain Route With IP ${ip}/${prefix} - Log many ${node} ${id} ${out}= vpp_term: Show IP6 Fib Table ${node} ${id} - log many ${out} Should Not Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip6-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip6\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] Show IP Fib On ${node} - Log Many ${node} ${out}= vpp_term: Show IP Fib ${node} - Log Many ${out} Show IP6 Fib On ${node} - Log Many ${node} ${out}= vpp_term: Show IP6 Fib ${node} - Log Many ${out} Show Interfaces On ${node} ${out}= vpp_term: Show Interfaces ${node} - Log Many ${out} Show Interfaces Address On ${node} ${out}= vpp_term: Show Interfaces Address ${node} - Log Many ${out} Create Linux Route On ${node} With IP ${ip}/${prefix} With Next Hop ${next_hop} And Vrf Id ${id} - Log Many ${node} ${ip} ${prefix} ${next_hop} ${data}= OperatingSystem.Get File ${CURDIR}/../../robot/resources/linux_static_route.json - Log Many ${data} ${data}= replace variables ${data} - Log Many ${data} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/vrf/${id}/fib/${ip}/${prefix}/${next_hop} - Log Many ${uri} ${out}= vpp_ctl: Put Json ${uri} ${data} - Log Many ${out} diff --git a/tests/robot/libraries/rest_api.robot b/tests/robot/libraries/rest_api.robot index 549b4b36f9..10bacdb7a6 100644 --- a/tests/robot/libraries/rest_api.robot +++ b/tests/robot/libraries/rest_api.robot @@ -8,9 +8,7 @@ Library rest_api.py rest_api: Get [Arguments] ${node} ${uri} ${expected_code}=200 ${response}= Get Request ${node} ${uri} - Log Many ${response.text} ${response.status_code} # ${pretty}= Ordered Json ${response.text} -# log ${pretty} Sleep ${REST_CALL_SLEEP} Run Keyword If '${expected_code}'!='0' Should Be Equal As Integers ${response.status_code} ${expected_code} [Return] ${response.text} @@ -18,27 +16,20 @@ rest_api: Get rest_api: Put [Arguments] ${node} ${uri} ${expected_code}=200 - Log Many ${node} ${uri} ${response}= Put Request ${node} ${uri} - Log Many ${response.text} ${response.status_code} ${pretty}= Ordered Json ${response.text} - log ${pretty} Sleep ${REST_CALL_SLEEP} Run Keyword If '${expected_code}'!='0' Should Be Equal As Integers ${response.status_code} ${expected_code} [Return] ${response.text} rest_api: Get Loggers List [Arguments] ${node} - Log Many ${node} ${uri}= Set Variable log/list - Log ${uri} ${out}= rest_api: Get ${node} ${uri} [Return] ${out} rest_api: Change Logger Level [Arguments] ${node} ${logger} ${log_level} - Log Many ${node} ${logger} ${log_level} ${uri}= Set variable /log/${logger}/${log_level} - Log ${uri} ${out}= rest_api: Put ${node} ${uri} [Return] ${out} diff --git a/tests/robot/libraries/setup-teardown.robot b/tests/robot/libraries/setup-teardown.robot index cc78b96b20..e97b02396d 100644 --- a/tests/robot/libraries/setup-teardown.robot +++ b/tests/robot/libraries/setup-teardown.robot @@ -3,7 +3,7 @@ *** Settings *** Library String Library RequestsLibrary -Library SSHLibrary timeout=60s +Library SSHLibrary timeout=15s loglevel=TRACE #Resource ssh.robot Resource ${ENV}_setup-teardown.robot @@ -15,38 +15,37 @@ ${snapshot_num} 0 *** Keywords *** Open SSH Connection [Arguments] ${name} ${ip} ${user} ${pswd} - Log Many ${name} ${ip} ${user} ${pswd} Open Connection ${ip} ${name} Run Keyword If "${pswd}"!="rsa_id" Login ${user} ${pswd} Run Keyword If "${pswd}"=="rsa_id" SSHLibrary.Login_With_Public_Key ${user} %{HOME}/.ssh/id_rsa any Testsuite Setup - [Documentation] *Testsuite Setup* Discard old results + #Remove File ${OUTPUTDIR}/ssh.log + Enable SSH Logging ${OUTPUTDIR}/ssh.log Open Connection To Docker Host Create Connections For ETCD And Kafka - Start Kafka Server + #Start Kafka Server Start ETCD Server Start VPP Ctl Container Make Datastore Snapshots startup Testsuite Teardown - [Documentation] *Testsuite Teardown* Make Datastore Snapshots teardown -# Log All SSH Outputs Remove All Nodes Stop ETCD Server Stop VPP Ctl Container - Stop Kafka Server + #Stop Kafka Server Get Connections Close All Connections Check Agent Logs For Errors + #Copy File ${OUTPUTDIR}/ssh.log ${RESULTS_FOLDER_SUITE}/ssh.log Test Setup Open Connection To Docker Host Create Connections For ETCD And Kafka - Start Kafka Server + #Start Kafka Server Start ETCD Server Start VPP Ctl Container Make Datastore Snapshots startup @@ -54,9 +53,8 @@ Test Setup Test Teardown Make Datastore Snapshots teardown Stop VPP Ctl Container - Stop Kafka Server + #Stop Kafka Server Stop ETCD Server -# Log All SSH Outputs Remove All Nodes Get Connections Close All Connections @@ -68,10 +66,10 @@ Discard old results #Create Directory ${RESULTS_FOLDER} Remove Directory ${RESULTS_FOLDER_SUITE} recursive=true Create Directory ${RESULTS_FOLDER} + Create Directory ${RESULTS_FOLDER_SUITE} Log All SSH Outputs - [Documentation] *Log All SSH Outputs* ... Logs all connections outputs [Timeout] 120s :FOR ${id} IN @{NODES} @@ -83,10 +81,8 @@ Log All SSH Outputs Log ${machine} Output [Documentation] *Log ${machine} Output* ... Logs actual ${machine} output from begining - Log ${machine} Switch Connection ${machine} ${out}= Read delay=${SSH_READ_DELAY}s - Log ${out} Append To File ${RESULTS_FOLDER}/output_${machine}.log ${out} Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log ${out} @@ -94,7 +90,6 @@ Get Machine Status [Arguments] ${machine} [Documentation] *Get Machine Status ${machine}* ... Executing df, free, ifconfig -a, ps -aux... on ${machine} - Log ${machine} Execute On Machine ${machine} df Execute On Machine ${machine} free Execute On Machine ${machine} ifconfig -a @@ -109,11 +104,10 @@ Open Connection To Docker Host Create Connections For ETCD And Kafka Open SSH Connection etcd ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} - Open SSH Connection kafka ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} + #Open SSH Connection kafka ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} Make Datastore Snapshots [Arguments] ${tag}=notag - Log ${tag} ${prefix}= Create Next Snapshot Prefix Take ETCD Snapshots ${prefix}_${tag} @@ -125,7 +119,6 @@ Get ETCD Dump Take ETCD Snapshots [Arguments] ${tag} ${machine}=docker - Log ${tag} ${dump}= Get ETCD Dump ${machine} Append To File ${RESULTS_FOLDER}/etcd_dump-${tag}.txt ${dump} Append To File ${RESULTS_FOLDER_SUITE}/etcd_dump-${tag}.txt ${dump} @@ -141,7 +134,6 @@ Create Next Snapshot Prefix Check Agent Logs For Errors @{logs}= OperatingSystem.List Files In Directory ${RESULTS_FOLDER}/ *_container_agent.log - Log List ${logs} :FOR ${log} IN @{logs} \ ${data}= OperatingSystem.Get File ${RESULTS_FOLDER}/${log} \ Should Not Contain ${data} exited: agent (exit status diff --git a/tests/robot/libraries/ssh.robot b/tests/robot/libraries/ssh.robot index 33dc0de82f..3b937dafff 100644 --- a/tests/robot/libraries/ssh.robot +++ b/tests/robot/libraries/ssh.robot @@ -3,22 +3,22 @@ *** Settings *** #Library String #Library RequestsLibrary -Library SSHLibrary timeout=60 seconds +Library SSHLibrary timeout=15 seconds loglevel=TRACE *** Keywords *** Execute On Machine [Arguments] ${machine} ${command} ${log}=true [Documentation] *Execute On Machine ${machine} ${command}* ... Executing ${command} on connection with name ${machine} ... Output log is added to machine output log - Log Many ${machine} ${command} ${log} Switch Connection ${machine} ${currdate}= Get Current Date + Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} ${out} ${stderr}= Execute Command ${command} return_stderr=True - Log Many ${out} ${stderr} ${status}= Run Keyword And Return Status Should Be Empty ${stderr} Run Keyword If ${status}==False Log One or more error occured during execution of a command ${command} on ${machine} level=WARN - Run Keyword If '${log}'=='true' Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n} - Run Keyword If '${log}'=='true' Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n} + Run Keyword If '${log}'=='true' Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Response: ${out}${\n} + Run Keyword If '${log}'=='true' Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Response: ${out}${\n} Run Keyword If ${status}==False Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Error: ${stderr}${\n} Run Keyword If ${status}==False Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Error: ${stderr}${\n} [Return] ${out} @@ -27,14 +27,14 @@ Write To Machine [Arguments] ${machine} ${comma [Documentation] *Write Machine ${machine} ${command}* ... Writing ${command} to connection with name ${machine} ... Output log is added to machine output log - Log Many ${machine} ${command} ${delay} Switch Connection ${machine} ${currdate}= Get Current Date - Write ${command} - ${out}= Read delay=${delay} - Log ${out} - Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n} - Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${\n} + Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} + Write ${command} loglevel=TRACE + ${out}= Read loglevel=TRACE delay=${delay} + Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Response: ${out}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Response: ${out}${\n} [Return] ${out} Write To Machine Until Prompt @@ -43,16 +43,15 @@ Write To Machine Until Prompt ... Writing ${command} to connection with name ${machine} and reading until prompt ... Output log is added to machine output log Log Use 'Write To Container Until Prompt' instead of this kw level=WARN - Log Many ${machine} ${command} ${prompt} ${delay} Switch Connection ${machine} ${currdate}= Get Current Date - Write ${command} - ${out}= Read Until ${prompt}${${machine}_HOSTNAME} - Log ${out} - ${out2}= Read delay=${delay} - Log ${out2} - Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} - Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} + Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} + Write ${command} loglevel=TRACE + ${out}= Read Until ${prompt}${${machine}_HOSTNAME} loglevel=TRACE + ${out2}= Read loglevel=TRACE delay=${delay} + Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Response: ${out}${out2}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Response: ${out}${out2}${\n} [Return] ${out}${out2} Write To Machine Until String @@ -60,15 +59,14 @@ Write To Machine Until String [Documentation] *Write Machine ${machine} ${command}* ... Writing ${command} to connection with name ${machine} and reading until specified string ... Output log is added to machine output log - Log Many ${machine} ${command} ${string} ${delay} Switch Connection ${machine} ${currdate}= Get Current Date - Write ${command} - ${out}= Read Until ${string} - Log ${out} - ${out2}= Read delay=${delay} - Log ${out2} - Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} - Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n}${out}${out2}${\n} + Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Command: ${command}${\n} + Write ${command} loglevel=TRACE + ${out}= Read Until ${string} loglevel=TRACE + ${out2}= Read loglevel=TRACE delay=${delay} + Append To File ${RESULTS_FOLDER}/output_${machine}.log *** Time:${currdate} Response: ${out}${out2}${\n} + Append To File ${RESULTS_FOLDER_SUITE}/output_${machine}.log *** Time:${currdate} Response: ${out}${out2}${\n} [Return] ${out}${out2} diff --git a/tests/robot/libraries/vat_term.py b/tests/robot/libraries/vat_term.py index 0ca11597c4..1896cf6247 100644 --- a/tests/robot/libraries/vat_term.py +++ b/tests/robot/libraries/vat_term.py @@ -100,8 +100,9 @@ def Parse_Memif_Info(info): # output - state info list def Parse_BD_Details(details): state = [] + details = "\n".join([s for s in details.splitlines(True) if s.strip("\r\n")]) line = details.splitlines()[1] - if (line.strip().split()[6]) == "on": + if (line.strip().split()[6]) in ("on", "flood"): state.append("unicast=1") else: state.append("unicast=0") diff --git a/tests/robot/libraries/vat_term.robot b/tests/robot/libraries/vat_term.robot index bba46f7c22..d6c9f52a7e 100644 --- a/tests/robot/libraries/vat_term.robot +++ b/tests/robot/libraries/vat_term.robot @@ -12,12 +12,9 @@ ${bd_timeout}= 15s vat_term: Check VAT Terminal [Arguments] ${node} [Documentation] Check VAT terminal on node ${node} - Log Many ${node} ${node}_vat ${VAT_START_COMMAND} ${${node}_VPP_VAT_PROMPT} ${out}= Write To Machine ${node}_vat ${DOCKER_COMMAND} exec -it ${node} /bin/bash - Log ${out} ${command}= Set Variable ${VAT_START_COMMAND} ${out}= Write To Machine ${node}_vat ${command} - Log ${out} Should Contain ${out} ${${node}_VPP_VAT_PROMPT} [Return] ${out} @@ -28,32 +25,26 @@ vat_term: Open VAT Terminal vat_term: Exit VAT Terminal [Arguments] ${node} - Log Many ${node} ${node}_vat ${ctrl_c} Evaluate chr(int(3)) ${command}= Set Variable ${ctrl_c} ${out}= Write To Machine ${node}_vat ${command} - Log ${out} [Return] ${out} vat_term: Issue Command [Arguments] ${node} ${command} ${delay}=${SSH_READ_DELAY}s - Log Many ${node} ${command} ${delay} ${node}_vat ${${node}_VPP_VAT_PROMPT} ${out}= Write To Machine Until String ${node}_vat ${command} ${${node}_VPP_VAT_PROMPT} delay=${delay} - Log ${out} # Should Contain ${out} ${${node}_VPP_VAT_PROMPT} [Return] ${out} vat_term: Interfaces Dump [Arguments] ${node} [Documentation] Executing command sw_interface_dump - Log Many ${node} ${out}= vat_term: Issue Command ${node} sw_interface_dump [Return] ${out} vat_term: Bridge Domain Dump [Arguments] ${node} ${bd_id}=${EMPTY} [Documentation] Executing command bridge_domain_dump - Log Many ${node} ${bd_id} ${add_params}= Set Variable If '''${bd_id}'''=="" ${EMPTY} bd_id ${bd_id} ${out}= vat_term: Issue Command ${node} bridge_domain_dump ${add_params} ${out}= Evaluate """${out}"""["""${out}""".find('['):"""${out}""".rfind(']')+1] @@ -62,23 +53,19 @@ vat_term: Bridge Domain Dump vat_term: IP FIB Dump [Arguments] ${node} [Documentation] Executing command ip_fib_dump - Log Many ${node} ${out}= vat_term: Issue Command ${node} ip_fib_dump [Return] ${out} vat_term: VXLan Tunnel Dump [Arguments] ${node} ${args}=${EMPTY} [Documentation] Executing command vxlan_tunnel_dump - Log Many ${node} ${args} ${out}= vat_term: Issue Command ${node} vxlan_tunnel_dump ${args} ${out}= Evaluate """${out}"""["""${out}""".find('['):"""${out}""".rfind(']')+1] - Log ${out} [Return] ${out} vat_term: Check VXLan Tunnel Presence [Arguments] ${node} ${src} ${dst} ${vni} ${status}=${TRUE} [Documentation] Checking if specified vxlan tunnel exists - Log Many ${node} ${src} ${dst} ${vni} ${status} ${out}= vat_term: VXLan Tunnel Dump ${node} ${result} ${if_index}= Check VXLan Tunnel Presence ${out} ${src} ${dst} ${vni} Should Be Equal ${result} ${status} @@ -87,7 +74,6 @@ vat_term: Check VXLan Tunnel Presence vat_term: Get Interface Name [Arguments] ${node} ${index} [Documentation] Return interface with specified index name - Log Many ${node} ${index} ${out}= vat_term: Interfaces Dump ${node} ${name}= Get Interface Name ${out} ${index} [Return] ${name} @@ -95,45 +81,32 @@ vat_term: Get Interface Name vat_term: Get Interface Index [Arguments] ${node} ${name} [Documentation] Return interface index with specified name - Log Many ${node} ${name} ${out}= vat_term: Interfaces Dump ${node} ${index}= Get Interface Index ${out} ${name} [Return] ${index} vat_term: Check VXLan Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} ${desired_state} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${internal_index}= vat_term: Get Interface Index ${node} ${internal_name} - Log ${internal_index} ${vxlan_data}= vat_term: VXLan Tunnel Dump ${node} sw_if_index ${internal_index} ${vxlan_data}= Evaluate json.loads('''${vxlan_data}''') json - Log ${vxlan_data} ${interfaces}= vat_term: Interfaces Dump ${node} - Log ${interfaces} ${int_state}= Get Interface State ${interfaces} ${internal_index} - Log ${int_state} ${src}= Set Variable ${vxlan_data[0]["src_address"]} ${dst}= Set Variable ${vxlan_data[0]["dst_address"]} ${vni}= Set Variable ${vxlan_data[0]["vni"]} ${enabled}= Set Variable ${int_state["admin_up_down"]} ${actual_state}= Create List src=${src} dst=${dst} vni=${vni} enabled=${enabled} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vat_term: Check Afpacket Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} ${desired_state} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${internal_index}= vat_term: Get Interface Index ${node} ${internal_name} - Log ${internal_index} ${interfaces}= vat_term: Interfaces Dump ${node} - Log ${interfaces} ${int_state}= Get Interface State ${interfaces} ${internal_index} - Log ${int_state} ${ipv4_list}= vpp_term: Get Interface IPs ${node} ${internal_name} ${config}= vpp_ctl: Get VPP Interface Config As Json ${node} ${name} ${host_int}= Set Variable ${config["afpacket"]["host_if_name"]} @@ -145,21 +118,15 @@ vat_term: Check Afpacket Interface State ${actual_state}= Create List enabled=${enabled} mtu=${mtu} mac=${mac} :FOR ${ip} IN @{ipv4_list} \ Append To List ${actual_state} ipv4=${ip} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vat_term: Check Physical Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} ${desired_state} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${internal_index}= vat_term: Get Interface Index ${node} ${internal_name} - Log ${internal_index} ${interfaces}= vat_term: Interfaces Dump ${node} - Log ${interfaces} ${int_state}= Get Interface State ${interfaces} ${internal_index} - Log ${int_state} ${ipv4_list}= vpp_term: Get Interface IPs ${node} ${internal_name} ${enabled}= Set Variable ${int_state["admin_up_down"]} ${mtu}= Set Variable ${int_state["mtu"]} @@ -168,21 +135,15 @@ vat_term: Check Physical Interface State ${actual_state}= Create List enabled=${enabled} mtu=${mtu} mac=${mac} :FOR ${ip} IN @{ipv4_list} \ Append To List ${actual_state} ipv4=${ip} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vat_term: Check Loopback Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} ${desired_state} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${internal_index}= vat_term: Get Interface Index ${node} ${internal_name} - Log ${internal_index} ${interfaces}= vat_term: Interfaces Dump ${node} - Log ${interfaces} ${int_state}= Get Interface State ${interfaces} ${internal_index} - Log ${int_state} ${ipv4_list}= vpp_term: Get Interface IPs ${node} ${internal_name} ${ipv6_list}= vpp_term: Get Interface IP6 IPs ${node} ${internal_name} ${enabled}= Set Variable ${int_state["admin_up_down"]} @@ -194,19 +155,14 @@ vat_term: Check Loopback Interface State \ Append To List ${actual_state} ipv4=${ip} :FOR ${ip} IN @{ipv6_list} \ Append To List ${actual_state} ipv6=${ip} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vat_term: Check Memif Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} ${desired_state} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${memif_info}= vpp_term: Show Memif ${node} ${internal_name} - Log ${memif_info} ${memif_state}= Parse Memif Info ${memif_info} - Log ${memif_state} ${ipv4_list}= vpp_term: Get Interface IPs ${node} ${internal_name} ${ipv6_list}= vpp_term: Get Interface IP6 IPs ${node} ${internal_name} ${mac}= vpp_term: Get Interface MAC ${node} ${internal_name} @@ -216,68 +172,50 @@ vat_term: Check Memif Interface State :FOR ${ip} IN @{ipv6_list} \ Append To List ${actual_state} ipv6=${ip} Append To List ${actual_state} @{memif_state} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vat_term: Check Bridge Domain State [Arguments] ${node} ${bd} @{desired_state} - Log Many ${node} ${bd} ${desired_state} ${bd_id}= vpp_ctl: Get Bridge Domain ID ${node} ${bd} - Log ${bd_id} ${bd_dump}= vat_term: Bridge Domain Dump ${node} ${bd_id} - Log ${bd_dump} ${bd_json}= Evaluate json.loads('''${bd_dump}''') json - Log ${bd_json} ${flood}= Set Variable ${bd_json[0]["flood"]} ${forward}= Set Variable ${bd_json[0]["forward"]} ${learn}= Set Variable ${bd_json[0]["learn"]} ${bd_details}= vpp_term: Show Bridge-Domain Detail ${node} ${bd_id} - Log ${bd_details} ${bd_state}= Parse BD Details ${bd_details} - Log ${bd_state} ${etcd_dump}= Get ETCD Dump - Log ${etcd_dump} ${etcd_json}= Convert_ETCD_Dump_To_JSON ${etcd_dump} - Log ${etcd_json} ${interfaces}= Parse BD Interfaces ${node} ${bd} ${etcd_json} ${bd_dump} - Log ${interfaces} ${actual_state}= Create List flood=${flood} forward=${forward} learn=${learn} Append To List ${actual_state} @{bd_state} @{interfaces} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vat_term: BD Is Created [Arguments] ${node} @{interfaces} - Log Many ${node} ${interfaces} Wait Until Keyword Succeeds ${bd_timeout} 3s vat_term: Check BD Presence ${node} ${interfaces} vat_term: BD Is Deleted [Arguments] ${node} @{interfaces} - Log Many ${node} ${interfaces} Wait Until Keyword Succeeds ${bd_timeout} 3s vat_term: Check BD Presence ${node} ${interfaces} ${FALSE} vat_term: BD Exists [Arguments] ${node} @{interfaces} - Log Many ${node} ${interfaces} vat_term: Check BD Presence ${node} ${interfaces} vat_term: BD Not Exists [Arguments] ${node} @{interfaces} - Log Many ${node} ${interfaces} vat_term: Check BD Presence ${node} ${interfaces} ${FALSE} vat_term: Check BD Presence [Arguments] ${node} ${interfaces} ${status}=${TRUE} - Log Many ${node} ${interfaces} ${status} ${indexes}= Create List :FOR ${int} IN @{interfaces} \ ${sw_if_index}= vpp_ctl: Get Interface Sw If Index ${node} ${int} \ Append To List ${indexes} ${sw_if_index} - Log List ${indexes} - ${bd_dump}= vat_term: Bridge Domain Dump ${node} - Log ${bd_dump} + ${bd_dump}= vat_term: Bridge Domain Dump ${node} ${result}= Check BD Presence ${bd_dump} ${indexes} Should Be Equal ${result} ${status} @@ -285,36 +223,28 @@ vat_term: Check BD Presence vat_term: ACL Dump [Arguments] ${node} ${acl_name} [Documentation] Executing command acl_dump - Log Many ${node} ${out}= vat_term: Issue Command ${node} acl_dump ${out_data_vat}= Strip String ${out} ${out_data}= Remove String ${out_data_vat} vat#${SPACE} vat# - Log ${out_data} OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply_${acl_name}_term.json ${out_data} [Return] ${out_data} vat_term: ACL All Dump [Arguments] ${node} [Documentation] Executing command acl_dump - Log Many ${node} ${out}= vat_term: Issue Command ${node} acl_dump ${out_data_vat}= Strip String ${out} ${out_data}= Remove String ${out_data_vat} vat#${SPACE} vat# - Log ${out_data} OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply_acl_all_term.json ${out_data} [Return] ${out_data} vat_term: Check All ACL [Arguments] ${node} - Log Many ${node} ${acl_list}= vat_term: ACL All Dump ${node} - Log ${acl_list} [Return] ${acl_list} vat_term: Check ACL [Arguments] ${node} ${acl_name} - Log Many ${node} ${acl_name} ${acl_list}= vat_term: ACL Dump ${node} ${acl_name} - Log ${acl_list} [Return] ${acl_list} \ No newline at end of file diff --git a/tests/robot/libraries/vpp.robot b/tests/robot/libraries/vpp.robot index 81ba07ecb4..084c5de4c3 100644 --- a/tests/robot/libraries/vpp.robot +++ b/tests/robot/libraries/vpp.robot @@ -2,7 +2,6 @@ Open VPP terminal [Arguments] ${node} ${out}= Write To Machine ${node} telnet localhost 5002 - Log Many ${out} Should Contain ${out} vpp# Close VPP terminal @@ -10,7 +9,6 @@ Close VPP terminal ${ctrl_c} Evaluate chr(int(3)) ${command}= Set Variable ${ctrl_c} ${out}= Write To Machine ${node} ${command} - Log ${out} [Return] ${out} # TODO: this will not work in case there is physical int @@ -33,16 +31,12 @@ Wait until VPP successful load Try connect to VPP terminal [Arguments] ${node} ${out}= Write To Machine docker telnet localhost ${${node}_VPP_HOST_PORT} - Log Many ${out} Should Contain ${out} vpp# Execute In VPP [Arguments] ${container} ${command} - Log Many ${container} ${command} Switch Connection docker ${out} ${stderr}= Execute Command ${DOCKER_COMMAND} exec -it ${container} vppctl ${command} return_stderr=True - Log ${out} - Log ${stderr} ${currdate}= Get Current Date ${status}= Run Keyword And Return Status Should be Empty ${stderr} Run Keyword If ${status}==False Log One or more error occured during execution of a command ${command} in container ${container} level=WARN diff --git a/tests/robot/libraries/vpp_ctl.robot b/tests/robot/libraries/vpp_ctl.robot index 137d1fc80e..4cd0a30493 100644 --- a/tests/robot/libraries/vpp_ctl.robot +++ b/tests/robot/libraries/vpp_ctl.robot @@ -10,14 +10,12 @@ Library String vpp_ctl: Put Json [Arguments] ${key} ${json} ${container}=vpp_agent_ctl - Log Many ${key} ${json} ${container} ${command}= Set Variable echo '${json}' | vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -put ${key} - ${out}= Write To Container Until Prompt ${container} ${command} [Return] ${out} vpp_ctl: Read Key [Arguments] ${key} ${container}=vpp_agent_ctl - Log Many ${key} ${container} ${command}= Set Variable vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -get ${key} # ${out}= Write To Container Until Prompt ${container} ${command} ${out}= Execute In Container ${container} ${command} @@ -25,7 +23,6 @@ vpp_ctl: Read Key vpp_ctl: Read Key With Prefix [Arguments] ${key} ${container}=vpp_agent_ctl - Log Many ${key} ${container} ${command}= Set Variable vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -get ${key} # ${out}= Write To Container Until Prompt ${container} ${command} ${out}= Execute In Container ${container} ${command} @@ -33,50 +30,51 @@ vpp_ctl: Read Key With Prefix vpp_ctl: Put Memif Interface [Arguments] ${node} ${name} ${mac} ${master} ${id} ${socket}=memif.sock ${mtu}=1500 ${vrf}=0 ${enabled}=true - Log Many ${node} ${name} ${mac} ${master} ${id} ${socket} ${mtu} ${vrf} ${enabled} ${socket}= Set Variable ${${node}_MEMIF_SOCKET_FOLDER}/${socket} - Log ${socket} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/memif_interface.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Memif Interface With IP [Arguments] ${node} ${name} ${mac} ${master} ${id} ${ip} ${prefix}=24 ${socket}=memif.sock ${mtu}=1500 ${vrf}=0 ${enabled}=true - Log Many ${node} ${name} ${mac} ${master} ${id} ${ip} ${prefix} ${socket} ${mtu} ${vrf} ${enabled} ${socket}= Set Variable ${${node}_MEMIF_SOCKET_FOLDER}/${socket} - Log ${socket} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/memif_interface_with_ip.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete key [Arguments] ${key} ${container}=vpp_agent_ctl - Log Many ${container} ${key} ${out}= Write To Container Until Prompt ${container} vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -del ${key} - Log Many ${out} [Return] ${out} vpp_ctl: Put Veth Interface [Arguments] ${node} ${name} ${mac} ${peer} ${enabled}=true - Log Many ${node} ${name} ${mac} ${peer} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/veth_interface.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} + vpp_ctl: Put Json ${uri} ${data} + +vpp_ctl: Put Veth Interface And Namespace + [Arguments] ${node} ${name} ${namespace} ${mac} ${peer} ${enabled}=true + ${data}= OperatingSystem.Get File ${CURDIR}/../resources/veth_interface.json + ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/interface/${name} + ${data}= Replace Variables ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Veth Interface With IP [Arguments] ${node} ${name} ${mac} ${peer} ${ip} ${prefix}=24 ${mtu}=1500 ${vrf}=0 ${enabled}=true - Log Many ${node} ${name} ${mac} ${peer} ${ip} ${prefix} ${mtu} ${vrf} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/veth_interface_with_ip.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/interface/${name} + ${data}= Replace Variables ${data} + vpp_ctl: Put Json ${uri} ${data} + +vpp_ctl: Put Veth Interface With IP And Namespace + [Arguments] ${node} ${name} ${namespace} ${mac} ${peer} ${ip} ${prefix}=24 ${mtu}=1500 ${enabled}=true + Log Many ${node} ${name} ${namespace} ${mac} ${peer} ${ip} ${prefix} ${mtu} ${enabled} + ${data}= OperatingSystem.Get File ${CURDIR}/../resources/veth_interface_with_ip_and_ns.json + ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/interface/${name} Log Many ${data} ${uri} ${data}= Replace Variables ${data} Log ${data} @@ -84,375 +82,260 @@ vpp_ctl: Put Veth Interface With IP vpp_ctl: Put Afpacket Interface [Arguments] ${node} ${name} ${mac} ${host_int} ${mtu}=1500 ${enabled}=true ${vrf}=0 - Log Many ${node} ${name} ${mac} ${host_int} ${mtu} ${vrf} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/afpacket_interface.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put VXLan Interface [Arguments] ${node} ${name} ${src} ${dst} ${vni} ${enabled}=true ${vrf}=0 - Log Many ${node} ${name} ${src} ${dst} ${vni} ${enabled} ${vrf} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/vxlan_interface.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Bridge Domain [Arguments] ${node} ${name} ${ints} ${flood}=true ${unicast}=true ${forward}=true ${learn}=true ${arp_term}=true - Log Many ${node} ${name} ${ints} ${flood} ${unicast} ${forward} ${learn} ${arp_term} ${interfaces}= Create Interfaces Json From List ${ints} - Log ${interfaces} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/bridge_domain.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/bd/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Loopback Interface [Arguments] ${node} ${name} ${mac} ${mtu}=1500 ${enabled}=true ${vrf}=0 - Log Many ${node} ${name} ${mac} ${mtu} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/loopback_interface.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Loopback Interface With IP [Arguments] ${node} ${name} ${mac} ${ip} ${prefix}=24 ${mtu}=1500 ${vrf}=0 ${enabled}=true - Log Many ${node} ${name} ${mac} ${ip} ${prefix} ${mtu} ${vrf} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/loopback_interface_with_ip.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Physical Interface With IP [Arguments] ${node} ${name} ${ip} ${prefix}=24 ${mtu}=1500 ${enabled}=true - Log Many ${node} ${name} ${ip} ${prefix} ${mtu} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/physical_interface_with_ip.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Get VPP Interface State [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${key}= Set Variable /vnf-agent/${node}/vpp/status/v1/interface/${interface} - Log ${key} ${out}= vpp_ctl: Read Key ${key} - Log ${out} [Return] ${out} vpp_ctl: Get VPP Interface State As Json [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${key}= Set Variable /vnf-agent/${node}/vpp/status/v1/interface/${interface} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json [Return] ${output} vpp_ctl: Get VPP Interface Config As Json [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${key}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${interface} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json [Return] ${output} vpp_ctl: Get Linux Interface Config As Json [Arguments] ${node} ${name} - Log Many ${node} ${name} ${key}= Set Variable /vnf-agent/${node}/linux/config/v1/interface/${name} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json [Return] ${output} vpp_ctl: Get Bridge Domain State As Json [Arguments] ${node} ${bd} - Log Many ${node} ${bd} ${key}= Set Variable /vnf-agent/${node}/vpp/status/v1/bd/${bd} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json [Return] ${output} vpp_ctl: Get Interface Internal Name [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${name}= Set Variable ${EMPTY} ${empty_dict}= Create Dictionary ${state}= vpp_ctl: Get VPP Interface State As Json ${node} ${interface} - Log ${state} ${length}= Get Length ${state} - Log ${length} ${name}= Run Keyword If ${length} != 0 Set Variable ${state["internal_name"]} - Log ${name} [Return] ${name} vpp_ctl: Get Interface Sw If Index [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${state}= vpp_ctl: Get VPP Interface State As Json ${node} ${interface} ${sw_if_index}= Set Variable ${state["if_index"]} - Log ${sw_if_index} [Return] ${sw_if_index} vpp_ctl: Get Bridge Domain ID [Arguments] ${node} ${bd} - Log Many ${node} ${bd} ${state}= vpp_ctl: Get Bridge Domain State As Json ${node} ${bd} ${bd_id}= Set Variable ${state["index"]} - Log ${bd_id} [Return] ${bd_id} vpp_ctl: Put TAP Interface With IP [Arguments] ${node} ${name} ${mac} ${ip} ${host_if_name} ${prefix}=24 ${mtu}=1500 ${enabled}=true ${vrf}=0 - Log Many ${node} ${name} ${mac} ${ip} ${host_if_name} ${prefix} ${mtu} ${enabled} ${vrf} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/tap_interface_with_ip.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put TAP Unnumbered Interface [Arguments] ${node} ${name} ${mac} ${unnumbered} ${interface_with_ip_name} ${host_if_name} ${mtu}=1500 ${enabled}=true - Log Many ${node} ${name} ${mac} ${unnumbered} ${interface_with_ip_name} ${host_if_name} ${mtu} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/tap_interface_unnumbered.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Static Fib Entry [Arguments] ${node} ${bd_name} ${mac} ${outgoing_interface} ${static}=true - Log Many ${node} ${bd_name} ${mac} ${outgoing_interface} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/static_fib.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/bd/${bd_name}/fib/${mac} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Create IPsec With SA And Json [Arguments] ${node} ${interface} ${file_name} ${name} ${spi} ${crypto_key} ${integ_key} - Log Many ${node} ${interface} ${file_name} ${name} ${spi} ${crypto_key} ${integ_key} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/${file_name} - Log Many ${data} ${data}= replace variables ${data} - Log Many ${data} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/ipsec/sa/${interface} - Log Many ${uri} ${out}= vpp_ctl: Put Json ${uri} ${data} - Log Many ${out} vpp_ctl: Create IPsec With SPD And Json [Arguments] ${node} ${spd_name} ${file_name} ${interface_name} ${remote_addr} ${local_addr} ${sa_name_1} ${sa_name_2} - Log Many ${node} ${spd_name} ${file_name} ${interface_name} ${remote_addr} ${local_addr} ${sa_name_1} ${sa_name_2} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/${file_name} - Log Many ${data} ${data}= replace variables ${data} - Log Many ${data} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/ipsec/spd/${spd_name} - Log Many ${uri} ${out}= vpp_ctl: Put Json ${uri} ${data} - Log Many ${out} vpp_ctl: Delete Bridge Domain [Arguments] ${node} ${name} - Log Many ${node} ${name} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/bd/${name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Delete VPP Interface [Arguments] ${node} ${name} - Log Many ${node} ${name} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Delete Linux Interface [Arguments] ${node} ${name} - Log Many ${node} ${name} ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/interface/${name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Delete Route [Arguments] ${node} ${id} ${ip} ${prefix} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/vrf/${id}/fib/${ip}/${prefix} - Log Many ${uri} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Delete Routes [Arguments] ${node} ${id} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/vrf/${id}/fib - Log Many ${uri} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Delete IPsec [Arguments] ${node} ${prefix} ${name} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/ipsec/${prefix}/${name} - Log Many ${uri} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put BFD Session [Arguments] ${node} ${session_name} ${min_tx_interval} ${dest_adr} ${detect_multiplier} ${interface} ${min_rx_interval} ${source_adr} ${enabled} ${auth_key_id}=0 ${BFD_auth_key_id}=0 - Log Many ${node} ${session_name} ${min_tx_interval} ${dest_adr} ${detect_multiplier} ${interface} ${min_rx_interval} ${source_adr} ${enabled} ${auth_key_id} ${BFD_auth_key_id} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/bfd_session.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/bfd/session/${session_name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put BFD Authentication Key [Arguments] ${node} ${key_name} ${auth_type} ${id} ${secret} - Log Many ${node} ${key_name} ${auth_type} ${id} ${secret} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/bfd_key.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/bfd/auth-key/${key_name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put BFD Echo Function [Arguments] ${node} ${echo_func_name} ${source_intf} - Log Many ${node} ${echo_func_name} ${source_intf} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/bfd_echo_function.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/bfd/echo-function - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Get BFD Session As Json [Arguments] ${node} ${session_name} - Log Many ${node} ${session_name} ${key}= Set Variable /vnf-agent/${node}/vpp/config/v1/bfd/session/${session_name} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json - Log ${output} [Return] ${output} vpp_ctl: Get BFD Authentication Key As Json [Arguments] ${node} ${key_name} - Log Many ${node} ${key_name} ${key}= Set Variable /vnf-agent/${node}/vpp/config/v1/bfd/auth-key/${key_name} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json [Return] ${output} vpp_ctl: Get BFD Echo Function As Json [Arguments] ${node} - Log Many ${node} ${key}= Set Variable /vnf-agent/${node}/vpp/config/v1/bfd/echo-function - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json [Return] ${output} vpp_ctl: Put ACL TCP [Arguments] ${node} ${acl_name} ${egr_intf1} ${ingr_intf1} ${acl_action} ${dest_ntw} ${src_ntw} ${dest_port_low} ${dest_port_up} ${src_port_low} ${src_port_up} - Log Many ${node} ${acl_name} ${egr_intf1} ${ingr_intf1} ${acl_action} ${dest_ntw} ${src_ntw} ${dest_port_low} ${dest_port_up} ${src_port_low} ${src_port_up} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/acl_TCP.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/acl/${acl_name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} #OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply.json ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put ACL UDP [Arguments] ${node} ${acl_name} ${egr_intf1} ${ingr_intf1} ${egr_intf2} ${ingr_intf2} ${acl_action} ${dest_ntw} ${src_ntw} ${dest_port_low} ${dest_port_up} ${src_port_low} ${src_port_up} - Log Many ${node} ${acl_name} ${egr_intf1} ${ingr_intf1} ${egr_intf2} ${ingr_intf2} ${acl_action} ${dest_ntw} ${src_ntw} ${dest_port_low} ${dest_port_up} ${src_port_low} ${src_port_up} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/acl_UDP.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/acl/${acl_name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} #OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply.json ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put ACL MACIP [Arguments] ${node} ${acl_name} ${egr_intf1} ${ingr_intf1} ${acl_action} ${src_addr} ${src_addr_prefix} ${src_mac_addr} ${src_mac_addr_mask} - Log Many ${node} ${acl_name} ${egr_intf1} ${ingr_intf1} ${acl_action} ${src_addr} ${src_addr_prefix} ${src_mac_addr} ${src_mac_addr_mask} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/acl_MACIP.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/acl/${acl_name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} #OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply.json ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put ACL ICMP [Arguments] ${node} ${acl_name} ${egr_intf1} ${egr_intf2} ${ingr_intf1} ${ingr_intf2} ${acl_action} ${dest_ntw} ${src_ntw} ${icmpv6} ${code_range_low} ${code_range_up} ${type_range_low} ${type_range_up} - Log Many ${node} ${acl_name} ${egr_intf1} ${egr_intf2} ${ingr_intf1} ${ingr_intf2} ${acl_action} ${dest_ntw} ${src_ntw} ${icmpv6} ${code_range_low} ${code_range_up} ${type_range_low} ${type_range_up} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/acl_ICMP.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/acl/${acl_name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} #OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply.json ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Get ACL As Json [Arguments] ${node} ${acl_name} - Log Many ${node} ${acl_name} ${key}= Set Variable /vnf-agent/${node}/vpp/config/v1/acl/${acl_name} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} #${output}= Evaluate json.loads('''${data}''') json #log ${output} OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply_${acl_name}.json ${data} @@ -461,13 +344,9 @@ vpp_ctl: Get ACL As Json vpp_ctl: Get All ACL As Json [Arguments] ${node} - Log Many ${node} ${key}= Set Variable /vnf-agent/${node}/vpp/config/v1/acl - Log ${key} ${data}= etcd: Get ETCD Tree ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} #${output}= Evaluate json.loads('''${data}''') json #log ${output} OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply_acl_all.json ${data} @@ -476,121 +355,85 @@ vpp_ctl: Get All ACL As Json etcd: Get ETCD Tree [Arguments] ${key} - Log Many ${key} ${command}= Set Variable ${DOCKER_COMMAND} exec etcd etcdctl get --prefix="true" ${key} ${out}= Execute On Machine docker ${command} log=false [Return] ${out} vpp_ctl: Delete ACL [Arguments] ${node} ${name} - Log Many ${node} ${name} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/acl/${name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put Veth Interface Via Linux Plugin [Arguments] ${node} ${namespace} ${name} ${host_if_name} ${mac} ${peer} ${ip} ${prefix}=24 ${mtu}=1500 ${enabled}=true - Log Many ${node} ${namespace} ${name} ${host_if_name} ${mac} ${peer} ${ip} ${prefix} ${mtu} ${enabled} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/linux_veth_interface.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Linux Route [Arguments] ${node} ${namespace} ${interface} ${routename} ${ip} ${next_hop} ${prefix}=24 ${metric}=100 ${isdefault}=false - Log Many ${node} ${namespace} ${interface} ${routename} ${ip} ${prefix} ${next_hop} ${metric} ${isdefault} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/linux_static_route.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/route/${routename} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Default Linux Route [Arguments] ${node} ${namespace} ${interface} ${routename} ${next_hop} ${metric}=100 ${isdefault}=true - Log Many ${node} ${namespace} ${interface} ${routename} ${next_hop} ${metric} ${isdefault} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/linux_default_static_route.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/route/${routename} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Linux Route Without Interface [Arguments] ${node} ${namespace} ${routename} ${ip} ${next_hop} ${prefix}=24 ${metric}=100 - Log Many ${node} ${namespace} ${routename} ${ip} ${prefix} ${next_hop} ${metric} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/linux_static_route_without_interface.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/route/${routename} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete Linux Route [Arguments] ${node} ${routename} - Log Many ${node} ${routename} ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/route/${routename} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Get Linux Route As Json [Arguments] ${node} ${routename} - Log Many ${node} ${routename} ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/route/${routename} - Log ${uri} ${data}= vpp_ctl: Read Key ${uri} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json [Return] ${output} vpp_ctl: Check ACL Reply [Arguments] ${node} ${acl_name} ${reply_json} ${reply_term} ${api_h}=$(API_HANDLER} - Log Many ${node} ${acl_name} ${reply_json} ${reply_term} ${api_h} ${acl_d}= vpp_ctl: Get ACL As Json ${node} ${acl_name} ${term_d}= vat_term: Check ACL ${node} ${acl_name} ${term_d_lines}= Split To Lines ${term_d} - Log ${term_d_lines} ${data}= OperatingSystem.Get File ${reply_json} - Log ${data} ${data}= Replace Variables ${data} - Log ${data} Should Be Equal ${data} ${acl_d} ${data}= OperatingSystem.Get File ${reply_term} - Log ${data} ${data}= Replace Variables ${data} - Log ${data} ${t_data_lines}= Split To Lines ${data} - Log ${t_data_lines} List Should Contain Sub List ${term_d_lines} ${t_data_lines} vpp_ctl: Put ARP [Arguments] ${node} ${interface} ${ipv4} ${MAC} ${static} - Log Many ${node} ${interface} ${ipv4} ${MAC} ${static} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/arp.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/arp/${interface}/${ipv4} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Get ARP As Json [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${key}= Set Variable /vnf-agent/${node}/vpp/config/v1/arp/${interface} - Log ${key} ${data}= vpp_ctl: Read Key ${key} - Log ${data} ${data}= Set Variable If '''${data}'''=="" {} ${data} - Log ${data} ${output}= Evaluate json.loads('''${data}''') json - log ${output} [Return] ${output} vpp_ctl: Set L4 Features On Node @@ -598,184 +441,136 @@ vpp_ctl: Set L4 Features On Node [Documentation] Enable [disable] L4 features by setting ${enabled} to true [false]. ${data}= OperatingSystem.Get File ${CURDIR}/../resources/enable-l4.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/l4/features/feature - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Application Namespace [Arguments] ${node} ${id} ${secret} ${interface} [Documentation] Put application namespace config json to etcd. - Log Many ${node} ${id} ${secret} ${interface} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/app_namespace.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/l4/namespaces/${id} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete ARP [Arguments] ${node} ${interface} ${ipv4} - Log Many ${node} ${interface} ${ipv4} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/arp/${interface}/${ipv4} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put Linux ARP With Namespace [Arguments] ${node} ${interface} ${arpname} ${ipv4} ${MAC} ${nsname} ${nstype} - Log Many ${node} ${interface} ${arpname} ${ipv4} ${MAC} ${nsname} ${nstype} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/arp_linux.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/arp/${arpname} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put Linux ARP [Arguments] ${node} ${interface} ${arpname} ${ipv4} ${MAC} - Log Many ${node} ${interface} ${arpname} ${ipv4} ${MAC} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/arp_linux.json ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/arp/${arpname} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete Linux ARP [Arguments] ${node} ${arpname} - Log Many ${node} ${arpname} ${uri}= Set Variable /vnf-agent/${node}/linux/config/v1/arp/${arpname} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put L2XConnect [Arguments] ${node} ${rx_if} ${tx_if} [Documentation] Put L2 Xconnect config json to etcd. - Log Many ${node} ${rx_if} ${tx_if} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/l2xconnect.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/xconnect/${rx_if} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete L2XConnect [Arguments] ${node} ${rx_if} [Documentation] Delete L2 Xconnect config json from etcd. - Log Many ${node} ${rx_if} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/xconnect/${rx_if} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put TAPv2 Interface With IP [Arguments] ${node} ${name} ${mac} ${ip} ${host_if_name} ${prefix}=24 ${mtu}=1500 ${enabled}=true ${vrf}=0 - Log Many ${node} ${name} ${mac} ${ip} ${host_if_name} ${prefix} ${mtu} ${enabled} ${vrf} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/tapv2_interface_with_ip.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/interface/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Put STN Rule [Arguments] ${node} ${interface} ${ip} ${rule_name} - Log Many ${node} ${interface} ${ip} ${rule_name} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/stn_rule.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/stn/rules/${rule_name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete STN Rule [Arguments] ${node} ${rule_name} - Log Many ${node} ${rule_name} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/stn/rules/${rule_name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put Local SID [Arguments] ${node} ${localsidName} ${sidAddress} ${fibtable} ${outinterface} ${nexthop} [Documentation] Add Local SID config json to etcd. - Log Many ${node} ${localsidName} ${sidAddress} ${fibtable} ${outinterface} ${nexthop} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/srv6_local_sid.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/localsid/${localsidName} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete Local SID [Arguments] ${node} ${localsidName} [Documentation] Delete Local SID config json from etcd. - Log Many ${node} ${localsidName} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/localsid/${localsidName} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put SRv6 Policy [Arguments] ${node} ${name} ${bsid} ${fibtable} ${srhEncapsulation} ${sprayBehaviour} [Documentation] Add SRv6 Policy config json to etcd. - Log Many ${node} ${name} ${bsid} ${fibtable} ${srhEncapsulation} ${sprayBehaviour} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/srv6_policy.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/policy/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete SRv6 Policy [Arguments] ${node} ${name} [Documentation] Delete SRv6 policy config json from etcd. - Log Many ${node} ${name} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/policy/${name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put SRv6 Policy Segment [Arguments] ${node} ${name} ${policyName} ${policyBSID} ${weight} ${segmentlist} [Documentation] Add SRv6 Policy Segment config json to etcd. - Log Many ${node} ${name} ${policyName} ${policyBSID} ${weight} ${segmentlist} length should be ${segmentlist} 3 ${data}= OperatingSystem.Get File ${CURDIR}/../resources/srv6_policy_segment.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/policy/${policyName}/segment/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete SRv6 Policy Segment [Arguments] ${node} ${name} ${policyName} [Documentation] Delete SRv6 policy segment config json from etcd. - Log Many ${node} ${name} ${policyName} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/policy/${policyName}/segment/${name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} vpp_ctl: Put SRv6 Steering [Arguments] ${node} ${name} ${bsid} ${fibtable} ${prefixAddress} [Documentation] Add SRv6 steering config json to etcd. - Log Many ${node} ${name} ${bsid} ${fibtable} ${prefixAddress} ${data}= OperatingSystem.Get File ${CURDIR}/../resources/srv6_steering.json ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/steering/${name} - Log Many ${data} ${uri} ${data}= Replace Variables ${data} - Log ${data} vpp_ctl: Put Json ${uri} ${data} vpp_ctl: Delete SRv6 Steering [Arguments] ${node} ${name} [Documentation] Delete SRv6 steering config json from etcd. - Log Many ${node} ${name} ${uri}= Set Variable /vnf-agent/${node}/vpp/config/v1/srv6/steering/${name} ${out}= vpp_ctl: Delete key ${uri} - Log Many ${out} [Return] ${out} \ No newline at end of file diff --git a/tests/robot/libraries/vpp_term.robot b/tests/robot/libraries/vpp_term.robot index b821fd549e..8f96282fd8 100644 --- a/tests/robot/libraries/vpp_term.robot +++ b/tests/robot/libraries/vpp_term.robot @@ -13,7 +13,6 @@ ${terminal_timeout}= 30s vpp_term: Check VPP Terminal [Arguments] ${node} [Documentation] Check terminal on node ${node} - Log Many ${node} ${${node}_VPP_HOST_PORT} ${${node}_VPP_TERM_PROMPT} # using telnet does not work with latest VPP #${command}= Set Variable telnet 0 ${${node}_VPP_HOST_PORT} ${command}= Set Variable docker exec -it ${node} vppctl -s localhost:${${node}_VPP_PORT} @@ -28,15 +27,12 @@ vpp_term: Open VPP Terminal vpp_term: Issue Command [Arguments] ${node} ${command} ${delay}=${SSH_READ_DELAY}s - Log Many ${node} ${command} ${delay} ${node}_term ${${node}_VPP_TERM_PROMPT} ${out}= Write To Machine Until String ${node}_term ${command} ${${node}_VPP_TERM_PROMPT} delay=${delay} - Log ${out} # Should Contain ${out} ${${node}_VPP_TERM_PROMPT} [Return] ${out} vpp_term: Exit VPP Terminal [Arguments] ${node} - Log Many ${node} ${node}_term ${ctrl_d} Evaluate chr(int(4)) ${command}= Set Variable ${ctrl_d} ${out}= Write To Machine ${node}_term ${command} @@ -45,63 +41,53 @@ vpp_term: Exit VPP Terminal vpp_term: Show Interfaces [Arguments] ${node} ${interface}=${EMPTY} [Documentation] Show interfaces through vpp terminal - Log Many ${node} ${interface} ${out}= vpp_term: Issue Command ${node} sh int ${interface} [Return] ${out} vpp_term: Show Interfaces Address [Arguments] ${node} ${interface}=${EMPTY} [Documentation] Show interfaces address through vpp terminal - Log Many ${node} ${interface} ${out}= vpp_term: Issue Command ${node} sh int addr ${interface} - Log ${out} [Return] ${out} vpp_term: Show Hardware [Arguments] ${node} ${interface}=${EMPTY} [Documentation] Show interfaces hardware through vpp terminal - Log Many ${node} ${interface} ${out}= vpp_term: Issue Command ${node} sh h ${interface} [Return] ${out} vpp_term: Show IP Fib [Arguments] ${node} ${ip}=${EMPTY} [Documentation] Show IP fib output - Log Many ${node} ${ip} ${out}= vpp_term: Issue Command ${node} show ip fib ${ip} [Return] ${out} vpp_term: Show IP6 Fib [Arguments] ${node} ${ip}=${EMPTY} [Documentation] Show IP fib output - Log Many ${node} ${ip} ${out}= vpp_term: Issue Command ${node} show ip6 fib ${ip} [Return] ${out} vpp_term: Show IP Fib Table [Arguments] ${node} ${id} [Documentation] Show IP fib output for VRF table defined in input - Log Many ${node} ${id} ${out}= vpp_term: Issue Command ${node} show ip fib table ${id} [Return] ${out} vpp_term: Show IP6 Fib Table [Arguments] ${node} ${id} [Documentation] Show IP fib output for VRF table defined in input - Log Many ${node} ${id} ${out}= vpp_term: Issue Command ${node} show ip6 fib table ${id} [Return] ${out} vpp_term: Show L2fib [Arguments] ${node} - Log Many ${node} [Documentation] Show verbose l2fib output ${out}= vpp_term: Issue Command ${node} show l2fib verbose [Return] ${out} vpp_term: Show Bridge-Domain Detail [Arguments] ${node} ${id}=1 - Log Many ${node} [Documentation] Show detail of bridge-domain ${out}= vpp_term: Issue Command ${node} show bridge-domain ${id} detail [Return] ${out} @@ -109,34 +95,29 @@ vpp_term: Show Bridge-Domain Detail vpp_term: Show IPsec [Arguments] ${node} [Documentation] Show IPsec output - Log Many ${node} ${out}= vpp_term: Issue Command ${node} show ipsec [Return] ${out} vpp_term: Check Ping [Arguments] ${node} ${ip} ${count}=5 - Log Many ${node} ${ip} ${count} ${out}= vpp_term: Issue Command ${node} ping ${ip} repeat ${count} delay=10s Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss vpp_term: Check Ping6 [Arguments] ${node} ${ip} ${count}=5 - Log Many ${node} ${ip} ${count} ${out}= vpp_term: Issue Command ${node} ping ${ip} repeat ${count} delay=10s Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss vpp_term: Check Ping Within Interface [Arguments] ${node} ${ip} ${source} ${count}=5 - Log Many ${node} ${ip} ${source} ${count} ${out}= vpp_term: Issue Command ${node} ping ${ip} source ${source} repeat ${count} delay=10s Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss vpp_term: Check No Ping Within Interface [Arguments] ${node} ${ip} ${source} ${count}=5 - Log Many ${node} ${ip} ${source} ${count} ${out}= vpp_term: Issue Command ${node} ping ${ip} source ${source} repeat ${count} delay=10s Should Not Contain ${out} from ${ip} Should Contain ${out} 100% packet loss @@ -144,195 +125,147 @@ vpp_term: Check No Ping Within Interface vpp_term: Check Interface Presence [Arguments] ${node} ${mac} ${status}=${TRUE} [Documentation] Checking if specified interface with mac exists in VPP - Log Many ${node} ${mac} ${status} ${ints}= vpp_term: Show Hardware ${node} ${result}= Run Keyword And Return Status Should Contain ${ints} ${mac} Should Be Equal ${result} ${status} vpp_term: Interface Is Created [Arguments] ${node} ${mac} - Log Many ${node} ${mac} Wait Until Keyword Succeeds ${interface_timeout} 3s vpp_term: Check Interface Presence ${node} ${mac} vpp_term: Interface Is Deleted [Arguments] ${node} ${mac} - Log Many ${node} ${mac} Wait Until Keyword Succeeds ${interface_timeout} 3s vpp_term: Check Interface Presence ${node} ${mac} ${FALSE} vpp_term: Interface Exists [Arguments] ${node} ${mac} - Log Many ${node} ${mac} vpp_term: Check Interface Presence ${node} ${mac} vpp_term: Interface Not Exists [Arguments] ${node} ${mac} - Log Many ${node} ${mac} vpp_term: Check Interface Presence ${node} ${mac} ${FALSE} vpp_term: Check Interface UpDown Status [Arguments] ${node} ${interface} ${status}=1 [Documentation] Checking up/down state of specified internal interface - Log Many ${node} ${interface} ${status} ${internal_index}= vat_term: Get Interface Index agent_vpp_1 ${interface} - Log ${internal_index} ${interfaces}= vat_term: Interfaces Dump agent_vpp_1 - Log ${interfaces} ${int_state}= Get Interface State ${interfaces} ${internal_index} - Log ${int_state} ${enabled}= Set Variable ${int_state["admin_up_down"]} Should Be Equal As Integers ${enabled} ${status} vpp_term: Get Interface IPs [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${int_addr}= vpp_term: Show Interfaces Address ${node} ${interface} - Log ${int_addr} @{ipv4_list}= Find IPV4 In Text ${int_addr} - Log ${ipv4_list} [Return] ${ipv4_list} vpp_term: Get Interface IP6 IPs [Arguments] ${node} ${interface} [Documentation] Get all IPv6 addresses for the specified interface. - Log Many ${node} ${interface} ${int_addr}= vpp_term: Show Interfaces Address ${node} ${interface} - Log ${int_addr} @{ipv6_list}= Find IPV6 In Text ${int_addr} # Remove link-local address as it is hardware-dependent :FOR ${address} IN @{ipv6_list} \ Run Keyword If ${address.startswith('fd80:')} Remove Values From List ${ipv6_list} ${address} - Log ${ipv6_list} [Return] ${ipv6_list} vpp_term: Get Interface MAC [Arguments] ${node} ${interface} - Log Many ${node} ${interface} ${sh_h}= vpp_term: Show Hardware ${node} ${interface} - Log ${sh_h} ${mac}= Find MAC In Text ${sh_h} - Log ${mac} [Return] ${mac} vpp_term: Interface Is Enabled [Arguments] ${node} ${interface} - Log Many ${node} ${interface} Wait Until Keyword Succeeds ${interface_timeout} 3s vpp_term: Check Interface UpDown Status ${node} ${interface} vpp_term: Interface Is Disabled [Arguments] ${node} ${interface} - Log Many ${node} ${interface} Wait Until Keyword Succeeds ${interface_timeout} 3s vpp_term: Check Interface UpDown Status ${node} ${interface} 0 vpp_term: Interface Is Up [Arguments] ${node} ${interface} - Log Many ${node} ${interface} vpp_term: Check Interface UpDown Status ${node} ${interface} vpp_term: Interface Is Down [Arguments] ${node} ${interface} - Log Many ${node} ${interface} vpp_term: Check Interface UpDown Status ${node} ${interface} 0 vpp_term: Show Memif [Arguments] ${node} ${interface}=${EMPTY} [Documentation] Show memif interfaces through vpp terminal - Log Many ${node} ${interface} ${out}= vpp_term: Issue Command ${node} sh memif ${interface} [Return] ${out} vpp_term: Check TAP Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} @{desired_state} Sleep 10s Time to let etcd to get state of newly setup tap interface. ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${interface}= vpp_term: Show Interfaces ${node} ${internal_name} - Log ${interface} ${state}= Set Variable up ${status}= Evaluate "${state}" in """${interface}""" ${tap_int_state}= Set Variable If ${status}==True ${state} down - Log ${tap_int_state} ${ipv4}= vpp_term: Get Interface IPs ${node} ${internal_name} ${ipv4_string}= Get From List ${ipv4} 0 - Log ${ipv4} ${mac}= vpp_term: Get Interface MAC ${node} ${internal_name} - Log ${mac} ${actual_state}= Create List mac=${mac} ipv4=${ipv4_string} state=${tap_int_state} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vpp_term: Check TAP IP6 Interface State [Arguments] ${node} ${name} @{desired_state} [Documentation] Get operational state of the specified interface and compare with expected state. - Log Many ${node} ${name} @{desired_state} Sleep 10s Time to let etcd to get state of newly setup tap interface. ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${interface}= vpp_term: Show Interfaces ${node} ${internal_name} - Log ${interface} ${state}= Set Variable up ${status}= Evaluate "${state}" in """${interface}""" ${tap_int_state}= Set Variable If ${status}==True ${state} down - Log ${tap_int_state} ${ipv6}= vpp_term: Get Interface IP6 IPs ${node} ${internal_name} ${ipv6_string}= Get From List ${ipv6} 0 - Log ${ipv6} ${mac}= vpp_term: Get Interface MAC ${node} ${internal_name} - Log ${mac} ${actual_state}= Create List mac=${mac} ipv6=${ipv6_string} state=${tap_int_state} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vpp_term: Show ACL [Arguments] ${node} [Documentation] Show ACLs through vpp terminal - Log Many ${node} ${out}= vpp_term: Issue Command ${node} sh acl-plugin acl [Return] ${out} vpp_term: Add Route [Arguments] ${node} ${destination_ip} ${prefix} ${next_hop_ip} [Documentation] Add ip route through vpp terminal. - Log Many ${node} ${destination_ip} ${prefix} ${next_hop_ip} vpp_term: Issue Command ${node} ip route add ${destination_ip}/${prefix} via ${next_hop_ip} vpp_term: Show ARP [Arguments] ${node} [Documentation] Show ARPs through vpp terminal - Log Many ${node} ${out}= vpp_term: Issue Command ${node} sh ip arp #OperatingSystem.Create File ${REPLY_DATA_FOLDER}/reply_arp.json ${out} [Return] ${out} vpp_term: Check ARP [Arguments] ${node} ${interface} ${ipv4} ${MAC} ${presence} - Log Many ${node} ${interface} ${ipv4} ${MAC} ${presence} [Documentation] Check ARPs presence on interface - Log Many ${node} ${out}= vpp_term: Show ARP ${node} - Log ${out} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${interface} #Should Not Be Equal ${internal_name} ${None} - Log ${internal_name} ${status}= Run Keyword If '${internal_name}'!='${None}' Parse ARP ${out} ${internal_name} ${ipv4} ${MAC} ELSE Set Variable False - Log ${status} Should Be Equal As Strings ${status} ${presence} vpp_term: Show Application Namespaces [Arguments] ${node} [Documentation] Show application namespaces through vpp terminal - Log Many ${node} ${out}= vpp_term: Issue Command ${node} sh app ns - Log ${out} [Return] ${out} vpp_term: Return Data From Show Application Namespaces Output [Arguments] ${node} ${id} [Documentation] Returns a list containing namespace id, index, namespace secret and sw_if_index of an ... interface associated with the namespace. - Log Many ${node} ${id} ${out}= vpp_term: Show Application Namespaces ${node} ${out_line}= Get Lines Containing String ${out} ${id} ${out_data}= Split String ${out_line} @@ -342,65 +275,48 @@ vpp_term: Check Data In Show Application Namespaces Output [Arguments] ${node} ${id} @{desired_state} [Documentation] Desired data is a list variable containing namespace index, namespace secret and sw_if_index of an ... interface associated with the namespace. - Log Many ${node} ${id} @{desired_state} ${actual_state}= vpp_term: Return Data From Show Application Namespaces Output ${node} ${id} List Should Contain Sub List ${actual_state} ${desired_state} vpp_term: Show Interface Mode [Arguments] ${node} [Documentation] vpp_term: Show Interfaces Mode - Log Many ${node} ${out}= vpp_term: Issue Command ${node} show mode [Return] ${out} vpp_term: Check TAPv2 Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} @{desired_state} Sleep 10s Time to let etcd to get state of newly setup tapv2 interface. ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${interface}= vpp_term: Show Interfaces ${node} ${internal_name} - Log ${interface} ${state}= Set Variable up ${status}= Evaluate "${state}" in """${interface}""" ${tap_int_state}= Set Variable If ${status}==True ${state} down - Log ${tap_int_state} ${ipv4}= vpp_term: Get Interface IPs ${node} ${internal_name} ${ipv4_string}= Get From List ${ipv4} 0 - Log ${ipv4} ${mac}= vpp_term: Get Interface MAC ${node} ${internal_name} - Log ${mac} ${actual_state}= Create List mac=${mac} ipv4=${ipv4_string} state=${tap_int_state} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vpp_term: Check TAPv2 IP6 Interface State [Arguments] ${node} ${name} @{desired_state} - Log Many ${node} ${name} @{desired_state} Sleep 10s Time to let etcd to get state of newly setup tapv2 interface. ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${name} - Log ${internal_name} ${interface}= vpp_term: Show Interfaces ${node} ${internal_name} - Log ${interface} ${state}= Set Variable up ${status}= Evaluate "${state}" in """${interface}""" ${tap_int_state}= Set Variable If ${status}==True ${state} down - Log ${tap_int_state} ${ipv6}= vpp_term: Get Interface IP6 IPs ${node} ${internal_name} ${ipv6_string}= Get From List ${ipv6} 0 - Log ${ipv6} ${mac}= vpp_term: Get Interface MAC ${node} ${internal_name} - Log ${mac} ${actual_state}= Create List mac=${mac} ipv6=${ipv6_string} state=${tap_int_state} - Log List ${actual_state} List Should Contain Sub List ${actual_state} ${desired_state} [Return] ${actual_state} vpp_term: Show Trace [Arguments] ${node} [Documentation] vpp_term: Show Trace - Log Many ${node} ${out}= vpp_term: Issue Command ${node} show trace [Return] ${out} @@ -408,7 +324,6 @@ vpp_term: Show Trace vpp_term: Add Trace Memif [Arguments] ${node} [Documentation] vpp_term: Add Trace for memif interfaces - Log Many ${node} ${out}= vpp_term: Issue Command ${node} trace add memif-input 10 [Return] ${out} @@ -416,67 +331,46 @@ vpp_term: Add Trace Memif vpp_term: Show STN Rules [Arguments] ${node} [Documentation] Show STN Rules - Log Many ${node} ${out}= vpp_term: Issue Command ${node} show stn rules [Return] ${out} vpp_term: Check STN Rule State [Arguments] ${node} ${interface} ${ip} - Log Many ${node} ${ip} [Documentation] Check STN Rules - Log Many ${node} ${out}= vpp_term: Show STN Rules ${node} - Log ${out} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${interface} - Log ${internal_name} ${ip_address} ${iface} ${next_node} Parse STN Rule ${out} - Log ${ip_address} Should Be Equal As Strings ${ip} ${ip_address} - Log ${iface} Should Be Equal As Strings ${internal_name} ${iface} - Log ${next_node} vpp_term: Check STN Rule Deleted [Arguments] ${node} ${interface} ${ip} - Log Many ${node} ${ip} [Documentation] Check STN Rules - Log Many ${node} ${out}= vpp_term: Show STN Rules ${node} - Log ${out} ${internal_name}= vpp_ctl: Get Interface Internal Name ${node} ${interface} - Log ${internal_name} Should Not Contain ${out} ${ip} Should Not Contain ${out} ${internal_name} vpp_term: Add Trace Afpacket [Arguments] ${node} [Documentation] vpp_term: Add Trace for afpacket interfaces - Log Many ${node} ${out}= vpp_term: Issue Command ${node} trace add af-packet-input 10 [Return] ${out} vpp_term: Set VPP Tracing And Debugging [Arguments] ${node} [Documentation] vpp_term: Add More Tracing and debugging - Log Many ${node} ${out}= vpp_term: Issue Command ${node} clear hardware - Log ${out} ${out}= vpp_term: Issue Command ${node} clear interface - Log ${out} ${out}= vpp_term: Issue Command ${node} clear error - Log ${out} ${out}= vpp_term: Issue Command ${node} clear run - Log ${out} ${out}= vpp_term: Issue Command ${node} api trace on - Log ${out} ${out}= vpp_term: Issue Command ${node} api trace post-mortem-on - Log ${out} [Return] ${out} vpp_term: Dump Trace [Arguments] ${node} [Documentation] vpp_term: Dump VPP Trace - Log Many ${node} ${out}= vpp_term: Issue Command ${node} api trace save apitrace.trc [Return] ${out} @@ -484,7 +378,6 @@ vpp_term: Dump Trace vpp_term: Check Local SID Presence [Arguments] ${node} ${sidAddress} ${interface} ${nexthop} [Documentation] Checking if specified local sid exists or will show up - Log Many ${node} ${sidAddress} ${interface} ${nexthop} #${terminal_timeout} Wait Until Keyword Succeeds 5x 2s vpp_term: Local SID exists node=${node} sidAddress=${sidAddress} interface=${interface} nexthop=${nexthop} @@ -496,24 +389,20 @@ vpp_term: Local SID exists ${localsidsStr}= OperatingSystem.Get File /tmp/srv6_sh_sr_localsid_output.txt ${localsidsStr}= Basic_Operations.Replace_Rn_N ${localsidsStr} #FIX for BUG with New Line ${localsidsStr}= Convert To Lowercase ${localsidsStr} - Log ${localsidsStr} ${matchdata}= OperatingSystem.Get File ${CURDIR}/../suites/crud/test_data/srv6_sh_sr_localsid_output_match.txt ${matchdata}= Replace Variables ${matchdata} ${matchdata}= Convert To Lowercase ${matchdata} - Log ${matchdata} Should Contain ${localsidsStr} ${matchdata} vpp_term: Show Local SIDs [Arguments] ${node} [Documentation] Show locasids through vpp terminal - Log Many ${node} ${out}= vpp_term: Issue Command ${node} sh sr localsids [Return] ${out} vpp_term: Check Local SID Deleted [Arguments] ${node} ${sidAddress} [Documentation] Checking if specified local sid will be(or already is) deleted - Log Many ${node} ${sidAddress} Wait Until Keyword Succeeds 5x 2s vpp_term: Local SID doesnt exist node=${node} sidAddress=${sidAddress} vpp_term: Local SID doesnt exist @@ -523,17 +412,14 @@ vpp_term: Local SID doesnt exist Create File /tmp/srv6_sh_sr_localsid_output.txt ${localsidsStr} #FIXME remove dirty trick with saving string to file just to be able to match substring in string ${localsidsStr}= OperatingSystem.Get File /tmp/srv6_sh_sr_localsid_output.txt ${localsidsStr}= Convert To Lowercase ${localsidsStr} - Log ${localsidsStr} ${matchdata}= OperatingSystem.Get File ${CURDIR}/../suites/crud/test_data/srv6_sh_sr_localsid_output_no_match.txt ${matchdata}= Replace Variables ${matchdata} ${matchdata}= Convert To Lowercase ${matchdata} - Log ${matchdata} Should Not Contain ${localsidsStr} ${matchdata} vpp_term: Check SRv6 Policy Presence [Arguments] ${node} ${bsid} ${fibtable} ${behaviour} ${type} ${index} ${segmentlists} [Documentation] Checking if specified SRv6 policy exists or will show up - Log Many ${node} ${bsid} ${fibtable} ${behaviour} ${type} ${index} ${segmentlists} #${terminal_timeout} Wait Until Keyword Succeeds 5x 2s vpp_term: SRv6 Policy exists node=${node} bsid=${bsid} fibtable=${fibtable} behaviour=${behaviour} type=${type} index=${index} segmentlists=${segmentlists} @@ -545,7 +431,6 @@ vpp_term: SRv6 Policy exists ${policyStr}= OperatingSystem.Get File /tmp/srv6_sh_sr_policies_output.txt ${policyStr}= Basic_Operations.Replace_Rn_N ${policyStr} #FIX for BUG with New Line ${policyStr}= Convert To Lowercase ${policyStr} - Log ${policyStr} ${policymatchdata}= OperatingSystem.Get File ${CURDIR}/../suites/crud/test_data/srv6_sh_sr_policies_output_match.txt ${policymatchdata}= Replace Variables ${policymatchdata} ${policymatchdata}= Convert To Lowercase ${policymatchdata} @@ -556,20 +441,17 @@ vpp_term: SRv6 Policy exists \ ${segmentlistmatchdata}= Convert To Lowercase ${segmentlistmatchdata} \ ${segmentlistsmatchdata}= Catenate SEPARATOR= ${segmentlistsmatchdata} ${segmentlistmatchdata} ${matchdata}= Catenate SEPARATOR= ${policymatchdata} ${segmentlistsmatchdata} - Log ${matchdata} Should Contain ${policyStr} ${matchdata} vpp_term: Show SRv6 policies [Arguments] ${node} [Documentation] Show SRv6 policies through vpp terminal - Log Many ${node} ${out}= vpp_term: Issue Command ${node} sh sr policies [Return] ${out} vpp_term: Check SRv6 Policy Nonexistence [Arguments] ${node} ${bsid} [Documentation] Checking if specified SRv6 policy doesn't exist (or will be deleted soon) - Log Many ${node} ${bsid} Wait Until Keyword Succeeds 5x 2s vpp_term: SRv6 Policy doesnt exist node=${node} bsid=${bsid} vpp_term: SRv6 Policy doesnt exist @@ -579,17 +461,14 @@ vpp_term: SRv6 Policy doesnt exist Create File /tmp/srv6_sh_sr_policies_output.txt ${policyStr} #FIXME remove dirty trick with saving string to file just to be able to match substring in string ${policyStr}= OperatingSystem.Get File /tmp/srv6_sh_sr_policies_output.txt ${policyStr}= Convert To Lowercase ${policyStr} - Log ${policyStr} ${matchdata}= OperatingSystem.Get File ${CURDIR}/../suites/crud/test_data/srv6_sh_sr_policies_output_no_match.txt ${matchdata}= Replace Variables ${matchdata} ${matchdata}= Convert To Lowercase ${matchdata} - Log ${matchdata} Should Not Contain ${policyStr} ${matchdata} vpp_term: Check SRv6 Steering Presence [Arguments] ${node} ${bsid} ${prefixAddress} [Documentation] Checking if specified steering exists or will show up - Log Many ${node} ${bsid} ${prefixAddress} #${terminal_timeout} Wait Until Keyword Succeeds 5x 2s vpp_term: SRv6 Steering exists node=${node} bsid=${bsid} prefixAddress=${prefixAddress} @@ -600,24 +479,20 @@ vpp_term: SRv6 Steering exists Create File /tmp/srv6_sh_sr_steerings_output.txt ${steeringStr} #FIXME remove dirty trick with saving string to file just to be able to match substring in string ${steeringStr}= OperatingSystem.Get File /tmp/srv6_sh_sr_steerings_output.txt ${steeringStr}= Convert To Lowercase ${steeringStr} - Log ${steeringStr} ${matchdata}= OperatingSystem.Get File ${CURDIR}/../suites/crud/test_data/srv6_sh_sr_steering_output_match.txt ${matchdata}= Replace Variables ${matchdata} ${matchdata}= Convert To Lowercase ${matchdata} - Log ${matchdata} Should Contain ${steeringStr} ${matchdata} vpp_term: Show SRv6 steering policies [Arguments] ${node} [Documentation] Show SRv6 steering policies through vpp terminal - Log Many ${node} ${out}= vpp_term: Issue Command ${node} sh sr steering policies [Return] ${out} vpp_term: Check SRv6 Steering NonExistence [Arguments] ${node} ${bsid} ${prefixAddress} [Documentation] Checking if specified steering is deleted (or soon will be deleted) - Log Many ${node} ${bsid} ${prefixAddress} #${terminal_timeout} Wait Until Keyword Succeeds 5x 2s vpp_term: SRv6 Steering doesnt exist node=${node} bsid=${bsid} prefixAddress=${prefixAddress} @@ -628,9 +503,7 @@ vpp_term: SRv6 Steering doesnt exist Create File /tmp/srv6_sh_sr_steerings_output.txt ${steeringStr} #FIXME remove dirty trick with saving string to file just to be able to match substring in string ${steeringStr}= OperatingSystem.Get File /tmp/srv6_sh_sr_steerings_output.txt ${steeringStr}= Convert To Lowercase ${steeringStr} - Log ${steeringStr} ${matchdata}= OperatingSystem.Get File ${CURDIR}/../suites/crud/test_data/srv6_sh_sr_steering_output_match.txt ${matchdata}= Replace Variables ${matchdata} ${matchdata}= Convert To Lowercase ${matchdata} - Log ${matchdata} Should Not Contain ${steeringStr} ${matchdata} \ No newline at end of file diff --git a/tests/robot/libraries/vxlan.robot b/tests/robot/libraries/vxlan.robot index 0830327438..bd9278bedc 100644 --- a/tests/robot/libraries/vxlan.robot +++ b/tests/robot/libraries/vxlan.robot @@ -8,23 +8,19 @@ ${tunnel_timeout}= 15s *** Keywords *** vxlan: Tunnel Is Created [Arguments] ${node} ${src} ${dst} ${vni} - Log Many ${node} ${src} ${dst} ${vni} ${int_index}= Wait Until Keyword Succeeds ${tunnel_timeout} 3s vat_term: Check VXLan Tunnel Presence ${node} ${src} ${dst} ${vni} [Return] ${int_index} vxlan: Tunnel Is Deleted [Arguments] ${node} ${src} ${dst} ${vni} - Log Many ${node} ${src} ${dst} ${vni} Wait Until Keyword Succeeds ${tunnel_timeout} 3s vat_term: Check VXLan Tunnel Presence ${node} ${src} ${dst} ${vni} ${FALSE} vxlan: Tunnel Exists [Arguments] ${node} ${src} ${dst} ${vni} - Log Many ${node} ${src} ${dst} ${vni} ${int_index}= vat_term: Check VXLan Tunnel Presence ${node} ${src} ${dst} ${vni} [Return] ${int_index} vxlan: Tunnel Not Exists [Arguments] ${node} ${src} ${dst} ${vni} - Log Many ${node} ${src} ${dst} ${vni} vat_term: Check VXLan Tunnel Presence ${node} ${src} ${dst} ${vni} ${FALSE} diff --git a/tests/robot/lists/list_api.txt b/tests/robot/lists/list_api.txt new file mode 100644 index 0000000000..6cab0bfe60 --- /dev/null +++ b/tests/robot/lists/list_api.txt @@ -0,0 +1,2 @@ +--suite Api.Management Api.Management Api +--suite Api.BFD.Bfd Api \ No newline at end of file diff --git a/tests/robot/lists/list_crud_ipv4.txt b/tests/robot/lists/list_crud_ipv4.txt new file mode 100644 index 0000000000..0e8e7f3aac --- /dev/null +++ b/tests/robot/lists/list_crud_ipv4.txt @@ -0,0 +1,20 @@ +--suite Crud.Acl Crud +#--suite Crud.Afpacket Crud +--suite Crud.App Namespaces Crud +#--suite Crud.Arp Crud +#--suite Crud.Bd Crud +--suite Crud.Ip Route Crud +--suite Crud.Ipsec Crud +--suite Crud.L2Xconnect Crud +--suite Crud.Linux Arp Crud +--suite Crud.Linux Ip Route Crud +--suite Crud.Loopback Crud +--suite Crud.Memif Crud +#--suite Crud.Physical Crud +--suite Crud.Srv6 Crud +#--suite Crud.Stn Rule Crud +--suite Crud.Tap Crud +#--suite Crud.Tap Unnumbered Crud +#--suite Crud.Tapv2 Crud +--suite Crud.Veth Crud +--suite Crud.Vxlan Crud \ No newline at end of file diff --git a/tests/robot/lists/list_crud_ipv6.txt b/tests/robot/lists/list_crud_ipv6.txt new file mode 100644 index 0000000000..1cd490e703 --- /dev/null +++ b/tests/robot/lists/list_crud_ipv6.txt @@ -0,0 +1,20 @@ +--suite CrudIPv6.Acl CrudIPv6 +#--suite CrudIPv6.Afpacket CrudIPv6 +--suite CrudIPv6.App Namespaces CrudIPv6 +#--suite CrudIPv6.Arp CrudIPv6 +#--suite CrudIPv6.Bd CrudIPv6 +--suite CrudIPv6.Ip Route CrudIPv6 +--suite CrudIPv6.Ipsec CrudIPv6 +--suite CrudIPv6.L2Xconnect CrudIPv6 +--suite CrudIPv6.Linux Arp CrudIPv6 +--suite CrudIPv6.Linux Ip Route CrudIPv6 +--suite CrudIPv6.Loopback CrudIPv6 +--suite CrudIPv6.Memif CrudIPv6 +#--suite CrudIPv6.Physical CrudIPv6 +#--suite CrudIPv6.Srv6 CrudIPv6 +#--suite CrudIPv6.Stn Rule CrudIPv6 +--suite CrudIPv6.Tap CrudIPv6 +#--suite CrudIPv6.Tap Unnumbered CrudIPv6 +#--suite CrudIPv6.Tapv2 CrudIPv6 +--suite CrudIPv6.Veth CrudIPv6 +--suite CrudIPv6.Vxlan CrudIPv6 \ No newline at end of file diff --git a/tests/robot/lists/list_intregration_restarts.txt b/tests/robot/lists/list_intregration_restarts.txt new file mode 100644 index 0000000000..759bef980b --- /dev/null +++ b/tests/robot/lists/list_intregration_restarts.txt @@ -0,0 +1,2 @@ +--suite Integration.Restarts.Basic Restarts +#--suite Integration.Restarts.Scale Restarts \ No newline at end of file diff --git a/tests/robot/lists/list_misc.txt b/tests/robot/lists/list_misc.txt new file mode 100644 index 0000000000..588305affa --- /dev/null +++ b/tests/robot/lists/list_misc.txt @@ -0,0 +1,2 @@ +#--suite Misc.Errors Handling.Errors Handling +#--suite Integration.Etcd Clear \ No newline at end of file diff --git a/tests/robot/lists/list_sfc_ipv4.txt b/tests/robot/lists/list_sfc_ipv4.txt new file mode 100644 index 0000000000..464bc8530f --- /dev/null +++ b/tests/robot/lists/list_sfc_ipv4.txt @@ -0,0 +1,3 @@ +--suite Sfc.East West.Vswitch 1x Vpp 1x Novpp.Vswitch 1x Vpp 1x Novpp +--suite Sfc.East West.Vswitch 2x Vnf Vpp.Vswitch 2x Vnf Vpp +--suite Sfc.Test Controller Start.Controller Start \ No newline at end of file diff --git a/tests/robot/lists/list_sfc_ipv6.txt b/tests/robot/lists/list_sfc_ipv6.txt new file mode 100644 index 0000000000..eec91ac7ef --- /dev/null +++ b/tests/robot/lists/list_sfc_ipv6.txt @@ -0,0 +1,3 @@ +--suite SfcIPv6.East West.Vswitch 1x Vpp 1x Novpp.Vswitch 1x Vpp 1x NovppIPv6 +--suite SfcIPv6.East West.Vswitch 2x Vnf Vpp.Vswitch 2x Vnf VppIPv6 +--suite SfcIPv6.Test Controller Start.Controller StartIPv6 \ No newline at end of file diff --git a/tests/robot/lists/list_traffic_ipv4.txt b/tests/robot/lists/list_traffic_ipv4.txt new file mode 100644 index 0000000000..81f666d1dd --- /dev/null +++ b/tests/robot/lists/list_traffic_ipv4.txt @@ -0,0 +1,19 @@ +#--suite Traffic.3X Vpp Traffic.3X Vpp Traffic +#--suite Traffic.Acl Traffic.Acl Traffic +--suite Traffic.Bridge Domain.Test Bridge Domain +--suite Traffic.Ip Route.Test Ip Route +#--suite Traffic.L2Xconnect Traffic.L2Xconnect Trafic +#--suite Traffic.Libmemif.Libmemif Master Trafic1 +#--suite Traffic.Libmemif.Libmemif Master Trafic2 +#--suite Traffic.Libmemif.Libmemif Slave Trafic1 +#--suite Traffic.Libmemif.Libmemif Slave Trafic2 +#--suite Traffic.Linux Traffic.1x Vpp 3x Namespaces Traffic +#--suite Traffic.Physical Int Traffic.Physical Int Traffic +--suite Traffic.Tap Int Traffic.Tap Int Traffic +#--suite Traffic.Tap Int Traffic.Tap Int And Route Config Order Traffic +#--suite Traffic.Tapv2 Int Traffic.Tapv2 Int Traffic +#--suite Traffic.Tapv2 Int Traffic.Tapv2 Int And Route Config Order Traffic +--suite Traffic.Veth Af Packet Traffic.Veth Af Packet Traffic +--suite Traffic.Veth Afpacket Memif Vxlan Traffic.Veth Afpacket Memif Vxlan Traffic +#--suite Traffic.Veth Afpacket Memif Vxlan Traffic.Veth Afpacket Memif Vxlan Traffic Other Vrf +#--suite Traffic.Vpp 2Novpp Memif Traffic.Vpp 2Novpp Memif Traffic \ No newline at end of file diff --git a/tests/robot/lists/list_traffic_ipv6.txt b/tests/robot/lists/list_traffic_ipv6.txt new file mode 100644 index 0000000000..e85a54a56e --- /dev/null +++ b/tests/robot/lists/list_traffic_ipv6.txt @@ -0,0 +1,24 @@ +#--suite TrafficIPv6.3x Vpp Traffic.3x Vpp TrafficIPv6 +#--suite TrafficIPv6.Acl Traffic.Acl TrafficIPv6 +--suite TrafficIPv6.Bridge Domain.Test1 Bridge DomainIPv6 +--suite TrafficIPv6.Bridge Domain.Test2 Bridge DomainIPv6 +--suite TrafficIPv6.Bridge Domain.Test3 Bridge DomainIPv6 +--suite TrafficIPv6.Ip Route.Test1 Ip RouteIPv6 +--suite TrafficIPv6.Ip Route.Test2 Ip RouteIPv6 +--suite TrafficIPv6.Ip Route.Test3 Ip RouteIPv6 +--suite TrafficIPv6.Ip Route.Test4 Ip RouteIPv6 +#--suite TrafficIPv6.L2xconnect Traffic.L2xconnect TraficIPv6 +#--suite TrafficIPv6.Libmemif.Libmemif Master Trafic1IPv6 +#--suite TrafficIPv6.Libmemif.Libmemif Master Trafic2IPv6 +#--suite TrafficIPv6.Libmemif.Libmemif Slave Trafic1IPv6 +#--suite TrafficIPv6.Libmemif.Libmemif Slave Trafic2IPv6 +#--suite TrafficIPv6.Linux Traffic.1x Vpp 3x Namespaces TrafficIPv6 +#--suite TrafficIPv6.Physical Int Traffic.Physical Int TrafficIPv6 +--suite TrafficIPv6.Tap Int Traffic.Tap Int TrafficIPv6 +#--suite TrafficIPv6.Tap Int Traffic.Tap Int And Route Config Order TrafficIPv6 +#--suite TrafficIPv6.Tapv2 Int Traffic.Tapv2 Int TrafficIPv6 +#--suite TrafficIPv6.Tapv2 Int Traffic.Tapv2 Int And Route Config Order TrafficIPv6 +--suite TrafficIPv6.Veth Af Packet Traffic.Veth Af Packet TrafficIPv6 +--suite TrafficIPv6.Veth Afpacket Memif Vxlan Traffic.Veth Afpacket Memif Vxlan TrafficIPv6 +#--suite TrafficIPv6.Veth Afpacket Memif Vxlan Traffic.Veth Afpacket Memif Vxlan Traffic Other VrfIPv6 +#--suite TrafficIPv6.Vpp 2Novpp Memif Traffic.Vpp 2Novpp Memif TrafficIPv6 \ No newline at end of file diff --git a/tests/robot/resources/k8-yaml/sfc-k8.yaml b/tests/robot/resources/k8-yaml/sfc-k8.yaml index 8aa41efac1..d937ed9ecc 100644 --- a/tests/robot/resources/k8-yaml/sfc-k8.yaml +++ b/tests/robot/resources/k8-yaml/sfc-k8.yaml @@ -9,13 +9,13 @@ data: endpoints: - "172.17.0.1:22379" sfc.conf: | - sfc_controller_config_version: 1 + sfc_controller_config_version: 2 description: Basic restarts topology - host_entities: - - name: agent_vpp_vswitch + network_nodes: + - metadata: + name: agent_vpp_vswitch - sfc_entities: --- apiVersion: v1 kind: Pod @@ -24,7 +24,7 @@ metadata: spec: containers: - name: "sfc-controller" - image: ligato/prod_sfc_controller:latest + image: ligato/dev_sfc_controller:latest imagePullPolicy: IfNotPresent securityContext: privileged: true diff --git a/tests/robot/resources/veth_interface_with_ip_and_ns.json b/tests/robot/resources/veth_interface_with_ip_and_ns.json new file mode 100644 index 0000000000..e0ddcd2acb --- /dev/null +++ b/tests/robot/resources/veth_interface_with_ip_and_ns.json @@ -0,0 +1,17 @@ +{ + "name": "${name}", + "type": 0, + "enabled": ${enabled}, + "phys_address": "${mac}", + "veth": { + "peer_if_name": "${peer}" + }, + "namespace": { + "microservice": "${namespace}", + "type": 1 + }, + "mtu": ${mtu}, + "ip_addresses": [ + "${ip}/${prefix}" + ] +} \ No newline at end of file diff --git a/tests/robot/resources/veth_interface_with_ns.json b/tests/robot/resources/veth_interface_with_ns.json new file mode 100644 index 0000000000..c309634e90 --- /dev/null +++ b/tests/robot/resources/veth_interface_with_ns.json @@ -0,0 +1,13 @@ +{ + "name": "${name}", + "type": 0, + "enabled": ${enabled}, + "phys_address": "${mac}", + "veth": { + "peer_if_name": "${peer}" + }, + "namespace": { + "name": "${namespace}", + "type": 1 + } +} \ No newline at end of file diff --git a/tests/robot/suites/api/BFD/bfd_api.robot b/tests/robot/suites/api/BFD/bfd_api.robot index e9c83d108a..9770af11c3 100644 --- a/tests/robot/suites/api/BFD/bfd_api.robot +++ b/tests/robot/suites/api/BFD/bfd_api.robot @@ -45,13 +45,11 @@ Setup Interfaces Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 ${VPP1_BFD_INTF} Should Contain ${out} ${int} Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 ${VPP2_BFD_INTF} Should Contain ${out} ${int} diff --git a/tests/robot/suites/api/management_api/management_api.robot b/tests/robot/suites/api/management_api/management_api.robot index 2a2e154f8a..01b7b52c32 100644 --- a/tests/robot/suites/api/management_api/management_api.robot +++ b/tests/robot/suites/api/management_api/management_api.robot @@ -23,11 +23,9 @@ Change Logger Level Change Log Level On agent_vpp_1 From debug To info On vpp-plugin Change Log Level On agent_vpp_1 From debug To info On vpp-plugin-if-conf ${from_now}= Get Time epoch - Log Many ${from_now} vpp_ctl: Put Loopback Interface With IP agent_vpp_1 loop0 8a:f1:be:90:00:03 10.1.1.1 Sleep 5 ${out}= Write To Machine docker docker logs --since ${from_now} agent_vpp_1 - Log Many ${out} Should Not Contain ${out} level=debug msg="Start processing change for key: vpp/config/v1/interface/loop0" Should Not Contain ${out} level=debug msg="MAC address added" MAC address="8a:f1:be:90:00:03" Should Not Contain ${out} level=debug msg="IP address added." IPAddress=10.1.1.1 @@ -58,9 +56,7 @@ Teardown Remove Node agent_vpp_1 Get All Loggers On ${node} - Log Many ${node} ${out}= rest_api: Get Loggers List agent_vpp_1 - Log Many ${out} Should Contain ${out} etcd Should Contain ${out} govpp Should Contain ${out} http @@ -71,26 +67,20 @@ Get All Loggers On ${node} Should Contain ${out} cassandra Change Log Level On ${node} From ${old_level} To ${expected_level} On ${logger_name} - Log Many ${node} ${old_level} ${expected_level} ${logger_name} ${out}= rest_api: Get Loggers List ${node} ${level}= Extract Logger Level ${logger_name} ${out} - Log Many ${out} ${level} Should Be Equal ${level} ${old_level} Should Not Be Equal ${level} ${expected_level} rest_api: Change Logger Level ${node} ${logger_name} ${expected_level} ${out}= rest_api: Get Loggers List ${node} ${level}= Extract Logger Level ${logger_name} ${out} - Log Many ${out} ${level} Should Be Equal ${level} ${expected_level} Should Not Be Equal ${level} ${old_level} Agent ${ability} Should Be ${expected} On ${node} - Log Many ${ability} ${expected} ${node} ${expected}= Set Variable if "${expected}"=="OK" 1 0 - Log Many ${expected} ${uri}= Set Variable /${ability} ${out}= rest_api: Get ${node} ${uri} - Log Many ${out} #Should Match Regexp ${out} \\{\\"build_version\\":\\"[a-f0-9]+\\"\\,\\"build_date\\"\\:\\"\\d{4}\\-\\d{2}\\-\\d{2}\\T\\d{2}\\:\\d{2}\\+\\d{2}\\:\\d{2}\\",\\"state\\"\\:${expected},\\"start_time\\":\\d+,\\"last_change\\":\\d+,\\"last_update\\":\\d+,\\"commit_hash\\":\\"[a-e0-9]+\\"\\} Should Match Regexp ${out} \\"build_version\\":\\"[a-z0-9_.-]+\\" Should Match Regexp ${out} \\"build_date\\"\\:\\"\\d{4}\\-\\d{2}\\-\\d{2}\\T\\d{2}\\:\\d{2}\\+\\d{2}\\:\\d{2}\\" @@ -101,11 +91,8 @@ Agent ${ability} Should Be ${expected} On ${node} Should Match Regexp ${out} \\"commit_hash\\":\\"[a-f0-9]+\\" Change API Port From ${old_port} To ${new_port} On ${node} - Log Many ${old_port} ${new_port} ${node} - Log Many ${${node}_REST_API_HOST_PORT} ${${node}_REST_API_PORT} Set Test Variable ${${node}_REST_API_PORT} ${new_port} Set Test Variable ${${node}_REST_API_HOST_PORT} ${new_port} - Log Many ${${node}_REST_API_HOST_PORT} ${${node}_REST_API_PORT} Should Be Equal ${${node}_REST_API_PORT} ${new_port} Should Not Be Equal ${${node}_REST_API_PORT} ${old_port} Remove Node agent_vpp_1 @@ -116,11 +103,8 @@ Change API Port From ${old_port} To ${new_port} On ${node} Agent readiness Should Be OK On ${node} Get Agent Status For ${node} From ETCD Should be ${expected} - Log Many ${node} ${expected} ${expected}= Set Variable if "${expected}"=="OK" 1 0 - Log Many ${expected} ${out}= Write To Machine docker docker exec -it etcd etcdctl get /vnf-agent/${node}/check/status/v1/agent - Log Many ${out} Should Contain ${out} ${node} #Should Match Regexp ${out} \\{\\"build_version\\":\\"[a-f0-9]+\\"\\,\\"build_date\\"\\:\\"\\d{4}\\-\\d{2}\\-\\d{2}\\T\\d{2}\\:\\d{2}\\+\\d{2}\\:\\d{2}\\",\\"state\\"\\:${expected},\\"start_time\\":\\d+,\\"last_change\\":\\d+,\\"last_update\\":\\d+\\} Should Match Regexp ${out} \\"build_version\\":\\"[a-z0-9_.-]+\\" @@ -132,19 +116,15 @@ Get Agent Status For ${node} From ETCD Should be ${expected} Should Match Regexp ${out} \\"commit_hash\\":\\"[a-f0-9]+\\" Sleep 20s ${out2}= Write To Machine docker docker exec -it etcd etcdctl get /vnf-agent/${node}/check/status/v1/agent - Log Many ${out} ${out2} Should Not Be Equal ${out} ${out2} Get ${plugin} Plugin Status For ${node} From ETCD - Log Many ${plugin} ${node} ${out}= Write To Machine docker docker exec -it etcd etcdctl get /vnf-agent/${node}/check/status/v1/plugin/${plugin} - Log Many ${out} Should Contain ${out} ${node} Start Agent On ${node} With Port ${port} ${out}= Execute In Container ${node} vpp-agent -http-probe-port ${port} --etcd-config=${AGENT_VPP_ETCD_CONF_PATH} --kafka-config=${AGENT_VPP_KAFKA_CONF_PATH} & - Log Many ${out} [Return] ${out} Add VPP Agent ${node} @@ -156,7 +136,6 @@ Add VPP Agent ${node} # ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' # Set Suite Variable ${${node}_HOlSTNAME} ${hostname} - Log ${node} Open SSH Connection ${node} ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} Execute On Machine ${node} ${DOCKER_COMMAND} create -e MICROSERVICE_LABEL=${node} -it --privileged -v "${DOCKER_SOCKET_FOLDER}:${${node}_SOCKET_FOLDER}" -p ${${node}_VPP_HOST_PORT}:${${node}_VPP_PORT} -p ${${node}_REST_API_HOST_PORT}:${${node}_REST_API_PORT} --name ${node} ${AGENT_VPP_1_DOCKER_IMAGE} bash Write To Machine ${node} ${DOCKER_COMMAND} start ${node} @@ -169,10 +148,8 @@ Add VPP Agent ${node} Create Session ${node} http://${DOCKER_HOST_IP}:${${node}_REST_API_HOST_PORT} ${hostname}= Execute On Machine docker ${DOCKER_COMMAND} exec ${node} bash -c 'echo $HOSTNAME' Set Suite Variable ${${node}_HOSTNAME} ${hostname} - Log List ${NODES} Start VPP On Node ${node} - Log ${node} # Execute In Container ${node} vpp unix { cli-listen localhost:5002 } plugins { plugin dpdk_plugin.so { disable } } & Execute In Container ${node} vpp unix { nodaemon cli-listen 0.0.0.0:5002 cli-no-pager } plugins { plugin dpdk_plugin.so { disable } } & Open SSH Connection ${node}_term ${DOCKER_HOST_IP} ${DOCKER_HOST_USER} ${DOCKER_HOST_PSWD} diff --git a/tests/robot/suites/crud/acl_crud.robot b/tests/robot/suites/crud/acl_crud.robot index 2514431157..656eedf484 100644 --- a/tests/robot/suites/crud/acl_crud.robot +++ b/tests/robot/suites/crud/acl_crud.robot @@ -9,7 +9,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -49,7 +49,7 @@ ${2DEST_PORT_U}= 2200 ${2SRC_PORT_L}= 20010 ${2SRC_PORT_U}= 20020 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${NO_ACL}= @@ -166,22 +166,15 @@ Check All 6 ACLs Added Check ACL All Reply [Arguments] ${node} ${reply_json} ${reply_term} - Log Many ${node} ${reply_json} ${reply_term} ${acl_d}= vpp_ctl: Get All ACL As Json ${node} ${term_d}= vat_term: Check All ACL ${node} ${term_d_lines}= Split To Lines ${term_d} - Log ${term_d_lines} ${data}= OperatingSystem.Get File ${reply_json} - Log ${data} ${data}= Replace Variables ${data} - Log ${data} Should Be Equal ${data} ${acl_d} ${data}= OperatingSystem.Get File ${reply_term} - Log ${data} ${data}= Replace Variables ${data} - Log ${data} ${t_data_lines}= Split To Lines ${data} - Log ${t_data_lines} List Should Contain Sub List ${term_d_lines} ${t_data_lines} TestSetup diff --git a/tests/robot/suites/crud/afpacket_crud.robot b/tests/robot/suites/crud/afpacket_crud.robot index 5de4cb0179..276d98ae1d 100644 --- a/tests/robot/suites/crud/afpacket_crud.robot +++ b/tests/robot/suites/crud/afpacket_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -25,7 +25,7 @@ ${AFP1_MAC}= a2:01:01:01:01:01 ${AFP2_MAC}= a2:02:02:02:02:02 ${AFP2_SEC_MAC}= a2:22:22:22:22:22 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/crud/app_namespaces_crud.robot b/tests/robot/suites/crud/app_namespaces_crud.robot index c2640dd2fd..5745fda5e2 100644 --- a/tests/robot/suites/crud/app_namespaces_crud.robot +++ b/tests/robot/suites/crud/app_namespaces_crud.robot @@ -4,7 +4,7 @@ Library OperatingSystem Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown @@ -48,7 +48,7 @@ ${MTU}= 1500 ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 50s @@ -67,14 +67,12 @@ Enable L4 Features Check Default Namespace Was Added ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Should Contain ${out} default Put Interface TAP1 And Namespace NS1 Associated With TAP1 And Check The Namespace Is Present In Namespaces List vpp_ctl: Put TAP Interface With IP node=agent_vpp_1 name=${TAP1_NAME} mac=${TAP1_MAC} ip=${TAP1_IP} prefix=${PREFIX} host_if_name=linux_${TAP1_NAME} vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS1_ID} secret=${SECRET1} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} ${out_lines1}= Get Line Count ${out} Set Suite Variable ${out_lines1} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET1} ${TAP1_SW_IF_INDEX} @@ -82,7 +80,6 @@ Put Interface TAP1 And Namespace NS1 Associated With TAP1 And Check The Namespac Put Already Existing Namespace NS1 And Check Namespace Was Not Added To Namespaces List vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS1_ID} secret=${SECRET1} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} ${out_lines2}= Get Line Count ${out} Should Be Equal ${out_lines1} ${out_lines2} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET1} ${TAP1_SW_IF_INDEX} @@ -90,13 +87,11 @@ Put Already Existing Namespace NS1 And Check Namespace Was Not Added To Namespac Update Namespace NS1 Secret And Check The Namespace's Update Is Reflected In Namespaces List vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS1_ID} secret=${SECRET2} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET2} ${TAP1_SW_IF_INDEX} Put New NS2 Namespace And Check The Namespace Is Present In Namespaces List And Namespace NS1 Is Still Configured vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS2_ID} secret=${SECRET3} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS2_ID} 2 ${SECRET3} ${TAP1_SW_IF_INDEX} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET2} ${TAP1_SW_IF_INDEX} @@ -104,7 +99,6 @@ Put Interface TAP2 And Namespace NS3 Associated With TAP2 And Check The Namespac vpp_ctl: Put TAP Interface With IP node=agent_vpp_1 name=${TAP2_NAME} mac=${TAP2_MAC} ip=${TAP2_IP} prefix=${PREFIX} host_if_name=linux_${TAP2_NAME} vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS3_ID} secret=${SECRET4} interface=${TAP2_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS3_ID} 3 ${SECRET4} ${TAP2_SW_IF_INDEX} Check NS1 And NS2 Namespaces Remained Configured @@ -114,7 +108,6 @@ Check NS1 And NS2 Namespaces Remained Configured Update Namespace NS2 Associated Interface To TAP2 And Secret And Check The Namespace's Update Is Reflected In Namespaces List vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS2_ID} secret=${SECRET1} interface=${TAP2_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS2_ID} 2 ${SECRET1} ${TAP2_SW_IF_INDEX} Check NS1 And NS3 Namespaces Are Still Configured diff --git a/tests/robot/suites/crud/arp_crud.robot b/tests/robot/suites/crud/arp_crud.robot index d1d27dcc08..483ca30427 100644 --- a/tests/robot/suites/crud/arp_crud.robot +++ b/tests/robot/suites/crud/arp_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${VETH1_MAC}= 1a:00:00:11:11:11 ${VETH2_MAC}= 2a:00:00:22:22:22 ${AFP1_MAC}= a2:01:01:01:01:01 diff --git a/tests/robot/suites/crud/bd_crud.robot b/tests/robot/suites/crud/bd_crud.robot index 0937984b2e..ccfd9d2d03 100644 --- a/tests/robot/suites/crud/bd_crud.robot +++ b/tests/robot/suites/crud/bd_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,8 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s + *** Test Cases *** Configure Environment [Tags] setup @@ -28,14 +29,14 @@ Show Interfaces Before Setup vpp_term: Show Interfaces agent_vpp_1 Add Interfaces For BDs - vpp_ctl: Put Memif Interface With IP node=agent_vpp_1 name=vpp1_memif1 mac=62:61:61:61:61:61 master=true id=1 ip=192.168.1.1 + vpp_ctl: Put Memif Interface With IP node=agent_vpp_1 name=vpp1_memif1 mac=62:61:61:61:61:61 master=true id=1 ip=192.168.10.1 vpp_ctl: Put Veth Interface With IP node=agent_vpp_1 name=vpp1_veth1 mac=12:11:11:11:11:11 peer=vpp1_veth2 ip=10.10.1.1 vpp_ctl: Put Veth Interface node=agent_vpp_1 name=vpp1_veth2 mac=12:12:12:12:12:12 peer=vpp1_veth1 vpp_ctl: Put Afpacket Interface node=agent_vpp_1 name=vpp1_afpacket1 mac=a2:a1:a1:a1:a1:a1 host_int=vpp1_veth2 vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=192.168.1.1 dst=192.168.1.2 vni=5 vpp_ctl: Put Loopback Interface With IP node=agent_vpp_1 name=vpp1_loop1 mac=12:21:21:11:11:11 ip=20.20.1.1 vpp_ctl: Put TAP Interface With IP node=agent_vpp_1 name=vpp1_tap1 mac=32:21:21:11:11:11 ip=30.30.1.1 host_if_name=linux_vpp1_tap1 - vpp_ctl: Put Memif Interface With IP node=agent_vpp_1 name=vpp1_memif2 mac=62:61:61:61:61:62 master=true id=2 ip=192.168.1.2 + vpp_ctl: Put Memif Interface With IP node=agent_vpp_1 name=vpp1_memif2 mac=62:61:61:61:61:62 master=true id=2 ip=192.168.20.2 vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan2 src=192.168.2.1 dst=192.168.2.2 vni=15 vpp_ctl: Put Loopback Interface With IP node=agent_vpp_1 name=bvi_vpp1_loop2 mac=12:21:21:11:11:12 ip=20.20.2.1 vpp_ctl: Put Loopback Interface With IP node=agent_vpp_1 name=bvi_vpp1_loop3 mac=12:21:21:11:11:13 ip=20.20.3.1 diff --git a/tests/robot/suites/crud/inter_vrf_routing_crud.robot b/tests/robot/suites/crud/inter_vrf_routing_crud.robot index d83a6e0c98..8bfdca05a3 100644 --- a/tests/robot/suites/crud/inter_vrf_routing_crud.robot +++ b/tests/robot/suites/crud/inter_vrf_routing_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot Resource ../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags crud IPv4 Suite Setup Run Keywords Discard old results Test Setup Suite Teardown Test Teardown @@ -153,19 +153,13 @@ Final Sleep For Manual Checking *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} IP Fib Table ${table_id} On ${node} Should Contain Vrf ${inter_vrf_string} - Log many ${table_id} ${node} ${inter_vrf_string} ${out}= vpp_term: Show IP Fib Table ${node} ${table_id} - log many ${out} Should Contain ${out} ${inter_vrf_string} IP6 Fib Table ${table_id} On ${node} Should Contain Vrf ${inter_vrf_string} - Log many ${table_id} ${node} ${inter_vrf_string} ${out}= vpp_term: Show IP6 Fib Table ${node} ${table_id} - log many ${out} Should Contain ${out} ${inter_vrf_string} diff --git a/tests/robot/suites/crud/ip_route_crud.robot b/tests/robot/suites/crud/ip_route_crud.robot index 3007887251..720e5b21e9 100644 --- a/tests/robot/suites/crud/ip_route_crud.robot +++ b/tests/robot/suites/crud/ip_route_crud.robot @@ -8,14 +8,14 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot Resource ../../libraries/pretty_keywords.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Run Keywords Discard old results *** Variables *** ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** # CRUD tests for routing @@ -157,13 +157,9 @@ Add VRF Table In Background While Creating Interface VXLAN *** Keywords *** IP Fib On ${node} Should Not Contain Route With IP ${ip}/${prefix} - Log many ${node} ${out}= vpp_term: Show IP Fib ${node} - log many ${out} Should Not Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip4-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip4\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] IP Fib On ${node} Should Contain Route With IP ${ip}/${prefix} - Log many ${node} ${out}= vpp_term: Show IP Fib ${node} - log many ${out} Should Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip4-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip4\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] diff --git a/tests/robot/suites/crud/ipsec_crud.robot b/tests/robot/suites/crud/ipsec_crud.robot index a592ac4f92..80b9c03c80 100644 --- a/tests/robot/suites/crud/ipsec_crud.robot +++ b/tests/robot/suites/crud/ipsec_crud.robot @@ -1,5 +1,4 @@ *** Settings *** -Documentation IPsec CRUD Library OperatingSystem Library String @@ -13,7 +12,8 @@ Suite Teardown Testsuite Teardown *** Variables *** ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s + *** Test Cases *** # CRUD tests for IPsec Add Agent Vpp Node @@ -82,22 +82,16 @@ Delete SAs And SPD2 For Default IPsec *** Keywords *** IP Sec On ${node} Should Not Contain SA ${sa} - Log many ${node} ${out}= vpp_term: Show IPsec ${node} - log many ${out} Should Not Contain ${out} ${sa} IP Sec On ${node} Should Contain SA ${sa} - Log many ${node} ${out}= vpp_term: Show IPsec ${node} - log many ${out} Should Contain ${out} ${sa} IP Sec Should Contain [Arguments] ${node} ${sa_name_1} ${sa_name_2} ${spd_name_1} ${ipsec_esp} ${outbound_policies} - Log many ${node} ${out}= vpp_term: Show IPsec ${node} - log many ${out} Run Keyword Unless "${sa_name_1}" == "${EMPTY}" Should Contain ${out} ${sa_name_1} Run Keyword Unless "${sa_name_2}" == "${EMPTY}" Should Contain ${out} ${sa_name_2} Run Keyword Unless "${spd_name_1}" == "${EMPTY}" Should Contain ${out} ${spd_name_1} diff --git a/tests/robot/suites/crud/l2xconnect_crud.robot b/tests/robot/suites/crud/l2xconnect_crud.robot index b205904138..59d9e33ae1 100644 --- a/tests/robot/suites/crud/l2xconnect_crud.robot +++ b/tests/robot/suites/crud/l2xconnect_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -24,7 +24,7 @@ ${VETH1_MAC}= 1a:00:00:11:11:11 ${VETH2_MAC}= 2a:00:00:22:22:22 ${AFP1_MAC}= a2:01:01:01:01:01 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/crud/linux_arp_crud.robot b/tests/robot/suites/crud/linux_arp_crud.robot index a1cd9efa15..d83c4161d6 100644 --- a/tests/robot/suites/crud/linux_arp_crud.robot +++ b/tests/robot/suites/crud/linux_arp_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -24,7 +24,7 @@ ${AFP1_MAC}= a2:01:01:01:01:01 ${NAMESPACE}= ${NSTYPE}= 3 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment @@ -62,44 +62,46 @@ Check AFpacket Interface Created Add ARPs vpp_ctl: Put Linux ARP agent_vpp_1 vpp1_veth1 veth1_arp 155.155.155.155 32:51:51:51:51:51 vpp_ctl: Put Linux ARP agent_vpp_1 vpp1_veth2 veth2_arp 155.155.155.156 32:51:51:51:51:52 - vpp_ctl: Put Linux ARP agent_vpp_1 lo loopback_arp 155.155.155.156 32:51:51:51:51:52 + vpp_ctl: Put Linux ARP agent_vpp_1 lo loopback_arp 155.155.155.156 32:51:51:51:51:52 #some change in Ubuntu, 'lo' have always ip: 0.0.0.0, test isn't affected #vpp_ctl: Put Linux ARP agent_vpp_1 eth0 eth_arp 155.155.155.156 32:51:51:51:51:52 Check ARPSs ${out}= Execute In Container agent_vpp_1 ip neigh - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.155.155.156 dev vpp1_veth2 lladdr 32:51:51:51:51:52 PERMANENT Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.155.155.155 dev vpp1_veth1 lladdr 32:51:51:51:51:51 PERMANENT #Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.155.155.156 dev eth0 lladdr 32:51:51:51:51:52 PERMANENT - Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.155.155.156 dev lo lladdr 32:51:51:51:51:52 PERMANENT + #some change in Ubuntu, 'lo' have always ip: 0.0.0.0, test isn't affected + #Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.155.155.156 dev lo lladdr 32:51:51:51:51:52 PERMANENT + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain Any ${out} 0.0.0.0 dev lo lladdr 32:51:51:51:51:52 PERMANENT 155.155.155.156 dev lo lladdr 32:51:51:51:51:52 PERMANENT Change ARPs vpp_ctl: Put Linux ARP agent_vpp_1 vpp1_veth1 veth1_arp 155.255.155.155 32:61:51:51:51:51 vpp_ctl: Put Linux ARP agent_vpp_1 vpp1_veth2 veth2_arp 155.255.155.156 32:61:51:51:51:52 - vpp_ctl: Put Linux ARP agent_vpp_1 lo loopback_arp 155.255.155.156 32:61:51:51:51:52 + vpp_ctl: Put Linux ARP agent_vpp_1 lo loopback_arp 155.255.155.156 32:61:51:51:51:52 #some change in Ubuntu, 'lo' have always ip: 0.0.0.0, test isn't affected #vpp_ctl: Put Linux ARP agent_vpp_1 eth0 eth_arp 155.255.155.156 32:61:51:51:51:52 Check ARPSs Again ${out}= Execute In Container agent_vpp_1 ip neigh - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.255.155.156 dev vpp1_veth2 lladdr 32:61:51:51:51:52 PERMANENT Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.255.155.155 dev vpp1_veth1 lladdr 32:61:51:51:51:51 PERMANENT #Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.255.155.156 dev eth0 lladdr 32:61:51:51:51:52 PERMANENT - Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.255.155.156 dev lo lladdr 32:61:51:51:51:52 PERMANENT + #some change in Ubuntu, 'lo' have always ip: 0.0.0.0, test isn't affected + #Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} 155.255.155.156 dev lo lladdr 32:61:51:51:51:52 PERMANENT + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain Any ${out} 0.0.0.0 dev lo lladdr 32:61:51:51:51:52 PERMANENT 155.255.155.156 dev lo lladdr 32:61:51:51:51:52 PERMANENT Delete ARPs vpp_ctl: Delete Linux ARP agent_vpp_1 veth1_arp vpp_ctl: Delete Linux ARP agent_vpp_1 veth2_arp - vpp_ctl: Delete Linux ARP agent_vpp_1 loopback_arp + vpp_ctl: Delete Linux ARP agent_vpp_1 loopback_arp #some change in Ubuntu, 'lo' can't be deleted, test isn't affected #vpp_ctl: Delete Linux ARP agent_vpp_1 eth_arp Check ARPSs After Delete ${out}= Execute In Container agent_vpp_1 ip neigh - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Not Contain ${out} 155.255.155.156 dev vpp1_veth2 lladdr 32:61:51:51:51:52 PERMANENT Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Not Contain ${out} 155.255.155.155 dev vpp1_veth1 lladdr 32:61:51:51:51:51 PERMANENT #Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Not Contain ${out} 155.255.155.156 dev eth0 lladdr 32:61:51:51:51:52 PERMANENT - Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Not Contain ${out} 155.255.155.156 dev lo lladdr 32:61:51:51:51:52 PERMANENT + #some change in Ubuntu, 'lo' can't be deleted, test isn't affected + #Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Not Contain ${out} 0.0.0.0 dev lo lladdr 32:61:51:51:51:52 PERMANENT *** Keywords *** diff --git a/tests/robot/suites/crud/linux_ip_route_crud.robot b/tests/robot/suites/crud/linux_ip_route_crud.robot index 6ea413cec0..5f57557ad5 100644 --- a/tests/robot/suites/crud/linux_ip_route_crud.robot +++ b/tests/robot/suites/crud/linux_ip_route_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s # wait for resync vpps after restart ${RESYNC_WAIT}= 30s @@ -150,16 +150,13 @@ Start VPP1 Again Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip netns exec ns1 ip a - Log ${out} Should Contain ${out} ns1_veth1_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns2 ip a - Log ${out} Should Contain ${out} ns2_veth2_linux Should Contain ${out} ns2_veth3_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns3 ip a - Log ${out} Should Contain ${out} ns3_veth3_linux Check linux Routes On VPP1 After Resync @@ -176,43 +173,32 @@ Check linux Routes On VPP1 After Resync *** Keywords *** Check Linux Interfaces [Arguments] ${node} ${namespace} ${interface} - Log Many ${node} ${namespace} ${interface} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip a - Log ${out} Should Contain ${out} ${interface} Check Linux Routes [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via Check Linux Routes Gateway [Arguments] ${node} ${namespace} ${ip} ${next_hop}=${EMPTY} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via ${next_hop} Check Linux Routes Metric [Arguments] ${node} ${namespace} ${ip} ${metric} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Match Regexp ${out} ${ip} via.*metric ${metric}\\s Check Removed Linux Route [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Not Contain ${out} ${ip} via Ping in namespace [Arguments] ${node} ${namespace} ${ip} ${out}= Execute In Container ${node} ip netns exec ${namespace} ping -c 5 ${ip} - Log ${out} Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss diff --git a/tests/robot/suites/crud/loopback_crud.robot b/tests/robot/suites/crud/loopback_crud.robot index b6a7c45d60..13075743fd 100644 --- a/tests/robot/suites/crud/loopback_crud.robot +++ b/tests/robot/suites/crud/loopback_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -28,7 +28,7 @@ ${IP_LOOP2}= 20.20.2.2 ${PREFIX}= 24 ${MTU}= 4800 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/crud/memif_crud.robot b/tests/robot/suites/crud/memif_crud.robot index b0c3ed33ba..e841d662ca 100644 --- a/tests/robot/suites/crud/memif_crud.robot +++ b/tests/robot/suites/crud/memif_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -24,7 +24,7 @@ ${MEMIF21_SEC_MAC}= 2a:00:00:22:22:23 ${MEMIF12_MAC}= 3a:00:00:33:33:33 ${MEMIF22_MAC}= 4a:00:00:44:44:44 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment @@ -95,7 +95,7 @@ Update VPP2_memif1 Interface Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Memif Interface State agent_vpp_2 vpp2_memif1 mac=${MEMIF21_SEC_MAC} role=slave id=1 ipv4=192.168.10.2/24 connected=1 enabled=1 socket=${AGENT_VPP_2_MEMIF_SOCKET_FOLDER}/default.sock Check That VPP1_memif1 Is Still Configured And Connected - vat_term: Check Memif Interface State agent_vpp_1 vpp1_memif1 mac=${MEMIF11_SEC_MAC} role=master id=1 ipv4=192.168.10.1/30 connected=1 enabled=1 socket=${AGENT_VPP_1_MEMIF_SOCKET_FOLDER}/default.sock + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Memif Interface State agent_vpp_1 vpp1_memif1 mac=${MEMIF11_SEC_MAC} role=master id=1 ipv4=192.168.10.1/30 connected=1 enabled=1 socket=${AGENT_VPP_1_MEMIF_SOCKET_FOLDER}/default.sock Check That VPP1_memif2 And VPP2_memif2 Are Not Affected By VPP2_memif1 Update Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Memif Interface State agent_vpp_2 vpp2_memif2 mac=${MEMIF22_MAC} role=slave id=2 ipv4=192.168.2.2/28 connected=1 enabled=1 socket=${AGENT_VPP_2_MEMIF_SOCKET_FOLDER}/default.sock diff --git a/tests/robot/suites/crud/physical_crud.robot b/tests/robot/suites/crud/physical_crud.robot index 43efd04211..dd47c3f26d 100644 --- a/tests/robot/suites/crud/physical_crud.robot +++ b/tests/robot/suites/crud/physical_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/crud/srv6_crud.robot b/tests/robot/suites/crud/srv6_crud.robot index 263e7dca2a..6e1648251d 100644 --- a/tests/robot/suites/crud/srv6_crud.robot +++ b/tests/robot/suites/crud/srv6_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 30s @{segmentList1} B:: C:: D:: @@ -96,7 +96,7 @@ Check Resynchronization for clean VPP start Remove All VPP Nodes Sleep 3s Add Agent VPP Node agent_vpp_1 - + Sleep 8s Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Local SID Presence node=agent_vpp_1 sidAddress=A:: interface=host-vpp1_veth2 nexthop=A::1 Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check SRv6 Policy Presence node=agent_vpp_1 bsid=A::E fibtable=0 behaviour=Encapsulation type=Spray index=0 segmentlists=${segmentLists1} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check SRv6 Steering Presence node=agent_vpp_1 bsid=A::E prefixAddress=E::/64 diff --git a/tests/robot/suites/crud/stn_rule_crud.robot b/tests/robot/suites/crud/stn_rule_crud.robot index 3a6ab7daad..1a2c5fb3ca 100644 --- a/tests/robot/suites/crud/stn_rule_crud.robot +++ b/tests/robot/suites/crud/stn_rule_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -16,7 +16,7 @@ Test Teardown TestTeardown *** Variables *** ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 15s ${VARIABLES}= common ${ENV}= common @@ -46,7 +46,6 @@ Add TAP1 Interface Check TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAP interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv4=${IP_TAP1}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crud/tap_crud.robot b/tests/robot/suites/crud/tap_crud.robot index 8fb6a0662c..37285cd36d 100644 --- a/tests/robot/suites/crud/tap_crud.robot +++ b/tests/robot/suites/crud/tap_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -29,7 +29,7 @@ ${PREFIX}= 24 ${MTU}= 4800 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment @@ -45,7 +45,6 @@ Add TAP1 Interface Check TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAP interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv4=${IP_TAP1}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crud/tap_unnumbered_crud.robot b/tests/robot/suites/crud/tap_unnumbered_crud.robot index 066b4fadf0..98287eddb9 100644 --- a/tests/robot/suites/crud/tap_unnumbered_crud.robot +++ b/tests/robot/suites/crud/tap_unnumbered_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -32,7 +32,7 @@ ${PREFIX}= 24 ${MTU}= 4800 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment @@ -48,7 +48,6 @@ Add TAP1 Interface Check TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAP interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv4=${IP_TAP1}/${PREFIX} state=${UP_STATE} @@ -79,7 +78,6 @@ Add TAP3 Interface Check TAP3 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP3} ${actual_state}= vpp_term: Check TAP interface State agent_vpp_1 ${NAME_TAP3} mac=${MAC_TAP3} ipv4=${IP_TAP3}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crud/tapv2_crud.robot b/tests/robot/suites/crud/tapv2_crud.robot index 268f7f9335..13f36a1ee8 100644 --- a/tests/robot/suites/crud/tapv2_crud.robot +++ b/tests/robot/suites/crud/tapv2_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -29,7 +29,7 @@ ${PREFIX}= 24 ${MTU}= 4800 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup @@ -44,7 +44,6 @@ Add TAP1v2 Interface Check TAP1v2 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAPv2 interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv4=${IP_TAP1}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crud/test_data/acl_basic.conf b/tests/robot/suites/crud/test_data/acl_basic.conf index 48a5080868..3e5c9b5e16 100644 --- a/tests/robot/suites/crud/test_data/acl_basic.conf +++ b/tests/robot/suites/crud/test_data/acl_basic.conf @@ -1,27 +1,48 @@ -sfc_controller_config_version: 1 -description: Basic Example static config for hosting 2 containers with a -vnf-agent and 1 container with agent and vpp +sfc_controller_config_version: 2 +description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_1 + node: agent_vpp_1 + - pod: agent_2 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_1 - port_label: agent1_afpacket1 - ipv4_addr: 10.0.0.10 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: agent_2 - port_label: agent2_afpacket1 - ipv4_addr: 10.0.0.11 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 + +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_1 + spec: + pod_type: vppcontainer + interfaces: + - name: agent1_afpacket1 + if_type: veth + ip_addresses: + - 10.0.0.10/24 + - metadata: + name: agent_2 + spec: + pod_type: vppcontainer + interfaces: + - name: agent2_afpacket1 + if_type: veth + ip_addresses: + - 10.0.0.11/24 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_1/agent1_afpacket1 + - agent_2/agent2_afpacket1 diff --git a/tests/robot/suites/crud/veth_crud.robot b/tests/robot/suites/crud/veth_crud.robot index b746805d86..020c5e405b 100644 --- a/tests/robot/suites/crud/veth_crud.robot +++ b/tests/robot/suites/crud/veth_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -23,7 +23,7 @@ ${VETH2_MAC}= 2a:00:00:22:22:22 ${VETH3_MAC}= 3a:00:00:33:33:33 ${VETH4_MAC}= 4a:00:00:44:44:44 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup diff --git a/tests/robot/suites/crud/vxlan_crud.robot b/tests/robot/suites/crud/vxlan_crud.robot index 6ca1d9e41b..dd1561bd1a 100644 --- a/tests/robot/suites/crud/vxlan_crud.robot +++ b/tests/robot/suites/crud/vxlan_crud.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -19,12 +19,14 @@ ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup Configure Environment 1 + Sleep 10s + Show Interfaces Before Setup vpp_term: Show Interfaces agent_vpp_1 diff --git a/tests/robot/suites/crudIPv6/acl_crudIPv6.robot b/tests/robot/suites/crudIPv6/acl_crudIPv6.robot index d5070148c7..435bf41171 100644 --- a/tests/robot/suites/crudIPv6/acl_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/acl_crudIPv6.robot @@ -9,7 +9,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -49,7 +49,7 @@ ${2DEST_PORT_U}= 2200 ${2SRC_PORT_L}= 20010 ${2SRC_PORT_U}= 20020 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${NO_ACL}= @@ -162,22 +162,15 @@ Check All 6 ACLs Added Check ACL All Reply [Arguments] ${node} ${reply_json} ${reply_term} - Log Many ${node} ${reply_json} ${reply_term} ${acl_d}= vpp_ctl: Get All ACL As Json ${node} ${term_d}= vat_term: Check All ACL ${node} ${term_d_lines}= Split To Lines ${term_d} - Log ${term_d_lines} ${data}= OperatingSystem.Get File ${reply_json} - Log ${data} ${data}= Replace Variables ${data} - Log ${data} Should Be Equal ${data} ${acl_d} ${data}= OperatingSystem.Get File ${reply_term} - Log ${data} ${data}= Replace Variables ${data} - Log ${data} ${t_data_lines}= Split To Lines ${data} - Log ${t_data_lines} List Should Contain Sub List ${term_d_lines} ${t_data_lines} diff --git a/tests/robot/suites/crudIPv6/afpacket_crudIPv6.robot b/tests/robot/suites/crudIPv6/afpacket_crudIPv6.robot index 66dc78500e..756d4aaeff 100644 --- a/tests/robot/suites/crudIPv6/afpacket_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/afpacket_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -29,7 +29,7 @@ ${IP_ADR_MASK}= fd30:0:0:1:e::/64 ${IP_ADR2}= fd30:0:0:2:f:: ${IP_ADR_MASK2}= fd30:0:0:2:f::/64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/crudIPv6/app_namespaces_crudIPv6.robot b/tests/robot/suites/crudIPv6/app_namespaces_crudIPv6.robot index 7ced67b411..2dea8d4034 100644 --- a/tests/robot/suites/crudIPv6/app_namespaces_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/app_namespaces_crudIPv6.robot @@ -4,7 +4,7 @@ Library OperatingSystem Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown @@ -48,7 +48,7 @@ ${MTU}= 1500 ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 50s @@ -67,14 +67,12 @@ Enable L4 Features Check Default Namespace Was Added ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Should Contain ${out} default Put Interface TAP1 And Namespace NS1 Associated With TAP1 And Check The Namespace Is Present In Namespaces List vpp_ctl: Put TAP Interface With IP node=agent_vpp_1 name=${TAP1_NAME} mac=${TAP1_MAC} ip=${TAP1_IP} prefix=${PREFIX} host_if_name=linux_${TAP1_NAME} vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS1_ID} secret=${SECRET1} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} ${out_lines1}= Get Line Count ${out} Set Suite Variable ${out_lines1} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET1} ${TAP1_SW_IF_INDEX} @@ -82,7 +80,6 @@ Put Interface TAP1 And Namespace NS1 Associated With TAP1 And Check The Namespac Put Already Existing Namespace NS1 And Check Namespace Was Not Added To Namespaces List vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS1_ID} secret=${SECRET1} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} ${out_lines2}= Get Line Count ${out} Should Be Equal ${out_lines1} ${out_lines2} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET1} ${TAP1_SW_IF_INDEX} @@ -90,13 +87,11 @@ Put Already Existing Namespace NS1 And Check Namespace Was Not Added To Namespac Update Namespace NS1 Secret And Check The Namespace's Update Is Reflected In Namespaces List vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS1_ID} secret=${SECRET2} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET2} ${TAP1_SW_IF_INDEX} Put New NS2 Namespace And Check The Namespace Is Present In Namespaces List And Namespace NS1 Is Still Configured vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS2_ID} secret=${SECRET3} interface=${TAP1_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS2_ID} 2 ${SECRET3} ${TAP1_SW_IF_INDEX} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS1_ID} 1 ${SECRET2} ${TAP1_SW_IF_INDEX} @@ -104,7 +99,6 @@ Put Interface TAP2 And Namespace NS3 Associated With TAP2 And Check The Namespac vpp_ctl: Put TAP Interface With IP node=agent_vpp_1 name=${TAP2_NAME} mac=${TAP2_MAC} ip=${TAP2_IP} prefix=${PREFIX} host_if_name=linux_${TAP2_NAME} vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS3_ID} secret=${SECRET4} interface=${TAP2_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS3_ID} 3 ${SECRET4} ${TAP2_SW_IF_INDEX} Check NS1 And NS2 Namespaces Remained Configured @@ -114,7 +108,6 @@ Check NS1 And NS2 Namespaces Remained Configured Update Namespace NS2 Associated Interface To TAP2 And Secret And Check The Namespace's Update Is Reflected In Namespaces List vpp_ctl: Put Application Namespace node=agent_vpp_1 id=${NS2_ID} secret=${SECRET1} interface=${TAP2_NAME} ${out}= vpp_term: Show Application Namespaces node=agent_vpp_1 - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check Data In Show Application Namespaces Output agent_vpp_1 ${NS2_ID} 2 ${SECRET1} ${TAP2_SW_IF_INDEX} Check NS1 And NS3 Namespaces Are Still Configured diff --git a/tests/robot/suites/crudIPv6/arp_crudIPv6.robot b/tests/robot/suites/crudIPv6/arp_crudIPv6.robot index 9ddbeb46b2..ac67f72700 100644 --- a/tests/robot/suites/crudIPv6/arp_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/arp_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${VETH1_MAC}= 1a:00:00:11:11:11 ${VETH2_MAC}= 2a:00:00:22:22:22 ${AFP1_MAC}= a2:01:01:01:01:01 diff --git a/tests/robot/suites/crudIPv6/bd_crudIPv6.robot b/tests/robot/suites/crudIPv6/bd_crudIPv6.robot index c74f70220a..61984cb79e 100644 --- a/tests/robot/suites/crudIPv6/bd_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/bd_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -30,7 +30,7 @@ ${LOOPBACK_IP_PREFIX}= fd32::1:1:0:0:1/64 ${TAP_IP}= fd33::1:1:0:0:1 ${TAP_IP_PREFIX}= fd33::1:1:0:0:1/64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/crudIPv6/inter_vrf_routing_crud_ipv6.robot b/tests/robot/suites/crudIPv6/inter_vrf_routing_crud_ipv6.robot index 03a6c50279..3f5086dc6c 100644 --- a/tests/robot/suites/crudIPv6/inter_vrf_routing_crud_ipv6.robot +++ b/tests/robot/suites/crudIPv6/inter_vrf_routing_crud_ipv6.robot @@ -153,19 +153,13 @@ Final Sleep For Manual Checking *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} IP Fib Table ${table_id} On ${node} Should Contain Vrf ${inter_vrf_string} - Log many ${table_id} ${node} ${inter_vrf_string} ${out}= vpp_term: Show IP Fib Table ${node} ${table_id} - log many ${out} Should Contain ${out} ${inter_vrf_string} IP6 Fib Table ${table_id} On ${node} Should Contain Vrf ${inter_vrf_string} - Log many ${table_id} ${node} ${inter_vrf_string} ${out}= vpp_term: Show IP6 Fib Table ${node} ${table_id} - log many ${out} Should Contain ${out} ${inter_vrf_string} diff --git a/tests/robot/suites/crudIPv6/ip_route_crudIPv6.robot b/tests/robot/suites/crudIPv6/ip_route_crudIPv6.robot index 770a19f6e5..0ad94ef045 100644 --- a/tests/robot/suites/crudIPv6/ip_route_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/ip_route_crudIPv6.robot @@ -8,12 +8,18 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot Resource ../../libraries/pretty_keywords.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Run Keywords Discard old results *** Variables *** ${VARIABLES}= common ${ENV}= common +${IP1}= fd31::1:1:0:0:1 +${IP2}= fd31::1:1:0:0:2 +${IPNET1}= fd30:0:0:1:: +${IPNET2}= fd31:0:0:1:: +${WAIT_TIMEOUT}= 20s +${SYNC_SLEEP}= 2s *** Test Cases *** # CRUD tests for routing @@ -22,32 +28,32 @@ Add Route, Then Delete Route And Again Add Route For Default VRF [Teardown] Test Teardown Given Add Agent VPP Node agent_vpp_1 - Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP fd30:0:0:1::/64 - Then Create Route On agent_vpp_1 With IP fd30:0:0:1::/64 With Next Hop fd31:0:0:1:1::1 And Vrf Id 0 + Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP ${IPNET1}/64 + Then Create Route On agent_vpp_1 With IP ${IPNET1}/64 With Next Hop ${IP1} And Vrf Id 0 Then Show Interfaces On agent_vpp_1 - Then IP6 Fib On agent_vpp_1 Should Contain Route With IP fd30:0:0:1::/64 + Then IP6 Fib On agent_vpp_1 Should Contain Route With IP ${IPNET1}/64 Then Delete Routes On agent_vpp_1 And Vrf Id 0 - Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP fd30:0:0:1::/64 - Then Create Route On agent_vpp_1 With IP fd30:0:0:1::/64 With Next Hop fd31:0:0:1:1::1 And Vrf Id 0 + Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP ${IPNET1}/64 + Then Create Route On agent_vpp_1 With IP ${IPNET1}/64 With Next Hop ${IP1} And Vrf Id 0 Add Route, Then Delete Route And Again Add Route For Non Default VRF [Setup] Test Setup [Teardown] Test Teardown Given Add Agent VPP Node agent_vpp_1 - Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1::/64 - Then Create Route On agent_vpp_1 With IP fd30:0:0:1::/64 With Next Hop fd31:0:0:1:1::1 And Vrf Id 2 + Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP ${IPNET2}/64 + Then Create Route On agent_vpp_1 With IP ${IPNET1}/64 With Next Hop ${IP1} And Vrf Id 2 Then Show Interfaces On agent_vpp_1 - Then IP6 Fib On agent_vpp_1 Should Contain Route With IP fd30:0:0:1::/64 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd30:0:0:1::/64 - Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd30:0:0:1::/64 + Then IP6 Fib On agent_vpp_1 Should Contain Route With IP ${IPNET1}/64 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IPNET1}/64 + Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IPNET1}/64 Then Delete Routes On agent_vpp_1 And Vrf Id 2 - Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP fd30:0:0:1::/64 - Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP fd30:0:0:1::/64 - Then Create Route On agent_vpp_1 With IP fd30:0:0:1::/64 With Next Hop fd31:0:0:1:1::1 And Vrf Id 2 - Then IP6 Fib On agent_vpp_1 Should Contain Route With IP fd30:0:0:1::/64 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd30:0:0:1::/64 - Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd30:0:0:1::/64 + Then IP6 Fib On agent_vpp_1 Should Not Contain Route With IP ${IPNET1}/64 + Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP ${IPNET1}/64 + Then Create Route On agent_vpp_1 With IP ${IPNET1}/64 With Next Hop ${IP1} And Vrf Id 2 + Then IP6 Fib On agent_vpp_1 Should Contain Route With IP ${IPNET1}/64 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IPNET1}/64 + Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IPNET1}/64 # CRUD tests for VRF - automatically added with creating of interface - delete is not implemented Add VRF Table In Background While Creating Interface Memif @@ -56,33 +62,33 @@ Add VRF Table In Background While Creating Interface Memif Given Add Agent VPP Node agent_vpp_1 # create memif interface in default vrf - Then Create Master memif0 on agent_vpp_1 with IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket + Then Create Master memif0 on agent_vpp_1 with IP ${IP1}, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket Then Show Interfaces On agent_vpp_1 Then IP6 Fib Table 2 On agent_vpp_1 Should Be Empty - Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 # this will transfer interface to newly-in-background-created non default vrf table - Then Create Master memif0 on agent_vpp_1 with VRF 2, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket - Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then Create Master memif0 on agent_vpp_1 with VRF 2, IP ${IP1}, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket + Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will transfer interface to other newly-in-background-created non default vrf table - Then Create Master memif0 on agent_vpp_1 with VRF 1, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket - Then IP6 Fib Table 1 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then Create Master memif0 on agent_vpp_1 with VRF 1, IP ${IP1}, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket + Then IP6 Fib Table 1 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will remove non default vrf table in background - N/A # Then IP6 Fib Table 2 On agent_vpp_1 Should Be Empty - N/A - Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will transfer interface to existing non default vrf table - Then Create Master memif0 on agent_vpp_1 with VRF 2, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket - Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then Create Master memif0 on agent_vpp_1 with VRF 2, IP ${IP1}, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket + Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will transfer interface to default vrf table - Then Create Master memif0 on agent_vpp_1 with IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket + Then Create Master memif0 on agent_vpp_1 with IP ${IP1}, MAC 02:f1:be:90:00:00, key 1 and m0.sock socket # 10 nov 2017 this will fail for memif - reason is that Create Master memif0 does not transfer interface to the VRF table 0 - Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # 10 nov 2017 this will fail for memif - reason is that Create Master memif0 does not transfer interface to the VRF table 0 - Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 Add VRF Table In Background While Creating Interface Tap [Setup] Test Setup @@ -90,31 +96,31 @@ Add VRF Table In Background While Creating Interface Tap Given Add Agent VPP Node agent_vpp_1 # create Tap interface in default vrf - Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 0, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 + Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 0, IP ${IP1}, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 Then Show Interfaces On agent_vpp_1 Then IP6 Fib Table 2 On agent_vpp_1 Should Be Empty - Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 # this will transfer interface to newly-in-background-created non default vrf table - Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 2, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 - Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 2, IP ${IP1}, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 + Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will transfer interface to other newly-in-background-created non default vrf table - Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 1, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 - Then IP6 Fib Table 1 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 1, IP ${IP1}, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 + Then IP6 Fib Table 1 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will remove non default vrf table in background - N/A # Then IP6 Fib Table 2 On agent_vpp_1 Should Be Empty - N/A - Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will transfer interface to existing non default vrf table - Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 2, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 - Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 2, IP ${IP1}, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 + Then IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 0 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 # this will transfer interface to default vrf table - Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 0, IP fd31:0:0:1:1::1, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 - Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 - Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP fd31:0:0:1:1::1/128 + Then Create Tap Interface tap0 On agent_vpp_1 With Vrf 0, IP ${IP1}, MAC 02:f1:be:90:00:00 And HostIfName linux_tap0 + Then IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 1 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 + Then IP6 Fib Table 2 On agent_vpp_1 Should Not Contain Route With IP ${IP1}/128 Add VRF Table In Background While Creating Interface VXLAN [Setup] Test Setup @@ -123,45 +129,41 @@ Add VRF Table In Background While Creating Interface VXLAN Add Agent VPP Node agent_vpp_1 Sleep 10 # create VXLan interface in default vrf - vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=fd31:0:0:1:1::1 dst=fd31:0:0:1:1::2 vni=5 vrf=0 + vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=${IP1} dst=${IP2} vni=5 vrf=0 Write To Machine agent_vpp_1_term show vxlan tunnel Show IP6 Fib On agent_vpp_1 Show Interfaces Address On agent_vpp_1 - IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::2/128 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP ${IP2}/128 # this will transfer interface to newly-in-background-created non default vrf table - vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=fd31:0:0:1:1::1 dst=fd31:0:0:1:1::2 vni=5 vrf=2 + vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=${IP1} dst=${IP2} vni=5 vrf=2 Write To Machine agent_vpp_1_term show vxlan tunnel Show IP6 Fib On agent_vpp_1 Show Interfaces Address On agent_vpp_1 - IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::2/128 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IP2}/128 # this will transfer interface to other newly-in-background-created non default vrf table - vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=fd31:0:0:1:1::1 dst=fd31:0:0:1:1::2 vni=5 vrf=1 + vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=${IP1} dst=${IP2} vni=5 vrf=1 Write To Machine agent_vpp_1_term show vxlan tunnel Show IP6 Fib On agent_vpp_1 Show Interfaces Address On agent_vpp_1 - IP6 Fib Table 1 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::2/128 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} IP6 Fib Table 1 On agent_vpp_1 Should Contain Route With IP ${IP2}/128 # this will transfer interface to existing non default vrf table - vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=fd31:0:0:1:1::1 dst=fd31:0:0:1:1::2 vni=5 vrf=2 + vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=${IP1} dst=${IP2} vni=5 vrf=2 Write To Machine agent_vpp_1_term show vxlan tunnel Show IP6 Fib On agent_vpp_1 Show Interfaces Address On agent_vpp_1 - IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::2/128 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} IP6 Fib Table 2 On agent_vpp_1 Should Contain Route With IP ${IP2}/128 # this will transfer interface to default vrf table - vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=fd31:0:0:1:1::1 dst=fd31:0:0:1:1::2 vni=5 vrf=0 + vpp_ctl: Put VXLan Interface node=agent_vpp_1 name=vpp1_vxlan1 src=${IP1} dst=${IP2} vni=5 vrf=0 Write To Machine agent_vpp_1_term show vxlan tunnel Show IP6 Fib On agent_vpp_1 Show Interfaces Address On agent_vpp_1 - IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP fd31:0:0:1:1::2/128 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} IP6 Fib Table 0 On agent_vpp_1 Should Contain Route With IP ${IP2}/128 *** Keywords *** IP6 Fib On ${node} Should Not Contain Route With IP ${ip}/${prefix} - Log many ${node} ${out}= vpp_term: Show IP6 Fib ${node} - log many ${out} Should Not Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip6-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip6\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] IP6 Fib On ${node} Should Contain Route With IP ${ip}/${prefix} - Log many ${node} ${out}= vpp_term: Show IP6 Fib ${node} - log many ${out} Should Match Regexp ${out} ${ip}\\/${prefix}\\s*unicast\\-ip6-chain\\s*\\[\\@0\\]:\\ dpo-load-balance:\\ \\[proto:ip6\\ index:\\d+\\ buckets:\\d+\\ uRPF:\\d+\\ to:\\[0:0\\]\\] diff --git a/tests/robot/suites/crudIPv6/ipsec_crudIPv6.robot b/tests/robot/suites/crudIPv6/ipsec_crudIPv6.robot index 14724f9524..0564ad2395 100644 --- a/tests/robot/suites/crudIPv6/ipsec_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/ipsec_crudIPv6.robot @@ -85,22 +85,16 @@ Delete SAs And SPD2 For Default IPsec *** Keywords *** IP Sec On ${node} Should Not Contain SA ${sa} - Log many ${node} ${out}= vpp_term: Show IPsec ${node} - log many ${out} Should Not Contain ${out} ${sa} IP Sec On ${node} Should Contain SA ${sa} - Log many ${node} ${out}= vpp_term: Show IPsec ${node} - log many ${out} Should Contain ${out} ${sa} IP Sec Should Contain [Arguments] ${node} ${sa_name_1} ${sa_name_2} ${spd_name_1} ${ipsec_esp} ${outbound_policies} - Log many ${node} ${out}= vpp_term: Show IPsec ${node} - log many ${out} Run Keyword Unless "${sa_name_1}" == "${EMPTY}" Should Contain ${out} ${sa_name_1} Run Keyword Unless "${sa_name_2}" == "${EMPTY}" Should Contain ${out} ${sa_name_2} Run Keyword Unless "${spd_name_1}" == "${EMPTY}" Should Contain ${out} ${spd_name_1} diff --git a/tests/robot/suites/crudIPv6/l2xconnect_crudIPv6.robot b/tests/robot/suites/crudIPv6/l2xconnect_crudIPv6.robot index a6b327ee69..a7959eb5eb 100644 --- a/tests/robot/suites/crudIPv6/l2xconnect_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/l2xconnect_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 16s ${VETH1_MAC}= 1a:00:00:11:11:11 ${VETH2_MAC}= 2a:00:00:22:22:22 diff --git a/tests/robot/suites/crudIPv6/linux_arp_crudIPv6.robot b/tests/robot/suites/crudIPv6/linux_arp_crudIPv6.robot index d0dcea63d4..ba6d571168 100644 --- a/tests/robot/suites/crudIPv6/linux_arp_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/linux_arp_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${VETH1_MAC}= 1a:00:00:11:11:11 ${VETH2_MAC}= 2a:00:00:22:22:22 ${AFP1_MAC}= a2:01:01:01:01:01 @@ -72,7 +72,6 @@ Add ARPs Check ARPSs ${out}= Execute In Container agent_vpp_1 ip neigh - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} ${ARP_IP2} dev vpp1_veth2 lladdr 32:51:51:51:51:52 PERMANENT Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} ${ARP_IP1} dev vpp1_veth1 lladdr 32:51:51:51:51:51 PERMANENT #Should Contain ${out} ${ARP_IP2} dev eth0 lladdr 32:51:51:51:51:52 PERMANENT @@ -86,7 +85,6 @@ Change ARPs Check ARPSs Again ${out}= Execute In Container agent_vpp_1 ip neigh - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} ${ARP_IP4} dev vpp1_veth2 lladdr 32:61:51:51:51:52 PERMANENT Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Contain ${out} ${ARP_IP3} dev vpp1_veth1 lladdr 32:61:51:51:51:51 PERMANENT #Should Contain ${out} ${ARP_IP4} dev eth0 lladdr 32:61:51:51:51:52 PERMANENT @@ -100,7 +98,6 @@ Delete ARPs Check ARPSs After Delete ${out}= Execute In Container agent_vpp_1 ip neigh - Log ${out} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Not Contain ${out} ${ARP_IP4} dev vpp1_veth2 lladdr 32:61:51:51:51:52 PERMANENT Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Should Not Contain ${out} ${ARP_IP3} dev vpp1_veth1 lladdr 32:61:51:51:51:51 PERMANENT #Should Not Contain ${out} ${ARP_IP4} dev eth0 lladdr 32:61:51:51:51:52 PERMANENT diff --git a/tests/robot/suites/crudIPv6/linux_ip_route_crudIPv6.robot b/tests/robot/suites/crudIPv6/linux_ip_route_crudIPv6.robot index 4c9b82596b..69cdd3b408 100644 --- a/tests/robot/suites/crudIPv6/linux_ip_route_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/linux_ip_route_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 15s # wait for resync vpps after restart ${RESYNC_WAIT}= 30s @@ -159,16 +159,13 @@ Start VPP1 Again Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip netns exec ns1 ip a - Log ${out} Should Contain ${out} ns1_veth1_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns2 ip a - Log ${out} Should Contain ${out} ns2_veth2_linux Should Contain ${out} ns2_veth3_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns3 ip a - Log ${out} Should Contain ${out} ns3_veth3_linux Check linux Routes On VPP1 After Resync @@ -185,50 +182,38 @@ Check linux Routes On VPP1 After Resync *** Keywords *** Check Linux Interfaces [Arguments] ${node} ${namespace} ${interface} - Log Many ${node} ${namespace} ${interface} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip a - Log ${out} Should Contain ${out} ${interface} Check Linux Routes [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via Check Linux Routes Gateway [Arguments] ${node} ${namespace} ${ip} ${next_hop}=${EMPTY} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via ${next_hop} Check Linux Routes Metric [Arguments] ${node} ${namespace} ${ip} ${metric} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Match Regexp ${out} ${ip} via.*metric ${metric}\\s Check Removed Linux Route [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Not Contain ${out} ${ip} via Ping in namespace [Arguments] ${node} ${namespace} ${ip} ${out}= Execute In Container ${node} ip netns exec ${namespace} ping -c 5 ${ip} - Log ${out} Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss Ping6 in namespace [Arguments] ${node} ${namespace} ${ip} ${out}= Execute In Container ${node} ip netns exec ${namespace} ping6 -c 5 ${ip} - Log ${out} Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss diff --git a/tests/robot/suites/crudIPv6/loopback_crudIPv6.robot b/tests/robot/suites/crudIPv6/loopback_crudIPv6.robot index b834ea2f7f..eff80e1017 100644 --- a/tests/robot/suites/crudIPv6/loopback_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/loopback_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -28,7 +28,7 @@ ${IP_LOOP2}= fd31::1:e:0:0:1 ${PREFIX}= 64 ${MTU}= 4800 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/crudIPv6/memif_crudIPv6.robot b/tests/robot/suites/crudIPv6/memif_crudIPv6.robot index 51f535a431..198a01a050 100644 --- a/tests/robot/suites/crudIPv6/memif_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/memif_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -31,7 +31,7 @@ ${IP_5}= fd32::1:e:0:0:1 ${IP_6}= fd32::1:e:0:0:2 ${PREFIX}= 64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup diff --git a/tests/robot/suites/crudIPv6/physical_crudIPv6.robot b/tests/robot/suites/crudIPv6/physical_crudIPv6.robot index e183bb4281..8e47d9cdf7 100644 --- a/tests/robot/suites/crudIPv6/physical_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/physical_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -21,7 +21,7 @@ ${IP_1}= fd33::1:b:0:0:1 ${IP_2}= fd30::1:b:0:0:1 ${IP_3}= fd31::1:b:0:0:1 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup diff --git a/tests/robot/suites/crudIPv6/stn_rule_crudIPv6.robot b/tests/robot/suites/crudIPv6/stn_rule_crudIPv6.robot index 2eb22dc037..2bb6076ec0 100644 --- a/tests/robot/suites/crudIPv6/stn_rule_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/stn_rule_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -31,7 +31,7 @@ ${MTU}= 4800 ${UP_STATE}= up ${RULE_NAME} rule1 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment @@ -47,7 +47,6 @@ Add TAP1 Interface Check TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAP IP6 interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv6=${IP_TAP1}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crudIPv6/tap_crudIPv6.robot b/tests/robot/suites/crudIPv6/tap_crudIPv6.robot index 35f8f08d0c..720ebcb962 100644 --- a/tests/robot/suites/crudIPv6/tap_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/tap_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv4 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -29,7 +29,7 @@ ${PREFIX}= 64 ${MTU}= 4800 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment @@ -45,7 +45,6 @@ Add TAP1 Interface Check TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAP IP6 interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv6=${IP_TAP1}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crudIPv6/tap_unnumbered_crudIPv6.robot b/tests/robot/suites/crudIPv6/tap_unnumbered_crudIPv6.robot index bd8612e43d..dd78afe0dc 100644 --- a/tests/robot/suites/crudIPv6/tap_unnumbered_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/tap_unnumbered_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -32,7 +32,7 @@ ${PREFIX}= 64 ${MTU}= 4800 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup @@ -47,7 +47,6 @@ Add TAP1 Interface Check TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAP IP6 interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv6=${IP_TAP1}/${PREFIX} state=${UP_STATE} @@ -78,7 +77,6 @@ Add TAP3 Interface Check TAP3 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP3} ${actual_state}= vpp_term: Check TAP IP6 interface State agent_vpp_1 ${NAME_TAP3} mac=${MAC_TAP3} ipv6=${IP_TAP3}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crudIPv6/tapv2_crudIPv6.robot b/tests/robot/suites/crudIPv6/tapv2_crudIPv6.robot index b9d412cfab..7ad4aab586 100644 --- a/tests/robot/suites/crudIPv6/tapv2_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/tapv2_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -29,7 +29,7 @@ ${PREFIX}= 64 ${MTU}= 4800 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup @@ -44,7 +44,6 @@ Add TAP1v2 Interface Check TAP1v2 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_TAP1} ${actual_state}= vpp_term: Check TAPv2 IP6 interface State agent_vpp_1 ${NAME_TAP1} mac=${MAC_TAP1} ipv6=${IP_TAP1}/${PREFIX} state=${UP_STATE} diff --git a/tests/robot/suites/crudIPv6/test_data/acl_basic.conf b/tests/robot/suites/crudIPv6/test_data/acl_basic.conf index 48a5080868..3e5c9b5e16 100644 --- a/tests/robot/suites/crudIPv6/test_data/acl_basic.conf +++ b/tests/robot/suites/crudIPv6/test_data/acl_basic.conf @@ -1,27 +1,48 @@ -sfc_controller_config_version: 1 -description: Basic Example static config for hosting 2 containers with a -vnf-agent and 1 container with agent and vpp +sfc_controller_config_version: 2 +description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_1 + node: agent_vpp_1 + - pod: agent_2 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_1 - port_label: agent1_afpacket1 - ipv4_addr: 10.0.0.10 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: agent_2 - port_label: agent2_afpacket1 - ipv4_addr: 10.0.0.11 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 + +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_1 + spec: + pod_type: vppcontainer + interfaces: + - name: agent1_afpacket1 + if_type: veth + ip_addresses: + - 10.0.0.10/24 + - metadata: + name: agent_2 + spec: + pod_type: vppcontainer + interfaces: + - name: agent2_afpacket1 + if_type: veth + ip_addresses: + - 10.0.0.11/24 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_1/agent1_afpacket1 + - agent_2/agent2_afpacket1 diff --git a/tests/robot/suites/crudIPv6/veth_crudIPv6.robot b/tests/robot/suites/crudIPv6/veth_crudIPv6.robot index 54b84feb3a..332246d0d3 100644 --- a/tests/robot/suites/crudIPv6/veth_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/veth_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -25,6 +25,9 @@ ${VETH4_MAC}= 4a:00:00:44:44:44 ${VETHIP1}= fd33::1:b:0:0:1 ${VETHIP2}= fd31::1:b:0:0:1 ${VETHIP3}= fd33::1:b:0:0:2 +${WAIT_TIMEOUT}= 20s +${SYNC_SLEEP}= 2s + *** Test Cases *** Configure Environment [Tags] setup diff --git a/tests/robot/suites/crudIPv6/vxlan_crudIPv6.robot b/tests/robot/suites/crudIPv6/vxlan_crudIPv6.robot index d67f9eca44..2d747083c8 100644 --- a/tests/robot/suites/crudIPv6/vxlan_crudIPv6.robot +++ b/tests/robot/suites/crudIPv6/vxlan_crudIPv6.robot @@ -8,7 +8,7 @@ Resource ../../variables/${VARIABLES}_variables.robot Resource ../../libraries/all_libs.robot -Force Tags crudIPv6 +Force Tags crud IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -25,7 +25,7 @@ ${IP4}= fd31::1:b:0:0:2 ${IP10}= fd32::1:b:0:0:1 ${IP20}= fd32::1:b:0:0:2 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment [Tags] setup diff --git a/tests/robot/suites/integration/restarts/basic_restarts.robot b/tests/robot/suites/integration/restarts/basic_restarts.robot index c88a361e1c..cda50702ba 100644 --- a/tests/robot/suites/integration/restarts/basic_restarts.robot +++ b/tests/robot/suites/integration/restarts/basic_restarts.robot @@ -6,6 +6,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Library SSHLibrary +Force Tags integration Suite Setup Run Keywords ... KubeSetup.Kubernetes Suite Setup ${CLUSTER_ID} ... AND Restarts Suite Setup with ${1} VNFs at ${1} memifs each and ${1} non-VPP containers diff --git a/tests/robot/suites/integration/restarts/scale_restarts.robot b/tests/robot/suites/integration/restarts/scale_restarts.robot index 1be55bf142..3b1cf73162 100644 --- a/tests/robot/suites/integration/restarts/scale_restarts.robot +++ b/tests/robot/suites/integration/restarts/scale_restarts.robot @@ -6,6 +6,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Library SSHLibrary +Force Tags integration ExpectedFailure Suite Setup Run Keywords ... KubeSetup.Kubernetes Suite Setup ${CLUSTER_ID} ... AND Restarts Suite Setup with ${16} VNFs at ${6} memifs each and ${48} non-VPP containers diff --git a/tests/robot/suites/misc/errors_handling/errors_handling.robot b/tests/robot/suites/misc/errors_handling/errors_handling.robot index 3df45e1191..57ad9b8adc 100644 --- a/tests/robot/suites/misc/errors_handling/errors_handling.robot +++ b/tests/robot/suites/misc/errors_handling/errors_handling.robot @@ -8,6 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot +Force Tags misc ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -32,7 +33,6 @@ Interface Should Not Be Present vpp_term: Interface Not Exists node=agent_vpp_1 mac=${MAC_GOOD} ${int_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/vpp1_memif1 ${int_error_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/error/vpp1_memif1 - Log Many ${int_key} ${int_error_key} ${out}= vpp_ctl: Read Key ${int_key} Should Be Empty ${out} ${out}= vpp_ctl: Read Key ${int_error_key} @@ -42,7 +42,6 @@ Add Memif With Wrong MAC vpp_ctl: Put Memif Interface With IP node=agent_vpp_1 name=vpp1_memif1 mac=${MAC_BAD1} master=true id=1 ip=192.168.1.1 prefix=24 socket=default.sock vpp_term: Interface Not Exists node=agent_vpp_1 mac=${MAC_BAD1} ${int_error_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/error/vpp1_memif1 - Log Many ${int_error_key} ${out}= vpp_ctl: Read Key ${int_error_key} Should Contain ${out} error_data @@ -51,7 +50,6 @@ Correct MAC In Memif vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_GOOD} ${int_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/vpp1_memif1 ${int_error_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/error/vpp1_memif1 - Log Many ${int_key} ${int_error_key} ${out}= vpp_ctl: Read Key ${int_key} Should Not Be Empty ${out} ${out}= vpp_ctl: Read Key ${int_error_key} @@ -62,7 +60,6 @@ Set Wrong MAC To Memif Again vpp_term: Interface Is Deleted node=agent_vpp_1 mac=${MAC_GOOD} ${int_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/vpp1_memif1 ${int_error_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/error/vpp1_memif1 - Log Many ${int_key} ${int_error_key} ${out}= vpp_ctl: Read Key ${int_key} Should Contain ${out} vpp1_memif1 ${out}= vpp_ctl: Read Key ${int_error_key} @@ -75,7 +72,6 @@ Delete Memif Sleep 5s ${int_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/vpp1_memif1 ${int_error_key}= Set Variable /vnf-agent/agent_vpp_1/vpp/status/v1/interface/error/vpp1_memif1 - Log Many ${int_key} ${int_error_key} ${out}= vpp_ctl: Read Key ${int_key} Should Be Empty ${out} ${out}= vpp_ctl: Read Key ${int_error_key} diff --git a/tests/robot/suites/misc/etcd_clear.robot b/tests/robot/suites/misc/etcd_clear.robot index 1d18d349d8..f88ccd807d 100644 --- a/tests/robot/suites/misc/etcd_clear.robot +++ b/tests/robot/suites/misc/etcd_clear.robot @@ -8,6 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot +Force Tags misc ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -44,54 +45,40 @@ Setup Interfaces Check Linux Interfaces On VPP1 ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_tap1 - Log ${int} Should Contain ${out} ${int} Check Linux Interfaces On VPP2 ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_tap1 - Log ${int} Should Contain ${out} ${int} Check Bridge Domain On VPP1 Is Created @@ -142,53 +129,40 @@ Start VPP1 And VPP2 Again Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_tap1 - Log ${int} Should Contain ${out} ${int} Check Linux Interfaces On VPP2 After Resync ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_loop1 Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_tap1 - Log ${int} Should Contain ${out} ${int} Check Bridge Domain On VPP1 Is Created After Resync diff --git a/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/test_data/basic.conf b/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/test_data/basic.conf index 0865aea775..3e7680056c 100644 --- a/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/test_data/basic.conf +++ b/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/test_data/basic.conf @@ -1,27 +1,48 @@ -sfc_controller_config_version: 1 +sfc_controller_config_version: 2 description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_vpp_2 + node: agent_vpp_1 + - pod: agent_1 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_vpp_2 - port_label: vpp2_memif1 - mac_addr: 02:02:02:02:02:02 - ipv4_addr: 10.0.0.1 - etcd_vpp_switch_key: agent_vpp_1 - type: 2 - - container: agent_1 - port_label: agent1_afp1 - ipv4_addr: 10.0.0.10 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_vpp_2 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp2_memif1 + if_type: memif + mac_address: 02:02:02:02:02:02 + ip_addresses: + - 10.0.0.1/24 + - metadata: + name: agent_1 + spec: + pod_type: nonvppcontainer + interfaces: + - name: agent1_afp1 + if_type: veth + ip_addresses: + - 10.0.0.10/24 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_vpp_2/vpp2_memif1 + - agent_1/agent1_afp1 diff --git a/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novpp.robot b/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novpp.robot index 2dd7b81c4a..b55c6ca5b7 100644 --- a/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novpp.robot +++ b/tests/robot/suites/sfc/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novpp.robot @@ -8,7 +8,7 @@ Resource ../../../../variables/${VARIABLES}_variables.robot Resource ../../../../libraries/all_libs.robot -Force Tags sfcIPv4 +Force Tags sfc IPv4 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/test_data/basic.conf b/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/test_data/basic.conf index cbd6255d6f..97f94c6124 100644 --- a/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/test_data/basic.conf +++ b/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/test_data/basic.conf @@ -1,27 +1,48 @@ -sfc_controller_config_version: 1 +sfc_controller_config_version: 2 description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_vpp_2 + node: agent_vpp_1 + - pod: agent_vpp_3 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_vpp_2 - port_label: vpp2_memif1 - mac_addr: 02:02:02:02:02:02 - ipv4_addr: 10.0.0.1 - etcd_vpp_switch_key: agent_vpp_1 - type: 2 - - container: agent_vpp_3 - port_label: vpp3_memif1 - ipv4_addr: 10.0.0.10 - etcd_vpp_switch_key: agent_vpp_1 - type: 2 +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_vpp_2 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp2_memif1 + if_type: memif + mac_address: 02:02:02:02:02:02 + ip_addresses: + - 10.0.0.1/24 + - metadata: + name: agent_vpp_3 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp3_memif1 + if_type: memif + ip_addresses: + - 10.0.0.10/24 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_vpp_2/vpp2_memif1 + - agent_vpp_3/vpp3_memif1 diff --git a/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vpp.robot b/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vpp.robot index 4945c6452a..f8955207e6 100644 --- a/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vpp.robot +++ b/tests/robot/suites/sfc/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vpp.robot @@ -8,7 +8,7 @@ Resource ../../../../variables/${VARIABLES}_variables.robot Resource ../../../../libraries/all_libs.robot -Force Tags sfcIPv4 +Force Tags sfc IPv4 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment diff --git a/tests/robot/suites/sfc/test_controller_start/controller_start.robot b/tests/robot/suites/sfc/test_controller_start/controller_start.robot index b2e8cfee2f..d4b0fd2f37 100644 --- a/tests/robot/suites/sfc/test_controller_start/controller_start.robot +++ b/tests/robot/suites/sfc/test_controller_start/controller_start.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags sfcIPv4 +Force Tags sfc IPv4 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -30,7 +30,6 @@ Configure Environment Check Memif Interface On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 Should Contain ${out} ${int} ${out}= Write To Machine agent_vpp_1_term show h @@ -38,7 +37,6 @@ Check Memif Interface On VPP1 Check Memif Interface On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 Should Contain ${out} ${int} ${out}= Write To Machine agent_vpp_2_term show int addr diff --git a/tests/robot/suites/sfc/test_controller_start/test_data/sfc.conf b/tests/robot/suites/sfc/test_controller_start/test_data/sfc.conf deleted file mode 100644 index 928b566231..0000000000 --- a/tests/robot/suites/sfc/test_controller_start/test_data/sfc.conf +++ /dev/null @@ -1,97 +0,0 @@ -sfc_controller_config_version: 1 -description: Sample SFC Controller Configuration -external_entities: - - name: VRouter-1 - mgmnt_ip_address: 192.168.42.1 - basic_auth_user_name: cisco - basic_auth_passwd: cisco - eth_ipv4: 8.42.0.1 - eth_ipv4_mask: 255.255.255.0 - loopback_ipv4: 112.1.1.3 - loopback_ipv4_mask: 255.255.255.0 - - - name: RAS-1 - basic_auth_user_name: cisco - basic_auth_passwd: cisco - mgmnt_ip_address: 192.168.42.2 - eth_ipv4: 8.42.0.1 - eth_ipv4_mask: 255.255.255.0 - loopback_ipv4: 112.1.1.3 - loopback_ipv4_mask: 255.255.255.0 - -host_entities: - - name: CCMTS-HOST-1 - mgmnt_ip_address: 192.168.42.3 - eth_if_name: GigabitEthernet13/0/0 - eth_ipv4: 8.42.0.2 - eth_ipv4_mask: 255.255.255.0 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 - -sfc_entities: - - name: RAS-dp - description: RAS-dp memif - type: 1 - elements: - - container: RAS-1 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 1 - - container: dp - port_label: rpd - ipv4_addr: 166.111.8.2 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - - name: VRouter-dp - description: VRouter-dp memif - type: 1 - elements: - - container: VRouter-1 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 1 - - container: dp - port_label: wan - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - - name: ccmts-ew-rng-ussched-dp-tftp-dhcp - description: ccmts east west container memif's - type: 2 - elements: - - container: rng - port_label: rng - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: ussched - port_label: ussched - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: dp - port_label: macpi - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: tftp - port_label: tftp - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: dhcp - port_label: dhcp - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: dp - port_label: l3pi - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - - name: VRouter-dhcp - description: VRouter-dhcp memif - type: 1 - elements: - - container: VRouter-1 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 1 - - container: dhcp - port_label: cnr - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 diff --git a/tests/robot/suites/sfc/test_controller_start/test_data/simple.conf b/tests/robot/suites/sfc/test_controller_start/test_data/simple.conf index b78283935e..c603925349 100644 --- a/tests/robot/suites/sfc/test_controller_start/test_data/simple.conf +++ b/tests/robot/suites/sfc/test_controller_start/test_data/simple.conf @@ -1,30 +1,45 @@ -sfc_controller_config_version: 1 +sfc_controller_config_version: 2 description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: HOST-1 - mgmnt_ip_address: 192.168.0.1 - eth_if_name: GigabitEthernet13/0/0 - eth_ipv4: 8.42.0.2 - eth_ipv4_mask: 255.255.255.0 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_vpp_1 + node: HOST-1 + - pod: agent_vpp_2 + node: HOST-1 -sfc_entities: - - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_vpp_1 - port_label: vpp1_memif1 - mac_addr: 02:02:02:02:02:02 - etcd_vpp_switch_key: HOST-1 - type: 2 - - container: agent_vpp_2 - port_label: vpp2_memif1 - ipv4_addr: 10.0.0.10 - etcd_vpp_switch_key: HOST-1 - type: 2 +network_nodes: + - metadata: + name: HOST-1 + spec: + node_type: host + l2bds: + - name: east-west-bd +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_vpp_1 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp1_memif1 + if_type: memif + mac_address: 02:02:02:02:02:02 + - metadata: + name: agent_vpp_2 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp2_memif1 + if_type: memif + ip_addresses: + - 10.0.0.10/24 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_vpp_1/vpp1_memif1 + - agent_vpp_2/vpp2_memif1 diff --git a/tests/robot/suites/sfc/traffic/veth_af_packet_traffic/sfc_veth_af_packet_traffic.robot b/tests/robot/suites/sfc/traffic/veth_af_packet_traffic/sfc_veth_af_packet_traffic.robot new file mode 100644 index 0000000000..ed53c21373 --- /dev/null +++ b/tests/robot/suites/sfc/traffic/veth_af_packet_traffic/sfc_veth_af_packet_traffic.robot @@ -0,0 +1,412 @@ +*** Settings *** +Library OperatingSystem +#Library RequestsLibrary +#Library SSHLibrary timeout=60s +#Library String + +Resource ../../../../variables/${VARIABLES}_variables.robot + +Resource ../../../../libraries/all_libs.robot + +Force Tags traffic IPv4 ExpectedFailure +Suite Setup Testsuite Setup +Suite Teardown Suite Cleanup +Test Setup TestSetup +Test Teardown TestTeardown + +*** Variables *** +${VARIABLES}= common +${ENV}= common +${WAIT_TIMEOUT}= 20s +${SYNC_SLEEP}= 3s +${RESYNC_SLEEP}= 15s + +${AGENT1_VETH_MAC}= 02:00:00:00:00:01 +${AGENT2_VETH_MAC}= 02:00:00:00:00:02 +${AGENT3_VETH_MAC}= 02:00:00:00:00:03 + +${VARIABLES}= common +${ENV}= common + + +*** Test Cases *** +Configure Environment + [Tags] setup + ${DATA_FOLDER}= Catenate SEPARATOR=/ ${CURDIR} ${TEST_DATA_FOLDER} + Set Suite Variable ${DATA_FOLDER} + Configure Environment 4 veth_basic.conf + Sleep ${SYNC_SLEEP} + Show Interfaces And Other Objects + +Check Stuff At Beginning + Check Stuff + +Check Ping At Beginning + Check all Pings + +Remove VPP And Two Nodes + Remove Node agent_vpp_1 + Remove Node node_1 + Remove Node node_2 + Remove Node node_3 + Sleep ${SYNC_SLEEP} + +Start VPP And Two Nodes + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Add Agent Node node_1 + Add Agent Node node_2 + Add Agent Node node_3 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Resync + Check Stuff + +Check Ping After Resync + Check all Pings + +Remove VPP + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start VPP + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP Restart + Check Stuff + +Check Ping After VPP Restart + Check all Pings + +Remove Node1 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node1 + Add Agent Node node_1 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 Restart + Check Stuff + +Check Ping After Node1 Restart + Check all Pings + +Remove Node1 Again + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node1 Again + Add Agent Node node_1 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 Restart Again + Check Stuff + +Check Ping After Node1 Restart Again + Check all Pings + +Remove Node2 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node2 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node2 Restart + Check Stuff + +Check Ping After Node2 Restart + Check all Pings + +Remove Node2 Again + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node2 Again + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node2 Restart Again + Check Stuff + +Check Ping After Node2 Restart Again + Check all Pings + +Remove Node 1 and Node2 + Remove Node node_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 + Add Agent Node node_1 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart + Check Stuff + +Check Ping After Node1 and Node2 Restart + Check all Pings + +Remove Node 1 and Node2 Again + Remove Node node_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 Again + Add Agent Node node_1 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart Again + Check Stuff + +Check Ping Ater Node1 and Node2 Restart Again + Check all Pings + +Remove Node 1 and Node2 Again 2 + Remove Node node_2 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 Again 2 + Add Agent Node node_2 + Add Agent Node node_1 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart Again 2 + Check Stuff + +Check Ping After Node1 and Node2 Restart Again 2 + Check all Pings + +Remove Node 1 and Node2 Again 3 + Remove Node node_2 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 Again 3 + Add Agent Node node_1 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart Again 3 + Check Stuff + +Check Ping After Node1 and Node2 Restart Again 3 + Check all Pings + +Remove Node 1 and VPP + Remove Node node_1 + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start Node 1 and VPP + Add Agent Node node_1 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and VPP Restart + Check Stuff + +Check Ping After Node1 and VPP Restart + Check all Pings + +Remove VPP And Node1 + Remove Node agent_vpp_1 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start VPP And Node1 + Add Agent Node node_1 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node1 Restart + Check Stuff + +Check Ping After VPP And Node1 Restart + Check all Pings + +Remove VPP And Node1 Again + Remove Node agent_vpp_1 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start VPP And Node1 Again + Add Agent Node node_1 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node1 Restart Again + Check Stuff + +Check Ping After VPP And Node1 Restart Again + Check all Pings + +Remove Node 2 and VPP + Remove Node node_2 + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start Node 2 and VPP + Add Agent Node node_2 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node2 and VPP Restart + Check Stuff + +Check Ping After Node2 and VPP Restart + Check all Pings + +Remove VPP And Node2 + Remove Node agent_vpp_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start VPP And Node2 + Add Agent Node node_2 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node2 Restart + Check Stuff + +Check Ping After VPP And Node2 Restart + Check all Pings + +Remove VPP And Node2 Again + Remove Node agent_vpp_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start VPP And Node2 Again + Add Agent Node node_2 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node2 Restart Again + Check Stuff + +Check Ping After VPP And Node2 Restart Again + Check all Pings + +Remove All Nodes + Remove Node node_1 + Remove Node node_2 + Remove Node node_3 + Sleep ${SYNC_SLEEP} + +Start All Nodes + Add Agent Node node_1 + Add Agent Node node_2 + Add Agent Node node_3 + Sleep ${RESYNC_SLEEP} + +Check Stuff After All Nodes Restart + Check Stuff + +Check Ping After All Nodes Restart + Check all Pings + +Remove All Nodes Again + Remove Node node_1 + Remove Node node_2 + Remove Node node_3 + Sleep ${SYNC_SLEEP} + +Start All Nodes Again + Add Agent Node node_1 + Add Agent Node node_2 + Add Agent Node node_3 + Sleep ${RESYNC_SLEEP} + +Check Stuff After All Nodes Restart Again + Check Stuff + +Check Ping After All Nodes Restart Again + Check all Pings + +Remove VPP 2x + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start VPP 2x + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Remove VPP 2x + Check Stuff + +Check Ping After Remove VPP 2x + Check all Pings + +Remove VPP 3x + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start VPP 3x + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Remove VPP 3x + Check Stuff + +Check Ping After Remove VPP 3x + Check all Pings + + +Done + [Tags] debug + No Operation + + +Remove Agent Nodes Again + Remove All Nodes + +*** Keywords *** +Check all Pings + linux: Check Ping node_1 10.0.0.11 + linux: Check Ping node_1 10.0.0.12 + linux: Check Ping node_2 10.0.0.10 + linux: Check Ping node_2 10.0.0.12 + linux: Check Ping node_3 10.0.0.10 + linux: Check Ping node_3 10.0.0.11 + +Show Interfaces And Other Objects + vpp_term: Show Interfaces agent_vpp_1 + Write To Machine agent_vpp_1_term show int addr + Write To Machine agent_vpp_1_term show h + Write To Machine agent_vpp_1_term show br + Write To Machine agent_vpp_1_term show err + vat_term: Interfaces Dump agent_vpp_1 + Write To Machine vpp_agent_ctl vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -ps + Execute In Container agent_vpp_1 ip a + Execute In Container node_1 ip a + Execute In Container node_2 ip a + Execute In Container node_3 ip a + Make Datastore Snapshots before_check stuff + +Check Stuff + Show Interfaces And Other Objects + vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth enabled=1 + vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_2_nod2_veth enabled=1 + vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_3_nod3_veth enabled=1 + linux: Interface With IP Is Created node=node_1 mac=${AGENT1_VETH_MAC} ipv4=10.0.0.10/24 + linux: Interface With IP Is Created node=node_2 mac=${AGENT2_VETH_MAC} ipv4=10.0.0.11/24 + linux: Interface With IP Is Created node=node_3 mac=${AGENT3_VETH_MAC} ipv4=10.0.0.12/24 + vat_term: BD Is Created agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth IF_AFPIF_VSWITCH_node_2_nod2_veth IF_AFPIF_VSWITCH_node_3_nod3_veth + + +TestSetup + Make Datastore Snapshots ${TEST_NAME}_test_setup + +TestTeardown + Make Datastore Snapshots ${TEST_NAME}_test_teardown + +Suite Cleanup + Stop SFC Controller Container + Testsuite Teardown diff --git a/tests/robot/suites/sfc/traffic/veth_af_packet_traffic/test_data/veth_basic.conf b/tests/robot/suites/sfc/traffic/veth_af_packet_traffic/test_data/veth_basic.conf new file mode 100644 index 0000000000..fa925cb100 --- /dev/null +++ b/tests/robot/suites/sfc/traffic/veth_af_packet_traffic/test_data/veth_basic.conf @@ -0,0 +1,59 @@ +sfc_controller_config_version: 2 +description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp + +network_pod_to_node_map: + - pod: node_1 + node: agent_vpp_1 + - pod: node_2 + node: agent_vpp_1 + - pod: node_3 + node: agent_vpp_1 + +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: node_1 + spec: + pod_type: vppcontainer + interfaces: + - name: node1_veth + if_type: veth + ip_addresses: + - 10.0.0.10/24 + - metadata: + name: node_2 + spec: + pod_type: vppcontainer + interfaces: + - name: node2_veth + if_type: veth + ip_addresses: + - 10.0.0.11/24 + - metadata: + name: node_3 + spec: + pod_type: vppcontainer + interfaces: + - name: node3_veth + if_type: veth + ip_addresses: + - 10.0.0.12/24 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - node_1/node1_veth + - node_2/node2_veth + - node_3/node3_veth + diff --git a/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/test_data/basicIPv6.conf b/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/test_data/basicIPv6.conf index 9f3663054b..18872df8b6 100644 --- a/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/test_data/basicIPv6.conf +++ b/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/test_data/basicIPv6.conf @@ -1,27 +1,48 @@ -sfc_controller_config_version: 1 +sfc_controller_config_version: 2 description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_vpp_2 + node: agent_vpp_1 + - pod: agent_1 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_vpp_2 - port_label: vpp2_memif1 - mac_addr: 02:02:02:02:02:02 - ipv6_addr: fd30::1:b:0:0:1/64 - etcd_vpp_switch_key: agent_vpp_1 - type: 2 - - container: agent_1 - port_label: agent1_afp1 - ipv6_addr: fd30::1:b:0:0:10/64 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_vpp_2 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp2_memif1 + if_type: memif + mac_address: 02:02:02:02:02:02 + ip_addresses: + - fd30::1:b:0:0:1/64 + - metadata: + name: agent_1 + spec: + pod_type: nonvppcontainer + interfaces: + - name: agent1_afp1 + if_type: veth + ip_addresses: + - fd30::1:b:0:0:10/64 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_vpp_2/vpp2_memif1 + - agent_1/agent1_afp1 diff --git a/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novppIPv6.robot b/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novppIPv6.robot index 26f2c7ac36..323cb9997c 100644 --- a/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novppIPv6.robot +++ b/tests/robot/suites/sfcIPv6/east-west/vswitch_1x_vpp_1x_novpp/vswitch_1x_vpp_1x_novppIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../../variables/${VARIABLES}_variables.robot Resource ../../../../libraries/all_libs.robot -Force Tags sfcIPv6 +Force Tags sfc IPv6 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${IP_1}= fd30::1:b:0:0:1 ${IP_2}= fd30::1:b:0:0:10 diff --git a/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/test_data/basicIPv6.conf b/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/test_data/basicIPv6.conf index ed409e65b0..421c212088 100644 --- a/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/test_data/basicIPv6.conf +++ b/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/test_data/basicIPv6.conf @@ -1,27 +1,48 @@ -sfc_controller_config_version: 1 +sfc_controller_config_version: 2 description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_vpp_2 + node: agent_vpp_1 + - pod: agent_vpp_3 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_vpp_2 - port_label: vpp2_memif1 - mac_addr: 02:02:02:02:02:02 - ipv6_addr: fd30::1:b:0:0:1/64 - etcd_vpp_switch_key: agent_vpp_1 - type: 2 - - container: agent_vpp_3 - port_label: vpp3_memif1 - ipv6_addr: fd30::1:b:0:0:10/64 - etcd_vpp_switch_key: agent_vpp_1 - type: 2 +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_vpp_2 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp2_memif1 + if_type: memif + mac_address: 02:02:02:02:02:02 + ip_addresses: + - fd30::1:b:0:0:1/64 + - metadata: + name: agent_vpp_3 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp3_memif1 + if_type: memif + ip_addresses: + - fd30::1:b:0:0:10/64 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_vpp_2/vpp2_memif1 + - agent_vpp_3/vpp3_memif1 diff --git a/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vppIPv6.robot b/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vppIPv6.robot index 8de363de2f..841a09cbfa 100644 --- a/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vppIPv6.robot +++ b/tests/robot/suites/sfcIPv6/east-west/vswitch_2x_vnf_vpp/vswitch_2x_vnf_vppIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../../variables/${VARIABLES}_variables.robot Resource ../../../../libraries/all_libs.robot -Force Tags sfcIPv6 +Force Tags sfc IPv6 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${IP_1}= fd30::1:b:0:0:1 ${IP_2}= fd30::1:b:0:0:10 diff --git a/tests/robot/suites/sfcIPv6/test_controller_start/controller_startIPv6.robot b/tests/robot/suites/sfcIPv6/test_controller_start/controller_startIPv6.robot index fe5cd75bee..013e48d373 100644 --- a/tests/robot/suites/sfcIPv6/test_controller_start/controller_startIPv6.robot +++ b/tests/robot/suites/sfcIPv6/test_controller_start/controller_startIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags sfcIPv6 +Force Tags sfc IPv6 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup @@ -29,7 +29,6 @@ Configure Environment Check Memif Interface On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 Should Contain ${out} ${int} ${out}= Write To Machine agent_vpp_1_term show h @@ -37,7 +36,6 @@ Check Memif Interface On VPP1 Check Memif Interface On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 Should Contain ${out} ${int} ${out}= Write To Machine agent_vpp_2_term show int addr diff --git a/tests/robot/suites/sfcIPv6/test_controller_start/test_data/sfc.conf b/tests/robot/suites/sfcIPv6/test_controller_start/test_data/sfc.conf deleted file mode 100644 index 928b566231..0000000000 --- a/tests/robot/suites/sfcIPv6/test_controller_start/test_data/sfc.conf +++ /dev/null @@ -1,97 +0,0 @@ -sfc_controller_config_version: 1 -description: Sample SFC Controller Configuration -external_entities: - - name: VRouter-1 - mgmnt_ip_address: 192.168.42.1 - basic_auth_user_name: cisco - basic_auth_passwd: cisco - eth_ipv4: 8.42.0.1 - eth_ipv4_mask: 255.255.255.0 - loopback_ipv4: 112.1.1.3 - loopback_ipv4_mask: 255.255.255.0 - - - name: RAS-1 - basic_auth_user_name: cisco - basic_auth_passwd: cisco - mgmnt_ip_address: 192.168.42.2 - eth_ipv4: 8.42.0.1 - eth_ipv4_mask: 255.255.255.0 - loopback_ipv4: 112.1.1.3 - loopback_ipv4_mask: 255.255.255.0 - -host_entities: - - name: CCMTS-HOST-1 - mgmnt_ip_address: 192.168.42.3 - eth_if_name: GigabitEthernet13/0/0 - eth_ipv4: 8.42.0.2 - eth_ipv4_mask: 255.255.255.0 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 - -sfc_entities: - - name: RAS-dp - description: RAS-dp memif - type: 1 - elements: - - container: RAS-1 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 1 - - container: dp - port_label: rpd - ipv4_addr: 166.111.8.2 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - - name: VRouter-dp - description: VRouter-dp memif - type: 1 - elements: - - container: VRouter-1 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 1 - - container: dp - port_label: wan - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - - name: ccmts-ew-rng-ussched-dp-tftp-dhcp - description: ccmts east west container memif's - type: 2 - elements: - - container: rng - port_label: rng - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: ussched - port_label: ussched - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: dp - port_label: macpi - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: tftp - port_label: tftp - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: dhcp - port_label: dhcp - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - container: dp - port_label: l3pi - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 - - - name: VRouter-dhcp - description: VRouter-dhcp memif - type: 1 - elements: - - container: VRouter-1 - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 1 - - container: dhcp - port_label: cnr - etcd_vpp_switch_key: CCMTS-HOST-1 - type: 2 diff --git a/tests/robot/suites/sfcIPv6/test_controller_start/test_data/simpleIPv6.conf b/tests/robot/suites/sfcIPv6/test_controller_start/test_data/simpleIPv6.conf index ec8de1457a..56e17896bd 100644 --- a/tests/robot/suites/sfcIPv6/test_controller_start/test_data/simpleIPv6.conf +++ b/tests/robot/suites/sfcIPv6/test_controller_start/test_data/simpleIPv6.conf @@ -1,30 +1,46 @@ -sfc_controller_config_version: 1 +sfc_controller_config_version: 2 description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: HOST-1 - mgmnt_ip_address: 192.168.0.1 - eth_if_name: GigabitEthernet13/0/0 - eth_ipv4: 8.42.0.2 - eth_ipv4_mask: 255.255.255.0 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: agent_vpp_2 + node: HOST-1 + - pod: agent_vpp_3 + node: HOST-1 -sfc_entities: +network_nodes: + - metadata: + name: HOST-1 + spec: + node_type: host + l2bds: + - name: east-west-bd - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: agent_vpp_1 - port_label: vpp1_memif1 - mac_addr: 02:02:02:02:02:02 - etcd_vpp_switch_key: HOST-1 - type: 2 - - container: agent_vpp_2 - port_label: vpp2_memif1 - ipv6_addr: fd30::1:b:0:0:10 - etcd_vpp_switch_key: HOST-1 - type: 2 +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: agent_vpp_2 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp2_memif1 + if_type: memif + mac_address: 02:02:02:02:02:02 + - metadata: + name: agent_vpp_3 + spec: + pod_type: vppcontainer + interfaces: + - name: vpp3_memif1 + if_type: memif + ip_addresses: + - fd30::1:b:0:0:10/64 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - agent_vpp_2/vpp2_memif1 + - agent_vpp_3/vpp3_memif1 diff --git a/tests/robot/suites/sfcIPv6/traffic/veth_af_packet_traffic/sfc_veth_af_packet_trafficIPv6.robot b/tests/robot/suites/sfcIPv6/traffic/veth_af_packet_traffic/sfc_veth_af_packet_trafficIPv6.robot new file mode 100644 index 0000000000..4917d19730 --- /dev/null +++ b/tests/robot/suites/sfcIPv6/traffic/veth_af_packet_traffic/sfc_veth_af_packet_trafficIPv6.robot @@ -0,0 +1,416 @@ +*** Settings *** +Library OperatingSystem +#Library RequestsLibrary +#Library SSHLibrary timeout=60s +#Library String + +Resource ../../../../variables/${VARIABLES}_variables.robot + +Resource ../../../../libraries/all_libs.robot + +Force Tags traffic IPv6 ExpectedFailure +Suite Setup Testsuite Setup +Suite Teardown Suite Cleanup +Test Setup TestSetup +Test Teardown TestTeardown + +*** Variables *** +${VARIABLES}= common +${ENV}= common +${WAIT_TIMEOUT}= 20s +${SYNC_SLEEP}= 5s +${RESYNC_SLEEP}= 20s + +${AGENT1_VETH_MAC}= 02:00:00:00:00:01 +${AGENT2_VETH_MAC}= 02:00:00:00:00:02 +${AGENT3_VETH_MAC}= 02:00:00:00:00:03 +${IP_1}= fd30::1:a:0:0:1 +${IP_2}= fd30::1:a:0:0:2 +${IP_3}= fd30::1:a:0:0:3 +${VARIABLES}= common +${ENV}= common +${PREFIX}= 128 + + +*** Test Cases *** +Configure Environment + [Tags] setup + ${DATA_FOLDER}= Catenate SEPARATOR=/ ${CURDIR} ${TEST_DATA_FOLDER} + Set Suite Variable ${DATA_FOLDER} + Configure Environment 4 veth_basicIPv6.conf + Sleep ${SYNC_SLEEP} + Show Interfaces And Other Objects + +Check Stuff At Beginning + Check Stuff + +Check Ping At Beginning + Check all Pings + +Remove VPP And Two Nodes + Remove Node agent_vpp_1 + Remove Node node_1 + Remove Node node_2 + Remove Node node_3 + Sleep ${SYNC_SLEEP} + +Start VPP And Two Nodes + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Add Agent Node node_1 + Add Agent Node node_2 + Add Agent Node node_3 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Resync + Check Stuff + +Check Ping After Resync + Check all Pings + +Remove VPP + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start VPP + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP Restart + Check Stuff + +Check Ping After VPP Restart + Check all Pings + +Remove Node1 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node1 + Add Agent Node node_1 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 Restart + Check Stuff + +Check Ping After Node1 Restart + Check all Pings + +Remove Node1 Again + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node1 Again + Add Agent Node node_1 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 Restart Again + Check Stuff + +Check Ping After Node1 Restart Again + Check all Pings + +Remove Node2 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node2 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node2 Restart + Check Stuff + +Check Ping After Node2 Restart + Check all Pings + +Remove Node2 Again + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node2 Again + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node2 Restart Again + Check Stuff + +Check Ping After Node2 Restart Again + Check all Pings + +Remove Node 1 and Node2 + Remove Node node_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 + Add Agent Node node_1 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart + Check Stuff + +Check Ping After Node1 and Node2 Restart + Check all Pings + +Remove Node 1 and Node2 Again + Remove Node node_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 Again + Add Agent Node node_1 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart Again + Check Stuff + +Check Ping Ater Node1 and Node2 Restart Again + Check all Pings + +Remove Node 1 and Node2 Again 2 + Remove Node node_2 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 Again 2 + Add Agent Node node_2 + Add Agent Node node_1 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart Again 2 + Check Stuff + +Check Ping After Node1 and Node2 Restart Again 2 + Check all Pings + +Remove Node 1 and Node2 Again 3 + Remove Node node_2 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start Node 1 and Node2 Again 3 + Add Agent Node node_1 + Add Agent Node node_2 + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and Node2 Restart Again 3 + Check Stuff + +Check Ping After Node1 and Node2 Restart Again 3 + Check all Pings + +Remove Node 1 and VPP + Remove Node node_1 + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start Node 1 and VPP + Add Agent Node node_1 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node1 and VPP Restart + Check Stuff + +Check Ping After Node1 and VPP Restart + Check all Pings + +Remove VPP And Node1 + Remove Node agent_vpp_1 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start VPP And Node1 + Add Agent Node node_1 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node1 Restart + Check Stuff + +Check Ping After VPP And Node1 Restart + Check all Pings + +Remove VPP And Node1 Again + Remove Node agent_vpp_1 + Remove Node node_1 + Sleep ${SYNC_SLEEP} + +Start VPP And Node1 Again + Add Agent Node node_1 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node1 Restart Again + Check Stuff + +Check Ping After VPP And Node1 Restart Again + Check all Pings + +Remove Node 2 and VPP + Remove Node node_2 + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start Node 2 and VPP + Add Agent Node node_2 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Node2 and VPP Restart + Check Stuff + +Check Ping After Node2 and VPP Restart + Check all Pings + +Remove VPP And Node2 + Remove Node agent_vpp_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start VPP And Node2 + Add Agent Node node_2 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node2 Restart + Check Stuff + +Check Ping After VPP And Node2 Restart + Check all Pings + +Remove VPP And Node2 Again + Remove Node agent_vpp_1 + Remove Node node_2 + Sleep ${SYNC_SLEEP} + +Start VPP And Node2 Again + Add Agent Node node_2 + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After VPP And Node2 Restart Again + Check Stuff + +Check Ping After VPP And Node2 Restart Again + Check all Pings + +Remove All Nodes + Remove Node node_1 + Remove Node node_2 + Remove Node node_3 + Sleep ${SYNC_SLEEP} + +Start All Nodes + Add Agent Node node_1 + Add Agent Node node_2 + Add Agent Node node_3 + Sleep ${RESYNC_SLEEP} + +Check Stuff After All Nodes Restart + Check Stuff + +Check Ping After All Nodes Restart + Check all Pings + +Remove All Nodes Again + Remove Node node_1 + Remove Node node_2 + Remove Node node_3 + Sleep ${SYNC_SLEEP} + +Start All Nodes Again + Add Agent Node node_1 + Add Agent Node node_2 + Add Agent Node node_3 + Sleep ${RESYNC_SLEEP} + +Check Stuff After All Nodes Restart Again + Check Stuff + +Check Ping After All Nodes Restart Again + Check all Pings + +Remove VPP 2x + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start VPP 2x + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Remove VPP 2x + Check Stuff + +Check Ping After Remove VPP 2x + Check all Pings + +Remove VPP 3x + Remove Node agent_vpp_1 + Sleep ${SYNC_SLEEP} + +Start VPP 3x + Add Agent VPP Node agent_vpp_1 vswitch=${TRUE} + Sleep ${RESYNC_SLEEP} + +Check Stuff After Remove VPP 3x + Check Stuff + +Check Ping After Remove VPP 3x + Check all Pings + + +Done + [Tags] debug + No Operation + + +Remove Agent Nodes Again + Remove All Nodes + +*** Keywords *** +Check all Pings + linux: Check Ping6 node_1 ${IP_2} + linux: Check Ping6 node_1 ${IP_3} + linux: Check Ping6 node_2 ${IP_1} + linux: Check Ping6 node_2 ${IP_3} + linux: Check Ping6 node_3 ${IP_1} + linux: Check Ping6 node_3 ${IP_2} + +Show Interfaces And Other Objects + vpp_term: Show Interfaces agent_vpp_1 + Write To Machine agent_vpp_1_term show int addr + Write To Machine agent_vpp_1_term show h + Write To Machine agent_vpp_1_term show br + Write To Machine agent_vpp_1_term show err + vat_term: Interfaces Dump agent_vpp_1 + Write To Machine vpp_agent_ctl vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -ps + Execute In Container agent_vpp_1 ip a + Execute In Container node_1 ip a + Execute In Container node_2 ip a + Execute In Container node_3 ip a + Make Datastore Snapshots before_check stuff + +Check Stuff + Show Interfaces And Other Objects + vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth enabled=1 + vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_2_nod2_veth enabled=1 + vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_3_nod3_veth enabled=1 + linux: Interface With IP Is Created node_1 ${AGENT1_VETH_MAC} ${IP_1}/${PREFIX} + linux: Interface With IP Is Created node_2 ${AGENT2_VETH_MAC} ${IP_2}/${PREFIX} + linux: Interface With IP Is Created node_3 ${AGENT3_VETH_MAC} ${IP_3}/${PREFIX} + vat_term: BD Is Created agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth IF_AFPIF_VSWITCH_node_2_nod2_veth IF_AFPIF_VSWITCH_node_3_nod3_veth + + + +TestSetup + Make Datastore Snapshots ${TEST_NAME}_test_setup + +TestTeardown + Make Datastore Snapshots ${TEST_NAME}_test_teardown + +Suite Cleanup + Stop SFC Controller Container + Testsuite Teardown \ No newline at end of file diff --git a/tests/robot/suites/sfcIPv6/traffic/veth_af_packet_traffic/test_data/veth_basicIPv6.conf b/tests/robot/suites/sfcIPv6/traffic/veth_af_packet_traffic/test_data/veth_basicIPv6.conf new file mode 100644 index 0000000000..b15d25847d --- /dev/null +++ b/tests/robot/suites/sfcIPv6/traffic/veth_af_packet_traffic/test_data/veth_basicIPv6.conf @@ -0,0 +1,59 @@ +sfc_controller_config_version: 2 +description: Basic Example static config for hosting 3 containers with a vnf-agent and vpp + +network_pod_to_node_map: + - pod: node_1 + node: agent_vpp_1 + - pod: node_2 + node: agent_vpp_1 + - pod: node_3 + node: agent_vpp_1 + +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: node_1 + spec: + pod_type: vppcontainer + interfaces: + - name: node1_veth + if_type: veth + ip_addresses: + - fd30::1:a:0:0:1/128 + - metadata: + name: node_2 + spec: + pod_type: vppcontainer + interfaces: + - name: node2_veth + if_type: veth + ip_addresses: + - fd30::1:a:0:0:2/128 + - metadata: + name: node_3 + spec: + pod_type: vppcontainer + interfaces: + - name: node3_veth + if_type: veth + ip_addresses: + - fd30::1:a:0:0:3/128 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - node_1/node1_veth + - node_2/node2_veth + - node_3/node3_veth + diff --git a/tests/robot/suites/traffic/3x_vpp_traffic/3x_vpp_traffic.robot b/tests/robot/suites/traffic/3x_vpp_traffic/3x_vpp_traffic.robot index 165d50ce3c..a1a19f7635 100644 --- a/tests/robot/suites/traffic/3x_vpp_traffic/3x_vpp_traffic.robot +++ b/tests/robot/suites/traffic/3x_vpp_traffic/3x_vpp_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup diff --git a/tests/robot/suites/traffic/acl_traffic/acl_traffic.robot b/tests/robot/suites/traffic/acl_traffic/acl_traffic.robot index abf6ab6f15..53c21807f7 100644 --- a/tests/robot/suites/traffic/acl_traffic/acl_traffic.robot +++ b/tests/robot/suites/traffic/acl_traffic/acl_traffic.robot @@ -9,7 +9,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -20,7 +20,7 @@ ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 20s ${AGENT1_VETH_MAC}= 02:00:00:00:00:01 diff --git a/tests/robot/suites/traffic/acl_traffic/test_data/acl_basic.conf b/tests/robot/suites/traffic/acl_traffic/test_data/acl_basic.conf index d2876687f1..9c5f61a7e6 100644 --- a/tests/robot/suites/traffic/acl_traffic/test_data/acl_basic.conf +++ b/tests/robot/suites/traffic/acl_traffic/test_data/acl_basic.conf @@ -1,26 +1,47 @@ -sfc_controller_config_version: 1 -description: Basic Example static config for hosting 2 containers with a vnf-agent and 1 container with agent and vpp +sfc_controller_config_version: 2 +description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: node_1 + node: agent_vpp_1 + - pod: node_2 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: node_1 - port_label: node1_veth - ipv4_addr: 10.0.0.10 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: node_2 - port_label: node2_veth - ipv4_addr: 10.0.0.11 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: node_1 + spec: + pod_type: vppcontainer + interfaces: + - name: node1_veth + if_type: veth + ip_addresses: + - 10.0.0.1/24 + - metadata: + name: node_2 + spec: + pod_type: vppcontainer + interfaces: + - name: node2_veth + if_type: veth + ip_addresses: + - 10.0.0.10/24 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - node_1/node1_veth + - node_2/node2_veth diff --git a/tests/robot/suites/traffic/bridge_domain/test_bridge_domain.robot b/tests/robot/suites/traffic/bridge_domain/test_bridge_domain.robot index 04a2b1d5bc..088c0c1b63 100644 --- a/tests/robot/suites/traffic/bridge_domain/test_bridge_domain.robot +++ b/tests/robot/suites/traffic/bridge_domain/test_bridge_domain.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 Suite Setup Run Keywords Discard old results *** Variables *** diff --git a/tests/robot/suites/traffic/ip_route/test_inter_vrf_routes.robot b/tests/robot/suites/traffic/ip_route/test_inter_vrf_routes.robot index 224e2e2b96..49db036d00 100644 --- a/tests/robot/suites/traffic/ip_route/test_inter_vrf_routes.robot +++ b/tests/robot/suites/traffic/ip_route/test_inter_vrf_routes.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 Suite Setup Run Keywords Discard old results Test Setup Suite Teardown Test Teardown @@ -98,13 +98,9 @@ Final Sleep For Manual Checking *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} IP Fib Table ${table_id} On ${node} Should Contain Vrf ${inter_vrf_string} - Log many ${table_id} ${node} ${inter_vrf_string} ${out}= vpp_term: Show IP Fib Table ${node} ${table_id} - log many ${out} Should Contain ${out} ${inter_vrf_string} diff --git a/tests/robot/suites/traffic/ip_route/test_ip_route.robot b/tests/robot/suites/traffic/ip_route/test_ip_route.robot index 5421b4357d..a710fda044 100644 --- a/tests/robot/suites/traffic/ip_route/test_ip_route.robot +++ b/tests/robot/suites/traffic/ip_route/test_ip_route.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 Suite Setup Run Keywords Discard old results *** Variables *** @@ -159,7 +159,5 @@ Start Three Agents, Then Configure With Interfaces Assigned To Non Default VRF *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} \ No newline at end of file diff --git a/tests/robot/suites/traffic/l2xconnect_traffic/l2xconnect_trafic.robot b/tests/robot/suites/traffic/l2xconnect_traffic/l2xconnect_trafic.robot index e4555344c5..c5fcbacd9d 100644 --- a/tests/robot/suites/traffic/l2xconnect_traffic/l2xconnect_trafic.robot +++ b/tests/robot/suites/traffic/l2xconnect_traffic/l2xconnect_trafic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -17,7 +17,7 @@ Test Teardown TestTeardown *** Variables *** ${VARIABLES}= common ${ENV}= common -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Configure Environment 1 diff --git a/tests/robot/suites/traffic/libmemif/libmemif_master_trafic1.robot b/tests/robot/suites/traffic/libmemif/libmemif_master_trafic1.robot index 4640031448..1d5d4898fa 100644 --- a/tests/robot/suites/traffic/libmemif/libmemif_master_trafic1.robot +++ b/tests/robot/suites/traffic/libmemif/libmemif_master_trafic1.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 diff --git a/tests/robot/suites/traffic/libmemif/libmemif_master_trafic2.robot b/tests/robot/suites/traffic/libmemif/libmemif_master_trafic2.robot index adfc2279c6..81843112fd 100644 --- a/tests/robot/suites/traffic/libmemif/libmemif_master_trafic2.robot +++ b/tests/robot/suites/traffic/libmemif/libmemif_master_trafic2.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 ${VPP1MEMIF_IP1}= 192.168.1.1 @@ -140,7 +140,6 @@ Add Libmemif Node Again Create And Check Memif1 On Agent Libmemif 1 After node restart2 ${out_c}= lmterm: Issue Command agent_libmemif_1 conn 0 1 ${out}= lmterm: Issue Command agent_libmemif_1 show - Log Many ${out_c} ${out} Should Contain ${out} interface ip: ${LIBMEMIF_IP1} Should Contain ${out} link: up diff --git a/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic1.robot b/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic1.robot index f2cb2e0801..a3d8062b81 100644 --- a/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic1.robot +++ b/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic1.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 ${VPP1MEMIF_IP1}= 192.168.1.1 @@ -184,7 +184,6 @@ Add Libmemif Node Again Create And Check Memif1 On Agent Libmemif 1 After node restart ${out_c}= lmterm: Issue Command agent_libmemif_1 conn 0 0 ${out}= lmterm: Issue Command agent_libmemif_1 show - Log Many ${out_c} ${out} Should Contain ${out} interface ip: ${LIBMEMIF_IP1} Should Contain ${out} link: up diff --git a/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic2.robot b/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic2.robot index 243663d311..12d0f279b6 100644 --- a/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic2.robot +++ b/tests/robot/suites/traffic/libmemif/libmemif_slave_trafic2.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 ${VPP1MEMIF_IP1}= 192.168.1.1 @@ -183,7 +183,6 @@ Add Libmemif Node Again Create And Check Memif1 On Agent Libmemif 1 After node restart ${out_c}= lmterm: Issue Command agent_libmemif_1 conn 0 0 ${out}= lmterm: Issue Command agent_libmemif_1 show - Log Many ${out_c} ${out} Should Contain ${out} interface ip: ${LIBMEMIF_IP1} Should Contain ${out} link: up diff --git a/tests/robot/suites/traffic/linux_traffic/1x_vpp_3x_namespaces_traffic.robot b/tests/robot/suites/traffic/linux_traffic/1x_vpp_3x_namespaces_traffic.robot index ef84851054..b88fa9441f 100644 --- a/tests/robot/suites/traffic/linux_traffic/1x_vpp_3x_namespaces_traffic.robot +++ b/tests/robot/suites/traffic/linux_traffic/1x_vpp_3x_namespaces_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -17,7 +17,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s # wait for resync vpps after restart ${RESYNC_WAIT}= 30s @@ -114,16 +114,13 @@ Start VPP1 Again Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip netns exec ns1 ip a - Log ${out} Should Contain ${out} ns1_veth1_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns2 ip a - Log ${out} Should Contain ${out} ns2_veth2_linux Should Contain ${out} ns2_veth3_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns3 ip a - Log ${out} Should Contain ${out} ns3_veth3_linux Check Linux Interfaces node=agent_vpp_1 namespace=ns1 interface=ns1_veth1 @@ -162,50 +159,37 @@ Try to ping among namespaces *** Keywords *** Check Linux Interfaces [Arguments] ${node} ${namespace} ${interface} - Log Many ${node} ${namespace} ${interface} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip a - Log ${out} Should Contain ${out} ${interface} Check Linux Routes [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via Check Linux Routes Gateway [Arguments] ${node} ${namespace} ${ip} ${next_hop}=${EMPTY} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via ${next_hop} Check Linux Default Routes [Arguments] ${node} ${namespace} ${next_hop} - Log Many ${node} ${namespace} ${next_hop} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} default via ${next_hop} Check Linux Routes Metric [Arguments] ${node} ${namespace} ${ip} ${metric} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Match Regexp ${out} ${ip} via.*metric ${metric}\\s Check Removed Linux Route [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Not Contain ${out} ${ip} via Ping in namespace [Arguments] ${node} ${namespace} ${ip} ${out}= Execute In Container ${node} ip netns exec ${namespace} ping -c 5 ${ip} - Log ${out} Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss diff --git a/tests/robot/suites/traffic/physical_int_traffic/physical_int_traffic.robot b/tests/robot/suites/traffic/physical_int_traffic/physical_int_traffic.robot index 862cff9113..12595dc17c 100644 --- a/tests/robot/suites/traffic/physical_int_traffic/physical_int_traffic.robot +++ b/tests/robot/suites/traffic/physical_int_traffic/physical_int_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown @@ -16,7 +16,7 @@ Suite Teardown Testsuite Teardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s # wait for resync vpps after restart ${RESYNC_WAIT}= 30s @@ -59,14 +59,12 @@ Setup Interfaces Check Linux Interfaces On VPP1 ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} # ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 # Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 @@ -82,14 +80,12 @@ Check Interfaces On VPP1 Check Linux Interfaces On VPP2 ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} # ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 # Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 diff --git a/tests/robot/suites/traffic/tap_int_traffic/tap_int_and_route_config_order_traffic.robot b/tests/robot/suites/traffic/tap_int_traffic/tap_int_and_route_config_order_traffic.robot index 4e6962ba14..d42954e195 100644 --- a/tests/robot/suites/traffic/tap_int_traffic/tap_int_and_route_config_order_traffic.robot +++ b/tests/robot/suites/traffic/tap_int_traffic/tap_int_and_route_config_order_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -38,7 +38,7 @@ ${IP_VPP2_MEMIF1}= 192.168.1.2 ${PREFIX}= 24 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 20s @@ -92,24 +92,20 @@ Add Static Route From VPP2 To VPP1 Show Routes On VPP1 Linux ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route1} Show Route To VPP2 Configured On VPP1 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route1} Show Route To VPP1 Configured On VPP2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 @@ -179,24 +175,20 @@ Add VPP2_memif1 Interface 2 Show Routes On VPP1 Linux 2 ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route2} Show Route To VPP2 Configured On VPP1 2 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux 2 ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route2} Show Route To VPP1 Configured On VPP2 2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 diff --git a/tests/robot/suites/traffic/tap_int_traffic/tap_int_traffic.robot b/tests/robot/suites/traffic/tap_int_traffic/tap_int_traffic.robot index a7f881ed75..37ee1109cd 100644 --- a/tests/robot/suites/traffic/tap_int_traffic/tap_int_traffic.robot +++ b/tests/robot/suites/traffic/tap_int_traffic/tap_int_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -36,7 +36,7 @@ ${IP_VPP2_MEMIF1}= 192.168.1.2 ${PREFIX}= 24 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 50s @@ -57,7 +57,6 @@ Add VPP1_TAP1 Interface Check VPP1_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_VPP1_TAP1} ${actual_state}= vpp_term: Check TAP interface State agent_vpp_1 ${NAME_VPP1_TAP1} mac=${MAC_VPP1_TAP1} ipv4=${IP_VPP1_TAP1}/${PREFIX} state=${UP_STATE} @@ -77,9 +76,8 @@ Add VPP2_TAP1 Interface Check VPP2_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_2 mac=${MAC_VPP2_TAP1} - ${actual_state}= vpp_term: Check TAP interface State agent_vpp_2 ${NAME_VPP2_TAP1} mac=${MAC_VPP2_TAP1} ipv4=${IP_VPP2_TAP1}/${PREFIX} state=${UP_STATE} + ${actual_state}= Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Check TAP interface State agent_vpp_2 ${NAME_VPP2_TAP1} mac=${MAC_VPP2_TAP1} ipv4=${IP_VPP2_TAP1}/${PREFIX} state=${UP_STATE} Check Ping Between VPP2 And linux_VPP2_TAP1 Interface linux: Check Ping node=agent_vpp_2 ip=${IP_VPP2_TAP1} @@ -118,7 +116,7 @@ Add Static Route From VPP2 Linux To VPP1 linux: Add Route node=agent_vpp_2 destination_ip=${IP_VPP1_TAP1_NETWORK} prefix=${PREFIX} next_hop_ip=${IP_VPP2_TAP1} Add Static Route From VPP2 To VPP1 - Create Route On agent_vpp_2 With IP ${IP_VPP1_TAP1_NETWORK}/${PREFIX} With Next Hop ${IP_VPP2_MEMIF1} And Vrf Id 0 + Create Route On agent_vpp_2 With IP ${IP_VPP1_TAP1_NETWORK}/${PREFIX} With Next Hop ${IP_VPP1_MEMIF1} And Vrf Id 0 Sleep ${SYNC_SLEEP} Check Ping From VPP1 Linux To VPP2_TAP1 And LINUX_VPP2_TAP1 @@ -144,12 +142,10 @@ Create linux_VPP1_TAP1 And linux_VPP2_TAP1 Interfaces After Resync Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP1_TAP1} Check Interfaces On VPP1 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_TAP1} @@ -161,12 +157,10 @@ TestTeardown Make Datastore Snapshots ${TEST_NAME}_test_teardown Check Linux Interfaces On VPP2 After Resync ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP2_TAP1} Check Interfaces On VPP2 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_TAP1} @@ -178,7 +172,7 @@ Add Static Route From VPP1 Linux To VPP2 After Resync Add Static Route From VPP2 Linux To VPP1 After Resync linux: Add Route node=agent_vpp_2 destination_ip=${IP_VPP1_TAP1_NETWORK} prefix=${PREFIX} next_hop_ip=${IP_VPP2_TAP1} Sleep ${SYNC_SLEEP} - + Check Ping From VPP1 Linux To VPP2_TAP1 And LINUX_VPP2_TAP1 After Resync linux: Check Ping node=agent_vpp_1 ip=${IP_VPP2_TAP1} linux: Check Ping node=agent_vpp_1 ip=${IP_LINUX_VPP2_TAP1} diff --git a/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_and_route_config_order_traffic.robot b/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_and_route_config_order_traffic.robot index 734ff8e0b4..498ee65d14 100644 --- a/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_and_route_config_order_traffic.robot +++ b/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_and_route_config_order_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -38,7 +38,7 @@ ${IP_VPP2_MEMIF1}= 192.168.1.2 ${PREFIX}= 24 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 20s @@ -92,24 +92,20 @@ Add Static Route From VPP2 To VPP1 Show Routes On VPP1 Linux ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route1} Show Route To VPP2 Configured On VPP1 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route1} Show Route To VPP1 Configured On VPP2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 @@ -179,24 +175,20 @@ Add VPP2_memif1 Interface 2 Show Routes On VPP1 Linux 2 ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route2} Show Route To VPP2 Configured On VPP1 2 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux 2 ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route2} Show Route To VPP1 Configured On VPP2 2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 Again diff --git a/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_traffic.robot b/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_traffic.robot index c856aeaee8..6f280bb612 100644 --- a/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_traffic.robot +++ b/tests/robot/suites/traffic/tapv2_int_traffic/tapv2_int_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -36,7 +36,7 @@ ${IP_VPP2_MEMIF1}= 192.168.1.2 ${PREFIX}= 24 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 50s @@ -57,7 +57,6 @@ Add VPP1_TAP1 Interface Check VPP1_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_VPP1_TAP1} ${actual_state}= vpp_term: Check TAPv2 interface State agent_vpp_1 ${NAME_VPP1_TAP1} mac=${MAC_VPP1_TAP1} ipv4=${IP_VPP1_TAP1}/${PREFIX} state=${UP_STATE} @@ -77,7 +76,6 @@ Add VPP2_TAP1 Interface Check VPP2_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_2 mac=${MAC_VPP2_TAP1} ${actual_state}= vpp_term: Check TAPv2 interface State agent_vpp_2 ${NAME_VPP2_TAP1} mac=${MAC_VPP2_TAP1} ipv4=${IP_VPP2_TAP1}/${PREFIX} state=${UP_STATE} @@ -143,12 +141,10 @@ Create linux_VPP1_TAP1 And linux_VPP2_TAP1 Interfaces After Resync Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP1_TAP1} Check Interfaces On VPP1 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_TAP1} @@ -156,12 +152,10 @@ Check Interfaces On VPP1 After Resync Check Linux Interfaces On VPP2 After Resync ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP2_TAP1} Check Interfaces On VPP2 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_TAP1} diff --git a/tests/robot/suites/traffic/veth_af_packet_traffic/test_data/veth_basic.conf b/tests/robot/suites/traffic/veth_af_packet_traffic/test_data/veth_basic.conf deleted file mode 100644 index 21ee531f4e..0000000000 --- a/tests/robot/suites/traffic/veth_af_packet_traffic/test_data/veth_basic.conf +++ /dev/null @@ -1,31 +0,0 @@ -sfc_controller_config_version: 1 -description: Basic Example static config for hosting 3 containers with a vnf-agent and 1 container with agent and vpp - -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 - -sfc_entities: - - name: three-sample-vnf-containers - description: Wire 3 VNF containers to the vpp switch - type: 2 - elements: - - container: node_1 - port_label: nod1_veth - ipv4_addr: 10.0.0.10 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: node_2 - port_label: nod2_veth - ipv4_addr: 10.0.0.11 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: node_3 - port_label: nod3_veth - ipv4_addr: 10.0.0.12 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - diff --git a/tests/robot/suites/traffic/veth_af_packet_traffic/veth_af_packet_traffic.robot b/tests/robot/suites/traffic/veth_af_packet_traffic/veth_af_packet_traffic.robot index b400e8fdc6..7d7ca27dc2 100644 --- a/tests/robot/suites/traffic/veth_af_packet_traffic/veth_af_packet_traffic.robot +++ b/tests/robot/suites/traffic/veth_af_packet_traffic/veth_af_packet_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -17,13 +17,13 @@ Test Teardown TestTeardown *** Variables *** ${VARIABLES}= common ${ENV}= common -${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${WAIT_TIMEOUT}= 60s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 15s -${AGENT1_VETH_MAC}= 02:00:00:00:00:01 -${AGENT2_VETH_MAC}= 02:00:00:00:00:02 -${AGENT3_VETH_MAC}= 02:00:00:00:00:03 +${AGENT1_VETH_MAC}= 12:11:11:11:11:11 +${AGENT2_VETH_MAC}= 12:11:11:11:11:12 +${AGENT3_VETH_MAC}= 12:11:11:11:11:13 ${VARIABLES}= common ${ENV}= common @@ -34,8 +34,27 @@ Configure Environment [Tags] setup ${DATA_FOLDER}= Catenate SEPARATOR=/ ${CURDIR} ${TEST_DATA_FOLDER} Set Suite Variable ${DATA_FOLDER} - Configure Environment 4 veth_basic.conf - Sleep ${SYNC_SLEEP} + Configure Environment 7 + +Configure Interfaces + Write To Machine vpp_agent_ctl vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -ps + + vpp_ctl: Put Veth Interface With IP And Namespace node=agent_vpp_1 name=node1_veth namespace=node_1 mac=12:11:11:11:11:11 peer=vpp1_veth1 ip=10.0.0.10 + vpp_ctl: Put Veth Interface And Namespace node=agent_vpp_1 name=vpp1_veth1 namespace=agent_vpp_1 mac=12:12:12:12:12:11 peer=node1_veth + vpp_ctl: Put Afpacket Interface node=agent_vpp_1 name=vpp1_afpacket1 mac=a2:a1:a1:a1:a1:a1 host_int=vpp1_veth1 + + vpp_ctl: Put Veth Interface With IP And Namespace node=agent_vpp_1 name=node2_veth namespace=node_2 mac=12:11:11:11:11:12 peer=vpp1_veth2 ip=10.0.0.11 + vpp_ctl: Put Veth Interface And Namespace node=agent_vpp_1 name=vpp1_veth2 namespace=agent_vpp_1 mac=12:12:12:12:12:12 peer=node2_veth + vpp_ctl: Put Afpacket Interface node=agent_vpp_1 name=vpp1_afpacket2 mac=a2:a1:a1:a1:a1:a2 host_int=vpp1_veth2 + + vpp_ctl: Put Veth Interface With IP And Namespace node=agent_vpp_1 name=node3_veth namespace=node_3 mac=12:11:11:11:11:13 peer=vpp1_veth3 ip=10.0.0.12 + vpp_ctl: Put Veth Interface And Namespace node=agent_vpp_1 name=vpp1_veth3 namespace=agent_vpp_1 mac=12:12:12:12:12:13 peer=node3_veth + vpp_ctl: Put Afpacket Interface node=agent_vpp_1 name=vpp1_afpacket3 mac=a2:a1:a1:a1:a1:a3 host_int=vpp1_veth3 + + @{ints}= Create List vpp1_afpacket1 vpp1_afpacket2 vpp1_afpacket3 + vpp_ctl: Put Bridge Domain node=agent_vpp_1 name=east-west-bd ints=${ints} + + Sleep ${RESYNC_SLEEP} Show Interfaces And Other Objects Check Stuff At Beginning @@ -391,15 +410,16 @@ Show Interfaces And Other Objects Make Datastore Snapshots before_check stuff Check Stuff - Show Interfaces And Other Objects - vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth enabled=1 - vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_2_nod2_veth enabled=1 - vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_3_nod3_veth enabled=1 - linux: Interface With IP Is Created node=node_1 mac=${AGENT1_VETH_MAC} ipv4=10.0.0.10/24 - linux: Interface With IP Is Created node=node_2 mac=${AGENT2_VETH_MAC} ipv4=10.0.0.11/24 - linux: Interface With IP Is Created node=node_3 mac=${AGENT3_VETH_MAC} ipv4=10.0.0.12/24 - vat_term: BD Is Created agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth IF_AFPIF_VSWITCH_node_2_nod2_veth IF_AFPIF_VSWITCH_node_3_nod3_veth - + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Show Interfaces And Other Objects + #${WAIT_TIMEOUT} in first keyword is 60s because after restart agent_vpp_1 need waiting to interface internal name + #Bug: CV-595 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Afpacket Interface State agent_vpp_1 vpp1_afpacket1 enabled=1 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Afpacket Interface State agent_vpp_1 vpp1_afpacket2 enabled=1 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Afpacket Interface State agent_vpp_1 vpp1_afpacket3 enabled=1 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} linux: Interface With IP Is Created node=node_1 mac=${AGENT1_VETH_MAC} ipv4=10.0.0.10/24 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} linux: Interface With IP Is Created node=node_2 mac=${AGENT2_VETH_MAC} ipv4=10.0.0.11/24 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} linux: Interface With IP Is Created node=node_3 mac=${AGENT3_VETH_MAC} ipv4=10.0.0.12/24 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: BD Is Created agent_vpp_1 vpp1_afpacket1 vpp1_afpacket2 vpp1_afpacket3 TestSetup @@ -409,5 +429,4 @@ TestTeardown Make Datastore Snapshots ${TEST_NAME}_test_teardown Suite Cleanup - Stop SFC Controller Container Testsuite Teardown \ No newline at end of file diff --git a/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic.robot b/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic.robot index fdb603b6e5..5e60554d2a 100644 --- a/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic.robot +++ b/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -57,54 +57,40 @@ Setup Interfaces Check Linux Interfaces On VPP1 ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_tap1 - Log ${int} Should Contain ${out} ${int} Check Linux Interfaces On VPP2 ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_tap1 - Log ${int} Should Contain ${out} ${int} Check Bridge Domain On VPP1 Is Created @@ -155,53 +141,40 @@ Start VPP1 And VPP2 Again Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_tap1 - Log ${int} Should Contain ${out} ${int} Check Linux Interfaces On VPP2 After Resync ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_loop1 Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_tap1 - Log ${int} Should Contain ${out} ${int} Check Bridge Domain On VPP1 Is Created After Resync diff --git a/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrf.robot b/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrf.robot index 1e998aa7f5..2669cadc52 100644 --- a/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrf.robot +++ b/tests/robot/suites/traffic/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrf.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -60,13 +60,11 @@ Setup Interfaces Check Linux Interfaces On VPP1 ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 @@ -76,13 +74,11 @@ Check Interfaces On VPP1 Check Linux Interfaces On VPP2 ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 diff --git a/tests/robot/suites/traffic/vpp_2novpp_memif_traffic/vpp_2novpp_memif_traffic.robot b/tests/robot/suites/traffic/vpp_2novpp_memif_traffic/vpp_2novpp_memif_traffic.robot index 1b5d3d5a80..60f003e2d3 100644 --- a/tests/robot/suites/traffic/vpp_2novpp_memif_traffic/vpp_2novpp_memif_traffic.robot +++ b/tests/robot/suites/traffic/vpp_2novpp_memif_traffic/vpp_2novpp_memif_traffic.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv4 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup diff --git a/tests/robot/suites/trafficIPv6/3x_vpp_traffic/3x_vpp_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/3x_vpp_traffic/3x_vpp_trafficIPv6.robot index cd537b8719..c37b975ada 100644 --- a/tests/robot/suites/trafficIPv6/3x_vpp_traffic/3x_vpp_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/3x_vpp_traffic/3x_vpp_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup diff --git a/tests/robot/suites/trafficIPv6/acl_traffic/acl_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/acl_traffic/acl_trafficIPv6.robot index 0b8914628d..250fa67dbb 100644 --- a/tests/robot/suites/trafficIPv6/acl_traffic/acl_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/acl_traffic/acl_trafficIPv6.robot @@ -9,7 +9,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -19,7 +19,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 20s ${AGENT1_VETH_MAC}= 02:00:00:00:00:01 diff --git a/tests/robot/suites/trafficIPv6/acl_traffic/test_data/acl_basicIPv6.conf b/tests/robot/suites/trafficIPv6/acl_traffic/test_data/acl_basicIPv6.conf index 81608252f0..703822be2b 100644 --- a/tests/robot/suites/trafficIPv6/acl_traffic/test_data/acl_basicIPv6.conf +++ b/tests/robot/suites/trafficIPv6/acl_traffic/test_data/acl_basicIPv6.conf @@ -1,26 +1,47 @@ -sfc_controller_config_version: 1 -description: Basic Example static config for hosting 2 containers with a vnf-agent and 1 container with agent and vpp +sfc_controller_config_version: 2 +description: Basic Example static config for hosting 2 containers with a vnf-agent and vpp -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 +network_pod_to_node_map: + - pod: node_1 + node: agent_vpp_1 + - pod: node_2 + node: agent_vpp_1 -sfc_entities: - - name: two-sample-vnf-containers - description: Wire 2 VNF containers to the vpp switch - type: 2 - elements: - - container: node_1 - port_label: node1_veth - ipv6_addr: fd35::1:a:0:0:10 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: node_2 - port_label: node2_veth - ipv6_addr: fd35::1:a:0:0:11 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 +network_nodes: + - metadata: + name: agent_vpp_1 + spec: + node_type: host + l2bds: + - name: east-west-bd + +network_services: + - metadata: + name: two-sample-vnf-containers + spec: + network_pods: + - metadata: + name: node_1 + spec: + pod_type: vppcontainer + interfaces: + - name: node1_veth + if_type: veth + ip_addresses: + - fd35::1:a:0:0:10/64 + - metadata: + name: node_2 + spec: + pod_type: vppcontainer + interfaces: + - name: node2_veth + if_type: veth + ip_addresses: + - fd35::1:a:0:0:11/64 + connections: + - conn_type: l2mp + use_node_l2bd: east-west-bd + pod_interfaces: + - node_1/node1_veth + - node_2/node2_veth diff --git a/tests/robot/suites/trafficIPv6/bridge_domain/test1_bridge_domainIPv6.robot b/tests/robot/suites/trafficIPv6/bridge_domain/test1_bridge_domainIPv6.robot index ce70b2363f..09d968a062 100644 --- a/tests/robot/suites/trafficIPv6/bridge_domain/test1_bridge_domainIPv6.robot +++ b/tests/robot/suites/trafficIPv6/bridge_domain/test1_bridge_domainIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -32,7 +32,7 @@ ${IP_5}= fd31::1:b:0:0:2 ${PREFIX}= 64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Start 2 Agents diff --git a/tests/robot/suites/trafficIPv6/bridge_domain/test2_bridge_domainIPv6.robot b/tests/robot/suites/trafficIPv6/bridge_domain/test2_bridge_domainIPv6.robot index d9ca830e5c..29fdfbf20e 100644 --- a/tests/robot/suites/trafficIPv6/bridge_domain/test2_bridge_domainIPv6.robot +++ b/tests/robot/suites/trafficIPv6/bridge_domain/test2_bridge_domainIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -33,7 +33,7 @@ ${IP_5}= fd31::1:b:0:0:2 ${PREFIX}= 64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** First configure Bridge Domain with Memif interfaces and VXLan then add two agents and try traffic diff --git a/tests/robot/suites/trafficIPv6/bridge_domain/test3_bridge_domainIPv6.robot b/tests/robot/suites/trafficIPv6/bridge_domain/test3_bridge_domainIPv6.robot index 216d04b2a3..ddf628e0bc 100644 --- a/tests/robot/suites/trafficIPv6/bridge_domain/test3_bridge_domainIPv6.robot +++ b/tests/robot/suites/trafficIPv6/bridge_domain/test3_bridge_domainIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -33,7 +33,7 @@ ${IP_5}= fd31::1:b:0:0:2 ${PREFIX}= 64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** Start Agents diff --git a/tests/robot/suites/trafficIPv6/ip_route/test1_ip_routeIPv6.robot b/tests/robot/suites/trafficIPv6/ip_route/test1_ip_routeIPv6.robot index d70c463059..47394517c0 100644 --- a/tests/robot/suites/trafficIPv6/ip_route/test1_ip_routeIPv6.robot +++ b/tests/robot/suites/trafficIPv6/ip_route/test1_ip_routeIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -35,7 +35,7 @@ ${MAC3_MEMIF1}= 02:f1:be:90:00:03 ${PREFIX}= 64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** # Default VRF table ... Start Three Agents @@ -123,9 +123,7 @@ Pinging *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} TestSetup diff --git a/tests/robot/suites/trafficIPv6/ip_route/test2_ip_routeIPv6.robot b/tests/robot/suites/trafficIPv6/ip_route/test2_ip_routeIPv6.robot index 9604420388..cadf4a220b 100644 --- a/tests/robot/suites/trafficIPv6/ip_route/test2_ip_routeIPv6.robot +++ b/tests/robot/suites/trafficIPv6/ip_route/test2_ip_routeIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -118,9 +118,7 @@ Pinging *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} TestSetup diff --git a/tests/robot/suites/trafficIPv6/ip_route/test3_ip_routeIPv6.robot b/tests/robot/suites/trafficIPv6/ip_route/test3_ip_routeIPv6.robot index 2060158f83..e7d31f6be0 100644 --- a/tests/robot/suites/trafficIPv6/ip_route/test3_ip_routeIPv6.robot +++ b/tests/robot/suites/trafficIPv6/ip_route/test3_ip_routeIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -35,7 +35,7 @@ ${MAC3_MEMIF1}= 02:f1:be:90:00:03 ${PREFIX}= 64 ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s *** Test Cases *** # Default VRF table ... Start Three Agents @@ -136,9 +136,7 @@ Check bd1 on Agent3 Is Created *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} TestSetup diff --git a/tests/robot/suites/trafficIPv6/ip_route/test4_ip_routeIPv6.robot b/tests/robot/suites/trafficIPv6/ip_route/test4_ip_routeIPv6.robot index a2d2756312..b3d0852916 100644 --- a/tests/robot/suites/trafficIPv6/ip_route/test4_ip_routeIPv6.robot +++ b/tests/robot/suites/trafficIPv6/ip_route/test4_ip_routeIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -143,9 +143,7 @@ Pinging *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} TestSetup diff --git a/tests/robot/suites/trafficIPv6/ip_route/test_inter_vrf_routes_ipv6.robot b/tests/robot/suites/trafficIPv6/ip_route/test_inter_vrf_routes_ipv6.robot index ff8766572d..0be8050f5c 100644 --- a/tests/robot/suites/trafficIPv6/ip_route/test_inter_vrf_routes_ipv6.robot +++ b/tests/robot/suites/trafficIPv6/ip_route/test_inter_vrf_routes_ipv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv4 +Force Tags traffic IPv6 Suite Setup Run Keywords Discard old results Test Setup Suite Teardown Test Teardown @@ -99,13 +99,9 @@ Final Sleep For Manual Checking *** Keywords *** List of interfaces On ${node} Should Contain Interface ${int} - Log many ${node} ${int} ${out}= vpp_term: Show Interfaces ${node} - log many ${out} Should Match Regexp ${out} ${int} IP6 Fib Table ${table_id} On ${node} Should Contain Vrf ${inter_vrf_string} - Log many ${table_id} ${node} ${inter_vrf_string} ${out}= vpp_term: Show IP6 Fib Table ${node} ${table_id} - log many ${out} Should Contain ${out} ${inter_vrf_string} diff --git a/tests/robot/suites/trafficIPv6/l2xconnect_traffic/l2xconnect_traficIPv6.robot b/tests/robot/suites/trafficIPv6/l2xconnect_traffic/l2xconnect_traficIPv6.robot index 108f199682..8cb1532679 100644 --- a/tests/robot/suites/trafficIPv6/l2xconnect_traffic/l2xconnect_traficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/l2xconnect_traffic/l2xconnect_traficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup diff --git a/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic1IPv6.robot b/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic1IPv6.robot index 13c9f4e9f2..40c094084f 100644 --- a/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic1IPv6.robot +++ b/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic1IPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 diff --git a/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic2IPv6.robot b/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic2IPv6.robot index 2fb01aab40..cdc2c9e82a 100644 --- a/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic2IPv6.robot +++ b/tests/robot/suites/trafficIPv6/libmemif/libmemif_master_trafic2IPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 @@ -144,7 +144,6 @@ Create And Check Memif1 On Agent Libmemif 1 After node restart2 ${out_c}= lmterm: Issue Command agent_libmemif_1 conn 0 1 Sleep ${SYNC_SLEEP} ${out}= lmterm: Issue Command agent_libmemif_1 show - Log Many ${out_c} ${out} Should Contain ${out} interface ip: ${LIBMEMIF_IP1} Should Contain ${out} link: up diff --git a/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic1IPv6.robot b/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic1IPv6.robot index b32e12ddca..b0aa202fbb 100644 --- a/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic1IPv6.robot +++ b/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic1IPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 @@ -184,7 +184,6 @@ Create And Check Memif1 On Agent Libmemif 1 After node restart ${out_c}= lmterm: Issue Command agent_libmemif_1 conn 0 0 Sleep ${SYNC_SLEEP} ${out}= lmterm: Issue Command agent_libmemif_1 show - Log Many ${out_c} ${out} Should Contain ${out} interface ip: ${LIBMEMIF_IP1} Should Contain ${out} link: up diff --git a/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic2IPv6.robot b/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic2IPv6.robot index c5af860ad1..f6fc4294dc 100644 --- a/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic2IPv6.robot +++ b/tests/robot/suites/trafficIPv6/libmemif/libmemif_slave_trafic2IPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -18,7 +18,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s ${LIBMEMIF_IP1}= 192.168.1.2 ${VPP2MEMIF_IP1}= 192.168.1.2 @@ -184,7 +184,6 @@ Create And Check Memif1 On Agent Libmemif 1 After node restart ${out_c}= lmterm: Issue Command agent_libmemif_1 conn 0 0 Sleep ${SYNC_SLEEP} ${out}= lmterm: Issue Command agent_libmemif_1 show - Log Many ${out_c} ${out} Should Contain ${out} interface ip: ${LIBMEMIF_IP1} Should Contain ${out} link: up diff --git a/tests/robot/suites/trafficIPv6/linux_traffic/1x_vpp_3x_namespaces_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/linux_traffic/1x_vpp_3x_namespaces_trafficIPv6.robot index ad11fa3c67..e436476d81 100644 --- a/tests/robot/suites/trafficIPv6/linux_traffic/1x_vpp_3x_namespaces_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/linux_traffic/1x_vpp_3x_namespaces_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -17,7 +17,7 @@ Test Teardown TestTeardown ${VARIABLES}= common ${ENV}= common ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s ${RESYNC_SLEEP}= 1s # wait for resync vpps after restart ${RESYNC_WAIT}= 30s @@ -122,16 +122,13 @@ Start VPP1 Again Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip netns exec ns1 ip a - Log ${out} Should Contain ${out} ns1_veth1_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns2 ip a - Log ${out} Should Contain ${out} ns2_veth2_linux Should Contain ${out} ns2_veth3_linux ${out}= Execute In Container agent_vpp_1 ip netns exec ns3 ip a - Log ${out} Should Contain ${out} ns3_veth3_linux Check Linux Interfaces node=agent_vpp_1 namespace=ns1 interface=ns1_veth1 @@ -170,50 +167,37 @@ Try to Ping6 among namespaces *** Keywords *** Check Linux Interfaces [Arguments] ${node} ${namespace} ${interface} - Log Many ${node} ${namespace} ${interface} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip a - Log ${out} Should Contain ${out} ${interface} Check Linux Routes [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via Check Linux Routes Gateway [Arguments] ${node} ${namespace} ${ip} ${next_hop}=${EMPTY} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} ${ip} via ${next_hop} Check Linux Default Routes [Arguments] ${node} ${namespace} ${next_hop} - Log Many ${node} ${namespace} ${next_hop} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Contain ${out} default via ${next_hop} Check Linux Routes Metric [Arguments] ${node} ${namespace} ${ip} ${metric} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Match Regexp ${out} ${ip} via.*metric ${metric}\\s Check Removed Linux Route [Arguments] ${node} ${namespace} ${ip} - Log Many ${node} ${namespace} ${out}= Execute In Container ${node} ip netns exec ${namespace} ip route show - Log ${out} Should Not Contain ${out} ${ip} via Ping6 in namespace [Arguments] ${node} ${namespace} ${ip} ${out}= Execute In Container ${node} ip netns exec ${namespace} ping6 -c 5 ${ip} - Log ${out} Should Contain ${out} from ${ip} Should Not Contain ${out} 100% packet loss diff --git a/tests/robot/suites/trafficIPv6/physical_int_traffic/physical_int_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/physical_int_traffic/physical_int_trafficIPv6.robot index b02b534cc9..5b41b3849c 100644 --- a/tests/robot/suites/trafficIPv6/physical_int_traffic/physical_int_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/physical_int_traffic/physical_int_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown @@ -64,14 +64,12 @@ Setup Interfaces Check Linux Interfaces On VPP1 ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} # ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 # Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 @@ -87,14 +85,12 @@ Check Interfaces On VPP1 Check Linux Interfaces On VPP2 ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} # ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 # Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 diff --git a/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_and_route_config_order_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_and_route_config_order_trafficIPv6.robot index 6d26ca3f83..713035806c 100644 --- a/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_and_route_config_order_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_and_route_config_order_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -38,7 +38,7 @@ ${IP_VPP2_MEMIF1}= fd33::1:a:0:0:2 ${PREFIX}= 64 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 50s @@ -91,24 +91,20 @@ Add Static Route From VPP2 To VPP1 Show Routes On VPP1 Linux ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route1} Show Route To VPP2 Configured On VPP1 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route1} Show Route To VPP1 Configured On VPP2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 @@ -178,24 +174,20 @@ Add VPP2_memif1 Interface 2 Show Routes On VPP1 Linux 2 ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route2} Show Route To VPP2 Configured On VPP1 2 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux 2 ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route2} Show Route To VPP1 Configured On VPP2 2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 diff --git a/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_trafficIPv6.robot index df2c9a166a..12ba5661c0 100644 --- a/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/tap_int_traffic/tap_int_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -54,7 +54,6 @@ Add VPP1_TAP1 Interface Check VPP1_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_VPP1_TAP1} ${actual_state}= vpp_term: Check TAP IP6 interface State agent_vpp_1 ${NAME_VPP1_TAP1} mac=${MAC_VPP1_TAP1} ipv6=${IP_VPP1_TAP1}/${PREFIX} state=${UP_STATE} @@ -77,7 +76,6 @@ Add VPP2_TAP1 Interface Check VPP2_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} vpp_term: Interface Is Created node=agent_vpp_2 mac=${MAC_VPP2_TAP1} ${actual_state}= vpp_term: Check TAP IP6 interface State agent_vpp_2 ${NAME_VPP2_TAP1} mac=${MAC_VPP2_TAP1} ipv6=${IP_VPP2_TAP1}/${PREFIX} state=${UP_STATE} @@ -143,12 +141,10 @@ Create linux_VPP1_TAP1 And linux_VPP2_TAP1 Interfaces After Resync Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP1_TAP1} Check Interfaces On VPP1 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_TAP1} @@ -156,12 +152,10 @@ Check Interfaces On VPP1 After Resync Check Linux Interfaces On VPP2 After Resync ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP2_TAP1} Check Interfaces On VPP2 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_TAP1} diff --git a/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_and_route_config_order_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_and_route_config_order_trafficIPv6.robot index 5691c1e0f5..5b397c8bc5 100644 --- a/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_and_route_config_order_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_and_route_config_order_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown @@ -36,7 +36,7 @@ ${IP_VPP2_MEMIF1}= fd33::1:a:0:0:2 ${PREFIX}= 64 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 50s @@ -90,24 +90,20 @@ Add Static Route From VPP2 To VPP1 Show Routes On VPP1 Linux ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route1} Show Route To VPP2 Configured On VPP1 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route1}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route1} Show Route To VPP1 Configured On VPP2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 @@ -177,24 +173,20 @@ Add VPP2_memif1 Interface 2 Show Routes On VPP1 Linux 2 ${out}= Execute In Container agent_vpp_1 ip addr show linux_${NAME_VPP1_TAP1} - Log ${out} ${linux_vpp1_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP1_TAP1} Set Suite Variable ${linux_vpp1_tap1_route2} Show Route To VPP2 Configured On VPP1 2 ${out}= vpp_term: Show Ip Fib agent_vpp_1 ${IP_VPP2_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP2_MEMIF1} Show Routes On VPP2 Linux 2 ${out}= Execute In Container agent_vpp_2 ip addr show linux_${NAME_VPP2_TAP1} - Log ${out} ${linux_vpp2_tap1_route2}= Get Lines Containing String ${out} linux_${NAME_VPP2_TAP1} Set Suite Variable ${linux_vpp2_tap1_route2} Show Route To VPP1 Configured On VPP2 2 ${out}= vpp_term: Show Ip Fib agent_vpp_2 ${IP_VPP1_TAP1_NETWORK}/${PREFIX} - Log ${out} Should Contain ${out} via ${IP_VPP1_MEMIF1} Check Ping From VPP1 To VPP2_memif1 Again diff --git a/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_trafficIPv6.robot index 5ddcaa7a9d..32328f1edf 100644 --- a/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/tapv2_int_traffic/tapv2_int_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown @@ -34,7 +34,7 @@ ${IP_VPP2_MEMIF1}= fd33::1:a:0:0:2 ${PREFIX}= 64 ${UP_STATE}= up ${WAIT_TIMEOUT}= 20s -${SYNC_SLEEP}= 2s +${SYNC_SLEEP}= 3s # wait for resync vpps after restart ${RESYNC_WAIT}= 50s @@ -55,7 +55,6 @@ Add VPP1_TAP1 Interface Check VPP1_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vpp_term: Interface Is Created node=agent_vpp_1 mac=${MAC_VPP1_TAP1} ${actual_state}= vpp_term: Check TAPv2 interface State agent_vpp_1 ${NAME_VPP1_TAP1} mac=${MAC_VPP1_TAP1} ipv6=${IP_VPP1_TAP1}/${PREFIX} state=${UP_STATE} @@ -75,7 +74,6 @@ Add VPP2_TAP1 Interface Check VPP2_TAP1 Interface Is Created ${interfaces}= vat_term: Interfaces Dump node=agent_vpp_1 - Log ${interfaces} vpp_term: Interface Is Created node=agent_vpp_2 mac=${MAC_VPP2_TAP1} ${actual_state}= vpp_term: Check TAPv2 interface State agent_vpp_2 ${NAME_VPP2_TAP1} mac=${MAC_VPP2_TAP1} ipv6=${IP_VPP2_TAP1}/${PREFIX} state=${UP_STATE} @@ -141,12 +139,10 @@ Create linux_VPP1_TAP1 And linux_VPP2_TAP1 Interfaces After Resync Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP1_TAP1} Check Interfaces On VPP1 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_1 interface=${NAME_VPP1_TAP1} @@ -154,12 +150,10 @@ Check Interfaces On VPP1 After Resync Check Linux Interfaces On VPP2 After Resync ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} linux_${NAME_VPP2_TAP1} Check Interfaces On VPP2 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_MEMIF1} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name node=agent_vpp_2 interface=${NAME_VPP2_TAP1} diff --git a/tests/robot/suites/trafficIPv6/veth_af_packet_traffic/test_data/veth_basicIPv6.conf b/tests/robot/suites/trafficIPv6/veth_af_packet_traffic/test_data/veth_basicIPv6.conf deleted file mode 100644 index 0be1450ec9..0000000000 --- a/tests/robot/suites/trafficIPv6/veth_af_packet_traffic/test_data/veth_basicIPv6.conf +++ /dev/null @@ -1,31 +0,0 @@ -sfc_controller_config_version: 1 -description: Basic Example static config for hosting 3 containers with a vnf-agent and 1 container with agent and vpp - -host_entities: - - name: agent_vpp_1 - mgmnt_ip_address: 192.168.0.1 - loopback_mac_addr: 02:00:00:AA:BB:00 - loopback_ipv4: 6.0.0.100 - loopback_ipv4_mask: 255.255.255.0 - -sfc_entities: - - name: three-sample-vnf-containers - description: Wire 3 VNF containers to the vpp switch - type: 2 - elements: - - container: node_1 - port_label: nod1_veth - ipv6_addr: fd30::1:a:0:0:1 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: node_2 - port_label: nod2_veth - ipv6_addr: fd30::1:a:0:0:2 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - - container: node_3 - port_label: nod3_veth - ipv6_addr: fd30::1:a:0:0:3 - etcd_vpp_switch_key: agent_vpp_1 - type: 3 - diff --git a/tests/robot/suites/trafficIPv6/veth_af_packet_traffic/veth_af_packet_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/veth_af_packet_traffic/veth_af_packet_trafficIPv6.robot index 9190ec79ac..6fa034fafd 100644 --- a/tests/robot/suites/trafficIPv6/veth_af_packet_traffic/veth_af_packet_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/veth_af_packet_traffic/veth_af_packet_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Suite Cleanup Test Setup TestSetup @@ -17,19 +17,19 @@ Test Teardown TestTeardown *** Variables *** ${VARIABLES}= common ${ENV}= common -${WAIT_TIMEOUT}= 20s +${WAIT_TIMEOUT}= 90s ${SYNC_SLEEP}= 5s ${RESYNC_SLEEP}= 20s -${AGENT1_VETH_MAC}= 02:00:00:00:00:01 -${AGENT2_VETH_MAC}= 02:00:00:00:00:02 -${AGENT3_VETH_MAC}= 02:00:00:00:00:03 +${AGENT1_VETH_MAC}= 12:11:11:11:11:11 +${AGENT2_VETH_MAC}= 12:11:11:11:11:12 +${AGENT3_VETH_MAC}= 12:11:11:11:11:13 ${IP_1}= fd30::1:a:0:0:1 ${IP_2}= fd30::1:a:0:0:2 ${IP_3}= fd30::1:a:0:0:3 ${VARIABLES}= common ${ENV}= common -${PREFIX}= 128 +${PREFIX}= 64 *** Test Cases *** @@ -37,7 +37,26 @@ Configure Environment [Tags] setup ${DATA_FOLDER}= Catenate SEPARATOR=/ ${CURDIR} ${TEST_DATA_FOLDER} Set Suite Variable ${DATA_FOLDER} - Configure Environment 4 veth_basicIPv6.conf + Configure Environment 7 + +Configure Interfaces + Write To Machine vpp_agent_ctl vpp-agent-ctl ${AGENT_VPP_ETCD_CONF_PATH} -ps + + vpp_ctl: Put Veth Interface With IP And Namespace node=agent_vpp_1 name=node1_veth namespace=node_1 mac=12:11:11:11:11:11 peer=vpp1_veth1 ip=${IP_1} prefix=${PREFIX} + vpp_ctl: Put Veth Interface And Namespace node=agent_vpp_1 name=vpp1_veth1 namespace=agent_vpp_1 mac=12:12:12:12:12:11 peer=node1_veth + vpp_ctl: Put Afpacket Interface node=agent_vpp_1 name=vpp1_afpacket1 mac=a2:a1:a1:a1:a1:a1 host_int=vpp1_veth1 + + vpp_ctl: Put Veth Interface With IP And Namespace node=agent_vpp_1 name=node2_veth namespace=node_2 mac=12:11:11:11:11:12 peer=vpp1_veth2 ip=${IP_2} prefix=${PREFIX} + vpp_ctl: Put Veth Interface And Namespace node=agent_vpp_1 name=vpp1_veth2 namespace=agent_vpp_1 mac=12:12:12:12:12:12 peer=node2_veth + vpp_ctl: Put Afpacket Interface node=agent_vpp_1 name=vpp1_afpacket2 mac=a2:a1:a1:a1:a1:a2 host_int=vpp1_veth2 + + vpp_ctl: Put Veth Interface With IP And Namespace node=agent_vpp_1 name=node3_veth namespace=node_3 mac=12:11:11:11:11:13 peer=vpp1_veth3 ip=${IP_3} prefix=${PREFIX} + vpp_ctl: Put Veth Interface And Namespace node=agent_vpp_1 name=vpp1_veth3 namespace=agent_vpp_1 mac=12:12:12:12:12:13 peer=node3_veth + vpp_ctl: Put Afpacket Interface node=agent_vpp_1 name=vpp1_afpacket3 mac=a2:a1:a1:a1:a1:a3 host_int=vpp1_veth3 + + @{ints}= Create List vpp1_afpacket1 vpp1_afpacket2 vpp1_afpacket3 + vpp_ctl: Put Bridge Domain node=agent_vpp_1 name=east-west-bd ints=${ints} + Sleep ${SYNC_SLEEP} Show Interfaces And Other Objects @@ -394,14 +413,16 @@ Show Interfaces And Other Objects Make Datastore Snapshots before_check stuff Check Stuff - Show Interfaces And Other Objects - vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth enabled=1 - vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_2_nod2_veth enabled=1 - vat_term: Check Afpacket Interface State agent_vpp_1 IF_AFPIF_VSWITCH_node_3_nod3_veth enabled=1 - linux: Interface With IP Is Created node_1 ${AGENT1_VETH_MAC} ${IP_1}/${PREFIX} - linux: Interface With IP Is Created node_2 ${AGENT2_VETH_MAC} ${IP_2}/${PREFIX} - linux: Interface With IP Is Created node_3 ${AGENT3_VETH_MAC} ${IP_3}/${PREFIX} - vat_term: BD Is Created agent_vpp_1 IF_AFPIF_VSWITCH_node_1_nod1_veth IF_AFPIF_VSWITCH_node_2_nod2_veth IF_AFPIF_VSWITCH_node_3_nod3_veth + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} Show Interfaces And Other Objects + #${WAIT_TIMEOUT} in first keyword is over 20s because after restart agent_vpp_1 need waiting to interface internal name + #Bug: CV-595 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Afpacket Interface State agent_vpp_1 vpp1_afpacket1 enabled=1 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Afpacket Interface State agent_vpp_1 vpp1_afpacket2 enabled=1 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: Check Afpacket Interface State agent_vpp_1 vpp1_afpacket3 enabled=1 + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} linux: Interface With IP Is Created node_1 ${AGENT1_VETH_MAC} ${IP_1}/${PREFIX} + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} linux: Interface With IP Is Created node_2 ${AGENT2_VETH_MAC} ${IP_2}/${PREFIX} + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} linux: Interface With IP Is Created node_3 ${AGENT3_VETH_MAC} ${IP_3}/${PREFIX} + Wait Until Keyword Succeeds ${WAIT_TIMEOUT} ${SYNC_SLEEP} vat_term: BD Is Created agent_vpp_1 vpp1_afpacket1 vpp1_afpacket2 vpp1_afpacket3 diff --git a/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_trafficIPv6.robot index 43ff6d71e7..971a307930 100644 --- a/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown Test Setup TestSetup @@ -65,54 +65,40 @@ Setup Interfaces Check Linux Interfaces On VPP1 ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_tap1 - Log ${int} Should Contain ${out} ${int} Check Linux Interfaces On VPP2 ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_tap1 - Log ${int} Should Contain ${out} ${int} Check Bridge Domain On VPP1 Is Created @@ -163,53 +149,40 @@ Start VPP1 And VPP2 Again Check Linux Interfaces On VPP1 After Resync ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Should Contain ${out} linux_vpp1_tap1 Check Interfaces On VPP1 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_loop1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_tap1 - Log ${int} Should Contain ${out} ${int} Check Linux Interfaces On VPP2 After Resync ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Should Contain ${out} linux_vpp2_tap1 Check Interfaces On VPP2 After Resync ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_vxlan1 - Log ${int} Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_loop1 Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_tap1 - Log ${int} Should Contain ${out} ${int} Check Bridge Domain On VPP1 Is Created After Resync diff --git a/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrfIPv6.robot b/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrfIPv6.robot index d91feb0e15..6bd036d93d 100644 --- a/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrfIPv6.robot +++ b/tests/robot/suites/trafficIPv6/veth_afpacket_memif_vxlan_traffic/veth_afpacket_memif_vxlan_traffic_other_vrfIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown @@ -62,13 +62,11 @@ Setup Interfaces Check Linux Interfaces On VPP1 ${out}= Execute In Container agent_vpp_1 ip a - Log ${out} Should Contain ${out} vpp1_veth2@vpp1_veth1 Should Contain ${out} vpp1_veth1@vpp1_veth2 Check Interfaces On VPP1 ${out}= vpp_term: Show Interfaces agent_vpp_1 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_memif1 Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_1 vpp1_afpacket1 @@ -78,13 +76,11 @@ Check Interfaces On VPP1 Check Linux Interfaces On VPP2 ${out}= Execute In Container agent_vpp_2 ip a - Log ${out} Should Contain ${out} vpp2_veth2@vpp2_veth1 Should Contain ${out} vpp2_veth1@vpp2_veth2 Check Interfaces On VPP2 ${out}= vpp_term: Show Interfaces agent_vpp_2 - Log ${out} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_memif1 Should Contain ${out} ${int} ${int}= vpp_ctl: Get Interface Internal Name agent_vpp_2 vpp2_afpacket1 diff --git a/tests/robot/suites/trafficIPv6/vpp_2novpp_memif_traffic/vpp_2novpp_memif_trafficIPv6.robot b/tests/robot/suites/trafficIPv6/vpp_2novpp_memif_traffic/vpp_2novpp_memif_trafficIPv6.robot index 44d7ef7777..910cd3b0d1 100644 --- a/tests/robot/suites/trafficIPv6/vpp_2novpp_memif_traffic/vpp_2novpp_memif_trafficIPv6.robot +++ b/tests/robot/suites/trafficIPv6/vpp_2novpp_memif_traffic/vpp_2novpp_memif_trafficIPv6.robot @@ -8,7 +8,7 @@ Resource ../../../variables/${VARIABLES}_variables.robot Resource ../../../libraries/all_libs.robot Resource ../../../libraries/pretty_keywords.robot -Force Tags trafficIPv6 +Force Tags traffic IPv6 ExpectedFailure Suite Setup Testsuite Setup Suite Teardown Testsuite Teardown diff --git a/tests/robot/variables/ccmts_vm_variables.robot b/tests/robot/variables/ccmts_vm_variables.robot index 44dab02297..65d99ae9e7 100644 --- a/tests/robot/variables/ccmts_vm_variables.robot +++ b/tests/robot/variables/ccmts_vm_variables.robot @@ -8,4 +8,4 @@ ${DOCKER_HOST_PSWD} rsa_id ${AGENT_VPP_IMAGE_NAME} ligato/vpp-agent:pantheon-dev ${VNF_IMAGE_NAME} ligato/vpp-agent:pantheon-dev -${SFC_CONTROLLER_IMAGE_NAME} ligato/prod_sfc_controller:latest +${SFC_CONTROLLER_IMAGE_NAME} ligato/dev_sfc_controller:latest diff --git a/tests/robot/variables/common_variables.robot b/tests/robot/variables/common_variables.robot index f2ed27686d..30fa78f9bd 100644 --- a/tests/robot/variables/common_variables.robot +++ b/tests/robot/variables/common_variables.robot @@ -19,7 +19,7 @@ ${KAFKA_SERVER_CREATE} ${DOCKER_COMMAND} create -it -p 2181:2181 -p ${KAFKA_SERVER_DESTROY} ${DOCKER_COMMAND} rm -f kafka #${SFC_CONTROLLER_IMAGE_NAME} containers.cisco.com/odpm_jenkins_gen/dev_sfc_controller:master -${SFC_CONTROLLER_IMAGE_NAME} ligato/prod_sfc_controller +${SFC_CONTROLLER_IMAGE_NAME} ligato/dev_sfc_controller ${SFC_CONTROLLER_CONF_PATH} /opt/sfc-controller/dev/sfc.conf # Variables for container with agent and VPP @@ -74,7 +74,8 @@ ${AGENT_VPP_4_VPP_TERM_PROMPT} vpp# ${AGENT_VPP_4_VPP_VAT_PROMPT} vat# # Variables for container with agent and without vpp -${AGENT_IMAGE_NAME} ligato/dev-cn-infra:latest +#${AGENT_IMAGE_NAME} ligato/dev-cn-infra:latest +${AGENT_IMAGE_NAME} ligato/vpp-agent:pantheon-dev ${AGENT_ETCD_CONF_PATH} /opt/vpp-agent/dev/etcd.conf ${AGENT_KAFKA_CONF_PATH} /opt/vpp-agent/dev/kafka.conf @@ -128,7 +129,7 @@ ${RESULTS_FOLDER} results ${RESULTS_FOLDER_SUITE} ${RESULTS_FOLDER}/${SUITE_NAME} ${TEST_DATA_FOLDER} test_data ${REST_CALL_SLEEP} 0 -${SSH_READ_DELAY} 6 +${SSH_READ_DELAY} 1 ${EXAMPLE_PLUGIN_NAME} example_plugin.so diff --git a/tests/vppcallmock/vpp_ctx_mock.go b/tests/vppcallmock/vpp_ctx_mock.go index e6adbf6b8b..cb79009918 100644 --- a/tests/vppcallmock/vpp_ctx_mock.go +++ b/tests/vppcallmock/vpp_ctx_mock.go @@ -21,18 +21,7 @@ import ( govppapi "git.fd.io/govpp.git/api" govpp "git.fd.io/govpp.git/core" log "github.com/ligato/cn-infra/logging/logrus" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/acl" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/af_packet" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/bfd" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/interfaces" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/ip" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/memif" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/nat" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/stn" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/tap" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/tapv2" "github.com/ligato/vpp-agent/plugins/vpp/binapi/vpe" - "github.com/ligato/vpp-agent/plugins/vpp/binapi/vxlan" . "github.com/onsi/gomega" "github.com/sirupsen/logrus" ) @@ -55,7 +44,7 @@ func SetupTestCtx(t *testing.T) *TestCtx { RegisterTestingT(t) ctx := &TestCtx{ - MockVpp: &mock.VppAdapter{}, + MockVpp: mock.NewVppAdapter(), } var err error @@ -113,19 +102,6 @@ type HandleReplies struct { func (ctx *TestCtx) MockReplies(dataList []*HandleReplies) { var sendControlPing bool - ctx.MockVpp.RegisterBinAPITypes(acl.Types) - ctx.MockVpp.RegisterBinAPITypes(af_packet.Types) - ctx.MockVpp.RegisterBinAPITypes(bfd.Types) - ctx.MockVpp.RegisterBinAPITypes(nat.Types) - ctx.MockVpp.RegisterBinAPITypes(stn.Types) - ctx.MockVpp.RegisterBinAPITypes(interfaces.Types) - ctx.MockVpp.RegisterBinAPITypes(ip.Types) - ctx.MockVpp.RegisterBinAPITypes(memif.Types) - ctx.MockVpp.RegisterBinAPITypes(tap.Types) - ctx.MockVpp.RegisterBinAPITypes(tapv2.Types) - ctx.MockVpp.RegisterBinAPITypes(vpe.Types) - ctx.MockVpp.RegisterBinAPITypes(vxlan.Types) - ctx.MockVpp.MockReplyHandler(func(request mock.MessageDTO) (reply []byte, msgID uint16, prepared bool) { // Following types are not automatically stored in mock adapter's map and will be sent with empty MsgName // TODO: initialize mock adapter's map with these diff --git a/vendor/git.fd.io/govpp.git/adapter/adapter.go b/vendor/git.fd.io/govpp.git/adapter/adapter.go index 7d3d1e429a..aa34329454 100644 --- a/vendor/git.fd.io/govpp.git/adapter/adapter.go +++ b/vendor/git.fd.io/govpp.git/adapter/adapter.go @@ -22,7 +22,7 @@ import ( var ErrNotImplemented = errors.New("not implemented for this OS") // MsgCallback defines func signature for message callback. -type MsgCallback func(msgID uint16, context uint32, data []byte) +type MsgCallback func(msgID uint16, data []byte) // VppAdapter provides connection to VPP. It is responsible for sending and receiving of binary-encoded messages to/from VPP. type VppAdapter interface { diff --git a/vendor/git.fd.io/govpp.git/adapter/mock/mock_adapter.go b/vendor/git.fd.io/govpp.git/adapter/mock/mock_adapter.go index 3f5686f352..cdf2081bc2 100644 --- a/vendor/git.fd.io/govpp.git/adapter/mock/mock_adapter.go +++ b/vendor/git.fd.io/govpp.git/adapter/mock/mock_adapter.go @@ -90,8 +90,15 @@ const ( ) // NewVppAdapter returns a new mock adapter. -func NewVppAdapter() adapter.VppAdapter { - return &VppAdapter{} +func NewVppAdapter() *VppAdapter { + a := &VppAdapter{ + msgIDSeq: 1000, + msgIDsToName: make(map[uint16]string), + msgNameToIds: make(map[string]uint16), + binAPITypes: make(map[string]reflect.Type), + } + a.registerBinAPITypes() + return a } // Connect emulates connecting the process to VPP. @@ -119,21 +126,16 @@ func (a *VppAdapter) GetMsgNameByID(msgID uint16) (string, bool) { a.access.Lock() defer a.access.Unlock() - a.initMaps() msgName, found := a.msgIDsToName[msgID] return msgName, found } -// RegisterBinAPITypes registers binary API message types in the mock adapter. -func (a *VppAdapter) RegisterBinAPITypes(binAPITypes map[string]reflect.Type) { +func (a *VppAdapter) registerBinAPITypes() { a.access.Lock() defer a.access.Unlock() - a.initMaps() - for _, v := range binAPITypes { - if msg, ok := reflect.New(v).Interface().(api.Message); ok { - a.binAPITypes[msg.GetMessageName()] = v - } + for _, msg := range api.GetAllMessages() { + a.binAPITypes[msg.GetMessageName()] = reflect.TypeOf(msg).Elem() } } @@ -177,8 +179,16 @@ func (a *VppAdapter) ReplyBytes(request MessageDTO, reply api.Message) ([]byte, log.Println("ReplyBytes ", replyMsgID, " ", reply.GetMessageName(), " clientId: ", request.ClientID) buf := new(bytes.Buffer) - struc.Pack(buf, &codec.VppReplyHeader{VlMsgID: replyMsgID, Context: request.ClientID}) - struc.Pack(buf, reply) + err = struc.Pack(buf, &codec.VppReplyHeader{ + VlMsgID: replyMsgID, + Context: request.ClientID, + }) + if err != nil { + return nil, err + } + if err = struc.Pack(buf, reply); err != nil { + return nil, err + } return buf.Bytes(), nil } @@ -198,7 +208,6 @@ func (a *VppAdapter) GetMsgID(msgName string, msgCrc string) (uint16, error) { a.access.Lock() defer a.access.Unlock() - a.initMaps() msgID, found := a.msgNameToIds[msgName] if found { @@ -213,24 +222,10 @@ func (a *VppAdapter) GetMsgID(msgName string, msgCrc string) (uint16, error) { return msgID, nil } -// initMaps initializes internal maps (if not already initialized). -func (a *VppAdapter) initMaps() { - if a.msgIDsToName == nil { - a.msgIDsToName = map[uint16]string{} - a.msgNameToIds = map[string]uint16{} - a.msgIDSeq = 1000 - } - - if a.binAPITypes == nil { - a.binAPITypes = map[string]reflect.Type{} - } -} - // SendMsg emulates sending a binary-encoded message to VPP. func (a *VppAdapter) SendMsg(clientID uint32, data []byte) error { switch a.mode { case useReplyHandlers: - a.initMaps() for i := len(a.replyHandlers) - 1; i >= 0; i-- { replyHandler := a.replyHandlers[i] @@ -249,7 +244,7 @@ func (a *VppAdapter) SendMsg(clientID uint32, data []byte) error { Data: data, }) if finished { - a.callback(msgID, clientID, reply) + a.callback(msgID, reply) return nil } } @@ -280,7 +275,7 @@ func (a *VppAdapter) SendMsg(clientID uint32, data []byte) error { struc.Pack(buf, &codec.VppOtherHeader{VlMsgID: msgID}) } struc.Pack(buf, msg.Msg) - a.callback(msgID, context, buf.Bytes()) + a.callback(msgID, buf.Bytes()) } a.replies = a.replies[1:] @@ -299,7 +294,7 @@ func (a *VppAdapter) SendMsg(clientID uint32, data []byte) error { msgID := uint16(defaultReplyMsgID) struc.Pack(buf, &codec.VppReplyHeader{VlMsgID: msgID, Context: clientID}) struc.Pack(buf, &defaultReply{}) - a.callback(msgID, clientID, buf.Bytes()) + a.callback(msgID, buf.Bytes()) } return nil } diff --git a/vendor/git.fd.io/govpp.git/adapter/vppapiclient/vppapiclient_adapter.go b/vendor/git.fd.io/govpp.git/adapter/vppapiclient/vppapiclient_adapter.go index 7aafa5527b..e62bccd5f8 100644 --- a/vendor/git.fd.io/govpp.git/adapter/vppapiclient/vppapiclient_adapter.go +++ b/vendor/git.fd.io/govpp.git/adapter/vppapiclient/vppapiclient_adapter.go @@ -28,7 +28,7 @@ package vppapiclient #include #include -extern void go_msg_callback(uint16_t msg_id, uint32_t context, void* data, size_t size); +extern void go_msg_callback(uint16_t msg_id, void* data, size_t size); typedef struct __attribute__((__packed__)) _req_header { uint16_t msg_id; @@ -38,14 +38,13 @@ typedef struct __attribute__((__packed__)) _req_header { typedef struct __attribute__((__packed__)) _reply_header { uint16_t msg_id; - uint32_t context; // currently not all reply messages contain context field } reply_header_t; static void govpp_msg_callback (unsigned char *data, int size) { reply_header_t *header = ((reply_header_t *)data); - go_msg_callback(ntohs(header->msg_id), ntohl(header->context), data, size); + go_msg_callback(ntohs(header->msg_id), data, size); } static int @@ -204,10 +203,10 @@ func fileExists(name string) bool { } //export go_msg_callback -func go_msg_callback(msgID C.uint16_t, context C.uint32_t, data unsafe.Pointer, size C.size_t) { +func go_msg_callback(msgID C.uint16_t, data unsafe.Pointer, size C.size_t) { // convert unsafe.Pointer to byte slice slice := &reflect.SliceHeader{Data: uintptr(data), Len: int(size), Cap: int(size)} byteArr := *(*[]byte)(unsafe.Pointer(slice)) - vppClient.callback(uint16(msgID), uint32(context), byteArr) + vppClient.callback(uint16(msgID), byteArr) } diff --git a/vendor/git.fd.io/govpp.git/api/api.go b/vendor/git.fd.io/govpp.git/api/api.go index 39fe60f0c3..9b7f0fff19 100644 --- a/vendor/git.fd.io/govpp.git/api/api.go +++ b/vendor/git.fd.io/govpp.git/api/api.go @@ -58,21 +58,6 @@ type DataType interface { GetCrcString() string } -// MessageDecoder provides functionality for decoding binary data to generated API messages. -type MessageDecoder interface { - // DecodeMsg decodes binary-encoded data of a message into provided Message structure. - DecodeMsg(data []byte, msg Message) error -} - -// MessageIdentifier provides identification of generated API messages. -type MessageIdentifier interface { - // GetMessageID returns message identifier of given API message. - GetMessageID(msg Message) (uint16, error) - - // LookupByID looks up message name and crc by ID - LookupByID(msgID uint16) (Message, error) -} - // ChannelProvider provides the communication channel with govpp core. type ChannelProvider interface { // NewAPIChannel returns a new channel for communication with VPP via govpp core. @@ -86,9 +71,6 @@ type ChannelProvider interface { // Channel provides methods for direct communication with VPP channel. type Channel interface { - // GetID returns channel's ID - GetID() uint16 - // SendRequest asynchronously sends a request to VPP. Returns a request context, that can be used to call ReceiveReply. // In case of any errors by sending, the error will be delivered to ReplyChan (and returned by ReceiveReply). SendRequest(msg Message) RequestCtx @@ -101,10 +83,7 @@ type Channel interface { // SubscribeNotification subscribes for receiving of the specified notification messages via provided Go channel. // Note that the caller is responsible for creating the Go channel with preferred buffer size. If the channel's // buffer is full, the notifications will not be delivered into it. - SubscribeNotification(notifChan chan Message, msgFactory func() Message) (*NotifSubscription, error) - - // UnsubscribeNotification unsubscribes from receiving the notifications tied to the provided notification subscription. - UnsubscribeNotification(subscription *NotifSubscription) error + SubscribeNotification(notifChan chan Message, event Message) (SubscriptionCtx, error) // SetReplyTimeout sets the timeout for replies from VPP. It represents the maximum time the API waits for a reply // from VPP before returning an error. @@ -114,14 +93,14 @@ type Channel interface { Close() } -// RequestCtx is helper interface which allows to receive reply on request context data +// RequestCtx is helper interface which allows to receive reply on request. type RequestCtx interface { // ReceiveReply receives a reply from VPP (blocks until a reply is delivered from VPP, or until an error occurs). // The reply will be decoded into the msg argument. Error will be returned if the response cannot be received or decoded. ReceiveReply(msg Message) error } -// MultiRequestCtx is helper interface which allows to receive reply on multi-request context data +// MultiRequestCtx is helper interface which allows to receive reply on multi-request. type MultiRequestCtx interface { // ReceiveReply receives a reply from VPP (blocks until a reply is delivered from VPP, or until an error occurs). // The reply will be decoded into the msg argument. If the last reply has been already consumed, lastReplyReceived is @@ -130,13 +109,13 @@ type MultiRequestCtx interface { ReceiveReply(msg Message) (lastReplyReceived bool, err error) } -// NotifSubscription represents a subscription for delivery of specific notification messages. -type NotifSubscription struct { - NotifChan chan Message // channel where notification messages will be delivered to - MsgFactory func() Message // function that returns a new instance of the specific message that is expected as a notification - // TODO: use Message directly here, not a factory, eliminating need to allocation +// SubscriptionCtx is helper interface which allows to control subscription for notification events. +type SubscriptionCtx interface { + // Unsubscribe unsubscribes from receiving the notifications tied to the subscription context. + Unsubscribe() error } +// map of registered messages var registeredMessages = make(map[string]Message) // RegisterMessage is called from generated code to register message. diff --git a/vendor/git.fd.io/govpp.git/api/vppapi_errors.go b/vendor/git.fd.io/govpp.git/api/vppapi_errors.go index c921e14f8b..18ab87f0b9 100644 --- a/vendor/git.fd.io/govpp.git/api/vppapi_errors.go +++ b/vendor/git.fd.io/govpp.git/api/vppapi_errors.go @@ -5,16 +5,26 @@ import ( "strconv" ) +// RetvalToVPPApiError returns error for retval value. +// Retval 0 returns nil error. +func RetvalToVPPApiError(retval int32) error { + if retval == 0 { + return nil + } + return VPPApiError(retval) +} + // VPPApiError represents VPP's vnet API error that is usually // returned as Retval field in replies from VPP binary API. type VPPApiError int32 func (e VPPApiError) Error() string { + errid := int64(e) var errstr string if s, ok := vppApiErrors[e]; ok { - errstr = s + errstr = fmt.Sprintf("%s (%d)", s, errid) } else { - errstr = strconv.Itoa(int(e)) + errstr = strconv.FormatInt(errid, 10) } return fmt.Sprintf("VPPApiError: %s", errstr) } diff --git a/vendor/git.fd.io/govpp.git/cmd/binapi-generator/generate.go b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/generate.go index 251d39decd..7cfe338dc8 100644 --- a/vendor/git.fd.io/govpp.git/cmd/binapi-generator/generate.go +++ b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/generate.go @@ -140,9 +140,9 @@ func generatePackage(ctx *context, w *bufio.Writer) error { if len(ctx.packageData.Services) > 0 { fmt.Fprintf(w, "/* Services */\n\n") - fmt.Fprintf(w, "type %s interface {\n", "Services") ctx.inputBuff = bytes.NewBuffer(ctx.inputData) ctx.inputLine = 0 + fmt.Fprintf(w, "type %s interface {\n", "Services") for _, svc := range ctx.packageData.Services { generateService(ctx, w, &svc) } @@ -171,22 +171,19 @@ func generatePackage(ctx *context, w *bufio.Writer) error { // generateHeader writes generated package header into w func generateHeader(ctx *context, w io.Writer) { fmt.Fprintln(w, "// Code generated by GoVPP binapi-generator. DO NOT EDIT.") - fmt.Fprintf(w, "// source: %s\n", ctx.inputFile) + fmt.Fprintf(w, "// source: %s\n", ctx.inputFile) fmt.Fprintln(w) fmt.Fprintln(w, "/*") - fmt.Fprintf(w, "Package %s is a generated VPP binary API of the '%s' VPP module.\n", ctx.packageName, ctx.moduleName) + fmt.Fprintf(w, " Package %s is a generated from VPP binary API module '%s'.\n", ctx.packageName, ctx.moduleName) fmt.Fprintln(w) - fmt.Fprintln(w, "It is generated from this file:") - fmt.Fprintf(w, "\t%s\n", filepath.Base(ctx.inputFile)) - fmt.Fprintln(w) - fmt.Fprintln(w, "It contains these VPP binary API objects:") + fmt.Fprintln(w, " It contains following objects:") var printObjNum = func(obj string, num int) { if num > 0 { if num > 1 { obj += "s" } - fmt.Fprintf(w, "\t%d %s\n", num, obj) + fmt.Fprintf(w, "\t%3d %s\n", num, obj) } } printObjNum("message", len(ctx.packageData.Messages)) @@ -194,6 +191,7 @@ func generateHeader(ctx *context, w io.Writer) { printObjNum("enum", len(ctx.packageData.Enums)) printObjNum("union", len(ctx.packageData.Unions)) printObjNum("service", len(ctx.packageData.Services)) + fmt.Fprintln(w) fmt.Fprintln(w, "*/") fmt.Fprintf(w, "package %s\n", ctx.packageName) fmt.Fprintln(w) @@ -207,6 +205,7 @@ func generateImports(ctx *context, w io.Writer) { fmt.Fprintln(w) fmt.Fprintf(w, "// Reference imports to suppress errors if they are not otherwise used.\n") + fmt.Fprintf(w, "var _ = api.RegisterMessage\n") fmt.Fprintf(w, "var _ = struc.Pack\n") fmt.Fprintf(w, "var _ = bytes.NewBuffer\n") fmt.Fprintln(w) @@ -239,7 +238,6 @@ func generateComment(ctx *context, w io.Writer, goName string, vppName string, o // If no other non-whitespace character then we are at the message header. if trimmed := strings.TrimSpace(line); trimmed == objTitle { objFound = true - fmt.Fprintf(w, "// Generated from '%s', line %d:\n", filepath.Base(ctx.inputFile), ctx.inputLine) fmt.Fprintln(w, "//") } } else { @@ -460,9 +458,6 @@ func generateMessage(ctx *context, w io.Writer, msg *Message) { // generate message type getter method generateMessageTypeGetter(w, name, msgType) - - // generate message factory - generateMessageFactory(w, name) } // generateField writes generated code for the field into w @@ -504,13 +499,7 @@ func generateService(ctx *context, w io.Writer, svc *Service) { reqTyp := camelCaseName(svc.RequestType) // method name is same as parameter type name by default - method := reqTyp - if svc.Stream { - // use Dump as prefix instead of suffix for stream services - if m := strings.TrimSuffix(method, "Dump"); method != m { - method = "Dump" + m - } - } + method := svc.MethodName() params := fmt.Sprintf("*%s", reqTyp) returns := "error" if replyTyp := camelCaseName(svc.ReplyType); replyTyp != "" { @@ -521,25 +510,28 @@ func generateService(ctx *context, w io.Writer, svc *Service) { } // generateMessageNameGetter generates getter for original VPP message name into the provider writer -func generateMessageNameGetter(w io.Writer, structName string, msgName string) { - fmt.Fprintln(w, "func (*"+structName+") GetMessageName() string {") - fmt.Fprintln(w, "\treturn \""+msgName+"\"") - fmt.Fprintln(w, "}") +func generateMessageNameGetter(w io.Writer, structName, msgName string) { + fmt.Fprintf(w, `func (*%s) GetMessageName() string { + return %q +} +`, structName, msgName) } // generateTypeNameGetter generates getter for original VPP type name into the provider writer -func generateTypeNameGetter(w io.Writer, structName string, msgName string) { - fmt.Fprintln(w, "func (*"+structName+") GetTypeName() string {") - fmt.Fprintln(w, "\treturn \""+msgName+"\"") - fmt.Fprintln(w, "}") +func generateTypeNameGetter(w io.Writer, structName, msgName string) { + fmt.Fprintf(w, `func (*%s) GetTypeName() string { + return %q +} +`, structName, msgName) } // generateCrcGetter generates getter for CRC checksum of the message definition into the provider writer -func generateCrcGetter(w io.Writer, structName string, crc string) { +func generateCrcGetter(w io.Writer, structName, crc string) { crc = strings.TrimPrefix(crc, "0x") - fmt.Fprintln(w, "func (*"+structName+") GetCrcString() string {") - fmt.Fprintln(w, "\treturn \""+crc+"\"") - fmt.Fprintln(w, "}") + fmt.Fprintf(w, `func (*%s) GetCrcString() string { + return %q +} +`, structName, crc) } // generateMessageTypeGetter generates message factory for the generated message into the provider writer @@ -556,10 +548,3 @@ func generateMessageTypeGetter(w io.Writer, structName string, msgType MessageTy } fmt.Fprintln(w, "}") } - -// generateMessageFactory generates message factory for the generated message into the provider writer -func generateMessageFactory(w io.Writer, structName string) { - fmt.Fprintln(w, "func New"+structName+"() api.Message {") - fmt.Fprintln(w, "\treturn &"+structName+"{}") - fmt.Fprintln(w, "}") -} diff --git a/vendor/git.fd.io/govpp.git/cmd/binapi-generator/main.go b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/main.go index 804521287f..b73a6993e4 100644 --- a/vendor/git.fd.io/govpp.git/cmd/binapi-generator/main.go +++ b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/main.go @@ -20,13 +20,13 @@ import ( "flag" "fmt" "io/ioutil" - "log" "os" "os/exec" "path/filepath" "strings" "github.com/bennyscetbun/jsongo" + "github.com/sirupsen/logrus" ) var ( @@ -38,15 +38,26 @@ var ( continueOnError = flag.Bool("continue-onerror", false, "Wheter to continue with next file on error.") ) +func init() { + flag.Parse() + if *debug { + logrus.SetLevel(logrus.DebugLevel) + } +} + func logf(f string, v ...interface{}) { if *debug { - log.Printf(f, v...) + logrus.Debugf(f, v...) } } -func main() { - flag.Parse() +var log = logrus.Logger{ + Level: logrus.InfoLevel, + Formatter: &logrus.TextFormatter{}, + Out: os.Stdout, +} +func main() { if *inputFile == "" && *inputDir == "" { fmt.Fprintln(os.Stderr, "ERROR: input-file or input-dir must be specified") os.Exit(1) @@ -143,7 +154,7 @@ func generateFromFile(inputFile, outputDir string) error { // count number of lines in generated output file cmd = exec.Command("wc", "-l", ctx.outputFile) if output, err := cmd.CombinedOutput(); err != nil { - log.Printf("wc command failed: %v\n%s", err, string(output)) + log.Warnf("wc command failed: %v\n%s", err, string(output)) } else { logf("generated lines: %s", output) } diff --git a/vendor/git.fd.io/govpp.git/cmd/binapi-generator/objects.go b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/objects.go new file mode 100644 index 0000000000..26810850f9 --- /dev/null +++ b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/objects.go @@ -0,0 +1,120 @@ +package main + +import "strings" + +// Package represents collection of objects parsed from VPP binary API JSON data +type Package struct { + APIVersion string + Enums []Enum + Unions []Union + Types []Type + Messages []Message + Services []Service + RefMap map[string]string +} + +// MessageType represents the type of a VPP message +type MessageType int + +const ( + requestMessage MessageType = iota // VPP request message + replyMessage // VPP reply message + eventMessage // VPP event message + otherMessage // other VPP message +) + +// Message represents VPP binary API message +type Message struct { + Name string + CRC string + Fields []Field +} + +// Type represents VPP binary API type +type Type struct { + Name string + CRC string + Fields []Field +} + +// Union represents VPP binary API union +type Union struct { + Name string + CRC string + Fields []Field +} + +// Field represents VPP binary API object field +type Field struct { + Name string + Type string + Length int + SizeFrom string +} + +func (f *Field) IsArray() bool { + return f.Length > 0 || f.SizeFrom != "" +} + +// Enum represents VPP binary API enum +type Enum struct { + Name string + Type string + Entries []EnumEntry +} + +// EnumEntry represents VPP binary API enum entry +type EnumEntry struct { + Name string + Value interface{} +} + +// Service represents VPP binary API service +type Service struct { + Name string + RequestType string + ReplyType string + Stream bool + Events []string +} + +func (s Service) MethodName() string { + reqTyp := camelCaseName(s.RequestType) + + // method name is same as parameter type name by default + method := reqTyp + if s.Stream { + // use Dump as prefix instead of suffix for stream services + if m := strings.TrimSuffix(method, "Dump"); method != m { + method = "Dump" + m + } + } + + return method +} + +func (s Service) IsDumpService() bool { + return s.Stream +} + +func (s Service) IsEventService() bool { + return len(s.Events) > 0 +} + +func (s Service) IsRequestService() bool { + // some binapi messages might have `null` reply (for example: memclnt) + return s.ReplyType != "" && s.ReplyType != "null" // not null +} + +func getSizeOfType(typ *Type) (size int) { + for _, field := range typ.Fields { + if n := getBinapiTypeSize(field.Type); n > 0 { + if field.Length > 0 { + size += n * field.Length + } else { + size += n + } + } + } + return size +} diff --git a/vendor/git.fd.io/govpp.git/cmd/binapi-generator/parse.go b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/parse.go index 7f7880b5e2..2d6fdd4d7d 100644 --- a/vendor/git.fd.io/govpp.git/cmd/binapi-generator/parse.go +++ b/vendor/git.fd.io/govpp.git/cmd/binapi-generator/parse.go @@ -17,101 +17,12 @@ package main import ( "errors" "fmt" - "log" "sort" "strings" "github.com/bennyscetbun/jsongo" ) -// Package represents collection of objects parsed from VPP binary API JSON data -type Package struct { - APIVersion string - Enums []Enum - Unions []Union - Types []Type - Messages []Message - Services []Service - RefMap map[string]string -} - -// MessageType represents the type of a VPP message -type MessageType int - -const ( - requestMessage MessageType = iota // VPP request message - replyMessage // VPP reply message - eventMessage // VPP event message - otherMessage // other VPP message -) - -// Message represents VPP binary API message -type Message struct { - Name string - CRC string - Fields []Field -} - -// Type represents VPP binary API type -type Type struct { - Name string - CRC string - Fields []Field -} - -// Union represents VPP binary API union -type Union struct { - Name string - CRC string - Fields []Field -} - -// Field represents VPP binary API object field -type Field struct { - Name string - Type string - Length int - SizeFrom string -} - -func (f *Field) IsArray() bool { - return f.Length > 0 || f.SizeFrom != "" -} - -// Enum represents VPP binary API enum -type Enum struct { - Name string - Type string - Entries []EnumEntry -} - -// EnumEntry represents VPP binary API enum entry -type EnumEntry struct { - Name string - Value interface{} -} - -// Service represents VPP binary API service -type Service struct { - RequestType string - ReplyType string - Stream bool - Events []string -} - -func getSizeOfType(typ *Type) (size int) { - for _, field := range typ.Fields { - if n := getBinapiTypeSize(field.Type); n > 0 { - if field.Length > 0 { - size += n * field.Length - } else { - size += n - } - } - } - return size -} - func getTypeByRef(ctx *context, ref string) *Type { for _, typ := range ctx.packageData.Types { if ref == toApiType(typ.Name) { @@ -409,6 +320,7 @@ func parseMessage(ctx *context, msgNode *jsongo.JSONNode) (*Message, error) { } msgCRC, ok := msgNode.At(msgNode.Len() - 1).At("crc").Get().(string) if !ok { + return nil, fmt.Errorf("message crc invalid or missing") } @@ -478,6 +390,7 @@ func parseService(ctx *context, svcName string, svcNode *jsongo.JSONNode) (*Serv } svc := Service{ + Name: ctx.moduleName + "." + svcName, RequestType: svcName, } @@ -486,7 +399,6 @@ func parseService(ctx *context, svcName string, svcNode *jsongo.JSONNode) (*Serv if !ok { return nil, fmt.Errorf("service reply is %T, not a string", replyNode.Get()) } - // some binapi messages might have `null` reply (for example: memclnt) if reply != "null" { svc.ReplyType = reply } @@ -510,20 +422,24 @@ func parseService(ctx *context, svcName string, svcNode *jsongo.JSONNode) (*Serv } // validate service - if svc.Stream { + if svc.IsEventService() { + if !strings.HasPrefix(svc.RequestType, "want_") { + log.Warnf("Unusual EVENTS SERVICE: %+v\n"+ + "- events service %q does not have 'want_' prefix in request.", + svc, svc.Name) + } + } else if svc.IsDumpService() { if !strings.HasSuffix(svc.RequestType, "_dump") || !strings.HasSuffix(svc.ReplyType, "_details") { - fmt.Printf("Invalid STREAM SERVICE: %+v\n", svc) - } - } else if len(svc.Events) > 0 { - if (!strings.HasSuffix(svc.RequestType, "_events") && - !strings.HasSuffix(svc.RequestType, "_stats")) || - !strings.HasSuffix(svc.ReplyType, "_reply") { - fmt.Printf("Invalid EVENTS SERVICE: %+v\n", svc) + log.Warnf("Unusual STREAM SERVICE: %+v\n"+ + "- stream service %q does not have '_dump' suffix in request or reply does not have '_details' suffix.", + svc, svc.Name) } - } else if svc.ReplyType != "" { + } else if svc.IsRequestService() { if !strings.HasSuffix(svc.ReplyType, "_reply") { - fmt.Printf("Invalid SERVICE: %+v\n", svc) + log.Warnf("Unusual REQUEST SERVICE: %+v\n"+ + "- service %q does not have '_reply' suffix in reply.", + svc, svc.Name) } } @@ -540,7 +456,7 @@ func convertToGoType(ctx *context, binapiType string) (typ string) { typ = camelCaseName(r) } else { // fallback type - log.Printf("found unknown VPP binary API type %q, using byte", binapiType) + log.Warnf("found unknown VPP binary API type %q, using byte", binapiType) typ = "byte" } return typ diff --git a/vendor/git.fd.io/govpp.git/codec/msg_codec.go b/vendor/git.fd.io/govpp.git/codec/msg_codec.go index 572e672c63..67628a4d55 100644 --- a/vendor/git.fd.io/govpp.git/codec/msg_codec.go +++ b/vendor/git.fd.io/govpp.git/codec/msg_codec.go @@ -53,13 +53,25 @@ type VppOtherHeader struct { } // EncodeMsg encodes provided `Message` structure into its binary-encoded data representation. -func (*MsgCodec) EncodeMsg(msg api.Message, msgID uint16) ([]byte, error) { +func (*MsgCodec) EncodeMsg(msg api.Message, msgID uint16) (data []byte, err error) { if msg == nil { return nil, errors.New("nil message passed in") } - // encode message header + // try to recover panic which might possibly occur in struc.Pack call + defer func() { + if r := recover(); r != nil { + var ok bool + if err, ok = r.(error); !ok { + err = fmt.Errorf("%v", r) + } + err = fmt.Errorf("panic occurred: %v", err) + } + }() + var header interface{} + + // encode message header switch msg.GetMessageType() { case api.RequestMessage: header = &VppRequestHeader{VlMsgID: msgID} @@ -75,13 +87,13 @@ func (*MsgCodec) EncodeMsg(msg api.Message, msgID uint16) ([]byte, error) { // encode message header if err := struc.Pack(buf, header); err != nil { - return nil, fmt.Errorf("unable to encode message header: %v, error %v", header, err) + return nil, fmt.Errorf("failed to encode message header: %+v, error: %v", header, err) } // encode message content if reflect.TypeOf(msg).Elem().NumField() > 0 { if err := struc.Pack(buf, msg); err != nil { - return nil, fmt.Errorf("unable to encode message data: %v, error %v", header, err) + return nil, fmt.Errorf("failed to encode message data: %+v, error: %v", data, err) } } @@ -94,8 +106,9 @@ func (*MsgCodec) DecodeMsg(data []byte, msg api.Message) error { return errors.New("nil message passed in") } - // check which header is expected var header interface{} + + // check which header is expected switch msg.GetMessageType() { case api.RequestMessage: header = new(VppRequestHeader) @@ -111,12 +124,12 @@ func (*MsgCodec) DecodeMsg(data []byte, msg api.Message) error { // decode message header if err := struc.Unpack(buf, header); err != nil { - return fmt.Errorf("unable to decode message header: %+v, error %v", data, err) + return fmt.Errorf("failed to decode message header: %+v, error: %v", header, err) } // decode message content if err := struc.Unpack(buf, msg); err != nil { - return fmt.Errorf("unable to decode message data: %+v, error %v", data, err) + return fmt.Errorf("failed to decode message data: %+v, error: %v", data, err) } return nil @@ -127,17 +140,19 @@ func (*MsgCodec) DecodeMsgContext(data []byte, msg api.Message) (uint32, error) return 0, errors.New("nil message passed in") } + var header interface{} var getContext func() uint32 // check which header is expected - var header interface{} switch msg.GetMessageType() { case api.RequestMessage: header = new(VppRequestHeader) getContext = func() uint32 { return header.(*VppRequestHeader).Context } + case api.ReplyMessage: header = new(VppReplyHeader) getContext = func() uint32 { return header.(*VppReplyHeader).Context } + default: return 0, nil } diff --git a/vendor/git.fd.io/govpp.git/core/channel.go b/vendor/git.fd.io/govpp.git/core/channel.go index 5f7763ec65..a7d95fe1ec 100644 --- a/vendor/git.fd.io/govpp.git/core/channel.go +++ b/vendor/git.fd.io/govpp.git/core/channel.go @@ -29,40 +29,20 @@ var ( ErrInvalidRequestCtx = errors.New("invalid request context") ) -// requestCtx is a context for request with single reply -type requestCtx struct { - ch *channel - seqNum uint16 +// MessageCodec provides functionality for decoding binary data to generated API messages. +type MessageCodec interface { + //EncodeMsg encodes message into binary data. + EncodeMsg(msg api.Message, msgID uint16) ([]byte, error) + // DecodeMsg decodes binary-encoded data of a message into provided Message structure. + DecodeMsg(data []byte, msg api.Message) error } -// multiRequestCtx is a context for request with multiple responses -type multiRequestCtx struct { - ch *channel - seqNum uint16 -} - -func (req *requestCtx) ReceiveReply(msg api.Message) error { - if req == nil || req.ch == nil { - return ErrInvalidRequestCtx - } - - lastReplyReceived, err := req.ch.receiveReplyInternal(msg, req.seqNum) - if err != nil { - return err - } - if lastReplyReceived { - return errors.New("multipart reply recieved while a single reply expected") - } - - return nil -} - -func (req *multiRequestCtx) ReceiveReply(msg api.Message) (lastReplyReceived bool, err error) { - if req == nil || req.ch == nil { - return false, ErrInvalidRequestCtx - } - - return req.ch.receiveReplyInternal(msg, req.seqNum) +// MessageIdentifier provides identification of generated API messages. +type MessageIdentifier interface { + // GetMessageID returns message identifier of given API message. + GetMessageID(msg api.Message) (uint16, error) + // LookupByID looks up message name and crc by ID + LookupByID(msgID uint16) (api.Message, error) } // vppRequest is a request that will be sent to VPP. @@ -81,27 +61,40 @@ type vppReply struct { err error // in case of error, data is nil and this member contains error } -// NotifSubscribeRequest is a request to subscribe for delivery of specific notification messages. -type subscriptionRequest struct { - sub *api.NotifSubscription // subscription details - subscribe bool // true if this is a request to subscribe +// requestCtx is a context for request with single reply +type requestCtx struct { + ch *Channel + seqNum uint16 +} + +// multiRequestCtx is a context for request with multiple responses +type multiRequestCtx struct { + ch *Channel + seqNum uint16 +} + +// subscriptionCtx is a context of subscription for delivery of specific notification messages. +type subscriptionCtx struct { + ch *Channel + notifChan chan api.Message // channel where notification messages will be delivered to + msgID uint16 // message ID for the subscribed event message + event api.Message // event message that this subscription is for + msgFactory func() api.Message // function that returns a new instance of the specific message that is expected as a notification } // channel is the main communication interface with govpp core. It contains four Go channels, one for sending the requests // to VPP, one for receiving the replies from it and the same set for notifications. The user can access the Go channels // via methods provided by Channel interface in this package. Do not use the same channel from multiple goroutines // concurrently, otherwise the responses could mix! Use multiple channels instead. -type channel struct { - id uint16 // channel ID +type Channel struct { + id uint16 + conn *Connection reqChan chan *vppRequest // channel for sending the requests to VPP replyChan chan *vppReply // channel where VPP replies are delivered to - notifSubsChan chan *subscriptionRequest // channel for sending notification subscribe requests - notifSubsReplyChan chan error // channel where replies to notification subscribe requests are delivered to - - msgDecoder api.MessageDecoder // used to decode binary data to generated API messages - msgIdentifier api.MessageIdentifier // used to retrieve message ID of a message + msgCodec MessageCodec // used to decode binary data to generated API messages + msgIdentifier MessageIdentifier // used to retrieve message ID of a message lastSeqNum uint16 // sequence number of the last sent request @@ -109,73 +102,142 @@ type channel struct { replyTimeout time.Duration // maximum time that the API waits for a reply from VPP before returning an error, can be set with SetReplyTimeout } -func (ch *channel) GetID() uint16 { +func newChannel(id uint16, conn *Connection, codec MessageCodec, identifier MessageIdentifier, reqSize, replySize int) *Channel { + return &Channel{ + id: id, + conn: conn, + msgCodec: codec, + msgIdentifier: identifier, + reqChan: make(chan *vppRequest, reqSize), + replyChan: make(chan *vppReply, replySize), + replyTimeout: DefaultReplyTimeout, + } +} + +func (ch *Channel) GetID() uint16 { return ch.id } -func (ch *channel) nextSeqNum() uint16 { +func (ch *Channel) nextSeqNum() uint16 { ch.lastSeqNum++ return ch.lastSeqNum } -func (ch *channel) SendRequest(msg api.Message) api.RequestCtx { - req := &vppRequest{ +func (ch *Channel) SendRequest(msg api.Message) api.RequestCtx { + seqNum := ch.nextSeqNum() + ch.reqChan <- &vppRequest{ msg: msg, - seqNum: ch.nextSeqNum(), + seqNum: seqNum, } - ch.reqChan <- req - return &requestCtx{ch: ch, seqNum: req.seqNum} + return &requestCtx{ch: ch, seqNum: seqNum} } -func (ch *channel) SendMultiRequest(msg api.Message) api.MultiRequestCtx { - req := &vppRequest{ +func (ch *Channel) SendMultiRequest(msg api.Message) api.MultiRequestCtx { + seqNum := ch.nextSeqNum() + ch.reqChan <- &vppRequest{ msg: msg, - seqNum: ch.nextSeqNum(), + seqNum: seqNum, multi: true, } - ch.reqChan <- req - return &multiRequestCtx{ch: ch, seqNum: req.seqNum} + return &multiRequestCtx{ch: ch, seqNum: seqNum} } -func (ch *channel) SubscribeNotification(notifChan chan api.Message, msgFactory func() api.Message) (*api.NotifSubscription, error) { - sub := &api.NotifSubscription{ - NotifChan: notifChan, - MsgFactory: msgFactory, - } - // TODO: get rid of notifSubsChan and notfSubsReplyChan, - // it's no longer need because we know all message IDs and can store subscription right here - ch.notifSubsChan <- &subscriptionRequest{ - sub: sub, - subscribe: true, +func getMsgFactory(msg api.Message) func() api.Message { + return func() api.Message { + return reflect.New(reflect.TypeOf(msg).Elem()).Interface().(api.Message) } - return sub, <-ch.notifSubsReplyChan } -func (ch *channel) UnsubscribeNotification(subscription *api.NotifSubscription) error { - ch.notifSubsChan <- &subscriptionRequest{ - sub: subscription, - subscribe: false, +func (ch *Channel) SubscribeNotification(notifChan chan api.Message, event api.Message) (api.SubscriptionCtx, error) { + msgID, err := ch.msgIdentifier.GetMessageID(event) + if err != nil { + log.WithFields(logrus.Fields{ + "msg_name": event.GetMessageName(), + "msg_crc": event.GetCrcString(), + }).Errorf("unable to retrieve message ID: %v", err) + return nil, fmt.Errorf("unable to retrieve event message ID: %v", err) + } + + sub := &subscriptionCtx{ + ch: ch, + notifChan: notifChan, + msgID: msgID, + event: event, + msgFactory: getMsgFactory(event), } - return <-ch.notifSubsReplyChan + + // add the subscription into map + ch.conn.subscriptionsLock.Lock() + defer ch.conn.subscriptionsLock.Unlock() + + ch.conn.subscriptions[msgID] = append(ch.conn.subscriptions[msgID], sub) + + return sub, nil } -func (ch *channel) SetReplyTimeout(timeout time.Duration) { +func (ch *Channel) SetReplyTimeout(timeout time.Duration) { ch.replyTimeout = timeout } -func (ch *channel) Close() { +func (ch *Channel) Close() { if ch.reqChan != nil { close(ch.reqChan) + ch.reqChan = nil + } +} + +func (req *requestCtx) ReceiveReply(msg api.Message) error { + if req == nil || req.ch == nil { + return ErrInvalidRequestCtx + } + + lastReplyReceived, err := req.ch.receiveReplyInternal(msg, req.seqNum) + if err != nil { + return err + } else if lastReplyReceived { + return errors.New("multipart reply recieved while a single reply expected") + } + + return nil +} + +func (req *multiRequestCtx) ReceiveReply(msg api.Message) (lastReplyReceived bool, err error) { + if req == nil || req.ch == nil { + return false, ErrInvalidRequestCtx + } + + return req.ch.receiveReplyInternal(msg, req.seqNum) +} + +func (sub *subscriptionCtx) Unsubscribe() error { + log.WithFields(logrus.Fields{ + "msg_name": sub.event.GetMessageName(), + "msg_id": sub.msgID, + }).Debug("Removing notification subscription.") + + // remove the subscription from the map + sub.ch.conn.subscriptionsLock.Lock() + defer sub.ch.conn.subscriptionsLock.Unlock() + + for i, item := range sub.ch.conn.subscriptions[sub.msgID] { + if item == sub { + // remove i-th item in the slice + sub.ch.conn.subscriptions[sub.msgID] = append(sub.ch.conn.subscriptions[sub.msgID][:i], sub.ch.conn.subscriptions[sub.msgID][i+1:]...) + return nil + } } + + return fmt.Errorf("subscription for %q not found", sub.event.GetMessageName()) } // receiveReplyInternal receives a reply from the reply channel into the provided msg structure. -func (ch *channel) receiveReplyInternal(msg api.Message, expSeqNum uint16) (lastReplyReceived bool, err error) { - var ignore bool +func (ch *Channel) receiveReplyInternal(msg api.Message, expSeqNum uint16) (lastReplyReceived bool, err error) { if msg == nil { return false, errors.New("nil message passed in") } + var ignore bool + if vppReply := ch.delayedReply; vppReply != nil { // try the delayed reply ch.delayedReply = nil @@ -204,12 +266,12 @@ func (ch *channel) receiveReplyInternal(msg api.Message, expSeqNum uint16) (last return } -func (ch *channel) processReply(reply *vppReply, expSeqNum uint16, msg api.Message) (ignore bool, lastReplyReceived bool, err error) { +func (ch *Channel) processReply(reply *vppReply, expSeqNum uint16, msg api.Message) (ignore bool, lastReplyReceived bool, err error) { // check the sequence number cmpSeqNums := compareSeqNumbers(reply.seqNum, expSeqNum) if cmpSeqNums == -1 { // reply received too late, ignore the message - logrus.WithField("sequence-number", reply.seqNum).Warn( + logrus.WithField("seqNum", reply.seqNum).Warn( "Received reply to an already closed binary API request") ignore = true return @@ -253,7 +315,7 @@ func (ch *channel) processReply(reply *vppReply, expSeqNum uint16, msg api.Messa } // decode the message - if err = ch.msgDecoder.DecodeMsg(reply.data, msg); err != nil { + if err = ch.msgCodec.DecodeMsg(reply.data, msg); err != nil { return } @@ -261,9 +323,8 @@ func (ch *channel) processReply(reply *vppReply, expSeqNum uint16, msg api.Messa if strings.HasSuffix(msg.GetMessageName(), "_reply") { // TODO: use categories for messages to avoid checking message name if f := reflect.Indirect(reflect.ValueOf(msg)).FieldByName("Retval"); f.IsValid() { - if retval := f.Int(); retval != 0 { - err = api.VPPApiError(retval) - } + retval := int32(f.Int()) + err = api.RetvalToVPPApiError(retval) } } diff --git a/vendor/git.fd.io/govpp.git/core/connection.go b/vendor/git.fd.io/govpp.git/core/connection.go index c77358f76c..7d014ceaa5 100644 --- a/vendor/git.fd.io/govpp.git/core/connection.go +++ b/vendor/git.fd.io/govpp.git/core/connection.go @@ -29,42 +29,19 @@ import ( "git.fd.io/govpp.git/codec" ) -const ( - requestChannelBufSize = 100 // default size of the request channel buffer - replyChannelBufSize = 100 // default size of the reply channel buffer - notificationChannelBufSize = 100 // default size of the notification channel buffer - - defaultReplyTimeout = time.Second * 1 // default timeout for replies from VPP, can be changed with SetReplyTimeout +var ( + RequestChanBufSize = 100 // default size of the request channel buffer + ReplyChanBufSize = 100 // default size of the reply channel buffer + NotificationChanBufSize = 100 // default size of the notification channel buffer ) var ( - healthCheckInterval = time.Second * 1 // default health check interval - healthCheckReplyTimeout = time.Millisecond * 100 // timeout for reply to a health check - healthCheckThreshold = 1 // number of failed health checks until the error is reported + HealthCheckProbeInterval = time.Second * 1 // default health check probe interval + HealthCheckReplyTimeout = time.Millisecond * 100 // timeout for reply to a health check probe + HealthCheckThreshold = 1 // number of failed health checks until the error is reported + DefaultReplyTimeout = time.Second * 1 // default timeout for replies from VPP ) -// SetHealthCheckProbeInterval sets health check probe interval. -// Beware: Function is not thread-safe. It is recommended to setup this parameter -// before connecting to vpp. -func SetHealthCheckProbeInterval(interval time.Duration) { - healthCheckInterval = interval -} - -// SetHealthCheckReplyTimeout sets timeout for reply to a health check probe. -// If reply arrives after the timeout, check is considered as failed. -// Beware: Function is not thread-safe. It is recommended to setup this parameter -// before connecting to vpp. -func SetHealthCheckReplyTimeout(timeout time.Duration) { - healthCheckReplyTimeout = timeout -} - -// SetHealthCheckThreshold sets the number of failed healthProbe checks until the error is reported. -// Beware: Function is not thread-safe. It is recommended to setup this parameter -// before connecting to vpp. -func SetHealthCheckThreshold(threshold int) { - healthCheckThreshold = threshold -} - // ConnectionState represents the current state of the connection to VPP. type ConnectionState int @@ -104,10 +81,10 @@ type Connection struct { maxChannelID uint32 // maximum used channel ID (the real limit is 2^15, 32-bit is used for atomic operations) channelsLock sync.RWMutex // lock for the channels map - channels map[uint16]*channel // map of all API channels indexed by the channel ID + channels map[uint16]*Channel // map of all API channels indexed by the channel ID - notifSubscriptionsLock sync.RWMutex // lock for the subscriptions map - notifSubscriptions map[uint16][]*api.NotifSubscription // map od all notification subscriptions indexed by message ID + subscriptionsLock sync.RWMutex // lock for the subscriptions map + subscriptions map[uint16][]*subscriptionCtx // map od all notification subscriptions indexed by message ID pingReqID uint16 // ID if the ControlPing message pingReplyID uint16 // ID of the ControlPingReply message @@ -116,18 +93,30 @@ type Connection struct { lastReply time.Time // time of the last received reply from VPP } +func newConnection(vpp adapter.VppAdapter) *Connection { + c := &Connection{ + vpp: vpp, + codec: &codec.MsgCodec{}, + msgIDs: make(map[string]uint16), + msgMap: make(map[uint16]api.Message), + channels: make(map[uint16]*Channel), + subscriptions: make(map[uint16][]*subscriptionCtx), + } + vpp.SetMsgCallback(c.msgCallback) + return c +} + // Connect connects to VPP using specified VPP adapter and returns the connection handle. // This call blocks until VPP is connected, or an error occurs. Only one connection attempt will be performed. func Connect(vppAdapter adapter.VppAdapter) (*Connection, error) { // create new connection handle - c, err := newConnection(vppAdapter) + c, err := createConnection(vppAdapter) if err != nil { return nil, err } // blocking attempt to connect to VPP - err = c.connectVPP() - if err != nil { + if err := c.connectVPP(); err != nil { return nil, err } @@ -140,13 +129,13 @@ func Connect(vppAdapter adapter.VppAdapter) (*Connection, error) { // Connected/Disconnected events. In case of disconnect, the library will asynchronously try to reconnect. func AsyncConnect(vppAdapter adapter.VppAdapter) (*Connection, chan ConnectionEvent, error) { // create new connection handle - c, err := newConnection(vppAdapter) + c, err := createConnection(vppAdapter) if err != nil { return nil, nil, err } // asynchronously attempt to connect to VPP - connChan := make(chan ConnectionEvent, notificationChannelBufSize) + connChan := make(chan ConnectionEvent, NotificationChanBufSize) go c.connectLoop(connChan) return c, connChan, nil @@ -168,7 +157,7 @@ func (c *Connection) Disconnect() { } // newConnection returns new connection handle. -func newConnection(vppAdapter adapter.VppAdapter) (*Connection, error) { +func createConnection(vppAdapter adapter.VppAdapter) (*Connection, error) { connLock.Lock() defer connLock.Unlock() @@ -176,15 +165,7 @@ func newConnection(vppAdapter adapter.VppAdapter) (*Connection, error) { return nil, errors.New("only one connection per process is supported") } - conn = &Connection{ - vpp: vppAdapter, - codec: &codec.MsgCodec{}, - channels: make(map[uint16]*channel), - msgIDs: make(map[string]uint16), - msgMap: make(map[uint16]api.Message), - notifSubscriptions: make(map[uint16][]*api.NotifSubscription), - } - conn.vpp.SetMsgCallback(conn.msgCallback) + conn = newConnection(vppAdapter) return conn, nil } @@ -211,8 +192,72 @@ func (c *Connection) connectVPP() error { return nil } -func getMsgNameWithCrc(x api.Message) string { - return x.GetMessageName() + "_" + x.GetCrcString() +func (c *Connection) NewAPIChannel() (api.Channel, error) { + return c.newAPIChannel(RequestChanBufSize, ReplyChanBufSize) +} + +func (c *Connection) NewAPIChannelBuffered(reqChanBufSize, replyChanBufSize int) (api.Channel, error) { + return c.newAPIChannel(reqChanBufSize, replyChanBufSize) +} + +// NewAPIChannelBuffered returns a new API channel for communication with VPP via govpp core. +// It allows to specify custom buffer sizes for the request and reply Go channels. +func (c *Connection) newAPIChannel(reqChanBufSize, replyChanBufSize int) (*Channel, error) { + if c == nil { + return nil, errors.New("nil connection passed in") + } + + // create new channel + chID := uint16(atomic.AddUint32(&c.maxChannelID, 1) & 0x7fff) + channel := newChannel(chID, c, c.codec, c, reqChanBufSize, replyChanBufSize) + + // store API channel within the client + c.channelsLock.Lock() + c.channels[chID] = channel + c.channelsLock.Unlock() + + // start watching on the request channel + go c.watchRequests(channel) + + return channel, nil +} + +// releaseAPIChannel releases API channel that needs to be closed. +func (c *Connection) releaseAPIChannel(ch *Channel) { + log.WithFields(logger.Fields{ + "channel": ch.id, + }).Debug("API channel released") + + // delete the channel from channels map + c.channelsLock.Lock() + delete(c.channels, ch.id) + c.channelsLock.Unlock() +} + +// GetMessageID returns message identifier of given API message. +func (c *Connection) GetMessageID(msg api.Message) (uint16, error) { + if c == nil { + return 0, errors.New("nil connection passed in") + } + + if msgID, ok := c.msgIDs[getMsgNameWithCrc(msg)]; ok { + return msgID, nil + } + + return 0, fmt.Errorf("unknown message: %s (%s)", msg.GetMessageName(), msg.GetCrcString()) +} + +// LookupByID looks up message name and crc by ID. +func (c *Connection) LookupByID(msgID uint16) (api.Message, error) { + if c == nil { + return nil, errors.New("nil connection passed in") + } + + if msg, ok := c.msgMap[msgID]; ok { + return msg, nil + } + + return nil, fmt.Errorf("unknown message ID: %d", msgID) } // retrieveMessageIDs retrieves IDs for all registered messages and stores them in map @@ -268,32 +313,6 @@ func (c *Connection) retrieveMessageIDs() (err error) { return nil } -// GetMessageID returns message identifier of given API message. -func (c *Connection) GetMessageID(msg api.Message) (uint16, error) { - if c == nil { - return 0, errors.New("nil connection passed in") - } - - if msgID, ok := c.msgIDs[getMsgNameWithCrc(msg)]; ok { - return msgID, nil - } - - return 0, fmt.Errorf("unknown message: %s (%s)", msg.GetMessageName(), msg.GetCrcString()) -} - -// LookupByID looks up message name and crc by ID. -func (c *Connection) LookupByID(msgID uint16) (api.Message, error) { - if c == nil { - return nil, errors.New("nil connection passed in") - } - - if msg, ok := c.msgMap[msgID]; ok { - return msg, nil - } - - return nil, fmt.Errorf("unknown message ID: %d", msgID) -} - // disconnectVPP disconnects from VPP in case it is connected. func (c *Connection) disconnectVPP() { if atomic.CompareAndSwapUint32(&c.connected, 1, 0) { @@ -341,7 +360,7 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) { // send health check probes until an error or timeout occurs for { // sleep until next health check probe period - time.Sleep(healthCheckInterval) + time.Sleep(HealthCheckProbeInterval) if atomic.LoadUint32(&c.connected) == 0 { // Disconnect has been called in the meantime, return the healthcheck - reconnect loop @@ -365,7 +384,7 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) { case vppReply := <-ch.replyChan: err = vppReply.err - case <-time.After(healthCheckReplyTimeout): + case <-time.After(HealthCheckReplyTimeout): err = ErrProbeTimeout // check if time since last reply from any other @@ -374,7 +393,7 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) { sinceLastReply = time.Since(c.lastReply) c.lastReplyLock.Unlock() - if sinceLastReply < healthCheckReplyTimeout { + if sinceLastReply < HealthCheckReplyTimeout { log.Warnf("VPP health check probe timing out, but some request on other channel was received %v ago, continue waiting!", sinceLastReply) continue } @@ -384,10 +403,10 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) { if err == ErrProbeTimeout { failedChecks++ - log.Warnf("VPP health check probe timed out after %v (%d. timeout)", healthCheckReplyTimeout, failedChecks) - if failedChecks > healthCheckThreshold { + log.Warnf("VPP health check probe timed out after %v (%d. timeout)", HealthCheckReplyTimeout, failedChecks) + if failedChecks > HealthCheckThreshold { // in case of exceeded failed check treshold, assume VPP disconnected - log.Errorf("VPP health check exceeded treshold for timeouts (>%d), assuming disconnect", healthCheckThreshold) + log.Errorf("VPP health check exceeded treshold for timeouts (>%d), assuming disconnect", HealthCheckThreshold) connChan <- ConnectionEvent{Timestamp: time.Now(), State: Disconnected} break } @@ -411,52 +430,6 @@ func (c *Connection) healthCheckLoop(connChan chan ConnectionEvent) { c.connectLoop(connChan) } -func (c *Connection) NewAPIChannel() (api.Channel, error) { - return c.newAPIChannel(requestChannelBufSize, replyChannelBufSize) -} - -func (c *Connection) NewAPIChannelBuffered(reqChanBufSize, replyChanBufSize int) (api.Channel, error) { - return c.newAPIChannel(reqChanBufSize, replyChanBufSize) -} - -// NewAPIChannelBuffered returns a new API channel for communication with VPP via govpp core. -// It allows to specify custom buffer sizes for the request and reply Go channels. -func (c *Connection) newAPIChannel(reqChanBufSize, replyChanBufSize int) (*channel, error) { - if c == nil { - return nil, errors.New("nil connection passed in") - } - - chID := uint16(atomic.AddUint32(&c.maxChannelID, 1) & 0x7fff) - ch := &channel{ - id: chID, - replyTimeout: defaultReplyTimeout, - msgDecoder: c.codec, - msgIdentifier: c, - reqChan: make(chan *vppRequest, reqChanBufSize), - replyChan: make(chan *vppReply, replyChanBufSize), - notifSubsChan: make(chan *subscriptionRequest, reqChanBufSize), - notifSubsReplyChan: make(chan error, replyChanBufSize), - } - - // store API channel within the client - c.channelsLock.Lock() - c.channels[chID] = ch - c.channelsLock.Unlock() - - // start watching on the request channel - go c.watchRequests(ch) - - return ch, nil -} - -// releaseAPIChannel releases API channel that needs to be closed. -func (c *Connection) releaseAPIChannel(ch *channel) { - log.WithFields(logger.Fields{ - "channel": ch.id, - }).Debug("API channel released") - - // delete the channel from channels map - c.channelsLock.Lock() - delete(c.channels, ch.id) - c.channelsLock.Unlock() +func getMsgNameWithCrc(x api.Message) string { + return x.GetMessageName() + "_" + x.GetCrcString() } diff --git a/vendor/git.fd.io/govpp.git/core/notification_handler.go b/vendor/git.fd.io/govpp.git/core/notification_handler.go deleted file mode 100644 index 7b889e37ab..0000000000 --- a/vendor/git.fd.io/govpp.git/core/notification_handler.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) 2017 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 core - -import ( - "fmt" - - "git.fd.io/govpp.git/api" - logger "github.com/sirupsen/logrus" -) - -// processSubscriptionRequest processes a notification subscribe request. -func (c *Connection) processSubscriptionRequest(ch *channel, req *subscriptionRequest) error { - var err error - - // subscribe / unsubscribe - if req.subscribe { - err = c.addNotifSubscription(req.sub) - } else { - err = c.removeNotifSubscription(req.sub) - } - - // send the reply into the go channel - select { - case ch.notifSubsReplyChan <- err: - // reply sent successfully - default: - // unable to write into the channel without blocking - log.WithFields(logger.Fields{ - "channel": ch.id, - }).Warn("Unable to deliver the subscribe reply, reciever end not ready.") - } - - return err -} - -// addNotifSubscription adds the notification subscription into the subscriptions map of the connection. -func (c *Connection) addNotifSubscription(subs *api.NotifSubscription) error { - // get message ID of the notification message - msgID, msgName, err := c.getSubscriptionMessageID(subs) - if err != nil { - return err - } - - log.WithFields(logger.Fields{ - "msg_name": msgName, - "msg_id": msgID, - }).Debug("Adding new notification subscription.") - - // add the subscription into map - c.notifSubscriptionsLock.Lock() - defer c.notifSubscriptionsLock.Unlock() - - c.notifSubscriptions[msgID] = append(c.notifSubscriptions[msgID], subs) - - return nil -} - -// removeNotifSubscription removes the notification subscription from the subscriptions map of the connection. -func (c *Connection) removeNotifSubscription(subs *api.NotifSubscription) error { - // get message ID of the notification message - msgID, msgName, err := c.getSubscriptionMessageID(subs) - if err != nil { - return err - } - - log.WithFields(logger.Fields{ - "msg_name": msgName, - "msg_id": msgID, - }).Debug("Removing notification subscription.") - - // remove the subscription from the map - c.notifSubscriptionsLock.Lock() - defer c.notifSubscriptionsLock.Unlock() - - for i, item := range c.notifSubscriptions[msgID] { - if item == subs { - // remove i-th item in the slice - c.notifSubscriptions[msgID] = append(c.notifSubscriptions[msgID][:i], c.notifSubscriptions[msgID][i+1:]...) - break - } - } - - return nil -} - -// isNotificationMessage returns true if someone has subscribed to provided message ID. -func (c *Connection) isNotificationMessage(msgID uint16) bool { - c.notifSubscriptionsLock.RLock() - defer c.notifSubscriptionsLock.RUnlock() - - _, exists := c.notifSubscriptions[msgID] - return exists -} - -// sendNotifications send a notification message to all subscribers subscribed for that message. -func (c *Connection) sendNotifications(msgID uint16, data []byte) { - c.notifSubscriptionsLock.RLock() - defer c.notifSubscriptionsLock.RUnlock() - - matched := false - - // send to notification to each subscriber - for _, subs := range c.notifSubscriptions[msgID] { - msg := subs.MsgFactory() - log.WithFields(logger.Fields{ - "msg_name": msg.GetMessageName(), - "msg_id": msgID, - "msg_size": len(data), - }).Debug("Sending a notification to the subscription channel.") - - if err := c.codec.DecodeMsg(data, msg); err != nil { - log.WithFields(logger.Fields{ - "msg_name": msg.GetMessageName(), - "msg_id": msgID, - "msg_size": len(data), - }).Errorf("Unable to decode the notification message: %v", err) - continue - } - - // send the message into the go channel of the subscription - select { - case subs.NotifChan <- msg: - // message sent successfully - default: - // unable to write into the channel without blocking - log.WithFields(logger.Fields{ - "msg_name": msg.GetMessageName(), - "msg_id": msgID, - "msg_size": len(data), - }).Warn("Unable to deliver the notification, reciever end not ready.") - } - - matched = true - } - - if !matched { - log.WithFields(logger.Fields{ - "msg_id": msgID, - "msg_size": len(data), - }).Info("No subscription found for the notification message.") - } -} - -// getSubscriptionMessageID returns ID of the message the subscription is tied to. -func (c *Connection) getSubscriptionMessageID(subs *api.NotifSubscription) (uint16, string, error) { - msg := subs.MsgFactory() - msgID, err := c.GetMessageID(msg) - if err != nil { - log.WithFields(logger.Fields{ - "msg_name": msg.GetMessageName(), - "msg_crc": msg.GetCrcString(), - }).Errorf("unable to retrieve message ID: %v", err) - return 0, "", fmt.Errorf("unable to retrieve message ID: %v", err) - } - - return msgID, msg.GetMessageName(), nil -} diff --git a/vendor/git.fd.io/govpp.git/core/request_handler.go b/vendor/git.fd.io/govpp.git/core/request_handler.go index fd6d10027e..e52e2628be 100644 --- a/vendor/git.fd.io/govpp.git/core/request_handler.go +++ b/vendor/git.fd.io/govpp.git/core/request_handler.go @@ -29,7 +29,7 @@ var ( ) // watchRequests watches for requests on the request API channel and forwards them as messages to VPP. -func (c *Connection) watchRequests(ch *channel) { +func (c *Connection) watchRequests(ch *Channel) { for { select { case req, ok := <-ch.reqChan: @@ -39,54 +39,49 @@ func (c *Connection) watchRequests(ch *channel) { c.releaseAPIChannel(ch) return } - c.processRequest(ch, req) - - case req := <-ch.notifSubsChan: - // new request on the notification subscribe channel - c.processSubscriptionRequest(ch, req) + if err := c.processRequest(ch, req); err != nil { + sendReplyError(ch, req, err) + } } } } // processRequest processes a single request received on the request channel. -func (c *Connection) processRequest(ch *channel, req *vppRequest) error { +func (c *Connection) processRequest(ch *Channel, req *vppRequest) error { // check whether we are connected to VPP if atomic.LoadUint32(&c.connected) == 0 { err := ErrNotConnected log.Errorf("processing request failed: %v", err) - sendReplyError(ch, req, err) return err } // retrieve message ID msgID, err := c.GetMessageID(req.msg) if err != nil { - err = fmt.Errorf("unable to retrieve message ID: %v", err) log.WithFields(logger.Fields{ "msg_name": req.msg.GetMessageName(), "msg_crc": req.msg.GetCrcString(), "seq_num": req.seqNum, - }).Error(err) - sendReplyError(ch, req, err) - return err + "error": err, + }).Errorf("failed to retrieve message ID") + return fmt.Errorf("unable to retrieve message ID: %v", err) } // encode the message into binary data, err := c.codec.EncodeMsg(req.msg, msgID) if err != nil { - err = fmt.Errorf("unable to encode the messge: %v", err) log.WithFields(logger.Fields{ "channel": ch.id, "msg_id": msgID, "msg_name": req.msg.GetMessageName(), "seq_num": req.seqNum, - }).Error(err) - sendReplyError(ch, req, err) - return err + "error": err, + }).Errorf("failed to encode message: %#v", req.msg) + return fmt.Errorf("unable to encode the message: %v", err) } - // get context context := packRequestContext(ch.id, req.multi, req.seqNum) + if log.Level == logger.DebugLevel { // for performance reasons - logrus does some processing even if debugs are disabled log.WithFields(logger.Fields{ "channel": ch.id, @@ -108,7 +103,6 @@ func (c *Connection) processRequest(ch *channel, req *vppRequest) error { "msg_id": msgID, "seq_num": req.seqNum, }).Error(err) - sendReplyError(ch, req, err) return err } @@ -137,7 +131,7 @@ func (c *Connection) processRequest(ch *channel, req *vppRequest) error { } // msgCallback is called whenever any binary API message comes from VPP. -func (c *Connection) msgCallback(msgID uint16, context uint32, data []byte) { +func (c *Connection) msgCallback(msgID uint16, data []byte) { connLock.RLock() defer connLock.RUnlock() @@ -157,13 +151,8 @@ func (c *Connection) msgCallback(msgID uint16, context uint32, data []byte) { // - replies that don't have context as first field (comes as zero) // - events that don't have context at all (comes as non zero) // - msgContext, err := c.codec.DecodeMsgContext(data, msg) - if err == nil { - if context != msgContext { - log.Debugf("different context was decoded from message (%d -> %d)", context, msgContext) - context = msgContext - } - } else { + context, err := c.codec.DecodeMsgContext(data, msg) + if err != nil { log.Errorf("decoding context failed: %v", err) } @@ -202,11 +191,12 @@ func (c *Connection) msgCallback(msgID uint16, context uint32, data []byte) { // treat this as a last part of the reply lastReplyReceived := isMulti && msgID == c.pingReplyID - // send the data to the channel + // send the data to the channel, it needs to be copied, + // because it will be freed after this function returns sendReply(ch, &vppReply{ msgID: msgID, seqNum: seqNum, - data: data, + data: append([]byte(nil), data...), lastReceived: lastReplyReceived, }) @@ -218,7 +208,7 @@ func (c *Connection) msgCallback(msgID uint16, context uint32, data []byte) { // sendReply sends the reply into the go channel, if it cannot be completed without blocking, otherwise // it logs the error and do not send the message. -func sendReply(ch *channel, reply *vppReply) { +func sendReply(ch *Channel, reply *vppReply) { select { case ch.replyChan <- reply: // reply sent successfully @@ -232,10 +222,68 @@ func sendReply(ch *channel, reply *vppReply) { } } -func sendReplyError(ch *channel, req *vppRequest, err error) { +func sendReplyError(ch *Channel, req *vppRequest, err error) { sendReply(ch, &vppReply{seqNum: req.seqNum, err: err}) } +// isNotificationMessage returns true if someone has subscribed to provided message ID. +func (c *Connection) isNotificationMessage(msgID uint16) bool { + c.subscriptionsLock.RLock() + defer c.subscriptionsLock.RUnlock() + + _, exists := c.subscriptions[msgID] + return exists +} + +// sendNotifications send a notification message to all subscribers subscribed for that message. +func (c *Connection) sendNotifications(msgID uint16, data []byte) { + c.subscriptionsLock.RLock() + defer c.subscriptionsLock.RUnlock() + + matched := false + + // send to notification to each subscriber + for _, sub := range c.subscriptions[msgID] { + log.WithFields(logger.Fields{ + "msg_name": sub.event.GetMessageName(), + "msg_id": msgID, + "msg_size": len(data), + }).Debug("Sending a notification to the subscription channel.") + + event := sub.msgFactory() + if err := c.codec.DecodeMsg(data, event); err != nil { + log.WithFields(logger.Fields{ + "msg_name": sub.event.GetMessageName(), + "msg_id": msgID, + "msg_size": len(data), + }).Errorf("Unable to decode the notification message: %v", err) + continue + } + + // send the message into the go channel of the subscription + select { + case sub.notifChan <- event: + // message sent successfully + default: + // unable to write into the channel without blocking + log.WithFields(logger.Fields{ + "msg_name": sub.event.GetMessageName(), + "msg_id": msgID, + "msg_size": len(data), + }).Warn("Unable to deliver the notification, reciever end not ready.") + } + + matched = true + } + + if !matched { + log.WithFields(logger.Fields{ + "msg_id": msgID, + "msg_size": len(data), + }).Info("No subscription found for the notification message.") + } +} + // +------------------+-------------------+-----------------------+ // | 15b = channel ID | 1b = is multipart | 16b = sequence number | // +------------------+-------------------+-----------------------+ diff --git a/vendor/github.com/bsm/sarama-cluster/.travis.yml b/vendor/github.com/bsm/sarama-cluster/.travis.yml index d9d5efcc20..07c7c10fee 100644 --- a/vendor/github.com/bsm/sarama-cluster/.travis.yml +++ b/vendor/github.com/bsm/sarama-cluster/.travis.yml @@ -1,16 +1,15 @@ sudo: false language: go go: + - 1.10.x - 1.9.x - - 1.8.x install: - go get -u github.com/golang/dep/cmd/dep - dep ensure env: - - SCALA_VERSION=2.11 KAFKA_VERSION=0.10.1.1 - - SCALA_VERSION=2.12 KAFKA_VERSION=0.10.2.1 - SCALA_VERSION=2.12 KAFKA_VERSION=0.11.0.1 - - SCALA_VERSION=2.12 KAFKA_VERSION=1.0.0 + - SCALA_VERSION=2.12 KAFKA_VERSION=1.0.1 + - SCALA_VERSION=2.12 KAFKA_VERSION=1.1.0 script: - make default test-race addons: diff --git a/vendor/github.com/bsm/sarama-cluster/Gopkg.lock b/vendor/github.com/bsm/sarama-cluster/Gopkg.lock index 3ab8b6ab2c..e1bc110285 100644 --- a/vendor/github.com/bsm/sarama-cluster/Gopkg.lock +++ b/vendor/github.com/bsm/sarama-cluster/Gopkg.lock @@ -4,8 +4,8 @@ [[projects]] name = "github.com/Shopify/sarama" packages = ["."] - revision = "3b1b38866a79f06deddf0487d5c27ba0697ccd65" - version = "v1.15.0" + revision = "35324cf48e33d8260e1c7c18854465a904ade249" + version = "v1.17.0" [[projects]] name = "github.com/davecgh/go-spew" @@ -16,8 +16,8 @@ [[projects]] name = "github.com/eapache/go-resiliency" packages = ["breaker"] - revision = "6800482f2c813e689c88b7ed3282262385011890" - version = "v1.0.0" + revision = "ea41b0fad31007accc7f806884dcdf3da98b79ce" + version = "v1.1.0" [[projects]] branch = "master" @@ -35,7 +35,7 @@ branch = "master" name = "github.com/golang/snappy" packages = ["."] - revision = "553a641470496b2327abcac10b36396bd98e45c9" + revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" [[projects]] name = "github.com/onsi/ginkgo" @@ -60,8 +60,8 @@ "reporters/stenographer/support/go-isatty", "types" ] - revision = "9eda700730cba42af70d53180f9dcce9266bc2bc" - version = "v1.4.0" + revision = "fa5fabab2a1bfbd924faf4c067d07ae414e2aedf" + version = "v1.5.0" [[projects]] name = "github.com/onsi/gomega" @@ -79,26 +79,23 @@ "matchers/support/goraph/util", "types" ] - revision = "003f63b7f4cff3fc95357005358af2de0f5fe152" - version = "v1.3.0" + revision = "62bff4df71bdbc266561a0caee19f0594b17c240" + version = "v1.4.0" [[projects]] name = "github.com/pierrec/lz4" - packages = ["."] - revision = "2fcda4cb7018ce05a25959d2fe08c83e3329f169" - version = "v1.1" - -[[projects]] - name = "github.com/pierrec/xxHash" - packages = ["xxHash32"] - revision = "f051bb7f1d1aaf1b5a665d74fb6b0217712c69f7" - version = "v0.1.1" + packages = [ + ".", + "internal/xxh32" + ] + revision = "6b9367c9ff401dbc54fabce3fb8d972e799b702d" + version = "v2.0.2" [[projects]] branch = "master" name = "github.com/rcrowley/go-metrics" packages = ["."] - revision = "8732c616f52954686704c8645fe1a9d59e9df7c1" + revision = "e2704e165165ec55d062f5919b4b29494e9fa790" [[projects]] branch = "master" @@ -108,16 +105,15 @@ "html/atom", "html/charset" ] - revision = "0ed95abb35c445290478a5348a7b38bb154135fd" + revision = "afe8f62b1d6bbd81f31868121a50b06d8188e1f9" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "3dbebcf8efb6a5011a60c2b4591c1022a759af8a" + revision = "63fc586f45fe72d95d5240a5d5eb95e6503907d3" [[projects]] - branch = "master" name = "golang.org/x/text" packages = [ "encoding", @@ -138,13 +134,14 @@ "transform", "unicode/cldr" ] - revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3" + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" [[projects]] - branch = "v2" name = "gopkg.in/yaml.v2" packages = ["."] - revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4" + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" [solve-meta] analyzer-name = "dep" diff --git a/vendor/github.com/bsm/sarama-cluster/Makefile b/vendor/github.com/bsm/sarama-cluster/Makefile index 706f58ec17..25c5bc2071 100644 --- a/vendor/github.com/bsm/sarama-cluster/Makefile +++ b/vendor/github.com/bsm/sarama-cluster/Makefile @@ -1,5 +1,5 @@ SCALA_VERSION?= 2.12 -KAFKA_VERSION?= 1.0.0 +KAFKA_VERSION?= 1.1.0 KAFKA_DIR= kafka_$(SCALA_VERSION)-$(KAFKA_VERSION) KAFKA_SRC= https://archive.apache.org/dist/kafka/$(KAFKA_VERSION)/$(KAFKA_DIR).tgz KAFKA_ROOT= testdata/$(KAFKA_DIR) diff --git a/vendor/github.com/bsm/sarama-cluster/balancer.go b/vendor/github.com/bsm/sarama-cluster/balancer.go index 0f9b445ee4..3aeaecef7a 100644 --- a/vendor/github.com/bsm/sarama-cluster/balancer.go +++ b/vendor/github.com/bsm/sarama-cluster/balancer.go @@ -157,10 +157,6 @@ func (r *balancer) Topic(name string, memberID string) error { } func (r *balancer) Perform(s Strategy) map[string]map[string][]int32 { - if r == nil { - return nil - } - res := make(map[string]map[string][]int32, 1) for topic, info := range r.topics { for memberID, partitions := range info.Perform(s) { diff --git a/vendor/github.com/bsm/sarama-cluster/consumer.go b/vendor/github.com/bsm/sarama-cluster/consumer.go index 13500cc8e7..e7a67dac8b 100644 --- a/vendor/github.com/bsm/sarama-cluster/consumer.go +++ b/vendor/github.com/bsm/sarama-cluster/consumer.go @@ -140,18 +140,16 @@ func (c *Consumer) HighWaterMarks() map[string]map[int32]int64 { return c.consum // your application crashes. This means that you may end up processing the same // message twice, and your processing should ideally be idempotent. func (c *Consumer) MarkOffset(msg *sarama.ConsumerMessage, metadata string) { - sub := c.subs.Fetch(msg.Topic, msg.Partition) - if sub != nil { - sub.MarkOffset(msg.Offset+1, metadata) + if sub := c.subs.Fetch(msg.Topic, msg.Partition); sub != nil { + sub.MarkOffset(msg.Offset, metadata) } } // MarkPartitionOffset marks an offset of the provided topic/partition as processed. // See MarkOffset for additional explanation. func (c *Consumer) MarkPartitionOffset(topic string, partition int32, offset int64, metadata string) { - sub := c.subs.Fetch(topic, partition) - if sub != nil { - sub.MarkOffset(offset+1, metadata) + if sub := c.subs.Fetch(topic, partition); sub != nil { + sub.MarkOffset(offset, metadata) } } @@ -162,9 +160,8 @@ func (c *Consumer) MarkOffsets(s *OffsetStash) { defer s.mu.Unlock() for tp, info := range s.offsets { - sub := c.subs.Fetch(tp.Topic, tp.Partition) - if sub != nil { - sub.MarkOffset(info.Offset+1, info.Metadata) + if sub := c.subs.Fetch(tp.Topic, tp.Partition); sub != nil { + sub.MarkOffset(info.Offset, info.Metadata) } delete(s.offsets, tp) } @@ -177,9 +174,8 @@ func (c *Consumer) MarkOffsets(s *OffsetStash) { // // Difference between ResetOffset and MarkOffset is that it allows to rewind to an earlier offset func (c *Consumer) ResetOffset(msg *sarama.ConsumerMessage, metadata string) { - sub := c.subs.Fetch(msg.Topic, msg.Partition) - if sub != nil { - sub.ResetOffset(msg.Offset+1, metadata) + if sub := c.subs.Fetch(msg.Topic, msg.Partition); sub != nil { + sub.ResetOffset(msg.Offset, metadata) } } @@ -188,7 +184,7 @@ func (c *Consumer) ResetOffset(msg *sarama.ConsumerMessage, metadata string) { func (c *Consumer) ResetPartitionOffset(topic string, partition int32, offset int64, metadata string) { sub := c.subs.Fetch(topic, partition) if sub != nil { - sub.ResetOffset(offset+1, metadata) + sub.ResetOffset(offset, metadata) } } @@ -199,9 +195,8 @@ func (c *Consumer) ResetOffsets(s *OffsetStash) { defer s.mu.Unlock() for tp, info := range s.offsets { - sub := c.subs.Fetch(tp.Topic, tp.Partition) - if sub != nil { - sub.ResetOffset(info.Offset+1, info.Metadata) + if sub := c.subs.Fetch(tp.Topic, tp.Partition); sub != nil { + sub.ResetOffset(info.Offset, info.Metadata) } delete(s.offsets, tp) } @@ -264,9 +259,8 @@ func (c *Consumer) CommitOffsets() error { if kerr != sarama.ErrNoError { err = kerr } else if state, ok := snap[topicPartition{topic, partition}]; ok { - sub := c.subs.Fetch(topic, partition) - if sub != nil { - sub.MarkCommitted(state.Info.Offset) + if sub := c.subs.Fetch(topic, partition); sub != nil { + sub.markCommitted(state.Info.Offset) } } } @@ -706,12 +700,13 @@ func (c *Consumer) syncGroup(strategy *balancer) (map[string][]int32, error) { GenerationId: generationID, } - for memberID, topics := range strategy.Perform(c.client.config.Group.PartitionStrategy) { - if err := req.AddGroupAssignmentMember(memberID, &sarama.ConsumerGroupMemberAssignment{ - Version: 1, - Topics: topics, - }); err != nil { - return nil, err + if strategy != nil { + for memberID, topics := range strategy.Perform(c.client.config.Group.PartitionStrategy) { + if err := req.AddGroupAssignmentMember(memberID, &sarama.ConsumerGroupMemberAssignment{ + Topics: topics, + }); err != nil { + return nil, err + } } } @@ -829,9 +824,9 @@ func (c *Consumer) createConsumer(tomb *loopTomb, topic string, partition int32, // Start partition consumer goroutine tomb.Go(func(stopper <-chan none) { if c.client.config.Group.Mode == ConsumerModePartitions { - pc.WaitFor(stopper, c.errors) + pc.waitFor(stopper, c.errors) } else { - pc.Multiplex(stopper, c.messages, c.errors) + pc.multiplex(stopper, c.messages, c.errors) } }) diff --git a/vendor/github.com/bsm/sarama-cluster/partitions.go b/vendor/github.com/bsm/sarama-cluster/partitions.go index 987780bde1..bfaa587830 100644 --- a/vendor/github.com/bsm/sarama-cluster/partitions.go +++ b/vendor/github.com/bsm/sarama-cluster/partitions.go @@ -19,6 +19,16 @@ type PartitionConsumer interface { // Partition returns the consumed partition Partition() int32 + + // InitialOffset returns the offset used for creating the PartitionConsumer instance. + // The returned offset can be a literal offset, or OffsetNewest, or OffsetOldest + InitialOffset() int64 + + // MarkOffset marks the offset of a message as preocessed. + MarkOffset(offset int64, metadata string) + + // ResetOffset resets the offset to a previously processed message. + ResetOffset(offset int64, metadata string) } type partitionConsumer struct { @@ -27,8 +37,9 @@ type partitionConsumer struct { state partitionState mu sync.Mutex - topic string - partition int32 + topic string + partition int32 + initialOffset int64 closeOnce sync.Once closeErr error @@ -37,12 +48,14 @@ type partitionConsumer struct { } func newPartitionConsumer(manager sarama.Consumer, topic string, partition int32, info offsetInfo, defaultOffset int64) (*partitionConsumer, error) { - pcm, err := manager.ConsumePartition(topic, partition, info.NextOffset(defaultOffset)) + offset := info.NextOffset(defaultOffset) + pcm, err := manager.ConsumePartition(topic, partition, offset) // Resume from default offset, if requested offset is out-of-range if err == sarama.ErrOffsetOutOfRange { info.Offset = -1 - pcm, err = manager.ConsumePartition(topic, partition, defaultOffset) + offset = defaultOffset + pcm, err = manager.ConsumePartition(topic, partition, offset) } if err != nil { return nil, err @@ -52,8 +65,9 @@ func newPartitionConsumer(manager sarama.Consumer, topic string, partition int32 PartitionConsumer: pcm, state: partitionState{Info: info}, - topic: topic, - partition: partition, + topic: topic, + partition: partition, + initialOffset: offset, dying: make(chan none), dead: make(chan none), @@ -66,6 +80,9 @@ func (c *partitionConsumer) Topic() string { return c.topic } // Partition implements PartitionConsumer func (c *partitionConsumer) Partition() int32 { return c.partition } +// InitialOffset implements PartitionConsumer +func (c *partitionConsumer) InitialOffset() int64 { return c.initialOffset } + // AsyncClose implements PartitionConsumer func (c *partitionConsumer) AsyncClose() { c.closeOnce.Do(func() { @@ -81,7 +98,7 @@ func (c *partitionConsumer) Close() error { return c.closeErr } -func (c *partitionConsumer) WaitFor(stopper <-chan none, errors chan<- error) { +func (c *partitionConsumer) waitFor(stopper <-chan none, errors chan<- error) { defer close(c.dead) for { @@ -105,7 +122,7 @@ func (c *partitionConsumer) WaitFor(stopper <-chan none, errors chan<- error) { } } -func (c *partitionConsumer) Multiplex(stopper <-chan none, messages chan<- *sarama.ConsumerMessage, errors chan<- error) { +func (c *partitionConsumer) multiplex(stopper <-chan none, messages chan<- *sarama.ConsumerMessage, errors chan<- error) { defer close(c.dead) for { @@ -140,11 +157,7 @@ func (c *partitionConsumer) Multiplex(stopper <-chan none, messages chan<- *sara } } -func (c *partitionConsumer) State() partitionState { - if c == nil { - return partitionState{} - } - +func (c *partitionConsumer) getState() partitionState { c.mu.Lock() state := c.state c.mu.Unlock() @@ -152,11 +165,7 @@ func (c *partitionConsumer) State() partitionState { return state } -func (c *partitionConsumer) MarkCommitted(offset int64) { - if c == nil { - return - } - +func (c *partitionConsumer) markCommitted(offset int64) { c.mu.Lock() if offset == c.state.Info.Offset { c.state.Dirty = false @@ -164,28 +173,22 @@ func (c *partitionConsumer) MarkCommitted(offset int64) { c.mu.Unlock() } +// MarkOffset implements PartitionConsumer func (c *partitionConsumer) MarkOffset(offset int64, metadata string) { - if c == nil { - return - } - c.mu.Lock() - if offset > c.state.Info.Offset { - c.state.Info.Offset = offset + if next := offset + 1; next > c.state.Info.Offset { + c.state.Info.Offset = next c.state.Info.Metadata = metadata c.state.Dirty = true } c.mu.Unlock() } +// ResetOffset implements PartitionConsumer func (c *partitionConsumer) ResetOffset(offset int64, metadata string) { - if c == nil { - return - } - c.mu.Lock() - if offset <= c.state.Info.Offset { - c.state.Info.Offset = offset + if next := offset + 1; next <= c.state.Info.Offset { + c.state.Info.Offset = next c.state.Info.Metadata = metadata c.state.Dirty = true } @@ -244,7 +247,7 @@ func (m *partitionMap) Snapshot() map[topicPartition]partitionState { snap := make(map[topicPartition]partitionState, len(m.data)) for tp, pc := range m.data { - snap[tp] = pc.State() + snap[tp] = pc.getState() } return snap } diff --git a/vendor/github.com/buger/goterm/plot.go b/vendor/github.com/buger/goterm/plot.go index 77b9fb0971..1201476232 100644 --- a/vendor/github.com/buger/goterm/plot.go +++ b/vendor/github.com/buger/goterm/plot.go @@ -242,10 +242,10 @@ func (c *LineChart) DrawLine(x0, y0, x1, y1 int, symbol string) { } func getBoundaryValues(data *DataTable, index int) (maxX, minX, maxY, minY float64) { - maxX = data.rows[0][0] - minX = data.rows[0][0] - maxY = data.rows[0][1] - minY = data.rows[0][1] + maxX = math.Inf(-1) + minX = math.Inf(1) + maxY = math.Inf(-1) + minY = math.Inf(1) for _, r := range data.rows { maxX = math.Max(maxX, r[0]) diff --git a/vendor/github.com/buger/goterm/terminal.go b/vendor/github.com/buger/goterm/terminal.go index 16b36428fa..d9452cd176 100644 --- a/vendor/github.com/buger/goterm/terminal.go +++ b/vendor/github.com/buger/goterm/terminal.go @@ -148,7 +148,7 @@ func MoveTo(str string, x int, y int) (out string) { // Return carrier to start of line func ResetLine(str string) (out string) { return applyTransform(str, func(idx int, line string) string { - return fmt.Sprintf(RESET_LINE, line) + return fmt.Sprintf("%s%s", RESET_LINE, line) }) } diff --git a/vendor/github.com/buger/goterm/terminal_sysioctl.go b/vendor/github.com/buger/goterm/terminal_sysioctl.go index e98430fb92..5a61cd52ba 100644 --- a/vendor/github.com/buger/goterm/terminal_sysioctl.go +++ b/vendor/github.com/buger/goterm/terminal_sysioctl.go @@ -3,34 +3,16 @@ package goterm import ( - "fmt" "os" - "runtime" - "syscall" - "unsafe" + "golang.org/x/sys/unix" ) -func getWinsize() (*winsize, error) { - ws := new(winsize) +func getWinsize() (*unix.Winsize, error) { - var _TIOCGWINSZ int64 - - switch runtime.GOOS { - case "linux": - _TIOCGWINSZ = 0x5413 - case "darwin": - _TIOCGWINSZ = 1074295912 + ws, err := unix.IoctlGetWinsize(int(os.Stdout.Fd()), unix.TIOCGWINSZ) + if err != nil { + return nil, os.NewSyscallError("GetWinsize", err) } - r1, _, errno := syscall.Syscall(syscall.SYS_IOCTL, - uintptr(syscall.Stdin), - uintptr(_TIOCGWINSZ), - uintptr(unsafe.Pointer(ws)), - ) - - if int(r1) == -1 { - fmt.Println("Error:", os.NewSyscallError("GetWinsize", errno)) - return nil, os.NewSyscallError("GetWinsize", errno) - } return ws, nil } diff --git a/vendor/github.com/containerd/console/.travis.yml b/vendor/github.com/containerd/console/.travis.yml new file mode 100644 index 0000000000..95e91698e9 --- /dev/null +++ b/vendor/github.com/containerd/console/.travis.yml @@ -0,0 +1,19 @@ +language: go +go: + - "1.10.x" + +go_import_path: github.com/containerd/console + +install: + - go get -d + - GOOS=openbsd go get -d + - GOOS=solaris go get -d + - GOOS=windows go get -d + +script: + - go test -race + - GOOS=openbsd go build + - GOOS=openbsd go test -c + - GOOS=solaris go build + - GOOS=solaris go test -c + - GOOS=windows go test diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/LICENSE b/vendor/github.com/containerd/console/LICENSE similarity index 94% rename from vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/LICENSE rename to vendor/github.com/containerd/console/LICENSE index 9f64db8582..261eeb9e9f 100644 --- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/LICENSE +++ b/vendor/github.com/containerd/console/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -176,8 +175,18 @@ END OF TERMS AND CONDITIONS - Copyright 2014 Vishvananda Ishaya. - Copyright 2014 Docker, Inc. + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/containerd/console/README.md b/vendor/github.com/containerd/console/README.md new file mode 100644 index 0000000000..4c56d9d134 --- /dev/null +++ b/vendor/github.com/containerd/console/README.md @@ -0,0 +1,17 @@ +# console + +[![Build Status](https://travis-ci.org/containerd/console.svg?branch=master)](https://travis-ci.org/containerd/console) + +Golang package for dealing with consoles. Light on deps and a simple API. + +## Modifying the current process + +```go +current := console.Current() +defer current.Reset() + +if err := current.SetRaw(); err != nil { +} +ws, err := current.Size() +current.Resize(ws) +``` diff --git a/vendor/github.com/containerd/console/console.go b/vendor/github.com/containerd/console/console.go new file mode 100644 index 0000000000..c187a9b412 --- /dev/null +++ b/vendor/github.com/containerd/console/console.go @@ -0,0 +1,78 @@ +/* + Copyright The containerd Authors. + + 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 console + +import ( + "errors" + "io" + "os" +) + +var ErrNotAConsole = errors.New("provided file is not a console") + +type Console interface { + io.Reader + io.Writer + io.Closer + + // Resize resizes the console to the provided window size + Resize(WinSize) error + // ResizeFrom resizes the calling console to the size of the + // provided console + ResizeFrom(Console) error + // SetRaw sets the console in raw mode + SetRaw() error + // DisableEcho disables echo on the console + DisableEcho() error + // Reset restores the console to its orignal state + Reset() error + // Size returns the window size of the console + Size() (WinSize, error) + // Fd returns the console's file descriptor + Fd() uintptr + // Name returns the console's file name + Name() string +} + +// WinSize specifies the window size of the console +type WinSize struct { + // Height of the console + Height uint16 + // Width of the console + Width uint16 + x uint16 + y uint16 +} + +// Current returns the current processes console +func Current() Console { + c, err := ConsoleFromFile(os.Stdin) + if err != nil { + // stdin should always be a console for the design + // of this function + panic(err) + } + return c +} + +// ConsoleFromFile returns a console using the provided file +func ConsoleFromFile(f *os.File) (Console, error) { + if err := checkConsole(f); err != nil { + return nil, err + } + return newMaster(f) +} diff --git a/vendor/github.com/containerd/console/console_linux.go b/vendor/github.com/containerd/console/console_linux.go new file mode 100644 index 0000000000..42274e100e --- /dev/null +++ b/vendor/github.com/containerd/console/console_linux.go @@ -0,0 +1,275 @@ +// +build linux + +/* + Copyright The containerd Authors. + + 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 console + +import ( + "io" + "os" + "sync" + + "golang.org/x/sys/unix" +) + +const ( + maxEvents = 128 +) + +// Epoller manages multiple epoll consoles using edge-triggered epoll api so we +// dont have to deal with repeated wake-up of EPOLLER or EPOLLHUP. +// For more details, see: +// - https://github.com/systemd/systemd/pull/4262 +// - https://github.com/moby/moby/issues/27202 +// +// Example usage of Epoller and EpollConsole can be as follow: +// +// epoller, _ := NewEpoller() +// epollConsole, _ := epoller.Add(console) +// go epoller.Wait() +// var ( +// b bytes.Buffer +// wg sync.WaitGroup +// ) +// wg.Add(1) +// go func() { +// io.Copy(&b, epollConsole) +// wg.Done() +// }() +// // perform I/O on the console +// epollConsole.Shutdown(epoller.CloseConsole) +// wg.Wait() +// epollConsole.Close() +type Epoller struct { + efd int + mu sync.Mutex + fdMapping map[int]*EpollConsole +} + +// NewEpoller returns an instance of epoller with a valid epoll fd. +func NewEpoller() (*Epoller, error) { + efd, err := unix.EpollCreate1(unix.EPOLL_CLOEXEC) + if err != nil { + return nil, err + } + return &Epoller{ + efd: efd, + fdMapping: make(map[int]*EpollConsole), + }, nil +} + +// Add creates an epoll console based on the provided console. The console will +// be registered with EPOLLET (i.e. using edge-triggered notification) and its +// file descriptor will be set to non-blocking mode. After this, user should use +// the return console to perform I/O. +func (e *Epoller) Add(console Console) (*EpollConsole, error) { + sysfd := int(console.Fd()) + // Set sysfd to non-blocking mode + if err := unix.SetNonblock(sysfd, true); err != nil { + return nil, err + } + + ev := unix.EpollEvent{ + Events: unix.EPOLLIN | unix.EPOLLOUT | unix.EPOLLRDHUP | unix.EPOLLET, + Fd: int32(sysfd), + } + if err := unix.EpollCtl(e.efd, unix.EPOLL_CTL_ADD, sysfd, &ev); err != nil { + return nil, err + } + ef := &EpollConsole{ + Console: console, + sysfd: sysfd, + readc: sync.NewCond(&sync.Mutex{}), + writec: sync.NewCond(&sync.Mutex{}), + } + e.mu.Lock() + e.fdMapping[sysfd] = ef + e.mu.Unlock() + return ef, nil +} + +// Wait starts the loop to wait for its consoles' notifications and signal +// appropriate console that it can perform I/O. +func (e *Epoller) Wait() error { + events := make([]unix.EpollEvent, maxEvents) + for { + n, err := unix.EpollWait(e.efd, events, -1) + if err != nil { + // EINTR: The call was interrupted by a signal handler before either + // any of the requested events occurred or the timeout expired + if err == unix.EINTR { + continue + } + return err + } + for i := 0; i < n; i++ { + ev := &events[i] + // the console is ready to be read from + if ev.Events&(unix.EPOLLIN|unix.EPOLLHUP|unix.EPOLLERR) != 0 { + if epfile := e.getConsole(int(ev.Fd)); epfile != nil { + epfile.signalRead() + } + } + // the console is ready to be written to + if ev.Events&(unix.EPOLLOUT|unix.EPOLLHUP|unix.EPOLLERR) != 0 { + if epfile := e.getConsole(int(ev.Fd)); epfile != nil { + epfile.signalWrite() + } + } + } + } +} + +// CloseConsole unregisters the console's file descriptor from epoll interface +func (e *Epoller) CloseConsole(fd int) error { + e.mu.Lock() + defer e.mu.Unlock() + delete(e.fdMapping, fd) + return unix.EpollCtl(e.efd, unix.EPOLL_CTL_DEL, fd, &unix.EpollEvent{}) +} + +func (e *Epoller) getConsole(sysfd int) *EpollConsole { + e.mu.Lock() + f := e.fdMapping[sysfd] + e.mu.Unlock() + return f +} + +// Close closes the epoll fd +func (e *Epoller) Close() error { + return unix.Close(e.efd) +} + +// EpollConsole acts like a console but registers its file descriptor with an +// epoll fd and uses epoll API to perform I/O. +type EpollConsole struct { + Console + readc *sync.Cond + writec *sync.Cond + sysfd int + closed bool +} + +// Read reads up to len(p) bytes into p. It returns the number of bytes read +// (0 <= n <= len(p)) and any error encountered. +// +// If the console's read returns EAGAIN or EIO, we assume that it's a +// temporary error because the other side went away and wait for the signal +// generated by epoll event to continue. +func (ec *EpollConsole) Read(p []byte) (n int, err error) { + var read int + ec.readc.L.Lock() + defer ec.readc.L.Unlock() + for { + read, err = ec.Console.Read(p[n:]) + n += read + if err != nil { + var hangup bool + if perr, ok := err.(*os.PathError); ok { + hangup = (perr.Err == unix.EAGAIN || perr.Err == unix.EIO) + } else { + hangup = (err == unix.EAGAIN || err == unix.EIO) + } + // if the other end disappear, assume this is temporary and wait for the + // signal to continue again. Unless we didnt read anything and the + // console is already marked as closed then we should exit + if hangup && !(n == 0 && len(p) > 0 && ec.closed) { + ec.readc.Wait() + continue + } + } + break + } + // if we didnt read anything then return io.EOF to end gracefully + if n == 0 && len(p) > 0 && err == nil { + err = io.EOF + } + // signal for others that we finished the read + ec.readc.Signal() + return n, err +} + +// Writes len(p) bytes from p to the console. It returns the number of bytes +// written from p (0 <= n <= len(p)) and any error encountered that caused +// the write to stop early. +// +// If writes to the console returns EAGAIN or EIO, we assume that it's a +// temporary error because the other side went away and wait for the signal +// generated by epoll event to continue. +func (ec *EpollConsole) Write(p []byte) (n int, err error) { + var written int + ec.writec.L.Lock() + defer ec.writec.L.Unlock() + for { + written, err = ec.Console.Write(p[n:]) + n += written + if err != nil { + var hangup bool + if perr, ok := err.(*os.PathError); ok { + hangup = (perr.Err == unix.EAGAIN || perr.Err == unix.EIO) + } else { + hangup = (err == unix.EAGAIN || err == unix.EIO) + } + // if the other end disappears, assume this is temporary and wait for the + // signal to continue again. + if hangup { + ec.writec.Wait() + continue + } + } + // unrecoverable error, break the loop and return the error + break + } + if n < len(p) && err == nil { + err = io.ErrShortWrite + } + // signal for others that we finished the write + ec.writec.Signal() + return n, err +} + +// Shutdown closes the file descriptor and signals call waiters for this fd. +// It accepts a callback which will be called with the console's fd. The +// callback typically will be used to do further cleanup such as unregister the +// console's fd from the epoll interface. +// User should call Shutdown and wait for all I/O operation to be finished +// before closing the console. +func (ec *EpollConsole) Shutdown(close func(int) error) error { + ec.readc.L.Lock() + defer ec.readc.L.Unlock() + ec.writec.L.Lock() + defer ec.writec.L.Unlock() + + ec.readc.Broadcast() + ec.writec.Broadcast() + ec.closed = true + return close(ec.sysfd) +} + +// signalRead signals that the console is readable. +func (ec *EpollConsole) signalRead() { + ec.readc.L.Lock() + ec.readc.Signal() + ec.readc.L.Unlock() +} + +// signalWrite signals that the console is writable. +func (ec *EpollConsole) signalWrite() { + ec.writec.L.Lock() + ec.writec.Signal() + ec.writec.L.Unlock() +} diff --git a/vendor/github.com/containerd/console/console_unix.go b/vendor/github.com/containerd/console/console_unix.go new file mode 100644 index 0000000000..a4a8d1267b --- /dev/null +++ b/vendor/github.com/containerd/console/console_unix.go @@ -0,0 +1,158 @@ +// +build darwin freebsd linux openbsd solaris + +/* + Copyright The containerd Authors. + + 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 console + +import ( + "os" + + "golang.org/x/sys/unix" +) + +// NewPty creates a new pty pair +// The master is returned as the first console and a string +// with the path to the pty slave is returned as the second +func NewPty() (Console, string, error) { + f, err := os.OpenFile("/dev/ptmx", unix.O_RDWR|unix.O_NOCTTY|unix.O_CLOEXEC, 0) + if err != nil { + return nil, "", err + } + slave, err := ptsname(f) + if err != nil { + return nil, "", err + } + if err := unlockpt(f); err != nil { + return nil, "", err + } + m, err := newMaster(f) + if err != nil { + return nil, "", err + } + return m, slave, nil +} + +type master struct { + f *os.File + original *unix.Termios +} + +func (m *master) Read(b []byte) (int, error) { + return m.f.Read(b) +} + +func (m *master) Write(b []byte) (int, error) { + return m.f.Write(b) +} + +func (m *master) Close() error { + return m.f.Close() +} + +func (m *master) Resize(ws WinSize) error { + return tcswinsz(m.f.Fd(), ws) +} + +func (m *master) ResizeFrom(c Console) error { + ws, err := c.Size() + if err != nil { + return err + } + return m.Resize(ws) +} + +func (m *master) Reset() error { + if m.original == nil { + return nil + } + return tcset(m.f.Fd(), m.original) +} + +func (m *master) getCurrent() (unix.Termios, error) { + var termios unix.Termios + if err := tcget(m.f.Fd(), &termios); err != nil { + return unix.Termios{}, err + } + return termios, nil +} + +func (m *master) SetRaw() error { + rawState, err := m.getCurrent() + if err != nil { + return err + } + rawState = cfmakeraw(rawState) + rawState.Oflag = rawState.Oflag | unix.OPOST + return tcset(m.f.Fd(), &rawState) +} + +func (m *master) DisableEcho() error { + rawState, err := m.getCurrent() + if err != nil { + return err + } + rawState.Lflag = rawState.Lflag &^ unix.ECHO + return tcset(m.f.Fd(), &rawState) +} + +func (m *master) Size() (WinSize, error) { + return tcgwinsz(m.f.Fd()) +} + +func (m *master) Fd() uintptr { + return m.f.Fd() +} + +func (m *master) Name() string { + return m.f.Name() +} + +// checkConsole checks if the provided file is a console +func checkConsole(f *os.File) error { + var termios unix.Termios + if tcget(f.Fd(), &termios) != nil { + return ErrNotAConsole + } + return nil +} + +func newMaster(f *os.File) (Console, error) { + m := &master{ + f: f, + } + t, err := m.getCurrent() + if err != nil { + return nil, err + } + m.original = &t + return m, nil +} + +// ClearONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair +// created by us acts normally. In particular, a not-very-well-known default of +// Linux unix98 ptys is that they have +onlcr by default. While this isn't a +// problem for terminal emulators, because we relay data from the terminal we +// also relay that funky line discipline. +func ClearONLCR(fd uintptr) error { + return setONLCR(fd, false) +} + +// SetONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair +// created by us acts as intended for a terminal emulator. +func SetONLCR(fd uintptr) error { + return setONLCR(fd, true) +} diff --git a/vendor/github.com/containerd/console/console_windows.go b/vendor/github.com/containerd/console/console_windows.go new file mode 100644 index 0000000000..62dbe1c033 --- /dev/null +++ b/vendor/github.com/containerd/console/console_windows.go @@ -0,0 +1,216 @@ +/* + Copyright The containerd Authors. + + 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 console + +import ( + "fmt" + "os" + + "github.com/pkg/errors" + "golang.org/x/sys/windows" +) + +var ( + vtInputSupported bool + ErrNotImplemented = errors.New("not implemented") +) + +func (m *master) initStdios() { + m.in = windows.Handle(os.Stdin.Fd()) + if err := windows.GetConsoleMode(m.in, &m.inMode); err == nil { + // Validate that windows.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it. + if err = windows.SetConsoleMode(m.in, m.inMode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err == nil { + vtInputSupported = true + } + // Unconditionally set the console mode back even on failure because SetConsoleMode + // remembers invalid bits on input handles. + windows.SetConsoleMode(m.in, m.inMode) + } else { + fmt.Printf("failed to get console mode for stdin: %v\n", err) + } + + m.out = windows.Handle(os.Stdout.Fd()) + if err := windows.GetConsoleMode(m.out, &m.outMode); err == nil { + if err := windows.SetConsoleMode(m.out, m.outMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil { + m.outMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + } else { + windows.SetConsoleMode(m.out, m.outMode) + } + } else { + fmt.Printf("failed to get console mode for stdout: %v\n", err) + } + + m.err = windows.Handle(os.Stderr.Fd()) + if err := windows.GetConsoleMode(m.err, &m.errMode); err == nil { + if err := windows.SetConsoleMode(m.err, m.errMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil { + m.errMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + } else { + windows.SetConsoleMode(m.err, m.errMode) + } + } else { + fmt.Printf("failed to get console mode for stderr: %v\n", err) + } +} + +type master struct { + in windows.Handle + inMode uint32 + + out windows.Handle + outMode uint32 + + err windows.Handle + errMode uint32 +} + +func (m *master) SetRaw() error { + if err := makeInputRaw(m.in, m.inMode); err != nil { + return err + } + + // Set StdOut and StdErr to raw mode, we ignore failures since + // windows.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this version of + // Windows. + + windows.SetConsoleMode(m.out, m.outMode|windows.DISABLE_NEWLINE_AUTO_RETURN) + + windows.SetConsoleMode(m.err, m.errMode|windows.DISABLE_NEWLINE_AUTO_RETURN) + + return nil +} + +func (m *master) Reset() error { + for _, s := range []struct { + fd windows.Handle + mode uint32 + }{ + {m.in, m.inMode}, + {m.out, m.outMode}, + {m.err, m.errMode}, + } { + if err := windows.SetConsoleMode(s.fd, s.mode); err != nil { + return errors.Wrap(err, "unable to restore console mode") + } + } + + return nil +} + +func (m *master) Size() (WinSize, error) { + var info windows.ConsoleScreenBufferInfo + err := windows.GetConsoleScreenBufferInfo(m.out, &info) + if err != nil { + return WinSize{}, errors.Wrap(err, "unable to get console info") + } + + winsize := WinSize{ + Width: uint16(info.Window.Right - info.Window.Left + 1), + Height: uint16(info.Window.Bottom - info.Window.Top + 1), + } + + return winsize, nil +} + +func (m *master) Resize(ws WinSize) error { + return ErrNotImplemented +} + +func (m *master) ResizeFrom(c Console) error { + return ErrNotImplemented +} + +func (m *master) DisableEcho() error { + mode := m.inMode &^ windows.ENABLE_ECHO_INPUT + mode |= windows.ENABLE_PROCESSED_INPUT + mode |= windows.ENABLE_LINE_INPUT + + if err := windows.SetConsoleMode(m.in, mode); err != nil { + return errors.Wrap(err, "unable to set console to disable echo") + } + + return nil +} + +func (m *master) Close() error { + return nil +} + +func (m *master) Read(b []byte) (int, error) { + return os.Stdin.Read(b) +} + +func (m *master) Write(b []byte) (int, error) { + return os.Stdout.Write(b) +} + +func (m *master) Fd() uintptr { + return uintptr(m.in) +} + +// on windows, console can only be made from os.Std{in,out,err}, hence there +// isnt a single name here we can use. Return a dummy "console" value in this +// case should be sufficient. +func (m *master) Name() string { + return "console" +} + +// makeInputRaw puts the terminal (Windows Console) connected to the given +// file descriptor into raw mode +func makeInputRaw(fd windows.Handle, mode uint32) error { + // See + // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx + + // Disable these modes + mode &^= windows.ENABLE_ECHO_INPUT + mode &^= windows.ENABLE_LINE_INPUT + mode &^= windows.ENABLE_MOUSE_INPUT + mode &^= windows.ENABLE_WINDOW_INPUT + mode &^= windows.ENABLE_PROCESSED_INPUT + + // Enable these modes + mode |= windows.ENABLE_EXTENDED_FLAGS + mode |= windows.ENABLE_INSERT_MODE + mode |= windows.ENABLE_QUICK_EDIT_MODE + + if vtInputSupported { + mode |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT + } + + if err := windows.SetConsoleMode(fd, mode); err != nil { + return errors.Wrap(err, "unable to set console to raw mode") + } + + return nil +} + +func checkConsole(f *os.File) error { + var mode uint32 + if err := windows.GetConsoleMode(windows.Handle(f.Fd()), &mode); err != nil { + return err + } + return nil +} + +func newMaster(f *os.File) (Console, error) { + if f != os.Stdin && f != os.Stdout && f != os.Stderr { + return nil, errors.New("creating a console from a file is not supported on windows") + } + m := &master{} + m.initStdios() + return m, nil +} diff --git a/vendor/github.com/containerd/console/tc_darwin.go b/vendor/github.com/containerd/console/tc_darwin.go new file mode 100644 index 0000000000..b0128abb0c --- /dev/null +++ b/vendor/github.com/containerd/console/tc_darwin.go @@ -0,0 +1,53 @@ +/* + Copyright The containerd Authors. + + 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 console + +import ( + "fmt" + "os" + "unsafe" + + "golang.org/x/sys/unix" +) + +const ( + cmdTcGet = unix.TIOCGETA + cmdTcSet = unix.TIOCSETA +) + +func ioctl(fd, flag, data uintptr) error { + if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, flag, data); err != 0 { + return err + } + return nil +} + +// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. +// unlockpt should be called before opening the slave side of a pty. +func unlockpt(f *os.File) error { + var u int32 + return ioctl(f.Fd(), unix.TIOCPTYUNLK, uintptr(unsafe.Pointer(&u))) +} + +// ptsname retrieves the name of the first available pts for the given master. +func ptsname(f *os.File) (string, error) { + n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCPTYGNAME) + if err != nil { + return "", err + } + return fmt.Sprintf("/dev/pts/%d", n), nil +} diff --git a/vendor/github.com/containerd/console/tc_freebsd.go b/vendor/github.com/containerd/console/tc_freebsd.go new file mode 100644 index 0000000000..04583a6156 --- /dev/null +++ b/vendor/github.com/containerd/console/tc_freebsd.go @@ -0,0 +1,45 @@ +/* + Copyright The containerd Authors. + + 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 console + +import ( + "fmt" + "os" + + "golang.org/x/sys/unix" +) + +const ( + cmdTcGet = unix.TIOCGETA + cmdTcSet = unix.TIOCSETA +) + +// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. +// unlockpt should be called before opening the slave side of a pty. +// This does not exist on FreeBSD, it does not allocate controlling terminals on open +func unlockpt(f *os.File) error { + return nil +} + +// ptsname retrieves the name of the first available pts for the given master. +func ptsname(f *os.File) (string, error) { + n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN) + if err != nil { + return "", err + } + return fmt.Sprintf("/dev/pts/%d", n), nil +} diff --git a/vendor/github.com/containerd/console/tc_linux.go b/vendor/github.com/containerd/console/tc_linux.go new file mode 100644 index 0000000000..1bdd68e6d5 --- /dev/null +++ b/vendor/github.com/containerd/console/tc_linux.go @@ -0,0 +1,49 @@ +/* + Copyright The containerd Authors. + + 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 console + +import ( + "fmt" + "os" + "unsafe" + + "golang.org/x/sys/unix" +) + +const ( + cmdTcGet = unix.TCGETS + cmdTcSet = unix.TCSETS +) + +// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. +// unlockpt should be called before opening the slave side of a pty. +func unlockpt(f *os.File) error { + var u int32 + if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))); err != 0 { + return err + } + return nil +} + +// ptsname retrieves the name of the first available pts for the given master. +func ptsname(f *os.File) (string, error) { + var u uint32 + if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&u))); err != 0 { + return "", err + } + return fmt.Sprintf("/dev/pts/%d", u), nil +} diff --git a/vendor/github.com/containerd/console/tc_openbsd_cgo.go b/vendor/github.com/containerd/console/tc_openbsd_cgo.go new file mode 100644 index 0000000000..f0cec06a72 --- /dev/null +++ b/vendor/github.com/containerd/console/tc_openbsd_cgo.go @@ -0,0 +1,51 @@ +// +build openbsd,cgo + +/* + Copyright The containerd Authors. + + 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 console + +import ( + "os" + + "golang.org/x/sys/unix" +) + +//#include +import "C" + +const ( + cmdTcGet = unix.TIOCGETA + cmdTcSet = unix.TIOCSETA +) + +// ptsname retrieves the name of the first available pts for the given master. +func ptsname(f *os.File) (string, error) { + ptspath, err := C.ptsname(C.int(f.Fd())) + if err != nil { + return "", err + } + return C.GoString(ptspath), nil +} + +// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. +// unlockpt should be called before opening the slave side of a pty. +func unlockpt(f *os.File) error { + if _, err := C.grantpt(C.int(f.Fd())); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/containerd/console/tc_openbsd_nocgo.go b/vendor/github.com/containerd/console/tc_openbsd_nocgo.go new file mode 100644 index 0000000000..daccce2058 --- /dev/null +++ b/vendor/github.com/containerd/console/tc_openbsd_nocgo.go @@ -0,0 +1,47 @@ +// +build openbsd,!cgo + +/* + Copyright The containerd Authors. + + 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. +*/ + +// +// Implementing the functions below requires cgo support. Non-cgo stubs +// versions are defined below to enable cross-compilation of source code +// that depends on these functions, but the resultant cross-compiled +// binaries cannot actually be used. If the stub function(s) below are +// actually invoked they will display an error message and cause the +// calling process to exit. +// + +package console + +import ( + "os" + + "golang.org/x/sys/unix" +) + +const ( + cmdTcGet = unix.TIOCGETA + cmdTcSet = unix.TIOCSETA +) + +func ptsname(f *os.File) (string, error) { + panic("ptsname() support requires cgo.") +} + +func unlockpt(f *os.File) error { + panic("unlockpt() support requires cgo.") +} diff --git a/vendor/github.com/containerd/console/tc_solaris_cgo.go b/vendor/github.com/containerd/console/tc_solaris_cgo.go new file mode 100644 index 0000000000..e36a68edd1 --- /dev/null +++ b/vendor/github.com/containerd/console/tc_solaris_cgo.go @@ -0,0 +1,51 @@ +// +build solaris,cgo + +/* + Copyright The containerd Authors. + + 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 console + +import ( + "os" + + "golang.org/x/sys/unix" +) + +//#include +import "C" + +const ( + cmdTcGet = unix.TCGETS + cmdTcSet = unix.TCSETS +) + +// ptsname retrieves the name of the first available pts for the given master. +func ptsname(f *os.File) (string, error) { + ptspath, err := C.ptsname(C.int(f.Fd())) + if err != nil { + return "", err + } + return C.GoString(ptspath), nil +} + +// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. +// unlockpt should be called before opening the slave side of a pty. +func unlockpt(f *os.File) error { + if _, err := C.grantpt(C.int(f.Fd())); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/containerd/console/tc_solaris_nocgo.go b/vendor/github.com/containerd/console/tc_solaris_nocgo.go new file mode 100644 index 0000000000..eb0bd2c36b --- /dev/null +++ b/vendor/github.com/containerd/console/tc_solaris_nocgo.go @@ -0,0 +1,47 @@ +// +build solaris,!cgo + +/* + Copyright The containerd Authors. + + 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. +*/ + +// +// Implementing the functions below requires cgo support. Non-cgo stubs +// versions are defined below to enable cross-compilation of source code +// that depends on these functions, but the resultant cross-compiled +// binaries cannot actually be used. If the stub function(s) below are +// actually invoked they will display an error message and cause the +// calling process to exit. +// + +package console + +import ( + "os" + + "golang.org/x/sys/unix" +) + +const ( + cmdTcGet = unix.TCGETS + cmdTcSet = unix.TCSETS +) + +func ptsname(f *os.File) (string, error) { + panic("ptsname() support requires cgo.") +} + +func unlockpt(f *os.File) error { + panic("unlockpt() support requires cgo.") +} diff --git a/vendor/github.com/containerd/console/tc_unix.go b/vendor/github.com/containerd/console/tc_unix.go new file mode 100644 index 0000000000..7ae773c53e --- /dev/null +++ b/vendor/github.com/containerd/console/tc_unix.go @@ -0,0 +1,91 @@ +// +build darwin freebsd linux openbsd solaris + +/* + Copyright The containerd Authors. + + 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 console + +import ( + "golang.org/x/sys/unix" +) + +func tcget(fd uintptr, p *unix.Termios) error { + termios, err := unix.IoctlGetTermios(int(fd), cmdTcGet) + if err != nil { + return err + } + *p = *termios + return nil +} + +func tcset(fd uintptr, p *unix.Termios) error { + return unix.IoctlSetTermios(int(fd), cmdTcSet, p) +} + +func tcgwinsz(fd uintptr) (WinSize, error) { + var ws WinSize + + uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) + if err != nil { + return ws, err + } + + // Translate from unix.Winsize to console.WinSize + ws.Height = uws.Row + ws.Width = uws.Col + ws.x = uws.Xpixel + ws.y = uws.Ypixel + return ws, nil +} + +func tcswinsz(fd uintptr, ws WinSize) error { + // Translate from console.WinSize to unix.Winsize + + var uws unix.Winsize + uws.Row = ws.Height + uws.Col = ws.Width + uws.Xpixel = ws.x + uws.Ypixel = ws.y + + return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, &uws) +} + +func setONLCR(fd uintptr, enable bool) error { + var termios unix.Termios + if err := tcget(fd, &termios); err != nil { + return err + } + if enable { + // Set +onlcr so we can act like a real terminal + termios.Oflag |= unix.ONLCR + } else { + // Set -onlcr so we don't have to deal with \r. + termios.Oflag &^= unix.ONLCR + } + return tcset(fd, &termios) +} + +func cfmakeraw(t unix.Termios) unix.Termios { + t.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) + t.Oflag &^= unix.OPOST + t.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) + t.Cflag &^= (unix.CSIZE | unix.PARENB) + t.Cflag &^= unix.CS8 + t.Cc[unix.VMIN] = 1 + t.Cc[unix.VTIME] = 0 + + return t +} diff --git a/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go b/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go index 009ebda70c..1a940c39b2 100644 --- a/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go +++ b/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: auth.proto -// DO NOT EDIT! /* Package authpb is a generated protocol buffer package. @@ -22,6 +21,8 @@ import ( math "math" + _ "github.com/gogo/protobuf/gogoproto" + io "io" ) @@ -217,24 +218,6 @@ func (m *Role) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func encodeFixed64Auth(dAtA []byte, offset int, v uint64) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - dAtA[offset+4] = uint8(v >> 32) - dAtA[offset+5] = uint8(v >> 40) - dAtA[offset+6] = uint8(v >> 48) - dAtA[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Auth(dAtA []byte, offset int, v uint32) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - return offset + 4 -} func encodeVarintAuth(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) diff --git a/vendor/github.com/coreos/etcd/clientv3/README.md b/vendor/github.com/coreos/etcd/clientv3/README.md index 643d0e2f07..376bfba761 100644 --- a/vendor/github.com/coreos/etcd/clientv3/README.md +++ b/vendor/github.com/coreos/etcd/clientv3/README.md @@ -1,6 +1,6 @@ # etcd/clientv3 -[![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/coreos/etcd/clientv3) +[![Godoc](https://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/coreos/etcd/clientv3) `etcd/clientv3` is the official Go etcd client for v3. diff --git a/vendor/github.com/coreos/etcd/clientv3/auth.go b/vendor/github.com/coreos/etcd/clientv3/auth.go index 18f1f5b091..7545bb6ca1 100644 --- a/vendor/github.com/coreos/etcd/clientv3/auth.go +++ b/vendor/github.com/coreos/etcd/clientv3/auth.go @@ -15,12 +15,13 @@ package clientv3 import ( + "context" "fmt" "strings" "github.com/coreos/etcd/auth/authpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "golang.org/x/net/context" + "google.golang.org/grpc" ) @@ -100,60 +101,65 @@ type Auth interface { } type auth struct { - remote pb.AuthClient + remote pb.AuthClient + callOpts []grpc.CallOption } func NewAuth(c *Client) Auth { - return &auth{remote: pb.NewAuthClient(c.ActiveConnection())} + api := &auth{remote: RetryAuthClient(c)} + if c != nil { + api.callOpts = c.callOpts + } + return api } func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) { - resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, grpc.FailFast(false)) + resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, auth.callOpts...) return (*AuthEnableResponse)(resp), toErr(ctx, err) } func (auth *auth) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) { - resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, grpc.FailFast(false)) + resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, auth.callOpts...) return (*AuthDisableResponse)(resp), toErr(ctx, err) } func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) { - resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}) + resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}, auth.callOpts...) return (*AuthUserAddResponse)(resp), toErr(ctx, err) } func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) { - resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}) + resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, auth.callOpts...) return (*AuthUserDeleteResponse)(resp), toErr(ctx, err) } func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) { - resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}) + resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, auth.callOpts...) return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err) } func (auth *auth) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) { - resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}) + resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, auth.callOpts...) return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err) } func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) { - resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, grpc.FailFast(false)) + resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, auth.callOpts...) return (*AuthUserGetResponse)(resp), toErr(ctx, err) } func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) { - resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, grpc.FailFast(false)) + resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, auth.callOpts...) return (*AuthUserListResponse)(resp), toErr(ctx, err) } func (auth *auth) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) { - resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}) + resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, auth.callOpts...) return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err) } func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) { - resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}) + resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, auth.callOpts...) return (*AuthRoleAddResponse)(resp), toErr(ctx, err) } @@ -163,27 +169,27 @@ func (auth *auth) RoleGrantPermission(ctx context.Context, name string, key, ran RangeEnd: []byte(rangeEnd), PermType: authpb.Permission_Type(permType), } - resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}) + resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}, auth.callOpts...) return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err) } func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) { - resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, grpc.FailFast(false)) + resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, auth.callOpts...) return (*AuthRoleGetResponse)(resp), toErr(ctx, err) } func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) { - resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, grpc.FailFast(false)) + resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, auth.callOpts...) return (*AuthRoleListResponse)(resp), toErr(ctx, err) } func (auth *auth) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) { - resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: key, RangeEnd: rangeEnd}) + resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: key, RangeEnd: rangeEnd}, auth.callOpts...) return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err) } func (auth *auth) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) { - resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}) + resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, auth.callOpts...) return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err) } @@ -196,12 +202,13 @@ func StrToPermissionType(s string) (PermissionType, error) { } type authenticator struct { - conn *grpc.ClientConn // conn in-use - remote pb.AuthClient + conn *grpc.ClientConn // conn in-use + remote pb.AuthClient + callOpts []grpc.CallOption } func (auth *authenticator) authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) { - resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password}, grpc.FailFast(false)) + resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password}, auth.callOpts...) return (*AuthenticateResponse)(resp), toErr(ctx, err) } @@ -209,14 +216,18 @@ func (auth *authenticator) close() { auth.conn.Close() } -func newAuthenticator(endpoint string, opts []grpc.DialOption) (*authenticator, error) { +func newAuthenticator(endpoint string, opts []grpc.DialOption, c *Client) (*authenticator, error) { conn, err := grpc.Dial(endpoint, opts...) if err != nil { return nil, err } - return &authenticator{ + api := &authenticator{ conn: conn, remote: pb.NewAuthClient(conn), - }, nil + } + if c != nil { + api.callOpts = c.callOpts + } + return api, nil } diff --git a/vendor/github.com/coreos/etcd/clientv3/balancer.go b/vendor/github.com/coreos/etcd/clientv3/balancer.go deleted file mode 100644 index 6ae047e984..0000000000 --- a/vendor/github.com/coreos/etcd/clientv3/balancer.go +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2016 The etcd Authors -// -// 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 clientv3 - -import ( - "net/url" - "strings" - "sync" - - "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" -) - -// ErrNoAddrAvilable is returned by Get() when the balancer does not have -// any active connection to endpoints at the time. -// This error is returned only when opts.BlockingWait is true. -var ErrNoAddrAvilable = grpc.Errorf(codes.Unavailable, "there is no address available") - -// simpleBalancer does the bare minimum to expose multiple eps -// to the grpc reconnection code path -type simpleBalancer struct { - // addrs are the client's endpoints for grpc - addrs []grpc.Address - // notifyCh notifies grpc of the set of addresses for connecting - notifyCh chan []grpc.Address - - // readyc closes once the first connection is up - readyc chan struct{} - readyOnce sync.Once - - // mu protects upEps, pinAddr, and connectingAddr - mu sync.RWMutex - - // upc closes when upEps transitions from empty to non-zero or the balancer closes. - upc chan struct{} - - // downc closes when grpc calls down() on pinAddr - downc chan struct{} - - // stopc is closed to signal updateNotifyLoop should stop. - stopc chan struct{} - - // donec closes when all goroutines are exited - donec chan struct{} - - // updateAddrsC notifies updateNotifyLoop to update addrs. - updateAddrsC chan struct{} - - // grpc issues TLS cert checks using the string passed into dial so - // that string must be the host. To recover the full scheme://host URL, - // have a map from hosts to the original endpoint. - host2ep map[string]string - - // pinAddr is the currently pinned address; set to the empty string on - // intialization and shutdown. - pinAddr string - - closed bool -} - -func newSimpleBalancer(eps []string) *simpleBalancer { - notifyCh := make(chan []grpc.Address, 1) - addrs := make([]grpc.Address, len(eps)) - for i := range eps { - addrs[i].Addr = getHost(eps[i]) - } - sb := &simpleBalancer{ - addrs: addrs, - notifyCh: notifyCh, - readyc: make(chan struct{}), - upc: make(chan struct{}), - stopc: make(chan struct{}), - downc: make(chan struct{}), - donec: make(chan struct{}), - updateAddrsC: make(chan struct{}, 1), - host2ep: getHost2ep(eps), - } - close(sb.downc) - go sb.updateNotifyLoop() - return sb -} - -func (b *simpleBalancer) Start(target string, config grpc.BalancerConfig) error { return nil } - -func (b *simpleBalancer) ConnectNotify() <-chan struct{} { - b.mu.Lock() - defer b.mu.Unlock() - return b.upc -} - -func (b *simpleBalancer) getEndpoint(host string) string { - b.mu.Lock() - defer b.mu.Unlock() - return b.host2ep[host] -} - -func getHost2ep(eps []string) map[string]string { - hm := make(map[string]string, len(eps)) - for i := range eps { - _, host, _ := parseEndpoint(eps[i]) - hm[host] = eps[i] - } - return hm -} - -func (b *simpleBalancer) updateAddrs(eps []string) { - np := getHost2ep(eps) - - b.mu.Lock() - - match := len(np) == len(b.host2ep) - for k, v := range np { - if b.host2ep[k] != v { - match = false - break - } - } - if match { - // same endpoints, so no need to update address - b.mu.Unlock() - return - } - - b.host2ep = np - - addrs := make([]grpc.Address, 0, len(eps)) - for i := range eps { - addrs = append(addrs, grpc.Address{Addr: getHost(eps[i])}) - } - b.addrs = addrs - - // updating notifyCh can trigger new connections, - // only update addrs if all connections are down - // or addrs does not include pinAddr. - update := !hasAddr(addrs, b.pinAddr) - b.mu.Unlock() - - if update { - select { - case b.updateAddrsC <- struct{}{}: - case <-b.stopc: - } - } -} - -func hasAddr(addrs []grpc.Address, targetAddr string) bool { - for _, addr := range addrs { - if targetAddr == addr.Addr { - return true - } - } - return false -} - -func (b *simpleBalancer) updateNotifyLoop() { - defer close(b.donec) - - for { - b.mu.RLock() - upc, downc, addr := b.upc, b.downc, b.pinAddr - b.mu.RUnlock() - // downc or upc should be closed - select { - case <-downc: - downc = nil - default: - } - select { - case <-upc: - upc = nil - default: - } - switch { - case downc == nil && upc == nil: - // stale - select { - case <-b.stopc: - return - default: - } - case downc == nil: - b.notifyAddrs() - select { - case <-upc: - case <-b.updateAddrsC: - b.notifyAddrs() - case <-b.stopc: - return - } - case upc == nil: - select { - // close connections that are not the pinned address - case b.notifyCh <- []grpc.Address{{Addr: addr}}: - case <-downc: - case <-b.stopc: - return - } - select { - case <-downc: - case <-b.updateAddrsC: - case <-b.stopc: - return - } - b.notifyAddrs() - } - } -} - -func (b *simpleBalancer) notifyAddrs() { - b.mu.RLock() - addrs := b.addrs - b.mu.RUnlock() - select { - case b.notifyCh <- addrs: - case <-b.stopc: - } -} - -func (b *simpleBalancer) Up(addr grpc.Address) func(error) { - b.mu.Lock() - defer b.mu.Unlock() - - // gRPC might call Up after it called Close. We add this check - // to "fix" it up at application layer. Or our simplerBalancer - // might panic since b.upc is closed. - if b.closed { - return func(err error) {} - } - // gRPC might call Up on a stale address. - // Prevent updating pinAddr with a stale address. - if !hasAddr(b.addrs, addr.Addr) { - return func(err error) {} - } - if b.pinAddr != "" { - return func(err error) {} - } - // notify waiting Get()s and pin first connected address - close(b.upc) - b.downc = make(chan struct{}) - b.pinAddr = addr.Addr - // notify client that a connection is up - b.readyOnce.Do(func() { close(b.readyc) }) - return func(err error) { - b.mu.Lock() - b.upc = make(chan struct{}) - close(b.downc) - b.pinAddr = "" - b.mu.Unlock() - } -} - -func (b *simpleBalancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (grpc.Address, func(), error) { - var ( - addr string - closed bool - ) - - // If opts.BlockingWait is false (for fail-fast RPCs), it should return - // an address it has notified via Notify immediately instead of blocking. - if !opts.BlockingWait { - b.mu.RLock() - closed = b.closed - addr = b.pinAddr - b.mu.RUnlock() - if closed { - return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing - } - if addr == "" { - return grpc.Address{Addr: ""}, nil, ErrNoAddrAvilable - } - return grpc.Address{Addr: addr}, func() {}, nil - } - - for { - b.mu.RLock() - ch := b.upc - b.mu.RUnlock() - select { - case <-ch: - case <-b.donec: - return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing - case <-ctx.Done(): - return grpc.Address{Addr: ""}, nil, ctx.Err() - } - b.mu.RLock() - closed = b.closed - addr = b.pinAddr - b.mu.RUnlock() - // Close() which sets b.closed = true can be called before Get(), Get() must exit if balancer is closed. - if closed { - return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing - } - if addr != "" { - break - } - } - return grpc.Address{Addr: addr}, func() {}, nil -} - -func (b *simpleBalancer) Notify() <-chan []grpc.Address { return b.notifyCh } - -func (b *simpleBalancer) Close() error { - b.mu.Lock() - // In case gRPC calls close twice. TODO: remove the checking - // when we are sure that gRPC wont call close twice. - if b.closed { - b.mu.Unlock() - <-b.donec - return nil - } - b.closed = true - close(b.stopc) - b.pinAddr = "" - - // In the case of following scenario: - // 1. upc is not closed; no pinned address - // 2. client issues an rpc, calling invoke(), which calls Get(), enters for loop, blocks - // 3. clientconn.Close() calls balancer.Close(); closed = true - // 4. for loop in Get() never exits since ctx is the context passed in by the client and may not be canceled - // we must close upc so Get() exits from blocking on upc - select { - case <-b.upc: - default: - // terminate all waiting Get()s - close(b.upc) - } - - b.mu.Unlock() - - // wait for updateNotifyLoop to finish - <-b.donec - close(b.notifyCh) - - return nil -} - -func getHost(ep string) string { - url, uerr := url.Parse(ep) - if uerr != nil || !strings.Contains(ep, "://") { - return ep - } - return url.Host -} diff --git a/vendor/github.com/coreos/etcd/clientv3/client.go b/vendor/github.com/coreos/etcd/clientv3/client.go index f220a895ef..7132807767 100644 --- a/vendor/github.com/coreos/etcd/clientv3/client.go +++ b/vendor/github.com/coreos/etcd/clientv3/client.go @@ -15,6 +15,7 @@ package clientv3 import ( + "context" "crypto/tls" "errors" "fmt" @@ -27,11 +28,12 @@ import ( "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" - "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" ) var ( @@ -51,21 +53,22 @@ type Client struct { conn *grpc.ClientConn dialerrc chan error - cfg Config - creds *credentials.TransportCredentials - balancer *simpleBalancer - retryWrapper retryRpcFunc - retryAuthWrapper retryRpcFunc + cfg Config + creds *credentials.TransportCredentials + balancer *healthBalancer + mu *sync.Mutex ctx context.Context cancel context.CancelFunc - // Username is a username for authentication + // Username is a user name for authentication. Username string - // Password is a password for authentication + // Password is a password for authentication. Password string // tokenCred is an instance of WithPerRPCCredentials()'s argument tokenCred *authTokenCredential + + callOpts []grpc.CallOption } // New creates a new etcdv3 client from a given configuration. @@ -116,8 +119,23 @@ func (c *Client) Endpoints() (eps []string) { // SetEndpoints updates client's endpoints. func (c *Client) SetEndpoints(eps ...string) { + c.mu.Lock() c.cfg.Endpoints = eps - c.balancer.updateAddrs(eps) + c.mu.Unlock() + c.balancer.updateAddrs(eps...) + + // updating notifyCh can trigger new connections, + // need update addrs if all connections are down + // or addrs does not include pinAddr. + c.balancer.mu.RLock() + update := !hasAddr(c.balancer.addrs, c.balancer.pinAddr) + c.balancer.mu.RUnlock() + if update { + select { + case c.balancer.updateAddrsC <- notifyNext: + case <-c.balancer.stopc: + } + } } // Sync synchronizes client's endpoints with the known endpoints from the etcd membership. @@ -144,8 +162,10 @@ func (c *Client) autoSync() { case <-c.ctx.Done(): return case <-time.After(c.cfg.AutoSyncInterval): - ctx, _ := context.WithTimeout(c.ctx, 5*time.Second) - if err := c.Sync(ctx); err != nil && err != c.ctx.Err() { + ctx, cancel := context.WithTimeout(c.ctx, 5*time.Second) + err := c.Sync(ctx) + cancel() + if err != nil && err != c.ctx.Err() { logger.Println("Auto sync endpoints failed:", err) } } @@ -174,7 +194,7 @@ func parseEndpoint(endpoint string) (proto string, host string, scheme string) { host = endpoint url, uerr := url.Parse(endpoint) if uerr != nil || !strings.Contains(endpoint, "://") { - return + return proto, host, scheme } scheme = url.Scheme @@ -188,7 +208,7 @@ func parseEndpoint(endpoint string) (proto string, host string, scheme string) { default: proto, host = "", "" } - return + return proto, host, scheme } func (c *Client) processCreds(scheme string) (creds *credentials.TransportCredentials) { @@ -207,7 +227,7 @@ func (c *Client) processCreds(scheme string) (creds *credentials.TransportCreden default: creds = nil } - return + return creds } // dialSetupOpts gives the dial opts prior to any authentication @@ -215,10 +235,17 @@ func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) (opts if c.cfg.DialTimeout > 0 { opts = []grpc.DialOption{grpc.WithTimeout(c.cfg.DialTimeout)} } + if c.cfg.DialKeepAliveTime > 0 { + params := keepalive.ClientParameters{ + Time: c.cfg.DialKeepAliveTime, + Timeout: c.cfg.DialKeepAliveTimeout, + } + opts = append(opts, grpc.WithKeepaliveParams(params)) + } opts = append(opts, dopts...) f := func(host string, t time.Duration) (net.Conn, error) { - proto, host, _ := parseEndpoint(c.balancer.getEndpoint(host)) + proto, host, _ := parseEndpoint(c.balancer.endpoint(host)) if host == "" && endpoint != "" { // dialing an endpoint not in the balancer; use // endpoint passed into dial @@ -270,7 +297,7 @@ func (c *Client) getToken(ctx context.Context) error { endpoint := c.cfg.Endpoints[i] host := getHost(endpoint) // use dial options without dopts to avoid reusing the client balancer - auth, err = newAuthenticator(host, c.dialSetupOpts(endpoint)) + auth, err = newAuthenticator(host, c.dialSetupOpts(endpoint), c) if err != nil { continue } @@ -311,7 +338,7 @@ func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientCo if err != nil { if toErr(ctx, err) != rpctypes.ErrAuthNotEnabled { if err == ctx.Err() && ctx.Err() != c.ctx.Err() { - err = grpc.ErrClientConnTimeout + err = context.DeadlineExceeded } return nil, err } @@ -333,7 +360,7 @@ func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientCo // when the cluster has a leader. func WithRequireLeader(ctx context.Context) context.Context { md := metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader) - return metadata.NewContext(ctx, md) + return metadata.NewOutgoingContext(ctx, md) } func newClient(cfg *Config) (*Client, error) { @@ -360,15 +387,37 @@ func newClient(cfg *Config) (*Client, error) { creds: creds, ctx: ctx, cancel: cancel, + mu: new(sync.Mutex), + callOpts: defaultCallOpts, } if cfg.Username != "" && cfg.Password != "" { client.Username = cfg.Username client.Password = cfg.Password } + if cfg.MaxCallSendMsgSize > 0 || cfg.MaxCallRecvMsgSize > 0 { + if cfg.MaxCallRecvMsgSize > 0 && cfg.MaxCallSendMsgSize > cfg.MaxCallRecvMsgSize { + return nil, fmt.Errorf("gRPC message recv limit (%d bytes) must be greater than send limit (%d bytes)", cfg.MaxCallRecvMsgSize, cfg.MaxCallSendMsgSize) + } + callOpts := []grpc.CallOption{ + defaultFailFast, + defaultMaxCallSendMsgSize, + defaultMaxCallRecvMsgSize, + } + if cfg.MaxCallSendMsgSize > 0 { + callOpts[1] = grpc.MaxCallSendMsgSize(cfg.MaxCallSendMsgSize) + } + if cfg.MaxCallRecvMsgSize > 0 { + callOpts[2] = grpc.MaxCallRecvMsgSize(cfg.MaxCallRecvMsgSize) + } + client.callOpts = callOpts + } + + client.balancer = newHealthBalancer(cfg.Endpoints, cfg.DialTimeout, func(ep string) (bool, error) { + return grpcHealthCheck(client, ep) + }) - client.balancer = newSimpleBalancer(cfg.Endpoints) // use Endpoints[0] so that for https:// without any tls config given, then - // grpc will assume the ServerName is in the endpoint. + // grpc will assume the certificate server name is the endpoint host. conn, err := client.dial(cfg.Endpoints[0], grpc.WithBalancer(client.balancer)) if err != nil { client.cancel() @@ -376,21 +425,19 @@ func newClient(cfg *Config) (*Client, error) { return nil, err } client.conn = conn - client.retryWrapper = client.newRetryWrapper() - client.retryAuthWrapper = client.newAuthRetryWrapper() // wait for a connection if cfg.DialTimeout > 0 { hasConn := false waitc := time.After(cfg.DialTimeout) select { - case <-client.balancer.readyc: + case <-client.balancer.ready(): hasConn = true case <-ctx.Done(): case <-waitc: } if !hasConn { - err := grpc.ErrClientConnTimeout + err := context.DeadlineExceeded select { case err = <-client.dialerrc: default: @@ -425,7 +472,7 @@ func (c *Client) checkVersion() (err error) { errc := make(chan error, len(c.cfg.Endpoints)) ctx, cancel := context.WithCancel(c.ctx) if c.cfg.DialTimeout > 0 { - ctx, _ = context.WithTimeout(ctx, c.cfg.DialTimeout) + ctx, cancel = context.WithTimeout(ctx, c.cfg.DialTimeout) } wg.Add(len(c.cfg.Endpoints)) for _, ep := range c.cfg.Endpoints { @@ -440,7 +487,7 @@ func (c *Client) checkVersion() (err error) { vs := strings.Split(resp.Version, ".") maj, min := 0, 0 if len(vs) >= 2 { - maj, rerr = strconv.Atoi(vs[0]) + maj, _ = strconv.Atoi(vs[0]) min, rerr = strconv.Atoi(vs[1]) } if maj < 3 || (maj == 3 && min < 2) { @@ -472,14 +519,28 @@ func isHaltErr(ctx context.Context, err error) bool { if err == nil { return false } - code := grpc.Code(err) + ev, _ := status.FromError(err) // Unavailable codes mean the system will be right back. // (e.g., can't connect, lost leader) // Treat Internal codes as if something failed, leaving the // system in an inconsistent state, but retrying could make progress. // (e.g., failed in middle of send, corrupted frame) // TODO: are permanent Internal errors possible from grpc? - return code != codes.Unavailable && code != codes.Internal + return ev.Code() != codes.Unavailable && ev.Code() != codes.Internal +} + +// isUnavailableErr returns true if the given error is an unavailable error +func isUnavailableErr(ctx context.Context, err error) bool { + if ctx != nil && ctx.Err() != nil { + return false + } + if err == nil { + return false + } + ev, _ := status.FromError(err) + // Unavailable codes mean the system will be right back. + // (e.g., can't connect, lost leader) + return ev.Code() == codes.Unavailable } func toErr(ctx context.Context, err error) error { @@ -490,7 +551,8 @@ func toErr(ctx context.Context, err error) error { if _, ok := err.(rpctypes.EtcdError); ok { return err } - code := grpc.Code(err) + ev, _ := status.FromError(err) + code := ev.Code() switch code { case codes.DeadlineExceeded: fallthrough @@ -499,7 +561,6 @@ func toErr(ctx context.Context, err error) error { err = ctx.Err() } case codes.Unavailable: - err = ErrNoAvailableEndpoints case codes.FailedPrecondition: err = grpc.ErrClientConnClosing } diff --git a/vendor/github.com/coreos/etcd/clientv3/cluster.go b/vendor/github.com/coreos/etcd/clientv3/cluster.go index 922d900e3c..785672be8c 100644 --- a/vendor/github.com/coreos/etcd/clientv3/cluster.go +++ b/vendor/github.com/coreos/etcd/clientv3/cluster.go @@ -15,8 +15,11 @@ package clientv3 import ( + "context" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "golang.org/x/net/context" + "github.com/coreos/etcd/pkg/types" + "google.golang.org/grpc" ) @@ -43,20 +46,34 @@ type Cluster interface { } type cluster struct { - remote pb.ClusterClient + remote pb.ClusterClient + callOpts []grpc.CallOption } func NewCluster(c *Client) Cluster { - return &cluster{remote: RetryClusterClient(c)} + api := &cluster{remote: RetryClusterClient(c)} + if c != nil { + api.callOpts = c.callOpts + } + return api } -func NewClusterFromClusterClient(remote pb.ClusterClient) Cluster { - return &cluster{remote: remote} +func NewClusterFromClusterClient(remote pb.ClusterClient, c *Client) Cluster { + api := &cluster{remote: remote} + if c != nil { + api.callOpts = c.callOpts + } + return api } func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) { + // fail-fast before panic in rafthttp + if _, err := types.NewURLs(peerAddrs); err != nil { + return nil, err + } + r := &pb.MemberAddRequest{PeerURLs: peerAddrs} - resp, err := c.remote.MemberAdd(ctx, r) + resp, err := c.remote.MemberAdd(ctx, r, c.callOpts...) if err != nil { return nil, toErr(ctx, err) } @@ -65,7 +82,7 @@ func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAdd func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error) { r := &pb.MemberRemoveRequest{ID: id} - resp, err := c.remote.MemberRemove(ctx, r) + resp, err := c.remote.MemberRemove(ctx, r, c.callOpts...) if err != nil { return nil, toErr(ctx, err) } @@ -73,28 +90,25 @@ func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveRes } func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) { + // fail-fast before panic in rafthttp + if _, err := types.NewURLs(peerAddrs); err != nil { + return nil, err + } + // it is safe to retry on update. - for { - r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs} - resp, err := c.remote.MemberUpdate(ctx, r, grpc.FailFast(false)) - if err == nil { - return (*MemberUpdateResponse)(resp), nil - } - if isHaltErr(ctx, err) { - return nil, toErr(ctx, err) - } + r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs} + resp, err := c.remote.MemberUpdate(ctx, r, c.callOpts...) + if err == nil { + return (*MemberUpdateResponse)(resp), nil } + return nil, toErr(ctx, err) } func (c *cluster) MemberList(ctx context.Context) (*MemberListResponse, error) { // it is safe to retry on list. - for { - resp, err := c.remote.MemberList(ctx, &pb.MemberListRequest{}, grpc.FailFast(false)) - if err == nil { - return (*MemberListResponse)(resp), nil - } - if isHaltErr(ctx, err) { - return nil, toErr(ctx, err) - } + resp, err := c.remote.MemberList(ctx, &pb.MemberListRequest{}, c.callOpts...) + if err == nil { + return (*MemberListResponse)(resp), nil } + return nil, toErr(ctx, err) } diff --git a/vendor/github.com/coreos/etcd/clientv3/compact_op.go b/vendor/github.com/coreos/etcd/clientv3/compact_op.go index 32d97eb0cc..41e80c1da5 100644 --- a/vendor/github.com/coreos/etcd/clientv3/compact_op.go +++ b/vendor/github.com/coreos/etcd/clientv3/compact_op.go @@ -44,10 +44,8 @@ func (op CompactOp) toRequest() *pb.CompactionRequest { return &pb.CompactionRequest{Revision: op.revision, Physical: op.physical} } -// WithCompactPhysical makes compact RPC call wait until -// the compaction is physically applied to the local database -// such that compacted entries are totally removed from the -// backend database. +// WithCompactPhysical makes Compact wait until all compacted entries are +// removed from the etcd server's storage. func WithCompactPhysical() CompactOption { return func(op *CompactOp) { op.physical = true } } diff --git a/vendor/github.com/coreos/etcd/clientv3/compare.go b/vendor/github.com/coreos/etcd/clientv3/compare.go index c55228cc0b..b5f0a25527 100644 --- a/vendor/github.com/coreos/etcd/clientv3/compare.go +++ b/vendor/github.com/coreos/etcd/clientv3/compare.go @@ -60,6 +60,8 @@ func Compare(cmp Cmp, result string, v interface{}) Cmp { cmp.TargetUnion = &pb.Compare_CreateRevision{CreateRevision: mustInt64(v)} case pb.Compare_MOD: cmp.TargetUnion = &pb.Compare_ModRevision{ModRevision: mustInt64(v)} + case pb.Compare_LEASE: + cmp.TargetUnion = &pb.Compare_Lease{Lease: mustInt64orLeaseID(v)} default: panic("Unknown compare type") } @@ -82,6 +84,12 @@ func ModRevision(key string) Cmp { return Cmp{Key: []byte(key), Target: pb.Compare_MOD} } +// LeaseValue compares a key's LeaseID to a value of your choosing. The empty +// LeaseID is 0, otherwise known as `NoLease`. +func LeaseValue(key string) Cmp { + return Cmp{Key: []byte(key), Target: pb.Compare_LEASE} +} + // KeyBytes returns the byte slice holding with the comparison key. func (cmp *Cmp) KeyBytes() []byte { return cmp.Key } @@ -99,6 +107,19 @@ func (cmp *Cmp) ValueBytes() []byte { // WithValueBytes sets the byte slice for the comparison's value. func (cmp *Cmp) WithValueBytes(v []byte) { cmp.TargetUnion.(*pb.Compare_Value).Value = v } +// WithRange sets the comparison to scan the range [key, end). +func (cmp Cmp) WithRange(end string) Cmp { + cmp.RangeEnd = []byte(end) + return cmp +} + +// WithPrefix sets the comparison to scan all keys prefixed by the key. +func (cmp Cmp) WithPrefix() Cmp { + cmp.RangeEnd = getPrefix(cmp.Key) + return cmp +} + +// mustInt64 panics if val isn't an int or int64. It returns an int64 otherwise. func mustInt64(val interface{}) int64 { if v, ok := val.(int64); ok { return v @@ -108,3 +129,12 @@ func mustInt64(val interface{}) int64 { } panic("bad value") } + +// mustInt64orLeaseID panics if val isn't a LeaseID, int or int64. It returns an +// int64 otherwise. +func mustInt64orLeaseID(val interface{}) int64 { + if v, ok := val.(LeaseID); ok { + return int64(v) + } + return mustInt64(val) +} diff --git a/vendor/github.com/coreos/etcd/clientv3/config.go b/vendor/github.com/coreos/etcd/clientv3/config.go index dda72a748e..79d6e2a984 100644 --- a/vendor/github.com/coreos/etcd/clientv3/config.go +++ b/vendor/github.com/coreos/etcd/clientv3/config.go @@ -15,10 +15,10 @@ package clientv3 import ( + "context" "crypto/tls" "time" - "golang.org/x/net/context" "google.golang.org/grpc" ) @@ -33,10 +33,31 @@ type Config struct { // DialTimeout is the timeout for failing to establish a connection. DialTimeout time.Duration `json:"dial-timeout"` + // DialKeepAliveTime is the time after which client pings the server to see if + // transport is alive. + DialKeepAliveTime time.Duration `json:"dial-keep-alive-time"` + + // DialKeepAliveTimeout is the time that the client waits for a response for the + // keep-alive probe. If the response is not received in this time, the connection is closed. + DialKeepAliveTimeout time.Duration `json:"dial-keep-alive-timeout"` + + // MaxCallSendMsgSize is the client-side request send limit in bytes. + // If 0, it defaults to 2.0 MiB (2 * 1024 * 1024). + // Make sure that "MaxCallSendMsgSize" < server-side default send/recv limit. + // ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes"). + MaxCallSendMsgSize int + + // MaxCallRecvMsgSize is the client-side response receive limit. + // If 0, it defaults to "math.MaxInt32", because range response can + // easily exceed request send limits. + // Make sure that "MaxCallRecvMsgSize" >= server-side default send/recv limit. + // ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes"). + MaxCallRecvMsgSize int + // TLS holds the client secure credentials, if any. TLS *tls.Config - // Username is a username for authentication. + // Username is a user name for authentication. Username string `json:"username"` // Password is a password for authentication. diff --git a/vendor/github.com/coreos/etcd/clientv3/doc.go b/vendor/github.com/coreos/etcd/clientv3/doc.go index 470ca4dc47..717fbe435e 100644 --- a/vendor/github.com/coreos/etcd/clientv3/doc.go +++ b/vendor/github.com/coreos/etcd/clientv3/doc.go @@ -16,6 +16,22 @@ // // Create client using `clientv3.New`: // +// // expect dial time-out on ipv4 blackhole +// _, err := clientv3.New(clientv3.Config{ +// Endpoints: []string{"http://254.0.0.1:12345"}, +// DialTimeout: 2 * time.Second +// }) +// +// // etcd clientv3 >= v3.2.10, grpc/grpc-go >= v1.7.3 +// if err == context.DeadlineExceeded { +// // handle errors +// } +// +// // etcd clientv3 <= v3.2.9, grpc/grpc-go <= v1.2.1 +// if err == grpc.ErrClientConnTimeout { +// // handle errors +// } +// // cli, err := clientv3.New(clientv3.Config{ // Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"}, // DialTimeout: 5 * time.Second, @@ -28,7 +44,7 @@ // Make sure to close the client after using it. If the client is not closed, the // connection will have leaky goroutines. // -// To specify client request timeout, pass context.WithTimeout to APIs: +// To specify a client request timeout, wrap the context with context.WithTimeout: // // ctx, cancel := context.WithTimeout(context.Background(), timeout) // resp, err := kvc.Put(ctx, "sample_key", "sample_value") @@ -41,10 +57,11 @@ // The Client has internal state (watchers and leases), so Clients should be reused instead of created as needed. // Clients are safe for concurrent use by multiple goroutines. // -// etcd client returns 2 types of errors: +// etcd client returns 3 types of errors: // -// 1. context error: canceled or deadline exceeded. -// 2. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go +// 1. context error: canceled or deadline exceeded. +// 2. gRPC status error: e.g. when clock drifts in server-side before client's context deadline exceeded. +// 3. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go // // Here is the example code to handle client errors: // @@ -54,6 +71,12 @@ // // ctx is canceled by another routine // } else if err == context.DeadlineExceeded { // // ctx is attached with a deadline and it exceeded +// } else if ev, ok := status.FromError(err); ok { +// code := ev.Code() +// if code == codes.DeadlineExceeded { +// // server-side context might have timed-out first (due to clock skew) +// // while original client-side context is not timed-out yet +// } // } else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok { // // process (verr.Errors) // } else { @@ -61,4 +84,14 @@ // } // } // +// go func() { cli.Close() }() +// _, err := kvc.Get(ctx, "a") +// if err != nil { +// if err == context.Canceled { +// // grpc balancer calls 'Get' with an inflight client.Close +// } else if err == grpc.ErrClientConnClosing { +// // grpc balancer calls 'Get' after client.Close. +// } +// } +// package clientv3 diff --git a/vendor/github.com/coreos/etcd/clientv3/health_balancer.go b/vendor/github.com/coreos/etcd/clientv3/health_balancer.go new file mode 100644 index 0000000000..5918cba848 --- /dev/null +++ b/vendor/github.com/coreos/etcd/clientv3/health_balancer.go @@ -0,0 +1,609 @@ +// Copyright 2017 The etcd Authors +// +// 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 clientv3 + +import ( + "context" + "errors" + "net/url" + "strings" + "sync" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + healthpb "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/status" +) + +const ( + minHealthRetryDuration = 3 * time.Second + unknownService = "unknown service grpc.health.v1.Health" +) + +// ErrNoAddrAvilable is returned by Get() when the balancer does not have +// any active connection to endpoints at the time. +// This error is returned only when opts.BlockingWait is true. +var ErrNoAddrAvilable = status.Error(codes.Unavailable, "there is no address available") + +type healthCheckFunc func(ep string) (bool, error) + +type notifyMsg int + +const ( + notifyReset notifyMsg = iota + notifyNext +) + +// healthBalancer does the bare minimum to expose multiple eps +// to the grpc reconnection code path +type healthBalancer struct { + // addrs are the client's endpoint addresses for grpc + addrs []grpc.Address + + // eps holds the raw endpoints from the client + eps []string + + // notifyCh notifies grpc of the set of addresses for connecting + notifyCh chan []grpc.Address + + // readyc closes once the first connection is up + readyc chan struct{} + readyOnce sync.Once + + // healthCheck checks an endpoint's health. + healthCheck healthCheckFunc + healthCheckTimeout time.Duration + + unhealthyMu sync.RWMutex + unhealthyHostPorts map[string]time.Time + + // mu protects all fields below. + mu sync.RWMutex + + // upc closes when pinAddr transitions from empty to non-empty or the balancer closes. + upc chan struct{} + + // downc closes when grpc calls down() on pinAddr + downc chan struct{} + + // stopc is closed to signal updateNotifyLoop should stop. + stopc chan struct{} + stopOnce sync.Once + wg sync.WaitGroup + + // donec closes when all goroutines are exited + donec chan struct{} + + // updateAddrsC notifies updateNotifyLoop to update addrs. + updateAddrsC chan notifyMsg + + // grpc issues TLS cert checks using the string passed into dial so + // that string must be the host. To recover the full scheme://host URL, + // have a map from hosts to the original endpoint. + hostPort2ep map[string]string + + // pinAddr is the currently pinned address; set to the empty string on + // initialization and shutdown. + pinAddr string + + closed bool +} + +func newHealthBalancer(eps []string, timeout time.Duration, hc healthCheckFunc) *healthBalancer { + notifyCh := make(chan []grpc.Address) + addrs := eps2addrs(eps) + hb := &healthBalancer{ + addrs: addrs, + eps: eps, + notifyCh: notifyCh, + readyc: make(chan struct{}), + healthCheck: hc, + unhealthyHostPorts: make(map[string]time.Time), + upc: make(chan struct{}), + stopc: make(chan struct{}), + downc: make(chan struct{}), + donec: make(chan struct{}), + updateAddrsC: make(chan notifyMsg), + hostPort2ep: getHostPort2ep(eps), + } + if timeout < minHealthRetryDuration { + timeout = minHealthRetryDuration + } + hb.healthCheckTimeout = timeout + + close(hb.downc) + go hb.updateNotifyLoop() + hb.wg.Add(1) + go func() { + defer hb.wg.Done() + hb.updateUnhealthy() + }() + return hb +} + +func (b *healthBalancer) Start(target string, config grpc.BalancerConfig) error { return nil } + +func (b *healthBalancer) ConnectNotify() <-chan struct{} { + b.mu.Lock() + defer b.mu.Unlock() + return b.upc +} + +func (b *healthBalancer) ready() <-chan struct{} { return b.readyc } + +func (b *healthBalancer) endpoint(hostPort string) string { + b.mu.RLock() + defer b.mu.RUnlock() + return b.hostPort2ep[hostPort] +} + +func (b *healthBalancer) pinned() string { + b.mu.RLock() + defer b.mu.RUnlock() + return b.pinAddr +} + +func (b *healthBalancer) hostPortError(hostPort string, err error) { + if b.endpoint(hostPort) == "" { + logger.Lvl(4).Infof("clientv3/balancer: %q is stale (skip marking as unhealthy on %q)", hostPort, err.Error()) + return + } + + b.unhealthyMu.Lock() + b.unhealthyHostPorts[hostPort] = time.Now() + b.unhealthyMu.Unlock() + logger.Lvl(4).Infof("clientv3/balancer: %q is marked unhealthy (%q)", hostPort, err.Error()) +} + +func (b *healthBalancer) removeUnhealthy(hostPort, msg string) { + if b.endpoint(hostPort) == "" { + logger.Lvl(4).Infof("clientv3/balancer: %q was not in unhealthy (%q)", hostPort, msg) + return + } + + b.unhealthyMu.Lock() + delete(b.unhealthyHostPorts, hostPort) + b.unhealthyMu.Unlock() + logger.Lvl(4).Infof("clientv3/balancer: %q is removed from unhealthy (%q)", hostPort, msg) +} + +func (b *healthBalancer) countUnhealthy() (count int) { + b.unhealthyMu.RLock() + count = len(b.unhealthyHostPorts) + b.unhealthyMu.RUnlock() + return count +} + +func (b *healthBalancer) isUnhealthy(hostPort string) (unhealthy bool) { + b.unhealthyMu.RLock() + _, unhealthy = b.unhealthyHostPorts[hostPort] + b.unhealthyMu.RUnlock() + return unhealthy +} + +func (b *healthBalancer) cleanupUnhealthy() { + b.unhealthyMu.Lock() + for k, v := range b.unhealthyHostPorts { + if time.Since(v) > b.healthCheckTimeout { + delete(b.unhealthyHostPorts, k) + logger.Lvl(4).Infof("clientv3/balancer: removed %q from unhealthy after %v", k, b.healthCheckTimeout) + } + } + b.unhealthyMu.Unlock() +} + +func (b *healthBalancer) liveAddrs() ([]grpc.Address, map[string]struct{}) { + unhealthyCnt := b.countUnhealthy() + + b.mu.RLock() + defer b.mu.RUnlock() + + hbAddrs := b.addrs + if len(b.addrs) == 1 || unhealthyCnt == 0 || unhealthyCnt == len(b.addrs) { + liveHostPorts := make(map[string]struct{}, len(b.hostPort2ep)) + for k := range b.hostPort2ep { + liveHostPorts[k] = struct{}{} + } + return hbAddrs, liveHostPorts + } + + addrs := make([]grpc.Address, 0, len(b.addrs)-unhealthyCnt) + liveHostPorts := make(map[string]struct{}, len(addrs)) + for _, addr := range b.addrs { + if !b.isUnhealthy(addr.Addr) { + addrs = append(addrs, addr) + liveHostPorts[addr.Addr] = struct{}{} + } + } + return addrs, liveHostPorts +} + +func (b *healthBalancer) updateUnhealthy() { + for { + select { + case <-time.After(b.healthCheckTimeout): + b.cleanupUnhealthy() + pinned := b.pinned() + if pinned == "" || b.isUnhealthy(pinned) { + select { + case b.updateAddrsC <- notifyNext: + case <-b.stopc: + return + } + } + case <-b.stopc: + return + } + } +} + +func (b *healthBalancer) updateAddrs(eps ...string) { + np := getHostPort2ep(eps) + + b.mu.Lock() + defer b.mu.Unlock() + + match := len(np) == len(b.hostPort2ep) + if match { + for k, v := range np { + if b.hostPort2ep[k] != v { + match = false + break + } + } + } + if match { + // same endpoints, so no need to update address + return + } + + b.hostPort2ep = np + b.addrs, b.eps = eps2addrs(eps), eps + + b.unhealthyMu.Lock() + b.unhealthyHostPorts = make(map[string]time.Time) + b.unhealthyMu.Unlock() +} + +func (b *healthBalancer) next() { + b.mu.RLock() + downc := b.downc + b.mu.RUnlock() + select { + case b.updateAddrsC <- notifyNext: + case <-b.stopc: + } + // wait until disconnect so new RPCs are not issued on old connection + select { + case <-downc: + case <-b.stopc: + } +} + +func (b *healthBalancer) updateNotifyLoop() { + defer close(b.donec) + + for { + b.mu.RLock() + upc, downc, addr := b.upc, b.downc, b.pinAddr + b.mu.RUnlock() + // downc or upc should be closed + select { + case <-downc: + downc = nil + default: + } + select { + case <-upc: + upc = nil + default: + } + switch { + case downc == nil && upc == nil: + // stale + select { + case <-b.stopc: + return + default: + } + case downc == nil: + b.notifyAddrs(notifyReset) + select { + case <-upc: + case msg := <-b.updateAddrsC: + b.notifyAddrs(msg) + case <-b.stopc: + return + } + case upc == nil: + select { + // close connections that are not the pinned address + case b.notifyCh <- []grpc.Address{{Addr: addr}}: + case <-downc: + case <-b.stopc: + return + } + select { + case <-downc: + b.notifyAddrs(notifyReset) + case msg := <-b.updateAddrsC: + b.notifyAddrs(msg) + case <-b.stopc: + return + } + } + } +} + +func (b *healthBalancer) notifyAddrs(msg notifyMsg) { + if msg == notifyNext { + select { + case b.notifyCh <- []grpc.Address{}: + case <-b.stopc: + return + } + } + b.mu.RLock() + pinAddr := b.pinAddr + downc := b.downc + b.mu.RUnlock() + addrs, hostPorts := b.liveAddrs() + + var waitDown bool + if pinAddr != "" { + _, ok := hostPorts[pinAddr] + waitDown = !ok + } + + select { + case b.notifyCh <- addrs: + if waitDown { + select { + case <-downc: + case <-b.stopc: + } + } + case <-b.stopc: + } +} + +func (b *healthBalancer) Up(addr grpc.Address) func(error) { + if !b.mayPin(addr) { + return func(err error) {} + } + + b.mu.Lock() + defer b.mu.Unlock() + + // gRPC might call Up after it called Close. We add this check + // to "fix" it up at application layer. Otherwise, will panic + // if b.upc is already closed. + if b.closed { + return func(err error) {} + } + + // gRPC might call Up on a stale address. + // Prevent updating pinAddr with a stale address. + if !hasAddr(b.addrs, addr.Addr) { + return func(err error) {} + } + + if b.pinAddr != "" { + logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (already pinned %q)", addr.Addr, b.pinAddr) + return func(err error) {} + } + + // notify waiting Get()s and pin first connected address + close(b.upc) + b.downc = make(chan struct{}) + b.pinAddr = addr.Addr + logger.Lvl(4).Infof("clientv3/balancer: pin %q", addr.Addr) + + // notify client that a connection is up + b.readyOnce.Do(func() { close(b.readyc) }) + + return func(err error) { + // If connected to a black hole endpoint or a killed server, the gRPC ping + // timeout will induce a network I/O error, and retrying until success; + // finding healthy endpoint on retry could take several timeouts and redials. + // To avoid wasting retries, gray-list unhealthy endpoints. + b.hostPortError(addr.Addr, err) + + b.mu.Lock() + b.upc = make(chan struct{}) + close(b.downc) + b.pinAddr = "" + b.mu.Unlock() + logger.Lvl(4).Infof("clientv3/balancer: unpin %q (%q)", addr.Addr, err.Error()) + } +} + +func (b *healthBalancer) mayPin(addr grpc.Address) bool { + if b.endpoint(addr.Addr) == "" { // stale host:port + return false + } + + b.unhealthyMu.RLock() + unhealthyCnt := len(b.unhealthyHostPorts) + failedTime, bad := b.unhealthyHostPorts[addr.Addr] + b.unhealthyMu.RUnlock() + + b.mu.RLock() + skip := len(b.addrs) == 1 || unhealthyCnt == 0 || len(b.addrs) == unhealthyCnt + b.mu.RUnlock() + if skip || !bad { + return true + } + + // prevent isolated member's endpoint from being infinitely retried, as follows: + // 1. keepalive pings detects GoAway with http2.ErrCodeEnhanceYourCalm + // 2. balancer 'Up' unpins with grpc: failed with network I/O error + // 3. grpc-healthcheck still SERVING, thus retry to pin + // instead, return before grpc-healthcheck if failed within healthcheck timeout + if elapsed := time.Since(failedTime); elapsed < b.healthCheckTimeout { + logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (failed %v ago, require minimum %v after failure)", addr.Addr, elapsed, b.healthCheckTimeout) + return false + } + + if ok, _ := b.healthCheck(addr.Addr); ok { + b.removeUnhealthy(addr.Addr, "health check success") + return true + } + + b.hostPortError(addr.Addr, errors.New("health check failed")) + return false +} + +func (b *healthBalancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (grpc.Address, func(), error) { + var ( + addr string + closed bool + ) + + // If opts.BlockingWait is false (for fail-fast RPCs), it should return + // an address it has notified via Notify immediately instead of blocking. + if !opts.BlockingWait { + b.mu.RLock() + closed = b.closed + addr = b.pinAddr + b.mu.RUnlock() + if closed { + return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing + } + if addr == "" { + return grpc.Address{Addr: ""}, nil, ErrNoAddrAvilable + } + return grpc.Address{Addr: addr}, func() {}, nil + } + + for { + b.mu.RLock() + ch := b.upc + b.mu.RUnlock() + select { + case <-ch: + case <-b.donec: + return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing + case <-ctx.Done(): + return grpc.Address{Addr: ""}, nil, ctx.Err() + } + b.mu.RLock() + closed = b.closed + addr = b.pinAddr + b.mu.RUnlock() + // Close() which sets b.closed = true can be called before Get(), Get() must exit if balancer is closed. + if closed { + return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing + } + if addr != "" { + break + } + } + return grpc.Address{Addr: addr}, func() {}, nil +} + +func (b *healthBalancer) Notify() <-chan []grpc.Address { return b.notifyCh } + +func (b *healthBalancer) Close() error { + b.mu.Lock() + // In case gRPC calls close twice. TODO: remove the checking + // when we are sure that gRPC wont call close twice. + if b.closed { + b.mu.Unlock() + <-b.donec + return nil + } + b.closed = true + b.stopOnce.Do(func() { close(b.stopc) }) + b.pinAddr = "" + + // In the case of following scenario: + // 1. upc is not closed; no pinned address + // 2. client issues an RPC, calling invoke(), which calls Get(), enters for loop, blocks + // 3. client.conn.Close() calls balancer.Close(); closed = true + // 4. for loop in Get() never exits since ctx is the context passed in by the client and may not be canceled + // we must close upc so Get() exits from blocking on upc + select { + case <-b.upc: + default: + // terminate all waiting Get()s + close(b.upc) + } + + b.mu.Unlock() + b.wg.Wait() + + // wait for updateNotifyLoop to finish + <-b.donec + close(b.notifyCh) + + return nil +} + +func grpcHealthCheck(client *Client, ep string) (bool, error) { + conn, err := client.dial(ep) + if err != nil { + return false, err + } + defer conn.Close() + cli := healthpb.NewHealthClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + resp, err := cli.Check(ctx, &healthpb.HealthCheckRequest{}) + cancel() + if err != nil { + if s, ok := status.FromError(err); ok && s.Code() == codes.Unavailable { + if s.Message() == unknownService { // etcd < v3.3.0 + return true, nil + } + } + return false, err + } + return resp.Status == healthpb.HealthCheckResponse_SERVING, nil +} + +func hasAddr(addrs []grpc.Address, targetAddr string) bool { + for _, addr := range addrs { + if targetAddr == addr.Addr { + return true + } + } + return false +} + +func getHost(ep string) string { + url, uerr := url.Parse(ep) + if uerr != nil || !strings.Contains(ep, "://") { + return ep + } + return url.Host +} + +func eps2addrs(eps []string) []grpc.Address { + addrs := make([]grpc.Address, len(eps)) + for i := range eps { + addrs[i].Addr = getHost(eps[i]) + } + return addrs +} + +func getHostPort2ep(eps []string) map[string]string { + hm := make(map[string]string, len(eps)) + for i := range eps { + _, host, _ := parseEndpoint(eps[i]) + hm[host] = eps[i] + } + return hm +} diff --git a/vendor/github.com/coreos/etcd/clientv3/kv.go b/vendor/github.com/coreos/etcd/clientv3/kv.go index dc45fa4ad0..5a7469bd4c 100644 --- a/vendor/github.com/coreos/etcd/clientv3/kv.go +++ b/vendor/github.com/coreos/etcd/clientv3/kv.go @@ -15,8 +15,10 @@ package clientv3 import ( + "context" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "golang.org/x/net/context" + "google.golang.org/grpc" ) @@ -66,22 +68,46 @@ type OpResponse struct { put *PutResponse get *GetResponse del *DeleteResponse + txn *TxnResponse } func (op OpResponse) Put() *PutResponse { return op.put } func (op OpResponse) Get() *GetResponse { return op.get } func (op OpResponse) Del() *DeleteResponse { return op.del } +func (op OpResponse) Txn() *TxnResponse { return op.txn } + +func (resp *PutResponse) OpResponse() OpResponse { + return OpResponse{put: resp} +} +func (resp *GetResponse) OpResponse() OpResponse { + return OpResponse{get: resp} +} +func (resp *DeleteResponse) OpResponse() OpResponse { + return OpResponse{del: resp} +} +func (resp *TxnResponse) OpResponse() OpResponse { + return OpResponse{txn: resp} +} type kv struct { - remote pb.KVClient + remote pb.KVClient + callOpts []grpc.CallOption } func NewKV(c *Client) KV { - return &kv{remote: RetryKVClient(c)} + api := &kv{remote: RetryKVClient(c)} + if c != nil { + api.callOpts = c.callOpts + } + return api } -func NewKVFromKVClient(remote pb.KVClient) KV { - return &kv{remote: remote} +func NewKVFromKVClient(remote pb.KVClient, c *Client) KV { + api := &kv{remote: remote} + if c != nil { + api.callOpts = c.callOpts + } + return api } func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) { @@ -100,7 +126,7 @@ func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*Delete } func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) { - resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest()) + resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest(), kv.callOpts...) if err != nil { return nil, toErr(ctx, err) } @@ -109,54 +135,43 @@ func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*C func (kv *kv) Txn(ctx context.Context) Txn { return &txn{ - kv: kv, - ctx: ctx, + kv: kv, + ctx: ctx, + callOpts: kv.callOpts, } } func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) { - for { - resp, err := kv.do(ctx, op) - if err == nil { - return resp, nil - } - - if isHaltErr(ctx, err) { - return resp, toErr(ctx, err) - } - // do not retry on modifications - if op.isWrite() { - return resp, toErr(ctx, err) - } - } -} - -func (kv *kv) do(ctx context.Context, op Op) (OpResponse, error) { var err error switch op.t { - // TODO: handle other ops case tRange: var resp *pb.RangeResponse - resp, err = kv.remote.Range(ctx, op.toRangeRequest(), grpc.FailFast(false)) + resp, err = kv.remote.Range(ctx, op.toRangeRequest(), kv.callOpts...) if err == nil { return OpResponse{get: (*GetResponse)(resp)}, nil } case tPut: var resp *pb.PutResponse r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease} - resp, err = kv.remote.Put(ctx, r) + resp, err = kv.remote.Put(ctx, r, kv.callOpts...) if err == nil { return OpResponse{put: (*PutResponse)(resp)}, nil } case tDeleteRange: var resp *pb.DeleteRangeResponse r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV} - resp, err = kv.remote.DeleteRange(ctx, r) + resp, err = kv.remote.DeleteRange(ctx, r, kv.callOpts...) if err == nil { return OpResponse{del: (*DeleteResponse)(resp)}, nil } + case tTxn: + var resp *pb.TxnResponse + resp, err = kv.remote.Txn(ctx, op.toTxnRequest(), kv.callOpts...) + if err == nil { + return OpResponse{txn: (*TxnResponse)(resp)}, nil + } default: panic("Unknown op") } - return OpResponse{}, err + return OpResponse{}, toErr(ctx, err) } diff --git a/vendor/github.com/coreos/etcd/clientv3/lease.go b/vendor/github.com/coreos/etcd/clientv3/lease.go index 6e7ea1f82d..3729cf37be 100644 --- a/vendor/github.com/coreos/etcd/clientv3/lease.go +++ b/vendor/github.com/coreos/etcd/clientv3/lease.go @@ -15,12 +15,13 @@ package clientv3 import ( + "context" "sync" "time" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "golang.org/x/net/context" + "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) @@ -30,7 +31,7 @@ type ( LeaseID int64 ) -// LeaseGrantResponse is used to convert the protobuf grant response. +// LeaseGrantResponse wraps the protobuf message LeaseGrantResponse. type LeaseGrantResponse struct { *pb.ResponseHeader ID LeaseID @@ -38,19 +39,19 @@ type LeaseGrantResponse struct { Error string } -// LeaseKeepAliveResponse is used to convert the protobuf keepalive response. +// LeaseKeepAliveResponse wraps the protobuf message LeaseKeepAliveResponse. type LeaseKeepAliveResponse struct { *pb.ResponseHeader ID LeaseID TTL int64 } -// LeaseTimeToLiveResponse is used to convert the protobuf lease timetolive response. +// LeaseTimeToLiveResponse wraps the protobuf message LeaseTimeToLiveResponse. type LeaseTimeToLiveResponse struct { *pb.ResponseHeader ID LeaseID `json:"id"` - // TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. + // TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. Expired lease will return -1. TTL int64 `json:"ttl"` // GrantedTTL is the initial granted time in seconds upon lease creation/renewal. @@ -60,12 +61,22 @@ type LeaseTimeToLiveResponse struct { Keys [][]byte `json:"keys"` } +// LeaseStatus represents a lease status. +type LeaseStatus struct { + ID LeaseID `json:"id"` + // TODO: TTL int64 +} + +// LeaseLeasesResponse wraps the protobuf message LeaseLeasesResponse. +type LeaseLeasesResponse struct { + *pb.ResponseHeader + Leases []LeaseStatus `json:"leases"` +} + const ( // defaultTTL is the assumed lease TTL used for the first keepalive // deadline before the actual TTL is known to the client. defaultTTL = 5 * time.Second - // a small buffer to store unsent lease responses. - leaseResponseChSize = 16 // NoLease is a lease ID for the absence of a lease. NoLease LeaseID = 0 @@ -73,6 +84,11 @@ const ( retryConnWait = 500 * time.Millisecond ) +// LeaseResponseChSize is the size of buffer to store unsent lease responses. +// WARNING: DO NOT UPDATE. +// Only for testing purposes. +var LeaseResponseChSize = 16 + // ErrKeepAliveHalted is returned if client keep alive loop halts with an unexpected error. // // This usually means that automatic lease renewal via KeepAlive is broken, but KeepAliveOnce will still work as expected. @@ -98,11 +114,32 @@ type Lease interface { // TimeToLive retrieves the lease information of the given lease ID. TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) - // KeepAlive keeps the given lease alive forever. + // Leases retrieves all leases. + Leases(ctx context.Context) (*LeaseLeasesResponse, error) + + // KeepAlive keeps the given lease alive forever. If the keepalive response + // posted to the channel is not consumed immediately, the lease client will + // continue sending keep alive requests to the etcd server at least every + // second until latest response is consumed. + // + // The returned "LeaseKeepAliveResponse" channel closes if underlying keep + // alive stream is interrupted in some way the client cannot handle itself; + // given context "ctx" is canceled or timed out. "LeaseKeepAliveResponse" + // from this closed channel is nil. + // + // If client keep alive loop halts with an unexpected error (e.g. "etcdserver: + // no leader") or canceled by the caller (e.g. context.Canceled), the error + // is returned. Otherwise, it retries. + // + // TODO(v4.0): post errors to last keep alive message before closing + // (see https://github.com/coreos/etcd/pull/7866) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) - // KeepAliveOnce renews the lease once. In most of the cases, Keepalive - // should be used instead of KeepAliveOnce. + // KeepAliveOnce renews the lease once. The response corresponds to the + // first message from calling KeepAlive. If the response has a recoverable + // error, KeepAliveOnce will retry the RPC with a new keep alive message. + // + // In most of the cases, Keepalive should be used instead of KeepAliveOnce. KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) // Close releases all resources Lease keeps for efficient communication @@ -133,6 +170,8 @@ type lessor struct { // firstKeepAliveOnce ensures stream starts after first KeepAlive call. firstKeepAliveOnce sync.Once + + callOpts []grpc.CallOption } // keepAlive multiplexes a keepalive for a lease over multiple channels @@ -148,10 +187,10 @@ type keepAlive struct { } func NewLease(c *Client) Lease { - return NewLeaseFromLeaseClient(RetryLeaseClient(c), c.cfg.DialTimeout+time.Second) + return NewLeaseFromLeaseClient(RetryLeaseClient(c), c, c.cfg.DialTimeout+time.Second) } -func NewLeaseFromLeaseClient(remote pb.LeaseClient, keepAliveTimeout time.Duration) Lease { +func NewLeaseFromLeaseClient(remote pb.LeaseClient, c *Client, keepAliveTimeout time.Duration) Lease { l := &lessor{ donec: make(chan struct{}), keepAlives: make(map[LeaseID]*keepAlive), @@ -161,66 +200,68 @@ func NewLeaseFromLeaseClient(remote pb.LeaseClient, keepAliveTimeout time.Durati if l.firstKeepAliveTimeout == time.Second { l.firstKeepAliveTimeout = defaultTTL } + if c != nil { + l.callOpts = c.callOpts + } reqLeaderCtx := WithRequireLeader(context.Background()) l.stopCtx, l.stopCancel = context.WithCancel(reqLeaderCtx) return l } func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) { - for { - r := &pb.LeaseGrantRequest{TTL: ttl} - resp, err := l.remote.LeaseGrant(ctx, r) - if err == nil { - gresp := &LeaseGrantResponse{ - ResponseHeader: resp.GetHeader(), - ID: LeaseID(resp.ID), - TTL: resp.TTL, - Error: resp.Error, - } - return gresp, nil - } - if isHaltErr(ctx, err) { - return nil, toErr(ctx, err) + r := &pb.LeaseGrantRequest{TTL: ttl} + resp, err := l.remote.LeaseGrant(ctx, r, l.callOpts...) + if err == nil { + gresp := &LeaseGrantResponse{ + ResponseHeader: resp.GetHeader(), + ID: LeaseID(resp.ID), + TTL: resp.TTL, + Error: resp.Error, } + return gresp, nil } + return nil, toErr(ctx, err) } func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) { - for { - r := &pb.LeaseRevokeRequest{ID: int64(id)} - resp, err := l.remote.LeaseRevoke(ctx, r) - - if err == nil { - return (*LeaseRevokeResponse)(resp), nil - } - if isHaltErr(ctx, err) { - return nil, toErr(ctx, err) - } + r := &pb.LeaseRevokeRequest{ID: int64(id)} + resp, err := l.remote.LeaseRevoke(ctx, r, l.callOpts...) + if err == nil { + return (*LeaseRevokeResponse)(resp), nil } + return nil, toErr(ctx, err) } func (l *lessor) TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) { - for { - r := toLeaseTimeToLiveRequest(id, opts...) - resp, err := l.remote.LeaseTimeToLive(ctx, r, grpc.FailFast(false)) - if err == nil { - gresp := &LeaseTimeToLiveResponse{ - ResponseHeader: resp.GetHeader(), - ID: LeaseID(resp.ID), - TTL: resp.TTL, - GrantedTTL: resp.GrantedTTL, - Keys: resp.Keys, - } - return gresp, nil + r := toLeaseTimeToLiveRequest(id, opts...) + resp, err := l.remote.LeaseTimeToLive(ctx, r, l.callOpts...) + if err == nil { + gresp := &LeaseTimeToLiveResponse{ + ResponseHeader: resp.GetHeader(), + ID: LeaseID(resp.ID), + TTL: resp.TTL, + GrantedTTL: resp.GrantedTTL, + Keys: resp.Keys, } - if isHaltErr(ctx, err) { - return nil, toErr(ctx, err) + return gresp, nil + } + return nil, toErr(ctx, err) +} + +func (l *lessor) Leases(ctx context.Context) (*LeaseLeasesResponse, error) { + resp, err := l.remote.LeaseLeases(ctx, &pb.LeaseLeasesRequest{}, l.callOpts...) + if err == nil { + leases := make([]LeaseStatus, len(resp.Leases)) + for i := range resp.Leases { + leases[i] = LeaseStatus{ID: LeaseID(resp.Leases[i].ID)} } + return &LeaseLeasesResponse{ResponseHeader: resp.GetHeader(), Leases: leases}, nil } + return nil, toErr(ctx, err) } func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) { - ch := make(chan *LeaseKeepAliveResponse, leaseResponseChSize) + ch := make(chan *LeaseKeepAliveResponse, LeaseResponseChSize) l.mu.Lock() // ensure that recvKeepAliveLoop is still running @@ -314,7 +355,7 @@ func (l *lessor) keepAliveCtxCloser(id LeaseID, ctx context.Context, donec <-cha } } -// closeRequireLeader scans all keep alives for ctxs that have require leader +// closeRequireLeader scans keepAlives for ctxs that have require leader // and closes the associated channels. func (l *lessor) closeRequireLeader() { l.mu.Lock() @@ -323,7 +364,7 @@ func (l *lessor) closeRequireLeader() { reqIdxs := 0 // find all required leader channels, close, mark as nil for i, ctx := range ka.ctxs { - md, ok := metadata.FromContext(ctx) + md, ok := metadata.FromOutgoingContext(ctx) if !ok { continue } @@ -357,7 +398,7 @@ func (l *lessor) keepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAlive cctx, cancel := context.WithCancel(ctx) defer cancel() - stream, err := l.remote.LeaseKeepAlive(cctx, grpc.FailFast(false)) + stream, err := l.remote.LeaseKeepAlive(cctx, l.callOpts...) if err != nil { return nil, toErr(ctx, err) } @@ -386,7 +427,7 @@ func (l *lessor) recvKeepAliveLoop() (gerr error) { close(l.donec) l.loopErr = gerr for _, ka := range l.keepAlives { - ka.Close() + ka.close() } l.keepAlives = make(map[LeaseID]*keepAlive) l.mu.Unlock() @@ -401,7 +442,6 @@ func (l *lessor) recvKeepAliveLoop() (gerr error) { } else { for { resp, err := stream.Recv() - if err != nil { if canceledByCaller(l.stopCtx, err) { return err @@ -426,10 +466,10 @@ func (l *lessor) recvKeepAliveLoop() (gerr error) { } } -// resetRecv opens a new lease stream and starts sending LeaseKeepAliveRequests +// resetRecv opens a new lease stream and starts sending keep alive requests. func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) { sctx, cancel := context.WithCancel(l.stopCtx) - stream, err := l.remote.LeaseKeepAlive(sctx, grpc.FailFast(false)) + stream, err := l.remote.LeaseKeepAlive(sctx, l.callOpts...) if err != nil { cancel() return nil, err @@ -467,7 +507,7 @@ func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) { if karesp.TTL <= 0 { // lease expired; close all keep alive channels delete(l.keepAlives, karesp.ID) - ka.Close() + ka.close() return } @@ -477,9 +517,10 @@ func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) { for _, ch := range ka.chs { select { case ch <- karesp: - ka.nextKeepAlive = nextKeepAlive default: } + // still advance in order to rate-limit keep-alive sends + ka.nextKeepAlive = nextKeepAlive } } @@ -497,7 +538,7 @@ func (l *lessor) deadlineLoop() { for id, ka := range l.keepAlives { if ka.deadline.Before(now) { // waited too long for response; lease may be expired - ka.Close() + ka.close() delete(l.keepAlives, id) } } @@ -505,7 +546,7 @@ func (l *lessor) deadlineLoop() { } } -// sendKeepAliveLoop sends LeaseKeepAliveRequests for the lifetime of a lease stream +// sendKeepAliveLoop sends keep alive requests for the lifetime of the given stream. func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { for { var tosend []LeaseID @@ -539,7 +580,7 @@ func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { } } -func (ka *keepAlive) Close() { +func (ka *keepAlive) close() { close(ka.donec) for _, ch := range ka.chs { close(ch) diff --git a/vendor/github.com/coreos/etcd/clientv3/logger.go b/vendor/github.com/coreos/etcd/clientv3/logger.go index 519db45d8e..782e313137 100644 --- a/vendor/github.com/coreos/etcd/clientv3/logger.go +++ b/vendor/github.com/coreos/etcd/clientv3/logger.go @@ -16,67 +16,120 @@ package clientv3 import ( "io/ioutil" - "log" "sync" "google.golang.org/grpc/grpclog" ) // Logger is the logger used by client library. -// It implements grpclog.Logger interface. -type Logger grpclog.Logger +// It implements grpclog.LoggerV2 interface. +type Logger interface { + grpclog.LoggerV2 + + // Lvl returns logger if logger's verbosity level >= "lvl". + // Otherwise, logger that discards all logs. + Lvl(lvl int) Logger + + // to satisfy capnslog + + Print(args ...interface{}) + Printf(format string, args ...interface{}) + Println(args ...interface{}) +} var ( - logger settableLogger + loggerMu sync.RWMutex + logger Logger ) type settableLogger struct { - l grpclog.Logger + l grpclog.LoggerV2 mu sync.RWMutex } func init() { // disable client side logs by default - logger.mu.Lock() - logger.l = log.New(ioutil.Discard, "", 0) - - // logger has to override the grpclog at initialization so that - // any changes to the grpclog go through logger with locking - // instead of through SetLogger - // - // now updates only happen through settableLogger.set - grpclog.SetLogger(&logger) - logger.mu.Unlock() + logger = &settableLogger{} + SetLogger(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard)) } -// SetLogger sets client-side Logger. By default, logs are disabled. -func SetLogger(l Logger) { - logger.set(l) +// SetLogger sets client-side Logger. +func SetLogger(l grpclog.LoggerV2) { + loggerMu.Lock() + logger = NewLogger(l) + // override grpclog so that any changes happen with locking + grpclog.SetLoggerV2(logger) + loggerMu.Unlock() } // GetLogger returns the current logger. func GetLogger() Logger { - return logger.get() + loggerMu.RLock() + l := logger + loggerMu.RUnlock() + return l } -func (s *settableLogger) set(l Logger) { - s.mu.Lock() - logger.l = l - s.mu.Unlock() +// NewLogger returns a new Logger with grpclog.LoggerV2. +func NewLogger(gl grpclog.LoggerV2) Logger { + return &settableLogger{l: gl} } -func (s *settableLogger) get() Logger { +func (s *settableLogger) get() grpclog.LoggerV2 { s.mu.RLock() - l := logger.l + l := s.l s.mu.RUnlock() return l } -// implement the grpclog.Logger interface +// implement the grpclog.LoggerV2 interface +func (s *settableLogger) Info(args ...interface{}) { s.get().Info(args...) } +func (s *settableLogger) Infof(format string, args ...interface{}) { s.get().Infof(format, args...) } +func (s *settableLogger) Infoln(args ...interface{}) { s.get().Infoln(args...) } +func (s *settableLogger) Warning(args ...interface{}) { s.get().Warning(args...) } +func (s *settableLogger) Warningf(format string, args ...interface{}) { + s.get().Warningf(format, args...) +} +func (s *settableLogger) Warningln(args ...interface{}) { s.get().Warningln(args...) } +func (s *settableLogger) Error(args ...interface{}) { s.get().Error(args...) } +func (s *settableLogger) Errorf(format string, args ...interface{}) { + s.get().Errorf(format, args...) +} +func (s *settableLogger) Errorln(args ...interface{}) { s.get().Errorln(args...) } func (s *settableLogger) Fatal(args ...interface{}) { s.get().Fatal(args...) } func (s *settableLogger) Fatalf(format string, args ...interface{}) { s.get().Fatalf(format, args...) } func (s *settableLogger) Fatalln(args ...interface{}) { s.get().Fatalln(args...) } -func (s *settableLogger) Print(args ...interface{}) { s.get().Print(args...) } -func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Printf(format, args...) } -func (s *settableLogger) Println(args ...interface{}) { s.get().Println(args...) } +func (s *settableLogger) Print(args ...interface{}) { s.get().Info(args...) } +func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Infof(format, args...) } +func (s *settableLogger) Println(args ...interface{}) { s.get().Infoln(args...) } +func (s *settableLogger) V(l int) bool { return s.get().V(l) } +func (s *settableLogger) Lvl(lvl int) Logger { + s.mu.RLock() + l := s.l + s.mu.RUnlock() + if l.V(lvl) { + return s + } + return &noLogger{} +} + +type noLogger struct{} + +func (*noLogger) Info(args ...interface{}) {} +func (*noLogger) Infof(format string, args ...interface{}) {} +func (*noLogger) Infoln(args ...interface{}) {} +func (*noLogger) Warning(args ...interface{}) {} +func (*noLogger) Warningf(format string, args ...interface{}) {} +func (*noLogger) Warningln(args ...interface{}) {} +func (*noLogger) Error(args ...interface{}) {} +func (*noLogger) Errorf(format string, args ...interface{}) {} +func (*noLogger) Errorln(args ...interface{}) {} +func (*noLogger) Fatal(args ...interface{}) {} +func (*noLogger) Fatalf(format string, args ...interface{}) {} +func (*noLogger) Fatalln(args ...interface{}) {} +func (*noLogger) Print(args ...interface{}) {} +func (*noLogger) Printf(format string, args ...interface{}) {} +func (*noLogger) Println(args ...interface{}) {} +func (*noLogger) V(l int) bool { return false } +func (ng *noLogger) Lvl(lvl int) Logger { return ng } diff --git a/vendor/github.com/coreos/etcd/clientv3/maintenance.go b/vendor/github.com/coreos/etcd/clientv3/maintenance.go index 2a75b7e9c5..f60cfbe471 100644 --- a/vendor/github.com/coreos/etcd/clientv3/maintenance.go +++ b/vendor/github.com/coreos/etcd/clientv3/maintenance.go @@ -15,11 +15,11 @@ package clientv3 import ( + "context" "io" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "golang.org/x/net/context" "google.golang.org/grpc" ) @@ -28,6 +28,8 @@ type ( AlarmResponse pb.AlarmResponse AlarmMember pb.AlarmMember StatusResponse pb.StatusResponse + HashKVResponse pb.HashKVResponse + MoveLeaderResponse pb.MoveLeaderResponse ) type Maintenance interface { @@ -37,7 +39,7 @@ type Maintenance interface { // AlarmDisarm disarms a given alarm. AlarmDisarm(ctx context.Context, m *AlarmMember) (*AlarmResponse, error) - // Defragment defragments storage backend of the etcd member with given endpoint. + // Defragment releases wasted space from internal fragmentation on a given etcd member. // Defragment is only needed when deleting a large number of keys and want to reclaim // the resources. // Defragment is an expensive operation. User should avoid defragmenting multiple members @@ -49,36 +51,54 @@ type Maintenance interface { // Status gets the status of the endpoint. Status(ctx context.Context, endpoint string) (*StatusResponse, error) - // Snapshot provides a reader for a snapshot of a backend. + // HashKV returns a hash of the KV state at the time of the RPC. + // If revision is zero, the hash is computed on all keys. If the revision + // is non-zero, the hash is computed on all keys at or below the given revision. + HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error) + + // Snapshot provides a reader for a point-in-time snapshot of etcd. Snapshot(ctx context.Context) (io.ReadCloser, error) + + // MoveLeader requests current leader to transfer its leadership to the transferee. + // Request must be made to the leader. + MoveLeader(ctx context.Context, transfereeID uint64) (*MoveLeaderResponse, error) } type maintenance struct { - dial func(endpoint string) (pb.MaintenanceClient, func(), error) - remote pb.MaintenanceClient + dial func(endpoint string) (pb.MaintenanceClient, func(), error) + remote pb.MaintenanceClient + callOpts []grpc.CallOption } func NewMaintenance(c *Client) Maintenance { - return &maintenance{ + api := &maintenance{ dial: func(endpoint string) (pb.MaintenanceClient, func(), error) { conn, err := c.dial(endpoint) if err != nil { return nil, nil, err } cancel := func() { conn.Close() } - return pb.NewMaintenanceClient(conn), cancel, nil + return RetryMaintenanceClient(c, conn), cancel, nil }, - remote: pb.NewMaintenanceClient(c.conn), + remote: RetryMaintenanceClient(c, c.conn), } + if c != nil { + api.callOpts = c.callOpts + } + return api } -func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient) Maintenance { - return &maintenance{ +func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient, c *Client) Maintenance { + api := &maintenance{ dial: func(string) (pb.MaintenanceClient, func(), error) { return remote, func() {}, nil }, remote: remote, } + if c != nil { + api.callOpts = c.callOpts + } + return api } func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) { @@ -87,15 +107,11 @@ func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) { MemberID: 0, // all Alarm: pb.AlarmType_NONE, // all } - for { - resp, err := m.remote.Alarm(ctx, req, grpc.FailFast(false)) - if err == nil { - return (*AlarmResponse)(resp), nil - } - if isHaltErr(ctx, err) { - return nil, toErr(ctx, err) - } + resp, err := m.remote.Alarm(ctx, req, m.callOpts...) + if err == nil { + return (*AlarmResponse)(resp), nil } + return nil, toErr(ctx, err) } func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmResponse, error) { @@ -121,7 +137,7 @@ func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmR return &ret, nil } - resp, err := m.remote.Alarm(ctx, req, grpc.FailFast(false)) + resp, err := m.remote.Alarm(ctx, req, m.callOpts...) if err == nil { return (*AlarmResponse)(resp), nil } @@ -134,7 +150,7 @@ func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*Defragm return nil, toErr(ctx, err) } defer cancel() - resp, err := remote.Defragment(ctx, &pb.DefragmentRequest{}, grpc.FailFast(false)) + resp, err := remote.Defragment(ctx, &pb.DefragmentRequest{}, m.callOpts...) if err != nil { return nil, toErr(ctx, err) } @@ -147,15 +163,28 @@ func (m *maintenance) Status(ctx context.Context, endpoint string) (*StatusRespo return nil, toErr(ctx, err) } defer cancel() - resp, err := remote.Status(ctx, &pb.StatusRequest{}, grpc.FailFast(false)) + resp, err := remote.Status(ctx, &pb.StatusRequest{}, m.callOpts...) if err != nil { return nil, toErr(ctx, err) } return (*StatusResponse)(resp), nil } +func (m *maintenance) HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error) { + remote, cancel, err := m.dial(endpoint) + if err != nil { + return nil, toErr(ctx, err) + } + defer cancel() + resp, err := remote.HashKV(ctx, &pb.HashKVRequest{Revision: rev}, m.callOpts...) + if err != nil { + return nil, toErr(ctx, err) + } + return (*HashKVResponse)(resp), nil +} + func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) { - ss, err := m.remote.Snapshot(ctx, &pb.SnapshotRequest{}, grpc.FailFast(false)) + ss, err := m.remote.Snapshot(ctx, &pb.SnapshotRequest{}, m.callOpts...) if err != nil { return nil, toErr(ctx, err) } @@ -178,5 +207,20 @@ func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) { } pw.Close() }() - return pr, nil + return &snapshotReadCloser{ctx: ctx, ReadCloser: pr}, nil +} + +type snapshotReadCloser struct { + ctx context.Context + io.ReadCloser +} + +func (rc *snapshotReadCloser) Read(p []byte) (n int, err error) { + n, err = rc.ReadCloser.Read(p) + return n, toErr(rc.ctx, err) +} + +func (m *maintenance) MoveLeader(ctx context.Context, transfereeID uint64) (*MoveLeaderResponse, error) { + resp, err := m.remote.MoveLeader(ctx, &pb.MoveLeaderRequest{TargetID: transfereeID}, m.callOpts...) + return (*MoveLeaderResponse)(resp), toErr(ctx, err) } diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/kv.go b/vendor/github.com/coreos/etcd/clientv3/namespace/kv.go index f3e82d6b89..13dd83a245 100644 --- a/vendor/github.com/coreos/etcd/clientv3/namespace/kv.go +++ b/vendor/github.com/coreos/etcd/clientv3/namespace/kv.go @@ -15,7 +15,7 @@ package namespace import ( - "golang.org/x/net/context" + "context" "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" @@ -74,7 +74,7 @@ func (kv *kvPrefix) Delete(ctx context.Context, key string, opts ...clientv3.OpO } func (kv *kvPrefix) Do(ctx context.Context, op clientv3.Op) (clientv3.OpResponse, error) { - if len(op.KeyBytes()) == 0 { + if len(op.KeyBytes()) == 0 && !op.IsTxn() { return clientv3.OpResponse{}, rpctypes.ErrEmptyKey } r, err := kv.KV.Do(ctx, kv.prefixOp(op)) @@ -88,6 +88,8 @@ func (kv *kvPrefix) Do(ctx context.Context, op clientv3.Op) (clientv3.OpResponse kv.unprefixPutResponse(r.Put()) case r.Del() != nil: kv.unprefixDeleteResponse(r.Del()) + case r.Txn() != nil: + kv.unprefixTxnResponse(r.Txn()) } return r, nil } @@ -102,31 +104,17 @@ func (kv *kvPrefix) Txn(ctx context.Context) clientv3.Txn { } func (txn *txnPrefix) If(cs ...clientv3.Cmp) clientv3.Txn { - newCmps := make([]clientv3.Cmp, len(cs)) - for i := range cs { - newCmps[i] = cs[i] - pfxKey, _ := txn.kv.prefixInterval(cs[i].KeyBytes(), nil) - newCmps[i].WithKeyBytes(pfxKey) - } - txn.Txn = txn.Txn.If(newCmps...) + txn.Txn = txn.Txn.If(txn.kv.prefixCmps(cs)...) return txn } func (txn *txnPrefix) Then(ops ...clientv3.Op) clientv3.Txn { - newOps := make([]clientv3.Op, len(ops)) - for i := range ops { - newOps[i] = txn.kv.prefixOp(ops[i]) - } - txn.Txn = txn.Txn.Then(newOps...) + txn.Txn = txn.Txn.Then(txn.kv.prefixOps(ops)...) return txn } func (txn *txnPrefix) Else(ops ...clientv3.Op) clientv3.Txn { - newOps := make([]clientv3.Op, len(ops)) - for i := range ops { - newOps[i] = txn.kv.prefixOp(ops[i]) - } - txn.Txn = txn.Txn.Else(newOps...) + txn.Txn = txn.Txn.Else(txn.kv.prefixOps(ops)...) return txn } @@ -140,10 +128,14 @@ func (txn *txnPrefix) Commit() (*clientv3.TxnResponse, error) { } func (kv *kvPrefix) prefixOp(op clientv3.Op) clientv3.Op { - begin, end := kv.prefixInterval(op.KeyBytes(), op.RangeBytes()) - op.WithKeyBytes(begin) - op.WithRangeBytes(end) - return op + if !op.IsTxn() { + begin, end := kv.prefixInterval(op.KeyBytes(), op.RangeBytes()) + op.WithKeyBytes(begin) + op.WithRangeBytes(end) + return op + } + cmps, thenOps, elseOps := op.Txn() + return clientv3.OpTxn(kv.prefixCmps(cmps), kv.prefixOps(thenOps), kv.prefixOps(elseOps)) } func (kv *kvPrefix) unprefixGetResponse(resp *clientv3.GetResponse) { @@ -179,11 +171,36 @@ func (kv *kvPrefix) unprefixTxnResponse(resp *clientv3.TxnResponse) { if tv.ResponseDeleteRange != nil { kv.unprefixDeleteResponse((*clientv3.DeleteResponse)(tv.ResponseDeleteRange)) } + case *pb.ResponseOp_ResponseTxn: + if tv.ResponseTxn != nil { + kv.unprefixTxnResponse((*clientv3.TxnResponse)(tv.ResponseTxn)) + } default: } } } -func (p *kvPrefix) prefixInterval(key, end []byte) (pfxKey []byte, pfxEnd []byte) { - return prefixInterval(p.pfx, key, end) +func (kv *kvPrefix) prefixInterval(key, end []byte) (pfxKey []byte, pfxEnd []byte) { + return prefixInterval(kv.pfx, key, end) +} + +func (kv *kvPrefix) prefixCmps(cs []clientv3.Cmp) []clientv3.Cmp { + newCmps := make([]clientv3.Cmp, len(cs)) + for i := range cs { + newCmps[i] = cs[i] + pfxKey, endKey := kv.prefixInterval(cs[i].KeyBytes(), cs[i].RangeEnd) + newCmps[i].WithKeyBytes(pfxKey) + if len(cs[i].RangeEnd) != 0 { + newCmps[i].RangeEnd = endKey + } + } + return newCmps +} + +func (kv *kvPrefix) prefixOps(ops []clientv3.Op) []clientv3.Op { + newOps := make([]clientv3.Op, len(ops)) + for i := range ops { + newOps[i] = kv.prefixOp(ops[i]) + } + return newOps } diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/lease.go b/vendor/github.com/coreos/etcd/clientv3/namespace/lease.go index fc7c228699..f092106cbf 100644 --- a/vendor/github.com/coreos/etcd/clientv3/namespace/lease.go +++ b/vendor/github.com/coreos/etcd/clientv3/namespace/lease.go @@ -16,8 +16,7 @@ package namespace import ( "bytes" - - "golang.org/x/net/context" + "context" "github.com/coreos/etcd/clientv3" ) diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/watch.go b/vendor/github.com/coreos/etcd/clientv3/namespace/watch.go index 6257e29682..5a9596df5d 100644 --- a/vendor/github.com/coreos/etcd/clientv3/namespace/watch.go +++ b/vendor/github.com/coreos/etcd/clientv3/namespace/watch.go @@ -15,10 +15,9 @@ package namespace import ( + "context" "sync" - "golang.org/x/net/context" - "github.com/coreos/etcd/clientv3" ) diff --git a/vendor/github.com/coreos/etcd/clientv3/op.go b/vendor/github.com/coreos/etcd/clientv3/op.go index 63b99501e8..c6ec5bf520 100644 --- a/vendor/github.com/coreos/etcd/clientv3/op.go +++ b/vendor/github.com/coreos/etcd/clientv3/op.go @@ -23,6 +23,7 @@ const ( tRange opType = iota + 1 tPut tDeleteRange + tTxn ) var ( @@ -67,9 +68,17 @@ type Op struct { // for put val []byte leaseID LeaseID + + // txn + cmps []Cmp + thenOps []Op + elseOps []Op } -// accesors / mutators +// accessors / mutators + +func (op Op) IsTxn() bool { return op.t == tTxn } +func (op Op) Txn() ([]Cmp, []Op, []Op) { return op.cmps, op.thenOps, op.elseOps } // KeyBytes returns the byte slice holding the Op's key. func (op Op) KeyBytes() []byte { return op.key } @@ -80,6 +89,39 @@ func (op *Op) WithKeyBytes(key []byte) { op.key = key } // RangeBytes returns the byte slice holding with the Op's range end, if any. func (op Op) RangeBytes() []byte { return op.end } +// Rev returns the requested revision, if any. +func (op Op) Rev() int64 { return op.rev } + +// IsPut returns true iff the operation is a Put. +func (op Op) IsPut() bool { return op.t == tPut } + +// IsGet returns true iff the operation is a Get. +func (op Op) IsGet() bool { return op.t == tRange } + +// IsDelete returns true iff the operation is a Delete. +func (op Op) IsDelete() bool { return op.t == tDeleteRange } + +// IsSerializable returns true if the serializable field is true. +func (op Op) IsSerializable() bool { return op.serializable == true } + +// IsKeysOnly returns whether keysOnly is set. +func (op Op) IsKeysOnly() bool { return op.keysOnly == true } + +// IsCountOnly returns whether countOnly is set. +func (op Op) IsCountOnly() bool { return op.countOnly == true } + +// MinModRev returns the operation's minimum modify revision. +func (op Op) MinModRev() int64 { return op.minModRev } + +// MaxModRev returns the operation's maximum modify revision. +func (op Op) MaxModRev() int64 { return op.maxModRev } + +// MinCreateRev returns the operation's minimum create revision. +func (op Op) MinCreateRev() int64 { return op.minCreateRev } + +// MaxCreateRev returns the operation's maximum create revision. +func (op Op) MaxCreateRev() int64 { return op.maxCreateRev } + // WithRangeBytes sets the byte slice for the Op's range end. func (op *Op) WithRangeBytes(end []byte) { op.end = end } @@ -113,6 +155,22 @@ func (op Op) toRangeRequest() *pb.RangeRequest { return r } +func (op Op) toTxnRequest() *pb.TxnRequest { + thenOps := make([]*pb.RequestOp, len(op.thenOps)) + for i, tOp := range op.thenOps { + thenOps[i] = tOp.toRequestOp() + } + elseOps := make([]*pb.RequestOp, len(op.elseOps)) + for i, eOp := range op.elseOps { + elseOps[i] = eOp.toRequestOp() + } + cmps := make([]*pb.Compare, len(op.cmps)) + for i := range op.cmps { + cmps[i] = (*pb.Compare)(&op.cmps[i]) + } + return &pb.TxnRequest{Compare: cmps, Success: thenOps, Failure: elseOps} +} + func (op Op) toRequestOp() *pb.RequestOp { switch op.t { case tRange: @@ -123,12 +181,27 @@ func (op Op) toRequestOp() *pb.RequestOp { case tDeleteRange: r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV} return &pb.RequestOp{Request: &pb.RequestOp_RequestDeleteRange{RequestDeleteRange: r}} + case tTxn: + return &pb.RequestOp{Request: &pb.RequestOp_RequestTxn{RequestTxn: op.toTxnRequest()}} default: panic("Unknown Op") } } func (op Op) isWrite() bool { + if op.t == tTxn { + for _, tOp := range op.thenOps { + if tOp.isWrite() { + return true + } + } + for _, tOp := range op.elseOps { + if tOp.isWrite() { + return true + } + } + return false + } return op.t != tRange } @@ -194,6 +267,10 @@ func OpPut(key, val string, opts ...OpOption) Op { return ret } +func OpTxn(cmps []Cmp, thenOps []Op, elseOps []Op) Op { + return Op{t: tTxn, cmps: cmps, thenOps: thenOps, elseOps: elseOps} +} + func opWatch(key string, opts ...OpOption) Op { ret := Op{t: tRange, key: []byte(key)} ret.applyOpts(opts) @@ -247,9 +324,9 @@ func WithSort(target SortTarget, order SortOrder) OpOption { if target == SortByKey && order == SortAscend { // If order != SortNone, server fetches the entire key-space, // and then applies the sort and limit, if provided. - // Since current mvcc.Range implementation returns results - // sorted by keys in lexicographically ascending order, - // client should ignore SortOrder if the target is SortByKey. + // Since by default the server returns results sorted by keys + // in lexicographically ascending order, the client should ignore + // SortOrder if the target is SortByKey. order = SortNone } op.sort = &SortOption{target, order} @@ -390,7 +467,7 @@ func WithPrevKV() OpOption { } // WithIgnoreValue updates the key using its current value. -// Empty value should be passed when ignore_value is set. +// This option can not be combined with non-empty values. // Returns an error if the key does not exist. func WithIgnoreValue() OpOption { return func(op *Op) { @@ -399,7 +476,7 @@ func WithIgnoreValue() OpOption { } // WithIgnoreLease updates the key using its current lease. -// Empty lease should be passed when ignore_lease is set. +// This option can not be combined with WithLease. // Returns an error if the key does not exist. func WithIgnoreLease() OpOption { return func(op *Op) { @@ -424,8 +501,7 @@ func (op *LeaseOp) applyOpts(opts []LeaseOption) { } } -// WithAttachedKeys requests lease timetolive API to return -// attached keys of given lease ID. +// WithAttachedKeys makes TimeToLive list the keys attached to the given lease ID. func WithAttachedKeys() LeaseOption { return func(op *LeaseOp) { op.attachedKeys = true } } diff --git a/vendor/github.com/coreos/etcd/clientv3/options.go b/vendor/github.com/coreos/etcd/clientv3/options.go new file mode 100644 index 0000000000..fa25811f3b --- /dev/null +++ b/vendor/github.com/coreos/etcd/clientv3/options.go @@ -0,0 +1,49 @@ +// Copyright 2017 The etcd Authors +// +// 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 clientv3 + +import ( + "math" + + "google.golang.org/grpc" +) + +var ( + // Disable gRPC internal retrial logic + // TODO: enable when gRPC retry is stable (FailFast=false) + // Reference: + // - https://github.com/grpc/grpc-go/issues/1532 + // - https://github.com/grpc/proposal/blob/master/A6-client-retries.md + defaultFailFast = grpc.FailFast(true) + + // client-side request send limit, gRPC default is math.MaxInt32 + // Make sure that "client-side send limit < server-side default send/recv limit" + // Same value as "embed.DefaultMaxRequestBytes" plus gRPC overhead bytes + defaultMaxCallSendMsgSize = grpc.MaxCallSendMsgSize(2 * 1024 * 1024) + + // client-side response receive limit, gRPC default is 4MB + // Make sure that "client-side receive limit >= server-side default send/recv limit" + // because range response can easily exceed request send limits + // Default to math.MaxInt32; writes exceeding server-side send limit fails anyway + defaultMaxCallRecvMsgSize = grpc.MaxCallRecvMsgSize(math.MaxInt32) +) + +// defaultCallOpts defines a list of default "gRPC.CallOption". +// Some options are exposed to "clientv3.Config". +// Defaults will be overridden by the settings in "clientv3.Config". +var defaultCallOpts = []grpc.CallOption{defaultFailFast, defaultMaxCallSendMsgSize, defaultMaxCallRecvMsgSize} + +// MaxLeaseTTL is the maximum lease TTL value +const MaxLeaseTTL = 9000000000 diff --git a/vendor/github.com/coreos/etcd/clientv3/ready_wait.go b/vendor/github.com/coreos/etcd/clientv3/ready_wait.go new file mode 100644 index 0000000000..c6ef585b5b --- /dev/null +++ b/vendor/github.com/coreos/etcd/clientv3/ready_wait.go @@ -0,0 +1,30 @@ +// Copyright 2017 The etcd Authors +// +// 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 clientv3 + +import "context" + +// TODO: remove this when "FailFast=false" is fixed. +// See https://github.com/grpc/grpc-go/issues/1532. +func readyWait(rpcCtx, clientCtx context.Context, ready <-chan struct{}) error { + select { + case <-ready: + return nil + case <-rpcCtx.Done(): + return rpcCtx.Err() + case <-clientCtx.Done(): + return clientCtx.Err() + } +} diff --git a/vendor/github.com/coreos/etcd/clientv3/retry.go b/vendor/github.com/coreos/etcd/clientv3/retry.go index 78f31a8c4b..7f89ba641a 100644 --- a/vendor/github.com/coreos/etcd/clientv3/retry.go +++ b/vendor/github.com/coreos/etcd/clientv3/retry.go @@ -15,279 +15,482 @@ package clientv3 import ( + "context" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "golang.org/x/net/context" + "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type retryPolicy uint8 + +const ( + repeatable retryPolicy = iota + nonRepeatable ) type rpcFunc func(ctx context.Context) error -type retryRpcFunc func(context.Context, rpcFunc) error +type retryRPCFunc func(context.Context, rpcFunc, retryPolicy) error +type retryStopErrFunc func(error) bool + +// immutable requests (e.g. Get) should be retried unless it's +// an obvious server-side error (e.g. rpctypes.ErrRequestTooLarge). +// +// "isRepeatableStopError" returns "true" when an immutable request +// is interrupted by server-side or gRPC-side error and its status +// code is not transient (!= codes.Unavailable). +// +// Returning "true" means retry should stop, since client cannot +// handle itself even with retries. +func isRepeatableStopError(err error) bool { + eErr := rpctypes.Error(err) + // always stop retry on etcd errors + if serverErr, ok := eErr.(rpctypes.EtcdError); ok && serverErr.Code() != codes.Unavailable { + return true + } + // only retry if unavailable + ev, _ := status.FromError(err) + return ev.Code() != codes.Unavailable +} -func (c *Client) newRetryWrapper() retryRpcFunc { - return func(rpcCtx context.Context, f rpcFunc) error { +// mutable requests (e.g. Put, Delete, Txn) should only be retried +// when the status code is codes.Unavailable when initial connection +// has not been established (no pinned endpoint). +// +// "isNonRepeatableStopError" returns "true" when a mutable request +// is interrupted by non-transient error that client cannot handle itself, +// or transient error while the connection has already been established +// (pinned endpoint exists). +// +// Returning "true" means retry should stop, otherwise it violates +// write-at-most-once semantics. +func isNonRepeatableStopError(err error) bool { + ev, _ := status.FromError(err) + if ev.Code() != codes.Unavailable { + return true + } + desc := rpctypes.ErrorDesc(err) + return desc != "there is no address available" && desc != "there is no connection available" +} + +func (c *Client) newRetryWrapper() retryRPCFunc { + return func(rpcCtx context.Context, f rpcFunc, rp retryPolicy) error { + var isStop retryStopErrFunc + switch rp { + case repeatable: + isStop = isRepeatableStopError + case nonRepeatable: + isStop = isNonRepeatableStopError + } for { + if err := readyWait(rpcCtx, c.ctx, c.balancer.ConnectNotify()); err != nil { + return err + } + pinned := c.balancer.pinned() err := f(rpcCtx) if err == nil { return nil } + logger.Lvl(4).Infof("clientv3/retry: error %q on pinned endpoint %q", err.Error(), pinned) - eErr := rpctypes.Error(err) - // always stop retry on etcd errors - if _, ok := eErr.(rpctypes.EtcdError); ok { - return err + if s, ok := status.FromError(err); ok && (s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded || s.Code() == codes.Internal) { + // mark this before endpoint switch is triggered + c.balancer.hostPortError(pinned, err) + c.balancer.next() + logger.Lvl(4).Infof("clientv3/retry: switching from %q due to error %q", pinned, err.Error()) } - // only retry if unavailable - if grpc.Code(err) != codes.Unavailable { + if isStop(err) { return err } - - select { - case <-c.balancer.ConnectNotify(): - case <-rpcCtx.Done(): - return rpcCtx.Err() - case <-c.ctx.Done(): - return c.ctx.Err() - } } } } -func (c *Client) newAuthRetryWrapper() retryRpcFunc { - return func(rpcCtx context.Context, f rpcFunc) error { +func (c *Client) newAuthRetryWrapper(retryf retryRPCFunc) retryRPCFunc { + return func(rpcCtx context.Context, f rpcFunc, rp retryPolicy) error { for { - err := f(rpcCtx) + pinned := c.balancer.pinned() + err := retryf(rpcCtx, f, rp) if err == nil { return nil } - + logger.Lvl(4).Infof("clientv3/auth-retry: error %q on pinned endpoint %q", err.Error(), pinned) // always stop retry on etcd errors other than invalid auth token if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken { gterr := c.getToken(rpcCtx) if gterr != nil { + logger.Lvl(4).Infof("clientv3/auth-retry: cannot retry due to error %q(%q) on pinned endpoint %q", err.Error(), gterr.Error(), pinned) return err // return the original error for simplicity } continue } - return err } } } -// RetryKVClient implements a KVClient that uses the client's FailFast retry policy. -func RetryKVClient(c *Client) pb.KVClient { - retryWrite := &retryWriteKVClient{pb.NewKVClient(c.conn), c.retryWrapper} - return &retryKVClient{&retryWriteKVClient{retryWrite, c.retryAuthWrapper}} -} - type retryKVClient struct { - *retryWriteKVClient + kc pb.KVClient + retryf retryRPCFunc } +// RetryKVClient implements a KVClient. +func RetryKVClient(c *Client) pb.KVClient { + return &retryKVClient{ + kc: pb.NewKVClient(c.conn), + retryf: c.newAuthRetryWrapper(c.newRetryWrapper()), + } +} func (rkv *retryKVClient) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (resp *pb.RangeResponse, err error) { err = rkv.retryf(ctx, func(rctx context.Context) error { - resp, err = rkv.retryWriteKVClient.Range(rctx, in, opts...) + resp, err = rkv.kc.Range(rctx, in, opts...) return err - }) + }, repeatable) return resp, err } -type retryWriteKVClient struct { - pb.KVClient - retryf retryRpcFunc -} - -func (rkv *retryWriteKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) { +func (rkv *retryKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) { err = rkv.retryf(ctx, func(rctx context.Context) error { - resp, err = rkv.KVClient.Put(rctx, in, opts...) + resp, err = rkv.kc.Put(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } -func (rkv *retryWriteKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) { +func (rkv *retryKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) { err = rkv.retryf(ctx, func(rctx context.Context) error { - resp, err = rkv.KVClient.DeleteRange(rctx, in, opts...) + resp, err = rkv.kc.DeleteRange(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } -func (rkv *retryWriteKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) { +func (rkv *retryKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) { + // TODO: "repeatable" for read-only txn err = rkv.retryf(ctx, func(rctx context.Context) error { - resp, err = rkv.KVClient.Txn(rctx, in, opts...) + resp, err = rkv.kc.Txn(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } -func (rkv *retryWriteKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) { +func (rkv *retryKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) { err = rkv.retryf(ctx, func(rctx context.Context) error { - resp, err = rkv.KVClient.Compact(rctx, in, opts...) + resp, err = rkv.kc.Compact(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } type retryLeaseClient struct { - pb.LeaseClient - retryf retryRpcFunc + lc pb.LeaseClient + retryf retryRPCFunc } -// RetryLeaseClient implements a LeaseClient that uses the client's FailFast retry policy. +// RetryLeaseClient implements a LeaseClient. func RetryLeaseClient(c *Client) pb.LeaseClient { - retry := &retryLeaseClient{pb.NewLeaseClient(c.conn), c.retryWrapper} - return &retryLeaseClient{retry, c.retryAuthWrapper} + return &retryLeaseClient{ + lc: pb.NewLeaseClient(c.conn), + retryf: c.newAuthRetryWrapper(c.newRetryWrapper()), + } +} + +func (rlc *retryLeaseClient) LeaseTimeToLive(ctx context.Context, in *pb.LeaseTimeToLiveRequest, opts ...grpc.CallOption) (resp *pb.LeaseTimeToLiveResponse, err error) { + err = rlc.retryf(ctx, func(rctx context.Context) error { + resp, err = rlc.lc.LeaseTimeToLive(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rlc *retryLeaseClient) LeaseLeases(ctx context.Context, in *pb.LeaseLeasesRequest, opts ...grpc.CallOption) (resp *pb.LeaseLeasesResponse, err error) { + err = rlc.retryf(ctx, func(rctx context.Context) error { + resp, err = rlc.lc.LeaseLeases(rctx, in, opts...) + return err + }, repeatable) + return resp, err } func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (resp *pb.LeaseGrantResponse, err error) { err = rlc.retryf(ctx, func(rctx context.Context) error { - resp, err = rlc.LeaseClient.LeaseGrant(rctx, in, opts...) + resp, err = rlc.lc.LeaseGrant(rctx, in, opts...) return err - }) + }, repeatable) return resp, err } func (rlc *retryLeaseClient) LeaseRevoke(ctx context.Context, in *pb.LeaseRevokeRequest, opts ...grpc.CallOption) (resp *pb.LeaseRevokeResponse, err error) { err = rlc.retryf(ctx, func(rctx context.Context) error { - resp, err = rlc.LeaseClient.LeaseRevoke(rctx, in, opts...) + resp, err = rlc.lc.LeaseRevoke(rctx, in, opts...) return err - }) + }, repeatable) return resp, err } +func (rlc *retryLeaseClient) LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (stream pb.Lease_LeaseKeepAliveClient, err error) { + err = rlc.retryf(ctx, func(rctx context.Context) error { + stream, err = rlc.lc.LeaseKeepAlive(rctx, opts...) + return err + }, repeatable) + return stream, err +} + type retryClusterClient struct { - pb.ClusterClient - retryf retryRpcFunc + cc pb.ClusterClient + retryf retryRPCFunc } -// RetryClusterClient implements a ClusterClient that uses the client's FailFast retry policy. +// RetryClusterClient implements a ClusterClient. func RetryClusterClient(c *Client) pb.ClusterClient { - return &retryClusterClient{pb.NewClusterClient(c.conn), c.retryWrapper} + return &retryClusterClient{ + cc: pb.NewClusterClient(c.conn), + retryf: c.newRetryWrapper(), + } +} + +func (rcc *retryClusterClient) MemberList(ctx context.Context, in *pb.MemberListRequest, opts ...grpc.CallOption) (resp *pb.MemberListResponse, err error) { + err = rcc.retryf(ctx, func(rctx context.Context) error { + resp, err = rcc.cc.MemberList(rctx, in, opts...) + return err + }, repeatable) + return resp, err } func (rcc *retryClusterClient) MemberAdd(ctx context.Context, in *pb.MemberAddRequest, opts ...grpc.CallOption) (resp *pb.MemberAddResponse, err error) { err = rcc.retryf(ctx, func(rctx context.Context) error { - resp, err = rcc.ClusterClient.MemberAdd(rctx, in, opts...) + resp, err = rcc.cc.MemberAdd(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rcc *retryClusterClient) MemberRemove(ctx context.Context, in *pb.MemberRemoveRequest, opts ...grpc.CallOption) (resp *pb.MemberRemoveResponse, err error) { err = rcc.retryf(ctx, func(rctx context.Context) error { - resp, err = rcc.ClusterClient.MemberRemove(rctx, in, opts...) + resp, err = rcc.cc.MemberRemove(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rcc *retryClusterClient) MemberUpdate(ctx context.Context, in *pb.MemberUpdateRequest, opts ...grpc.CallOption) (resp *pb.MemberUpdateResponse, err error) { err = rcc.retryf(ctx, func(rctx context.Context) error { - resp, err = rcc.ClusterClient.MemberUpdate(rctx, in, opts...) + resp, err = rcc.cc.MemberUpdate(rctx, in, opts...) return err - }) + }, nonRepeatable) + return resp, err +} + +type retryMaintenanceClient struct { + mc pb.MaintenanceClient + retryf retryRPCFunc +} + +// RetryMaintenanceClient implements a Maintenance. +func RetryMaintenanceClient(c *Client, conn *grpc.ClientConn) pb.MaintenanceClient { + return &retryMaintenanceClient{ + mc: pb.NewMaintenanceClient(conn), + retryf: c.newRetryWrapper(), + } +} + +func (rmc *retryMaintenanceClient) Alarm(ctx context.Context, in *pb.AlarmRequest, opts ...grpc.CallOption) (resp *pb.AlarmResponse, err error) { + err = rmc.retryf(ctx, func(rctx context.Context) error { + resp, err = rmc.mc.Alarm(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rmc *retryMaintenanceClient) Status(ctx context.Context, in *pb.StatusRequest, opts ...grpc.CallOption) (resp *pb.StatusResponse, err error) { + err = rmc.retryf(ctx, func(rctx context.Context) error { + resp, err = rmc.mc.Status(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rmc *retryMaintenanceClient) Hash(ctx context.Context, in *pb.HashRequest, opts ...grpc.CallOption) (resp *pb.HashResponse, err error) { + err = rmc.retryf(ctx, func(rctx context.Context) error { + resp, err = rmc.mc.Hash(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rmc *retryMaintenanceClient) HashKV(ctx context.Context, in *pb.HashKVRequest, opts ...grpc.CallOption) (resp *pb.HashKVResponse, err error) { + err = rmc.retryf(ctx, func(rctx context.Context) error { + resp, err = rmc.mc.HashKV(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rmc *retryMaintenanceClient) Snapshot(ctx context.Context, in *pb.SnapshotRequest, opts ...grpc.CallOption) (stream pb.Maintenance_SnapshotClient, err error) { + err = rmc.retryf(ctx, func(rctx context.Context) error { + stream, err = rmc.mc.Snapshot(rctx, in, opts...) + return err + }, repeatable) + return stream, err +} + +func (rmc *retryMaintenanceClient) MoveLeader(ctx context.Context, in *pb.MoveLeaderRequest, opts ...grpc.CallOption) (resp *pb.MoveLeaderResponse, err error) { + err = rmc.retryf(ctx, func(rctx context.Context) error { + resp, err = rmc.mc.MoveLeader(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rmc *retryMaintenanceClient) Defragment(ctx context.Context, in *pb.DefragmentRequest, opts ...grpc.CallOption) (resp *pb.DefragmentResponse, err error) { + err = rmc.retryf(ctx, func(rctx context.Context) error { + resp, err = rmc.mc.Defragment(rctx, in, opts...) + return err + }, nonRepeatable) return resp, err } type retryAuthClient struct { - pb.AuthClient - retryf retryRpcFunc + ac pb.AuthClient + retryf retryRPCFunc } -// RetryAuthClient implements a AuthClient that uses the client's FailFast retry policy. +// RetryAuthClient implements a AuthClient. func RetryAuthClient(c *Client) pb.AuthClient { - return &retryAuthClient{pb.NewAuthClient(c.conn), c.retryWrapper} + return &retryAuthClient{ + ac: pb.NewAuthClient(c.conn), + retryf: c.newRetryWrapper(), + } +} + +func (rac *retryAuthClient) UserList(ctx context.Context, in *pb.AuthUserListRequest, opts ...grpc.CallOption) (resp *pb.AuthUserListResponse, err error) { + err = rac.retryf(ctx, func(rctx context.Context) error { + resp, err = rac.ac.UserList(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rac *retryAuthClient) UserGet(ctx context.Context, in *pb.AuthUserGetRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGetResponse, err error) { + err = rac.retryf(ctx, func(rctx context.Context) error { + resp, err = rac.ac.UserGet(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rac *retryAuthClient) RoleGet(ctx context.Context, in *pb.AuthRoleGetRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGetResponse, err error) { + err = rac.retryf(ctx, func(rctx context.Context) error { + resp, err = rac.ac.RoleGet(rctx, in, opts...) + return err + }, repeatable) + return resp, err +} + +func (rac *retryAuthClient) RoleList(ctx context.Context, in *pb.AuthRoleListRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleListResponse, err error) { + err = rac.retryf(ctx, func(rctx context.Context) error { + resp, err = rac.ac.RoleList(rctx, in, opts...) + return err + }, repeatable) + return resp, err } func (rac *retryAuthClient) AuthEnable(ctx context.Context, in *pb.AuthEnableRequest, opts ...grpc.CallOption) (resp *pb.AuthEnableResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.AuthEnable(rctx, in, opts...) + resp, err = rac.ac.AuthEnable(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.AuthDisableRequest, opts ...grpc.CallOption) (resp *pb.AuthDisableResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.AuthDisable(rctx, in, opts...) + resp, err = rac.ac.AuthDisable(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (resp *pb.AuthUserAddResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.UserAdd(rctx, in, opts...) + resp, err = rac.ac.UserAdd(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) UserDelete(ctx context.Context, in *pb.AuthUserDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthUserDeleteResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.UserDelete(rctx, in, opts...) + resp, err = rac.ac.UserDelete(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) UserChangePassword(ctx context.Context, in *pb.AuthUserChangePasswordRequest, opts ...grpc.CallOption) (resp *pb.AuthUserChangePasswordResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.UserChangePassword(rctx, in, opts...) + resp, err = rac.ac.UserChangePassword(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) UserGrantRole(ctx context.Context, in *pb.AuthUserGrantRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGrantRoleResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.UserGrantRole(rctx, in, opts...) + resp, err = rac.ac.UserGrantRole(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) UserRevokeRole(ctx context.Context, in *pb.AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserRevokeRoleResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.UserRevokeRole(rctx, in, opts...) + resp, err = rac.ac.UserRevokeRole(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) RoleAdd(ctx context.Context, in *pb.AuthRoleAddRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleAddResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.RoleAdd(rctx, in, opts...) + resp, err = rac.ac.RoleAdd(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) RoleDelete(ctx context.Context, in *pb.AuthRoleDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleDeleteResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.RoleDelete(rctx, in, opts...) + resp, err = rac.ac.RoleDelete(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) RoleGrantPermission(ctx context.Context, in *pb.AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGrantPermissionResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.RoleGrantPermission(rctx, in, opts...) + resp, err = rac.ac.RoleGrantPermission(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } func (rac *retryAuthClient) RoleRevokePermission(ctx context.Context, in *pb.AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleRevokePermissionResponse, err error) { err = rac.retryf(ctx, func(rctx context.Context) error { - resp, err = rac.AuthClient.RoleRevokePermission(rctx, in, opts...) + resp, err = rac.ac.RoleRevokePermission(rctx, in, opts...) + return err + }, nonRepeatable) + return resp, err +} + +func (rac *retryAuthClient) Authenticate(ctx context.Context, in *pb.AuthenticateRequest, opts ...grpc.CallOption) (resp *pb.AuthenticateResponse, err error) { + err = rac.retryf(ctx, func(rctx context.Context) error { + resp, err = rac.ac.Authenticate(rctx, in, opts...) return err - }) + }, nonRepeatable) return resp, err } diff --git a/vendor/github.com/coreos/etcd/clientv3/txn.go b/vendor/github.com/coreos/etcd/clientv3/txn.go index 7bde6fd725..c3c2d24856 100644 --- a/vendor/github.com/coreos/etcd/clientv3/txn.go +++ b/vendor/github.com/coreos/etcd/clientv3/txn.go @@ -15,16 +15,17 @@ package clientv3 import ( + "context" "sync" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "golang.org/x/net/context" + "google.golang.org/grpc" ) // Txn is the interface that wraps mini-transactions. // -// Tx.If( +// Txn(context.TODO()).If( // Compare(Value(k1), ">", v1), // Compare(Version(k1), "=", 2) // ).Then( @@ -66,6 +67,8 @@ type txn struct { sus []*pb.RequestOp fas []*pb.RequestOp + + callOpts []grpc.CallOption } func (txn *txn) If(cs ...Cmp) Txn { @@ -135,30 +138,14 @@ func (txn *txn) Else(ops ...Op) Txn { func (txn *txn) Commit() (*TxnResponse, error) { txn.mu.Lock() defer txn.mu.Unlock() - for { - resp, err := txn.commit() - if err == nil { - return resp, err - } - if isHaltErr(txn.ctx, err) { - return nil, toErr(txn.ctx, err) - } - if txn.isWrite { - return nil, toErr(txn.ctx, err) - } - } -} -func (txn *txn) commit() (*TxnResponse, error) { r := &pb.TxnRequest{Compare: txn.cmps, Success: txn.sus, Failure: txn.fas} - var opts []grpc.CallOption - if !txn.isWrite { - opts = []grpc.CallOption{grpc.FailFast(false)} - } - resp, err := txn.kv.remote.Txn(txn.ctx, r, opts...) + var resp *pb.TxnResponse + var err error + resp, err = txn.kv.remote.Txn(txn.ctx, r, txn.callOpts...) if err != nil { - return nil, err + return nil, toErr(txn.ctx, err) } return (*TxnResponse)(resp), nil } diff --git a/vendor/github.com/coreos/etcd/clientv3/watch.go b/vendor/github.com/coreos/etcd/clientv3/watch.go index a707f74494..d7633850e7 100644 --- a/vendor/github.com/coreos/etcd/clientv3/watch.go +++ b/vendor/github.com/coreos/etcd/clientv3/watch.go @@ -15,6 +15,7 @@ package clientv3 import ( + "context" "fmt" "sync" "time" @@ -22,9 +23,11 @@ import ( v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" mvccpb "github.com/coreos/etcd/mvcc/mvccpb" - "golang.org/x/net/context" + "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" ) const ( @@ -40,10 +43,9 @@ type WatchChan <-chan WatchResponse type Watcher interface { // Watch watches on a key or prefix. The watched events will be returned - // through the returned channel. - // If the watch is slow or the required rev is compacted, the watch request - // might be canceled from the server-side and the chan will be closed. - // 'opts' can be: 'WithRev' and/or 'WithPrefix'. + // through the returned channel. If revisions waiting to be sent over the + // watch are compacted, then the watch will be canceled by the server, the + // client will post a compacted error watch response, and the channel will close. Watch(ctx context.Context, key string, opts ...OpOption) WatchChan // Close closes the watcher and cancels all watch requests. @@ -90,7 +92,7 @@ func (wr *WatchResponse) Err() error { return v3rpc.ErrCompacted case wr.Canceled: if len(wr.cancelReason) != 0 { - return v3rpc.Error(grpc.Errorf(codes.FailedPrecondition, "%s", wr.cancelReason)) + return v3rpc.Error(status.Error(codes.FailedPrecondition, wr.cancelReason)) } return v3rpc.ErrFutureRev } @@ -104,7 +106,8 @@ func (wr *WatchResponse) IsProgressNotify() bool { // watcher implements the Watcher interface type watcher struct { - remote pb.WatchClient + remote pb.WatchClient + callOpts []grpc.CallOption // mu protects the grpc streams map mu sync.RWMutex @@ -115,8 +118,9 @@ type watcher struct { // watchGrpcStream tracks all watch resources attached to a single grpc stream. type watchGrpcStream struct { - owner *watcher - remote pb.WatchClient + owner *watcher + remote pb.WatchClient + callOpts []grpc.CallOption // ctx controls internal remote.Watch requests ctx context.Context @@ -135,7 +139,7 @@ type watchGrpcStream struct { respc chan *pb.WatchResponse // donec closes to broadcast shutdown donec chan struct{} - // errc transmits errors from grpc Recv to the watch stream reconn logic + // errc transmits errors from grpc Recv to the watch stream reconnect logic errc chan error // closingc gets the watcherStream of closing watchers closingc chan *watcherStream @@ -187,14 +191,18 @@ type watcherStream struct { } func NewWatcher(c *Client) Watcher { - return NewWatchFromWatchClient(pb.NewWatchClient(c.conn)) + return NewWatchFromWatchClient(pb.NewWatchClient(c.conn), c) } -func NewWatchFromWatchClient(wc pb.WatchClient) Watcher { - return &watcher{ +func NewWatchFromWatchClient(wc pb.WatchClient, c *Client) Watcher { + w := &watcher{ remote: wc, streams: make(map[string]*watchGrpcStream), } + if c != nil { + w.callOpts = c.callOpts + } + return w } // never closes @@ -213,17 +221,17 @@ func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream { wgs := &watchGrpcStream{ owner: w, remote: w.remote, + callOpts: w.callOpts, ctx: ctx, - ctxKey: fmt.Sprintf("%v", inctx), + ctxKey: streamKeyFromCtx(inctx), cancel: cancel, substreams: make(map[int64]*watcherStream), - - respc: make(chan *pb.WatchResponse), - reqc: make(chan *watchRequest), - donec: make(chan struct{}), - errc: make(chan error, 1), - closingc: make(chan *watcherStream), - resumec: make(chan struct{}), + respc: make(chan *pb.WatchResponse), + reqc: make(chan *watchRequest), + donec: make(chan struct{}), + errc: make(chan error, 1), + closingc: make(chan *watcherStream), + resumec: make(chan struct{}), } go wgs.run() return wgs @@ -254,7 +262,7 @@ func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) Watch } ok := false - ctxKey := fmt.Sprintf("%v", ctx) + ctxKey := streamKeyFromCtx(ctx) // find or allocate appropriate grpc watch stream w.mu.Lock() @@ -317,14 +325,14 @@ func (w *watcher) Close() (err error) { w.streams = nil w.mu.Unlock() for _, wgs := range streams { - if werr := wgs.Close(); werr != nil { + if werr := wgs.close(); werr != nil { err = werr } } return err } -func (w *watchGrpcStream) Close() (err error) { +func (w *watchGrpcStream) close() (err error) { w.cancel() <-w.donec select { @@ -435,7 +443,7 @@ func (w *watchGrpcStream) run() { initReq: *wreq, id: -1, outc: outc, - // unbufffered so resumes won't cause repeat events + // unbuffered so resumes won't cause repeat events recvc: make(chan *WatchResponse), } @@ -462,7 +470,7 @@ func (w *watchGrpcStream) run() { if ws := w.nextResume(); ws != nil { wc.Send(ws.initReq.toPB()) } - case pbresp.Canceled: + case pbresp.Canceled && pbresp.CompactRevision == 0: delete(cancelSet, pbresp.WatchId) if ws, ok := w.substreams[pbresp.WatchId]; ok { // signal to stream goroutine to update closingc @@ -487,7 +495,7 @@ func (w *watchGrpcStream) run() { req := &pb.WatchRequest{RequestUnion: cr} wc.Send(req) } - // watch client failed to recv; spawn another if possible + // watch client failed on Recv; spawn another if possible case err := <-w.errc: if isHaltErr(w.ctx, err) || toErr(w.ctx, err) == v3rpc.ErrNoLeader { closeErr = err @@ -749,7 +757,7 @@ func (w *watchGrpcStream) waitCancelSubstreams(stopc <-chan struct{}) <-chan str return donec } -// joinSubstream waits for all substream goroutines to complete +// joinSubstreams waits for all substream goroutines to complete. func (w *watchGrpcStream) joinSubstreams() { for _, ws := range w.substreams { <-ws.donec @@ -761,8 +769,13 @@ func (w *watchGrpcStream) joinSubstreams() { } } -// openWatchClient retries opening a watchclient until retryConnection fails +var maxBackoff = 100 * time.Millisecond + +// openWatchClient retries opening a watch client until success or halt. +// manually retry in case "ws==nil && err==nil" +// TODO: remove FailFast=false func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) { + backoff := time.Millisecond for { select { case <-w.ctx.Done(): @@ -772,17 +785,28 @@ func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) return nil, err default: } - if ws, err = w.remote.Watch(w.ctx, grpc.FailFast(false)); ws != nil && err == nil { + if ws, err = w.remote.Watch(w.ctx, w.callOpts...); ws != nil && err == nil { break } if isHaltErr(w.ctx, err) { return nil, v3rpc.Error(err) } + if isUnavailableErr(w.ctx, err) { + // retry, but backoff + if backoff < maxBackoff { + // 25% backoff factor + backoff = backoff + backoff/4 + if backoff > maxBackoff { + backoff = maxBackoff + } + } + time.Sleep(backoff) + } } return ws, nil } -// toPB converts an internal watch request structure to its protobuf messagefunc (wr *watchRequest) +// toPB converts an internal watch request structure to its protobuf WatchRequest structure. func (wr *watchRequest) toPB() *pb.WatchRequest { req := &pb.WatchCreateRequest{ StartRevision: wr.rev, @@ -795,3 +819,10 @@ func (wr *watchRequest) toPB() *pb.WatchRequest { cr := &pb.WatchRequest_CreateRequest{CreateRequest: req} return &pb.WatchRequest{RequestUnion: cr} } + +func streamKeyFromCtx(ctx context.Context) string { + if md, ok := metadata.FromOutgoingContext(ctx); ok { + return fmt.Sprintf("%+v", md) + } + return "" +} diff --git a/vendor/github.com/coreos/etcd/cmd/functional b/vendor/github.com/coreos/etcd/cmd/functional new file mode 120000 index 0000000000..44faa31aef --- /dev/null +++ b/vendor/github.com/coreos/etcd/cmd/functional @@ -0,0 +1 @@ +../functional \ No newline at end of file diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go index 0907e902c6..55eab38ef1 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go @@ -15,106 +15,114 @@ package rpctypes import ( - "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) +// server-side error var ( - // server-side error - ErrGRPCEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided") - ErrGRPCKeyNotFound = grpc.Errorf(codes.InvalidArgument, "etcdserver: key not found") - ErrGRPCValueProvided = grpc.Errorf(codes.InvalidArgument, "etcdserver: value is provided") - ErrGRPCLeaseProvided = grpc.Errorf(codes.InvalidArgument, "etcdserver: lease is provided") - ErrGRPCTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request") - ErrGRPCDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request") - ErrGRPCCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted") - ErrGRPCFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision") - ErrGRPCNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded") - - ErrGRPCLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found") - ErrGRPCLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists") - - ErrGRPCMemberExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: member ID already exist") - ErrGRPCPeerURLExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: Peer URLs already exists") - ErrGRPCMemberNotEnoughStarted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: re-configuration failed due to not enough started members") - ErrGRPCMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid") - ErrGRPCMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found") - - ErrGRPCRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") - ErrGRPCRequestTooManyRequests = grpc.Errorf(codes.ResourceExhausted, "etcdserver: too many requests") - - ErrGRPCRootUserNotExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: root user does not exist") - ErrGRPCRootRoleNotExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: root user does not have root role") - ErrGRPCUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists") - ErrGRPCUserEmpty = grpc.Errorf(codes.InvalidArgument, "etcdserver: user name is empty") - ErrGRPCUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found") - ErrGRPCRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists") - ErrGRPCRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found") - ErrGRPCAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password") - ErrGRPCPermissionDenied = grpc.Errorf(codes.PermissionDenied, "etcdserver: permission denied") - ErrGRPCRoleNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role is not granted to the user") - ErrGRPCPermissionNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission is not granted to the role") - ErrGRPCAuthNotEnabled = grpc.Errorf(codes.FailedPrecondition, "etcdserver: authentication is not enabled") - ErrGRPCInvalidAuthToken = grpc.Errorf(codes.Unauthenticated, "etcdserver: invalid auth token") - ErrGRPCInvalidAuthMgmt = grpc.Errorf(codes.InvalidArgument, "etcdserver: invalid auth management") - - ErrGRPCNoLeader = grpc.Errorf(codes.Unavailable, "etcdserver: no leader") - ErrGRPCNotCapable = grpc.Errorf(codes.Unavailable, "etcdserver: not capable") - ErrGRPCStopped = grpc.Errorf(codes.Unavailable, "etcdserver: server stopped") - ErrGRPCTimeout = grpc.Errorf(codes.Unavailable, "etcdserver: request timed out") - ErrGRPCTimeoutDueToLeaderFail = grpc.Errorf(codes.Unavailable, "etcdserver: request timed out, possibly due to previous leader failure") - ErrGRPCTimeoutDueToConnectionLost = grpc.Errorf(codes.Unavailable, "etcdserver: request timed out, possibly due to connection lost") - ErrGRPCUnhealthy = grpc.Errorf(codes.Unavailable, "etcdserver: unhealthy cluster") + ErrGRPCEmptyKey = status.New(codes.InvalidArgument, "etcdserver: key is not provided").Err() + ErrGRPCKeyNotFound = status.New(codes.InvalidArgument, "etcdserver: key not found").Err() + ErrGRPCValueProvided = status.New(codes.InvalidArgument, "etcdserver: value is provided").Err() + ErrGRPCLeaseProvided = status.New(codes.InvalidArgument, "etcdserver: lease is provided").Err() + ErrGRPCTooManyOps = status.New(codes.InvalidArgument, "etcdserver: too many operations in txn request").Err() + ErrGRPCDuplicateKey = status.New(codes.InvalidArgument, "etcdserver: duplicate key given in txn request").Err() + ErrGRPCCompacted = status.New(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted").Err() + ErrGRPCFutureRev = status.New(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision").Err() + ErrGRPCNoSpace = status.New(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded").Err() + + ErrGRPCLeaseNotFound = status.New(codes.NotFound, "etcdserver: requested lease not found").Err() + ErrGRPCLeaseExist = status.New(codes.FailedPrecondition, "etcdserver: lease already exists").Err() + ErrGRPCLeaseTTLTooLarge = status.New(codes.OutOfRange, "etcdserver: too large lease TTL").Err() + + ErrGRPCMemberExist = status.New(codes.FailedPrecondition, "etcdserver: member ID already exist").Err() + ErrGRPCPeerURLExist = status.New(codes.FailedPrecondition, "etcdserver: Peer URLs already exists").Err() + ErrGRPCMemberNotEnoughStarted = status.New(codes.FailedPrecondition, "etcdserver: re-configuration failed due to not enough started members").Err() + ErrGRPCMemberBadURLs = status.New(codes.InvalidArgument, "etcdserver: given member URLs are invalid").Err() + ErrGRPCMemberNotFound = status.New(codes.NotFound, "etcdserver: member not found").Err() + + ErrGRPCRequestTooLarge = status.New(codes.InvalidArgument, "etcdserver: request is too large").Err() + ErrGRPCRequestTooManyRequests = status.New(codes.ResourceExhausted, "etcdserver: too many requests").Err() + + ErrGRPCRootUserNotExist = status.New(codes.FailedPrecondition, "etcdserver: root user does not exist").Err() + ErrGRPCRootRoleNotExist = status.New(codes.FailedPrecondition, "etcdserver: root user does not have root role").Err() + ErrGRPCUserAlreadyExist = status.New(codes.FailedPrecondition, "etcdserver: user name already exists").Err() + ErrGRPCUserEmpty = status.New(codes.InvalidArgument, "etcdserver: user name is empty").Err() + ErrGRPCUserNotFound = status.New(codes.FailedPrecondition, "etcdserver: user name not found").Err() + ErrGRPCRoleAlreadyExist = status.New(codes.FailedPrecondition, "etcdserver: role name already exists").Err() + ErrGRPCRoleNotFound = status.New(codes.FailedPrecondition, "etcdserver: role name not found").Err() + ErrGRPCAuthFailed = status.New(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password").Err() + ErrGRPCPermissionDenied = status.New(codes.PermissionDenied, "etcdserver: permission denied").Err() + ErrGRPCRoleNotGranted = status.New(codes.FailedPrecondition, "etcdserver: role is not granted to the user").Err() + ErrGRPCPermissionNotGranted = status.New(codes.FailedPrecondition, "etcdserver: permission is not granted to the role").Err() + ErrGRPCAuthNotEnabled = status.New(codes.FailedPrecondition, "etcdserver: authentication is not enabled").Err() + ErrGRPCInvalidAuthToken = status.New(codes.Unauthenticated, "etcdserver: invalid auth token").Err() + ErrGRPCInvalidAuthMgmt = status.New(codes.InvalidArgument, "etcdserver: invalid auth management").Err() + + ErrGRPCNoLeader = status.New(codes.Unavailable, "etcdserver: no leader").Err() + ErrGRPCNotLeader = status.New(codes.FailedPrecondition, "etcdserver: not leader").Err() + ErrGRPCNotCapable = status.New(codes.Unavailable, "etcdserver: not capable").Err() + ErrGRPCStopped = status.New(codes.Unavailable, "etcdserver: server stopped").Err() + ErrGRPCTimeout = status.New(codes.Unavailable, "etcdserver: request timed out").Err() + ErrGRPCTimeoutDueToLeaderFail = status.New(codes.Unavailable, "etcdserver: request timed out, possibly due to previous leader failure").Err() + ErrGRPCTimeoutDueToConnectionLost = status.New(codes.Unavailable, "etcdserver: request timed out, possibly due to connection lost").Err() + ErrGRPCUnhealthy = status.New(codes.Unavailable, "etcdserver: unhealthy cluster").Err() + ErrGRPCCorrupt = status.New(codes.DataLoss, "etcdserver: corrupt cluster").Err() errStringToError = map[string]error{ - grpc.ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey, - grpc.ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound, - grpc.ErrorDesc(ErrGRPCValueProvided): ErrGRPCValueProvided, - grpc.ErrorDesc(ErrGRPCLeaseProvided): ErrGRPCLeaseProvided, - - grpc.ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps, - grpc.ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey, - grpc.ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted, - grpc.ErrorDesc(ErrGRPCFutureRev): ErrGRPCFutureRev, - grpc.ErrorDesc(ErrGRPCNoSpace): ErrGRPCNoSpace, - - grpc.ErrorDesc(ErrGRPCLeaseNotFound): ErrGRPCLeaseNotFound, - grpc.ErrorDesc(ErrGRPCLeaseExist): ErrGRPCLeaseExist, - - grpc.ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist, - grpc.ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist, - grpc.ErrorDesc(ErrGRPCMemberNotEnoughStarted): ErrGRPCMemberNotEnoughStarted, - grpc.ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs, - grpc.ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound, - - grpc.ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, - grpc.ErrorDesc(ErrGRPCRequestTooManyRequests): ErrGRPCRequestTooManyRequests, - - grpc.ErrorDesc(ErrGRPCRootUserNotExist): ErrGRPCRootUserNotExist, - grpc.ErrorDesc(ErrGRPCRootRoleNotExist): ErrGRPCRootRoleNotExist, - grpc.ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, - grpc.ErrorDesc(ErrGRPCUserEmpty): ErrGRPCUserEmpty, - grpc.ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, - grpc.ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, - grpc.ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, - grpc.ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed, - grpc.ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, - grpc.ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted, - grpc.ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted, - grpc.ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled, - grpc.ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken, - grpc.ErrorDesc(ErrGRPCInvalidAuthMgmt): ErrGRPCInvalidAuthMgmt, - - grpc.ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, - grpc.ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable, - grpc.ErrorDesc(ErrGRPCStopped): ErrGRPCStopped, - grpc.ErrorDesc(ErrGRPCTimeout): ErrGRPCTimeout, - grpc.ErrorDesc(ErrGRPCTimeoutDueToLeaderFail): ErrGRPCTimeoutDueToLeaderFail, - grpc.ErrorDesc(ErrGRPCTimeoutDueToConnectionLost): ErrGRPCTimeoutDueToConnectionLost, - grpc.ErrorDesc(ErrGRPCUnhealthy): ErrGRPCUnhealthy, + ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey, + ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound, + ErrorDesc(ErrGRPCValueProvided): ErrGRPCValueProvided, + ErrorDesc(ErrGRPCLeaseProvided): ErrGRPCLeaseProvided, + + ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps, + ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey, + ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted, + ErrorDesc(ErrGRPCFutureRev): ErrGRPCFutureRev, + ErrorDesc(ErrGRPCNoSpace): ErrGRPCNoSpace, + + ErrorDesc(ErrGRPCLeaseNotFound): ErrGRPCLeaseNotFound, + ErrorDesc(ErrGRPCLeaseExist): ErrGRPCLeaseExist, + ErrorDesc(ErrGRPCLeaseTTLTooLarge): ErrGRPCLeaseTTLTooLarge, + + ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist, + ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist, + ErrorDesc(ErrGRPCMemberNotEnoughStarted): ErrGRPCMemberNotEnoughStarted, + ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs, + ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound, + + ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, + ErrorDesc(ErrGRPCRequestTooManyRequests): ErrGRPCRequestTooManyRequests, + + ErrorDesc(ErrGRPCRootUserNotExist): ErrGRPCRootUserNotExist, + ErrorDesc(ErrGRPCRootRoleNotExist): ErrGRPCRootRoleNotExist, + ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, + ErrorDesc(ErrGRPCUserEmpty): ErrGRPCUserEmpty, + ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, + ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, + ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, + ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed, + ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, + ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted, + ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted, + ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled, + ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken, + ErrorDesc(ErrGRPCInvalidAuthMgmt): ErrGRPCInvalidAuthMgmt, + + ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, + ErrorDesc(ErrGRPCNotLeader): ErrGRPCNotLeader, + ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable, + ErrorDesc(ErrGRPCStopped): ErrGRPCStopped, + ErrorDesc(ErrGRPCTimeout): ErrGRPCTimeout, + ErrorDesc(ErrGRPCTimeoutDueToLeaderFail): ErrGRPCTimeoutDueToLeaderFail, + ErrorDesc(ErrGRPCTimeoutDueToConnectionLost): ErrGRPCTimeoutDueToConnectionLost, + ErrorDesc(ErrGRPCUnhealthy): ErrGRPCUnhealthy, + ErrorDesc(ErrGRPCCorrupt): ErrGRPCCorrupt, } +) - // client-side error +// client-side error +var ( ErrEmptyKey = Error(ErrGRPCEmptyKey) ErrKeyNotFound = Error(ErrGRPCKeyNotFound) ErrValueProvided = Error(ErrGRPCValueProvided) @@ -125,8 +133,9 @@ var ( ErrFutureRev = Error(ErrGRPCFutureRev) ErrNoSpace = Error(ErrGRPCNoSpace) - ErrLeaseNotFound = Error(ErrGRPCLeaseNotFound) - ErrLeaseExist = Error(ErrGRPCLeaseExist) + ErrLeaseNotFound = Error(ErrGRPCLeaseNotFound) + ErrLeaseExist = Error(ErrGRPCLeaseExist) + ErrLeaseTTLTooLarge = Error(ErrGRPCLeaseTTLTooLarge) ErrMemberExist = Error(ErrGRPCMemberExist) ErrPeerURLExist = Error(ErrGRPCPeerURLExist) @@ -153,12 +162,14 @@ var ( ErrInvalidAuthMgmt = Error(ErrGRPCInvalidAuthMgmt) ErrNoLeader = Error(ErrGRPCNoLeader) + ErrNotLeader = Error(ErrGRPCNotLeader) ErrNotCapable = Error(ErrGRPCNotCapable) ErrStopped = Error(ErrGRPCStopped) ErrTimeout = Error(ErrGRPCTimeout) ErrTimeoutDueToLeaderFail = Error(ErrGRPCTimeoutDueToLeaderFail) ErrTimeoutDueToConnectionLost = Error(ErrGRPCTimeoutDueToConnectionLost) ErrUnhealthy = Error(ErrGRPCUnhealthy) + ErrCorrupt = Error(ErrGRPCCorrupt) ) // EtcdError defines gRPC server errors. @@ -182,9 +193,23 @@ func Error(err error) error { if err == nil { return nil } - verr, ok := errStringToError[grpc.ErrorDesc(err)] + verr, ok := errStringToError[ErrorDesc(err)] if !ok { // not gRPC error return err } - return EtcdError{code: grpc.Code(verr), desc: grpc.ErrorDesc(verr)} + ev, ok := status.FromError(verr) + var desc string + if ok { + desc = ev.Message() + } else { + desc = verr.Error() + } + return EtcdError{code: ev.Code(), desc: desc} +} + +func ErrorDesc(err error) string { + if s, ok := status.FromError(err); ok { + return s.Message() + } + return err.Error() } diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go index aabf90061f..90045a5c97 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: etcdserver.proto -// DO NOT EDIT! /* Package etcdserverpb is a generated protocol buffer package. @@ -32,6 +31,8 @@ CompactionRequest CompactionResponse HashRequest + HashKVRequest + HashKVResponse HashResponse SnapshotRequest SnapshotResponse @@ -47,6 +48,9 @@ LeaseKeepAliveResponse LeaseTimeToLiveRequest LeaseTimeToLiveResponse + LeaseLeasesRequest + LeaseStatus + LeaseLeasesResponse Member MemberAddRequest MemberAddResponse @@ -58,6 +62,8 @@ MemberListResponse DefragmentRequest DefragmentResponse + MoveLeaderRequest + MoveLeaderResponse AlarmRequest AlarmMember AlarmResponse @@ -105,6 +111,8 @@ import ( math "math" + _ "github.com/gogo/protobuf/gogoproto" + io "io" ) @@ -311,24 +319,6 @@ func (m *Metadata) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func encodeFixed64Etcdserver(dAtA []byte, offset int, v uint64) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - dAtA[offset+4] = uint8(v >> 32) - dAtA[offset+5] = uint8(v >> 40) - dAtA[offset+6] = uint8(v >> 48) - dAtA[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Etcdserver(dAtA []byte, offset int, v uint32) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - return offset + 4 -} func encodeVarintEtcdserver(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go index 44a3b6f69e..3084c6cbf8 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: raft_internal.proto -// DO NOT EDIT! package etcdserverpb @@ -11,6 +10,8 @@ import ( math "math" + _ "github.com/gogo/protobuf/gogoproto" + io "io" ) @@ -505,24 +506,6 @@ func (m *InternalAuthenticateRequest) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func encodeFixed64RaftInternal(dAtA []byte, offset int, v uint64) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - dAtA[offset+4] = uint8(v >> 32) - dAtA[offset+5] = uint8(v >> 40) - dAtA[offset+6] = uint8(v >> 48) - dAtA[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32RaftInternal(dAtA []byte, offset int, v uint32) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - return offset + 4 -} func encodeVarintRaftInternal(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go new file mode 100644 index 0000000000..ec6b6397b3 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go @@ -0,0 +1,183 @@ +// Copyright 2018 The etcd Authors +// +// 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 etcdserverpb + +import ( + "fmt" + "strings" + + proto "github.com/golang/protobuf/proto" +) + +// InternalRaftStringer implements custom proto Stringer: +// redact password, replace value fields with value_size fields. +type InternalRaftStringer struct { + Request *InternalRaftRequest +} + +func (as *InternalRaftStringer) String() string { + switch { + case as.Request.LeaseGrant != nil: + return fmt.Sprintf("header:<%s> lease_grant:", + as.Request.Header.String(), + as.Request.LeaseGrant.TTL, + as.Request.LeaseGrant.ID, + ) + case as.Request.LeaseRevoke != nil: + return fmt.Sprintf("header:<%s> lease_revoke:", + as.Request.Header.String(), + as.Request.LeaseRevoke.ID, + ) + case as.Request.Authenticate != nil: + return fmt.Sprintf("header:<%s> authenticate:", + as.Request.Header.String(), + as.Request.Authenticate.Name, + as.Request.Authenticate.SimpleToken, + ) + case as.Request.AuthUserAdd != nil: + return fmt.Sprintf("header:<%s> auth_user_add:", + as.Request.Header.String(), + as.Request.AuthUserAdd.Name, + ) + case as.Request.AuthUserChangePassword != nil: + return fmt.Sprintf("header:<%s> auth_user_change_password:", + as.Request.Header.String(), + as.Request.AuthUserChangePassword.Name, + ) + case as.Request.Put != nil: + return fmt.Sprintf("header:<%s> put:<%s>", + as.Request.Header.String(), + newLoggablePutRequest(as.Request.Put).String(), + ) + case as.Request.Txn != nil: + return fmt.Sprintf("header:<%s> txn:<%s>", + as.Request.Header.String(), + NewLoggableTxnRequest(as.Request.Txn).String(), + ) + default: + // nothing to redact + } + return as.Request.String() +} + +// txnRequestStringer implements a custom proto String to replace value bytes fields with value size +// fields in any nested txn and put operations. +type txnRequestStringer struct { + Request *TxnRequest +} + +func NewLoggableTxnRequest(request *TxnRequest) *txnRequestStringer { + return &txnRequestStringer{request} +} + +func (as *txnRequestStringer) String() string { + var compare []string + for _, c := range as.Request.Compare { + switch cv := c.TargetUnion.(type) { + case *Compare_Value: + compare = append(compare, newLoggableValueCompare(c, cv).String()) + default: + // nothing to redact + compare = append(compare, c.String()) + } + } + var success []string + for _, s := range as.Request.Success { + success = append(success, newLoggableRequestOp(s).String()) + } + var failure []string + for _, f := range as.Request.Failure { + failure = append(failure, newLoggableRequestOp(f).String()) + } + return fmt.Sprintf("compare:<%s> success:<%s> failure:<%s>", + strings.Join(compare, " "), + strings.Join(success, " "), + strings.Join(failure, " "), + ) +} + +// requestOpStringer implements a custom proto String to replace value bytes fields with value +// size fields in any nested txn and put operations. +type requestOpStringer struct { + Op *RequestOp +} + +func newLoggableRequestOp(op *RequestOp) *requestOpStringer { + return &requestOpStringer{op} +} + +func (as *requestOpStringer) String() string { + switch op := as.Op.Request.(type) { + case *RequestOp_RequestPut: + return fmt.Sprintf("request_put:<%s>", newLoggablePutRequest(op.RequestPut).String()) + case *RequestOp_RequestTxn: + return fmt.Sprintf("request_txn:<%s>", NewLoggableTxnRequest(op.RequestTxn).String()) + default: + // nothing to redact + } + return as.Op.String() +} + +// loggableValueCompare implements a custom proto String for Compare.Value union member types to +// replace the value bytes field with a value size field. +// To preserve proto encoding of the key and range_end bytes, a faked out proto type is used here. +type loggableValueCompare struct { + Result Compare_CompareResult `protobuf:"varint,1,opt,name=result,proto3,enum=etcdserverpb.Compare_CompareResult"` + Target Compare_CompareTarget `protobuf:"varint,2,opt,name=target,proto3,enum=etcdserverpb.Compare_CompareTarget"` + Key []byte `protobuf:"bytes,3,opt,name=key,proto3"` + ValueSize int `protobuf:"bytes,7,opt,name=value_size,proto3"` + RangeEnd []byte `protobuf:"bytes,64,opt,name=range_end,proto3"` +} + +func newLoggableValueCompare(c *Compare, cv *Compare_Value) *loggableValueCompare { + return &loggableValueCompare{ + c.Result, + c.Target, + c.Key, + len(cv.Value), + c.RangeEnd, + } +} + +func (m *loggableValueCompare) Reset() { *m = loggableValueCompare{} } +func (m *loggableValueCompare) String() string { return proto.CompactTextString(m) } +func (*loggableValueCompare) ProtoMessage() {} + +// loggablePutRequest implements a custom proto String to replace value bytes field with a value +// size field. +// To preserve proto encoding of the key bytes, a faked out proto type is used here. +type loggablePutRequest struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3"` + ValueSize int `protobuf:"varint,2,opt,name=value_size,proto3"` + Lease int64 `protobuf:"varint,3,opt,name=lease,proto3"` + PrevKv bool `protobuf:"varint,4,opt,name=prev_kv,proto3"` + IgnoreValue bool `protobuf:"varint,5,opt,name=ignore_value,proto3"` + IgnoreLease bool `protobuf:"varint,6,opt,name=ignore_lease,proto3"` +} + +func newLoggablePutRequest(request *PutRequest) *loggablePutRequest { + return &loggablePutRequest{ + request.Key, + len(request.Value), + request.Lease, + request.PrevKv, + request.IgnoreValue, + request.IgnoreLease, + } +} + +func (m *loggablePutRequest) Reset() { *m = loggablePutRequest{} } +func (m *loggablePutRequest) String() string { return proto.CompactTextString(m) } +func (*loggablePutRequest) ProtoMessage() {} diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go index 018a3652be..40147f935a 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: rpc.proto -// DO NOT EDIT! package etcdserverpb @@ -11,6 +10,8 @@ import ( math "math" + _ "github.com/gogo/protobuf/gogoproto" + mvccpb "github.com/coreos/etcd/mvcc/mvccpb" authpb "github.com/coreos/etcd/auth/authpb" @@ -32,15 +33,18 @@ type AlarmType int32 const ( AlarmType_NONE AlarmType = 0 AlarmType_NOSPACE AlarmType = 1 + AlarmType_CORRUPT AlarmType = 2 ) var AlarmType_name = map[int32]string{ 0: "NONE", 1: "NOSPACE", + 2: "CORRUPT", } var AlarmType_value = map[string]int32{ "NONE": 0, "NOSPACE": 1, + "CORRUPT": 2, } func (x AlarmType) String() string { @@ -136,6 +140,7 @@ const ( Compare_CREATE Compare_CompareTarget = 1 Compare_MOD Compare_CompareTarget = 2 Compare_VALUE Compare_CompareTarget = 3 + Compare_LEASE Compare_CompareTarget = 4 ) var Compare_CompareTarget_name = map[int32]string{ @@ -143,12 +148,14 @@ var Compare_CompareTarget_name = map[int32]string{ 1: "CREATE", 2: "MOD", 3: "VALUE", + 4: "LEASE", } var Compare_CompareTarget_value = map[string]int32{ "VERSION": 0, "CREATE": 1, "MOD": 2, "VALUE": 3, + "LEASE": 4, } func (x Compare_CompareTarget) String() string { @@ -178,7 +185,7 @@ func (x WatchCreateRequest_FilterType) String() string { return proto.EnumName(WatchCreateRequest_FilterType_name, int32(x)) } func (WatchCreateRequest_FilterType) EnumDescriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{19, 0} + return fileDescriptorRpc, []int{21, 0} } type AlarmRequest_AlarmAction int32 @@ -204,7 +211,7 @@ func (x AlarmRequest_AlarmAction) String() string { return proto.EnumName(AlarmRequest_AlarmAction_name, int32(x)) } func (AlarmRequest_AlarmAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{41, 0} + return fileDescriptorRpc, []int{48, 0} } type ResponseHeader struct { @@ -223,6 +230,34 @@ func (m *ResponseHeader) String() string { return proto.CompactTextSt func (*ResponseHeader) ProtoMessage() {} func (*ResponseHeader) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{0} } +func (m *ResponseHeader) GetClusterId() uint64 { + if m != nil { + return m.ClusterId + } + return 0 +} + +func (m *ResponseHeader) GetMemberId() uint64 { + if m != nil { + return m.MemberId + } + return 0 +} + +func (m *ResponseHeader) GetRevision() int64 { + if m != nil { + return m.Revision + } + return 0 +} + +func (m *ResponseHeader) GetRaftTerm() uint64 { + if m != nil { + return m.RaftTerm + } + return 0 +} + type RangeRequest struct { // key is the first key for the range. If range_end is not given, the request only looks up key. Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -273,6 +308,97 @@ func (m *RangeRequest) String() string { return proto.CompactTextStri func (*RangeRequest) ProtoMessage() {} func (*RangeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1} } +func (m *RangeRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *RangeRequest) GetRangeEnd() []byte { + if m != nil { + return m.RangeEnd + } + return nil +} + +func (m *RangeRequest) GetLimit() int64 { + if m != nil { + return m.Limit + } + return 0 +} + +func (m *RangeRequest) GetRevision() int64 { + if m != nil { + return m.Revision + } + return 0 +} + +func (m *RangeRequest) GetSortOrder() RangeRequest_SortOrder { + if m != nil { + return m.SortOrder + } + return RangeRequest_NONE +} + +func (m *RangeRequest) GetSortTarget() RangeRequest_SortTarget { + if m != nil { + return m.SortTarget + } + return RangeRequest_KEY +} + +func (m *RangeRequest) GetSerializable() bool { + if m != nil { + return m.Serializable + } + return false +} + +func (m *RangeRequest) GetKeysOnly() bool { + if m != nil { + return m.KeysOnly + } + return false +} + +func (m *RangeRequest) GetCountOnly() bool { + if m != nil { + return m.CountOnly + } + return false +} + +func (m *RangeRequest) GetMinModRevision() int64 { + if m != nil { + return m.MinModRevision + } + return 0 +} + +func (m *RangeRequest) GetMaxModRevision() int64 { + if m != nil { + return m.MaxModRevision + } + return 0 +} + +func (m *RangeRequest) GetMinCreateRevision() int64 { + if m != nil { + return m.MinCreateRevision + } + return 0 +} + +func (m *RangeRequest) GetMaxCreateRevision() int64 { + if m != nil { + return m.MaxCreateRevision + } + return 0 +} + type RangeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` // kvs is the list of key-value pairs matched by the range request. @@ -303,6 +429,20 @@ func (m *RangeResponse) GetKvs() []*mvccpb.KeyValue { return nil } +func (m *RangeResponse) GetMore() bool { + if m != nil { + return m.More + } + return false +} + +func (m *RangeResponse) GetCount() int64 { + if m != nil { + return m.Count + } + return 0 +} + type PutRequest struct { // key is the key, in bytes, to put into the key-value store. Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -327,6 +467,48 @@ func (m *PutRequest) String() string { return proto.CompactTextString func (*PutRequest) ProtoMessage() {} func (*PutRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{3} } +func (m *PutRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *PutRequest) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *PutRequest) GetLease() int64 { + if m != nil { + return m.Lease + } + return 0 +} + +func (m *PutRequest) GetPrevKv() bool { + if m != nil { + return m.PrevKv + } + return false +} + +func (m *PutRequest) GetIgnoreValue() bool { + if m != nil { + return m.IgnoreValue + } + return false +} + +func (m *PutRequest) GetIgnoreLease() bool { + if m != nil { + return m.IgnoreLease + } + return false +} + type PutResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` // if prev_kv is set in the request, the previous key-value pair will be returned. @@ -371,6 +553,27 @@ func (m *DeleteRangeRequest) String() string { return proto.CompactTe func (*DeleteRangeRequest) ProtoMessage() {} func (*DeleteRangeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{5} } +func (m *DeleteRangeRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *DeleteRangeRequest) GetRangeEnd() []byte { + if m != nil { + return m.RangeEnd + } + return nil +} + +func (m *DeleteRangeRequest) GetPrevKv() bool { + if m != nil { + return m.PrevKv + } + return false +} + type DeleteRangeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` // deleted is the number of keys deleted by the delete range request. @@ -391,6 +594,13 @@ func (m *DeleteRangeResponse) GetHeader() *ResponseHeader { return nil } +func (m *DeleteRangeResponse) GetDeleted() int64 { + if m != nil { + return m.Deleted + } + return 0 +} + func (m *DeleteRangeResponse) GetPrevKvs() []*mvccpb.KeyValue { if m != nil { return m.PrevKvs @@ -405,6 +615,7 @@ type RequestOp struct { // *RequestOp_RequestRange // *RequestOp_RequestPut // *RequestOp_RequestDeleteRange + // *RequestOp_RequestTxn Request isRequestOp_Request `protobuf_oneof:"request"` } @@ -428,10 +639,14 @@ type RequestOp_RequestPut struct { type RequestOp_RequestDeleteRange struct { RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range,json=requestDeleteRange,oneof"` } +type RequestOp_RequestTxn struct { + RequestTxn *TxnRequest `protobuf:"bytes,4,opt,name=request_txn,json=requestTxn,oneof"` +} func (*RequestOp_RequestRange) isRequestOp_Request() {} func (*RequestOp_RequestPut) isRequestOp_Request() {} func (*RequestOp_RequestDeleteRange) isRequestOp_Request() {} +func (*RequestOp_RequestTxn) isRequestOp_Request() {} func (m *RequestOp) GetRequest() isRequestOp_Request { if m != nil { @@ -461,12 +676,20 @@ func (m *RequestOp) GetRequestDeleteRange() *DeleteRangeRequest { return nil } +func (m *RequestOp) GetRequestTxn() *TxnRequest { + if x, ok := m.GetRequest().(*RequestOp_RequestTxn); ok { + return x.RequestTxn + } + return nil +} + // XXX_OneofFuncs is for the internal use of the proto package. func (*RequestOp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { return _RequestOp_OneofMarshaler, _RequestOp_OneofUnmarshaler, _RequestOp_OneofSizer, []interface{}{ (*RequestOp_RequestRange)(nil), (*RequestOp_RequestPut)(nil), (*RequestOp_RequestDeleteRange)(nil), + (*RequestOp_RequestTxn)(nil), } } @@ -489,6 +712,11 @@ func _RequestOp_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { if err := b.EncodeMessage(x.RequestDeleteRange); err != nil { return err } + case *RequestOp_RequestTxn: + _ = b.EncodeVarint(4<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.RequestTxn); err != nil { + return err + } case nil: default: return fmt.Errorf("RequestOp.Request has unexpected type %T", x) @@ -523,6 +751,14 @@ func _RequestOp_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buff err := b.DecodeMessage(msg) m.Request = &RequestOp_RequestDeleteRange{msg} return true, err + case 4: // request.request_txn + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(TxnRequest) + err := b.DecodeMessage(msg) + m.Request = &RequestOp_RequestTxn{msg} + return true, err default: return false, nil } @@ -547,6 +783,11 @@ func _RequestOp_OneofSizer(msg proto.Message) (n int) { n += proto.SizeVarint(3<<3 | proto.WireBytes) n += proto.SizeVarint(uint64(s)) n += s + case *RequestOp_RequestTxn: + s := proto.Size(x.RequestTxn) + n += proto.SizeVarint(4<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s case nil: default: panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) @@ -561,6 +802,7 @@ type ResponseOp struct { // *ResponseOp_ResponseRange // *ResponseOp_ResponsePut // *ResponseOp_ResponseDeleteRange + // *ResponseOp_ResponseTxn Response isResponseOp_Response `protobuf_oneof:"response"` } @@ -584,10 +826,14 @@ type ResponseOp_ResponsePut struct { type ResponseOp_ResponseDeleteRange struct { ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range,json=responseDeleteRange,oneof"` } +type ResponseOp_ResponseTxn struct { + ResponseTxn *TxnResponse `protobuf:"bytes,4,opt,name=response_txn,json=responseTxn,oneof"` +} func (*ResponseOp_ResponseRange) isResponseOp_Response() {} func (*ResponseOp_ResponsePut) isResponseOp_Response() {} func (*ResponseOp_ResponseDeleteRange) isResponseOp_Response() {} +func (*ResponseOp_ResponseTxn) isResponseOp_Response() {} func (m *ResponseOp) GetResponse() isResponseOp_Response { if m != nil { @@ -617,12 +863,20 @@ func (m *ResponseOp) GetResponseDeleteRange() *DeleteRangeResponse { return nil } +func (m *ResponseOp) GetResponseTxn() *TxnResponse { + if x, ok := m.GetResponse().(*ResponseOp_ResponseTxn); ok { + return x.ResponseTxn + } + return nil +} + // XXX_OneofFuncs is for the internal use of the proto package. func (*ResponseOp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { return _ResponseOp_OneofMarshaler, _ResponseOp_OneofUnmarshaler, _ResponseOp_OneofSizer, []interface{}{ (*ResponseOp_ResponseRange)(nil), (*ResponseOp_ResponsePut)(nil), (*ResponseOp_ResponseDeleteRange)(nil), + (*ResponseOp_ResponseTxn)(nil), } } @@ -645,6 +899,11 @@ func _ResponseOp_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { if err := b.EncodeMessage(x.ResponseDeleteRange); err != nil { return err } + case *ResponseOp_ResponseTxn: + _ = b.EncodeVarint(4<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ResponseTxn); err != nil { + return err + } case nil: default: return fmt.Errorf("ResponseOp.Response has unexpected type %T", x) @@ -679,6 +938,14 @@ func _ResponseOp_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buf err := b.DecodeMessage(msg) m.Response = &ResponseOp_ResponseDeleteRange{msg} return true, err + case 4: // response.response_txn + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(TxnResponse) + err := b.DecodeMessage(msg) + m.Response = &ResponseOp_ResponseTxn{msg} + return true, err default: return false, nil } @@ -703,6 +970,11 @@ func _ResponseOp_OneofSizer(msg proto.Message) (n int) { n += proto.SizeVarint(3<<3 | proto.WireBytes) n += proto.SizeVarint(uint64(s)) n += s + case *ResponseOp_ResponseTxn: + s := proto.Size(x.ResponseTxn) + n += proto.SizeVarint(4<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s case nil: default: panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) @@ -722,7 +994,11 @@ type Compare struct { // *Compare_CreateRevision // *Compare_ModRevision // *Compare_Value + // *Compare_Lease TargetUnion isCompare_TargetUnion `protobuf_oneof:"target_union"` + // range_end compares the given target to all keys in the range [key, range_end). + // See RangeRequest for more details on key ranges. + RangeEnd []byte `protobuf:"bytes,64,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"` } func (m *Compare) Reset() { *m = Compare{} } @@ -748,11 +1024,15 @@ type Compare_ModRevision struct { type Compare_Value struct { Value []byte `protobuf:"bytes,7,opt,name=value,proto3,oneof"` } +type Compare_Lease struct { + Lease int64 `protobuf:"varint,8,opt,name=lease,proto3,oneof"` +} func (*Compare_Version) isCompare_TargetUnion() {} func (*Compare_CreateRevision) isCompare_TargetUnion() {} func (*Compare_ModRevision) isCompare_TargetUnion() {} func (*Compare_Value) isCompare_TargetUnion() {} +func (*Compare_Lease) isCompare_TargetUnion() {} func (m *Compare) GetTargetUnion() isCompare_TargetUnion { if m != nil { @@ -761,6 +1041,27 @@ func (m *Compare) GetTargetUnion() isCompare_TargetUnion { return nil } +func (m *Compare) GetResult() Compare_CompareResult { + if m != nil { + return m.Result + } + return Compare_EQUAL +} + +func (m *Compare) GetTarget() Compare_CompareTarget { + if m != nil { + return m.Target + } + return Compare_VERSION +} + +func (m *Compare) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + func (m *Compare) GetVersion() int64 { if x, ok := m.GetTargetUnion().(*Compare_Version); ok { return x.Version @@ -789,6 +1090,20 @@ func (m *Compare) GetValue() []byte { return nil } +func (m *Compare) GetLease() int64 { + if x, ok := m.GetTargetUnion().(*Compare_Lease); ok { + return x.Lease + } + return 0 +} + +func (m *Compare) GetRangeEnd() []byte { + if m != nil { + return m.RangeEnd + } + return nil +} + // XXX_OneofFuncs is for the internal use of the proto package. func (*Compare) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { return _Compare_OneofMarshaler, _Compare_OneofUnmarshaler, _Compare_OneofSizer, []interface{}{ @@ -796,6 +1111,7 @@ func (*Compare) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error (*Compare_CreateRevision)(nil), (*Compare_ModRevision)(nil), (*Compare_Value)(nil), + (*Compare_Lease)(nil), } } @@ -815,6 +1131,9 @@ func _Compare_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { case *Compare_Value: _ = b.EncodeVarint(7<<3 | proto.WireBytes) _ = b.EncodeRawBytes(x.Value) + case *Compare_Lease: + _ = b.EncodeVarint(8<<3 | proto.WireVarint) + _ = b.EncodeVarint(uint64(x.Lease)) case nil: default: return fmt.Errorf("Compare.TargetUnion has unexpected type %T", x) @@ -853,6 +1172,13 @@ func _Compare_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer x, err := b.DecodeRawBytes(true) m.TargetUnion = &Compare_Value{x} return true, err + case 8: // target_union.lease + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.TargetUnion = &Compare_Lease{int64(x)} + return true, err default: return false, nil } @@ -875,6 +1201,9 @@ func _Compare_OneofSizer(msg proto.Message) (n int) { n += proto.SizeVarint(7<<3 | proto.WireBytes) n += proto.SizeVarint(uint64(len(x.Value))) n += len(x.Value) + case *Compare_Lease: + n += proto.SizeVarint(8<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Lease)) case nil: default: panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) @@ -957,6 +1286,13 @@ func (m *TxnResponse) GetHeader() *ResponseHeader { return nil } +func (m *TxnResponse) GetSucceeded() bool { + if m != nil { + return m.Succeeded + } + return false +} + func (m *TxnResponse) GetResponses() []*ResponseOp { if m != nil { return m.Responses @@ -980,6 +1316,20 @@ func (m *CompactionRequest) String() string { return proto.CompactTex func (*CompactionRequest) ProtoMessage() {} func (*CompactionRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{12} } +func (m *CompactionRequest) GetRevision() int64 { + if m != nil { + return m.Revision + } + return 0 +} + +func (m *CompactionRequest) GetPhysical() bool { + if m != nil { + return m.Physical + } + return false +} + type CompactionResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } @@ -1004,16 +1354,67 @@ func (m *HashRequest) String() string { return proto.CompactTextStrin func (*HashRequest) ProtoMessage() {} func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{14} } +type HashKVRequest struct { + // revision is the key-value store revision for the hash operation. + Revision int64 `protobuf:"varint,1,opt,name=revision,proto3" json:"revision,omitempty"` +} + +func (m *HashKVRequest) Reset() { *m = HashKVRequest{} } +func (m *HashKVRequest) String() string { return proto.CompactTextString(m) } +func (*HashKVRequest) ProtoMessage() {} +func (*HashKVRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{15} } + +func (m *HashKVRequest) GetRevision() int64 { + if m != nil { + return m.Revision + } + return 0 +} + +type HashKVResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // hash is the hash value computed from the responding member's MVCC keys up to a given revision. + Hash uint32 `protobuf:"varint,2,opt,name=hash,proto3" json:"hash,omitempty"` + // compact_revision is the compacted revision of key-value store when hash begins. + CompactRevision int64 `protobuf:"varint,3,opt,name=compact_revision,json=compactRevision,proto3" json:"compact_revision,omitempty"` +} + +func (m *HashKVResponse) Reset() { *m = HashKVResponse{} } +func (m *HashKVResponse) String() string { return proto.CompactTextString(m) } +func (*HashKVResponse) ProtoMessage() {} +func (*HashKVResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{16} } + +func (m *HashKVResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *HashKVResponse) GetHash() uint32 { + if m != nil { + return m.Hash + } + return 0 +} + +func (m *HashKVResponse) GetCompactRevision() int64 { + if m != nil { + return m.CompactRevision + } + return 0 +} + type HashResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - // hash is the hash value computed from the responding member's key-value store. + // hash is the hash value computed from the responding member's KV's backend. Hash uint32 `protobuf:"varint,2,opt,name=hash,proto3" json:"hash,omitempty"` } func (m *HashResponse) Reset() { *m = HashResponse{} } func (m *HashResponse) String() string { return proto.CompactTextString(m) } func (*HashResponse) ProtoMessage() {} -func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{15} } +func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{17} } func (m *HashResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1022,13 +1423,20 @@ func (m *HashResponse) GetHeader() *ResponseHeader { return nil } +func (m *HashResponse) GetHash() uint32 { + if m != nil { + return m.Hash + } + return 0 +} + type SnapshotRequest struct { } func (m *SnapshotRequest) Reset() { *m = SnapshotRequest{} } func (m *SnapshotRequest) String() string { return proto.CompactTextString(m) } func (*SnapshotRequest) ProtoMessage() {} -func (*SnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{16} } +func (*SnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{18} } type SnapshotResponse struct { // header has the current key-value store information. The first header in the snapshot @@ -1043,7 +1451,7 @@ type SnapshotResponse struct { func (m *SnapshotResponse) Reset() { *m = SnapshotResponse{} } func (m *SnapshotResponse) String() string { return proto.CompactTextString(m) } func (*SnapshotResponse) ProtoMessage() {} -func (*SnapshotResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{17} } +func (*SnapshotResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{19} } func (m *SnapshotResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1052,6 +1460,20 @@ func (m *SnapshotResponse) GetHeader() *ResponseHeader { return nil } +func (m *SnapshotResponse) GetRemainingBytes() uint64 { + if m != nil { + return m.RemainingBytes + } + return 0 +} + +func (m *SnapshotResponse) GetBlob() []byte { + if m != nil { + return m.Blob + } + return nil +} + type WatchRequest struct { // request_union is a request to either create a new watcher or cancel an existing watcher. // @@ -1064,7 +1486,7 @@ type WatchRequest struct { func (m *WatchRequest) Reset() { *m = WatchRequest{} } func (m *WatchRequest) String() string { return proto.CompactTextString(m) } func (*WatchRequest) ProtoMessage() {} -func (*WatchRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{18} } +func (*WatchRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{20} } type isWatchRequest_RequestUnion interface { isWatchRequest_RequestUnion() @@ -1203,17 +1625,66 @@ type WatchCreateRequest struct { func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} } func (m *WatchCreateRequest) String() string { return proto.CompactTextString(m) } func (*WatchCreateRequest) ProtoMessage() {} -func (*WatchCreateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{19} } +func (*WatchCreateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{21} } -type WatchCancelRequest struct { - // watch_id is the watcher id to cancel so that no more events are transmitted. - WatchId int64 `protobuf:"varint,1,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"` -} +func (m *WatchCreateRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *WatchCreateRequest) GetRangeEnd() []byte { + if m != nil { + return m.RangeEnd + } + return nil +} + +func (m *WatchCreateRequest) GetStartRevision() int64 { + if m != nil { + return m.StartRevision + } + return 0 +} + +func (m *WatchCreateRequest) GetProgressNotify() bool { + if m != nil { + return m.ProgressNotify + } + return false +} + +func (m *WatchCreateRequest) GetFilters() []WatchCreateRequest_FilterType { + if m != nil { + return m.Filters + } + return nil +} + +func (m *WatchCreateRequest) GetPrevKv() bool { + if m != nil { + return m.PrevKv + } + return false +} + +type WatchCancelRequest struct { + // watch_id is the watcher id to cancel so that no more events are transmitted. + WatchId int64 `protobuf:"varint,1,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"` +} func (m *WatchCancelRequest) Reset() { *m = WatchCancelRequest{} } func (m *WatchCancelRequest) String() string { return proto.CompactTextString(m) } func (*WatchCancelRequest) ProtoMessage() {} -func (*WatchCancelRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{20} } +func (*WatchCancelRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{22} } + +func (m *WatchCancelRequest) GetWatchId() int64 { + if m != nil { + return m.WatchId + } + return 0 +} type WatchResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1244,7 +1715,7 @@ type WatchResponse struct { func (m *WatchResponse) Reset() { *m = WatchResponse{} } func (m *WatchResponse) String() string { return proto.CompactTextString(m) } func (*WatchResponse) ProtoMessage() {} -func (*WatchResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{21} } +func (*WatchResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{23} } func (m *WatchResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1253,6 +1724,41 @@ func (m *WatchResponse) GetHeader() *ResponseHeader { return nil } +func (m *WatchResponse) GetWatchId() int64 { + if m != nil { + return m.WatchId + } + return 0 +} + +func (m *WatchResponse) GetCreated() bool { + if m != nil { + return m.Created + } + return false +} + +func (m *WatchResponse) GetCanceled() bool { + if m != nil { + return m.Canceled + } + return false +} + +func (m *WatchResponse) GetCompactRevision() int64 { + if m != nil { + return m.CompactRevision + } + return 0 +} + +func (m *WatchResponse) GetCancelReason() string { + if m != nil { + return m.CancelReason + } + return "" +} + func (m *WatchResponse) GetEvents() []*mvccpb.Event { if m != nil { return m.Events @@ -1261,7 +1767,7 @@ func (m *WatchResponse) GetEvents() []*mvccpb.Event { } type LeaseGrantRequest struct { - // TTL is the advisory time-to-live in seconds. + // TTL is the advisory time-to-live in seconds. Expired lease will return -1. TTL int64 `protobuf:"varint,1,opt,name=TTL,proto3" json:"TTL,omitempty"` // ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID. ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` @@ -1270,7 +1776,21 @@ type LeaseGrantRequest struct { func (m *LeaseGrantRequest) Reset() { *m = LeaseGrantRequest{} } func (m *LeaseGrantRequest) String() string { return proto.CompactTextString(m) } func (*LeaseGrantRequest) ProtoMessage() {} -func (*LeaseGrantRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{22} } +func (*LeaseGrantRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{24} } + +func (m *LeaseGrantRequest) GetTTL() int64 { + if m != nil { + return m.TTL + } + return 0 +} + +func (m *LeaseGrantRequest) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} type LeaseGrantResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1284,7 +1804,7 @@ type LeaseGrantResponse struct { func (m *LeaseGrantResponse) Reset() { *m = LeaseGrantResponse{} } func (m *LeaseGrantResponse) String() string { return proto.CompactTextString(m) } func (*LeaseGrantResponse) ProtoMessage() {} -func (*LeaseGrantResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{23} } +func (*LeaseGrantResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{25} } func (m *LeaseGrantResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1293,6 +1813,27 @@ func (m *LeaseGrantResponse) GetHeader() *ResponseHeader { return nil } +func (m *LeaseGrantResponse) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *LeaseGrantResponse) GetTTL() int64 { + if m != nil { + return m.TTL + } + return 0 +} + +func (m *LeaseGrantResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + type LeaseRevokeRequest struct { // ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted. ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` @@ -1301,7 +1842,14 @@ type LeaseRevokeRequest struct { func (m *LeaseRevokeRequest) Reset() { *m = LeaseRevokeRequest{} } func (m *LeaseRevokeRequest) String() string { return proto.CompactTextString(m) } func (*LeaseRevokeRequest) ProtoMessage() {} -func (*LeaseRevokeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{24} } +func (*LeaseRevokeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{26} } + +func (m *LeaseRevokeRequest) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} type LeaseRevokeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1310,7 +1858,7 @@ type LeaseRevokeResponse struct { func (m *LeaseRevokeResponse) Reset() { *m = LeaseRevokeResponse{} } func (m *LeaseRevokeResponse) String() string { return proto.CompactTextString(m) } func (*LeaseRevokeResponse) ProtoMessage() {} -func (*LeaseRevokeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{25} } +func (*LeaseRevokeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{27} } func (m *LeaseRevokeResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1327,7 +1875,14 @@ type LeaseKeepAliveRequest struct { func (m *LeaseKeepAliveRequest) Reset() { *m = LeaseKeepAliveRequest{} } func (m *LeaseKeepAliveRequest) String() string { return proto.CompactTextString(m) } func (*LeaseKeepAliveRequest) ProtoMessage() {} -func (*LeaseKeepAliveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{26} } +func (*LeaseKeepAliveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{28} } + +func (m *LeaseKeepAliveRequest) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} type LeaseKeepAliveResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1340,7 +1895,7 @@ type LeaseKeepAliveResponse struct { func (m *LeaseKeepAliveResponse) Reset() { *m = LeaseKeepAliveResponse{} } func (m *LeaseKeepAliveResponse) String() string { return proto.CompactTextString(m) } func (*LeaseKeepAliveResponse) ProtoMessage() {} -func (*LeaseKeepAliveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{27} } +func (*LeaseKeepAliveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} } func (m *LeaseKeepAliveResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1349,6 +1904,20 @@ func (m *LeaseKeepAliveResponse) GetHeader() *ResponseHeader { return nil } +func (m *LeaseKeepAliveResponse) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *LeaseKeepAliveResponse) GetTTL() int64 { + if m != nil { + return m.TTL + } + return 0 +} + type LeaseTimeToLiveRequest struct { // ID is the lease ID for the lease. ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` @@ -1359,7 +1928,21 @@ type LeaseTimeToLiveRequest struct { func (m *LeaseTimeToLiveRequest) Reset() { *m = LeaseTimeToLiveRequest{} } func (m *LeaseTimeToLiveRequest) String() string { return proto.CompactTextString(m) } func (*LeaseTimeToLiveRequest) ProtoMessage() {} -func (*LeaseTimeToLiveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{28} } +func (*LeaseTimeToLiveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} } + +func (m *LeaseTimeToLiveRequest) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *LeaseTimeToLiveRequest) GetKeys() bool { + if m != nil { + return m.Keys + } + return false +} type LeaseTimeToLiveResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1376,7 +1959,7 @@ type LeaseTimeToLiveResponse struct { func (m *LeaseTimeToLiveResponse) Reset() { *m = LeaseTimeToLiveResponse{} } func (m *LeaseTimeToLiveResponse) String() string { return proto.CompactTextString(m) } func (*LeaseTimeToLiveResponse) ProtoMessage() {} -func (*LeaseTimeToLiveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} } +func (*LeaseTimeToLiveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{31} } func (m *LeaseTimeToLiveResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1385,6 +1968,82 @@ func (m *LeaseTimeToLiveResponse) GetHeader() *ResponseHeader { return nil } +func (m *LeaseTimeToLiveResponse) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *LeaseTimeToLiveResponse) GetTTL() int64 { + if m != nil { + return m.TTL + } + return 0 +} + +func (m *LeaseTimeToLiveResponse) GetGrantedTTL() int64 { + if m != nil { + return m.GrantedTTL + } + return 0 +} + +func (m *LeaseTimeToLiveResponse) GetKeys() [][]byte { + if m != nil { + return m.Keys + } + return nil +} + +type LeaseLeasesRequest struct { +} + +func (m *LeaseLeasesRequest) Reset() { *m = LeaseLeasesRequest{} } +func (m *LeaseLeasesRequest) String() string { return proto.CompactTextString(m) } +func (*LeaseLeasesRequest) ProtoMessage() {} +func (*LeaseLeasesRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{32} } + +type LeaseStatus struct { + ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` +} + +func (m *LeaseStatus) Reset() { *m = LeaseStatus{} } +func (m *LeaseStatus) String() string { return proto.CompactTextString(m) } +func (*LeaseStatus) ProtoMessage() {} +func (*LeaseStatus) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{33} } + +func (m *LeaseStatus) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +type LeaseLeasesResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Leases []*LeaseStatus `protobuf:"bytes,2,rep,name=leases" json:"leases,omitempty"` +} + +func (m *LeaseLeasesResponse) Reset() { *m = LeaseLeasesResponse{} } +func (m *LeaseLeasesResponse) String() string { return proto.CompactTextString(m) } +func (*LeaseLeasesResponse) ProtoMessage() {} +func (*LeaseLeasesResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{34} } + +func (m *LeaseLeasesResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *LeaseLeasesResponse) GetLeases() []*LeaseStatus { + if m != nil { + return m.Leases + } + return nil +} + type Member struct { // ID is the member ID for this member. ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` @@ -1399,7 +2058,35 @@ type Member struct { func (m *Member) Reset() { *m = Member{} } func (m *Member) String() string { return proto.CompactTextString(m) } func (*Member) ProtoMessage() {} -func (*Member) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} } +func (*Member) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{35} } + +func (m *Member) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *Member) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Member) GetPeerURLs() []string { + if m != nil { + return m.PeerURLs + } + return nil +} + +func (m *Member) GetClientURLs() []string { + if m != nil { + return m.ClientURLs + } + return nil +} type MemberAddRequest struct { // peerURLs is the list of URLs the added member will use to communicate with the cluster. @@ -1409,7 +2096,14 @@ type MemberAddRequest struct { func (m *MemberAddRequest) Reset() { *m = MemberAddRequest{} } func (m *MemberAddRequest) String() string { return proto.CompactTextString(m) } func (*MemberAddRequest) ProtoMessage() {} -func (*MemberAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{31} } +func (*MemberAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{36} } + +func (m *MemberAddRequest) GetPeerURLs() []string { + if m != nil { + return m.PeerURLs + } + return nil +} type MemberAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1422,7 +2116,7 @@ type MemberAddResponse struct { func (m *MemberAddResponse) Reset() { *m = MemberAddResponse{} } func (m *MemberAddResponse) String() string { return proto.CompactTextString(m) } func (*MemberAddResponse) ProtoMessage() {} -func (*MemberAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{32} } +func (*MemberAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{37} } func (m *MemberAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1453,7 +2147,14 @@ type MemberRemoveRequest struct { func (m *MemberRemoveRequest) Reset() { *m = MemberRemoveRequest{} } func (m *MemberRemoveRequest) String() string { return proto.CompactTextString(m) } func (*MemberRemoveRequest) ProtoMessage() {} -func (*MemberRemoveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{33} } +func (*MemberRemoveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{38} } + +func (m *MemberRemoveRequest) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} type MemberRemoveResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1464,7 +2165,7 @@ type MemberRemoveResponse struct { func (m *MemberRemoveResponse) Reset() { *m = MemberRemoveResponse{} } func (m *MemberRemoveResponse) String() string { return proto.CompactTextString(m) } func (*MemberRemoveResponse) ProtoMessage() {} -func (*MemberRemoveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{34} } +func (*MemberRemoveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{39} } func (m *MemberRemoveResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1490,7 +2191,21 @@ type MemberUpdateRequest struct { func (m *MemberUpdateRequest) Reset() { *m = MemberUpdateRequest{} } func (m *MemberUpdateRequest) String() string { return proto.CompactTextString(m) } func (*MemberUpdateRequest) ProtoMessage() {} -func (*MemberUpdateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{35} } +func (*MemberUpdateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{40} } + +func (m *MemberUpdateRequest) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *MemberUpdateRequest) GetPeerURLs() []string { + if m != nil { + return m.PeerURLs + } + return nil +} type MemberUpdateResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1501,7 +2216,7 @@ type MemberUpdateResponse struct { func (m *MemberUpdateResponse) Reset() { *m = MemberUpdateResponse{} } func (m *MemberUpdateResponse) String() string { return proto.CompactTextString(m) } func (*MemberUpdateResponse) ProtoMessage() {} -func (*MemberUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{36} } +func (*MemberUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{41} } func (m *MemberUpdateResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1523,7 +2238,7 @@ type MemberListRequest struct { func (m *MemberListRequest) Reset() { *m = MemberListRequest{} } func (m *MemberListRequest) String() string { return proto.CompactTextString(m) } func (*MemberListRequest) ProtoMessage() {} -func (*MemberListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{37} } +func (*MemberListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{42} } type MemberListResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1534,7 +2249,7 @@ type MemberListResponse struct { func (m *MemberListResponse) Reset() { *m = MemberListResponse{} } func (m *MemberListResponse) String() string { return proto.CompactTextString(m) } func (*MemberListResponse) ProtoMessage() {} -func (*MemberListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{38} } +func (*MemberListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{43} } func (m *MemberListResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1556,7 +2271,7 @@ type DefragmentRequest struct { func (m *DefragmentRequest) Reset() { *m = DefragmentRequest{} } func (m *DefragmentRequest) String() string { return proto.CompactTextString(m) } func (*DefragmentRequest) ProtoMessage() {} -func (*DefragmentRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{39} } +func (*DefragmentRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{44} } type DefragmentResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1565,7 +2280,7 @@ type DefragmentResponse struct { func (m *DefragmentResponse) Reset() { *m = DefragmentResponse{} } func (m *DefragmentResponse) String() string { return proto.CompactTextString(m) } func (*DefragmentResponse) ProtoMessage() {} -func (*DefragmentResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{40} } +func (*DefragmentResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{45} } func (m *DefragmentResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1574,6 +2289,39 @@ func (m *DefragmentResponse) GetHeader() *ResponseHeader { return nil } +type MoveLeaderRequest struct { + // targetID is the node ID for the new leader. + TargetID uint64 `protobuf:"varint,1,opt,name=targetID,proto3" json:"targetID,omitempty"` +} + +func (m *MoveLeaderRequest) Reset() { *m = MoveLeaderRequest{} } +func (m *MoveLeaderRequest) String() string { return proto.CompactTextString(m) } +func (*MoveLeaderRequest) ProtoMessage() {} +func (*MoveLeaderRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{46} } + +func (m *MoveLeaderRequest) GetTargetID() uint64 { + if m != nil { + return m.TargetID + } + return 0 +} + +type MoveLeaderResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` +} + +func (m *MoveLeaderResponse) Reset() { *m = MoveLeaderResponse{} } +func (m *MoveLeaderResponse) String() string { return proto.CompactTextString(m) } +func (*MoveLeaderResponse) ProtoMessage() {} +func (*MoveLeaderResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{47} } + +func (m *MoveLeaderResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + type AlarmRequest struct { // action is the kind of alarm request to issue. The action // may GET alarm statuses, ACTIVATE an alarm, or DEACTIVATE a @@ -1589,7 +2337,28 @@ type AlarmRequest struct { func (m *AlarmRequest) Reset() { *m = AlarmRequest{} } func (m *AlarmRequest) String() string { return proto.CompactTextString(m) } func (*AlarmRequest) ProtoMessage() {} -func (*AlarmRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{41} } +func (*AlarmRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{48} } + +func (m *AlarmRequest) GetAction() AlarmRequest_AlarmAction { + if m != nil { + return m.Action + } + return AlarmRequest_GET +} + +func (m *AlarmRequest) GetMemberID() uint64 { + if m != nil { + return m.MemberID + } + return 0 +} + +func (m *AlarmRequest) GetAlarm() AlarmType { + if m != nil { + return m.Alarm + } + return AlarmType_NONE +} type AlarmMember struct { // memberID is the ID of the member associated with the raised alarm. @@ -1601,7 +2370,21 @@ type AlarmMember struct { func (m *AlarmMember) Reset() { *m = AlarmMember{} } func (m *AlarmMember) String() string { return proto.CompactTextString(m) } func (*AlarmMember) ProtoMessage() {} -func (*AlarmMember) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{42} } +func (*AlarmMember) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{49} } + +func (m *AlarmMember) GetMemberID() uint64 { + if m != nil { + return m.MemberID + } + return 0 +} + +func (m *AlarmMember) GetAlarm() AlarmType { + if m != nil { + return m.Alarm + } + return AlarmType_NONE +} type AlarmResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1612,7 +2395,7 @@ type AlarmResponse struct { func (m *AlarmResponse) Reset() { *m = AlarmResponse{} } func (m *AlarmResponse) String() string { return proto.CompactTextString(m) } func (*AlarmResponse) ProtoMessage() {} -func (*AlarmResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{43} } +func (*AlarmResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{50} } func (m *AlarmResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1634,7 +2417,7 @@ type StatusRequest struct { func (m *StatusRequest) Reset() { *m = StatusRequest{} } func (m *StatusRequest) String() string { return proto.CompactTextString(m) } func (*StatusRequest) ProtoMessage() {} -func (*StatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{44} } +func (*StatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{51} } type StatusResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1653,7 +2436,7 @@ type StatusResponse struct { func (m *StatusResponse) Reset() { *m = StatusResponse{} } func (m *StatusResponse) String() string { return proto.CompactTextString(m) } func (*StatusResponse) ProtoMessage() {} -func (*StatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{45} } +func (*StatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{52} } func (m *StatusResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1662,21 +2445,56 @@ func (m *StatusResponse) GetHeader() *ResponseHeader { return nil } -type AuthEnableRequest struct { +func (m *StatusResponse) GetVersion() string { + if m != nil { + return m.Version + } + return "" } -func (m *AuthEnableRequest) Reset() { *m = AuthEnableRequest{} } -func (m *AuthEnableRequest) String() string { return proto.CompactTextString(m) } -func (*AuthEnableRequest) ProtoMessage() {} -func (*AuthEnableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{46} } +func (m *StatusResponse) GetDbSize() int64 { + if m != nil { + return m.DbSize + } + return 0 +} -type AuthDisableRequest struct { +func (m *StatusResponse) GetLeader() uint64 { + if m != nil { + return m.Leader + } + return 0 } -func (m *AuthDisableRequest) Reset() { *m = AuthDisableRequest{} } -func (m *AuthDisableRequest) String() string { return proto.CompactTextString(m) } -func (*AuthDisableRequest) ProtoMessage() {} -func (*AuthDisableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{47} } +func (m *StatusResponse) GetRaftIndex() uint64 { + if m != nil { + return m.RaftIndex + } + return 0 +} + +func (m *StatusResponse) GetRaftTerm() uint64 { + if m != nil { + return m.RaftTerm + } + return 0 +} + +type AuthEnableRequest struct { +} + +func (m *AuthEnableRequest) Reset() { *m = AuthEnableRequest{} } +func (m *AuthEnableRequest) String() string { return proto.CompactTextString(m) } +func (*AuthEnableRequest) ProtoMessage() {} +func (*AuthEnableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{53} } + +type AuthDisableRequest struct { +} + +func (m *AuthDisableRequest) Reset() { *m = AuthDisableRequest{} } +func (m *AuthDisableRequest) String() string { return proto.CompactTextString(m) } +func (*AuthDisableRequest) ProtoMessage() {} +func (*AuthDisableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{54} } type AuthenticateRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1686,7 +2504,21 @@ type AuthenticateRequest struct { func (m *AuthenticateRequest) Reset() { *m = AuthenticateRequest{} } func (m *AuthenticateRequest) String() string { return proto.CompactTextString(m) } func (*AuthenticateRequest) ProtoMessage() {} -func (*AuthenticateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{48} } +func (*AuthenticateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{55} } + +func (m *AuthenticateRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *AuthenticateRequest) GetPassword() string { + if m != nil { + return m.Password + } + return "" +} type AuthUserAddRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1696,7 +2528,21 @@ type AuthUserAddRequest struct { func (m *AuthUserAddRequest) Reset() { *m = AuthUserAddRequest{} } func (m *AuthUserAddRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserAddRequest) ProtoMessage() {} -func (*AuthUserAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{49} } +func (*AuthUserAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{56} } + +func (m *AuthUserAddRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *AuthUserAddRequest) GetPassword() string { + if m != nil { + return m.Password + } + return "" +} type AuthUserGetRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1705,7 +2551,14 @@ type AuthUserGetRequest struct { func (m *AuthUserGetRequest) Reset() { *m = AuthUserGetRequest{} } func (m *AuthUserGetRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserGetRequest) ProtoMessage() {} -func (*AuthUserGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{50} } +func (*AuthUserGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{57} } + +func (m *AuthUserGetRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} type AuthUserDeleteRequest struct { // name is the name of the user to delete. @@ -1715,7 +2568,14 @@ type AuthUserDeleteRequest struct { func (m *AuthUserDeleteRequest) Reset() { *m = AuthUserDeleteRequest{} } func (m *AuthUserDeleteRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserDeleteRequest) ProtoMessage() {} -func (*AuthUserDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{51} } +func (*AuthUserDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{58} } + +func (m *AuthUserDeleteRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} type AuthUserChangePasswordRequest struct { // name is the name of the user whose password is being changed. @@ -1728,7 +2588,21 @@ func (m *AuthUserChangePasswordRequest) Reset() { *m = AuthUserChangePas func (m *AuthUserChangePasswordRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordRequest) ProtoMessage() {} func (*AuthUserChangePasswordRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{52} + return fileDescriptorRpc, []int{59} +} + +func (m *AuthUserChangePasswordRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *AuthUserChangePasswordRequest) GetPassword() string { + if m != nil { + return m.Password + } + return "" } type AuthUserGrantRoleRequest struct { @@ -1741,7 +2615,21 @@ type AuthUserGrantRoleRequest struct { func (m *AuthUserGrantRoleRequest) Reset() { *m = AuthUserGrantRoleRequest{} } func (m *AuthUserGrantRoleRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserGrantRoleRequest) ProtoMessage() {} -func (*AuthUserGrantRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{53} } +func (*AuthUserGrantRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{60} } + +func (m *AuthUserGrantRoleRequest) GetUser() string { + if m != nil { + return m.User + } + return "" +} + +func (m *AuthUserGrantRoleRequest) GetRole() string { + if m != nil { + return m.Role + } + return "" +} type AuthUserRevokeRoleRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1751,7 +2639,21 @@ type AuthUserRevokeRoleRequest struct { func (m *AuthUserRevokeRoleRequest) Reset() { *m = AuthUserRevokeRoleRequest{} } func (m *AuthUserRevokeRoleRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserRevokeRoleRequest) ProtoMessage() {} -func (*AuthUserRevokeRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{54} } +func (*AuthUserRevokeRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{61} } + +func (m *AuthUserRevokeRoleRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *AuthUserRevokeRoleRequest) GetRole() string { + if m != nil { + return m.Role + } + return "" +} type AuthRoleAddRequest struct { // name is the name of the role to add to the authentication system. @@ -1761,7 +2663,14 @@ type AuthRoleAddRequest struct { func (m *AuthRoleAddRequest) Reset() { *m = AuthRoleAddRequest{} } func (m *AuthRoleAddRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleAddRequest) ProtoMessage() {} -func (*AuthRoleAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{55} } +func (*AuthRoleAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{62} } + +func (m *AuthRoleAddRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} type AuthRoleGetRequest struct { Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` @@ -1770,7 +2679,14 @@ type AuthRoleGetRequest struct { func (m *AuthRoleGetRequest) Reset() { *m = AuthRoleGetRequest{} } func (m *AuthRoleGetRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleGetRequest) ProtoMessage() {} -func (*AuthRoleGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{56} } +func (*AuthRoleGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{63} } + +func (m *AuthRoleGetRequest) GetRole() string { + if m != nil { + return m.Role + } + return "" +} type AuthUserListRequest struct { } @@ -1778,7 +2694,7 @@ type AuthUserListRequest struct { func (m *AuthUserListRequest) Reset() { *m = AuthUserListRequest{} } func (m *AuthUserListRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserListRequest) ProtoMessage() {} -func (*AuthUserListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{57} } +func (*AuthUserListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{64} } type AuthRoleListRequest struct { } @@ -1786,7 +2702,7 @@ type AuthRoleListRequest struct { func (m *AuthRoleListRequest) Reset() { *m = AuthRoleListRequest{} } func (m *AuthRoleListRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleListRequest) ProtoMessage() {} -func (*AuthRoleListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{58} } +func (*AuthRoleListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{65} } type AuthRoleDeleteRequest struct { Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` @@ -1795,7 +2711,14 @@ type AuthRoleDeleteRequest struct { func (m *AuthRoleDeleteRequest) Reset() { *m = AuthRoleDeleteRequest{} } func (m *AuthRoleDeleteRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleDeleteRequest) ProtoMessage() {} -func (*AuthRoleDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{59} } +func (*AuthRoleDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{66} } + +func (m *AuthRoleDeleteRequest) GetRole() string { + if m != nil { + return m.Role + } + return "" +} type AuthRoleGrantPermissionRequest struct { // name is the name of the role which will be granted the permission. @@ -1808,7 +2731,14 @@ func (m *AuthRoleGrantPermissionRequest) Reset() { *m = AuthRoleGrantPer func (m *AuthRoleGrantPermissionRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleGrantPermissionRequest) ProtoMessage() {} func (*AuthRoleGrantPermissionRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{60} + return fileDescriptorRpc, []int{67} +} + +func (m *AuthRoleGrantPermissionRequest) GetName() string { + if m != nil { + return m.Name + } + return "" } func (m *AuthRoleGrantPermissionRequest) GetPerm() *authpb.Permission { @@ -1828,7 +2758,28 @@ func (m *AuthRoleRevokePermissionRequest) Reset() { *m = AuthRoleRevokeP func (m *AuthRoleRevokePermissionRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleRevokePermissionRequest) ProtoMessage() {} func (*AuthRoleRevokePermissionRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{61} + return fileDescriptorRpc, []int{68} +} + +func (m *AuthRoleRevokePermissionRequest) GetRole() string { + if m != nil { + return m.Role + } + return "" +} + +func (m *AuthRoleRevokePermissionRequest) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *AuthRoleRevokePermissionRequest) GetRangeEnd() string { + if m != nil { + return m.RangeEnd + } + return "" } type AuthEnableResponse struct { @@ -1838,7 +2789,7 @@ type AuthEnableResponse struct { func (m *AuthEnableResponse) Reset() { *m = AuthEnableResponse{} } func (m *AuthEnableResponse) String() string { return proto.CompactTextString(m) } func (*AuthEnableResponse) ProtoMessage() {} -func (*AuthEnableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{62} } +func (*AuthEnableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{69} } func (m *AuthEnableResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1854,7 +2805,7 @@ type AuthDisableResponse struct { func (m *AuthDisableResponse) Reset() { *m = AuthDisableResponse{} } func (m *AuthDisableResponse) String() string { return proto.CompactTextString(m) } func (*AuthDisableResponse) ProtoMessage() {} -func (*AuthDisableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{63} } +func (*AuthDisableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{70} } func (m *AuthDisableResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1872,7 +2823,7 @@ type AuthenticateResponse struct { func (m *AuthenticateResponse) Reset() { *m = AuthenticateResponse{} } func (m *AuthenticateResponse) String() string { return proto.CompactTextString(m) } func (*AuthenticateResponse) ProtoMessage() {} -func (*AuthenticateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{64} } +func (*AuthenticateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{71} } func (m *AuthenticateResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1881,6 +2832,13 @@ func (m *AuthenticateResponse) GetHeader() *ResponseHeader { return nil } +func (m *AuthenticateResponse) GetToken() string { + if m != nil { + return m.Token + } + return "" +} + type AuthUserAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } @@ -1888,7 +2846,7 @@ type AuthUserAddResponse struct { func (m *AuthUserAddResponse) Reset() { *m = AuthUserAddResponse{} } func (m *AuthUserAddResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserAddResponse) ProtoMessage() {} -func (*AuthUserAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{65} } +func (*AuthUserAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{72} } func (m *AuthUserAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1905,7 +2863,7 @@ type AuthUserGetResponse struct { func (m *AuthUserGetResponse) Reset() { *m = AuthUserGetResponse{} } func (m *AuthUserGetResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserGetResponse) ProtoMessage() {} -func (*AuthUserGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{66} } +func (*AuthUserGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{73} } func (m *AuthUserGetResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1914,6 +2872,13 @@ func (m *AuthUserGetResponse) GetHeader() *ResponseHeader { return nil } +func (m *AuthUserGetResponse) GetRoles() []string { + if m != nil { + return m.Roles + } + return nil +} + type AuthUserDeleteResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } @@ -1921,7 +2886,7 @@ type AuthUserDeleteResponse struct { func (m *AuthUserDeleteResponse) Reset() { *m = AuthUserDeleteResponse{} } func (m *AuthUserDeleteResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserDeleteResponse) ProtoMessage() {} -func (*AuthUserDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{67} } +func (*AuthUserDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{74} } func (m *AuthUserDeleteResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1938,7 +2903,7 @@ func (m *AuthUserChangePasswordResponse) Reset() { *m = AuthUserChangePa func (m *AuthUserChangePasswordResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordResponse) ProtoMessage() {} func (*AuthUserChangePasswordResponse) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{68} + return fileDescriptorRpc, []int{75} } func (m *AuthUserChangePasswordResponse) GetHeader() *ResponseHeader { @@ -1955,7 +2920,7 @@ type AuthUserGrantRoleResponse struct { func (m *AuthUserGrantRoleResponse) Reset() { *m = AuthUserGrantRoleResponse{} } func (m *AuthUserGrantRoleResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserGrantRoleResponse) ProtoMessage() {} -func (*AuthUserGrantRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{69} } +func (*AuthUserGrantRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{76} } func (m *AuthUserGrantRoleResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1971,7 +2936,7 @@ type AuthUserRevokeRoleResponse struct { func (m *AuthUserRevokeRoleResponse) Reset() { *m = AuthUserRevokeRoleResponse{} } func (m *AuthUserRevokeRoleResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserRevokeRoleResponse) ProtoMessage() {} -func (*AuthUserRevokeRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{70} } +func (*AuthUserRevokeRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{77} } func (m *AuthUserRevokeRoleResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1987,7 +2952,7 @@ type AuthRoleAddResponse struct { func (m *AuthRoleAddResponse) Reset() { *m = AuthRoleAddResponse{} } func (m *AuthRoleAddResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleAddResponse) ProtoMessage() {} -func (*AuthRoleAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{71} } +func (*AuthRoleAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{78} } func (m *AuthRoleAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -2004,7 +2969,7 @@ type AuthRoleGetResponse struct { func (m *AuthRoleGetResponse) Reset() { *m = AuthRoleGetResponse{} } func (m *AuthRoleGetResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleGetResponse) ProtoMessage() {} -func (*AuthRoleGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{72} } +func (*AuthRoleGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{79} } func (m *AuthRoleGetResponse) GetHeader() *ResponseHeader { if m != nil { @@ -2028,7 +2993,7 @@ type AuthRoleListResponse struct { func (m *AuthRoleListResponse) Reset() { *m = AuthRoleListResponse{} } func (m *AuthRoleListResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleListResponse) ProtoMessage() {} -func (*AuthRoleListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{73} } +func (*AuthRoleListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{80} } func (m *AuthRoleListResponse) GetHeader() *ResponseHeader { if m != nil { @@ -2037,6 +3002,13 @@ func (m *AuthRoleListResponse) GetHeader() *ResponseHeader { return nil } +func (m *AuthRoleListResponse) GetRoles() []string { + if m != nil { + return m.Roles + } + return nil +} + type AuthUserListResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` Users []string `protobuf:"bytes,2,rep,name=users" json:"users,omitempty"` @@ -2045,7 +3017,7 @@ type AuthUserListResponse struct { func (m *AuthUserListResponse) Reset() { *m = AuthUserListResponse{} } func (m *AuthUserListResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserListResponse) ProtoMessage() {} -func (*AuthUserListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{74} } +func (*AuthUserListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{81} } func (m *AuthUserListResponse) GetHeader() *ResponseHeader { if m != nil { @@ -2054,6 +3026,13 @@ func (m *AuthUserListResponse) GetHeader() *ResponseHeader { return nil } +func (m *AuthUserListResponse) GetUsers() []string { + if m != nil { + return m.Users + } + return nil +} + type AuthRoleDeleteResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } @@ -2061,7 +3040,7 @@ type AuthRoleDeleteResponse struct { func (m *AuthRoleDeleteResponse) Reset() { *m = AuthRoleDeleteResponse{} } func (m *AuthRoleDeleteResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleDeleteResponse) ProtoMessage() {} -func (*AuthRoleDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{75} } +func (*AuthRoleDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{82} } func (m *AuthRoleDeleteResponse) GetHeader() *ResponseHeader { if m != nil { @@ -2078,7 +3057,7 @@ func (m *AuthRoleGrantPermissionResponse) Reset() { *m = AuthRoleGrantPe func (m *AuthRoleGrantPermissionResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleGrantPermissionResponse) ProtoMessage() {} func (*AuthRoleGrantPermissionResponse) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{76} + return fileDescriptorRpc, []int{83} } func (m *AuthRoleGrantPermissionResponse) GetHeader() *ResponseHeader { @@ -2096,7 +3075,7 @@ func (m *AuthRoleRevokePermissionResponse) Reset() { *m = AuthRoleRevoke func (m *AuthRoleRevokePermissionResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleRevokePermissionResponse) ProtoMessage() {} func (*AuthRoleRevokePermissionResponse) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{77} + return fileDescriptorRpc, []int{84} } func (m *AuthRoleRevokePermissionResponse) GetHeader() *ResponseHeader { @@ -2122,6 +3101,8 @@ func init() { proto.RegisterType((*CompactionRequest)(nil), "etcdserverpb.CompactionRequest") proto.RegisterType((*CompactionResponse)(nil), "etcdserverpb.CompactionResponse") proto.RegisterType((*HashRequest)(nil), "etcdserverpb.HashRequest") + proto.RegisterType((*HashKVRequest)(nil), "etcdserverpb.HashKVRequest") + proto.RegisterType((*HashKVResponse)(nil), "etcdserverpb.HashKVResponse") proto.RegisterType((*HashResponse)(nil), "etcdserverpb.HashResponse") proto.RegisterType((*SnapshotRequest)(nil), "etcdserverpb.SnapshotRequest") proto.RegisterType((*SnapshotResponse)(nil), "etcdserverpb.SnapshotResponse") @@ -2137,6 +3118,9 @@ func init() { proto.RegisterType((*LeaseKeepAliveResponse)(nil), "etcdserverpb.LeaseKeepAliveResponse") proto.RegisterType((*LeaseTimeToLiveRequest)(nil), "etcdserverpb.LeaseTimeToLiveRequest") proto.RegisterType((*LeaseTimeToLiveResponse)(nil), "etcdserverpb.LeaseTimeToLiveResponse") + proto.RegisterType((*LeaseLeasesRequest)(nil), "etcdserverpb.LeaseLeasesRequest") + proto.RegisterType((*LeaseStatus)(nil), "etcdserverpb.LeaseStatus") + proto.RegisterType((*LeaseLeasesResponse)(nil), "etcdserverpb.LeaseLeasesResponse") proto.RegisterType((*Member)(nil), "etcdserverpb.Member") proto.RegisterType((*MemberAddRequest)(nil), "etcdserverpb.MemberAddRequest") proto.RegisterType((*MemberAddResponse)(nil), "etcdserverpb.MemberAddResponse") @@ -2148,6 +3132,8 @@ func init() { proto.RegisterType((*MemberListResponse)(nil), "etcdserverpb.MemberListResponse") proto.RegisterType((*DefragmentRequest)(nil), "etcdserverpb.DefragmentRequest") proto.RegisterType((*DefragmentResponse)(nil), "etcdserverpb.DefragmentResponse") + proto.RegisterType((*MoveLeaderRequest)(nil), "etcdserverpb.MoveLeaderRequest") + proto.RegisterType((*MoveLeaderResponse)(nil), "etcdserverpb.MoveLeaderResponse") proto.RegisterType((*AlarmRequest)(nil), "etcdserverpb.AlarmRequest") proto.RegisterType((*AlarmMember)(nil), "etcdserverpb.AlarmMember") proto.RegisterType((*AlarmResponse)(nil), "etcdserverpb.AlarmResponse") @@ -2546,6 +3532,8 @@ type LeaseClient interface { LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (Lease_LeaseKeepAliveClient, error) // LeaseTimeToLive retrieves lease information. LeaseTimeToLive(ctx context.Context, in *LeaseTimeToLiveRequest, opts ...grpc.CallOption) (*LeaseTimeToLiveResponse, error) + // LeaseLeases lists all existing leases. + LeaseLeases(ctx context.Context, in *LeaseLeasesRequest, opts ...grpc.CallOption) (*LeaseLeasesResponse, error) } type leaseClient struct { @@ -2614,6 +3602,15 @@ func (c *leaseClient) LeaseTimeToLive(ctx context.Context, in *LeaseTimeToLiveRe return out, nil } +func (c *leaseClient) LeaseLeases(ctx context.Context, in *LeaseLeasesRequest, opts ...grpc.CallOption) (*LeaseLeasesResponse, error) { + out := new(LeaseLeasesResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseLeases", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Lease service type LeaseServer interface { @@ -2628,6 +3625,8 @@ type LeaseServer interface { LeaseKeepAlive(Lease_LeaseKeepAliveServer) error // LeaseTimeToLive retrieves lease information. LeaseTimeToLive(context.Context, *LeaseTimeToLiveRequest) (*LeaseTimeToLiveResponse, error) + // LeaseLeases lists all existing leases. + LeaseLeases(context.Context, *LeaseLeasesRequest) (*LeaseLeasesResponse, error) } func RegisterLeaseServer(s *grpc.Server, srv LeaseServer) { @@ -2714,6 +3713,24 @@ func _Lease_LeaseTimeToLive_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _Lease_LeaseLeases_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LeaseLeasesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LeaseServer).LeaseLeases(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Lease/LeaseLeases", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LeaseServer).LeaseLeases(ctx, req.(*LeaseLeasesRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Lease_serviceDesc = grpc.ServiceDesc{ ServiceName: "etcdserverpb.Lease", HandlerType: (*LeaseServer)(nil), @@ -2730,6 +3747,10 @@ var _Lease_serviceDesc = grpc.ServiceDesc{ MethodName: "LeaseTimeToLive", Handler: _Lease_LeaseTimeToLive_Handler, }, + { + MethodName: "LeaseLeases", + Handler: _Lease_LeaseLeases_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -2922,12 +3943,16 @@ type MaintenanceClient interface { Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) // Defragment defragments a member's backend database to recover storage space. Defragment(ctx context.Context, in *DefragmentRequest, opts ...grpc.CallOption) (*DefragmentResponse, error) - // Hash returns the hash of the local KV state for consistency checking purpose. + // Hash computes the hash of the KV's backend. // This is designed for testing; do not use this in production when there // are ongoing transactions. Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) + // HashKV computes the hash of all MVCC keys up to a given revision. + HashKV(ctx context.Context, in *HashKVRequest, opts ...grpc.CallOption) (*HashKVResponse, error) // Snapshot sends a snapshot of the entire backend from a member over a stream to a client. Snapshot(ctx context.Context, in *SnapshotRequest, opts ...grpc.CallOption) (Maintenance_SnapshotClient, error) + // MoveLeader requests current leader node to transfer its leadership to transferee. + MoveLeader(ctx context.Context, in *MoveLeaderRequest, opts ...grpc.CallOption) (*MoveLeaderResponse, error) } type maintenanceClient struct { @@ -2974,6 +3999,15 @@ func (c *maintenanceClient) Hash(ctx context.Context, in *HashRequest, opts ...g return out, nil } +func (c *maintenanceClient) HashKV(ctx context.Context, in *HashKVRequest, opts ...grpc.CallOption) (*HashKVResponse, error) { + out := new(HashKVResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/HashKV", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *maintenanceClient) Snapshot(ctx context.Context, in *SnapshotRequest, opts ...grpc.CallOption) (Maintenance_SnapshotClient, error) { stream, err := grpc.NewClientStream(ctx, &_Maintenance_serviceDesc.Streams[0], c.cc, "/etcdserverpb.Maintenance/Snapshot", opts...) if err != nil { @@ -3006,6 +4040,15 @@ func (x *maintenanceSnapshotClient) Recv() (*SnapshotResponse, error) { return m, nil } +func (c *maintenanceClient) MoveLeader(ctx context.Context, in *MoveLeaderRequest, opts ...grpc.CallOption) (*MoveLeaderResponse, error) { + out := new(MoveLeaderResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/MoveLeader", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Maintenance service type MaintenanceServer interface { @@ -3015,12 +4058,16 @@ type MaintenanceServer interface { Status(context.Context, *StatusRequest) (*StatusResponse, error) // Defragment defragments a member's backend database to recover storage space. Defragment(context.Context, *DefragmentRequest) (*DefragmentResponse, error) - // Hash returns the hash of the local KV state for consistency checking purpose. + // Hash computes the hash of the KV's backend. // This is designed for testing; do not use this in production when there // are ongoing transactions. Hash(context.Context, *HashRequest) (*HashResponse, error) + // HashKV computes the hash of all MVCC keys up to a given revision. + HashKV(context.Context, *HashKVRequest) (*HashKVResponse, error) // Snapshot sends a snapshot of the entire backend from a member over a stream to a client. Snapshot(*SnapshotRequest, Maintenance_SnapshotServer) error + // MoveLeader requests current leader node to transfer its leadership to transferee. + MoveLeader(context.Context, *MoveLeaderRequest) (*MoveLeaderResponse, error) } func RegisterMaintenanceServer(s *grpc.Server, srv MaintenanceServer) { @@ -3099,6 +4146,24 @@ func _Maintenance_Hash_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Maintenance_HashKV_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HashKVRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MaintenanceServer).HashKV(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/HashKV", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).HashKV(ctx, req.(*HashKVRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Maintenance_Snapshot_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(SnapshotRequest) if err := stream.RecvMsg(m); err != nil { @@ -3120,6 +4185,24 @@ func (x *maintenanceSnapshotServer) Send(m *SnapshotResponse) error { return x.ServerStream.SendMsg(m) } +func _Maintenance_MoveLeader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MoveLeaderRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MaintenanceServer).MoveLeader(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/MoveLeader", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).MoveLeader(ctx, req.(*MoveLeaderRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Maintenance_serviceDesc = grpc.ServiceDesc{ ServiceName: "etcdserverpb.Maintenance", HandlerType: (*MaintenanceServer)(nil), @@ -3140,6 +4223,14 @@ var _Maintenance_serviceDesc = grpc.ServiceDesc{ MethodName: "Hash", Handler: _Maintenance_Hash_Handler, }, + { + MethodName: "HashKV", + Handler: _Maintenance_HashKV_Handler, + }, + { + MethodName: "MoveLeader", + Handler: _Maintenance_MoveLeader_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -4190,6 +5281,20 @@ func (m *RequestOp_RequestDeleteRange) MarshalTo(dAtA []byte) (int, error) { } return i, nil } +func (m *RequestOp_RequestTxn) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.RequestTxn != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.RequestTxn.Size())) + n9, err := m.RequestTxn.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n9 + } + return i, nil +} func (m *ResponseOp) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4206,11 +5311,11 @@ func (m *ResponseOp) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Response != nil { - nn9, err := m.Response.MarshalTo(dAtA[i:]) + nn10, err := m.Response.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn9 + i += nn10 } return i, nil } @@ -4221,11 +5326,11 @@ func (m *ResponseOp_ResponseRange) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.ResponseRange.Size())) - n10, err := m.ResponseRange.MarshalTo(dAtA[i:]) + n11, err := m.ResponseRange.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n11 } return i, nil } @@ -4235,11 +5340,11 @@ func (m *ResponseOp_ResponsePut) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintRpc(dAtA, i, uint64(m.ResponsePut.Size())) - n11, err := m.ResponsePut.MarshalTo(dAtA[i:]) + n12, err := m.ResponsePut.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n12 } return i, nil } @@ -4249,11 +5354,25 @@ func (m *ResponseOp_ResponseDeleteRange) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintRpc(dAtA, i, uint64(m.ResponseDeleteRange.Size())) - n12, err := m.ResponseDeleteRange.MarshalTo(dAtA[i:]) + n13, err := m.ResponseDeleteRange.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n13 + } + return i, nil +} +func (m *ResponseOp_ResponseTxn) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.ResponseTxn != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.ResponseTxn.Size())) + n14, err := m.ResponseTxn.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n14 } return i, nil } @@ -4289,11 +5408,19 @@ func (m *Compare) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.Key) } if m.TargetUnion != nil { - nn13, err := m.TargetUnion.MarshalTo(dAtA[i:]) + nn15, err := m.TargetUnion.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn13 + i += nn15 + } + if len(m.RangeEnd) > 0 { + dAtA[i] = 0x82 + i++ + dAtA[i] = 0x4 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd))) + i += copy(dAtA[i:], m.RangeEnd) } return i, nil } @@ -4329,6 +5456,13 @@ func (m *Compare_Value) MarshalTo(dAtA []byte) (int, error) { } return i, nil } +func (m *Compare_Lease) MarshalTo(dAtA []byte) (int, error) { + i := 0 + dAtA[i] = 0x40 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Lease)) + return i, nil +} func (m *TxnRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4402,11 +5536,11 @@ func (m *TxnResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n14, err := m.Header.MarshalTo(dAtA[i:]) + n16, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n16 } if m.Succeeded { dAtA[i] = 0x10 @@ -4485,11 +5619,11 @@ func (m *CompactionResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n15, err := m.Header.MarshalTo(dAtA[i:]) + n17, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n17 } return i, nil } @@ -4512,7 +5646,7 @@ func (m *HashRequest) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *HashResponse) Marshal() (dAtA []byte, err error) { +func (m *HashKVRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -4522,7 +5656,30 @@ func (m *HashResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *HashResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *HashKVRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Revision != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Revision)) + } + return i, nil +} + +func (m *HashKVResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HashKVResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -4531,21 +5688,26 @@ func (m *HashResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n16, err := m.Header.MarshalTo(dAtA[i:]) + n18, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n18 } if m.Hash != 0 { dAtA[i] = 0x10 i++ i = encodeVarintRpc(dAtA, i, uint64(m.Hash)) } + if m.CompactRevision != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.CompactRevision)) + } return i, nil } -func (m *SnapshotRequest) Marshal() (dAtA []byte, err error) { +func (m *HashResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -4555,12 +5717,45 @@ func (m *SnapshotRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *SnapshotRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *HashResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - return i, nil + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n19, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n19 + } + if m.Hash != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Hash)) + } + return i, nil +} + +func (m *SnapshotRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SnapshotRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil } func (m *SnapshotResponse) Marshal() (dAtA []byte, err error) { @@ -4582,11 +5777,11 @@ func (m *SnapshotResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n17, err := m.Header.MarshalTo(dAtA[i:]) + n20, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n20 } if m.RemainingBytes != 0 { dAtA[i] = 0x10 @@ -4618,11 +5813,11 @@ func (m *WatchRequest) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.RequestUnion != nil { - nn18, err := m.RequestUnion.MarshalTo(dAtA[i:]) + nn21, err := m.RequestUnion.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn18 + i += nn21 } return i, nil } @@ -4633,11 +5828,11 @@ func (m *WatchRequest_CreateRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.CreateRequest.Size())) - n19, err := m.CreateRequest.MarshalTo(dAtA[i:]) + n22, err := m.CreateRequest.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n22 } return i, nil } @@ -4647,11 +5842,11 @@ func (m *WatchRequest_CancelRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintRpc(dAtA, i, uint64(m.CancelRequest.Size())) - n20, err := m.CancelRequest.MarshalTo(dAtA[i:]) + n23, err := m.CancelRequest.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n23 } return i, nil } @@ -4698,21 +5893,21 @@ func (m *WatchCreateRequest) MarshalTo(dAtA []byte) (int, error) { i++ } if len(m.Filters) > 0 { - dAtA22 := make([]byte, len(m.Filters)*10) - var j21 int + dAtA25 := make([]byte, len(m.Filters)*10) + var j24 int for _, num := range m.Filters { for num >= 1<<7 { - dAtA22[j21] = uint8(uint64(num)&0x7f | 0x80) + dAtA25[j24] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j21++ + j24++ } - dAtA22[j21] = uint8(num) - j21++ + dAtA25[j24] = uint8(num) + j24++ } dAtA[i] = 0x2a i++ - i = encodeVarintRpc(dAtA, i, uint64(j21)) - i += copy(dAtA[i:], dAtA22[:j21]) + i = encodeVarintRpc(dAtA, i, uint64(j24)) + i += copy(dAtA[i:], dAtA25[:j24]) } if m.PrevKv { dAtA[i] = 0x30 @@ -4769,11 +5964,11 @@ func (m *WatchResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n23, err := m.Header.MarshalTo(dAtA[i:]) + n26, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n26 } if m.WatchId != 0 { dAtA[i] = 0x10 @@ -4873,11 +6068,11 @@ func (m *LeaseGrantResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n24, err := m.Header.MarshalTo(dAtA[i:]) + n27, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n27 } if m.ID != 0 { dAtA[i] = 0x10 @@ -4940,11 +6135,11 @@ func (m *LeaseRevokeResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n25, err := m.Header.MarshalTo(dAtA[i:]) + n28, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n28 } return i, nil } @@ -4991,11 +6186,11 @@ func (m *LeaseKeepAliveResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n26, err := m.Header.MarshalTo(dAtA[i:]) + n29, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n29 } if m.ID != 0 { dAtA[i] = 0x10 @@ -5062,11 +6257,11 @@ func (m *LeaseTimeToLiveResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n27, err := m.Header.MarshalTo(dAtA[i:]) + n30, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n30 } if m.ID != 0 { dAtA[i] = 0x10 @@ -5094,6 +6289,87 @@ func (m *LeaseTimeToLiveResponse) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *LeaseLeasesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseLeasesRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *LeaseStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseStatus) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ID != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) + } + return i, nil +} + +func (m *LeaseLeasesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseLeasesResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n31, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n31 + } + if len(m.Leases) > 0 { + for _, msg := range m.Leases { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + func (m *Member) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5205,21 +6481,21 @@ func (m *MemberAddResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n28, err := m.Header.MarshalTo(dAtA[i:]) + n32, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n32 } if m.Member != nil { dAtA[i] = 0x12 i++ i = encodeVarintRpc(dAtA, i, uint64(m.Member.Size())) - n29, err := m.Member.MarshalTo(dAtA[i:]) + n33, err := m.Member.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n33 } if len(m.Members) > 0 { for _, msg := range m.Members { @@ -5278,11 +6554,11 @@ func (m *MemberRemoveResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n30, err := m.Header.MarshalTo(dAtA[i:]) + n34, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n34 } if len(m.Members) > 0 { for _, msg := range m.Members { @@ -5356,11 +6632,11 @@ func (m *MemberUpdateResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n31, err := m.Header.MarshalTo(dAtA[i:]) + n35, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n35 } if len(m.Members) > 0 { for _, msg := range m.Members { @@ -5414,11 +6690,11 @@ func (m *MemberListResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n32, err := m.Header.MarshalTo(dAtA[i:]) + n36, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n36 } if len(m.Members) > 0 { for _, msg := range m.Members { @@ -5472,11 +6748,62 @@ func (m *DefragmentResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n33, err := m.Header.MarshalTo(dAtA[i:]) + n37, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n37 + } + return i, nil +} + +func (m *MoveLeaderRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MoveLeaderRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TargetID != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.TargetID)) + } + return i, nil +} + +func (m *MoveLeaderResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MoveLeaderResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n38, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n38 } return i, nil } @@ -5561,11 +6888,11 @@ func (m *AlarmResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n34, err := m.Header.MarshalTo(dAtA[i:]) + n39, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n39 } if len(m.Alarms) > 0 { for _, msg := range m.Alarms { @@ -5619,11 +6946,11 @@ func (m *StatusResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n35, err := m.Header.MarshalTo(dAtA[i:]) + n40, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n40 } if len(m.Version) > 0 { dAtA[i] = 0x12 @@ -6021,11 +7348,11 @@ func (m *AuthRoleGrantPermissionRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintRpc(dAtA, i, uint64(m.Perm.Size())) - n36, err := m.Perm.MarshalTo(dAtA[i:]) + n41, err := m.Perm.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n41 } return i, nil } @@ -6085,11 +7412,11 @@ func (m *AuthEnableResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n37, err := m.Header.MarshalTo(dAtA[i:]) + n42, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n42 } return i, nil } @@ -6113,11 +7440,11 @@ func (m *AuthDisableResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n38, err := m.Header.MarshalTo(dAtA[i:]) + n43, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n43 } return i, nil } @@ -6141,11 +7468,11 @@ func (m *AuthenticateResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n39, err := m.Header.MarshalTo(dAtA[i:]) + n44, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n44 } if len(m.Token) > 0 { dAtA[i] = 0x12 @@ -6175,11 +7502,11 @@ func (m *AuthUserAddResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n40, err := m.Header.MarshalTo(dAtA[i:]) + n45, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n45 } return i, nil } @@ -6203,11 +7530,11 @@ func (m *AuthUserGetResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n41, err := m.Header.MarshalTo(dAtA[i:]) + n46, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n46 } if len(m.Roles) > 0 { for _, s := range m.Roles { @@ -6246,11 +7573,11 @@ func (m *AuthUserDeleteResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n42, err := m.Header.MarshalTo(dAtA[i:]) + n47, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n42 + i += n47 } return i, nil } @@ -6274,11 +7601,11 @@ func (m *AuthUserChangePasswordResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n43, err := m.Header.MarshalTo(dAtA[i:]) + n48, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n43 + i += n48 } return i, nil } @@ -6302,11 +7629,11 @@ func (m *AuthUserGrantRoleResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n44, err := m.Header.MarshalTo(dAtA[i:]) + n49, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n44 + i += n49 } return i, nil } @@ -6330,11 +7657,11 @@ func (m *AuthUserRevokeRoleResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n45, err := m.Header.MarshalTo(dAtA[i:]) + n50, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n45 + i += n50 } return i, nil } @@ -6358,11 +7685,11 @@ func (m *AuthRoleAddResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n46, err := m.Header.MarshalTo(dAtA[i:]) + n51, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n46 + i += n51 } return i, nil } @@ -6386,11 +7713,11 @@ func (m *AuthRoleGetResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n47, err := m.Header.MarshalTo(dAtA[i:]) + n52, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n47 + i += n52 } if len(m.Perm) > 0 { for _, msg := range m.Perm { @@ -6426,11 +7753,11 @@ func (m *AuthRoleListResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n48, err := m.Header.MarshalTo(dAtA[i:]) + n53, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n48 + i += n53 } if len(m.Roles) > 0 { for _, s := range m.Roles { @@ -6469,11 +7796,11 @@ func (m *AuthUserListResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n49, err := m.Header.MarshalTo(dAtA[i:]) + n54, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n49 + i += n54 } if len(m.Users) > 0 { for _, s := range m.Users { @@ -6512,11 +7839,11 @@ func (m *AuthRoleDeleteResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n50, err := m.Header.MarshalTo(dAtA[i:]) + n55, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n50 + i += n55 } return i, nil } @@ -6540,11 +7867,11 @@ func (m *AuthRoleGrantPermissionResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n51, err := m.Header.MarshalTo(dAtA[i:]) + n56, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n51 + i += n56 } return i, nil } @@ -6568,33 +7895,15 @@ func (m *AuthRoleRevokePermissionResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) - n52, err := m.Header.MarshalTo(dAtA[i:]) + n57, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n52 + i += n57 } return i, nil } -func encodeFixed64Rpc(dAtA []byte, offset int, v uint64) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - dAtA[offset+4] = uint8(v >> 32) - dAtA[offset+5] = uint8(v >> 40) - dAtA[offset+6] = uint8(v >> 48) - dAtA[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Rpc(dAtA []byte, offset int, v uint32) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - return offset + 4 -} func encodeVarintRpc(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -6803,6 +8112,15 @@ func (m *RequestOp_RequestDeleteRange) Size() (n int) { } return n } +func (m *RequestOp_RequestTxn) Size() (n int) { + var l int + _ = l + if m.RequestTxn != nil { + l = m.RequestTxn.Size() + n += 1 + l + sovRpc(uint64(l)) + } + return n +} func (m *ResponseOp) Size() (n int) { var l int _ = l @@ -6839,6 +8157,15 @@ func (m *ResponseOp_ResponseDeleteRange) Size() (n int) { } return n } +func (m *ResponseOp_ResponseTxn) Size() (n int) { + var l int + _ = l + if m.ResponseTxn != nil { + l = m.ResponseTxn.Size() + n += 1 + l + sovRpc(uint64(l)) + } + return n +} func (m *Compare) Size() (n int) { var l int _ = l @@ -6855,6 +8182,10 @@ func (m *Compare) Size() (n int) { if m.TargetUnion != nil { n += m.TargetUnion.Size() } + l = len(m.RangeEnd) + if l > 0 { + n += 2 + l + sovRpc(uint64(l)) + } return n } @@ -6885,6 +8216,12 @@ func (m *Compare_Value) Size() (n int) { } return n } +func (m *Compare_Lease) Size() (n int) { + var l int + _ = l + n += 1 + sovRpc(uint64(m.Lease)) + return n +} func (m *TxnRequest) Size() (n int) { var l int _ = l @@ -6956,6 +8293,31 @@ func (m *HashRequest) Size() (n int) { return n } +func (m *HashKVRequest) Size() (n int) { + var l int + _ = l + if m.Revision != 0 { + n += 1 + sovRpc(uint64(m.Revision)) + } + return n +} + +func (m *HashKVResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if m.Hash != 0 { + n += 1 + sovRpc(uint64(m.Hash)) + } + if m.CompactRevision != 0 { + n += 1 + sovRpc(uint64(m.CompactRevision)) + } + return n +} + func (m *HashResponse) Size() (n int) { var l int _ = l @@ -7203,6 +8565,37 @@ func (m *LeaseTimeToLiveResponse) Size() (n int) { return n } +func (m *LeaseLeasesRequest) Size() (n int) { + var l int + _ = l + return n +} + +func (m *LeaseStatus) Size() (n int) { + var l int + _ = l + if m.ID != 0 { + n += 1 + sovRpc(uint64(m.ID)) + } + return n +} + +func (m *LeaseLeasesResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if len(m.Leases) > 0 { + for _, e := range m.Leases { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + return n +} + func (m *Member) Size() (n int) { var l int _ = l @@ -7354,6 +8747,25 @@ func (m *DefragmentResponse) Size() (n int) { return n } +func (m *MoveLeaderRequest) Size() (n int) { + var l int + _ = l + if m.TargetID != 0 { + n += 1 + sovRpc(uint64(m.TargetID)) + } + return n +} + +func (m *MoveLeaderResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + func (m *AlarmRequest) Size() (n int) { var l int _ = l @@ -9106,6 +10518,38 @@ func (m *RequestOp) Unmarshal(dAtA []byte) error { } m.Request = &RequestOp_RequestDeleteRange{v} iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestTxn", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &TxnRequest{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &RequestOp_RequestTxn{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -9252,6 +10696,38 @@ func (m *ResponseOp) Unmarshal(dAtA []byte) error { } m.Response = &ResponseOp_ResponseDeleteRange{v} iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResponseTxn", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &TxnResponse{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Response = &ResponseOp_ResponseTxn{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -9461,6 +10937,57 @@ func (m *Compare) Unmarshal(dAtA []byte) error { copy(v, dAtA[iNdEx:postIndex]) m.TargetUnion = &Compare_Value{v} iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Lease", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.TargetUnion = &Compare_Lease{v} + case 64: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...) + if m.RangeEnd == nil { + m.RangeEnd = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -9981,7 +11508,7 @@ func (m *HashRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *HashResponse) Unmarshal(dAtA []byte) error { +func (m *HashKVRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10004,50 +11531,17 @@ func (m *HashResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HashResponse: wiretype end group for non-group") + return fmt.Errorf("proto: HashKVRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HashResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HashKVRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthRpc - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Header == nil { - m.Header = &ResponseHeader{} - } - if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) } - m.Hash = 0 + m.Revision = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowRpc @@ -10057,7 +11551,7 @@ func (m *HashResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Hash |= (uint32(b) & 0x7F) << shift + m.Revision |= (int64(b) & 0x7F) << shift if b < 0x80 { break } @@ -10083,7 +11577,7 @@ func (m *HashResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *SnapshotRequest) Unmarshal(dAtA []byte) error { +func (m *HashKVResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10106,30 +11600,253 @@ func (m *SnapshotRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SnapshotRequest: wiretype end group for non-group") + return fmt.Errorf("proto: HashKVResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SnapshotRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HashKVResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipRpc(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthRpc - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + m.Hash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Hash |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CompactRevision", wireType) + } + m.CompactRevision = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CompactRevision |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HashResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HashResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HashResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + m.Hash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Hash |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SnapshotRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SnapshotRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF } return nil } @@ -10511,7 +12228,24 @@ func (m *WatchCreateRequest) Unmarshal(dAtA []byte) error { } m.ProgressNotify = bool(v != 0) case 5: - if wireType == 2 { + if wireType == 0 { + var v WatchCreateRequest_FilterType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (WatchCreateRequest_FilterType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Filters = append(m.Filters, v) + } else if wireType == 2 { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { @@ -10552,23 +12286,6 @@ func (m *WatchCreateRequest) Unmarshal(dAtA []byte) error { } m.Filters = append(m.Filters, v) } - } else if wireType == 0 { - var v WatchCreateRequest_FilterType - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (WatchCreateRequest_FilterType(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Filters = append(m.Filters, v) } else { return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) } @@ -10926,32 +12643,251 @@ func (m *LeaseGrantRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseGrantRequest: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseGrantRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) + } + m.TTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TTL |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LeaseGrantResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseGrantResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) + } + m.TTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TTL |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LeaseRevokeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseRevokeRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) - } - m.TTL = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TTL |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) } @@ -10991,7 +12927,7 @@ func (m *LeaseGrantRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *LeaseGrantResponse) Unmarshal(dAtA []byte) error { +func (m *LeaseRevokeResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11014,10 +12950,10 @@ func (m *LeaseGrantResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseGrantResponse: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseRevokeResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11053,73 +12989,6 @@ func (m *LeaseGrantResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) - } - m.ID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ID |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) - } - m.TTL = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TTL |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthRpc - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Error = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -11141,7 +13010,7 @@ func (m *LeaseGrantResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *LeaseRevokeRequest) Unmarshal(dAtA []byte) error { +func (m *LeaseKeepAliveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11164,10 +13033,10 @@ func (m *LeaseRevokeRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseRevokeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseKeepAliveRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseKeepAliveRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11210,7 +13079,7 @@ func (m *LeaseRevokeRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *LeaseRevokeResponse) Unmarshal(dAtA []byte) error { +func (m *LeaseKeepAliveResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11233,10 +13102,10 @@ func (m *LeaseRevokeResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseRevokeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseKeepAliveResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseKeepAliveResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11272,6 +13141,44 @@ func (m *LeaseRevokeResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) + } + m.TTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TTL |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -11293,7 +13200,7 @@ func (m *LeaseRevokeResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *LeaseKeepAliveRequest) Unmarshal(dAtA []byte) error { +func (m *LeaseTimeToLiveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11316,10 +13223,10 @@ func (m *LeaseKeepAliveRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseKeepAliveRequest: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseTimeToLiveRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseKeepAliveRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseTimeToLiveRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11341,6 +13248,26 @@ func (m *LeaseKeepAliveRequest) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Keys = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -11362,7 +13289,7 @@ func (m *LeaseKeepAliveRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *LeaseKeepAliveResponse) Unmarshal(dAtA []byte) error { +func (m *LeaseTimeToLiveResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11385,10 +13312,10 @@ func (m *LeaseKeepAliveResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseKeepAliveResponse: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseTimeToLiveResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseKeepAliveResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseTimeToLiveResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11462,6 +13389,104 @@ func (m *LeaseKeepAliveResponse) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GrantedTTL", wireType) + } + m.GrantedTTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GrantedTTL |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, make([]byte, postIndex-iNdEx)) + copy(m.Keys[len(m.Keys)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LeaseLeasesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseLeasesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseLeasesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -11483,7 +13508,7 @@ func (m *LeaseKeepAliveResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *LeaseTimeToLiveRequest) Unmarshal(dAtA []byte) error { +func (m *LeaseStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11506,10 +13531,10 @@ func (m *LeaseTimeToLiveRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseTimeToLiveRequest: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseTimeToLiveRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11531,26 +13556,6 @@ func (m *LeaseTimeToLiveRequest) Unmarshal(dAtA []byte) error { break } } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Keys = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -11572,7 +13577,7 @@ func (m *LeaseTimeToLiveRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *LeaseTimeToLiveResponse) Unmarshal(dAtA []byte) error { +func (m *LeaseLeasesResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11595,10 +13600,10 @@ func (m *LeaseTimeToLiveResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseTimeToLiveResponse: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseLeasesResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseTimeToLiveResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseLeasesResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11635,67 +13640,10 @@ func (m *LeaseTimeToLiveResponse) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) - } - m.ID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ID |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) - } - m.TTL = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TTL |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field GrantedTTL", wireType) - } - m.GrantedTTL = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.GrantedTTL |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Leases", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowRpc @@ -11705,20 +13653,22 @@ func (m *LeaseTimeToLiveResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= (int(b) & 0x7F) << shift + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthRpc } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex > l { return io.ErrUnexpectedEOF } - m.Keys = append(m.Keys, make([]byte, postIndex-iNdEx)) - copy(m.Keys[len(m.Keys)-1], dAtA[iNdEx:postIndex]) + m.Leases = append(m.Leases, &LeaseStatus{}) + if err := m.Leases[len(m.Leases)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -12815,6 +14765,158 @@ func (m *DefragmentResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MoveLeaderRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MoveLeaderRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MoveLeaderRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetID", wireType) + } + m.TargetID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TargetID |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MoveLeaderResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MoveLeaderResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MoveLeaderResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *AlarmRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -16329,221 +18431,235 @@ var ( func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 3450 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3b, 0x5b, 0x6f, 0x1b, 0xc7, - 0xb9, 0x5a, 0x5e, 0xc5, 0x8f, 0x17, 0xd1, 0x23, 0xd9, 0xa6, 0x68, 0x5b, 0x96, 0xc7, 0x37, 0xd9, - 0x4e, 0xa4, 0x44, 0xc9, 0x39, 0x0f, 0x3e, 0x41, 0x70, 0x64, 0x89, 0xb1, 0x74, 0x24, 0x4b, 0xce, - 0x4a, 0x76, 0x72, 0x80, 0xa0, 0xc4, 0x8a, 0x1c, 0x53, 0x0b, 0x91, 0xbb, 0xcc, 0xee, 0x92, 0x96, - 0xd2, 0x14, 0x28, 0xd2, 0x04, 0x45, 0x0b, 0xf4, 0xa5, 0x79, 0xe8, 0xed, 0xb1, 0x28, 0x8a, 0xfc, - 0x80, 0xbe, 0xf5, 0x07, 0x14, 0x7d, 0x69, 0x81, 0xfe, 0x81, 0x22, 0xed, 0x63, 0xdf, 0xfb, 0x54, - 0xb4, 0x98, 0xdb, 0xee, 0xec, 0x72, 0x97, 0x52, 0xca, 0x26, 0x2f, 0xd6, 0xce, 0x37, 0xdf, 0x7c, - 0xb7, 0x99, 0xef, 0x32, 0xdf, 0xd0, 0x50, 0x70, 0xfa, 0xad, 0xe5, 0xbe, 0x63, 0x7b, 0x36, 0x2a, - 0x11, 0xaf, 0xd5, 0x76, 0x89, 0x33, 0x24, 0x4e, 0xff, 0xb0, 0x3e, 0xd7, 0xb1, 0x3b, 0x36, 0x9b, - 0x58, 0xa1, 0x5f, 0x1c, 0xa7, 0x3e, 0x4f, 0x71, 0x56, 0x7a, 0xc3, 0x56, 0x8b, 0xfd, 0xd3, 0x3f, - 0x5c, 0x39, 0x1e, 0x8a, 0xa9, 0x2b, 0x6c, 0xca, 0x18, 0x78, 0x47, 0xec, 0x9f, 0xfe, 0x21, 0xfb, - 0x23, 0x26, 0xaf, 0x76, 0x6c, 0xbb, 0xd3, 0x25, 0x2b, 0x46, 0xdf, 0x5c, 0x31, 0x2c, 0xcb, 0xf6, - 0x0c, 0xcf, 0xb4, 0x2d, 0x97, 0xcf, 0xe2, 0xcf, 0x34, 0xa8, 0xe8, 0xc4, 0xed, 0xdb, 0x96, 0x4b, - 0x36, 0x89, 0xd1, 0x26, 0x0e, 0xba, 0x06, 0xd0, 0xea, 0x0e, 0x5c, 0x8f, 0x38, 0x4d, 0xb3, 0x5d, - 0xd3, 0x16, 0xb5, 0xa5, 0x8c, 0x5e, 0x10, 0x90, 0xad, 0x36, 0xba, 0x02, 0x85, 0x1e, 0xe9, 0x1d, - 0xf2, 0xd9, 0x14, 0x9b, 0x9d, 0xe6, 0x80, 0xad, 0x36, 0xaa, 0xc3, 0xb4, 0x43, 0x86, 0xa6, 0x6b, - 0xda, 0x56, 0x2d, 0xbd, 0xa8, 0x2d, 0xa5, 0x75, 0x7f, 0x4c, 0x17, 0x3a, 0xc6, 0x0b, 0xaf, 0xe9, - 0x11, 0xa7, 0x57, 0xcb, 0xf0, 0x85, 0x14, 0x70, 0x40, 0x9c, 0x1e, 0xfe, 0x34, 0x0b, 0x25, 0xdd, - 0xb0, 0x3a, 0x44, 0x27, 0x1f, 0x0e, 0x88, 0xeb, 0xa1, 0x2a, 0xa4, 0x8f, 0xc9, 0x29, 0x63, 0x5f, - 0xd2, 0xe9, 0x27, 0x5f, 0x6f, 0x75, 0x48, 0x93, 0x58, 0x9c, 0x71, 0x89, 0xae, 0xb7, 0x3a, 0xa4, - 0x61, 0xb5, 0xd1, 0x1c, 0x64, 0xbb, 0x66, 0xcf, 0xf4, 0x04, 0x57, 0x3e, 0x08, 0x89, 0x93, 0x89, - 0x88, 0xb3, 0x0e, 0xe0, 0xda, 0x8e, 0xd7, 0xb4, 0x9d, 0x36, 0x71, 0x6a, 0xd9, 0x45, 0x6d, 0xa9, - 0xb2, 0x7a, 0x6b, 0x59, 0xdd, 0x88, 0x65, 0x55, 0xa0, 0xe5, 0x7d, 0xdb, 0xf1, 0xf6, 0x28, 0xae, - 0x5e, 0x70, 0xe5, 0x27, 0x7a, 0x07, 0x8a, 0x8c, 0x88, 0x67, 0x38, 0x1d, 0xe2, 0xd5, 0x72, 0x8c, - 0xca, 0xed, 0x33, 0xa8, 0x1c, 0x30, 0x64, 0x9d, 0xb1, 0xe7, 0xdf, 0x08, 0x43, 0xc9, 0x25, 0x8e, - 0x69, 0x74, 0xcd, 0x8f, 0x8c, 0xc3, 0x2e, 0xa9, 0xe5, 0x17, 0xb5, 0xa5, 0x69, 0x3d, 0x04, 0xa3, - 0xfa, 0x1f, 0x93, 0x53, 0xb7, 0x69, 0x5b, 0xdd, 0xd3, 0xda, 0x34, 0x43, 0x98, 0xa6, 0x80, 0x3d, - 0xab, 0x7b, 0xca, 0x36, 0xcd, 0x1e, 0x58, 0x1e, 0x9f, 0x2d, 0xb0, 0xd9, 0x02, 0x83, 0xb0, 0xe9, - 0x25, 0xa8, 0xf6, 0x4c, 0xab, 0xd9, 0xb3, 0xdb, 0x4d, 0xdf, 0x20, 0xc0, 0x0c, 0x52, 0xe9, 0x99, - 0xd6, 0x13, 0xbb, 0xad, 0x4b, 0xb3, 0x50, 0x4c, 0xe3, 0x24, 0x8c, 0x59, 0x14, 0x98, 0xc6, 0x89, - 0x8a, 0xb9, 0x0c, 0xb3, 0x94, 0x66, 0xcb, 0x21, 0x86, 0x47, 0x02, 0xe4, 0x12, 0x43, 0xbe, 0xd0, - 0x33, 0xad, 0x75, 0x36, 0x13, 0xc2, 0x37, 0x4e, 0x46, 0xf0, 0xcb, 0x02, 0xdf, 0x38, 0x09, 0xe3, - 0xe3, 0x65, 0x28, 0xf8, 0x36, 0x47, 0xd3, 0x90, 0xd9, 0xdd, 0xdb, 0x6d, 0x54, 0xa7, 0x10, 0x40, - 0x6e, 0x6d, 0x7f, 0xbd, 0xb1, 0xbb, 0x51, 0xd5, 0x50, 0x11, 0xf2, 0x1b, 0x0d, 0x3e, 0x48, 0xe1, - 0x47, 0x00, 0x81, 0x75, 0x51, 0x1e, 0xd2, 0xdb, 0x8d, 0xff, 0xaf, 0x4e, 0x51, 0x9c, 0xe7, 0x0d, - 0x7d, 0x7f, 0x6b, 0x6f, 0xb7, 0xaa, 0xd1, 0xc5, 0xeb, 0x7a, 0x63, 0xed, 0xa0, 0x51, 0x4d, 0x51, - 0x8c, 0x27, 0x7b, 0x1b, 0xd5, 0x34, 0x2a, 0x40, 0xf6, 0xf9, 0xda, 0xce, 0xb3, 0x46, 0x35, 0x83, - 0x3f, 0xd7, 0xa0, 0x2c, 0xf6, 0x8b, 0xfb, 0x04, 0x7a, 0x13, 0x72, 0x47, 0xcc, 0x2f, 0xd8, 0x51, - 0x2c, 0xae, 0x5e, 0x8d, 0x6c, 0x6e, 0xc8, 0x77, 0x74, 0x81, 0x8b, 0x30, 0xa4, 0x8f, 0x87, 0x6e, - 0x2d, 0xb5, 0x98, 0x5e, 0x2a, 0xae, 0x56, 0x97, 0xb9, 0xc3, 0x2e, 0x6f, 0x93, 0xd3, 0xe7, 0x46, - 0x77, 0x40, 0x74, 0x3a, 0x89, 0x10, 0x64, 0x7a, 0xb6, 0x43, 0xd8, 0x89, 0x9d, 0xd6, 0xd9, 0x37, - 0x3d, 0xc6, 0x6c, 0xd3, 0xc4, 0x69, 0xe5, 0x03, 0xfc, 0x85, 0x06, 0xf0, 0x74, 0xe0, 0x25, 0xbb, - 0xc6, 0x1c, 0x64, 0x87, 0x94, 0xb0, 0x70, 0x0b, 0x3e, 0x60, 0x3e, 0x41, 0x0c, 0x97, 0xf8, 0x3e, - 0x41, 0x07, 0xe8, 0x32, 0xe4, 0xfb, 0x0e, 0x19, 0x36, 0x8f, 0x87, 0x8c, 0xc9, 0xb4, 0x9e, 0xa3, - 0xc3, 0xed, 0x21, 0xba, 0x01, 0x25, 0xb3, 0x63, 0xd9, 0x0e, 0x69, 0x72, 0x5a, 0x59, 0x36, 0x5b, - 0xe4, 0x30, 0x26, 0xb7, 0x82, 0xc2, 0x09, 0xe7, 0x54, 0x94, 0x1d, 0x0a, 0xc2, 0x16, 0x14, 0x99, - 0xa8, 0x13, 0x99, 0xef, 0x5e, 0x20, 0x63, 0x8a, 0x2d, 0x1b, 0x35, 0xa1, 0x90, 0x1a, 0x7f, 0x00, - 0x68, 0x83, 0x74, 0x89, 0x47, 0x26, 0x89, 0x1e, 0x8a, 0x4d, 0xd2, 0xaa, 0x4d, 0xf0, 0x8f, 0x35, - 0x98, 0x0d, 0x91, 0x9f, 0x48, 0xad, 0x1a, 0xe4, 0xdb, 0x8c, 0x18, 0x97, 0x20, 0xad, 0xcb, 0x21, - 0x7a, 0x00, 0xd3, 0x42, 0x00, 0xb7, 0x96, 0x4e, 0x38, 0x34, 0x79, 0x2e, 0x93, 0x8b, 0xff, 0xa6, - 0x41, 0x41, 0x28, 0xba, 0xd7, 0x47, 0x6b, 0x50, 0x76, 0xf8, 0xa0, 0xc9, 0xf4, 0x11, 0x12, 0xd5, - 0x93, 0x83, 0xd0, 0xe6, 0x94, 0x5e, 0x12, 0x4b, 0x18, 0x18, 0xfd, 0x0f, 0x14, 0x25, 0x89, 0xfe, - 0xc0, 0x13, 0x26, 0xaf, 0x85, 0x09, 0x04, 0xe7, 0x6f, 0x73, 0x4a, 0x07, 0x81, 0xfe, 0x74, 0xe0, - 0xa1, 0x03, 0x98, 0x93, 0x8b, 0xb9, 0x36, 0x42, 0x8c, 0x34, 0xa3, 0xb2, 0x18, 0xa6, 0x32, 0xba, - 0x55, 0x9b, 0x53, 0x3a, 0x12, 0xeb, 0x95, 0xc9, 0x47, 0x05, 0xc8, 0x0b, 0x28, 0xfe, 0xbb, 0x06, - 0x20, 0x0d, 0xba, 0xd7, 0x47, 0x1b, 0x50, 0x71, 0xc4, 0x28, 0xa4, 0xf0, 0x95, 0x58, 0x85, 0xc5, - 0x3e, 0x4c, 0xe9, 0x65, 0xb9, 0x88, 0xab, 0xfc, 0x36, 0x94, 0x7c, 0x2a, 0x81, 0xce, 0xf3, 0x31, - 0x3a, 0xfb, 0x14, 0x8a, 0x72, 0x01, 0xd5, 0xfa, 0x3d, 0xb8, 0xe8, 0xaf, 0x8f, 0x51, 0xfb, 0xc6, - 0x18, 0xb5, 0x7d, 0x82, 0xb3, 0x92, 0x82, 0xaa, 0x38, 0xd0, 0x94, 0xc5, 0xc1, 0xf8, 0x8b, 0x34, - 0xe4, 0xd7, 0xed, 0x5e, 0xdf, 0x70, 0xe8, 0x1e, 0xe5, 0x1c, 0xe2, 0x0e, 0xba, 0x1e, 0x53, 0xb7, - 0xb2, 0x7a, 0x33, 0xcc, 0x41, 0xa0, 0xc9, 0xbf, 0x3a, 0x43, 0xd5, 0xc5, 0x12, 0xba, 0x58, 0x64, - 0xa8, 0xd4, 0x39, 0x16, 0x8b, 0xfc, 0x24, 0x96, 0x48, 0x5f, 0x4a, 0x07, 0xbe, 0x54, 0x87, 0xfc, - 0x90, 0x38, 0x41, 0x56, 0xdd, 0x9c, 0xd2, 0x25, 0x00, 0xdd, 0x83, 0x99, 0x68, 0x84, 0xcf, 0x0a, - 0x9c, 0x4a, 0x2b, 0x9c, 0x10, 0x6e, 0x42, 0x29, 0x94, 0x66, 0x72, 0x02, 0xaf, 0xd8, 0x53, 0xb2, - 0xcc, 0x25, 0x19, 0xda, 0x68, 0x4a, 0x2c, 0x6d, 0x4e, 0x89, 0xe0, 0x86, 0xff, 0x17, 0xca, 0x21, - 0x5d, 0x69, 0x14, 0x6f, 0xbc, 0xfb, 0x6c, 0x6d, 0x87, 0x87, 0xfc, 0xc7, 0x2c, 0xca, 0xeb, 0x55, - 0x8d, 0x66, 0x8e, 0x9d, 0xc6, 0xfe, 0x7e, 0x35, 0x85, 0xca, 0x50, 0xd8, 0xdd, 0x3b, 0x68, 0x72, - 0xac, 0x34, 0x7e, 0xcb, 0xa7, 0x20, 0x52, 0x86, 0x92, 0x29, 0xa6, 0x94, 0x4c, 0xa1, 0xc9, 0x4c, - 0x91, 0x0a, 0x32, 0x45, 0xfa, 0x51, 0x05, 0x4a, 0xdc, 0x3e, 0xcd, 0x81, 0x45, 0xb3, 0xd5, 0x2f, - 0x35, 0x80, 0x83, 0x13, 0x4b, 0x06, 0xa0, 0x15, 0xc8, 0xb7, 0x38, 0xf1, 0x9a, 0xc6, 0xfc, 0xf9, - 0x62, 0xac, 0xc9, 0x75, 0x89, 0x85, 0x5e, 0x87, 0xbc, 0x3b, 0x68, 0xb5, 0x88, 0x2b, 0xb3, 0xc6, - 0xe5, 0x68, 0x48, 0x11, 0x0e, 0xaf, 0x4b, 0x3c, 0xba, 0xe4, 0x85, 0x61, 0x76, 0x07, 0x2c, 0x87, - 0x8c, 0x5f, 0x22, 0xf0, 0xf0, 0xcf, 0x34, 0x28, 0x32, 0x29, 0x27, 0x8a, 0x63, 0x57, 0xa1, 0xc0, - 0x64, 0x20, 0x6d, 0x11, 0xc9, 0xa6, 0xf5, 0x00, 0x80, 0xfe, 0x1b, 0x0a, 0xf2, 0x04, 0xcb, 0x60, - 0x56, 0x8b, 0x27, 0xbb, 0xd7, 0xd7, 0x03, 0x54, 0xbc, 0x0d, 0x17, 0x98, 0x55, 0x5a, 0xb4, 0x3e, - 0x95, 0x76, 0x54, 0x2b, 0x38, 0x2d, 0x52, 0xc1, 0xd5, 0x61, 0xba, 0x7f, 0x74, 0xea, 0x9a, 0x2d, - 0xa3, 0x2b, 0xa4, 0xf0, 0xc7, 0xf8, 0xff, 0x00, 0xa9, 0xc4, 0x26, 0x51, 0x17, 0x97, 0xa1, 0xb8, - 0x69, 0xb8, 0x47, 0x42, 0x24, 0xfc, 0x3e, 0x94, 0xf8, 0x70, 0x22, 0x1b, 0x22, 0xc8, 0x1c, 0x19, - 0xee, 0x11, 0x13, 0xbc, 0xac, 0xb3, 0x6f, 0x7c, 0x01, 0x66, 0xf6, 0x2d, 0xa3, 0xef, 0x1e, 0xd9, - 0x32, 0xd6, 0xd2, 0xfa, 0xbc, 0x1a, 0xc0, 0x26, 0xe2, 0x78, 0x17, 0x66, 0x1c, 0xd2, 0x33, 0x4c, - 0xcb, 0xb4, 0x3a, 0xcd, 0xc3, 0x53, 0x8f, 0xb8, 0xa2, 0x7c, 0xaf, 0xf8, 0xe0, 0x47, 0x14, 0x4a, - 0x45, 0x3b, 0xec, 0xda, 0x87, 0xc2, 0xe3, 0xd9, 0x37, 0xfe, 0x8d, 0x06, 0xa5, 0xf7, 0x0c, 0xaf, - 0x25, 0xad, 0x80, 0xb6, 0xa0, 0xe2, 0xfb, 0x39, 0x83, 0x08, 0x59, 0x22, 0x01, 0x9f, 0xad, 0x91, - 0x85, 0x9d, 0x0c, 0xf8, 0xe5, 0x96, 0x0a, 0x60, 0xa4, 0x0c, 0xab, 0x45, 0xba, 0x3e, 0xa9, 0x54, - 0x32, 0x29, 0x86, 0xa8, 0x92, 0x52, 0x01, 0x8f, 0x66, 0x82, 0x64, 0xc8, 0xdd, 0xf2, 0xe7, 0x29, - 0x40, 0xa3, 0x32, 0x7c, 0xd5, 0xfa, 0xe0, 0x36, 0x54, 0x5c, 0xcf, 0x70, 0xbc, 0x66, 0xe4, 0x72, - 0x53, 0x66, 0x50, 0x3f, 0x56, 0xdd, 0x85, 0x99, 0xbe, 0x63, 0x77, 0x1c, 0xe2, 0xba, 0x4d, 0xcb, - 0xf6, 0xcc, 0x17, 0xa7, 0xa2, 0xc4, 0xaa, 0x48, 0xf0, 0x2e, 0x83, 0xa2, 0x06, 0xe4, 0x5f, 0x98, - 0x5d, 0x8f, 0x38, 0x6e, 0x2d, 0xbb, 0x98, 0x5e, 0xaa, 0xac, 0x3e, 0x38, 0xcb, 0x6a, 0xcb, 0xef, - 0x30, 0xfc, 0x83, 0xd3, 0x3e, 0xd1, 0xe5, 0x5a, 0xb5, 0x6c, 0xc9, 0x85, 0xca, 0x96, 0xdb, 0x00, - 0x01, 0x3e, 0x8d, 0x5a, 0xbb, 0x7b, 0x4f, 0x9f, 0x1d, 0x54, 0xa7, 0x50, 0x09, 0xa6, 0x77, 0xf7, - 0x36, 0x1a, 0x3b, 0x0d, 0x1a, 0xd7, 0xf0, 0x8a, 0xb4, 0x8d, 0x6a, 0x43, 0x34, 0x0f, 0xd3, 0x2f, - 0x29, 0x54, 0xde, 0xfe, 0xd2, 0x7a, 0x9e, 0x8d, 0xb7, 0xda, 0xf8, 0x47, 0x29, 0x28, 0x8b, 0x53, - 0x30, 0xd1, 0x51, 0x54, 0x59, 0xa4, 0x42, 0x2c, 0x68, 0x8d, 0xc4, 0x4f, 0x47, 0x5b, 0x94, 0x62, - 0x72, 0x48, 0xdd, 0x9d, 0x6f, 0x36, 0x69, 0x0b, 0xb3, 0xfa, 0x63, 0x74, 0x0f, 0xaa, 0x2d, 0xee, - 0xee, 0x91, 0xb4, 0xa3, 0xcf, 0x08, 0xb8, 0x92, 0x75, 0xca, 0xfe, 0x69, 0x33, 0x5c, 0x91, 0x76, - 0x0a, 0x7a, 0x49, 0x1e, 0x24, 0x0a, 0x43, 0xb7, 0x21, 0x47, 0x86, 0xc4, 0xf2, 0xdc, 0x5a, 0x91, - 0x05, 0xb0, 0xb2, 0xac, 0xc6, 0x1a, 0x14, 0xaa, 0x8b, 0x49, 0xfc, 0x5f, 0x70, 0x81, 0x55, 0xbd, - 0x8f, 0x1d, 0xc3, 0x52, 0xcb, 0xf3, 0x83, 0x83, 0x1d, 0x61, 0x3a, 0xfa, 0x89, 0x2a, 0x90, 0xda, - 0xda, 0x10, 0x8a, 0xa6, 0xb6, 0x36, 0xf0, 0x27, 0x1a, 0x20, 0x75, 0xdd, 0x44, 0xb6, 0x8c, 0x10, - 0x97, 0xec, 0xd3, 0x01, 0xfb, 0x39, 0xc8, 0x12, 0xc7, 0xb1, 0x1d, 0x66, 0xb5, 0x82, 0xce, 0x07, - 0xf8, 0x96, 0x90, 0x41, 0x27, 0x43, 0xfb, 0xd8, 0x77, 0x0c, 0x4e, 0x4d, 0xf3, 0x45, 0xdd, 0x86, - 0xd9, 0x10, 0xd6, 0x44, 0x81, 0xf4, 0x2e, 0x5c, 0x64, 0xc4, 0xb6, 0x09, 0xe9, 0xaf, 0x75, 0xcd, - 0x61, 0x22, 0xd7, 0x3e, 0x5c, 0x8a, 0x22, 0x7e, 0xbd, 0x36, 0xc2, 0x6f, 0x09, 0x8e, 0x07, 0x66, - 0x8f, 0x1c, 0xd8, 0x3b, 0xc9, 0xb2, 0xd1, 0xe8, 0x48, 0x6f, 0xdd, 0x22, 0xe3, 0xb0, 0x6f, 0xfc, - 0x2b, 0x0d, 0x2e, 0x8f, 0x2c, 0xff, 0x9a, 0x77, 0x75, 0x01, 0xa0, 0x43, 0x8f, 0x0f, 0x69, 0xd3, - 0x09, 0x7e, 0x5f, 0x54, 0x20, 0xbe, 0x9c, 0x34, 0xc0, 0x94, 0x84, 0x9c, 0x47, 0x90, 0x7b, 0xc2, - 0x5a, 0x35, 0x8a, 0x56, 0x19, 0xa9, 0x95, 0x65, 0xf4, 0xf8, 0x05, 0xb2, 0xa0, 0xb3, 0x6f, 0x96, - 0x5f, 0x09, 0x71, 0x9e, 0xe9, 0x3b, 0x3c, 0x8f, 0x17, 0x74, 0x7f, 0x4c, 0xb9, 0xb7, 0xba, 0x26, - 0xb1, 0x3c, 0x36, 0x9b, 0x61, 0xb3, 0x0a, 0x04, 0x2f, 0x43, 0x95, 0x73, 0x5a, 0x6b, 0xb7, 0x95, - 0x5c, 0xee, 0xd3, 0xd3, 0xc2, 0xf4, 0xf0, 0xaf, 0x35, 0xb8, 0xa0, 0x2c, 0x98, 0xc8, 0x76, 0xaf, - 0x40, 0x8e, 0x37, 0xa4, 0x44, 0x1e, 0x99, 0x0b, 0xaf, 0xe2, 0x6c, 0x74, 0x81, 0x83, 0x96, 0x21, - 0xcf, 0xbf, 0x64, 0xb1, 0x12, 0x8f, 0x2e, 0x91, 0xf0, 0x6d, 0x98, 0x15, 0x20, 0xd2, 0xb3, 0xe3, - 0x8e, 0x09, 0x33, 0x28, 0xfe, 0x18, 0xe6, 0xc2, 0x68, 0x13, 0xa9, 0xa4, 0x08, 0x99, 0x3a, 0x8f, - 0x90, 0x6b, 0x52, 0xc8, 0x67, 0xfd, 0xb6, 0x92, 0xf6, 0xa2, 0xbb, 0xae, 0xee, 0x48, 0x2a, 0xb2, - 0x23, 0xbe, 0x02, 0x92, 0xc4, 0x37, 0xaa, 0xc0, 0xac, 0x3c, 0x0e, 0x3b, 0xa6, 0xeb, 0x17, 0x43, - 0x1f, 0x01, 0x52, 0x81, 0xdf, 0xb4, 0x40, 0x1b, 0xe4, 0x85, 0x63, 0x74, 0x7a, 0xc4, 0x0f, 0xf5, - 0xb4, 0xca, 0x54, 0x81, 0x13, 0x05, 0xc7, 0x3f, 0x68, 0x50, 0x5a, 0xeb, 0x1a, 0x4e, 0x4f, 0x6e, - 0xd6, 0xdb, 0x90, 0xe3, 0xe5, 0xab, 0xb8, 0xf1, 0xdd, 0x09, 0x93, 0x51, 0x71, 0xf9, 0x60, 0x8d, - 0x17, 0xbb, 0x62, 0x15, 0xdd, 0x5c, 0xd1, 0x97, 0xdd, 0x88, 0xf4, 0x69, 0x37, 0xd0, 0xab, 0x90, - 0x35, 0xe8, 0x12, 0x16, 0x50, 0x2a, 0xd1, 0x8b, 0x03, 0xa3, 0xc6, 0x4a, 0x0d, 0x8e, 0x85, 0xdf, - 0x84, 0xa2, 0xc2, 0x81, 0xde, 0x87, 0x1e, 0x37, 0x44, 0x39, 0xb1, 0xb6, 0x7e, 0xb0, 0xf5, 0x9c, - 0x5f, 0x93, 0x2a, 0x00, 0x1b, 0x0d, 0x7f, 0x9c, 0xc2, 0xef, 0x8b, 0x55, 0x22, 0xe4, 0xa8, 0xf2, - 0x68, 0x49, 0xf2, 0xa4, 0xce, 0x25, 0xcf, 0x09, 0x94, 0x85, 0xfa, 0x13, 0x9d, 0x81, 0xd7, 0x21, - 0xc7, 0xe8, 0xc9, 0x23, 0x30, 0x1f, 0xc3, 0x56, 0x46, 0x0b, 0x8e, 0x88, 0x67, 0xa0, 0xbc, 0xef, - 0x19, 0xde, 0xc0, 0x95, 0x47, 0xe0, 0xf7, 0x1a, 0x54, 0x24, 0x64, 0xd2, 0xe6, 0x90, 0xbc, 0x54, - 0xf3, 0x20, 0xec, 0x5f, 0xa9, 0x2f, 0x41, 0xae, 0x7d, 0xb8, 0x6f, 0x7e, 0x24, 0x1b, 0x79, 0x62, - 0x44, 0xe1, 0x5d, 0xce, 0x87, 0x77, 0xd3, 0xc5, 0x88, 0x5e, 0xcf, 0x1c, 0xe3, 0x85, 0xb7, 0x65, - 0xb5, 0xc9, 0x09, 0xab, 0x82, 0x32, 0x7a, 0x00, 0x60, 0x37, 0x2a, 0xd1, 0x75, 0x67, 0xa5, 0x8f, - 0xda, 0x85, 0x9f, 0x85, 0x0b, 0x6b, 0x03, 0xef, 0xa8, 0x61, 0x19, 0x87, 0x5d, 0x19, 0x34, 0xf0, - 0x1c, 0x20, 0x0a, 0xdc, 0x30, 0x5d, 0x15, 0xda, 0x80, 0x59, 0x0a, 0x25, 0x96, 0x67, 0xb6, 0x94, - 0x08, 0x23, 0xf3, 0x88, 0x16, 0xc9, 0x23, 0x86, 0xeb, 0xbe, 0xb4, 0x9d, 0xb6, 0x50, 0xcd, 0x1f, - 0xe3, 0x0d, 0x4e, 0xfc, 0x99, 0x1b, 0xca, 0x14, 0x5f, 0x95, 0xca, 0x52, 0x40, 0xe5, 0x31, 0xf1, - 0xc6, 0x50, 0xc1, 0x0f, 0xe0, 0xa2, 0xc4, 0x14, 0x5d, 0x97, 0x31, 0xc8, 0x7b, 0x70, 0x4d, 0x22, - 0xaf, 0x1f, 0xd1, 0xbb, 0xc0, 0x53, 0xc1, 0xf0, 0xdf, 0x95, 0xf3, 0x11, 0xd4, 0x7c, 0x39, 0x59, - 0xe9, 0x67, 0x77, 0x55, 0x01, 0x06, 0xae, 0x38, 0x33, 0x05, 0x9d, 0x7d, 0x53, 0x98, 0x63, 0x77, - 0xfd, 0xac, 0x4c, 0xbf, 0xf1, 0x3a, 0xcc, 0x4b, 0x1a, 0xa2, 0x28, 0x0b, 0x13, 0x19, 0x11, 0x28, - 0x8e, 0x88, 0x30, 0x18, 0x5d, 0x3a, 0xde, 0xec, 0x2a, 0x66, 0xd8, 0xb4, 0x8c, 0xa6, 0xa6, 0xd0, - 0xbc, 0xc8, 0x4f, 0x04, 0x15, 0x4c, 0x0d, 0xda, 0x02, 0x4c, 0x09, 0xa8, 0x60, 0xb1, 0x11, 0x14, - 0x3c, 0xb2, 0x11, 0x23, 0xa4, 0x3f, 0x80, 0x05, 0x5f, 0x08, 0x6a, 0xb7, 0xa7, 0xc4, 0xe9, 0x99, - 0xae, 0xab, 0xf4, 0x09, 0xe2, 0x14, 0xbf, 0x03, 0x99, 0x3e, 0x11, 0x31, 0xa5, 0xb8, 0x8a, 0x96, - 0xf9, 0xdb, 0xd8, 0xb2, 0xb2, 0x98, 0xcd, 0xe3, 0x36, 0x5c, 0x97, 0xd4, 0xb9, 0x45, 0x63, 0xc9, - 0x47, 0x85, 0x92, 0x77, 0x48, 0x6e, 0xd6, 0xd1, 0x3b, 0x64, 0x9a, 0xef, 0xbd, 0xbc, 0x43, 0xd2, - 0x5c, 0xa1, 0xfa, 0xd6, 0x44, 0xb9, 0x62, 0x9b, 0xdb, 0xd4, 0x77, 0xc9, 0x89, 0x88, 0x1d, 0xc2, - 0x5c, 0xd8, 0x93, 0x27, 0x0a, 0x63, 0x73, 0x90, 0xf5, 0xec, 0x63, 0x22, 0x83, 0x18, 0x1f, 0x48, - 0x81, 0x7d, 0x37, 0x9f, 0x48, 0x60, 0x23, 0x20, 0xc6, 0x8e, 0xe4, 0xa4, 0xf2, 0xd2, 0xdd, 0x94, - 0xf5, 0x0f, 0x1f, 0xe0, 0x5d, 0xb8, 0x14, 0x0d, 0x13, 0x13, 0x89, 0xfc, 0x9c, 0x1f, 0xe0, 0xb8, - 0x48, 0x32, 0x11, 0xdd, 0x77, 0x83, 0x60, 0xa0, 0x04, 0x94, 0x89, 0x48, 0xea, 0x50, 0x8f, 0x8b, - 0x2f, 0xff, 0x89, 0xf3, 0xea, 0x87, 0x9b, 0x89, 0x88, 0xb9, 0x01, 0xb1, 0xc9, 0xb7, 0x3f, 0x88, - 0x11, 0xe9, 0xb1, 0x31, 0x42, 0x38, 0x49, 0x10, 0xc5, 0xbe, 0x86, 0x43, 0x27, 0x78, 0x04, 0x01, - 0x74, 0x52, 0x1e, 0x34, 0x87, 0xf8, 0x3c, 0xd8, 0x40, 0x1e, 0x6c, 0x35, 0xec, 0x4e, 0xb4, 0x19, - 0xef, 0x05, 0xb1, 0x73, 0x24, 0x32, 0x4f, 0x44, 0xf8, 0x7d, 0x58, 0x4c, 0x0e, 0xca, 0x93, 0x50, - 0xbe, 0x8f, 0xa1, 0xe0, 0x17, 0x94, 0xca, 0xbb, 0x72, 0x11, 0xf2, 0xbb, 0x7b, 0xfb, 0x4f, 0xd7, - 0xd6, 0x1b, 0x55, 0x6d, 0xf5, 0x1f, 0x69, 0x48, 0x6d, 0x3f, 0x47, 0xdf, 0x82, 0x2c, 0x7f, 0x2e, - 0x1a, 0xf3, 0x9a, 0x56, 0x1f, 0xf7, 0xf0, 0x84, 0xaf, 0x7e, 0xf2, 0xa7, 0xbf, 0x7e, 0x9e, 0xba, - 0x84, 0x2f, 0xac, 0x0c, 0xdf, 0x30, 0xba, 0xfd, 0x23, 0x63, 0xe5, 0x78, 0xb8, 0xc2, 0x72, 0xc2, - 0x43, 0xed, 0x3e, 0x7a, 0x0e, 0xe9, 0xa7, 0x03, 0x0f, 0x25, 0x3e, 0xb5, 0xd5, 0x93, 0x1f, 0xa4, - 0x70, 0x9d, 0x51, 0x9e, 0xc3, 0x33, 0x2a, 0xe5, 0xfe, 0xc0, 0xa3, 0x74, 0x87, 0x50, 0x54, 0xde, - 0x94, 0xd0, 0x99, 0x8f, 0x70, 0xf5, 0xb3, 0xdf, 0xab, 0x30, 0x66, 0xfc, 0xae, 0xe2, 0xcb, 0x2a, - 0x3f, 0xfe, 0xf4, 0xa5, 0xea, 0x73, 0x70, 0x62, 0x45, 0xf5, 0x09, 0x9e, 0x45, 0xa2, 0xfa, 0x28, - 0x4f, 0x11, 0xf1, 0xfa, 0x78, 0x27, 0x16, 0xa5, 0x6b, 0x8b, 0x77, 0xb0, 0x96, 0x87, 0xae, 0xc7, - 0xbc, 0xa3, 0xa8, 0x2f, 0x06, 0xf5, 0xc5, 0x64, 0x04, 0xc1, 0xe9, 0x06, 0xe3, 0x74, 0x05, 0x5f, - 0x52, 0x39, 0xb5, 0x7c, 0xbc, 0x87, 0xda, 0xfd, 0xd5, 0x23, 0xc8, 0xb2, 0x3e, 0x27, 0x6a, 0xca, - 0x8f, 0x7a, 0x4c, 0x87, 0x36, 0xe1, 0x04, 0x84, 0x3a, 0xa4, 0x78, 0x9e, 0x71, 0x9b, 0xc5, 0x15, - 0x9f, 0x1b, 0x6b, 0x75, 0x3e, 0xd4, 0xee, 0x2f, 0x69, 0xaf, 0x69, 0xab, 0xdf, 0xcb, 0x40, 0x96, - 0xb5, 0x8e, 0x50, 0x1f, 0x20, 0x68, 0x0a, 0x46, 0xf5, 0x1c, 0x69, 0x33, 0x46, 0xf5, 0x1c, 0xed, - 0x27, 0xe2, 0xeb, 0x8c, 0xf3, 0x3c, 0x9e, 0xf3, 0x39, 0xb3, 0x57, 0xfb, 0x15, 0xd6, 0x24, 0xa2, - 0x66, 0x7d, 0x09, 0x45, 0xa5, 0xb9, 0x87, 0xe2, 0x28, 0x86, 0xba, 0x83, 0xd1, 0x63, 0x12, 0xd3, - 0x19, 0xc4, 0x37, 0x19, 0xd3, 0x6b, 0xb8, 0xa6, 0x1a, 0x97, 0xf3, 0x75, 0x18, 0x26, 0x65, 0xfc, - 0xa9, 0x06, 0x95, 0x70, 0x83, 0x0f, 0xdd, 0x8c, 0x21, 0x1d, 0xed, 0x13, 0xd6, 0x6f, 0x8d, 0x47, - 0x4a, 0x14, 0x81, 0xf3, 0x3f, 0x26, 0xa4, 0x6f, 0x50, 0x4c, 0x61, 0x7b, 0xf4, 0x7d, 0x0d, 0x66, - 0x22, 0x6d, 0x3b, 0x14, 0xc7, 0x62, 0xa4, 0x29, 0x58, 0xbf, 0x7d, 0x06, 0x96, 0x90, 0xe4, 0x2e, - 0x93, 0xe4, 0x06, 0xbe, 0x3a, 0x6a, 0x0c, 0xcf, 0xec, 0x11, 0xcf, 0x16, 0xd2, 0xac, 0xfe, 0x33, - 0x0d, 0xf9, 0x75, 0xfe, 0x13, 0x2b, 0xe4, 0x41, 0xc1, 0xef, 0x84, 0xa1, 0x85, 0xb8, 0xae, 0x44, - 0x50, 0xb2, 0xd7, 0xaf, 0x27, 0xce, 0x0b, 0x11, 0xee, 0x30, 0x11, 0x16, 0xf1, 0x15, 0x5f, 0x04, - 0xf1, 0x53, 0xae, 0x15, 0x7e, 0xf9, 0x5e, 0x31, 0xda, 0x6d, 0xba, 0x25, 0xdf, 0xd5, 0xa0, 0xa4, - 0x36, 0xac, 0xd0, 0x8d, 0xd8, 0x7e, 0x88, 0xda, 0xf3, 0xaa, 0xe3, 0x71, 0x28, 0x82, 0xff, 0x3d, - 0xc6, 0xff, 0x26, 0x5e, 0x48, 0xe2, 0xef, 0x30, 0xfc, 0xb0, 0x08, 0xbc, 0xe5, 0x14, 0x2f, 0x42, - 0xa8, 0xa3, 0x15, 0x2f, 0x42, 0xb8, 0x63, 0x75, 0xb6, 0x08, 0x03, 0x86, 0x4f, 0x45, 0x38, 0x01, - 0x08, 0x3a, 0x4c, 0x28, 0xd6, 0xb8, 0xca, 0x25, 0x26, 0xea, 0x83, 0xa3, 0xcd, 0xa9, 0x98, 0x13, - 0x10, 0xe1, 0xdd, 0x35, 0x5d, 0xea, 0x8b, 0xab, 0xbf, 0xcd, 0x40, 0xf1, 0x89, 0x61, 0x5a, 0x1e, - 0xb1, 0x0c, 0xab, 0x45, 0x50, 0x07, 0xb2, 0x2c, 0x4b, 0x45, 0x03, 0x8f, 0xda, 0xf6, 0x89, 0x06, - 0x9e, 0x50, 0x4f, 0x04, 0xdf, 0x66, 0xac, 0xaf, 0xe3, 0xba, 0xcf, 0xba, 0x17, 0xd0, 0x5f, 0x61, - 0xfd, 0x0c, 0xaa, 0xf2, 0x31, 0xe4, 0x78, 0xff, 0x02, 0x45, 0xa8, 0x85, 0xfa, 0x1c, 0xf5, 0xab, - 0xf1, 0x93, 0x89, 0xa7, 0x4c, 0xe5, 0xe5, 0x32, 0x64, 0xca, 0xec, 0xdb, 0x00, 0x41, 0xc3, 0x2c, - 0x6a, 0xdf, 0x91, 0xfe, 0x5a, 0x7d, 0x31, 0x19, 0x41, 0x30, 0xbe, 0xcf, 0x18, 0xdf, 0xc2, 0xd7, - 0x63, 0x19, 0xb7, 0xfd, 0x05, 0x94, 0x79, 0x0b, 0x32, 0x9b, 0x86, 0x7b, 0x84, 0x22, 0x49, 0x48, - 0x79, 0xdb, 0xad, 0xd7, 0xe3, 0xa6, 0x04, 0xab, 0x5b, 0x8c, 0xd5, 0x02, 0x9e, 0x8f, 0x65, 0x75, - 0x64, 0xb8, 0x34, 0xa6, 0xa3, 0x01, 0x4c, 0xcb, 0xf7, 0x5a, 0x74, 0x2d, 0x62, 0xb3, 0xf0, 0xdb, - 0x6e, 0x7d, 0x21, 0x69, 0x5a, 0x30, 0x5c, 0x62, 0x0c, 0x31, 0xbe, 0x16, 0x6f, 0x54, 0x81, 0xfe, - 0x50, 0xbb, 0xff, 0x9a, 0xb6, 0xfa, 0xc3, 0x2a, 0x64, 0x68, 0xbd, 0x44, 0xb3, 0x48, 0x70, 0xcd, - 0x8c, 0x5a, 0x78, 0xa4, 0xb9, 0x13, 0xb5, 0xf0, 0xe8, 0x0d, 0x35, 0x26, 0x8b, 0xb0, 0x1f, 0x9a, - 0x12, 0x86, 0x45, 0x35, 0xf6, 0xa0, 0xa8, 0x5c, 0x46, 0x51, 0x0c, 0xc5, 0x70, 0xeb, 0x28, 0x9a, - 0x45, 0x62, 0x6e, 0xb2, 0x78, 0x91, 0x31, 0xad, 0xe3, 0x8b, 0x61, 0xa6, 0x6d, 0x8e, 0x46, 0xb9, - 0x7e, 0x0c, 0x25, 0xf5, 0xd6, 0x8a, 0x62, 0x88, 0x46, 0x7a, 0x53, 0xd1, 0x58, 0x11, 0x77, 0xe9, - 0x8d, 0x71, 0x1a, 0xff, 0x67, 0xb5, 0x12, 0x97, 0x72, 0xff, 0x10, 0xf2, 0xe2, 0x2e, 0x1b, 0xa7, - 0x6f, 0xb8, 0x9b, 0x15, 0xa7, 0x6f, 0xe4, 0x22, 0x1c, 0x53, 0x92, 0x30, 0xb6, 0xb4, 0x66, 0x97, - 0x01, 0x5a, 0xb0, 0x7c, 0x4c, 0xbc, 0x24, 0x96, 0x41, 0x7f, 0x26, 0x89, 0xa5, 0x72, 0x5f, 0x1a, - 0xcb, 0xb2, 0x43, 0x3c, 0x71, 0x96, 0xe5, 0x65, 0x04, 0x25, 0x50, 0x54, 0xa3, 0x21, 0x1e, 0x87, - 0x92, 0x58, 0x45, 0x06, 0x5c, 0x45, 0x28, 0x44, 0xdf, 0x01, 0x08, 0x2e, 0xde, 0xd1, 0xc2, 0x20, - 0xb6, 0x7b, 0x17, 0x2d, 0x0c, 0xe2, 0xef, 0xee, 0x31, 0x1e, 0x1c, 0x30, 0xe7, 0x95, 0x2c, 0x65, - 0xff, 0x13, 0x0d, 0xd0, 0xe8, 0x45, 0x1d, 0x3d, 0x88, 0x67, 0x11, 0xdb, 0x18, 0xac, 0xbf, 0x72, - 0x3e, 0xe4, 0xc4, 0xe8, 0x19, 0xc8, 0xd5, 0x62, 0x4b, 0xfa, 0x2f, 0xa9, 0x64, 0x9f, 0x69, 0x50, - 0x0e, 0x5d, 0xf5, 0xd1, 0x9d, 0x84, 0x7d, 0x8e, 0x34, 0x17, 0xeb, 0x77, 0xcf, 0xc4, 0x4b, 0xac, - 0x9d, 0x94, 0x53, 0x21, 0xeb, 0xc6, 0x1f, 0x68, 0x50, 0x09, 0xf7, 0x07, 0x50, 0x02, 0x83, 0x91, - 0x0e, 0x65, 0x7d, 0xe9, 0x6c, 0xc4, 0x73, 0xec, 0x56, 0x50, 0x4a, 0x7e, 0x08, 0x79, 0xd1, 0x56, - 0x88, 0x73, 0x8b, 0x70, 0x83, 0x33, 0xce, 0x2d, 0x22, 0x3d, 0x89, 0x24, 0xb7, 0xa0, 0x37, 0x74, - 0xc5, 0x13, 0x45, 0xf3, 0x21, 0x89, 0xe5, 0x78, 0x4f, 0x8c, 0x74, 0x2e, 0xc6, 0xb2, 0x0c, 0x3c, - 0x51, 0xb6, 0x1e, 0x50, 0x02, 0xc5, 0x33, 0x3c, 0x31, 0xda, 0xb9, 0x48, 0xf2, 0x44, 0xc6, 0x55, - 0xf1, 0xc4, 0xa0, 0x53, 0x10, 0xe7, 0x89, 0x23, 0xed, 0xdb, 0x38, 0x4f, 0x1c, 0x6d, 0x36, 0x24, - 0xed, 0x2d, 0x63, 0x1e, 0xf2, 0xc4, 0xd9, 0x98, 0xce, 0x02, 0x7a, 0x25, 0xc1, 0xa6, 0xb1, 0xad, - 0xe1, 0xfa, 0xab, 0xe7, 0xc4, 0x1e, 0xef, 0x01, 0x7c, 0x37, 0xa4, 0x07, 0xfc, 0x42, 0x83, 0xb9, - 0xb8, 0xd6, 0x04, 0x4a, 0x60, 0x96, 0xd0, 0x57, 0xae, 0x2f, 0x9f, 0x17, 0xfd, 0x1c, 0x76, 0xf3, - 0x7d, 0xe2, 0x51, 0xf5, 0x77, 0x5f, 0x2e, 0x68, 0x7f, 0xfc, 0x72, 0x41, 0xfb, 0xf3, 0x97, 0x0b, - 0xda, 0x4f, 0xff, 0xb2, 0x30, 0x75, 0x98, 0x63, 0xff, 0xdb, 0xe3, 0x8d, 0x7f, 0x05, 0x00, 0x00, - 0xff, 0xff, 0x63, 0x1c, 0x78, 0x24, 0x74, 0x32, 0x00, 0x00, + // 3669 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5b, 0x5b, 0x6f, 0x23, 0xc7, + 0x72, 0xd6, 0x90, 0x22, 0x29, 0x16, 0x2f, 0xe2, 0xb6, 0xb4, 0xbb, 0x14, 0x77, 0x57, 0xab, 0xed, + 0xbd, 0x69, 0x2f, 0x16, 0x6d, 0xd9, 0xc9, 0xc3, 0x26, 0x30, 0xac, 0x95, 0xe8, 0x95, 0x2c, 0xad, + 0x24, 0x8f, 0xa8, 0xb5, 0x03, 0x38, 0x11, 0x46, 0x64, 0x4b, 0x62, 0x44, 0xce, 0x30, 0x33, 0x43, + 0xae, 0xb4, 0x31, 0x12, 0xc0, 0x71, 0x82, 0xbc, 0xe4, 0x25, 0x06, 0x82, 0xc4, 0xaf, 0x41, 0x60, + 0xf8, 0x07, 0x04, 0xf9, 0x0b, 0x41, 0x5e, 0x12, 0x20, 0x7f, 0xe0, 0xc0, 0xe7, 0xbc, 0x9c, 0x5f, + 0x70, 0x2e, 0x4f, 0x07, 0x7d, 0x9b, 0xe9, 0xb9, 0x51, 0xb2, 0x69, 0xfb, 0x45, 0x3b, 0x5d, 0x5d, + 0x5d, 0x55, 0x5d, 0xdd, 0x55, 0xd5, 0xfd, 0x35, 0x17, 0xf2, 0x76, 0xbf, 0xb5, 0xd4, 0xb7, 0x2d, + 0xd7, 0x42, 0x45, 0xe2, 0xb6, 0xda, 0x0e, 0xb1, 0x87, 0xc4, 0xee, 0x1f, 0xd6, 0x66, 0x8f, 0xad, + 0x63, 0x8b, 0x75, 0xd4, 0xe9, 0x17, 0xe7, 0xa9, 0xcd, 0x51, 0x9e, 0x7a, 0x6f, 0xd8, 0x6a, 0xb1, + 0x3f, 0xfd, 0xc3, 0xfa, 0xe9, 0x50, 0x74, 0xdd, 0x60, 0x5d, 0xc6, 0xc0, 0x3d, 0x61, 0x7f, 0xfa, + 0x87, 0xec, 0x1f, 0xd1, 0x79, 0xf3, 0xd8, 0xb2, 0x8e, 0xbb, 0xa4, 0x6e, 0xf4, 0x3b, 0x75, 0xc3, + 0x34, 0x2d, 0xd7, 0x70, 0x3b, 0x96, 0xe9, 0xf0, 0x5e, 0xfc, 0xf7, 0x1a, 0x94, 0x75, 0xe2, 0xf4, + 0x2d, 0xd3, 0x21, 0xeb, 0xc4, 0x68, 0x13, 0x1b, 0xdd, 0x02, 0x68, 0x75, 0x07, 0x8e, 0x4b, 0xec, + 0x83, 0x4e, 0xbb, 0xaa, 0x2d, 0x68, 0x8b, 0x93, 0x7a, 0x5e, 0x50, 0x36, 0xda, 0xe8, 0x06, 0xe4, + 0x7b, 0xa4, 0x77, 0xc8, 0x7b, 0x53, 0xac, 0x77, 0x8a, 0x13, 0x36, 0xda, 0xa8, 0x06, 0x53, 0x36, + 0x19, 0x76, 0x9c, 0x8e, 0x65, 0x56, 0xd3, 0x0b, 0xda, 0x62, 0x5a, 0xf7, 0xda, 0x74, 0xa0, 0x6d, + 0x1c, 0xb9, 0x07, 0x2e, 0xb1, 0x7b, 0xd5, 0x49, 0x3e, 0x90, 0x12, 0x9a, 0xc4, 0xee, 0xe1, 0x2f, + 0x33, 0x50, 0xd4, 0x0d, 0xf3, 0x98, 0xe8, 0xe4, 0xaf, 0x06, 0xc4, 0x71, 0x51, 0x05, 0xd2, 0xa7, + 0xe4, 0x9c, 0xa9, 0x2f, 0xea, 0xf4, 0x93, 0x8f, 0x37, 0x8f, 0xc9, 0x01, 0x31, 0xb9, 0xe2, 0x22, + 0x1d, 0x6f, 0x1e, 0x93, 0x86, 0xd9, 0x46, 0xb3, 0x90, 0xe9, 0x76, 0x7a, 0x1d, 0x57, 0x68, 0xe5, + 0x8d, 0x80, 0x39, 0x93, 0x21, 0x73, 0x56, 0x01, 0x1c, 0xcb, 0x76, 0x0f, 0x2c, 0xbb, 0x4d, 0xec, + 0x6a, 0x66, 0x41, 0x5b, 0x2c, 0x2f, 0xdf, 0x5b, 0x52, 0x17, 0x62, 0x49, 0x35, 0x68, 0x69, 0xcf, + 0xb2, 0xdd, 0x1d, 0xca, 0xab, 0xe7, 0x1d, 0xf9, 0x89, 0x3e, 0x84, 0x02, 0x13, 0xe2, 0x1a, 0xf6, + 0x31, 0x71, 0xab, 0x59, 0x26, 0xe5, 0xfe, 0x05, 0x52, 0x9a, 0x8c, 0x59, 0x67, 0xea, 0xf9, 0x37, + 0xc2, 0x50, 0x74, 0x88, 0xdd, 0x31, 0xba, 0x9d, 0x37, 0xc6, 0x61, 0x97, 0x54, 0x73, 0x0b, 0xda, + 0xe2, 0x94, 0x1e, 0xa0, 0xd1, 0xf9, 0x9f, 0x92, 0x73, 0xe7, 0xc0, 0x32, 0xbb, 0xe7, 0xd5, 0x29, + 0xc6, 0x30, 0x45, 0x09, 0x3b, 0x66, 0xf7, 0x9c, 0x2d, 0x9a, 0x35, 0x30, 0x5d, 0xde, 0x9b, 0x67, + 0xbd, 0x79, 0x46, 0x61, 0xdd, 0x8b, 0x50, 0xe9, 0x75, 0xcc, 0x83, 0x9e, 0xd5, 0x3e, 0xf0, 0x1c, + 0x02, 0xcc, 0x21, 0xe5, 0x5e, 0xc7, 0x7c, 0x69, 0xb5, 0x75, 0xe9, 0x16, 0xca, 0x69, 0x9c, 0x05, + 0x39, 0x0b, 0x82, 0xd3, 0x38, 0x53, 0x39, 0x97, 0x60, 0x86, 0xca, 0x6c, 0xd9, 0xc4, 0x70, 0x89, + 0xcf, 0x5c, 0x64, 0xcc, 0x57, 0x7a, 0x1d, 0x73, 0x95, 0xf5, 0x04, 0xf8, 0x8d, 0xb3, 0x08, 0x7f, + 0x49, 0xf0, 0x1b, 0x67, 0x41, 0x7e, 0xbc, 0x04, 0x79, 0xcf, 0xe7, 0x68, 0x0a, 0x26, 0xb7, 0x77, + 0xb6, 0x1b, 0x95, 0x09, 0x04, 0x90, 0x5d, 0xd9, 0x5b, 0x6d, 0x6c, 0xaf, 0x55, 0x34, 0x54, 0x80, + 0xdc, 0x5a, 0x83, 0x37, 0x52, 0xf8, 0x39, 0x80, 0xef, 0x5d, 0x94, 0x83, 0xf4, 0x66, 0xe3, 0xcf, + 0x2a, 0x13, 0x94, 0xe7, 0x55, 0x43, 0xdf, 0xdb, 0xd8, 0xd9, 0xae, 0x68, 0x74, 0xf0, 0xaa, 0xde, + 0x58, 0x69, 0x36, 0x2a, 0x29, 0xca, 0xf1, 0x72, 0x67, 0xad, 0x92, 0x46, 0x79, 0xc8, 0xbc, 0x5a, + 0xd9, 0xda, 0x6f, 0x54, 0x26, 0xf1, 0x57, 0x1a, 0x94, 0xc4, 0x7a, 0xf1, 0x98, 0x40, 0xef, 0x41, + 0xf6, 0x84, 0xc5, 0x05, 0xdb, 0x8a, 0x85, 0xe5, 0x9b, 0xa1, 0xc5, 0x0d, 0xc4, 0x8e, 0x2e, 0x78, + 0x11, 0x86, 0xf4, 0xe9, 0xd0, 0xa9, 0xa6, 0x16, 0xd2, 0x8b, 0x85, 0xe5, 0xca, 0x12, 0x0f, 0xd8, + 0xa5, 0x4d, 0x72, 0xfe, 0xca, 0xe8, 0x0e, 0x88, 0x4e, 0x3b, 0x11, 0x82, 0xc9, 0x9e, 0x65, 0x13, + 0xb6, 0x63, 0xa7, 0x74, 0xf6, 0x4d, 0xb7, 0x31, 0x5b, 0x34, 0xb1, 0x5b, 0x79, 0x03, 0x7f, 0xab, + 0x01, 0xec, 0x0e, 0xdc, 0xe4, 0xd0, 0x98, 0x85, 0xcc, 0x90, 0x0a, 0x16, 0x61, 0xc1, 0x1b, 0x2c, + 0x26, 0x88, 0xe1, 0x10, 0x2f, 0x26, 0x68, 0x03, 0x5d, 0x87, 0x5c, 0xdf, 0x26, 0xc3, 0x83, 0xd3, + 0x21, 0x53, 0x32, 0xa5, 0x67, 0x69, 0x73, 0x73, 0x88, 0xee, 0x40, 0xb1, 0x73, 0x6c, 0x5a, 0x36, + 0x39, 0xe0, 0xb2, 0x32, 0xac, 0xb7, 0xc0, 0x69, 0xcc, 0x6e, 0x85, 0x85, 0x0b, 0xce, 0xaa, 0x2c, + 0x5b, 0x94, 0x84, 0x4d, 0x28, 0x30, 0x53, 0xc7, 0x72, 0xdf, 0x23, 0xdf, 0xc6, 0x14, 0x1b, 0x16, + 0x75, 0xa1, 0xb0, 0x1a, 0x7f, 0x06, 0x68, 0x8d, 0x74, 0x89, 0x4b, 0xc6, 0xc9, 0x1e, 0x8a, 0x4f, + 0xd2, 0xaa, 0x4f, 0xf0, 0x3f, 0x6b, 0x30, 0x13, 0x10, 0x3f, 0xd6, 0xb4, 0xaa, 0x90, 0x6b, 0x33, + 0x61, 0xdc, 0x82, 0xb4, 0x2e, 0x9b, 0xe8, 0x09, 0x4c, 0x09, 0x03, 0x9c, 0x6a, 0x3a, 0x61, 0xd3, + 0xe4, 0xb8, 0x4d, 0x0e, 0xfe, 0x36, 0x05, 0x79, 0x31, 0xd1, 0x9d, 0x3e, 0x5a, 0x81, 0x92, 0xcd, + 0x1b, 0x07, 0x6c, 0x3e, 0xc2, 0xa2, 0x5a, 0x72, 0x12, 0x5a, 0x9f, 0xd0, 0x8b, 0x62, 0x08, 0x23, + 0xa3, 0x3f, 0x81, 0x82, 0x14, 0xd1, 0x1f, 0xb8, 0xc2, 0xe5, 0xd5, 0xa0, 0x00, 0x7f, 0xff, 0xad, + 0x4f, 0xe8, 0x20, 0xd8, 0x77, 0x07, 0x2e, 0x6a, 0xc2, 0xac, 0x1c, 0xcc, 0x67, 0x23, 0xcc, 0x48, + 0x33, 0x29, 0x0b, 0x41, 0x29, 0xd1, 0xa5, 0x5a, 0x9f, 0xd0, 0x91, 0x18, 0xaf, 0x74, 0xaa, 0x26, + 0xb9, 0x67, 0x3c, 0x79, 0x47, 0x4c, 0x6a, 0x9e, 0x99, 0x51, 0x93, 0x9a, 0x67, 0xe6, 0xf3, 0x3c, + 0xe4, 0x44, 0x0b, 0xff, 0x57, 0x0a, 0x40, 0xae, 0xc6, 0x4e, 0x1f, 0xad, 0x41, 0xd9, 0x16, 0xad, + 0x80, 0xb7, 0x6e, 0xc4, 0x7a, 0x4b, 0x2c, 0xe2, 0x84, 0x5e, 0x92, 0x83, 0xb8, 0x71, 0xef, 0x43, + 0xd1, 0x93, 0xe2, 0x3b, 0x6c, 0x2e, 0xc6, 0x61, 0x9e, 0x84, 0x82, 0x1c, 0x40, 0x5d, 0xf6, 0x09, + 0x5c, 0xf5, 0xc6, 0xc7, 0xf8, 0xec, 0xce, 0x08, 0x9f, 0x79, 0x02, 0x67, 0xa4, 0x04, 0xd5, 0x6b, + 0xaa, 0x61, 0xbe, 0xdb, 0xe6, 0x62, 0xdc, 0x16, 0x35, 0x8c, 0x3a, 0x0e, 0x68, 0xbd, 0xe4, 0x4d, + 0xfc, 0xeb, 0x34, 0xe4, 0x56, 0xad, 0x5e, 0xdf, 0xb0, 0xe9, 0x6a, 0x64, 0x6d, 0xe2, 0x0c, 0xba, + 0x2e, 0x73, 0x57, 0x79, 0xf9, 0x6e, 0x50, 0xa2, 0x60, 0x93, 0xff, 0xea, 0x8c, 0x55, 0x17, 0x43, + 0xe8, 0x60, 0x51, 0x1e, 0x53, 0x97, 0x18, 0x2c, 0x8a, 0xa3, 0x18, 0x22, 0x03, 0x39, 0xed, 0x07, + 0x72, 0x0d, 0x72, 0x43, 0x62, 0xfb, 0x25, 0x7d, 0x7d, 0x42, 0x97, 0x04, 0xf4, 0x08, 0xa6, 0xc3, + 0xe5, 0x25, 0x23, 0x78, 0xca, 0xad, 0x60, 0x35, 0xba, 0x0b, 0xc5, 0x40, 0x8d, 0xcb, 0x0a, 0xbe, + 0x42, 0x4f, 0x29, 0x71, 0xd7, 0x64, 0x5e, 0xa5, 0xf5, 0xb8, 0xb8, 0x3e, 0x21, 0x33, 0xeb, 0x35, + 0x99, 0x59, 0xa7, 0xc4, 0x28, 0x91, 0x5b, 0x03, 0x49, 0xe6, 0x83, 0x60, 0x92, 0xc1, 0x1f, 0x40, + 0x29, 0xe0, 0x20, 0x5a, 0x77, 0x1a, 0x1f, 0xef, 0xaf, 0x6c, 0xf1, 0x22, 0xf5, 0x82, 0xd5, 0x25, + 0xbd, 0xa2, 0xd1, 0x5a, 0xb7, 0xd5, 0xd8, 0xdb, 0xab, 0xa4, 0x50, 0x09, 0xf2, 0xdb, 0x3b, 0xcd, + 0x03, 0xce, 0x95, 0xc6, 0x2f, 0x3c, 0x09, 0xa2, 0xc8, 0x29, 0xb5, 0x6d, 0x42, 0xa9, 0x6d, 0x9a, + 0xac, 0x6d, 0x29, 0xbf, 0xb6, 0xb1, 0x32, 0xb7, 0xd5, 0x58, 0xd9, 0x6b, 0x54, 0x26, 0x9f, 0x97, + 0xa1, 0xc8, 0xfd, 0x7b, 0x30, 0x30, 0x69, 0xa9, 0xfd, 0x77, 0x0d, 0xc0, 0x8f, 0x26, 0x54, 0x87, + 0x5c, 0x8b, 0xeb, 0xa9, 0x6a, 0x2c, 0x19, 0x5d, 0x8d, 0x5d, 0x32, 0x5d, 0x72, 0xa1, 0x77, 0x20, + 0xe7, 0x0c, 0x5a, 0x2d, 0xe2, 0xc8, 0x92, 0x77, 0x3d, 0x9c, 0x0f, 0x45, 0xb6, 0xd2, 0x25, 0x1f, + 0x1d, 0x72, 0x64, 0x74, 0xba, 0x03, 0x56, 0x00, 0x47, 0x0f, 0x11, 0x7c, 0xf8, 0xdf, 0x34, 0x28, + 0x28, 0x9b, 0xf7, 0x07, 0x26, 0xe1, 0x9b, 0x90, 0x67, 0x36, 0x90, 0xb6, 0x48, 0xc3, 0x53, 0xba, + 0x4f, 0x40, 0x7f, 0x0c, 0x79, 0x19, 0x01, 0x32, 0x13, 0x57, 0xe3, 0xc5, 0xee, 0xf4, 0x75, 0x9f, + 0x15, 0x6f, 0xc2, 0x15, 0xe6, 0x95, 0x16, 0x3d, 0x5c, 0x4b, 0x3f, 0xaa, 0xc7, 0x4f, 0x2d, 0x74, + 0xfc, 0xac, 0xc1, 0x54, 0xff, 0xe4, 0xdc, 0xe9, 0xb4, 0x8c, 0xae, 0xb0, 0xc2, 0x6b, 0xe3, 0x8f, + 0x00, 0xa9, 0xc2, 0xc6, 0x99, 0x2e, 0x2e, 0x41, 0x61, 0xdd, 0x70, 0x4e, 0x84, 0x49, 0xf8, 0x09, + 0x94, 0x68, 0x73, 0xf3, 0xd5, 0x25, 0x6c, 0x64, 0x97, 0x03, 0xc9, 0x3d, 0x96, 0xcf, 0x11, 0x4c, + 0x9e, 0x18, 0xce, 0x09, 0x9b, 0x68, 0x49, 0x67, 0xdf, 0xe8, 0x11, 0x54, 0x5a, 0x7c, 0x92, 0x07, + 0xa1, 0x2b, 0xc3, 0xb4, 0xa0, 0x7b, 0x27, 0xc1, 0x4f, 0xa1, 0xc8, 0xe7, 0xf0, 0x63, 0x1b, 0x81, + 0xaf, 0xc0, 0xf4, 0x9e, 0x69, 0xf4, 0x9d, 0x13, 0x4b, 0x56, 0x37, 0x3a, 0xe9, 0x8a, 0x4f, 0x1b, + 0x4b, 0xe3, 0x43, 0x98, 0xb6, 0x49, 0xcf, 0xe8, 0x98, 0x1d, 0xf3, 0xf8, 0xe0, 0xf0, 0xdc, 0x25, + 0x8e, 0xb8, 0x30, 0x95, 0x3d, 0xf2, 0x73, 0x4a, 0xa5, 0xa6, 0x1d, 0x76, 0xad, 0x43, 0x91, 0xe6, + 0xd8, 0x37, 0xfe, 0x4f, 0x0d, 0x8a, 0x9f, 0x18, 0x6e, 0x4b, 0x2e, 0x1d, 0xda, 0x80, 0xb2, 0x97, + 0xdc, 0x18, 0x45, 0xd8, 0x12, 0x2a, 0xb1, 0x6c, 0x8c, 0x3c, 0x4a, 0xcb, 0xea, 0x58, 0x6a, 0xa9, + 0x04, 0x26, 0xca, 0x30, 0x5b, 0xa4, 0xeb, 0x89, 0x4a, 0x25, 0x8b, 0x62, 0x8c, 0xaa, 0x28, 0x95, + 0xf0, 0x7c, 0xda, 0x3f, 0x7e, 0xf0, 0x5c, 0xf2, 0x75, 0x0a, 0x50, 0xd4, 0x86, 0xef, 0x7b, 0x22, + 0xbb, 0x0f, 0x65, 0xc7, 0x35, 0xec, 0xc8, 0xde, 0x28, 0x31, 0xaa, 0x97, 0xa0, 0x1f, 0xc2, 0x74, + 0xdf, 0xb6, 0x8e, 0x6d, 0xe2, 0x38, 0x07, 0xa6, 0xe5, 0x76, 0x8e, 0xce, 0xc5, 0xa1, 0xb6, 0x2c, + 0xc9, 0xdb, 0x8c, 0x8a, 0x1a, 0x90, 0x3b, 0xea, 0x74, 0x5d, 0x62, 0x3b, 0xd5, 0xcc, 0x42, 0x7a, + 0xb1, 0xbc, 0xfc, 0xe4, 0x22, 0xaf, 0x2d, 0x7d, 0xc8, 0xf8, 0x9b, 0xe7, 0x7d, 0xa2, 0xcb, 0xb1, + 0xea, 0x41, 0x31, 0x1b, 0x38, 0x28, 0xde, 0x07, 0xf0, 0xf9, 0x69, 0xaa, 0xdd, 0xde, 0xd9, 0xdd, + 0x6f, 0x56, 0x26, 0x50, 0x11, 0xa6, 0xb6, 0x77, 0xd6, 0x1a, 0x5b, 0x0d, 0x9a, 0x97, 0x71, 0x5d, + 0xfa, 0x46, 0xf5, 0x21, 0x9a, 0x83, 0xa9, 0xd7, 0x94, 0x2a, 0xef, 0xdb, 0x69, 0x3d, 0xc7, 0xda, + 0x1b, 0x6d, 0xfc, 0x4f, 0x29, 0x28, 0x89, 0x5d, 0x30, 0xd6, 0x56, 0x54, 0x55, 0xa4, 0x02, 0x2a, + 0xe8, 0xa9, 0x94, 0xef, 0x8e, 0xb6, 0x38, 0xfc, 0xca, 0x26, 0xcd, 0x0d, 0x7c, 0xb1, 0x49, 0x5b, + 0xb8, 0xd5, 0x6b, 0xc7, 0x86, 0x6f, 0x26, 0x36, 0x7c, 0xd1, 0x5d, 0x28, 0x79, 0xbb, 0xcd, 0x70, + 0x44, 0xad, 0xcd, 0xeb, 0x45, 0xb9, 0x91, 0x28, 0x0d, 0xdd, 0x87, 0x2c, 0x19, 0x12, 0xd3, 0x75, + 0xaa, 0x05, 0x96, 0x75, 0x4b, 0xf2, 0xfc, 0xdb, 0xa0, 0x54, 0x5d, 0x74, 0xe2, 0x3f, 0x82, 0x2b, + 0xec, 0x9e, 0xf1, 0xc2, 0x36, 0x4c, 0xf5, 0x42, 0xd4, 0x6c, 0x6e, 0x09, 0xd7, 0xd1, 0x4f, 0x54, + 0x86, 0xd4, 0xc6, 0x9a, 0x98, 0x68, 0x6a, 0x63, 0x0d, 0x7f, 0xa1, 0x01, 0x52, 0xc7, 0x8d, 0xe5, + 0xcb, 0x90, 0x70, 0xa9, 0x3e, 0xed, 0xab, 0x9f, 0x85, 0x0c, 0xb1, 0x6d, 0xcb, 0x66, 0x5e, 0xcb, + 0xeb, 0xbc, 0x81, 0xef, 0x09, 0x1b, 0x74, 0x32, 0xb4, 0x4e, 0xbd, 0xc0, 0xe0, 0xd2, 0x34, 0xcf, + 0xd4, 0x4d, 0x98, 0x09, 0x70, 0x8d, 0x95, 0xfd, 0x1f, 0xc2, 0x55, 0x26, 0x6c, 0x93, 0x90, 0xfe, + 0x4a, 0xb7, 0x33, 0x4c, 0xd4, 0xda, 0x87, 0x6b, 0x61, 0xc6, 0x9f, 0xd6, 0x47, 0xf8, 0x4f, 0x85, + 0xc6, 0x66, 0xa7, 0x47, 0x9a, 0xd6, 0x56, 0xb2, 0x6d, 0x34, 0x3b, 0x9e, 0x92, 0x73, 0x47, 0x94, + 0x49, 0xf6, 0x8d, 0xff, 0x43, 0x83, 0xeb, 0x91, 0xe1, 0x3f, 0xf1, 0xaa, 0xce, 0x03, 0x1c, 0xd3, + 0xed, 0x43, 0xda, 0xb4, 0x83, 0xdf, 0xd0, 0x15, 0x8a, 0x67, 0x27, 0x4d, 0x30, 0x45, 0x61, 0xe7, + 0xac, 0x58, 0x73, 0xf6, 0xc7, 0x91, 0x35, 0xe6, 0x16, 0x14, 0x18, 0x61, 0xcf, 0x35, 0xdc, 0x81, + 0x13, 0x59, 0x8c, 0xbf, 0x11, 0x5b, 0x40, 0x0e, 0x1a, 0x6b, 0x5e, 0xef, 0x40, 0x96, 0x1d, 0x4e, + 0xe5, 0xd1, 0x2c, 0x74, 0x1b, 0x50, 0xec, 0xd0, 0x05, 0x23, 0x3e, 0x81, 0xec, 0x4b, 0x86, 0xe8, + 0x29, 0x96, 0x4d, 0xca, 0xa5, 0x30, 0x8d, 0x1e, 0xc7, 0x19, 0xf2, 0x3a, 0xfb, 0x66, 0x27, 0x19, + 0x42, 0xec, 0x7d, 0x7d, 0x8b, 0x9f, 0x98, 0xf2, 0xba, 0xd7, 0xa6, 0x2e, 0x6b, 0x75, 0x3b, 0xc4, + 0x74, 0x59, 0xef, 0x24, 0xeb, 0x55, 0x28, 0x78, 0x09, 0x2a, 0x5c, 0xd3, 0x4a, 0xbb, 0xad, 0x9c, + 0x48, 0x3c, 0x79, 0x5a, 0x50, 0x1e, 0xfe, 0x46, 0x83, 0x2b, 0xca, 0x80, 0xb1, 0x1c, 0xf3, 0x14, + 0xb2, 0x1c, 0xb7, 0x14, 0xc5, 0x6f, 0x36, 0x38, 0x8a, 0xab, 0xd1, 0x05, 0x0f, 0x5a, 0x82, 0x1c, + 0xff, 0x92, 0xc7, 0xc2, 0x78, 0x76, 0xc9, 0x84, 0xef, 0xc3, 0x8c, 0x20, 0x91, 0x9e, 0x15, 0xb7, + 0xb7, 0x99, 0x43, 0xf1, 0xe7, 0x30, 0x1b, 0x64, 0x1b, 0x6b, 0x4a, 0x8a, 0x91, 0xa9, 0xcb, 0x18, + 0xb9, 0x22, 0x8d, 0xdc, 0xef, 0xb7, 0x95, 0x5a, 0x1d, 0x5e, 0x75, 0x75, 0x45, 0x52, 0xa1, 0x15, + 0xf1, 0x26, 0x20, 0x45, 0xfc, 0xac, 0x13, 0x98, 0x91, 0xdb, 0x61, 0xab, 0xe3, 0x78, 0x27, 0xb8, + 0x37, 0x80, 0x54, 0xe2, 0xcf, 0x6d, 0xd0, 0x1a, 0x39, 0xb2, 0x8d, 0xe3, 0x1e, 0xf1, 0xea, 0x13, + 0x3d, 0xcf, 0xab, 0xc4, 0xb1, 0x32, 0x7a, 0x1d, 0xae, 0xbc, 0xb4, 0x86, 0x34, 0x35, 0x50, 0xaa, + 0x1f, 0x32, 0xfc, 0x3e, 0xe7, 0x2d, 0x9b, 0xd7, 0xa6, 0xca, 0xd5, 0x01, 0x63, 0x29, 0xff, 0x5f, + 0x0d, 0x8a, 0x2b, 0x5d, 0xc3, 0xee, 0x49, 0xc5, 0xef, 0x43, 0x96, 0xdf, 0x52, 0x04, 0x30, 0xf0, + 0x20, 0x28, 0x46, 0xe5, 0xe5, 0x8d, 0x15, 0x7e, 0xa7, 0x11, 0xa3, 0xa8, 0xe1, 0xe2, 0xed, 0x60, + 0x2d, 0xf4, 0x96, 0xb0, 0x86, 0xde, 0x82, 0x8c, 0x41, 0x87, 0xb0, 0x14, 0x5c, 0x0e, 0xdf, 0x0f, + 0x99, 0x34, 0x76, 0x38, 0xe3, 0x5c, 0xf8, 0x3d, 0x28, 0x28, 0x1a, 0xe8, 0x0d, 0xf8, 0x45, 0x43, + 0x1c, 0xc0, 0x56, 0x56, 0x9b, 0x1b, 0xaf, 0xf8, 0xc5, 0xb8, 0x0c, 0xb0, 0xd6, 0xf0, 0xda, 0x29, + 0xfc, 0xa9, 0x18, 0x25, 0xf2, 0x9d, 0x6a, 0x8f, 0x96, 0x64, 0x4f, 0xea, 0x52, 0xf6, 0x9c, 0x41, + 0x49, 0x4c, 0x7f, 0xdc, 0xf4, 0xcd, 0xe4, 0x25, 0xa4, 0x6f, 0xc5, 0x78, 0x5d, 0x30, 0xe2, 0x69, + 0x28, 0x89, 0x84, 0x2e, 0xf6, 0xdf, 0xff, 0x68, 0x50, 0x96, 0x94, 0x71, 0x01, 0x4c, 0x89, 0xbd, + 0xf0, 0x0a, 0xe0, 0x21, 0x2f, 0xd7, 0x20, 0xdb, 0x3e, 0xdc, 0xeb, 0xbc, 0x91, 0x60, 0xb3, 0x68, + 0x51, 0x7a, 0x97, 0xeb, 0xe1, 0x2f, 0x3e, 0xa2, 0x45, 0x6f, 0xe1, 0xb6, 0x71, 0xe4, 0x6e, 0x98, + 0x6d, 0x72, 0xc6, 0xce, 0x8d, 0x93, 0xba, 0x4f, 0x60, 0x97, 0x52, 0xf1, 0x32, 0xc4, 0x0e, 0x8b, + 0xea, 0x4b, 0xd1, 0x0c, 0x5c, 0x59, 0x19, 0xb8, 0x27, 0x0d, 0xd3, 0x38, 0xec, 0xca, 0x8c, 0x45, + 0xcb, 0x2c, 0x25, 0xae, 0x75, 0x1c, 0x95, 0xda, 0x80, 0x19, 0x4a, 0x25, 0xa6, 0xdb, 0x69, 0x29, + 0xe9, 0x4d, 0x16, 0x31, 0x2d, 0x54, 0xc4, 0x0c, 0xc7, 0x79, 0x6d, 0xd9, 0x6d, 0x31, 0x35, 0xaf, + 0x8d, 0xd7, 0xb8, 0xf0, 0x7d, 0x27, 0x50, 0xa6, 0xbe, 0xaf, 0x94, 0x45, 0x5f, 0xca, 0x0b, 0xe2, + 0x8e, 0x90, 0x82, 0x9f, 0xc0, 0x55, 0xc9, 0x29, 0xc0, 0xbd, 0x11, 0xcc, 0x3b, 0x70, 0x4b, 0x32, + 0xaf, 0x9e, 0xd0, 0xdb, 0xd3, 0xae, 0x50, 0xf8, 0x43, 0xed, 0x7c, 0x0e, 0x55, 0xcf, 0x4e, 0x76, + 0x58, 0xb6, 0xba, 0xaa, 0x01, 0x03, 0x47, 0xec, 0x99, 0xbc, 0xce, 0xbe, 0x29, 0xcd, 0xb6, 0xba, + 0xde, 0x91, 0x80, 0x7e, 0xe3, 0x55, 0x98, 0x93, 0x32, 0xc4, 0x31, 0x36, 0x28, 0x24, 0x62, 0x50, + 0x9c, 0x10, 0xe1, 0x30, 0x3a, 0x74, 0xb4, 0xdb, 0x55, 0xce, 0xa0, 0x6b, 0x99, 0x4c, 0x4d, 0x91, + 0x79, 0x95, 0xef, 0x08, 0x6a, 0x98, 0x5a, 0x31, 0x04, 0x99, 0x0a, 0x50, 0xc9, 0x62, 0x21, 0x28, + 0x39, 0xb2, 0x10, 0x11, 0xd1, 0x9f, 0xc1, 0xbc, 0x67, 0x04, 0xf5, 0xdb, 0x2e, 0xb1, 0x7b, 0x1d, + 0xc7, 0x51, 0xe0, 0xa0, 0xb8, 0x89, 0x3f, 0x80, 0xc9, 0x3e, 0x11, 0x39, 0xa5, 0xb0, 0x8c, 0x96, + 0xf8, 0xfb, 0xed, 0x92, 0x32, 0x98, 0xf5, 0xe3, 0x36, 0xdc, 0x96, 0xd2, 0xb9, 0x47, 0x63, 0xc5, + 0x87, 0x8d, 0x92, 0xb7, 0x6e, 0xee, 0xd6, 0xe8, 0xad, 0x3b, 0xcd, 0xd7, 0xde, 0x83, 0x28, 0x3f, + 0xe2, 0x8e, 0x94, 0xb1, 0x35, 0x56, 0xad, 0xd8, 0xe4, 0x3e, 0xf5, 0x42, 0x72, 0x2c, 0x61, 0x87, + 0x30, 0x1b, 0x8c, 0xe4, 0xb1, 0xd2, 0xd8, 0x2c, 0x64, 0x5c, 0xeb, 0x94, 0xc8, 0x24, 0xc6, 0x1b, + 0xd2, 0x60, 0x2f, 0xcc, 0xc7, 0x32, 0xd8, 0xf0, 0x85, 0xb1, 0x2d, 0x39, 0xae, 0xbd, 0x74, 0x35, + 0xe5, 0xe1, 0x8b, 0x37, 0xf0, 0x36, 0x5c, 0x0b, 0xa7, 0x89, 0xb1, 0x4c, 0x7e, 0xc5, 0x37, 0x70, + 0x5c, 0x26, 0x19, 0x4b, 0xee, 0xc7, 0x7e, 0x32, 0x50, 0x12, 0xca, 0x58, 0x22, 0x75, 0xa8, 0xc5, + 0xe5, 0x97, 0x1f, 0x63, 0xbf, 0x7a, 0xe9, 0x66, 0x2c, 0x61, 0x8e, 0x2f, 0x6c, 0xfc, 0xe5, 0xf7, + 0x73, 0x44, 0x7a, 0x64, 0x8e, 0x10, 0x41, 0xe2, 0x67, 0xb1, 0x9f, 0x60, 0xd3, 0x09, 0x1d, 0x7e, + 0x02, 0x1d, 0x57, 0x07, 0xad, 0x21, 0x9e, 0x0e, 0xd6, 0x90, 0x1b, 0x5b, 0x4d, 0xbb, 0x63, 0x2d, + 0xc6, 0x27, 0x7e, 0xee, 0x8c, 0x64, 0xe6, 0xb1, 0x04, 0x7f, 0x0a, 0x0b, 0xc9, 0x49, 0x79, 0x1c, + 0xc9, 0x8f, 0xeb, 0x90, 0xf7, 0x0e, 0x94, 0xca, 0x6f, 0x1f, 0x0a, 0x90, 0xdb, 0xde, 0xd9, 0xdb, + 0x5d, 0x59, 0x6d, 0xf0, 0x1f, 0x3f, 0xac, 0xee, 0xe8, 0xfa, 0xfe, 0x6e, 0xb3, 0x92, 0x5a, 0xfe, + 0x6d, 0x1a, 0x52, 0x9b, 0xaf, 0xd0, 0x9f, 0x43, 0x86, 0xbf, 0x04, 0x8e, 0x78, 0xfe, 0xad, 0x8d, + 0x7a, 0xec, 0xc4, 0x37, 0xbe, 0xf8, 0xff, 0x5f, 0x7d, 0x95, 0xba, 0x8a, 0x2b, 0xf5, 0xe1, 0xbb, + 0x87, 0xc4, 0x35, 0xea, 0xa7, 0xc3, 0x3a, 0xab, 0x0f, 0xcf, 0xb4, 0xc7, 0x68, 0x1f, 0xd2, 0xbb, + 0x03, 0x17, 0x25, 0x3e, 0x0d, 0xd7, 0x92, 0xdf, 0x40, 0xf1, 0x1c, 0x13, 0x3c, 0x83, 0xcb, 0x8a, + 0xe0, 0xfe, 0xc0, 0xa5, 0x62, 0x07, 0x50, 0x50, 0x5f, 0x31, 0x2f, 0x7c, 0x33, 0xae, 0x5d, 0xfc, + 0x42, 0x8a, 0xef, 0x30, 0x75, 0x37, 0xf0, 0x35, 0x45, 0x1d, 0x7f, 0x6b, 0x55, 0x67, 0xd3, 0x3c, + 0x33, 0x51, 0xe2, 0xab, 0x72, 0x2d, 0xf9, 0xe1, 0x34, 0x76, 0x36, 0xee, 0x99, 0x49, 0xc5, 0x9a, + 0xe2, 0xdd, 0xb4, 0xe5, 0xa2, 0xdb, 0x31, 0xef, 0x66, 0xea, 0x0b, 0x51, 0x6d, 0x21, 0x99, 0x41, + 0x28, 0x5a, 0x60, 0x8a, 0x6a, 0xf8, 0xaa, 0xa2, 0xa8, 0xe5, 0xb1, 0x3d, 0xd3, 0x1e, 0x2f, 0x1f, + 0x43, 0x86, 0x21, 0xc4, 0xe8, 0x2f, 0xe4, 0x47, 0x2d, 0x06, 0xdb, 0x4e, 0x58, 0xfc, 0x00, 0xb6, + 0x8c, 0xab, 0x4c, 0x19, 0xc2, 0x25, 0xa9, 0x8c, 0x61, 0xc4, 0xcf, 0xb4, 0xc7, 0x8b, 0xda, 0xdb, + 0xda, 0xf2, 0x6f, 0x26, 0x21, 0xc3, 0xe0, 0x22, 0x64, 0x01, 0xf8, 0x68, 0x6a, 0x78, 0x96, 0x11, + 0x7c, 0x36, 0x3c, 0xcb, 0x28, 0x10, 0x8b, 0xe7, 0x99, 0xe2, 0x2a, 0x9e, 0x91, 0x8a, 0x19, 0x12, + 0x55, 0x67, 0xe0, 0x1a, 0xf5, 0xe9, 0x50, 0x00, 0x66, 0x3c, 0xcc, 0x50, 0x9c, 0xc0, 0x00, 0xaa, + 0x1a, 0xde, 0x21, 0x31, 0x88, 0x2a, 0xc6, 0x4c, 0xe7, 0x4d, 0x7c, 0x5d, 0xf1, 0x2c, 0x57, 0x6b, + 0x33, 0x46, 0xaa, 0xf7, 0xef, 0x34, 0x28, 0x07, 0x71, 0x51, 0x74, 0x37, 0x46, 0x72, 0x18, 0x5e, + 0xad, 0xdd, 0x1b, 0xcd, 0x94, 0x64, 0x01, 0x57, 0x7f, 0x4a, 0x48, 0xdf, 0xa0, 0x8c, 0xc2, 0xf1, + 0xe8, 0x1f, 0x34, 0x98, 0x0e, 0x81, 0x9d, 0x28, 0x4e, 0x43, 0x04, 0x4a, 0xad, 0xdd, 0xbf, 0x80, + 0x4b, 0x18, 0xf2, 0x80, 0x19, 0xb2, 0x80, 0x6f, 0x44, 0x5c, 0xe1, 0x76, 0x7a, 0xc4, 0xb5, 0x84, + 0x31, 0xde, 0x32, 0x70, 0x60, 0x32, 0x76, 0x19, 0x02, 0x40, 0x67, 0xec, 0x32, 0x04, 0x51, 0xcd, + 0x11, 0xcb, 0xc0, 0xd1, 0x48, 0xba, 0xc5, 0x7f, 0x97, 0x86, 0xdc, 0x2a, 0xff, 0x05, 0x22, 0x72, + 0x20, 0xef, 0x21, 0x80, 0x68, 0x3e, 0x0e, 0x8d, 0xf1, 0x6f, 0x0b, 0xb5, 0xdb, 0x89, 0xfd, 0x42, + 0xfb, 0x7d, 0xa6, 0xfd, 0x36, 0xae, 0x49, 0xed, 0xe2, 0x87, 0x8e, 0x75, 0x7e, 0xed, 0xaf, 0x1b, + 0xed, 0x36, 0x9d, 0xf8, 0xdf, 0x42, 0x51, 0x85, 0xe9, 0xd0, 0x9d, 0x58, 0x14, 0x48, 0x45, 0xfa, + 0x6a, 0x78, 0x14, 0x8b, 0xd0, 0xbe, 0xc8, 0xb4, 0x63, 0x7c, 0x2b, 0x41, 0xbb, 0xcd, 0xd8, 0x03, + 0x06, 0x70, 0x98, 0x2d, 0xde, 0x80, 0x00, 0x8a, 0x17, 0x6f, 0x40, 0x10, 0xa5, 0xbb, 0xd0, 0x80, + 0x01, 0x63, 0xa7, 0x06, 0xbc, 0x06, 0xf0, 0x41, 0x35, 0x14, 0xeb, 0x57, 0xe5, 0xea, 0x14, 0x0e, + 0xf9, 0x28, 0x1e, 0x17, 0xdd, 0x73, 0x21, 0xd5, 0xdd, 0x8e, 0x43, 0x43, 0x7f, 0xf9, 0x9b, 0x2c, + 0x14, 0x5e, 0x1a, 0x1d, 0xd3, 0x25, 0xa6, 0x61, 0xb6, 0x08, 0x3a, 0x82, 0x0c, 0x2b, 0x8d, 0xe1, + 0x2c, 0xa7, 0x62, 0x4d, 0xe1, 0x2c, 0x17, 0x00, 0x62, 0xf0, 0x3d, 0xa6, 0x79, 0x1e, 0xcf, 0x49, + 0xcd, 0x3d, 0x5f, 0x7c, 0x9d, 0x61, 0x28, 0x74, 0xc2, 0x7f, 0x09, 0x59, 0x01, 0xcf, 0x87, 0x84, + 0x05, 0xb0, 0x95, 0xda, 0xcd, 0xf8, 0xce, 0xa4, 0xed, 0xa5, 0xaa, 0x72, 0x18, 0x2f, 0xd5, 0xf5, + 0x06, 0xc0, 0x07, 0x08, 0xc3, 0xce, 0x8d, 0xe0, 0x89, 0xb5, 0x85, 0x64, 0x06, 0xa1, 0xf7, 0x11, + 0xd3, 0x7b, 0x17, 0xcf, 0xc7, 0xe9, 0x6d, 0x7b, 0xfc, 0x54, 0xf7, 0x21, 0x4c, 0xae, 0x1b, 0xce, + 0x09, 0x0a, 0x15, 0x3b, 0xe5, 0x47, 0x03, 0xb5, 0x5a, 0x5c, 0x97, 0xd0, 0x74, 0x97, 0x69, 0xba, + 0x85, 0xab, 0x71, 0x9a, 0x4e, 0x0c, 0x87, 0x56, 0x0f, 0x74, 0x02, 0x59, 0xfe, 0x3b, 0x82, 0xb0, + 0x2f, 0x03, 0xbf, 0x45, 0x08, 0xfb, 0x32, 0xf8, 0xd3, 0x83, 0xcb, 0x69, 0x72, 0x61, 0x4a, 0x3e, + 0xde, 0xa3, 0x5b, 0xa1, 0xa5, 0x09, 0x3e, 0xf4, 0xd7, 0xe6, 0x93, 0xba, 0x85, 0xbe, 0x87, 0x4c, + 0xdf, 0x1d, 0x7c, 0x33, 0x76, 0xed, 0x04, 0xf7, 0x33, 0xed, 0xf1, 0xdb, 0x1a, 0x2d, 0x13, 0xe0, + 0x83, 0xac, 0x91, 0xe8, 0x08, 0xe3, 0xb5, 0x91, 0xe8, 0x88, 0xe0, 0xb3, 0x78, 0x99, 0x29, 0x7f, + 0x8a, 0x1f, 0xc6, 0x29, 0x77, 0x6d, 0xc3, 0x74, 0x8e, 0x88, 0xfd, 0x16, 0x07, 0xd3, 0x9c, 0x93, + 0x4e, 0x9f, 0x46, 0xca, 0xef, 0xa7, 0x61, 0x92, 0x9e, 0x47, 0x69, 0x79, 0xf6, 0xaf, 0xf1, 0x61, + 0x6b, 0x22, 0xe0, 0x59, 0xd8, 0x9a, 0x28, 0x02, 0x10, 0x2d, 0xcf, 0xec, 0xb7, 0xe6, 0x84, 0x31, + 0x51, 0xaf, 0x3b, 0x50, 0x50, 0xee, 0xfa, 0x28, 0x46, 0x60, 0x10, 0x99, 0x0b, 0xd7, 0x85, 0x18, + 0xa0, 0x00, 0xdf, 0x66, 0x3a, 0xe7, 0xf0, 0x6c, 0x40, 0x67, 0x9b, 0x73, 0x51, 0xa5, 0x7f, 0x0d, + 0x45, 0x15, 0x13, 0x40, 0x31, 0x32, 0x43, 0xc8, 0x5f, 0x38, 0x25, 0xc6, 0x41, 0x0a, 0xd1, 0xec, + 0xe0, 0xfd, 0xae, 0x5e, 0xb2, 0x52, 0xe5, 0x7d, 0xc8, 0x09, 0xa0, 0x20, 0x6e, 0xb6, 0x41, 0xa8, + 0x30, 0x6e, 0xb6, 0x21, 0x94, 0x21, 0x7a, 0xcc, 0x63, 0x5a, 0xe9, 0x7d, 0x48, 0x96, 0x20, 0xa1, + 0xf1, 0x05, 0x71, 0x93, 0x34, 0xfa, 0xd8, 0x57, 0x92, 0x46, 0xe5, 0x2e, 0x3a, 0x4a, 0xe3, 0x31, + 0x71, 0x45, 0x2c, 0xc9, 0x7b, 0x1e, 0x4a, 0x10, 0xa8, 0xa6, 0x7c, 0x3c, 0x8a, 0x25, 0xe9, 0x54, + 0xee, 0x2b, 0x15, 0xf9, 0x1e, 0x7d, 0x0e, 0xe0, 0x43, 0x1a, 0xe1, 0xd3, 0x56, 0x2c, 0x2e, 0x1a, + 0x3e, 0x6d, 0xc5, 0xa3, 0x22, 0xd1, 0xfc, 0xe1, 0xeb, 0xe6, 0x17, 0x03, 0xaa, 0xfd, 0x5f, 0x34, + 0x40, 0x51, 0x04, 0x04, 0x3d, 0x89, 0xd7, 0x10, 0x8b, 0xb8, 0xd6, 0x9e, 0x5e, 0x8e, 0x39, 0xa9, + 0x44, 0xf8, 0x66, 0xb5, 0xd8, 0x88, 0xfe, 0x6b, 0x6a, 0xd8, 0x97, 0x1a, 0x94, 0x02, 0x10, 0x0a, + 0x7a, 0x90, 0xb0, 0xc6, 0x21, 0xd0, 0xb6, 0xf6, 0xf0, 0x42, 0xbe, 0xa4, 0x93, 0x98, 0xb2, 0x23, + 0xe4, 0x41, 0xfc, 0x1f, 0x35, 0x28, 0x07, 0x61, 0x17, 0x94, 0x20, 0x3f, 0x02, 0xfc, 0xd6, 0x16, + 0x2f, 0x66, 0xbc, 0x78, 0xa9, 0xfc, 0xb3, 0x79, 0x1f, 0x72, 0x02, 0xac, 0x89, 0x0b, 0x88, 0x20, + 0x6c, 0x1c, 0x17, 0x10, 0x21, 0xa4, 0x27, 0x21, 0x20, 0x6c, 0xab, 0x4b, 0x94, 0x10, 0x14, 0x88, + 0x4e, 0x92, 0xc6, 0xd1, 0x21, 0x18, 0x82, 0x83, 0x46, 0x69, 0xf4, 0x43, 0x50, 0xc2, 0x39, 0x28, + 0x41, 0xe0, 0x05, 0x21, 0x18, 0x46, 0x83, 0x12, 0x42, 0x90, 0x29, 0x55, 0x42, 0xd0, 0x07, 0x5f, + 0xe2, 0x42, 0x30, 0x82, 0x88, 0xc7, 0x85, 0x60, 0x14, 0xbf, 0x49, 0x58, 0x57, 0xa6, 0x3b, 0x10, + 0x82, 0x33, 0x31, 0x58, 0x0d, 0x7a, 0x9a, 0xe0, 0xd0, 0x58, 0xb0, 0xbd, 0xf6, 0xd6, 0x25, 0xb9, + 0x47, 0xee, 0x7d, 0xbe, 0x14, 0x72, 0xef, 0x7f, 0xad, 0xc1, 0x6c, 0x1c, 0xd6, 0x83, 0x12, 0x74, + 0x25, 0x00, 0xf5, 0xb5, 0xa5, 0xcb, 0xb2, 0x5f, 0xec, 0x35, 0x2f, 0x1a, 0x9e, 0x57, 0xfe, 0xfb, + 0xbb, 0x79, 0xed, 0xff, 0xbe, 0x9b, 0xd7, 0x7e, 0xf1, 0xdd, 0xbc, 0xf6, 0xaf, 0xbf, 0x9c, 0x9f, + 0x38, 0xcc, 0xb2, 0xff, 0xe1, 0xf5, 0xee, 0x1f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x74, 0x55, 0x61, + 0xe6, 0x68, 0x36, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto index a6cd00ab7c..e80e6e7d0b 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto @@ -15,7 +15,7 @@ service KV { // Range gets the keys in the range from the key-value store. rpc Range(RangeRequest) returns (RangeResponse) { option (google.api.http) = { - post: "/v3alpha/kv/range" + post: "/v3beta/kv/range" body: "*" }; } @@ -25,7 +25,7 @@ service KV { // and generates one event in the event history. rpc Put(PutRequest) returns (PutResponse) { option (google.api.http) = { - post: "/v3alpha/kv/put" + post: "/v3beta/kv/put" body: "*" }; } @@ -35,7 +35,7 @@ service KV { // and generates a delete event in the event history for every deleted key. rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse) { option (google.api.http) = { - post: "/v3alpha/kv/deleterange" + post: "/v3beta/kv/deleterange" body: "*" }; } @@ -46,7 +46,7 @@ service KV { // It is not allowed to modify the same key several times within one txn. rpc Txn(TxnRequest) returns (TxnResponse) { option (google.api.http) = { - post: "/v3alpha/kv/txn" + post: "/v3beta/kv/txn" body: "*" }; } @@ -56,7 +56,7 @@ service KV { // indefinitely. rpc Compact(CompactionRequest) returns (CompactionResponse) { option (google.api.http) = { - post: "/v3alpha/kv/compaction" + post: "/v3beta/kv/compaction" body: "*" }; } @@ -70,7 +70,7 @@ service Watch { // last compaction revision. rpc Watch(stream WatchRequest) returns (stream WatchResponse) { option (google.api.http) = { - post: "/v3alpha/watch" + post: "/v3beta/watch" body: "*" }; } @@ -82,7 +82,7 @@ service Lease { // deleted if the lease expires. Each expired key generates a delete event in the event history. rpc LeaseGrant(LeaseGrantRequest) returns (LeaseGrantResponse) { option (google.api.http) = { - post: "/v3alpha/lease/grant" + post: "/v3beta/lease/grant" body: "*" }; } @@ -90,7 +90,7 @@ service Lease { // LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted. rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) { option (google.api.http) = { - post: "/v3alpha/kv/lease/revoke" + post: "/v3beta/kv/lease/revoke" body: "*" }; } @@ -99,7 +99,7 @@ service Lease { // to the server and streaming keep alive responses from the server to the client. rpc LeaseKeepAlive(stream LeaseKeepAliveRequest) returns (stream LeaseKeepAliveResponse) { option (google.api.http) = { - post: "/v3alpha/lease/keepalive" + post: "/v3beta/lease/keepalive" body: "*" }; } @@ -107,19 +107,25 @@ service Lease { // LeaseTimeToLive retrieves lease information. rpc LeaseTimeToLive(LeaseTimeToLiveRequest) returns (LeaseTimeToLiveResponse) { option (google.api.http) = { - post: "/v3alpha/kv/lease/timetolive" + post: "/v3beta/kv/lease/timetolive" body: "*" }; } - // TODO(xiangli) List all existing Leases? + // LeaseLeases lists all existing leases. + rpc LeaseLeases(LeaseLeasesRequest) returns (LeaseLeasesResponse) { + option (google.api.http) = { + post: "/v3beta/kv/lease/leases" + body: "*" + }; + } } service Cluster { // MemberAdd adds a member into the cluster. rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) { option (google.api.http) = { - post: "/v3alpha/cluster/member/add" + post: "/v3beta/cluster/member/add" body: "*" }; } @@ -127,7 +133,7 @@ service Cluster { // MemberRemove removes an existing member from the cluster. rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) { option (google.api.http) = { - post: "/v3alpha/cluster/member/remove" + post: "/v3beta/cluster/member/remove" body: "*" }; } @@ -135,7 +141,7 @@ service Cluster { // MemberUpdate updates the member configuration. rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) { option (google.api.http) = { - post: "/v3alpha/cluster/member/update" + post: "/v3beta/cluster/member/update" body: "*" }; } @@ -143,7 +149,7 @@ service Cluster { // MemberList lists all the members in the cluster. rpc MemberList(MemberListRequest) returns (MemberListResponse) { option (google.api.http) = { - post: "/v3alpha/cluster/member/list" + post: "/v3beta/cluster/member/list" body: "*" }; } @@ -153,7 +159,7 @@ service Maintenance { // Alarm activates, deactivates, and queries alarms regarding cluster health. rpc Alarm(AlarmRequest) returns (AlarmResponse) { option (google.api.http) = { - post: "/v3alpha/maintenance/alarm" + post: "/v3beta/maintenance/alarm" body: "*" }; } @@ -161,7 +167,7 @@ service Maintenance { // Status gets the status of the member. rpc Status(StatusRequest) returns (StatusResponse) { option (google.api.http) = { - post: "/v3alpha/maintenance/status" + post: "/v3beta/maintenance/status" body: "*" }; } @@ -169,17 +175,25 @@ service Maintenance { // Defragment defragments a member's backend database to recover storage space. rpc Defragment(DefragmentRequest) returns (DefragmentResponse) { option (google.api.http) = { - post: "/v3alpha/maintenance/defragment" + post: "/v3beta/maintenance/defragment" body: "*" }; } - // Hash returns the hash of the local KV state for consistency checking purpose. + // Hash computes the hash of the KV's backend. // This is designed for testing; do not use this in production when there // are ongoing transactions. rpc Hash(HashRequest) returns (HashResponse) { option (google.api.http) = { - post: "/v3alpha/maintenance/hash" + post: "/v3beta/maintenance/hash" + body: "*" + }; + } + + // HashKV computes the hash of all MVCC keys up to a given revision. + rpc HashKV(HashKVRequest) returns (HashKVResponse) { + option (google.api.http) = { + post: "/v3beta/maintenance/hash" body: "*" }; } @@ -187,7 +201,15 @@ service Maintenance { // Snapshot sends a snapshot of the entire backend from a member over a stream to a client. rpc Snapshot(SnapshotRequest) returns (stream SnapshotResponse) { option (google.api.http) = { - post: "/v3alpha/maintenance/snapshot" + post: "/v3beta/maintenance/snapshot" + body: "*" + }; + } + + // MoveLeader requests current leader node to transfer its leadership to transferee. + rpc MoveLeader(MoveLeaderRequest) returns (MoveLeaderResponse) { + option (google.api.http) = { + post: "/v3beta/maintenance/transfer-leadership" body: "*" }; } @@ -197,7 +219,7 @@ service Auth { // AuthEnable enables authentication. rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) { option (google.api.http) = { - post: "/v3alpha/auth/enable" + post: "/v3beta/auth/enable" body: "*" }; } @@ -205,7 +227,7 @@ service Auth { // AuthDisable disables authentication. rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) { option (google.api.http) = { - post: "/v3alpha/auth/disable" + post: "/v3beta/auth/disable" body: "*" }; } @@ -213,7 +235,7 @@ service Auth { // Authenticate processes an authenticate request. rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) { option (google.api.http) = { - post: "/v3alpha/auth/authenticate" + post: "/v3beta/auth/authenticate" body: "*" }; } @@ -221,7 +243,7 @@ service Auth { // UserAdd adds a new user. rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) { option (google.api.http) = { - post: "/v3alpha/auth/user/add" + post: "/v3beta/auth/user/add" body: "*" }; } @@ -229,7 +251,7 @@ service Auth { // UserGet gets detailed user information. rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) { option (google.api.http) = { - post: "/v3alpha/auth/user/get" + post: "/v3beta/auth/user/get" body: "*" }; } @@ -237,7 +259,7 @@ service Auth { // UserList gets a list of all users. rpc UserList(AuthUserListRequest) returns (AuthUserListResponse) { option (google.api.http) = { - post: "/v3alpha/auth/user/list" + post: "/v3beta/auth/user/list" body: "*" }; } @@ -245,7 +267,7 @@ service Auth { // UserDelete deletes a specified user. rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) { option (google.api.http) = { - post: "/v3alpha/auth/user/delete" + post: "/v3beta/auth/user/delete" body: "*" }; } @@ -253,7 +275,7 @@ service Auth { // UserChangePassword changes the password of a specified user. rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) { option (google.api.http) = { - post: "/v3alpha/auth/user/changepw" + post: "/v3beta/auth/user/changepw" body: "*" }; } @@ -261,7 +283,7 @@ service Auth { // UserGrant grants a role to a specified user. rpc UserGrantRole(AuthUserGrantRoleRequest) returns (AuthUserGrantRoleResponse) { option (google.api.http) = { - post: "/v3alpha/auth/user/grant" + post: "/v3beta/auth/user/grant" body: "*" }; } @@ -269,7 +291,7 @@ service Auth { // UserRevokeRole revokes a role of specified user. rpc UserRevokeRole(AuthUserRevokeRoleRequest) returns (AuthUserRevokeRoleResponse) { option (google.api.http) = { - post: "/v3alpha/auth/user/revoke" + post: "/v3beta/auth/user/revoke" body: "*" }; } @@ -277,7 +299,7 @@ service Auth { // RoleAdd adds a new role. rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) { option (google.api.http) = { - post: "/v3alpha/auth/role/add" + post: "/v3beta/auth/role/add" body: "*" }; } @@ -285,7 +307,7 @@ service Auth { // RoleGet gets detailed role information. rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) { option (google.api.http) = { - post: "/v3alpha/auth/role/get" + post: "/v3beta/auth/role/get" body: "*" }; } @@ -293,7 +315,7 @@ service Auth { // RoleList gets lists of all roles. rpc RoleList(AuthRoleListRequest) returns (AuthRoleListResponse) { option (google.api.http) = { - post: "/v3alpha/auth/role/list" + post: "/v3beta/auth/role/list" body: "*" }; } @@ -301,7 +323,7 @@ service Auth { // RoleDelete deletes a specified role. rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) { option (google.api.http) = { - post: "/v3alpha/auth/role/delete" + post: "/v3beta/auth/role/delete" body: "*" }; } @@ -309,7 +331,7 @@ service Auth { // RoleGrantPermission grants a permission of a specified key or range to a specified role. rpc RoleGrantPermission(AuthRoleGrantPermissionRequest) returns (AuthRoleGrantPermissionResponse) { option (google.api.http) = { - post: "/v3alpha/auth/role/grant" + post: "/v3beta/auth/role/grant" body: "*" }; } @@ -317,7 +339,7 @@ service Auth { // RoleRevokePermission revokes a key or range permission of a specified role. rpc RoleRevokePermission(AuthRoleRevokePermissionRequest) returns (AuthRoleRevokePermissionResponse) { option (google.api.http) = { - post: "/v3alpha/auth/role/revoke" + post: "/v3beta/auth/role/revoke" body: "*" }; } @@ -380,7 +402,7 @@ message RangeRequest { // keys_only when set returns only the keys and not the values. bool keys_only = 8; - + // count_only when set returns only the count of the keys in the range. bool count_only = 9; @@ -469,6 +491,7 @@ message RequestOp { RangeRequest request_range = 1; PutRequest request_put = 2; DeleteRangeRequest request_delete_range = 3; + TxnRequest request_txn = 4; } } @@ -478,6 +501,7 @@ message ResponseOp { RangeResponse response_range = 1; PutResponse response_put = 2; DeleteRangeResponse response_delete_range = 3; + TxnResponse response_txn = 4; } } @@ -493,6 +517,7 @@ message Compare { CREATE = 1; MOD = 2; VALUE= 3; + LEASE = 4; } // result is logical comparison operation for this comparison. CompareResult result = 1; @@ -509,7 +534,15 @@ message Compare { int64 mod_revision = 6; // value is the value of the given key, in bytes. bytes value = 7; + // lease is the lease id of the given key. + int64 lease = 8; + // leave room for more target_union field tags, jump to 64 } + + // range_end compares the given target to all keys in the range [key, range_end). + // See RangeRequest for more details on key ranges. + bytes range_end = 64; + // TODO: fill out with most of the rest of RangeRequest fields when needed. } // From google paxosdb paper: @@ -552,7 +585,7 @@ message TxnResponse { // CompactionRequest compacts the key-value store up to a given revision. All superseded keys // with a revision less than the compaction revision will be removed. message CompactionRequest { - // revision is the key-value store revision for the compaction operation. + // revision is the key-value store revision for the compaction operation. int64 revision = 1; // physical is set so the RPC will wait until the compaction is physically // applied to the local database such that compacted entries are totally @@ -567,9 +600,22 @@ message CompactionResponse { message HashRequest { } +message HashKVRequest { + // revision is the key-value store revision for the hash operation. + int64 revision = 1; +} + +message HashKVResponse { + ResponseHeader header = 1; + // hash is the hash value computed from the responding member's MVCC keys up to a given revision. + uint32 hash = 2; + // compact_revision is the compacted revision of key-value store when hash begins. + int64 compact_revision = 3; +} + message HashResponse { ResponseHeader header = 1; - // hash is the hash value computed from the responding member's key-value store. + // hash is the hash value computed from the responding member's KV's backend. uint32 hash = 2; } @@ -648,7 +694,7 @@ message WatchResponse { // at a compacted index. // // This happens when creating a watcher at a compacted revision or the watcher cannot - // catch up with the progress of the key-value store. + // catch up with the progress of the key-value store. // // The client should treat the watcher as canceled and should not try to create any // watcher with the same start_revision again. @@ -661,7 +707,7 @@ message WatchResponse { } message LeaseGrantRequest { - // TTL is the advisory time-to-live in seconds. + // TTL is the advisory time-to-live in seconds. Expired lease will return -1. int64 TTL = 1; // ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID. int64 ID = 2; @@ -717,6 +763,19 @@ message LeaseTimeToLiveResponse { repeated bytes keys = 5; } +message LeaseLeasesRequest { +} + +message LeaseStatus { + int64 ID = 1; + // TODO: int64 TTL = 2; +} + +message LeaseLeasesResponse { + ResponseHeader header = 1; + repeated LeaseStatus leases = 2; +} + message Member { // ID is the member ID for this member. uint64 ID = 1; @@ -781,9 +840,19 @@ message DefragmentResponse { ResponseHeader header = 1; } +message MoveLeaderRequest { + // targetID is the node ID for the new leader. + uint64 targetID = 1; +} + +message MoveLeaderResponse { + ResponseHeader header = 1; +} + enum AlarmType { NONE = 0; // default, used to query if any alarm is active NOSPACE = 1; // space quota is exhausted + CORRUPT = 2; // kv store corruption detected } message AlarmRequest { diff --git a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go index 7033f13266..23fe337a59 100644 --- a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go +++ b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: kv.proto -// DO NOT EDIT! /* Package mvccpb is a generated protocol buffer package. @@ -21,6 +20,8 @@ import ( math "math" + _ "github.com/gogo/protobuf/gogoproto" + io "io" ) @@ -198,24 +199,6 @@ func (m *Event) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func encodeFixed64Kv(dAtA []byte, offset int, v uint64) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - dAtA[offset+4] = uint8(v >> 32) - dAtA[offset+5] = uint8(v >> 40) - dAtA[offset+6] = uint8(v >> 48) - dAtA[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Kv(dAtA []byte, offset int, v uint32) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - return offset + 4 -} func encodeVarintKv(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) diff --git a/vendor/github.com/coreos/etcd/pkg/tlsutil/cipher_suites.go b/vendor/github.com/coreos/etcd/pkg/tlsutil/cipher_suites.go new file mode 100644 index 0000000000..b5916bb54d --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/tlsutil/cipher_suites.go @@ -0,0 +1,51 @@ +// Copyright 2018 The etcd Authors +// +// 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 tlsutil + +import "crypto/tls" + +// cipher suites implemented by Go +// https://github.com/golang/go/blob/dev.boringcrypto.go1.10/src/crypto/tls/cipher_suites.go +var cipherSuites = map[string]uint16{ + "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, +} + +// GetCipherSuite returns the corresponding cipher suite, +// and boolean value if it is supported. +func GetCipherSuite(s string) (uint16, bool) { + v, ok := cipherSuites[s] + return v, ok +} diff --git a/vendor/github.com/coreos/etcd/pkg/types/doc.go b/vendor/github.com/coreos/etcd/pkg/types/doc.go new file mode 100644 index 0000000000..de8ef0bd71 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/types/doc.go @@ -0,0 +1,17 @@ +// Copyright 2015 The etcd Authors +// +// 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 types declares various data types and implements type-checking +// functions. +package types diff --git a/vendor/github.com/coreos/etcd/pkg/types/id.go b/vendor/github.com/coreos/etcd/pkg/types/id.go new file mode 100644 index 0000000000..1b042d9ce6 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/types/id.go @@ -0,0 +1,41 @@ +// Copyright 2015 The etcd Authors +// +// 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 types + +import ( + "strconv" +) + +// ID represents a generic identifier which is canonically +// stored as a uint64 but is typically represented as a +// base-16 string for input/output +type ID uint64 + +func (i ID) String() string { + return strconv.FormatUint(uint64(i), 16) +} + +// IDFromString attempts to create an ID from a base-16 string. +func IDFromString(s string) (ID, error) { + i, err := strconv.ParseUint(s, 16, 64) + return ID(i), err +} + +// IDSlice implements the sort interface +type IDSlice []ID + +func (p IDSlice) Len() int { return len(p) } +func (p IDSlice) Less(i, j int) bool { return uint64(p[i]) < uint64(p[j]) } +func (p IDSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/github.com/coreos/etcd/pkg/types/set.go b/vendor/github.com/coreos/etcd/pkg/types/set.go new file mode 100644 index 0000000000..c111b0c0c0 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/types/set.go @@ -0,0 +1,178 @@ +// Copyright 2015 The etcd Authors +// +// 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 types + +import ( + "reflect" + "sort" + "sync" +) + +type Set interface { + Add(string) + Remove(string) + Contains(string) bool + Equals(Set) bool + Length() int + Values() []string + Copy() Set + Sub(Set) Set +} + +func NewUnsafeSet(values ...string) *unsafeSet { + set := &unsafeSet{make(map[string]struct{})} + for _, v := range values { + set.Add(v) + } + return set +} + +func NewThreadsafeSet(values ...string) *tsafeSet { + us := NewUnsafeSet(values...) + return &tsafeSet{us, sync.RWMutex{}} +} + +type unsafeSet struct { + d map[string]struct{} +} + +// Add adds a new value to the set (no-op if the value is already present) +func (us *unsafeSet) Add(value string) { + us.d[value] = struct{}{} +} + +// Remove removes the given value from the set +func (us *unsafeSet) Remove(value string) { + delete(us.d, value) +} + +// Contains returns whether the set contains the given value +func (us *unsafeSet) Contains(value string) (exists bool) { + _, exists = us.d[value] + return exists +} + +// ContainsAll returns whether the set contains all given values +func (us *unsafeSet) ContainsAll(values []string) bool { + for _, s := range values { + if !us.Contains(s) { + return false + } + } + return true +} + +// Equals returns whether the contents of two sets are identical +func (us *unsafeSet) Equals(other Set) bool { + v1 := sort.StringSlice(us.Values()) + v2 := sort.StringSlice(other.Values()) + v1.Sort() + v2.Sort() + return reflect.DeepEqual(v1, v2) +} + +// Length returns the number of elements in the set +func (us *unsafeSet) Length() int { + return len(us.d) +} + +// Values returns the values of the Set in an unspecified order. +func (us *unsafeSet) Values() (values []string) { + values = make([]string, 0) + for val := range us.d { + values = append(values, val) + } + return values +} + +// Copy creates a new Set containing the values of the first +func (us *unsafeSet) Copy() Set { + cp := NewUnsafeSet() + for val := range us.d { + cp.Add(val) + } + + return cp +} + +// Sub removes all elements in other from the set +func (us *unsafeSet) Sub(other Set) Set { + oValues := other.Values() + result := us.Copy().(*unsafeSet) + + for _, val := range oValues { + if _, ok := result.d[val]; !ok { + continue + } + delete(result.d, val) + } + + return result +} + +type tsafeSet struct { + us *unsafeSet + m sync.RWMutex +} + +func (ts *tsafeSet) Add(value string) { + ts.m.Lock() + defer ts.m.Unlock() + ts.us.Add(value) +} + +func (ts *tsafeSet) Remove(value string) { + ts.m.Lock() + defer ts.m.Unlock() + ts.us.Remove(value) +} + +func (ts *tsafeSet) Contains(value string) (exists bool) { + ts.m.RLock() + defer ts.m.RUnlock() + return ts.us.Contains(value) +} + +func (ts *tsafeSet) Equals(other Set) bool { + ts.m.RLock() + defer ts.m.RUnlock() + return ts.us.Equals(other) +} + +func (ts *tsafeSet) Length() int { + ts.m.RLock() + defer ts.m.RUnlock() + return ts.us.Length() +} + +func (ts *tsafeSet) Values() (values []string) { + ts.m.RLock() + defer ts.m.RUnlock() + return ts.us.Values() +} + +func (ts *tsafeSet) Copy() Set { + ts.m.RLock() + defer ts.m.RUnlock() + usResult := ts.us.Copy().(*unsafeSet) + return &tsafeSet{usResult, sync.RWMutex{}} +} + +func (ts *tsafeSet) Sub(other Set) Set { + ts.m.RLock() + defer ts.m.RUnlock() + usResult := ts.us.Sub(other).(*unsafeSet) + return &tsafeSet{usResult, sync.RWMutex{}} +} diff --git a/vendor/github.com/coreos/etcd/pkg/types/slice.go b/vendor/github.com/coreos/etcd/pkg/types/slice.go new file mode 100644 index 0000000000..0dd9ca798a --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/types/slice.go @@ -0,0 +1,22 @@ +// Copyright 2015 The etcd Authors +// +// 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 types + +// Uint64Slice implements sort interface +type Uint64Slice []uint64 + +func (p Uint64Slice) Len() int { return len(p) } +func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] } +func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/github.com/coreos/etcd/pkg/types/urls.go b/vendor/github.com/coreos/etcd/pkg/types/urls.go new file mode 100644 index 0000000000..9e5d03ff64 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/types/urls.go @@ -0,0 +1,82 @@ +// Copyright 2015 The etcd Authors +// +// 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 types + +import ( + "errors" + "fmt" + "net" + "net/url" + "sort" + "strings" +) + +type URLs []url.URL + +func NewURLs(strs []string) (URLs, error) { + all := make([]url.URL, len(strs)) + if len(all) == 0 { + return nil, errors.New("no valid URLs given") + } + for i, in := range strs { + in = strings.TrimSpace(in) + u, err := url.Parse(in) + if err != nil { + return nil, err + } + if u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "unix" && u.Scheme != "unixs" { + return nil, fmt.Errorf("URL scheme must be http, https, unix, or unixs: %s", in) + } + if _, _, err := net.SplitHostPort(u.Host); err != nil { + return nil, fmt.Errorf(`URL address does not have the form "host:port": %s`, in) + } + if u.Path != "" { + return nil, fmt.Errorf("URL must not contain a path: %s", in) + } + all[i] = *u + } + us := URLs(all) + us.Sort() + + return us, nil +} + +func MustNewURLs(strs []string) URLs { + urls, err := NewURLs(strs) + if err != nil { + panic(err) + } + return urls +} + +func (us URLs) String() string { + return strings.Join(us.StringSlice(), ",") +} + +func (us *URLs) Sort() { + sort.Sort(us) +} +func (us URLs) Len() int { return len(us) } +func (us URLs) Less(i, j int) bool { return us[i].String() < us[j].String() } +func (us URLs) Swap(i, j int) { us[i], us[j] = us[j], us[i] } + +func (us URLs) StringSlice() []string { + out := make([]string, len(us)) + for i := range us { + out[i] = us[i].String() + } + + return out +} diff --git a/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go b/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go new file mode 100644 index 0000000000..47690cc381 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go @@ -0,0 +1,107 @@ +// Copyright 2015 The etcd Authors +// +// 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 types + +import ( + "fmt" + "sort" + "strings" +) + +// URLsMap is a map from a name to its URLs. +type URLsMap map[string]URLs + +// NewURLsMap returns a URLsMap instantiated from the given string, +// which consists of discovery-formatted names-to-URLs, like: +// mach0=http://1.1.1.1:2380,mach0=http://2.2.2.2::2380,mach1=http://3.3.3.3:2380,mach2=http://4.4.4.4:2380 +func NewURLsMap(s string) (URLsMap, error) { + m := parse(s) + + cl := URLsMap{} + for name, urls := range m { + us, err := NewURLs(urls) + if err != nil { + return nil, err + } + cl[name] = us + } + return cl, nil +} + +// NewURLsMapFromStringMap takes a map of strings and returns a URLsMap. The +// string values in the map can be multiple values separated by the sep string. +func NewURLsMapFromStringMap(m map[string]string, sep string) (URLsMap, error) { + var err error + um := URLsMap{} + for k, v := range m { + um[k], err = NewURLs(strings.Split(v, sep)) + if err != nil { + return nil, err + } + } + return um, nil +} + +// String turns URLsMap into discovery-formatted name-to-URLs sorted by name. +func (c URLsMap) String() string { + var pairs []string + for name, urls := range c { + for _, url := range urls { + pairs = append(pairs, fmt.Sprintf("%s=%s", name, url.String())) + } + } + sort.Strings(pairs) + return strings.Join(pairs, ",") +} + +// URLs returns a list of all URLs. +// The returned list is sorted in ascending lexicographical order. +func (c URLsMap) URLs() []string { + var urls []string + for _, us := range c { + for _, u := range us { + urls = append(urls, u.String()) + } + } + sort.Strings(urls) + return urls +} + +// Len returns the size of URLsMap. +func (c URLsMap) Len() int { + return len(c) +} + +// parse parses the given string and returns a map listing the values specified for each key. +func parse(s string) map[string][]string { + m := make(map[string][]string) + for s != "" { + key := s + if i := strings.IndexAny(key, ","); i >= 0 { + key, s = key[:i], key[i+1:] + } else { + s = "" + } + if key == "" { + continue + } + value := "" + if i := strings.Index(key, "="); i >= 0 { + key, value = key[:i], key[i+1:] + } + m[key] = append(m[key], value) + } + return m +} diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/LICENSE b/vendor/github.com/coreos/go-systemd/LICENSE similarity index 100% rename from vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/LICENSE rename to vendor/github.com/coreos/go-systemd/LICENSE diff --git a/vendor/github.com/coreos/go-systemd/NOTICE b/vendor/github.com/coreos/go-systemd/NOTICE new file mode 100644 index 0000000000..23a0ada2fb --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-systemd/activation/files.go b/vendor/github.com/coreos/go-systemd/activation/files.go new file mode 100644 index 0000000000..29dd18defa --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/activation/files.go @@ -0,0 +1,67 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 activation implements primitives for systemd socket activation. +package activation + +import ( + "os" + "strconv" + "strings" + "syscall" +) + +const ( + // listenFdsStart corresponds to `SD_LISTEN_FDS_START`. + listenFdsStart = 3 +) + +// Files returns a slice containing a `os.File` object for each +// file descriptor passed to this process via systemd fd-passing protocol. +// +// The order of the file descriptors is preserved in the returned slice. +// `unsetEnv` is typically set to `true` in order to avoid clashes in +// fd usage and to avoid leaking environment flags to child processes. +func Files(unsetEnv bool) []*os.File { + if unsetEnv { + defer os.Unsetenv("LISTEN_PID") + defer os.Unsetenv("LISTEN_FDS") + defer os.Unsetenv("LISTEN_FDNAMES") + } + + pid, err := strconv.Atoi(os.Getenv("LISTEN_PID")) + if err != nil || pid != os.Getpid() { + return nil + } + + nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) + if err != nil || nfds == 0 { + return nil + } + + names := strings.Split(os.Getenv("LISTEN_FDNAMES"), ":") + + files := make([]*os.File, 0, nfds) + for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ { + syscall.CloseOnExec(fd) + name := "LISTEN_FD_" + strconv.Itoa(fd) + offset := fd - listenFdsStart + if offset < len(names) && len(names[offset]) > 0 { + name = names[offset] + } + files = append(files, os.NewFile(uintptr(fd), name)) + } + + return files +} diff --git a/vendor/github.com/coreos/go-systemd/activation/listeners.go b/vendor/github.com/coreos/go-systemd/activation/listeners.go new file mode 100644 index 0000000000..bb5cc2311e --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/activation/listeners.go @@ -0,0 +1,103 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 activation + +import ( + "crypto/tls" + "net" +) + +// Listeners returns a slice containing a net.Listener for each matching socket type +// passed to this process. +// +// The order of the file descriptors is preserved in the returned slice. +// Nil values are used to fill any gaps. For example if systemd were to return file descriptors +// corresponding with "udp, tcp, tcp", then the slice would contain {nil, net.Listener, net.Listener} +func Listeners() ([]net.Listener, error) { + files := Files(true) + listeners := make([]net.Listener, len(files)) + + for i, f := range files { + if pc, err := net.FileListener(f); err == nil { + listeners[i] = pc + f.Close() + } + } + return listeners, nil +} + +// ListenersWithNames maps a listener name to a set of net.Listener instances. +func ListenersWithNames() (map[string][]net.Listener, error) { + files := Files(true) + listeners := map[string][]net.Listener{} + + for _, f := range files { + if pc, err := net.FileListener(f); err == nil { + current, ok := listeners[f.Name()] + if !ok { + listeners[f.Name()] = []net.Listener{pc} + } else { + listeners[f.Name()] = append(current, pc) + } + f.Close() + } + } + return listeners, nil +} + +// TLSListeners returns a slice containing a net.listener for each matching TCP socket type +// passed to this process. +// It uses default Listeners func and forces TCP sockets handlers to use TLS based on tlsConfig. +func TLSListeners(tlsConfig *tls.Config) ([]net.Listener, error) { + listeners, err := Listeners() + + if listeners == nil || err != nil { + return nil, err + } + + if tlsConfig != nil && err == nil { + for i, l := range listeners { + // Activate TLS only for TCP sockets + if l.Addr().Network() == "tcp" { + listeners[i] = tls.NewListener(l, tlsConfig) + } + } + } + + return listeners, err +} + +// TLSListenersWithNames maps a listener name to a net.Listener with +// the associated TLS configuration. +func TLSListenersWithNames(tlsConfig *tls.Config) (map[string][]net.Listener, error) { + listeners, err := ListenersWithNames() + + if listeners == nil || err != nil { + return nil, err + } + + if tlsConfig != nil && err == nil { + for _, ll := range listeners { + // Activate TLS only for TCP sockets + for i, l := range ll { + if l.Addr().Network() == "tcp" { + ll[i] = tls.NewListener(l, tlsConfig) + } + } + } + } + + return listeners, err +} diff --git a/vendor/github.com/coreos/go-systemd/activation/packetconns.go b/vendor/github.com/coreos/go-systemd/activation/packetconns.go new file mode 100644 index 0000000000..a97206785a --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/activation/packetconns.go @@ -0,0 +1,38 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 activation + +import ( + "net" +) + +// PacketConns returns a slice containing a net.PacketConn for each matching socket type +// passed to this process. +// +// The order of the file descriptors is preserved in the returned slice. +// Nil values are used to fill any gaps. For example if systemd were to return file descriptors +// corresponding with "udp, tcp, udp", then the slice would contain {net.PacketConn, nil, net.PacketConn} +func PacketConns() ([]net.PacketConn, error) { + files := Files(true) + conns := make([]net.PacketConn, len(files)) + + for i, f := range files { + if pc, err := net.FilePacketConn(f); err == nil { + conns[i] = pc + f.Close() + } + } + return conns, nil +} diff --git a/vendor/github.com/coreos/go-systemd/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/dbus/dbus.go new file mode 100644 index 0000000000..1d54810aff --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/dbus/dbus.go @@ -0,0 +1,240 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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. + +// Integration with the systemd D-Bus API. See http://www.freedesktop.org/wiki/Software/systemd/dbus/ +package dbus + +import ( + "encoding/hex" + "fmt" + "os" + "strconv" + "strings" + "sync" + + "github.com/godbus/dbus" +) + +const ( + alpha = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ` + num = `0123456789` + alphanum = alpha + num + signalBuffer = 100 +) + +// needsEscape checks whether a byte in a potential dbus ObjectPath needs to be escaped +func needsEscape(i int, b byte) bool { + // Escape everything that is not a-z-A-Z-0-9 + // Also escape 0-9 if it's the first character + return strings.IndexByte(alphanum, b) == -1 || + (i == 0 && strings.IndexByte(num, b) != -1) +} + +// PathBusEscape sanitizes a constituent string of a dbus ObjectPath using the +// rules that systemd uses for serializing special characters. +func PathBusEscape(path string) string { + // Special case the empty string + if len(path) == 0 { + return "_" + } + n := []byte{} + for i := 0; i < len(path); i++ { + c := path[i] + if needsEscape(i, c) { + e := fmt.Sprintf("_%x", c) + n = append(n, []byte(e)...) + } else { + n = append(n, c) + } + } + return string(n) +} + +// pathBusUnescape is the inverse of PathBusEscape. +func pathBusUnescape(path string) string { + if path == "_" { + return "" + } + n := []byte{} + for i := 0; i < len(path); i++ { + c := path[i] + if c == '_' && i+2 < len(path) { + res, err := hex.DecodeString(path[i+1 : i+3]) + if err == nil { + n = append(n, res...) + } + i += 2 + } else { + n = append(n, c) + } + } + return string(n) +} + +// Conn is a connection to systemd's dbus endpoint. +type Conn struct { + // sysconn/sysobj are only used to call dbus methods + sysconn *dbus.Conn + sysobj dbus.BusObject + + // sigconn/sigobj are only used to receive dbus signals + sigconn *dbus.Conn + sigobj dbus.BusObject + + jobListener struct { + jobs map[dbus.ObjectPath]chan<- string + sync.Mutex + } + subStateSubscriber struct { + updateCh chan<- *SubStateUpdate + errCh chan<- error + sync.Mutex + ignore map[dbus.ObjectPath]int64 + cleanIgnore int64 + } + propertiesSubscriber struct { + updateCh chan<- *PropertiesUpdate + errCh chan<- error + sync.Mutex + } +} + +// New establishes a connection to any available bus and authenticates. +// Callers should call Close() when done with the connection. +func New() (*Conn, error) { + conn, err := NewSystemConnection() + if err != nil && os.Geteuid() == 0 { + return NewSystemdConnection() + } + return conn, err +} + +// NewSystemConnection establishes a connection to the system bus and authenticates. +// Callers should call Close() when done with the connection +func NewSystemConnection() (*Conn, error) { + return NewConnection(func() (*dbus.Conn, error) { + return dbusAuthHelloConnection(dbus.SystemBusPrivate) + }) +} + +// NewUserConnection establishes a connection to the session bus and +// authenticates. This can be used to connect to systemd user instances. +// Callers should call Close() when done with the connection. +func NewUserConnection() (*Conn, error) { + return NewConnection(func() (*dbus.Conn, error) { + return dbusAuthHelloConnection(dbus.SessionBusPrivate) + }) +} + +// NewSystemdConnection establishes a private, direct connection to systemd. +// This can be used for communicating with systemd without a dbus daemon. +// Callers should call Close() when done with the connection. +func NewSystemdConnection() (*Conn, error) { + return NewConnection(func() (*dbus.Conn, error) { + // We skip Hello when talking directly to systemd. + return dbusAuthConnection(func() (*dbus.Conn, error) { + return dbus.Dial("unix:path=/run/systemd/private") + }) + }) +} + +// Close closes an established connection +func (c *Conn) Close() { + c.sysconn.Close() + c.sigconn.Close() +} + +// NewConnection establishes a connection to a bus using a caller-supplied function. +// This allows connecting to remote buses through a user-supplied mechanism. +// The supplied function may be called multiple times, and should return independent connections. +// The returned connection must be fully initialised: the org.freedesktop.DBus.Hello call must have succeeded, +// and any authentication should be handled by the function. +func NewConnection(dialBus func() (*dbus.Conn, error)) (*Conn, error) { + sysconn, err := dialBus() + if err != nil { + return nil, err + } + + sigconn, err := dialBus() + if err != nil { + sysconn.Close() + return nil, err + } + + c := &Conn{ + sysconn: sysconn, + sysobj: systemdObject(sysconn), + sigconn: sigconn, + sigobj: systemdObject(sigconn), + } + + c.subStateSubscriber.ignore = make(map[dbus.ObjectPath]int64) + c.jobListener.jobs = make(map[dbus.ObjectPath]chan<- string) + + // Setup the listeners on jobs so that we can get completions + c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, + "type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'") + + c.dispatch() + return c, nil +} + +// GetManagerProperty returns the value of a property on the org.freedesktop.systemd1.Manager +// interface. The value is returned in its string representation, as defined at +// https://developer.gnome.org/glib/unstable/gvariant-text.html +func (c *Conn) GetManagerProperty(prop string) (string, error) { + variant, err := c.sysobj.GetProperty("org.freedesktop.systemd1.Manager." + prop) + if err != nil { + return "", err + } + return variant.String(), nil +} + +func dbusAuthConnection(createBus func() (*dbus.Conn, error)) (*dbus.Conn, error) { + conn, err := createBus() + if err != nil { + return nil, err + } + + // Only use EXTERNAL method, and hardcode the uid (not username) + // to avoid a username lookup (which requires a dynamically linked + // libc) + methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))} + + err = conn.Auth(methods) + if err != nil { + conn.Close() + return nil, err + } + + return conn, nil +} + +func dbusAuthHelloConnection(createBus func() (*dbus.Conn, error)) (*dbus.Conn, error) { + conn, err := dbusAuthConnection(createBus) + if err != nil { + return nil, err + } + + if err = conn.Hello(); err != nil { + conn.Close() + return nil, err + } + + return conn, nil +} + +func systemdObject(conn *dbus.Conn) dbus.BusObject { + return conn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1")) +} diff --git a/vendor/github.com/coreos/go-systemd/dbus/methods.go b/vendor/github.com/coreos/go-systemd/dbus/methods.go new file mode 100644 index 0000000000..0b4207229f --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/dbus/methods.go @@ -0,0 +1,592 @@ +// Copyright 2015, 2018 CoreOS, Inc. +// +// 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 dbus + +import ( + "errors" + "fmt" + "path" + "strconv" + + "github.com/godbus/dbus" +) + +func (c *Conn) jobComplete(signal *dbus.Signal) { + var id uint32 + var job dbus.ObjectPath + var unit string + var result string + dbus.Store(signal.Body, &id, &job, &unit, &result) + c.jobListener.Lock() + out, ok := c.jobListener.jobs[job] + if ok { + out <- result + delete(c.jobListener.jobs, job) + } + c.jobListener.Unlock() +} + +func (c *Conn) startJob(ch chan<- string, job string, args ...interface{}) (int, error) { + if ch != nil { + c.jobListener.Lock() + defer c.jobListener.Unlock() + } + + var p dbus.ObjectPath + err := c.sysobj.Call(job, 0, args...).Store(&p) + if err != nil { + return 0, err + } + + if ch != nil { + c.jobListener.jobs[p] = ch + } + + // ignore error since 0 is fine if conversion fails + jobID, _ := strconv.Atoi(path.Base(string(p))) + + return jobID, nil +} + +// StartUnit enqueues a start job and depending jobs, if any (unless otherwise +// specified by the mode string). +// +// Takes the unit to activate, plus a mode string. The mode needs to be one of +// replace, fail, isolate, ignore-dependencies, ignore-requirements. If +// "replace" the call will start the unit and its dependencies, possibly +// replacing already queued jobs that conflict with this. If "fail" the call +// will start the unit and its dependencies, but will fail if this would change +// an already queued job. If "isolate" the call will start the unit in question +// and terminate all units that aren't dependencies of it. If +// "ignore-dependencies" it will start a unit but ignore all its dependencies. +// If "ignore-requirements" it will start a unit but only ignore the +// requirement dependencies. It is not recommended to make use of the latter +// two options. +// +// If the provided channel is non-nil, a result string will be sent to it upon +// job completion: one of done, canceled, timeout, failed, dependency, skipped. +// done indicates successful execution of a job. canceled indicates that a job +// has been canceled before it finished execution. timeout indicates that the +// job timeout was reached. failed indicates that the job failed. dependency +// indicates that a job this job has been depending on failed and the job hence +// has been removed too. skipped indicates that a job was skipped because it +// didn't apply to the units current state. +// +// If no error occurs, the ID of the underlying systemd job will be returned. There +// does exist the possibility for no error to be returned, but for the returned job +// ID to be 0. In this case, the actual underlying ID is not 0 and this datapoint +// should not be considered authoritative. +// +// If an error does occur, it will be returned to the user alongside a job ID of 0. +func (c *Conn) StartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode) +} + +// StopUnit is similar to StartUnit but stops the specified unit rather +// than starting it. +func (c *Conn) StopUnit(name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode) +} + +// ReloadUnit reloads a unit. Reloading is done only if the unit is already running and fails otherwise. +func (c *Conn) ReloadUnit(name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode) +} + +// RestartUnit restarts a service. If a service is restarted that isn't +// running it will be started. +func (c *Conn) RestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode) +} + +// TryRestartUnit is like RestartUnit, except that a service that isn't running +// is not affected by the restart. +func (c *Conn) TryRestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode) +} + +// ReloadOrRestart attempts a reload if the unit supports it and use a restart +// otherwise. +func (c *Conn) ReloadOrRestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode) +} + +// ReloadOrTryRestart attempts a reload if the unit supports it and use a "Try" +// flavored restart otherwise. +func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode) +} + +// StartTransientUnit() may be used to create and start a transient unit, which +// will be released as soon as it is not running or referenced anymore or the +// system is rebooted. name is the unit name including suffix, and must be +// unique. mode is the same as in StartUnit(), properties contains properties +// of the unit. +func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) { + return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0)) +} + +// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's +// processes are killed. +func (c *Conn) KillUnit(name string, signal int32) { + c.sysobj.Call("org.freedesktop.systemd1.Manager.KillUnit", 0, name, "all", signal).Store() +} + +// ResetFailedUnit resets the "failed" state of a specific unit. +func (c *Conn) ResetFailedUnit(name string) error { + return c.sysobj.Call("org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store() +} + +// SystemState returns the systemd state. Equivalent to `systemctl is-system-running`. +func (c *Conn) SystemState() (*Property, error) { + var err error + var prop dbus.Variant + + obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") + err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop) + if err != nil { + return nil, err + } + + return &Property{Name: "SystemState", Value: prop}, nil +} + +// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface +func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) { + var err error + var props map[string]dbus.Variant + + if !path.IsValid() { + return nil, fmt.Errorf("invalid unit name: %v", path) + } + + obj := c.sysconn.Object("org.freedesktop.systemd1", path) + err = obj.Call("org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props) + if err != nil { + return nil, err + } + + out := make(map[string]interface{}, len(props)) + for k, v := range props { + out[k] = v.Value() + } + + return out, nil +} + +// GetUnitProperties takes the (unescaped) unit name and returns all of its dbus object properties. +func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) { + path := unitPath(unit) + return c.getProperties(path, "org.freedesktop.systemd1.Unit") +} + +// GetUnitProperties takes the (escaped) unit path and returns all of its dbus object properties. +func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) { + return c.getProperties(path, "org.freedesktop.systemd1.Unit") +} + +func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) { + var err error + var prop dbus.Variant + + path := unitPath(unit) + if !path.IsValid() { + return nil, errors.New("invalid unit name: " + unit) + } + + obj := c.sysconn.Object("org.freedesktop.systemd1", path) + err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop) + if err != nil { + return nil, err + } + + return &Property{Name: propertyName, Value: prop}, nil +} + +func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) { + return c.getProperty(unit, "org.freedesktop.systemd1.Unit", propertyName) +} + +// GetServiceProperty returns property for given service name and property name +func (c *Conn) GetServiceProperty(service string, propertyName string) (*Property, error) { + return c.getProperty(service, "org.freedesktop.systemd1.Service", propertyName) +} + +// GetUnitTypeProperties returns the extra properties for a unit, specific to the unit type. +// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope +// return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit +func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) { + path := unitPath(unit) + return c.getProperties(path, "org.freedesktop.systemd1."+unitType) +} + +// SetUnitProperties() may be used to modify certain unit properties at runtime. +// Not all properties may be changed at runtime, but many resource management +// settings (primarily those in systemd.cgroup(5)) may. The changes are applied +// instantly, and stored on disk for future boots, unless runtime is true, in which +// case the settings only apply until the next reboot. name is the name of the unit +// to modify. properties are the settings to set, encoded as an array of property +// name and value pairs. +func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error { + return c.sysobj.Call("org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store() +} + +func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) { + return c.getProperty(unit, "org.freedesktop.systemd1."+unitType, propertyName) +} + +type UnitStatus struct { + Name string // The primary unit name as string + Description string // The human readable description string + LoadState string // The load state (i.e. whether the unit file has been loaded successfully) + ActiveState string // The active state (i.e. whether the unit is currently started or not) + SubState string // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not) + Followed string // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string. + Path dbus.ObjectPath // The unit object path + JobId uint32 // If there is a job queued for the job unit the numeric job id, 0 otherwise + JobType string // The job type as string + JobPath dbus.ObjectPath // The job object path +} + +type storeFunc func(retvalues ...interface{}) error + +func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) { + result := make([][]interface{}, 0) + err := f(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + status := make([]UnitStatus, len(result)) + statusInterface := make([]interface{}, len(status)) + for i := range status { + statusInterface[i] = &status[i] + } + + err = dbus.Store(resultInterface, statusInterface...) + if err != nil { + return nil, err + } + + return status, nil +} + +// ListUnits returns an array with all currently loaded units. Note that +// units may be known by multiple names at the same time, and hence there might +// be more unit names loaded than actual units behind them. +func (c *Conn) ListUnits() ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnits", 0).Store) +} + +// ListUnitsFiltered returns an array with units filtered by state. +// It takes a list of units' statuses to filter. +func (c *Conn) ListUnitsFiltered(states []string) ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store) +} + +// ListUnitsByPatterns returns an array with units. +// It takes a list of units' statuses and names to filter. +// Note that units may be known by multiple names at the same time, +// and hence there might be more unit names loaded than actual units behind them. +func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store) +} + +// ListUnitsByNames returns an array with units. It takes a list of units' +// names and returns an UnitStatus array. Comparing to ListUnitsByPatterns +// method, this method returns statuses even for inactive or non-existing +// units. Input array should contain exact unit names, but not patterns. +// Note: Requires systemd v230 or higher +func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store) +} + +type UnitFile struct { + Path string + Type string +} + +func (c *Conn) listUnitFilesInternal(f storeFunc) ([]UnitFile, error) { + result := make([][]interface{}, 0) + err := f(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + files := make([]UnitFile, len(result)) + fileInterface := make([]interface{}, len(files)) + for i := range files { + fileInterface[i] = &files[i] + } + + err = dbus.Store(resultInterface, fileInterface...) + if err != nil { + return nil, err + } + + return files, nil +} + +// ListUnitFiles returns an array of all available units on disk. +func (c *Conn) ListUnitFiles() ([]UnitFile, error) { + return c.listUnitFilesInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store) +} + +// ListUnitFilesByPatterns returns an array of all available units on disk matched the patterns. +func (c *Conn) ListUnitFilesByPatterns(states []string, patterns []string) ([]UnitFile, error) { + return c.listUnitFilesInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store) +} + +type LinkUnitFileChange EnableUnitFileChange + +// LinkUnitFiles() links unit files (that are located outside of the +// usual unit search paths) into the unit search path. +// +// It takes a list of absolute paths to unit files to link and two +// booleans. The first boolean controls whether the unit shall be +// enabled for runtime only (true, /run), or persistently (false, +// /etc). +// The second controls whether symlinks pointing to other units shall +// be replaced if necessary. +// +// This call returns a list of the changes made. The list consists of +// structures with three strings: the type of the change (one of symlink +// or unlink), the file name of the symlink and the destination of the +// symlink. +func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.Call("org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]LinkUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +// EnableUnitFiles() may be used to enable one or more units in the system (by +// creating symlinks to them in /etc or /run). +// +// It takes a list of unit files to enable (either just file names or full +// absolute paths if the unit files are residing outside the usual unit +// search paths), and two booleans: the first controls whether the unit shall +// be enabled for runtime only (true, /run), or persistently (false, /etc). +// The second one controls whether symlinks pointing to other units shall +// be replaced if necessary. +// +// This call returns one boolean and an array with the changes made. The +// boolean signals whether the unit files contained any enablement +// information (i.e. an [Install]) section. The changes list consists of +// structures with three strings: the type of the change (one of symlink +// or unlink), the file name of the symlink and the destination of the +// symlink. +func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { + var carries_install_info bool + + result := make([][]interface{}, 0) + err := c.sysobj.Call("org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result) + if err != nil { + return false, nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]EnableUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return false, nil, err + } + + return carries_install_info, changes, nil +} + +type EnableUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// DisableUnitFiles() may be used to disable one or more units in the system (by +// removing symlinks to them from /etc or /run). +// +// It takes a list of unit files to disable (either just file names or full +// absolute paths if the unit files are residing outside the usual unit +// search paths), and one boolean: whether the unit was enabled for runtime +// only (true, /run), or persistently (false, /etc). +// +// This call returns an array with the changes made. The changes list +// consists of structures with three strings: the type of the change (one of +// symlink or unlink), the file name of the symlink and the destination of the +// symlink. +func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.Call("org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]DisableUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +type DisableUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// MaskUnitFiles masks one or more units in the system +// +// It takes three arguments: +// * list of units to mask (either just file names or full +// absolute paths if the unit files are residing outside +// the usual unit search paths) +// * runtime to specify whether the unit was enabled for runtime +// only (true, /run/systemd/..), or persistently (false, /etc/systemd/..) +// * force flag +func (c *Conn) MaskUnitFiles(files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.Call("org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]MaskUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +type MaskUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// UnmaskUnitFiles unmasks one or more units in the system +// +// It takes two arguments: +// * list of unit files to mask (either just file names or full +// absolute paths if the unit files are residing outside +// the usual unit search paths) +// * runtime to specify whether the unit was enabled for runtime +// only (true, /run/systemd/..), or persistently (false, /etc/systemd/..) +func (c *Conn) UnmaskUnitFiles(files []string, runtime bool) ([]UnmaskUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.Call("org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]UnmaskUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +type UnmaskUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// Reload instructs systemd to scan for and reload unit files. This is +// equivalent to a 'systemctl daemon-reload'. +func (c *Conn) Reload() error { + return c.sysobj.Call("org.freedesktop.systemd1.Manager.Reload", 0).Store() +} + +func unitPath(name string) dbus.ObjectPath { + return dbus.ObjectPath("/org/freedesktop/systemd1/unit/" + PathBusEscape(name)) +} + +// unitName returns the unescaped base element of the supplied escaped path +func unitName(dpath dbus.ObjectPath) string { + return pathBusUnescape(path.Base(string(dpath))) +} diff --git a/vendor/github.com/coreos/go-systemd/dbus/properties.go b/vendor/github.com/coreos/go-systemd/dbus/properties.go new file mode 100644 index 0000000000..6c81895876 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/dbus/properties.go @@ -0,0 +1,237 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 dbus + +import ( + "github.com/godbus/dbus" +) + +// From the systemd docs: +// +// The properties array of StartTransientUnit() may take many of the settings +// that may also be configured in unit files. Not all parameters are currently +// accepted though, but we plan to cover more properties with future release. +// Currently you may set the Description, Slice and all dependency types of +// units, as well as RemainAfterExit, ExecStart for service units, +// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares, +// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth, +// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit, +// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map +// directly to their counterparts in unit files and as normal D-Bus object +// properties. The exception here is the PIDs field of scope units which is +// used for construction of the scope only and specifies the initial PIDs to +// add to the scope object. + +type Property struct { + Name string + Value dbus.Variant +} + +type PropertyCollection struct { + Name string + Properties []Property +} + +type execStart struct { + Path string // the binary path to execute + Args []string // an array with all arguments to pass to the executed command, starting with argument 0 + UncleanIsFailure bool // a boolean whether it should be considered a failure if the process exits uncleanly +} + +// PropExecStart sets the ExecStart service property. The first argument is a +// slice with the binary path to execute followed by the arguments to pass to +// the executed command. See +// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= +func PropExecStart(command []string, uncleanIsFailure bool) Property { + execStarts := []execStart{ + execStart{ + Path: command[0], + Args: command, + UncleanIsFailure: uncleanIsFailure, + }, + } + + return Property{ + Name: "ExecStart", + Value: dbus.MakeVariant(execStarts), + } +} + +// PropRemainAfterExit sets the RemainAfterExit service property. See +// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit= +func PropRemainAfterExit(b bool) Property { + return Property{ + Name: "RemainAfterExit", + Value: dbus.MakeVariant(b), + } +} + +// PropType sets the Type service property. See +// http://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= +func PropType(t string) Property { + return Property{ + Name: "Type", + Value: dbus.MakeVariant(t), + } +} + +// PropDescription sets the Description unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description= +func PropDescription(desc string) Property { + return Property{ + Name: "Description", + Value: dbus.MakeVariant(desc), + } +} + +func propDependency(name string, units []string) Property { + return Property{ + Name: name, + Value: dbus.MakeVariant(units), + } +} + +// PropRequires sets the Requires unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires= +func PropRequires(units ...string) Property { + return propDependency("Requires", units) +} + +// PropRequiresOverridable sets the RequiresOverridable unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresOverridable= +func PropRequiresOverridable(units ...string) Property { + return propDependency("RequiresOverridable", units) +} + +// PropRequisite sets the Requisite unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requisite= +func PropRequisite(units ...string) Property { + return propDependency("Requisite", units) +} + +// PropRequisiteOverridable sets the RequisiteOverridable unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequisiteOverridable= +func PropRequisiteOverridable(units ...string) Property { + return propDependency("RequisiteOverridable", units) +} + +// PropWants sets the Wants unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Wants= +func PropWants(units ...string) Property { + return propDependency("Wants", units) +} + +// PropBindsTo sets the BindsTo unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo= +func PropBindsTo(units ...string) Property { + return propDependency("BindsTo", units) +} + +// PropRequiredBy sets the RequiredBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredBy= +func PropRequiredBy(units ...string) Property { + return propDependency("RequiredBy", units) +} + +// PropRequiredByOverridable sets the RequiredByOverridable unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredByOverridable= +func PropRequiredByOverridable(units ...string) Property { + return propDependency("RequiredByOverridable", units) +} + +// PropWantedBy sets the WantedBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy= +func PropWantedBy(units ...string) Property { + return propDependency("WantedBy", units) +} + +// PropBoundBy sets the BoundBy unit property. See +// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy= +func PropBoundBy(units ...string) Property { + return propDependency("BoundBy", units) +} + +// PropConflicts sets the Conflicts unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Conflicts= +func PropConflicts(units ...string) Property { + return propDependency("Conflicts", units) +} + +// PropConflictedBy sets the ConflictedBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConflictedBy= +func PropConflictedBy(units ...string) Property { + return propDependency("ConflictedBy", units) +} + +// PropBefore sets the Before unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before= +func PropBefore(units ...string) Property { + return propDependency("Before", units) +} + +// PropAfter sets the After unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#After= +func PropAfter(units ...string) Property { + return propDependency("After", units) +} + +// PropOnFailure sets the OnFailure unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#OnFailure= +func PropOnFailure(units ...string) Property { + return propDependency("OnFailure", units) +} + +// PropTriggers sets the Triggers unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Triggers= +func PropTriggers(units ...string) Property { + return propDependency("Triggers", units) +} + +// PropTriggeredBy sets the TriggeredBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#TriggeredBy= +func PropTriggeredBy(units ...string) Property { + return propDependency("TriggeredBy", units) +} + +// PropPropagatesReloadTo sets the PropagatesReloadTo unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#PropagatesReloadTo= +func PropPropagatesReloadTo(units ...string) Property { + return propDependency("PropagatesReloadTo", units) +} + +// PropRequiresMountsFor sets the RequiresMountsFor unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresMountsFor= +func PropRequiresMountsFor(units ...string) Property { + return propDependency("RequiresMountsFor", units) +} + +// PropSlice sets the Slice unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Slice= +func PropSlice(slice string) Property { + return Property{ + Name: "Slice", + Value: dbus.MakeVariant(slice), + } +} + +// PropPids sets the PIDs field of scope units used in the initial construction +// of the scope only and specifies the initial PIDs to add to the scope object. +// See https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/#properties +func PropPids(pids ...uint32) Property { + return Property{ + Name: "PIDs", + Value: dbus.MakeVariant(pids), + } +} diff --git a/vendor/github.com/coreos/go-systemd/dbus/set.go b/vendor/github.com/coreos/go-systemd/dbus/set.go new file mode 100644 index 0000000000..17c5d48565 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/dbus/set.go @@ -0,0 +1,47 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 dbus + +type set struct { + data map[string]bool +} + +func (s *set) Add(value string) { + s.data[value] = true +} + +func (s *set) Remove(value string) { + delete(s.data, value) +} + +func (s *set) Contains(value string) (exists bool) { + _, exists = s.data[value] + return +} + +func (s *set) Length() int { + return len(s.data) +} + +func (s *set) Values() (values []string) { + for val := range s.data { + values = append(values, val) + } + return +} + +func newSet() *set { + return &set{make(map[string]bool)} +} diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription.go b/vendor/github.com/coreos/go-systemd/dbus/subscription.go new file mode 100644 index 0000000000..70e63a6f16 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/dbus/subscription.go @@ -0,0 +1,333 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 dbus + +import ( + "errors" + "log" + "time" + + "github.com/godbus/dbus" +) + +const ( + cleanIgnoreInterval = int64(10 * time.Second) + ignoreInterval = int64(30 * time.Millisecond) +) + +// Subscribe sets up this connection to subscribe to all systemd dbus events. +// This is required before calling SubscribeUnits. When the connection closes +// systemd will automatically stop sending signals so there is no need to +// explicitly call Unsubscribe(). +func (c *Conn) Subscribe() error { + c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, + "type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'") + c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, + "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'") + + return c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store() +} + +// Unsubscribe this connection from systemd dbus events. +func (c *Conn) Unsubscribe() error { + return c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store() +} + +func (c *Conn) dispatch() { + ch := make(chan *dbus.Signal, signalBuffer) + + c.sigconn.Signal(ch) + + go func() { + for { + signal, ok := <-ch + if !ok { + return + } + + if signal.Name == "org.freedesktop.systemd1.Manager.JobRemoved" { + c.jobComplete(signal) + } + + if c.subStateSubscriber.updateCh == nil && + c.propertiesSubscriber.updateCh == nil { + continue + } + + var unitPath dbus.ObjectPath + switch signal.Name { + case "org.freedesktop.systemd1.Manager.JobRemoved": + unitName := signal.Body[2].(string) + c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath) + case "org.freedesktop.systemd1.Manager.UnitNew": + unitPath = signal.Body[1].(dbus.ObjectPath) + case "org.freedesktop.DBus.Properties.PropertiesChanged": + if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" { + unitPath = signal.Path + + if len(signal.Body) >= 2 { + if changed, ok := signal.Body[1].(map[string]dbus.Variant); ok { + c.sendPropertiesUpdate(unitPath, changed) + } + } + } + } + + if unitPath == dbus.ObjectPath("") { + continue + } + + c.sendSubStateUpdate(unitPath) + } + }() +} + +// Returns two unbuffered channels which will receive all changed units every +// interval. Deleted units are sent as nil. +func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) { + return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, nil) +} + +// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer +// size of the channels, the comparison function for detecting changes and a filter +// function for cutting down on the noise that your channel receives. +func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func(string) bool) (<-chan map[string]*UnitStatus, <-chan error) { + old := make(map[string]*UnitStatus) + statusChan := make(chan map[string]*UnitStatus, buffer) + errChan := make(chan error, buffer) + + go func() { + for { + timerChan := time.After(interval) + + units, err := c.ListUnits() + if err == nil { + cur := make(map[string]*UnitStatus) + for i := range units { + if filterUnit != nil && filterUnit(units[i].Name) { + continue + } + cur[units[i].Name] = &units[i] + } + + // add all new or changed units + changed := make(map[string]*UnitStatus) + for n, u := range cur { + if oldU, ok := old[n]; !ok || isChanged(oldU, u) { + changed[n] = u + } + delete(old, n) + } + + // add all deleted units + for oldN := range old { + changed[oldN] = nil + } + + old = cur + + if len(changed) != 0 { + statusChan <- changed + } + } else { + errChan <- err + } + + <-timerChan + } + }() + + return statusChan, errChan +} + +type SubStateUpdate struct { + UnitName string + SubState string +} + +// SetSubStateSubscriber writes to updateCh when any unit's substate changes. +// Although this writes to updateCh on every state change, the reported state +// may be more recent than the change that generated it (due to an unavoidable +// race in the systemd dbus interface). That is, this method provides a good +// way to keep a current view of all units' states, but is not guaranteed to +// show every state transition they go through. Furthermore, state changes +// will only be written to the channel with non-blocking writes. If updateCh +// is full, it attempts to write an error to errCh; if errCh is full, the error +// passes silently. +func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) { + if c == nil { + msg := "nil receiver" + select { + case errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } + + c.subStateSubscriber.Lock() + defer c.subStateSubscriber.Unlock() + c.subStateSubscriber.updateCh = updateCh + c.subStateSubscriber.errCh = errCh +} + +func (c *Conn) sendSubStateUpdate(unitPath dbus.ObjectPath) { + c.subStateSubscriber.Lock() + defer c.subStateSubscriber.Unlock() + + if c.subStateSubscriber.updateCh == nil { + return + } + + isIgnored := c.shouldIgnore(unitPath) + defer c.cleanIgnore() + if isIgnored { + return + } + + info, err := c.GetUnitPathProperties(unitPath) + if err != nil { + select { + case c.subStateSubscriber.errCh <- err: + default: + log.Printf("full error channel while reporting: %s\n", err) + } + return + } + defer c.updateIgnore(unitPath, info) + + name, ok := info["Id"].(string) + if !ok { + msg := "failed to cast info.Id" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", err) + } + return + } + substate, ok := info["SubState"].(string) + if !ok { + msg := "failed to cast info.SubState" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } + + update := &SubStateUpdate{name, substate} + select { + case c.subStateSubscriber.updateCh <- update: + default: + msg := "update channel is full" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } +} + +// The ignore functions work around a wart in the systemd dbus interface. +// Requesting the properties of an unloaded unit will cause systemd to send a +// pair of UnitNew/UnitRemoved signals. Because we need to get a unit's +// properties on UnitNew (as that's the only indication of a new unit coming up +// for the first time), we would enter an infinite loop if we did not attempt +// to detect and ignore these spurious signals. The signal themselves are +// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an +// unloaded unit's signals for a short time after requesting its properties. +// This means that we will miss e.g. a transient unit being restarted +// *immediately* upon failure and also a transient unit being started +// immediately after requesting its status (with systemctl status, for example, +// because this causes a UnitNew signal to be sent which then causes us to fetch +// the properties). + +func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool { + t, ok := c.subStateSubscriber.ignore[path] + return ok && t >= time.Now().UnixNano() +} + +func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) { + loadState, ok := info["LoadState"].(string) + if !ok { + return + } + + // unit is unloaded - it will trigger bad systemd dbus behavior + if loadState == "not-found" { + c.subStateSubscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval + } +} + +// without this, ignore would grow unboundedly over time +func (c *Conn) cleanIgnore() { + now := time.Now().UnixNano() + if c.subStateSubscriber.cleanIgnore < now { + c.subStateSubscriber.cleanIgnore = now + cleanIgnoreInterval + + for p, t := range c.subStateSubscriber.ignore { + if t < now { + delete(c.subStateSubscriber.ignore, p) + } + } + } +} + +// PropertiesUpdate holds a map of a unit's changed properties +type PropertiesUpdate struct { + UnitName string + Changed map[string]dbus.Variant +} + +// SetPropertiesSubscriber writes to updateCh when any unit's properties +// change. Every property change reported by systemd will be sent; that is, no +// transitions will be "missed" (as they might be with SetSubStateSubscriber). +// However, state changes will only be written to the channel with non-blocking +// writes. If updateCh is full, it attempts to write an error to errCh; if +// errCh is full, the error passes silently. +func (c *Conn) SetPropertiesSubscriber(updateCh chan<- *PropertiesUpdate, errCh chan<- error) { + c.propertiesSubscriber.Lock() + defer c.propertiesSubscriber.Unlock() + c.propertiesSubscriber.updateCh = updateCh + c.propertiesSubscriber.errCh = errCh +} + +// we don't need to worry about shouldIgnore() here because +// sendPropertiesUpdate doesn't call GetProperties() +func (c *Conn) sendPropertiesUpdate(unitPath dbus.ObjectPath, changedProps map[string]dbus.Variant) { + c.propertiesSubscriber.Lock() + defer c.propertiesSubscriber.Unlock() + + if c.propertiesSubscriber.updateCh == nil { + return + } + + update := &PropertiesUpdate{unitName(unitPath), changedProps} + + select { + case c.propertiesSubscriber.updateCh <- update: + default: + msg := "update channel is full" + select { + case c.propertiesSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } +} diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription_set.go b/vendor/github.com/coreos/go-systemd/dbus/subscription_set.go new file mode 100644 index 0000000000..5b408d5847 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/dbus/subscription_set.go @@ -0,0 +1,57 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 dbus + +import ( + "time" +) + +// SubscriptionSet returns a subscription set which is like conn.Subscribe but +// can filter to only return events for a set of units. +type SubscriptionSet struct { + *set + conn *Conn +} + +func (s *SubscriptionSet) filter(unit string) bool { + return !s.Contains(unit) +} + +// Subscribe starts listening for dbus events for all of the units in the set. +// Returns channels identical to conn.SubscribeUnits. +func (s *SubscriptionSet) Subscribe() (<-chan map[string]*UnitStatus, <-chan error) { + // TODO: Make fully evented by using systemd 209 with properties changed values + return s.conn.SubscribeUnitsCustom(time.Second, 0, + mismatchUnitStatus, + func(unit string) bool { return s.filter(unit) }, + ) +} + +// NewSubscriptionSet returns a new subscription set. +func (conn *Conn) NewSubscriptionSet() *SubscriptionSet { + return &SubscriptionSet{newSet(), conn} +} + +// mismatchUnitStatus returns true if the provided UnitStatus objects +// are not equivalent. false is returned if the objects are equivalent. +// Only the Name, Description and state-related fields are used in +// the comparison. +func mismatchUnitStatus(u1, u2 *UnitStatus) bool { + return u1.Name != u2.Name || + u1.Description != u2.Description || + u1.LoadState != u2.LoadState || + u1.ActiveState != u2.ActiveState || + u1.SubState != u2.SubState +} diff --git a/vendor/github.com/coreos/go-systemd/util/util.go b/vendor/github.com/coreos/go-systemd/util/util.go new file mode 100644 index 0000000000..7828ce6f04 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/util/util.go @@ -0,0 +1,90 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 util contains utility functions related to systemd that applications +// can use to check things like whether systemd is running. Note that some of +// these functions attempt to manually load systemd libraries at runtime rather +// than linking against them. +package util + +import ( + "fmt" + "io/ioutil" + "os" + "strings" +) + +var ( + ErrNoCGO = fmt.Errorf("go-systemd built with CGO disabled") +) + +// GetRunningSlice attempts to retrieve the name of the systemd slice in which +// the current process is running. +// This function is a wrapper around the libsystemd C library; if it cannot be +// opened, an error is returned. +func GetRunningSlice() (string, error) { + return getRunningSlice() +} + +// RunningFromSystemService tries to detect whether the current process has +// been invoked from a system service. The condition for this is whether the +// process is _not_ a user process. User processes are those running in session +// scopes or under per-user `systemd --user` instances. +// +// To avoid false positives on systems without `pam_systemd` (which is +// responsible for creating user sessions), this function also uses a heuristic +// to detect whether it's being invoked from a session leader process. This is +// the case if the current process is executed directly from a service file +// (e.g. with `ExecStart=/this/cmd`). Note that this heuristic will fail if the +// command is instead launched in a subshell or similar so that it is not +// session leader (e.g. `ExecStart=/bin/bash -c "/this/cmd"`) +// +// This function is a wrapper around the libsystemd C library; if this is +// unable to successfully open a handle to the library for any reason (e.g. it +// cannot be found), an error will be returned. +func RunningFromSystemService() (bool, error) { + return runningFromSystemService() +} + +// CurrentUnitName attempts to retrieve the name of the systemd system unit +// from which the calling process has been invoked. It wraps the systemd +// `sd_pid_get_unit` call, with the same caveat: for processes not part of a +// systemd system unit, this function will return an error. +func CurrentUnitName() (string, error) { + return currentUnitName() +} + +// IsRunningSystemd checks whether the host was booted with systemd as its init +// system. This functions similarly to systemd's `sd_booted(3)`: internally, it +// checks whether /run/systemd/system/ exists and is a directory. +// http://www.freedesktop.org/software/systemd/man/sd_booted.html +func IsRunningSystemd() bool { + fi, err := os.Lstat("/run/systemd/system") + if err != nil { + return false + } + return fi.IsDir() +} + +// GetMachineID returns a host's 128-bit machine ID as a string. This functions +// similarly to systemd's `sd_id128_get_machine`: internally, it simply reads +// the contents of /etc/machine-id +// http://www.freedesktop.org/software/systemd/man/sd_id128_get_machine.html +func GetMachineID() (string, error) { + machineID, err := ioutil.ReadFile("/etc/machine-id") + if err != nil { + return "", fmt.Errorf("failed to read /etc/machine-id: %v", err) + } + return strings.TrimSpace(string(machineID)), nil +} diff --git a/vendor/github.com/coreos/go-systemd/util/util_cgo.go b/vendor/github.com/coreos/go-systemd/util/util_cgo.go new file mode 100644 index 0000000000..6269bc7323 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/util/util_cgo.go @@ -0,0 +1,175 @@ +// Copyright 2016 CoreOS, Inc. +// +// 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. + +// +build cgo + +package util + +// #include +// #include +// #include +// +// int +// my_sd_pid_get_owner_uid(void *f, pid_t pid, uid_t *uid) +// { +// int (*sd_pid_get_owner_uid)(pid_t, uid_t *); +// +// sd_pid_get_owner_uid = (int (*)(pid_t, uid_t *))f; +// return sd_pid_get_owner_uid(pid, uid); +// } +// +// int +// my_sd_pid_get_unit(void *f, pid_t pid, char **unit) +// { +// int (*sd_pid_get_unit)(pid_t, char **); +// +// sd_pid_get_unit = (int (*)(pid_t, char **))f; +// return sd_pid_get_unit(pid, unit); +// } +// +// int +// my_sd_pid_get_slice(void *f, pid_t pid, char **slice) +// { +// int (*sd_pid_get_slice)(pid_t, char **); +// +// sd_pid_get_slice = (int (*)(pid_t, char **))f; +// return sd_pid_get_slice(pid, slice); +// } +// +// int +// am_session_leader() +// { +// return (getsid(0) == getpid()); +// } +import "C" +import ( + "fmt" + "syscall" + "unsafe" + + "github.com/coreos/pkg/dlopen" +) + +var libsystemdNames = []string{ + // systemd < 209 + "libsystemd-login.so.0", + "libsystemd-login.so", + + // systemd >= 209 merged libsystemd-login into libsystemd proper + "libsystemd.so.0", + "libsystemd.so", +} + +func getRunningSlice() (slice string, err error) { + var h *dlopen.LibHandle + h, err = dlopen.GetHandle(libsystemdNames) + if err != nil { + return + } + defer func() { + if err1 := h.Close(); err1 != nil { + err = err1 + } + }() + + sd_pid_get_slice, err := h.GetSymbolPointer("sd_pid_get_slice") + if err != nil { + return + } + + var s string + sl := C.CString(s) + defer C.free(unsafe.Pointer(sl)) + + ret := C.my_sd_pid_get_slice(sd_pid_get_slice, 0, &sl) + if ret < 0 { + err = fmt.Errorf("error calling sd_pid_get_slice: %v", syscall.Errno(-ret)) + return + } + + return C.GoString(sl), nil +} + +func runningFromSystemService() (ret bool, err error) { + var h *dlopen.LibHandle + h, err = dlopen.GetHandle(libsystemdNames) + if err != nil { + return + } + defer func() { + if err1 := h.Close(); err1 != nil { + err = err1 + } + }() + + sd_pid_get_owner_uid, err := h.GetSymbolPointer("sd_pid_get_owner_uid") + if err != nil { + return + } + + var uid C.uid_t + errno := C.my_sd_pid_get_owner_uid(sd_pid_get_owner_uid, 0, &uid) + serrno := syscall.Errno(-errno) + // when we're running from a unit file, sd_pid_get_owner_uid returns + // ENOENT (systemd <220), ENXIO (systemd 220-223), or ENODATA + // (systemd >=234) + switch { + case errno >= 0: + ret = false + case serrno == syscall.ENOENT, serrno == syscall.ENXIO, serrno == syscall.ENODATA: + // Since the implementation of sessions in systemd relies on + // the `pam_systemd` module, using the sd_pid_get_owner_uid + // heuristic alone can result in false positives if that module + // (or PAM itself) is not present or properly configured on the + // system. As such, we also check if we're the session leader, + // which should be the case if we're invoked from a unit file, + // but not if e.g. we're invoked from the command line from a + // user's login session + ret = C.am_session_leader() == 1 + default: + err = fmt.Errorf("error calling sd_pid_get_owner_uid: %v", syscall.Errno(-errno)) + } + return +} + +func currentUnitName() (unit string, err error) { + var h *dlopen.LibHandle + h, err = dlopen.GetHandle(libsystemdNames) + if err != nil { + return + } + defer func() { + if err1 := h.Close(); err1 != nil { + err = err1 + } + }() + + sd_pid_get_unit, err := h.GetSymbolPointer("sd_pid_get_unit") + if err != nil { + return + } + + var s string + u := C.CString(s) + defer C.free(unsafe.Pointer(u)) + + ret := C.my_sd_pid_get_unit(sd_pid_get_unit, 0, &u) + if ret < 0 { + err = fmt.Errorf("error calling sd_pid_get_unit: %v", syscall.Errno(-ret)) + return + } + + unit = C.GoString(u) + return +} diff --git a/vendor/github.com/coreos/go-systemd/util/util_stub.go b/vendor/github.com/coreos/go-systemd/util/util_stub.go new file mode 100644 index 0000000000..477589e122 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/util/util_stub.go @@ -0,0 +1,23 @@ +// Copyright 2016 CoreOS, Inc. +// +// 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. + +// +build !cgo + +package util + +func getRunningSlice() (string, error) { return "", ErrNoCGO } + +func runningFromSystemService() (bool, error) { return false, ErrNoCGO } + +func currentUnitName() (string, error) { return "", ErrNoCGO } diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/LICENSE b/vendor/github.com/coreos/pkg/LICENSE similarity index 93% rename from vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/LICENSE rename to vendor/github.com/coreos/pkg/LICENSE index c7a3f0cfd4..e06d208186 100644 --- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/LICENSE +++ b/vendor/github.com/coreos/pkg/LICENSE @@ -1,7 +1,6 @@ - - Apache License +Apache License Version 2.0, January 2004 - https://www.apache.org/licenses/ + http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -176,16 +175,28 @@ END OF TERMS AND CONDITIONS - Copyright 2013-2015 Docker, Inc. + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} 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 - https://www.apache.org/licenses/LICENSE-2.0 + 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. + diff --git a/vendor/github.com/coreos/pkg/NOTICE b/vendor/github.com/coreos/pkg/NOTICE new file mode 100644 index 0000000000..b39ddfa5cb --- /dev/null +++ b/vendor/github.com/coreos/pkg/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen.go b/vendor/github.com/coreos/pkg/dlopen/dlopen.go new file mode 100644 index 0000000000..23774f612e --- /dev/null +++ b/vendor/github.com/coreos/pkg/dlopen/dlopen.go @@ -0,0 +1,82 @@ +// Copyright 2016 CoreOS, Inc. +// +// 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 dlopen provides some convenience functions to dlopen a library and +// get its symbols. +package dlopen + +// #cgo LDFLAGS: -ldl +// #include +// #include +import "C" +import ( + "errors" + "fmt" + "unsafe" +) + +var ErrSoNotFound = errors.New("unable to open a handle to the library") + +// LibHandle represents an open handle to a library (.so) +type LibHandle struct { + Handle unsafe.Pointer + Libname string +} + +// GetHandle tries to get a handle to a library (.so), attempting to access it +// by the names specified in libs and returning the first that is successfully +// opened. Callers are responsible for closing the handler. If no library can +// be successfully opened, an error is returned. +func GetHandle(libs []string) (*LibHandle, error) { + for _, name := range libs { + libname := C.CString(name) + defer C.free(unsafe.Pointer(libname)) + handle := C.dlopen(libname, C.RTLD_LAZY) + if handle != nil { + h := &LibHandle{ + Handle: handle, + Libname: name, + } + return h, nil + } + } + return nil, ErrSoNotFound +} + +// GetSymbolPointer takes a symbol name and returns a pointer to the symbol. +func (l *LibHandle) GetSymbolPointer(symbol string) (unsafe.Pointer, error) { + sym := C.CString(symbol) + defer C.free(unsafe.Pointer(sym)) + + C.dlerror() + p := C.dlsym(l.Handle, sym) + e := C.dlerror() + if e != nil { + return nil, fmt.Errorf("error resolving symbol %q: %v", symbol, errors.New(C.GoString(e))) + } + + return p, nil +} + +// Close closes a LibHandle. +func (l *LibHandle) Close() error { + C.dlerror() + C.dlclose(l.Handle) + e := C.dlerror() + if e != nil { + return fmt.Errorf("error closing %v: %v", l.Libname, errors.New(C.GoString(e))) + } + + return nil +} diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go b/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go new file mode 100644 index 0000000000..48a660104f --- /dev/null +++ b/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go @@ -0,0 +1,56 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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. +// +// +build linux + +package dlopen + +// #include +// #include +// +// int +// my_strlen(void *f, const char *s) +// { +// size_t (*strlen)(const char *); +// +// strlen = (size_t (*)(const char *))f; +// return strlen(s); +// } +import "C" + +import ( + "fmt" + "unsafe" +) + +func strlen(libs []string, s string) (int, error) { + h, err := GetHandle(libs) + if err != nil { + return -1, fmt.Errorf(`couldn't get a handle to the library: %v`, err) + } + defer h.Close() + + f := "strlen" + cs := C.CString(s) + defer C.free(unsafe.Pointer(cs)) + + strlen, err := h.GetSymbolPointer(f) + if err != nil { + return -1, fmt.Errorf(`couldn't get symbol %q: %v`, f, err) + } + + len := C.my_strlen(strlen, cs) + + return int(len), nil +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/.travis.yml b/vendor/github.com/cyphar/filepath-securejoin/.travis.yml new file mode 100644 index 0000000000..3938f38349 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/.travis.yml @@ -0,0 +1,19 @@ +# Copyright (C) 2017 SUSE LLC. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +language: go +go: + - 1.7.x + - 1.8.x + - tip + +os: + - linux + - osx + +script: + - go test -cover -v ./... + +notifications: + email: false diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/LICENSE b/vendor/github.com/cyphar/filepath-securejoin/LICENSE similarity index 92% rename from vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/LICENSE rename to vendor/github.com/cyphar/filepath-securejoin/LICENSE index ac74d8f049..bec842f294 100644 --- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/LICENSE +++ b/vendor/github.com/cyphar/filepath-securejoin/LICENSE @@ -1,4 +1,5 @@ -Copyright (c) 2014-2015 The Docker & Go Authors. All rights reserved. +Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. +Copyright (C) 2017 SUSE LLC. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/vendor/github.com/cyphar/filepath-securejoin/README.md b/vendor/github.com/cyphar/filepath-securejoin/README.md new file mode 100644 index 0000000000..49b2baa9f3 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/README.md @@ -0,0 +1,65 @@ +## `filepath-securejoin` ## + +[![Build Status](https://travis-ci.org/cyphar/filepath-securejoin.svg?branch=master)](https://travis-ci.org/cyphar/filepath-securejoin) + +An implementation of `SecureJoin`, a [candidate for inclusion in the Go +standard library][go#20126]. The purpose of this function is to be a "secure" +alternative to `filepath.Join`, and in particular it provides certain +guarantees that are not provided by `filepath.Join`. + +This is the function prototype: + +```go +func SecureJoin(root, unsafePath string) (string, error) +``` + +This library **guarantees** the following: + +* If no error is set, the resulting string **must** be a child path of + `SecureJoin` and will not contain any symlink path components (they will all + be expanded). + +* When expanding symlinks, all symlink path components **must** be resolved + relative to the provided root. In particular, this can be considered a + userspace implementation of how `chroot(2)` operates on file paths. Note that + these symlinks will **not** be expanded lexically (`filepath.Clean` is not + called on the input before processing). + +* Non-existant path components are unaffected by `SecureJoin` (similar to + `filepath.EvalSymlinks`'s semantics). + +* The returned path will always be `filepath.Clean`ed and thus not contain any + `..` components. + +A (trivial) implementation of this function on GNU/Linux systems could be done +with the following (note that this requires root privileges and is far more +opaque than the implementation in this library, and also requires that +`readlink` is inside the `root` path): + +```go +package securejoin + +import ( + "os/exec" + "path/filepath" +) + +func SecureJoin(root, unsafePath string) (string, error) { + unsafePath = string(filepath.Separator) + unsafePath + cmd := exec.Command("chroot", root, + "readlink", "--canonicalize-missing", "--no-newline", unsafePath) + output, err := cmd.CombinedOutput() + if err != nil { + return "", err + } + expanded := string(output) + return filepath.Join(root, expanded), nil +} +``` + +[go#20126]: https://github.com/golang/go/issues/20126 + +### License ### + +The license of this project is the same as Go, which is a BSD 3-clause license +available in the `LICENSE` file. diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION new file mode 100644 index 0000000000..0c62199f16 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/VERSION @@ -0,0 +1 @@ +0.2.1 diff --git a/vendor/github.com/cyphar/filepath-securejoin/join.go b/vendor/github.com/cyphar/filepath-securejoin/join.go new file mode 100644 index 0000000000..f20985479d --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/join.go @@ -0,0 +1,135 @@ +// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. +// Copyright (C) 2017 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package securejoin is an implementation of the hopefully-soon-to-be-included +// SecureJoin helper that is meant to be part of the "path/filepath" package. +// The purpose of this project is to provide a PoC implementation to make the +// SecureJoin proposal (https://github.com/golang/go/issues/20126) more +// tangible. +package securejoin + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "strings" + "syscall" + + "github.com/pkg/errors" +) + +// ErrSymlinkLoop is returned by SecureJoinVFS when too many symlinks have been +// evaluated in attempting to securely join the two given paths. +var ErrSymlinkLoop = fmt.Errorf("SecureJoin: too many links") + +// IsNotExist tells you if err is an error that implies that either the path +// accessed does not exist (or path components don't exist). This is +// effectively a more broad version of os.IsNotExist. +func IsNotExist(err error) bool { + // If it's a bone-fide ENOENT just bail. + if os.IsNotExist(errors.Cause(err)) { + return true + } + + // Check that it's not actually an ENOTDIR, which in some cases is a more + // convoluted case of ENOENT (usually involving weird paths). + var errno error + switch err := errors.Cause(err).(type) { + case *os.PathError: + errno = err.Err + case *os.LinkError: + errno = err.Err + case *os.SyscallError: + errno = err.Err + } + return errno == syscall.ENOTDIR || errno == syscall.ENOENT +} + +// SecureJoinVFS joins the two given path components (similar to Join) except +// that the returned path is guaranteed to be scoped inside the provided root +// path (when evaluated). Any symbolic links in the path are evaluated with the +// given root treated as the root of the filesystem, similar to a chroot. The +// filesystem state is evaluated through the given VFS interface (if nil, the +// standard os.* family of functions are used). +// +// Note that the guarantees provided by this function only apply if the path +// components in the returned string are not modified (in other words are not +// replaced with symlinks on the filesystem) after this function has returned. +// Such a symlink race is necessarily out-of-scope of SecureJoin. +func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { + // Use the os.* VFS implementation if none was specified. + if vfs == nil { + vfs = osVFS{} + } + + var path bytes.Buffer + n := 0 + for unsafePath != "" { + if n > 255 { + return "", ErrSymlinkLoop + } + + // Next path component, p. + i := strings.IndexRune(unsafePath, filepath.Separator) + var p string + if i == -1 { + p, unsafePath = unsafePath, "" + } else { + p, unsafePath = unsafePath[:i], unsafePath[i+1:] + } + + // Create a cleaned path, using the lexical semantics of /../a, to + // create a "scoped" path component which can safely be joined to fullP + // for evaluation. At this point, path.String() doesn't contain any + // symlink components. + cleanP := filepath.Clean(string(filepath.Separator) + path.String() + p) + if cleanP == string(filepath.Separator) { + path.Reset() + continue + } + fullP := filepath.Clean(root + cleanP) + + // Figure out whether the path is a symlink. + fi, err := vfs.Lstat(fullP) + if err != nil && !IsNotExist(err) { + return "", err + } + // Treat non-existent path components the same as non-symlinks (we + // can't do any better here). + if IsNotExist(err) || fi.Mode()&os.ModeSymlink == 0 { + path.WriteString(p) + path.WriteRune(filepath.Separator) + continue + } + + // Only increment when we actually dereference a link. + n++ + + // It's a symlink, expand it by prepending it to the yet-unparsed path. + dest, err := vfs.Readlink(fullP) + if err != nil { + return "", err + } + // Absolute symlinks reset any work we've already done. + if filepath.IsAbs(dest) { + path.Reset() + } + unsafePath = dest + string(filepath.Separator) + unsafePath + } + + // We have to clean path.String() here because it may contain '..' + // components that are entirely lexical, but would be misleading otherwise. + // And finally do a final clean to ensure that root is also lexically + // clean. + fullP := filepath.Clean(string(filepath.Separator) + path.String()) + return filepath.Clean(root + fullP), nil +} + +// SecureJoin is a wrapper around SecureJoinVFS that just uses the os.* library +// of functions as the VFS. If in doubt, use this function over SecureJoinVFS. +func SecureJoin(root, unsafePath string) (string, error) { + return SecureJoinVFS(root, unsafePath, nil) +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/vendor.conf b/vendor/github.com/cyphar/filepath-securejoin/vendor.conf new file mode 100644 index 0000000000..66bb574b95 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/vendor.conf @@ -0,0 +1 @@ +github.com/pkg/errors v0.8.0 diff --git a/vendor/github.com/cyphar/filepath-securejoin/vfs.go b/vendor/github.com/cyphar/filepath-securejoin/vfs.go new file mode 100644 index 0000000000..a82a5eae11 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/vfs.go @@ -0,0 +1,41 @@ +// Copyright (C) 2017 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package securejoin + +import "os" + +// In future this should be moved into a separate package, because now there +// are several projects (umoci and go-mtree) that are using this sort of +// interface. + +// VFS is the minimal interface necessary to use SecureJoinVFS. A nil VFS is +// equivalent to using the standard os.* family of functions. This is mainly +// used for the purposes of mock testing, but also can be used to otherwise use +// SecureJoin with VFS-like system. +type VFS interface { + // Lstat returns a FileInfo describing the named file. If the file is a + // symbolic link, the returned FileInfo describes the symbolic link. Lstat + // makes no attempt to follow the link. These semantics are identical to + // os.Lstat. + Lstat(name string) (os.FileInfo, error) + + // Readlink returns the destination of the named symbolic link. These + // semantics are identical to os.Readlink. + Readlink(name string) (string, error) +} + +// osVFS is the "nil" VFS, in that it just passes everything through to the os +// module. +type osVFS struct{} + +// Lstat returns a FileInfo describing the named file. If the file is a +// symbolic link, the returned FileInfo describes the symbolic link. Lstat +// makes no attempt to follow the link. These semantics are identical to +// os.Lstat. +func (o osVFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) } + +// Readlink returns the destination of the named symbolic link. These +// semantics are identical to os.Readlink. +func (o osVFS) Readlink(name string) (string, error) { return os.Readlink(name) } diff --git a/vendor/github.com/dgrijalva/jwt-go/.gitignore b/vendor/github.com/dgrijalva/jwt-go/.gitignore new file mode 100644 index 0000000000..80bed650ec --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +bin + + diff --git a/vendor/github.com/dgrijalva/jwt-go/.travis.yml b/vendor/github.com/dgrijalva/jwt-go/.travis.yml new file mode 100644 index 0000000000..1027f56cd9 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/.travis.yml @@ -0,0 +1,13 @@ +language: go + +script: + - go vet ./... + - go test -v ./... + +go: + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - 1.7 + - tip diff --git a/vendor/github.com/ungerik/pkgreflect/LICENSE b/vendor/github.com/dgrijalva/jwt-go/LICENSE similarity index 94% rename from vendor/github.com/ungerik/pkgreflect/LICENSE rename to vendor/github.com/dgrijalva/jwt-go/LICENSE index 3fb89d20d7..df83a9c2f0 100644 --- a/vendor/github.com/ungerik/pkgreflect/LICENSE +++ b/vendor/github.com/dgrijalva/jwt-go/LICENSE @@ -1,8 +1,8 @@ -MIT License -Copyright (c) 2012 Erik Unger +Copyright (c) 2012 Dave Grijalva Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md b/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md new file mode 100644 index 0000000000..7fc1f793cb --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md @@ -0,0 +1,97 @@ +## Migration Guide from v2 -> v3 + +Version 3 adds several new, frequently requested features. To do so, it introduces a few breaking changes. We've worked to keep these as minimal as possible. This guide explains the breaking changes and how you can quickly update your code. + +### `Token.Claims` is now an interface type + +The most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`. We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`. + +`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior. It is the default claims type when using `Parse`. The usage is unchanged except you must type cast the claims property. + +The old example for parsing a token looked like this.. + +```go + if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil { + fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"]) + } +``` + +is now directly mapped to... + +```go + if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil { + claims := token.Claims.(jwt.MapClaims) + fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"]) + } +``` + +`StandardClaims` is designed to be embedded in your custom type. You can supply a custom claims type with the new `ParseWithClaims` function. Here's an example of using a custom claims type. + +```go + type MyCustomClaims struct { + User string + *StandardClaims + } + + if token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil { + claims := token.Claims.(*MyCustomClaims) + fmt.Printf("Token for user %v expires %v", claims.User, claims.StandardClaims.ExpiresAt) + } +``` + +### `ParseFromRequest` has been moved + +To keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`. The method signatues have also been augmented to receive a new argument: `Extractor`. + +`Extractors` do the work of picking the token string out of a request. The interface is simple and composable. + +This simple parsing example: + +```go + if token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil { + fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"]) + } +``` + +is directly mapped to: + +```go + if token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil { + claims := token.Claims.(jwt.MapClaims) + fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"]) + } +``` + +There are several concrete `Extractor` types provided for your convenience: + +* `HeaderExtractor` will search a list of headers until one contains content. +* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content. +* `MultiExtractor` will try a list of `Extractors` in order until one returns content. +* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token. +* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument +* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed. A simple example is stripping the `Bearer ` text from a header + + +### RSA signing methods no longer accept `[]byte` keys + +Due to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse. + +To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`. These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types. + +```go + func keyLookupFunc(*Token) (interface{}, error) { + // Don't forget to validate the alg is what you expect: + if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { + return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + } + + // Look up key + key, err := lookupPublicKey(token.Header["kid"]) + if err != nil { + return nil, err + } + + // Unpack key from PEM encoded PKCS8 + return jwt.ParseRSAPublicKeyFromPEM(key) + } +``` diff --git a/vendor/github.com/dgrijalva/jwt-go/README.md b/vendor/github.com/dgrijalva/jwt-go/README.md new file mode 100644 index 0000000000..d358d881b8 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/README.md @@ -0,0 +1,100 @@ +# jwt-go + +[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go) +[![GoDoc](https://godoc.org/github.com/dgrijalva/jwt-go?status.svg)](https://godoc.org/github.com/dgrijalva/jwt-go) + +A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) + +**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3. + +**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail. + +**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided. + +## What the heck is a JWT? + +JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens. + +In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded. The last part is the signature, encoded the same way. + +The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used. + +The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own. + +## What's in the box? + +This library supports the parsing and verification as well as the generation and signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own. + +## Examples + +See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage: + +* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac) +* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac) +* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples) + +## Extensions + +This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`. + +Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go + +## Compliance + +This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences: + +* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key. + +## Project Status & Versioning + +This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason). + +This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `master`. Periodically, versions will be tagged from `master`. You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases). + +While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`. It will do the right thing WRT semantic versioning. + +**BREAKING CHANGES:*** +* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code. + +## Usage Tips + +### Signing vs Encryption + +A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data: + +* The author of the token was in the possession of the signing secret +* The data has not been modified since it was signed + +It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library. + +### Choosing a Signing Method + +There are several signing methods available, and you should probably take the time to learn about the various options before choosing one. The principal design decision is most likely going to be symmetric vs asymmetric. + +Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation. + +Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification. + +### Signing Methods and Key Types + +Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones: + +* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation +* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation +* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation + +### JWT and OAuth + +It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication. + +Without going too far down the rabbit hole, here's a description of the interaction of these technologies: + +* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth. +* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token. +* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL. + +## More + +Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go). + +The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation. diff --git a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md new file mode 100644 index 0000000000..6370298313 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md @@ -0,0 +1,118 @@ +## `jwt-go` Version History + +#### 3.2.0 + +* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation +* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate +* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. +* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. + +#### 3.1.0 + +* Improvements to `jwt` command line tool +* Added `SkipClaimsValidation` option to `Parser` +* Documentation updates + +#### 3.0.0 + +* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code + * Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods. + * `ParseFromRequest` has been moved to `request` subpackage and usage has changed + * The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims. +* Other Additions and Changes + * Added `Claims` interface type to allow users to decode the claims into a custom type + * Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into. + * Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage + * Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims` + * Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`. + * Added several new, more specific, validation errors to error type bitmask + * Moved examples from README to executable example files + * Signing method registry is now thread safe + * Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser) + +#### 2.7.0 + +This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes. + +* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying +* Error text for expired tokens includes how long it's been expired +* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM` +* Documentation updates + +#### 2.6.0 + +* Exposed inner error within ValidationError +* Fixed validation errors when using UseJSONNumber flag +* Added several unit tests + +#### 2.5.0 + +* Added support for signing method none. You shouldn't use this. The API tries to make this clear. +* Updated/fixed some documentation +* Added more helpful error message when trying to parse tokens that begin with `BEARER ` + +#### 2.4.0 + +* Added new type, Parser, to allow for configuration of various parsing parameters + * You can now specify a list of valid signing methods. Anything outside this set will be rejected. + * You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON +* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go) +* Fixed some bugs with ECDSA parsing + +#### 2.3.0 + +* Added support for ECDSA signing methods +* Added support for RSA PSS signing methods (requires go v1.4) + +#### 2.2.0 + +* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic. + +#### 2.1.0 + +Backwards compatible API change that was missed in 2.0.0. + +* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte` + +#### 2.0.0 + +There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change. + +The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`. + +It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`. + +* **Compatibility Breaking Changes** + * `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct` + * `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct` + * `KeyFunc` now returns `interface{}` instead of `[]byte` + * `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key + * `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key +* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodHS256` + * Added public package global `SigningMethodHS384` + * Added public package global `SigningMethodHS512` +* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodRS256` + * Added public package global `SigningMethodRS384` + * Added public package global `SigningMethodRS512` +* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged. +* Refactored the RSA implementation to be easier to read +* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM` + +#### 1.0.2 + +* Fixed bug in parsing public keys from certificates +* Added more tests around the parsing of keys for RS256 +* Code refactoring in RS256 implementation. No functional changes + +#### 1.0.1 + +* Fixed panic if RS256 signing method was passed an invalid key + +#### 1.0.0 + +* First versioned release +* API stabilized +* Supports creating, signing, parsing, and validating JWT tokens +* Supports RS256 and HS256 signing methods \ No newline at end of file diff --git a/vendor/github.com/dgrijalva/jwt-go/claims.go b/vendor/github.com/dgrijalva/jwt-go/claims.go new file mode 100644 index 0000000000..f0228f02e0 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/claims.go @@ -0,0 +1,134 @@ +package jwt + +import ( + "crypto/subtle" + "fmt" + "time" +) + +// For a type to be a Claims object, it must just have a Valid method that determines +// if the token is invalid for any supported reason +type Claims interface { + Valid() error +} + +// Structured version of Claims Section, as referenced at +// https://tools.ietf.org/html/rfc7519#section-4.1 +// See examples for how to use this with your own claim types +type StandardClaims struct { + Audience string `json:"aud,omitempty"` + ExpiresAt int64 `json:"exp,omitempty"` + Id string `json:"jti,omitempty"` + IssuedAt int64 `json:"iat,omitempty"` + Issuer string `json:"iss,omitempty"` + NotBefore int64 `json:"nbf,omitempty"` + Subject string `json:"sub,omitempty"` +} + +// Validates time based claims "exp, iat, nbf". +// There is no accounting for clock skew. +// As well, if any of the above claims are not in the token, it will still +// be considered a valid claim. +func (c StandardClaims) Valid() error { + vErr := new(ValidationError) + now := TimeFunc().Unix() + + // The claims below are optional, by default, so if they are set to the + // default value in Go, let's not fail the verification for them. + if c.VerifyExpiresAt(now, false) == false { + delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0)) + vErr.Inner = fmt.Errorf("token is expired by %v", delta) + vErr.Errors |= ValidationErrorExpired + } + + if c.VerifyIssuedAt(now, false) == false { + vErr.Inner = fmt.Errorf("Token used before issued") + vErr.Errors |= ValidationErrorIssuedAt + } + + if c.VerifyNotBefore(now, false) == false { + vErr.Inner = fmt.Errorf("token is not valid yet") + vErr.Errors |= ValidationErrorNotValidYet + } + + if vErr.valid() { + return nil + } + + return vErr +} + +// Compares the aud claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool { + return verifyAud(c.Audience, cmp, req) +} + +// Compares the exp claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool { + return verifyExp(c.ExpiresAt, cmp, req) +} + +// Compares the iat claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool { + return verifyIat(c.IssuedAt, cmp, req) +} + +// Compares the iss claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool { + return verifyIss(c.Issuer, cmp, req) +} + +// Compares the nbf claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { + return verifyNbf(c.NotBefore, cmp, req) +} + +// ----- helpers + +func verifyAud(aud string, cmp string, required bool) bool { + if aud == "" { + return !required + } + if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 { + return true + } else { + return false + } +} + +func verifyExp(exp int64, now int64, required bool) bool { + if exp == 0 { + return !required + } + return now <= exp +} + +func verifyIat(iat int64, now int64, required bool) bool { + if iat == 0 { + return !required + } + return now >= iat +} + +func verifyIss(iss string, cmp string, required bool) bool { + if iss == "" { + return !required + } + if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 { + return true + } else { + return false + } +} + +func verifyNbf(nbf int64, now int64, required bool) bool { + if nbf == 0 { + return !required + } + return now >= nbf +} diff --git a/vendor/github.com/dgrijalva/jwt-go/doc.go b/vendor/github.com/dgrijalva/jwt-go/doc.go new file mode 100644 index 0000000000..a86dc1a3b3 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/doc.go @@ -0,0 +1,4 @@ +// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html +// +// See README.md for more info. +package jwt diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go new file mode 100644 index 0000000000..f977381240 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go @@ -0,0 +1,148 @@ +package jwt + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rand" + "errors" + "math/big" +) + +var ( + // Sadly this is missing from crypto/ecdsa compared to crypto/rsa + ErrECDSAVerification = errors.New("crypto/ecdsa: verification error") +) + +// Implements the ECDSA family of signing methods signing methods +// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification +type SigningMethodECDSA struct { + Name string + Hash crypto.Hash + KeySize int + CurveBits int +} + +// Specific instances for EC256 and company +var ( + SigningMethodES256 *SigningMethodECDSA + SigningMethodES384 *SigningMethodECDSA + SigningMethodES512 *SigningMethodECDSA +) + +func init() { + // ES256 + SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256} + RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod { + return SigningMethodES256 + }) + + // ES384 + SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384} + RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod { + return SigningMethodES384 + }) + + // ES512 + SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521} + RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod { + return SigningMethodES512 + }) +} + +func (m *SigningMethodECDSA) Alg() string { + return m.Name +} + +// Implements the Verify method from SigningMethod +// For this verify method, key must be an ecdsa.PublicKey struct +func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + // Get the key + var ecdsaKey *ecdsa.PublicKey + switch k := key.(type) { + case *ecdsa.PublicKey: + ecdsaKey = k + default: + return ErrInvalidKeyType + } + + if len(sig) != 2*m.KeySize { + return ErrECDSAVerification + } + + r := big.NewInt(0).SetBytes(sig[:m.KeySize]) + s := big.NewInt(0).SetBytes(sig[m.KeySize:]) + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true { + return nil + } else { + return ErrECDSAVerification + } +} + +// Implements the Sign method from SigningMethod +// For this signing method, key must be an ecdsa.PrivateKey struct +func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) { + // Get the key + var ecdsaKey *ecdsa.PrivateKey + switch k := key.(type) { + case *ecdsa.PrivateKey: + ecdsaKey = k + default: + return "", ErrInvalidKeyType + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return r, s + if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil { + curveBits := ecdsaKey.Curve.Params().BitSize + + if m.CurveBits != curveBits { + return "", ErrInvalidKey + } + + keyBytes := curveBits / 8 + if curveBits%8 > 0 { + keyBytes += 1 + } + + // We serialize the outpus (r and s) into big-endian byte arrays and pad + // them with zeros on the left to make sure the sizes work out. Both arrays + // must be keyBytes long, and the output must be 2*keyBytes long. + rBytes := r.Bytes() + rBytesPadded := make([]byte, keyBytes) + copy(rBytesPadded[keyBytes-len(rBytes):], rBytes) + + sBytes := s.Bytes() + sBytesPadded := make([]byte, keyBytes) + copy(sBytesPadded[keyBytes-len(sBytes):], sBytes) + + out := append(rBytesPadded, sBytesPadded...) + + return EncodeSegment(out), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go new file mode 100644 index 0000000000..d19624b726 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go @@ -0,0 +1,67 @@ +package jwt + +import ( + "crypto/ecdsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrNotECPublicKey = errors.New("Key is not a valid ECDSA public key") + ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key") +) + +// Parse PEM encoded Elliptic Curve Private Key Structure +func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { + return nil, err + } + + var pkey *ecdsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok { + return nil, ErrNotECPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 public key +func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *ecdsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok { + return nil, ErrNotECPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/errors.go b/vendor/github.com/dgrijalva/jwt-go/errors.go new file mode 100644 index 0000000000..1c93024aad --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/errors.go @@ -0,0 +1,59 @@ +package jwt + +import ( + "errors" +) + +// Error constants +var ( + ErrInvalidKey = errors.New("key is invalid") + ErrInvalidKeyType = errors.New("key is of invalid type") + ErrHashUnavailable = errors.New("the requested hash function is unavailable") +) + +// The errors that might occur when parsing and validating a token +const ( + ValidationErrorMalformed uint32 = 1 << iota // Token is malformed + ValidationErrorUnverifiable // Token could not be verified because of signing problems + ValidationErrorSignatureInvalid // Signature validation failed + + // Standard Claim validation errors + ValidationErrorAudience // AUD validation failed + ValidationErrorExpired // EXP validation failed + ValidationErrorIssuedAt // IAT validation failed + ValidationErrorIssuer // ISS validation failed + ValidationErrorNotValidYet // NBF validation failed + ValidationErrorId // JTI validation failed + ValidationErrorClaimsInvalid // Generic claims validation error +) + +// Helper for constructing a ValidationError with a string error message +func NewValidationError(errorText string, errorFlags uint32) *ValidationError { + return &ValidationError{ + text: errorText, + Errors: errorFlags, + } +} + +// The error from Parse if token is not valid +type ValidationError struct { + Inner error // stores the error returned by external dependencies, i.e.: KeyFunc + Errors uint32 // bitfield. see ValidationError... constants + text string // errors that do not have a valid error just have text +} + +// Validation error is an error type +func (e ValidationError) Error() string { + if e.Inner != nil { + return e.Inner.Error() + } else if e.text != "" { + return e.text + } else { + return "token is invalid" + } +} + +// No errors +func (e *ValidationError) valid() bool { + return e.Errors == 0 +} diff --git a/vendor/github.com/dgrijalva/jwt-go/hmac.go b/vendor/github.com/dgrijalva/jwt-go/hmac.go new file mode 100644 index 0000000000..addbe5d401 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/hmac.go @@ -0,0 +1,95 @@ +package jwt + +import ( + "crypto" + "crypto/hmac" + "errors" +) + +// Implements the HMAC-SHA family of signing methods signing methods +// Expects key type of []byte for both signing and validation +type SigningMethodHMAC struct { + Name string + Hash crypto.Hash +} + +// Specific instances for HS256 and company +var ( + SigningMethodHS256 *SigningMethodHMAC + SigningMethodHS384 *SigningMethodHMAC + SigningMethodHS512 *SigningMethodHMAC + ErrSignatureInvalid = errors.New("signature is invalid") +) + +func init() { + // HS256 + SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod { + return SigningMethodHS256 + }) + + // HS384 + SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod { + return SigningMethodHS384 + }) + + // HS512 + SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod { + return SigningMethodHS512 + }) +} + +func (m *SigningMethodHMAC) Alg() string { + return m.Name +} + +// Verify the signature of HSXXX tokens. Returns nil if the signature is valid. +func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error { + // Verify the key is the right type + keyBytes, ok := key.([]byte) + if !ok { + return ErrInvalidKeyType + } + + // Decode signature, for comparison + sig, err := DecodeSegment(signature) + if err != nil { + return err + } + + // Can we use the specified hashing method? + if !m.Hash.Available() { + return ErrHashUnavailable + } + + // This signing method is symmetric, so we validate the signature + // by reproducing the signature from the signing string and key, then + // comparing that against the provided signature. + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + if !hmac.Equal(sig, hasher.Sum(nil)) { + return ErrSignatureInvalid + } + + // No validation errors. Signature is good. + return nil +} + +// Implements the Sign method from SigningMethod for this signing method. +// Key must be []byte +func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) { + if keyBytes, ok := key.([]byte); ok { + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + + return EncodeSegment(hasher.Sum(nil)), nil + } + + return "", ErrInvalidKeyType +} diff --git a/vendor/github.com/dgrijalva/jwt-go/map_claims.go b/vendor/github.com/dgrijalva/jwt-go/map_claims.go new file mode 100644 index 0000000000..291213c460 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/map_claims.go @@ -0,0 +1,94 @@ +package jwt + +import ( + "encoding/json" + "errors" + // "fmt" +) + +// Claims type that uses the map[string]interface{} for JSON decoding +// This is the default claims type if you don't supply one +type MapClaims map[string]interface{} + +// Compares the aud claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyAudience(cmp string, req bool) bool { + aud, _ := m["aud"].(string) + return verifyAud(aud, cmp, req) +} + +// Compares the exp claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool { + switch exp := m["exp"].(type) { + case float64: + return verifyExp(int64(exp), cmp, req) + case json.Number: + v, _ := exp.Int64() + return verifyExp(v, cmp, req) + } + return req == false +} + +// Compares the iat claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool { + switch iat := m["iat"].(type) { + case float64: + return verifyIat(int64(iat), cmp, req) + case json.Number: + v, _ := iat.Int64() + return verifyIat(v, cmp, req) + } + return req == false +} + +// Compares the iss claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyIssuer(cmp string, req bool) bool { + iss, _ := m["iss"].(string) + return verifyIss(iss, cmp, req) +} + +// Compares the nbf claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool { + switch nbf := m["nbf"].(type) { + case float64: + return verifyNbf(int64(nbf), cmp, req) + case json.Number: + v, _ := nbf.Int64() + return verifyNbf(v, cmp, req) + } + return req == false +} + +// Validates time based claims "exp, iat, nbf". +// There is no accounting for clock skew. +// As well, if any of the above claims are not in the token, it will still +// be considered a valid claim. +func (m MapClaims) Valid() error { + vErr := new(ValidationError) + now := TimeFunc().Unix() + + if m.VerifyExpiresAt(now, false) == false { + vErr.Inner = errors.New("Token is expired") + vErr.Errors |= ValidationErrorExpired + } + + if m.VerifyIssuedAt(now, false) == false { + vErr.Inner = errors.New("Token used before issued") + vErr.Errors |= ValidationErrorIssuedAt + } + + if m.VerifyNotBefore(now, false) == false { + vErr.Inner = errors.New("Token is not valid yet") + vErr.Errors |= ValidationErrorNotValidYet + } + + if vErr.valid() { + return nil + } + + return vErr +} diff --git a/vendor/github.com/dgrijalva/jwt-go/none.go b/vendor/github.com/dgrijalva/jwt-go/none.go new file mode 100644 index 0000000000..f04d189d06 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/none.go @@ -0,0 +1,52 @@ +package jwt + +// Implements the none signing method. This is required by the spec +// but you probably should never use it. +var SigningMethodNone *signingMethodNone + +const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" + +var NoneSignatureTypeDisallowedError error + +type signingMethodNone struct{} +type unsafeNoneMagicConstant string + +func init() { + SigningMethodNone = &signingMethodNone{} + NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid) + + RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { + return SigningMethodNone + }) +} + +func (m *signingMethodNone) Alg() string { + return "none" +} + +// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) { + // Key must be UnsafeAllowNoneSignatureType to prevent accidentally + // accepting 'none' signing method + if _, ok := key.(unsafeNoneMagicConstant); !ok { + return NoneSignatureTypeDisallowedError + } + // If signing method is none, signature must be an empty string + if signature != "" { + return NewValidationError( + "'none' signing method with non-empty signature", + ValidationErrorSignatureInvalid, + ) + } + + // Accept 'none' signing method. + return nil +} + +// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) { + if _, ok := key.(unsafeNoneMagicConstant); ok { + return "", nil + } + return "", NoneSignatureTypeDisallowedError +} diff --git a/vendor/github.com/dgrijalva/jwt-go/parser.go b/vendor/github.com/dgrijalva/jwt-go/parser.go new file mode 100644 index 0000000000..d6901d9adb --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/parser.go @@ -0,0 +1,148 @@ +package jwt + +import ( + "bytes" + "encoding/json" + "fmt" + "strings" +) + +type Parser struct { + ValidMethods []string // If populated, only these methods will be considered valid + UseJSONNumber bool // Use JSON Number format in JSON decoder + SkipClaimsValidation bool // Skip claims validation during token parsing +} + +// Parse, validate, and return a token. +// keyFunc will receive the parsed token and should return the key for validating. +// If everything is kosher, err will be nil +func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) +} + +func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + token, parts, err := p.ParseUnverified(tokenString, claims) + if err != nil { + return token, err + } + + // Verify signing method is in the required set + if p.ValidMethods != nil { + var signingMethodValid = false + var alg = token.Method.Alg() + for _, m := range p.ValidMethods { + if m == alg { + signingMethodValid = true + break + } + } + if !signingMethodValid { + // signing method is not in the listed set + return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid) + } + } + + // Lookup key + var key interface{} + if keyFunc == nil { + // keyFunc was not provided. short circuiting validation + return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable) + } + if key, err = keyFunc(token); err != nil { + // keyFunc returned an error + if ve, ok := err.(*ValidationError); ok { + return token, ve + } + return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable} + } + + vErr := &ValidationError{} + + // Validate Claims + if !p.SkipClaimsValidation { + if err := token.Claims.Valid(); err != nil { + + // If the Claims Valid returned an error, check if it is a validation error, + // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set + if e, ok := err.(*ValidationError); !ok { + vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid} + } else { + vErr = e + } + } + } + + // Perform validation + token.Signature = parts[2] + if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil { + vErr.Inner = err + vErr.Errors |= ValidationErrorSignatureInvalid + } + + if vErr.valid() { + token.Valid = true + return token, nil + } + + return token, vErr +} + +// WARNING: Don't use this method unless you know what you're doing +// +// This method parses the token but doesn't validate the signature. It's only +// ever useful in cases where you know the signature is valid (because it has +// been checked previously in the stack) and you want to extract values from +// it. +func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { + parts = strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) + } + + token = &Token{Raw: tokenString} + + // parse Header + var headerBytes []byte + if headerBytes, err = DecodeSegment(parts[0]); err != nil { + if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { + return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) + } + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // parse Claims + var claimBytes []byte + token.Claims = claims + + if claimBytes, err = DecodeSegment(parts[1]); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) + if p.UseJSONNumber { + dec.UseNumber() + } + // JSON Decode. Special case for map type to avoid weird pointer behavior + if c, ok := token.Claims.(MapClaims); ok { + err = dec.Decode(&c) + } else { + err = dec.Decode(&claims) + } + // Handle decode error + if err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) + } + } else { + return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) + } + + return token, parts, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa.go b/vendor/github.com/dgrijalva/jwt-go/rsa.go new file mode 100644 index 0000000000..e4caf1ca4a --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa.go @@ -0,0 +1,101 @@ +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// Implements the RSA family of signing methods signing methods +// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation +type SigningMethodRSA struct { + Name string + Hash crypto.Hash +} + +// Specific instances for RS256 and company +var ( + SigningMethodRS256 *SigningMethodRSA + SigningMethodRS384 *SigningMethodRSA + SigningMethodRS512 *SigningMethodRSA +) + +func init() { + // RS256 + SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { + return SigningMethodRS256 + }) + + // RS384 + SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { + return SigningMethodRS384 + }) + + // RS512 + SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { + return SigningMethodRS512 + }) +} + +func (m *SigningMethodRSA) Alg() string { + return m.Name +} + +// Implements the Verify method from SigningMethod +// For this signing method, must be an *rsa.PublicKey structure. +func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + var rsaKey *rsa.PublicKey + var ok bool + + if rsaKey, ok = key.(*rsa.PublicKey); !ok { + return ErrInvalidKeyType + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) +} + +// Implements the Sign method from SigningMethod +// For this signing method, must be an *rsa.PrivateKey structure. +func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { + var rsaKey *rsa.PrivateKey + var ok bool + + // Validate type of key + if rsaKey, ok = key.(*rsa.PrivateKey); !ok { + return "", ErrInvalidKey + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { + return EncodeSegment(sigBytes), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go b/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go new file mode 100644 index 0000000000..10ee9db8a4 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go @@ -0,0 +1,126 @@ +// +build go1.4 + +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// Implements the RSAPSS family of signing methods signing methods +type SigningMethodRSAPSS struct { + *SigningMethodRSA + Options *rsa.PSSOptions +} + +// Specific instances for RS/PS and company +var ( + SigningMethodPS256 *SigningMethodRSAPSS + SigningMethodPS384 *SigningMethodRSAPSS + SigningMethodPS512 *SigningMethodRSAPSS +) + +func init() { + // PS256 + SigningMethodPS256 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS256", + Hash: crypto.SHA256, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA256, + }, + } + RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { + return SigningMethodPS256 + }) + + // PS384 + SigningMethodPS384 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS384", + Hash: crypto.SHA384, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA384, + }, + } + RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { + return SigningMethodPS384 + }) + + // PS512 + SigningMethodPS512 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS512", + Hash: crypto.SHA512, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA512, + }, + } + RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { + return SigningMethodPS512 + }) +} + +// Implements the Verify method from SigningMethod +// For this verify method, key must be an rsa.PublicKey struct +func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + var rsaKey *rsa.PublicKey + switch k := key.(type) { + case *rsa.PublicKey: + rsaKey = k + default: + return ErrInvalidKey + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options) +} + +// Implements the Sign method from SigningMethod +// For this signing method, key must be an rsa.PrivateKey struct +func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) { + var rsaKey *rsa.PrivateKey + + switch k := key.(type) { + case *rsa.PrivateKey: + rsaKey = k + default: + return "", ErrInvalidKeyType + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { + return EncodeSegment(sigBytes), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go new file mode 100644 index 0000000000..a5ababf956 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go @@ -0,0 +1,101 @@ +package jwt + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key") + ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key") + ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key") +) + +// Parse PEM encoded PKCS1 or PKCS8 private key +func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 private key protected with password +func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + + var blockDecrypted []byte + if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { + return nil, err + } + + if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 public key +func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *rsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { + return nil, ErrNotRSAPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/signing_method.go b/vendor/github.com/dgrijalva/jwt-go/signing_method.go new file mode 100644 index 0000000000..ed1f212b21 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/signing_method.go @@ -0,0 +1,35 @@ +package jwt + +import ( + "sync" +) + +var signingMethods = map[string]func() SigningMethod{} +var signingMethodLock = new(sync.RWMutex) + +// Implement SigningMethod to add new methods for signing or verifying tokens. +type SigningMethod interface { + Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid + Sign(signingString string, key interface{}) (string, error) // Returns encoded signature or error + Alg() string // returns the alg identifier for this method (example: 'HS256') +} + +// Register the "alg" name and a factory function for signing method. +// This is typically done during init() in the method's implementation +func RegisterSigningMethod(alg string, f func() SigningMethod) { + signingMethodLock.Lock() + defer signingMethodLock.Unlock() + + signingMethods[alg] = f +} + +// Get a signing method from an "alg" string +func GetSigningMethod(alg string) (method SigningMethod) { + signingMethodLock.RLock() + defer signingMethodLock.RUnlock() + + if methodF, ok := signingMethods[alg]; ok { + method = methodF() + } + return +} diff --git a/vendor/github.com/dgrijalva/jwt-go/token.go b/vendor/github.com/dgrijalva/jwt-go/token.go new file mode 100644 index 0000000000..d637e0867c --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/token.go @@ -0,0 +1,108 @@ +package jwt + +import ( + "encoding/base64" + "encoding/json" + "strings" + "time" +) + +// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time). +// You can override it to use another time value. This is useful for testing or if your +// server uses a different time zone than your tokens. +var TimeFunc = time.Now + +// Parse methods use this callback function to supply +// the key for verification. The function receives the parsed, +// but unverified Token. This allows you to use properties in the +// Header of the token (such as `kid`) to identify which key to use. +type Keyfunc func(*Token) (interface{}, error) + +// A JWT Token. Different fields will be used depending on whether you're +// creating or parsing/verifying a token. +type Token struct { + Raw string // The raw token. Populated when you Parse a token + Method SigningMethod // The signing method used or to be used + Header map[string]interface{} // The first segment of the token + Claims Claims // The second segment of the token + Signature string // The third segment of the token. Populated when you Parse a token + Valid bool // Is the token valid? Populated when you Parse/Verify a token +} + +// Create a new Token. Takes a signing method +func New(method SigningMethod) *Token { + return NewWithClaims(method, MapClaims{}) +} + +func NewWithClaims(method SigningMethod, claims Claims) *Token { + return &Token{ + Header: map[string]interface{}{ + "typ": "JWT", + "alg": method.Alg(), + }, + Claims: claims, + Method: method, + } +} + +// Get the complete, signed token +func (t *Token) SignedString(key interface{}) (string, error) { + var sig, sstr string + var err error + if sstr, err = t.SigningString(); err != nil { + return "", err + } + if sig, err = t.Method.Sign(sstr, key); err != nil { + return "", err + } + return strings.Join([]string{sstr, sig}, "."), nil +} + +// Generate the signing string. This is the +// most expensive part of the whole deal. Unless you +// need this for something special, just go straight for +// the SignedString. +func (t *Token) SigningString() (string, error) { + var err error + parts := make([]string, 2) + for i, _ := range parts { + var jsonValue []byte + if i == 0 { + if jsonValue, err = json.Marshal(t.Header); err != nil { + return "", err + } + } else { + if jsonValue, err = json.Marshal(t.Claims); err != nil { + return "", err + } + } + + parts[i] = EncodeSegment(jsonValue) + } + return strings.Join(parts, "."), nil +} + +// Parse, validate, and return a token. +// keyFunc will receive the parsed token and should return the key for validating. +// If everything is kosher, err will be nil +func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return new(Parser).Parse(tokenString, keyFunc) +} + +func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + return new(Parser).ParseWithClaims(tokenString, claims, keyFunc) +} + +// Encode JWT specific base64url encoding with padding stripped +func EncodeSegment(seg []byte) string { + return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=") +} + +// Decode JWT specific base64url encoding with padding stripped +func DecodeSegment(seg string) ([]byte, error) { + if l := len(seg) % 4; l > 0 { + seg += strings.Repeat("=", 4-l) + } + + return base64.URLEncoding.DecodeString(seg) +} diff --git a/vendor/github.com/go-errors/errors/.travis.yml b/vendor/github.com/go-errors/errors/.travis.yml new file mode 100644 index 0000000000..9d00fdd5d6 --- /dev/null +++ b/vendor/github.com/go-errors/errors/.travis.yml @@ -0,0 +1,5 @@ +language: go + +go: + - "1.8.x" + - "1.10.x" diff --git a/vendor/github.com/go-errors/errors/LICENSE.MIT b/vendor/github.com/go-errors/errors/LICENSE.MIT new file mode 100644 index 0000000000..c9a5b2eeb7 --- /dev/null +++ b/vendor/github.com/go-errors/errors/LICENSE.MIT @@ -0,0 +1,7 @@ +Copyright (c) 2015 Conrad Irwin + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-errors/errors/README.md b/vendor/github.com/go-errors/errors/README.md new file mode 100644 index 0000000000..5d4f1873dd --- /dev/null +++ b/vendor/github.com/go-errors/errors/README.md @@ -0,0 +1,66 @@ +go-errors/errors +================ + +[![Build Status](https://travis-ci.org/go-errors/errors.svg?branch=master)](https://travis-ci.org/go-errors/errors) + +Package errors adds stacktrace support to errors in go. + +This is particularly useful when you want to understand the state of execution +when an error was returned unexpectedly. + +It provides the type \*Error which implements the standard golang error +interface, so you can use this library interchangably with code that is +expecting a normal error return. + +Usage +----- + +Full documentation is available on +[godoc](https://godoc.org/github.com/go-errors/errors), but here's a simple +example: + +```go +package crashy + +import "github.com/go-errors/errors" + +var Crashed = errors.Errorf("oh dear") + +func Crash() error { + return errors.New(Crashed) +} +``` + +This can be called as follows: + +```go +package main + +import ( + "crashy" + "fmt" + "github.com/go-errors/errors" +) + +func main() { + err := crashy.Crash() + if err != nil { + if errors.Is(err, crashy.Crashed) { + fmt.Println(err.(*errors.Error).ErrorStack()) + } else { + panic(err) + } + } +} +``` + +Meta-fu +------- + +This package was original written to allow reporting to +[Bugsnag](https://bugsnag.com/) from +[bugsnag-go](https://github.com/bugsnag/bugsnag-go), but after I found similar +packages by Facebook and Dropbox, it was moved to one canonical location so +everyone can benefit. + +This package is licensed under the MIT license, see LICENSE.MIT for details. diff --git a/vendor/github.com/go-errors/errors/cover.out b/vendor/github.com/go-errors/errors/cover.out new file mode 100644 index 0000000000..ab18b0519f --- /dev/null +++ b/vendor/github.com/go-errors/errors/cover.out @@ -0,0 +1,89 @@ +mode: set +github.com/go-errors/errors/stackframe.go:27.51,30.25 2 1 +github.com/go-errors/errors/stackframe.go:33.2,38.8 3 1 +github.com/go-errors/errors/stackframe.go:30.25,32.3 1 0 +github.com/go-errors/errors/stackframe.go:43.47,44.31 1 1 +github.com/go-errors/errors/stackframe.go:47.2,47.48 1 1 +github.com/go-errors/errors/stackframe.go:44.31,46.3 1 1 +github.com/go-errors/errors/stackframe.go:52.42,56.16 3 1 +github.com/go-errors/errors/stackframe.go:60.2,60.60 1 1 +github.com/go-errors/errors/stackframe.go:56.16,58.3 1 0 +github.com/go-errors/errors/stackframe.go:64.55,67.16 2 1 +github.com/go-errors/errors/stackframe.go:71.2,72.61 2 1 +github.com/go-errors/errors/stackframe.go:76.2,76.66 1 1 +github.com/go-errors/errors/stackframe.go:67.16,69.3 1 0 +github.com/go-errors/errors/stackframe.go:72.61,74.3 1 0 +github.com/go-errors/errors/stackframe.go:79.56,91.63 3 1 +github.com/go-errors/errors/stackframe.go:95.2,95.53 1 1 +github.com/go-errors/errors/stackframe.go:100.2,101.18 2 1 +github.com/go-errors/errors/stackframe.go:91.63,94.3 2 1 +github.com/go-errors/errors/stackframe.go:95.53,98.3 2 1 +github.com/go-errors/errors/error.go:70.32,73.23 2 1 +github.com/go-errors/errors/error.go:80.2,85.3 3 1 +github.com/go-errors/errors/error.go:74.2,75.10 1 1 +github.com/go-errors/errors/error.go:76.2,77.28 1 1 +github.com/go-errors/errors/error.go:92.43,95.23 2 1 +github.com/go-errors/errors/error.go:104.2,109.3 3 1 +github.com/go-errors/errors/error.go:96.2,97.11 1 1 +github.com/go-errors/errors/error.go:98.2,99.10 1 1 +github.com/go-errors/errors/error.go:100.2,101.28 1 1 +github.com/go-errors/errors/error.go:115.39,117.19 1 1 +github.com/go-errors/errors/error.go:121.2,121.29 1 1 +github.com/go-errors/errors/error.go:125.2,125.43 1 1 +github.com/go-errors/errors/error.go:129.2,129.14 1 1 +github.com/go-errors/errors/error.go:117.19,119.3 1 1 +github.com/go-errors/errors/error.go:121.29,123.3 1 1 +github.com/go-errors/errors/error.go:125.43,127.3 1 1 +github.com/go-errors/errors/error.go:135.53,137.2 1 1 +github.com/go-errors/errors/error.go:140.34,142.2 1 1 +github.com/go-errors/errors/error.go:146.34,149.42 2 1 +github.com/go-errors/errors/error.go:153.2,153.20 1 1 +github.com/go-errors/errors/error.go:149.42,151.3 1 1 +github.com/go-errors/errors/error.go:158.39,160.2 1 1 +github.com/go-errors/errors/error.go:164.46,165.23 1 1 +github.com/go-errors/errors/error.go:173.2,173.19 1 1 +github.com/go-errors/errors/error.go:165.23,168.32 2 1 +github.com/go-errors/errors/error.go:168.32,170.4 1 1 +github.com/go-errors/errors/error.go:177.37,178.42 1 1 +github.com/go-errors/errors/error.go:181.2,181.41 1 1 +github.com/go-errors/errors/error.go:178.42,180.3 1 1 +github.com/go-errors/errors/parse_panic.go:10.39,12.2 1 1 +github.com/go-errors/errors/parse_panic.go:16.46,24.34 5 1 +github.com/go-errors/errors/parse_panic.go:70.2,70.43 1 1 +github.com/go-errors/errors/parse_panic.go:73.2,73.55 1 0 +github.com/go-errors/errors/parse_panic.go:24.34,27.23 2 1 +github.com/go-errors/errors/parse_panic.go:27.23,28.42 1 1 +github.com/go-errors/errors/parse_panic.go:28.42,31.5 2 1 +github.com/go-errors/errors/parse_panic.go:31.6,33.5 1 0 +github.com/go-errors/errors/parse_panic.go:35.5,35.29 1 1 +github.com/go-errors/errors/parse_panic.go:35.29,36.86 1 1 +github.com/go-errors/errors/parse_panic.go:36.86,38.5 1 1 +github.com/go-errors/errors/parse_panic.go:40.5,40.32 1 1 +github.com/go-errors/errors/parse_panic.go:40.32,41.18 1 1 +github.com/go-errors/errors/parse_panic.go:45.4,46.46 2 1 +github.com/go-errors/errors/parse_panic.go:51.4,53.23 2 1 +github.com/go-errors/errors/parse_panic.go:57.4,58.18 2 1 +github.com/go-errors/errors/parse_panic.go:62.4,63.17 2 1 +github.com/go-errors/errors/parse_panic.go:41.18,43.10 2 1 +github.com/go-errors/errors/parse_panic.go:46.46,49.5 2 1 +github.com/go-errors/errors/parse_panic.go:53.23,55.5 1 0 +github.com/go-errors/errors/parse_panic.go:58.18,60.5 1 0 +github.com/go-errors/errors/parse_panic.go:63.17,65.10 2 1 +github.com/go-errors/errors/parse_panic.go:70.43,72.3 1 1 +github.com/go-errors/errors/parse_panic.go:80.85,82.29 2 1 +github.com/go-errors/errors/parse_panic.go:85.2,85.15 1 1 +github.com/go-errors/errors/parse_panic.go:88.2,90.63 2 1 +github.com/go-errors/errors/parse_panic.go:94.2,94.53 1 1 +github.com/go-errors/errors/parse_panic.go:99.2,101.36 2 1 +github.com/go-errors/errors/parse_panic.go:105.2,106.15 2 1 +github.com/go-errors/errors/parse_panic.go:109.2,112.49 3 1 +github.com/go-errors/errors/parse_panic.go:116.2,117.16 2 1 +github.com/go-errors/errors/parse_panic.go:121.2,126.8 1 1 +github.com/go-errors/errors/parse_panic.go:82.29,84.3 1 0 +github.com/go-errors/errors/parse_panic.go:85.15,87.3 1 1 +github.com/go-errors/errors/parse_panic.go:90.63,93.3 2 1 +github.com/go-errors/errors/parse_panic.go:94.53,97.3 2 1 +github.com/go-errors/errors/parse_panic.go:101.36,103.3 1 0 +github.com/go-errors/errors/parse_panic.go:106.15,108.3 1 0 +github.com/go-errors/errors/parse_panic.go:112.49,114.3 1 1 +github.com/go-errors/errors/parse_panic.go:117.16,119.3 1 0 diff --git a/vendor/github.com/go-errors/errors/error.go b/vendor/github.com/go-errors/errors/error.go new file mode 100644 index 0000000000..60062a4372 --- /dev/null +++ b/vendor/github.com/go-errors/errors/error.go @@ -0,0 +1,217 @@ +// Package errors provides errors that have stack-traces. +// +// This is particularly useful when you want to understand the +// state of execution when an error was returned unexpectedly. +// +// It provides the type *Error which implements the standard +// golang error interface, so you can use this library interchangably +// with code that is expecting a normal error return. +// +// For example: +// +// package crashy +// +// import "github.com/go-errors/errors" +// +// var Crashed = errors.Errorf("oh dear") +// +// func Crash() error { +// return errors.New(Crashed) +// } +// +// This can be called as follows: +// +// package main +// +// import ( +// "crashy" +// "fmt" +// "github.com/go-errors/errors" +// ) +// +// func main() { +// err := crashy.Crash() +// if err != nil { +// if errors.Is(err, crashy.Crashed) { +// fmt.Println(err.(*errors.Error).ErrorStack()) +// } else { +// panic(err) +// } +// } +// } +// +// This package was original written to allow reporting to Bugsnag, +// but after I found similar packages by Facebook and Dropbox, it +// was moved to one canonical location so everyone can benefit. +package errors + +import ( + "bytes" + "fmt" + "reflect" + "runtime" +) + +// The maximum number of stackframes on any error. +var MaxStackDepth = 50 + +// Error is an error with an attached stacktrace. It can be used +// wherever the builtin error interface is expected. +type Error struct { + Err error + stack []uintptr + frames []StackFrame + prefix string +} + +// New makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The stacktrace will point to the line of code that +// called New. +func New(e interface{}) *Error { + var err error + + switch e := e.(type) { + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + + stack := make([]uintptr, MaxStackDepth) + length := runtime.Callers(2, stack[:]) + return &Error{ + Err: err, + stack: stack[:length], + } +} + +// Wrap makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The skip parameter indicates how far up the stack +// to start the stacktrace. 0 is from the current call, 1 from its caller, etc. +func Wrap(e interface{}, skip int) *Error { + var err error + + switch e := e.(type) { + case *Error: + return e + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + + stack := make([]uintptr, MaxStackDepth) + length := runtime.Callers(2+skip, stack[:]) + return &Error{ + Err: err, + stack: stack[:length], + } +} + +// WrapPrefix makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The prefix parameter is used to add a prefix to the +// error message when calling Error(). The skip parameter indicates how far +// up the stack to start the stacktrace. 0 is from the current call, +// 1 from its caller, etc. +func WrapPrefix(e interface{}, prefix string, skip int) *Error { + + err := Wrap(e, 1+skip) + + if err.prefix != "" { + prefix = fmt.Sprintf("%s: %s", prefix, err.prefix) + } + + return &Error{ + Err: err.Err, + stack: err.stack, + prefix: prefix, + } + +} + +// Is detects whether the error is equal to a given error. Errors +// are considered equal by this function if they are the same object, +// or if they both contain the same error inside an errors.Error. +func Is(e error, original error) bool { + + if e == original { + return true + } + + if e, ok := e.(*Error); ok { + return Is(e.Err, original) + } + + if original, ok := original.(*Error); ok { + return Is(e, original.Err) + } + + return false +} + +// Errorf creates a new error with the given message. You can use it +// as a drop-in replacement for fmt.Errorf() to provide descriptive +// errors in return values. +func Errorf(format string, a ...interface{}) *Error { + return Wrap(fmt.Errorf(format, a...), 1) +} + +// Error returns the underlying error's message. +func (err *Error) Error() string { + + msg := err.Err.Error() + if err.prefix != "" { + msg = fmt.Sprintf("%s: %s", err.prefix, msg) + } + + return msg +} + +// Stack returns the callstack formatted the same way that go does +// in runtime/debug.Stack() +func (err *Error) Stack() []byte { + buf := bytes.Buffer{} + + for _, frame := range err.StackFrames() { + buf.WriteString(frame.String()) + } + + return buf.Bytes() +} + +// Callers satisfies the bugsnag ErrorWithCallerS() interface +// so that the stack can be read out. +func (err *Error) Callers() []uintptr { + return err.stack +} + +// ErrorStack returns a string that contains both the +// error message and the callstack. +func (err *Error) ErrorStack() string { + return err.TypeName() + " " + err.Error() + "\n" + string(err.Stack()) +} + +// StackFrames returns an array of frames containing information about the +// stack. +func (err *Error) StackFrames() []StackFrame { + if err.frames == nil { + err.frames = make([]StackFrame, len(err.stack)) + + for i, pc := range err.stack { + err.frames[i] = NewStackFrame(pc) + } + } + + return err.frames +} + +// TypeName returns the type this error. e.g. *errors.stringError. +func (err *Error) TypeName() string { + if _, ok := err.Err.(uncaughtPanic); ok { + return "panic" + } + return reflect.TypeOf(err.Err).String() +} diff --git a/vendor/github.com/go-errors/errors/parse_panic.go b/vendor/github.com/go-errors/errors/parse_panic.go new file mode 100644 index 0000000000..cc37052d78 --- /dev/null +++ b/vendor/github.com/go-errors/errors/parse_panic.go @@ -0,0 +1,127 @@ +package errors + +import ( + "strconv" + "strings" +) + +type uncaughtPanic struct{ message string } + +func (p uncaughtPanic) Error() string { + return p.message +} + +// ParsePanic allows you to get an error object from the output of a go program +// that panicked. This is particularly useful with https://github.com/mitchellh/panicwrap. +func ParsePanic(text string) (*Error, error) { + lines := strings.Split(text, "\n") + + state := "start" + + var message string + var stack []StackFrame + + for i := 0; i < len(lines); i++ { + line := lines[i] + + if state == "start" { + if strings.HasPrefix(line, "panic: ") { + message = strings.TrimPrefix(line, "panic: ") + state = "seek" + } else { + return nil, Errorf("bugsnag.panicParser: Invalid line (no prefix): %s", line) + } + + } else if state == "seek" { + if strings.HasPrefix(line, "goroutine ") && strings.HasSuffix(line, "[running]:") { + state = "parsing" + } + + } else if state == "parsing" { + if line == "" { + state = "done" + break + } + createdBy := false + if strings.HasPrefix(line, "created by ") { + line = strings.TrimPrefix(line, "created by ") + createdBy = true + } + + i++ + + if i >= len(lines) { + return nil, Errorf("bugsnag.panicParser: Invalid line (unpaired): %s", line) + } + + frame, err := parsePanicFrame(line, lines[i], createdBy) + if err != nil { + return nil, err + } + + stack = append(stack, *frame) + if createdBy { + state = "done" + break + } + } + } + + if state == "done" || state == "parsing" { + return &Error{Err: uncaughtPanic{message}, frames: stack}, nil + } + return nil, Errorf("could not parse panic: %v", text) +} + +// The lines we're passing look like this: +// +// main.(*foo).destruct(0xc208067e98) +// /0/go/src/github.com/bugsnag/bugsnag-go/pan/main.go:22 +0x151 +func parsePanicFrame(name string, line string, createdBy bool) (*StackFrame, error) { + idx := strings.LastIndex(name, "(") + if idx == -1 && !createdBy { + return nil, Errorf("bugsnag.panicParser: Invalid line (no call): %s", name) + } + if idx != -1 { + name = name[:idx] + } + pkg := "" + + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + + if !strings.HasPrefix(line, "\t") { + return nil, Errorf("bugsnag.panicParser: Invalid line (no tab): %s", line) + } + + idx = strings.LastIndex(line, ":") + if idx == -1 { + return nil, Errorf("bugsnag.panicParser: Invalid line (no line number): %s", line) + } + file := line[1:idx] + + number := line[idx+1:] + if idx = strings.Index(number, " +"); idx > -1 { + number = number[:idx] + } + + lno, err := strconv.ParseInt(number, 10, 32) + if err != nil { + return nil, Errorf("bugsnag.panicParser: Invalid line (bad line number): %s", line) + } + + return &StackFrame{ + File: file, + LineNumber: int(lno), + Package: pkg, + Name: name, + }, nil +} diff --git a/vendor/github.com/go-errors/errors/stackframe.go b/vendor/github.com/go-errors/errors/stackframe.go new file mode 100644 index 0000000000..750ab9a521 --- /dev/null +++ b/vendor/github.com/go-errors/errors/stackframe.go @@ -0,0 +1,102 @@ +package errors + +import ( + "bytes" + "fmt" + "io/ioutil" + "runtime" + "strings" +) + +// A StackFrame contains all necessary information about to generate a line +// in a callstack. +type StackFrame struct { + // The path to the file containing this ProgramCounter + File string + // The LineNumber in that file + LineNumber int + // The Name of the function that contains this ProgramCounter + Name string + // The Package that contains this function + Package string + // The underlying ProgramCounter + ProgramCounter uintptr +} + +// NewStackFrame popoulates a stack frame object from the program counter. +func NewStackFrame(pc uintptr) (frame StackFrame) { + + frame = StackFrame{ProgramCounter: pc} + if frame.Func() == nil { + return + } + frame.Package, frame.Name = packageAndName(frame.Func()) + + // pc -1 because the program counters we use are usually return addresses, + // and we want to show the line that corresponds to the function call + frame.File, frame.LineNumber = frame.Func().FileLine(pc - 1) + return + +} + +// Func returns the function that contained this frame. +func (frame *StackFrame) Func() *runtime.Func { + if frame.ProgramCounter == 0 { + return nil + } + return runtime.FuncForPC(frame.ProgramCounter) +} + +// String returns the stackframe formatted in the same way as go does +// in runtime/debug.Stack() +func (frame *StackFrame) String() string { + str := fmt.Sprintf("%s:%d (0x%x)\n", frame.File, frame.LineNumber, frame.ProgramCounter) + + source, err := frame.SourceLine() + if err != nil { + return str + } + + return str + fmt.Sprintf("\t%s: %s\n", frame.Name, source) +} + +// SourceLine gets the line of code (from File and Line) of the original source if possible. +func (frame *StackFrame) SourceLine() (string, error) { + data, err := ioutil.ReadFile(frame.File) + + if err != nil { + return "", New(err) + } + + lines := bytes.Split(data, []byte{'\n'}) + if frame.LineNumber <= 0 || frame.LineNumber >= len(lines) { + return "???", nil + } + // -1 because line-numbers are 1 based, but our array is 0 based + return string(bytes.Trim(lines[frame.LineNumber-1], " \t")), nil +} + +func packageAndName(fn *runtime.Func) (string, string) { + name := fn.Name() + pkg := "" + + // The name includes the path name to the package, which is unnecessary + // since the file name is already included. Plus, it has center dots. + // That is, we see + // runtime/debug.*T·ptrmethod + // and want + // *T.ptrmethod + // Since the package path might contains dots (e.g. code.google.com/...), + // we first remove the path prefix if there is one. + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + return pkg, name +} diff --git a/vendor/github.com/godbus/dbus/.travis.yml b/vendor/github.com/godbus/dbus/.travis.yml new file mode 100644 index 0000000000..2e1bbb78c3 --- /dev/null +++ b/vendor/github.com/godbus/dbus/.travis.yml @@ -0,0 +1,40 @@ +dist: precise +language: go +go_import_path: github.com/godbus/dbus +sudo: true + +go: + - 1.6.3 + - 1.7.3 + - tip + +env: + global: + matrix: + - TARGET=amd64 + - TARGET=arm64 + - TARGET=arm + - TARGET=386 + - TARGET=ppc64le + +matrix: + fast_finish: true + allow_failures: + - go: tip + exclude: + - go: tip + env: TARGET=arm + - go: tip + env: TARGET=arm64 + - go: tip + env: TARGET=386 + - go: tip + env: TARGET=ppc64le + +addons: + apt: + packages: + - dbus + - dbus-x11 + +before_install: diff --git a/vendor/github.com/godbus/dbus/CONTRIBUTING.md b/vendor/github.com/godbus/dbus/CONTRIBUTING.md new file mode 100644 index 0000000000..c88f9b2bdd --- /dev/null +++ b/vendor/github.com/godbus/dbus/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# How to Contribute + +## Getting Started + +- Fork the repository on GitHub +- Read the [README](README.markdown) for build and test instructions +- Play with the project, submit bugs, submit patches! + +## Contribution Flow + +This is a rough outline of what a contributor's workflow looks like: + +- Create a topic branch from where you want to base your work (usually master). +- Make commits of logical units. +- Make sure your commit messages are in the proper format (see below). +- Push your changes to a topic branch in your fork of the repository. +- Make sure the tests pass, and add any new tests as appropriate. +- Submit a pull request to the original repository. + +Thanks for your contributions! + +### Format of the Commit Message + +We follow a rough convention for commit messages that is designed to answer two +questions: what changed and why. The subject line should feature the what and +the body of the commit should describe the why. + +``` +scripts: add the test-cluster command + +this uses tmux to setup a test cluster that you can easily kill and +start for debugging. + +Fixes #38 +``` + +The format can be described more formally as follows: + +``` +: + + + +