]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/ldp_snmp.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[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 "lib/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_in_addr(name + v->namelen, &entityLdpId);
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
376 static 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;
404 oid_copy_in_addr(name + v->namelen, &entityLdpId);
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
445 #define LDP_ADJACENCY_ENTRY_MAX_IDX_LEN 14
446
447 static 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
496 static struct adj *
497 nbr_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
509 static struct ctl_adj *
510 ldpHelloAdjacencyTable_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
532 static struct ctl_adj *
533 ldpHelloAdjacencyTable_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
572 static struct ctl_adj *
573 ldpHelloAdjacencyTable_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
610 static 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
641 oid_copy_in_addr(name + v->namelen, &entityLdpId);
642 name[v->namelen + 4] = 0;
643 name[v->namelen + 5] = 0;
644 name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
645 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
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
676 static 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
714 static struct ctl_nbr *
715 ldpPeerTable_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
732 static struct ctl_nbr *
733 ldpPeerTable_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
773 static 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 */
803 oid_copy_in_addr(name + v->namelen, &entityLdpId);
804
805 name[v->namelen + 4] = 0;
806 name[v->namelen + 5] = 0;
807 name[v->namelen + 6] = entityIndex;
808 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
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 }
844 static 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 */
872 oid_copy_in_addr(name + v->namelen, &entityLdpId);
873
874 name[v->namelen + 4] = 0;
875 name[v->namelen + 5] = 0;
876 name[v->namelen + 6] = entityIndex;
877 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
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
928 static 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 */
956 oid_copy_in_addr(name + v->namelen, &entityLdpId);
957 name[v->namelen + 4] = 0;
958 name[v->namelen + 5] = 0;
959 name[v->namelen + 6] = entityIndex;
960 oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
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
979 static 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
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
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
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
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
1110 static struct variable lde_variables[] = {
1111 };
1112
1113 static 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
1125 static void
1126 ldpTrapSession(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
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;
1147
1148 index[LDP_PEER_ENTRY_MAX_IDX_LEN] = 0;
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
1157 static void
1158 ldpTrapSessionUp(struct nbr * nbr)
1159 {
1160 ldpTrapSession(nbr, LDPSESSIONUP);
1161 }
1162
1163 static void
1164 ldpTrapSessionDown(struct nbr * nbr)
1165 {
1166 ldpTrapSession(nbr, LDPSESSIONDOWN);
1167 }
1168
1169 static int ldp_snmp_agentx_enabled(void)
1170 {
1171 main_imsg_compose_both(IMSG_AGENTX_ENABLED, NULL, 0);
1172
1173 return 0;
1174 }
1175
1176 static 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
1189 static 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
1198 static 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
1222 static 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
1232 FRR_MODULE_SETUP(
1233 .name = "ldp_snmp",
1234 .version = FRR_VERSION,
1235 .description = "ldp AgentX SNMP module",
1236 .init = ldp_snmp_module_init,
1237 );