diff --git a/glide.lock b/glide.lock
index 2e004575..ffbffe67 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,5 +1,5 @@
-hash: aa4807befbaa3fa5d489feed6ecaca17a92edb6761f7a3aebfbb053f1c636754
-updated: 2017-07-12T21:49:20.87386587-05:00
+hash: ec07230b29cc1473d02179ae0a62534d03e5b4b7683e4227174a9296e7661081
+updated: 2017-07-14T02:08:26.222807645+05:30
imports:
- name: github.com/armon/go-radix
version: 4239b77079c7b5d1243b7b4736304ce8ddb6f0f2
@@ -125,7 +125,7 @@ imports:
- name: github.com/opencontainers/go-digest
version: 279bed98673dd5bef374d3b6e4b09e2af76183bf
- name: github.com/osrg/gobgp
- version: 9f9a71eab2bc9f2fed0d7c32a05f74d4c42b12ae
+ version: 3d01f04c8cb10ad91fb53e432d82ad9c4d8efff2
subpackages:
- api
- config
@@ -147,7 +147,9 @@ imports:
- name: github.com/satori/go.uuid
version: 5bf94b69c6b68ee1b541973bb8e1144db23a194b
- name: github.com/sirupsen/logrus
- version: 1fe8319fcaef78ef9220c9b05178df0f871dbc5d
+ version: 51dc0fc64317a2861273909081f9c315786533eb
+- name: github.com/Sirupsen/logrus
+ version: 51dc0fc64317a2861273909081f9c315786533eb
- name: github.com/spf13/afero
version: 9be650865eab0c12963d8753212f4f9c66cdcf12
subpackages:
diff --git a/glide.yaml b/glide.yaml
index fdf513ae..a17b863a 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -15,7 +15,7 @@ import:
- package: github.com/mqliang/libipvs
version: master
- package: github.com/osrg/gobgp
- version: ^1.17.0
+ version: ~1.20
subpackages:
- api
- config
diff --git a/vendor/github.com/Sirupsen/logrus/.gitignore b/vendor/github.com/Sirupsen/logrus/.gitignore
new file mode 100644
index 00000000..66be63a0
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/.gitignore
@@ -0,0 +1 @@
+logrus
diff --git a/vendor/github.com/Sirupsen/logrus/.travis.yml b/vendor/github.com/Sirupsen/logrus/.travis.yml
new file mode 100644
index 00000000..ceace13b
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/.travis.yml
@@ -0,0 +1,12 @@
+language: go
+go:
+ - 1.6.x
+ - 1.7.x
+ - 1.8.x
+ - tip
+env:
+ - GOMAXPROCS=4 GORACE=halt_on_error=1
+install:
+ - go get github.com/stretchr/testify/assert
+script:
+ - go test -race -v .
diff --git a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md
new file mode 100644
index 00000000..c443aed0
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md
@@ -0,0 +1,109 @@
+# 1.0.2
+
+* bug: quote non-string values in text formatter (#583)
+* Make (*Logger) SetLevel a public method
+
+# 1.0.1
+
+* bug: fix escaping in text formatter (#575)
+
+# 1.0.0
+
+* Officially changed name to lower-case
+* bug: colors on Windows 10 (#541)
+* bug: fix race in accessing level (#512)
+
+# 0.11.5
+
+* feature: add writer and writerlevel to entry (#372)
+
+# 0.11.4
+
+* bug: fix undefined variable on solaris (#493)
+
+# 0.11.3
+
+* formatter: configure quoting of empty values (#484)
+* formatter: configure quoting character (default is `"`) (#484)
+* bug: fix not importing io correctly in non-linux environments (#481)
+
+# 0.11.2
+
+* bug: fix windows terminal detection (#476)
+
+# 0.11.1
+
+* bug: fix tty detection with custom out (#471)
+
+# 0.11.0
+
+* performance: Use bufferpool to allocate (#370)
+* terminal: terminal detection for app-engine (#343)
+* feature: exit handler (#375)
+
+# 0.10.0
+
+* feature: Add a test hook (#180)
+* feature: `ParseLevel` is now case-insensitive (#326)
+* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
+* performance: avoid re-allocations on `WithFields` (#335)
+
+# 0.9.0
+
+* logrus/text_formatter: don't emit empty msg
+* logrus/hooks/airbrake: move out of main repository
+* logrus/hooks/sentry: move out of main repository
+* logrus/hooks/papertrail: move out of main repository
+* logrus/hooks/bugsnag: move out of main repository
+* logrus/core: run tests with `-race`
+* logrus/core: detect TTY based on `stderr`
+* logrus/core: support `WithError` on logger
+* logrus/core: Solaris support
+
+# 0.8.7
+
+* logrus/core: fix possible race (#216)
+* logrus/doc: small typo fixes and doc improvements
+
+
+# 0.8.6
+
+* hooks/raven: allow passing an initialized client
+
+# 0.8.5
+
+* logrus/core: revert #208
+
+# 0.8.4
+
+* formatter/text: fix data race (#218)
+
+# 0.8.3
+
+* logrus/core: fix entry log level (#208)
+* logrus/core: improve performance of text formatter by 40%
+* logrus/core: expose `LevelHooks` type
+* logrus/core: add support for DragonflyBSD and NetBSD
+* formatter/text: print structs more verbosely
+
+# 0.8.2
+
+* logrus: fix more Fatal family functions
+
+# 0.8.1
+
+* logrus: fix not exiting on `Fatalf` and `Fatalln`
+
+# 0.8.0
+
+* logrus: defaults to stderr instead of stdout
+* hooks/sentry: add special field for `*http.Request`
+* formatter/text: ignore Windows for colors
+
+# 0.7.3
+
+* formatter/\*: allow configuration of timestamp layout
+
+# 0.7.2
+
+* formatter/text: Add configuration option for time format (#158)
diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/Sirupsen/logrus/LICENSE
new file mode 100644
index 00000000..f090cb42
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Simon Eskildsen
+
+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/Sirupsen/logrus/README.md b/vendor/github.com/Sirupsen/logrus/README.md
new file mode 100644
index 00000000..82aeb4ee
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/README.md
@@ -0,0 +1,504 @@
+# Logrus
[](https://travis-ci.org/sirupsen/logrus) [](https://godoc.org/github.com/sirupsen/logrus)
+
+Logrus is a structured logger for Go (golang), completely API compatible with
+the standard library logger. [Godoc][godoc].
+
+**Seeing weird case-sensitive problems?** It's in the past been possible to
+import Logrus as both upper- and lower-case. Due to the Go package environment,
+this caused issues in the community and we needed a standard. Some environments
+experienced problems with the upper-case variant, so the lower-case was decided.
+Everything using `logrus` will need to use the lower-case:
+`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
+
+To fix Glide, see [these
+comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
+For an in-depth explanation of the casing issue, see [this
+comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
+
+**Are you interested in assisting in maintaining Logrus?** Currently I have a
+lot of obligations, and I am unable to provide Logrus with the maintainership it
+needs. If you'd like to help, please reach out to me at `simon at author's
+username dot com`.
+
+Nicely color-coded in development (when a TTY is attached, otherwise just
+plain text):
+
+
+
+With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
+or Splunk:
+
+```json
+{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
+ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
+
+{"level":"warning","msg":"The group's number increased tremendously!",
+"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
+
+{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
+"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
+
+{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
+"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
+
+{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
+"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
+```
+
+With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
+attached, the output is compatible with the
+[logfmt](http://godoc.org/github.com/kr/logfmt) format:
+
+```text
+time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
+time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
+time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
+time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
+time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
+time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
+exit status 1
+```
+
+#### Case-sensitivity
+
+The organization's name was changed to lower-case--and this will not be changed
+back. If you are getting import conflicts due to case sensitivity, please use
+the lower-case import: `github.com/sirupsen/logrus`.
+
+#### Example
+
+The simplest way to use Logrus is simply the package-level exported logger:
+
+```go
+package main
+
+import (
+ log "github.com/sirupsen/logrus"
+)
+
+func main() {
+ log.WithFields(log.Fields{
+ "animal": "walrus",
+ }).Info("A walrus appears")
+}
+```
+
+Note that it's completely api-compatible with the stdlib logger, so you can
+replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
+and you'll now have the flexibility of Logrus. You can customize it all you
+want:
+
+```go
+package main
+
+import (
+ "os"
+ log "github.com/sirupsen/logrus"
+)
+
+func init() {
+ // Log as JSON instead of the default ASCII formatter.
+ log.SetFormatter(&log.JSONFormatter{})
+
+ // Output to stdout instead of the default stderr
+ // Can be any io.Writer, see below for File example
+ log.SetOutput(os.Stdout)
+
+ // Only log the warning severity or above.
+ log.SetLevel(log.WarnLevel)
+}
+
+func main() {
+ log.WithFields(log.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+
+ log.WithFields(log.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("The group's number increased tremendously!")
+
+ log.WithFields(log.Fields{
+ "omg": true,
+ "number": 100,
+ }).Fatal("The ice breaks!")
+
+ // A common pattern is to re-use fields between logging statements by re-using
+ // the logrus.Entry returned from WithFields()
+ contextLogger := log.WithFields(log.Fields{
+ "common": "this is a common field",
+ "other": "I also should be logged always",
+ })
+
+ contextLogger.Info("I'll be logged with common and other field")
+ contextLogger.Info("Me too")
+}
+```
+
+For more advanced usage such as logging to multiple locations from the same
+application, you can also create an instance of the `logrus` Logger:
+
+```go
+package main
+
+import (
+ "os"
+ "github.com/sirupsen/logrus"
+)
+
+// Create a new instance of the logger. You can have any number of instances.
+var log = logrus.New()
+
+func main() {
+ // The API for setting attributes is a little different than the package level
+ // exported logger. See Godoc.
+ log.Out = os.Stdout
+
+ // You could set this to any `io.Writer` such as a file
+ // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
+ // if err == nil {
+ // log.Out = file
+ // } else {
+ // log.Info("Failed to log to file, using default stderr")
+ // }
+
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+}
+```
+
+#### Fields
+
+Logrus encourages careful, structured logging through logging fields instead of
+long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
+to send event %s to topic %s with key %d")`, you should log the much more
+discoverable:
+
+```go
+log.WithFields(log.Fields{
+ "event": event,
+ "topic": topic,
+ "key": key,
+}).Fatal("Failed to send event")
+```
+
+We've found this API forces you to think about logging in a way that produces
+much more useful logging messages. We've been in countless situations where just
+a single added field to a log statement that was already there would've saved us
+hours. The `WithFields` call is optional.
+
+In general, with Logrus using any of the `printf`-family functions should be
+seen as a hint you should add a field, however, you can still use the
+`printf`-family functions with Logrus.
+
+#### Default Fields
+
+Often it's helpful to have fields _always_ attached to log statements in an
+application or parts of one. For example, you may want to always log the
+`request_id` and `user_ip` in the context of a request. Instead of writing
+`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on
+every line, you can create a `logrus.Entry` to pass around instead:
+
+```go
+requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
+requestLogger.Info("something happened on that request") # will log request_id and user_ip
+requestLogger.Warn("something not great happened")
+```
+
+#### Hooks
+
+You can add hooks for logging levels. For example to send errors to an exception
+tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
+multiple places simultaneously, e.g. syslog.
+
+Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
+`init`:
+
+```go
+import (
+ log "github.com/sirupsen/logrus"
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
+ logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
+ "log/syslog"
+)
+
+func init() {
+
+ // Use the Airbrake hook to report errors that have Error severity or above to
+ // an exception tracker. You can create custom hooks, see the Hooks section.
+ log.AddHook(airbrake.NewHook(123, "xyz", "production"))
+
+ hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+ if err != nil {
+ log.Error("Unable to connect to local syslog daemon")
+ } else {
+ log.AddHook(hook)
+ }
+}
+```
+Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
+
+| Hook | Description |
+| ----- | ----------- |
+| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
+| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. |
+| [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) |
+| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) |
+| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
+| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
+| [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) |
+| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch|
+| [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/)
+| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
+| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) |
+| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) |
+| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
+| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
+| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
+| [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) |
+| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
+| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
+| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
+| [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) |
+| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) |
+| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) |
+| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
+| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
+| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
+| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) |
+| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
+| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
+| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
+| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
+| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) |
+| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) |
+| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) |
+| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) |
+| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
+| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)|
+| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
+| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
+| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
+| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
+| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
+| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
+| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
+| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
+| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
+| [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) |
+
+#### Level logging
+
+Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
+
+```go
+log.Debug("Useful debugging information.")
+log.Info("Something noteworthy happened!")
+log.Warn("You should probably take a look at this.")
+log.Error("Something failed but I'm not quitting.")
+// Calls os.Exit(1) after logging
+log.Fatal("Bye.")
+// Calls panic() after logging
+log.Panic("I'm bailing.")
+```
+
+You can set the logging level on a `Logger`, then it will only log entries with
+that severity or anything above it:
+
+```go
+// Will log anything that is info or above (warn, error, fatal, panic). Default.
+log.SetLevel(log.InfoLevel)
+```
+
+It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
+environment if your application has that.
+
+#### Entries
+
+Besides the fields added with `WithField` or `WithFields` some fields are
+automatically added to all logging events:
+
+1. `time`. The timestamp when the entry was created.
+2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
+ the `AddFields` call. E.g. `Failed to send event.`
+3. `level`. The logging level. E.g. `info`.
+
+#### Environments
+
+Logrus has no notion of environment.
+
+If you wish for hooks and formatters to only be used in specific environments,
+you should handle that yourself. For example, if your application has a global
+variable `Environment`, which is a string representation of the environment you
+could do:
+
+```go
+import (
+ log "github.com/sirupsen/logrus"
+)
+
+init() {
+ // do something here to set environment depending on an environment variable
+ // or command-line flag
+ if Environment == "production" {
+ log.SetFormatter(&log.JSONFormatter{})
+ } else {
+ // The TextFormatter is default, you don't actually have to do this.
+ log.SetFormatter(&log.TextFormatter{})
+ }
+}
+```
+
+This configuration is how `logrus` was intended to be used, but JSON in
+production is mostly only useful if you do log aggregation with tools like
+Splunk or Logstash.
+
+#### Formatters
+
+The built-in logging formatters are:
+
+* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
+ without colors.
+ * *Note:* to force colored output when there is no TTY, set the `ForceColors`
+ field to `true`. To force no colored output even if there is a TTY set the
+ `DisableColors` field to `true`. For Windows, see
+ [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
+ * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
+* `logrus.JSONFormatter`. Logs fields as JSON.
+ * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
+
+Third party logging formatters:
+
+* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
+* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
+* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
+
+You can define your formatter by implementing the `Formatter` interface,
+requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
+`Fields` type (`map[string]interface{}`) with all your fields as well as the
+default ones (see Entries section above):
+
+```go
+type MyJSONFormatter struct {
+}
+
+log.SetFormatter(new(MyJSONFormatter))
+
+func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
+ // Note this doesn't include Time, Level and Message which are available on
+ // the Entry. Consult `godoc` on information about those fields or read the
+ // source of the official loggers.
+ serialized, err := json.Marshal(entry.Data)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
+ }
+ return append(serialized, '\n'), nil
+}
+```
+
+#### Logger as an `io.Writer`
+
+Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
+
+```go
+w := logger.Writer()
+defer w.Close()
+
+srv := http.Server{
+ // create a stdlib log.Logger that writes to
+ // logrus.Logger.
+ ErrorLog: log.New(w, "", 0),
+}
+```
+
+Each line written to that writer will be printed the usual way, using formatters
+and hooks. The level for those entries is `info`.
+
+This means that we can override the standard library logger easily:
+
+```go
+logger := logrus.New()
+logger.Formatter = &logrus.JSONFormatter{}
+
+// Use logrus for standard log output
+// Note that `log` here references stdlib's log
+// Not logrus imported under the name `log`.
+log.SetOutput(logger.Writer())
+```
+
+#### Rotation
+
+Log rotation is not provided with Logrus. Log rotation should be done by an
+external program (like `logrotate(8)`) that can compress and delete old log
+entries. It should not be a feature of the application-level logger.
+
+#### Tools
+
+| Tool | Description |
+| ---- | ----------- |
+|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
+|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
+
+#### Testing
+
+Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
+
+* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook
+* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
+
+```go
+import(
+ "github.com/sirupsen/logrus"
+ "github.com/sirupsen/logrus/hooks/test"
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestSomething(t*testing.T){
+ logger, hook := test.NewNullLogger()
+ logger.Error("Helloerror")
+
+ assert.Equal(t, 1, len(hook.Entries))
+ assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
+ assert.Equal(t, "Helloerror", hook.LastEntry().Message)
+
+ hook.Reset()
+ assert.Nil(t, hook.LastEntry())
+}
+```
+
+#### Fatal handlers
+
+Logrus can register one or more functions that will be called when any `fatal`
+level message is logged. The registered handlers will be executed before
+logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need
+to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
+
+```
+...
+handler := func() {
+ // gracefully shutdown something...
+}
+logrus.RegisterExitHandler(handler)
+...
+```
+
+#### Thread safety
+
+By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs.
+If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
+
+Situation when locking is not needed includes:
+
+* You have no hooks registered, or hooks calling is already thread-safe.
+
+* Writing to logger.Out is already thread-safe, for example:
+
+ 1) logger.Out is protected by locks.
+
+ 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing)
+
+ (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/Sirupsen/logrus/alt_exit.go
new file mode 100644
index 00000000..8af90637
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/alt_exit.go
@@ -0,0 +1,64 @@
+package logrus
+
+// The following code was sourced and modified from the
+// https://github.com/tebeka/atexit package governed by the following license:
+//
+// Copyright (c) 2012 Miki Tebeka .
+//
+// 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.
+
+import (
+ "fmt"
+ "os"
+)
+
+var handlers = []func(){}
+
+func runHandler(handler func()) {
+ defer func() {
+ if err := recover(); err != nil {
+ fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
+ }
+ }()
+
+ handler()
+}
+
+func runHandlers() {
+ for _, handler := range handlers {
+ runHandler(handler)
+ }
+}
+
+// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
+func Exit(code int) {
+ runHandlers()
+ os.Exit(code)
+}
+
+// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
+// all handlers. The handlers will also be invoked when any Fatal log entry is
+// made.
+//
+// This method is useful when a caller wishes to use logrus to log a fatal
+// message but also needs to gracefully shutdown. An example usecase could be
+// closing database connections, or sending a alert that the application is
+// closing.
+func RegisterExitHandler(handler func()) {
+ handlers = append(handlers, handler)
+}
diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit_test.go b/vendor/github.com/Sirupsen/logrus/alt_exit_test.go
new file mode 100644
index 00000000..d1829634
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/alt_exit_test.go
@@ -0,0 +1,74 @@
+package logrus
+
+import (
+ "io/ioutil"
+ "os/exec"
+ "testing"
+ "time"
+)
+
+func TestRegister(t *testing.T) {
+ current := len(handlers)
+ RegisterExitHandler(func() {})
+ if len(handlers) != current+1 {
+ t.Fatalf("can't add handler")
+ }
+}
+
+func TestHandler(t *testing.T) {
+ gofile := "/tmp/testprog.go"
+ if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil {
+ t.Fatalf("can't create go file")
+ }
+
+ outfile := "/tmp/testprog.out"
+ arg := time.Now().UTC().String()
+ err := exec.Command("go", "run", gofile, outfile, arg).Run()
+ if err == nil {
+ t.Fatalf("completed normally, should have failed")
+ }
+
+ data, err := ioutil.ReadFile(outfile)
+ if err != nil {
+ t.Fatalf("can't read output file %s", outfile)
+ }
+
+ if string(data) != arg {
+ t.Fatalf("bad data")
+ }
+}
+
+var testprog = []byte(`
+// Test program for atexit, gets output file and data as arguments and writes
+// data to output file in atexit handler.
+package main
+
+import (
+ "github.com/sirupsen/logrus"
+ "flag"
+ "fmt"
+ "io/ioutil"
+)
+
+var outfile = ""
+var data = ""
+
+func handler() {
+ ioutil.WriteFile(outfile, []byte(data), 0666)
+}
+
+func badHandler() {
+ n := 0
+ fmt.Println(1/n)
+}
+
+func main() {
+ flag.Parse()
+ outfile = flag.Arg(0)
+ data = flag.Arg(1)
+
+ logrus.RegisterExitHandler(handler)
+ logrus.RegisterExitHandler(badHandler)
+ logrus.Fatal("Bye bye")
+}
+`)
diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/Sirupsen/logrus/doc.go
new file mode 100644
index 00000000..da67aba0
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/doc.go
@@ -0,0 +1,26 @@
+/*
+Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
+
+
+The simplest way to use Logrus is simply the package-level exported logger:
+
+ package main
+
+ import (
+ log "github.com/sirupsen/logrus"
+ )
+
+ func main() {
+ log.WithFields(log.Fields{
+ "animal": "walrus",
+ "number": 1,
+ "size": 10,
+ }).Info("A walrus appears")
+ }
+
+Output:
+ time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
+
+For a full guide visit https://github.com/sirupsen/logrus
+*/
+package logrus
diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/Sirupsen/logrus/entry.go
new file mode 100644
index 00000000..320e5d5b
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/entry.go
@@ -0,0 +1,275 @@
+package logrus
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "sync"
+ "time"
+)
+
+var bufferPool *sync.Pool
+
+func init() {
+ bufferPool = &sync.Pool{
+ New: func() interface{} {
+ return new(bytes.Buffer)
+ },
+ }
+}
+
+// Defines the key when adding errors using WithError.
+var ErrorKey = "error"
+
+// An entry is the final or intermediate Logrus logging entry. It contains all
+// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
+// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
+// passed around as much as you wish to avoid field duplication.
+type Entry struct {
+ Logger *Logger
+
+ // Contains all the fields set by the user.
+ Data Fields
+
+ // Time at which the log entry was created
+ Time time.Time
+
+ // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
+ Level Level
+
+ // Message passed to Debug, Info, Warn, Error, Fatal or Panic
+ Message string
+
+ // When formatter is called in entry.log(), an Buffer may be set to entry
+ Buffer *bytes.Buffer
+}
+
+func NewEntry(logger *Logger) *Entry {
+ return &Entry{
+ Logger: logger,
+ // Default is three fields, give a little extra room
+ Data: make(Fields, 5),
+ }
+}
+
+// Returns the string representation from the reader and ultimately the
+// formatter.
+func (entry *Entry) String() (string, error) {
+ serialized, err := entry.Logger.Formatter.Format(entry)
+ if err != nil {
+ return "", err
+ }
+ str := string(serialized)
+ return str, nil
+}
+
+// Add an error as single field (using the key defined in ErrorKey) to the Entry.
+func (entry *Entry) WithError(err error) *Entry {
+ return entry.WithField(ErrorKey, err)
+}
+
+// Add a single field to the Entry.
+func (entry *Entry) WithField(key string, value interface{}) *Entry {
+ return entry.WithFields(Fields{key: value})
+}
+
+// Add a map of fields to the Entry.
+func (entry *Entry) WithFields(fields Fields) *Entry {
+ data := make(Fields, len(entry.Data)+len(fields))
+ for k, v := range entry.Data {
+ data[k] = v
+ }
+ for k, v := range fields {
+ data[k] = v
+ }
+ return &Entry{Logger: entry.Logger, Data: data}
+}
+
+// This function is not declared with a pointer value because otherwise
+// race conditions will occur when using multiple goroutines
+func (entry Entry) log(level Level, msg string) {
+ var buffer *bytes.Buffer
+ entry.Time = time.Now()
+ entry.Level = level
+ entry.Message = msg
+
+ if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
+ entry.Logger.mu.Lock()
+ fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
+ entry.Logger.mu.Unlock()
+ }
+ buffer = bufferPool.Get().(*bytes.Buffer)
+ buffer.Reset()
+ defer bufferPool.Put(buffer)
+ entry.Buffer = buffer
+ serialized, err := entry.Logger.Formatter.Format(&entry)
+ entry.Buffer = nil
+ if err != nil {
+ entry.Logger.mu.Lock()
+ fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
+ entry.Logger.mu.Unlock()
+ } else {
+ entry.Logger.mu.Lock()
+ _, err = entry.Logger.Out.Write(serialized)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
+ }
+ entry.Logger.mu.Unlock()
+ }
+
+ // To avoid Entry#log() returning a value that only would make sense for
+ // panic() to use in Entry#Panic(), we avoid the allocation by checking
+ // directly here.
+ if level <= PanicLevel {
+ panic(&entry)
+ }
+}
+
+func (entry *Entry) Debug(args ...interface{}) {
+ if entry.Logger.level() >= DebugLevel {
+ entry.log(DebugLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Print(args ...interface{}) {
+ entry.Info(args...)
+}
+
+func (entry *Entry) Info(args ...interface{}) {
+ if entry.Logger.level() >= InfoLevel {
+ entry.log(InfoLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Warn(args ...interface{}) {
+ if entry.Logger.level() >= WarnLevel {
+ entry.log(WarnLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Warning(args ...interface{}) {
+ entry.Warn(args...)
+}
+
+func (entry *Entry) Error(args ...interface{}) {
+ if entry.Logger.level() >= ErrorLevel {
+ entry.log(ErrorLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Fatal(args ...interface{}) {
+ if entry.Logger.level() >= FatalLevel {
+ entry.log(FatalLevel, fmt.Sprint(args...))
+ }
+ Exit(1)
+}
+
+func (entry *Entry) Panic(args ...interface{}) {
+ if entry.Logger.level() >= PanicLevel {
+ entry.log(PanicLevel, fmt.Sprint(args...))
+ }
+ panic(fmt.Sprint(args...))
+}
+
+// Entry Printf family functions
+
+func (entry *Entry) Debugf(format string, args ...interface{}) {
+ if entry.Logger.level() >= DebugLevel {
+ entry.Debug(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Infof(format string, args ...interface{}) {
+ if entry.Logger.level() >= InfoLevel {
+ entry.Info(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Printf(format string, args ...interface{}) {
+ entry.Infof(format, args...)
+}
+
+func (entry *Entry) Warnf(format string, args ...interface{}) {
+ if entry.Logger.level() >= WarnLevel {
+ entry.Warn(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Warningf(format string, args ...interface{}) {
+ entry.Warnf(format, args...)
+}
+
+func (entry *Entry) Errorf(format string, args ...interface{}) {
+ if entry.Logger.level() >= ErrorLevel {
+ entry.Error(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Fatalf(format string, args ...interface{}) {
+ if entry.Logger.level() >= FatalLevel {
+ entry.Fatal(fmt.Sprintf(format, args...))
+ }
+ Exit(1)
+}
+
+func (entry *Entry) Panicf(format string, args ...interface{}) {
+ if entry.Logger.level() >= PanicLevel {
+ entry.Panic(fmt.Sprintf(format, args...))
+ }
+}
+
+// Entry Println family functions
+
+func (entry *Entry) Debugln(args ...interface{}) {
+ if entry.Logger.level() >= DebugLevel {
+ entry.Debug(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Infoln(args ...interface{}) {
+ if entry.Logger.level() >= InfoLevel {
+ entry.Info(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Println(args ...interface{}) {
+ entry.Infoln(args...)
+}
+
+func (entry *Entry) Warnln(args ...interface{}) {
+ if entry.Logger.level() >= WarnLevel {
+ entry.Warn(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Warningln(args ...interface{}) {
+ entry.Warnln(args...)
+}
+
+func (entry *Entry) Errorln(args ...interface{}) {
+ if entry.Logger.level() >= ErrorLevel {
+ entry.Error(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Fatalln(args ...interface{}) {
+ if entry.Logger.level() >= FatalLevel {
+ entry.Fatal(entry.sprintlnn(args...))
+ }
+ Exit(1)
+}
+
+func (entry *Entry) Panicln(args ...interface{}) {
+ if entry.Logger.level() >= PanicLevel {
+ entry.Panic(entry.sprintlnn(args...))
+ }
+}
+
+// Sprintlnn => Sprint no newline. This is to get the behavior of how
+// fmt.Sprintln where spaces are always added between operands, regardless of
+// their type. Instead of vendoring the Sprintln implementation to spare a
+// string allocation, we do the simplest thing.
+func (entry *Entry) sprintlnn(args ...interface{}) string {
+ msg := fmt.Sprintln(args...)
+ return msg[:len(msg)-1]
+}
diff --git a/vendor/github.com/Sirupsen/logrus/entry_test.go b/vendor/github.com/Sirupsen/logrus/entry_test.go
new file mode 100644
index 00000000..99c3b41d
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/entry_test.go
@@ -0,0 +1,77 @@
+package logrus
+
+import (
+ "bytes"
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestEntryWithError(t *testing.T) {
+
+ assert := assert.New(t)
+
+ defer func() {
+ ErrorKey = "error"
+ }()
+
+ err := fmt.Errorf("kaboom at layer %d", 4711)
+
+ assert.Equal(err, WithError(err).Data["error"])
+
+ logger := New()
+ logger.Out = &bytes.Buffer{}
+ entry := NewEntry(logger)
+
+ assert.Equal(err, entry.WithError(err).Data["error"])
+
+ ErrorKey = "err"
+
+ assert.Equal(err, entry.WithError(err).Data["err"])
+
+}
+
+func TestEntryPanicln(t *testing.T) {
+ errBoom := fmt.Errorf("boom time")
+
+ defer func() {
+ p := recover()
+ assert.NotNil(t, p)
+
+ switch pVal := p.(type) {
+ case *Entry:
+ assert.Equal(t, "kaboom", pVal.Message)
+ assert.Equal(t, errBoom, pVal.Data["err"])
+ default:
+ t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
+ }
+ }()
+
+ logger := New()
+ logger.Out = &bytes.Buffer{}
+ entry := NewEntry(logger)
+ entry.WithField("err", errBoom).Panicln("kaboom")
+}
+
+func TestEntryPanicf(t *testing.T) {
+ errBoom := fmt.Errorf("boom again")
+
+ defer func() {
+ p := recover()
+ assert.NotNil(t, p)
+
+ switch pVal := p.(type) {
+ case *Entry:
+ assert.Equal(t, "kaboom true", pVal.Message)
+ assert.Equal(t, errBoom, pVal.Data["err"])
+ default:
+ t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
+ }
+ }()
+
+ logger := New()
+ logger.Out = &bytes.Buffer{}
+ entry := NewEntry(logger)
+ entry.WithField("err", errBoom).Panicf("kaboom %v", true)
+}
diff --git a/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go b/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
new file mode 100644
index 00000000..3e112b4e
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
@@ -0,0 +1,59 @@
+package main
+
+import (
+ "github.com/sirupsen/logrus"
+ // "os"
+)
+
+var log = logrus.New()
+
+func init() {
+ log.Formatter = new(logrus.JSONFormatter)
+ log.Formatter = new(logrus.TextFormatter) // default
+
+ // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
+ // if err == nil {
+ // log.Out = file
+ // } else {
+ // log.Info("Failed to log to file, using default stderr")
+ // }
+
+ log.Level = logrus.DebugLevel
+}
+
+func main() {
+ defer func() {
+ err := recover()
+ if err != nil {
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "err": err,
+ "number": 100,
+ }).Fatal("The ice breaks!")
+ }
+ }()
+
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "number": 8,
+ }).Debug("Started observing beach")
+
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("The group's number increased tremendously!")
+
+ log.WithFields(logrus.Fields{
+ "temperature": -4,
+ }).Debug("Temperature changes")
+
+ log.WithFields(logrus.Fields{
+ "animal": "orca",
+ "size": 9009,
+ }).Panic("It's over 9000!")
+}
diff --git a/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go b/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
new file mode 100644
index 00000000..c8470c38
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
@@ -0,0 +1,30 @@
+package main
+
+import (
+ "github.com/sirupsen/logrus"
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
+)
+
+var log = logrus.New()
+
+func init() {
+ log.Formatter = new(logrus.TextFormatter) // default
+ log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
+}
+
+func main() {
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("The group's number increased tremendously!")
+
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 100,
+ }).Fatal("The ice breaks!")
+}
diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/Sirupsen/logrus/exported.go
new file mode 100644
index 00000000..013183ed
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/exported.go
@@ -0,0 +1,193 @@
+package logrus
+
+import (
+ "io"
+)
+
+var (
+ // std is the name of the standard logger in stdlib `log`
+ std = New()
+)
+
+func StandardLogger() *Logger {
+ return std
+}
+
+// SetOutput sets the standard logger output.
+func SetOutput(out io.Writer) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.Out = out
+}
+
+// SetFormatter sets the standard logger formatter.
+func SetFormatter(formatter Formatter) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.Formatter = formatter
+}
+
+// SetLevel sets the standard logger level.
+func SetLevel(level Level) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.SetLevel(level)
+}
+
+// GetLevel returns the standard logger level.
+func GetLevel() Level {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ return std.level()
+}
+
+// AddHook adds a hook to the standard logger hooks.
+func AddHook(hook Hook) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.Hooks.Add(hook)
+}
+
+// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
+func WithError(err error) *Entry {
+ return std.WithField(ErrorKey, err)
+}
+
+// WithField creates an entry from the standard logger and adds a field to
+// it. If you want multiple fields, use `WithFields`.
+//
+// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
+// or Panic on the Entry it returns.
+func WithField(key string, value interface{}) *Entry {
+ return std.WithField(key, value)
+}
+
+// WithFields creates an entry from the standard logger and adds multiple
+// fields to it. This is simply a helper for `WithField`, invoking it
+// once for each field.
+//
+// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
+// or Panic on the Entry it returns.
+func WithFields(fields Fields) *Entry {
+ return std.WithFields(fields)
+}
+
+// Debug logs a message at level Debug on the standard logger.
+func Debug(args ...interface{}) {
+ std.Debug(args...)
+}
+
+// Print logs a message at level Info on the standard logger.
+func Print(args ...interface{}) {
+ std.Print(args...)
+}
+
+// Info logs a message at level Info on the standard logger.
+func Info(args ...interface{}) {
+ std.Info(args...)
+}
+
+// Warn logs a message at level Warn on the standard logger.
+func Warn(args ...interface{}) {
+ std.Warn(args...)
+}
+
+// Warning logs a message at level Warn on the standard logger.
+func Warning(args ...interface{}) {
+ std.Warning(args...)
+}
+
+// Error logs a message at level Error on the standard logger.
+func Error(args ...interface{}) {
+ std.Error(args...)
+}
+
+// Panic logs a message at level Panic on the standard logger.
+func Panic(args ...interface{}) {
+ std.Panic(args...)
+}
+
+// Fatal logs a message at level Fatal on the standard logger.
+func Fatal(args ...interface{}) {
+ std.Fatal(args...)
+}
+
+// Debugf logs a message at level Debug on the standard logger.
+func Debugf(format string, args ...interface{}) {
+ std.Debugf(format, args...)
+}
+
+// Printf logs a message at level Info on the standard logger.
+func Printf(format string, args ...interface{}) {
+ std.Printf(format, args...)
+}
+
+// Infof logs a message at level Info on the standard logger.
+func Infof(format string, args ...interface{}) {
+ std.Infof(format, args...)
+}
+
+// Warnf logs a message at level Warn on the standard logger.
+func Warnf(format string, args ...interface{}) {
+ std.Warnf(format, args...)
+}
+
+// Warningf logs a message at level Warn on the standard logger.
+func Warningf(format string, args ...interface{}) {
+ std.Warningf(format, args...)
+}
+
+// Errorf logs a message at level Error on the standard logger.
+func Errorf(format string, args ...interface{}) {
+ std.Errorf(format, args...)
+}
+
+// Panicf logs a message at level Panic on the standard logger.
+func Panicf(format string, args ...interface{}) {
+ std.Panicf(format, args...)
+}
+
+// Fatalf logs a message at level Fatal on the standard logger.
+func Fatalf(format string, args ...interface{}) {
+ std.Fatalf(format, args...)
+}
+
+// Debugln logs a message at level Debug on the standard logger.
+func Debugln(args ...interface{}) {
+ std.Debugln(args...)
+}
+
+// Println logs a message at level Info on the standard logger.
+func Println(args ...interface{}) {
+ std.Println(args...)
+}
+
+// Infoln logs a message at level Info on the standard logger.
+func Infoln(args ...interface{}) {
+ std.Infoln(args...)
+}
+
+// Warnln logs a message at level Warn on the standard logger.
+func Warnln(args ...interface{}) {
+ std.Warnln(args...)
+}
+
+// Warningln logs a message at level Warn on the standard logger.
+func Warningln(args ...interface{}) {
+ std.Warningln(args...)
+}
+
+// Errorln logs a message at level Error on the standard logger.
+func Errorln(args ...interface{}) {
+ std.Errorln(args...)
+}
+
+// Panicln logs a message at level Panic on the standard logger.
+func Panicln(args ...interface{}) {
+ std.Panicln(args...)
+}
+
+// Fatalln logs a message at level Fatal on the standard logger.
+func Fatalln(args ...interface{}) {
+ std.Fatalln(args...)
+}
diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/Sirupsen/logrus/formatter.go
new file mode 100644
index 00000000..b5fbe934
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/formatter.go
@@ -0,0 +1,45 @@
+package logrus
+
+import "time"
+
+const DefaultTimestampFormat = time.RFC3339
+
+// The Formatter interface is used to implement a custom Formatter. It takes an
+// `Entry`. It exposes all the fields, including the default ones:
+//
+// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
+// * `entry.Data["time"]`. The timestamp.
+// * `entry.Data["level"]. The level the entry was logged at.
+//
+// Any additional fields added with `WithField` or `WithFields` are also in
+// `entry.Data`. Format is expected to return an array of bytes which are then
+// logged to `logger.Out`.
+type Formatter interface {
+ Format(*Entry) ([]byte, error)
+}
+
+// This is to not silently overwrite `time`, `msg` and `level` fields when
+// dumping it. If this code wasn't there doing:
+//
+// logrus.WithField("level", 1).Info("hello")
+//
+// Would just silently drop the user provided level. Instead with this code
+// it'll logged as:
+//
+// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
+//
+// It's not exported because it's still using Data in an opinionated way. It's to
+// avoid code duplication between the two default formatters.
+func prefixFieldClashes(data Fields) {
+ if t, ok := data["time"]; ok {
+ data["fields.time"] = t
+ }
+
+ if m, ok := data["msg"]; ok {
+ data["fields.msg"] = m
+ }
+
+ if l, ok := data["level"]; ok {
+ data["fields.level"] = l
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/formatter_bench_test.go b/vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
new file mode 100644
index 00000000..d9481589
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
@@ -0,0 +1,101 @@
+package logrus
+
+import (
+ "fmt"
+ "testing"
+ "time"
+)
+
+// smallFields is a small size data set for benchmarking
+var smallFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+}
+
+// largeFields is a large size data set for benchmarking
+var largeFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+ "five": "six",
+ "seven": "eight",
+ "nine": "ten",
+ "eleven": "twelve",
+ "thirteen": "fourteen",
+ "fifteen": "sixteen",
+ "seventeen": "eighteen",
+ "nineteen": "twenty",
+ "a": "b",
+ "c": "d",
+ "e": "f",
+ "g": "h",
+ "i": "j",
+ "k": "l",
+ "m": "n",
+ "o": "p",
+ "q": "r",
+ "s": "t",
+ "u": "v",
+ "w": "x",
+ "y": "z",
+ "this": "will",
+ "make": "thirty",
+ "entries": "yeah",
+}
+
+var errorFields = Fields{
+ "foo": fmt.Errorf("bar"),
+ "baz": fmt.Errorf("qux"),
+}
+
+func BenchmarkErrorTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields)
+}
+
+func BenchmarkSmallTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
+}
+
+func BenchmarkLargeTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
+}
+
+func BenchmarkSmallColoredTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
+}
+
+func BenchmarkLargeColoredTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
+}
+
+func BenchmarkSmallJSONFormatter(b *testing.B) {
+ doBenchmark(b, &JSONFormatter{}, smallFields)
+}
+
+func BenchmarkLargeJSONFormatter(b *testing.B) {
+ doBenchmark(b, &JSONFormatter{}, largeFields)
+}
+
+func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
+ logger := New()
+
+ entry := &Entry{
+ Time: time.Time{},
+ Level: InfoLevel,
+ Message: "message",
+ Data: fields,
+ Logger: logger,
+ }
+ var d []byte
+ var err error
+ for i := 0; i < b.N; i++ {
+ d, err = formatter.Format(entry)
+ if err != nil {
+ b.Fatal(err)
+ }
+ b.SetBytes(int64(len(d)))
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/hook_test.go b/vendor/github.com/Sirupsen/logrus/hook_test.go
new file mode 100644
index 00000000..13f34cb6
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/hook_test.go
@@ -0,0 +1,122 @@
+package logrus
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+type TestHook struct {
+ Fired bool
+}
+
+func (hook *TestHook) Fire(entry *Entry) error {
+ hook.Fired = true
+ return nil
+}
+
+func (hook *TestHook) Levels() []Level {
+ return []Level{
+ DebugLevel,
+ InfoLevel,
+ WarnLevel,
+ ErrorLevel,
+ FatalLevel,
+ PanicLevel,
+ }
+}
+
+func TestHookFires(t *testing.T) {
+ hook := new(TestHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ assert.Equal(t, hook.Fired, false)
+
+ log.Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, hook.Fired, true)
+ })
+}
+
+type ModifyHook struct {
+}
+
+func (hook *ModifyHook) Fire(entry *Entry) error {
+ entry.Data["wow"] = "whale"
+ return nil
+}
+
+func (hook *ModifyHook) Levels() []Level {
+ return []Level{
+ DebugLevel,
+ InfoLevel,
+ WarnLevel,
+ ErrorLevel,
+ FatalLevel,
+ PanicLevel,
+ }
+}
+
+func TestHookCanModifyEntry(t *testing.T) {
+ hook := new(ModifyHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ log.WithField("wow", "elephant").Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["wow"], "whale")
+ })
+}
+
+func TestCanFireMultipleHooks(t *testing.T) {
+ hook1 := new(ModifyHook)
+ hook2 := new(TestHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook1)
+ log.Hooks.Add(hook2)
+
+ log.WithField("wow", "elephant").Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["wow"], "whale")
+ assert.Equal(t, hook2.Fired, true)
+ })
+}
+
+type ErrorHook struct {
+ Fired bool
+}
+
+func (hook *ErrorHook) Fire(entry *Entry) error {
+ hook.Fired = true
+ return nil
+}
+
+func (hook *ErrorHook) Levels() []Level {
+ return []Level{
+ ErrorLevel,
+ }
+}
+
+func TestErrorHookShouldntFireOnInfo(t *testing.T) {
+ hook := new(ErrorHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ log.Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, hook.Fired, false)
+ })
+}
+
+func TestErrorHookShouldFireOnError(t *testing.T) {
+ hook := new(ErrorHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ log.Error("test")
+ }, func(fields Fields) {
+ assert.Equal(t, hook.Fired, true)
+ })
+}
diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/Sirupsen/logrus/hooks.go
new file mode 100644
index 00000000..3f151cdc
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/hooks.go
@@ -0,0 +1,34 @@
+package logrus
+
+// A hook to be fired when logging on the logging levels returned from
+// `Levels()` on your implementation of the interface. Note that this is not
+// fired in a goroutine or a channel with workers, you should handle such
+// functionality yourself if your call is non-blocking and you don't wish for
+// the logging calls for levels returned from `Levels()` to block.
+type Hook interface {
+ Levels() []Level
+ Fire(*Entry) error
+}
+
+// Internal type for storing the hooks on a logger instance.
+type LevelHooks map[Level][]Hook
+
+// Add a hook to an instance of logger. This is called with
+// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
+func (hooks LevelHooks) Add(hook Hook) {
+ for _, level := range hook.Levels() {
+ hooks[level] = append(hooks[level], hook)
+ }
+}
+
+// Fire all the hooks for the passed level. Used by `entry.log` to fire
+// appropriate hooks for a log entry.
+func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
+ for _, hook := range hooks[level] {
+ if err := hook.Fire(entry); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md b/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
new file mode 100644
index 00000000..92b391c1
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
@@ -0,0 +1,39 @@
+# Syslog Hooks for Logrus
+
+## Usage
+
+```go
+import (
+ "log/syslog"
+ "github.com/sirupsen/logrus"
+ logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
+)
+
+func main() {
+ log := logrus.New()
+ hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+
+ if err == nil {
+ log.Hooks.Add(hook)
+ }
+}
+```
+
+If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following.
+
+```go
+import (
+ "log/syslog"
+ "github.com/sirupsen/logrus"
+ logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
+)
+
+func main() {
+ log := logrus.New()
+ hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
+
+ if err == nil {
+ log.Hooks.Add(hook)
+ }
+}
+```
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go b/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
new file mode 100644
index 00000000..204f0016
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
@@ -0,0 +1,54 @@
+// +build !windows,!nacl,!plan9
+
+package logrus_syslog
+
+import (
+ "fmt"
+ "github.com/sirupsen/logrus"
+ "log/syslog"
+ "os"
+)
+
+// SyslogHook to send logs via syslog.
+type SyslogHook struct {
+ Writer *syslog.Writer
+ SyslogNetwork string
+ SyslogRaddr string
+}
+
+// Creates a hook to be added to an instance of logger. This is called with
+// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
+// `if err == nil { log.Hooks.Add(hook) }`
+func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
+ w, err := syslog.Dial(network, raddr, priority, tag)
+ return &SyslogHook{w, network, raddr}, err
+}
+
+func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
+ line, err := entry.String()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
+ return err
+ }
+
+ switch entry.Level {
+ case logrus.PanicLevel:
+ return hook.Writer.Crit(line)
+ case logrus.FatalLevel:
+ return hook.Writer.Crit(line)
+ case logrus.ErrorLevel:
+ return hook.Writer.Err(line)
+ case logrus.WarnLevel:
+ return hook.Writer.Warning(line)
+ case logrus.InfoLevel:
+ return hook.Writer.Info(line)
+ case logrus.DebugLevel:
+ return hook.Writer.Debug(line)
+ default:
+ return nil
+ }
+}
+
+func (hook *SyslogHook) Levels() []logrus.Level {
+ return logrus.AllLevels
+}
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go b/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
new file mode 100644
index 00000000..8d7fbe45
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
@@ -0,0 +1,26 @@
+package logrus_syslog
+
+import (
+ "github.com/sirupsen/logrus"
+ "log/syslog"
+ "testing"
+)
+
+func TestLocalhostAddAndPrint(t *testing.T) {
+ log := logrus.New()
+ hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+
+ if err != nil {
+ t.Errorf("Unable to connect to local syslog.")
+ }
+
+ log.Hooks.Add(hook)
+
+ for _, level := range hook.Levels() {
+ if len(log.Hooks[level]) != 1 {
+ t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
+ }
+ }
+
+ log.Info("Congratulations!")
+}
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/test/test.go b/vendor/github.com/Sirupsen/logrus/hooks/test/test.go
new file mode 100644
index 00000000..62c4845d
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/hooks/test/test.go
@@ -0,0 +1,95 @@
+// The Test package is used for testing logrus. It is here for backwards
+// compatibility from when logrus' organization was upper-case. Please use
+// lower-case logrus and the `null` package instead of this one.
+package test
+
+import (
+ "io/ioutil"
+ "sync"
+
+ "github.com/sirupsen/logrus"
+)
+
+// Hook is a hook designed for dealing with logs in test scenarios.
+type Hook struct {
+ // Entries is an array of all entries that have been received by this hook.
+ // For safe access, use the AllEntries() method, rather than reading this
+ // value directly.
+ Entries []*logrus.Entry
+ mu sync.RWMutex
+}
+
+// NewGlobal installs a test hook for the global logger.
+func NewGlobal() *Hook {
+
+ hook := new(Hook)
+ logrus.AddHook(hook)
+
+ return hook
+
+}
+
+// NewLocal installs a test hook for a given local logger.
+func NewLocal(logger *logrus.Logger) *Hook {
+
+ hook := new(Hook)
+ logger.Hooks.Add(hook)
+
+ return hook
+
+}
+
+// NewNullLogger creates a discarding logger and installs the test hook.
+func NewNullLogger() (*logrus.Logger, *Hook) {
+
+ logger := logrus.New()
+ logger.Out = ioutil.Discard
+
+ return logger, NewLocal(logger)
+
+}
+
+func (t *Hook) Fire(e *logrus.Entry) error {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ t.Entries = append(t.Entries, e)
+ return nil
+}
+
+func (t *Hook) Levels() []logrus.Level {
+ return logrus.AllLevels
+}
+
+// LastEntry returns the last entry that was logged or nil.
+func (t *Hook) LastEntry() *logrus.Entry {
+ t.mu.RLock()
+ defer t.mu.RUnlock()
+ i := len(t.Entries) - 1
+ if i < 0 {
+ return nil
+ }
+ // Make a copy, for safety
+ e := *t.Entries[i]
+ return &e
+}
+
+// AllEntries returns all entries that were logged.
+func (t *Hook) AllEntries() []*logrus.Entry {
+ t.mu.RLock()
+ defer t.mu.RUnlock()
+ // Make a copy so the returned value won't race with future log requests
+ entries := make([]*logrus.Entry, len(t.Entries))
+ for i, entry := range t.Entries {
+ // Make a copy, for safety
+ e := *entry
+ entries[i] = &e
+ }
+ return entries
+}
+
+// Reset removes all Entries from this test hook.
+func (t *Hook) Reset() {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ t.Entries = make([]*logrus.Entry, 0)
+}
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/test/test_test.go b/vendor/github.com/Sirupsen/logrus/hooks/test/test_test.go
new file mode 100644
index 00000000..3f55cfe3
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/hooks/test/test_test.go
@@ -0,0 +1,39 @@
+package test
+
+import (
+ "testing"
+
+ "github.com/sirupsen/logrus"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAllHooks(t *testing.T) {
+
+ assert := assert.New(t)
+
+ logger, hook := NewNullLogger()
+ assert.Nil(hook.LastEntry())
+ assert.Equal(0, len(hook.Entries))
+
+ logger.Error("Hello error")
+ assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
+ assert.Equal("Hello error", hook.LastEntry().Message)
+ assert.Equal(1, len(hook.Entries))
+
+ logger.Warn("Hello warning")
+ assert.Equal(logrus.WarnLevel, hook.LastEntry().Level)
+ assert.Equal("Hello warning", hook.LastEntry().Message)
+ assert.Equal(2, len(hook.Entries))
+
+ hook.Reset()
+ assert.Nil(hook.LastEntry())
+ assert.Equal(0, len(hook.Entries))
+
+ hook = NewGlobal()
+
+ logrus.Error("Hello error")
+ assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
+ assert.Equal("Hello error", hook.LastEntry().Message)
+ assert.Equal(1, len(hook.Entries))
+
+}
diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/Sirupsen/logrus/json_formatter.go
new file mode 100644
index 00000000..e787ea17
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/json_formatter.go
@@ -0,0 +1,74 @@
+package logrus
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+type fieldKey string
+type FieldMap map[fieldKey]string
+
+const (
+ FieldKeyMsg = "msg"
+ FieldKeyLevel = "level"
+ FieldKeyTime = "time"
+)
+
+func (f FieldMap) resolve(key fieldKey) string {
+ if k, ok := f[key]; ok {
+ return k
+ }
+
+ return string(key)
+}
+
+type JSONFormatter struct {
+ // TimestampFormat sets the format used for marshaling timestamps.
+ TimestampFormat string
+
+ // DisableTimestamp allows disabling automatic timestamps in output
+ DisableTimestamp bool
+
+ // FieldMap allows users to customize the names of keys for various fields.
+ // As an example:
+ // formatter := &JSONFormatter{
+ // FieldMap: FieldMap{
+ // FieldKeyTime: "@timestamp",
+ // FieldKeyLevel: "@level",
+ // FieldKeyMsg: "@message",
+ // },
+ // }
+ FieldMap FieldMap
+}
+
+func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
+ data := make(Fields, len(entry.Data)+3)
+ for k, v := range entry.Data {
+ switch v := v.(type) {
+ case error:
+ // Otherwise errors are ignored by `encoding/json`
+ // https://github.com/sirupsen/logrus/issues/137
+ data[k] = v.Error()
+ default:
+ data[k] = v
+ }
+ }
+ prefixFieldClashes(data)
+
+ timestampFormat := f.TimestampFormat
+ if timestampFormat == "" {
+ timestampFormat = DefaultTimestampFormat
+ }
+
+ if !f.DisableTimestamp {
+ data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
+ }
+ data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
+ data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
+
+ serialized, err := json.Marshal(data)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
+ }
+ return append(serialized, '\n'), nil
+}
diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter_test.go b/vendor/github.com/Sirupsen/logrus/json_formatter_test.go
new file mode 100644
index 00000000..51093a79
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/json_formatter_test.go
@@ -0,0 +1,199 @@
+package logrus
+
+import (
+ "encoding/json"
+ "errors"
+ "strings"
+ "testing"
+)
+
+func TestErrorNotLost(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["error"] != "wild walrus" {
+ t.Fatal("Error field not set")
+ }
+}
+
+func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["omg"] != "wild walrus" {
+ t.Fatal("Error field not set")
+ }
+}
+
+func TestFieldClashWithTime(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("time", "right now!"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["fields.time"] != "right now!" {
+ t.Fatal("fields.time not set to original time field")
+ }
+
+ if entry["time"] != "0001-01-01T00:00:00Z" {
+ t.Fatal("time field not set to current time, was: ", entry["time"])
+ }
+}
+
+func TestFieldClashWithMsg(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("msg", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["fields.msg"] != "something" {
+ t.Fatal("fields.msg not set to original msg field")
+ }
+}
+
+func TestFieldClashWithLevel(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["fields.level"] != "something" {
+ t.Fatal("fields.level not set to original level field")
+ }
+}
+
+func TestJSONEntryEndsWithNewline(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ if b[len(b)-1] != '\n' {
+ t.Fatal("Expected JSON log entry to end with a newline")
+ }
+}
+
+func TestJSONMessageKey(t *testing.T) {
+ formatter := &JSONFormatter{
+ FieldMap: FieldMap{
+ FieldKeyMsg: "message",
+ },
+ }
+
+ b, err := formatter.Format(&Entry{Message: "oh hai"})
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !(strings.Contains(s, "message") && strings.Contains(s, "oh hai")) {
+ t.Fatal("Expected JSON to format message key")
+ }
+}
+
+func TestJSONLevelKey(t *testing.T) {
+ formatter := &JSONFormatter{
+ FieldMap: FieldMap{
+ FieldKeyLevel: "somelevel",
+ },
+ }
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !strings.Contains(s, "somelevel") {
+ t.Fatal("Expected JSON to format level key")
+ }
+}
+
+func TestJSONTimeKey(t *testing.T) {
+ formatter := &JSONFormatter{
+ FieldMap: FieldMap{
+ FieldKeyTime: "timeywimey",
+ },
+ }
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !strings.Contains(s, "timeywimey") {
+ t.Fatal("Expected JSON to format time key")
+ }
+}
+
+func TestJSONDisableTimestamp(t *testing.T) {
+ formatter := &JSONFormatter{
+ DisableTimestamp: true,
+ }
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if strings.Contains(s, FieldKeyTime) {
+ t.Error("Did not prevent timestamp", s)
+ }
+}
+
+func TestJSONEnableTimestamp(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !strings.Contains(s, FieldKeyTime) {
+ t.Error("Timestamp not present", s)
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/Sirupsen/logrus/logger.go
new file mode 100644
index 00000000..b44966f9
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/logger.go
@@ -0,0 +1,317 @@
+package logrus
+
+import (
+ "io"
+ "os"
+ "sync"
+ "sync/atomic"
+)
+
+type Logger struct {
+ // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
+ // file, or leave it default which is `os.Stderr`. You can also set this to
+ // something more adventorous, such as logging to Kafka.
+ Out io.Writer
+ // Hooks for the logger instance. These allow firing events based on logging
+ // levels and log entries. For example, to send errors to an error tracking
+ // service, log to StatsD or dump the core on fatal errors.
+ Hooks LevelHooks
+ // All log entries pass through the formatter before logged to Out. The
+ // included formatters are `TextFormatter` and `JSONFormatter` for which
+ // TextFormatter is the default. In development (when a TTY is attached) it
+ // logs with colors, but to a file it wouldn't. You can easily implement your
+ // own that implements the `Formatter` interface, see the `README` or included
+ // formatters for examples.
+ Formatter Formatter
+ // The logging level the logger should log at. This is typically (and defaults
+ // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
+ // logged. `logrus.Debug` is useful in
+ Level Level
+ // Used to sync writing to the log. Locking is enabled by Default
+ mu MutexWrap
+ // Reusable empty entry
+ entryPool sync.Pool
+}
+
+type MutexWrap struct {
+ lock sync.Mutex
+ disabled bool
+}
+
+func (mw *MutexWrap) Lock() {
+ if !mw.disabled {
+ mw.lock.Lock()
+ }
+}
+
+func (mw *MutexWrap) Unlock() {
+ if !mw.disabled {
+ mw.lock.Unlock()
+ }
+}
+
+func (mw *MutexWrap) Disable() {
+ mw.disabled = true
+}
+
+// Creates a new logger. Configuration should be set by changing `Formatter`,
+// `Out` and `Hooks` directly on the default logger instance. You can also just
+// instantiate your own:
+//
+// var log = &Logger{
+// Out: os.Stderr,
+// Formatter: new(JSONFormatter),
+// Hooks: make(LevelHooks),
+// Level: logrus.DebugLevel,
+// }
+//
+// It's recommended to make this a global instance called `log`.
+func New() *Logger {
+ return &Logger{
+ Out: os.Stderr,
+ Formatter: new(TextFormatter),
+ Hooks: make(LevelHooks),
+ Level: InfoLevel,
+ }
+}
+
+func (logger *Logger) newEntry() *Entry {
+ entry, ok := logger.entryPool.Get().(*Entry)
+ if ok {
+ return entry
+ }
+ return NewEntry(logger)
+}
+
+func (logger *Logger) releaseEntry(entry *Entry) {
+ logger.entryPool.Put(entry)
+}
+
+// Adds a field to the log entry, note that it doesn't log until you call
+// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
+// If you want multiple fields, use `WithFields`.
+func (logger *Logger) WithField(key string, value interface{}) *Entry {
+ entry := logger.newEntry()
+ defer logger.releaseEntry(entry)
+ return entry.WithField(key, value)
+}
+
+// Adds a struct of fields to the log entry. All it does is call `WithField` for
+// each `Field`.
+func (logger *Logger) WithFields(fields Fields) *Entry {
+ entry := logger.newEntry()
+ defer logger.releaseEntry(entry)
+ return entry.WithFields(fields)
+}
+
+// Add an error as single field to the log entry. All it does is call
+// `WithError` for the given `error`.
+func (logger *Logger) WithError(err error) *Entry {
+ entry := logger.newEntry()
+ defer logger.releaseEntry(entry)
+ return entry.WithError(err)
+}
+
+func (logger *Logger) Debugf(format string, args ...interface{}) {
+ if logger.level() >= DebugLevel {
+ entry := logger.newEntry()
+ entry.Debugf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Infof(format string, args ...interface{}) {
+ if logger.level() >= InfoLevel {
+ entry := logger.newEntry()
+ entry.Infof(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Printf(format string, args ...interface{}) {
+ entry := logger.newEntry()
+ entry.Printf(format, args...)
+ logger.releaseEntry(entry)
+}
+
+func (logger *Logger) Warnf(format string, args ...interface{}) {
+ if logger.level() >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Warningf(format string, args ...interface{}) {
+ if logger.level() >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Errorf(format string, args ...interface{}) {
+ if logger.level() >= ErrorLevel {
+ entry := logger.newEntry()
+ entry.Errorf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Fatalf(format string, args ...interface{}) {
+ if logger.level() >= FatalLevel {
+ entry := logger.newEntry()
+ entry.Fatalf(format, args...)
+ logger.releaseEntry(entry)
+ }
+ Exit(1)
+}
+
+func (logger *Logger) Panicf(format string, args ...interface{}) {
+ if logger.level() >= PanicLevel {
+ entry := logger.newEntry()
+ entry.Panicf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Debug(args ...interface{}) {
+ if logger.level() >= DebugLevel {
+ entry := logger.newEntry()
+ entry.Debug(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Info(args ...interface{}) {
+ if logger.level() >= InfoLevel {
+ entry := logger.newEntry()
+ entry.Info(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Print(args ...interface{}) {
+ entry := logger.newEntry()
+ entry.Info(args...)
+ logger.releaseEntry(entry)
+}
+
+func (logger *Logger) Warn(args ...interface{}) {
+ if logger.level() >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warn(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Warning(args ...interface{}) {
+ if logger.level() >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warn(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Error(args ...interface{}) {
+ if logger.level() >= ErrorLevel {
+ entry := logger.newEntry()
+ entry.Error(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Fatal(args ...interface{}) {
+ if logger.level() >= FatalLevel {
+ entry := logger.newEntry()
+ entry.Fatal(args...)
+ logger.releaseEntry(entry)
+ }
+ Exit(1)
+}
+
+func (logger *Logger) Panic(args ...interface{}) {
+ if logger.level() >= PanicLevel {
+ entry := logger.newEntry()
+ entry.Panic(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Debugln(args ...interface{}) {
+ if logger.level() >= DebugLevel {
+ entry := logger.newEntry()
+ entry.Debugln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Infoln(args ...interface{}) {
+ if logger.level() >= InfoLevel {
+ entry := logger.newEntry()
+ entry.Infoln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Println(args ...interface{}) {
+ entry := logger.newEntry()
+ entry.Println(args...)
+ logger.releaseEntry(entry)
+}
+
+func (logger *Logger) Warnln(args ...interface{}) {
+ if logger.level() >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Warningln(args ...interface{}) {
+ if logger.level() >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Errorln(args ...interface{}) {
+ if logger.level() >= ErrorLevel {
+ entry := logger.newEntry()
+ entry.Errorln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Fatalln(args ...interface{}) {
+ if logger.level() >= FatalLevel {
+ entry := logger.newEntry()
+ entry.Fatalln(args...)
+ logger.releaseEntry(entry)
+ }
+ Exit(1)
+}
+
+func (logger *Logger) Panicln(args ...interface{}) {
+ if logger.level() >= PanicLevel {
+ entry := logger.newEntry()
+ entry.Panicln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+//When file is opened with appending mode, it's safe to
+//write concurrently to a file (within 4k message on Linux).
+//In these cases user can choose to disable the lock.
+func (logger *Logger) SetNoLock() {
+ logger.mu.Disable()
+}
+
+func (logger *Logger) level() Level {
+ return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
+}
+
+func (logger *Logger) SetLevel(level Level) {
+ atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
+}
diff --git a/vendor/github.com/Sirupsen/logrus/logger_bench_test.go b/vendor/github.com/Sirupsen/logrus/logger_bench_test.go
new file mode 100644
index 00000000..dd23a353
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/logger_bench_test.go
@@ -0,0 +1,61 @@
+package logrus
+
+import (
+ "os"
+ "testing"
+)
+
+// smallFields is a small size data set for benchmarking
+var loggerFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+}
+
+func BenchmarkDummyLogger(b *testing.B) {
+ nullf, err := os.OpenFile("/dev/null", os.O_WRONLY, 0666)
+ if err != nil {
+ b.Fatalf("%v", err)
+ }
+ defer nullf.Close()
+ doLoggerBenchmark(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
+}
+
+func BenchmarkDummyLoggerNoLock(b *testing.B) {
+ nullf, err := os.OpenFile("/dev/null", os.O_WRONLY|os.O_APPEND, 0666)
+ if err != nil {
+ b.Fatalf("%v", err)
+ }
+ defer nullf.Close()
+ doLoggerBenchmarkNoLock(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
+}
+
+func doLoggerBenchmark(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
+ logger := Logger{
+ Out: out,
+ Level: InfoLevel,
+ Formatter: formatter,
+ }
+ entry := logger.WithFields(fields)
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ entry.Info("aaa")
+ }
+ })
+}
+
+func doLoggerBenchmarkNoLock(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
+ logger := Logger{
+ Out: out,
+ Level: InfoLevel,
+ Formatter: formatter,
+ }
+ logger.SetNoLock()
+ entry := logger.WithFields(fields)
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ entry.Info("aaa")
+ }
+ })
+}
diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/Sirupsen/logrus/logrus.go
new file mode 100644
index 00000000..dd389997
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/logrus.go
@@ -0,0 +1,143 @@
+package logrus
+
+import (
+ "fmt"
+ "log"
+ "strings"
+)
+
+// Fields type, used to pass to `WithFields`.
+type Fields map[string]interface{}
+
+// Level type
+type Level uint32
+
+// Convert the Level to a string. E.g. PanicLevel becomes "panic".
+func (level Level) String() string {
+ switch level {
+ case DebugLevel:
+ return "debug"
+ case InfoLevel:
+ return "info"
+ case WarnLevel:
+ return "warning"
+ case ErrorLevel:
+ return "error"
+ case FatalLevel:
+ return "fatal"
+ case PanicLevel:
+ return "panic"
+ }
+
+ return "unknown"
+}
+
+// ParseLevel takes a string level and returns the Logrus log level constant.
+func ParseLevel(lvl string) (Level, error) {
+ switch strings.ToLower(lvl) {
+ case "panic":
+ return PanicLevel, nil
+ case "fatal":
+ return FatalLevel, nil
+ case "error":
+ return ErrorLevel, nil
+ case "warn", "warning":
+ return WarnLevel, nil
+ case "info":
+ return InfoLevel, nil
+ case "debug":
+ return DebugLevel, nil
+ }
+
+ var l Level
+ return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
+}
+
+// A constant exposing all logging levels
+var AllLevels = []Level{
+ PanicLevel,
+ FatalLevel,
+ ErrorLevel,
+ WarnLevel,
+ InfoLevel,
+ DebugLevel,
+}
+
+// These are the different logging levels. You can set the logging level to log
+// on your instance of logger, obtained with `logrus.New()`.
+const (
+ // PanicLevel level, highest level of severity. Logs and then calls panic with the
+ // message passed to Debug, Info, ...
+ PanicLevel Level = iota
+ // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
+ // logging level is set to Panic.
+ FatalLevel
+ // ErrorLevel level. Logs. Used for errors that should definitely be noted.
+ // Commonly used for hooks to send errors to an error tracking service.
+ ErrorLevel
+ // WarnLevel level. Non-critical entries that deserve eyes.
+ WarnLevel
+ // InfoLevel level. General operational entries about what's going on inside the
+ // application.
+ InfoLevel
+ // DebugLevel level. Usually only enabled when debugging. Very verbose logging.
+ DebugLevel
+)
+
+// Won't compile if StdLogger can't be realized by a log.Logger
+var (
+ _ StdLogger = &log.Logger{}
+ _ StdLogger = &Entry{}
+ _ StdLogger = &Logger{}
+)
+
+// StdLogger is what your logrus-enabled library should take, that way
+// it'll accept a stdlib logger and a logrus logger. There's no standard
+// interface, this is the closest we get, unfortunately.
+type StdLogger interface {
+ Print(...interface{})
+ Printf(string, ...interface{})
+ Println(...interface{})
+
+ Fatal(...interface{})
+ Fatalf(string, ...interface{})
+ Fatalln(...interface{})
+
+ Panic(...interface{})
+ Panicf(string, ...interface{})
+ Panicln(...interface{})
+}
+
+// The FieldLogger interface generalizes the Entry and Logger types
+type FieldLogger interface {
+ WithField(key string, value interface{}) *Entry
+ WithFields(fields Fields) *Entry
+ WithError(err error) *Entry
+
+ Debugf(format string, args ...interface{})
+ Infof(format string, args ...interface{})
+ Printf(format string, args ...interface{})
+ Warnf(format string, args ...interface{})
+ Warningf(format string, args ...interface{})
+ Errorf(format string, args ...interface{})
+ Fatalf(format string, args ...interface{})
+ Panicf(format string, args ...interface{})
+
+ Debug(args ...interface{})
+ Info(args ...interface{})
+ Print(args ...interface{})
+ Warn(args ...interface{})
+ Warning(args ...interface{})
+ Error(args ...interface{})
+ Fatal(args ...interface{})
+ Panic(args ...interface{})
+
+ Debugln(args ...interface{})
+ Infoln(args ...interface{})
+ Println(args ...interface{})
+ Warnln(args ...interface{})
+ Warningln(args ...interface{})
+ Errorln(args ...interface{})
+ Fatalln(args ...interface{})
+ Panicln(args ...interface{})
+}
diff --git a/vendor/github.com/Sirupsen/logrus/logrus_test.go b/vendor/github.com/Sirupsen/logrus/logrus_test.go
new file mode 100644
index 00000000..78cbc282
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/logrus_test.go
@@ -0,0 +1,386 @@
+package logrus
+
+import (
+ "bytes"
+ "encoding/json"
+ "strconv"
+ "strings"
+ "sync"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
+ var buffer bytes.Buffer
+ var fields Fields
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = new(JSONFormatter)
+
+ log(logger)
+
+ err := json.Unmarshal(buffer.Bytes(), &fields)
+ assert.Nil(t, err)
+
+ assertions(fields)
+}
+
+func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
+ var buffer bytes.Buffer
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = &TextFormatter{
+ DisableColors: true,
+ }
+
+ log(logger)
+
+ fields := make(map[string]string)
+ for _, kv := range strings.Split(buffer.String(), " ") {
+ if !strings.Contains(kv, "=") {
+ continue
+ }
+ kvArr := strings.Split(kv, "=")
+ key := strings.TrimSpace(kvArr[0])
+ val := kvArr[1]
+ if kvArr[1][0] == '"' {
+ var err error
+ val, err = strconv.Unquote(val)
+ assert.NoError(t, err)
+ }
+ fields[key] = val
+ }
+ assertions(fields)
+}
+
+func TestPrint(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["level"], "info")
+ })
+}
+
+func TestInfo(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["level"], "info")
+ })
+}
+
+func TestWarn(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Warn("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["level"], "warning")
+ })
+}
+
+func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln("test", "test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test test")
+ })
+}
+
+func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln("test", 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test 10")
+ })
+}
+
+func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln(10, 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "10 10")
+ })
+}
+
+func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln(10, 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "10 10")
+ })
+}
+
+func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Info("test", 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test10")
+ })
+}
+
+func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Info("test", "test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "testtest")
+ })
+}
+
+func TestWithFieldsShouldAllowAssignments(t *testing.T) {
+ var buffer bytes.Buffer
+ var fields Fields
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = new(JSONFormatter)
+
+ localLog := logger.WithFields(Fields{
+ "key1": "value1",
+ })
+
+ localLog.WithField("key2", "value2").Info("test")
+ err := json.Unmarshal(buffer.Bytes(), &fields)
+ assert.Nil(t, err)
+
+ assert.Equal(t, "value2", fields["key2"])
+ assert.Equal(t, "value1", fields["key1"])
+
+ buffer = bytes.Buffer{}
+ fields = Fields{}
+ localLog.Info("test")
+ err = json.Unmarshal(buffer.Bytes(), &fields)
+ assert.Nil(t, err)
+
+ _, ok := fields["key2"]
+ assert.Equal(t, false, ok)
+ assert.Equal(t, "value1", fields["key1"])
+}
+
+func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("msg", "hello").Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ })
+}
+
+func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("msg", "hello").Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["fields.msg"], "hello")
+ })
+}
+
+func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("time", "hello").Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["fields.time"], "hello")
+ })
+}
+
+func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("level", 1).Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["level"], "info")
+ assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
+ })
+}
+
+func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
+ LogAndAssertText(t, func(log *Logger) {
+ ll := log.WithField("herp", "derp")
+ ll.Info("hello")
+ ll.Info("bye")
+ }, func(fields map[string]string) {
+ for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
+ if _, ok := fields[fieldName]; ok {
+ t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
+ }
+ }
+ })
+}
+
+func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
+
+ var buffer bytes.Buffer
+ var fields Fields
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = new(JSONFormatter)
+
+ llog := logger.WithField("context", "eating raw fish")
+
+ llog.Info("looks delicious")
+
+ err := json.Unmarshal(buffer.Bytes(), &fields)
+ assert.NoError(t, err, "should have decoded first message")
+ assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
+ assert.Equal(t, fields["msg"], "looks delicious")
+ assert.Equal(t, fields["context"], "eating raw fish")
+
+ buffer.Reset()
+
+ llog.Warn("omg it is!")
+
+ err = json.Unmarshal(buffer.Bytes(), &fields)
+ assert.NoError(t, err, "should have decoded second message")
+ assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
+ assert.Equal(t, fields["msg"], "omg it is!")
+ assert.Equal(t, fields["context"], "eating raw fish")
+ assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
+
+}
+
+func TestConvertLevelToString(t *testing.T) {
+ assert.Equal(t, "debug", DebugLevel.String())
+ assert.Equal(t, "info", InfoLevel.String())
+ assert.Equal(t, "warning", WarnLevel.String())
+ assert.Equal(t, "error", ErrorLevel.String())
+ assert.Equal(t, "fatal", FatalLevel.String())
+ assert.Equal(t, "panic", PanicLevel.String())
+}
+
+func TestParseLevel(t *testing.T) {
+ l, err := ParseLevel("panic")
+ assert.Nil(t, err)
+ assert.Equal(t, PanicLevel, l)
+
+ l, err = ParseLevel("PANIC")
+ assert.Nil(t, err)
+ assert.Equal(t, PanicLevel, l)
+
+ l, err = ParseLevel("fatal")
+ assert.Nil(t, err)
+ assert.Equal(t, FatalLevel, l)
+
+ l, err = ParseLevel("FATAL")
+ assert.Nil(t, err)
+ assert.Equal(t, FatalLevel, l)
+
+ l, err = ParseLevel("error")
+ assert.Nil(t, err)
+ assert.Equal(t, ErrorLevel, l)
+
+ l, err = ParseLevel("ERROR")
+ assert.Nil(t, err)
+ assert.Equal(t, ErrorLevel, l)
+
+ l, err = ParseLevel("warn")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("WARN")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("warning")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("WARNING")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("info")
+ assert.Nil(t, err)
+ assert.Equal(t, InfoLevel, l)
+
+ l, err = ParseLevel("INFO")
+ assert.Nil(t, err)
+ assert.Equal(t, InfoLevel, l)
+
+ l, err = ParseLevel("debug")
+ assert.Nil(t, err)
+ assert.Equal(t, DebugLevel, l)
+
+ l, err = ParseLevel("DEBUG")
+ assert.Nil(t, err)
+ assert.Equal(t, DebugLevel, l)
+
+ l, err = ParseLevel("invalid")
+ assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
+}
+
+func TestGetSetLevelRace(t *testing.T) {
+ wg := sync.WaitGroup{}
+ for i := 0; i < 100; i++ {
+ wg.Add(1)
+ go func(i int) {
+ defer wg.Done()
+ if i%2 == 0 {
+ SetLevel(InfoLevel)
+ } else {
+ GetLevel()
+ }
+ }(i)
+
+ }
+ wg.Wait()
+}
+
+func TestLoggingRace(t *testing.T) {
+ logger := New()
+
+ var wg sync.WaitGroup
+ wg.Add(100)
+
+ for i := 0; i < 100; i++ {
+ go func() {
+ logger.Info("info")
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+}
+
+// Compile test
+func TestLogrusInterface(t *testing.T) {
+ var buffer bytes.Buffer
+ fn := func(l FieldLogger) {
+ b := l.WithField("key", "value")
+ b.Debug("Test")
+ }
+ // test logger
+ logger := New()
+ logger.Out = &buffer
+ fn(logger)
+
+ // test Entry
+ e := logger.WithField("another", "value")
+ fn(e)
+}
+
+// Implements io.Writer using channels for synchronization, so we can wait on
+// the Entry.Writer goroutine to write in a non-racey way. This does assume that
+// there is a single call to Logger.Out for each message.
+type channelWriter chan []byte
+
+func (cw channelWriter) Write(p []byte) (int, error) {
+ cw <- p
+ return len(p), nil
+}
+
+func TestEntryWriter(t *testing.T) {
+ cw := channelWriter(make(chan []byte, 1))
+ log := New()
+ log.Out = cw
+ log.Formatter = new(JSONFormatter)
+ log.WithField("foo", "bar").WriterLevel(WarnLevel).Write([]byte("hello\n"))
+
+ bs := <-cw
+ var fields Fields
+ err := json.Unmarshal(bs, &fields)
+ assert.Nil(t, err)
+ assert.Equal(t, fields["foo"], "bar")
+ assert.Equal(t, fields["level"], "warning")
+}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_appengine.go b/vendor/github.com/Sirupsen/logrus/terminal_appengine.go
new file mode 100644
index 00000000..e011a869
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/terminal_appengine.go
@@ -0,0 +1,10 @@
+// +build appengine
+
+package logrus
+
+import "io"
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ return true
+}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go
new file mode 100644
index 00000000..5f6be4d3
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go
@@ -0,0 +1,10 @@
+// +build darwin freebsd openbsd netbsd dragonfly
+// +build !appengine
+
+package logrus
+
+import "syscall"
+
+const ioctlReadTermios = syscall.TIOCGETA
+
+type Termios syscall.Termios
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/Sirupsen/logrus/terminal_linux.go
new file mode 100644
index 00000000..308160ca
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/terminal_linux.go
@@ -0,0 +1,14 @@
+// Based on ssh/terminal:
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package logrus
+
+import "syscall"
+
+const ioctlReadTermios = syscall.TCGETS
+
+type Termios syscall.Termios
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
new file mode 100644
index 00000000..190297ab
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
@@ -0,0 +1,28 @@
+// Based on ssh/terminal:
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux darwin freebsd openbsd netbsd dragonfly
+// +build !appengine
+
+package logrus
+
+import (
+ "io"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ var termios Termios
+ switch v := f.(type) {
+ case *os.File:
+ _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+ return err == 0
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go b/vendor/github.com/Sirupsen/logrus/terminal_solaris.go
new file mode 100644
index 00000000..3c86b1ab
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/terminal_solaris.go
@@ -0,0 +1,21 @@
+// +build solaris,!appengine
+
+package logrus
+
+import (
+ "io"
+ "os"
+
+ "golang.org/x/sys/unix"
+)
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ switch v := f.(type) {
+ case *os.File:
+ _, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA)
+ return err == nil
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_windows.go
new file mode 100644
index 00000000..7a336307
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/terminal_windows.go
@@ -0,0 +1,82 @@
+// Based on ssh/terminal:
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows,!appengine
+
+package logrus
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+var kernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+var (
+ procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
+ procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
+)
+
+const (
+ enableProcessedOutput = 0x0001
+ enableWrapAtEolOutput = 0x0002
+ enableVirtualTerminalProcessing = 0x0004
+)
+
+func getVersion() (float64, error) {
+ stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
+ cmd := exec.Command("cmd", "ver")
+ cmd.Stdout = stdout
+ cmd.Stderr = stderr
+ err := cmd.Run()
+ if err != nil {
+ return -1, err
+ }
+
+ // The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
+ version := strings.Replace(stdout.String(), "\n", "", -1)
+ version = strings.Replace(version, "\r\n", "", -1)
+
+ x1 := strings.Index(version, "[Version")
+
+ if x1 == -1 || strings.Index(version, "]") == -1 {
+ return -1, errors.New("Can't determine Windows version")
+ }
+
+ return strconv.ParseFloat(version[x1+9:x1+13], 64)
+}
+
+func init() {
+ ver, err := getVersion()
+ if err != nil {
+ return
+ }
+
+ // Activate Virtual Processing for Windows CMD
+ // Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
+ if ver >= 10 {
+ handle := syscall.Handle(os.Stderr.Fd())
+ procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
+ }
+}
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ switch v := f.(type) {
+ case *os.File:
+ var st uint32
+ r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
+ return r != 0 && e == 0
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/Sirupsen/logrus/text_formatter.go
new file mode 100644
index 00000000..cf3f17f2
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/text_formatter.go
@@ -0,0 +1,175 @@
+package logrus
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+)
+
+const (
+ nocolor = 0
+ red = 31
+ green = 32
+ yellow = 33
+ blue = 36
+ gray = 37
+)
+
+var (
+ baseTimestamp time.Time
+)
+
+func init() {
+ baseTimestamp = time.Now()
+}
+
+type TextFormatter struct {
+ // Set to true to bypass checking for a TTY before outputting colors.
+ ForceColors bool
+
+ // Force disabling colors.
+ DisableColors bool
+
+ // Disable timestamp logging. useful when output is redirected to logging
+ // system that already adds timestamps.
+ DisableTimestamp bool
+
+ // Enable logging the full timestamp when a TTY is attached instead of just
+ // the time passed since beginning of execution.
+ FullTimestamp bool
+
+ // TimestampFormat to use for display when a full timestamp is printed
+ TimestampFormat string
+
+ // The fields are sorted by default for a consistent output. For applications
+ // that log extremely frequently and don't use the JSON formatter this may not
+ // be desired.
+ DisableSorting bool
+
+ // QuoteEmptyFields will wrap empty fields in quotes if true
+ QuoteEmptyFields bool
+
+ // Whether the logger's out is to a terminal
+ isTerminal bool
+
+ sync.Once
+}
+
+func (f *TextFormatter) init(entry *Entry) {
+ if entry.Logger != nil {
+ f.isTerminal = IsTerminal(entry.Logger.Out)
+ }
+}
+
+func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
+ var b *bytes.Buffer
+ keys := make([]string, 0, len(entry.Data))
+ for k := range entry.Data {
+ keys = append(keys, k)
+ }
+
+ if !f.DisableSorting {
+ sort.Strings(keys)
+ }
+ if entry.Buffer != nil {
+ b = entry.Buffer
+ } else {
+ b = &bytes.Buffer{}
+ }
+
+ prefixFieldClashes(entry.Data)
+
+ f.Do(func() { f.init(entry) })
+
+ isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
+
+ timestampFormat := f.TimestampFormat
+ if timestampFormat == "" {
+ timestampFormat = DefaultTimestampFormat
+ }
+ if isColored {
+ f.printColored(b, entry, keys, timestampFormat)
+ } else {
+ if !f.DisableTimestamp {
+ f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
+ }
+ f.appendKeyValue(b, "level", entry.Level.String())
+ if entry.Message != "" {
+ f.appendKeyValue(b, "msg", entry.Message)
+ }
+ for _, key := range keys {
+ f.appendKeyValue(b, key, entry.Data[key])
+ }
+ }
+
+ b.WriteByte('\n')
+ return b.Bytes(), nil
+}
+
+func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
+ var levelColor int
+ switch entry.Level {
+ case DebugLevel:
+ levelColor = gray
+ case WarnLevel:
+ levelColor = yellow
+ case ErrorLevel, FatalLevel, PanicLevel:
+ levelColor = red
+ default:
+ levelColor = blue
+ }
+
+ levelText := strings.ToUpper(entry.Level.String())[0:4]
+
+ if f.DisableTimestamp {
+ fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
+ } else if !f.FullTimestamp {
+ fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
+ } else {
+ fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
+ }
+ for _, k := range keys {
+ v := entry.Data[k]
+ fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
+ f.appendValue(b, v)
+ }
+}
+
+func (f *TextFormatter) needsQuoting(text string) bool {
+ if f.QuoteEmptyFields && len(text) == 0 {
+ return true
+ }
+ for _, ch := range text {
+ if !((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z') ||
+ (ch >= '0' && ch <= '9') ||
+ ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
+ return true
+ }
+ }
+ return false
+}
+
+func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
+
+ b.WriteString(key)
+ b.WriteByte('=')
+ f.appendValue(b, value)
+ b.WriteByte(' ')
+}
+
+func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
+ stringVal, ok := value.(string)
+ if !ok {
+ stringVal = fmt.Sprint(value)
+ }
+
+ if !f.needsQuoting(stringVal) {
+ b.WriteString(stringVal)
+ } else {
+ b.WriteString(fmt.Sprintf("%q", stringVal))
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter_test.go b/vendor/github.com/Sirupsen/logrus/text_formatter_test.go
new file mode 100644
index 00000000..ecb8f127
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/text_formatter_test.go
@@ -0,0 +1,122 @@
+package logrus
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestQuoting(t *testing.T) {
+ tf := &TextFormatter{DisableColors: true}
+
+ checkQuoting := func(q bool, value interface{}) {
+ b, _ := tf.Format(WithField("test", value))
+ idx := bytes.Index(b, ([]byte)("test="))
+ cont := bytes.Contains(b[idx+5:], []byte("\""))
+ if cont != q {
+ if q {
+ t.Errorf("quoting expected for: %#v", value)
+ } else {
+ t.Errorf("quoting not expected for: %#v", value)
+ }
+ }
+ }
+
+ checkQuoting(false, "")
+ checkQuoting(false, "abcd")
+ checkQuoting(false, "v1.0")
+ checkQuoting(false, "1234567890")
+ checkQuoting(false, "/foobar")
+ checkQuoting(false, "foo_bar")
+ checkQuoting(false, "foo@bar")
+ checkQuoting(false, "foobar^")
+ checkQuoting(false, "+/-_^@f.oobar")
+ checkQuoting(true, "foobar$")
+ checkQuoting(true, "&foobar")
+ checkQuoting(true, "x y")
+ checkQuoting(true, "x,y")
+ checkQuoting(false, errors.New("invalid"))
+ checkQuoting(true, errors.New("invalid argument"))
+
+ // Test for quoting empty fields.
+ tf.QuoteEmptyFields = true
+ checkQuoting(true, "")
+ checkQuoting(false, "abcd")
+ checkQuoting(true, errors.New("invalid argument"))
+}
+
+func TestEscaping(t *testing.T) {
+ tf := &TextFormatter{DisableColors: true}
+
+ testCases := []struct {
+ value string
+ expected string
+ }{
+ {`ba"r`, `ba\"r`},
+ {`ba'r`, `ba'r`},
+ }
+
+ for _, tc := range testCases {
+ b, _ := tf.Format(WithField("test", tc.value))
+ if !bytes.Contains(b, []byte(tc.expected)) {
+ t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
+ }
+ }
+}
+
+func TestEscaping_Interface(t *testing.T) {
+ tf := &TextFormatter{DisableColors: true}
+
+ ts := time.Now()
+
+ testCases := []struct {
+ value interface{}
+ expected string
+ }{
+ {ts, fmt.Sprintf("\"%s\"", ts.String())},
+ {errors.New("error: something went wrong"), "\"error: something went wrong\""},
+ }
+
+ for _, tc := range testCases {
+ b, _ := tf.Format(WithField("test", tc.value))
+ if !bytes.Contains(b, []byte(tc.expected)) {
+ t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
+ }
+ }
+}
+
+func TestTimestampFormat(t *testing.T) {
+ checkTimeStr := func(format string) {
+ customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
+ customStr, _ := customFormatter.Format(WithField("test", "test"))
+ timeStart := bytes.Index(customStr, ([]byte)("time="))
+ timeEnd := bytes.Index(customStr, ([]byte)("level="))
+ timeStr := customStr[timeStart+5+len("\"") : timeEnd-1-len("\"")]
+ if format == "" {
+ format = time.RFC3339
+ }
+ _, e := time.Parse(format, (string)(timeStr))
+ if e != nil {
+ t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
+ }
+ }
+
+ checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
+ checkTimeStr("Mon Jan _2 15:04:05 2006")
+ checkTimeStr("")
+}
+
+func TestDisableTimestampWithColoredOutput(t *testing.T) {
+ tf := &TextFormatter{DisableTimestamp: true, ForceColors: true}
+
+ b, _ := tf.Format(WithField("test", "test"))
+ if strings.Contains(string(b), "[0000]") {
+ t.Error("timestamp not expected when DisableTimestamp is true")
+ }
+}
+
+// TODO add tests for sorting etc., this requires a parser for the text
+// formatter output.
diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/Sirupsen/logrus/writer.go
new file mode 100644
index 00000000..7bdebedc
--- /dev/null
+++ b/vendor/github.com/Sirupsen/logrus/writer.go
@@ -0,0 +1,62 @@
+package logrus
+
+import (
+ "bufio"
+ "io"
+ "runtime"
+)
+
+func (logger *Logger) Writer() *io.PipeWriter {
+ return logger.WriterLevel(InfoLevel)
+}
+
+func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
+ return NewEntry(logger).WriterLevel(level)
+}
+
+func (entry *Entry) Writer() *io.PipeWriter {
+ return entry.WriterLevel(InfoLevel)
+}
+
+func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
+ reader, writer := io.Pipe()
+
+ var printFunc func(args ...interface{})
+
+ switch level {
+ case DebugLevel:
+ printFunc = entry.Debug
+ case InfoLevel:
+ printFunc = entry.Info
+ case WarnLevel:
+ printFunc = entry.Warn
+ case ErrorLevel:
+ printFunc = entry.Error
+ case FatalLevel:
+ printFunc = entry.Fatal
+ case PanicLevel:
+ printFunc = entry.Panic
+ default:
+ printFunc = entry.Print
+ }
+
+ go entry.writerScanner(reader, printFunc)
+ runtime.SetFinalizer(writer, writerFinalizer)
+
+ return writer
+}
+
+func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
+ scanner := bufio.NewScanner(reader)
+ for scanner.Scan() {
+ printFunc(scanner.Text())
+ }
+ if err := scanner.Err(); err != nil {
+ entry.Errorf("Error while reading from Writer: %s", err)
+ }
+ reader.Close()
+}
+
+func writerFinalizer(writer *io.PipeWriter) {
+ writer.Close()
+}
diff --git a/vendor/github.com/osrg/gobgp/VERSION b/vendor/github.com/osrg/gobgp/VERSION
index 0f6abf48..0fdd2359 100644
--- a/vendor/github.com/osrg/gobgp/VERSION
+++ b/vendor/github.com/osrg/gobgp/VERSION
@@ -1 +1 @@
-1.21
\ No newline at end of file
+1.20
\ No newline at end of file
diff --git a/vendor/github.com/osrg/gobgp/api/gobgp.pb.go b/vendor/github.com/osrg/gobgp/api/gobgp.pb.go
index 162e5d42..787b9758 100644
--- a/vendor/github.com/osrg/gobgp/api/gobgp.pb.go
+++ b/vendor/github.com/osrg/gobgp/api/gobgp.pb.go
@@ -1,5 +1,6 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
+// Code generated by protoc-gen-go.
// source: gobgp.proto
+// DO NOT EDIT!
/*
Package gobgpapi is a generated protocol buffer package.
@@ -125,31 +126,6 @@ It has these top-level messages:
TimersState
Transport
RouteServer
- GracefulRestart
- MpGracefulRestartConfig
- MpGracefulRestartState
- MpGracefulRestart
- AfiSafiConfig
- AfiSafiState
- RouteSelectionOptionsConfig
- RouteSelectionOptionsState
- RouteSelectionOptions
- UseMultiplePathsConfig
- UseMultiplePathsState
- EbgpConfig
- EbgpState
- Ebgp
- IbgpConfig
- IbgpState
- Ibgp
- UseMultiplePaths
- RouteTargetMembershipConfig
- RouteTargetMembershipState
- RouteTargetMembership
- LongLivedGracefulRestartConfig
- LongLivedGracefulRestartState
- LongLivedGracefulRestart
- AfiSafi
Prefix
DefinedSet
MatchSet
@@ -529,7 +505,7 @@ var Conditions_RouteType_value = map[string]int32{
func (x Conditions_RouteType) String() string {
return proto.EnumName(Conditions_RouteType_name, int32(x))
}
-func (Conditions_RouteType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{146, 0} }
+func (Conditions_RouteType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{121, 0} }
type GetNeighborRequest struct {
EnableAdvertised bool `protobuf:"varint,1,opt,name=enableAdvertised" json:"enableAdvertised,omitempty"`
@@ -2462,17 +2438,15 @@ func (*ValidateRibResponse) ProtoMessage() {}
func (*ValidateRibResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{101} }
type Peer struct {
- Families []uint32 `protobuf:"varint,1,rep,packed,name=families" json:"families,omitempty"`
- ApplyPolicy *ApplyPolicy `protobuf:"bytes,2,opt,name=apply_policy,json=applyPolicy" json:"apply_policy,omitempty"`
- Conf *PeerConf `protobuf:"bytes,3,opt,name=conf" json:"conf,omitempty"`
- EbgpMultihop *EbgpMultihop `protobuf:"bytes,4,opt,name=ebgp_multihop,json=ebgpMultihop" json:"ebgp_multihop,omitempty"`
- RouteReflector *RouteReflector `protobuf:"bytes,5,opt,name=route_reflector,json=routeReflector" json:"route_reflector,omitempty"`
- Info *PeerState `protobuf:"bytes,6,opt,name=info" json:"info,omitempty"`
- Timers *Timers `protobuf:"bytes,7,opt,name=timers" json:"timers,omitempty"`
- Transport *Transport `protobuf:"bytes,8,opt,name=transport" json:"transport,omitempty"`
- RouteServer *RouteServer `protobuf:"bytes,9,opt,name=route_server,json=routeServer" json:"route_server,omitempty"`
- GracefulRestart *GracefulRestart `protobuf:"bytes,10,opt,name=graceful_restart,json=gracefulRestart" json:"graceful_restart,omitempty"`
- AfiSafis []*AfiSafi `protobuf:"bytes,11,rep,name=afi_safis,json=afiSafis" json:"afi_safis,omitempty"`
+ Families []uint32 `protobuf:"varint,1,rep,packed,name=families" json:"families,omitempty"`
+ ApplyPolicy *ApplyPolicy `protobuf:"bytes,2,opt,name=apply_policy,json=applyPolicy" json:"apply_policy,omitempty"`
+ Conf *PeerConf `protobuf:"bytes,3,opt,name=conf" json:"conf,omitempty"`
+ EbgpMultihop *EbgpMultihop `protobuf:"bytes,4,opt,name=ebgp_multihop,json=ebgpMultihop" json:"ebgp_multihop,omitempty"`
+ RouteReflector *RouteReflector `protobuf:"bytes,5,opt,name=route_reflector,json=routeReflector" json:"route_reflector,omitempty"`
+ Info *PeerState `protobuf:"bytes,6,opt,name=info" json:"info,omitempty"`
+ Timers *Timers `protobuf:"bytes,7,opt,name=timers" json:"timers,omitempty"`
+ Transport *Transport `protobuf:"bytes,8,opt,name=transport" json:"transport,omitempty"`
+ RouteServer *RouteServer `protobuf:"bytes,9,opt,name=route_server,json=routeServer" json:"route_server,omitempty"`
}
func (m *Peer) Reset() { *m = Peer{} }
@@ -2543,20 +2517,6 @@ func (m *Peer) GetRouteServer() *RouteServer {
return nil
}
-func (m *Peer) GetGracefulRestart() *GracefulRestart {
- if m != nil {
- return m.GracefulRestart
- }
- return nil
-}
-
-func (m *Peer) GetAfiSafis() []*AfiSafi {
- if m != nil {
- return m.AfiSafis
- }
- return nil
-}
-
type ApplyPolicy struct {
InPolicy *PolicyAssignment `protobuf:"bytes,1,opt,name=in_policy,json=inPolicy" json:"in_policy,omitempty"`
ExportPolicy *PolicyAssignment `protobuf:"bytes,2,opt,name=export_policy,json=exportPolicy" json:"export_policy,omitempty"`
@@ -2622,28 +2582,25 @@ func (m *PrefixLimit) GetShutdownThresholdPct() uint32 {
}
type PeerConf struct {
- AuthPassword string `protobuf:"bytes,1,opt,name=auth_password,json=authPassword" json:"auth_password,omitempty"`
- Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"`
- LocalAs uint32 `protobuf:"varint,3,opt,name=local_as,json=localAs" json:"local_as,omitempty"`
- NeighborAddress string `protobuf:"bytes,4,opt,name=neighbor_address,json=neighborAddress" json:"neighbor_address,omitempty"`
- PeerAs uint32 `protobuf:"varint,5,opt,name=peer_as,json=peerAs" json:"peer_as,omitempty"`
- PeerGroup string `protobuf:"bytes,6,opt,name=peer_group,json=peerGroup" json:"peer_group,omitempty"`
- PeerType uint32 `protobuf:"varint,7,opt,name=peer_type,json=peerType" json:"peer_type,omitempty"`
- RemovePrivateAs PeerConf_RemovePrivateAs `protobuf:"varint,8,opt,name=remove_private_as,json=removePrivateAs,enum=gobgpapi.PeerConf_RemovePrivateAs" json:"remove_private_as,omitempty"`
- RouteFlapDamping bool `protobuf:"varint,9,opt,name=route_flap_damping,json=routeFlapDamping" json:"route_flap_damping,omitempty"`
- SendCommunity uint32 `protobuf:"varint,10,opt,name=send_community,json=sendCommunity" json:"send_community,omitempty"`
- RemoteCap [][]byte `protobuf:"bytes,11,rep,name=remote_cap,json=remoteCap,proto3" json:"remote_cap,omitempty"`
- LocalCap [][]byte `protobuf:"bytes,12,rep,name=local_cap,json=localCap,proto3" json:"local_cap,omitempty"`
- Id string `protobuf:"bytes,13,opt,name=id" json:"id,omitempty"`
- // Note: Regarding to the consistency with OpenConfig mode, list of
- // PrefixLimit should be removed from here, and list of PrefixLimit in
- // AfiSafi should be used instead.
- PrefixLimits []*PrefixLimit `protobuf:"bytes,14,rep,name=prefix_limits,json=prefixLimits" json:"prefix_limits,omitempty"`
- LocalAddress string `protobuf:"bytes,15,opt,name=local_address,json=localAddress" json:"local_address,omitempty"`
- NeighborInterface string `protobuf:"bytes,16,opt,name=neighbor_interface,json=neighborInterface" json:"neighbor_interface,omitempty"`
- Vrf string `protobuf:"bytes,17,opt,name=vrf" json:"vrf,omitempty"`
- AllowOwnAs uint32 `protobuf:"varint,18,opt,name=allow_own_as,json=allowOwnAs" json:"allow_own_as,omitempty"`
- ReplacePeerAs bool `protobuf:"varint,19,opt,name=replace_peer_as,json=replacePeerAs" json:"replace_peer_as,omitempty"`
+ AuthPassword string `protobuf:"bytes,1,opt,name=auth_password,json=authPassword" json:"auth_password,omitempty"`
+ Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"`
+ LocalAs uint32 `protobuf:"varint,3,opt,name=local_as,json=localAs" json:"local_as,omitempty"`
+ NeighborAddress string `protobuf:"bytes,4,opt,name=neighbor_address,json=neighborAddress" json:"neighbor_address,omitempty"`
+ PeerAs uint32 `protobuf:"varint,5,opt,name=peer_as,json=peerAs" json:"peer_as,omitempty"`
+ PeerGroup string `protobuf:"bytes,6,opt,name=peer_group,json=peerGroup" json:"peer_group,omitempty"`
+ PeerType uint32 `protobuf:"varint,7,opt,name=peer_type,json=peerType" json:"peer_type,omitempty"`
+ RemovePrivateAs PeerConf_RemovePrivateAs `protobuf:"varint,8,opt,name=remove_private_as,json=removePrivateAs,enum=gobgpapi.PeerConf_RemovePrivateAs" json:"remove_private_as,omitempty"`
+ RouteFlapDamping bool `protobuf:"varint,9,opt,name=route_flap_damping,json=routeFlapDamping" json:"route_flap_damping,omitempty"`
+ SendCommunity uint32 `protobuf:"varint,10,opt,name=send_community,json=sendCommunity" json:"send_community,omitempty"`
+ RemoteCap [][]byte `protobuf:"bytes,11,rep,name=remote_cap,json=remoteCap,proto3" json:"remote_cap,omitempty"`
+ LocalCap [][]byte `protobuf:"bytes,12,rep,name=local_cap,json=localCap,proto3" json:"local_cap,omitempty"`
+ Id string `protobuf:"bytes,13,opt,name=id" json:"id,omitempty"`
+ PrefixLimits []*PrefixLimit `protobuf:"bytes,14,rep,name=prefix_limits,json=prefixLimits" json:"prefix_limits,omitempty"`
+ LocalAddress string `protobuf:"bytes,15,opt,name=local_address,json=localAddress" json:"local_address,omitempty"`
+ NeighborInterface string `protobuf:"bytes,16,opt,name=neighbor_interface,json=neighborInterface" json:"neighbor_interface,omitempty"`
+ Vrf string `protobuf:"bytes,17,opt,name=vrf" json:"vrf,omitempty"`
+ AllowOwnAs uint32 `protobuf:"varint,18,opt,name=allow_own_as,json=allowOwnAs" json:"allow_own_as,omitempty"`
+ ReplacePeerAs bool `protobuf:"varint,19,opt,name=replace_peer_as,json=replacePeerAs" json:"replace_peer_as,omitempty"`
}
func (m *PeerConf) Reset() { *m = PeerConf{} }
@@ -3328,788 +3285,6 @@ func (m *RouteServer) GetRouteServerClient() bool {
return false
}
-type GracefulRestart struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
- RestartTime uint32 `protobuf:"varint,2,opt,name=restart_time,json=restartTime" json:"restart_time,omitempty"`
- HelperOnly bool `protobuf:"varint,3,opt,name=helper_only,json=helperOnly" json:"helper_only,omitempty"`
- DeferralTime uint32 `protobuf:"varint,4,opt,name=deferral_time,json=deferralTime" json:"deferral_time,omitempty"`
- NotificationEnabled bool `protobuf:"varint,5,opt,name=notification_enabled,json=notificationEnabled" json:"notification_enabled,omitempty"`
- LonglivedEnabled bool `protobuf:"varint,6,opt,name=longlived_enabled,json=longlivedEnabled" json:"longlived_enabled,omitempty"`
-}
-
-func (m *GracefulRestart) Reset() { *m = GracefulRestart{} }
-func (m *GracefulRestart) String() string { return proto.CompactTextString(m) }
-func (*GracefulRestart) ProtoMessage() {}
-func (*GracefulRestart) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{117} }
-
-func (m *GracefulRestart) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-func (m *GracefulRestart) GetRestartTime() uint32 {
- if m != nil {
- return m.RestartTime
- }
- return 0
-}
-
-func (m *GracefulRestart) GetHelperOnly() bool {
- if m != nil {
- return m.HelperOnly
- }
- return false
-}
-
-func (m *GracefulRestart) GetDeferralTime() uint32 {
- if m != nil {
- return m.DeferralTime
- }
- return 0
-}
-
-func (m *GracefulRestart) GetNotificationEnabled() bool {
- if m != nil {
- return m.NotificationEnabled
- }
- return false
-}
-
-func (m *GracefulRestart) GetLonglivedEnabled() bool {
- if m != nil {
- return m.LonglivedEnabled
- }
- return false
-}
-
-type MpGracefulRestartConfig struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
-}
-
-func (m *MpGracefulRestartConfig) Reset() { *m = MpGracefulRestartConfig{} }
-func (m *MpGracefulRestartConfig) String() string { return proto.CompactTextString(m) }
-func (*MpGracefulRestartConfig) ProtoMessage() {}
-func (*MpGracefulRestartConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{118} }
-
-func (m *MpGracefulRestartConfig) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-type MpGracefulRestartState struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
- Received bool `protobuf:"varint,2,opt,name=received" json:"received,omitempty"`
- Advertised bool `protobuf:"varint,3,opt,name=advertised" json:"advertised,omitempty"`
- EndOfRibReceived bool `protobuf:"varint,4,opt,name=end_of_rib_received,json=endOfRibReceived" json:"end_of_rib_received,omitempty"`
- EndOfRibSent bool `protobuf:"varint,5,opt,name=end_of_rib_sent,json=endOfRibSent" json:"end_of_rib_sent,omitempty"`
-}
-
-func (m *MpGracefulRestartState) Reset() { *m = MpGracefulRestartState{} }
-func (m *MpGracefulRestartState) String() string { return proto.CompactTextString(m) }
-func (*MpGracefulRestartState) ProtoMessage() {}
-func (*MpGracefulRestartState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{119} }
-
-func (m *MpGracefulRestartState) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-func (m *MpGracefulRestartState) GetReceived() bool {
- if m != nil {
- return m.Received
- }
- return false
-}
-
-func (m *MpGracefulRestartState) GetAdvertised() bool {
- if m != nil {
- return m.Advertised
- }
- return false
-}
-
-func (m *MpGracefulRestartState) GetEndOfRibReceived() bool {
- if m != nil {
- return m.EndOfRibReceived
- }
- return false
-}
-
-func (m *MpGracefulRestartState) GetEndOfRibSent() bool {
- if m != nil {
- return m.EndOfRibSent
- }
- return false
-}
-
-type MpGracefulRestart struct {
- Config *MpGracefulRestartConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
- State *MpGracefulRestartState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
-}
-
-func (m *MpGracefulRestart) Reset() { *m = MpGracefulRestart{} }
-func (m *MpGracefulRestart) String() string { return proto.CompactTextString(m) }
-func (*MpGracefulRestart) ProtoMessage() {}
-func (*MpGracefulRestart) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{120} }
-
-func (m *MpGracefulRestart) GetConfig() *MpGracefulRestartConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *MpGracefulRestart) GetState() *MpGracefulRestartState {
- if m != nil {
- return m.State
- }
- return nil
-}
-
-type AfiSafiConfig struct {
- Family uint32 `protobuf:"varint,1,opt,name=family" json:"family,omitempty"`
- Enabled bool `protobuf:"varint,2,opt,name=enabled" json:"enabled,omitempty"`
-}
-
-func (m *AfiSafiConfig) Reset() { *m = AfiSafiConfig{} }
-func (m *AfiSafiConfig) String() string { return proto.CompactTextString(m) }
-func (*AfiSafiConfig) ProtoMessage() {}
-func (*AfiSafiConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{121} }
-
-func (m *AfiSafiConfig) GetFamily() uint32 {
- if m != nil {
- return m.Family
- }
- return 0
-}
-
-func (m *AfiSafiConfig) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-type AfiSafiState struct {
- Family uint32 `protobuf:"varint,1,opt,name=family" json:"family,omitempty"`
- Enabled bool `protobuf:"varint,2,opt,name=enabled" json:"enabled,omitempty"`
- TotalPaths uint32 `protobuf:"varint,3,opt,name=total_paths,json=totalPaths" json:"total_paths,omitempty"`
- TotalPrefixes uint32 `protobuf:"varint,4,opt,name=total_prefixes,json=totalPrefixes" json:"total_prefixes,omitempty"`
-}
-
-func (m *AfiSafiState) Reset() { *m = AfiSafiState{} }
-func (m *AfiSafiState) String() string { return proto.CompactTextString(m) }
-func (*AfiSafiState) ProtoMessage() {}
-func (*AfiSafiState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{122} }
-
-func (m *AfiSafiState) GetFamily() uint32 {
- if m != nil {
- return m.Family
- }
- return 0
-}
-
-func (m *AfiSafiState) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-func (m *AfiSafiState) GetTotalPaths() uint32 {
- if m != nil {
- return m.TotalPaths
- }
- return 0
-}
-
-func (m *AfiSafiState) GetTotalPrefixes() uint32 {
- if m != nil {
- return m.TotalPrefixes
- }
- return 0
-}
-
-type RouteSelectionOptionsConfig struct {
- AlwaysCompareMed bool `protobuf:"varint,1,opt,name=always_compare_med,json=alwaysCompareMed" json:"always_compare_med,omitempty"`
- IgnoreAsPathLength bool `protobuf:"varint,2,opt,name=ignore_as_path_length,json=ignoreAsPathLength" json:"ignore_as_path_length,omitempty"`
- ExternalCompareRouterId bool `protobuf:"varint,3,opt,name=external_compare_router_id,json=externalCompareRouterId" json:"external_compare_router_id,omitempty"`
- AdvertiseInactiveRoutes bool `protobuf:"varint,4,opt,name=advertise_inactive_routes,json=advertiseInactiveRoutes" json:"advertise_inactive_routes,omitempty"`
- EnableAigp bool `protobuf:"varint,5,opt,name=enable_aigp,json=enableAigp" json:"enable_aigp,omitempty"`
- IgnoreNextHopIgpMetric bool `protobuf:"varint,6,opt,name=ignore_next_hop_igp_metric,json=ignoreNextHopIgpMetric" json:"ignore_next_hop_igp_metric,omitempty"`
-}
-
-func (m *RouteSelectionOptionsConfig) Reset() { *m = RouteSelectionOptionsConfig{} }
-func (m *RouteSelectionOptionsConfig) String() string { return proto.CompactTextString(m) }
-func (*RouteSelectionOptionsConfig) ProtoMessage() {}
-func (*RouteSelectionOptionsConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{123} }
-
-func (m *RouteSelectionOptionsConfig) GetAlwaysCompareMed() bool {
- if m != nil {
- return m.AlwaysCompareMed
- }
- return false
-}
-
-func (m *RouteSelectionOptionsConfig) GetIgnoreAsPathLength() bool {
- if m != nil {
- return m.IgnoreAsPathLength
- }
- return false
-}
-
-func (m *RouteSelectionOptionsConfig) GetExternalCompareRouterId() bool {
- if m != nil {
- return m.ExternalCompareRouterId
- }
- return false
-}
-
-func (m *RouteSelectionOptionsConfig) GetAdvertiseInactiveRoutes() bool {
- if m != nil {
- return m.AdvertiseInactiveRoutes
- }
- return false
-}
-
-func (m *RouteSelectionOptionsConfig) GetEnableAigp() bool {
- if m != nil {
- return m.EnableAigp
- }
- return false
-}
-
-func (m *RouteSelectionOptionsConfig) GetIgnoreNextHopIgpMetric() bool {
- if m != nil {
- return m.IgnoreNextHopIgpMetric
- }
- return false
-}
-
-type RouteSelectionOptionsState struct {
- AlwaysCompareMed bool `protobuf:"varint,1,opt,name=always_compare_med,json=alwaysCompareMed" json:"always_compare_med,omitempty"`
- IgnoreAsPathLength bool `protobuf:"varint,2,opt,name=ignore_as_path_length,json=ignoreAsPathLength" json:"ignore_as_path_length,omitempty"`
- ExternalCompareRouterId bool `protobuf:"varint,3,opt,name=external_compare_router_id,json=externalCompareRouterId" json:"external_compare_router_id,omitempty"`
- AdvertiseInactiveRoutes bool `protobuf:"varint,4,opt,name=advertise_inactive_routes,json=advertiseInactiveRoutes" json:"advertise_inactive_routes,omitempty"`
- EnableAigp bool `protobuf:"varint,5,opt,name=enable_aigp,json=enableAigp" json:"enable_aigp,omitempty"`
- IgnoreNextHopIgpMetric bool `protobuf:"varint,6,opt,name=ignore_next_hop_igp_metric,json=ignoreNextHopIgpMetric" json:"ignore_next_hop_igp_metric,omitempty"`
-}
-
-func (m *RouteSelectionOptionsState) Reset() { *m = RouteSelectionOptionsState{} }
-func (m *RouteSelectionOptionsState) String() string { return proto.CompactTextString(m) }
-func (*RouteSelectionOptionsState) ProtoMessage() {}
-func (*RouteSelectionOptionsState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{124} }
-
-func (m *RouteSelectionOptionsState) GetAlwaysCompareMed() bool {
- if m != nil {
- return m.AlwaysCompareMed
- }
- return false
-}
-
-func (m *RouteSelectionOptionsState) GetIgnoreAsPathLength() bool {
- if m != nil {
- return m.IgnoreAsPathLength
- }
- return false
-}
-
-func (m *RouteSelectionOptionsState) GetExternalCompareRouterId() bool {
- if m != nil {
- return m.ExternalCompareRouterId
- }
- return false
-}
-
-func (m *RouteSelectionOptionsState) GetAdvertiseInactiveRoutes() bool {
- if m != nil {
- return m.AdvertiseInactiveRoutes
- }
- return false
-}
-
-func (m *RouteSelectionOptionsState) GetEnableAigp() bool {
- if m != nil {
- return m.EnableAigp
- }
- return false
-}
-
-func (m *RouteSelectionOptionsState) GetIgnoreNextHopIgpMetric() bool {
- if m != nil {
- return m.IgnoreNextHopIgpMetric
- }
- return false
-}
-
-type RouteSelectionOptions struct {
- Config *RouteSelectionOptionsConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
- State *RouteSelectionOptionsState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
-}
-
-func (m *RouteSelectionOptions) Reset() { *m = RouteSelectionOptions{} }
-func (m *RouteSelectionOptions) String() string { return proto.CompactTextString(m) }
-func (*RouteSelectionOptions) ProtoMessage() {}
-func (*RouteSelectionOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{125} }
-
-func (m *RouteSelectionOptions) GetConfig() *RouteSelectionOptionsConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *RouteSelectionOptions) GetState() *RouteSelectionOptionsState {
- if m != nil {
- return m.State
- }
- return nil
-}
-
-type UseMultiplePathsConfig struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
-}
-
-func (m *UseMultiplePathsConfig) Reset() { *m = UseMultiplePathsConfig{} }
-func (m *UseMultiplePathsConfig) String() string { return proto.CompactTextString(m) }
-func (*UseMultiplePathsConfig) ProtoMessage() {}
-func (*UseMultiplePathsConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{126} }
-
-func (m *UseMultiplePathsConfig) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-type UseMultiplePathsState struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
-}
-
-func (m *UseMultiplePathsState) Reset() { *m = UseMultiplePathsState{} }
-func (m *UseMultiplePathsState) String() string { return proto.CompactTextString(m) }
-func (*UseMultiplePathsState) ProtoMessage() {}
-func (*UseMultiplePathsState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{127} }
-
-func (m *UseMultiplePathsState) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-type EbgpConfig struct {
- AllowMultipleAs bool `protobuf:"varint,1,opt,name=allow_multiple_as,json=allowMultipleAs" json:"allow_multiple_as,omitempty"`
- MaximumPaths uint32 `protobuf:"varint,2,opt,name=maximum_paths,json=maximumPaths" json:"maximum_paths,omitempty"`
-}
-
-func (m *EbgpConfig) Reset() { *m = EbgpConfig{} }
-func (m *EbgpConfig) String() string { return proto.CompactTextString(m) }
-func (*EbgpConfig) ProtoMessage() {}
-func (*EbgpConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{128} }
-
-func (m *EbgpConfig) GetAllowMultipleAs() bool {
- if m != nil {
- return m.AllowMultipleAs
- }
- return false
-}
-
-func (m *EbgpConfig) GetMaximumPaths() uint32 {
- if m != nil {
- return m.MaximumPaths
- }
- return 0
-}
-
-type EbgpState struct {
- AllowMultipleAs bool `protobuf:"varint,1,opt,name=allow_multiple_as,json=allowMultipleAs" json:"allow_multiple_as,omitempty"`
- MaximumPaths uint32 `protobuf:"varint,2,opt,name=maximum_paths,json=maximumPaths" json:"maximum_paths,omitempty"`
-}
-
-func (m *EbgpState) Reset() { *m = EbgpState{} }
-func (m *EbgpState) String() string { return proto.CompactTextString(m) }
-func (*EbgpState) ProtoMessage() {}
-func (*EbgpState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{129} }
-
-func (m *EbgpState) GetAllowMultipleAs() bool {
- if m != nil {
- return m.AllowMultipleAs
- }
- return false
-}
-
-func (m *EbgpState) GetMaximumPaths() uint32 {
- if m != nil {
- return m.MaximumPaths
- }
- return 0
-}
-
-type Ebgp struct {
- Config *EbgpConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
- State *EbgpState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
-}
-
-func (m *Ebgp) Reset() { *m = Ebgp{} }
-func (m *Ebgp) String() string { return proto.CompactTextString(m) }
-func (*Ebgp) ProtoMessage() {}
-func (*Ebgp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{130} }
-
-func (m *Ebgp) GetConfig() *EbgpConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *Ebgp) GetState() *EbgpState {
- if m != nil {
- return m.State
- }
- return nil
-}
-
-type IbgpConfig struct {
- MaximumPaths uint32 `protobuf:"varint,1,opt,name=maximum_paths,json=maximumPaths" json:"maximum_paths,omitempty"`
-}
-
-func (m *IbgpConfig) Reset() { *m = IbgpConfig{} }
-func (m *IbgpConfig) String() string { return proto.CompactTextString(m) }
-func (*IbgpConfig) ProtoMessage() {}
-func (*IbgpConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{131} }
-
-func (m *IbgpConfig) GetMaximumPaths() uint32 {
- if m != nil {
- return m.MaximumPaths
- }
- return 0
-}
-
-type IbgpState struct {
- MaximumPaths uint32 `protobuf:"varint,1,opt,name=maximum_paths,json=maximumPaths" json:"maximum_paths,omitempty"`
-}
-
-func (m *IbgpState) Reset() { *m = IbgpState{} }
-func (m *IbgpState) String() string { return proto.CompactTextString(m) }
-func (*IbgpState) ProtoMessage() {}
-func (*IbgpState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{132} }
-
-func (m *IbgpState) GetMaximumPaths() uint32 {
- if m != nil {
- return m.MaximumPaths
- }
- return 0
-}
-
-type Ibgp struct {
- Config *IbgpConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
- State *IbgpState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
-}
-
-func (m *Ibgp) Reset() { *m = Ibgp{} }
-func (m *Ibgp) String() string { return proto.CompactTextString(m) }
-func (*Ibgp) ProtoMessage() {}
-func (*Ibgp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{133} }
-
-func (m *Ibgp) GetConfig() *IbgpConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *Ibgp) GetState() *IbgpState {
- if m != nil {
- return m.State
- }
- return nil
-}
-
-type UseMultiplePaths struct {
- Config *UseMultiplePathsConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
- State *UseMultiplePathsState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
- Ebgp *Ebgp `protobuf:"bytes,3,opt,name=ebgp" json:"ebgp,omitempty"`
- Ibgp *Ibgp `protobuf:"bytes,4,opt,name=ibgp" json:"ibgp,omitempty"`
-}
-
-func (m *UseMultiplePaths) Reset() { *m = UseMultiplePaths{} }
-func (m *UseMultiplePaths) String() string { return proto.CompactTextString(m) }
-func (*UseMultiplePaths) ProtoMessage() {}
-func (*UseMultiplePaths) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{134} }
-
-func (m *UseMultiplePaths) GetConfig() *UseMultiplePathsConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *UseMultiplePaths) GetState() *UseMultiplePathsState {
- if m != nil {
- return m.State
- }
- return nil
-}
-
-func (m *UseMultiplePaths) GetEbgp() *Ebgp {
- if m != nil {
- return m.Ebgp
- }
- return nil
-}
-
-func (m *UseMultiplePaths) GetIbgp() *Ibgp {
- if m != nil {
- return m.Ibgp
- }
- return nil
-}
-
-type RouteTargetMembershipConfig struct {
- DeferralTime uint32 `protobuf:"varint,1,opt,name=deferral_time,json=deferralTime" json:"deferral_time,omitempty"`
-}
-
-func (m *RouteTargetMembershipConfig) Reset() { *m = RouteTargetMembershipConfig{} }
-func (m *RouteTargetMembershipConfig) String() string { return proto.CompactTextString(m) }
-func (*RouteTargetMembershipConfig) ProtoMessage() {}
-func (*RouteTargetMembershipConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{135} }
-
-func (m *RouteTargetMembershipConfig) GetDeferralTime() uint32 {
- if m != nil {
- return m.DeferralTime
- }
- return 0
-}
-
-type RouteTargetMembershipState struct {
- DeferralTime uint32 `protobuf:"varint,1,opt,name=deferral_time,json=deferralTime" json:"deferral_time,omitempty"`
-}
-
-func (m *RouteTargetMembershipState) Reset() { *m = RouteTargetMembershipState{} }
-func (m *RouteTargetMembershipState) String() string { return proto.CompactTextString(m) }
-func (*RouteTargetMembershipState) ProtoMessage() {}
-func (*RouteTargetMembershipState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{136} }
-
-func (m *RouteTargetMembershipState) GetDeferralTime() uint32 {
- if m != nil {
- return m.DeferralTime
- }
- return 0
-}
-
-type RouteTargetMembership struct {
- Config *RouteTargetMembershipConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
- State *RouteTargetMembershipState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
-}
-
-func (m *RouteTargetMembership) Reset() { *m = RouteTargetMembership{} }
-func (m *RouteTargetMembership) String() string { return proto.CompactTextString(m) }
-func (*RouteTargetMembership) ProtoMessage() {}
-func (*RouteTargetMembership) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{137} }
-
-func (m *RouteTargetMembership) GetConfig() *RouteTargetMembershipConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *RouteTargetMembership) GetState() *RouteTargetMembershipState {
- if m != nil {
- return m.State
- }
- return nil
-}
-
-type LongLivedGracefulRestartConfig struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
- RestartTime uint32 `protobuf:"varint,2,opt,name=restart_time,json=restartTime" json:"restart_time,omitempty"`
-}
-
-func (m *LongLivedGracefulRestartConfig) Reset() { *m = LongLivedGracefulRestartConfig{} }
-func (m *LongLivedGracefulRestartConfig) String() string { return proto.CompactTextString(m) }
-func (*LongLivedGracefulRestartConfig) ProtoMessage() {}
-func (*LongLivedGracefulRestartConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor0, []int{138}
-}
-
-func (m *LongLivedGracefulRestartConfig) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-func (m *LongLivedGracefulRestartConfig) GetRestartTime() uint32 {
- if m != nil {
- return m.RestartTime
- }
- return 0
-}
-
-type LongLivedGracefulRestartState struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
- Received bool `protobuf:"varint,2,opt,name=received" json:"received,omitempty"`
- Advertised bool `protobuf:"varint,3,opt,name=advertised" json:"advertised,omitempty"`
- PeerRestartTime uint32 `protobuf:"varint,4,opt,name=peer_restart_time,json=peerRestartTime" json:"peer_restart_time,omitempty"`
- PeerRestartTimerExpired bool `protobuf:"varint,5,opt,name=peer_restart_timer_expired,json=peerRestartTimerExpired" json:"peer_restart_timer_expired,omitempty"`
-}
-
-func (m *LongLivedGracefulRestartState) Reset() { *m = LongLivedGracefulRestartState{} }
-func (m *LongLivedGracefulRestartState) String() string { return proto.CompactTextString(m) }
-func (*LongLivedGracefulRestartState) ProtoMessage() {}
-func (*LongLivedGracefulRestartState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{139} }
-
-func (m *LongLivedGracefulRestartState) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-func (m *LongLivedGracefulRestartState) GetReceived() bool {
- if m != nil {
- return m.Received
- }
- return false
-}
-
-func (m *LongLivedGracefulRestartState) GetAdvertised() bool {
- if m != nil {
- return m.Advertised
- }
- return false
-}
-
-func (m *LongLivedGracefulRestartState) GetPeerRestartTime() uint32 {
- if m != nil {
- return m.PeerRestartTime
- }
- return 0
-}
-
-func (m *LongLivedGracefulRestartState) GetPeerRestartTimerExpired() bool {
- if m != nil {
- return m.PeerRestartTimerExpired
- }
- return false
-}
-
-type LongLivedGracefulRestart struct {
- Config *LongLivedGracefulRestartConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
- State *LongLivedGracefulRestartState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
-}
-
-func (m *LongLivedGracefulRestart) Reset() { *m = LongLivedGracefulRestart{} }
-func (m *LongLivedGracefulRestart) String() string { return proto.CompactTextString(m) }
-func (*LongLivedGracefulRestart) ProtoMessage() {}
-func (*LongLivedGracefulRestart) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{140} }
-
-func (m *LongLivedGracefulRestart) GetConfig() *LongLivedGracefulRestartConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *LongLivedGracefulRestart) GetState() *LongLivedGracefulRestartState {
- if m != nil {
- return m.State
- }
- return nil
-}
-
-type AfiSafi struct {
- MpGracefulRestart *MpGracefulRestart `protobuf:"bytes,1,opt,name=mp_graceful_restart,json=mpGracefulRestart" json:"mp_graceful_restart,omitempty"`
- Config *AfiSafiConfig `protobuf:"bytes,2,opt,name=config" json:"config,omitempty"`
- ApplyPolicy *ApplyPolicy `protobuf:"bytes,3,opt,name=apply_policy,json=applyPolicy" json:"apply_policy,omitempty"`
- // TODO:
- // Support the following structures:
- // - Ipv4Unicast
- // - Ipv6Unicast
- // - Ipv4LabelledUnicast
- // - Ipv6LabelledUnicast
- // - L3vpnIpv4Unicast
- // - L3vpnIpv6Unicast
- // - L3vpnIpv4Multicast
- // - L3vpnIpv6Multicast
- // - L2vpnVpls
- // - L2vpnEvpn
- RouteSelectionOptions *RouteSelectionOptions `protobuf:"bytes,4,opt,name=route_selection_options,json=routeSelectionOptions" json:"route_selection_options,omitempty"`
- UseMultiplePaths *UseMultiplePaths `protobuf:"bytes,5,opt,name=use_multiple_paths,json=useMultiplePaths" json:"use_multiple_paths,omitempty"`
- PrefixLimits *PrefixLimit `protobuf:"bytes,6,opt,name=prefix_limits,json=prefixLimits" json:"prefix_limits,omitempty"`
- RouteTargetMembership *RouteTargetMembership `protobuf:"bytes,7,opt,name=route_target_membership,json=routeTargetMembership" json:"route_target_membership,omitempty"`
- LongLivedGracefulRestart *LongLivedGracefulRestart `protobuf:"bytes,8,opt,name=long_lived_graceful_restart,json=longLivedGracefulRestart" json:"long_lived_graceful_restart,omitempty"`
-}
-
-func (m *AfiSafi) Reset() { *m = AfiSafi{} }
-func (m *AfiSafi) String() string { return proto.CompactTextString(m) }
-func (*AfiSafi) ProtoMessage() {}
-func (*AfiSafi) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{141} }
-
-func (m *AfiSafi) GetMpGracefulRestart() *MpGracefulRestart {
- if m != nil {
- return m.MpGracefulRestart
- }
- return nil
-}
-
-func (m *AfiSafi) GetConfig() *AfiSafiConfig {
- if m != nil {
- return m.Config
- }
- return nil
-}
-
-func (m *AfiSafi) GetApplyPolicy() *ApplyPolicy {
- if m != nil {
- return m.ApplyPolicy
- }
- return nil
-}
-
-func (m *AfiSafi) GetRouteSelectionOptions() *RouteSelectionOptions {
- if m != nil {
- return m.RouteSelectionOptions
- }
- return nil
-}
-
-func (m *AfiSafi) GetUseMultiplePaths() *UseMultiplePaths {
- if m != nil {
- return m.UseMultiplePaths
- }
- return nil
-}
-
-func (m *AfiSafi) GetPrefixLimits() *PrefixLimit {
- if m != nil {
- return m.PrefixLimits
- }
- return nil
-}
-
-func (m *AfiSafi) GetRouteTargetMembership() *RouteTargetMembership {
- if m != nil {
- return m.RouteTargetMembership
- }
- return nil
-}
-
-func (m *AfiSafi) GetLongLivedGracefulRestart() *LongLivedGracefulRestart {
- if m != nil {
- return m.LongLivedGracefulRestart
- }
- return nil
-}
-
type Prefix struct {
IpPrefix string `protobuf:"bytes,1,opt,name=ip_prefix,json=ipPrefix" json:"ip_prefix,omitempty"`
MaskLengthMin uint32 `protobuf:"varint,2,opt,name=mask_length_min,json=maskLengthMin" json:"mask_length_min,omitempty"`
@@ -4119,7 +3294,7 @@ type Prefix struct {
func (m *Prefix) Reset() { *m = Prefix{} }
func (m *Prefix) String() string { return proto.CompactTextString(m) }
func (*Prefix) ProtoMessage() {}
-func (*Prefix) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{142} }
+func (*Prefix) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{117} }
func (m *Prefix) GetIpPrefix() string {
if m != nil {
@@ -4152,7 +3327,7 @@ type DefinedSet struct {
func (m *DefinedSet) Reset() { *m = DefinedSet{} }
func (m *DefinedSet) String() string { return proto.CompactTextString(m) }
func (*DefinedSet) ProtoMessage() {}
-func (*DefinedSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{143} }
+func (*DefinedSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{118} }
func (m *DefinedSet) GetType() DefinedType {
if m != nil {
@@ -4190,7 +3365,7 @@ type MatchSet struct {
func (m *MatchSet) Reset() { *m = MatchSet{} }
func (m *MatchSet) String() string { return proto.CompactTextString(m) }
func (*MatchSet) ProtoMessage() {}
-func (*MatchSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{144} }
+func (*MatchSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{119} }
func (m *MatchSet) GetType() MatchType {
if m != nil {
@@ -4214,7 +3389,7 @@ type AsPathLength struct {
func (m *AsPathLength) Reset() { *m = AsPathLength{} }
func (m *AsPathLength) String() string { return proto.CompactTextString(m) }
func (*AsPathLength) ProtoMessage() {}
-func (*AsPathLength) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{145} }
+func (*AsPathLength) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{120} }
func (m *AsPathLength) GetType() AsPathLengthType {
if m != nil {
@@ -4245,7 +3420,7 @@ type Conditions struct {
func (m *Conditions) Reset() { *m = Conditions{} }
func (m *Conditions) String() string { return proto.CompactTextString(m) }
func (*Conditions) ProtoMessage() {}
-func (*Conditions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{146} }
+func (*Conditions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{121} }
func (m *Conditions) GetPrefixSet() *MatchSet {
if m != nil {
@@ -4318,7 +3493,7 @@ type CommunityAction struct {
func (m *CommunityAction) Reset() { *m = CommunityAction{} }
func (m *CommunityAction) String() string { return proto.CompactTextString(m) }
func (*CommunityAction) ProtoMessage() {}
-func (*CommunityAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{147} }
+func (*CommunityAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{122} }
func (m *CommunityAction) GetType() CommunityActionType {
if m != nil {
@@ -4342,7 +3517,7 @@ type MedAction struct {
func (m *MedAction) Reset() { *m = MedAction{} }
func (m *MedAction) String() string { return proto.CompactTextString(m) }
func (*MedAction) ProtoMessage() {}
-func (*MedAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{148} }
+func (*MedAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{123} }
func (m *MedAction) GetType() MedActionType {
if m != nil {
@@ -4367,7 +3542,7 @@ type AsPrependAction struct {
func (m *AsPrependAction) Reset() { *m = AsPrependAction{} }
func (m *AsPrependAction) String() string { return proto.CompactTextString(m) }
func (*AsPrependAction) ProtoMessage() {}
-func (*AsPrependAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{149} }
+func (*AsPrependAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{124} }
func (m *AsPrependAction) GetAsn() uint32 {
if m != nil {
@@ -4398,7 +3573,7 @@ type NexthopAction struct {
func (m *NexthopAction) Reset() { *m = NexthopAction{} }
func (m *NexthopAction) String() string { return proto.CompactTextString(m) }
func (*NexthopAction) ProtoMessage() {}
-func (*NexthopAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{150} }
+func (*NexthopAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{125} }
func (m *NexthopAction) GetAddress() string {
if m != nil {
@@ -4421,7 +3596,7 @@ type LocalPrefAction struct {
func (m *LocalPrefAction) Reset() { *m = LocalPrefAction{} }
func (m *LocalPrefAction) String() string { return proto.CompactTextString(m) }
func (*LocalPrefAction) ProtoMessage() {}
-func (*LocalPrefAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{151} }
+func (*LocalPrefAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{126} }
func (m *LocalPrefAction) GetValue() uint32 {
if m != nil {
@@ -4444,7 +3619,7 @@ type Actions struct {
func (m *Actions) Reset() { *m = Actions{} }
func (m *Actions) String() string { return proto.CompactTextString(m) }
func (*Actions) ProtoMessage() {}
-func (*Actions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{152} }
+func (*Actions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{127} }
func (m *Actions) GetRouteAction() RouteAction {
if m != nil {
@@ -4511,7 +3686,7 @@ type Statement struct {
func (m *Statement) Reset() { *m = Statement{} }
func (m *Statement) String() string { return proto.CompactTextString(m) }
func (*Statement) ProtoMessage() {}
-func (*Statement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{153} }
+func (*Statement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{128} }
func (m *Statement) GetName() string {
if m != nil {
@@ -4542,7 +3717,7 @@ type Policy struct {
func (m *Policy) Reset() { *m = Policy{} }
func (m *Policy) String() string { return proto.CompactTextString(m) }
func (*Policy) ProtoMessage() {}
-func (*Policy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{154} }
+func (*Policy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{129} }
func (m *Policy) GetName() string {
if m != nil {
@@ -4569,7 +3744,7 @@ type PolicyAssignment struct {
func (m *PolicyAssignment) Reset() { *m = PolicyAssignment{} }
func (m *PolicyAssignment) String() string { return proto.CompactTextString(m) }
func (*PolicyAssignment) ProtoMessage() {}
-func (*PolicyAssignment) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{155} }
+func (*PolicyAssignment) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{130} }
func (m *PolicyAssignment) GetType() PolicyType {
if m != nil {
@@ -4617,7 +3792,7 @@ type Roa struct {
func (m *Roa) Reset() { *m = Roa{} }
func (m *Roa) String() string { return proto.CompactTextString(m) }
func (*Roa) ProtoMessage() {}
-func (*Roa) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{156} }
+func (*Roa) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{131} }
func (m *Roa) GetAs() uint32 {
if m != nil {
@@ -4661,7 +3836,7 @@ type GetRoaRequest struct {
func (m *GetRoaRequest) Reset() { *m = GetRoaRequest{} }
func (m *GetRoaRequest) String() string { return proto.CompactTextString(m) }
func (*GetRoaRequest) ProtoMessage() {}
-func (*GetRoaRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{157} }
+func (*GetRoaRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{132} }
func (m *GetRoaRequest) GetFamily() uint32 {
if m != nil {
@@ -4677,7 +3852,7 @@ type GetRoaResponse struct {
func (m *GetRoaResponse) Reset() { *m = GetRoaResponse{} }
func (m *GetRoaResponse) String() string { return proto.CompactTextString(m) }
func (*GetRoaResponse) ProtoMessage() {}
-func (*GetRoaResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{158} }
+func (*GetRoaResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{133} }
func (m *GetRoaResponse) GetRoas() []*Roa {
if m != nil {
@@ -4697,7 +3872,7 @@ type Vrf struct {
func (m *Vrf) Reset() { *m = Vrf{} }
func (m *Vrf) String() string { return proto.CompactTextString(m) }
func (*Vrf) ProtoMessage() {}
-func (*Vrf) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{159} }
+func (*Vrf) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{134} }
func (m *Vrf) GetName() string {
if m != nil {
@@ -4746,7 +3921,7 @@ type Global struct {
func (m *Global) Reset() { *m = Global{} }
func (m *Global) String() string { return proto.CompactTextString(m) }
func (*Global) ProtoMessage() {}
-func (*Global) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{160} }
+func (*Global) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{135} }
func (m *Global) GetAs() uint32 {
if m != nil {
@@ -4802,7 +3977,7 @@ type TableInfo struct {
func (m *TableInfo) Reset() { *m = TableInfo{} }
func (m *TableInfo) String() string { return proto.CompactTextString(m) }
func (*TableInfo) ProtoMessage() {}
-func (*TableInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{161} }
+func (*TableInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{136} }
func (m *TableInfo) GetType() Resource {
if m != nil {
@@ -4853,7 +4028,7 @@ type GetRibInfoRequest struct {
func (m *GetRibInfoRequest) Reset() { *m = GetRibInfoRequest{} }
func (m *GetRibInfoRequest) String() string { return proto.CompactTextString(m) }
func (*GetRibInfoRequest) ProtoMessage() {}
-func (*GetRibInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{162} }
+func (*GetRibInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{137} }
func (m *GetRibInfoRequest) GetInfo() *TableInfo {
if m != nil {
@@ -4869,7 +4044,7 @@ type GetRibInfoResponse struct {
func (m *GetRibInfoResponse) Reset() { *m = GetRibInfoResponse{} }
func (m *GetRibInfoResponse) String() string { return proto.CompactTextString(m) }
func (*GetRibInfoResponse) ProtoMessage() {}
-func (*GetRibInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{163} }
+func (*GetRibInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{138} }
func (m *GetRibInfoResponse) GetInfo() *TableInfo {
if m != nil {
@@ -4996,31 +4171,6 @@ func init() {
proto.RegisterType((*TimersState)(nil), "gobgpapi.TimersState")
proto.RegisterType((*Transport)(nil), "gobgpapi.Transport")
proto.RegisterType((*RouteServer)(nil), "gobgpapi.RouteServer")
- proto.RegisterType((*GracefulRestart)(nil), "gobgpapi.GracefulRestart")
- proto.RegisterType((*MpGracefulRestartConfig)(nil), "gobgpapi.MpGracefulRestartConfig")
- proto.RegisterType((*MpGracefulRestartState)(nil), "gobgpapi.MpGracefulRestartState")
- proto.RegisterType((*MpGracefulRestart)(nil), "gobgpapi.MpGracefulRestart")
- proto.RegisterType((*AfiSafiConfig)(nil), "gobgpapi.AfiSafiConfig")
- proto.RegisterType((*AfiSafiState)(nil), "gobgpapi.AfiSafiState")
- proto.RegisterType((*RouteSelectionOptionsConfig)(nil), "gobgpapi.RouteSelectionOptionsConfig")
- proto.RegisterType((*RouteSelectionOptionsState)(nil), "gobgpapi.RouteSelectionOptionsState")
- proto.RegisterType((*RouteSelectionOptions)(nil), "gobgpapi.RouteSelectionOptions")
- proto.RegisterType((*UseMultiplePathsConfig)(nil), "gobgpapi.UseMultiplePathsConfig")
- proto.RegisterType((*UseMultiplePathsState)(nil), "gobgpapi.UseMultiplePathsState")
- proto.RegisterType((*EbgpConfig)(nil), "gobgpapi.EbgpConfig")
- proto.RegisterType((*EbgpState)(nil), "gobgpapi.EbgpState")
- proto.RegisterType((*Ebgp)(nil), "gobgpapi.Ebgp")
- proto.RegisterType((*IbgpConfig)(nil), "gobgpapi.IbgpConfig")
- proto.RegisterType((*IbgpState)(nil), "gobgpapi.IbgpState")
- proto.RegisterType((*Ibgp)(nil), "gobgpapi.Ibgp")
- proto.RegisterType((*UseMultiplePaths)(nil), "gobgpapi.UseMultiplePaths")
- proto.RegisterType((*RouteTargetMembershipConfig)(nil), "gobgpapi.RouteTargetMembershipConfig")
- proto.RegisterType((*RouteTargetMembershipState)(nil), "gobgpapi.RouteTargetMembershipState")
- proto.RegisterType((*RouteTargetMembership)(nil), "gobgpapi.RouteTargetMembership")
- proto.RegisterType((*LongLivedGracefulRestartConfig)(nil), "gobgpapi.LongLivedGracefulRestartConfig")
- proto.RegisterType((*LongLivedGracefulRestartState)(nil), "gobgpapi.LongLivedGracefulRestartState")
- proto.RegisterType((*LongLivedGracefulRestart)(nil), "gobgpapi.LongLivedGracefulRestart")
- proto.RegisterType((*AfiSafi)(nil), "gobgpapi.AfiSafi")
proto.RegisterType((*Prefix)(nil), "gobgpapi.Prefix")
proto.RegisterType((*DefinedSet)(nil), "gobgpapi.DefinedSet")
proto.RegisterType((*MatchSet)(nil), "gobgpapi.MatchSet")
@@ -6872,428 +6022,367 @@ var _GobgpApi_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("gobgp.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
- // 6761 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x7c, 0x4b, 0x8f, 0x1b, 0x49,
- 0x72, 0x70, 0xf3, 0xd1, 0x6c, 0x32, 0x48, 0x36, 0xd9, 0xd9, 0x2f, 0x8a, 0x3d, 0x7a, 0xd5, 0x8e,
- 0x46, 0x1a, 0x8d, 0x46, 0x33, 0xd2, 0xcc, 0x68, 0x66, 0x47, 0xab, 0xd9, 0xa5, 0xba, 0xa9, 0x16,
- 0x77, 0xfa, 0xc1, 0xc9, 0xa6, 0xb4, 0x9a, 0xfd, 0x76, 0xbf, 0x72, 0x35, 0x2b, 0xc9, 0x2e, 0x4f,
- 0xb1, 0xaa, 0xa6, 0xaa, 0xd8, 0xea, 0x86, 0x01, 0x1b, 0x58, 0x03, 0x86, 0x01, 0xc3, 0x17, 0x5f,
- 0x6d, 0xc0, 0xf7, 0x85, 0x7d, 0xf0, 0xc9, 0x80, 0xcf, 0x5e, 0xc3, 0xc0, 0x02, 0xbe, 0xd8, 0x47,
- 0x63, 0x7d, 0xf0, 0x0f, 0xf0, 0xc5, 0x07, 0x1f, 0x7c, 0x30, 0xf2, 0x51, 0x55, 0x59, 0x0f, 0x76,
- 0xb7, 0xb4, 0x5a, 0x1b, 0x06, 0x7c, 0x22, 0x2b, 0x22, 0x32, 0x32, 0x32, 0x33, 0x22, 0x32, 0xf2,
- 0x15, 0x50, 0x1d, 0xdb, 0x87, 0x63, 0xe7, 0xae, 0xe3, 0xda, 0xbe, 0x8d, 0xca, 0xec, 0x43, 0x73,
- 0x0c, 0xe5, 0xc7, 0x80, 0xb6, 0x89, 0xbf, 0x47, 0x8c, 0xf1, 0xd1, 0xa1, 0xed, 0x62, 0xf2, 0xed,
- 0x94, 0x78, 0x3e, 0xba, 0x0d, 0x4d, 0x62, 0x69, 0x87, 0x26, 0xe9, 0xe8, 0xc7, 0xc4, 0xf5, 0x0d,
- 0x8f, 0xe8, 0xad, 0xdc, 0xb5, 0xdc, 0xad, 0x32, 0x4e, 0xc1, 0x51, 0x0b, 0x16, 0x34, 0x5d, 0x77,
- 0x89, 0xe7, 0xb5, 0xf2, 0xd7, 0x72, 0xb7, 0x2a, 0x38, 0xf8, 0x54, 0x1e, 0xc2, 0x72, 0x8c, 0xb7,
- 0xe7, 0xd8, 0x96, 0x47, 0xd0, 0xdb, 0x30, 0xef, 0x10, 0xe2, 0x7a, 0xad, 0xdc, 0xb5, 0xc2, 0xad,
- 0xea, 0xfd, 0xc5, 0xbb, 0x81, 0x30, 0x77, 0xfb, 0x84, 0xb8, 0x98, 0x23, 0x95, 0x31, 0x54, 0x3a,
- 0xee, 0x78, 0x3a, 0x21, 0x96, 0xef, 0xa1, 0xbb, 0x50, 0x76, 0x89, 0x67, 0x4f, 0xdd, 0x21, 0x61,
- 0x72, 0x2c, 0xde, 0x47, 0x51, 0x29, 0x2c, 0x30, 0x38, 0xa4, 0x41, 0x6b, 0x50, 0x1a, 0x69, 0x13,
- 0xc3, 0x3c, 0x65, 0x22, 0xd5, 0xb1, 0xf8, 0x42, 0x08, 0x8a, 0x96, 0x36, 0x21, 0xad, 0x02, 0x13,
- 0x94, 0xfd, 0x57, 0x7e, 0x07, 0x16, 0x3b, 0xba, 0xde, 0xd7, 0xfc, 0xa3, 0xa0, 0xf5, 0xaf, 0x5a,
- 0xdb, 0x2a, 0x94, 0x8e, 0xdd, 0x91, 0x6a, 0xe8, 0xa2, 0x03, 0xe6, 0x8f, 0xdd, 0x51, 0x4f, 0x47,
- 0x0a, 0x14, 0x1d, 0xcd, 0x3f, 0x62, 0x95, 0xc5, 0x9b, 0x49, 0xeb, 0x62, 0x38, 0xe5, 0x06, 0x34,
- 0xc2, 0xca, 0x45, 0xf7, 0x20, 0x28, 0x4e, 0xa7, 0x06, 0xef, 0xef, 0x1a, 0x66, 0xff, 0x95, 0x9f,
- 0xe7, 0x60, 0x69, 0x8b, 0x98, 0xc4, 0x27, 0xbf, 0x01, 0x39, 0xa3, 0xce, 0x2a, 0xc4, 0x3a, 0x2b,
- 0x90, 0xbf, 0x38, 0x5b, 0xfe, 0x50, 0xd8, 0x79, 0x49, 0xd8, 0x15, 0x40, 0xb2, 0xac, 0xbc, 0x59,
- 0xca, 0x67, 0x80, 0x3a, 0xba, 0x9e, 0x54, 0x34, 0x5a, 0x07, 0x21, 0x2e, 0x13, 0x3f, 0xad, 0x0a,
- 0x0c, 0xa7, 0xac, 0xc2, 0x72, 0xac, 0xa4, 0x60, 0xf8, 0x10, 0x56, 0x79, 0x35, 0xaf, 0xc3, 0xb3,
- 0x05, 0x6b, 0xc9, 0xc2, 0x82, 0xed, 0x73, 0x58, 0xc1, 0xc4, 0x4b, 0x9b, 0x84, 0xa4, 0xe6, 0xb9,
- 0x98, 0x9a, 0xa3, 0xb7, 0xa1, 0x3e, 0xb4, 0x27, 0x93, 0xa9, 0x65, 0x0c, 0x35, 0xdf, 0xb0, 0x2d,
- 0xd1, 0xbb, 0x71, 0xa0, 0xb2, 0x0e, 0xab, 0x09, 0xbe, 0xa2, 0xc2, 0xbf, 0xc9, 0x41, 0xeb, 0xc0,
- 0x1e, 0xf9, 0xaf, 0x58, 0xeb, 0x01, 0x54, 0x74, 0xc3, 0x25, 0xc3, 0xb0, 0xc6, 0xc5, 0xfb, 0x9f,
- 0x44, 0x4d, 0x9d, 0xc5, 0x30, 0x42, 0x6c, 0x05, 0x85, 0x71, 0xc4, 0x47, 0xf9, 0x00, 0x50, 0x9a,
- 0x00, 0x95, 0x20, 0xdf, 0xdb, 0x6b, 0xce, 0xa1, 0x05, 0x28, 0xec, 0x3f, 0x1b, 0x34, 0x73, 0xa8,
- 0x0c, 0xc5, 0xc7, 0xfb, 0x83, 0xa7, 0xcd, 0xbc, 0xb2, 0x01, 0x97, 0x32, 0xaa, 0x12, 0x2d, 0xfb,
- 0x1a, 0xd6, 0x0f, 0x8e, 0xa6, 0xbe, 0x6e, 0xbf, 0xb4, 0xde, 0x74, 0x6f, 0xb6, 0xa1, 0x95, 0x66,
- 0x2d, 0xaa, 0xbd, 0x07, 0xab, 0x5d, 0xe6, 0xa4, 0x2e, 0x5c, 0x29, 0x55, 0x87, 0x64, 0x11, 0xc1,
- 0xec, 0x05, 0xac, 0x6d, 0x19, 0xde, 0x2b, 0x71, 0xbb, 0x60, 0x13, 0x2e, 0xc1, 0x7a, 0x8a, 0xb3,
- 0xa8, 0x74, 0x0c, 0x4d, 0x2e, 0xce, 0xae, 0xeb, 0x07, 0xd5, 0x6d, 0x40, 0x45, 0x9f, 0x4e, 0x1c,
- 0xd5, 0x3f, 0x75, 0xb8, 0xb5, 0xcf, 0xe3, 0x32, 0x05, 0x0c, 0x4e, 0x1d, 0x82, 0xda, 0x50, 0x1e,
- 0x19, 0x26, 0x61, 0xbe, 0x8d, 0x57, 0x16, 0x7e, 0x53, 0x9c, 0x61, 0xf9, 0xc4, 0x3d, 0xd6, 0x4c,
- 0x66, 0xe0, 0x45, 0x1c, 0x7e, 0x2b, 0xcb, 0xb0, 0x24, 0x55, 0x24, 0x6a, 0x5f, 0x86, 0x25, 0x21,
- 0x58, 0x54, 0x3d, 0x33, 0x6a, 0x09, 0x28, 0x48, 0x7f, 0x0f, 0x9a, 0x3d, 0xeb, 0xb7, 0xc9, 0xd0,
- 0x97, 0x04, 0x7d, 0x43, 0x5e, 0x89, 0xce, 0x12, 0x9a, 0x7f, 0xe4, 0xb5, 0x0a, 0xa9, 0x59, 0x82,
- 0xba, 0x15, 0x8e, 0xa4, 0xb2, 0x4a, 0x02, 0x08, 0xa9, 0xfe, 0x22, 0x07, 0xf5, 0x8e, 0xae, 0x3f,
- 0x9e, 0x38, 0xe7, 0x8f, 0x15, 0x82, 0xa2, 0x63, 0xbb, 0xbe, 0x98, 0x27, 0xd8, 0x7f, 0xf4, 0x3d,
- 0x28, 0xb2, 0x5e, 0x2e, 0x30, 0xe9, 0x6f, 0x45, 0x35, 0xc7, 0x98, 0xde, 0xdd, 0xb5, 0x2d, 0xc3,
- 0xb7, 0x5d, 0xc3, 0x1a, 0xf7, 0x6d, 0xd3, 0x18, 0x9e, 0x62, 0x56, 0x4a, 0xf9, 0x00, 0x9a, 0x49,
- 0x0c, 0xb5, 0x9c, 0x3e, 0xee, 0x36, 0xe7, 0xa8, 0xe5, 0xf4, 0xf7, 0x0f, 0xe2, 0x36, 0xd4, 0x64,
- 0x13, 0x10, 0x63, 0x2c, 0x1a, 0xf0, 0x03, 0x68, 0x72, 0xef, 0xf4, 0xba, 0x4d, 0x60, 0x63, 0x18,
- 0x71, 0x10, 0x6c, 0x07, 0xb0, 0x24, 0x24, 0xc3, 0xc6, 0x61, 0xc0, 0xf7, 0x06, 0xcc, 0xfb, 0x74,
- 0x58, 0x85, 0xbb, 0x6c, 0x44, 0xad, 0x1d, 0x50, 0x30, 0xe6, 0x58, 0x5a, 0xfd, 0x70, 0xea, 0xba,
- 0xc4, 0xe2, 0xf5, 0x94, 0x71, 0xf0, 0xa9, 0x74, 0xa1, 0x8c, 0xfb, 0x5f, 0xf6, 0x36, 0x6d, 0x6b,
- 0x74, 0x86, 0x90, 0x57, 0xa1, 0xea, 0x92, 0x89, 0xed, 0x13, 0x35, 0x94, 0xb5, 0x82, 0x81, 0x83,
- 0xfa, 0x54, 0xe2, 0x3f, 0x2b, 0x42, 0x85, 0xf2, 0x39, 0xf0, 0x35, 0x9f, 0x4d, 0xe0, 0x53, 0xc7,
- 0x37, 0x26, 0x5c, 0xac, 0x02, 0x16, 0x5f, 0x54, 0x99, 0xa9, 0xcd, 0x33, 0x4c, 0x9e, 0x61, 0xc2,
- 0x6f, 0xb4, 0x08, 0xf9, 0xa9, 0xc3, 0x06, 0xad, 0x8c, 0xf3, 0x53, 0x87, 0x57, 0x39, 0xb4, 0x5d,
- 0x5d, 0x35, 0x9c, 0xe3, 0x8f, 0xd9, 0x34, 0x56, 0xa7, 0x55, 0x52, 0x50, 0xcf, 0x39, 0xfe, 0x38,
- 0x4e, 0xf0, 0x80, 0xcd, 0x61, 0x32, 0xc1, 0x03, 0x4a, 0xe0, 0xb8, 0x64, 0x64, 0x9c, 0x70, 0x0e,
- 0x25, 0x4e, 0xc0, 0x41, 0x01, 0x87, 0x88, 0xe0, 0x41, 0x6b, 0x21, 0x41, 0xf0, 0x80, 0xb6, 0xc3,
- 0x23, 0xae, 0xa1, 0x99, 0xad, 0x32, 0x9f, 0x5b, 0xf9, 0x17, 0xfa, 0x0e, 0xd4, 0x5d, 0x32, 0x24,
- 0xc6, 0x31, 0x11, 0xd2, 0x55, 0x58, 0x63, 0x6a, 0x01, 0x90, 0x71, 0x4f, 0x10, 0x3d, 0x68, 0x41,
- 0x8a, 0xe8, 0x01, 0x25, 0xe2, 0x3c, 0x55, 0xcb, 0xf6, 0x8d, 0xd1, 0x69, 0xab, 0xca, 0x89, 0x38,
- 0x70, 0x8f, 0xc1, 0xa8, 0x9c, 0x43, 0x6d, 0x78, 0x44, 0x54, 0x97, 0x3a, 0xea, 0x56, 0x8d, 0x91,
- 0x00, 0x03, 0x31, 0xd7, 0x8d, 0x6e, 0xc0, 0x62, 0x48, 0xc0, 0x94, 0xa5, 0x55, 0x67, 0x34, 0xf5,
- 0x80, 0x86, 0xc7, 0x26, 0x57, 0xa0, 0x4a, 0x2c, 0x5d, 0xb5, 0x47, 0xaa, 0xae, 0xf9, 0x5a, 0x6b,
- 0x91, 0xd1, 0x54, 0x88, 0xa5, 0xef, 0x8f, 0xb6, 0x34, 0x5f, 0x43, 0x2b, 0x30, 0x4f, 0x5c, 0xd7,
- 0x76, 0x5b, 0x0d, 0x86, 0xe1, 0x1f, 0xe8, 0x3a, 0x08, 0x69, 0xd4, 0x6f, 0xa7, 0xc4, 0x3d, 0x6d,
- 0x35, 0x19, 0xb2, 0xca, 0x61, 0x5f, 0x51, 0x10, 0x1f, 0x0a, 0x8f, 0xf8, 0x82, 0x62, 0x89, 0x0b,
- 0xc8, 0x40, 0x8c, 0x40, 0xf9, 0x1a, 0x8a, 0xd8, 0xf9, 0xc6, 0x40, 0xef, 0x40, 0x71, 0x68, 0x5b,
- 0x23, 0xa1, 0xad, 0xb2, 0x67, 0x11, 0x3a, 0x88, 0x19, 0x1e, 0xbd, 0x0b, 0xf3, 0x1e, 0xd5, 0x24,
- 0xa6, 0x25, 0xd5, 0xfb, 0xcb, 0x71, 0x42, 0xa6, 0x64, 0x98, 0x53, 0x28, 0xb7, 0x60, 0x71, 0x9b,
- 0xf8, 0x94, 0x7b, 0x60, 0x13, 0x51, 0x44, 0x94, 0x93, 0x23, 0x22, 0xe5, 0x21, 0x34, 0x42, 0x4a,
- 0xd1, 0x23, 0xb7, 0x60, 0xc1, 0x23, 0xee, 0x71, 0x66, 0x38, 0xcb, 0x08, 0x03, 0xb4, 0xf2, 0x63,
- 0x66, 0xe6, 0x72, 0x35, 0xaf, 0xe6, 0x95, 0xda, 0x50, 0x36, 0x8d, 0x11, 0x61, 0xaa, 0x5f, 0xe0,
- 0xaa, 0x1f, 0x7c, 0x2b, 0x4b, 0x2c, 0x8c, 0x94, 0x05, 0x53, 0x3a, 0x81, 0x07, 0x78, 0xed, 0x1a,
- 0xa3, 0x40, 0x2e, 0xc6, 0xf8, 0xfd, 0x60, 0xce, 0xb8, 0x10, 0x63, 0xca, 0x44, 0x26, 0x17, 0x4c,
- 0xee, 0x86, 0xd3, 0xc9, 0xc5, 0xb8, 0xac, 0xc2, 0x72, 0x8c, 0x5e, 0xb0, 0xb9, 0x03, 0x4d, 0xa6,
- 0xbf, 0x17, 0x63, 0xb2, 0x0c, 0x4b, 0x12, 0xb5, 0x60, 0xf1, 0x21, 0xac, 0x84, 0x11, 0xcc, 0xc5,
- 0xd8, 0xac, 0xc3, 0x6a, 0xa2, 0x84, 0x60, 0xf5, 0xcb, 0x5c, 0xd0, 0xd6, 0x1f, 0x93, 0x43, 0x57,
- 0x0b, 0x38, 0x35, 0xa1, 0x30, 0x75, 0x4d, 0xc1, 0x85, 0xfe, 0x65, 0xda, 0x6e, 0x4f, 0x7d, 0xc2,
- 0x26, 0x73, 0xba, 0x6c, 0x2a, 0x30, 0x67, 0x48, 0x41, 0x74, 0x3a, 0xf7, 0x68, 0xe5, 0x54, 0x67,
- 0x68, 0xec, 0xc0, 0x63, 0xf2, 0xe0, 0x13, 0x7d, 0x0c, 0x6b, 0x16, 0x39, 0xf1, 0x8f, 0x6c, 0x47,
- 0xf5, 0x5d, 0x63, 0x3c, 0x26, 0xae, 0xca, 0x57, 0x64, 0xcc, 0xbf, 0x95, 0xf1, 0x8a, 0xc0, 0x0e,
- 0x38, 0x92, 0x8b, 0x83, 0xee, 0xc3, 0x6a, 0xb2, 0x94, 0x4e, 0x4c, 0xed, 0x54, 0xf8, 0xbc, 0xe5,
- 0x78, 0xa1, 0x2d, 0x8a, 0xa2, 0x5d, 0x1e, 0x6b, 0x8c, 0x68, 0x64, 0x03, 0xea, 0xdb, 0xc4, 0x7f,
- 0xee, 0x8e, 0x82, 0xc8, 0xe0, 0x23, 0x66, 0x3e, 0x0c, 0x20, 0x6c, 0xe2, 0x3a, 0x14, 0x8f, 0xdd,
- 0x51, 0x60, 0x10, 0xf5, 0xc8, 0x20, 0x28, 0x11, 0x43, 0x29, 0x1f, 0xb2, 0x19, 0x3a, 0xe2, 0x82,
- 0xae, 0x42, 0xe1, 0xd8, 0x0d, 0xcc, 0x3a, 0x51, 0x84, 0x62, 0xc4, 0x2c, 0x29, 0x55, 0xa3, 0x7c,
- 0x14, 0xcc, 0x92, 0xaf, 0xc2, 0x26, 0x9c, 0x18, 0x65, 0x4e, 0xcf, 0x60, 0x65, 0x9b, 0xf8, 0x5b,
- 0x64, 0x64, 0x58, 0x44, 0x3f, 0x20, 0x61, 0x28, 0xf3, 0xae, 0x08, 0x04, 0x78, 0x18, 0xb3, 0x1a,
- 0xb1, 0x13, 0xa4, 0x74, 0xb0, 0xf8, 0xac, 0x1f, 0xae, 0x2c, 0xf3, 0xd2, 0xca, 0xb2, 0x03, 0xab,
- 0x09, 0xb6, 0xa1, 0xd3, 0x28, 0x7a, 0xc4, 0x0f, 0x3a, 0x68, 0x25, 0xc5, 0x97, 0xd2, 0x32, 0x0a,
- 0xe5, 0x0b, 0x58, 0xe9, 0xe8, 0x7a, 0x5a, 0xb2, 0x77, 0xa0, 0x40, 0x1d, 0x39, 0x6f, 0x67, 0x36,
- 0x03, 0x4a, 0x40, 0x75, 0x35, 0x51, 0x5e, 0x34, 0xf9, 0x00, 0xd6, 0x79, 0x3f, 0xbc, 0x36, 0x6f,
- 0xaa, 0xd7, 0x9a, 0x69, 0x8a, 0x70, 0x80, 0xfe, 0xa5, 0x51, 0x79, 0x9a, 0xa9, 0xa8, 0xf0, 0x31,
- 0xb4, 0x30, 0x71, 0x4c, 0x6d, 0xf8, 0xfa, 0x35, 0xd2, 0xd5, 0x46, 0x06, 0x0f, 0x51, 0xc1, 0x2a,
- 0xdb, 0x6d, 0x60, 0x9e, 0x7d, 0x42, 0xac, 0x30, 0x70, 0xfd, 0x92, 0x8d, 0xad, 0x04, 0x16, 0x63,
- 0xf0, 0x11, 0x80, 0x17, 0x00, 0x83, 0x91, 0x90, 0x66, 0x89, 0xa8, 0x80, 0x44, 0xa6, 0x3c, 0x65,
- 0x4b, 0xd1, 0x64, 0x1d, 0xe8, 0x1e, 0x54, 0x42, 0x22, 0xd1, 0x8a, 0x4c, 0x56, 0x11, 0x95, 0xb2,
- 0xc6, 0x06, 0x36, 0x25, 0x96, 0xf2, 0xd3, 0x60, 0x61, 0xfa, 0x06, 0x2a, 0xc9, 0x18, 0xa1, 0x4b,
- 0xc1, 0xb0, 0xa7, 0x6b, 0xde, 0x81, 0x75, 0xd1, 0xb9, 0x6f, 0xa2, 0x7d, 0xed, 0x70, 0xb8, 0xd3,
- 0x35, 0x21, 0x68, 0x6e, 0x13, 0x5f, 0x04, 0xcd, 0x62, 0x98, 0x3a, 0xb0, 0x24, 0xc1, 0xc4, 0x18,
- 0xdd, 0x81, 0xb2, 0x43, 0x21, 0x06, 0x09, 0x46, 0xa8, 0x29, 0x2d, 0x03, 0x38, 0x6d, 0x48, 0xa1,
- 0x9c, 0x40, 0xb3, 0xa3, 0xeb, 0x31, 0xb6, 0xe8, 0x16, 0x94, 0x18, 0xfe, 0x54, 0x88, 0x9d, 0x2e,
- 0x2f, 0xf0, 0xe8, 0x73, 0xb8, 0xe4, 0x92, 0x11, 0x75, 0xa7, 0x27, 0x86, 0xe7, 0x1b, 0xd6, 0x58,
- 0x95, 0xd4, 0x83, 0xf7, 0xe0, 0x3a, 0x23, 0xe8, 0x0a, 0xfc, 0x41, 0xa4, 0x16, 0xcb, 0xb0, 0x24,
- 0xd5, 0x2c, 0x5a, 0xf9, 0xb3, 0x1c, 0x2c, 0x8b, 0x7d, 0x90, 0xd7, 0x14, 0xe9, 0x03, 0x58, 0x76,
- 0x68, 0x08, 0xe4, 0x1e, 0x93, 0xb4, 0x30, 0x28, 0x40, 0x45, 0x72, 0x04, 0xe3, 0x5d, 0x88, 0xc6,
- 0x7b, 0x0d, 0x56, 0xe2, 0x32, 0x08, 0xe1, 0xfe, 0x32, 0x07, 0x2b, 0x62, 0x7c, 0xfe, 0x07, 0x3a,
- 0x6c, 0x56, 0xcb, 0x0a, 0xb3, 0x5a, 0xc6, 0x77, 0x4f, 0x62, 0xe2, 0x86, 0xeb, 0xf3, 0x76, 0xa8,
- 0x37, 0x1d, 0xcf, 0x33, 0xc6, 0x96, 0xac, 0xb8, 0x9f, 0x03, 0x68, 0x21, 0x50, 0xb4, 0xa8, 0x9d,
- 0x6c, 0x91, 0x54, 0x4c, 0xa2, 0x56, 0xbe, 0x86, 0x8d, 0x4c, 0xce, 0x42, 0x37, 0x7f, 0x1d, 0xd6,
- 0x2f, 0xa0, 0x1d, 0xea, 0xcb, 0x9b, 0x15, 0xfa, 0x32, 0x6c, 0x64, 0x72, 0x16, 0xbd, 0x35, 0x81,
- 0xcb, 0xb2, 0x3a, 0xbc, 0xd1, 0xba, 0x33, 0xbc, 0xcd, 0x35, 0xb8, 0x32, 0xab, 0x3a, 0x21, 0xd0,
- 0x4f, 0xe0, 0x4a, 0x6c, 0x5c, 0xdf, 0x6c, 0x6f, 0x5c, 0x87, 0xab, 0x33, 0xb9, 0xc7, 0x7c, 0xd1,
- 0x01, 0x8b, 0xd1, 0x03, 0x5f, 0xf4, 0x88, 0xf9, 0xa2, 0x00, 0x16, 0xce, 0xd9, 0xa5, 0xb1, 0x69,
- 0x1f, 0x6a, 0x66, 0xda, 0x30, 0xb6, 0x19, 0x1c, 0x0b, 0xbc, 0xf2, 0x05, 0xa0, 0x03, 0x5f, 0x73,
- 0xe3, 0x4c, 0x5f, 0xa1, 0xfc, 0x2a, 0x2c, 0xc7, 0xca, 0x47, 0xdb, 0x32, 0x07, 0xbe, 0xed, 0xc4,
- 0x45, 0x5d, 0xa1, 0x75, 0x45, 0x40, 0x41, 0xfa, 0xab, 0x02, 0x14, 0xfb, 0x62, 0x7b, 0xd6, 0x32,
- 0x5d, 0x23, 0xd8, 0x4b, 0xa6, 0xff, 0xe9, 0xe2, 0xc6, 0xd1, 0x7c, 0xdf, 0xe5, 0x71, 0x67, 0x0d,
- 0x8b, 0x2f, 0x36, 0x7c, 0xe3, 0x60, 0x69, 0x41, 0xff, 0xd2, 0xd2, 0x87, 0xc4, 0xf3, 0x45, 0x64,
- 0xc9, 0xfe, 0xd3, 0xd0, 0xd5, 0xf0, 0xd4, 0x97, 0x86, 0x7f, 0xa4, 0xbb, 0xda, 0x4b, 0x16, 0x3f,
- 0x96, 0x31, 0x18, 0xde, 0x8f, 0x04, 0x04, 0x5d, 0x01, 0x38, 0xd6, 0x4c, 0x43, 0xe7, 0x3b, 0x5f,
- 0x25, 0xb6, 0x51, 0x25, 0x41, 0xd0, 0x87, 0xb0, 0x62, 0xd9, 0xaa, 0x31, 0x71, 0xa8, 0xd7, 0xf6,
- 0x23, 0x4e, 0x0b, 0xdc, 0xf6, 0x2d, 0xbb, 0x27, 0x50, 0x21, 0xc7, 0x68, 0x35, 0x56, 0x8e, 0xed,
- 0x4f, 0x5f, 0x06, 0xe0, 0x5b, 0x48, 0xaa, 0xe6, 0x59, 0x6c, 0x01, 0x5d, 0xc7, 0x15, 0x0e, 0xe9,
- 0x78, 0x16, 0xda, 0x00, 0xf1, 0xa1, 0x1a, 0x3a, 0x5b, 0x39, 0x57, 0x70, 0x99, 0x03, 0x7a, 0xba,
- 0xd8, 0x30, 0xf3, 0x89, 0x4b, 0x74, 0xb6, 0x60, 0x2e, 0xe3, 0xf0, 0x9b, 0x2e, 0x62, 0x3d, 0x5f,
- 0x33, 0x09, 0x5b, 0x26, 0x97, 0x31, 0xff, 0x40, 0xb7, 0xa0, 0x69, 0x78, 0xea, 0xc8, 0xb5, 0x27,
- 0x2a, 0x39, 0xf1, 0x89, 0x6b, 0x69, 0x26, 0x5b, 0x23, 0x97, 0xf1, 0xa2, 0xe1, 0x3d, 0x71, 0xed,
- 0x49, 0x57, 0x40, 0x69, 0x17, 0x59, 0x62, 0x47, 0x4f, 0x35, 0x1c, 0xb6, 0x48, 0xae, 0x60, 0x08,
- 0x40, 0x3d, 0x27, 0xdc, 0x34, 0x6f, 0x44, 0x9b, 0xe6, 0xe8, 0x0e, 0x20, 0xc3, 0x53, 0x83, 0x20,
- 0xdd, 0xb0, 0x58, 0x8f, 0xb1, 0x95, 0x72, 0x19, 0x37, 0x0d, 0x6f, 0x8f, 0x23, 0x7a, 0x1c, 0xae,
- 0xfc, 0x79, 0x0e, 0xaa, 0x5b, 0x84, 0x7a, 0x55, 0xde, 0xa9, 0x74, 0x4c, 0xd9, 0xa6, 0x83, 0x58,
- 0x65, 0x88, 0xaf, 0x68, 0x13, 0x2d, 0x7f, 0xc6, 0x26, 0x1a, 0xba, 0x09, 0x0d, 0xd3, 0xb6, 0xe8,
- 0xa2, 0x80, 0x17, 0x23, 0x81, 0x27, 0x5e, 0xe4, 0xe0, 0xbe, 0x80, 0xa2, 0x77, 0xa1, 0xe9, 0x1d,
- 0xd9, 0xae, 0x2f, 0x53, 0x72, 0xe5, 0x68, 0x08, 0x78, 0x40, 0xaa, 0xfc, 0x75, 0x0e, 0xe6, 0xd9,
- 0x06, 0x12, 0x5d, 0xb1, 0x4b, 0x41, 0x74, 0xd6, 0x5e, 0xe0, 0xcc, 0x08, 0x7a, 0xe6, 0xd1, 0xc4,
- 0x77, 0xa1, 0xa6, 0x47, 0xcd, 0xa7, 0x42, 0xd0, 0xe6, 0xc5, 0x02, 0xf4, 0x10, 0x8b, 0x63, 0xa4,
- 0x6c, 0xcb, 0xc6, 0xf6, 0x7c, 0x55, 0xcc, 0x72, 0x42, 0x81, 0x29, 0x88, 0xfb, 0x08, 0xe5, 0x01,
- 0x5b, 0xe0, 0xbc, 0xf2, 0x0e, 0x99, 0xf2, 0x29, 0xdf, 0x46, 0xa0, 0xe5, 0x84, 0xcb, 0xb8, 0x60,
- 0x41, 0x13, 0xd0, 0x73, 0x6e, 0x1f, 0x44, 0xaa, 0xf5, 0xa2, 0xdd, 0x36, 0xeb, 0xa8, 0x2b, 0x52,
- 0x89, 0x82, 0xac, 0x12, 0xd4, 0xbb, 0xc4, 0x6a, 0x0b, 0x4e, 0x21, 0x8a, 0x50, 0xec, 0x13, 0xe2,
- 0x32, 0xcb, 0xa0, 0x1c, 0x82, 0x98, 0xab, 0x8e, 0xc3, 0x6f, 0xf4, 0x19, 0xd4, 0x34, 0xc7, 0x31,
- 0x4f, 0x83, 0xce, 0xe3, 0x7b, 0x2b, 0x52, 0xb7, 0x77, 0x28, 0x56, 0xcc, 0xd0, 0x55, 0x2d, 0xfa,
- 0x08, 0xb7, 0x6d, 0x0a, 0xc9, 0x6d, 0x1b, 0x5a, 0xa7, 0xb4, 0x6d, 0xf3, 0x10, 0xea, 0xe4, 0x70,
- 0xec, 0xa8, 0x93, 0xa9, 0xe9, 0x1b, 0x47, 0xb6, 0x23, 0x0e, 0x9f, 0xd6, 0xa2, 0x02, 0xdd, 0xc3,
- 0xb1, 0xb3, 0x2b, 0xb0, 0xb8, 0x46, 0xa4, 0x2f, 0xd4, 0x81, 0x06, 0x5f, 0x56, 0xbb, 0x64, 0x64,
- 0x92, 0xa1, 0x6f, 0xbb, 0x6c, 0x78, 0xab, 0xf7, 0x5b, 0x52, 0xef, 0x51, 0x02, 0x1c, 0xe0, 0xf1,
- 0xa2, 0x1b, 0xfb, 0x46, 0x37, 0xa1, 0x68, 0x58, 0x23, 0x9b, 0xf9, 0xad, 0x58, 0x90, 0x4b, 0xe5,
- 0xe4, 0xbb, 0x46, 0x8c, 0x80, 0xba, 0x73, 0xdf, 0x98, 0x10, 0xd7, 0x63, 0x8e, 0x2b, 0xe6, 0xce,
- 0x07, 0x0c, 0x8e, 0x05, 0x9e, 0x06, 0xcf, 0xbe, 0xab, 0x59, 0x1e, 0xdb, 0x5e, 0x29, 0x27, 0xf9,
- 0x0e, 0x02, 0x14, 0x8e, 0xa8, 0x68, 0x3f, 0xf3, 0x86, 0xf0, 0xbd, 0x23, 0xe6, 0xdb, 0x62, 0xfd,
- 0xcc, 0x5a, 0x21, 0x9c, 0x3e, 0xdf, 0x4a, 0xe0, 0x1f, 0x68, 0x0b, 0x9a, 0x63, 0x57, 0x1b, 0x92,
- 0xd1, 0xd4, 0x54, 0x5d, 0xe2, 0xd1, 0x69, 0x84, 0xf9, 0xbe, 0xea, 0xfd, 0x4b, 0xd2, 0x7c, 0x23,
- 0x28, 0x30, 0x27, 0xc0, 0x8d, 0x71, 0x1c, 0x80, 0xee, 0x42, 0x45, 0x1b, 0x19, 0xaa, 0xa7, 0x8d,
- 0x0c, 0xaf, 0x55, 0x65, 0xb6, 0xb5, 0x24, 0x0d, 0xf2, 0xc8, 0x38, 0xd0, 0x46, 0x06, 0x2e, 0x6b,
- 0xfc, 0x8f, 0xa7, 0xfc, 0x7d, 0x0e, 0xaa, 0xd2, 0xd0, 0xa3, 0x4f, 0xa1, 0x62, 0x58, 0x6a, 0x2c,
- 0x8e, 0x3c, 0x6b, 0xca, 0x2e, 0x1b, 0x96, 0x28, 0xf8, 0x7d, 0xa8, 0x93, 0x13, 0xda, 0x05, 0x71,
- 0x0d, 0x3b, 0xab, 0x70, 0x8d, 0x17, 0x88, 0x18, 0x18, 0x13, 0x99, 0x41, 0xe1, 0x7c, 0x06, 0xbc,
- 0x80, 0xb0, 0xfe, 0xdf, 0x85, 0x2a, 0xf7, 0x61, 0x3b, 0xc6, 0xc4, 0x98, 0xb9, 0x13, 0x88, 0xae,
- 0x43, 0x6d, 0xa2, 0x9d, 0x44, 0x5e, 0x90, 0xdb, 0x5e, 0x75, 0xa2, 0x9d, 0x84, 0xce, 0xf2, 0x63,
- 0x58, 0xf3, 0xc4, 0x11, 0x95, 0xea, 0x1f, 0xb9, 0xc4, 0x3b, 0xb2, 0x4d, 0x5d, 0x75, 0x86, 0xbe,
- 0xf0, 0x65, 0x2b, 0x01, 0x76, 0x10, 0x20, 0xfb, 0x43, 0x5f, 0xf9, 0xcf, 0x79, 0x28, 0x07, 0x36,
- 0x81, 0xbe, 0x03, 0x75, 0x6d, 0xea, 0x1f, 0xa9, 0x8e, 0xe6, 0x79, 0x2f, 0x6d, 0x57, 0x17, 0xde,
- 0xbd, 0x46, 0x81, 0x7d, 0x01, 0x43, 0xd7, 0xa0, 0xaa, 0x13, 0x6f, 0xe8, 0x1a, 0x8e, 0x74, 0xd6,
- 0x24, 0x83, 0xd0, 0x25, 0x28, 0x9b, 0xf6, 0x50, 0x33, 0x55, 0xcd, 0x0b, 0xb6, 0x93, 0xd8, 0x77,
- 0x87, 0x79, 0xf4, 0x70, 0xae, 0x0a, 0xb6, 0xbb, 0x8a, 0x8c, 0x43, 0x23, 0x80, 0x77, 0xc4, 0x0e,
- 0xe1, 0x3a, 0x2c, 0x38, 0x84, 0xb8, 0x94, 0x09, 0xdf, 0x35, 0x2a, 0xd1, 0xcf, 0x8e, 0x47, 0xe7,
- 0x61, 0x86, 0x18, 0xbb, 0xf6, 0xd4, 0x61, 0x96, 0x53, 0xc1, 0x15, 0x0a, 0xd9, 0xa6, 0x00, 0x3a,
- 0x0f, 0x33, 0x34, 0xf3, 0x66, 0x7c, 0x87, 0xbc, 0x4c, 0x01, 0xec, 0xe0, 0x6a, 0x0f, 0x96, 0x5c,
- 0x32, 0xb1, 0x8f, 0x89, 0xea, 0xb8, 0xc6, 0xb1, 0xe6, 0xd3, 0xb9, 0x9c, 0x19, 0xc9, 0xe2, 0x7d,
- 0x25, 0xed, 0x24, 0xee, 0x62, 0x46, 0xdb, 0xe7, 0xa4, 0x1d, 0x0f, 0x37, 0xdc, 0x38, 0x80, 0x4e,
- 0xa3, 0xdc, 0x72, 0x46, 0xa6, 0xe6, 0xa8, 0xba, 0x36, 0x71, 0x0c, 0x6b, 0xcc, 0xec, 0xa7, 0x8c,
- 0x9b, 0x0c, 0xf3, 0xc4, 0xd4, 0x9c, 0x2d, 0x0e, 0x47, 0x37, 0x60, 0xd1, 0x23, 0x96, 0xae, 0x8a,
- 0x83, 0x39, 0xff, 0x94, 0xd9, 0x4a, 0x1d, 0xd7, 0x29, 0x74, 0x33, 0x00, 0xd2, 0x06, 0x8a, 0xb3,
- 0x8b, 0xa1, 0xe6, 0x30, 0x7b, 0xa8, 0xe1, 0x0a, 0x87, 0x6c, 0x6a, 0xac, 0x81, 0xbc, 0x7b, 0x29,
- 0xb6, 0xc6, 0xb0, 0xbc, 0xbf, 0x29, 0x72, 0x11, 0xf2, 0x86, 0xce, 0x02, 0x85, 0x0a, 0xce, 0x1b,
- 0x3a, 0xfa, 0x1c, 0xea, 0xe2, 0xc4, 0xc0, 0xa4, 0x0a, 0xe6, 0xb5, 0x16, 0x93, 0x53, 0x97, 0xa4,
- 0x7e, 0xb8, 0xe6, 0x44, 0x1f, 0x1e, 0x55, 0x07, 0x31, 0x8e, 0x62, 0xa4, 0x1a, 0x5c, 0x1d, 0xf8,
- 0x60, 0x8a, 0x61, 0x7a, 0x1f, 0x50, 0x14, 0x7d, 0x58, 0x3e, 0x71, 0x47, 0xda, 0x90, 0xb0, 0x40,
- 0xa2, 0x82, 0x97, 0xc2, 0x20, 0x24, 0x40, 0xd0, 0xa8, 0xef, 0xd8, 0x1d, 0xb1, 0x0d, 0xf7, 0x0a,
- 0xdb, 0x21, 0x43, 0xd7, 0xa0, 0xa6, 0x99, 0xa6, 0xfd, 0x52, 0xa5, 0x8a, 0xab, 0x79, 0x2d, 0xc4,
- 0x0f, 0x35, 0x18, 0x6c, 0xff, 0xa5, 0xd5, 0xf1, 0xd0, 0x3b, 0xd0, 0x70, 0x79, 0x58, 0xad, 0x06,
- 0x1a, 0xb1, 0xcc, 0x7a, 0xb8, 0x2e, 0xc0, 0x7d, 0xa6, 0x18, 0xca, 0x3d, 0x68, 0x24, 0x06, 0x0c,
- 0x95, 0xa1, 0xb8, 0xb7, 0xbf, 0xd7, 0xe5, 0x87, 0xc9, 0x9d, 0x9d, 0x9d, 0x66, 0x0e, 0x55, 0x61,
- 0x01, 0x77, 0xfb, 0x3b, 0x9d, 0xcd, 0x6e, 0x33, 0xaf, 0x7c, 0x09, 0x35, 0xd9, 0xc1, 0xa3, 0x16,
- 0x2c, 0xf0, 0xed, 0xcd, 0xe0, 0xfe, 0x49, 0xf0, 0xc9, 0x2c, 0x50, 0x50, 0xa9, 0xbe, 0x6f, 0x86,
- 0x16, 0x28, 0x60, 0x03, 0xdf, 0x54, 0x7e, 0x3f, 0x07, 0x8b, 0x71, 0x7f, 0x4f, 0x8d, 0x32, 0x31,
- 0x45, 0xa8, 0x43, 0xd3, 0x08, 0x56, 0x16, 0x65, 0xbc, 0x12, 0x9f, 0x0f, 0x36, 0x19, 0x0e, 0x3d,
- 0x84, 0x76, 0xba, 0xd4, 0xd4, 0xa3, 0x71, 0x50, 0x78, 0x6c, 0xb9, 0x9e, 0x2c, 0xc9, 0xf0, 0x3d,
- 0x5d, 0xf9, 0xab, 0x12, 0x54, 0xc2, 0xd9, 0xe3, 0xbf, 0xc1, 0xa4, 0xef, 0x42, 0x79, 0x42, 0x3c,
- 0x4f, 0x1b, 0x8b, 0xe0, 0x2c, 0x36, 0xdd, 0xee, 0x0a, 0x0c, 0x0e, 0x69, 0x32, 0x5d, 0xc0, 0xfc,
- 0xb9, 0x2e, 0xa0, 0x74, 0x86, 0x0b, 0x58, 0x38, 0xd3, 0x05, 0x94, 0x13, 0x2e, 0xe0, 0x16, 0x94,
- 0xbe, 0x9d, 0x92, 0x29, 0xf1, 0xc4, 0x34, 0x27, 0xcd, 0xa4, 0x5f, 0x31, 0x38, 0x16, 0x78, 0x74,
- 0x3b, 0xcb, 0x59, 0x70, 0x8b, 0xbd, 0xa0, 0x23, 0xa8, 0x5e, 0xd8, 0x11, 0xd4, 0xb2, 0x1c, 0x01,
- 0x3b, 0x6b, 0xf3, 0x3c, 0xc3, 0xb6, 0xf8, 0xae, 0x05, 0xb3, 0xeb, 0x3a, 0xae, 0x09, 0x20, 0x1f,
- 0xe1, 0x4f, 0x60, 0xcd, 0x9b, 0x3a, 0x74, 0x4a, 0x21, 0x3a, 0x75, 0x09, 0xda, 0xa1, 0x61, 0x1a,
- 0x3e, 0x0d, 0xa7, 0x16, 0xd9, 0x3e, 0xff, 0x6a, 0x88, 0xdd, 0x94, 0x90, 0xb4, 0x8f, 0x68, 0xe0,
- 0xc3, 0xf9, 0x72, 0xc3, 0x2e, 0x1f, 0x8e, 0x1d, 0xce, 0xf3, 0xfb, 0x50, 0xd5, 0xf4, 0x89, 0x11,
- 0x54, 0xdb, 0x64, 0x0e, 0xf2, 0x4a, 0x46, 0x74, 0x72, 0xb7, 0x43, 0xc9, 0x78, 0xa0, 0x02, 0x5a,
- 0xf8, 0x9f, 0x46, 0x75, 0xc1, 0xa9, 0x21, 0xb3, 0xf5, 0x3a, 0x0e, 0xbf, 0x29, 0x4e, 0x1b, 0x0e,
- 0x89, 0xe3, 0x13, 0x5d, 0x18, 0x7b, 0xf8, 0x4d, 0x57, 0x73, 0x5a, 0x74, 0x05, 0x6c, 0x59, 0xb8,
- 0x82, 0xe8, 0xf2, 0xd7, 0x32, 0xcc, 0xdb, 0x53, 0x5f, 0xfd, 0xb6, 0xb5, 0xc2, 0xcf, 0x8d, 0xec,
- 0xa9, 0xff, 0x15, 0x5d, 0x40, 0x8d, 0x4c, 0xdb, 0xf1, 0x5a, 0xab, 0x0c, 0xc8, 0x3f, 0x94, 0xdb,
- 0x00, 0x91, 0x70, 0xa8, 0x04, 0xf9, 0x67, 0x7d, 0x7e, 0x20, 0xbe, 0xb5, 0xff, 0xa3, 0xbd, 0x66,
- 0x0e, 0x01, 0x94, 0xfa, 0x4f, 0x5e, 0xa8, 0x9b, 0x83, 0x66, 0x5e, 0xf9, 0x2d, 0x28, 0x07, 0x9a,
- 0x8a, 0xde, 0x97, 0x44, 0xe7, 0xb1, 0xc4, 0x52, 0x4a, 0x9f, 0xa5, 0xd6, 0xdc, 0x80, 0xa2, 0x17,
- 0x9c, 0x52, 0x67, 0x92, 0x32, 0xb4, 0xf2, 0x8b, 0x1c, 0x2c, 0x08, 0x08, 0x52, 0xa0, 0xb6, 0xb7,
- 0x3f, 0xe8, 0x3d, 0xe9, 0x6d, 0x76, 0x06, 0xbd, 0xfd, 0x3d, 0x56, 0x4b, 0x11, 0xc7, 0x60, 0x34,
- 0x10, 0x78, 0xd6, 0xdf, 0xea, 0x0c, 0xba, 0x8c, 0x71, 0x11, 0x8b, 0x2f, 0xba, 0x6a, 0xd9, 0xef,
- 0x77, 0xf7, 0xc4, 0xcd, 0x0a, 0xf6, 0x1f, 0xbd, 0x05, 0x95, 0x2f, 0xbb, 0xdd, 0x7e, 0x67, 0xa7,
- 0xf7, 0xbc, 0xcb, 0x4c, 0xb0, 0x88, 0x23, 0x00, 0x75, 0x69, 0xb8, 0xfb, 0x04, 0x77, 0x0f, 0x9e,
- 0x32, 0x33, 0x2b, 0xe2, 0xe0, 0x93, 0x96, 0xdb, 0xea, 0x1d, 0x6c, 0x76, 0xf0, 0x56, 0x77, 0x8b,
- 0x19, 0x58, 0x11, 0x47, 0x00, 0xda, 0xab, 0x83, 0xfd, 0x41, 0x67, 0x87, 0x99, 0x57, 0x11, 0xf3,
- 0x0f, 0xe5, 0x01, 0x94, 0xb8, 0x95, 0x50, 0xbc, 0x61, 0x39, 0x53, 0x5f, 0x44, 0x2a, 0xfc, 0x83,
- 0xca, 0x6d, 0x4f, 0x7d, 0x0a, 0x16, 0xcb, 0x03, 0xfe, 0xa5, 0x10, 0x28, 0xf1, 0x38, 0x15, 0xdd,
- 0x85, 0x12, 0x0d, 0xbd, 0x8d, 0xb1, 0xe8, 0xdd, 0xb5, 0x64, 0x24, 0xbb, 0xc9, 0xb0, 0x58, 0x50,
- 0xa1, 0xf7, 0xe2, 0x27, 0xab, 0xab, 0x49, 0xf2, 0xd8, 0xd9, 0xea, 0x2f, 0x72, 0x50, 0x93, 0xb9,
- 0x50, 0x13, 0x1a, 0xda, 0x96, 0x45, 0x86, 0xbe, 0xea, 0x12, 0xdf, 0x3d, 0x0d, 0x3a, 0x5b, 0x00,
- 0x31, 0x85, 0x51, 0x5b, 0x60, 0xc1, 0x52, 0x78, 0xcc, 0x5f, 0xc4, 0x65, 0x0a, 0xa0, 0x9c, 0xe8,
- 0x04, 0xf7, 0x0d, 0x21, 0x8e, 0x66, 0x1a, 0xc7, 0x44, 0x4d, 0xdc, 0x6c, 0x59, 0x0a, 0x31, 0x3d,
- 0x81, 0x40, 0x5b, 0x70, 0x65, 0x62, 0x58, 0xc6, 0x64, 0x3a, 0x51, 0x43, 0xbd, 0xa5, 0x71, 0x5f,
- 0x54, 0x94, 0x8f, 0xd0, 0x5b, 0x82, 0xaa, 0x23, 0x13, 0x05, 0x5c, 0x94, 0x9f, 0xe7, 0xa1, 0x2a,
- 0x35, 0xef, 0x7f, 0x69, 0x33, 0xd8, 0xe6, 0x0b, 0x19, 0xdb, 0xbe, 0xa1, 0x51, 0xe7, 0x14, 0x09,
- 0xc7, 0x15, 0x11, 0x45, 0xb8, 0xa7, 0x81, 0x98, 0xd1, 0x45, 0x0c, 0xae, 0x90, 0x59, 0x17, 0x31,
- 0xb8, 0x42, 0x86, 0xdf, 0xca, 0x7f, 0xe4, 0xa0, 0x12, 0xae, 0x6b, 0xd2, 0x51, 0x4b, 0x2e, 0x23,
- 0x6a, 0xb9, 0x0c, 0xc0, 0x89, 0xa4, 0x43, 0x68, 0x1e, 0x55, 0xf5, 0x05, 0x8f, 0x89, 0x3f, 0x55,
- 0x75, 0xc3, 0x1b, 0xda, 0xc7, 0xc4, 0x3d, 0x15, 0xfb, 0x13, 0xb5, 0x89, 0x3f, 0xdd, 0x0a, 0x60,
- 0x34, 0x22, 0xa0, 0xb3, 0x2a, 0xed, 0xcf, 0x89, 0xad, 0x07, 0x07, 0xa2, 0x55, 0x01, 0xdb, 0xb5,
- 0x75, 0xba, 0x22, 0x5f, 0x14, 0x91, 0x5c, 0x7c, 0xa6, 0xab, 0x73, 0x68, 0x27, 0xfb, 0xb2, 0x4a,
- 0x29, 0xb8, 0x18, 0x12, 0x5c, 0x56, 0xa1, 0x13, 0xa1, 0x3f, 0x74, 0xd4, 0x89, 0xe7, 0x89, 0x88,
- 0xb6, 0xe4, 0x0f, 0x9d, 0x5d, 0xcf, 0x53, 0x1e, 0x41, 0x55, 0x5a, 0x9b, 0xa1, 0xbb, 0xb0, 0x2c,
- 0x2f, 0xe4, 0xe2, 0xb1, 0xc6, 0x92, 0xb4, 0x70, 0xe3, 0x81, 0x86, 0xf2, 0xef, 0x39, 0x68, 0x24,
- 0x56, 0x67, 0x67, 0x87, 0x40, 0x62, 0x8d, 0x17, 0xa9, 0x58, 0x1d, 0x57, 0x05, 0x8c, 0x0d, 0xdf,
- 0x55, 0xa8, 0x1e, 0x11, 0xd3, 0x21, 0xae, 0x6a, 0x5b, 0x66, 0xd0, 0x6d, 0xc0, 0x41, 0xfb, 0x96,
- 0xc9, 0xa6, 0x34, 0x9d, 0x8c, 0x88, 0xeb, 0x6a, 0x26, 0x67, 0xc2, 0xaf, 0xc9, 0xd4, 0x02, 0x20,
- 0xe3, 0x72, 0x0f, 0x56, 0xd8, 0xe5, 0x12, 0x71, 0x75, 0x4d, 0x0d, 0xe4, 0xe1, 0x9b, 0x27, 0xcb,
- 0x32, 0xae, 0x2b, 0x64, 0x7b, 0x0f, 0x96, 0x4c, 0xdb, 0x1a, 0x9b, 0xec, 0xf2, 0x4a, 0x40, 0x5f,
- 0xe2, 0xd3, 0x6f, 0x88, 0x10, 0xc4, 0xca, 0x47, 0xb0, 0xbe, 0xeb, 0x24, 0xda, 0x2d, 0xfc, 0xc5,
- 0xcc, 0xd6, 0x2b, 0x7f, 0x9b, 0x83, 0xb5, 0x54, 0x29, 0x6e, 0x9d, 0xb3, 0xbb, 0x4c, 0x9e, 0x07,
- 0xf9, 0x46, 0x75, 0x34, 0x73, 0xc4, 0xe7, 0x3a, 0xd1, 0x55, 0xd2, 0x5c, 0xf7, 0x3e, 0x2c, 0x8b,
- 0xcb, 0x2f, 0xae, 0x71, 0xa8, 0x86, 0x6c, 0x8a, 0xc1, 0xbd, 0x68, 0x7d, 0x7f, 0xc4, 0x76, 0x54,
- 0xc2, 0x89, 0xa8, 0x21, 0x91, 0xb3, 0x39, 0x89, 0xf7, 0x57, 0x2d, 0x20, 0x3d, 0xa0, 0x43, 0xfe,
- 0x07, 0x39, 0x58, 0x4a, 0x35, 0x03, 0x7d, 0x37, 0xe1, 0x94, 0xaf, 0x4b, 0xf3, 0x58, 0x76, 0x4f,
- 0x85, 0xfe, 0xf9, 0x41, 0xdc, 0x3f, 0x5f, 0x3b, 0xa3, 0x64, 0xcc, 0x55, 0x77, 0xa0, 0x2e, 0x56,
- 0xf6, 0xa2, 0xeb, 0x67, 0xad, 0x7d, 0xa5, 0xde, 0xcd, 0xc7, 0x87, 0xe4, 0x0f, 0x73, 0x50, 0x13,
- 0x3c, 0xc2, 0x6b, 0x5c, 0xaf, 0xc6, 0x82, 0x2a, 0xac, 0x6f, 0xfb, 0xd4, 0x11, 0x88, 0xcb, 0x7f,
- 0xcc, 0xf4, 0x18, 0xa8, 0xcf, 0x36, 0x2b, 0x6f, 0xc0, 0xa2, 0x20, 0x90, 0x77, 0x20, 0xeb, 0xb8,
- 0xce, 0x69, 0x82, 0xfd, 0xc7, 0x7f, 0xca, 0xc3, 0x86, 0xb0, 0x44, 0x93, 0x5f, 0x63, 0xdd, 0x67,
- 0x91, 0x73, 0x30, 0x0f, 0xdd, 0x01, 0xa4, 0x99, 0x2f, 0xb5, 0x53, 0x8f, 0xc6, 0x7c, 0x8e, 0xe6,
- 0x12, 0x75, 0x12, 0xdd, 0x71, 0xe7, 0x98, 0x4d, 0x8e, 0xd8, 0x25, 0x3a, 0xba, 0x07, 0xab, 0xc6,
- 0xd8, 0xb2, 0x5d, 0x1a, 0x71, 0x32, 0xc9, 0x54, 0x93, 0x58, 0x63, 0xff, 0x28, 0x38, 0x8b, 0xe3,
- 0xc8, 0x8e, 0x47, 0x45, 0xdc, 0x61, 0x18, 0xba, 0x66, 0x08, 0xf6, 0x89, 0xc3, 0x2a, 0x98, 0xc1,
- 0xb3, 0x35, 0x03, 0xd7, 0xae, 0xf5, 0x80, 0x42, 0x54, 0xc5, 0x04, 0x76, 0x7b, 0x74, 0x95, 0x78,
- 0x29, 0x54, 0x3c, 0xd5, 0xb0, 0xb4, 0xa1, 0x4f, 0xbd, 0x1a, 0x2b, 0x1e, 0xec, 0xb8, 0xae, 0x87,
- 0x04, 0x3d, 0x81, 0x67, 0xa5, 0x99, 0xf3, 0xe2, 0x9d, 0xa9, 0x6a, 0xc6, 0xd8, 0x09, 0x36, 0x38,
- 0xc5, 0xb5, 0x7d, 0x63, 0xec, 0xa0, 0xcf, 0xa1, 0x2d, 0x1a, 0x63, 0x91, 0x13, 0x5f, 0x65, 0xfb,
- 0xcd, 0x63, 0x47, 0x9d, 0x10, 0xdf, 0x35, 0x86, 0xc2, 0x46, 0xd7, 0x38, 0xc5, 0x1e, 0x39, 0xf1,
- 0x9f, 0xda, 0x4e, 0x6f, 0xec, 0xec, 0x32, 0xac, 0xf2, 0x8f, 0x79, 0x68, 0x67, 0x76, 0x2b, 0x1f,
- 0xef, 0xff, 0xeb, 0xd5, 0xd7, 0xea, 0xd5, 0x3f, 0xc9, 0xc1, 0x6a, 0x66, 0xaf, 0xa2, 0x47, 0x09,
- 0x3f, 0x70, 0x23, 0xb5, 0x07, 0x98, 0xa5, 0xdd, 0xa1, 0x2f, 0xf8, 0x3c, 0xee, 0x0b, 0xde, 0x3e,
- 0xa7, 0x74, 0xcc, 0x1f, 0xdc, 0x87, 0xb5, 0x67, 0x1e, 0x61, 0x2b, 0x71, 0xc7, 0x64, 0x77, 0xf9,
- 0xbd, 0x73, 0x7d, 0xf2, 0x3d, 0x58, 0x4d, 0x96, 0x39, 0xc7, 0x23, 0x2b, 0x3f, 0x05, 0xa0, 0x2b,
- 0x7e, 0xc1, 0xfa, 0x36, 0x2c, 0xf1, 0xcd, 0x87, 0x89, 0xe0, 0x41, 0x97, 0x78, 0xbc, 0x44, 0x83,
- 0x21, 0x02, 0xde, 0x1d, 0xb6, 0x1d, 0x32, 0xd1, 0x4e, 0x58, 0x48, 0x14, 0x1c, 0x72, 0xb0, 0xa9,
- 0x4b, 0x00, 0x59, 0xed, 0xca, 0x4f, 0xa0, 0xd2, 0x0d, 0x97, 0x51, 0x6f, 0x9c, 0xbb, 0x0a, 0x45,
- 0xca, 0x1d, 0xdd, 0x49, 0x0c, 0xd3, 0x4a, 0x7c, 0xbf, 0x3a, 0x31, 0x2a, 0xb3, 0xef, 0x26, 0x86,
- 0xa2, 0x06, 0x83, 0x70, 0x0f, 0xa0, 0x17, 0xf5, 0x4e, 0x4a, 0xa6, 0x5c, 0x86, 0x4c, 0x1f, 0x42,
- 0xa5, 0x17, 0xb6, 0xf8, 0x42, 0x25, 0x54, 0x28, 0xf6, 0xce, 0x69, 0x45, 0xef, 0x55, 0x5a, 0xd1,
- 0x4b, 0xb6, 0xe2, 0x97, 0x39, 0x68, 0x26, 0xf5, 0x02, 0x7d, 0x96, 0xa8, 0x4d, 0x9a, 0xa8, 0xb2,
- 0xf5, 0x2e, 0xac, 0xf9, 0x93, 0x78, 0xcd, 0x57, 0x67, 0x17, 0x94, 0xa5, 0x40, 0x0a, 0x14, 0xc9,
- 0xe1, 0xd8, 0x49, 0xbf, 0xc7, 0xa1, 0xbd, 0x8e, 0x19, 0x8e, 0xd2, 0x18, 0x94, 0x26, 0xf5, 0xe6,
- 0xa5, 0xc7, 0x68, 0x28, 0x4e, 0x79, 0x2c, 0x66, 0x96, 0x81, 0xe6, 0x8e, 0x89, 0xbf, 0x4b, 0x26,
- 0x87, 0xc4, 0xf5, 0x8e, 0x0c, 0x69, 0x90, 0xe2, 0x11, 0x55, 0x2e, 0x1d, 0x51, 0x29, 0x1d, 0xe1,
- 0x46, 0x93, 0x3c, 0xc2, 0x51, 0x3b, 0x9f, 0x45, 0xe8, 0x34, 0x92, 0x3c, 0xce, 0x75, 0x1a, 0xd9,
- 0x82, 0x5f, 0xd4, 0x69, 0x64, 0x8a, 0x1c, 0x8c, 0xf4, 0x4f, 0xe1, 0xca, 0x8e, 0x6d, 0x8d, 0x77,
- 0x68, 0x04, 0xf4, 0x8a, 0x01, 0xdd, 0x05, 0xc2, 0x59, 0xe5, 0x57, 0x39, 0xb8, 0x3c, 0x8b, 0xff,
- 0x6f, 0x32, 0xf4, 0xbb, 0x0d, 0x4b, 0x6c, 0x03, 0x2b, 0x26, 0x1f, 0x8f, 0x3b, 0x1a, 0x14, 0x81,
- 0xa5, 0x90, 0xfb, 0x21, 0xb4, 0x53, 0xb4, 0xae, 0x4a, 0x4e, 0x1c, 0xc3, 0x0d, 0x43, 0xe6, 0xf5,
- 0x44, 0x21, 0xb7, 0xcb, 0xd1, 0xca, 0x9f, 0xe6, 0xa0, 0x35, 0xab, 0x81, 0xe8, 0x07, 0x89, 0x71,
- 0x95, 0x5e, 0x26, 0x9c, 0xdd, 0xe9, 0xe1, 0xd0, 0x3e, 0x8a, 0x0f, 0xed, 0xcd, 0xf3, 0x19, 0xc4,
- 0x46, 0xf7, 0x9f, 0x8b, 0xb0, 0x20, 0xe2, 0x3b, 0xf4, 0x25, 0x2c, 0x4f, 0x1c, 0x35, 0x75, 0xd8,
- 0xc4, 0x25, 0xdb, 0x38, 0x23, 0xe8, 0xc4, 0x4b, 0x93, 0x54, 0xb8, 0xfb, 0x41, 0xd8, 0x32, 0x2e,
- 0xd8, 0x7a, 0xea, 0xb4, 0x29, 0xd1, 0x90, 0xe4, 0x49, 0x64, 0xe1, 0xc2, 0x27, 0x91, 0x3f, 0x82,
- 0xf5, 0x60, 0x49, 0x26, 0x26, 0x3f, 0xd5, 0x76, 0x82, 0x53, 0xe4, 0x84, 0x3b, 0xc9, 0x9c, 0x24,
- 0xf1, 0xaa, 0x9b, 0x39, 0x55, 0x3f, 0x05, 0x34, 0xf5, 0x48, 0x34, 0xb5, 0x70, 0x7f, 0x3b, 0x9f,
- 0x3c, 0x7f, 0x4a, 0xba, 0x28, 0xdc, 0x9c, 0x26, 0x3d, 0x63, 0xea, 0x8c, 0xa0, 0x94, 0x6c, 0xdd,
- 0xec, 0x33, 0x82, 0xb0, 0x79, 0x3e, 0x33, 0x53, 0x75, 0x12, 0xda, 0xa9, 0x38, 0xa8, 0xbc, 0x7a,
- 0x8e, 0x39, 0x8b, 0xe6, 0xa5, 0x9c, 0x8a, 0x06, 0x1b, 0x74, 0xdd, 0xa6, 0xf2, 0x15, 0x5d, 0x6a,
- 0xdc, 0xf9, 0xc1, 0xa6, 0x72, 0xbe, 0x42, 0xe1, 0x96, 0x39, 0x03, 0xa3, 0x4c, 0xa1, 0xc4, 0x1b,
- 0x86, 0x36, 0xa0, 0x62, 0x38, 0x6a, 0xec, 0x4a, 0x43, 0xd9, 0x70, 0x04, 0xf2, 0x1d, 0x68, 0x4c,
- 0x34, 0xef, 0x1b, 0x11, 0x2c, 0xaa, 0x13, 0xc3, 0x12, 0xae, 0xa2, 0x4e, 0xc1, 0x3c, 0x50, 0xdc,
- 0x35, 0xac, 0x14, 0x9d, 0x76, 0x22, 0x96, 0x13, 0x32, 0x9d, 0x76, 0xa2, 0xfc, 0x71, 0x0e, 0x20,
- 0xba, 0x4f, 0xfa, 0x6b, 0x5e, 0xfa, 0xa5, 0x30, 0xd3, 0xf0, 0x7c, 0xf6, 0x6c, 0xa9, 0x82, 0xd9,
- 0x7f, 0x76, 0x8f, 0x31, 0x5a, 0xad, 0x24, 0xef, 0x31, 0x32, 0x0c, 0x0e, 0x29, 0x94, 0x6d, 0x28,
- 0xef, 0x6a, 0xfe, 0xf0, 0x88, 0x0a, 0x73, 0x33, 0x26, 0x8c, 0x34, 0xc7, 0x32, 0x8a, 0x73, 0xee,
- 0x1f, 0x3f, 0x87, 0x5a, 0x2c, 0x78, 0xbe, 0x1b, 0x63, 0x26, 0xe9, 0xa4, 0x4c, 0x25, 0xf1, 0x5c,
- 0x83, 0x92, 0x14, 0x90, 0xd7, 0xb1, 0xf8, 0x52, 0xfe, 0xad, 0x08, 0xb0, 0x69, 0x5b, 0xba, 0xc1,
- 0x15, 0xff, 0x1e, 0x88, 0x17, 0x2f, 0x6a, 0x74, 0x89, 0x17, 0x25, 0x24, 0x3d, 0x20, 0x3e, 0xae,
- 0x70, 0x2a, 0xda, 0xac, 0x4f, 0xa0, 0x16, 0x9e, 0x39, 0xd0, 0x42, 0xf9, 0x99, 0x85, 0xc2, 0xab,
- 0x34, 0xb4, 0xd8, 0xf7, 0x60, 0x31, 0xb1, 0x52, 0x28, 0x24, 0xb7, 0x2c, 0xe5, 0xa6, 0xe0, 0x9a,
- 0x26, 0x37, 0xff, 0x3e, 0x54, 0x83, 0xd2, 0xb4, 0xce, 0xe2, 0x6c, 0x41, 0x79, 0x31, 0x5a, 0xe3,
- 0xa7, 0xe1, 0x53, 0x3e, 0xff, 0x94, 0x95, 0x9a, 0x9f, 0x59, 0xaa, 0x16, 0x12, 0xd2, 0x82, 0x5f,
- 0xc0, 0x12, 0x5d, 0x06, 0xc4, 0x0b, 0x97, 0x66, 0x16, 0x6e, 0x90, 0x13, 0x7f, 0x53, 0x2e, 0x7f,
- 0x15, 0xaa, 0xae, 0xf3, 0x8d, 0x41, 0xed, 0x6b, 0x6a, 0xfa, 0xcc, 0x76, 0xe7, 0x31, 0xb8, 0xfc,
- 0xb9, 0xc1, 0xd4, 0xf4, 0xd1, 0x23, 0x80, 0xe8, 0x0d, 0x81, 0x38, 0x32, 0x95, 0x4e, 0x04, 0xa2,
- 0xf1, 0x11, 0x66, 0x4e, 0x87, 0xb5, 0x12, 0x3e, 0x31, 0x40, 0x8f, 0x61, 0xd9, 0xa4, 0x26, 0x9e,
- 0x90, 0xb0, 0x32, 0x53, 0xc2, 0x25, 0x46, 0x2e, 0xcb, 0xa8, 0x1c, 0x41, 0x25, 0xe4, 0x8d, 0x96,
- 0xa1, 0x81, 0xf7, 0x9f, 0x0d, 0xba, 0xea, 0xe0, 0xeb, 0x7e, 0x57, 0x15, 0x87, 0x7c, 0xeb, 0xb0,
- 0x2c, 0x01, 0x7b, 0x7b, 0x83, 0x2e, 0xde, 0xeb, 0xec, 0x34, 0x73, 0x09, 0x44, 0xf7, 0x85, 0x40,
- 0xe4, 0xd1, 0x0a, 0x34, 0x25, 0xc4, 0xce, 0xfe, 0x66, 0x67, 0xa7, 0x59, 0x50, 0x46, 0xd0, 0x08,
- 0x6b, 0xee, 0xf0, 0x47, 0xa9, 0xf7, 0x62, 0xca, 0x7c, 0x59, 0x6e, 0x79, 0x8c, 0x50, 0xd2, 0xe7,
- 0x6b, 0x50, 0x0d, 0x5a, 0x6b, 0x84, 0xcf, 0x2e, 0x64, 0x90, 0xb2, 0x07, 0x95, 0x5d, 0xa2, 0x8b,
- 0x1a, 0xde, 0x8b, 0xd5, 0xb0, 0x2e, 0x9f, 0x24, 0xe8, 0x29, 0xde, 0x2b, 0x30, 0x7f, 0xac, 0x99,
- 0xd3, 0xe0, 0x55, 0x1a, 0xff, 0x50, 0x54, 0x68, 0x74, 0xbc, 0xbe, 0x4b, 0x1c, 0x62, 0x05, 0x5c,
- 0x9b, 0x50, 0xd0, 0x3c, 0x4b, 0x44, 0x74, 0xf4, 0x2f, 0x35, 0x33, 0x4a, 0xa1, 0x85, 0x5b, 0xf4,
- 0xfc, 0x0b, 0x29, 0x50, 0xa7, 0x13, 0x8a, 0x49, 0x46, 0xbe, 0x3a, 0xb1, 0x3d, 0x5f, 0xc4, 0x25,
- 0xd5, 0xa9, 0x47, 0x76, 0xc8, 0xc8, 0xdf, 0xb5, 0xd9, 0x55, 0xc5, 0xba, 0xb8, 0x1a, 0x26, 0xd8,
- 0x9f, 0xf9, 0xc2, 0xc7, 0x23, 0xe6, 0x48, 0xc4, 0x3e, 0xec, 0xbf, 0x72, 0x13, 0x1a, 0x3b, 0x6c,
- 0x93, 0xd5, 0x25, 0x23, 0xc1, 0x20, 0x6c, 0x88, 0x38, 0x46, 0xe0, 0x0d, 0xf9, 0x87, 0x02, 0x2c,
- 0x70, 0x02, 0x2f, 0xba, 0x9d, 0xa2, 0xf1, 0xc7, 0xc7, 0x29, 0x47, 0xc9, 0x94, 0x82, 0x53, 0x8b,
- 0xdb, 0x29, 0x82, 0xf7, 0xa7, 0x50, 0x89, 0x4e, 0xd8, 0xf2, 0xc9, 0x6b, 0x29, 0x89, 0x81, 0xc3,
- 0x11, 0x2d, 0xba, 0x01, 0x85, 0x89, 0x08, 0xcc, 0x62, 0x2b, 0x8d, 0x70, 0x24, 0x30, 0xc5, 0xa3,
- 0xcf, 0x00, 0xa8, 0x85, 0xf3, 0xfe, 0x16, 0x06, 0x7e, 0x29, 0xe6, 0x1b, 0xe4, 0xa1, 0x60, 0x76,
- 0xce, 0x01, 0xe8, 0x0b, 0xa8, 0xc7, 0xcc, 0x55, 0xd8, 0xf9, 0x19, 0xd2, 0xd5, 0x64, 0x8b, 0x45,
- 0xf7, 0x60, 0x41, 0xdc, 0xdd, 0x13, 0x46, 0x2e, 0xa9, 0x4b, 0x6c, 0x80, 0x70, 0x40, 0x47, 0x85,
- 0x15, 0x5b, 0xde, 0x2e, 0x19, 0x89, 0xc9, 0xf9, 0x92, 0x3c, 0x7f, 0xc6, 0xc6, 0x25, 0xd8, 0x0d,
- 0x77, 0xc9, 0x08, 0x3d, 0x86, 0x46, 0xc2, 0x76, 0xc5, 0xf4, 0x7b, 0x86, 0xb8, 0x8b, 0x71, 0xf3,
- 0x55, 0x7e, 0x96, 0x83, 0x4a, 0x78, 0xbf, 0x3a, 0x9c, 0x3d, 0x72, 0xd2, 0x44, 0xf6, 0x31, 0xc0,
- 0x30, 0x74, 0x22, 0x62, 0xb4, 0x56, 0xb2, 0x1c, 0x0c, 0x96, 0xe8, 0xd0, 0x7b, 0xb0, 0xc0, 0xd5,
- 0xc2, 0x13, 0xa3, 0x25, 0x5f, 0x1c, 0xe2, 0x08, 0x1c, 0x50, 0x28, 0x5f, 0x41, 0x49, 0x44, 0x65,
- 0x59, 0x02, 0xc4, 0x5f, 0x68, 0xe4, 0x2f, 0xf6, 0x42, 0xe3, 0x5f, 0x72, 0xd0, 0x4c, 0x5e, 0xf1,
- 0x41, 0xb7, 0x62, 0x96, 0xbc, 0x92, 0xbc, 0x0c, 0x24, 0x99, 0xb1, 0xfc, 0x78, 0x39, 0x7f, 0x81,
- 0xc7, 0xcb, 0x19, 0x09, 0x25, 0x62, 0xaf, 0x16, 0x8a, 0xe7, 0xbd, 0x5a, 0x40, 0x1f, 0xc0, 0x82,
- 0x4e, 0x46, 0x1a, 0x75, 0xf2, 0xf3, 0x67, 0x19, 0x52, 0x40, 0xa5, 0xfc, 0x51, 0x0e, 0x0a, 0xd8,
- 0xd6, 0xd0, 0x22, 0xe4, 0xb5, 0x60, 0x3d, 0x9f, 0xd7, 0x3c, 0xf4, 0x16, 0x88, 0x09, 0xd6, 0x24,
- 0x41, 0x40, 0x14, 0x01, 0xa8, 0x93, 0x99, 0x68, 0x0c, 0x25, 0x6e, 0x52, 0xf2, 0x2f, 0xe9, 0x9a,
- 0x60, 0x31, 0x76, 0x73, 0x34, 0xb8, 0xb0, 0x37, 0x7f, 0xf6, 0x3b, 0x4b, 0xe5, 0x26, 0xbf, 0x2d,
- 0x69, 0x6b, 0xe7, 0xbd, 0x9d, 0xe4, 0xcf, 0xc4, 0x18, 0x61, 0xf4, 0x4c, 0xcc, 0xb5, 0xb5, 0x8c,
- 0x67, 0x62, 0x94, 0x88, 0xa1, 0x14, 0x0f, 0x0a, 0xcf, 0xdd, 0x51, 0xa6, 0x76, 0x2c, 0x42, 0xde,
- 0xe5, 0x0b, 0xb9, 0x1a, 0xce, 0xbb, 0x3a, 0x0b, 0x19, 0xf9, 0xcd, 0x2f, 0x97, 0x07, 0x5f, 0x35,
- 0x5c, 0xe6, 0x00, 0xcc, 0x1e, 0xcf, 0x8b, 0x7b, 0x65, 0xae, 0xcf, 0xc6, 0xa4, 0x86, 0xcb, 0x1c,
- 0x80, 0x7d, 0x71, 0x45, 0x87, 0xdf, 0x69, 0xca, 0x1b, 0xba, 0xf2, 0xcb, 0x1c, 0x94, 0xf8, 0x95,
- 0xec, 0x54, 0x1f, 0x6f, 0x40, 0x25, 0xda, 0x6d, 0x14, 0x0f, 0xed, 0xdd, 0x60, 0x7b, 0xf1, 0x2a,
- 0x54, 0x69, 0xb4, 0x47, 0x2c, 0x7e, 0x6a, 0x54, 0xe0, 0x53, 0x36, 0x07, 0xb1, 0x53, 0xa3, 0x77,
- 0xa1, 0x29, 0x08, 0x84, 0x4f, 0x16, 0x0a, 0x52, 0xc1, 0x0d, 0x0e, 0xef, 0x04, 0xe0, 0xd8, 0x2d,
- 0xcc, 0xf9, 0xc4, 0x2d, 0xcc, 0x3b, 0x99, 0x0b, 0x0d, 0x71, 0xb6, 0x92, 0x5c, 0x4c, 0x28, 0x7f,
- 0x97, 0x83, 0x0a, 0xbb, 0x6e, 0xda, 0xb3, 0x46, 0xf6, 0x6f, 0xe4, 0x32, 0xee, 0x4d, 0x68, 0x58,
- 0xd3, 0x89, 0x2a, 0xdd, 0xb2, 0x15, 0x67, 0x91, 0x8b, 0xd6, 0x74, 0x22, 0xdf, 0x52, 0xbe, 0x04,
- 0x65, 0x4b, 0x6c, 0x44, 0x05, 0x47, 0xdf, 0x16, 0xdf, 0x83, 0xa2, 0x6b, 0x7f, 0x8a, 0x0a, 0xef,
- 0x21, 0xf0, 0xc3, 0xc6, 0xaa, 0x35, 0x9d, 0x74, 0x04, 0x48, 0xf9, 0x1e, 0xbb, 0x95, 0x8f, 0x8d,
- 0x43, 0xda, 0x90, 0x40, 0xdb, 0x82, 0xfb, 0x9a, 0xa9, 0x47, 0x49, 0x61, 0x93, 0xf9, 0x7d, 0x4d,
- 0xe5, 0x11, 0xcb, 0x73, 0x13, 0x96, 0x16, 0x2a, 0x78, 0xd1, 0xe2, 0xb7, 0x37, 0xa1, 0x1c, 0xf4,
- 0x10, 0x02, 0x28, 0x6d, 0xef, 0xec, 0x3f, 0xee, 0xec, 0x34, 0xe7, 0x50, 0x05, 0xe6, 0x79, 0x8c,
- 0xc2, 0xee, 0x2f, 0x74, 0xb6, 0x7e, 0xa8, 0xf6, 0xf6, 0x9a, 0x79, 0x54, 0x85, 0x05, 0xfa, 0x7f,
- 0xff, 0xd9, 0xa0, 0x59, 0x40, 0x0b, 0x50, 0x78, 0x8e, 0x9f, 0x34, 0x8b, 0xb7, 0x7d, 0xa8, 0x4a,
- 0x6b, 0x08, 0x76, 0xe1, 0x01, 0x77, 0x9f, 0xf4, 0x5e, 0x34, 0xe7, 0x50, 0x0d, 0xca, 0x7b, 0xdd,
- 0xde, 0xf6, 0xd3, 0xc7, 0xfb, 0xb8, 0x99, 0xa3, 0x25, 0x06, 0x9d, 0x6d, 0xc1, 0xe7, 0x40, 0xed,
- 0x77, 0x06, 0x4f, 0x9b, 0x05, 0x54, 0x87, 0xca, 0xe6, 0xfe, 0xee, 0xee, 0xb3, 0xbd, 0xde, 0xe0,
- 0xeb, 0x66, 0x11, 0x2d, 0x41, 0xbd, 0xfb, 0x62, 0xa0, 0x46, 0xa0, 0x79, 0x1a, 0x83, 0xed, 0x74,
- 0xf0, 0x76, 0x57, 0x02, 0x96, 0x6e, 0xbf, 0x0b, 0x95, 0x70, 0xb1, 0xc0, 0x6e, 0x5d, 0xed, 0x7d,
- 0x2d, 0x5f, 0xbf, 0x02, 0x28, 0xf5, 0xf6, 0x9e, 0x77, 0xf1, 0xa0, 0x99, 0xbf, 0x7d, 0x1b, 0x9a,
- 0xc9, 0xa5, 0x00, 0x2a, 0x41, 0xbe, 0xfb, 0x55, 0x73, 0x8e, 0xfe, 0x6e, 0x77, 0x9b, 0x39, 0xfa,
- 0xbb, 0xd3, 0x6d, 0xe6, 0x6f, 0x7f, 0x20, 0x4e, 0x3a, 0xc5, 0xd4, 0x1e, 0x5d, 0xec, 0xa2, 0xfd,
- 0xb0, 0xb9, 0xd9, 0xed, 0x0f, 0x38, 0x73, 0xdc, 0xfd, 0x61, 0x77, 0x93, 0x32, 0x7f, 0x06, 0xcb,
- 0x19, 0xa1, 0x19, 0x6d, 0x46, 0x28, 0xad, 0xda, 0xd9, 0xda, 0x6a, 0xce, 0xd1, 0x18, 0x30, 0x02,
- 0xe1, 0xee, 0xee, 0xfe, 0x73, 0x5a, 0xf1, 0x2a, 0x2c, 0xc9, 0x50, 0x71, 0x63, 0xec, 0xf6, 0xfb,
- 0x50, 0x8f, 0xc5, 0x63, 0xb4, 0xcf, 0x76, 0xbb, 0x5b, 0xea, 0xee, 0x3e, 0x65, 0xd5, 0x80, 0x2a,
- 0xfd, 0x08, 0xc8, 0x73, 0xb7, 0xef, 0x00, 0x44, 0x4e, 0x3f, 0xcc, 0x6c, 0x42, 0x3b, 0x61, 0xb7,
- 0xbf, 0x8f, 0x85, 0xcc, 0xdd, 0x17, 0xec, 0x7f, 0xfe, 0xfe, 0xbf, 0x5e, 0x85, 0xf2, 0x36, 0xd5,
- 0x89, 0x8e, 0x63, 0xa0, 0x1d, 0xa8, 0x4a, 0xef, 0x32, 0xd0, 0x5b, 0xb1, 0xa9, 0x28, 0xf1, 0xdc,
- 0xa3, 0x7d, 0x79, 0x06, 0x56, 0x5c, 0xb7, 0x9e, 0x43, 0x3d, 0x80, 0xe8, 0xe5, 0x06, 0xda, 0x90,
- 0xc9, 0x13, 0x8f, 0x3c, 0xda, 0x6f, 0x65, 0x23, 0x43, 0x56, 0x4f, 0xa0, 0x12, 0xbe, 0x57, 0x41,
- 0xd2, 0xb2, 0x2e, 0xf9, 0xb0, 0xa5, 0xbd, 0x91, 0x89, 0x0b, 0xf9, 0xec, 0x40, 0x55, 0x4a, 0xb4,
- 0x23, 0x37, 0x30, 0x9d, 0xb9, 0x47, 0x6e, 0x60, 0x56, 0x76, 0x9e, 0x39, 0xf4, 0x0c, 0x16, 0xe3,
- 0x29, 0x76, 0xd0, 0x55, 0x79, 0x2d, 0x9d, 0x91, 0xb9, 0xa7, 0x7d, 0x6d, 0x36, 0x81, 0x2c, 0xa4,
- 0x94, 0x54, 0x4a, 0x16, 0x32, 0x9d, 0xc7, 0x4a, 0x16, 0x32, 0x23, 0x13, 0x95, 0x32, 0x87, 0x30,
- 0xd4, 0x63, 0xb9, 0x6b, 0xd0, 0x95, 0x98, 0x4b, 0x4c, 0x73, 0xbc, 0x3a, 0x13, 0x1f, 0xf2, 0xfc,
- 0xff, 0xb0, 0x94, 0xca, 0x89, 0x83, 0x94, 0xf3, 0x73, 0xf3, 0xb4, 0xbf, 0x73, 0x26, 0x4d, 0xc8,
- 0xff, 0xff, 0x41, 0x33, 0x99, 0xfb, 0x06, 0x49, 0xe7, 0xc3, 0x33, 0x52, 0xee, 0xb4, 0x95, 0xb3,
- 0x48, 0xe4, 0x51, 0x8b, 0x67, 0xc2, 0x91, 0x47, 0x2d, 0x33, 0xad, 0x8e, 0x3c, 0x6a, 0x33, 0x92,
- 0xe8, 0xcc, 0xa1, 0x17, 0xd0, 0x48, 0x24, 0xbb, 0x41, 0xf2, 0x60, 0x67, 0x66, 0xd8, 0x69, 0x5f,
- 0x3f, 0x83, 0x22, 0xe4, 0xfc, 0x08, 0x4a, 0xdc, 0xb1, 0xa3, 0xf5, 0xd8, 0x60, 0x47, 0x4f, 0x29,
- 0xda, 0xad, 0x34, 0x42, 0x56, 0x27, 0xe9, 0x39, 0x84, 0xac, 0x4e, 0xe9, 0x37, 0x19, 0xb2, 0x3a,
- 0x65, 0xbd, 0xa1, 0x98, 0x43, 0x3f, 0x80, 0x05, 0x91, 0xce, 0x0b, 0xb5, 0x62, 0xf6, 0x21, 0xa5,
- 0xed, 0x6a, 0x5f, 0xca, 0xc0, 0xc8, 0x6e, 0x21, 0x4a, 0x9e, 0x25, 0xbb, 0x85, 0x54, 0xfa, 0x2f,
- 0xd9, 0x2d, 0x64, 0xe4, 0xdb, 0x9a, 0x43, 0x5b, 0x00, 0x51, 0xba, 0x17, 0x99, 0x55, 0x2a, 0x09,
- 0x4c, 0x3b, 0xfb, 0xe5, 0x8c, 0x32, 0xf7, 0x61, 0x0e, 0x3d, 0x0c, 0xd3, 0xd9, 0x44, 0x97, 0x58,
- 0xa5, 0x89, 0x32, 0xcc, 0xd1, 0xd6, 0x4e, 0x24, 0xda, 0x62, 0x85, 0x9f, 0x40, 0x25, 0xcc, 0x2f,
- 0x24, 0x7b, 0xa6, 0x64, 0x76, 0x23, 0xd9, 0x33, 0xa5, 0x13, 0x12, 0xf1, 0x5e, 0x09, 0xb3, 0x0f,
- 0xc5, 0x7a, 0x25, 0x99, 0xa8, 0x28, 0xd6, 0x2b, 0xe9, 0x84, 0x45, 0x73, 0xe8, 0x29, 0x54, 0xc2,
- 0x8c, 0x41, 0xb2, 0x48, 0xc9, 0x3c, 0x46, 0xb2, 0x48, 0xe9, 0x14, 0x43, 0x73, 0xb7, 0x72, 0x54,
- 0xf3, 0x78, 0xde, 0x1e, 0x59, 0xf3, 0x62, 0x29, 0x82, 0xda, 0xad, 0x34, 0x42, 0xf6, 0xda, 0x61,
- 0x8a, 0x1e, 0x59, 0x90, 0x64, 0xe6, 0x9f, 0xf6, 0x46, 0x26, 0x4e, 0xd6, 0x39, 0x91, 0x94, 0x04,
- 0x25, 0x14, 0x3d, 0xca, 0x66, 0x21, 0xeb, 0x5c, 0x22, 0x83, 0x49, 0xa8, 0xb5, 0x49, 0x0e, 0xf1,
- 0x64, 0x25, 0x09, 0xad, 0x4d, 0x70, 0x08, 0xb5, 0x96, 0x31, 0x49, 0x09, 0x2c, 0xf3, 0x79, 0x2b,
- 0x1b, 0x29, 0xb3, 0x8a, 0xf2, 0x85, 0xa0, 0x94, 0x5e, 0xcc, 0x60, 0x95, 0x91, 0x62, 0x84, 0xd9,
- 0xb6, 0x94, 0x34, 0x04, 0xa5, 0x35, 0x43, 0x66, 0x76, 0x79, 0x06, 0x56, 0x1e, 0xaf, 0x30, 0xe5,
- 0x87, 0x3c, 0x5e, 0xc9, 0xcc, 0x21, 0xf2, 0x78, 0xa5, 0x73, 0x84, 0xb0, 0x29, 0x27, 0x96, 0x3e,
- 0x44, 0x9e, 0x72, 0xb2, 0x32, 0x91, 0xc8, 0x53, 0x4e, 0x76, 0xde, 0x91, 0xd0, 0x09, 0xda, 0x5a,
- 0xd2, 0x09, 0x86, 0xeb, 0xb2, 0xa4, 0x13, 0x8c, 0xd6, 0x61, 0xbc, 0xa3, 0xa4, 0x54, 0x1f, 0x28,
- 0xd5, 0xaf, 0x72, 0x3a, 0x13, 0xb9, 0xa3, 0xb2, 0xf2, 0x83, 0xcc, 0x09, 0xbb, 0xa0, 0xeb, 0xb6,
- 0xb8, 0x5d, 0x44, 0x69, 0x3a, 0x12, 0x76, 0x21, 0xa7, 0xe2, 0x90, 0xec, 0x82, 0x72, 0x48, 0xd9,
- 0x85, 0xc4, 0x64, 0x23, 0x13, 0x97, 0xe8, 0x93, 0x84, 0x18, 0xb1, 0xd4, 0x25, 0x89, 0x3e, 0x89,
- 0x17, 0xc7, 0x6c, 0x61, 0x2b, 0x9d, 0x0b, 0x5c, 0x89, 0x11, 0xa7, 0x92, 0x58, 0xc8, 0xc3, 0x94,
- 0x99, 0xf5, 0x83, 0xf3, 0x8c, 0x65, 0xe3, 0x90, 0x79, 0x66, 0xa5, 0xf9, 0x90, 0x79, 0x66, 0xa7,
- 0xf1, 0x60, 0xd1, 0x40, 0x32, 0xe7, 0x86, 0x1c, 0x0d, 0xcc, 0x48, 0xf2, 0x21, 0x47, 0x03, 0x33,
- 0x53, 0x76, 0xb0, 0x50, 0x26, 0x95, 0x70, 0x43, 0x0e, 0x65, 0x66, 0x65, 0xf4, 0x90, 0x43, 0x99,
- 0xd9, 0x19, 0x3b, 0xe6, 0xd0, 0x3e, 0xd4, 0xe4, 0xe4, 0x1c, 0x28, 0x1e, 0xaf, 0x25, 0xf3, 0x50,
- 0xb4, 0xaf, 0xcc, 0x42, 0xcb, 0x0c, 0xe5, 0xb4, 0x1a, 0x28, 0x1e, 0xa5, 0x9e, 0xc5, 0x30, 0x33,
- 0x1b, 0x07, 0x0f, 0x5c, 0xe2, 0x09, 0x33, 0x50, 0x2a, 0x4a, 0x4d, 0xb1, 0xbd, 0x7e, 0x06, 0x85,
- 0x3c, 0x70, 0xc9, 0x0c, 0x19, 0xf2, 0xc0, 0xcd, 0xc8, 0xc5, 0xd1, 0x56, 0xce, 0x22, 0x49, 0x2c,
- 0x09, 0xc4, 0xe6, 0x5a, 0x7c, 0x49, 0x10, 0xcb, 0xf7, 0x90, 0x58, 0x12, 0x24, 0x92, 0x2b, 0x30,
- 0x3e, 0x61, 0x3e, 0x01, 0x99, 0x4f, 0x32, 0xd1, 0x86, 0xcc, 0x27, 0x9d, 0x0a, 0x83, 0x8d, 0x8b,
- 0x9c, 0x09, 0x40, 0x1e, 0x97, 0x8c, 0x1c, 0x19, 0xf2, 0xb8, 0x64, 0xa6, 0xaf, 0x10, 0x81, 0xbb,
- 0xf4, 0xb4, 0x3f, 0x1e, 0xb8, 0xa7, 0x13, 0x5b, 0xc4, 0x03, 0xf7, 0xac, 0x4c, 0x12, 0x73, 0x48,
- 0x67, 0x19, 0x64, 0x52, 0xbb, 0x87, 0x6f, 0x67, 0x74, 0x51, 0x2a, 0x4f, 0x41, 0xfb, 0xc6, 0x39,
- 0x54, 0x72, 0x2d, 0x19, 0x29, 0x1a, 0xe4, 0x5a, 0x66, 0xe7, 0x86, 0x90, 0x6b, 0x39, 0x2b, 0xcf,
- 0xc3, 0x1c, 0x9a, 0x04, 0x79, 0x64, 0x52, 0x15, 0xdd, 0xcc, 0xee, 0xdb, 0x74, 0x5d, 0xb7, 0xce,
- 0x27, 0x0c, 0xab, 0x73, 0xc2, 0xe4, 0x31, 0xe9, 0xcd, 0xd7, 0x19, 0x1d, 0x9f, 0xae, 0xf0, 0xdd,
- 0x0b, 0x50, 0xca, 0x71, 0x42, 0xb4, 0xa1, 0x83, 0x36, 0x92, 0x21, 0xbe, 0xb4, 0x49, 0xd4, 0x7e,
- 0x2b, 0x1b, 0x19, 0xb0, 0x3a, 0x2c, 0xb1, 0xa4, 0xc8, 0x1f, 0xfd, 0x57, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x0c, 0xb2, 0x36, 0x62, 0x23, 0x59, 0x00, 0x00,
+ // 5779 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x3c, 0xcb, 0x72, 0x1b, 0x49,
+ 0x72, 0xc4, 0x83, 0x20, 0x90, 0x78, 0xb2, 0xf8, 0x82, 0xa0, 0x77, 0xef, 0x6a, 0x44, 0x69, 0x67,
+ 0x38, 0x23, 0xcd, 0xac, 0x66, 0xbd, 0xda, 0x99, 0x5d, 0x88, 0x84, 0x28, 0xec, 0xf0, 0x81, 0x29,
+ 0x42, 0x5a, 0x69, 0xfc, 0x68, 0x37, 0xd1, 0x05, 0xb0, 0x3d, 0x8d, 0xee, 0x9e, 0xee, 0x06, 0x45,
+ 0x86, 0x23, 0xec, 0x88, 0xf5, 0xd1, 0xe1, 0x3f, 0x70, 0x84, 0xef, 0x1b, 0xf6, 0xc1, 0x27, 0x47,
+ 0xf8, 0xec, 0x75, 0x38, 0x62, 0x23, 0xfc, 0x09, 0xf6, 0xc1, 0x1f, 0xe0, 0xab, 0x0f, 0x3e, 0x38,
+ 0xea, 0xd1, 0xdd, 0xd5, 0x0f, 0x50, 0x94, 0x56, 0x6b, 0x87, 0x4f, 0x44, 0x67, 0x66, 0x65, 0x65,
+ 0x55, 0x65, 0x66, 0x65, 0x65, 0x55, 0x12, 0xaa, 0x13, 0xfb, 0x78, 0xe2, 0x6c, 0x39, 0xae, 0xed,
+ 0xdb, 0xa8, 0xcc, 0x3e, 0x34, 0xc7, 0x50, 0xbe, 0x01, 0xb4, 0x4b, 0xfc, 0x03, 0x62, 0x4c, 0x4e,
+ 0x8e, 0x6d, 0x17, 0x93, 0xef, 0x66, 0xc4, 0xf3, 0xd1, 0x7d, 0x68, 0x11, 0x4b, 0x3b, 0x36, 0x49,
+ 0x57, 0x3f, 0x25, 0xae, 0x6f, 0x78, 0x44, 0x6f, 0xe7, 0x6e, 0xe5, 0x36, 0xcb, 0x38, 0x05, 0x47,
+ 0x6d, 0x58, 0xd2, 0x74, 0xdd, 0x25, 0x9e, 0xd7, 0xce, 0xdf, 0xca, 0x6d, 0x56, 0x70, 0xf0, 0xa9,
+ 0x3c, 0x86, 0x95, 0x18, 0x6f, 0xcf, 0xb1, 0x2d, 0x8f, 0xa0, 0xef, 0xc3, 0xa2, 0x43, 0x88, 0xeb,
+ 0xb5, 0x73, 0xb7, 0x0a, 0x9b, 0xd5, 0x87, 0x8d, 0xad, 0x40, 0x98, 0xad, 0x01, 0x21, 0x2e, 0xe6,
+ 0x48, 0x65, 0x02, 0x95, 0xae, 0x3b, 0x99, 0x4d, 0x89, 0xe5, 0x7b, 0x68, 0x0b, 0xca, 0x2e, 0xf1,
+ 0xec, 0x99, 0x3b, 0x22, 0x4c, 0x8e, 0xc6, 0x43, 0x14, 0xb5, 0xc2, 0x02, 0x83, 0x43, 0x1a, 0xb4,
+ 0x0e, 0xa5, 0xb1, 0x36, 0x35, 0xcc, 0x73, 0x26, 0x52, 0x1d, 0x8b, 0x2f, 0x84, 0xa0, 0x68, 0x69,
+ 0x53, 0xd2, 0x2e, 0x30, 0x41, 0xd9, 0x6f, 0xe5, 0x4f, 0xa1, 0xd1, 0xd5, 0xf5, 0x81, 0xe6, 0x9f,
+ 0x04, 0xa3, 0x7f, 0xdb, 0xde, 0xd6, 0xa0, 0x74, 0xea, 0x8e, 0x55, 0x43, 0x17, 0x13, 0xb0, 0x78,
+ 0xea, 0x8e, 0xfb, 0x3a, 0x52, 0xa0, 0xe8, 0x68, 0xfe, 0x09, 0xeb, 0x2c, 0x3e, 0x4c, 0xda, 0x17,
+ 0xc3, 0x29, 0x77, 0xa0, 0x19, 0x76, 0x2e, 0xa6, 0x07, 0x41, 0x71, 0x36, 0x33, 0xf8, 0x7c, 0xd7,
+ 0x30, 0xfb, 0xad, 0xfc, 0x2a, 0x07, 0xcb, 0x3b, 0xc4, 0x24, 0x3e, 0xf9, 0x1d, 0xc8, 0x19, 0x4d,
+ 0x56, 0x21, 0x36, 0x59, 0x81, 0xfc, 0xc5, 0xf9, 0xf2, 0x87, 0xc2, 0x2e, 0x4a, 0xc2, 0xae, 0x02,
+ 0x92, 0x65, 0xe5, 0xc3, 0x52, 0x7e, 0x04, 0xa8, 0xab, 0xeb, 0x49, 0x45, 0xa3, 0x7d, 0x10, 0xe2,
+ 0x32, 0xf1, 0xd3, 0xaa, 0xc0, 0x70, 0xca, 0x1a, 0xac, 0xc4, 0x5a, 0x0a, 0x86, 0x8f, 0x61, 0x8d,
+ 0x77, 0xf3, 0x2e, 0x3c, 0xdb, 0xb0, 0x9e, 0x6c, 0x2c, 0xd8, 0xbe, 0x80, 0x55, 0x4c, 0xbc, 0xb4,
+ 0x49, 0x48, 0x6a, 0x9e, 0x8b, 0xa9, 0x39, 0xfa, 0x3e, 0xd4, 0x47, 0xf6, 0x74, 0x3a, 0xb3, 0x8c,
+ 0x91, 0xe6, 0x1b, 0xb6, 0x25, 0x66, 0x37, 0x0e, 0x54, 0x36, 0x60, 0x2d, 0xc1, 0x57, 0x74, 0xf8,
+ 0x8f, 0x39, 0x68, 0x1f, 0xd9, 0x63, 0xff, 0x2d, 0x7b, 0x3d, 0x82, 0x8a, 0x6e, 0xb8, 0x64, 0x14,
+ 0xf6, 0xd8, 0x78, 0xf8, 0xc3, 0x68, 0xa8, 0xf3, 0x18, 0x46, 0x88, 0x9d, 0xa0, 0x31, 0x8e, 0xf8,
+ 0x28, 0x1f, 0x03, 0x4a, 0x13, 0xa0, 0x12, 0xe4, 0xfb, 0x07, 0xad, 0x05, 0xb4, 0x04, 0x85, 0xc3,
+ 0xe7, 0xc3, 0x56, 0x0e, 0x95, 0xa1, 0xf8, 0xe4, 0x70, 0xf8, 0xac, 0x95, 0x57, 0xae, 0xc2, 0x95,
+ 0x8c, 0xae, 0xc4, 0xc8, 0x5e, 0xc1, 0xc6, 0xd1, 0xc9, 0xcc, 0xd7, 0xed, 0xd7, 0xd6, 0xfb, 0x9e,
+ 0xcd, 0x0e, 0xb4, 0xd3, 0xac, 0x45, 0xb7, 0x0f, 0x60, 0xad, 0xc7, 0x9c, 0xd4, 0xa5, 0x3b, 0xa5,
+ 0xea, 0x90, 0x6c, 0x22, 0x98, 0xbd, 0x84, 0xf5, 0x1d, 0xc3, 0x7b, 0x2b, 0x6e, 0x97, 0x1c, 0xc2,
+ 0x15, 0xd8, 0x48, 0x71, 0x16, 0x9d, 0x4e, 0xa0, 0xc5, 0xc5, 0xd9, 0x77, 0xfd, 0xa0, 0xbb, 0xab,
+ 0x50, 0xd1, 0x67, 0x53, 0x47, 0xf5, 0xcf, 0x1d, 0x6e, 0xed, 0x8b, 0xb8, 0x4c, 0x01, 0xc3, 0x73,
+ 0x87, 0xa0, 0x0e, 0x94, 0xc7, 0x86, 0x49, 0x98, 0x6f, 0xe3, 0x9d, 0x85, 0xdf, 0x14, 0x67, 0x58,
+ 0x3e, 0x71, 0x4f, 0x35, 0x93, 0x19, 0x78, 0x11, 0x87, 0xdf, 0xca, 0x0a, 0x2c, 0x4b, 0x1d, 0x89,
+ 0xde, 0x57, 0x60, 0x59, 0x08, 0x16, 0x75, 0xcf, 0x8c, 0x5a, 0x02, 0x0a, 0xd2, 0x3f, 0x87, 0x56,
+ 0xdf, 0xfa, 0x13, 0x32, 0xf2, 0x25, 0x41, 0xdf, 0x93, 0x57, 0xa2, 0xbb, 0x84, 0xe6, 0x9f, 0x78,
+ 0xed, 0x42, 0x6a, 0x97, 0xa0, 0x6e, 0x85, 0x23, 0xa9, 0xac, 0x92, 0x00, 0x42, 0xaa, 0xbf, 0xcd,
+ 0x41, 0xbd, 0xab, 0xeb, 0x4f, 0xa6, 0xce, 0x9b, 0xd7, 0x0a, 0x41, 0xd1, 0xb1, 0x5d, 0x5f, 0xec,
+ 0x13, 0xec, 0x37, 0xfa, 0x09, 0x14, 0xd9, 0x2c, 0x17, 0x98, 0xf4, 0x9b, 0x51, 0xcf, 0x31, 0xa6,
+ 0x5b, 0xfb, 0xb6, 0x65, 0xf8, 0xb6, 0x6b, 0x58, 0x93, 0x81, 0x6d, 0x1a, 0xa3, 0x73, 0xcc, 0x5a,
+ 0x29, 0x1f, 0x43, 0x2b, 0x89, 0xa1, 0x96, 0x33, 0xc0, 0xbd, 0xd6, 0x02, 0xb5, 0x9c, 0xc1, 0xe1,
+ 0x51, 0xdc, 0x86, 0x5a, 0x6c, 0x03, 0x62, 0x8c, 0xc5, 0x00, 0x7e, 0x06, 0x2d, 0xee, 0x9d, 0xde,
+ 0x75, 0x08, 0x6c, 0x0d, 0x23, 0x0e, 0x82, 0xed, 0x10, 0x96, 0x85, 0x64, 0xd8, 0x38, 0x0e, 0xf8,
+ 0xde, 0x81, 0x45, 0x9f, 0x2e, 0xab, 0x70, 0x97, 0xcd, 0x68, 0xb4, 0x43, 0x0a, 0xc6, 0x1c, 0x4b,
+ 0xbb, 0x1f, 0xcd, 0x5c, 0x97, 0x58, 0xbc, 0x9f, 0x32, 0x0e, 0x3e, 0x95, 0x1e, 0x94, 0xf1, 0xe0,
+ 0xab, 0xfe, 0xb6, 0x6d, 0x8d, 0x2f, 0x10, 0xf2, 0x26, 0x54, 0x5d, 0x32, 0xb5, 0x7d, 0xa2, 0x86,
+ 0xb2, 0x56, 0x30, 0x70, 0xd0, 0x80, 0x4a, 0xfc, 0xd7, 0x45, 0xa8, 0x50, 0x3e, 0x47, 0xbe, 0xe6,
+ 0xb3, 0x0d, 0x7c, 0xe6, 0xf8, 0xc6, 0x94, 0x8b, 0x55, 0xc0, 0xe2, 0x8b, 0x2a, 0x33, 0xb5, 0x79,
+ 0x86, 0xc9, 0x33, 0x4c, 0xf8, 0x8d, 0x1a, 0x90, 0x9f, 0x39, 0x6c, 0xd1, 0xca, 0x38, 0x3f, 0x73,
+ 0x78, 0x97, 0x23, 0xdb, 0xd5, 0x55, 0xc3, 0x39, 0xfd, 0x8c, 0x6d, 0x63, 0x75, 0xda, 0x25, 0x05,
+ 0xf5, 0x9d, 0xd3, 0xcf, 0xe2, 0x04, 0x8f, 0xd8, 0x1e, 0x26, 0x13, 0x3c, 0xa2, 0x04, 0x8e, 0x4b,
+ 0xc6, 0xc6, 0x19, 0xe7, 0x50, 0xe2, 0x04, 0x1c, 0x14, 0x70, 0x88, 0x08, 0x1e, 0xb5, 0x97, 0x12,
+ 0x04, 0x8f, 0xe8, 0x38, 0x3c, 0xe2, 0x1a, 0x9a, 0xd9, 0x2e, 0xf3, 0xbd, 0x95, 0x7f, 0xa1, 0xef,
+ 0x41, 0xdd, 0x25, 0x23, 0x62, 0x9c, 0x12, 0x21, 0x5d, 0x85, 0x0d, 0xa6, 0x16, 0x00, 0x19, 0xf7,
+ 0x04, 0xd1, 0xa3, 0x36, 0xa4, 0x88, 0x1e, 0x51, 0x22, 0xce, 0x53, 0xb5, 0x6c, 0xdf, 0x18, 0x9f,
+ 0xb7, 0xab, 0x9c, 0x88, 0x03, 0x0f, 0x18, 0x8c, 0xca, 0x39, 0xd2, 0x46, 0x27, 0x44, 0x75, 0xa9,
+ 0xa3, 0x6e, 0xd7, 0x18, 0x09, 0x30, 0x10, 0x73, 0xdd, 0xe8, 0x0e, 0x34, 0x42, 0x02, 0xa6, 0x2c,
+ 0xed, 0x3a, 0xa3, 0xa9, 0x07, 0x34, 0x3c, 0x36, 0xb9, 0x01, 0x55, 0x62, 0xe9, 0xaa, 0x3d, 0x56,
+ 0x75, 0xcd, 0xd7, 0xda, 0x0d, 0x46, 0x53, 0x21, 0x96, 0x7e, 0x38, 0xde, 0xd1, 0x7c, 0x0d, 0xad,
+ 0xc2, 0x22, 0x71, 0x5d, 0xdb, 0x6d, 0x37, 0x19, 0x86, 0x7f, 0xa0, 0xdb, 0x20, 0xa4, 0x51, 0xbf,
+ 0x9b, 0x11, 0xf7, 0xbc, 0xdd, 0x62, 0xc8, 0x2a, 0x87, 0x7d, 0x4d, 0x41, 0x7c, 0x29, 0x3c, 0xe2,
+ 0x0b, 0x8a, 0x65, 0x2e, 0x20, 0x03, 0x31, 0x02, 0xe5, 0x15, 0x14, 0xb1, 0xf3, 0xad, 0x81, 0x3e,
+ 0x80, 0xe2, 0xc8, 0xb6, 0xc6, 0x42, 0x5b, 0x65, 0xcf, 0x22, 0x74, 0x10, 0x33, 0x3c, 0xba, 0x07,
+ 0x8b, 0x1e, 0xd5, 0x24, 0xa6, 0x25, 0xd5, 0x87, 0x2b, 0x71, 0x42, 0xa6, 0x64, 0x98, 0x53, 0x28,
+ 0x9b, 0xd0, 0xd8, 0x25, 0x3e, 0xe5, 0x1e, 0xd8, 0x44, 0x14, 0x11, 0xe5, 0xe4, 0x88, 0x48, 0x79,
+ 0x0c, 0xcd, 0x90, 0x52, 0xcc, 0xc8, 0x26, 0x2c, 0x79, 0xc4, 0x3d, 0xcd, 0x0c, 0x67, 0x19, 0x61,
+ 0x80, 0x56, 0xbe, 0x61, 0x66, 0x2e, 0x77, 0xf3, 0x76, 0x5e, 0xa9, 0x03, 0x65, 0xd3, 0x18, 0x13,
+ 0xa6, 0xfa, 0x05, 0xae, 0xfa, 0xc1, 0xb7, 0xb2, 0xcc, 0xc2, 0x48, 0x59, 0x30, 0xa5, 0x1b, 0x78,
+ 0x80, 0x77, 0xee, 0x31, 0x0a, 0xe4, 0x62, 0x8c, 0x3f, 0x0a, 0xf6, 0x8c, 0x4b, 0x31, 0xa6, 0x4c,
+ 0x64, 0x72, 0xc1, 0x64, 0x2b, 0xdc, 0x4e, 0x2e, 0xc7, 0x65, 0x0d, 0x56, 0x62, 0xf4, 0x82, 0xcd,
+ 0x87, 0xd0, 0x62, 0xfa, 0x7b, 0x39, 0x26, 0x2b, 0xb0, 0x2c, 0x51, 0x0b, 0x16, 0x9f, 0xc0, 0x6a,
+ 0x18, 0xc1, 0x5c, 0x8e, 0xcd, 0x06, 0xac, 0x25, 0x5a, 0x08, 0x56, 0xbf, 0xc9, 0x05, 0x63, 0xfd,
+ 0x86, 0x1c, 0xbb, 0x5a, 0xc0, 0xa9, 0x05, 0x85, 0x99, 0x6b, 0x0a, 0x2e, 0xf4, 0x27, 0xd3, 0x76,
+ 0x7b, 0xe6, 0x13, 0xb6, 0x99, 0xd3, 0x63, 0x53, 0x81, 0x39, 0x43, 0x0a, 0xa2, 0xdb, 0xb9, 0x47,
+ 0x3b, 0xa7, 0x3a, 0x43, 0x63, 0x07, 0x1e, 0x93, 0x07, 0x9f, 0xe8, 0x33, 0x58, 0xb7, 0xc8, 0x99,
+ 0x7f, 0x62, 0x3b, 0xaa, 0xef, 0x1a, 0x93, 0x09, 0x71, 0x55, 0x7e, 0x22, 0x63, 0xfe, 0xad, 0x8c,
+ 0x57, 0x05, 0x76, 0xc8, 0x91, 0x5c, 0x1c, 0xf4, 0x10, 0xd6, 0x92, 0xad, 0x74, 0x62, 0x6a, 0xe7,
+ 0xc2, 0xe7, 0xad, 0xc4, 0x1b, 0xed, 0x50, 0x14, 0x9d, 0xf2, 0xd8, 0x60, 0xc4, 0x20, 0x9b, 0x50,
+ 0xdf, 0x25, 0xfe, 0x0b, 0x77, 0x1c, 0x44, 0x06, 0x9f, 0x32, 0xf3, 0x61, 0x00, 0x61, 0x13, 0xb7,
+ 0xa1, 0x78, 0xea, 0x8e, 0x03, 0x83, 0xa8, 0x47, 0x06, 0x41, 0x89, 0x18, 0x4a, 0xf9, 0x84, 0xed,
+ 0xd0, 0x11, 0x17, 0x74, 0x13, 0x0a, 0xa7, 0x6e, 0x60, 0xd6, 0x89, 0x26, 0x14, 0x23, 0x76, 0x49,
+ 0xa9, 0x1b, 0xe5, 0xd3, 0x60, 0x97, 0x7c, 0x1b, 0x36, 0xe1, 0xc6, 0x28, 0x73, 0x7a, 0x0e, 0xab,
+ 0xbb, 0xc4, 0xdf, 0x21, 0x63, 0xc3, 0x22, 0xfa, 0x11, 0x09, 0x43, 0x99, 0x7b, 0x22, 0x10, 0xe0,
+ 0x61, 0xcc, 0x5a, 0xc4, 0x4e, 0x90, 0xd2, 0xc5, 0xe2, 0xbb, 0x7e, 0x78, 0xb2, 0xcc, 0x4b, 0x27,
+ 0xcb, 0x2e, 0xac, 0x25, 0xd8, 0x86, 0x4e, 0xa3, 0xe8, 0x11, 0x3f, 0x98, 0xa0, 0xd5, 0x14, 0x5f,
+ 0x4a, 0xcb, 0x28, 0x94, 0x2f, 0x61, 0xb5, 0xab, 0xeb, 0x69, 0xc9, 0x3e, 0x80, 0x02, 0x75, 0xe4,
+ 0x7c, 0x9c, 0xd9, 0x0c, 0x28, 0x01, 0xd5, 0xd5, 0x44, 0x7b, 0x31, 0xe4, 0x23, 0xd8, 0xe0, 0xf3,
+ 0xf0, 0xce, 0xbc, 0xa9, 0x5e, 0x6b, 0xa6, 0x29, 0xc2, 0x01, 0xfa, 0x93, 0x46, 0xe5, 0x69, 0xa6,
+ 0xa2, 0xc3, 0x27, 0xd0, 0xc6, 0xc4, 0x31, 0xb5, 0xd1, 0xbb, 0xf7, 0x48, 0x4f, 0x1b, 0x19, 0x3c,
+ 0x44, 0x07, 0x6b, 0x2c, 0xdb, 0xc0, 0x3c, 0xfb, 0x94, 0x58, 0x61, 0xe0, 0xfa, 0x15, 0x5b, 0x5b,
+ 0x09, 0x2c, 0xd6, 0xe0, 0x53, 0x00, 0x2f, 0x00, 0x06, 0x2b, 0x21, 0xed, 0x12, 0x51, 0x03, 0x89,
+ 0x4c, 0x79, 0xc6, 0x8e, 0xa2, 0xc9, 0x3e, 0xd0, 0x03, 0xa8, 0x84, 0x44, 0x62, 0x14, 0x99, 0xac,
+ 0x22, 0x2a, 0x65, 0x9d, 0x2d, 0x6c, 0x4a, 0x2c, 0xe5, 0x0f, 0x83, 0x83, 0xe9, 0x7b, 0xe8, 0x24,
+ 0x63, 0x85, 0xae, 0x04, 0xcb, 0x9e, 0xee, 0x79, 0x0f, 0x36, 0xc4, 0xe4, 0xbe, 0x8f, 0xf1, 0x75,
+ 0xc2, 0xe5, 0x4e, 0xf7, 0x84, 0xa0, 0xb5, 0x4b, 0x7c, 0x11, 0x34, 0x8b, 0x65, 0xea, 0xc2, 0xb2,
+ 0x04, 0x13, 0x6b, 0xf4, 0x21, 0x94, 0x1d, 0x0a, 0x31, 0x48, 0xb0, 0x42, 0x2d, 0xe9, 0x18, 0xc0,
+ 0x69, 0x43, 0x0a, 0xe5, 0x0c, 0x5a, 0x5d, 0x5d, 0x8f, 0xb1, 0x45, 0x9b, 0x50, 0x62, 0xf8, 0x73,
+ 0x21, 0x76, 0xba, 0xbd, 0xc0, 0xa3, 0x1f, 0xc3, 0x15, 0x97, 0x8c, 0xa9, 0x3b, 0x3d, 0x33, 0x3c,
+ 0xdf, 0xb0, 0x26, 0xaa, 0xa4, 0x1e, 0x7c, 0x06, 0x37, 0x18, 0x41, 0x4f, 0xe0, 0x8f, 0x22, 0xb5,
+ 0x58, 0x81, 0x65, 0xa9, 0x67, 0x31, 0xca, 0x5f, 0xe6, 0x60, 0x45, 0xe4, 0x41, 0xde, 0x51, 0xa4,
+ 0x8f, 0x61, 0xc5, 0xa1, 0x21, 0x90, 0x7b, 0x4a, 0xd2, 0xc2, 0xa0, 0x00, 0x15, 0xc9, 0x11, 0xac,
+ 0x77, 0x21, 0x5a, 0xef, 0x75, 0x58, 0x8d, 0xcb, 0x20, 0x84, 0xfb, 0xbb, 0x1c, 0xac, 0x8a, 0xf5,
+ 0xf9, 0x3f, 0x98, 0xb0, 0x79, 0x23, 0x2b, 0xcc, 0x1b, 0x19, 0xcf, 0x9e, 0xc4, 0xc4, 0x0d, 0xcf,
+ 0xe7, 0x9d, 0x50, 0x6f, 0xba, 0x9e, 0x67, 0x4c, 0x2c, 0x59, 0x71, 0x7f, 0x0c, 0xa0, 0x85, 0x40,
+ 0x31, 0xa2, 0x4e, 0x72, 0x44, 0x52, 0x33, 0x89, 0x5a, 0x79, 0x05, 0x57, 0x33, 0x39, 0x0b, 0xdd,
+ 0xfc, 0x6d, 0x58, 0xbf, 0x84, 0x4e, 0xa8, 0x2f, 0xef, 0x57, 0xe8, 0xeb, 0x70, 0x35, 0x93, 0xb3,
+ 0x98, 0xad, 0x29, 0x5c, 0x97, 0xd5, 0xe1, 0xbd, 0xf6, 0x9d, 0xe1, 0x6d, 0x6e, 0xc1, 0x8d, 0x79,
+ 0xdd, 0x09, 0x81, 0xfe, 0x00, 0x6e, 0xc4, 0xd6, 0xf5, 0xfd, 0xce, 0xc6, 0x6d, 0xb8, 0x39, 0x97,
+ 0x7b, 0xcc, 0x17, 0x1d, 0xb1, 0x18, 0x3d, 0xf0, 0x45, 0x5f, 0x30, 0x5f, 0x14, 0xc0, 0xc2, 0x3d,
+ 0xbb, 0x34, 0x31, 0xed, 0x63, 0xcd, 0x4c, 0x1b, 0xc6, 0x2e, 0x83, 0x63, 0x81, 0x57, 0xbe, 0x04,
+ 0x74, 0xe4, 0x6b, 0x6e, 0x9c, 0xe9, 0x5b, 0xb4, 0x5f, 0x83, 0x95, 0x58, 0xfb, 0x28, 0x2d, 0x73,
+ 0xe4, 0xdb, 0x4e, 0x5c, 0xd4, 0x55, 0xda, 0x57, 0x04, 0x14, 0xa4, 0xff, 0x56, 0x80, 0xe2, 0x40,
+ 0xa4, 0x67, 0x2d, 0xd3, 0x35, 0x82, 0x5c, 0x32, 0xfd, 0x4d, 0x0f, 0x37, 0x8e, 0xe6, 0xfb, 0x2e,
+ 0x8f, 0x3b, 0x6b, 0x58, 0x7c, 0xb1, 0xe5, 0x9b, 0x04, 0x47, 0x0b, 0xfa, 0x93, 0xb6, 0x3e, 0x26,
+ 0x9e, 0x2f, 0x22, 0x4b, 0xf6, 0x9b, 0x86, 0xae, 0x86, 0xa7, 0xbe, 0x36, 0xfc, 0x13, 0xdd, 0xd5,
+ 0x5e, 0xb3, 0xf8, 0xb1, 0x8c, 0xc1, 0xf0, 0x7e, 0x21, 0x20, 0xe8, 0x06, 0xc0, 0xa9, 0x66, 0x1a,
+ 0x3a, 0xcf, 0x7c, 0x95, 0x58, 0xa2, 0x4a, 0x82, 0xa0, 0x4f, 0x60, 0xd5, 0xb2, 0x55, 0x63, 0xea,
+ 0x50, 0xaf, 0xed, 0x47, 0x9c, 0x96, 0xb8, 0xed, 0x5b, 0x76, 0x5f, 0xa0, 0x42, 0x8e, 0xd1, 0x69,
+ 0xac, 0x1c, 0xcb, 0x4f, 0x5f, 0x07, 0xe0, 0x29, 0x24, 0x55, 0xf3, 0x2c, 0x76, 0x80, 0xae, 0xe3,
+ 0x0a, 0x87, 0x74, 0x3d, 0x0b, 0x5d, 0x05, 0xf1, 0xa1, 0x1a, 0x3a, 0x3b, 0x39, 0x57, 0x70, 0x99,
+ 0x03, 0xfa, 0xba, 0x48, 0x98, 0xf9, 0xc4, 0x25, 0x3a, 0x3b, 0x30, 0x97, 0x71, 0xf8, 0x4d, 0x0f,
+ 0xb1, 0x9e, 0xaf, 0x99, 0x84, 0x1d, 0x93, 0xcb, 0x98, 0x7f, 0xa0, 0x4d, 0x68, 0x19, 0x9e, 0x3a,
+ 0x76, 0xed, 0xa9, 0x4a, 0xce, 0x7c, 0xe2, 0x5a, 0x9a, 0xc9, 0xce, 0xc8, 0x65, 0xdc, 0x30, 0xbc,
+ 0xa7, 0xae, 0x3d, 0xed, 0x09, 0x28, 0x9d, 0x22, 0x4b, 0x64, 0xf4, 0x54, 0xc3, 0x61, 0x87, 0xe4,
+ 0x0a, 0x86, 0x00, 0xd4, 0x77, 0xc2, 0xa4, 0x79, 0x33, 0x4a, 0x9a, 0xa3, 0x0f, 0x01, 0x19, 0x9e,
+ 0x1a, 0x04, 0xe9, 0x86, 0xc5, 0x66, 0x8c, 0x9d, 0x94, 0xcb, 0xb8, 0x65, 0x78, 0x07, 0x1c, 0xd1,
+ 0xe7, 0x70, 0xe5, 0x6f, 0x72, 0x50, 0xdd, 0x21, 0xd4, 0xab, 0xf2, 0x49, 0xa5, 0x6b, 0xca, 0x92,
+ 0x0e, 0xe2, 0x94, 0x21, 0xbe, 0xa2, 0x24, 0x5a, 0xfe, 0x82, 0x24, 0x1a, 0xba, 0x0b, 0x4d, 0xd3,
+ 0xb6, 0xe8, 0xa1, 0x80, 0x37, 0x23, 0x81, 0x27, 0x6e, 0x70, 0xf0, 0x40, 0x40, 0xd1, 0x3d, 0x68,
+ 0x79, 0x27, 0xb6, 0xeb, 0xcb, 0x94, 0x5c, 0x39, 0x9a, 0x02, 0x1e, 0x90, 0x2a, 0xff, 0x90, 0x83,
+ 0x45, 0x96, 0x40, 0xa2, 0x27, 0x76, 0x29, 0x88, 0xce, 0xca, 0x05, 0xce, 0x8d, 0xa0, 0xe7, 0x5e,
+ 0x4d, 0xfc, 0x1e, 0xd4, 0xf4, 0x68, 0xf8, 0x54, 0x08, 0x3a, 0xbc, 0x58, 0x80, 0x1e, 0x62, 0x71,
+ 0x8c, 0x94, 0xa5, 0x6c, 0x6c, 0xcf, 0x57, 0xc5, 0x2e, 0x27, 0x14, 0x98, 0x82, 0xb8, 0x8f, 0x50,
+ 0x1e, 0xb1, 0x03, 0xce, 0x5b, 0x67, 0xc8, 0x94, 0xcf, 0x79, 0x1a, 0x81, 0xb6, 0x13, 0x2e, 0xe3,
+ 0x92, 0x0d, 0x4d, 0x40, 0x2f, 0xb8, 0x7d, 0x10, 0xa9, 0xd7, 0xcb, 0x4e, 0xdb, 0xbc, 0xab, 0xae,
+ 0x48, 0x25, 0x0a, 0xb2, 0x4a, 0x50, 0xef, 0x12, 0xeb, 0x4d, 0xb8, 0x8c, 0x7f, 0xa2, 0x2e, 0x83,
+ 0x10, 0x97, 0x59, 0x06, 0xe5, 0x10, 0xc4, 0x5c, 0x75, 0x1c, 0x7e, 0xa3, 0x1f, 0x41, 0x4d, 0x73,
+ 0x1c, 0xf3, 0x3c, 0x98, 0x3c, 0x9e, 0x5b, 0x91, 0xa6, 0xbd, 0x4b, 0xb1, 0x62, 0x87, 0xae, 0x6a,
+ 0xd1, 0x47, 0x98, 0xb6, 0x29, 0x24, 0xd3, 0x36, 0xb4, 0x4f, 0x29, 0x6d, 0xf3, 0x18, 0xea, 0xe4,
+ 0x78, 0xe2, 0xa8, 0xd3, 0x99, 0xe9, 0x1b, 0x27, 0xb6, 0x23, 0x2e, 0x9f, 0xd6, 0xa3, 0x06, 0xbd,
+ 0xe3, 0x89, 0xb3, 0x2f, 0xb0, 0xb8, 0x46, 0xa4, 0x2f, 0xd4, 0x85, 0x26, 0x3f, 0x56, 0xbb, 0x64,
+ 0x6c, 0x92, 0x91, 0x6f, 0xbb, 0x6c, 0x79, 0xab, 0x0f, 0xdb, 0xd2, 0xec, 0x51, 0x02, 0x1c, 0xe0,
+ 0x71, 0xc3, 0x8d, 0x7d, 0xa3, 0xbb, 0x50, 0x34, 0xac, 0xb1, 0xcd, 0xfc, 0x56, 0x2c, 0xc8, 0xa5,
+ 0x72, 0xf2, 0xac, 0x11, 0x23, 0xa0, 0xee, 0xdc, 0x37, 0xa6, 0xc4, 0xf5, 0x98, 0xe3, 0x8a, 0xb9,
+ 0xf3, 0x21, 0x83, 0x63, 0x81, 0xa7, 0xc1, 0xb3, 0xef, 0x6a, 0x96, 0xc7, 0xd2, 0x2b, 0xe5, 0x24,
+ 0xdf, 0x61, 0x80, 0xc2, 0x11, 0x15, 0x9d, 0x67, 0x3e, 0x10, 0x9e, 0x3b, 0x62, 0xbe, 0x2d, 0x36,
+ 0xcf, 0x6c, 0x14, 0xc2, 0xe9, 0xf3, 0x54, 0x02, 0xff, 0x50, 0xfe, 0x25, 0x07, 0x55, 0x69, 0x11,
+ 0xd0, 0xe7, 0x50, 0x31, 0x2c, 0x35, 0x16, 0xd1, 0x5d, 0xb4, 0x79, 0x96, 0x0d, 0x4b, 0x34, 0xfc,
+ 0x29, 0xd4, 0xc9, 0x19, 0x15, 0x26, 0xbe, 0xd6, 0x17, 0x35, 0xae, 0xf1, 0x06, 0x11, 0x03, 0x63,
+ 0x2a, 0x33, 0x28, 0xbc, 0x99, 0x01, 0x6f, 0x20, 0xec, 0xf0, 0xcf, 0xa0, 0xca, 0xbd, 0xc9, 0x9e,
+ 0x31, 0x35, 0xe6, 0xe6, 0xe4, 0xd0, 0x6d, 0xa8, 0x4d, 0xb5, 0xb3, 0xc8, 0x1f, 0x71, 0x2b, 0xa8,
+ 0x4e, 0xb5, 0xb3, 0xd0, 0x6d, 0x7d, 0x06, 0xeb, 0x9e, 0xb8, 0x2c, 0x52, 0xfd, 0x13, 0x97, 0x78,
+ 0x27, 0xb6, 0xa9, 0xab, 0xce, 0xc8, 0x17, 0x5e, 0x65, 0x35, 0xc0, 0x0e, 0x03, 0xe4, 0x60, 0xe4,
+ 0x2b, 0xff, 0xbd, 0x08, 0xe5, 0x40, 0x3b, 0xd1, 0xf7, 0xa0, 0xae, 0xcd, 0xfc, 0x13, 0xd5, 0xd1,
+ 0x3c, 0xef, 0xb5, 0xed, 0xea, 0xc2, 0xcf, 0xd6, 0x28, 0x70, 0x20, 0x60, 0xe8, 0x16, 0x54, 0x75,
+ 0xe2, 0x8d, 0x5c, 0xc3, 0x91, 0x6e, 0x7d, 0x64, 0x10, 0xba, 0x02, 0x65, 0xd3, 0x1e, 0x69, 0xa6,
+ 0xaa, 0x79, 0x41, 0x62, 0x87, 0x7d, 0x77, 0x99, 0x6f, 0x0d, 0x77, 0x8d, 0x20, 0xf1, 0x54, 0x64,
+ 0x1c, 0x9a, 0x01, 0xbc, 0x2b, 0x72, 0x75, 0x1b, 0xb0, 0xe4, 0x10, 0xe2, 0x52, 0x26, 0x3c, 0x7f,
+ 0x53, 0xa2, 0x9f, 0x5d, 0x8f, 0xee, 0x88, 0x0c, 0x31, 0x71, 0xed, 0x99, 0xc3, 0x74, 0xb8, 0x82,
+ 0x2b, 0x14, 0xb2, 0x4b, 0x01, 0x74, 0x47, 0x64, 0x68, 0xe6, 0x57, 0x78, 0xae, 0xba, 0x4c, 0x01,
+ 0xec, 0x0a, 0xe9, 0x00, 0x96, 0x5d, 0x32, 0xb5, 0x4f, 0x89, 0xea, 0xb8, 0xc6, 0xa9, 0xe6, 0xd3,
+ 0x5d, 0x95, 0xa9, 0x6b, 0xe3, 0xa1, 0x92, 0x36, 0xd7, 0x2d, 0xcc, 0x68, 0x07, 0x9c, 0xb4, 0xeb,
+ 0xe1, 0xa6, 0x1b, 0x07, 0xd0, 0x0d, 0x8d, 0xeb, 0xf0, 0xd8, 0xd4, 0x1c, 0x55, 0xd7, 0xa6, 0x8e,
+ 0x61, 0x4d, 0x98, 0x26, 0x97, 0x71, 0x8b, 0x61, 0x9e, 0x9a, 0x9a, 0xb3, 0xc3, 0xe1, 0xe8, 0x0e,
+ 0x34, 0x3c, 0x62, 0xe9, 0xaa, 0xb8, 0x22, 0xf3, 0xcf, 0xd9, 0x8e, 0x5d, 0xc7, 0x75, 0x0a, 0xdd,
+ 0x0e, 0x80, 0x74, 0x80, 0xe2, 0x16, 0x61, 0xa4, 0x39, 0xed, 0x2a, 0x8b, 0x5f, 0x2a, 0x1c, 0xb2,
+ 0xad, 0xb1, 0x01, 0xf2, 0xe9, 0xa5, 0xd8, 0x1a, 0xc3, 0xf2, 0xf9, 0xa6, 0xc8, 0x06, 0xe4, 0x0d,
+ 0x9d, 0x6d, 0xd9, 0x15, 0x9c, 0x37, 0x74, 0xf4, 0x63, 0xa8, 0x8b, 0xdc, 0xbd, 0x49, 0x15, 0xcc,
+ 0x6b, 0x37, 0x92, 0x9b, 0x88, 0xa4, 0x7e, 0xb8, 0xe6, 0x44, 0x1f, 0x1e, 0x55, 0x07, 0xb1, 0x8e,
+ 0x62, 0xa5, 0x9a, 0x5c, 0x1d, 0xf8, 0x62, 0x8a, 0x65, 0xfa, 0x08, 0x50, 0x14, 0x07, 0x58, 0x3e,
+ 0x71, 0xc7, 0xda, 0x88, 0xb0, 0x2d, 0xbd, 0x82, 0x97, 0xc3, 0x70, 0x20, 0x40, 0xd0, 0xf8, 0xeb,
+ 0xd4, 0x1d, 0xb3, 0xd4, 0x77, 0x85, 0xe5, 0xaa, 0xd0, 0x2d, 0xa8, 0x69, 0xa6, 0x69, 0xbf, 0x56,
+ 0xa9, 0xe2, 0x6a, 0x5e, 0x1b, 0xf1, 0xeb, 0x05, 0x06, 0x3b, 0x7c, 0x6d, 0x75, 0x3d, 0xf4, 0x01,
+ 0x34, 0x5d, 0x1e, 0xe0, 0xaa, 0x81, 0x46, 0xac, 0xb0, 0x19, 0xae, 0x0b, 0xf0, 0x80, 0x29, 0x86,
+ 0xf2, 0x00, 0x9a, 0x89, 0x05, 0x43, 0x65, 0x28, 0x1e, 0x1c, 0x1e, 0xf4, 0xf8, 0xb5, 0x6e, 0x77,
+ 0x6f, 0xaf, 0x95, 0x43, 0x55, 0x58, 0xc2, 0xbd, 0xc1, 0x5e, 0x77, 0xbb, 0xd7, 0xca, 0x2b, 0x5f,
+ 0x41, 0x4d, 0x76, 0xb5, 0xa8, 0x0d, 0x4b, 0x3c, 0xd1, 0x18, 0xbc, 0x04, 0x09, 0x3e, 0x99, 0x05,
+ 0x0a, 0x2a, 0xd5, 0xf7, 0xcd, 0xd0, 0x02, 0x05, 0x6c, 0xe8, 0x9b, 0xca, 0x5f, 0xe4, 0xa0, 0x11,
+ 0xf7, 0xbc, 0xd4, 0x28, 0x13, 0xce, 0x5a, 0x1d, 0x99, 0x46, 0x10, 0xe3, 0x97, 0xf1, 0x6a, 0xdc,
+ 0x33, 0x6f, 0x33, 0x1c, 0x7a, 0x0c, 0x9d, 0x74, 0xab, 0x99, 0x47, 0x23, 0x92, 0xf0, 0x02, 0x71,
+ 0x23, 0xd9, 0x92, 0xe1, 0xfb, 0xba, 0xf2, 0xf7, 0x25, 0xa8, 0x84, 0x7e, 0xfc, 0x7f, 0xc1, 0xa4,
+ 0xb7, 0xa0, 0x3c, 0x25, 0x9e, 0xa7, 0x4d, 0x44, 0x98, 0x14, 0xdb, 0xf8, 0xf6, 0x05, 0x06, 0x87,
+ 0x34, 0x99, 0x2e, 0x60, 0xf1, 0x8d, 0x2e, 0xa0, 0x74, 0x81, 0x0b, 0x58, 0xba, 0xd0, 0x05, 0x94,
+ 0x13, 0x2e, 0x60, 0x13, 0x4a, 0xdf, 0xcd, 0xc8, 0x8c, 0x78, 0x62, 0xc3, 0x91, 0xf6, 0xb4, 0xaf,
+ 0x19, 0x1c, 0x0b, 0x3c, 0xba, 0x9f, 0xe5, 0x2c, 0xb8, 0xc5, 0x5e, 0xd2, 0x11, 0x54, 0x2f, 0xed,
+ 0x08, 0x6a, 0x59, 0x8e, 0x80, 0xdd, 0x7a, 0x79, 0x9e, 0x61, 0x5b, 0x3c, 0x7f, 0xc0, 0xec, 0xba,
+ 0x8e, 0x6b, 0x02, 0xc8, 0x57, 0xf8, 0x87, 0xb0, 0xee, 0xcd, 0x1c, 0xba, 0xa5, 0x10, 0x9d, 0xba,
+ 0x04, 0xed, 0xd8, 0x30, 0x0d, 0x9f, 0x06, 0x36, 0x0d, 0x96, 0x71, 0x5f, 0x0b, 0xb1, 0xdb, 0x12,
+ 0x92, 0xce, 0x11, 0x0d, 0x41, 0x38, 0x5f, 0x6e, 0xd8, 0xe5, 0xe3, 0x89, 0xc3, 0x79, 0xfe, 0x14,
+ 0xaa, 0x9a, 0x3e, 0x35, 0x82, 0x6e, 0x5b, 0xcc, 0x41, 0xde, 0xc8, 0x88, 0x13, 0xb6, 0xba, 0x94,
+ 0x8c, 0x87, 0x0c, 0xa0, 0x85, 0xbf, 0x69, 0x7c, 0x15, 0xdc, 0xdf, 0x31, 0x5b, 0xaf, 0xe3, 0xf0,
+ 0x9b, 0xe2, 0xb4, 0xd1, 0x88, 0x38, 0x3e, 0xd1, 0x85, 0xb1, 0x87, 0xdf, 0xf4, 0x5c, 0xa5, 0x45,
+ 0x8f, 0xb1, 0x56, 0x84, 0x2b, 0x88, 0x9e, 0x61, 0xad, 0xc0, 0xa2, 0x3d, 0xf3, 0xd5, 0xef, 0xda,
+ 0xab, 0xfc, 0x06, 0xc7, 0x9e, 0xf9, 0x5f, 0xd3, 0xa3, 0xcc, 0xd8, 0xb4, 0x1d, 0xaf, 0xbd, 0xc6,
+ 0x80, 0xfc, 0x43, 0xb9, 0x0f, 0x10, 0x09, 0x87, 0x4a, 0x90, 0x7f, 0x3e, 0xe0, 0x57, 0xd3, 0x3b,
+ 0x87, 0xbf, 0x38, 0x68, 0xe5, 0x10, 0x40, 0x69, 0xf0, 0xf4, 0xa5, 0xba, 0x3d, 0x6c, 0xe5, 0x95,
+ 0x3f, 0x86, 0x72, 0xa0, 0xa9, 0xe8, 0x23, 0x49, 0x74, 0x1e, 0x4b, 0x2c, 0xa7, 0xf4, 0x59, 0x1a,
+ 0xcd, 0x1d, 0x28, 0x7a, 0xc1, 0x7d, 0x71, 0x26, 0x29, 0x43, 0x2b, 0xbf, 0xce, 0xc1, 0x92, 0x80,
+ 0x20, 0x05, 0x6a, 0x07, 0x87, 0xc3, 0xfe, 0xd3, 0xfe, 0x76, 0x77, 0xd8, 0x3f, 0x3c, 0x60, 0xbd,
+ 0x14, 0x71, 0x0c, 0x46, 0x03, 0x81, 0xe7, 0x83, 0x9d, 0xee, 0xb0, 0xc7, 0x18, 0x17, 0xb1, 0xf8,
+ 0xa2, 0xe7, 0x87, 0xc3, 0x41, 0xef, 0x40, 0xbc, 0x71, 0x60, 0xbf, 0xd1, 0x35, 0xa8, 0x7c, 0xd5,
+ 0xeb, 0x0d, 0xba, 0x7b, 0xfd, 0x17, 0x3d, 0x66, 0x82, 0x45, 0x1c, 0x01, 0xa8, 0x4b, 0xc3, 0xbd,
+ 0xa7, 0xb8, 0x77, 0xf4, 0x8c, 0x99, 0x59, 0x11, 0x07, 0x9f, 0xb4, 0xdd, 0x4e, 0xff, 0x68, 0xbb,
+ 0x8b, 0x77, 0x7a, 0x3b, 0xcc, 0xc0, 0x8a, 0x38, 0x02, 0xd0, 0x59, 0x1d, 0x1e, 0x0e, 0xbb, 0x7b,
+ 0xcc, 0xbc, 0x8a, 0x98, 0x7f, 0x28, 0x8f, 0xa0, 0xc4, 0xad, 0x84, 0xe2, 0x0d, 0xcb, 0x99, 0xf9,
+ 0x22, 0x52, 0xe1, 0x1f, 0x54, 0x6e, 0x7b, 0xe6, 0x53, 0xb0, 0x08, 0xd4, 0xf9, 0x97, 0x42, 0xa0,
+ 0xc4, 0x23, 0x46, 0xb4, 0x05, 0x25, 0x1a, 0x04, 0x1b, 0x13, 0x31, 0xbb, 0xeb, 0xc9, 0x98, 0x72,
+ 0x9b, 0x61, 0xb1, 0xa0, 0x42, 0x3f, 0x88, 0xdf, 0x71, 0xae, 0x25, 0xc9, 0x63, 0xb7, 0x9c, 0xbf,
+ 0xce, 0x41, 0x4d, 0xe6, 0x42, 0x4d, 0x68, 0x64, 0x5b, 0x16, 0x19, 0xf9, 0xaa, 0x4b, 0x7c, 0xf7,
+ 0x3c, 0x98, 0x6c, 0x01, 0xc4, 0x14, 0x46, 0x6d, 0x81, 0x05, 0x4b, 0xe1, 0x85, 0x7b, 0x11, 0x97,
+ 0x29, 0x80, 0x72, 0xa2, 0x1b, 0xdc, 0xb7, 0x84, 0x38, 0x9a, 0x69, 0x9c, 0x12, 0x35, 0xf1, 0xc6,
+ 0x64, 0x39, 0xc4, 0xf4, 0x05, 0x02, 0xed, 0xc0, 0x8d, 0xa9, 0x61, 0x19, 0xd3, 0xd9, 0x54, 0x0d,
+ 0xf5, 0x96, 0xc6, 0x7d, 0x51, 0x53, 0xbe, 0x42, 0xd7, 0x04, 0x55, 0x57, 0x26, 0x0a, 0xb8, 0x28,
+ 0xbf, 0xca, 0x43, 0x55, 0x1a, 0xde, 0xff, 0xd3, 0x61, 0xb0, 0x34, 0x08, 0x99, 0xd8, 0xbe, 0xa1,
+ 0x51, 0xe7, 0x14, 0x09, 0xc7, 0x15, 0x11, 0x45, 0xb8, 0x67, 0x81, 0x98, 0xd1, 0x93, 0x08, 0xae,
+ 0x90, 0x59, 0x4f, 0x22, 0xb8, 0x42, 0x86, 0xdf, 0xca, 0x7f, 0xe5, 0xa0, 0x12, 0x9e, 0x30, 0xd2,
+ 0x51, 0x4b, 0x2e, 0x23, 0x6a, 0xb9, 0x0e, 0xc0, 0x89, 0xa4, 0xeb, 0x60, 0x1e, 0x55, 0x0d, 0x04,
+ 0x8f, 0xa9, 0x3f, 0x53, 0x75, 0xc3, 0x1b, 0xd9, 0xa7, 0xc4, 0x3d, 0x17, 0x99, 0x82, 0xda, 0xd4,
+ 0x9f, 0xed, 0x04, 0x30, 0x1a, 0x11, 0xd0, 0x5d, 0x95, 0xce, 0xe7, 0xd4, 0xd6, 0x83, 0xab, 0xc9,
+ 0xaa, 0x80, 0xed, 0xdb, 0x3a, 0x3d, 0x1b, 0x37, 0x44, 0x24, 0x17, 0xdf, 0xe9, 0xea, 0x1c, 0xda,
+ 0xcd, 0x7e, 0x36, 0x52, 0x0a, 0x9e, 0x68, 0x04, 0xcf, 0x46, 0xe8, 0x46, 0xe8, 0x8f, 0x1c, 0x75,
+ 0xea, 0x79, 0x22, 0xa2, 0x2d, 0xf9, 0x23, 0x67, 0xdf, 0xf3, 0x94, 0x2f, 0xa0, 0x2a, 0x9d, 0x92,
+ 0xd0, 0x16, 0xac, 0xc8, 0x47, 0xaa, 0x78, 0xac, 0xb1, 0x2c, 0x1d, 0xa1, 0x78, 0xa0, 0xa1, 0xcc,
+ 0xa0, 0xc4, 0xc3, 0x3f, 0xaa, 0x3b, 0x86, 0xa3, 0xc6, 0xd2, 0x2b, 0x65, 0xc3, 0x11, 0xc8, 0x0f,
+ 0xa0, 0x39, 0xd5, 0xbc, 0x6f, 0x55, 0x93, 0x58, 0x13, 0xff, 0x44, 0x9d, 0x1a, 0x96, 0x98, 0xb2,
+ 0x3a, 0x05, 0xef, 0x31, 0xe8, 0xbe, 0x61, 0xa5, 0xe8, 0xb4, 0x33, 0x11, 0x2c, 0xc8, 0x74, 0xda,
+ 0x99, 0xf2, 0x57, 0x39, 0x80, 0xe8, 0x6e, 0xeb, 0xb7, 0xbc, 0x80, 0xa4, 0x30, 0xd3, 0xf0, 0x7c,
+ 0xf6, 0x84, 0xaa, 0x82, 0xd9, 0x6f, 0x76, 0xa7, 0x12, 0xe5, 0x6e, 0x92, 0x77, 0x2a, 0x0c, 0x83,
+ 0x43, 0x0a, 0x65, 0x17, 0xca, 0xfb, 0x9a, 0x3f, 0x3a, 0xa1, 0xc2, 0xdc, 0x8d, 0x09, 0x23, 0x9d,
+ 0x61, 0x19, 0xc5, 0x1b, 0xee, 0x42, 0x5f, 0x40, 0xad, 0xeb, 0x0d, 0x34, 0xff, 0x84, 0x8f, 0x15,
+ 0x6d, 0xc5, 0x98, 0x49, 0xa7, 0x42, 0x99, 0x4a, 0xe2, 0xb9, 0x0e, 0x25, 0x3e, 0x77, 0x81, 0xf7,
+ 0xe4, 0x5f, 0xca, 0x7f, 0x16, 0x01, 0xb6, 0x6d, 0x4b, 0x37, 0x78, 0x76, 0xe7, 0x01, 0x88, 0xd7,
+ 0x37, 0x6a, 0x74, 0xa1, 0x88, 0x12, 0x92, 0x1e, 0x11, 0x1f, 0x57, 0x38, 0x15, 0x1d, 0xd6, 0x0f,
+ 0xa1, 0x16, 0x46, 0x5d, 0xb4, 0x51, 0x7e, 0x6e, 0xa3, 0x30, 0xad, 0x47, 0x9b, 0xfd, 0x04, 0x1a,
+ 0x9a, 0xa7, 0x3a, 0x9a, 0x7f, 0x22, 0x16, 0x55, 0x1c, 0x70, 0xd7, 0xb3, 0x87, 0x82, 0x6b, 0x9a,
+ 0x3c, 0xfc, 0x87, 0x50, 0x0d, 0x5a, 0xd3, 0x3e, 0x8b, 0xf3, 0x05, 0xe5, 0xcd, 0x68, 0x8f, 0x9f,
+ 0x87, 0xcf, 0x0a, 0xfd, 0x73, 0xd6, 0x6a, 0x71, 0x6e, 0xab, 0x5a, 0x48, 0x48, 0x1b, 0x7e, 0x09,
+ 0xcb, 0xe4, 0xcc, 0x57, 0xe3, 0x8d, 0x4b, 0x73, 0x1b, 0x37, 0xc9, 0x99, 0xbf, 0x2d, 0xb7, 0xa7,
+ 0x46, 0xe8, 0x7c, 0x6b, 0xa8, 0x2e, 0xf1, 0x66, 0xa6, 0xcf, 0xec, 0x6c, 0x11, 0x83, 0xcb, 0x9f,
+ 0x3e, 0xcc, 0x4c, 0x1f, 0x7d, 0x01, 0x10, 0xbd, 0x67, 0x10, 0x87, 0x46, 0x29, 0x26, 0x8a, 0xd6,
+ 0x87, 0x27, 0x2e, 0xd8, 0xb2, 0x56, 0xc2, 0xe7, 0x0e, 0xe8, 0x09, 0xac, 0x98, 0x9a, 0x3b, 0x21,
+ 0x09, 0x09, 0x2b, 0x73, 0x25, 0x5c, 0x66, 0xe4, 0xb2, 0x8c, 0xca, 0x09, 0x54, 0x42, 0xde, 0x68,
+ 0x05, 0x9a, 0xf8, 0xf0, 0xf9, 0xb0, 0xa7, 0x0e, 0x5f, 0x0d, 0x7a, 0xaa, 0x38, 0xe6, 0x6c, 0xc0,
+ 0x8a, 0x04, 0xec, 0x1f, 0x0c, 0x7b, 0xf8, 0xa0, 0x4b, 0x8f, 0x3d, 0x71, 0x44, 0xef, 0xa5, 0x40,
+ 0xe4, 0xd1, 0x2a, 0xb4, 0x24, 0xc4, 0xde, 0xe1, 0x76, 0x77, 0xaf, 0x55, 0x50, 0xc6, 0xd0, 0x0c,
+ 0x7b, 0xee, 0xf2, 0x07, 0xb2, 0x0f, 0x62, 0xca, 0x7c, 0x5d, 0x1e, 0x79, 0x8c, 0x50, 0xd2, 0xe7,
+ 0x5b, 0x50, 0x0d, 0x46, 0x6b, 0x84, 0x4f, 0x40, 0x64, 0x90, 0x72, 0x00, 0x95, 0x7d, 0xa2, 0x8b,
+ 0x1e, 0x7e, 0x10, 0xeb, 0x61, 0x43, 0x8e, 0xa5, 0xf4, 0x14, 0xef, 0x55, 0x58, 0x3c, 0xd5, 0xcc,
+ 0x59, 0xf0, 0x42, 0x8e, 0x7f, 0x28, 0x2a, 0x34, 0xbb, 0xde, 0xc0, 0x25, 0x0e, 0xb1, 0x02, 0xae,
+ 0x2d, 0x28, 0x68, 0x9e, 0x25, 0xc2, 0x14, 0xfa, 0x93, 0x9a, 0x19, 0xa5, 0xd0, 0xc2, 0x20, 0x85,
+ 0x7f, 0x21, 0x05, 0xea, 0x33, 0x8f, 0xa8, 0x26, 0x19, 0xfb, 0xea, 0xd4, 0xf6, 0x7c, 0xe1, 0xf6,
+ 0xab, 0x33, 0x8f, 0xec, 0x91, 0xb1, 0xbf, 0x6f, 0xb3, 0x6b, 0x93, 0xba, 0x48, 0x53, 0x0b, 0xf6,
+ 0x17, 0xbe, 0x36, 0xf2, 0x88, 0x39, 0x16, 0x77, 0x45, 0xec, 0xb7, 0x72, 0x17, 0x9a, 0x7b, 0x6c,
+ 0x9b, 0x71, 0xc9, 0x58, 0x30, 0x08, 0x07, 0x22, 0x02, 0x29, 0x3e, 0x90, 0x7f, 0x2d, 0xc0, 0x12,
+ 0x27, 0xf0, 0xa2, 0x4c, 0x99, 0xc6, 0x1f, 0x42, 0xa7, 0x1c, 0x25, 0x53, 0x0a, 0x4e, 0x2d, 0x32,
+ 0x65, 0x82, 0xf7, 0xe7, 0x50, 0x89, 0xce, 0x18, 0xdc, 0xe6, 0xaf, 0xcc, 0x5d, 0x38, 0x1c, 0xd1,
+ 0xa2, 0x3b, 0x50, 0x98, 0x12, 0x5d, 0x58, 0xfb, 0x4a, 0xc6, 0x4a, 0x60, 0x8a, 0x47, 0x3f, 0x02,
+ 0xa0, 0x16, 0xce, 0xe7, 0x5b, 0x18, 0xf8, 0x95, 0x98, 0x6f, 0x90, 0x97, 0x82, 0xd9, 0x39, 0x07,
+ 0xa0, 0x2f, 0xa1, 0x1e, 0x33, 0x57, 0x61, 0xe7, 0x17, 0x48, 0x57, 0x93, 0x2d, 0x16, 0x3d, 0x80,
+ 0x25, 0x71, 0x8f, 0x20, 0x8c, 0x5c, 0x52, 0x97, 0xd8, 0x02, 0xe1, 0x80, 0x8e, 0x0a, 0x2b, 0x36,
+ 0x7d, 0x97, 0x8c, 0x45, 0x46, 0x53, 0xea, 0x2f, 0xb1, 0x2e, 0x41, 0x3c, 0xe0, 0x92, 0x31, 0x7a,
+ 0x02, 0xcd, 0x84, 0xed, 0x8a, 0x1c, 0xe7, 0x05, 0xe2, 0x36, 0xe2, 0xe6, 0xab, 0xfc, 0x32, 0x07,
+ 0x95, 0xf0, 0xae, 0x37, 0xdc, 0x3d, 0x72, 0xd2, 0x46, 0xf6, 0x19, 0xc0, 0x28, 0x74, 0x22, 0x62,
+ 0xb5, 0x56, 0xb3, 0x1c, 0x0c, 0x96, 0xe8, 0xd0, 0x0f, 0x60, 0x89, 0xab, 0x85, 0x27, 0x56, 0x4b,
+ 0x3a, 0x83, 0x08, 0x05, 0xc2, 0x01, 0x85, 0xf2, 0x35, 0x94, 0x44, 0xe6, 0x32, 0x4b, 0x80, 0xf8,
+ 0x6b, 0x91, 0xfc, 0xe5, 0x5e, 0x8b, 0xfc, 0x7b, 0x0e, 0x5a, 0xc9, 0x24, 0x27, 0xda, 0x8c, 0x59,
+ 0xf2, 0x6a, 0x32, 0x1d, 0x2a, 0x99, 0xb1, 0xfc, 0x90, 0x3a, 0x7f, 0x89, 0x87, 0xd4, 0x19, 0xc5,
+ 0x2d, 0xb1, 0x17, 0x14, 0xc5, 0x37, 0xbd, 0xa0, 0x40, 0x1f, 0xc3, 0x92, 0x4e, 0xc6, 0x1a, 0x75,
+ 0xf2, 0x8b, 0x17, 0x19, 0x52, 0x40, 0xa5, 0xfc, 0x65, 0x0e, 0x0a, 0xd8, 0xd6, 0x50, 0x03, 0xf2,
+ 0x9a, 0x27, 0xac, 0x34, 0xaf, 0x79, 0xf4, 0xfc, 0xc4, 0x37, 0x58, 0x93, 0x04, 0x01, 0x51, 0x04,
+ 0xa0, 0x4e, 0x66, 0xaa, 0x31, 0x94, 0xb8, 0xd5, 0xe1, 0x5f, 0xd2, 0x95, 0x45, 0x31, 0x76, 0x8b,
+ 0x15, 0x5c, 0x1e, 0x2c, 0x5e, 0xfc, 0xe6, 0x53, 0xb9, 0xcb, 0x6f, 0x6e, 0x6c, 0xed, 0x4d, 0xef,
+ 0x38, 0xf9, 0x93, 0x35, 0x46, 0x18, 0x3d, 0x59, 0x73, 0x6d, 0x2d, 0xe3, 0xc9, 0x1a, 0x25, 0x62,
+ 0x28, 0xc5, 0x83, 0xc2, 0x0b, 0x77, 0x9c, 0xa9, 0x1d, 0x0d, 0xc8, 0xbb, 0x3c, 0xfb, 0x54, 0xc3,
+ 0x79, 0x57, 0x67, 0x21, 0x23, 0xcf, 0x7d, 0xbb, 0x3c, 0xf8, 0xaa, 0xe1, 0x32, 0x07, 0x60, 0xf6,
+ 0x90, 0x5f, 0x64, 0xd6, 0x5d, 0x9f, 0xad, 0x49, 0x0d, 0x97, 0x39, 0x00, 0xfb, 0x22, 0x49, 0xc9,
+ 0xb3, 0xba, 0x79, 0x43, 0x57, 0x7e, 0x93, 0x83, 0x12, 0xbf, 0x1e, 0x4e, 0xcd, 0xf1, 0x55, 0xe0,
+ 0x5b, 0xa8, 0x94, 0xf9, 0x2a, 0x73, 0x40, 0x5f, 0xa7, 0x5b, 0x36, 0x8d, 0xf6, 0x88, 0xc5, 0xe3,
+ 0xe6, 0x02, 0xdf, 0xb2, 0x39, 0x88, 0xc5, 0xcd, 0xf7, 0xa0, 0x25, 0x08, 0x84, 0x4f, 0x16, 0x0a,
+ 0x52, 0xc1, 0x4d, 0x0e, 0xef, 0x06, 0xe0, 0xd8, 0x8d, 0xd0, 0x62, 0xe2, 0x46, 0xe8, 0x43, 0x40,
+ 0x74, 0x5f, 0x60, 0xb9, 0x3e, 0xc7, 0x24, 0x2a, 0xbf, 0x6d, 0x2c, 0xf1, 0xe4, 0xce, 0xcc, 0x23,
+ 0xfb, 0x02, 0x31, 0x60, 0xaf, 0xf5, 0xff, 0x99, 0x1e, 0x47, 0xb4, 0x63, 0x93, 0xf4, 0xad, 0xb1,
+ 0xfd, 0x3b, 0xb9, 0x18, 0xbc, 0x0b, 0x4d, 0x6b, 0x36, 0x55, 0xa5, 0x1b, 0x3f, 0x71, 0x1a, 0x6b,
+ 0x58, 0xb3, 0xa9, 0x7c, 0x63, 0x7a, 0x05, 0xca, 0x94, 0x90, 0x15, 0x38, 0x89, 0xc3, 0xbf, 0x35,
+ 0x9b, 0xb2, 0x4b, 0xf3, 0xdb, 0x50, 0xa3, 0xa8, 0x30, 0x13, 0xc3, 0x8f, 0x5b, 0x55, 0x6b, 0x36,
+ 0xed, 0x0a, 0x90, 0xf2, 0x13, 0xf6, 0x42, 0x00, 0x1b, 0xc7, 0x74, 0x20, 0x81, 0xb6, 0x05, 0x77,
+ 0x47, 0xa9, 0x07, 0x52, 0xe1, 0x90, 0xf9, 0xdd, 0x91, 0xf2, 0x05, 0xab, 0xb9, 0x0b, 0x5b, 0x0b,
+ 0x15, 0xbc, 0x6c, 0xf3, 0xfb, 0xdb, 0x50, 0x0e, 0x66, 0x08, 0x01, 0x94, 0x76, 0xf7, 0x0e, 0x9f,
+ 0x74, 0xf7, 0x5a, 0x0b, 0xa8, 0x02, 0x8b, 0x3c, 0x46, 0x61, 0x19, 0x9c, 0xee, 0xce, 0xcf, 0xd5,
+ 0xfe, 0x41, 0x2b, 0x8f, 0xaa, 0xb0, 0x44, 0x7f, 0x1f, 0x3e, 0x1f, 0xb6, 0x0a, 0x68, 0x09, 0x0a,
+ 0x2f, 0xf0, 0xd3, 0x56, 0xf1, 0xbe, 0x0f, 0x55, 0xe9, 0x0c, 0xc1, 0x52, 0x3e, 0xb8, 0xf7, 0xb4,
+ 0xff, 0xb2, 0xb5, 0x80, 0x6a, 0x50, 0x3e, 0xe8, 0xf5, 0x77, 0x9f, 0x3d, 0x39, 0xc4, 0xad, 0x1c,
+ 0x6d, 0x31, 0xec, 0xee, 0x0a, 0x3e, 0x47, 0xea, 0xa0, 0x3b, 0x7c, 0xd6, 0x2a, 0xa0, 0x3a, 0x54,
+ 0xb6, 0x0f, 0xf7, 0xf7, 0x9f, 0x1f, 0xf4, 0x87, 0xaf, 0x5a, 0x45, 0xb4, 0x0c, 0xf5, 0xde, 0xcb,
+ 0xa1, 0x1a, 0x81, 0x16, 0x69, 0x0c, 0xb6, 0xd7, 0xc5, 0xbb, 0x3d, 0x09, 0x58, 0xba, 0x7f, 0x0f,
+ 0x2a, 0xe1, 0x61, 0x81, 0xe5, 0x9d, 0x0f, 0x5e, 0xc9, 0x09, 0x68, 0x80, 0x52, 0xff, 0xe0, 0x45,
+ 0x0f, 0x0f, 0x5b, 0xf9, 0xfb, 0xf7, 0xa1, 0x95, 0x3c, 0x0a, 0xa0, 0x12, 0xe4, 0x7b, 0x5f, 0xb7,
+ 0x16, 0xe8, 0xdf, 0xdd, 0x5e, 0x2b, 0x47, 0xff, 0xee, 0xf5, 0x5a, 0xf9, 0xfb, 0x1f, 0x8b, 0xb3,
+ 0x9e, 0xd8, 0xda, 0xa3, 0xd4, 0x36, 0x9d, 0x87, 0xed, 0xed, 0xde, 0x60, 0xc8, 0x99, 0xe3, 0xde,
+ 0xcf, 0x7b, 0xdb, 0x94, 0xf9, 0x73, 0x58, 0xc9, 0x08, 0xcd, 0xe8, 0x30, 0x42, 0x69, 0xd5, 0xee,
+ 0xce, 0x4e, 0x6b, 0x81, 0xc6, 0x80, 0x11, 0x08, 0xf7, 0xf6, 0x0f, 0x5f, 0xd0, 0x8e, 0xd7, 0x60,
+ 0x59, 0x86, 0x8a, 0x9c, 0xf9, 0xfd, 0x8f, 0xa0, 0x1e, 0x8b, 0xc7, 0xe8, 0x9c, 0xed, 0xf7, 0x76,
+ 0xd4, 0xfd, 0x43, 0xca, 0xaa, 0x09, 0x55, 0xfa, 0x11, 0x90, 0xe7, 0xee, 0x7f, 0x08, 0x10, 0x39,
+ 0xfd, 0xb0, 0xca, 0x8a, 0x4e, 0xc2, 0xfe, 0xe0, 0x10, 0x0b, 0x99, 0x7b, 0x2f, 0xd9, 0xef, 0xfc,
+ 0xc3, 0xff, 0xb8, 0x09, 0xe5, 0x5d, 0xaa, 0x13, 0x5d, 0xc7, 0x40, 0x7b, 0x50, 0x95, 0xde, 0x88,
+ 0xa0, 0x6b, 0xb1, 0xad, 0x28, 0xf1, 0xf4, 0xa4, 0x73, 0x7d, 0x0e, 0x56, 0x5c, 0xfd, 0x2e, 0xa0,
+ 0x3e, 0x40, 0xf4, 0x8a, 0x04, 0x5d, 0x95, 0xc9, 0x13, 0x0f, 0x4e, 0x3a, 0xd7, 0xb2, 0x91, 0x21,
+ 0xab, 0xa7, 0x50, 0x09, 0xdf, 0xce, 0x20, 0xe9, 0x58, 0x97, 0x7c, 0x64, 0xd3, 0xb9, 0x9a, 0x89,
+ 0x0b, 0xf9, 0xec, 0x41, 0x55, 0x2a, 0xfa, 0x93, 0x07, 0x98, 0xae, 0x22, 0x94, 0x07, 0x98, 0x55,
+ 0x29, 0xb8, 0x80, 0x9e, 0x43, 0x23, 0x5e, 0xee, 0x87, 0x6e, 0xca, 0x67, 0xe9, 0x8c, 0x2a, 0xc2,
+ 0xce, 0xad, 0xf9, 0x04, 0xb2, 0x90, 0x52, 0x81, 0xab, 0x2c, 0x64, 0xba, 0xa6, 0x56, 0x16, 0x32,
+ 0xa3, 0x2a, 0x56, 0x59, 0x40, 0x18, 0xea, 0xb1, 0x3a, 0x3a, 0x74, 0x23, 0xe6, 0x12, 0xd3, 0x1c,
+ 0x6f, 0xce, 0xc5, 0x87, 0x3c, 0xff, 0x08, 0x96, 0x53, 0xf5, 0x79, 0x48, 0x79, 0x73, 0x9d, 0x60,
+ 0xe7, 0x7b, 0x17, 0xd2, 0x84, 0xfc, 0x7f, 0x1f, 0x5a, 0xc9, 0x3a, 0x3c, 0x74, 0x5b, 0x6a, 0x9a,
+ 0x5d, 0xfe, 0xd7, 0x51, 0x2e, 0x22, 0x91, 0x57, 0x2d, 0x5e, 0x95, 0x27, 0xaf, 0x5a, 0x66, 0x89,
+ 0x9f, 0xbc, 0x6a, 0x73, 0x0a, 0xfa, 0x16, 0xd0, 0x4b, 0x68, 0x26, 0x0a, 0xef, 0x90, 0xbc, 0xd8,
+ 0x99, 0xd5, 0x7e, 0x9d, 0xdb, 0x17, 0x50, 0x84, 0x9c, 0xbf, 0x80, 0x12, 0x77, 0xec, 0x68, 0x23,
+ 0xb6, 0xd8, 0xd1, 0xb3, 0x8e, 0x4e, 0x3b, 0x8d, 0x90, 0xd5, 0x49, 0x7a, 0x9a, 0x21, 0xab, 0x53,
+ 0xfa, 0x7d, 0x88, 0xac, 0x4e, 0x59, 0xef, 0x39, 0x16, 0xd0, 0xcf, 0x60, 0x49, 0x94, 0x16, 0xa3,
+ 0x76, 0xcc, 0x3e, 0xa4, 0x12, 0xe2, 0xce, 0x95, 0x0c, 0x8c, 0xec, 0x16, 0xa2, 0x42, 0x5e, 0xd9,
+ 0x2d, 0xa4, 0x4a, 0x91, 0x65, 0xb7, 0x90, 0x51, 0xfb, 0xbb, 0x80, 0x76, 0x00, 0xa2, 0xd2, 0x33,
+ 0x99, 0x55, 0xaa, 0x20, 0xad, 0x93, 0xfd, 0x8a, 0x47, 0x59, 0xf8, 0x24, 0x87, 0x1e, 0x87, 0xa5,
+ 0x75, 0xd1, 0x35, 0x9e, 0xb4, 0x51, 0x86, 0xf5, 0xe2, 0x9d, 0x44, 0xd1, 0x2f, 0x6b, 0xfc, 0x14,
+ 0x2a, 0x61, 0xad, 0xa3, 0xec, 0x99, 0x92, 0x95, 0x96, 0xb2, 0x67, 0x4a, 0x17, 0x47, 0xf2, 0x59,
+ 0x09, 0x2b, 0x21, 0x63, 0xb3, 0x92, 0x2c, 0x9a, 0x8c, 0xcd, 0x4a, 0xba, 0x78, 0x72, 0x01, 0x3d,
+ 0x83, 0x4a, 0x58, 0xbd, 0x28, 0x8b, 0x94, 0xac, 0xa9, 0x94, 0x45, 0x4a, 0x97, 0x3b, 0x2e, 0x6c,
+ 0xe6, 0xa8, 0xe6, 0xf1, 0x1a, 0x42, 0x59, 0xf3, 0x62, 0xe5, 0x8a, 0x9d, 0x76, 0x1a, 0x21, 0x7b,
+ 0xed, 0xb0, 0x5c, 0x50, 0x16, 0x24, 0x59, 0x85, 0xd8, 0xb9, 0x9a, 0x89, 0x93, 0x75, 0x4e, 0x14,
+ 0x48, 0xa1, 0x84, 0xa2, 0x47, 0x95, 0x35, 0xb2, 0xce, 0x25, 0xaa, 0xa9, 0x42, 0xad, 0x4d, 0x72,
+ 0x88, 0x17, 0x4e, 0x25, 0xb4, 0x36, 0xc1, 0x21, 0xd4, 0x5a, 0xc6, 0x24, 0x25, 0xb0, 0xcc, 0xe7,
+ 0x5a, 0x36, 0x52, 0x66, 0x15, 0xd5, 0x2e, 0xa1, 0x94, 0x5e, 0xcc, 0x61, 0x95, 0x51, 0xee, 0xc4,
+ 0x6c, 0x5b, 0x2a, 0x60, 0x42, 0x69, 0xcd, 0x90, 0x99, 0x5d, 0x9f, 0x83, 0x95, 0xd7, 0x2b, 0x2c,
+ 0x3f, 0x92, 0xd7, 0x2b, 0x59, 0xc5, 0x24, 0xaf, 0x57, 0xba, 0x5e, 0x89, 0x6d, 0x39, 0xb1, 0x52,
+ 0x26, 0x79, 0xcb, 0xc9, 0xaa, 0x8a, 0x92, 0xb7, 0x9c, 0xec, 0x1a, 0xa8, 0xd0, 0x09, 0xda, 0x5a,
+ 0xd2, 0x09, 0x86, 0xe7, 0xb2, 0xa4, 0x13, 0x8c, 0xce, 0x61, 0x7c, 0xa2, 0xa4, 0xb2, 0x23, 0x94,
+ 0x9a, 0x57, 0xb9, 0xb4, 0x4a, 0x9e, 0xa8, 0xac, 0x5a, 0xa5, 0x05, 0x61, 0x17, 0xf4, 0xdc, 0x16,
+ 0xb7, 0x8b, 0xa8, 0x64, 0x28, 0x61, 0x17, 0x72, 0x59, 0x90, 0x64, 0x17, 0x94, 0x43, 0xca, 0x2e,
+ 0x24, 0x26, 0x57, 0x33, 0x71, 0x89, 0x39, 0x49, 0x88, 0x11, 0x2b, 0xa3, 0x4a, 0xcc, 0x49, 0xbc,
+ 0x39, 0x66, 0x07, 0x5b, 0xe9, 0x5e, 0xe0, 0x46, 0x8c, 0x38, 0x55, 0x50, 0x23, 0x2f, 0x53, 0x66,
+ 0x05, 0x12, 0xe7, 0x19, 0xab, 0x0c, 0x92, 0x79, 0x66, 0x95, 0x1c, 0xc9, 0x3c, 0xb3, 0x4b, 0x8a,
+ 0x58, 0x34, 0x90, 0xac, 0xff, 0x91, 0xa3, 0x81, 0x39, 0x05, 0x47, 0x72, 0x34, 0x30, 0xb7, 0x7c,
+ 0x88, 0x85, 0x32, 0xa9, 0xe2, 0x1f, 0x39, 0x94, 0x99, 0x57, 0x5d, 0x24, 0x87, 0x32, 0xf3, 0xab,
+ 0x87, 0x16, 0xd0, 0x21, 0xd4, 0xe4, 0x42, 0x21, 0x14, 0x8f, 0xd7, 0x92, 0x35, 0x31, 0x9d, 0x1b,
+ 0xf3, 0xd0, 0x32, 0x43, 0xb9, 0xc4, 0x07, 0xc5, 0xa3, 0xd4, 0x8b, 0x18, 0x66, 0x56, 0x06, 0xf1,
+ 0xc0, 0x25, 0x5e, 0xbc, 0x83, 0x52, 0x51, 0x6a, 0x8a, 0xed, 0xed, 0x0b, 0x28, 0xe4, 0x85, 0x4b,
+ 0x56, 0xeb, 0xc8, 0x0b, 0x37, 0xa7, 0x2e, 0xa8, 0xa3, 0x5c, 0x44, 0x92, 0x38, 0x12, 0x88, 0xe4,
+ 0x5a, 0xfc, 0x48, 0x10, 0xab, 0x3d, 0x49, 0x1c, 0x09, 0x12, 0x85, 0x1e, 0x8c, 0x4f, 0x58, 0xdb,
+ 0x20, 0xf3, 0x49, 0x16, 0xfd, 0xc8, 0x7c, 0xd2, 0x65, 0x39, 0x6c, 0x5d, 0xe4, 0xaa, 0x04, 0x79,
+ 0x5d, 0x32, 0xea, 0x75, 0xe4, 0x75, 0xc9, 0x2c, 0xa5, 0x11, 0x81, 0xbb, 0x54, 0x66, 0x10, 0x0f,
+ 0xdc, 0xd3, 0x45, 0x36, 0xf1, 0xc0, 0x3d, 0xab, 0xaa, 0x65, 0x01, 0xe9, 0xac, 0x9a, 0x2d, 0x95,
+ 0x3d, 0xfc, 0x7e, 0xc6, 0x14, 0xa5, 0x6a, 0x26, 0x3a, 0x77, 0xde, 0x40, 0x25, 0xf7, 0x92, 0x51,
+ 0x2e, 0x22, 0xf7, 0x32, 0xbf, 0x4e, 0x45, 0xee, 0xe5, 0xa2, 0x9a, 0x93, 0x05, 0x34, 0x0d, 0x6a,
+ 0xda, 0x52, 0x1d, 0xdd, 0xcd, 0x9e, 0xdb, 0x74, 0x5f, 0x9b, 0x6f, 0x26, 0x0c, 0xbb, 0x73, 0xc2,
+ 0x42, 0xb6, 0x74, 0xf2, 0x75, 0xce, 0xc4, 0xa7, 0x3b, 0xbc, 0x77, 0x09, 0x4a, 0x39, 0x4e, 0x88,
+ 0x12, 0x3a, 0xe8, 0x6a, 0x32, 0xc4, 0x97, 0x92, 0x44, 0x9d, 0x6b, 0xd9, 0xc8, 0x80, 0xd5, 0x71,
+ 0x89, 0xfd, 0x83, 0xa6, 0x4f, 0xff, 0x27, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x53, 0xb8, 0xe2, 0xaf,
+ 0x49, 0x00, 0x00,
}
diff --git a/vendor/github.com/osrg/gobgp/api/gobgp.proto b/vendor/github.com/osrg/gobgp/api/gobgp.proto
index ded9487d..9bee4501 100644
--- a/vendor/github.com/osrg/gobgp/api/gobgp.proto
+++ b/vendor/github.com/osrg/gobgp/api/gobgp.proto
@@ -553,8 +553,6 @@ message Peer {
Timers timers = 7;
Transport transport = 8;
RouteServer route_server = 9;
- GracefulRestart graceful_restart = 10;
- repeated AfiSafi afi_safis = 11;
}
message ApplyPolicy {
@@ -588,9 +586,6 @@ message PeerConf {
repeated bytes remote_cap = 11;
repeated bytes local_cap = 12;
string id = 13;
- // Note: Regarding to the consistency with OpenConfig mode, list of
- // PrefixLimit should be removed from here, and list of PrefixLimit in
- // AfiSafi should be used instead.
repeated PrefixLimit prefix_limits = 14;
string local_address = 15;
string neighbor_interface = 16;
@@ -694,163 +689,6 @@ message RouteServer {
bool route_server_client = 1;
}
-message GracefulRestart {
- bool enabled = 1;
- uint32 restart_time = 2;
- bool helper_only = 3;
- uint32 deferral_time = 4;
- bool notification_enabled = 5;
- bool longlived_enabled = 6;
-}
-
-message MpGracefulRestartConfig {
- bool enabled = 1;
-}
-
-message MpGracefulRestartState {
- bool enabled = 1;
- bool received = 2;
- bool advertised = 3;
- bool end_of_rib_received = 4;
- bool end_of_rib_sent = 5;
-}
-message MpGracefulRestart {
- MpGracefulRestartConfig config = 1;
- MpGracefulRestartState state = 2;
-}
-
-message AfiSafiConfig {
- uint32 family = 1;
- bool enabled = 2;
-}
-
-message AfiSafiState {
- uint32 family = 1;
- bool enabled = 2;
- uint32 total_paths = 3;
- uint32 total_prefixes = 4;
-}
-
-message RouteSelectionOptionsConfig {
- bool always_compare_med = 1;
- bool ignore_as_path_length = 2;
- bool external_compare_router_id = 3;
- bool advertise_inactive_routes = 4;
- bool enable_aigp = 5;
- bool ignore_next_hop_igp_metric = 6;
-}
-
-message RouteSelectionOptionsState {
- bool always_compare_med = 1;
- bool ignore_as_path_length = 2;
- bool external_compare_router_id = 3;
- bool advertise_inactive_routes = 4;
- bool enable_aigp = 5;
- bool ignore_next_hop_igp_metric = 6;
-}
-
-message RouteSelectionOptions {
- RouteSelectionOptionsConfig config = 1;
- RouteSelectionOptionsState state = 2;
-}
-
-message UseMultiplePathsConfig {
- bool enabled = 1;
-}
-
-message UseMultiplePathsState {
- bool enabled = 1;
-}
-
-message EbgpConfig {
- bool allow_multiple_as = 1;
- uint32 maximum_paths = 2;
-}
-
-message EbgpState {
- bool allow_multiple_as = 1;
- uint32 maximum_paths = 2;
-}
-
-message Ebgp {
- EbgpConfig config = 1;
- EbgpState state = 2;
-}
-
-message IbgpConfig {
- uint32 maximum_paths = 1;
-}
-
-message IbgpState {
- uint32 maximum_paths = 1;
-}
-
-message Ibgp {
- IbgpConfig config = 1;
- IbgpState state = 2;
-}
-
-message UseMultiplePaths {
- UseMultiplePathsConfig config = 1;
- UseMultiplePathsState state = 2;
- Ebgp ebgp = 3;
- Ibgp ibgp = 4;
-}
-
-message RouteTargetMembershipConfig {
- uint32 deferral_time = 1;
-}
-
-message RouteTargetMembershipState {
- uint32 deferral_time = 1;
-}
-
-message RouteTargetMembership {
- RouteTargetMembershipConfig config = 1;
- RouteTargetMembershipState state = 2;
-}
-
-message LongLivedGracefulRestartConfig {
- bool enabled = 1;
- uint32 restart_time = 2;
-}
-
-message LongLivedGracefulRestartState {
- bool enabled = 1;
- bool received = 2;
- bool advertised = 3;
- uint32 peer_restart_time = 4;
- bool peer_restart_timer_expired = 5;
-}
-
-message LongLivedGracefulRestart {
- LongLivedGracefulRestartConfig config = 1;
- LongLivedGracefulRestartState state = 2;
-}
-
-message AfiSafi {
- MpGracefulRestart mp_graceful_restart = 1;
- AfiSafiConfig config = 2;
- ApplyPolicy apply_policy = 3;
- // TODO:
- // Support the following structures:
- // - Ipv4Unicast
- // - Ipv6Unicast
- // - Ipv4LabelledUnicast
- // - Ipv6LabelledUnicast
- // - L3vpnIpv4Unicast
- // - L3vpnIpv6Unicast
- // - L3vpnIpv4Multicast
- // - L3vpnIpv6Multicast
- // - L2vpnVpls
- // - L2vpnEvpn
- RouteSelectionOptions route_selection_options = 4;
- UseMultiplePaths use_multiple_paths = 5;
- PrefixLimit prefix_limits = 6;
- RouteTargetMembership route_target_membership = 7;
- LongLivedGracefulRestart long_lived_graceful_restart = 8;
-}
-
message Prefix {
string ip_prefix = 1;
uint32 mask_length_min = 2;
diff --git a/vendor/github.com/osrg/gobgp/api/grpc_server.go b/vendor/github.com/osrg/gobgp/api/grpc_server.go
index cb83b132..a6306580 100644
--- a/vendor/github.com/osrg/gobgp/api/grpc_server.go
+++ b/vendor/github.com/osrg/gobgp/api/grpc_server.go
@@ -26,11 +26,11 @@ import (
"sync"
"time"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/server"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
@@ -88,138 +88,44 @@ func (s *Server) Serve() error {
return nil
}
-func NewMpGracefulRestartFromConfigStruct(c *config.MpGracefulRestart) *MpGracefulRestart {
- return &MpGracefulRestart{
- Config: &MpGracefulRestartConfig{
- Enabled: c.Config.Enabled,
- },
- }
-}
-
-func NewAfiSafiConfigFromConfigStruct(c *config.AfiSafiConfig) *AfiSafiConfig {
- return &AfiSafiConfig{
- Family: uint32(bgp.AddressFamilyValueMap[string(c.AfiSafiName)]),
- Enabled: c.Enabled,
- }
-}
-
-func NewApplyPolicyFromConfigStruct(c *config.ApplyPolicy) *ApplyPolicy {
- applyPolicy := &ApplyPolicy{
- ImportPolicy: &PolicyAssignment{
- Type: PolicyType_IMPORT,
- Default: RouteAction(c.Config.DefaultImportPolicy.ToInt()),
- },
- ExportPolicy: &PolicyAssignment{
- Type: PolicyType_EXPORT,
- Default: RouteAction(c.Config.DefaultExportPolicy.ToInt()),
- },
- InPolicy: &PolicyAssignment{
- Type: PolicyType_IN,
- Default: RouteAction(c.Config.DefaultInPolicy.ToInt()),
- },
- }
-
- for _, pname := range c.Config.ImportPolicyList {
- applyPolicy.ImportPolicy.Policies = append(applyPolicy.ImportPolicy.Policies, &Policy{Name: pname})
- }
- for _, pname := range c.Config.ExportPolicyList {
- applyPolicy.ExportPolicy.Policies = append(applyPolicy.ExportPolicy.Policies, &Policy{Name: pname})
- }
- for _, pname := range c.Config.InPolicyList {
- applyPolicy.InPolicy.Policies = append(applyPolicy.InPolicy.Policies, &Policy{Name: pname})
- }
-
- return applyPolicy
-}
-
-func NewRouteSelectionOptionsFromConfigStruct(c *config.RouteSelectionOptions) *RouteSelectionOptions {
- return &RouteSelectionOptions{
- Config: &RouteSelectionOptionsConfig{
- AlwaysCompareMed: c.Config.AlwaysCompareMed,
- IgnoreAsPathLength: c.Config.IgnoreAsPathLength,
- ExternalCompareRouterId: c.Config.ExternalCompareRouterId,
- AdvertiseInactiveRoutes: c.Config.AdvertiseInactiveRoutes,
- EnableAigp: c.Config.EnableAigp,
- IgnoreNextHopIgpMetric: c.Config.IgnoreNextHopIgpMetric,
- },
- }
-}
-
-func NewUseMultiplePathsFromConfigStruct(c *config.UseMultiplePaths) *UseMultiplePaths {
- return &UseMultiplePaths{
- Config: &UseMultiplePathsConfig{
- Enabled: c.Config.Enabled,
- },
- Ebgp: &Ebgp{
- Config: &EbgpConfig{
- AllowMultipleAs: c.Ebgp.Config.AllowMultipleAs,
- MaximumPaths: c.Ebgp.Config.MaximumPaths,
- },
- },
- Ibgp: &Ibgp{
- Config: &IbgpConfig{
- MaximumPaths: c.Ibgp.Config.MaximumPaths,
- },
- },
- }
-}
-
-func NewPrefixLimitFromConfigStruct(c *config.AfiSafi) *PrefixLimit {
- family, err := bgp.GetRouteFamily(string(c.Config.AfiSafiName))
- if err != nil || c.PrefixLimit.Config.MaxPrefixes == 0 {
- return nil
- }
-
- return &PrefixLimit{
- Family: uint32(family),
- MaxPrefixes: c.PrefixLimit.Config.MaxPrefixes,
- ShutdownThresholdPct: uint32(c.PrefixLimit.Config.ShutdownThresholdPct),
- }
-}
-
-func NewRouteTargetMembershipFromConfigStruct(c *config.RouteTargetMembership) *RouteTargetMembership {
- return &RouteTargetMembership{
- Config: &RouteTargetMembershipConfig{
- DeferralTime: uint32(c.Config.DeferralTime),
- },
- }
-}
-
-func NewLongLivedGracefulRestartFromConfigStruct(c *config.LongLivedGracefulRestart) *LongLivedGracefulRestart {
- return &LongLivedGracefulRestart{
- Config: &LongLivedGracefulRestartConfig{
- Enabled: c.Config.Enabled,
- RestartTime: c.Config.RestartTime,
- },
- }
-}
-
-func NewAfiSafiFromConfigStruct(c *config.AfiSafi) *AfiSafi {
- return &AfiSafi{
- MpGracefulRestart: NewMpGracefulRestartFromConfigStruct(&c.MpGracefulRestart),
- Config: NewAfiSafiConfigFromConfigStruct(&c.Config),
- ApplyPolicy: NewApplyPolicyFromConfigStruct(&c.ApplyPolicy),
- RouteSelectionOptions: NewRouteSelectionOptionsFromConfigStruct(&c.RouteSelectionOptions),
- UseMultiplePaths: NewUseMultiplePathsFromConfigStruct(&c.UseMultiplePaths),
- PrefixLimits: NewPrefixLimitFromConfigStruct(c),
- RouteTargetMembership: NewRouteTargetMembershipFromConfigStruct(&c.RouteTargetMembership),
- LongLivedGracefulRestart: NewLongLivedGracefulRestartFromConfigStruct(&c.LongLivedGracefulRestart),
- }
-}
-
func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
- families := make([]uint32, 0, len(pconf.AfiSafis))
- prefixLimits := make([]*PrefixLimit, 0, len(pconf.AfiSafis))
- afiSafis := make([]*AfiSafi, 0, len(pconf.AfiSafis))
+ var families []uint32
for _, f := range pconf.AfiSafis {
if family, ok := bgp.AddressFamilyValueMap[string(f.Config.AfiSafiName)]; ok {
families = append(families, uint32(family))
}
- if prefixLimit := NewPrefixLimitFromConfigStruct(&f); prefixLimit != nil {
- prefixLimits = append(prefixLimits, prefixLimit)
- }
- if afiSafi := NewAfiSafiFromConfigStruct(&f); afiSafi != nil {
- afiSafis = append(afiSafis, afiSafi)
+ }
+ applyPolicy := &ApplyPolicy{}
+ applyPolicy.ImportPolicy = &PolicyAssignment{
+ Type: PolicyType_IMPORT,
+ Default: RouteAction(pconf.ApplyPolicy.Config.DefaultImportPolicy.ToInt()),
+ }
+ for _, pname := range pconf.ApplyPolicy.Config.ImportPolicyList {
+ applyPolicy.ImportPolicy.Policies = append(applyPolicy.ImportPolicy.Policies, &Policy{Name: pname})
+ }
+ applyPolicy.ExportPolicy = &PolicyAssignment{
+ Type: PolicyType_EXPORT,
+ Default: RouteAction(pconf.ApplyPolicy.Config.DefaultExportPolicy.ToInt()),
+ }
+ for _, pname := range pconf.ApplyPolicy.Config.ExportPolicyList {
+ applyPolicy.ExportPolicy.Policies = append(applyPolicy.ExportPolicy.Policies, &Policy{Name: pname})
+ }
+ applyPolicy.InPolicy = &PolicyAssignment{
+ Type: PolicyType_IN,
+ Default: RouteAction(pconf.ApplyPolicy.Config.DefaultInPolicy.ToInt()),
+ }
+ for _, pname := range pconf.ApplyPolicy.Config.InPolicyList {
+ applyPolicy.InPolicy.Policies = append(applyPolicy.InPolicy.Policies, &Policy{Name: pname})
+ }
+ prefixLimits := make([]*PrefixLimit, 0, len(pconf.AfiSafis))
+ for _, family := range pconf.AfiSafis {
+ if c := family.PrefixLimit.Config; c.MaxPrefixes > 0 {
+ k, _ := bgp.GetRouteFamily(string(family.Config.AfiSafiName))
+ prefixLimits = append(prefixLimits, &PrefixLimit{
+ Family: uint32(k),
+ MaxPrefixes: c.MaxPrefixes,
+ ShutdownThresholdPct: uint32(c.ShutdownThresholdPct),
+ })
}
}
@@ -230,13 +136,13 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
localAddress = pconf.Transport.State.LocalAddress
}
var remoteCap, localCap [][]byte
- for _, c := range pconf.State.RemoteCapabilityList {
- cBuf, _ := c.Serialize()
- remoteCap = append(remoteCap, cBuf)
+ for _, cap := range pconf.State.RemoteCapabilityList {
+ c, _ := cap.Serialize()
+ remoteCap = append(remoteCap, c)
}
- for _, c := range pconf.State.LocalCapabilityList {
- cBuf, _ := c.Serialize()
- localCap = append(localCap, cBuf)
+ for _, cap := range pconf.State.LocalCapabilityList {
+ c, _ := cap.Serialize()
+ localCap = append(localCap, c)
}
var removePrivateAs PeerConf_RemovePrivateAs
switch pconf.Config.RemovePrivateAs {
@@ -247,7 +153,7 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
}
return &Peer{
Families: families,
- ApplyPolicy: NewApplyPolicyFromConfigStruct(&pconf.ApplyPolicy),
+ ApplyPolicy: applyPolicy,
Conf: &PeerConf{
NeighborAddress: pconf.Config.NeighborAddress,
Id: s.RemoteRouterId,
@@ -291,12 +197,11 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
TOTAL: s.Messages.Sent.Total,
},
},
- Received: s.AdjTable.Received,
- Accepted: s.AdjTable.Accepted,
- Advertised: s.AdjTable.Advertised,
- PeerAs: s.PeerAs,
- PeerType: uint32(s.PeerType.ToInt()),
- NeighborAddress: pconf.State.NeighborAddress,
+ Received: s.AdjTable.Received,
+ Accepted: s.AdjTable.Accepted,
+ Advertised: s.AdjTable.Advertised,
+ PeerAs: s.PeerAs,
+ PeerType: uint32(s.PeerType.ToInt()),
},
Timers: &Timers{
Config: &TimersConfig{
@@ -318,19 +223,10 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
RouteServer: &RouteServer{
RouteServerClient: pconf.RouteServer.Config.RouteServerClient,
},
- GracefulRestart: &GracefulRestart{
- Enabled: pconf.GracefulRestart.Config.Enabled,
- RestartTime: uint32(pconf.GracefulRestart.Config.RestartTime),
- HelperOnly: pconf.GracefulRestart.Config.HelperOnly,
- DeferralTime: uint32(pconf.GracefulRestart.Config.DeferralTime),
- NotificationEnabled: pconf.GracefulRestart.Config.NotificationEnabled,
- LonglivedEnabled: pconf.GracefulRestart.Config.LongLivedEnabled,
- },
Transport: &Transport{
RemotePort: uint32(pconf.Transport.Config.RemotePort),
LocalAddress: pconf.Transport.Config.LocalAddress,
},
- AfiSafis: afiSafis,
}
}
@@ -955,114 +851,10 @@ func (s *Server) DeleteVrf(ctx context.Context, arg *DeleteVrfRequest) (*DeleteV
return &DeleteVrfResponse{}, s.bgpServer.DeleteVrf(arg.Vrf.Name)
}
-func ReadMpGracefulRestartFromAPIStruct(c *config.MpGracefulRestart, a *MpGracefulRestart) {
- if c == nil || a == nil {
- return
- }
- if a.Config != nil {
- c.Config.Enabled = a.Config.Enabled
- }
-}
-
-func ReadAfiSafiConfigFromAPIStruct(c *config.AfiSafiConfig, a *AfiSafiConfig) {
- if c == nil || a == nil {
- return
- }
- c.Enabled = a.Enabled
-}
-
-func ReadPrefixLimitFromAPIStruct(c *config.PrefixLimit, a *PrefixLimit) {
- if c == nil || a == nil {
- return
- }
- c.Config.MaxPrefixes = a.MaxPrefixes
- c.Config.ShutdownThresholdPct = config.Percentage(a.ShutdownThresholdPct)
-}
-
-func ReadApplyPolicyFromAPIStruct(c *config.ApplyPolicy, a *ApplyPolicy) {
- if c == nil || a == nil {
- return
- }
- if a.ImportPolicy != nil {
- c.Config.DefaultImportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ImportPolicy.Default)]
- for _, p := range a.ImportPolicy.Policies {
- c.Config.ImportPolicyList = append(c.Config.ImportPolicyList, p.Name)
- }
- }
- if a.ExportPolicy != nil {
- c.Config.DefaultExportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ExportPolicy.Default)]
- for _, p := range a.ExportPolicy.Policies {
- c.Config.ExportPolicyList = append(c.Config.ExportPolicyList, p.Name)
- }
- }
- if a.InPolicy != nil {
- c.Config.DefaultInPolicy = config.IntToDefaultPolicyTypeMap[int(a.InPolicy.Default)]
- for _, p := range a.InPolicy.Policies {
- c.Config.InPolicyList = append(c.Config.InPolicyList, p.Name)
- }
- }
-}
-
-func ReadRouteSelectionOptionsFromAPIStruct(c *config.RouteSelectionOptions, a *RouteSelectionOptions) {
- if c == nil || a == nil {
- return
- }
- if a.Config != nil {
- c.Config.AlwaysCompareMed = a.Config.AlwaysCompareMed
- c.Config.IgnoreAsPathLength = a.Config.IgnoreAsPathLength
- c.Config.ExternalCompareRouterId = a.Config.ExternalCompareRouterId
- c.Config.AdvertiseInactiveRoutes = a.Config.AdvertiseInactiveRoutes
- c.Config.EnableAigp = a.Config.EnableAigp
- c.Config.IgnoreNextHopIgpMetric = a.Config.IgnoreNextHopIgpMetric
- }
-}
-
-func ReadUseMultiplePathsFromAPIStruct(c *config.UseMultiplePaths, a *UseMultiplePaths) {
- if c == nil || a == nil {
- return
- }
- if a.Config != nil {
- c.Config.Enabled = a.Config.Enabled
- }
- if a.Ebgp != nil && a.Ebgp.Config != nil {
- c.Ebgp = config.Ebgp{
- Config: config.EbgpConfig{
- AllowMultipleAs: a.Ebgp.Config.AllowMultipleAs,
- MaximumPaths: a.Ebgp.Config.MaximumPaths,
- },
- }
- }
- if a.Ibgp != nil && a.Ibgp.Config != nil {
- c.Ibgp = config.Ibgp{
- Config: config.IbgpConfig{
- MaximumPaths: a.Ibgp.Config.MaximumPaths,
- },
- }
- }
-}
-
-func ReadRouteTargetMembershipFromAPIStruct(c *config.RouteTargetMembership, a *RouteTargetMembership) {
- if c == nil || a == nil {
- return
- }
- if a.Config != nil {
- c.Config.DeferralTime = uint16(a.Config.DeferralTime)
- }
-}
-
-func ReadLongLivedGracefulRestartFromAPIStruct(c *config.LongLivedGracefulRestart, a *LongLivedGracefulRestart) {
- if c == nil || a == nil {
- return
- }
- if a.Config != nil {
- c.Config.Enabled = a.Config.Enabled
- c.Config.RestartTime = a.Config.RestartTime
- }
-}
-
func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
pconf := &config.Neighbor{}
if a.Conf != nil {
+ pconf.Config.NeighborAddress = a.Conf.NeighborAddress
pconf.Config.PeerAs = a.Conf.PeerAs
pconf.Config.LocalAs = a.Conf.LocalAs
pconf.Config.AuthPassword = a.Conf.AuthPassword
@@ -1085,11 +877,11 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
f := func(bufs [][]byte) ([]bgp.ParameterCapabilityInterface, error) {
var caps []bgp.ParameterCapabilityInterface
for _, buf := range bufs {
- c, err := bgp.DecodeCapability(buf)
+ cap, err := bgp.DecodeCapability(buf)
if err != nil {
return nil, err
}
- caps = append(caps, c)
+ caps = append(caps, cap)
}
return caps, nil
}
@@ -1107,31 +899,22 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
pconf.State.RemoteRouterId = a.Conf.Id
- for _, family := range a.Families {
- afiSafi := config.AfiSafi{
+ for _, f := range a.Families {
+ family := bgp.RouteFamily(f)
+ pconf.AfiSafis = append(pconf.AfiSafis, config.AfiSafi{
Config: config.AfiSafiConfig{
- AfiSafiName: config.AfiSafiType(bgp.RouteFamily(family).String()),
+ AfiSafiName: config.AfiSafiType(family.String()),
Enabled: true,
},
- }
- for _, pl := range a.Conf.PrefixLimits {
- if family == pl.Family {
- ReadPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, pl)
+ })
+ }
+ for _, pl := range a.Conf.PrefixLimits {
+ for i, f := range pconf.AfiSafis {
+ if f.Config.AfiSafiName == config.AfiSafiType(bgp.RouteFamily(pl.Family).String()) {
+ pconf.AfiSafis[i].PrefixLimit.Config.MaxPrefixes = pl.MaxPrefixes
+ pconf.AfiSafis[i].PrefixLimit.Config.ShutdownThresholdPct = config.Percentage(pl.ShutdownThresholdPct)
}
}
- for _, a := range a.AfiSafis {
- if a.Config != nil && family == a.Config.Family {
- ReadMpGracefulRestartFromAPIStruct(&afiSafi.MpGracefulRestart, a.MpGracefulRestart)
- ReadAfiSafiConfigFromAPIStruct(&afiSafi.Config, a.Config)
- ReadApplyPolicyFromAPIStruct(&afiSafi.ApplyPolicy, a.ApplyPolicy)
- ReadRouteSelectionOptionsFromAPIStruct(&afiSafi.RouteSelectionOptions, a.RouteSelectionOptions)
- ReadUseMultiplePathsFromAPIStruct(&afiSafi.UseMultiplePaths, a.UseMultiplePaths)
- ReadPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, a.PrefixLimits)
- ReadRouteTargetMembershipFromAPIStruct(&afiSafi.RouteTargetMembership, a.RouteTargetMembership)
- ReadLongLivedGracefulRestartFromAPIStruct(&afiSafi.LongLivedGracefulRestart, a.LongLivedGracefulRestart)
- }
- }
- pconf.AfiSafis = append(pconf.AfiSafis, afiSafi)
}
}
@@ -1156,15 +939,26 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
if a.RouteServer != nil {
pconf.RouteServer.Config.RouteServerClient = a.RouteServer.RouteServerClient
}
- if a.GracefulRestart != nil {
- pconf.GracefulRestart.Config.Enabled = a.GracefulRestart.Enabled
- pconf.GracefulRestart.Config.RestartTime = uint16(a.GracefulRestart.RestartTime)
- pconf.GracefulRestart.Config.HelperOnly = a.GracefulRestart.HelperOnly
- pconf.GracefulRestart.Config.DeferralTime = uint16(a.GracefulRestart.DeferralTime)
- pconf.GracefulRestart.Config.NotificationEnabled = a.GracefulRestart.NotificationEnabled
- pconf.GracefulRestart.Config.LongLivedEnabled = a.GracefulRestart.LonglivedEnabled
+ if a.ApplyPolicy != nil {
+ if a.ApplyPolicy.ImportPolicy != nil {
+ pconf.ApplyPolicy.Config.DefaultImportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ApplyPolicy.ImportPolicy.Default)]
+ for _, p := range a.ApplyPolicy.ImportPolicy.Policies {
+ pconf.ApplyPolicy.Config.ImportPolicyList = append(pconf.ApplyPolicy.Config.ImportPolicyList, p.Name)
+ }
+ }
+ if a.ApplyPolicy.ExportPolicy != nil {
+ pconf.ApplyPolicy.Config.DefaultExportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ApplyPolicy.ExportPolicy.Default)]
+ for _, p := range a.ApplyPolicy.ExportPolicy.Policies {
+ pconf.ApplyPolicy.Config.ExportPolicyList = append(pconf.ApplyPolicy.Config.ExportPolicyList, p.Name)
+ }
+ }
+ if a.ApplyPolicy.InPolicy != nil {
+ pconf.ApplyPolicy.Config.DefaultInPolicy = config.IntToDefaultPolicyTypeMap[int(a.ApplyPolicy.InPolicy.Default)]
+ for _, p := range a.ApplyPolicy.InPolicy.Policies {
+ pconf.ApplyPolicy.Config.InPolicyList = append(pconf.ApplyPolicy.Config.InPolicyList, p.Name)
+ }
+ }
}
- ReadApplyPolicyFromAPIStruct(&pconf.ApplyPolicy, a.ApplyPolicy)
if a.Transport != nil {
pconf.Transport.Config.LocalAddress = a.Transport.LocalAddress
pconf.Transport.Config.PassiveMode = a.Transport.PassiveMode
@@ -1183,7 +977,6 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
pconf.State.AdjTable.Advertised = a.Info.Advertised
pconf.State.PeerAs = a.Info.PeerAs
pconf.State.PeerType = config.IntToPeerTypeMap[int(a.Info.PeerType)]
- pconf.State.NeighborAddress = a.Info.NeighborAddress
if a.Info.Messages != nil {
if a.Info.Messages.Sent != nil {
diff --git a/vendor/github.com/osrg/gobgp/client/client.go b/vendor/github.com/osrg/gobgp/client/client.go
index b9faf6ba..4a94ac4a 100644
--- a/vendor/github.com/osrg/gobgp/client/client.go
+++ b/vendor/github.com/osrg/gobgp/client/client.go
@@ -136,14 +136,14 @@ func (cli *Client) getNeighbor(name string, afi int, vrf string, enableAdvertise
neighbors := make([]*config.Neighbor, 0, len(ret.Peers))
for _, p := range ret.Peers {
- if name != "" && name != p.Info.NeighborAddress && name != p.Conf.NeighborInterface {
+ if name != "" && name != p.Conf.NeighborAddress && name != p.Conf.NeighborInterface {
continue
}
if vrf != "" && name != p.Conf.Vrf {
continue
}
if afi > 0 {
- v6 := net.ParseIP(p.Info.NeighborAddress).To4() == nil
+ v6 := net.ParseIP(p.Conf.NeighborAddress).To4() == nil
if afi == bgp.AFI_IP && v6 || afi == bgp.AFI_IP6 && !v6 {
continue
}
diff --git a/vendor/github.com/osrg/gobgp/config/bgp_configs.go b/vendor/github.com/osrg/gobgp/config/bgp_configs.go
index f170e97c..45515d00 100644
--- a/vendor/github.com/osrg/gobgp/config/bgp_configs.go
+++ b/vendor/github.com/osrg/gobgp/config/bgp_configs.go
@@ -965,54 +965,6 @@ func (v RpkiValidationResultType) Validate() error {
return nil
}
-//struct for container gobgp:state
-type DynamicNeighborState struct {
- // original -> gobgp:prefix
- Prefix string `mapstructure:"prefix" json:"prefix,omitempty"`
- // original -> gobgp:peer-group
- PeerGroup string `mapstructure:"peer-group" json:"peer-group,omitempty"`
-}
-
-//struct for container gobgp:config
-type DynamicNeighborConfig struct {
- // original -> gobgp:prefix
- Prefix string `mapstructure:"prefix" json:"prefix,omitempty"`
- // original -> gobgp:peer-group
- PeerGroup string `mapstructure:"peer-group" json:"peer-group,omitempty"`
-}
-
-func (lhs *DynamicNeighborConfig) Equal(rhs *DynamicNeighborConfig) bool {
- if lhs == nil || rhs == nil {
- return false
- }
- if lhs.Prefix != rhs.Prefix {
- return false
- }
- if lhs.PeerGroup != rhs.PeerGroup {
- return false
- }
- return true
-}
-
-//struct for container gobgp:dynamic-neighbor
-type DynamicNeighbor struct {
- // original -> gobgp:prefix
- // original -> gobgp:dynamic-neighbor-config
- Config DynamicNeighborConfig `mapstructure:"config" json:"config,omitempty"`
- // original -> gobgp:dynamic-neighbor-state
- State DynamicNeighborState `mapstructure:"state" json:"state,omitempty"`
-}
-
-func (lhs *DynamicNeighbor) Equal(rhs *DynamicNeighbor) bool {
- if lhs == nil || rhs == nil {
- return false
- }
- if !lhs.Config.Equal(&(rhs.Config)) {
- return false
- }
- return true
-}
-
//struct for container gobgp:state
type CollectorState struct {
// original -> gobgp:url
@@ -1219,9 +1171,6 @@ type BmpServerConfig struct {
RouteMonitoringPolicy BmpRouteMonitoringPolicyType `mapstructure:"route-monitoring-policy" json:"route-monitoring-policy,omitempty"`
// original -> gobgp:statistics-timeout
StatisticsTimeout uint16 `mapstructure:"statistics-timeout" json:"statistics-timeout,omitempty"`
- // original -> gobgp:route-mirroring-enabled
- //gobgp:route-mirroring-enabled's original type is boolean
- RouteMirroringEnabled bool `mapstructure:"route-mirroring-enabled" json:"route-mirroring-enabled,omitempty"`
}
func (lhs *BmpServerConfig) Equal(rhs *BmpServerConfig) bool {
@@ -1240,9 +1189,6 @@ func (lhs *BmpServerConfig) Equal(rhs *BmpServerConfig) bool {
if lhs.StatisticsTimeout != rhs.StatisticsTimeout {
return false
}
- if lhs.RouteMirroringEnabled != rhs.RouteMirroringEnabled {
- return false
- }
return true
}
@@ -1565,8 +1511,6 @@ type PeerGroup struct {
UseMultiplePaths UseMultiplePaths `mapstructure:"use-multiple-paths" json:"use-multiple-paths,omitempty"`
// original -> gobgp:route-server
RouteServer RouteServer `mapstructure:"route-server" json:"route-server,omitempty"`
- // original -> gobgp:ttl-security
- TtlSecurity TtlSecurity `mapstructure:"ttl-security" json:"ttl-security,omitempty"`
}
func (lhs *PeerGroup) Equal(rhs *PeerGroup) bool {
@@ -1628,58 +1572,6 @@ func (lhs *PeerGroup) Equal(rhs *PeerGroup) bool {
if !lhs.RouteServer.Equal(&(rhs.RouteServer)) {
return false
}
- if !lhs.TtlSecurity.Equal(&(rhs.TtlSecurity)) {
- return false
- }
- return true
-}
-
-//struct for container gobgp:state
-type TtlSecurityState struct {
- // original -> gobgp:enabled
- //gobgp:enabled's original type is boolean
- Enabled bool `mapstructure:"enabled" json:"enabled,omitempty"`
- // original -> gobgp:ttl-min
- TtlMin uint8 `mapstructure:"ttl-min" json:"ttl-min,omitempty"`
-}
-
-//struct for container gobgp:config
-type TtlSecurityConfig struct {
- // original -> gobgp:enabled
- //gobgp:enabled's original type is boolean
- Enabled bool `mapstructure:"enabled" json:"enabled,omitempty"`
- // original -> gobgp:ttl-min
- TtlMin uint8 `mapstructure:"ttl-min" json:"ttl-min,omitempty"`
-}
-
-func (lhs *TtlSecurityConfig) Equal(rhs *TtlSecurityConfig) bool {
- if lhs == nil || rhs == nil {
- return false
- }
- if lhs.Enabled != rhs.Enabled {
- return false
- }
- if lhs.TtlMin != rhs.TtlMin {
- return false
- }
- return true
-}
-
-//struct for container gobgp:ttl-security
-type TtlSecurity struct {
- // original -> gobgp:ttl-security-config
- Config TtlSecurityConfig `mapstructure:"config" json:"config,omitempty"`
- // original -> gobgp:ttl-security-state
- State TtlSecurityState `mapstructure:"state" json:"state,omitempty"`
-}
-
-func (lhs *TtlSecurity) Equal(rhs *TtlSecurity) bool {
- if lhs == nil || rhs == nil {
- return false
- }
- if !lhs.Config.Equal(&(rhs.Config)) {
- return false
- }
return true
}
@@ -2073,8 +1965,6 @@ type TransportConfig struct {
// original -> gobgp:remote-port
//gobgp:remote-port's original type is inet:port-number
RemotePort uint16 `mapstructure:"remote-port" json:"remote-port,omitempty"`
- // original -> gobgp:ttl
- Ttl uint8 `mapstructure:"ttl" json:"ttl,omitempty"`
}
func (lhs *TransportConfig) Equal(rhs *TransportConfig) bool {
@@ -2096,9 +1986,6 @@ func (lhs *TransportConfig) Equal(rhs *TransportConfig) bool {
if lhs.RemotePort != rhs.RemotePort {
return false
}
- if lhs.Ttl != rhs.Ttl {
- return false
- }
return true
}
@@ -2275,10 +2162,6 @@ type Received struct {
Keepalive uint64 `mapstructure:"keepalive" json:"keepalive,omitempty"`
// original -> gobgp:DYNAMIC-CAP
DynamicCap uint64 `mapstructure:"dynamic-cap" json:"dynamic-cap,omitempty"`
- // original -> gobgp:WITHDRAW-UPDATE
- WithdrawUpdate uint32 `mapstructure:"withdraw-update" json:"withdraw-update,omitempty"`
- // original -> gobgp:WITHDRAW-PREFIX
- WithdrawPrefix uint32 `mapstructure:"withdraw-prefix" json:"withdraw-prefix,omitempty"`
// original -> gobgp:DISCARDED
Discarded uint64 `mapstructure:"discarded" json:"discarded,omitempty"`
// original -> gobgp:TOTAL
@@ -2307,12 +2190,6 @@ func (lhs *Received) Equal(rhs *Received) bool {
if lhs.DynamicCap != rhs.DynamicCap {
return false
}
- if lhs.WithdrawUpdate != rhs.WithdrawUpdate {
- return false
- }
- if lhs.WithdrawPrefix != rhs.WithdrawPrefix {
- return false
- }
if lhs.Discarded != rhs.Discarded {
return false
}
@@ -2336,10 +2213,6 @@ type Sent struct {
Keepalive uint64 `mapstructure:"keepalive" json:"keepalive,omitempty"`
// original -> gobgp:DYNAMIC-CAP
DynamicCap uint64 `mapstructure:"dynamic-cap" json:"dynamic-cap,omitempty"`
- // original -> gobgp:WITHDRAW-UPDATE
- WithdrawUpdate uint32 `mapstructure:"withdraw-update" json:"withdraw-update,omitempty"`
- // original -> gobgp:WITHDRAW-PREFIX
- WithdrawPrefix uint32 `mapstructure:"withdraw-prefix" json:"withdraw-prefix,omitempty"`
// original -> gobgp:DISCARDED
Discarded uint64 `mapstructure:"discarded" json:"discarded,omitempty"`
// original -> gobgp:TOTAL
@@ -2368,12 +2241,6 @@ func (lhs *Sent) Equal(rhs *Sent) bool {
if lhs.DynamicCap != rhs.DynamicCap {
return false
}
- if lhs.WithdrawUpdate != rhs.WithdrawUpdate {
- return false
- }
- if lhs.WithdrawPrefix != rhs.WithdrawPrefix {
- return false
- }
if lhs.Discarded != rhs.Discarded {
return false
}
@@ -2580,8 +2447,6 @@ type Neighbor struct {
UseMultiplePaths UseMultiplePaths `mapstructure:"use-multiple-paths" json:"use-multiple-paths,omitempty"`
// original -> gobgp:route-server
RouteServer RouteServer `mapstructure:"route-server" json:"route-server,omitempty"`
- // original -> gobgp:ttl-security
- TtlSecurity TtlSecurity `mapstructure:"ttl-security" json:"ttl-security,omitempty"`
}
func (lhs *Neighbor) Equal(rhs *Neighbor) bool {
@@ -2643,9 +2508,6 @@ func (lhs *Neighbor) Equal(rhs *Neighbor) bool {
if !lhs.RouteServer.Equal(&(rhs.RouteServer)) {
return false
}
- if !lhs.TtlSecurity.Equal(&(rhs.TtlSecurity)) {
- return false
- }
return true
}
@@ -3890,8 +3752,6 @@ type Bgp struct {
Zebra Zebra `mapstructure:"zebra" json:"zebra,omitempty"`
// original -> gobgp:collector
Collector Collector `mapstructure:"collector" json:"collector,omitempty"`
- // original -> gobgp:dynamic-neighbors
- DynamicNeighbors []DynamicNeighbor `mapstructure:"dynamic-neighbors" json:"dynamic-neighbors,omitempty"`
}
func (lhs *Bgp) Equal(rhs *Bgp) bool {
@@ -3987,22 +3847,6 @@ func (lhs *Bgp) Equal(rhs *Bgp) bool {
if !lhs.Collector.Equal(&(rhs.Collector)) {
return false
}
- if len(lhs.DynamicNeighbors) != len(rhs.DynamicNeighbors) {
- return false
- }
- {
- lmap := make(map[string]*DynamicNeighbor)
- for i, l := range lhs.DynamicNeighbors {
- lmap[mapkey(i, string(l.Config.Prefix))] = &lhs.DynamicNeighbors[i]
- }
- for i, r := range rhs.DynamicNeighbors {
- if l, y := lmap[mapkey(i, string(r.Config.Prefix))]; !y {
- return false
- } else if !r.Equal(l) {
- return false
- }
- }
- }
return true
}
diff --git a/vendor/github.com/osrg/gobgp/config/default.go b/vendor/github.com/osrg/gobgp/config/default.go
index 81ffe00f..7587fad8 100644
--- a/vendor/github.com/osrg/gobgp/config/default.go
+++ b/vendor/github.com/osrg/gobgp/config/default.go
@@ -7,7 +7,6 @@ import (
"github.com/osrg/gobgp/packet/rtr"
"github.com/spf13/viper"
"net"
- "reflect"
)
const (
@@ -16,20 +15,6 @@ const (
DEFAULT_CONNECT_RETRY = 120
)
-var forcedOverwrittenConfig = []string{
- "neighbor.config.peer-as",
- "neighbor.timers.config.minimum-advertisement-interval",
-}
-
-var configuredFields map[string]interface{}
-
-func RegisterConfiguredFields(addr string, n interface{}) {
- if configuredFields == nil {
- configuredFields = make(map[string]interface{}, 0)
- }
- configuredFields[addr] = n
-}
-
func defaultAfiSafi(typ AfiSafiType, enable bool) AfiSafi {
return AfiSafi{
Config: AfiSafiConfig{
@@ -130,10 +115,6 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
}
}
- if n.State.NeighborAddress == "" {
- n.State.NeighborAddress = n.Config.NeighborAddress
- }
-
n.State.PeerAs = n.Config.PeerAs
n.AsPathOptions.State.AllowOwnAs = n.AsPathOptions.Config.AllowOwnAs
@@ -158,14 +139,14 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
if err != nil {
return err
}
- n.State.NeighborAddress = addr
+ n.Config.NeighborAddress = addr
}
if n.Transport.Config.LocalAddress == "" {
- if n.State.NeighborAddress == "" {
+ if n.Config.NeighborAddress == "" {
return fmt.Errorf("no neighbor address/interface specified")
}
- ipAddr, err := net.ResolveIPAddr("ip", n.State.NeighborAddress)
+ ipAddr, err := net.ResolveIPAddr("ip", n.Config.NeighborAddress)
if err != nil {
return err
}
@@ -188,8 +169,8 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
defaultAfiSafi(AFI_SAFI_TYPE_IPV4_UNICAST, true),
defaultAfiSafi(AFI_SAFI_TYPE_IPV6_UNICAST, true),
}
- } else if ipAddr, err := net.ResolveIPAddr("ip", n.State.NeighborAddress); err != nil {
- return fmt.Errorf("invalid neighbor address: %s", n.State.NeighborAddress)
+ } else if ipAddr, err := net.ResolveIPAddr("ip", n.Config.NeighborAddress); err != nil {
+ return fmt.Errorf("invalid neighbor address: %s", n.Config.NeighborAddress)
} else if ipAddr.IP.To4() != nil {
n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV4_UNICAST, true)}
} else {
@@ -209,7 +190,6 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
if !vv.IsSet("afi-safi.config") {
af.Config.Enabled = true
}
- af.MpGracefulRestart.State.Enabled = af.MpGracefulRestart.Config.Enabled
n.AfiSafis[i] = af
}
}
@@ -232,11 +212,6 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
n.GracefulRestart.Config.DeferralTime = uint16(360)
}
}
-
- if n.EbgpMultihop.Config.Enabled && n.TtlSecurity.Config.Enabled {
- return fmt.Errorf("ebgp-multihop and ttl-security are mututally exclusive")
- }
-
return nil
}
@@ -279,45 +254,6 @@ func setDefaultPolicyConfigValuesWithViper(v *viper.Viper, p *PolicyDefinition)
return nil
}
-func validatePeerGroupConfig(n *Neighbor, b *BgpConfigSet) error {
- name := n.Config.PeerGroup
- if name == "" {
- return nil
- }
-
- pg, err := getPeerGroup(name, b)
- if err != nil {
- return err
- }
-
- if pg.Config.PeerAs != 0 && n.Config.PeerAs != 0 {
- return fmt.Errorf("Cannot configure remote-as for members. PeerGroup AS %d.", pg.Config.PeerAs)
- }
- return nil
-}
-
-func getPeerGroup(n string, b *BgpConfigSet) (*PeerGroup, error) {
- if n == "" {
- return nil, fmt.Errorf("peer-group name is not configured")
- }
- for _, pg := range b.PeerGroups {
- if n == pg.Config.PeerGroupName {
- return &pg, nil
- }
- }
- return nil, fmt.Errorf("No such peer-group: %s", n)
-}
-
-func validateDynamicNeighborConfig(d *DynamicNeighborConfig, b *BgpConfigSet) error {
- if _, err := getPeerGroup(d.PeerGroup, b); err != nil {
- return err
- }
- if _, _, err := net.ParseCIDR(d.Prefix); err != nil {
- return fmt.Errorf("Invalid Dynamic Neighbor prefix %s", d.Prefix)
- }
- return nil
-}
-
func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
if v == nil {
v = viper.New()
@@ -357,10 +293,6 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
}
for idx, n := range b.Neighbors {
- if err := validatePeerGroupConfig(&n, b); err != nil {
- return err
- }
-
vv := viper.New()
if len(list) > idx {
vv.Set("neighbor", list[idx])
@@ -369,16 +301,6 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
return err
}
b.Neighbors[idx] = n
-
- if n.Config.PeerGroup != "" {
- RegisterConfiguredFields(vv.Get("neighbor.config.neighbor-address").(string), list[idx])
- }
- }
-
- for _, d := range b.DynamicNeighbors {
- if err := validateDynamicNeighborConfig(&d.Config, b); err != nil {
- return err
- }
}
for idx, r := range b.RpkiServers {
@@ -405,57 +327,3 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
return nil
}
-
-func OverwriteNeighborConfigWithPeerGroup(c *Neighbor, pg *PeerGroup) error {
- v := viper.New()
-
- val, ok := configuredFields[c.State.NeighborAddress]
- if ok {
- v.Set("neighbor", val)
- } else {
- v.Set("neighbor.config.peer-group", c.Config.PeerGroup)
- }
-
- overwriteConfig(&c.Config, &pg.Config, "neighbor.config", v)
- overwriteConfig(&c.Timers.Config, &pg.Timers.Config, "neighbor.timers.config", v)
- overwriteConfig(&c.Transport.Config, &pg.Transport.Config, "neighbor.transport.config", v)
- overwriteConfig(&c.ErrorHandling.Config, &pg.ErrorHandling.Config, "neighbor.error-handling.config", v)
- overwriteConfig(&c.LoggingOptions.Config, &pg.LoggingOptions.Config, "neighbor.logging-options.config", v)
- overwriteConfig(&c.EbgpMultihop.Config, &pg.EbgpMultihop.Config, "neighbor.ebgp-multihop.config", v)
- overwriteConfig(&c.RouteReflector.Config, &pg.RouteReflector.Config, "neighbor.route-reflector.config", v)
- overwriteConfig(&c.AsPathOptions.Config, &pg.AsPathOptions.Config, "neighbor.as-path-options.config", v)
- overwriteConfig(&c.AddPaths.Config, &pg.AddPaths.Config, "neighbor.add-paths.config", v)
- overwriteConfig(&c.GracefulRestart.Config, &pg.GracefulRestart.Config, "neighbor.gradeful-restart.config", v)
- overwriteConfig(&c.ApplyPolicy.Config, &pg.ApplyPolicy.Config, "neighbor.apply-policy.config", v)
- overwriteConfig(&c.UseMultiplePaths.Config, &pg.UseMultiplePaths.Config, "neighbor.use-multiple-paths.config", v)
- overwriteConfig(&c.RouteServer.Config, &pg.RouteServer.Config, "neighbor.route-server.config", v)
- overwriteConfig(&c.TtlSecurity.Config, &pg.TtlSecurity.Config, "neighbor.ttl-security.config", v)
-
- if !v.IsSet("neighbor.afi-safis") {
- c.AfiSafis = pg.AfiSafis
- }
-
- return nil
-}
-
-func overwriteConfig(c, pg interface{}, tagPrefix string, v *viper.Viper) {
- nValue := reflect.Indirect(reflect.ValueOf(c))
- nType := reflect.Indirect(nValue).Type()
- pgValue := reflect.Indirect(reflect.ValueOf(pg))
- pgType := reflect.Indirect(pgValue).Type()
-
- for i := 0; i < pgType.NumField(); i++ {
- field := pgType.Field(i).Name
- tag := tagPrefix + "." + nType.Field(i).Tag.Get("mapstructure")
- if func() bool {
- for _, t := range forcedOverwrittenConfig {
- if t == tag {
- return true
- }
- }
- return false
- }() || !v.IsSet(tag) {
- nValue.FieldByName(field).Set(pgValue.FieldByName(field))
- }
- }
-}
diff --git a/vendor/github.com/osrg/gobgp/config/serve.go b/vendor/github.com/osrg/gobgp/config/serve.go
index 73e2c7bb..eeb7cb4d 100644
--- a/vendor/github.com/osrg/gobgp/config/serve.go
+++ b/vendor/github.com/osrg/gobgp/config/serve.go
@@ -1,7 +1,7 @@
package config
import (
- log "github.com/sirupsen/logrus"
+ log "github.com/Sirupsen/logrus"
"github.com/spf13/viper"
"os"
"os/signal"
@@ -19,7 +19,6 @@ type BgpConfigSet struct {
Collector Collector `mapstructure:"collector"`
DefinedSets DefinedSets `mapstructure:"defined-sets"`
PolicyDefinitions []PolicyDefinition `mapstructure:"policy-definitions"`
- DynamicNeighbors []DynamicNeighbor `mapstructure:"dynamic-neighbors"`
}
func ReadConfigfileServe(path, format string, configCh chan *BgpConfigSet) {
@@ -77,16 +76,7 @@ func ReadConfigfileServe(path, format string, configCh chan *BgpConfigSet) {
func inSlice(n Neighbor, b []Neighbor) int {
for i, nb := range b {
- if nb.State.NeighborAddress == n.State.NeighborAddress {
- return i
- }
- }
- return -1
-}
-
-func existPeerGroup(n string, b []PeerGroup) int {
- for i, nb := range b {
- if nb.Config.PeerGroupName == n {
+ if nb.Config.NeighborAddress == n.Config.NeighborAddress {
return i
}
}
@@ -100,34 +90,8 @@ func ConfigSetToRoutingPolicy(c *BgpConfigSet) *RoutingPolicy {
}
}
-func UpdatePeerGroupConfig(curC, newC *BgpConfigSet) ([]PeerGroup, []PeerGroup, []PeerGroup) {
- addedPg := []PeerGroup{}
- deletedPg := []PeerGroup{}
- updatedPg := []PeerGroup{}
+func UpdateConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []Neighbor, bool) {
- for _, n := range newC.PeerGroups {
- if idx := existPeerGroup(n.Config.PeerGroupName, curC.PeerGroups); idx < 0 {
- addedPg = append(addedPg, n)
- } else if !n.Equal(&curC.PeerGroups[idx]) {
- log.WithFields(log.Fields{
- "Topic": "Config",
- }).Debugf("Current peer-group config:%s", curC.PeerGroups[idx])
- log.WithFields(log.Fields{
- "Topic": "Config",
- }).Debugf("New peer-group config:%s", n)
- updatedPg = append(updatedPg, n)
- }
- }
-
- for _, n := range curC.PeerGroups {
- if existPeerGroup(n.Config.PeerGroupName, newC.PeerGroups) < 0 {
- deletedPg = append(deletedPg, n)
- }
- }
- return addedPg, deletedPg, updatedPg
-}
-
-func UpdateNeighborConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []Neighbor) {
added := []Neighbor{}
deleted := []Neighbor{}
updated := []Neighbor{}
@@ -151,7 +115,8 @@ func UpdateNeighborConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []N
deleted = append(deleted, n)
}
}
- return added, deleted, updated
+
+ return added, deleted, updated, CheckPolicyDifference(ConfigSetToRoutingPolicy(curC), ConfigSetToRoutingPolicy(newC))
}
func CheckPolicyDifference(currentPolicy *RoutingPolicy, newPolicy *RoutingPolicy) bool {
diff --git a/vendor/github.com/osrg/gobgp/config/util.go b/vendor/github.com/osrg/gobgp/config/util.go
index 8ecf56d5..36999411 100644
--- a/vendor/github.com/osrg/gobgp/config/util.go
+++ b/vendor/github.com/osrg/gobgp/config/util.go
@@ -140,14 +140,3 @@ func ParseMaskLength(prefix, mask string) (int, int, error) {
}
return min, max, nil
}
-
-func ExtractNeighborAddress(c *Neighbor) (string, error) {
- addr := c.State.NeighborAddress
- if addr == "" {
- addr = c.Config.NeighborAddress
- if addr == "" {
- return "", fmt.Errorf("NeighborAddress is not configured")
- }
- }
- return addr, nil
-}
diff --git a/vendor/github.com/osrg/gobgp/docs/sources/bmp.md b/vendor/github.com/osrg/gobgp/docs/sources/bmp.md
index 22f6a193..e6f6e2bb 100644
--- a/vendor/github.com/osrg/gobgp/docs/sources/bmp.md
+++ b/vendor/github.com/osrg/gobgp/docs/sources/bmp.md
@@ -64,17 +64,6 @@ Please note the range of this interval is 15 though 65535 seconds.
statistics-timeout = 3600
```
-To enable route mirroring feature, specify `true` for `route-mirroring-enabled` option.
-Please note this option is mainly for debugging purpose.
-
-```toml
-[[bmp-servers]]
- [bmp-servers.config]
- address = "127.0.0.1"
- port=11019
- route-mirroring-enabled = true
-```
-
## Verification
Let's check if BMP works with a bmp server. GoBGP also supports BMP server (currently, just shows received BMP messages in the json format).
diff --git a/vendor/github.com/osrg/gobgp/docs/sources/configuration.md b/vendor/github.com/osrg/gobgp/docs/sources/configuration.md
index 71e654fb..7403834c 100644
--- a/vendor/github.com/osrg/gobgp/docs/sources/configuration.md
+++ b/vendor/github.com/osrg/gobgp/docs/sources/configuration.md
@@ -52,8 +52,6 @@
# override global.config.as value
local-as = 1000
remove-private-as = "all"
- # To enable peer group setting, uncomment the following
- #peer-group = "my-peer-group"
[neighbors.as-path-options.config]
allow-own-as = 1
replace-peer-as = true
@@ -65,7 +63,6 @@
passive-mode = true
local-address = "192.168.10.1"
remote-port = 2016
- ttl = 64 # default value on Linux
[neighbors.ebgp-multihop.config]
enabled = true
multihop-ttl = 100
@@ -132,25 +129,6 @@
default-in-policy = "reject-route"
[neighbors.route-server.config]
route-server-client = true
- # To enable TTL Security, uncomment the following.
- # Please note that this feature is mututally exclusive with
- # "neighbors.ebgp-multihop.config".
- #[neighbors.ttl-security.config]
- # enabled = true
- # ttl-min = 255 # 255 means directly connected
-
-[[peer-groups]]
- [peer-groups.config]
- peer-group-name = "my-peer-group"
- peer-as = 65000
- [[peer-groups.afi-safis]]
- [peer-groups.afi-safis.config]
- afi-safi-name = "ipv4-unicast"
-
-[[dynamic-neighbors]]
- [dynamic-neighbors.config]
- prefix = "20.0.0.0/24"
- peer-group = "my-peer-group"
[[defined-sets.prefix-sets]]
prefix-set-name = "ps0"
diff --git a/vendor/github.com/osrg/gobgp/docs/sources/getting-started.md b/vendor/github.com/osrg/gobgp/docs/sources/getting-started.md
index cdd8ba83..b556592b 100644
--- a/vendor/github.com/osrg/gobgp/docs/sources/getting-started.md
+++ b/vendor/github.com/osrg/gobgp/docs/sources/getting-started.md
@@ -86,7 +86,7 @@ neighbors:
```
```bash
-$ sudo -E gobgpd -t yaml -f gobgpd.yml
+$ sudo -E gobgpd -t yaml gobgpd.yml
{"level":"info","msg":"Peer 10.0.255.1 is added","time":"2015-04-06T20:32:28+09:00"}
{"level":"info","msg":"Peer 10.0.255.2 is added","time":"2015-04-06T20:32:28+09:00"}
```
diff --git a/vendor/github.com/osrg/gobgp/docs/sources/grpc-client.md b/vendor/github.com/osrg/gobgp/docs/sources/grpc-client.md
index bc91c3f0..ad1bc163 100644
--- a/vendor/github.com/osrg/gobgp/docs/sources/grpc-client.md
+++ b/vendor/github.com/osrg/gobgp/docs/sources/grpc-client.md
@@ -3,24 +3,72 @@
This page explains how to managing GoBGP with your favorite Language.
You can use any language supported by [gRPC](http://www.grpc.io/) (10
languages are supported now). This page gives an example in Python,
-Ruby, C++, Node.js, and Java. It assumes that you use Ubuntu 16.04 (64bit).
+Ruby, C++, Node.js, and Java. It assumes that you use Ubuntu 14.04 (64bit).
## Contents
-- [Prerequisite](#prerequisite)
- [Python](#python)
- [Ruby](#ruby)
- [C++](#cpp)
- [Node.js](#nodejs)
- [Java](#java)
-## Prerequisite
-We assumes that you have finished installing `protoc` [protocol buffer](https://github.com/google/protobuf) compiler to generate stub server and client code and "protobuf runtime" for your favorite language.
-
-Please refer to [the official docs of gRPC](http://www.grpc.io/docs/) for details.
-
## Python
+We need to install ProtocolBuffers and gRPC libraries.
+
+### Install ProtocolBuffers:
+```bash
+$ sudo apt-get update
+$ sudo apt-get install -y build-essential autoconf git libtool unzip
+$ mkdir ~/work
+$ cd ~/work
+$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-1.tar.gz
+$ tar xvzf v3.0.0-beta-1.tar.gz
+$ cd protobuf-3.0.0-beta-1
+$ ./autogen.sh
+$ ./configure
+$ make
+$ sudo make install
+$ vi ~/.bashrc
+ export LD_LIBRARY_PATH=/usr/local/lib
+```
+
+please check the version.
+ ```bash
+ $ protoc --version
+ libprotoc 3.0.0
+ ```
+
+### Install gRPC:
+```bash
+$ sudo apt-get update
+$ sudo apt-get install -y python-all-dev python-virtualenv
+$ cd ~/work
+$ git clone https://github.com/grpc/grpc.git
+$ cd grpc
+$ git checkout -b release-0_11_1 release-0_11_1
+$ git submodule update --init
+$ make
+$ sudo make install
+```
+
+### Install Python Libraries:
+
+Install python libraries for protobuf and gRPC.
+Please use virtualenv if you want to keep your environment clean.
+In this example we create venv directory at $HOME/venv.
+
+```bash
+$ virtualenv ~/venv
+$ source ~/venv/bin/activate
+$ cd ~/work/protobuf-3.0.0-beta-1/python
+$ python setup.py install
+$ cd ~/work/grpc/src/python/grpcio/
+$ python setup.py install
+$ deactivate
+```
+
### Generating Stub Code
We need to generate stub code GoBGP at first.
@@ -32,23 +80,93 @@ $ protoc -I $GOBGP_API --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`wh
### Get Neighbor
-['tools/grpc/python/get_neighbor.py'](https://github.com/osrg/gobgp/blob/master/tools/grpc/python/get_neighbor.py) shows an example for getting neighbor's information.
+Here is an example for getting neighbor's information and we assumed that it's created in 'get_neighbor.py' under '$GOPATH/src/github.com/osrg/gobgp/tools/grpc/python'.
+```python
+import gobgp_pb2
+import sys
+
+from grpc.beta import implementations
+
+_TIMEOUT_SECONDS = 10
+
+
+def run(gobgpd_addr, neighbor_addr):
+ channel = implementations.insecure_channel(gobgpd_addr, 50051)
+ with gobgp_pb2.beta_create_GobgpApi_stub(channel) as stub:
+ peer = stub.GetNeighbor(gobgp_pb2.Arguments(rf=4, name=neighbor_addr), _TIMEOUT_SECONDS)
+ print("BGP neighbor is %s, remote AS %d" % (peer.conf.neighbor_address, peer.conf.peer_as))
+ print(" BGP version 4, remote router ID %s" % (peer.conf.id))
+ print(" BGP state = %s, up for %s" % (peer.info.bgp_state, peer.timers.state.uptime))
+ print(" BGP OutQ = %d, Flops = %d" % (peer.info.out_q, peer.info.flops))
+ print(" Hold time is %d, keepalive interval is %d seconds" % (peer.timers.state.negotiated_hold_time, peer.timers.state.keepalive_interval))
+ print(" Configured hold time is %d, keepalive interval is %d seconds" % (peer.timers.config.hold_time, peer.timers.config.keepalive_interval))
+
+
+if __name__ == '__main__':
+ gobgp = sys.argv[1]
+ neighbor = sys.argv[2]
+ run(gobgp, neighbor)
+```
+
+We need to import gobgp_pb2 and call 'beta_create_GobgpApi_stub' in your code.
+
Let's run this script.
```bash
-$ python get_neighbor.py 172.18.0.2
-BGP neighbor is 10.0.0.2, remote AS 65002
- BGP version 4, remote router ID
- BGP state = active, up for 0
+$ source ~/venv/bin/activate
+(venv)$ python get_neighbor.py 10.0.255.1 10.0.0.1
+BGP neighbor is 10.0.0.1, remote AS 65001
+ BGP version 4, remote router ID 192.168.0.1
+ BGP state = BGP_FSM_ESTABLISHED, up for 9042
BGP OutQ = 0, Flops = 0
- Hold time is 0, keepalive interval is 0 seconds
- Configured hold time is 90, keepalive interval is 30 seconds
+ Hold time is 30, keepalive interval is 10 seconds
+ Configured hold time is 30, keepalive interval is 10 seconds
+
```
We got the neighbor information successfully.
## Ruby
+### Install ProtoBuffers:
+
+```bash
+$ sudo apt-get update
+$ sudo apt-get install -y build-essential curl git m4 ruby autoconf libtool unzip
+$ mkdir ~/work
+$ cd ~/work
+$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-1.tar.gz
+$ tar xvzf v3.0.0-beta-1.tar.gz
+$ cd protobuf-3.0.0-beta-1
+$ ./autogen.sh
+$ ./configure
+$ make
+$ sudo make install
+$ vi ~/.bashrc
+ export LD_LIBRARY_PATH=/usr/local/lib
+```
+
+### Installing gRPC and Ruby Libraries
+
+```bash
+$ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
+$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2
+$ source $HOME/.rvm/scripts/rvm
+$ rvm install 2.1
+$ gem install bundler
+$ cd ~/work/
+$ git clone https://github.com/grpc/grpc.git
+$ cd grpc
+$ git checkout -b release-0_11_1 release-0_11_1
+$ git submodule update --init
+$ $ make
+$ $ sudo make install
+$ cd src/ruby/
+$ gem build grpc.gemspec
+$ bundle install
+$ gem install -l grpc-0.11.0.gem
+```
+
### Generating Stub Code
We need to generate stub code GoBGP at first.
@@ -60,67 +178,195 @@ $ protoc -I $GOBGP_API --ruby_out=. --grpc_out=. --plugin=protoc-gen-grpc=`whic
### Get Neighbor
-['tools/grpc/ruby/get_neighbor.py'](https://github.com/osrg/gobgp/blob/master/tools/grpc/ruby/get_neighbor.rb) shows an example for getting neighbor's information.
+Here is an example for getting neighbor's information.
+```ruby
+require 'gobgp'
+require 'gobgp_services'
+
+host = 'localhost'
+host = ARGV[0] if ARGV.length > 0
+
+stub = Gobgpapi::GobgpApi::Stub.new("#{host}:50051")
+arg = Gobgpapi::Arguments.new()
+stub.get_neighbors(arg).each do |n|
+ puts "BGP neighbor is #{n.conf.neighbor_address}, remote AS #{n.conf.peer_as}"
+ puts "\tBGP version 4, remote route ID #{n.conf.id}"
+ puts "\tBGP state = #{n.info.bgp_state}, up for #{n.timers.state.uptime}"
+ puts "\tBGP OutQ = #{n.info.out_q}, Flops = #{n.info.flops}"
+ puts "\tHold time is #{n.timers.state.hold_time}, keepalive interval is #{n.timers.state.keepalive_interval} seconds"
+ puts "\tConfigured hold time is #{n.timers.config.hold_time}"
+end
+```
+
Let's run this script.
```bash
-$ ruby -I . ./get_neighbors.rb 172.18.0.2
-BGP neighbor is 10.0.0.2, remote AS 65002
- BGP version 4, remote route ID
- BGP state = active, up for 0
- BGP OutQ = 0, Flops = 0
- Hold time is 0, keepalive interval is 0 seconds
- Configured hold time is 90
+$ruby -I . ./get_neighbors.rb
+BGP neighbor is 192.168.10.2, remote AS 65001
+ BGP version 4, remote route ID
+ BGP state = BGP_FSM_ACTIVE, up for 0
+ BGP OutQ = 0, Flops = 0
+ Hold time is 0, keepalive interval is 0 seconds
+ Configured hold time is 90
+BGP neighbor is 192.168.10.3, remote AS 65001
+ BGP version 4, remote route ID
+ BGP state = BGP_FSM_ACTIVE, up for 0
+ BGP OutQ = 0, Flops = 0
+ Hold time is 0, keepalive interval is 0 seconds
+ Configured hold time is 90
```
## C++
+For gRPC we need so much dependencies, please make coffee and be ready!
+
+### Install ProtoBuffers:
+```bash
+apt-get update
+apt-get install -y gcc make autoconf automake git libtool g++ curl
+
+cd /usr/src
+wget https://github.com/google/protobuf/archive/v3.0.0-alpha-4.tar.gz
+tar -xf v3.0.0-alpha-4.tar.gz
+cd protobuf-3.0.0-alpha-4/
+./autogen.sh
+./configure --prefix=/opt/protobuf_3.0.0_alpha4
+make -j 4
+make install
+```
+
+### Install gRPC:
+```bash
+apt-get update
+apt-get install -y gcc make autoconf automake git libtool g++ python-all-dev python-virtualenv
+
+cd /usr/src/
+git clone https://github.com/grpc/grpc.git
+cd grpc
+# We are using specific commit because gRPC is under heavy development right now
+git checkout e5cdbea1530a99a95fd3d032e7d69a19c61a0d16
+git submodule update --init
+make -j 4
+make install prefix=/opt/grpc
+```
+
We use .so compilation with golang, please use only 1.5 or newer version of Go Lang.
-['tools/grpc/cpp/gobgp_api_client.cc'](https://github.com/osrg/gobgp/blob/master/tools/grpc/cpp/gobgp_api_client.cc) shows an example for getting neighbor's information.
-
-We provide ['tools/grpc/cpp/build.sh'](https://github.com/osrg/gobgp/blob/master/tools/grpc/cpp/build.sh) to build this sample code.
-This script also generates stub codes and builds GoBGP shared library.
-
-Let's build the sample code:
+Clone this repository and build API example:
```bash
-$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/cpp
-$ bash build.sh
+export PATH="$PATH:/opt//grpc/bin:/opt/protobuf_3.0.0_alpha4/bin/"
+
+cd /usr/src
+git clone https://github.com/osrg/gobgp.git
+cd gobgp/gobgp/lib
+go build -buildmode=c-shared -o libgobgp.so *.go
+cp libgobgp.h /usr/src/gobgp/tools/grpc/cpp
+cp libgobgp.so /usr/src/gobgp/tools/grpc/cpp
+cp /usr/src/gobgp/api/gobgp.proto /usr/src/gobgp/tools/grpc/cpp/gobgp_api_client.proto
+cd /usr/src/gobgp/tools/grpc/cpp
+make
```
### Let's run it:
```bash
-$ ./gobgp_api_client 172.18.0.2
-BGP neighbor is: 10.0.0.2, remote AS: 1
- BGP version: 4, remote route ID
- BGP state = active, up for 0
- BGP OutQ = 0, Flops = 0
- Hold time is 0, keepalive interval is 0seconds
- Configured hold time is 90
-BGP neighbor is: 10.0.0.3, remote AS: 1
- BGP version: 4, remote route ID
- BGP state = active, up for 0
- BGP OutQ = 0, Flops = 0
- Hold time is 0, keepalive interval is 0seconds
- Configured hold time is 90
+LD_LIBRARY_PATH=".:/opt/grpc/lib:/opt/protobuf_3.0.0_alpha4/lib" ./gobgp_api_client
+
+List of announced prefixes for route family: 65537
+
+Prefix: 10.10.20.0/22
+NLRI: {"nlri":{"prefix":"10.10.20.0/22"},"attrs":[{"type":1,"value":0},{"type":3,"nexthop":"0.0.0.0"}]}
+
+
+List of announced prefixes for route family: 65669
+
+Prefix: [destination:10.0.0.0/24][protocol: tcp][source:20.0.0.0/24]
+NLRI: {"nlri":{"value":[{"type":1,"value":{"prefix":"10.0.0.0/24"}},{"type":3,"value":[{"op":129,"value":6}]},{"type":2,"value":{"prefix":"20.0.0.0/24"}}]},"attrs":[{"type":1,"value":0},{"type":14,"nexthop":"0.0.0.0","afi":1,"safi":133,"value":[{"value":[{"type":1,"value":{"prefix":"10.0.0.0/24"}},{"type":3,"value":[{"op":129,"value":6}]},{"type":2,"value":{"prefix":"20.0.0.0/24"}}]}]},{"type":16,"value":[{"type":128,"subtype":8,"value":"10:10"}]}]}
```
## Node.js
+Build from source code because there is no official gRPC package for Ubuntu 14.04.
+(Debian Linux and Mac OSX are much easier. See [the document](https://github.com/grpc/grpc/tree/release-0_11/src/node))
+
+
+### Install Protocol Buffers:
+
+Install protobuf v3.0.0-beta before gRPC. gRPC installation process will try to do it automatically but fail. (Probably because it tries another version of protobuf)
+
+See [installation document](https://github.com/grpc/grpc/blob/master/INSTALL).
+
+```bash
+$ [sudo] apt-get install unzip autoconf libtool build-essential
+
+$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-4.tar.gz
+$ tar zxvf v3.0.0-beta-4.tar.gz
+$ cd protobuf-3.0.0-beta-4/
+$ ./autogen.sh
+$ ./configure
+$ make
+$ [sudo] make install
+```
+
+### Install gRPC:
+
+```bash
+$ [sudo] apt-get install git
+
+$ git clone https://github.com/grpc/grpc.git
+$ cd grpc
+$ git submodule update --init
+$ make
+$ [sudo] make install
+```
+
+### Install Node.js gRPC library:
+
+Let's say Node.js is already installed,
+
+```bash
+npm install grpc
+```
+
### Example
Copy protocol definition.
```bash
-$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/nodejs
-$ ln -s $GOPATH/src/github.com/osrg/gobgp/api/gobgp.proto
+cp $GOPATH/src/github.com/osrg/gobgp/api/gobgp.proto .
+```
+
+Here is an example to show neighbor information.
+
+```javascript
+var grpc = require('grpc');
+var api = grpc.load('gobgp.proto').gobgpapi;
+var stub = new api.GobgpApi('localhost:50051', grpc.credentials.createInsecure());
+
+stub.getNeighbor({}, function(err, neighbor) {
+ neighbor.peers.forEach(function(peer) {
+ if(peer.info.bgp_state == 'BGP_FSM_ESTABLISHED') {
+ var date = new Date(Number(peer.timers.state.uptime)*1000);
+ var holdtime = peer.timers.state.negotiated_hold_time;
+ var keepalive = peer.timers.state.keepalive_interval;
+ }
+
+ console.log('BGP neighbor:', peer.conf.neighbor_address,
+ ', remote AS:', peer.conf.peer_as);
+ console.log("\tBGP version 4, remote router ID:", peer.conf.id);
+ console.log("\tBGP state:", peer.info.bgp_state,
+ ', uptime:', date);
+ console.log("\tBGP OutQ:", peer.info.out_q,
+ ', Flops:', peer.info.flops);
+ console.log("\tHold time:", holdtime,
+ ', keepalive interval:', keepalive, 'seconds');
+ console.log("\tConfigured hold time:", peer.timers.config.hold_time);
+ });
+});
```
-['tools/grpc/nodejs/get_neighbor.js'](https://github.com/osrg/gobgp/blob/master/tools/grpc/nodejs/get_neighbors.js) shows an example to show neighbor information.
Let's run this:
```
-$ node get_neighbors.js
BGP neighbor: 10.0.255.1 , remote AS: 65001
BGP version 4, remote router ID: 10.0.255.1
BGP state: BGP_FSM_ESTABLISHED , uptime: Wed Jul 20 2016 05:37:22 GMT+0900 (JST)
@@ -136,13 +382,7 @@ BGP neighbor: 10.0.255.2 , remote AS: 65002
```
## Java
-
-At the time of this writing, versions of each plugins and tools are as following:
-* ProtocolBuffer: 3.3.0
-* grpc-java: 1.4.0
-* java: 1.8.0_131
-
-In proceeding with the following procedure, please substitute versions to the latest.
+We can make a client in Java using [grpc-java](https://github.com/grpc/grpc-java).
### Install JDK:
We need to install JDK and we use Oracle JDK8 in this example.
@@ -151,18 +391,41 @@ $ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer
$ java -version
-java version "1.8.0_131"
-Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
-Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
+java version "1.8.0_72"
+Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
+Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode)
$ echo "export JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> ~/.bashrc
$ source ~/.bashrc
```
+
+### Install ProtocolBuffers:
+We use v3.0.0 beta2.
+```bash
+$ sudo apt-get install -y build-essential autoconf git libtool unzip
+$ mkdir ~/work
+$ cd ~/work
+$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-2.tar.gz
+$ tar xvzf v3.0.0-beta-2.tar.gz
+$ cd protobuf-3.0.0-beta-2
+$ ./autogen.sh
+$ ./configure
+$ make
+$ sudo make install
+$ echo "export LD_LIBRARY_PATH=/usr/local/lib" >> ~/.bashrc
+$ source ~/.bashrc
+```
+
+Please check the version.
+ ```bash
+ $ protoc --version
+ libprotoc 3.0.0
+ ```
+
### Create protobuf library for Java:
-We assume you've cloned gRPC repository in your home directory.
```bash
$ sudo apt-get install maven
-$ cd ~/grpc/third_party/protobuf/java
+$ cd ~/work/protobuf-3.0.0-beta-2/java
$ mvn package
...
[INFO]
@@ -174,20 +437,22 @@ $ mvn package
[INFO] Finished at: Mon Feb 08 11:51:51 JST 2016
[INFO] Final Memory: 31M/228M
[INFO] ------------------------------------------------------------------------
-$ ls ./core/target/proto*
-./core/target/protobuf-java-3.3.0.jar
+$ ls ./target/proto*
+./target/protobuf-java-3.0.0-beta-2.jar
```
-### Clone grpc-java and get plugins
+### Clone grpc-java and build protoc plugin and other dependencies:
```bash
$ cd ~/work
$ git clone https://github.com/grpc/grpc-java.git
$ cd ./grpc-java
-$ git checkout -b v1.4.0 v1.4.0
+$ git checkout -b v0.12.0 v0.12.0
$ cd ./all
$ ../gradlew build
$ ls ../compiler/build/binaries/java_pluginExecutable/
protoc-gen-grpc-java
+$ ls ./build/libs/grpc-all-0.12.0*
+./build/libs/grpc-all-0.12.0-javadoc.jar ./build/libs/grpc-all-0.12.0-sources.jar ./build/libs/grpc-all-0.12.0.jar
```
### Generate stub classes:
@@ -197,50 +462,94 @@ $ mkdir -p java/src
$ cd java
$ GOBGP_API=$GOPATH/src/github.com/osrg/gobgp/api
$ protoc --java_out=./src --proto_path="$GOBGP_API" $GOBGP_API/gobgp.proto
-$ protoc --plugin=protoc-gen-grpc-java=$HOME/work/grpc-java/compiler/build/exe/java_plugin/protoc-gen-grpc-java --grpc-java_out=./src --proto_path="$GOBGP_API" $GOBGP_API/gobgp.proto
+$ protoc --plugin=protoc-gen-grpc-java=$HOME/work/grpc-java/compiler/build/binaries/java_pluginExecutable/protoc-gen-grpc-java --grpc-java_out=./src --proto_path="$GOBGP_API" $GOBGP_API/gobgp.proto
$ ls ./src/gobgpapi/
Gobgp.java GobgpApiGrpc.java
```
-### Build sample client:
+### Create your own client and build it:
+```bash
+$ cd ~/go/src/github.com/osrg/gobgp/tools/grpc/java
+$ mkdir -p src/gobgp/example
+$ cd src/gobgp/example
+$ vi GobgpSampleClient.java
+```
-['tools/grpc/java/src/gobgp/example/GobgpSampleClient.java'](https://github.com/osrg/gobgp/blob/master/tools/grpc/java/src/gobgp/example/GobgpSampleClient.java) is an example to show neighbor information.
+```java
+package gobgp.example;
+
+import gobgpapi.Gobgp;
+import gobgpapi.GobgpApiGrpc;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+
+import java.util.Iterator;
+
+public class GobgpSampleClient {
+
+ private final GobgpApiGrpc.GobgpApiBlockingStub blockingStub;
+
+ public GobgpSampleClient(String host, int port) {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();
+ this.blockingStub = GobgpApiGrpc.newBlockingStub(channel);
+ }
+
+ public void getNeighbors(){
+
+ Gobgp.Arguments request = Gobgp.Arguments.newBuilder().build();
+
+ for(Iterator iterator = this.blockingStub.getNeighbors(request); iterator.hasNext(); ) {
+ Gobgp.Peer p = iterator.next();
+ Gobgp.PeerConf conf = p.getConf();
+ Gobgp.PeerState state = p.getInfo();
+ Gobgp.Timers timer = p.getTimers();
+
+ System.out.printf("BGP neighbor is %s, remote AS %d\n", conf.getNeighborAddress(), conf.getPeerAs());
+ System.out.printf("\tBGP version 4, remote router ID %s\n", conf.getId());
+ System.out.printf("\tBGP state = %s, up for %d\n", state.getBgpState(), timer.getState().getUptime());
+ System.out.printf("\tBGP OutQ = %d, Flops = %d\n", state.getOutQ(), state.getFlops());
+ System.out.printf("\tHold time is %d, keepalive interval is %d seconds\n",
+ timer.getState().getHoldTime(), timer.getState().getKeepaliveInterval());
+ System.out.printf("\tConfigured hold time is %d\n", timer.getConfig().getHoldTime());
+
+ }
+ }
+
+ public static void main(String args[]){
+ new GobgpSampleClient(args[0], 8080).getNeighbors();
+ }
+
+}
+
+```
Let's build and run it. However we need to download and copy some dependencies beforehand.
```bash
$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/java
$ mkdir lib
$ cd lib
-$ wget http://central.maven.org/maven2/com/google/guava/guava/22.0/guava-22.0.jar
-$ wget http://central.maven.org/maven2/com/squareup/okhttp/okhttp/2.5.0/okhttp-2.7.5.jar
-$ wget http://central.maven.org/maven2/com/squareup/okio/okio/1.13.0/okio-1.13.0.jar
-$ wget http://central.maven.org/maven2/com/google/instrumentation/instrumentation-api/0.4.3/instrumentation-api-0.4.3.jar
-$ cp ~/grpc/third_party/protobuf/java/core/target/protobuf-java-3.3.0.jar ./
-$ cp ~/work/grpc-java/stub/build/libs/grpc-stub-1.4.0.jar ./
-$ cp ~/work/grpc-java/core/build/libs/grpc-core-1.4.0.jar ./
-$ cp ~/work/grpc-java/protobuf/build/libs/grpc-protobuf-1.4.0.jar ./
-$ cp ~/work/grpc-java/protobuf-lite/build/libs/grpc-protobuf-lite-1.4.0.jar ./
-$ cp ~/work/grpc-java/context/build/libs/grpc-context-1.4.0.jar ./
-$ cp ~/work/grpc-java/okhttp/build/libs/grpc-okhttp-1.4.0.jar ./
+$ wget http://central.maven.org/maven2/com/google/guava/guava/18.0/guava-18.0.jar
+$ wget http://central.maven.org/maven2/com/squareup/okhttp/okhttp/2.5.0/okhttp-2.5.0.jar
+$ wget http://central.maven.org/maven2/com/squareup/okio/okio/1.6.0/okio-1.6.0.jar
+$ cp ~/work/protobuf-3.0.0-beta-2/java/target/protobuf-java-3.0.0-beta-2.jar ./
+$ cp ~/work/grpc-java/all/build/libs/grpc-all-0.12.0.jar ./
```
We are ready to build and run.
```bash
$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/java
$ mkdir classes
-$ CLASSPATH=./lib/protobuf-java-3.3.0.jar:./lib/guava-22.0.jar:./lib/grpc-okhttp-1.4.0.jar:./lib/okio-1.13.0.jar:./lib/grpc-stub-1.4.0.jar:./lib/grpc-core-1.4.0.jar:./lib/grpc-protobuf-1.4.0.jar:./lib/okhttp-2.7.5.jar:./lib/instrumentation-api-0.4.3.jar:./lib/grpc-context-1.4.0.jar:./lib/grpc-protobuf-lite-1.4.0.jar:./classes/
+$ CLASSPATH=./lib/protobuf-java-3.0.0-beta-2.jar:./lib/grpc-all-0.12.0.jar:./lib/guava-18.0.jar:./lib/okhttp-2.5.0.jar:./lib/okio-1.6.0.jar:./classes
$ javac -classpath $CLASSPATH -d ./classes ./src/gobgpapi/*.java
$ javac -classpath $CLASSPATH -d ./classes ./src/gobgp/example/GobgpSampleClient.java
$ java -cp $CLASSPATH gobgp.example.GobgpSampleClient localhost
-BGP neighbor is 10.0.0.2, remote AS 1
- BGP version 4, remote router ID
- BGP state = active, up for 0
- BGP OutQ = 0, Flops = 0
- Hold time is 0, keepalive interval is 0 seconds
- Configured hold time is 90
-BGP neighbor is 10.0.0.3, remote AS 1
- BGP version 4, remote router ID
- BGP state = active, up for 0
+Feb 08, 2016 2:39:29 PM io.grpc.internal.TransportSet$1 run
+INFO: Created transport io.grpc.okhttp.OkHttpClientTransport@ba4d54(localhost/127.0.0.1:8080) for localhost/127.0.0.1:8080
+Feb 08, 2016 2:39:29 PM io.grpc.internal.TransportSet$TransportListener transportReady
+INFO: Transport io.grpc.okhttp.OkHttpClientTransport@ba4d54(localhost/127.0.0.1:8080) for localhost/127.0.0.1:8080 is ready
+BGP neighbor is 10.0.255.1, remote AS 65001
+ BGP version 4, remote router ID
+ BGP state = BGP_FSM_ACTIVE, up for 0
BGP OutQ = 0, Flops = 0
Hold time is 0, keepalive interval is 0 seconds
Configured hold time is 90
diff --git a/vendor/github.com/osrg/gobgp/docs/sources/lib.md b/vendor/github.com/osrg/gobgp/docs/sources/lib.md
index 0e5b7e9f..e6bbd958 100644
--- a/vendor/github.com/osrg/gobgp/docs/sources/lib.md
+++ b/vendor/github.com/osrg/gobgp/docs/sources/lib.md
@@ -12,7 +12,7 @@ package main
import (
"fmt"
- log "github.com/sirupsen/logrus"
+ log "github.com/Sirupsen/logrus"
api "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
diff --git a/vendor/github.com/osrg/gobgp/gobgp/cmd/common.go b/vendor/github.com/osrg/gobgp/gobgp/cmd/common.go
index 124c2b99..a104c567 100644
--- a/vendor/github.com/osrg/gobgp/gobgp/cmd/common.go
+++ b/vendor/github.com/osrg/gobgp/gobgp/cmd/common.go
@@ -178,8 +178,8 @@ func (n neighbors) Swap(i, j int) {
}
func (n neighbors) Less(i, j int) bool {
- p1 := n[i].State.NeighborAddress
- p2 := n[j].State.NeighborAddress
+ p1 := n[i].Config.NeighborAddress
+ p2 := n[j].Config.NeighborAddress
p1Isv4 := !strings.Contains(p1, ":")
p2Isv4 := !strings.Contains(p2, ":")
if p1Isv4 != p2Isv4 {
diff --git a/vendor/github.com/osrg/gobgp/gobgp/cmd/monitor.go b/vendor/github.com/osrg/gobgp/gobgp/cmd/monitor.go
index 9d2d841f..661b6c24 100644
--- a/vendor/github.com/osrg/gobgp/gobgp/cmd/monitor.go
+++ b/vendor/github.com/osrg/gobgp/gobgp/cmd/monitor.go
@@ -89,7 +89,7 @@ func NewMonitorCmd() *cobra.Command {
j, _ := json.Marshal(s)
fmt.Println(string(j))
} else {
- addr := s.State.NeighborAddress
+ addr := s.Config.NeighborAddress
if s.Config.NeighborInterface != "" {
addr = fmt.Sprintf("%s(%s)", addr, s.Config.NeighborInterface)
}
diff --git a/vendor/github.com/osrg/gobgp/gobgp/cmd/mrt.go b/vendor/github.com/osrg/gobgp/gobgp/cmd/mrt.go
index f89e801f..680c51fa 100644
--- a/vendor/github.com/osrg/gobgp/gobgp/cmd/mrt.go
+++ b/vendor/github.com/osrg/gobgp/gobgp/cmd/mrt.go
@@ -80,8 +80,6 @@ func injectMrt(filename string, count int, skip int, onlyBest bool) error {
peers = msg.Body.(*mrt.PeerIndexTable).Peers
continue
case mrt.RIB_IPV4_UNICAST, mrt.RIB_IPV6_UNICAST:
- case mrt.GEO_PEER_TABLE:
- fmt.Printf("WARNING: Skipping GEO_PEER_TABLE: %s", msg.Body.(*mrt.GeoPeerTable))
default:
exitWithError(fmt.Errorf("unsupported subType: %v", subType))
}
diff --git a/vendor/github.com/osrg/gobgp/gobgp/cmd/neighbor.go b/vendor/github.com/osrg/gobgp/gobgp/cmd/neighbor.go
index ffd835fc..261e3d58 100644
--- a/vendor/github.com/osrg/gobgp/gobgp/cmd/neighbor.go
+++ b/vendor/github.com/osrg/gobgp/gobgp/cmd/neighbor.go
@@ -77,7 +77,7 @@ func showNeighbors(vrf string) error {
if globalOpts.Quiet {
for _, p := range m {
- fmt.Println(p.State.NeighborAddress)
+ fmt.Println(p.Config.NeighborAddress)
}
return nil
}
@@ -92,7 +92,7 @@ func showNeighbors(vrf string) error {
for _, n := range m {
if i := len(n.Config.NeighborInterface); i > maxaddrlen {
maxaddrlen = i
- } else if j := len(n.State.NeighborAddress); j > maxaddrlen {
+ } else if j := len(n.Config.NeighborAddress); j > maxaddrlen {
maxaddrlen = j
}
if l := len(getASN(n)); l > maxaslen {
@@ -142,7 +142,7 @@ func showNeighbors(vrf string) error {
}
for i, n := range m {
- neigh := n.State.NeighborAddress
+ neigh := n.Config.NeighborAddress
if n.Config.NeighborInterface != "" {
neigh = n.Config.NeighborInterface
}
@@ -163,7 +163,7 @@ func showNeighbor(args []string) error {
return nil
}
- fmt.Printf("BGP neighbor is %s, remote AS %s", p.State.NeighborAddress, getASN(p))
+ fmt.Printf("BGP neighbor is %s, remote AS %s", p.Config.NeighborAddress, getASN(p))
if p.RouteReflector.Config.RouteReflectorClient {
fmt.Printf(", route-reflector-client\n")
@@ -854,7 +854,6 @@ func modNeighbor(cmdType string, args []string) error {
peer.Config.NeighborInterface = m["interface"][0]
} else {
peer.Config.NeighborAddress = m[""][0]
- peer.State.NeighborAddress = m[""][0]
}
if len(m["vrf"]) == 1 {
peer.Config.Vrf = m["vrf"][0]
@@ -953,7 +952,7 @@ func NewNeighborCmd() *cobra.Command {
if err != nil {
exitWithError(err)
}
- addr = peer.State.NeighborAddress
+ addr = peer.Config.NeighborAddress
}
err := f(cmd.Use, addr, args[:len(args)-1])
if err != nil {
@@ -984,7 +983,7 @@ func NewNeighborCmd() *cobra.Command {
if err != nil {
exitWithError(err)
}
- remoteIP := peer.State.NeighborAddress
+ remoteIP := peer.Config.NeighborAddress
for _, v := range []string{CMD_IN, CMD_IMPORT, CMD_EXPORT} {
if err := showNeighborPolicy(remoteIP, v, 4); err != nil {
exitWithError(err)
@@ -1001,7 +1000,7 @@ func NewNeighborCmd() *cobra.Command {
if err != nil {
exitWithError(err)
}
- remoteIP := peer.State.NeighborAddress
+ remoteIP := peer.Config.NeighborAddress
err = showNeighborPolicy(remoteIP, cmd.Use, 0)
if err != nil {
exitWithError(err)
@@ -1017,7 +1016,7 @@ func NewNeighborCmd() *cobra.Command {
if err != nil {
exitWithError(err)
}
- remoteIP := peer.State.NeighborAddress
+ remoteIP := peer.Config.NeighborAddress
args = args[:len(args)-1]
if err = modNeighborPolicy(remoteIP, cmd.Use, subcmd.Use, args); err != nil {
exitWithError(err)
diff --git a/vendor/github.com/osrg/gobgp/gobgpd/main.go b/vendor/github.com/osrg/gobgp/gobgpd/main.go
index caf1793f..91e98f6c 100644
--- a/vendor/github.com/osrg/gobgp/gobgpd/main.go
+++ b/vendor/github.com/osrg/gobgp/gobgpd/main.go
@@ -24,6 +24,7 @@ import (
"runtime"
"syscall"
+ log "github.com/Sirupsen/logrus"
"github.com/jessevdk/go-flags"
p "github.com/kr/pretty"
api "github.com/osrg/gobgp/api"
@@ -31,7 +32,6 @@ import (
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/server"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
@@ -149,7 +149,6 @@ func main() {
select {
case newConfig := <-configCh:
var added, deleted, updated []config.Neighbor
- var addedPg, deletedPg, updatedPg []config.PeerGroup
var updatePolicy bool
if c == nil {
@@ -191,7 +190,6 @@ func main() {
}
added = newConfig.Neighbors
- addedPg = newConfig.PeerGroups
if opts.GracefulRestart {
for i, n := range added {
if n.GracefulRestart.Config.Enabled {
@@ -201,10 +199,7 @@ func main() {
}
} else {
- addedPg, deletedPg, updatedPg = config.UpdatePeerGroupConfig(c, newConfig)
- added, deleted, updated = config.UpdateNeighborConfig(c, newConfig)
- updatePolicy = config.CheckPolicyDifference(config.ConfigSetToRoutingPolicy(c), config.ConfigSetToRoutingPolicy(newConfig))
-
+ added, deleted, updated, updatePolicy = config.UpdateConfig(c, newConfig)
if updatePolicy {
log.Info("Policy config is updated")
p := config.ConfigSetToRoutingPolicy(newConfig)
@@ -246,46 +241,21 @@ func main() {
}
c = newConfig
}
- for i, pg := range addedPg {
- log.Infof("PeerGroup %s is added", pg.Config.PeerGroupName)
- if err := bgpServer.AddPeerGroup(&addedPg[i]); err != nil {
- log.Warn(err)
- }
- }
- for i, pg := range deletedPg {
- log.Infof("PeerGroup %s is deleted", pg.Config.PeerGroupName)
- if err := bgpServer.DeletePeerGroup(&deletedPg[i]); err != nil {
- log.Warn(err)
- }
- }
- for i, pg := range updatedPg {
- log.Infof("PeerGroup %s is updated", pg.Config.PeerGroupName)
- u, err := bgpServer.UpdatePeerGroup(&updatedPg[i])
- if err != nil {
- log.Warn(err)
- }
- updatePolicy = updatePolicy || u
- }
- for _, dn := range newConfig.DynamicNeighbors {
- log.Infof("Dynamic Neighbor %s is added to PeerGroup %s", dn.Config.Prefix, dn.Config.PeerGroup)
- if err := bgpServer.AddDynamicNeighbor(&dn); err != nil {
- log.Warn(err)
- }
- }
+
for i, p := range added {
- log.Infof("Peer %v is added", p.State.NeighborAddress)
+ log.Infof("Peer %v is added", p.Config.NeighborAddress)
if err := bgpServer.AddNeighbor(&added[i]); err != nil {
log.Warn(err)
}
}
for i, p := range deleted {
- log.Infof("Peer %v is deleted", p.State.NeighborAddress)
+ log.Infof("Peer %v is deleted", p.Config.NeighborAddress)
if err := bgpServer.DeleteNeighbor(&deleted[i]); err != nil {
log.Warn(err)
}
}
for i, p := range updated {
- log.Infof("Peer %v is updated", p.State.NeighborAddress)
+ log.Infof("Peer %v is updated", p.Config.NeighborAddress)
u, err := bgpServer.UpdateNeighbor(&updated[i])
if err != nil {
log.Warn(err)
diff --git a/vendor/github.com/osrg/gobgp/gobgpd/util.go b/vendor/github.com/osrg/gobgp/gobgpd/util.go
index 25e9b888..577363d3 100644
--- a/vendor/github.com/osrg/gobgp/gobgpd/util.go
+++ b/vendor/github.com/osrg/gobgp/gobgpd/util.go
@@ -26,8 +26,8 @@ import (
"strings"
"syscall"
- log "github.com/sirupsen/logrus"
- "github.com/sirupsen/logrus/hooks/syslog"
+ log "github.com/Sirupsen/logrus"
+ "github.com/Sirupsen/logrus/hooks/syslog"
)
func init() {
diff --git a/vendor/github.com/osrg/gobgp/gobmpd/main.go b/vendor/github.com/osrg/gobgp/gobmpd/main.go
index f875f847..a91d3752 100644
--- a/vendor/github.com/osrg/gobgp/gobmpd/main.go
+++ b/vendor/github.com/osrg/gobgp/gobmpd/main.go
@@ -19,8 +19,8 @@ import (
"bufio"
"encoding/json"
"fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet/bmp"
- log "github.com/sirupsen/logrus"
"net"
"os"
"strconv"
diff --git a/vendor/github.com/osrg/gobgp/packet/bgp/bgp.go b/vendor/github.com/osrg/gobgp/packet/bgp/bgp.go
index a32ce069..034a2bcb 100644
--- a/vendor/github.com/osrg/gobgp/packet/bgp/bgp.go
+++ b/vendor/github.com/osrg/gobgp/packet/bgp/bgp.go
@@ -590,31 +590,10 @@ func (m BGPAddPathMode) String() string {
}
}
-type CapAddPathTuple struct {
- RouteFamily RouteFamily
- Mode BGPAddPathMode
-}
-
-func (t *CapAddPathTuple) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- RouteFamily RouteFamily `json:"family"`
- Mode uint8 `json:"mode"`
- }{
- RouteFamily: t.RouteFamily,
- Mode: uint8(t.Mode),
- })
-}
-
-func NewCapAddPathTuple(family RouteFamily, mode BGPAddPathMode) *CapAddPathTuple {
- return &CapAddPathTuple{
- RouteFamily: family,
- Mode: mode,
- }
-}
-
type CapAddPath struct {
DefaultParameterCapability
- Tuples []*CapAddPathTuple
+ RouteFamily RouteFamily
+ Mode BGPAddPathMode
}
func (c *CapAddPath) DecodeFromBytes(data []byte) error {
@@ -623,46 +602,40 @@ func (c *CapAddPath) DecodeFromBytes(data []byte) error {
if len(data) < 4 {
return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityAddPath bytes available")
}
- c.Tuples = []*CapAddPathTuple{}
- for len(data) >= 4 {
- t := &CapAddPathTuple{
- RouteFamily: AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2]),
- Mode: BGPAddPathMode(data[3]),
- }
- c.Tuples = append(c.Tuples, t)
- data = data[4:]
- }
+ c.RouteFamily = AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2])
+ c.Mode = BGPAddPathMode(data[3])
return nil
}
func (c *CapAddPath) Serialize() ([]byte, error) {
- buf := make([]byte, len(c.Tuples)*4)
- for i, t := range c.Tuples {
- afi, safi := RouteFamilyToAfiSafi(t.RouteFamily)
- binary.BigEndian.PutUint16(buf[i*4:i*4+2], afi)
- buf[i*4+2] = safi
- buf[i*4+3] = byte(t.Mode)
- }
+ buf := make([]byte, 4)
+ afi, safi := RouteFamilyToAfiSafi(c.RouteFamily)
+ binary.BigEndian.PutUint16(buf, afi)
+ buf[2] = safi
+ buf[3] = byte(c.Mode)
c.DefaultParameterCapability.CapValue = buf
return c.DefaultParameterCapability.Serialize()
}
func (c *CapAddPath) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
- Code BGPCapabilityCode `json:"code"`
- Tuples []*CapAddPathTuple `json:"tuples"`
+ Code BGPCapabilityCode `json:"code"`
+ Value RouteFamily `json:"value"`
+ Mode BGPAddPathMode `json:"mode"`
}{
- Code: c.Code(),
- Tuples: c.Tuples,
+ Code: c.Code(),
+ Value: c.RouteFamily,
+ Mode: c.Mode,
})
}
-func NewCapAddPath(tuples []*CapAddPathTuple) *CapAddPath {
+func NewCapAddPath(rf RouteFamily, mode BGPAddPathMode) *CapAddPath {
return &CapAddPath{
DefaultParameterCapability: DefaultParameterCapability{
CapCode: BGP_CAP_ADD_PATH,
},
- Tuples: tuples,
+ RouteFamily: rf,
+ Mode: mode,
}
}
diff --git a/vendor/github.com/osrg/gobgp/packet/bgp/helper.go b/vendor/github.com/osrg/gobgp/packet/bgp/helper.go
index d97095f9..1a06db1e 100644
--- a/vendor/github.com/osrg/gobgp/packet/bgp/helper.go
+++ b/vendor/github.com/osrg/gobgp/packet/bgp/helper.go
@@ -31,7 +31,7 @@ func NewTestBGPOpenMessage() *BGPMessage {
p4 := NewOptionParameterCapability(
[]ParameterCapabilityInterface{NewCapFourOctetASNumber(100000)})
p5 := NewOptionParameterCapability(
- []ParameterCapabilityInterface{NewCapAddPath([]*CapAddPathTuple{NewCapAddPathTuple(RF_IPv4_UC, BGP_ADD_PATH_BOTH)})})
+ []ParameterCapabilityInterface{NewCapAddPath(RF_IPv4_UC, BGP_ADD_PATH_BOTH)})
return NewBGPOpenMessage(11033, 303, "100.4.10.3",
[]OptionParameterInterface{p1, p2, p3, p4, p5})
}
diff --git a/vendor/github.com/osrg/gobgp/packet/bmp/bmp.go b/vendor/github.com/osrg/gobgp/packet/bmp/bmp.go
index 6537e12c..342c8e97 100644
--- a/vendor/github.com/osrg/gobgp/packet/bmp/bmp.go
+++ b/vendor/github.com/osrg/gobgp/packet/bmp/bmp.go
@@ -802,159 +802,6 @@ const (
BMP_ROUTE_MIRRORING_INFO_MSG_LOST
)
-type BMPRouteMirrTLVInterface interface {
- ParseValue([]byte) error
- Serialize() ([]byte, error)
-}
-
-type BMPRouteMirrTLV struct {
- Type uint16
- Length uint16
-}
-
-type BMPRouteMirrTLVBGPMsg struct {
- BMPRouteMirrTLV
- Value *bgp.BGPMessage
-}
-
-func NewBMPRouteMirrTLVBGPMsg(t uint16, v *bgp.BGPMessage) *BMPRouteMirrTLVBGPMsg {
- return &BMPRouteMirrTLVBGPMsg{
- BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t},
- Value: v,
- }
-}
-
-func (s *BMPRouteMirrTLVBGPMsg) ParseValue(data []byte) error {
- v, err := bgp.ParseBGPMessage(data)
- if err != nil {
- return err
- }
- s.Value = v
- return nil
-}
-
-func (s *BMPRouteMirrTLVBGPMsg) Serialize() ([]byte, error) {
- m, err := s.Value.Serialize()
- if err != nil {
- return nil, err
- }
- s.Length = uint16(len(m))
- buf := make([]byte, 4)
- binary.BigEndian.PutUint16(buf[0:2], s.Type)
- binary.BigEndian.PutUint16(buf[2:4], s.Length)
- buf = append(buf, m...)
- return buf, nil
-}
-
-type BMPRouteMirrTLV16 struct {
- BMPRouteMirrTLV
- Value uint16
-}
-
-func NewBMPRouteMirrTLV16(t uint16, v uint16) *BMPRouteMirrTLV16 {
- return &BMPRouteMirrTLV16{
- BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t},
- Value: v,
- }
-}
-
-func (s *BMPRouteMirrTLV16) ParseValue(data []byte) error {
- s.Value = binary.BigEndian.Uint16(data[:2])
- return nil
-}
-
-func (s *BMPRouteMirrTLV16) Serialize() ([]byte, error) {
- s.Length = 2
- buf := make([]byte, 6)
- binary.BigEndian.PutUint16(buf[0:2], s.Type)
- binary.BigEndian.PutUint16(buf[2:4], s.Length)
- binary.BigEndian.PutUint16(buf[4:6], s.Value)
- return buf, nil
-}
-
-type BMPRouteMirrTLVUnknown struct {
- BMPRouteMirrTLV
- Value []byte
-}
-
-func NewBMPRouteMirrTLVUnknown(t uint16, v []byte) *BMPRouteMirrTLVUnknown {
- return &BMPRouteMirrTLVUnknown{
- BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t},
- Value: v,
- }
-}
-
-func (s *BMPRouteMirrTLVUnknown) ParseValue(data []byte) error {
- s.Value = data[:s.Length]
- return nil
-}
-
-func (s *BMPRouteMirrTLVUnknown) Serialize() ([]byte, error) {
- s.Length = uint16(len([]byte(s.Value)))
- buf := make([]byte, 4)
- binary.BigEndian.PutUint16(buf[0:2], s.Type)
- binary.BigEndian.PutUint16(buf[2:4], s.Length)
- buf = append(buf, s.Value...)
- return buf, nil
-}
-
-type BMPRouteMirroring struct {
- Info []BMPRouteMirrTLVInterface
-}
-
-func NewBMPRouteMirroring(p BMPPeerHeader, info []BMPRouteMirrTLVInterface) *BMPMessage {
- return &BMPMessage{
- Header: BMPHeader{
- Version: BMP_VERSION,
- Type: BMP_MSG_ROUTE_MIRRORING,
- },
- PeerHeader: p,
- Body: &BMPRouteMirroring{
- Info: info,
- },
- }
-}
-
-func (body *BMPRouteMirroring) ParseBody(msg *BMPMessage, data []byte) error {
- for len(data) >= 4 {
- tl := BMPRouteMirrTLV{
- Type: binary.BigEndian.Uint16(data[0:2]),
- Length: binary.BigEndian.Uint16(data[2:4]),
- }
- data = data[4:]
- if len(data) < int(tl.Length) {
- return fmt.Errorf("value lengh is not enough: %d bytes (%d bytes expected)", len(data), tl.Length)
- }
- var tlv BMPRouteMirrTLVInterface
- switch tl.Type {
- case BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG:
- tlv = &BMPRouteMirrTLVBGPMsg{BMPRouteMirrTLV: tl}
- case BMP_ROUTE_MIRRORING_TLV_TYPE_INFO:
- tlv = &BMPRouteMirrTLV16{BMPRouteMirrTLV: tl}
- default:
- tlv = &BMPRouteMirrTLVUnknown{BMPRouteMirrTLV: tl}
- }
- if err := tlv.ParseValue(data); err != nil {
- return err
- }
- body.Info = append(body.Info, tlv)
- data = data[tl.Length:]
- }
- return nil
-}
-
-func (body *BMPRouteMirroring) Serialize() ([]byte, error) {
- buf := make([]byte, 0)
- for _, tlv := range body.Info {
- b, err := tlv.Serialize()
- if err != nil {
- return buf, err
- }
- buf = append(buf, b...)
- }
- return buf, nil
-}
-
type BMPBody interface {
// Sigh, some body messages need a BMPHeader to parse the body
// data so we need to pass BMPHeader (avoid DecodeFromBytes
@@ -1037,10 +884,6 @@ func ParseBMPMessage(data []byte) (msg *BMPMessage, err error) {
msg.Body = &BMPInitiation{}
case BMP_MSG_TERMINATION:
msg.Body = &BMPTermination{}
- case BMP_MSG_ROUTE_MIRRORING:
- msg.Body = &BMPRouteMirroring{}
- default:
- return nil, fmt.Errorf("unsupported BMP message type: %d", msg.Header.Type)
}
if msg.Header.Type != BMP_MSG_INITIATION && msg.Header.Type != BMP_MSG_TERMINATION {
diff --git a/vendor/github.com/osrg/gobgp/packet/bmp/bmp_test.go b/vendor/github.com/osrg/gobgp/packet/bmp/bmp_test.go
index ecae38bc..061e870c 100644
--- a/vendor/github.com/osrg/gobgp/packet/bmp/bmp_test.go
+++ b/vendor/github.com/osrg/gobgp/packet/bmp/bmp_test.go
@@ -92,20 +92,6 @@ func Test_StatisticsReport(t *testing.T) {
verify(t, s0)
}
-func Test_RouteMirroring(t *testing.T) {
- p0 := NewBMPPeerHeader(0, 0, 1000, "10.0.0.1", 70000, "10.0.0.2", 1)
- s0 := NewBMPRouteMirroring(
- *p0,
- []BMPRouteMirrTLVInterface{
- NewBMPRouteMirrTLV16(BMP_ROUTE_MIRRORING_TLV_TYPE_INFO, BMP_ROUTE_MIRRORING_INFO_MSG_LOST),
- NewBMPRouteMirrTLVUnknown(0xff, []byte{0x01, 0x02, 0x03, 0x04}),
- // RFC7854: BGP Message TLV MUST occur last in the list of TLVs
- NewBMPRouteMirrTLVBGPMsg(BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG, bgp.NewTestBGPOpenMessage()),
- },
- )
- verify(t, s0)
-}
-
func Test_BogusHeader(t *testing.T) {
h, err := ParseBMPMessage(make([]byte, 10))
assert.Nil(t, h)
diff --git a/vendor/github.com/osrg/gobgp/packet/mrt/mrt.go b/vendor/github.com/osrg/gobgp/packet/mrt/mrt.go
index 559455d1..38be0e95 100644
--- a/vendor/github.com/osrg/gobgp/packet/mrt/mrt.go
+++ b/vendor/github.com/osrg/gobgp/packet/mrt/mrt.go
@@ -67,7 +67,6 @@ const (
RIB_IPV6_UNICAST MRTSubTypeTableDumpv2 = 4
RIB_IPV6_MULTICAST MRTSubTypeTableDumpv2 = 5
RIB_GENERIC MRTSubTypeTableDumpv2 = 6
- GEO_PEER_TABLE MRTSubTypeTableDumpv2 = 7 // RFC6397
RIB_IPV4_UNICAST_ADDPATH MRTSubTypeTableDumpv2 = 8 // RFC8050
RIB_IPV4_MULTICAST_ADDPATH MRTSubTypeTableDumpv2 = 9 // RFC8050
RIB_IPV6_UNICAST_ADDPATH MRTSubTypeTableDumpv2 = 10 // RFC8050
@@ -543,115 +542,6 @@ func (u *Rib) String() string {
return fmt.Sprintf("RIB: Seq [%d] Prefix [%s] Entries [%s]", u.SequenceNumber, u.Prefix, u.Entries)
}
-type GeoPeer struct {
- Type uint8
- BgpId net.IP
- Latitude float32
- Longitude float32
-}
-
-func (p *GeoPeer) DecodeFromBytes(data []byte) ([]byte, error) {
- if len(data) < 13 {
- return nil, fmt.Errorf("not all GeoPeer bytes are available")
- }
- // Peer IP Address and Peer AS should not be included
- p.Type = uint8(data[0])
- if p.Type != uint8(0) {
- return nil, fmt.Errorf("unsupported peer type for GeoPeer: %d", p.Type)
- }
- p.BgpId = net.IP(data[1:5])
- p.Latitude = math.Float32frombits(binary.BigEndian.Uint32(data[5:9]))
- p.Longitude = math.Float32frombits(binary.BigEndian.Uint32(data[9:13]))
- return data[13:], nil
-}
-
-func (p *GeoPeer) Serialize() ([]byte, error) {
- buf := make([]byte, 13)
- buf[0] = uint8(0) // Peer IP Address and Peer AS should not be included
- bgpId := p.BgpId.To4()
- if bgpId == nil {
- return nil, fmt.Errorf("invalid BgpId: %s", p.BgpId)
- }
- copy(buf[1:5], bgpId)
- binary.BigEndian.PutUint32(buf[5:9], math.Float32bits(p.Latitude))
- binary.BigEndian.PutUint32(buf[9:13], math.Float32bits(p.Longitude))
- return buf, nil
-}
-
-func NewGeoPeer(bgpid string, latitude float32, longitude float32) *GeoPeer {
- return &GeoPeer{
- Type: 0, // Peer IP Address and Peer AS should not be included
- BgpId: net.ParseIP(bgpid).To4(),
- Latitude: latitude,
- Longitude: longitude,
- }
-}
-
-func (p *GeoPeer) String() string {
- return fmt.Sprintf("PEER ENTRY: ID [%s] Latitude [%f] Longitude [%f]", p.BgpId, p.Latitude, p.Longitude)
-}
-
-type GeoPeerTable struct {
- CollectorBgpId net.IP
- CollectorLatitude float32
- CollectorLongitude float32
- Peers []*GeoPeer
-}
-
-func (t *GeoPeerTable) DecodeFromBytes(data []byte) error {
- if len(data) < 14 {
- return fmt.Errorf("not all GeoPeerTable bytes are available")
- }
- t.CollectorBgpId = net.IP(data[0:4])
- t.CollectorLatitude = math.Float32frombits(binary.BigEndian.Uint32(data[4:8]))
- t.CollectorLongitude = math.Float32frombits(binary.BigEndian.Uint32(data[8:12]))
- peerCount := binary.BigEndian.Uint16(data[12:14])
- data = data[14:]
- t.Peers = make([]*GeoPeer, 0, peerCount)
- var err error
- for i := 0; i < int(peerCount); i++ {
- p := &GeoPeer{}
- if data, err = p.DecodeFromBytes(data); err != nil {
- return err
- }
- t.Peers = append(t.Peers, p)
- }
- return nil
-}
-
-func (t *GeoPeerTable) Serialize() ([]byte, error) {
- buf := make([]byte, 14)
- collectorBgpId := t.CollectorBgpId.To4()
- if collectorBgpId == nil {
- return nil, fmt.Errorf("invalid CollectorBgpId: %s", t.CollectorBgpId)
- }
- copy(buf[0:4], collectorBgpId)
- binary.BigEndian.PutUint32(buf[4:8], math.Float32bits(t.CollectorLatitude))
- binary.BigEndian.PutUint32(buf[8:12], math.Float32bits(t.CollectorLongitude))
- binary.BigEndian.PutUint16(buf[12:14], uint16(len(t.Peers)))
- for _, peer := range t.Peers {
- pbuf, err := peer.Serialize()
- if err != nil {
- return nil, err
- }
- buf = append(buf, pbuf...)
- }
- return buf, nil
-}
-
-func NewGeoPeerTable(bgpid string, latitude float32, longitude float32, peers []*GeoPeer) *GeoPeerTable {
- return &GeoPeerTable{
- CollectorBgpId: net.ParseIP(bgpid).To4(),
- CollectorLatitude: latitude,
- CollectorLongitude: longitude,
- Peers: peers,
- }
-}
-
-func (t *GeoPeerTable) String() string {
- return fmt.Sprintf("GEO_PEER_TABLE: CollectorBgpId [%s] CollectorLatitude [%f] CollectorLongitude [%f] Peers [%s]", t.CollectorBgpId, t.CollectorLatitude, t.CollectorLongitude, t.Peers)
-}
-
type BGP4MPHeader struct {
PeerAS uint32
LocalAS uint32
@@ -922,8 +812,6 @@ func ParseMRTBody(h *MRTHeader, data []byte) (*MRTMessage, error) {
case RIB_IPV6_MULTICAST:
rf = bgp.RF_IPv6_MC
case RIB_GENERIC:
- case GEO_PEER_TABLE:
- msg.Body = &GeoPeerTable{}
case RIB_IPV4_UNICAST_ADDPATH:
rf = bgp.RF_IPv4_UC
isAddPath = true
@@ -942,7 +830,7 @@ func ParseMRTBody(h *MRTHeader, data []byte) (*MRTMessage, error) {
return nil, fmt.Errorf("unsupported table dumpv2 subtype: %v\n", subType)
}
- if msg.Body == nil {
+ if subType != PEER_INDEX_TABLE {
msg.Body = &Rib{
RouteFamily: rf,
isAddPath: isAddPath,
diff --git a/vendor/github.com/osrg/gobgp/packet/mrt/mrt_test.go b/vendor/github.com/osrg/gobgp/packet/mrt/mrt_test.go
index e2e601a5..1b5978b0 100644
--- a/vendor/github.com/osrg/gobgp/packet/mrt/mrt_test.go
+++ b/vendor/github.com/osrg/gobgp/packet/mrt/mrt_test.go
@@ -227,22 +227,6 @@ func TestMrtRibWithAddPath(t *testing.T) {
assert.Equal(t, reflect.DeepEqual(r1, r2), true)
}
-func TestMrtGeoPeerTable(t *testing.T) {
- p1 := NewGeoPeer("192.168.0.1", 28.031157, 86.899684)
- p2 := NewGeoPeer("192.168.0.1", 35.360556, 138.727778)
- pt1 := NewGeoPeerTable("192.168.0.1", 12.345678, 98.765432, []*GeoPeer{p1, p2})
- b1, err := pt1.Serialize()
- if err != nil {
- t.Fatal(err)
- }
- pt2 := &GeoPeerTable{}
- err = pt2.DecodeFromBytes(b1)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, reflect.DeepEqual(pt1, pt2), true)
-}
-
func TestMrtBgp4mpStateChange(t *testing.T) {
c1 := NewBGP4MPStateChange(65000, 65001, 1, "192.168.0.1", "192.168.0.2", false, ACTIVE, ESTABLISHED)
b1, err := c1.Serialize()
diff --git a/vendor/github.com/osrg/gobgp/server/bmp.go b/vendor/github.com/osrg/gobgp/server/bmp.go
index 1e12e372..e7dc3ea2 100644
--- a/vendor/github.com/osrg/gobgp/server/bmp.go
+++ b/vendor/github.com/osrg/gobgp/server/bmp.go
@@ -17,11 +17,11 @@ package server
import (
"fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/packet/bmp"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"net"
"strconv"
"time"
@@ -127,9 +127,6 @@ func (b *bmpClient) loop() {
if b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_LOCAL_RIB || b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_ALL {
ops = append(ops, WatchBestPath(true))
}
- if b.c.RouteMirroringEnabled {
- ops = append(ops, WatchMessage(false))
- }
w := b.s.Watch(ops...)
defer w.Stop()
@@ -212,15 +209,6 @@ func (b *bmpClient) loop() {
return false
}
}
- case *WatchEventMessage:
- info := &table.PeerInfo{
- Address: msg.PeerAddress,
- AS: msg.PeerAS,
- ID: msg.PeerID,
- }
- if err := write(bmpPeerRouteMirroring(bmp.BMP_PEER_TYPE_GLOBAL, 0, info, msg.Timestamp.Unix(), msg.Message)); err != nil {
- return false
- }
}
case <-tickerCh:
neighborList := b.s.GetNeighbor("", true)
@@ -289,26 +277,12 @@ func bmpPeerRoute(t uint8, policy bool, pd uint64, peeri *table.PeerInfo, timest
func bmpPeerStats(peerType uint8, peerDist uint64, timestamp int64, neighConf *config.Neighbor) *bmp.BMPMessage {
var peerFlags uint8 = 0
- ph := bmp.NewBMPPeerHeader(peerType, peerFlags, peerDist, neighConf.State.NeighborAddress, neighConf.State.PeerAs, neighConf.State.RemoteRouterId, float64(timestamp))
+ ph := bmp.NewBMPPeerHeader(peerType, peerFlags, peerDist, neighConf.Config.NeighborAddress, neighConf.State.PeerAs, neighConf.State.RemoteRouterId, float64(timestamp))
return bmp.NewBMPStatisticsReport(
*ph,
[]bmp.BMPStatsTLVInterface{
bmp.NewBMPStatsTLV64(bmp.BMP_STAT_TYPE_ADJ_RIB_IN, uint64(neighConf.State.AdjTable.Accepted)),
bmp.NewBMPStatsTLV64(bmp.BMP_STAT_TYPE_LOC_RIB, uint64(neighConf.State.AdjTable.Advertised+neighConf.State.AdjTable.Filtered)),
- bmp.NewBMPStatsTLV32(bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE, neighConf.State.Messages.Received.WithdrawUpdate),
- bmp.NewBMPStatsTLV32(bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX, neighConf.State.Messages.Received.WithdrawPrefix),
- },
- )
-}
-
-func bmpPeerRouteMirroring(peerType uint8, peerDist uint64, peerInfo *table.PeerInfo, timestamp int64, msg *bgp.BGPMessage) *bmp.BMPMessage {
- var peerFlags uint8 = 0
- ph := bmp.NewBMPPeerHeader(peerType, peerFlags, peerDist, peerInfo.Address.String(), peerInfo.AS, peerInfo.ID.String(), float64(timestamp))
- return bmp.NewBMPRouteMirroring(
- *ph,
- []bmp.BMPRouteMirrTLVInterface{
- // RFC7854: BGP Message TLV MUST occur last in the list of TLVs
- bmp.NewBMPRouteMirrTLVBGPMsg(bmp.BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG, msg),
},
)
}
diff --git a/vendor/github.com/osrg/gobgp/server/collector.go b/vendor/github.com/osrg/gobgp/server/collector.go
index 50fb72e9..59f945be 100644
--- a/vendor/github.com/osrg/gobgp/server/collector.go
+++ b/vendor/github.com/osrg/gobgp/server/collector.go
@@ -17,10 +17,10 @@ package server
import (
"fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/influxdata/influxdb/client/v2"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"time"
)
diff --git a/vendor/github.com/osrg/gobgp/server/fsm.go b/vendor/github.com/osrg/gobgp/server/fsm.go
index afd04b3e..e1b85cd0 100644
--- a/vendor/github.com/osrg/gobgp/server/fsm.go
+++ b/vendor/github.com/osrg/gobgp/server/fsm.go
@@ -17,12 +17,11 @@ package server
import (
"fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
- "github.com/osrg/gobgp/packet/bmp"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"gopkg.in/tomb.v2"
"io"
"math/rand"
@@ -183,18 +182,6 @@ func (fsm *FSM) bgpMessageStateUpdate(MessageType uint8, isIn bool) {
}
}
-func (fsm *FSM) bmpStatsUpdate(statType uint16, increment int) {
- stats := &fsm.pConf.State.Messages.Received
- switch statType {
- // TODO
- // Support other stat types.
- case bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE:
- stats.WithdrawUpdate += uint32(increment)
- case bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX:
- stats.WithdrawPrefix += uint32(increment)
- }
-}
-
func NewFSM(gConf *config.Global, pConf *config.Neighbor, policy *table.RoutingPolicy) *FSM {
adminState := ADMIN_STATE_UP
if pConf.Config.AdminDown {
@@ -227,7 +214,7 @@ func NewFSM(gConf *config.Global, pConf *config.Neighbor, policy *table.RoutingP
func (fsm *FSM) StateChange(nextState bgp.FSMState) {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"old": fsm.state.String(),
"new": nextState.String(),
"reason": fsm.reason,
@@ -298,12 +285,12 @@ func (fsm *FSM) sendNotificationFromErrorMsg(e *bgp.MessageError) error {
fsm.h.conn.Close()
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"Data": e,
}).Warn("sent notification")
return nil
}
- return fmt.Errorf("can't send notification to %s since TCP connection is not established", fsm.pConf.State.NeighborAddress)
+ return fmt.Errorf("can't send notification to %s since TCP connection is not established", fsm.pConf.Config.NeighborAddress)
}
func (fsm *FSM) sendNotification(code, subType uint8, data []byte, msg string) error {
@@ -323,7 +310,7 @@ func (fsm *FSM) connectLoop() error {
timer.Stop()
connect := func() {
- addr := fsm.pConf.State.NeighborAddress
+ addr := fsm.pConf.Config.NeighborAddress
port := int(bgp.BGP_PORT)
if fsm.pConf.Transport.Config.RemotePort != 0 {
port = int(fsm.pConf.Transport.Config.RemotePort)
@@ -342,7 +329,7 @@ func (fsm *FSM) connectLoop() error {
if e != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
}).Warnf("failed to resolve ltcpaddr: %s", e)
return
}
@@ -358,13 +345,13 @@ func (fsm *FSM) connectLoop() error {
conn.Close()
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
}).Warn("active conn is closed to avoid being blocked")
}
} else {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
}).Debugf("failed to connect: %s", err)
}
@@ -378,7 +365,7 @@ func (fsm *FSM) connectLoop() error {
case <-fsm.t.Dying():
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
}).Debug("stop connect loop")
return nil
case <-timer.C:
@@ -429,7 +416,7 @@ func (h *FSMHandler) idle() (bgp.FSMState, FsmStateReason) {
if fsm.pConf.GracefulRestart.State.PeerRestarting {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("graceful restart timer expired")
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
@@ -441,7 +428,7 @@ func (h *FSMHandler) idle() (bgp.FSMState, FsmStateReason) {
conn.Close()
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("Closed an accepted connection")
case <-idleHoldTimer.C:
@@ -449,7 +436,7 @@ func (h *FSMHandler) idle() (bgp.FSMState, FsmStateReason) {
if fsm.adminState == ADMIN_STATE_UP {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"Duration": fsm.idleHoldTime,
}).Debug("IdleHoldTimer expired")
fsm.idleHoldTime = HOLDTIME_IDLE
@@ -487,38 +474,13 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) {
break
}
fsm.conn = conn
- ttl := 0
- ttlMin := 0
- if fsm.pConf.TtlSecurity.Config.Enabled {
- ttl = 255
- ttlMin = int(fsm.pConf.TtlSecurity.Config.TtlMin)
- } else if fsm.pConf.Config.PeerAs != 0 && fsm.pConf.Config.PeerType == config.PEER_TYPE_EXTERNAL {
+ if fsm.pConf.Config.PeerAs != 0 && fsm.pConf.Config.PeerType == config.PEER_TYPE_EXTERNAL {
+ ttl := 1
if fsm.pConf.EbgpMultihop.Config.Enabled {
ttl = int(fsm.pConf.EbgpMultihop.Config.MultihopTtl)
- } else if fsm.pConf.Transport.Config.Ttl != 0 {
- ttl = int(fsm.pConf.Transport.Config.Ttl)
- } else {
- ttl = 1
}
- } else if fsm.pConf.Transport.Config.Ttl != 0 {
- ttl = int(fsm.pConf.Transport.Config.Ttl)
- }
- if ttl != 0 {
- if err := SetTcpTTLSockopts(conn.(*net.TCPConn), ttl); err != nil {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": fsm.pConf.Config.NeighborAddress,
- "State": fsm.state.String(),
- }).Warnf("cannot set TTL(=%d) for peer: %s", ttl, err)
- }
- }
- if ttlMin != 0 {
- if err := SetTcpMinTTLSockopts(conn.(*net.TCPConn), ttlMin); err != nil {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": fsm.pConf.Config.NeighborAddress,
- "State": fsm.state.String(),
- }).Warnf("cannot set minimal TTL(=%d) for peer: %s", ttl, err)
+ if ttl != 0 {
+ SetTcpTTLSockopts(conn.(*net.TCPConn), ttl)
}
}
// we don't implement delayed open timer so move to opensent right
@@ -528,7 +490,7 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) {
if fsm.pConf.GracefulRestart.State.PeerRestarting {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("graceful restart timer expired")
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
@@ -544,7 +506,7 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) {
case ADMIN_STATE_UP:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"AdminState": stateOp.State.String(),
}).Panic("code logic bug")
@@ -683,13 +645,13 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
h.fsm.bgpMessageStateUpdate(0, true)
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": h.fsm.pConf.State.NeighborAddress,
+ "Key": h.fsm.pConf.Config.NeighborAddress,
"State": h.fsm.state.String(),
"error": err,
}).Warn("malformed BGP Header")
fmsg := &FsmMsg{
MsgType: FSM_MSG_BGP_MESSAGE,
- MsgSrc: h.fsm.pConf.State.NeighborAddress,
+ MsgSrc: h.fsm.pConf.Config.NeighborAddress,
MsgData: err,
Version: h.fsm.version,
}
@@ -712,14 +674,14 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
}
fmsg := &FsmMsg{
MsgType: FSM_MSG_BGP_MESSAGE,
- MsgSrc: h.fsm.pConf.State.NeighborAddress,
+ MsgSrc: h.fsm.pConf.Config.NeighborAddress,
timestamp: now,
Version: h.fsm.version,
}
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": h.fsm.pConf.State.NeighborAddress,
+ "Key": h.fsm.pConf.Config.NeighborAddress,
"State": h.fsm.state.String(),
"error": err,
}).Warn("malformed BGP message")
@@ -742,7 +704,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": h.fsm.pConf.State.NeighborAddress,
+ "Key": h.fsm.pConf.Config.NeighborAddress,
"State": h.fsm.state.String(),
"error": err,
}).Warn("malformed BGP update message")
@@ -750,17 +712,6 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
return fmsg, err
}
- if routes := len(body.WithdrawnRoutes); routes > 0 {
- h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE, 1)
- h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX, routes)
- } else if attr := getPathAttrFromBGPUpdate(body, bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI); attr != nil {
- mpUnreach := attr.(*bgp.PathAttributeMpUnreachNLRI)
- if routes = len(mpUnreach.Value); routes > 0 {
- h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE, 1)
- h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX, routes)
- }
- }
-
table.UpdatePathAttrs4ByteAs(body)
if err = table.UpdatePathAggregator4ByteAs(body); err != nil {
fmsg.MsgData = err
@@ -777,7 +728,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
}
fmsg.PathList = table.ProcessMessage(m, h.fsm.peerInfo, fmsg.timestamp)
- id := h.fsm.pConf.State.NeighborAddress
+ id := h.fsm.pConf.Config.NeighborAddress
for _, path := range fmsg.PathList {
if path.IsEOR() {
continue
@@ -804,7 +755,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
communication, rest := decodeAdministrativeCommunication(body.Data)
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": h.fsm.pConf.State.NeighborAddress,
+ "Key": h.fsm.pConf.Config.NeighborAddress,
"Code": body.ErrorCode,
"Subcode": body.ErrorSubcode,
"Communicated-Reason": communication,
@@ -813,7 +764,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
} else {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": h.fsm.pConf.State.NeighborAddress,
+ "Key": h.fsm.pConf.Config.NeighborAddress,
"Code": body.ErrorCode,
"Subcode": body.ErrorSubcode,
"Data": body.Data,
@@ -905,17 +856,16 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
conn.Close()
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("Closed an accepted connection")
case <-fsm.gracefulRestartTimer.C:
if fsm.pConf.GracefulRestart.State.PeerRestarting {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("graceful restart timer expired")
- h.conn.Close()
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
}
case i, ok := <-h.msgCh.Out():
@@ -944,7 +894,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
fsm.pConf.State.PeerType = typ
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Infof("skiped asn negotiation: peer-as: %d, peer-type: %s", peerAs, typ)
} else {
@@ -999,7 +949,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
if fsm.pConf.GracefulRestart.State.PeerRestarting && cap.Flags&0x08 == 0 {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("restart flag is not set")
// send notification?
@@ -1043,7 +993,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
default:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Data": e.MsgData,
}).Panic("unknown msg type")
@@ -1065,7 +1015,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
case ADMIN_STATE_UP:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"AdminState": stateOp.State.String(),
}).Panic("code logic bug")
@@ -1116,17 +1066,16 @@ func (h *FSMHandler) openconfirm() (bgp.FSMState, FsmStateReason) {
conn.Close()
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("Closed an accepted connection")
case <-fsm.gracefulRestartTimer.C:
if fsm.pConf.GracefulRestart.State.PeerRestarting {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("graceful restart timer expired")
- h.conn.Close()
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
}
case <-ticker.C:
@@ -1155,7 +1104,7 @@ func (h *FSMHandler) openconfirm() (bgp.FSMState, FsmStateReason) {
default:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Data": e.MsgData,
}).Panic("unknown msg type")
@@ -1177,7 +1126,7 @@ func (h *FSMHandler) openconfirm() (bgp.FSMState, FsmStateReason) {
case ADMIN_STATE_UP:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"AdminState": stateOp.State.String(),
}).Panic("code logic bug")
@@ -1195,7 +1144,7 @@ func (h *FSMHandler) sendMessageloop() error {
if fsm.twoByteAsTrans && m.Header.Type == bgp.BGP_MSG_UPDATE {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Data": m,
}).Debug("update for 2byte AS peer")
@@ -1206,7 +1155,7 @@ func (h *FSMHandler) sendMessageloop() error {
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Data": err,
}).Warn("failed to serialize")
@@ -1222,7 +1171,7 @@ func (h *FSMHandler) sendMessageloop() error {
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Data": err,
}).Warn("failed to send")
@@ -1239,7 +1188,7 @@ func (h *FSMHandler) sendMessageloop() error {
communication, rest := decodeAdministrativeCommunication(body.Data)
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Code": body.ErrorCode,
"Subcode": body.ErrorSubcode,
@@ -1249,7 +1198,7 @@ func (h *FSMHandler) sendMessageloop() error {
} else {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Code": body.ErrorCode,
"Subcode": body.ErrorSubcode,
@@ -1263,7 +1212,7 @@ func (h *FSMHandler) sendMessageloop() error {
update := m.Body.(*bgp.BGPUpdate)
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"nlri": update.NLRI,
"withdrawals": update.WithdrawnRoutes,
@@ -1272,7 +1221,7 @@ func (h *FSMHandler) sendMessageloop() error {
default:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"data": m,
}).Debug("sent")
@@ -1348,7 +1297,7 @@ func (h *FSMHandler) established() (bgp.FSMState, FsmStateReason) {
conn.Close()
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("Closed an accepted connection")
case err := <-h.errorCh:
@@ -1358,7 +1307,7 @@ func (h *FSMHandler) established() (bgp.FSMState, FsmStateReason) {
err = FSM_GRACEFUL_RESTART
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Info("peer graceful restart")
fsm.gracefulRestartTimer.Reset(time.Duration(fsm.pConf.GracefulRestart.State.PeerRestartTime) * time.Second)
@@ -1367,7 +1316,7 @@ func (h *FSMHandler) established() (bgp.FSMState, FsmStateReason) {
case <-holdTimer.C:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("hold timer expired")
m := bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_HOLD_TIMER_EXPIRED, 0, nil)
@@ -1424,7 +1373,7 @@ func (h *FSMHandler) loop() error {
if nextState == bgp.BGP_FSM_ESTABLISHED && oldState == bgp.BGP_FSM_OPENCONFIRM {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Info("Peer Up")
}
@@ -1438,14 +1387,14 @@ func (h *FSMHandler) loop() error {
}
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"Reason": reason,
}).Info("Peer Down")
}
e := time.AfterFunc(time.Second*120, func() {
- log.WithFields(log.Fields{"Topic": "Peer"}).Fatalf("failed to free the fsm.h.t for %s %s %s", fsm.pConf.State.NeighborAddress, oldState, nextState)
+ log.WithFields(log.Fields{"Topic": "Peer"}).Fatalf("failed to free the fsm.h.t for %s %s %s", fsm.pConf.Config.NeighborAddress, oldState, nextState)
})
h.t.Wait()
e.Stop()
@@ -1454,7 +1403,7 @@ func (h *FSMHandler) loop() error {
if nextState >= bgp.BGP_FSM_IDLE {
e := &FsmMsg{
MsgType: FSM_MSG_STATE_CHANGE,
- MsgSrc: fsm.pConf.State.NeighborAddress,
+ MsgSrc: fsm.pConf.Config.NeighborAddress,
MsgData: nextState,
Version: h.fsm.version,
}
@@ -1468,7 +1417,7 @@ func (h *FSMHandler) changeAdminState(s AdminState) error {
if fsm.adminState != s {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
"AdminState": s.String(),
}).Debug("admin state changed")
@@ -1480,19 +1429,19 @@ func (h *FSMHandler) changeAdminState(s AdminState) error {
case ADMIN_STATE_UP:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Info("Administrative start")
case ADMIN_STATE_DOWN:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Info("Administrative shutdown")
case ADMIN_STATE_PFX_CT:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Info("Administrative shutdown(Prefix limit reached)")
}
@@ -1500,7 +1449,7 @@ func (h *FSMHandler) changeAdminState(s AdminState) error {
} else {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": fsm.pConf.State.NeighborAddress,
+ "Key": fsm.pConf.Config.NeighborAddress,
"State": fsm.state.String(),
}).Warn("cannot change to the same state")
diff --git a/vendor/github.com/osrg/gobgp/server/fsm_test.go b/vendor/github.com/osrg/gobgp/server/fsm_test.go
index 55318ac3..e8ad2ad8 100644
--- a/vendor/github.com/osrg/gobgp/server/fsm_test.go
+++ b/vendor/github.com/osrg/gobgp/server/fsm_test.go
@@ -23,11 +23,11 @@ import (
"testing"
"time"
+ log "github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
diff --git a/vendor/github.com/osrg/gobgp/server/mrt.go b/vendor/github.com/osrg/gobgp/server/mrt.go
index e2cfa6fc..6c66745d 100644
--- a/vendor/github.com/osrg/gobgp/server/mrt.go
+++ b/vendor/github.com/osrg/gobgp/server/mrt.go
@@ -21,11 +21,11 @@ import (
"os"
"time"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/packet/mrt"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
)
const (
@@ -109,7 +109,7 @@ func (m *mrtWriter) loop() error {
t := uint32(time.Now().Unix())
peers := make([]*mrt.Peer, 0, len(m.Neighbor))
for _, pconf := range m.Neighbor {
- peers = append(peers, mrt.NewPeer(pconf.State.RemoteRouterId, pconf.State.NeighborAddress, pconf.Config.PeerAs, true))
+ peers = append(peers, mrt.NewPeer(pconf.State.RemoteRouterId, pconf.Config.NeighborAddress, pconf.Config.PeerAs, true))
}
if bm, err := mrt.NewMRTMessage(t, mrt.TABLE_DUMPv2, mrt.PEER_INDEX_TABLE, mrt.NewPeerIndexTable(m.RouterId, "", peers)); err != nil {
break
@@ -119,7 +119,7 @@ func (m *mrtWriter) loop() error {
idx := func(p *table.Path) uint16 {
for i, pconf := range m.Neighbor {
- if p.GetSource().Address.String() == pconf.State.NeighborAddress {
+ if p.GetSource().Address.String() == pconf.Config.NeighborAddress {
return uint16(i)
}
}
diff --git a/vendor/github.com/osrg/gobgp/server/peer.go b/vendor/github.com/osrg/gobgp/server/peer.go
index e51efc93..6ead5fbe 100644
--- a/vendor/github.com/osrg/gobgp/server/peer.go
+++ b/vendor/github.com/osrg/gobgp/server/peer.go
@@ -17,11 +17,11 @@ package server
import (
"fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"net"
"time"
)
@@ -31,65 +31,6 @@ const (
MIN_CONNECT_RETRY = 10
)
-type PeerGroup struct {
- Conf *config.PeerGroup
- members map[string]config.Neighbor
- dynamicNeighbors map[string]*config.DynamicNeighbor
-}
-
-func NewPeerGroup(c *config.PeerGroup) *PeerGroup {
- return &PeerGroup{
- Conf: c,
- members: make(map[string]config.Neighbor, 0),
- dynamicNeighbors: make(map[string]*config.DynamicNeighbor, 0),
- }
-}
-
-func (pg *PeerGroup) AddMember(c config.Neighbor) {
- pg.members[c.State.NeighborAddress] = c
-}
-
-func (pg *PeerGroup) DeleteMember(c config.Neighbor) {
- delete(pg.members, c.State.NeighborAddress)
-}
-
-func (pg *PeerGroup) AddDynamicNeighbor(c *config.DynamicNeighbor) {
- pg.dynamicNeighbors[c.Config.Prefix] = c
-}
-
-func newDynamicPeer(g *config.Global, neighborAddress string, pg *config.PeerGroup, loc *table.TableManager, policy *table.RoutingPolicy) *Peer {
- conf := config.Neighbor{
- Config: config.NeighborConfig{
- PeerGroup: pg.Config.PeerGroupName,
- },
- State: config.NeighborState{
- NeighborAddress: neighborAddress,
- },
- Transport: config.Transport{
- Config: config.TransportConfig{
- PassiveMode: true,
- },
- },
- }
- if err := config.OverwriteNeighborConfigWithPeerGroup(&conf, pg); err != nil {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": neighborAddress,
- }).Debugf("Can't overwrite neighbor config: %s", err)
- return nil
- }
- if err := config.SetDefaultNeighborConfigValues(&conf, g.Config.As); err != nil {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": neighborAddress,
- }).Debugf("Can't set default config: %s", err)
- return nil
- }
- peer := NewPeer(g, &conf, loc, policy)
- peer.fsm.state = bgp.BGP_FSM_ACTIVE
- return peer
-}
-
type Peer struct {
tableId string
fsm *FSM
@@ -110,7 +51,7 @@ func NewPeer(g *config.Global, conf *config.Neighbor, loc *table.TableManager, p
prefixLimitWarned: make(map[bgp.RouteFamily]bool),
}
if peer.isRouteServerClient() {
- peer.tableId = conf.State.NeighborAddress
+ peer.tableId = conf.Config.NeighborAddress
} else {
peer.tableId = table.GLOBAL_RIB_NAME
}
@@ -120,7 +61,7 @@ func NewPeer(g *config.Global, conf *config.Neighbor, loc *table.TableManager, p
}
func (peer *Peer) ID() string {
- return peer.fsm.pConf.State.NeighborAddress
+ return peer.fsm.pConf.Config.NeighborAddress
}
func (peer *Peer) TableID() string {
@@ -143,10 +84,6 @@ func (peer *Peer) isGracefulRestartEnabled() bool {
return peer.fsm.pConf.GracefulRestart.State.Enabled
}
-func (peer *Peer) isDynamicNeighbor() bool {
- return peer.fsm.pConf.Config.NeighborAddress == "" && peer.fsm.pConf.Config.NeighborInterface == ""
-}
-
func (peer *Peer) recvedAllEOR() bool {
for _, a := range peer.fsm.pConf.AfiSafis {
if s := a.MpGracefulRestart.State; s.Enabled && !s.EndOfRibReceived {
@@ -403,7 +340,7 @@ func (peer *Peer) processOutgoingPaths(paths, olds []*table.Path) []*table.Path
if peer.fsm.pConf.GracefulRestart.State.LocalRestarting {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": peer.fsm.pConf.State.NeighborAddress,
+ "Key": peer.fsm.pConf.Config.NeighborAddress,
}).Debug("now syncing, suppress sending updates")
return nil
}
@@ -521,7 +458,7 @@ func (peer *Peer) handleUpdate(e *FsmMsg) ([]*table.Path, []bgp.RouteFamily, *bg
update := m.Body.(*bgp.BGPUpdate)
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": peer.fsm.pConf.State.NeighborAddress,
+ "Key": peer.fsm.pConf.Config.NeighborAddress,
"nlri": update.NLRI,
"withdrawals": update.WithdrawnRoutes,
"attributes": update.PathAttributes,
@@ -628,42 +565,3 @@ func (peer *Peer) ToConfig(getAdvertised bool) *config.Neighbor {
func (peer *Peer) DropAll(rfList []bgp.RouteFamily) {
peer.adjRibIn.Drop(rfList)
}
-
-func (peer *Peer) stopFSM() error {
- failed := false
- addr := peer.fsm.pConf.State.NeighborAddress
- t1 := time.AfterFunc(time.Minute*5, func() {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- }).Warnf("Failed to free the fsm.h.t for %s", addr)
- failed = true
- })
- peer.fsm.h.t.Kill(nil)
- peer.fsm.h.t.Wait()
- t1.Stop()
- if !failed {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": addr,
- }).Debug("freed fsm.h.t")
- cleanInfiniteChannel(peer.outgoing)
- }
- failed = false
- t2 := time.AfterFunc(time.Minute*5, func() {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- }).Warnf("Failed to free the fsm.t for %s", addr)
- failed = true
- })
- peer.fsm.t.Kill(nil)
- peer.fsm.t.Wait()
- t2.Stop()
- if !failed {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": addr,
- }).Debug("freed fsm.t")
- return nil
- }
- return fmt.Errorf("Failed to free FSM for %s", addr)
-}
diff --git a/vendor/github.com/osrg/gobgp/server/rpki.go b/vendor/github.com/osrg/gobgp/server/rpki.go
index a93decb8..5c8c3db9 100644
--- a/vendor/github.com/osrg/gobgp/server/rpki.go
+++ b/vendor/github.com/osrg/gobgp/server/rpki.go
@@ -24,12 +24,12 @@ import (
"strconv"
"time"
+ log "github.com/Sirupsen/logrus"
"github.com/armon/go-radix"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/packet/rtr"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
diff --git a/vendor/github.com/osrg/gobgp/server/server.go b/vendor/github.com/osrg/gobgp/server/server.go
index 1ecbedf0..0bd9c0d9 100644
--- a/vendor/github.com/osrg/gobgp/server/server.go
+++ b/vendor/github.com/osrg/gobgp/server/server.go
@@ -23,11 +23,11 @@ import (
"strconv"
"time"
+ log "github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
)
type TCPListener struct {
@@ -92,29 +92,27 @@ type BgpServer struct {
fsmStateCh chan *FsmMsg
acceptCh chan *net.TCPConn
- mgmtCh chan *mgmtOp
- policy *table.RoutingPolicy
- listeners []*TCPListener
- neighborMap map[string]*Peer
- peerGroupMap map[string]*PeerGroup
- globalRib *table.TableManager
- roaManager *roaManager
- shutdown bool
- watcherMap map[WatchEventType][]*Watcher
- zclient *zebraClient
- bmpManager *bmpClientManager
- mrtManager *mrtManager
+ mgmtCh chan *mgmtOp
+ policy *table.RoutingPolicy
+ listeners []*TCPListener
+ neighborMap map[string]*Peer
+ globalRib *table.TableManager
+ roaManager *roaManager
+ shutdown bool
+ watcherMap map[WatchEventType][]*Watcher
+ zclient *zebraClient
+ bmpManager *bmpClientManager
+ mrtManager *mrtManager
}
func NewBgpServer() *BgpServer {
roaManager, _ := NewROAManager(0)
s := &BgpServer{
- neighborMap: make(map[string]*Peer),
- peerGroupMap: make(map[string]*PeerGroup),
- policy: table.NewRoutingPolicy(),
- roaManager: roaManager,
- mgmtCh: make(chan *mgmtOp, 1),
- watcherMap: make(map[WatchEventType][]*Watcher),
+ neighborMap: make(map[string]*Peer),
+ policy: table.NewRoutingPolicy(),
+ roaManager: roaManager,
+ mgmtCh: make(chan *mgmtOp, 1),
+ watcherMap: make(map[WatchEventType][]*Watcher),
}
s.bmpManager = newBmpClientManager(s)
s.mrtManager = newMrtManager(s)
@@ -236,24 +234,6 @@ func (server *BgpServer) Serve() {
"Topic": "Peer",
}).Debugf("Accepted a new passive connection from:%s", remoteAddr)
peer.PassConn(conn)
- } else if pg := server.matchLongestDynamicNeighborPrefix(remoteAddr); pg != nil {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- }).Debugf("Accepted a new dynamic neighbor from:%s", remoteAddr)
- peer := newDynamicPeer(&server.bgpConfig.Global, remoteAddr, pg.Conf, server.globalRib, server.policy)
- if peer == nil {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": remoteAddr,
- }).Infof("Can't create new Dynamic Peer")
- conn.Close()
- return
- }
- server.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): peer.fsm.pConf.ApplyPolicy})
- server.neighborMap[remoteAddr] = peer
- peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh)
- server.broadcastPeerState(peer, bgp.BGP_FSM_ACTIVE)
- peer.PassConn(conn)
} else {
log.WithFields(log.Fields{
"Topic": "Peer",
@@ -298,24 +278,6 @@ func (server *BgpServer) Serve() {
}
}
-func (server *BgpServer) matchLongestDynamicNeighborPrefix(a string) *PeerGroup {
- ipAddr := net.ParseIP(a)
- longestMask := net.CIDRMask(0, 32).String()
- var longestPG *PeerGroup
- for _, pg := range server.peerGroupMap {
- for _, d := range pg.dynamicNeighbors {
- _, netAddr, _ := net.ParseCIDR(d.Config.Prefix)
- if netAddr.Contains(ipAddr) {
- if netAddr.Mask.String() > longestMask {
- longestMask = netAddr.Mask.String()
- longestPG = pg
- }
- }
- }
- }
- return longestPG
-}
-
func sendFsmOutgoingMsg(peer *Peer, paths []*table.Path, notification *bgp.BGPMessage, stayIdle bool) {
peer.outgoing.In() <- &FsmOutgoingMsg{
Paths: paths,
@@ -570,33 +532,6 @@ func (server *BgpServer) broadcastPeerState(peer *Peer, oldState bgp.FSMState) {
}
}
-func (server *BgpServer) notifyMessageWatcher(peer *Peer, timestamp time.Time, msg *bgp.BGPMessage, isSent bool) {
- // validation should be done in the caller of this function
- _, y := peer.fsm.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER]
- l, _ := peer.fsm.LocalHostPort()
- ev := &WatchEventMessage{
- Message: msg,
- PeerAS: peer.fsm.peerInfo.AS,
- LocalAS: peer.fsm.peerInfo.LocalAS,
- PeerAddress: peer.fsm.peerInfo.Address,
- LocalAddress: net.ParseIP(l),
- PeerID: peer.fsm.peerInfo.ID,
- FourBytesAs: y,
- Timestamp: timestamp,
- IsSent: isSent,
- }
- if !isSent {
- server.notifyWatcher(WATCH_EVENT_TYPE_RECV_MSG, ev)
- }
-}
-
-func (server *BgpServer) notifyRecvMessageWatcher(peer *Peer, timestamp time.Time, msg *bgp.BGPMessage) {
- if peer == nil || !server.isWatched(WATCH_EVENT_TYPE_RECV_MSG) {
- return
- }
- server.notifyMessageWatcher(peer, timestamp, msg, false)
-}
-
func (server *BgpServer) RSimportPaths(peer *Peer, pathList []*table.Path) []*table.Path {
moded := make([]*table.Path, 0, len(pathList)/2)
for _, before := range pathList {
@@ -757,11 +692,6 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
peer.fsm.pConf.State.PeerAs = 0
peer.fsm.peerInfo.AS = 0
}
- if peer.isDynamicNeighbor() {
- peer.stopPeerRestarting()
- go peer.stopFSM()
- delete(server.neighborMap, peer.fsm.pConf.State.NeighborAddress)
- }
} else if peer.fsm.pConf.GracefulRestart.State.PeerRestarting && nextState == bgp.BGP_FSM_IDLE {
if peer.fsm.pConf.GracefulRestart.State.LongLivedEnabled {
llgr, no_llgr := peer.llgrFamilies()
@@ -842,7 +772,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
deferralExpiredFunc := func(family bgp.RouteFamily) func() {
return func() {
server.mgmtOperation(func() error {
- server.softResetOut(peer.fsm.pConf.State.NeighborAddress, family, true)
+ server.softResetOut(peer.fsm.pConf.Config.NeighborAddress, family, true)
return nil
}, false)
}
@@ -905,7 +835,6 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
// clear counter
if peer.fsm.adminState == ADMIN_STATE_DOWN {
peer.fsm.pConf.State = config.NeighborState{}
- peer.fsm.pConf.State.NeighborAddress = peer.fsm.pConf.Config.NeighborAddress
peer.fsm.pConf.Timers.State = config.TimersState{}
}
peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh)
@@ -924,7 +853,6 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
sendFsmOutgoingMsg(peer, nil, bgp.NewBGPNotificationMessage(m.TypeCode, m.SubTypeCode, m.Data), false)
return
case *bgp.BGPMessage:
- server.notifyRecvMessageWatcher(peer, e.timestamp, m)
if peer.fsm.state != bgp.BGP_FSM_ESTABLISHED || e.timestamp.Unix() < peer.fsm.pConf.Timers.State.Uptime {
return
}
@@ -1012,7 +940,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
pathList := peer.adjRibIn.DropStale(peer.configuredRFlist())
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": peer.fsm.pConf.State.NeighborAddress,
+ "Key": peer.fsm.pConf.Config.NeighborAddress,
}).Debugf("withdraw %d stale routes", len(pathList))
server.propagateUpdate(peer, pathList)
}
@@ -1042,7 +970,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
default:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": peer.fsm.pConf.State.NeighborAddress,
+ "Key": peer.fsm.pConf.Config.NeighborAddress,
"Data": e.MsgData,
}).Panic("unknown msg type")
}
@@ -1103,7 +1031,7 @@ func (s *BgpServer) UpdatePolicy(policy config.RoutingPolicy) error {
for _, peer := range s.neighborMap {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": peer.fsm.pConf.State.NeighborAddress,
+ "Key": peer.fsm.pConf.Config.NeighborAddress,
}).Info("call set policy")
ap[peer.ID()] = peer.fsm.pConf.ApplyPolicy
}
@@ -1647,42 +1575,17 @@ func (s *BgpServer) GetNeighbor(address string, getAdvertised bool) (l []*config
return l
}
-func (server *BgpServer) addPeerGroup(c *config.PeerGroup) error {
- name := c.Config.PeerGroupName
- if _, y := server.peerGroupMap[name]; y {
- return fmt.Errorf("Can't overwrite the existing peer-group: %s", name)
- }
-
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Name": name,
- }).Info("Add a peer group configuration")
-
- server.peerGroupMap[c.Config.PeerGroupName] = NewPeerGroup(c)
-
- return nil
-}
-
func (server *BgpServer) addNeighbor(c *config.Neighbor) error {
- addr, err := config.ExtractNeighborAddress(c)
- if err != nil {
- return err
- }
-
- if _, y := server.neighborMap[addr]; y {
- return fmt.Errorf("Can't overwrite the existing peer: %s", addr)
- }
-
- if c.Config.PeerGroup != "" {
- if err := config.OverwriteNeighborConfigWithPeerGroup(c, server.peerGroupMap[c.Config.PeerGroup].Conf); err != nil {
- return err
- }
- }
if err := config.SetDefaultNeighborConfigValues(c, server.bgpConfig.Global.Config.As); err != nil {
return err
}
+ addr := c.Config.NeighborAddress
+ if _, y := server.neighborMap[addr]; y {
+ return fmt.Errorf("Can't overwrite the existing peer: %s", addr)
+ }
+
if vrf := c.Config.Vrf; vrf != "" {
if c.RouteServer.Config.RouteServerClient {
return fmt.Errorf("route server client can't be enslaved to VRF")
@@ -1737,62 +1640,19 @@ func (server *BgpServer) addNeighbor(c *config.Neighbor) error {
}
}
server.neighborMap[addr] = peer
- if name := c.Config.PeerGroup; name != "" {
- server.peerGroupMap[name].AddMember(*c)
- }
peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh)
server.broadcastPeerState(peer, bgp.BGP_FSM_IDLE)
return nil
}
-func (s *BgpServer) AddPeerGroup(c *config.PeerGroup) error {
- return s.mgmtOperation(func() error {
- return s.addPeerGroup(c)
- }, true)
-}
-
func (s *BgpServer) AddNeighbor(c *config.Neighbor) error {
return s.mgmtOperation(func() error {
return s.addNeighbor(c)
}, true)
}
-func (s *BgpServer) AddDynamicNeighbor(c *config.DynamicNeighbor) error {
- return s.mgmtOperation(func() error {
- s.peerGroupMap[c.Config.PeerGroup].AddDynamicNeighbor(c)
- return nil
- }, true)
-}
-
-func (server *BgpServer) deletePeerGroup(pg *config.PeerGroup) error {
- name := pg.Config.PeerGroupName
-
- if _, y := server.peerGroupMap[name]; !y {
- return fmt.Errorf("Can't delete a peer-group %s which does not exist", name)
- }
-
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Name": name,
- }).Info("Delete a peer group configuration")
-
- delete(server.peerGroupMap, name)
- return nil
-}
-
func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) error {
- if c.Config.PeerGroup != "" {
- _, y := server.peerGroupMap[c.Config.PeerGroup]
- if y {
- server.peerGroupMap[c.Config.PeerGroup].DeleteMember(*c)
- }
- }
-
- addr, err := config.ExtractNeighborAddress(c)
- if err != nil {
- return err
- }
-
+ addr := c.Config.NeighborAddress
if intf := c.Config.NeighborInterface; intf != "" {
var err error
addr, err = config.GetIPv6LinkLocalNeighborAddress(intf)
@@ -1814,151 +1674,130 @@ func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8)
n.fsm.sendNotification(code, subcode, nil, "")
n.stopPeerRestarting()
- go n.stopFSM()
+ go func(addr string) {
+ failed := false
+ t1 := time.AfterFunc(time.Minute*5, func() {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ }).Warnf("Failed to free the fsm.h.t for %s", addr)
+ failed = true
+ })
+ n.fsm.h.t.Kill(nil)
+ n.fsm.h.t.Wait()
+ t1.Stop()
+ if !failed {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": addr,
+ }).Debug("freed fsm.h.t")
+ cleanInfiniteChannel(n.outgoing)
+ }
+ failed = false
+ t2 := time.AfterFunc(time.Minute*5, func() {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ }).Warnf("Failed to free the fsm.t for %s", addr)
+ failed = true
+ })
+ n.fsm.t.Kill(nil)
+ n.fsm.t.Wait()
+ t2.Stop()
+ if !failed {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": addr,
+ }).Debug("freed fsm.t")
+ }
+ }(addr)
delete(server.neighborMap, addr)
server.dropPeerAllRoutes(n, n.configuredRFlist())
return nil
}
-func (s *BgpServer) DeletePeerGroup(c *config.PeerGroup) error {
- return s.mgmtOperation(func() error {
- name := c.Config.PeerGroupName
- for _, n := range s.neighborMap {
- if n.fsm.pConf.Config.PeerGroup == name {
- return fmt.Errorf("failed to delete peer-group %s: neighbor %s is in use", name, n.ID())
- }
- }
- return s.deletePeerGroup(c)
- }, true)
-}
-
func (s *BgpServer) DeleteNeighbor(c *config.Neighbor) error {
return s.mgmtOperation(func() error {
return s.deleteNeighbor(c, bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_PEER_DECONFIGURED)
}, true)
}
-func (s *BgpServer) updatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) {
- name := pg.Config.PeerGroupName
-
- _, ok := s.peerGroupMap[name]
- if !ok {
- return false, fmt.Errorf("Peer-group %s doesn't exist.", name)
- }
- s.peerGroupMap[name].Conf = pg
-
- for _, n := range s.peerGroupMap[name].members {
- c := n
- u, err := s.updateNeighbor(&c)
- if err != nil {
- return needsSoftResetIn, err
- }
- needsSoftResetIn = needsSoftResetIn || u
- }
- return needsSoftResetIn, nil
-}
-
-func (s *BgpServer) UpdatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) {
+func (s *BgpServer) UpdateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) {
err = s.mgmtOperation(func() error {
- needsSoftResetIn, err = s.updatePeerGroup(pg)
- return err
- }, true)
- return needsSoftResetIn, err
-}
-
-func (s *BgpServer) updateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) {
- if c.Config.PeerGroup != "" {
- if err := config.OverwriteNeighborConfigWithPeerGroup(c, s.peerGroupMap[c.Config.PeerGroup].Conf); err != nil {
- return needsSoftResetIn, err
+ addr := c.Config.NeighborAddress
+ peer, ok := s.neighborMap[addr]
+ if !ok {
+ return fmt.Errorf("Neighbor that has %v doesn't exist.", addr)
}
- }
- addr, err := config.ExtractNeighborAddress(c)
- if err != nil {
- return needsSoftResetIn, err
- }
+ if !peer.fsm.pConf.ApplyPolicy.Equal(&c.ApplyPolicy) {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": addr,
+ }).Info("Update ApplyPolicy")
+ s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy})
+ peer.fsm.pConf.ApplyPolicy = c.ApplyPolicy
+ needsSoftResetIn = true
+ }
+ original := peer.fsm.pConf
- peer, ok := s.neighborMap[addr]
- if !ok {
- return needsSoftResetIn, fmt.Errorf("Neighbor that has %v doesn't exist.", addr)
- }
-
- if !peer.fsm.pConf.ApplyPolicy.Equal(&c.ApplyPolicy) {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": addr,
- }).Info("Update ApplyPolicy")
- s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy})
- peer.fsm.pConf.ApplyPolicy = c.ApplyPolicy
- needsSoftResetIn = true
- }
- original := peer.fsm.pConf
-
- if !original.AsPathOptions.Config.Equal(&c.AsPathOptions.Config) {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": peer.ID(),
- }).Info("Update aspath options")
- peer.fsm.pConf.AsPathOptions = c.AsPathOptions
- needsSoftResetIn = true
- }
-
- if !original.Config.Equal(&c.Config) || !original.Transport.Config.Equal(&c.Transport.Config) || config.CheckAfiSafisChange(original.AfiSafis, c.AfiSafis) {
- sub := uint8(bgp.BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE)
- if original.Config.AdminDown != c.Config.AdminDown {
- sub = bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN
- state := "Admin Down"
- if c.Config.AdminDown == false {
- state = "Admin Up"
- }
+ if !original.AsPathOptions.Config.Equal(&c.AsPathOptions.Config) {
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": peer.ID(),
- "State": state,
- }).Info("Update admin-state configuration")
- } else if original.Config.PeerAs != c.Config.PeerAs {
- sub = bgp.BGP_ERROR_SUB_PEER_DECONFIGURED
+ }).Info("Update aspath options")
+ peer.fsm.pConf.AsPathOptions = c.AsPathOptions
+ needsSoftResetIn = true
}
- if err = s.deleteNeighbor(peer.fsm.pConf, bgp.BGP_ERROR_CEASE, sub); err != nil {
+
+ if !original.Config.Equal(&c.Config) || !original.Transport.Config.Equal(&c.Transport.Config) || config.CheckAfiSafisChange(original.AfiSafis, c.AfiSafis) {
+ sub := uint8(bgp.BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE)
+ if original.Config.AdminDown != c.Config.AdminDown {
+ sub = bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN
+ state := "Admin Down"
+ if c.Config.AdminDown == false {
+ state = "Admin Up"
+ }
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.ID(),
+ "State": state,
+ }).Info("Update admin-state configuration")
+ } else if original.Config.PeerAs != c.Config.PeerAs {
+ sub = bgp.BGP_ERROR_SUB_PEER_DECONFIGURED
+ }
+ if err = s.deleteNeighbor(peer.fsm.pConf, bgp.BGP_ERROR_CEASE, sub); err != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": addr,
+ }).Error(err)
+ return err
+ }
+ err = s.addNeighbor(c)
+ if err != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": addr,
+ }).Error(err)
+ }
+ return err
+ }
+
+ if !original.Timers.Config.Equal(&c.Timers.Config) {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": addr,
- }).Error(err)
- return needsSoftResetIn, err
+ "Key": peer.ID(),
+ }).Info("Update timer configuration")
+ peer.fsm.pConf.Timers.Config = c.Timers.Config
}
- err = s.addNeighbor(c)
+
+ err = peer.updatePrefixLimitConfig(c.AfiSafis)
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": addr,
}).Error(err)
+ // rollback to original state
+ peer.fsm.pConf = original
}
- return needsSoftResetIn, err
- }
-
- if !original.Timers.Config.Equal(&c.Timers.Config) {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": peer.ID(),
- }).Info("Update timer configuration")
- peer.fsm.pConf.Timers.Config = c.Timers.Config
- }
-
- err = peer.updatePrefixLimitConfig(c.AfiSafis)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": addr,
- }).Error(err)
- // rollback to original state
- peer.fsm.pConf = original
- }
- return needsSoftResetIn, err
-}
-
-func (s *BgpServer) UpdateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) {
- err = s.mgmtOperation(func() error {
- needsSoftResetIn, err = s.updateNeighbor(c)
return err
}, true)
return needsSoftResetIn, err
@@ -2025,10 +1864,10 @@ func (s *BgpServer) setAdminState(addr, communication string, enable bool) error
case peer.fsm.adminStateCh <- *stateOp:
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": peer.fsm.pConf.State.NeighborAddress,
+ "Key": peer.fsm.pConf.Config.NeighborAddress,
}).Debug(message)
default:
- log.Warning("previous request is still remaining. : ", peer.fsm.pConf.State.NeighborAddress)
+ log.Warning("previous request is still remaining. : ", peer.fsm.pConf.Config.NeighborAddress)
}
}
if enable {
@@ -2291,7 +2130,6 @@ const (
WATCH_EVENT_TYPE_POST_UPDATE WatchEventType = "postupdate"
WATCH_EVENT_TYPE_PEER_STATE WatchEventType = "peerstate"
WATCH_EVENT_TYPE_TABLE WatchEventType = "table"
- WATCH_EVENT_TYPE_RECV_MSG WatchEventType = "receivedmessage"
)
type WatchEvent interface {
@@ -2342,18 +2180,6 @@ type WatchEventBestPath struct {
MultiPathList [][]*table.Path
}
-type WatchEventMessage struct {
- Message *bgp.BGPMessage
- PeerAS uint32
- LocalAS uint32
- PeerAddress net.IP
- LocalAddress net.IP
- PeerID net.IP
- FourBytesAs bool
- Timestamp time.Time
- IsSent bool
-}
-
type watchOptions struct {
bestpath bool
preUpdate bool
@@ -2364,8 +2190,6 @@ type watchOptions struct {
initPostUpdate bool
initPeerState bool
tableName string
- recvMessage bool
- sentMessage bool
}
type WatchOption func(*watchOptions)
@@ -2412,19 +2236,6 @@ func WatchTableName(name string) WatchOption {
}
}
-func WatchMessage(isSent bool) WatchOption {
- return func(o *watchOptions) {
- if isSent {
- log.WithFields(log.Fields{
- "Topic": "Server",
- }).Warn("watch event for sent messages is not implemented yet")
- // o.sentMessage = true
- } else {
- o.recvMessage = true
- }
- }
-}
-
type Watcher struct {
opts watchOptions
realCh chan WatchEvent
@@ -2648,9 +2459,6 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) {
}
}
}
- if w.opts.recvMessage {
- register(WATCH_EVENT_TYPE_RECV_MSG, w)
- }
go w.loop()
return nil
diff --git a/vendor/github.com/osrg/gobgp/server/server_test.go b/vendor/github.com/osrg/gobgp/server/server_test.go
index e5deb975..9caf8a62 100644
--- a/vendor/github.com/osrg/gobgp/server/server_test.go
+++ b/vendor/github.com/osrg/gobgp/server/server_test.go
@@ -16,10 +16,10 @@
package server
import (
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"net"
"runtime"
@@ -31,17 +31,13 @@ func TestModPolicyAssign(t *testing.T) {
assert := assert.New(t)
s := NewBgpServer()
go s.Serve()
- err := s.Start(&config.Global{
+ s.Start(&config.Global{
Config: config.GlobalConfig{
As: 1,
RouterId: "1.1.1.1",
- Port: -1,
},
})
- assert.Nil(err)
- defer s.Stop()
-
- err = s.AddPolicy(&table.Policy{Name: "p1"}, false)
+ err := s.AddPolicy(&table.Policy{Name: "p1"}, false)
assert.Nil(err)
err = s.AddPolicy(&table.Policy{Name: "p2"}, false)
@@ -66,16 +62,13 @@ func TestMonitor(test *testing.T) {
assert := assert.New(test)
s := NewBgpServer()
go s.Serve()
- err := s.Start(&config.Global{
+ s.Start(&config.Global{
Config: config.GlobalConfig{
As: 1,
RouterId: "1.1.1.1",
Port: 10179,
},
})
- assert.Nil(err)
- defer s.Stop()
-
n := &config.Neighbor{
Config: config.NeighborConfig{
NeighborAddress: "127.0.0.1",
@@ -87,21 +80,18 @@ func TestMonitor(test *testing.T) {
},
},
}
- err = s.AddNeighbor(n)
- assert.Nil(err)
-
+ if err := s.AddNeighbor(n); err != nil {
+ log.Fatal(err)
+ }
t := NewBgpServer()
go t.Serve()
- err = t.Start(&config.Global{
+ t.Start(&config.Global{
Config: config.GlobalConfig{
As: 2,
RouterId: "2.2.2.2",
Port: -1,
},
})
- assert.Nil(err)
- defer t.Stop()
-
m := &config.Neighbor{
Config: config.NeighborConfig{
NeighborAddress: "127.0.0.1",
@@ -113,8 +103,9 @@ func TestMonitor(test *testing.T) {
},
},
}
- err = t.AddNeighbor(m)
- assert.Nil(err)
+ if err := t.AddNeighbor(m); err != nil {
+ log.Fatal(err)
+ }
for {
time.Sleep(time.Second)
@@ -168,10 +159,6 @@ func TestNumGoroutineWithAddDeleteNeighbor(t *testing.T) {
},
})
assert.Nil(err)
- defer s.Stop()
-
- // wait a few seconds to avoid taking effect from other test cases.
- time.Sleep(time.Second * 5)
num := runtime.NumGoroutine()
@@ -356,261 +343,3 @@ func TestFilterpathWithRejectPolicy(t *testing.T) {
}
}
-
-func TestPeerGroup(test *testing.T) {
- assert := assert.New(test)
- log.SetLevel(log.DebugLevel)
- s := NewBgpServer()
- go s.Serve()
- err := s.Start(&config.Global{
- Config: config.GlobalConfig{
- As: 1,
- RouterId: "1.1.1.1",
- Port: 10179,
- },
- })
- assert.Nil(err)
- defer s.Stop()
-
- g := &config.PeerGroup{
- Config: config.PeerGroupConfig{
- PeerAs: 2,
- PeerGroupName: "g",
- },
- }
- err = s.AddPeerGroup(g)
- assert.Nil(err)
-
- n := &config.Neighbor{
- Config: config.NeighborConfig{
- NeighborAddress: "127.0.0.1",
- PeerGroup: "g",
- },
- Transport: config.Transport{
- Config: config.TransportConfig{
- PassiveMode: true,
- },
- },
- }
- configured := map[string]interface{}{
- "config": map[string]interface{}{
- "neigbor-address": "127.0.0.1",
- "peer-group": "g",
- },
- "transport": map[string]interface{}{
- "config": map[string]interface{}{
- "passive-mode": true,
- },
- },
- }
- config.RegisterConfiguredFields("127.0.0.1", configured)
- err = s.AddNeighbor(n)
- assert.Nil(err)
-
- t := NewBgpServer()
- go t.Serve()
- err = t.Start(&config.Global{
- Config: config.GlobalConfig{
- As: 2,
- RouterId: "2.2.2.2",
- Port: -1,
- },
- })
- assert.Nil(err)
- defer t.Stop()
-
- m := &config.Neighbor{
- Config: config.NeighborConfig{
- NeighborAddress: "127.0.0.1",
- PeerAs: 1,
- },
- Transport: config.Transport{
- Config: config.TransportConfig{
- RemotePort: 10179,
- },
- },
- }
- err = t.AddNeighbor(m)
- assert.Nil(err)
-
- for {
- time.Sleep(time.Second)
- if t.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED {
- break
- }
- }
-}
-
-func TestDynamicNeighbor(t *testing.T) {
- assert := assert.New(t)
- log.SetLevel(log.DebugLevel)
- s1 := NewBgpServer()
- go s1.Serve()
- err := s1.Start(&config.Global{
- Config: config.GlobalConfig{
- As: 1,
- RouterId: "1.1.1.1",
- Port: 10179,
- },
- })
- assert.Nil(err)
- defer s1.Stop()
-
- g := &config.PeerGroup{
- Config: config.PeerGroupConfig{
- PeerAs: 2,
- PeerGroupName: "g",
- },
- }
- err = s1.AddPeerGroup(g)
- assert.Nil(err)
-
- d := &config.DynamicNeighbor{
- Config: config.DynamicNeighborConfig{
- Prefix: "127.0.0.0/24",
- PeerGroup: "g",
- },
- }
- err = s1.AddDynamicNeighbor(d)
- assert.Nil(err)
-
- s2 := NewBgpServer()
- go s2.Serve()
- err = s2.Start(&config.Global{
- Config: config.GlobalConfig{
- As: 2,
- RouterId: "2.2.2.2",
- Port: -1,
- },
- })
- assert.Nil(err)
- defer s2.Stop()
-
- m := &config.Neighbor{
- Config: config.NeighborConfig{
- NeighborAddress: "127.0.0.1",
- PeerAs: 1,
- },
- Transport: config.Transport{
- Config: config.TransportConfig{
- RemotePort: 10179,
- },
- },
- }
- err = s2.AddNeighbor(m)
-
- assert.Nil(err)
-
- for {
- time.Sleep(time.Second)
- if s2.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED {
- break
- }
- }
-}
-
-func TestGracefulRestartTimerExpired(t *testing.T) {
- assert := assert.New(t)
- s1 := NewBgpServer()
- go s1.Serve()
- err := s1.Start(&config.Global{
- Config: config.GlobalConfig{
- As: 1,
- RouterId: "1.1.1.1",
- Port: 10179,
- },
- })
- assert.Nil(err)
- defer s1.Stop()
-
- n := &config.Neighbor{
- Config: config.NeighborConfig{
- NeighborAddress: "127.0.0.1",
- PeerAs: 2,
- },
- Transport: config.Transport{
- Config: config.TransportConfig{
- PassiveMode: true,
- },
- },
- GracefulRestart: config.GracefulRestart{
- Config: config.GracefulRestartConfig{
- Enabled: true,
- RestartTime: 10,
- },
- },
- }
- err = s1.AddNeighbor(n)
- assert.Nil(err)
-
- s2 := NewBgpServer()
- go s2.Serve()
- err = s2.Start(&config.Global{
- Config: config.GlobalConfig{
- As: 2,
- RouterId: "2.2.2.2",
- Port: -1,
- },
- })
- assert.Nil(err)
- defer s2.Stop()
-
- m := &config.Neighbor{
- Config: config.NeighborConfig{
- NeighborAddress: "127.0.0.1",
- PeerAs: 1,
- },
- Transport: config.Transport{
- Config: config.TransportConfig{
- RemotePort: 10179,
- },
- },
- GracefulRestart: config.GracefulRestart{
- Config: config.GracefulRestartConfig{
- Enabled: true,
- RestartTime: 10,
- },
- },
- }
- err = s2.AddNeighbor(m)
- assert.Nil(err)
-
- // Waiting for BGP session established.
- for {
- time.Sleep(time.Second)
- if s2.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED {
- break
- }
- }
-
- // Force TCP session disconnected in order to cause Graceful Restart at s1
- // side.
- for _, n := range s2.neighborMap {
- n.fsm.conn.Close()
- }
- s2.Stop()
-
- time.Sleep(5 * time.Second)
-
- // Create dummy session which does NOT send BGP OPEN message in order to
- // cause Graceful Restart timer expired.
- var conn net.Conn
- for {
- time.Sleep(time.Second)
- var err error
- conn, err = net.Dial("tcp", "127.0.0.1:10179")
- if err != nil {
- log.Warn("net.Dial:", err)
- }
- break
- }
- defer conn.Close()
-
- // Waiting for Graceful Restart timer expired and moving on to IDLE state.
- for {
- time.Sleep(time.Second)
- if s1.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_IDLE {
- break
- }
- }
-}
diff --git a/vendor/github.com/osrg/gobgp/server/sockopt.go b/vendor/github.com/osrg/gobgp/server/sockopt.go
index 2f6a8bb6..34d9ed5e 100644
--- a/vendor/github.com/osrg/gobgp/server/sockopt.go
+++ b/vendor/github.com/osrg/gobgp/server/sockopt.go
@@ -29,10 +29,6 @@ func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
return fmt.Errorf("setting ttl is not supported")
}
-func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
- return fmt.Errorf("setting min ttl is not supported")
-}
-
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
return nil, fmt.Errorf("md5 active connection unsupported")
}
diff --git a/vendor/github.com/osrg/gobgp/server/sockopt_bsd.go b/vendor/github.com/osrg/gobgp/server/sockopt_bsd.go
index a9f9d61f..62514edb 100644
--- a/vendor/github.com/osrg/gobgp/server/sockopt_bsd.go
+++ b/vendor/github.com/osrg/gobgp/server/sockopt_bsd.go
@@ -25,8 +25,7 @@ import (
)
const (
- TCP_MD5SIG = 0x10 // TCP MD5 Signature (RFC2385)
- IPV6_MINHOPCOUNT = 73 // Generalized TTL Security Mechanism (RFC5082)
+ TCP_MD5SIG = 0x10
)
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
@@ -50,7 +49,13 @@ func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error
return nil
}
-func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
+func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
+ level := syscall.IPPROTO_IP
+ name := syscall.IP_TTL
+ if strings.Contains(conn.RemoteAddr().String(), "[") {
+ level = syscall.IPPROTO_IPV6
+ name = syscall.IPV6_UNICAST_HOPS
+ }
fi, err := conn.File()
defer fi.Close()
if err != nil {
@@ -59,27 +64,7 @@ func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
if conn, err := net.FileConn(fi); err == nil {
defer conn.Close()
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, value))
-}
-
-func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
- level := syscall.IPPROTO_IP
- name := syscall.IP_TTL
- if strings.Contains(conn.RemoteAddr().String(), "[") {
- level = syscall.IPPROTO_IPV6
- name = syscall.IPV6_UNICAST_HOPS
- }
- return setTcpSockoptInt(conn, level, name, ttl)
-}
-
-func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
- level := syscall.IPPROTO_IP
- name := syscall.IP_MINTTL
- if strings.Contains(conn.RemoteAddr().String(), "[") {
- level = syscall.IPPROTO_IPV6
- name = IPV6_MINHOPCOUNT
- }
- return setTcpSockoptInt(conn, level, name, ttl)
+ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl))
}
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
diff --git a/vendor/github.com/osrg/gobgp/server/sockopt_linux.go b/vendor/github.com/osrg/gobgp/server/sockopt_linux.go
index 0dc4cd5f..1db559b5 100644
--- a/vendor/github.com/osrg/gobgp/server/sockopt_linux.go
+++ b/vendor/github.com/osrg/gobgp/server/sockopt_linux.go
@@ -26,8 +26,7 @@ import (
)
const (
- TCP_MD5SIG = 14 // TCP MD5 Signature (RFC2385)
- IPV6_MINHOPCOUNT = 73 // Generalized TTL Security Mechanism (RFC5082)
+ TCP_MD5SIG = 14
)
type tcpmd5sig struct {
@@ -75,7 +74,13 @@ func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error
return nil
}
-func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
+func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
+ level := syscall.IPPROTO_IP
+ name := syscall.IP_TTL
+ if strings.Contains(conn.RemoteAddr().String(), "[") {
+ level = syscall.IPPROTO_IPV6
+ name = syscall.IPV6_UNICAST_HOPS
+ }
fi, err := conn.File()
defer fi.Close()
if err != nil {
@@ -84,27 +89,7 @@ func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
if conn, err := net.FileConn(fi); err == nil {
defer conn.Close()
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, value))
-}
-
-func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
- level := syscall.IPPROTO_IP
- name := syscall.IP_TTL
- if strings.Contains(conn.RemoteAddr().String(), "[") {
- level = syscall.IPPROTO_IPV6
- name = syscall.IPV6_UNICAST_HOPS
- }
- return setTcpSockoptInt(conn, level, name, ttl)
-}
-
-func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
- level := syscall.IPPROTO_IP
- name := syscall.IP_MINTTL
- if strings.Contains(conn.RemoteAddr().String(), "[") {
- level = syscall.IPPROTO_IPV6
- name = IPV6_MINHOPCOUNT
- }
- return setTcpSockoptInt(conn, level, name, ttl)
+ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl))
}
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
diff --git a/vendor/github.com/osrg/gobgp/server/sockopt_openbsd.go b/vendor/github.com/osrg/gobgp/server/sockopt_openbsd.go
index 6dd26e59..16ed2c3d 100644
--- a/vendor/github.com/osrg/gobgp/server/sockopt_openbsd.go
+++ b/vendor/github.com/osrg/gobgp/server/sockopt_openbsd.go
@@ -19,7 +19,7 @@ package server
import (
"encoding/binary"
"fmt"
- log "github.com/sirupsen/logrus"
+ log "github.com/Sirupsen/logrus"
"net"
"os"
"strings"
@@ -348,8 +348,7 @@ func saDelete(address string) error {
}
const (
- TCP_MD5SIG = 0x4 // TCP MD5 Signature (RFC2385)
- IPV6_MINHOPCOUNT = 73 // Generalized TTL Security Mechanism (RFC5082)
+ TCP_MD5SIG = 0x4
)
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
@@ -374,7 +373,13 @@ func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error
return saDelete(address)
}
-func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
+func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
+ level := syscall.IPPROTO_IP
+ name := syscall.IP_TTL
+ if strings.Contains(conn.RemoteAddr().String(), "[") {
+ level = syscall.IPPROTO_IPV6
+ name = syscall.IPV6_UNICAST_HOPS
+ }
fi, err := conn.File()
defer fi.Close()
if err != nil {
@@ -383,27 +388,7 @@ func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
if conn, err := net.FileConn(fi); err == nil {
defer conn.Close()
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, value))
-}
-
-func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
- level := syscall.IPPROTO_IP
- name := syscall.IP_TTL
- if strings.Contains(conn.RemoteAddr().String(), "[") {
- level = syscall.IPPROTO_IPV6
- name = syscall.IPV6_UNICAST_HOPS
- }
- return setTcpSockoptInt(conn, level, name, ttl)
-}
-
-func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
- level := syscall.IPPROTO_IP
- name := syscall.IP_MINTTL
- if strings.Contains(conn.RemoteAddr().String(), "[") {
- level = syscall.IPPROTO_IPV6
- name = IPV6_MINHOPCOUNT
- }
- return setTcpSockoptInt(conn, level, name, ttl)
+ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl))
}
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
diff --git a/vendor/github.com/osrg/gobgp/server/zclient.go b/vendor/github.com/osrg/gobgp/server/zclient.go
index 85d238c8..d432b96d 100644
--- a/vendor/github.com/osrg/gobgp/server/zclient.go
+++ b/vendor/github.com/osrg/gobgp/server/zclient.go
@@ -17,10 +17,10 @@ package server
import (
"fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
"github.com/osrg/gobgp/zebra"
- log "github.com/sirupsen/logrus"
"net"
"strconv"
"strings"
diff --git a/vendor/github.com/osrg/gobgp/table/destination.go b/vendor/github.com/osrg/gobgp/table/destination.go
index af74f8fd..9664fdbc 100644
--- a/vendor/github.com/osrg/gobgp/table/destination.go
+++ b/vendor/github.com/osrg/gobgp/table/destination.go
@@ -23,9 +23,9 @@ import (
"net"
"sort"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
- log "github.com/sirupsen/logrus"
)
var SelectionOptions config.RouteSelectionOptionsConfig
@@ -127,7 +127,7 @@ func (i *PeerInfo) String() string {
func NewPeerInfo(g *config.Global, p *config.Neighbor) *PeerInfo {
id := net.ParseIP(string(p.RouteReflector.Config.RouteReflectorClusterId)).To4()
// exclude zone info
- naddr, _ := net.ResolveIPAddr("ip", p.State.NeighborAddress)
+ naddr, _ := net.ResolveIPAddr("ip", p.Config.NeighborAddress)
return &PeerInfo{
AS: p.Config.PeerAs,
LocalAS: g.Config.As,
diff --git a/vendor/github.com/osrg/gobgp/table/message.go b/vendor/github.com/osrg/gobgp/table/message.go
index 30a75d24..af4affa6 100644
--- a/vendor/github.com/osrg/gobgp/table/message.go
+++ b/vendor/github.com/osrg/gobgp/table/message.go
@@ -17,8 +17,8 @@ package table
import (
"bytes"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet/bgp"
- log "github.com/sirupsen/logrus"
"hash/fnv"
"reflect"
)
diff --git a/vendor/github.com/osrg/gobgp/table/path.go b/vendor/github.com/osrg/gobgp/table/path.go
index b97ca40c..b2984fe4 100644
--- a/vendor/github.com/osrg/gobgp/table/path.go
+++ b/vendor/github.com/osrg/gobgp/table/path.go
@@ -24,10 +24,10 @@ import (
"sort"
"time"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/satori/go.uuid"
- log "github.com/sirupsen/logrus"
)
const (
@@ -258,7 +258,7 @@ func UpdatePathAttrs(global *config.Global, peer *config.Neighbor, info *PeerInf
} else {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": peer.State.NeighborAddress,
+ "Key": peer.Config.NeighborAddress,
}).Warnf("invalid peer type: %d", peer.State.PeerType)
}
return path
diff --git a/vendor/github.com/osrg/gobgp/table/policy.go b/vendor/github.com/osrg/gobgp/table/policy.go
index a73fa57a..2cca91a9 100644
--- a/vendor/github.com/osrg/gobgp/table/policy.go
+++ b/vendor/github.com/osrg/gobgp/table/policy.go
@@ -26,10 +26,10 @@ import (
"strings"
"sync"
+ log "github.com/Sirupsen/logrus"
"github.com/armon/go-radix"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
- log "github.com/sirupsen/logrus"
)
type PolicyOptions struct {
diff --git a/vendor/github.com/osrg/gobgp/table/policy_test.go b/vendor/github.com/osrg/gobgp/table/policy_test.go
index c55eb1c8..a846dabe 100644
--- a/vendor/github.com/osrg/gobgp/table/policy_test.go
+++ b/vendor/github.com/osrg/gobgp/table/policy_test.go
@@ -24,9 +24,9 @@ import (
"testing"
"time"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
- log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
diff --git a/vendor/github.com/osrg/gobgp/table/table.go b/vendor/github.com/osrg/gobgp/table/table.go
index c1ed3a29..6e90faf7 100644
--- a/vendor/github.com/osrg/gobgp/table/table.go
+++ b/vendor/github.com/osrg/gobgp/table/table.go
@@ -20,9 +20,9 @@ import (
"net"
"sort"
+ log "github.com/Sirupsen/logrus"
"github.com/armon/go-radix"
"github.com/osrg/gobgp/packet/bgp"
- log "github.com/sirupsen/logrus"
)
type LookupOption uint8
diff --git a/vendor/github.com/osrg/gobgp/table/table_manager.go b/vendor/github.com/osrg/gobgp/table/table_manager.go
index e41c2798..3060dda0 100644
--- a/vendor/github.com/osrg/gobgp/table/table_manager.go
+++ b/vendor/github.com/osrg/gobgp/table/table_manager.go
@@ -18,8 +18,8 @@ package table
import (
"bytes"
"fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet/bgp"
- log "github.com/sirupsen/logrus"
"net"
"time"
)
diff --git a/vendor/github.com/osrg/gobgp/table/table_manager_test.go b/vendor/github.com/osrg/gobgp/table/table_manager_test.go
index 2a8ed2f6..21d15026 100644
--- a/vendor/github.com/osrg/gobgp/table/table_manager_test.go
+++ b/vendor/github.com/osrg/gobgp/table/table_manager_test.go
@@ -17,8 +17,8 @@ package table
import (
_ "fmt"
+ log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet/bgp"
- log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"net"
"os"
diff --git a/vendor/github.com/osrg/gobgp/test/lib/base.py b/vendor/github.com/osrg/gobgp/test/lib/base.py
index 0421e9d7..907050bc 100644
--- a/vendor/github.com/osrg/gobgp/test/lib/base.py
+++ b/vendor/github.com/osrg/gobgp/test/lib/base.py
@@ -103,7 +103,7 @@ def make_gobgp_ctn(tag='gobgp', local_gobgp_path='', from_image='osrg/quagga'):
c = CmdBuffer()
c << 'FROM {0}'.format(from_image)
- c << 'RUN go get -d github.com/osrg/gobgp/...; exit 0'
+ c << 'RUN go get -d github.com/osrg/gobgp/...'
c << 'RUN rm -rf /go/src/github.com/osrg/gobgp'
c << 'ADD gobgp /go/src/github.com/osrg/gobgp/'
c << 'RUN go get github.com/osrg/gobgp/...'
diff --git a/vendor/github.com/osrg/gobgp/test/scenario_test/graceful_restart_test.py b/vendor/github.com/osrg/gobgp/test/scenario_test/graceful_restart_test.py
index 60e10437..4f3c1563 100644
--- a/vendor/github.com/osrg/gobgp/test/scenario_test/graceful_restart_test.py
+++ b/vendor/github.com/osrg/gobgp/test/scenario_test/graceful_restart_test.py
@@ -26,7 +26,6 @@ from lib.noseplugin import OptionParser, parser_option
from lib import base
from lib.base import (
- BGP_FSM_IDLE,
BGP_FSM_ACTIVE,
BGP_FSM_ESTABLISHED,
)
@@ -129,47 +128,6 @@ class GoBGPTestBase(unittest.TestCase):
g2 = self.bgpds['g2']
self.assertTrue(len(g2.get_global_rib()) == 0)
- def test_07_multineighbor_established(self):
- g1 = self.bgpds['g1']
- g2 = self.bgpds['g2']
- g3 = self.bgpds['g3']
-
- g1._start_gobgp()
-
- g1.del_peer(g2)
- g1.del_peer(g3)
- g2.del_peer(g1)
- g3.del_peer(g1)
- g1.add_peer(g2, graceful_restart=True, llgr=True)
- g1.add_peer(g3, graceful_restart=True, llgr=True)
- g2.add_peer(g1, graceful_restart=True, llgr=True)
- g3.add_peer(g1, graceful_restart=True, llgr=True)
-
- g2.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g1)
- g3.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g1)
-
- def test_08_multineighbor_graceful_restart(self):
- g1 = self.bgpds['g1']
- g2 = self.bgpds['g2']
- g3 = self.bgpds['g3']
-
- g1.graceful_restart()
- g2.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
- g3.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
-
- g1._start_gobgp(graceful_restart=True)
-
- count = 0
- while ((g1.get_neighbor_state(g2) != BGP_FSM_ESTABLISHED)
- or (g1.get_neighbor_state(g3) != BGP_FSM_ESTABLISHED)):
- count += 1
- # assert connections are not refused
- self.assertTrue(g1.get_neighbor_state(g2) != BGP_FSM_IDLE)
- self.assertTrue(g1.get_neighbor_state(g3) != BGP_FSM_IDLE)
- if count > 120:
- raise Exception('timeout')
- time.sleep(1)
-
if __name__ == '__main__':
output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
diff --git a/vendor/github.com/osrg/gobgp/tools/grpc/cpp/Makefile b/vendor/github.com/osrg/gobgp/tools/grpc/cpp/Makefile
index d50df9d9..2fcb5c8c 100644
--- a/vendor/github.com/osrg/gobgp/tools/grpc/cpp/Makefile
+++ b/vendor/github.com/osrg/gobgp/tools/grpc/cpp/Makefile
@@ -1,17 +1,7 @@
-HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
-SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
-CPPFLAGS += -I/usr/local/include -pthread
+CPPFLAGS += -I/opt/protobuf_3.0.0_alpha4/include -I/opt/grpc/include -pthread
CXXFLAGS += -std=c++11
-ifeq ($(SYSTEM),Darwin)
-LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \
- -lgrpc++_reflection \
- -lprotobuf -lpthread -ldl
-else
-LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \
- -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \
- -lprotobuf -lpthread -ldl
-endif
+LDFLAGS += -L/opt/grpc/lib -L/opt/protobuf_3.0.0_alpha4/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
@@ -23,7 +13,7 @@ vpath %.proto $(PROTOS_PATH)
all: system-check gobgp_api_client
gobgp_api_client: gobgp_api_client.pb.o gobgp_api_client.grpc.pb.o gobgp_api_client.o
- $(CXX) $^ $(LDFLAGS) -L. -lgobgp -o $@
+ $(CXX) $^ $(LDFLAGS) -L. -lgobgp -o $@
%.grpc.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
diff --git a/vendor/github.com/osrg/gobgp/tools/grpc/cpp/build.sh b/vendor/github.com/osrg/gobgp/tools/grpc/cpp/build.sh
deleted file mode 100644
index f1c7a92c..00000000
--- a/vendor/github.com/osrg/gobgp/tools/grpc/cpp/build.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-GOBGP_PATH=${GOPATH}/src/github.com/osrg/gobgp
-
-cd ${GOBGP_PATH}/gobgp/lib
-go build -buildmode=c-shared -o libgobgp.so *.go
-cd ${GOBGP_PATH}/tools/grpc/cpp
-ln -s ${GOBGP_PATH}/gobgp/lib/libgobgp.h
-ln -s ${GOBGP_PATH}/gobgp/lib/libgobgp.so
-ln -s ${GOBGP_PATH}/api/gobgp.proto gobgp_api_client.proto
-make
diff --git a/vendor/github.com/osrg/gobgp/tools/grpc/cpp/gobgp_api_client.cc b/vendor/github.com/osrg/gobgp/tools/grpc/cpp/gobgp_api_client.cc
index b704c932..413c140c 100644
--- a/vendor/github.com/osrg/gobgp/tools/grpc/cpp/gobgp_api_client.cc
+++ b/vendor/github.com/osrg/gobgp/tools/grpc/cpp/gobgp_api_client.cc
@@ -25,44 +25,218 @@ using gobgpapi::GobgpApi;
class GrpcClient {
public:
GrpcClient(std::shared_ptr channel) : stub_(GobgpApi::NewStub(channel)) {}
+ void GetAllActiveAnnounces(unsigned int route_family) {
+ ClientContext context;
+ gobgpapi::Table table;
- std::string GetNeighbor() {
- gobgpapi::GetNeighborRequest request;
+ table.set_family(route_family);
+ // We could specify certain neighbor here
+ table.set_name("");
+ table.set_type(gobgpapi::Resource::GLOBAL);
+
+ gobgpapi::Table response_table;
+
+ auto status = stub_->GetRib(&context, table, &response_table);
+
+ if (!status.ok()) {
+ // error_message
+ std::cout << "Problem with RPC: " << status.error_code() << " message " << status.error_message() << std::endl;
+ return;
+ } else {
+ // std::cout << "RPC working well" << std::endl;
+ }
+
+ std::cout << "List of announced prefixes for route family: " << route_family << std::endl << std::endl;
+
+ for (auto current_destination : response_table.destinations()) {
+ std::cout << "Prefix: " << current_destination.prefix() << std::endl;
+
+ //std::cout << "Paths size: " << current_destination.paths_size() << std::endl;
+
+ gobgpapi::Path my_path = current_destination.paths(0);
+
+ // std::cout << "Pattrs size: " << my_path.pattrs_size() << std::endl;
+
+ buf my_nlri;
+ my_nlri.value = (char*)my_path.nlri().c_str();
+ my_nlri.len = my_path.nlri().size();
+
+ path_t gobgp_lib_path;
+ gobgp_lib_path.nlri = my_nlri;
+ // Not used in library code!
+ gobgp_lib_path.path_attributes_cap = 0;
+ gobgp_lib_path.path_attributes_len = my_path.pattrs_size();
+
+ buf* my_path_attributes[ my_path.pattrs_size() ];
+ for (int i = 0; i < my_path.pattrs_size(); i++) {
+ my_path_attributes[i] = (buf*)malloc(sizeof(buf));
+ my_path_attributes[i]->len = my_path.pattrs(i).size();
+ my_path_attributes[i]->value = (char*)my_path.pattrs(i).c_str();
+ }
+
+ gobgp_lib_path.path_attributes = my_path_attributes;
+
+ std::cout << "NLRI: " << decode_path(&gobgp_lib_path) << std::endl;
+ }
+ }
+
+ void AnnounceFlowSpecPrefix(bool withdraw) {
+ const gobgpapi::ModPathArguments current_mod_path_arguments;
+
+ unsigned int AFI_IP = 1;
+ unsigned int SAFI_FLOW_SPEC_UNICAST = 133;
+ unsigned int ipv4_flow_spec_route_family = AFI_IP<<16 | SAFI_FLOW_SPEC_UNICAST;
+
+ gobgpapi::Path* current_path = new gobgpapi::Path;
+ current_path->set_is_withdraw(withdraw);
+
+ /*
+ buf:
+ char *value;
+ int len;
+
+ path:
+ buf nlri;
+ buf** path_attributes;
+ int path_attributes_len;
+ int path_attributes_cap;
+ */
+
+ path* path_c_struct = serialize_path(ipv4_flow_spec_route_family, (char*)"match destination 10.0.0.0/24 protocol tcp source 20.0.0.0/24 then redirect 10:10");
+
+ // printf("Decoded NLRI output: %s, length %d raw string length: %d\n", decode_path(path_c_struct), path_c_struct->nlri.len, strlen(path_c_struct->nlri.value));
+
+ for (int path_attribute_number = 0; path_attribute_number < path_c_struct->path_attributes_len; path_attribute_number++) {
+ current_path->add_pattrs(path_c_struct->path_attributes[path_attribute_number]->value,
+ path_c_struct->path_attributes[path_attribute_number]->len);
+ }
+
+ current_path->set_nlri(path_c_struct->nlri.value, path_c_struct->nlri.len);
+
+ gobgpapi::ModPathsArguments request;
+ request.set_resource(gobgpapi::Resource::GLOBAL);
+
+ google::protobuf::RepeatedPtrField< ::gobgpapi::Path >* current_path_list = request.mutable_paths();
+ current_path_list->AddAllocated(current_path);
+ request.set_name("");
ClientContext context;
- gobgpapi::GetNeighborResponse response;
- grpc::Status status = stub_->GetNeighbor(&context, request, &response);
+ gobgpapi::Error return_error;
+
+ // result is a std::unique_ptr >
+ auto send_stream = stub_->ModPaths(&context, &return_error);
+
+ bool write_result = send_stream->Write(request);
+
+ if (!write_result) {
+ std::cout << "Write to API failed\n";
+ }
+
+ // Finish all writes
+ send_stream->WritesDone();
+
+ auto status = send_stream->Finish();
+
+ if (status.ok()) {
+ //std::cout << "modpath executed correctly" << std::cout;
+ } else {
+ std::cout << "modpath failed with code: " << status.error_code()
+ << " message " << status.error_message() << std::endl;
+ }
+ }
+
+ void AnnounceUnicastPrefix(bool withdraw) {
+ const gobgpapi::ModPathArguments current_mod_path_arguments;
+
+ unsigned int AFI_IP = 1;
+ unsigned int SAFI_UNICAST = 1;
+ unsigned int ipv4_unicast_route_family = AFI_IP<<16 | SAFI_UNICAST;
+
+ gobgpapi::Path* current_path = new gobgpapi::Path;
+ current_path->set_is_withdraw(withdraw);
+
+ /*
+ buf:
+ char *value;
+ int len;
+
+ path:
+ buf nlri;
+ buf** path_attributes;
+ int path_attributes_len;
+ int path_attributes_cap;
+ */
+
+ // 10.10.20.33/22 nexthop 10.10.1.99/32
+ path* path_c_struct = serialize_path(ipv4_unicast_route_family, (char*)"10.10.20.33/22");
+
+ // printf("Decoded NLRI output: %s, length %d raw string length: %d\n", decode_path(path_c_struct), path_c_struct->nlri.len, strlen(path_c_struct->nlri.value));
+
+ for (int path_attribute_number = 0; path_attribute_number < path_c_struct->path_attributes_len; path_attribute_number++) {
+ current_path->add_pattrs(path_c_struct->path_attributes[path_attribute_number]->value,
+ path_c_struct->path_attributes[path_attribute_number]->len);
+ }
+
+ current_path->set_nlri(path_c_struct->nlri.value, path_c_struct->nlri.len);
+
+ gobgpapi::ModPathsArguments request;
+ request.set_resource(gobgpapi::Resource::GLOBAL);
+ google::protobuf::RepeatedPtrField< ::gobgpapi::Path >* current_path_list = request.mutable_paths();
+ current_path_list->AddAllocated(current_path);
+ request.set_name("");
+
+ ClientContext context;
+
+ gobgpapi::Error return_error;
+
+ // result is a std::unique_ptr >
+ auto send_stream = stub_->ModPaths(&context, &return_error);
+
+ bool write_result = send_stream->Write(request);
+
+ if (!write_result) {
+ std::cout << "Write to API failed\n";
+ }
+
+ // Finish all writes
+ send_stream->WritesDone();
+
+ auto status = send_stream->Finish();
+
+ if (status.ok()) {
+ //std::cout << "modpath executed correctly" << std::cout;
+ } else {
+ std::cout << "modpath failed with code: " << status.error_code()
+ << " message " << status.error_message() << std::endl;
+ }
+ }
+
+ std::string GetNeighbor(std::string neighbor_ip) {
+ gobgpapi::Arguments request;
+ request.set_family(4);
+ request.set_name(neighbor_ip);
+
+ ClientContext context;
+
+ gobgpapi::Peer peer;
+ grpc::Status status = stub_->GetNeighbor(&context, request, &peer);
if (status.ok()) {
+ gobgpapi::PeerConf peer_conf = peer.conf();
+ gobgpapi::PeerState peer_info = peer.info();
+
std::stringstream buffer;
- for (int i=0; i < response.peers_size(); i++) {
+
+ buffer
+ << "Peer AS: " << peer_conf.peer_as() << "\n"
+ << "Peer router id: " << peer_conf.id() << "\n"
+ << "Peer flops: " << peer_info.flops() << "\n"
+ << "BGP state: " << peer_info.bgp_state();
- gobgpapi::PeerConf peer_conf = response.peers(i).conf();
- gobgpapi::PeerState peer_info = response.peers(i).info();
- gobgpapi::Timers peer_timers = response.peers(i).timers();
-
- buffer
- << "BGP neighbor is: " << peer_conf.neighbor_address()
- << ", remote AS: " << peer_conf.peer_as() << "\n"
- << "\tBGP version: 4, remote route ID " << peer_conf.id() << "\n"
- << "\tBGP state = " << peer_info.bgp_state()
- << ", up for " << peer_timers.state().uptime() << "\n"
- << "\tBGP OutQ = " << peer_info.out_q()
- << ", Flops = " << peer_info.flops() << "\n"
- << "\tHold time is " << peer_timers.state().hold_time()
- << ", keepalive interval is " << peer_timers.state().keepalive_interval() << "seconds\n"
- << "\tConfigured hold time is " << peer_timers.config().hold_time() << "\n";
-
- }
return buffer.str();
} else {
- std::stringstream buffer;
- buffer
- << status.error_code() << "\n"
- << status.error_message() << "\n"
- << status.error_details() << "\n";
- return buffer.str();
+ return "Something wrong";
}
}
@@ -71,16 +245,25 @@ class GrpcClient {
};
int main(int argc, char** argv) {
- if(argc < 2) {
- std::cout << "Usage: ./gobgp_api_client [gobgp address]\n";
- return 1;
- }
+ GrpcClient gobgp_client(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
+
+ std::string reply = gobgp_client.GetNeighbor("213.133.111.200");
+ std::cout << "Neighbor information: " << reply << std::endl;
- std::string addr = argv[1];
- GrpcClient gobgp_client(grpc::CreateChannel(addr + ":50051", grpc::InsecureChannelCredentials()));
+ gobgp_client.AnnounceUnicastPrefix(false);
- std::string reply = gobgp_client.GetNeighbor();
- std::cout << reply;
+ gobgp_client.AnnounceFlowSpecPrefix(false);
+
+ unsigned int AFI_IP = 1;
+ unsigned int SAFI_UNICAST = 1;
+ unsigned int SAFI_FLOW_SPEC_UNICAST = 133;
+
+ unsigned int ipv4_unicast_route_family = AFI_IP<<16 | SAFI_UNICAST;
+ unsigned int ipv4_flow_spec_route_family = AFI_IP<<16 | SAFI_FLOW_SPEC_UNICAST;
+
+ gobgp_client.GetAllActiveAnnounces(ipv4_unicast_route_family);
+ std::cout << std::endl << std::endl;
+ gobgp_client.GetAllActiveAnnounces(ipv4_flow_spec_route_family);
return 0;
}
diff --git a/vendor/github.com/osrg/gobgp/tools/grpc/java/src/gobgp/example/GobgpSampleClient.java b/vendor/github.com/osrg/gobgp/tools/grpc/java/src/gobgp/example/GobgpSampleClient.java
deleted file mode 100644
index 287b46b6..00000000
--- a/vendor/github.com/osrg/gobgp/tools/grpc/java/src/gobgp/example/GobgpSampleClient.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package gobgp.example;
-
-import gobgpapi.Gobgp;
-import gobgpapi.GobgpApiGrpc;
-import io.grpc.ManagedChannel;
-import io.grpc.ManagedChannelBuilder;
-
-import java.util.List;
-
-public class GobgpSampleClient {
-
- private final GobgpApiGrpc.GobgpApiBlockingStub blockingStub;
-
- public GobgpSampleClient(String host, int port) {
- ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();
- this.blockingStub = GobgpApiGrpc.newBlockingStub(channel);
- }
-
- public void getNeighbors(){
-
- Gobgp.GetNeighborRequest request = Gobgp.GetNeighborRequest.newBuilder().build();
-
- for(Gobgp.Peer peer: this.blockingStub.getNeighbor(request).getPeersList()) {
- Gobgp.PeerConf conf = peer.getConf();
- Gobgp.PeerState state = peer.getInfo();
- Gobgp.Timers timer = peer.getTimers();
-
- System.out.printf("BGP neighbor is %s, remote AS %d\n", conf.getNeighborAddress(), conf.getPeerAs());
- System.out.printf("\tBGP version 4, remote router ID %s\n", conf.getId());
- System.out.printf("\tBGP state = %s, up for %d\n", state.getBgpState(), timer.getState().getUptime());
- System.out.printf("\tBGP OutQ = %d, Flops = %d\n", state.getOutQ(), state.getFlops());
- System.out.printf("\tHold time is %d, keepalive interval is %d seconds\n",
- timer.getState().getHoldTime(), timer.getState().getKeepaliveInterval());
- System.out.printf("\tConfigured hold time is %d\n", timer.getConfig().getHoldTime());
-
- }
- }
-
- public static void main(String args[]){
- new GobgpSampleClient(args[0], 50051).getNeighbors();
- }
-
-}
-
diff --git a/vendor/github.com/osrg/gobgp/tools/grpc/python/get_neighbor.py b/vendor/github.com/osrg/gobgp/tools/grpc/python/get_neighbor.py
index ff94569d..3a57fdb8 100644
--- a/vendor/github.com/osrg/gobgp/tools/grpc/python/get_neighbor.py
+++ b/vendor/github.com/osrg/gobgp/tools/grpc/python/get_neighbor.py
@@ -1,28 +1,27 @@
-import gobgp_pb2_grpc
import gobgp_pb2
import sys
-import grpc
+from grpc.beta import implementations
from grpc.framework.interfaces.face.face import ExpirationError
_TIMEOUT_SECONDS = 1
def run(gobgpd_addr):
- channel = grpc.insecure_channel(gobgpd_addr + ':50051')
- stub = gobgp_pb2_grpc.GobgpApiStub(channel)
- try:
- peers = stub.GetNeighbor(gobgp_pb2.GetNeighborRequest()).peers
- for peer in peers:
- print("BGP neighbor is %s, remote AS %d" % (peer.conf.neighbor_address, peer.conf.peer_as))
- print(" BGP version 4, remote router ID %s" % (peer.conf.id))
- print(" BGP state = %s, up for %s" % (peer.info.bgp_state, peer.timers.state.uptime))
- print(" BGP OutQ = %d, Flops = %d" % (peer.info.out_q, peer.info.flops))
- print(" Hold time is %d, keepalive interval is %d seconds" % (peer.timers.state.negotiated_hold_time, peer.timers.state.keepalive_interval))
- print(" Configured hold time is %d, keepalive interval is %d seconds" % (peer.timers.config.hold_time, peer.timers.config.keepalive_interval))
- except ExpirationError, e:
- print str(e)
- sys.exit(-1)
+ channel = implementations.insecure_channel(gobgpd_addr, 50051)
+ with gobgp_pb2.beta_create_GobgpApi_stub(channel) as stub:
+ try:
+ peers = stub.GetNeighbor(gobgp_pb2.GetNeighborRequest(), _TIMEOUT_SECONDS).peers
+ for peer in peers:
+ print("BGP neighbor is %s, remote AS %d" % (peer.conf.neighbor_address, peer.conf.peer_as))
+ print(" BGP version 4, remote router ID %s" % (peer.conf.id))
+ print(" BGP state = %s, up for %s" % (peer.info.bgp_state, peer.timers.state.uptime))
+ print(" BGP OutQ = %d, Flops = %d" % (peer.info.out_q, peer.info.flops))
+ print(" Hold time is %d, keepalive interval is %d seconds" % (peer.timers.state.negotiated_hold_time, peer.timers.state.keepalive_interval))
+ print(" Configured hold time is %d, keepalive interval is %d seconds" % (peer.timers.config.hold_time, peer.timers.config.keepalive_interval))
+ except ExpirationError, e:
+ print str(e)
+ sys.exit(-1)
if __name__ == '__main__':
gobgp = sys.argv[1]
diff --git a/vendor/github.com/osrg/gobgp/tools/grpc/ruby/get_neighbors.rb b/vendor/github.com/osrg/gobgp/tools/grpc/ruby/get_neighbors.rb
index a451f67f..36347373 100644
--- a/vendor/github.com/osrg/gobgp/tools/grpc/ruby/get_neighbors.rb
+++ b/vendor/github.com/osrg/gobgp/tools/grpc/ruby/get_neighbors.rb
@@ -1,11 +1,12 @@
-require 'gobgp_pb'
-require 'gobgp_services_pb'
+require 'gobgp'
+require 'gobgp_services'
-host = ARGV[0]
+host = 'localhost'
+host = ARGV[0] if ARGV.length > 0
stub = Gobgpapi::GobgpApi::Stub.new("#{host}:50051", :this_channel_is_insecure)
-arg = Gobgpapi::GetNeighborRequest.new()
-stub.get_neighbor(arg).peers.each do |n|
+arg = Gobgpapi::Arguments.new()
+stub.get_neighbors(arg).each do |n|
puts "BGP neighbor is #{n.conf.neighbor_address}, remote AS #{n.conf.peer_as}"
puts "\tBGP version 4, remote route ID #{n.conf.id}"
puts "\tBGP state = #{n.info.bgp_state}, up for #{n.timers.state.uptime}"
diff --git a/vendor/github.com/osrg/gobgp/tools/pyang_plugins/README.rst b/vendor/github.com/osrg/gobgp/tools/pyang_plugins/README.rst
index 976b878c..ddf41f27 100644
--- a/vendor/github.com/osrg/gobgp/tools/pyang_plugins/README.rst
+++ b/vendor/github.com/osrg/gobgp/tools/pyang_plugins/README.rst
@@ -3,38 +3,21 @@ What's this ?
This is a pyang plugin to generate config/bgp_configs.go from
openconfig yang files (see https://github.com/openconfig/public).
-Prerequisites
-=============
-Please confirm $GOPATH is configured before the following steps.
-
How to use
==========
-Set the environment variables for this tool::
+::
- $ GOBGP_PATH=$GOPATH/src/github.com/osrg/gobgp/
-
-Clone the required resources by using Git::
-
- $ cd $HOME
$ git clone https://github.com/osrg/public
$ git clone https://github.com/YangModels/yang
- $ git clone https://github.com/mbj4668/pyang
-
-Setup environments for pyang::
-
- $ cd $HOME/pyang
+ $ YANG_DIR=`pwd`
+ $ cd $PYANG_INSTALL_DIR
$ source ./env.sh
-
-Generate config/bgp_configs.go from yang files::
-
- $ PYTHONPATH=. ./bin/pyang \
- --plugindir $GOBGP_PATH/tools/pyang_plugins \
- -p $HOME/yang/standard/ietf/RFC \
- -p $HOME/public/release/models \
- -p $HOME/public/release/models/bgp \
- -p $HOME/public/release/models/policy \
- -f golang \
- $HOME/public/release/models/bgp/openconfig-bgp.yang \
- $HOME/public/release/models/policy/openconfig-routing-policy.yang \
+ $ PYTHONPATH=. ./bin/pyang --plugindir $GOBGP_PATH/tools/pyang_plugins \
+ -p $YANG_DIR/yang/standard/ietf/RFC \
+ -p $YANG_DIR/public/release/models \
+ -p $YANG_DIR/public/release/models/bgp \
+ -p $YANG_DIR/public/release/models/policy \
+ -f golang $YANG_DIR/public/release/models/bgp/openconfig-bgp.yang \
+ $YANG_DIR/public/release/models/policy/openconfig-routing-policy.yang \
$GOBGP_PATH/tools/pyang_plugins/gobgp.yang \
| gofmt > $GOBGP_PATH/config/bgp_configs.go
diff --git a/vendor/github.com/osrg/gobgp/tools/pyang_plugins/gobgp.yang b/vendor/github.com/osrg/gobgp/tools/pyang_plugins/gobgp.yang
index 9ada88d4..25299cc2 100644
--- a/vendor/github.com/osrg/gobgp/tools/pyang_plugins/gobgp.yang
+++ b/vendor/github.com/osrg/gobgp/tools/pyang_plugins/gobgp.yang
@@ -180,18 +180,6 @@ module gobgp {
error condition has occurred exchanged.";
}
- leaf WITHDRAW-UPDATE {
- type uint32;
- description
- "Number of updates subjected to treat-as-withdraw treatment.";
- }
-
- leaf WITHDRAW-PREFIX {
- type uint32;
- description
- "Number of prefixes subjected to treat-as-withdraw treatment.";
- }
-
leaf DISCARDED {
type uint64;
description
@@ -207,6 +195,7 @@ module gobgp {
}
}
+
grouping gobgp-adjacent-table {
container adj-table {
leaf ADVERTISED {
@@ -559,30 +548,20 @@ module gobgp {
"Reference to the address of the BMP server used as
a key in the BMP server list";
}
-
leaf port {
type uint32;
description
"Reference to the port of the BMP server";
}
-
leaf route-monitoring-policy {
type bmp-route-monitoring-policy-type;
default PRE-POLICY;
}
-
leaf statistics-timeout {
type uint16;
description
"Interval seconds of statistics messages sent to BMP server";
}
-
- leaf route-mirroring-enabled {
- type boolean;
- description
- "Enable feature for mirroring of received BGP messages
- mainly for debugging purpose";
- }
}
grouping gobgp-bmp-server-state {
@@ -653,47 +632,6 @@ module gobgp {
}
}
- grouping gobgp-ttl-security-config {
- description
- "Configuration parameters for TTL Security";
-
- leaf enabled {
- type boolean;
- default "false";
- description
- "Enable features for TTL Security";
- }
-
- leaf ttl-min {
- type uint8;
- description
- "Reference to the port of the BMP server";
- }
- }
-
- grouping gobgp-ttl-security-config-set {
- description
- "set of configurations for Generalized TTL Security Mechanism (GTSM)";
-
- container ttl-security {
- description
- "Configure TTL Security feature";
-
- container config {
- description
- "Configuration parameters for TTL Security";
- uses gobgp-ttl-security-config;
- }
-
- container state {
- config false;
- description
- "State information for TTL Security";
- uses gobgp-ttl-security-config;
- }
- }
- }
-
// augment statements
augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:state/bgp:messages/bgp:sent" {
description "additional counters";
@@ -807,11 +745,6 @@ module gobgp {
leaf remote-port {
type inet:port-number;
}
-
- leaf ttl {
- description "TTL value for BGP packets";
- type uint8;
- }
}
augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:timers/bgp:config" {
@@ -871,16 +804,6 @@ module gobgp {
uses gobgp-route-server-config-set;
}
- augment "/bgp:bgp/bgp:peer-groups/bgp:peer-group" {
- description "TTL Security configuration for peer-group";
- uses gobgp-ttl-security-config-set;
- }
-
- augment "/bgp:bgp/bgp:neighbors/bgp:neighbor" {
- description "TTL Security configuration for neighbor";
- uses gobgp-ttl-security-config-set;
- }
-
augment "/bgp:bgp/bgp:global/bgp:apply-policy/bgp:config" {
description "addtional policy";
uses gobgp-in-policy;
@@ -1182,45 +1105,6 @@ module gobgp {
uses listen-config;
}
- grouping dynamic-neighbors {
- container dynamic-neighbors {
- list dynamic-neighbor {
- key "prefix";
-
- leaf prefix {
- type leafref {
- path "../config/prefix";
- }
- }
-
- container config {
- uses bgp-global-dynamic-neighbor-config;
- }
-
- container state {
- config false;
- uses bgp-global-dynamic-neighbor-config;
- }
- }
- }
- }
-
- grouping bgp-global-dynamic-neighbor-config {
- description "A dynamic neighbor belongs to a peer group.
- This configuration structure was taken from the latest openconfig.";
-
- leaf prefix {
- type string;
- }
- leaf peer-group {
- type string;
- }
- }
-
- augment "/bgp:bgp" {
- uses dynamic-neighbors;
- }
-
augment "/bgp:bgp/bgp:global/bgp:afi-safis/bgp:afi-safi" {
uses bgp-mp:all-afi-safi-common;
}
diff --git a/vendor/github.com/osrg/gobgp/zebra/zapi.go b/vendor/github.com/osrg/gobgp/zebra/zapi.go
index 01e8d2ff..0c131f7f 100644
--- a/vendor/github.com/osrg/gobgp/zebra/zapi.go
+++ b/vendor/github.com/osrg/gobgp/zebra/zapi.go
@@ -23,7 +23,7 @@ import (
"strings"
"syscall"
- log "github.com/sirupsen/logrus"
+ log "github.com/Sirupsen/logrus"
)
const (
diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
index 03fe4b15..c443aed0 100644
--- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md
+++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
@@ -1,6 +1,7 @@
# 1.0.2
* bug: quote non-string values in text formatter (#583)
+* Make (*Logger) SetLevel a public method
# 1.0.1
diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
index 1aeaa90b..013183ed 100644
--- a/vendor/github.com/sirupsen/logrus/exported.go
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -31,7 +31,7 @@ func SetFormatter(formatter Formatter) {
func SetLevel(level Level) {
std.mu.Lock()
defer std.mu.Unlock()
- std.setLevel(level)
+ std.SetLevel(level)
}
// GetLevel returns the standard logger level.
diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
index 370fff5d..b44966f9 100644
--- a/vendor/github.com/sirupsen/logrus/logger.go
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -312,6 +312,6 @@ func (logger *Logger) level() Level {
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
}
-func (logger *Logger) setLevel(level Level) {
+func (logger *Logger) SetLevel(level Level) {
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
index 6aa48cfb..cf3f17f2 100644
--- a/vendor/github.com/sirupsen/logrus/text_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter.go
@@ -52,10 +52,6 @@ type TextFormatter struct {
// QuoteEmptyFields will wrap empty fields in quotes if true
QuoteEmptyFields bool
- // QuoteCharacter can be set to the override the default quoting character "
- // with something else. For example: ', or `.
- QuoteCharacter string
-
// Whether the logger's out is to a terminal
isTerminal bool
@@ -63,9 +59,6 @@ type TextFormatter struct {
}
func (f *TextFormatter) init(entry *Entry) {
- if len(f.QuoteCharacter) == 0 {
- f.QuoteCharacter = "\""
- }
if entry.Logger != nil {
f.isTerminal = IsTerminal(entry.Logger.Out)
}
@@ -177,13 +170,6 @@ func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
if !f.needsQuoting(stringVal) {
b.WriteString(stringVal)
} else {
- b.WriteString(f.quoteString(stringVal))
+ b.WriteString(fmt.Sprintf("%q", stringVal))
}
}
-
-func (f *TextFormatter) quoteString(v string) string {
- escapedQuote := fmt.Sprintf("\\%s", f.QuoteCharacter)
- escapedValue := strings.Replace(v, f.QuoteCharacter, escapedQuote, -1)
-
- return fmt.Sprintf("%s%v%s", f.QuoteCharacter, escapedValue, f.QuoteCharacter)
-}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter_test.go b/vendor/github.com/sirupsen/logrus/text_formatter_test.go
index d7b3bcb1..ecb8f127 100644
--- a/vendor/github.com/sirupsen/logrus/text_formatter_test.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter_test.go
@@ -3,10 +3,10 @@ package logrus
import (
"bytes"
"errors"
+ "fmt"
"strings"
"testing"
"time"
- "fmt"
)
func TestQuoting(t *testing.T) {
@@ -15,7 +15,7 @@ func TestQuoting(t *testing.T) {
checkQuoting := func(q bool, value interface{}) {
b, _ := tf.Format(WithField("test", value))
idx := bytes.Index(b, ([]byte)("test="))
- cont := bytes.Contains(b[idx+5:], []byte(tf.QuoteCharacter))
+ cont := bytes.Contains(b[idx+5:], []byte("\""))
if cont != q {
if q {
t.Errorf("quoting expected for: %#v", value)
@@ -41,23 +41,6 @@ func TestQuoting(t *testing.T) {
checkQuoting(false, errors.New("invalid"))
checkQuoting(true, errors.New("invalid argument"))
- // Test for custom quote character.
- tf.QuoteCharacter = "`"
- checkQuoting(false, "")
- checkQuoting(false, "abcd")
- checkQuoting(false, "/foobar")
- checkQuoting(false, "foo_bar")
- checkQuoting(false, "foo@bar")
- checkQuoting(false, "foobar^")
- checkQuoting(true, "foobar$")
- checkQuoting(true, "&foobar")
- checkQuoting(true, errors.New("invalid argument"))
-
- // Test for multi-character quotes.
- tf.QuoteCharacter = "§~±"
- checkQuoting(false, "abcd")
- checkQuoting(true, errors.New("invalid argument"))
-
// Test for quoting empty fields.
tf.QuoteEmptyFields = true
checkQuoting(true, "")
@@ -65,7 +48,7 @@ func TestQuoting(t *testing.T) {
checkQuoting(true, errors.New("invalid argument"))
}
-func TestEscaping_DefaultQuoteCharacter(t *testing.T) {
+func TestEscaping(t *testing.T) {
tf := &TextFormatter{DisableColors: true}
testCases := []struct {
@@ -105,35 +88,13 @@ func TestEscaping_Interface(t *testing.T) {
}
}
-func TestEscaping_CustomQuoteCharacter(t *testing.T) {
- tf := &TextFormatter{DisableColors: true}
-
- testCases := []struct {
- value string
- expected string
- quoteChar string
- }{
- {`ba"r`, `ba"r`, `'`},
- {`ba'r`, `ba\'r`, `'`},
- {`ba'r`, `ba'r`, `^`},
- }
-
- for _, tc := range testCases {
- tf.QuoteCharacter = tc.quoteChar
- b, _ := tf.Format(WithField("test", tc.value))
- if !bytes.Contains(b, []byte(tc.expected)) {
- t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
- }
- }
-}
-
func TestTimestampFormat(t *testing.T) {
checkTimeStr := func(format string) {
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
customStr, _ := customFormatter.Format(WithField("test", "test"))
timeStart := bytes.Index(customStr, ([]byte)("time="))
timeEnd := bytes.Index(customStr, ([]byte)("level="))
- timeStr := customStr[timeStart+5+len(customFormatter.QuoteCharacter) : timeEnd-1-len(customFormatter.QuoteCharacter)]
+ timeStr := customStr[timeStart+5+len("\"") : timeEnd-1-len("\"")]
if format == "" {
format = time.RFC3339
}