summaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/zebra
diff options
context:
space:
mode:
authorHitoshi Irino <irino@sfc.wide.ad.jp>2018-12-29 21:53:10 +0900
committerFUJITA Tomonori <fujita.tomonori@gmail.com>2018-12-30 21:52:15 +0900
commit4e862fa8f0017383ecdae22c757753214ba7815c (patch)
tree62700c8b24d6d5c234729d4cd89b6b0384ad9ade /internal/pkg/zebra
parent67947eeda62ff961208b19f29c652399dd93ea97 (diff)
zebra: Introducing MIN_ZAPIVER and MAX_ZAPIVER. And avoiding double close channel when sequential retry to connect zebra.
- Introducing MIN_ZAPIVER and MAX_ZAPIVER for avoiding editing files except for zapi.go when new ZAPI version will be supported in future. - Fix a bug avoiding panic by double close for a channel. - Changing algorithm for sequential retry to connect zebra.
Diffstat (limited to 'internal/pkg/zebra')
-rw-r--r--internal/pkg/zebra/zapi.go40
1 files changed, 33 insertions, 7 deletions
diff --git a/internal/pkg/zebra/zapi.go b/internal/pkg/zebra/zapi.go
index b0f8cc3a..e4391ca6 100644
--- a/internal/pkg/zebra/zapi.go
+++ b/internal/pkg/zebra/zapi.go
@@ -17,6 +17,7 @@ package zebra
import (
"encoding/binary"
+ "errors"
"fmt"
"io"
"math"
@@ -35,6 +36,11 @@ const (
INTERFACE_NAMSIZ = 20
)
+const (
+ MinZapiVer uint8 = 2
+ MaxZapiVer uint8 = 6
+)
+
// Internal Interface Status.
type INTERFACE_STATUS uint8
@@ -970,10 +976,10 @@ func NewClient(network, address string, typ ROUTE_TYPE, version uint8) (*Client,
}
outgoing := make(chan *Message)
incoming := make(chan *Message, 64)
- if version < 2 {
- version = 2
- } else if version > 6 {
- version = 6
+ if version < MinZapiVer {
+ version = MinZapiVer
+ } else if version > MaxZapiVer {
+ version = MaxZapiVer
}
c := &Client{
@@ -1001,7 +1007,8 @@ func NewClient(network, address string, typ ROUTE_TYPE, version uint8) (*Client,
log.WithFields(log.Fields{
"Topic": "Zebra",
}).Errorf("failed to write: %s", err)
- close(outgoing)
+ ChannelClose(outgoing)
+ return
}
} else {
log.Debug("finish outgoing loop")
@@ -1026,6 +1033,12 @@ func NewClient(network, address string, typ ROUTE_TYPE, version uint8) (*Client,
hd := &Header{}
err = hd.DecodeFromBytes(headerBuf)
+ if c.Version != hd.Version {
+ log.WithFields(log.Fields{
+ "Topic": "Zebra",
+ }).Warnf("ZAPI version mismatch. configured version: %d, version of received message:%d", c.Version, hd.Version)
+ return nil, errors.New("ZAPI version mismatch")
+ }
if err != nil {
log.WithFields(log.Fields{
"Topic": "Zebra",
@@ -1077,7 +1090,7 @@ func NewClient(network, address string, typ ROUTE_TYPE, version uint8) (*Client,
// Start receive loop only when the first message successfully received.
go func() {
- defer close(incoming)
+ defer ChannelClose(incoming)
for {
if m, err := receiveSingleMsg(); err != nil {
return
@@ -1298,8 +1311,21 @@ func (c *Client) SendNexthopRegister(vrfId uint32, body *NexthopRegisterBody, is
return c.SendCommand(command, vrfId, body)
}
+// for avoiding double close
+func ChannelClose(ch chan *Message) bool {
+ select {
+ case _, ok := <-ch:
+ if ok {
+ close(ch)
+ return true
+ }
+ default:
+ }
+ return false
+}
+
func (c *Client) Close() error {
- close(c.outgoing)
+ ChannelClose(c.outgoing)
return c.conn.Close()
}