summaryrefslogtreecommitdiff
path: root/bgpd/bgp_snmp_bgp4v2.c
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2022-12-19 22:56:41 +0200
committerDonatas Abraitis <donatas@opensourcerouting.org>2022-12-20 09:42:35 +0200
commit2789c909943da890f37001f245f9be336bdbb7ed (patch)
treee784ef09c97c43c356dc7b8d078be9fa13536fc9 /bgpd/bgp_snmp_bgp4v2.c
parent54257fae5d701c6d48b37364dc7d1eb9a3ce7686 (diff)
bgpd: Zero intial OID items in array at the beginning
If OID does not have an IP address encoded, initialized every item in an array to 0 to avoid a wrong comparison between IP addresses. With >= 5.8 net-snmp, it works without this hack. Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_snmp_bgp4v2.c')
-rw-r--r--bgpd/bgp_snmp_bgp4v2.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/bgpd/bgp_snmp_bgp4v2.c b/bgpd/bgp_snmp_bgp4v2.c
index 7baa370b70..d8d8549960 100644
--- a/bgpd/bgp_snmp_bgp4v2.c
+++ b/bgpd/bgp_snmp_bgp4v2.c
@@ -145,10 +145,24 @@ static struct peer *bgpv2PeerTable_lookup(struct variable *v, oid name[],
size_t namelen = v ? v->namelen : BGP4V2_PEER_ENTRY_OFFSET;
oid *offset = name + namelen;
sa_family_t family = name[namelen - 1] == 4 ? AF_INET : AF_INET6;
+ int afi_len = IN_ADDR_SIZE;
+ size_t offsetlen = *length - namelen;
+
+ if (family == AF_INET6)
+ afi_len = IN6_ADDR_SIZE;
+
+ /* Somehow with net-snmp 5.7.3, every OID item in an array
+ * is uninitialized and has a max random value, let's zero it.
+ * With 5.8, 5.9, it works fine even without this hack.
+ */
+ if (!offsetlen) {
+ for (int i = 0; i < afi_len; i++)
+ *(offset + i) = 0;
+ }
if (exact) {
if (family == AF_INET) {
- oid2in_addr(offset, IN_ADDR_SIZE, &addr->ip._v4_addr);
+ oid2in_addr(offset, afi_len, &addr->ip._v4_addr);
peer = peer_lookup_all_vrf(addr);
return peer;
} else if (family == AF_INET6) {
@@ -163,11 +177,11 @@ static struct peer *bgpv2PeerTable_lookup(struct variable *v, oid name[],
switch (sockunion_family(&peer->su)) {
case AF_INET:
oid_copy_in_addr(offset, &peer->su.sin.sin_addr);
- *length = IN_ADDR_SIZE + namelen;
+ *length = afi_len + namelen;
return peer;
case AF_INET6:
oid_copy_in6_addr(offset, &peer->su.sin6.sin6_addr);
- *length = IN6_ADDR_SIZE + namelen;
+ *length = afi_len + namelen;
return peer;
default:
break;