]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_snmp.c
lib: add RFC3164 logging timestamps
[mirror_frr.git] / ldpd / ldp_snmp.c
CommitLineData
f9a4d683
KS
1/*
2 * LDP SNMP support
3 * Copyright (C) 2020 Volta Networks, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/*
21 * This is minimal read-only implementations providing
22 * mplsLdpModuleReadOnlyCompliance as described in RFC 3815.
23 */
24
25#include <zebra.h>
26
27#include <net-snmp/net-snmp-config.h>
28#include <net-snmp/net-snmp-includes.h>
29
30#include "vrf.h"
31#include "if.h"
32#include "log.h"
33#include "prefix.h"
34#include "table.h"
35#include "command.h"
36#include "memory.h"
37#include "smux.h"
38#include "libfrr.h"
09781197 39#include "lib/version.h"
f9a4d683
KS
40#include "ldpd.h"
41#include "ldpe.h"
42
43/* SNMP value hack. */
44#define COUNTER32 ASN_COUNTER
45#define INTEGER ASN_INTEGER
46#define UNSIGNED32 ASN_GAUGE
47#define TIMESTAMP ASN_TIMETICKS
48#define TIMETICKS ASN_TIMETICKS
49#define STRING ASN_OCTET_STR
50#define IPADDRESS ASN_IPADDRESS
51
52#define LDP_LSRID_IDX_LEN 6
53#define LDP_ENTITY_IDX_LEN 1
54#define LDP_ADJACENCY_IDX_LEN 1
55
56/* MPLS-LDP-STD-MIB. */
57#define MPLS_LDP_STD_MIB 1, 3, 6, 1, 2, 1, 10, 166, 4
58
59#define MPLS_LDP_LSR_ID 0
60#define MPLS_LDP_LSR_LOOP_DETECTION_CAPABLE 0
61#define MPLS_LDP_ENTITY_LAST_CHANGE 0
62#define MPLS_LDP_ENTITY_INDEX_NEXT 0
63
64/* Declare static local variables for convenience. */
65SNMP_LOCAL_VARIABLES
66
67/* LDP-MIB instances. */
68static oid ldp_oid[] = {MPLS_LDP_STD_MIB};
69static oid ldp_trap_oid[] = {MPLS_LDP_STD_MIB, 0};
70
71static uint8_t snmp_ldp_rtrid[6] = {0, 0, 0, 0, 0};
72
73#define LDP_DEFAULT_ENTITY_INDEX 1
74
75#define MPLSLDPLSRLOOPDETECTIONCAPABLE_NONE 1
76#define MPLSLDPLSRLOOPDETECTIONCAPABLE_OTHER 2
77#define MPLSLDPLSRLOOPDETECTIONCAPABLE_HOPCOUNT 3
78#define MPLSLDPLSRLOOPDETECTIONCAPABLE_PATHVECTOR 4
79#define MPLSLDPLSRLOOPDETECTIONCAPABLE_HOPCOUNTANDPATHVECTOR 5
80
81/* MPLS LDP mplsLdpHelloAdjacencyTable. */
82#define MPLSLDPHELLOADJACENCYINDEX 1
83#define MPLSLDPHELLOADJACENCYHOLDTIMEREM 2
84#define MPLSLDPHELLOADJACENCYHOLDTIME 3
85#define MPLSLDPHELLOADJACENCYTYPE 4
86
87/* enums for column mplsLdpHelloAdjacencyType */
88#define MPLSLDPHELLOADJACENCYTYPE_LINK 1
89#define MPLSLDPHELLOADJACENCYTYPE_TARGETED 2
90
91#define MPLSLDPPEERTRANSPORTADDRTYPE_UNKNOWN 0
92#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV4 1
93#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV6 2
94#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV4Z 3
95#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV6Z 4
96#define MPLSLDPPEERTRANSPORTADDRTYPE_DNS 16
97
98#define DOWNSTREAMONDEMAND 1
99#define DOWNSTREAMUNSOLICITED 2
100
101#define CONSERVATIVERETENTION 1
102#define LIBERALRETENTION 2
103
104#define TRANSPORTADDRINTERFACE 1
105#define TRANSPORTADDRLOOPBACK 2
106
107#define LABELTYPEGENERIC 1
108
109#define STORAGETYPENONVOLATILE 3
110
111#define ROWSTATUSACTIVE 4
112
113#define ADMINSTATUSENABLED 1
114
115#define OPERSTATUSENABLED 2
116
117/* MPLS LDP mplsLdpPeerTable */
118#define MPLSLDPPEERLDPID 1
119#define MPLSLDPPEERLABELDISTMETHOD 2
120#define MPLSLDPPEERPATHVECTORLIMIT 3
121#define MPLSLDPPEERTRANSPORTADDRTYPE 4
122#define MPLSLDPPEERTRANSPORTADDR 5
123
124#define MPLSLDPSESSIONROLE_UNKNOWN 1
125#define MPLSLDPSESSIONROLE_ACTIVE 2
126#define MPLSLDPSESSIONROLE_PASSIVE 3
127
128#define MPLSLDPSESSIONSTATE_NONEXISTENT 1
129#define MPLSLDPSESSIONSTATE_INITIALIZED 2
130#define MPLSLDPSESSIONSTATE_OPENREC 3
131#define MPLSLDPSESSIONSTATE_OPENSENT 4
132#define MPLSLDPSESSIONSTATE_OPERATIONAL 5
133
134/* MPLS LDP mplsLdpSessionTable */
135#define MPLSLDPSESSIONSTATELASTCHANGE 1
136#define MPLSLDPSESSIONSTATE 2
137#define MPLSLDPSESSIONROLE 3
138#define MPLSLDPSESSIONPROTOCOLVERSION 4
139#define MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM 5
140#define MPLSLDPSESSIONKEEPALIVETIME 6
141#define MPLSLDPSESSIONMAXPDULENGTH 7
142#define MPLSLDPSESSIONDISCONTINUITYTIME 8
143
144/* MPLS LDP mplsLdpEntityTable */
145#define MPLSLDPENTITYLDPID 1
146#define MPLSLDPENTITYINDEX 2
147#define MPLSLDPENTITYPROTOCOLVERSION 3
148#define MPLSLDPENTITYADMINSTATUS 4
149#define MPLSLDPENTITYOPERSTATUS 5
150#define MPLSLDPENTITYTCPPORT 6
151#define MPLSLDPENTITYUDPDSCPORT 7
152#define MPLSLDPENTITYMAXPDULENGTH 8
153#define MPLSLDPENTITYKEEPALIVEHOLDTIMER 9
154#define MPLSLDPENTITYHELLOHOLDTIMER 10
155#define MPLSLDPENTITYINITSESSIONTHRESHOLD 11
156#define MPLSLDPENTITYLABELDISTMETHOD 12
157#define MPLSLDPENTITYLABELRETENTIONMODE 13
158#define MPLSLDPENTITYPATHVECTORLIMIT 14
159#define MPLSLDPENTITYHOPCOUNTLIMIT 15
160#define MPLSLDPENTITYTRANSPORTADDRKIND 16
161#define MPLSLDPENTITYTARGETPEER 17
162#define MPLSLDPENTITYTARGETPEERADDRTYPE 18
163#define MPLSLDPENTITYTARGETPEERADDR 19
164#define MPLSLDPENTITYLABELTYPE 20
165#define MPLSLDPENTITYDISCONTINUITYTIME 21
166#define MPLSLDPENTITYSTORAGETYPE 22
167#define MPLSLDPENTITYROWSTATUS 23
168
169/* MPLS LDP mplsLdpEntityStatsTable */
170#define MPLSLDPENTITYSTATSSESSIONATTEMPTS 1
171#define MPLSLDPENTITYSTATSSESSIONREJHELLO 2
172#define MPLSLDPENTITYSTATSSESSIONREJAD 3
173#define MPLSLDPENTITYSTATSSESSIONREJMAXPDU 4
174#define MPLSLDPENTITYSTATSSESSIONREJLR 5
175#define MPLSLDPENTITYSTATSBADLDPID 6
176#define MPLSLDPENTITYSTATSBADPDULENGTH 7
177#define MPLSLDPENTITYSTATSBADMSGLENGTH 8
178#define MPLSLDPENTITYSTATSBADTLVLENGTH 9
179#define MPLSLDPENTITYSTATSMALFORMEDTLV 10
180#define MPLSLDPENTITYSTATSKEEPALIVEEXP 11
181#define MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY 12
182#define MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY 13
183
184#define MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS 1
185#define MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS 2
186
187static uint8_t *ldpLsrId(struct variable *v, oid name[], size_t *length,
188 int exact, size_t *var_len,
189 WriteMethod **write_method)
190{
191 if (smux_header_generic(v, name, length, exact, var_len, write_method)
192 == MATCH_FAILED)
193 return NULL;
194
195 *var_len = 4;
196 return (uint8_t *)&leconf->rtr_id.s_addr;
197}
198
199static uint8_t *ldpLoopDetectCap(struct variable *v, oid name[], size_t *length,
200 int exact, size_t *var_len,
201 WriteMethod **write_method)
202{
203 if (smux_header_generic(v, name, length, exact, var_len, write_method)
204 == MATCH_FAILED)
205 return NULL;
206
207 return SNMP_INTEGER(MPLSLDPLSRLOOPDETECTIONCAPABLE_NONE);
208}
209
210extern uint32_t ldp_start_time;
211static uint8_t *ldpEntityLastChange(struct variable *v, oid name[],
212 size_t *length,
213 int exact, size_t *var_len,
214 WriteMethod **write_method)
215{
216 if (smux_header_generic(v, name, length, exact, var_len, write_method)
217 == MATCH_FAILED)
218 return NULL;
219
220 *var_len = sizeof(time_t);
221 return (uint8_t *) &(leconf->config_change_time);
222
223}
224
225static uint8_t *ldpEntityIndexNext(struct variable *v, oid name[],
226 size_t *length,int exact, size_t *var_len,
227 WriteMethod **write_method)
228{
229 if (smux_header_generic(v, name, length, exact, var_len, write_method)
230 == MATCH_FAILED)
231 return NULL;
232
233 return SNMP_INTEGER(0);
234}
235
236#define LDP_ENTITY_TOTAL_LEN 21
237#define LDP_ENTITY_MAX_IDX_LEN 6
238
239static struct ldpd_af_conf *ldpEntityTable_lookup(struct variable *v, oid *name,
240 size_t *length, int exact,
241 uint32_t *index)
242{
243 int len;
244 struct ldpd_af_conf *af_v4, *af_v6;
245
246 af_v4 = &leconf->ipv4;
247 af_v6 = &leconf->ipv6;
248
249 if (exact) {
250 if (*length != LDP_ENTITY_TOTAL_LEN)
251 return NULL;
252
253 if (leconf->trans_pref == DUAL_STACK_LDPOV6 &&
254 af_v6->flags & F_LDPD_AF_ENABLED) {
255 *index = 2;
256 return af_v6;
257 } else {
258 *index = 1;
259 return af_v4;
260 }
261 } else {
262 /* only support one router id so can just skip */
263 len = *length - v->namelen - LDP_ENTITY_MAX_IDX_LEN;
264 if (len <= 0) {
265 if (leconf->trans_pref == DUAL_STACK_LDPOV6 &&
266 af_v6->flags & F_LDPD_AF_ENABLED) {
267 *index = 2;
268 return af_v6;
269 } else {
270 *index = 1;
271 return af_v4;
272 }
273 }
274 }
275 return NULL;
276}
277
278static uint8_t *ldpEntityTable(struct variable *v, oid name[], size_t *length,
279 int exact, size_t *var_len,
280 WriteMethod **write_method)
281{
282 struct ldpd_af_conf *af;
283 struct in_addr entityLdpId = {.s_addr = 0};
284 uint32_t index = 0;
285
286 *write_method = NULL;
287
288 if (smux_header_table(v, name, length, exact, var_len, write_method)
289 == MATCH_FAILED)
290 return NULL;
291
292 af = ldpEntityTable_lookup(v, name, length, exact, &index);
293 if (af == NULL)
294 return NULL;
295
296 if (!exact) {
297 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
298
299 /* Copy the name out */
300 memcpy(name, v->name, v->namelen * sizeof(oid));
301
302 /* Append index */
303 *length = LDP_ENTITY_TOTAL_LEN;
9e263221 304 oid_copy_in_addr(name + v->namelen, &entityLdpId);
f9a4d683
KS
305 name[v->namelen + 4] = 0;
306 name[v->namelen + 5] = 0;
307 name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
308 }
309
310 /* Return the current value of the variable */
311 switch (v->magic) {
312 case MPLSLDPENTITYLDPID:
313 *var_len = 6;
314 memcpy (snmp_ldp_rtrid, &entityLdpId, IN_ADDR_SIZE);
315 return (uint8_t *)snmp_ldp_rtrid;
316 case MPLSLDPENTITYINDEX:
317 return SNMP_INTEGER(LDP_DEFAULT_ENTITY_INDEX);
318 case MPLSLDPENTITYPROTOCOLVERSION:
319 return SNMP_INTEGER(LDP_VERSION);
320 case MPLSLDPENTITYADMINSTATUS:
321 return SNMP_INTEGER(ADMINSTATUSENABLED);
322 case MPLSLDPENTITYOPERSTATUS:
323 return SNMP_INTEGER(OPERSTATUSENABLED);
324 case MPLSLDPENTITYTCPPORT:
325 return SNMP_INTEGER(LDP_PORT);
326 case MPLSLDPENTITYUDPDSCPORT:
327 return SNMP_INTEGER(LDP_PORT);
328 case MPLSLDPENTITYMAXPDULENGTH:
329 return SNMP_INTEGER(LDP_MAX_LEN);
330 case MPLSLDPENTITYKEEPALIVEHOLDTIMER:
331 return SNMP_INTEGER(af->keepalive);
332 case MPLSLDPENTITYHELLOHOLDTIMER:
333 return SNMP_INTEGER(af->lhello_holdtime);
334 case MPLSLDPENTITYINITSESSIONTHRESHOLD:
335 return SNMP_INTEGER(0); /* not supported */
336 case MPLSLDPENTITYLABELDISTMETHOD:
337 return SNMP_INTEGER(DOWNSTREAMUNSOLICITED);
338 case MPLSLDPENTITYLABELRETENTIONMODE:
339 return SNMP_INTEGER(LIBERALRETENTION);
340 case MPLSLDPENTITYPATHVECTORLIMIT:
341 return SNMP_INTEGER(0); /* not supported */
342 case MPLSLDPENTITYHOPCOUNTLIMIT:
343 return SNMP_INTEGER(0);
344 case MPLSLDPENTITYTRANSPORTADDRKIND:
345 return SNMP_INTEGER(TRANSPORTADDRLOOPBACK);
346 case MPLSLDPENTITYTARGETPEER:
347 return SNMP_INTEGER(1);
348 case MPLSLDPENTITYTARGETPEERADDRTYPE:
349 if (index == 1)
350 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV4);
351 else
352 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV6);
353 case MPLSLDPENTITYTARGETPEERADDR:
354 if (index == 1) {
355 *var_len = sizeof(af->trans_addr.v4);
356 return ((uint8_t *)&af->trans_addr.v4);
357 }else {
358 *var_len = sizeof(af->trans_addr.v6);
359 return ((uint8_t *)&af->trans_addr.v6);
360 }
361 case MPLSLDPENTITYLABELTYPE:
362 return SNMP_INTEGER(LABELTYPEGENERIC);
363 case MPLSLDPENTITYDISCONTINUITYTIME:
364 return SNMP_INTEGER(0);
365 case MPLSLDPENTITYSTORAGETYPE:
366 return SNMP_INTEGER(STORAGETYPENONVOLATILE);
367 case MPLSLDPENTITYROWSTATUS:
368 return SNMP_INTEGER(ROWSTATUSACTIVE);
369 default:
370 return NULL;
371 }
372
373 return NULL;
374}
375
d4d6e7d8
KS
376static uint8_t *ldpEntityStatsTable(struct variable *v, oid name[],
377 size_t *length, int exact, size_t *var_len,
378 WriteMethod **write_method)
379{
380 struct in_addr entityLdpId = {.s_addr = 0};
381 int len;
382
383 *write_method = NULL;
384
385 if (smux_header_table(v, name, length, exact, var_len, write_method)
386 == MATCH_FAILED)
387 return NULL;
388
389 if (exact) {
390 if (*length != LDP_ENTITY_TOTAL_LEN)
391 return NULL;
392 } else {
393 len = *length - v->namelen - LDP_ENTITY_MAX_IDX_LEN;
394 if (len > 0)
395 return NULL;
396
397 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
398
399 /* Copy the name out */
400 memcpy(name, v->name, v->namelen * sizeof(oid));
401
402 /* Append index */
403 *length = LDP_ENTITY_TOTAL_LEN;
9e263221 404 oid_copy_in_addr(name + v->namelen, &entityLdpId);
d4d6e7d8
KS
405 name[v->namelen + 4] = 0;
406 name[v->namelen + 5] = 0;
407 name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
408 }
409
410 /* Return the current value of the variable */
411 switch (v->magic) {
412 case MPLSLDPENTITYSTATSSESSIONATTEMPTS:
413 return SNMP_INTEGER(leconf->stats.session_attempts);
414 case MPLSLDPENTITYSTATSSESSIONREJHELLO:
415 return SNMP_INTEGER(leconf->stats.session_rejects_hello);
416 case MPLSLDPENTITYSTATSSESSIONREJAD:
417 return SNMP_INTEGER(leconf->stats.session_rejects_ad);
418 case MPLSLDPENTITYSTATSSESSIONREJMAXPDU:
419 return SNMP_INTEGER(leconf->stats.session_rejects_max_pdu);
420 case MPLSLDPENTITYSTATSSESSIONREJLR:
421 return SNMP_INTEGER(leconf->stats.session_rejects_lr);
422 case MPLSLDPENTITYSTATSBADLDPID:
423 return SNMP_INTEGER(leconf->stats.bad_ldp_id);
424 case MPLSLDPENTITYSTATSBADPDULENGTH:
425 return SNMP_INTEGER(leconf->stats.bad_pdu_len);
426 case MPLSLDPENTITYSTATSBADMSGLENGTH:
427 return SNMP_INTEGER(leconf->stats.bad_msg_len);
428 case MPLSLDPENTITYSTATSBADTLVLENGTH:
429 return SNMP_INTEGER(leconf->stats.bad_tlv_len);
430 case MPLSLDPENTITYSTATSMALFORMEDTLV:
431 return SNMP_INTEGER(leconf->stats.malformed_tlv);
432 case MPLSLDPENTITYSTATSKEEPALIVEEXP:
433 return SNMP_INTEGER(leconf->stats.keepalive_timer_exp);
434 case MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY:
435 return SNMP_INTEGER(leconf->stats.shutdown_rcv_notify);
436 case MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY:
437 return SNMP_INTEGER(leconf->stats.shutdown_send_notify);
438 default:
439 return NULL;
440 }
441
442 return NULL;
443}
444
f9a4d683
KS
445#define LDP_ADJACENCY_ENTRY_MAX_IDX_LEN 14
446
447static void ldpHelloAdjacencyTable_oid_to_index(
448 struct variable *v, oid name[],
449 size_t *length,
450 struct in_addr *entityLdpId,
451 uint32_t *entityIndex,
452 struct in_addr *peerLdpId,
453 uint32_t *adjacencyIndex)
454{
455 oid *offset = name + v->namelen;
456 int offsetlen = *length - v->namelen;
457 int len = offsetlen;
458
459 if (len > LDP_ADJACENCY_ENTRY_MAX_IDX_LEN)
460 len = LDP_ADJACENCY_ENTRY_MAX_IDX_LEN;
461
462 if (len >= LDP_LSRID_IDX_LEN)
463 oid2in_addr(offset, sizeof(struct in_addr), entityLdpId);
464
465 offset += LDP_LSRID_IDX_LEN;
466 offsetlen -= LDP_LSRID_IDX_LEN;
467 len = offsetlen;
468
469 if (len > LDP_ENTITY_IDX_LEN)
470 len = LDP_ENTITY_IDX_LEN;
471
472 if (len >= LDP_ENTITY_IDX_LEN)
473 *entityIndex = offset[0];
474
475 offset += LDP_ENTITY_IDX_LEN;
476 offsetlen -= LDP_ENTITY_IDX_LEN;
477 len = offsetlen;
478
479 if (len > LDP_LSRID_IDX_LEN)
480 len = LDP_LSRID_IDX_LEN;
481
482 if (len >= LDP_LSRID_IDX_LEN)
483 oid2in_addr(offset, sizeof(struct in_addr), peerLdpId);
484
485 offset += LDP_LSRID_IDX_LEN;
486 offsetlen -= LDP_LSRID_IDX_LEN;
487 len = offsetlen;
488
489 if (len > LDP_ADJACENCY_IDX_LEN)
490 len = LDP_ADJACENCY_IDX_LEN;
491
492 if (len >= LDP_ADJACENCY_IDX_LEN)
493 *adjacencyIndex = offset[0];
494}
495
496static struct adj *
497nbr_get_adj_by_index(struct nbr *nbr, uint32_t adjacencyIndex)
498{
499 struct adj *adj;
500 uint32_t i = 0;
501
502 RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
503 if (++i == adjacencyIndex)
504 return adj;
505
506 return NULL;
507}
508
509static struct ctl_adj *
510ldpHelloAdjacencyTable_lookup_helper(
511 struct in_addr *entityLdpId,
512 uint32_t *entityIndex,
513 struct in_addr *peerLdpId,
514 uint32_t *adjacencyIndex)
515{
516 struct ctl_adj *ctl_adj = NULL;
517 struct adj *adj = NULL;
518 struct nbr *cur_nbr = nbr_find_ldpid(peerLdpId->s_addr);
519
520 if (cur_nbr)
521 /* If found nbr, then look to see if the
522 * adjacency exists
523 */
524 adj = nbr_get_adj_by_index(cur_nbr, *adjacencyIndex);
525
526 if (adj)
527 ctl_adj = adj_to_ctl(adj);
528
529 return ctl_adj;
530}
531
532static struct ctl_adj *
533ldpHelloAdjacencyTable_next_helper(
534 int first,
535 struct in_addr *entityLdpId,
536 uint32_t *entityIndex,
537 struct in_addr *peerLdpId,
538 uint32_t *adjacencyIndex)
539{
540 struct ctl_adj *ctl_adj = NULL;
541 struct nbr *nbr = NULL;
542 struct adj *adj = NULL;
543
544 if (first)
545 nbr = nbr_get_first_ldpid();
546 else {
547 struct nbr *cur_nbr = nbr_find_ldpid(peerLdpId->s_addr);
548 if (cur_nbr)
549 /* If found nbr, then look to see if the
550 * adjacency exists
551 */
552 adj = nbr_get_adj_by_index(cur_nbr, *adjacencyIndex + 1);
553 if (adj)
554 *adjacencyIndex += 1;
555 else
556 nbr = nbr_get_next_ldpid(peerLdpId->s_addr);
557 }
558
559 if (!adj && nbr) {
560 adj = RB_MIN(nbr_adj_head, &nbr->adj_tree);
561 *adjacencyIndex = 1;
562 }
563
564 if (adj)
565 ctl_adj = adj_to_ctl(adj);
566
567 return ctl_adj;
568}
569
570#define HELLO_ADJ_MAX_IDX_LEN 14
571
572static struct ctl_adj *
573ldpHelloAdjacencyTable_lookup(struct variable *v, oid name[],
574 size_t *length, int exact,
575 struct in_addr *entityLdpId,
576 uint32_t *entityIndex,
577 struct in_addr *peerLdpId,
578 uint32_t *adjacencyIndex)
579{
580 struct ctl_adj *hello_adj = NULL;
581
582 if (exact) {
583 if (*length < HELLO_ADJ_MAX_IDX_LEN)
584 return NULL;
585
586 ldpHelloAdjacencyTable_oid_to_index(
587 v, name, length,
588 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
589
590 hello_adj = ldpHelloAdjacencyTable_lookup_helper(
591 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
592 } else {
593 int first = 0;
594 int offsetlen = *length - v->namelen;
595
596 if (offsetlen < HELLO_ADJ_MAX_IDX_LEN)
597 first = 1;
598
599 ldpHelloAdjacencyTable_oid_to_index(
600 v, name, length,
601 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
602
603 hello_adj = ldpHelloAdjacencyTable_next_helper(first,
604 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
605
606 }
607 return hello_adj;
608}
609
610static uint8_t *ldpHelloAdjacencyTable(struct variable *v, oid name[], size_t *length,
611 int exact, size_t *var_len,
612 WriteMethod **write_method)
613{
614 struct in_addr entityLdpId = {.s_addr = 0};
615 uint32_t entityIndex = 0;
616 struct in_addr peerLdpId = {.s_addr = 0};
617 uint32_t adjacencyIndex = 0;
618
619 if (smux_header_table(v, name, length, exact, var_len, write_method)
620 == MATCH_FAILED)
621 return NULL;
622
623 struct ctl_adj *ctl_adj = ldpHelloAdjacencyTable_lookup(v, name,
624 length, exact,
625 &entityLdpId, &entityIndex, &peerLdpId, &adjacencyIndex);
626
627 if (!ctl_adj)
628 return NULL;
629
630 if (!exact) {
631
632 /* Copy the name out */
633 memcpy(name, v->name, v->namelen * sizeof(oid));
634
635 /* Append index */
636 struct in_addr entityLdpId = {.s_addr = 0};
637 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
638
639 struct in_addr peerLdpId = ctl_adj->id;
640
9e263221 641 oid_copy_in_addr(name + v->namelen, &entityLdpId);
f9a4d683
KS
642 name[v->namelen + 4] = 0;
643 name[v->namelen + 5] = 0;
644 name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
9e263221 645 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
f9a4d683
KS
646 name[v->namelen + 11] = 0;
647 name[v->namelen + 12] = 0;
648 name[v->namelen + 13] = adjacencyIndex;
649
650 /* Set length */
651 *length = v->namelen + HELLO_ADJ_MAX_IDX_LEN;
652 }
653
654 switch (v->magic) {
655 case MPLSLDPHELLOADJACENCYINDEX:
656 return SNMP_INTEGER(adjacencyIndex);
657 case MPLSLDPHELLOADJACENCYHOLDTIMEREM:
658 return SNMP_INTEGER(ctl_adj->holdtime_remaining);
659 case MPLSLDPHELLOADJACENCYHOLDTIME:
660 return SNMP_INTEGER(ctl_adj->holdtime);
661 case MPLSLDPHELLOADJACENCYTYPE:
662 if (ctl_adj->type == HELLO_LINK)
663 return SNMP_INTEGER(MPLSLDPHELLOADJACENCYTYPE_LINK);
664 return SNMP_INTEGER(MPLSLDPHELLOADJACENCYTYPE_TARGETED);
665 default:
666 return NULL;
667 }
668
669 return NULL;
670}
671
672#define LDP_LSRID_IDX_LEN 6
673#define LDP_ENTITY_IDX_LEN 1
674#define LDP_PEER_ENTRY_MAX_IDX_LEN 13
675
676static void ldpPeerTable_oid_to_index(
677 struct variable *v, oid name[],
678 size_t *length,
679 struct in_addr *entityLdpId,
680 uint32_t *entityIndex,
681 struct in_addr *peerLdpId)
682{
683 oid *offset = name + v->namelen;
684 int offsetlen = *length - v->namelen;
685 int len = offsetlen;
686
687 if (len > LDP_PEER_ENTRY_MAX_IDX_LEN)
688 len = LDP_PEER_ENTRY_MAX_IDX_LEN;
689
690 if (len >= LDP_LSRID_IDX_LEN)
691 oid2in_addr(offset, sizeof(struct in_addr), entityLdpId);
692
693 offset += LDP_LSRID_IDX_LEN;
694 offsetlen -= LDP_LSRID_IDX_LEN;
695 len = offsetlen;
696
697 if (len > LDP_ENTITY_IDX_LEN)
698 len = LDP_ENTITY_IDX_LEN;
699
700 if (len >= LDP_ENTITY_IDX_LEN)
701 *entityIndex = offset[0];
702
703 offset += LDP_ENTITY_IDX_LEN;
704 offsetlen -= LDP_ENTITY_IDX_LEN;
705 len = offsetlen;
706
707 if (len > LDP_LSRID_IDX_LEN)
708 len = LDP_LSRID_IDX_LEN;
709
710 if (len >= LDP_LSRID_IDX_LEN)
711 oid2in_addr(offset, sizeof(struct in_addr), peerLdpId);
712}
713
714static struct ctl_nbr *
715ldpPeerTable_lookup_next(int first,
716 struct in_addr peerLdpId)
717{
718 struct nbr *nbr = NULL;
719 struct ctl_nbr *ctl_nbr = NULL;;
720
721 if (first)
722 nbr = nbr_get_first_ldpid();
723 else
724 nbr = nbr_get_next_ldpid(peerLdpId.s_addr);
725
726 if (nbr)
727 ctl_nbr = nbr_to_ctl(nbr);
728
729 return ctl_nbr;
730}
731
732static struct ctl_nbr *
733ldpPeerTable_lookup(struct variable *v, oid name[],
734 size_t *length, int exact,
735 struct in_addr *entityLdpId,
736 uint32_t *entityIndex,
737 struct in_addr *peerLdpId)
738{
739 struct ctl_nbr *ctl_nbr = NULL;
740 struct nbr *nbr = NULL;
741 int first = 0;
742
743 if (exact) {
744 if (*length < (long unsigned int)v->namelen
745 + LDP_PEER_ENTRY_MAX_IDX_LEN)
746 return NULL;
747
748 ldpPeerTable_oid_to_index(
749 v, name, length,
750 entityLdpId, entityIndex, peerLdpId);
751
752 nbr = nbr_find_ldpid(peerLdpId->s_addr);
753 if (nbr)
754 ctl_nbr = nbr_to_ctl(nbr);
755
756 return ctl_nbr;
757 } else {
758
759 int offsetlen = *length - v->namelen;
760 if (offsetlen < LDP_LSRID_IDX_LEN)
761 first = 1;
762
763 ldpPeerTable_oid_to_index(
764 v, name, length,
765 entityLdpId, entityIndex, peerLdpId);
766
767 ctl_nbr = ldpPeerTable_lookup_next(first, *peerLdpId);
768 return ctl_nbr;
769 }
770 return NULL;
771}
772
773static uint8_t *ldpPeerTable(struct variable *v, oid name[], size_t *length,
774 int exact, size_t *var_len,
775 WriteMethod **write_method)
776{
777 struct in_addr entityLdpId = {.s_addr = 0};
778 uint32_t entityIndex = 0;
779 struct in_addr peerLdpId = {.s_addr = 0};
780 struct ctl_nbr *ctl_nbr;
781
782
783 if (smux_header_table(v, name, length, exact, var_len, write_method)
784 == MATCH_FAILED)
785 return NULL;
786
787 ctl_nbr = ldpPeerTable_lookup(v, name, length, exact, &entityLdpId,
788 &entityIndex, &peerLdpId);
789
790 if (!ctl_nbr)
791 return NULL;
792
793 if (!exact) {
794
795 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
796 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
797 peerLdpId = ctl_nbr->id;
798
799 /* Copy the name out */
800 memcpy(name, v->name, v->namelen * sizeof(oid));
801
802 /* Append index */
9e263221 803 oid_copy_in_addr(name + v->namelen, &entityLdpId);
f9a4d683
KS
804
805 name[v->namelen + 4] = 0;
806 name[v->namelen + 5] = 0;
807 name[v->namelen + 6] = entityIndex;
9e263221 808 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
f9a4d683
KS
809 name[v->namelen + 11] = 0;
810 name[v->namelen + 12] = 0;
811
812 /* Set length */
813 *length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
814 }
815
816 switch (v->magic) {
817 case MPLSLDPPEERLDPID:
818 *var_len = 6;
819 memcpy(snmp_ldp_rtrid, &ctl_nbr->id, IN_ADDR_SIZE);
820 return snmp_ldp_rtrid;
821 case MPLSLDPPEERLABELDISTMETHOD:
822 return SNMP_INTEGER(DOWNSTREAMUNSOLICITED);
823 case MPLSLDPPEERPATHVECTORLIMIT:
824 return SNMP_INTEGER(0);
825 case MPLSLDPPEERTRANSPORTADDRTYPE:
826 if (ctl_nbr->af == AF_INET)
827 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV4);
828 else
829 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV6);
830 case MPLSLDPPEERTRANSPORTADDR:
831 if (ctl_nbr->af == AF_INET) {
832 *var_len = sizeof(ctl_nbr->raddr.v4);
833 return ((uint8_t *)&ctl_nbr->raddr.v4);
834 } else {
835 *var_len = sizeof(ctl_nbr->raddr.v6);
836 return ((uint8_t *)&ctl_nbr->raddr.v6);
837 }
838 default:
839 return NULL;
840 }
841
842 return NULL;
843}
844static uint8_t *ldpSessionTable(struct variable *v, oid name[], size_t *length,
845 int exact, size_t *var_len,
846 WriteMethod **write_method)
847{
848 struct in_addr entityLdpId = {.s_addr = 0};
849 uint32_t entityIndex = 0;
850 struct in_addr peerLdpId = {.s_addr = 0};
851 struct ctl_nbr *ctl_nbr;
852
853 if (smux_header_table(v, name, length, exact, var_len, write_method)
854 == MATCH_FAILED)
855 return NULL;
856
857 ctl_nbr = ldpPeerTable_lookup(v, name, length, exact, &entityLdpId,
858 &entityIndex, &peerLdpId);
859
860 if (!ctl_nbr)
861 return NULL;
862
863 if (!exact) {
864 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
865 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
866 peerLdpId = ctl_nbr->id;
867
868 /* Copy the name out */
869 memcpy(name, v->name, v->namelen * sizeof(oid));
870
871 /* Append index */
9e263221 872 oid_copy_in_addr(name + v->namelen, &entityLdpId);
f9a4d683
KS
873
874 name[v->namelen + 4] = 0;
875 name[v->namelen + 5] = 0;
876 name[v->namelen + 6] = entityIndex;
9e263221 877 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
f9a4d683
KS
878 name[v->namelen + 11] = 0;
879 name[v->namelen + 12] = 0;
880
881 /* Set length */
882 *length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
883 }
884
885 switch (v->magic) {
886 case MPLSLDPSESSIONSTATELASTCHANGE:
887 *var_len = sizeof(time_t);
888 return (uint8_t *) &(ctl_nbr->uptime);
889 case MPLSLDPSESSIONSTATE:
890 switch (ctl_nbr->nbr_state) {
891 case NBR_STA_INITIAL:
892 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_INITIALIZED);
893 case NBR_STA_OPENREC:
894 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPENREC);
895 case NBR_STA_OPENSENT:
896 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPENSENT);
897 case NBR_STA_OPER:
898 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPERATIONAL);
899 default:
900 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_NONEXISTENT);
901 }
902 case MPLSLDPSESSIONROLE:
903 if (ldp_addrcmp(ctl_nbr->af, &ctl_nbr->laddr, &ctl_nbr->raddr)
904 > 0)
905 return SNMP_INTEGER(MPLSLDPSESSIONROLE_ACTIVE);
906 else
907 return SNMP_INTEGER(MPLSLDPSESSIONROLE_PASSIVE);
908 case MPLSLDPSESSIONPROTOCOLVERSION:
909 return SNMP_INTEGER(LDP_VERSION);
910 case MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM:
911 return SNMP_INTEGER(ctl_nbr->hold_time_remaining);
912 case MPLSLDPSESSIONKEEPALIVETIME:
913 return SNMP_INTEGER(ctl_nbr->holdtime);
914 case MPLSLDPSESSIONMAXPDULENGTH:
915 if (ctl_nbr->nbr_state == NBR_STA_OPER)
916 return SNMP_INTEGER(ctl_nbr->max_pdu_len);
917 else
918 return SNMP_INTEGER(LDP_MAX_LEN);
919 case MPLSLDPSESSIONDISCONTINUITYTIME:
920 return SNMP_INTEGER(0); /* not supported */
921 default:
922 return NULL;
923 }
924
925 return NULL;
926}
927
d4d6e7d8
KS
928static uint8_t *ldpSessionStatsTable(struct variable *v, oid name[],
929 size_t *length,
930 int exact, size_t *var_len,
931 WriteMethod **write_method)
932{
933 struct in_addr entityLdpId = {.s_addr = 0};
934 uint32_t entityIndex = 0;
935 struct in_addr peerLdpId = {.s_addr = 0};
936
937 if (smux_header_table(v, name, length, exact, var_len, write_method)
938 == MATCH_FAILED)
939 return NULL;
940
941 struct ctl_nbr *ctl_nbr = ldpPeerTable_lookup(v, name, length, exact,
942 &entityLdpId, &entityIndex, &peerLdpId);
943
944 if (!ctl_nbr)
945 return NULL;
946
947 if (!exact) {
948 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
949 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
950 peerLdpId = ctl_nbr->id;
951
952 /* Copy the name out */
953 memcpy(name, v->name, v->namelen * sizeof(oid));
954
955 /* Append index */
9e263221 956 oid_copy_in_addr(name + v->namelen, &entityLdpId);
d4d6e7d8
KS
957 name[v->namelen + 4] = 0;
958 name[v->namelen + 5] = 0;
959 name[v->namelen + 6] = entityIndex;
9e263221 960 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
d4d6e7d8
KS
961 name[v->namelen + 11] = 0;
962 name[v->namelen + 12] = 0;
963
964 *length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
965 }
966
967 switch (v->magic) {
968 case MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS:
969 return SNMP_INTEGER(ctl_nbr->stats.unknown_msg);
970 case MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS:
971 return SNMP_INTEGER(ctl_nbr->stats.unknown_tlv);
972 default:
973 return NULL;
974 }
975
976 return NULL;
977}
978
f9a4d683
KS
979static struct variable ldpe_variables[] = {
980 {MPLS_LDP_LSR_ID, STRING, RONLY, ldpLsrId, 3, {1, 1, 1}},
981 {MPLS_LDP_LSR_LOOP_DETECTION_CAPABLE, INTEGER, RONLY,
982 ldpLoopDetectCap, 3, {1, 1, 2}},
983 {MPLS_LDP_ENTITY_LAST_CHANGE, TIMESTAMP, RONLY, ldpEntityLastChange,
984 3, {1, 2, 1}},
985 {MPLS_LDP_ENTITY_INDEX_NEXT, UNSIGNED32, RONLY, ldpEntityIndexNext,
986 3, {1, 2, 2}},
987
988 /* MPLS LDP mplsLdpEntityTable. */
989 {MPLSLDPENTITYLDPID, STRING, RONLY, ldpEntityTable,
990 5, {1, 2, 3, 1, 1}},
991 {MPLSLDPENTITYINDEX, UNSIGNED32, RONLY, ldpEntityTable,
992 5, {1, 2, 3, 1, 2}},
993 {MPLSLDPENTITYPROTOCOLVERSION, UNSIGNED32, RONLY, ldpEntityTable,
994 5, {1, 2, 3, 1, 3}},
995 {MPLSLDPENTITYADMINSTATUS, INTEGER, RONLY, ldpEntityTable,
996 5, {1, 2, 3, 1, 4}},
997 {MPLSLDPENTITYOPERSTATUS, INTEGER, RONLY, ldpEntityTable,
998 5, {1, 2, 3, 1, 5}},
999 {MPLSLDPENTITYTCPPORT, UNSIGNED32, RONLY, ldpEntityTable,
1000 5, {1, 2, 3, 1, 6}},
1001 {MPLSLDPENTITYUDPDSCPORT, UNSIGNED32, RONLY, ldpEntityTable,
1002 5, {1, 2, 3, 1, 7}},
1003 {MPLSLDPENTITYMAXPDULENGTH, UNSIGNED32, RONLY, ldpEntityTable,
1004 5, {1, 2, 3, 1, 8}},
1005 {MPLSLDPENTITYKEEPALIVEHOLDTIMER, UNSIGNED32, RONLY, ldpEntityTable,
1006 5, {1, 2, 3, 1, 9}},
1007 {MPLSLDPENTITYHELLOHOLDTIMER, UNSIGNED32, RONLY, ldpEntityTable,
1008 5, {1, 2, 3, 1, 10}},
1009 {MPLSLDPENTITYINITSESSIONTHRESHOLD, INTEGER, RONLY, ldpEntityTable,
1010 5, {1, 2, 3, 1, 11}},
1011 {MPLSLDPENTITYLABELDISTMETHOD, INTEGER, RONLY, ldpEntityTable,
1012 5, {1, 2, 3, 1, 12}},
1013 {MPLSLDPENTITYLABELRETENTIONMODE, INTEGER, RONLY, ldpEntityTable,
1014 5, {1, 2, 3, 1, 13}},
1015 {MPLSLDPENTITYPATHVECTORLIMIT, INTEGER, RONLY, ldpEntityTable,
1016 5, {1, 2, 3, 1, 14}},
1017 {MPLSLDPENTITYHOPCOUNTLIMIT, INTEGER, RONLY, ldpEntityTable,
1018 5, {1, 2, 3, 1, 15}},
1019 {MPLSLDPENTITYTRANSPORTADDRKIND, INTEGER, RONLY, ldpEntityTable,
1020 5, {1, 2, 3, 1, 16}},
1021 {MPLSLDPENTITYTARGETPEER, INTEGER, RONLY, ldpEntityTable,
1022 5, {1, 2, 3, 1, 17}},
1023 {MPLSLDPENTITYTARGETPEERADDRTYPE, INTEGER, RONLY, ldpEntityTable,
1024 5, {1, 2, 3, 1, 18}},
1025 {MPLSLDPENTITYTARGETPEERADDR, STRING, RONLY, ldpEntityTable,
1026 5, {1, 2, 3, 1, 19}},
1027 {MPLSLDPENTITYLABELTYPE, INTEGER, RONLY, ldpEntityTable,
1028 5, {1, 2, 3, 1, 20}},
1029 {MPLSLDPENTITYDISCONTINUITYTIME, TIMESTAMP, RONLY, ldpEntityTable,
1030 5, {1, 2, 3, 1, 21}},
1031 {MPLSLDPENTITYSTORAGETYPE, INTEGER, RONLY, ldpEntityTable,
1032 5, {1, 2, 3, 1, 22}},
1033 {MPLSLDPENTITYROWSTATUS, INTEGER, RONLY, ldpEntityTable,
1034 5, {1, 2, 3, 1, 23}},
1035
d4d6e7d8
KS
1036 /* MPLS LDP mplsLdpEntityStatsTable. */
1037 { MPLSLDPENTITYSTATSSESSIONATTEMPTS, COUNTER32, RONLY,
1038 ldpEntityStatsTable, 5, {1, 2, 4, 1, 1}},
1039 { MPLSLDPENTITYSTATSSESSIONREJHELLO, COUNTER32, RONLY,
1040 ldpEntityStatsTable, 5, {1, 2, 4, 1, 2}},
1041 { MPLSLDPENTITYSTATSSESSIONREJAD, COUNTER32, RONLY,
1042 ldpEntityStatsTable, 5, {1, 2, 4, 1, 3}},
1043 { MPLSLDPENTITYSTATSSESSIONREJMAXPDU, COUNTER32, RONLY,
1044 ldpEntityStatsTable, 5, {1, 2, 4, 1, 4}},
1045 { MPLSLDPENTITYSTATSSESSIONREJLR, COUNTER32, RONLY,
1046 ldpEntityStatsTable, 5, {1, 2, 4, 1, 5}},
1047 { MPLSLDPENTITYSTATSBADLDPID, COUNTER32, RONLY,
1048 ldpEntityStatsTable, 5, {1, 2, 4, 1, 6}},
1049 { MPLSLDPENTITYSTATSBADPDULENGTH, COUNTER32, RONLY,
1050 ldpEntityStatsTable, 5, {1, 2, 4, 1, 7}},
1051 { MPLSLDPENTITYSTATSBADMSGLENGTH, COUNTER32, RONLY,
1052 ldpEntityStatsTable, 5, {1, 2, 4, 1, 8}},
1053 { MPLSLDPENTITYSTATSBADTLVLENGTH, COUNTER32, RONLY,
1054 ldpEntityStatsTable, 5, {1, 2, 4, 1, 9}},
1055 { MPLSLDPENTITYSTATSMALFORMEDTLV, COUNTER32, RONLY,
1056 ldpEntityStatsTable, 5, {1, 2, 4, 1, 10}},
1057 { MPLSLDPENTITYSTATSKEEPALIVEEXP, COUNTER32, RONLY,
1058 ldpEntityStatsTable, 5, {1, 2, 4, 1, 11}},
1059 { MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY, COUNTER32, RONLY,
1060 ldpEntityStatsTable, 5, {1, 2, 4, 1, 12}},
1061 { MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY, COUNTER32, RONLY,
1062 ldpEntityStatsTable, 5, {1, 2, 4, 1, 13}},
1063
f9a4d683
KS
1064 /* MPLS LDP mplsLdpPeerTable */
1065 {MPLSLDPPEERLDPID, STRING, RONLY, ldpPeerTable, 5, {1, 3, 2, 1, 1}},
1066 {MPLSLDPPEERLABELDISTMETHOD, INTEGER, RONLY, ldpPeerTable,
1067 5, {1, 3, 2, 1, 2}},
1068 {MPLSLDPPEERPATHVECTORLIMIT, INTEGER, RONLY, ldpPeerTable,
1069 5, {1, 3, 2, 1, 3}},
1070 {MPLSLDPPEERTRANSPORTADDRTYPE, INTEGER, RONLY, ldpPeerTable,
1071 5, {1, 3, 2, 1, 4}},
1072 {MPLSLDPPEERTRANSPORTADDR, STRING, RONLY, ldpPeerTable,
1073 5, {1, 3, 2, 1, 5}},
1074
1075 /* MPLS LDP mplsLdpSessionTable */
1076 {MPLSLDPSESSIONSTATELASTCHANGE, TIMESTAMP, RONLY, ldpSessionTable,
1077 5, {1, 3, 3, 1, 1}},
1078 {MPLSLDPSESSIONSTATE, INTEGER, RONLY, ldpSessionTable,
1079 5, {1, 3, 3, 1, 2}},
1080 {MPLSLDPSESSIONROLE, INTEGER, RONLY, ldpSessionTable,
1081 5, {1, 3, 3, 1, 3}},
1082 {MPLSLDPSESSIONPROTOCOLVERSION, UNSIGNED32, RONLY, ldpSessionTable,
1083 5, {1, 3, 3, 1, 4}},
1084 {MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM, INTEGER, RONLY, ldpSessionTable,
1085 5, {1, 3, 3, 1, 5}},
1086 {MPLSLDPSESSIONKEEPALIVETIME, UNSIGNED32, RONLY, ldpSessionTable,
1087 5, {1, 3, 3, 1, 6}},
1088 {MPLSLDPSESSIONMAXPDULENGTH, UNSIGNED32, RONLY, ldpSessionTable,
1089 5, {1, 3, 3, 1, 7}},
1090 {MPLSLDPSESSIONDISCONTINUITYTIME, TIMESTAMP, RONLY, ldpSessionTable,
1091 5, {1, 3, 3, 1, 8}},
1092
d4d6e7d8
KS
1093 /* MPLS LDP mplsLdpSessionStatsTable */
1094 {MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS, COUNTER32, RONLY,
1095 ldpSessionStatsTable, 5, {1, 3, 4, 1, 1}},
1096 {MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS, COUNTER32, RONLY,
1097 ldpSessionStatsTable, 5, {1, 3, 4, 1, 2}},
1098
f9a4d683
KS
1099 /* MPLS LDP mplsLdpHelloAdjacencyTable. */
1100 {MPLSLDPHELLOADJACENCYINDEX, UNSIGNED32, RONLY,
1101 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 1}},
1102 {MPLSLDPHELLOADJACENCYHOLDTIMEREM, INTEGER, RONLY,
1103 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 2}},
1104 {MPLSLDPHELLOADJACENCYHOLDTIME, UNSIGNED32, RONLY,
1105 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 3}},
1106 {MPLSLDPHELLOADJACENCYTYPE, INTEGER, RONLY,
1107 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 4}},
1108};
1109
1110static struct variable lde_variables[] = {
1111};
1112
1113static struct trap_object ldpSessionTrapList[] = {
1114 {5, {1, 3, 3, 1, MPLSLDPSESSIONSTATE}},
1115 {5, {1, 3, 3, 1, MPLSLDPSESSIONDISCONTINUITYTIME}},
1116 {5, {1, 3, 4, 1, MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS}},
1117 {5, {1, 3, 4, 1, MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS}}};
1118
1119/* LDP TRAP. */
1120#define LDPINITSESSIONTHRESHOLDEXCEEDED 1
1121#define LDPPATHVECTORLIMITMISMATCH 2
1122#define LDPSESSIONUP 3
1123#define LDPSESSIONDOWN 4
1124
1125static void
1126ldpTrapSession(struct nbr * nbr, unsigned int sptrap)
1127{
1128 oid index[sizeof(oid) * (LDP_PEER_ENTRY_MAX_IDX_LEN + 1)];
1129
1130 struct in_addr entityLdpId = {.s_addr = 0};
1131 uint32_t entityIndex = 0;
1132 struct in_addr peerLdpId = {.s_addr = 0};
1133
1134 struct ctl_nbr *ctl_nbr = nbr_to_ctl(nbr);
1135
1136 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
1137 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
1138 peerLdpId = ctl_nbr->id;
1139
9e263221
PR
1140 oid_copy_in_addr(index, &entityLdpId);
1141 index[4] = 0;
1142 index[5] = 0;
1143 index[6] = entityIndex;
1144 oid_copy_in_addr(&index[7], &peerLdpId);
1145 index[11] = 0;
1146 index[12] = 0;
f9a4d683 1147
9e263221 1148 index[LDP_PEER_ENTRY_MAX_IDX_LEN] = 0;
f9a4d683
KS
1149
1150 smux_trap(ldpe_variables, array_size(ldpe_variables), ldp_trap_oid,
1151 array_size(ldp_trap_oid), ldp_oid,
1152 sizeof(ldp_oid) / sizeof(oid), index,
1153 LDP_PEER_ENTRY_MAX_IDX_LEN + 1,
1154 ldpSessionTrapList, array_size(ldpSessionTrapList), sptrap);
1155}
1156
1157static void
1158ldpTrapSessionUp(struct nbr * nbr)
1159{
1160 ldpTrapSession(nbr, LDPSESSIONUP);
1161}
1162
1163static void
1164ldpTrapSessionDown(struct nbr * nbr)
1165{
1166 ldpTrapSession(nbr, LDPSESSIONDOWN);
1167}
1168
1169static int ldp_snmp_agentx_enabled()
1170{
1171 main_imsg_compose_both(IMSG_AGENTX_ENABLED, NULL, 0);
1172
1173 return 0;
1174}
1175
1176static int ldp_snmp_nbr_state_change(struct nbr * nbr, int old_state)
1177{
1178 if (old_state == nbr->state)
1179 return 0;
1180
1181 if (nbr->state == NBR_STA_OPER)
1182 ldpTrapSessionUp(nbr);
1183 else if (old_state == NBR_STA_OPER)
1184 ldpTrapSessionDown(nbr);
1185
1186 return 0;
1187}
1188
1189static int ldp_snmp_init(struct thread_master *tm)
1190{
1191 hook_register(agentx_enabled, ldp_snmp_agentx_enabled);
1192
1193 smux_init(tm);
1194
1195 return 0;
1196}
1197
1198static int ldp_snmp_register_mib(struct thread_master *tm)
1199{
1200 static int registered = 0;
1201
1202 if (registered)
1203 return 0;
1204
1205 registered = 1;
1206
1207 smux_init(tm);
1208
1209 smux_agentx_enable();
1210
1211 if (ldpd_process == PROC_LDE_ENGINE)
1212 REGISTER_MIB("mibII/ldp", lde_variables, variable, ldp_oid);
1213 else if (ldpd_process == PROC_LDP_ENGINE) {
1214 REGISTER_MIB("mibII/ldp", ldpe_variables, variable, ldp_oid);
1215
1216 hook_register(ldp_nbr_state_change, ldp_snmp_nbr_state_change);
1217 }
1218
1219 return 0;
1220}
1221
1222static int ldp_snmp_module_init(void)
1223{
1224 if (ldpd_process == PROC_MAIN)
1225 hook_register(frr_late_init, ldp_snmp_init);
1226 else
1227 hook_register(ldp_register_mib, ldp_snmp_register_mib);
1228
1229 return 0;
1230}
1231
80413c20
DL
1232FRR_MODULE_SETUP(
1233 .name = "ldp_snmp",
1234 .version = FRR_VERSION,
1235 .description = "ldp AgentX SNMP module",
1236 .init = ldp_snmp_module_init,
1237);