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