diff options
author | kishiguro <ishi@hash-set.com> | 2016-09-28 12:09:45 -0700 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-09-29 16:29:15 -0700 |
commit | 554f309c9020fa580b7ae74766b069a7ae095444 (patch) | |
tree | 1f99f9d92041c2bd5d6efec28ccf2a9add5656b2 /zebra/zapi.go | |
parent | db3dbd7257836521fdab3d41b57dd5f73ed30baf (diff) |
Support of ZAPI version 3 (handles VRF ID).
Diffstat (limited to 'zebra/zapi.go')
-rw-r--r-- | zebra/zapi.go | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/zebra/zapi.go b/zebra/zapi.go index 69f72420..9afdefae 100644 --- a/zebra/zapi.go +++ b/zebra/zapi.go @@ -27,9 +27,7 @@ import ( ) const ( - HEADER_SIZE = 6 HEADER_MARKER = 255 - VERSION = 2 INTERFACE_NAMSIZ = 20 ) @@ -41,6 +39,15 @@ const ( INTERFACE_LINKDETECTION = 0x04 ) +func HeaderSize(version uint8) uint16 { + switch version { + case 3: + return 8 + default: + return 6 + } +} + func (t INTERFACE_STATUS) String() string { ss := make([]string, 0, 3) if t&INTERFACE_ACTIVE > 0 { @@ -213,21 +220,26 @@ type Client struct { incoming chan *Message redistDefault ROUTE_TYPE conn net.Conn + Version uint8 } -func NewClient(network, address string, typ ROUTE_TYPE) (*Client, error) { +func NewClient(network, address string, typ ROUTE_TYPE, version uint8) (*Client, error) { conn, err := net.Dial(network, address) if err != nil { return nil, err } outgoing := make(chan *Message) incoming := make(chan *Message, 64) + if version != 3 { + version = 2 + } c := &Client{ outgoing: outgoing, incoming: incoming, redistDefault: typ, conn: conn, + Version: version, } go func() { @@ -258,7 +270,7 @@ func NewClient(network, address string, typ ROUTE_TYPE) (*Client, error) { go func() { for { - headerBuf, err := readAll(conn, HEADER_SIZE) + headerBuf, err := readAll(conn, int(HeaderSize(version))) if err != nil { log.WithFields(log.Fields{ "Topic": "Zebra", @@ -277,7 +289,7 @@ func NewClient(network, address string, typ ROUTE_TYPE) (*Client, error) { return } - bodyBuf, err := readAll(conn, int(hd.Len-HEADER_SIZE)) + bodyBuf, err := readAll(conn, int(hd.Len-HeaderSize(version))) if err != nil { log.WithFields(log.Fields{ "Topic": "Zebra", @@ -331,9 +343,9 @@ func (c *Client) Send(m *Message) { func (c *Client) SendCommand(command API_TYPE, body Body) error { m := &Message{ Header: Header{ - Len: HEADER_SIZE, + Len: HeaderSize(c.Version), Marker: HEADER_MARKER, - Version: VERSION, + Version: c.Version, Command: command, }, Body: body, @@ -397,26 +409,40 @@ type Header struct { Len uint16 Marker uint8 Version uint8 + VrfId uint16 Command API_TYPE } func (h *Header) Serialize() ([]byte, error) { - buf := make([]byte, HEADER_SIZE) + buf := make([]byte, HeaderSize(h.Version)) binary.BigEndian.PutUint16(buf[0:], h.Len) buf[2] = h.Marker buf[3] = h.Version - binary.BigEndian.PutUint16(buf[4:], uint16(h.Command)) + if h.Version == 3 { + binary.BigEndian.PutUint16(buf[4:6], uint16(h.VrfId)) + binary.BigEndian.PutUint16(buf[6:], uint16(h.Command)) + } else { + binary.BigEndian.PutUint16(buf[4:], uint16(h.Command)) + } return buf, nil } func (h *Header) DecodeFromBytes(data []byte) error { - if uint16(len(data)) < HEADER_SIZE { + if uint16(len(data)) < 4 { return fmt.Errorf("Not all ZAPI message header") } h.Len = binary.BigEndian.Uint16(data[0:2]) h.Marker = data[2] h.Version = data[3] - h.Command = API_TYPE(binary.BigEndian.Uint16(data[4:6])) + if uint16(len(data)) < HeaderSize(h.Version) { + return fmt.Errorf("Not all ZAPI message header") + } + if h.Version == 3 { + h.VrfId = binary.BigEndian.Uint16(data[4:6]) + h.Command = API_TYPE(binary.BigEndian.Uint16(data[6:8])) + } else { + h.Command = API_TYPE(binary.BigEndian.Uint16(data[4:6])) + } return nil } @@ -925,7 +951,7 @@ func (m *Message) Serialize() ([]byte, error) { return nil, err } } - m.Header.Len = uint16(len(body)) + HEADER_SIZE + m.Header.Len = uint16(len(body)) + HeaderSize(m.Header.Version) hdr, err := m.Header.Serialize() if err != nil { return nil, err |