Panic on failing to decode message from zebra on debian bookworm
Problem
Latest gobgpd panics when trying to connect to zebra API. Also reproduced on gobgpd shipped with Debian bookworm (3.10 I think?)
Actual behaviour
./gobgpd -f /etc/gobgpd.conf -l debug
{"level":"info","msg":"gobgpd started","time":"2023-08-02T10:25:16Z"}
{"Topic":"Config","level":"info","msg":"Finished reading the config file","time":"2023-08-02T10:25:16Z"}
{"Body":{},"Header":{"Len":10,"Marker":254,"Version":6,"VrfID":0,"Command":18},"Topic":"Zebra","level":"debug","msg":"send command to zebra","time":"2023-08-02T10:25:16Z"}
{"Body":{},"Header":{"Len":10,"Marker":254,"Version":6,"VrfID":0,"Command":15},"Topic":"Zebra","level":"debug","msg":"send command to zebra","time":"2023-08-02T10:25:16Z"}
{"Body":{},"Header":{"Len":10,"Marker":254,"Version":6,"VrfID":0,"Command":15},"Topic":"Zebra","level":"debug","msg":"send command to zebra","time":"2023-08-02T10:25:16Z"}
{"Message":{"Header":{"Len":20,"Marker":254,"Version":6,"VrfID":0,"Command":19},"Body":{"Data":"AAAAAAAAAAEAAA=="}},"Topic":"Zebra","level":"debug","msg":"read message from zebra","time":"2023-08-02T10:25:16Z"}
{"Topic":"Zebra","Version":6,"level":"info","msg":"success to connect to Zebra","time":"2023-08-02T10:25:16Z"}
{"Body":null,"Header":{"Len":10,"Marker":254,"Version":6,"VrfID":0,"Command":0},"Topic":"Zebra","level":"debug","msg":"send command to zebra","time":"2023-08-02T10:25:16Z"}
{"Data":"/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRlZmF1bHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==","Error":"unknown route type: 254 in version: 6 (frr8.100000)","Header":{"Len":86,"Marker":254,"Version":6,"VrfID":0,"Command":33},"Topic":"Zebra","level":"warning","msg":"failed to decode body","time":"2023-08-02T10:25:16Z"}
{"Message":{"Header":{"Len":28,"Marker":254,"Version":6,"VrfID":0,"Command":17},"Body":{}},"Topic":"Zebra","level":"debug","msg":"read message from zebra","time":"2023-08-02T10:25:16Z"}
{"Data":"ZW5wMXMwAAAAAAAAAAAAAAAAAAIFAAAAAAABEEMAAgAAAAD/////AAAF3AAABdwAAAAAAAAAAAAAAAEAAAAGVgAEetORAA==","Error":"lack of bytes in remain data. need 1442841726 but 7","Header":{"Len":80,"Marker":254,"Version":6,"VrfID":0,"Command":0},"Topic":"Zebra","level":"warning","msg":"failed to decode body","time":"2023-08-02T10:25:16Z"}
{"Message":{"Header":{"Len":49,"Marker":254,"Version":6,"VrfID":0,"Command":2},"Body":{}},"Topic":"Zebra","level":"debug","msg":"read message from zebra","time":"2023-08-02T10:25:16Z"}
{"Message":{"Header":{"Len":49,"Marker":254,"Version":6,"VrfID":0,"Command":2},"Body":{}},"Topic":"Zebra","level":"debug","msg":"read message from zebra","time":"2023-08-02T10:25:16Z"}
{"Message":{"Header":{"Len":49,"Marker":254,"Version":6,"VrfID":0,"Command":2},"Body":{}},"Topic":"Zebra","level":"debug","msg":"read message from zebra","time":"2023-08-02T10:25:16Z"}
panic: runtime error: slice bounds out of range [:4] with capacity 1
goroutine 30 [running]:
github.com/osrg/gobgp/v3/internal/pkg/zebra.(*interfaceUpdateBody).decodeFromBytes(0xc0002d05b0, {0xc0000a5340, 0x40, 0x40}, 0x6, {{0xda77fa?, 0xc0000a5340?}, 0x40?})
/home/runner/work/gobgp/gobgp/internal/pkg/zebra/zapi.go:1953 +0x856
github.com/osrg/gobgp/v3/internal/pkg/zebra.parseMessage(0xc0001ddce0, {0xc0000a5340, 0x40, 0x40}, {{0xda77fa?, 0xc00022de78?}, 0x43bd20?})
/home/runner/work/gobgp/gobgp/internal/pkg/zebra/zapi.go:3577 +0x591
github.com/osrg/gobgp/v3/internal/pkg/zebra.NewClient.func2()
/home/runner/work/gobgp/gobgp/internal/pkg/zebra/zapi.go:1453 +0x451
github.com/osrg/gobgp/v3/internal/pkg/zebra.NewClient.func3()
/home/runner/work/gobgp/gobgp/internal/pkg/zebra/zapi.go:1486 +0x70
created by github.com/osrg/gobgp/v3/internal/pkg/zebra.NewClient
/home/runner/work/gobgp/gobgp/internal/pkg/zebra/zapi.go:1483 +0x499
Expected behaviour:
gobgpd connects to zebra and communicates routes with frr
Context
Config:
# cat /etc/gobgpd.conf
[global.config]
as = 204946
router-id = "127.0.0.5"
local-address-list = ['2a05:f480:3400:2148:5400:4ff:fe7a:d391']
[global.apply-policy.config]
default-import-policy = "accept-route"
default-export-policy = "accept-route"
[zebra]
[zebra.config]
enabled = true
url = "unix:/run/frr/zserv.api"
version = 6
Versions:
# ./gobgpd --version
gobgpd version 3.17.0
# dpkg --list |grep frr
ii frr 8.4.2-1 amd64 FRRouting suite of internet protocols (BGP, OSPF, IS-IS, ...)
ii frr-pythontools 8.4.2-1 all FRRouting suite - Python tools
# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
I guess that zebra API was updated. @irino
i have done some digging. Will try and update this as I go.
The issue seems to be that interfaceNameSize should not be 20. On my test system, it seems like it should actually be... 16?
Here's some bytes from the interfaceAdd message body:
Data length is 70 [101 110 115 51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 5 0 0 0 0 0 1 16 67 0 2 0 0 0 0 0 0 3 232 0 0 5 220 0 0 5 220 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 6 82 84 0 18 52 86 0]
Corresponding ip link
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
altname enp0s3
The name is at the front as you'd expect, but the ifIndex appears at 0x10 (=2). Then the status at 0x14 (5). If I manugally change interfaceNameSize to be 16, the interface is correctly parsed, all the waythrough tot he hwaddr.
Where did the value of 20 originally come from?
edit should add that I've worked around this for the moment by downgrading frr to 8.2 and specifying software-name as "8.2"
Thank you for debugging. I found INTEFACE_NAMSIZ is changed in newer version than frr8.2
FRR8.2:
grep -e IFNAMSIZ -e INTERFACE_NAMSIZ frr-frr-8.2.2/lib/if.h
#define IFNAMSIZ 16
#define IFNAMSIZ 16
#define INTERFACE_NAMSIZ 20
char name[INTERFACE_NAMSIZ];
FRR8.4.2
grep -e IFNAMSIZ -e INTERFACE_NAMSIZ frr-frr-8.4.2/lib/if.h
#define IFNAMSIZ 16
#define IFNAMSIZ 16
#define INTERFACE_NAMSIZ IFNAMSIZ
char name[INTERFACE_NAMSIZ];
INTERFACE_NAMSIZ is originally 20. However recent version is 16.