]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/ldp_snmp.c
Merge pull request #8273 from volta-networks/fix_ospf6_coverity
[mirror_frr.git] / ldpd / ldp_snmp.c
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"
39 #include "version.h"
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. */
65 SNMP_LOCAL_VARIABLES
66
67 /* LDP-MIB instances. */
68 static oid ldp_oid[] = {MPLS_LDP_STD_MIB};
69 static oid ldp_trap_oid[] = {MPLS_LDP_STD_MIB, 0};
70
71 static 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
187 static 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
199 static 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
210 extern uint32_t ldp_start_time;
211 static 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
225 static 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
239 static 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
278 static 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;
304 oid_copy_addr(name + v->namelen, &entityLdpId,
305 IN_ADDR_SIZE);
306 name[v->namelen + 4] = 0;
307 name[v->namelen + 5] = 0;
308 name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
309 }
310
311 /* Return the current value of the variable */
312 switch (v->magic) {
313 case MPLSLDPENTITYLDPID:
314 *var_len = 6;
315 memcpy (snmp_ldp_rtrid, &entityLdpId, IN_ADDR_SIZE);
316 return (uint8_t *)snmp_ldp_rtrid;
317 case MPLSLDPENTITYINDEX:
318 return SNMP_INTEGER(LDP_DEFAULT_ENTITY_INDEX);
319 case MPLSLDPENTITYPROTOCOLVERSION:
320 return SNMP_INTEGER(LDP_VERSION);
321 case MPLSLDPENTITYADMINSTATUS:
322 return SNMP_INTEGER(ADMINSTATUSENABLED);
323 case MPLSLDPENTITYOPERSTATUS:
324 return SNMP_INTEGER(OPERSTATUSENABLED);
325 case MPLSLDPENTITYTCPPORT:
326 return SNMP_INTEGER(LDP_PORT);
327 case MPLSLDPENTITYUDPDSCPORT:
328 return SNMP_INTEGER(LDP_PORT);
329 case MPLSLDPENTITYMAXPDULENGTH:
330 return SNMP_INTEGER(LDP_MAX_LEN);
331 case MPLSLDPENTITYKEEPALIVEHOLDTIMER:
332 return SNMP_INTEGER(af->keepalive);
333 case MPLSLDPENTITYHELLOHOLDTIMER:
334 return SNMP_INTEGER(af->lhello_holdtime);
335 case MPLSLDPENTITYINITSESSIONTHRESHOLD:
336 return SNMP_INTEGER(0); /* not supported */
337 case MPLSLDPENTITYLABELDISTMETHOD:
338 return SNMP_INTEGER(DOWNSTREAMUNSOLICITED);
339 case MPLSLDPENTITYLABELRETENTIONMODE:
340 return SNMP_INTEGER(LIBERALRETENTION);
341 case MPLSLDPENTITYPATHVECTORLIMIT:
342 return SNMP_INTEGER(0); /* not supported */
343 case MPLSLDPENTITYHOPCOUNTLIMIT:
344 return SNMP_INTEGER(0);
345 case MPLSLDPENTITYTRANSPORTADDRKIND:
346 return SNMP_INTEGER(TRANSPORTADDRLOOPBACK);
347 case MPLSLDPENTITYTARGETPEER:
348 return SNMP_INTEGER(1);
349 case MPLSLDPENTITYTARGETPEERADDRTYPE:
350 if (index == 1)
351 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV4);
352 else
353 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV6);
354 case MPLSLDPENTITYTARGETPEERADDR:
355 if (index == 1) {
356 *var_len = sizeof(af->trans_addr.v4);
357 return ((uint8_t *)&af->trans_addr.v4);
358 }else {
359 *var_len = sizeof(af->trans_addr.v6);
360 return ((uint8_t *)&af->trans_addr.v6);
361 }
362 case MPLSLDPENTITYLABELTYPE:
363 return SNMP_INTEGER(LABELTYPEGENERIC);
364 case MPLSLDPENTITYDISCONTINUITYTIME:
365 return SNMP_INTEGER(0);
366 case MPLSLDPENTITYSTORAGETYPE:
367 return SNMP_INTEGER(STORAGETYPENONVOLATILE);
368 case MPLSLDPENTITYROWSTATUS:
369 return SNMP_INTEGER(ROWSTATUSACTIVE);
370 default:
371 return NULL;
372 }
373
374 return NULL;
375 }
376
377 static uint8_t *ldpEntityStatsTable(struct variable *v, oid name[],
378 size_t *length, int exact, size_t *var_len,
379 WriteMethod **write_method)
380 {
381 struct in_addr entityLdpId = {.s_addr = 0};
382 int len;
383
384 *write_method = NULL;
385
386 if (smux_header_table(v, name, length, exact, var_len, write_method)
387 == MATCH_FAILED)
388 return NULL;
389
390 if (exact) {
391 if (*length != LDP_ENTITY_TOTAL_LEN)
392 return NULL;
393 } else {
394 len = *length - v->namelen - LDP_ENTITY_MAX_IDX_LEN;
395 if (len > 0)
396 return NULL;
397
398 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
399
400 /* Copy the name out */
401 memcpy(name, v->name, v->namelen * sizeof(oid));
402
403 /* Append index */
404 *length = LDP_ENTITY_TOTAL_LEN;
405 oid_copy_addr(name + v->namelen, &entityLdpId,
406 IN_ADDR_SIZE);
407 name[v->namelen + 4] = 0;
408 name[v->namelen + 5] = 0;
409 name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
410 }
411
412 /* Return the current value of the variable */
413 switch (v->magic) {
414 case MPLSLDPENTITYSTATSSESSIONATTEMPTS:
415 return SNMP_INTEGER(leconf->stats.session_attempts);
416 case MPLSLDPENTITYSTATSSESSIONREJHELLO:
417 return SNMP_INTEGER(leconf->stats.session_rejects_hello);
418 case MPLSLDPENTITYSTATSSESSIONREJAD:
419 return SNMP_INTEGER(leconf->stats.session_rejects_ad);
420 case MPLSLDPENTITYSTATSSESSIONREJMAXPDU:
421 return SNMP_INTEGER(leconf->stats.session_rejects_max_pdu);
422 case MPLSLDPENTITYSTATSSESSIONREJLR:
423 return SNMP_INTEGER(leconf->stats.session_rejects_lr);
424 case MPLSLDPENTITYSTATSBADLDPID:
425 return SNMP_INTEGER(leconf->stats.bad_ldp_id);
426 case MPLSLDPENTITYSTATSBADPDULENGTH:
427 return SNMP_INTEGER(leconf->stats.bad_pdu_len);
428 case MPLSLDPENTITYSTATSBADMSGLENGTH:
429 return SNMP_INTEGER(leconf->stats.bad_msg_len);
430 case MPLSLDPENTITYSTATSBADTLVLENGTH:
431 return SNMP_INTEGER(leconf->stats.bad_tlv_len);
432 case MPLSLDPENTITYSTATSMALFORMEDTLV:
433 return SNMP_INTEGER(leconf->stats.malformed_tlv);
434 case MPLSLDPENTITYSTATSKEEPALIVEEXP:
435 return SNMP_INTEGER(leconf->stats.keepalive_timer_exp);
436 case MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY:
437 return SNMP_INTEGER(leconf->stats.shutdown_rcv_notify);
438 case MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY:
439 return SNMP_INTEGER(leconf->stats.shutdown_send_notify);
440 default:
441 return NULL;
442 }
443
444 return NULL;
445 }
446
447 #define LDP_ADJACENCY_ENTRY_MAX_IDX_LEN 14
448
449 static void ldpHelloAdjacencyTable_oid_to_index(
450 struct variable *v, oid name[],
451 size_t *length,
452 struct in_addr *entityLdpId,
453 uint32_t *entityIndex,
454 struct in_addr *peerLdpId,
455 uint32_t *adjacencyIndex)
456 {
457 oid *offset = name + v->namelen;
458 int offsetlen = *length - v->namelen;
459 int len = offsetlen;
460
461 if (len > LDP_ADJACENCY_ENTRY_MAX_IDX_LEN)
462 len = LDP_ADJACENCY_ENTRY_MAX_IDX_LEN;
463
464 if (len >= LDP_LSRID_IDX_LEN)
465 oid2in_addr(offset, sizeof(struct in_addr), entityLdpId);
466
467 offset += LDP_LSRID_IDX_LEN;
468 offsetlen -= LDP_LSRID_IDX_LEN;
469 len = offsetlen;
470
471 if (len > LDP_ENTITY_IDX_LEN)
472 len = LDP_ENTITY_IDX_LEN;
473
474 if (len >= LDP_ENTITY_IDX_LEN)
475 *entityIndex = offset[0];
476
477 offset += LDP_ENTITY_IDX_LEN;
478 offsetlen -= LDP_ENTITY_IDX_LEN;
479 len = offsetlen;
480
481 if (len > LDP_LSRID_IDX_LEN)
482 len = LDP_LSRID_IDX_LEN;
483
484 if (len >= LDP_LSRID_IDX_LEN)
485 oid2in_addr(offset, sizeof(struct in_addr), peerLdpId);
486
487 offset += LDP_LSRID_IDX_LEN;
488 offsetlen -= LDP_LSRID_IDX_LEN;
489 len = offsetlen;
490
491 if (len > LDP_ADJACENCY_IDX_LEN)
492 len = LDP_ADJACENCY_IDX_LEN;
493
494 if (len >= LDP_ADJACENCY_IDX_LEN)
495 *adjacencyIndex = offset[0];
496 }
497
498 static struct adj *
499 nbr_get_adj_by_index(struct nbr *nbr, uint32_t adjacencyIndex)
500 {
501 struct adj *adj;
502 uint32_t i = 0;
503
504 RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
505 if (++i == adjacencyIndex)
506 return adj;
507
508 return NULL;
509 }
510
511 static struct ctl_adj *
512 ldpHelloAdjacencyTable_lookup_helper(
513 struct in_addr *entityLdpId,
514 uint32_t *entityIndex,
515 struct in_addr *peerLdpId,
516 uint32_t *adjacencyIndex)
517 {
518 struct ctl_adj *ctl_adj = NULL;
519 struct adj *adj = NULL;
520 struct nbr *cur_nbr = nbr_find_ldpid(peerLdpId->s_addr);
521
522 if (cur_nbr)
523 /* If found nbr, then look to see if the
524 * adjacency exists
525 */
526 adj = nbr_get_adj_by_index(cur_nbr, *adjacencyIndex);
527
528 if (adj)
529 ctl_adj = adj_to_ctl(adj);
530
531 return ctl_adj;
532 }
533
534 static struct ctl_adj *
535 ldpHelloAdjacencyTable_next_helper(
536 int first,
537 struct in_addr *entityLdpId,
538 uint32_t *entityIndex,
539 struct in_addr *peerLdpId,
540 uint32_t *adjacencyIndex)
541 {
542 struct ctl_adj *ctl_adj = NULL;
543 struct nbr *nbr = NULL;
544 struct adj *adj = NULL;
545
546 if (first)
547 nbr = nbr_get_first_ldpid();
548 else {
549 struct nbr *cur_nbr = nbr_find_ldpid(peerLdpId->s_addr);
550 if (cur_nbr)
551 /* If found nbr, then look to see if the
552 * adjacency exists
553 */
554 adj = nbr_get_adj_by_index(cur_nbr, *adjacencyIndex + 1);
555 if (adj)
556 *adjacencyIndex += 1;
557 else
558 nbr = nbr_get_next_ldpid(peerLdpId->s_addr);
559 }
560
561 if (!adj && nbr) {
562 adj = RB_MIN(nbr_adj_head, &nbr->adj_tree);
563 *adjacencyIndex = 1;
564 }
565
566 if (adj)
567 ctl_adj = adj_to_ctl(adj);
568
569 return ctl_adj;
570 }
571
572 #define HELLO_ADJ_MAX_IDX_LEN 14
573
574 static struct ctl_adj *
575 ldpHelloAdjacencyTable_lookup(struct variable *v, oid name[],
576 size_t *length, int exact,
577 struct in_addr *entityLdpId,
578 uint32_t *entityIndex,
579 struct in_addr *peerLdpId,
580 uint32_t *adjacencyIndex)
581 {
582 struct ctl_adj *hello_adj = NULL;
583
584 if (exact) {
585 if (*length < HELLO_ADJ_MAX_IDX_LEN)
586 return NULL;
587
588 ldpHelloAdjacencyTable_oid_to_index(
589 v, name, length,
590 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
591
592 hello_adj = ldpHelloAdjacencyTable_lookup_helper(
593 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
594 } else {
595 int first = 0;
596 int offsetlen = *length - v->namelen;
597
598 if (offsetlen < HELLO_ADJ_MAX_IDX_LEN)
599 first = 1;
600
601 ldpHelloAdjacencyTable_oid_to_index(
602 v, name, length,
603 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
604
605 hello_adj = ldpHelloAdjacencyTable_next_helper(first,
606 entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
607
608 }
609 return hello_adj;
610 }
611
612 static uint8_t *ldpHelloAdjacencyTable(struct variable *v, oid name[], size_t *length,
613 int exact, size_t *var_len,
614 WriteMethod **write_method)
615 {
616 struct in_addr entityLdpId = {.s_addr = 0};
617 uint32_t entityIndex = 0;
618 struct in_addr peerLdpId = {.s_addr = 0};
619 uint32_t adjacencyIndex = 0;
620
621 if (smux_header_table(v, name, length, exact, var_len, write_method)
622 == MATCH_FAILED)
623 return NULL;
624
625 struct ctl_adj *ctl_adj = ldpHelloAdjacencyTable_lookup(v, name,
626 length, exact,
627 &entityLdpId, &entityIndex, &peerLdpId, &adjacencyIndex);
628
629 if (!ctl_adj)
630 return NULL;
631
632 if (!exact) {
633
634 /* Copy the name out */
635 memcpy(name, v->name, v->namelen * sizeof(oid));
636
637 /* Append index */
638 struct in_addr entityLdpId = {.s_addr = 0};
639 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
640
641 struct in_addr peerLdpId = ctl_adj->id;
642
643 oid_copy_addr(name + v->namelen, &entityLdpId,
644 sizeof(struct in_addr));
645 name[v->namelen + 4] = 0;
646 name[v->namelen + 5] = 0;
647 name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
648 oid_copy_addr(name + v->namelen + 7, &peerLdpId,
649 sizeof(struct in_addr));
650 name[v->namelen + 11] = 0;
651 name[v->namelen + 12] = 0;
652 name[v->namelen + 13] = adjacencyIndex;
653
654 /* Set length */
655 *length = v->namelen + HELLO_ADJ_MAX_IDX_LEN;
656 }
657
658 switch (v->magic) {
659 case MPLSLDPHELLOADJACENCYINDEX:
660 return SNMP_INTEGER(adjacencyIndex);
661 case MPLSLDPHELLOADJACENCYHOLDTIMEREM:
662 return SNMP_INTEGER(ctl_adj->holdtime_remaining);
663 case MPLSLDPHELLOADJACENCYHOLDTIME:
664 return SNMP_INTEGER(ctl_adj->holdtime);
665 case MPLSLDPHELLOADJACENCYTYPE:
666 if (ctl_adj->type == HELLO_LINK)
667 return SNMP_INTEGER(MPLSLDPHELLOADJACENCYTYPE_LINK);
668 return SNMP_INTEGER(MPLSLDPHELLOADJACENCYTYPE_TARGETED);
669 default:
670 return NULL;
671 }
672
673 return NULL;
674 }
675
676 #define LDP_LSRID_IDX_LEN 6
677 #define LDP_ENTITY_IDX_LEN 1
678 #define LDP_PEER_ENTRY_MAX_IDX_LEN 13
679
680 static void ldpPeerTable_oid_to_index(
681 struct variable *v, oid name[],
682 size_t *length,
683 struct in_addr *entityLdpId,
684 uint32_t *entityIndex,
685 struct in_addr *peerLdpId)
686 {
687 oid *offset = name + v->namelen;
688 int offsetlen = *length - v->namelen;
689 int len = offsetlen;
690
691 if (len > LDP_PEER_ENTRY_MAX_IDX_LEN)
692 len = LDP_PEER_ENTRY_MAX_IDX_LEN;
693
694 if (len >= LDP_LSRID_IDX_LEN)
695 oid2in_addr(offset, sizeof(struct in_addr), entityLdpId);
696
697 offset += LDP_LSRID_IDX_LEN;
698 offsetlen -= LDP_LSRID_IDX_LEN;
699 len = offsetlen;
700
701 if (len > LDP_ENTITY_IDX_LEN)
702 len = LDP_ENTITY_IDX_LEN;
703
704 if (len >= LDP_ENTITY_IDX_LEN)
705 *entityIndex = offset[0];
706
707 offset += LDP_ENTITY_IDX_LEN;
708 offsetlen -= LDP_ENTITY_IDX_LEN;
709 len = offsetlen;
710
711 if (len > LDP_LSRID_IDX_LEN)
712 len = LDP_LSRID_IDX_LEN;
713
714 if (len >= LDP_LSRID_IDX_LEN)
715 oid2in_addr(offset, sizeof(struct in_addr), peerLdpId);
716 }
717
718 static struct ctl_nbr *
719 ldpPeerTable_lookup_next(int first,
720 struct in_addr peerLdpId)
721 {
722 struct nbr *nbr = NULL;
723 struct ctl_nbr *ctl_nbr = NULL;;
724
725 if (first)
726 nbr = nbr_get_first_ldpid();
727 else
728 nbr = nbr_get_next_ldpid(peerLdpId.s_addr);
729
730 if (nbr)
731 ctl_nbr = nbr_to_ctl(nbr);
732
733 return ctl_nbr;
734 }
735
736 static struct ctl_nbr *
737 ldpPeerTable_lookup(struct variable *v, oid name[],
738 size_t *length, int exact,
739 struct in_addr *entityLdpId,
740 uint32_t *entityIndex,
741 struct in_addr *peerLdpId)
742 {
743 struct ctl_nbr *ctl_nbr = NULL;
744 struct nbr *nbr = NULL;
745 int first = 0;
746
747 if (exact) {
748 if (*length < (long unsigned int)v->namelen
749 + LDP_PEER_ENTRY_MAX_IDX_LEN)
750 return NULL;
751
752 ldpPeerTable_oid_to_index(
753 v, name, length,
754 entityLdpId, entityIndex, peerLdpId);
755
756 nbr = nbr_find_ldpid(peerLdpId->s_addr);
757 if (nbr)
758 ctl_nbr = nbr_to_ctl(nbr);
759
760 return ctl_nbr;
761 } else {
762
763 int offsetlen = *length - v->namelen;
764 if (offsetlen < LDP_LSRID_IDX_LEN)
765 first = 1;
766
767 ldpPeerTable_oid_to_index(
768 v, name, length,
769 entityLdpId, entityIndex, peerLdpId);
770
771 ctl_nbr = ldpPeerTable_lookup_next(first, *peerLdpId);
772 return ctl_nbr;
773 }
774 return NULL;
775 }
776
777 static uint8_t *ldpPeerTable(struct variable *v, oid name[], size_t *length,
778 int exact, size_t *var_len,
779 WriteMethod **write_method)
780 {
781 struct in_addr entityLdpId = {.s_addr = 0};
782 uint32_t entityIndex = 0;
783 struct in_addr peerLdpId = {.s_addr = 0};
784 struct ctl_nbr *ctl_nbr;
785
786
787 if (smux_header_table(v, name, length, exact, var_len, write_method)
788 == MATCH_FAILED)
789 return NULL;
790
791 ctl_nbr = ldpPeerTable_lookup(v, name, length, exact, &entityLdpId,
792 &entityIndex, &peerLdpId);
793
794 if (!ctl_nbr)
795 return NULL;
796
797 if (!exact) {
798
799 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
800 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
801 peerLdpId = ctl_nbr->id;
802
803 /* Copy the name out */
804 memcpy(name, v->name, v->namelen * sizeof(oid));
805
806 /* Append index */
807 oid_copy_addr(name + v->namelen, &entityLdpId,
808 sizeof(struct in_addr));
809
810 name[v->namelen + 4] = 0;
811 name[v->namelen + 5] = 0;
812 name[v->namelen + 6] = entityIndex;
813 oid_copy_addr(name + v->namelen + 7, &peerLdpId,
814 sizeof(struct in_addr));
815 name[v->namelen + 11] = 0;
816 name[v->namelen + 12] = 0;
817
818 /* Set length */
819 *length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
820 }
821
822 switch (v->magic) {
823 case MPLSLDPPEERLDPID:
824 *var_len = 6;
825 memcpy(snmp_ldp_rtrid, &ctl_nbr->id, IN_ADDR_SIZE);
826 return snmp_ldp_rtrid;
827 case MPLSLDPPEERLABELDISTMETHOD:
828 return SNMP_INTEGER(DOWNSTREAMUNSOLICITED);
829 case MPLSLDPPEERPATHVECTORLIMIT:
830 return SNMP_INTEGER(0);
831 case MPLSLDPPEERTRANSPORTADDRTYPE:
832 if (ctl_nbr->af == AF_INET)
833 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV4);
834 else
835 return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV6);
836 case MPLSLDPPEERTRANSPORTADDR:
837 if (ctl_nbr->af == AF_INET) {
838 *var_len = sizeof(ctl_nbr->raddr.v4);
839 return ((uint8_t *)&ctl_nbr->raddr.v4);
840 } else {
841 *var_len = sizeof(ctl_nbr->raddr.v6);
842 return ((uint8_t *)&ctl_nbr->raddr.v6);
843 }
844 default:
845 return NULL;
846 }
847
848 return NULL;
849 }
850 static uint8_t *ldpSessionTable(struct variable *v, oid name[], size_t *length,
851 int exact, size_t *var_len,
852 WriteMethod **write_method)
853 {
854 struct in_addr entityLdpId = {.s_addr = 0};
855 uint32_t entityIndex = 0;
856 struct in_addr peerLdpId = {.s_addr = 0};
857 struct ctl_nbr *ctl_nbr;
858
859 if (smux_header_table(v, name, length, exact, var_len, write_method)
860 == MATCH_FAILED)
861 return NULL;
862
863 ctl_nbr = ldpPeerTable_lookup(v, name, length, exact, &entityLdpId,
864 &entityIndex, &peerLdpId);
865
866 if (!ctl_nbr)
867 return NULL;
868
869 if (!exact) {
870 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
871 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
872 peerLdpId = ctl_nbr->id;
873
874 /* Copy the name out */
875 memcpy(name, v->name, v->namelen * sizeof(oid));
876
877 /* Append index */
878 oid_copy_addr(name + v->namelen, &entityLdpId,
879 sizeof(struct in_addr));
880
881 name[v->namelen + 4] = 0;
882 name[v->namelen + 5] = 0;
883 name[v->namelen + 6] = entityIndex;
884 oid_copy_addr(name + v->namelen + 7, &peerLdpId,
885 sizeof(struct in_addr));
886 name[v->namelen + 11] = 0;
887 name[v->namelen + 12] = 0;
888
889 /* Set length */
890 *length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
891 }
892
893 switch (v->magic) {
894 case MPLSLDPSESSIONSTATELASTCHANGE:
895 *var_len = sizeof(time_t);
896 return (uint8_t *) &(ctl_nbr->uptime);
897 case MPLSLDPSESSIONSTATE:
898 switch (ctl_nbr->nbr_state) {
899 case NBR_STA_INITIAL:
900 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_INITIALIZED);
901 case NBR_STA_OPENREC:
902 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPENREC);
903 case NBR_STA_OPENSENT:
904 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPENSENT);
905 case NBR_STA_OPER:
906 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPERATIONAL);
907 default:
908 return SNMP_INTEGER(MPLSLDPSESSIONSTATE_NONEXISTENT);
909 }
910 case MPLSLDPSESSIONROLE:
911 if (ldp_addrcmp(ctl_nbr->af, &ctl_nbr->laddr, &ctl_nbr->raddr)
912 > 0)
913 return SNMP_INTEGER(MPLSLDPSESSIONROLE_ACTIVE);
914 else
915 return SNMP_INTEGER(MPLSLDPSESSIONROLE_PASSIVE);
916 case MPLSLDPSESSIONPROTOCOLVERSION:
917 return SNMP_INTEGER(LDP_VERSION);
918 case MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM:
919 return SNMP_INTEGER(ctl_nbr->hold_time_remaining);
920 case MPLSLDPSESSIONKEEPALIVETIME:
921 return SNMP_INTEGER(ctl_nbr->holdtime);
922 case MPLSLDPSESSIONMAXPDULENGTH:
923 if (ctl_nbr->nbr_state == NBR_STA_OPER)
924 return SNMP_INTEGER(ctl_nbr->max_pdu_len);
925 else
926 return SNMP_INTEGER(LDP_MAX_LEN);
927 case MPLSLDPSESSIONDISCONTINUITYTIME:
928 return SNMP_INTEGER(0); /* not supported */
929 default:
930 return NULL;
931 }
932
933 return NULL;
934 }
935
936 static uint8_t *ldpSessionStatsTable(struct variable *v, oid name[],
937 size_t *length,
938 int exact, size_t *var_len,
939 WriteMethod **write_method)
940 {
941 struct in_addr entityLdpId = {.s_addr = 0};
942 uint32_t entityIndex = 0;
943 struct in_addr peerLdpId = {.s_addr = 0};
944
945 if (smux_header_table(v, name, length, exact, var_len, write_method)
946 == MATCH_FAILED)
947 return NULL;
948
949 struct ctl_nbr *ctl_nbr = ldpPeerTable_lookup(v, name, length, exact,
950 &entityLdpId, &entityIndex, &peerLdpId);
951
952 if (!ctl_nbr)
953 return NULL;
954
955 if (!exact) {
956 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
957 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
958 peerLdpId = ctl_nbr->id;
959
960 /* Copy the name out */
961 memcpy(name, v->name, v->namelen * sizeof(oid));
962
963 /* Append index */
964 oid_copy_addr(name + v->namelen, &entityLdpId,
965 sizeof(struct in_addr));
966 name[v->namelen + 4] = 0;
967 name[v->namelen + 5] = 0;
968 name[v->namelen + 6] = entityIndex;
969 oid_copy_addr(name + v->namelen + 7, &peerLdpId,
970 sizeof(struct in_addr));
971 name[v->namelen + 11] = 0;
972 name[v->namelen + 12] = 0;
973
974 *length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
975 }
976
977 switch (v->magic) {
978 case MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS:
979 return SNMP_INTEGER(ctl_nbr->stats.unknown_msg);
980 case MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS:
981 return SNMP_INTEGER(ctl_nbr->stats.unknown_tlv);
982 default:
983 return NULL;
984 }
985
986 return NULL;
987 }
988
989 static struct variable ldpe_variables[] = {
990 {MPLS_LDP_LSR_ID, STRING, RONLY, ldpLsrId, 3, {1, 1, 1}},
991 {MPLS_LDP_LSR_LOOP_DETECTION_CAPABLE, INTEGER, RONLY,
992 ldpLoopDetectCap, 3, {1, 1, 2}},
993 {MPLS_LDP_ENTITY_LAST_CHANGE, TIMESTAMP, RONLY, ldpEntityLastChange,
994 3, {1, 2, 1}},
995 {MPLS_LDP_ENTITY_INDEX_NEXT, UNSIGNED32, RONLY, ldpEntityIndexNext,
996 3, {1, 2, 2}},
997
998 /* MPLS LDP mplsLdpEntityTable. */
999 {MPLSLDPENTITYLDPID, STRING, RONLY, ldpEntityTable,
1000 5, {1, 2, 3, 1, 1}},
1001 {MPLSLDPENTITYINDEX, UNSIGNED32, RONLY, ldpEntityTable,
1002 5, {1, 2, 3, 1, 2}},
1003 {MPLSLDPENTITYPROTOCOLVERSION, UNSIGNED32, RONLY, ldpEntityTable,
1004 5, {1, 2, 3, 1, 3}},
1005 {MPLSLDPENTITYADMINSTATUS, INTEGER, RONLY, ldpEntityTable,
1006 5, {1, 2, 3, 1, 4}},
1007 {MPLSLDPENTITYOPERSTATUS, INTEGER, RONLY, ldpEntityTable,
1008 5, {1, 2, 3, 1, 5}},
1009 {MPLSLDPENTITYTCPPORT, UNSIGNED32, RONLY, ldpEntityTable,
1010 5, {1, 2, 3, 1, 6}},
1011 {MPLSLDPENTITYUDPDSCPORT, UNSIGNED32, RONLY, ldpEntityTable,
1012 5, {1, 2, 3, 1, 7}},
1013 {MPLSLDPENTITYMAXPDULENGTH, UNSIGNED32, RONLY, ldpEntityTable,
1014 5, {1, 2, 3, 1, 8}},
1015 {MPLSLDPENTITYKEEPALIVEHOLDTIMER, UNSIGNED32, RONLY, ldpEntityTable,
1016 5, {1, 2, 3, 1, 9}},
1017 {MPLSLDPENTITYHELLOHOLDTIMER, UNSIGNED32, RONLY, ldpEntityTable,
1018 5, {1, 2, 3, 1, 10}},
1019 {MPLSLDPENTITYINITSESSIONTHRESHOLD, INTEGER, RONLY, ldpEntityTable,
1020 5, {1, 2, 3, 1, 11}},
1021 {MPLSLDPENTITYLABELDISTMETHOD, INTEGER, RONLY, ldpEntityTable,
1022 5, {1, 2, 3, 1, 12}},
1023 {MPLSLDPENTITYLABELRETENTIONMODE, INTEGER, RONLY, ldpEntityTable,
1024 5, {1, 2, 3, 1, 13}},
1025 {MPLSLDPENTITYPATHVECTORLIMIT, INTEGER, RONLY, ldpEntityTable,
1026 5, {1, 2, 3, 1, 14}},
1027 {MPLSLDPENTITYHOPCOUNTLIMIT, INTEGER, RONLY, ldpEntityTable,
1028 5, {1, 2, 3, 1, 15}},
1029 {MPLSLDPENTITYTRANSPORTADDRKIND, INTEGER, RONLY, ldpEntityTable,
1030 5, {1, 2, 3, 1, 16}},
1031 {MPLSLDPENTITYTARGETPEER, INTEGER, RONLY, ldpEntityTable,
1032 5, {1, 2, 3, 1, 17}},
1033 {MPLSLDPENTITYTARGETPEERADDRTYPE, INTEGER, RONLY, ldpEntityTable,
1034 5, {1, 2, 3, 1, 18}},
1035 {MPLSLDPENTITYTARGETPEERADDR, STRING, RONLY, ldpEntityTable,
1036 5, {1, 2, 3, 1, 19}},
1037 {MPLSLDPENTITYLABELTYPE, INTEGER, RONLY, ldpEntityTable,
1038 5, {1, 2, 3, 1, 20}},
1039 {MPLSLDPENTITYDISCONTINUITYTIME, TIMESTAMP, RONLY, ldpEntityTable,
1040 5, {1, 2, 3, 1, 21}},
1041 {MPLSLDPENTITYSTORAGETYPE, INTEGER, RONLY, ldpEntityTable,
1042 5, {1, 2, 3, 1, 22}},
1043 {MPLSLDPENTITYROWSTATUS, INTEGER, RONLY, ldpEntityTable,
1044 5, {1, 2, 3, 1, 23}},
1045
1046 /* MPLS LDP mplsLdpEntityStatsTable. */
1047 { MPLSLDPENTITYSTATSSESSIONATTEMPTS, COUNTER32, RONLY,
1048 ldpEntityStatsTable, 5, {1, 2, 4, 1, 1}},
1049 { MPLSLDPENTITYSTATSSESSIONREJHELLO, COUNTER32, RONLY,
1050 ldpEntityStatsTable, 5, {1, 2, 4, 1, 2}},
1051 { MPLSLDPENTITYSTATSSESSIONREJAD, COUNTER32, RONLY,
1052 ldpEntityStatsTable, 5, {1, 2, 4, 1, 3}},
1053 { MPLSLDPENTITYSTATSSESSIONREJMAXPDU, COUNTER32, RONLY,
1054 ldpEntityStatsTable, 5, {1, 2, 4, 1, 4}},
1055 { MPLSLDPENTITYSTATSSESSIONREJLR, COUNTER32, RONLY,
1056 ldpEntityStatsTable, 5, {1, 2, 4, 1, 5}},
1057 { MPLSLDPENTITYSTATSBADLDPID, COUNTER32, RONLY,
1058 ldpEntityStatsTable, 5, {1, 2, 4, 1, 6}},
1059 { MPLSLDPENTITYSTATSBADPDULENGTH, COUNTER32, RONLY,
1060 ldpEntityStatsTable, 5, {1, 2, 4, 1, 7}},
1061 { MPLSLDPENTITYSTATSBADMSGLENGTH, COUNTER32, RONLY,
1062 ldpEntityStatsTable, 5, {1, 2, 4, 1, 8}},
1063 { MPLSLDPENTITYSTATSBADTLVLENGTH, COUNTER32, RONLY,
1064 ldpEntityStatsTable, 5, {1, 2, 4, 1, 9}},
1065 { MPLSLDPENTITYSTATSMALFORMEDTLV, COUNTER32, RONLY,
1066 ldpEntityStatsTable, 5, {1, 2, 4, 1, 10}},
1067 { MPLSLDPENTITYSTATSKEEPALIVEEXP, COUNTER32, RONLY,
1068 ldpEntityStatsTable, 5, {1, 2, 4, 1, 11}},
1069 { MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY, COUNTER32, RONLY,
1070 ldpEntityStatsTable, 5, {1, 2, 4, 1, 12}},
1071 { MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY, COUNTER32, RONLY,
1072 ldpEntityStatsTable, 5, {1, 2, 4, 1, 13}},
1073
1074 /* MPLS LDP mplsLdpPeerTable */
1075 {MPLSLDPPEERLDPID, STRING, RONLY, ldpPeerTable, 5, {1, 3, 2, 1, 1}},
1076 {MPLSLDPPEERLABELDISTMETHOD, INTEGER, RONLY, ldpPeerTable,
1077 5, {1, 3, 2, 1, 2}},
1078 {MPLSLDPPEERPATHVECTORLIMIT, INTEGER, RONLY, ldpPeerTable,
1079 5, {1, 3, 2, 1, 3}},
1080 {MPLSLDPPEERTRANSPORTADDRTYPE, INTEGER, RONLY, ldpPeerTable,
1081 5, {1, 3, 2, 1, 4}},
1082 {MPLSLDPPEERTRANSPORTADDR, STRING, RONLY, ldpPeerTable,
1083 5, {1, 3, 2, 1, 5}},
1084
1085 /* MPLS LDP mplsLdpSessionTable */
1086 {MPLSLDPSESSIONSTATELASTCHANGE, TIMESTAMP, RONLY, ldpSessionTable,
1087 5, {1, 3, 3, 1, 1}},
1088 {MPLSLDPSESSIONSTATE, INTEGER, RONLY, ldpSessionTable,
1089 5, {1, 3, 3, 1, 2}},
1090 {MPLSLDPSESSIONROLE, INTEGER, RONLY, ldpSessionTable,
1091 5, {1, 3, 3, 1, 3}},
1092 {MPLSLDPSESSIONPROTOCOLVERSION, UNSIGNED32, RONLY, ldpSessionTable,
1093 5, {1, 3, 3, 1, 4}},
1094 {MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM, INTEGER, RONLY, ldpSessionTable,
1095 5, {1, 3, 3, 1, 5}},
1096 {MPLSLDPSESSIONKEEPALIVETIME, UNSIGNED32, RONLY, ldpSessionTable,
1097 5, {1, 3, 3, 1, 6}},
1098 {MPLSLDPSESSIONMAXPDULENGTH, UNSIGNED32, RONLY, ldpSessionTable,
1099 5, {1, 3, 3, 1, 7}},
1100 {MPLSLDPSESSIONDISCONTINUITYTIME, TIMESTAMP, RONLY, ldpSessionTable,
1101 5, {1, 3, 3, 1, 8}},
1102
1103 /* MPLS LDP mplsLdpSessionStatsTable */
1104 {MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS, COUNTER32, RONLY,
1105 ldpSessionStatsTable, 5, {1, 3, 4, 1, 1}},
1106 {MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS, COUNTER32, RONLY,
1107 ldpSessionStatsTable, 5, {1, 3, 4, 1, 2}},
1108
1109 /* MPLS LDP mplsLdpHelloAdjacencyTable. */
1110 {MPLSLDPHELLOADJACENCYINDEX, UNSIGNED32, RONLY,
1111 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 1}},
1112 {MPLSLDPHELLOADJACENCYHOLDTIMEREM, INTEGER, RONLY,
1113 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 2}},
1114 {MPLSLDPHELLOADJACENCYHOLDTIME, UNSIGNED32, RONLY,
1115 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 3}},
1116 {MPLSLDPHELLOADJACENCYTYPE, INTEGER, RONLY,
1117 ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 4}},
1118 };
1119
1120 static struct variable lde_variables[] = {
1121 };
1122
1123 static struct trap_object ldpSessionTrapList[] = {
1124 {5, {1, 3, 3, 1, MPLSLDPSESSIONSTATE}},
1125 {5, {1, 3, 3, 1, MPLSLDPSESSIONDISCONTINUITYTIME}},
1126 {5, {1, 3, 4, 1, MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS}},
1127 {5, {1, 3, 4, 1, MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS}}};
1128
1129 /* LDP TRAP. */
1130 #define LDPINITSESSIONTHRESHOLDEXCEEDED 1
1131 #define LDPPATHVECTORLIMITMISMATCH 2
1132 #define LDPSESSIONUP 3
1133 #define LDPSESSIONDOWN 4
1134
1135 static void
1136 ldpTrapSession(struct nbr * nbr, unsigned int sptrap)
1137 {
1138 oid index[sizeof(oid) * (LDP_PEER_ENTRY_MAX_IDX_LEN + 1)];
1139
1140 struct in_addr entityLdpId = {.s_addr = 0};
1141 uint32_t entityIndex = 0;
1142 struct in_addr peerLdpId = {.s_addr = 0};
1143
1144 struct ctl_nbr *ctl_nbr = nbr_to_ctl(nbr);
1145
1146 entityLdpId.s_addr = ldp_rtr_id_get(leconf);
1147 entityIndex = LDP_DEFAULT_ENTITY_INDEX;
1148 peerLdpId = ctl_nbr->id;
1149
1150 oid_copy_addr(index, &entityLdpId, sizeof(struct in_addr));
1151 index[4] = 0;
1152 index[5] = 0;
1153 index[6] = entityIndex;
1154 oid_copy_addr(&index[7], &peerLdpId, sizeof(struct in_addr));
1155 index[11] = 0;
1156 index[12] = 0;
1157
1158 index[LDP_PEER_ENTRY_MAX_IDX_LEN] = 0;
1159
1160 smux_trap(ldpe_variables, array_size(ldpe_variables), ldp_trap_oid,
1161 array_size(ldp_trap_oid), ldp_oid,
1162 sizeof(ldp_oid) / sizeof(oid), index,
1163 LDP_PEER_ENTRY_MAX_IDX_LEN + 1,
1164 ldpSessionTrapList, array_size(ldpSessionTrapList), sptrap);
1165 }
1166
1167 static void
1168 ldpTrapSessionUp(struct nbr * nbr)
1169 {
1170 ldpTrapSession(nbr, LDPSESSIONUP);
1171 }
1172
1173 static void
1174 ldpTrapSessionDown(struct nbr * nbr)
1175 {
1176 ldpTrapSession(nbr, LDPSESSIONDOWN);
1177 }
1178
1179 static int ldp_snmp_agentx_enabled()
1180 {
1181 main_imsg_compose_both(IMSG_AGENTX_ENABLED, NULL, 0);
1182
1183 return 0;
1184 }
1185
1186 static int ldp_snmp_nbr_state_change(struct nbr * nbr, int old_state)
1187 {
1188 if (old_state == nbr->state)
1189 return 0;
1190
1191 if (nbr->state == NBR_STA_OPER)
1192 ldpTrapSessionUp(nbr);
1193 else if (old_state == NBR_STA_OPER)
1194 ldpTrapSessionDown(nbr);
1195
1196 return 0;
1197 }
1198
1199 static int ldp_snmp_init(struct thread_master *tm)
1200 {
1201 hook_register(agentx_enabled, ldp_snmp_agentx_enabled);
1202
1203 smux_init(tm);
1204
1205 return 0;
1206 }
1207
1208 static int ldp_snmp_register_mib(struct thread_master *tm)
1209 {
1210 static int registered = 0;
1211
1212 if (registered)
1213 return 0;
1214
1215 registered = 1;
1216
1217 smux_init(tm);
1218
1219 smux_agentx_enable();
1220
1221 if (ldpd_process == PROC_LDE_ENGINE)
1222 REGISTER_MIB("mibII/ldp", lde_variables, variable, ldp_oid);
1223 else if (ldpd_process == PROC_LDP_ENGINE) {
1224 REGISTER_MIB("mibII/ldp", ldpe_variables, variable, ldp_oid);
1225
1226 hook_register(ldp_nbr_state_change, ldp_snmp_nbr_state_change);
1227 }
1228
1229 return 0;
1230 }
1231
1232 static int ldp_snmp_module_init(void)
1233 {
1234 if (ldpd_process == PROC_MAIN)
1235 hook_register(frr_late_init, ldp_snmp_init);
1236 else
1237 hook_register(ldp_register_mib, ldp_snmp_register_mib);
1238
1239 return 0;
1240 }
1241
1242 FRR_MODULE_SETUP(.name = "ldp_snmp", .version = FRR_VERSION,
1243 .description = "ldp AgentX SNMP module",
1244 .init = ldp_snmp_module_init, )