Coverage Report

Created: 2026-02-21 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/zebra/debug_nl.c
Line
Count
Source
1
// SPDX-License-Identifier: ISC
2
/*
3
 * Copyright (c) 2018 Rafael Zalamena
4
 */
5
6
#include <zebra.h>
7
8
#if defined(HAVE_NETLINK) && defined(NETLINK_DEBUG)
9
10
#include <sys/socket.h>
11
12
#include <linux/netconf.h>
13
#include <linux/netlink.h>
14
#include <linux/nexthop.h>
15
#include <linux/rtnetlink.h>
16
#include <net/if_arp.h>
17
#include <linux/fib_rules.h>
18
#include <linux/lwtunnel.h>
19
20
#include <stdio.h>
21
#include <stdint.h>
22
23
#include "zebra/rt_netlink.h"
24
#include "zebra/kernel_netlink.h"
25
#include "lib/vxlan.h"
26
27
const char *nlmsg_type2str(uint16_t type)
28
0
{
29
0
  switch (type) {
30
  /* Generic */
31
0
  case NLMSG_NOOP:
32
0
    return "NOOP";
33
0
  case NLMSG_ERROR:
34
0
    return "ERROR";
35
0
  case NLMSG_DONE:
36
0
    return "DONE";
37
0
  case NLMSG_OVERRUN:
38
0
    return "OVERRUN";
39
40
  /* RTM */
41
0
  case RTM_NEWLINK:
42
0
    return "NEWLINK";
43
0
  case RTM_DELLINK:
44
0
    return "DELLINK";
45
0
  case RTM_GETLINK:
46
0
    return "GETLINK";
47
0
  case RTM_SETLINK:
48
0
    return "SETLINK";
49
50
0
  case RTM_NEWADDR:
51
0
    return "NEWADDR";
52
0
  case RTM_DELADDR:
53
0
    return "DELADDR";
54
0
  case RTM_GETADDR:
55
0
    return "GETADDR";
56
57
0
  case RTM_NEWROUTE:
58
0
    return "NEWROUTE";
59
0
  case RTM_DELROUTE:
60
0
    return "DELROUTE";
61
0
  case RTM_GETROUTE:
62
0
    return "GETROUTE";
63
64
0
  case RTM_NEWNEIGH:
65
0
    return "NEWNEIGH";
66
0
  case RTM_DELNEIGH:
67
0
    return "DELNEIGH";
68
0
  case RTM_GETNEIGH:
69
0
    return "GETNEIGH";
70
71
0
  case RTM_NEWRULE:
72
0
    return "NEWRULE";
73
0
  case RTM_DELRULE:
74
0
    return "DELRULE";
75
0
  case RTM_GETRULE:
76
0
    return "GETRULE";
77
78
0
  case RTM_NEWNEXTHOP:
79
0
    return "NEWNEXTHOP";
80
0
  case RTM_DELNEXTHOP:
81
0
    return "DELNEXTHOP";
82
0
  case RTM_GETNEXTHOP:
83
0
    return "GETNEXTHOP";
84
85
0
  case RTM_NEWTUNNEL:
86
0
    return "NEWTUNNEL";
87
0
  case RTM_DELTUNNEL:
88
0
    return "DELTUNNEL";
89
0
  case RTM_GETTUNNEL:
90
0
    return "GETTUNNEL";
91
92
0
  case RTM_NEWNETCONF:
93
0
    return "RTM_NEWNETCONF";
94
0
  case RTM_DELNETCONF:
95
0
    return "RTM_DELNETCONF";
96
97
0
  default:
98
0
    return "UNKNOWN";
99
0
  }
100
0
}
101
102
const char *af_type2str(int type)
103
0
{
104
0
  switch (type) {
105
0
  case AF_UNSPEC:
106
0
    return "AF_UNSPEC";
107
0
  case AF_UNIX:
108
0
    return "AF_UNIX";
109
0
  case AF_INET:
110
0
    return "AF_INET";
111
0
  case AF_INET6:
112
0
    return "AF_INET6";
113
0
  case AF_BRIDGE:
114
0
    return "AF_BRIDGE";
115
0
  case AF_NETLINK:
116
0
    return "AF_NETLINK";
117
0
#ifdef AF_MPLS
118
0
  case AF_MPLS:
119
0
    return "AF_MPLS";
120
0
#endif /* AF_MPLS */
121
0
  case AF_BLUETOOTH:
122
0
    return "AF_BLUETOOTH";
123
0
  case AF_VSOCK:
124
0
    return "AF_VSOCK";
125
0
  case AF_KEY:
126
0
    return "AF_KEY";
127
0
  case AF_PACKET:
128
0
    return "AF_PACKET";
129
0
  default:
130
0
    return "UNKNOWN";
131
0
  }
132
0
}
133
134
const char *ifi_type2str(int type)
135
0
{
136
0
  switch (type) {
137
0
  case ARPHRD_ETHER:
138
0
    return "ETHER";
139
0
  case ARPHRD_EETHER:
140
0
    return "EETHER";
141
0
  case ARPHRD_NETROM:
142
0
    return "NETROM";
143
0
  case ARPHRD_AX25:
144
0
    return "AX25";
145
0
  case ARPHRD_PRONET:
146
0
    return "PRONET";
147
0
  case ARPHRD_CHAOS:
148
0
    return "CHAOS";
149
0
  case ARPHRD_IEEE802:
150
0
    return "IEEE802";
151
0
  case ARPHRD_ARCNET:
152
0
    return "ARCNET";
153
0
  case ARPHRD_APPLETLK:
154
0
    return "APPLETLK";
155
0
  case ARPHRD_DLCI:
156
0
    return "DLCI";
157
0
  case ARPHRD_ATM:
158
0
    return "ATM";
159
0
  case ARPHRD_METRICOM:
160
0
    return "METRICOM";
161
0
  case ARPHRD_IEEE1394:
162
0
    return "IEEE1394";
163
0
  case ARPHRD_EUI64:
164
0
    return "EUI64";
165
0
  case ARPHRD_INFINIBAND:
166
0
    return "INFINIBAND";
167
0
  case ARPHRD_SLIP:
168
0
    return "SLIP";
169
0
  case ARPHRD_CSLIP:
170
0
    return "CSLIP";
171
0
  case ARPHRD_SLIP6:
172
0
    return "SLIP6";
173
0
  case ARPHRD_CSLIP6:
174
0
    return "CSLIP6";
175
0
  case ARPHRD_RSRVD:
176
0
    return "RSRVD";
177
0
  case ARPHRD_ADAPT:
178
0
    return "ADAPT";
179
0
  case ARPHRD_ROSE:
180
0
    return "ROSE";
181
0
  case ARPHRD_X25:
182
0
    return "X25";
183
0
  case ARPHRD_PPP:
184
0
    return "PPP";
185
0
  case ARPHRD_HDLC:
186
0
    return "HDLC";
187
0
  case ARPHRD_LAPB:
188
0
    return "LAPB";
189
0
  case ARPHRD_DDCMP:
190
0
    return "DDCMP";
191
0
  case ARPHRD_RAWHDLC:
192
0
    return "RAWHDLC";
193
0
  case ARPHRD_TUNNEL:
194
0
    return "TUNNEL";
195
0
  case ARPHRD_TUNNEL6:
196
0
    return "TUNNEL6";
197
0
  case ARPHRD_FRAD:
198
0
    return "FRAD";
199
0
  case ARPHRD_SKIP:
200
0
    return "SKIP";
201
0
  case ARPHRD_LOOPBACK:
202
0
    return "LOOPBACK";
203
0
  case ARPHRD_LOCALTLK:
204
0
    return "LOCALTLK";
205
0
  case ARPHRD_FDDI:
206
0
    return "FDDI";
207
0
  case ARPHRD_BIF:
208
0
    return "BIF";
209
0
  case ARPHRD_SIT:
210
0
    return "SIT";
211
0
  case ARPHRD_IPDDP:
212
0
    return "IPDDP";
213
0
  case ARPHRD_IPGRE:
214
0
    return "IPGRE";
215
0
  case ARPHRD_PIMREG:
216
0
    return "PIMREG";
217
0
  case ARPHRD_HIPPI:
218
0
    return "HIPPI";
219
0
  case ARPHRD_ASH:
220
0
    return "ASH";
221
0
  case ARPHRD_ECONET:
222
0
    return "ECONET";
223
0
  case ARPHRD_IRDA:
224
0
    return "IRDA";
225
0
  case ARPHRD_FCPP:
226
0
    return "FCPP";
227
0
  case ARPHRD_FCAL:
228
0
    return "FCAL";
229
0
  case ARPHRD_FCPL:
230
0
    return "FCPL";
231
0
  case ARPHRD_FCFABRIC:
232
0
    return "FCFABRIC";
233
0
  case ARPHRD_IEEE802_TR:
234
0
    return "IEEE802_TR";
235
0
  case ARPHRD_IEEE80211:
236
0
    return "IEEE80211";
237
0
  case ARPHRD_IEEE80211_PRISM:
238
0
    return "IEEE80211_PRISM";
239
0
  case ARPHRD_IEEE80211_RADIOTAP:
240
0
    return "IEEE80211_RADIOTAP";
241
0
  case ARPHRD_IEEE802154:
242
0
    return "IEEE802154";
243
#ifdef ARPHRD_VSOCKMON
244
  case ARPHRD_VSOCKMON:
245
    return "VSOCKMON";
246
#endif /* ARPHRD_VSOCKMON */
247
0
  case ARPHRD_VOID:
248
0
    return "VOID";
249
0
  case ARPHRD_NONE:
250
0
    return "NONE";
251
0
  default:
252
0
    return "UNKNOWN";
253
0
  }
254
0
}
255
256
const char *ifla_pdr_type2str(int type)
257
0
{
258
0
  switch (type) {
259
0
  case IFLA_PROTO_DOWN_REASON_UNSPEC:
260
0
    return "UNSPEC";
261
0
  case IFLA_PROTO_DOWN_REASON_MASK:
262
0
    return "MASK";
263
0
  case IFLA_PROTO_DOWN_REASON_VALUE:
264
0
    return "VALUE";
265
0
  default:
266
0
    return "UNKNOWN";
267
0
  }
268
0
}
269
270
const char *ifla_info_type2str(int type)
271
0
{
272
0
  switch (type) {
273
0
  case IFLA_INFO_UNSPEC:
274
0
    return "UNSPEC";
275
0
  case IFLA_INFO_KIND:
276
0
    return "KIND";
277
0
  case IFLA_INFO_DATA:
278
0
    return "DATA";
279
0
  case IFLA_INFO_XSTATS:
280
0
    return "XSTATS";
281
0
  case IFLA_INFO_SLAVE_KIND:
282
0
    return "SLAVE_KIND";
283
0
  case IFLA_INFO_SLAVE_DATA:
284
0
    return "SLAVE_DATA";
285
0
  default:
286
0
    return "UNKNOWN";
287
0
  }
288
0
}
289
290
const char *rta_type2str(int type)
291
0
{
292
0
  switch (type) {
293
0
  case IFLA_UNSPEC:
294
0
    return "UNSPEC";
295
0
  case IFLA_ADDRESS:
296
0
    return "ADDRESS";
297
0
  case IFLA_BROADCAST:
298
0
    return "BROADCAST";
299
0
  case IFLA_IFNAME:
300
0
    return "IFNAME";
301
0
  case IFLA_MTU:
302
0
    return "MTU";
303
0
  case IFLA_LINK:
304
0
    return "LINK";
305
0
  case IFLA_QDISC:
306
0
    return "QDISC";
307
0
  case IFLA_STATS:
308
0
    return "STATS";
309
0
  case IFLA_COST:
310
0
    return "COST";
311
0
  case IFLA_PRIORITY:
312
0
    return "PRIORITY";
313
0
  case IFLA_MASTER:
314
0
    return "MASTER";
315
0
  case IFLA_WIRELESS:
316
0
    return "WIRELESS";
317
0
  case IFLA_PROTINFO:
318
0
    return "PROTINFO";
319
0
  case IFLA_TXQLEN:
320
0
    return "TXQLEN";
321
0
  case IFLA_MAP:
322
0
    return "MAP";
323
0
  case IFLA_WEIGHT:
324
0
    return "WEIGHT";
325
0
  case IFLA_OPERSTATE:
326
0
    return "OPERSTATE";
327
0
  case IFLA_LINKMODE:
328
0
    return "LINKMODE";
329
0
  case IFLA_LINKINFO:
330
0
    return "LINKINFO";
331
0
  case IFLA_NET_NS_PID:
332
0
    return "NET_NS_PID";
333
0
  case IFLA_IFALIAS:
334
0
    return "IFALIAS";
335
0
  case IFLA_NUM_VF:
336
0
    return "NUM_VF";
337
0
  case IFLA_VFINFO_LIST:
338
0
    return "VFINFO_LIST";
339
0
  case IFLA_STATS64:
340
0
    return "STATS64";
341
0
  case IFLA_VF_PORTS:
342
0
    return "VF_PORTS";
343
0
  case IFLA_PORT_SELF:
344
0
    return "PORT_SELF";
345
0
  case IFLA_AF_SPEC:
346
0
    return "AF_SPEC";
347
0
  case IFLA_GROUP:
348
0
    return "GROUP";
349
0
  case IFLA_NET_NS_FD:
350
0
    return "NET_NS_FD";
351
0
  case IFLA_EXT_MASK:
352
0
    return "EXT_MASK";
353
0
  case IFLA_PROMISCUITY:
354
0
    return "PROMISCUITY";
355
0
  case IFLA_NUM_TX_QUEUES:
356
0
    return "NUM_TX_QUEUES";
357
0
  case IFLA_NUM_RX_QUEUES:
358
0
    return "NUM_RX_QUEUES";
359
0
  case IFLA_CARRIER:
360
0
    return "CARRIER";
361
0
  case IFLA_PHYS_PORT_ID:
362
0
    return "PHYS_PORT_ID";
363
0
  case IFLA_CARRIER_CHANGES:
364
0
    return "CARRIER_CHANGES";
365
0
  case IFLA_PHYS_SWITCH_ID:
366
0
    return "PHYS_SWITCH_ID";
367
0
  case IFLA_LINK_NETNSID:
368
0
    return "LINK_NETNSID";
369
0
  case IFLA_PHYS_PORT_NAME:
370
0
    return "PHYS_PORT_NAME";
371
0
  case IFLA_PROTO_DOWN:
372
0
    return "PROTO_DOWN";
373
#ifdef IFLA_GSO_MAX_SEGS
374
  case IFLA_GSO_MAX_SEGS:
375
    return "GSO_MAX_SEGS";
376
#endif /* IFLA_GSO_MAX_SEGS */
377
#ifdef IFLA_GSO_MAX_SIZE
378
  case IFLA_GSO_MAX_SIZE:
379
    return "GSO_MAX_SIZE";
380
#endif /* IFLA_GSO_MAX_SIZE */
381
#ifdef IFLA_PAD
382
  case IFLA_PAD:
383
    return "PAD";
384
#endif /* IFLA_PAD */
385
#ifdef IFLA_XDP
386
  case IFLA_XDP:
387
    return "XDP";
388
#endif /* IFLA_XDP */
389
#ifdef IFLA_EVENT
390
  case IFLA_EVENT:
391
    return "EVENT";
392
#endif /* IFLA_EVENT */
393
0
  case IFLA_PROTO_DOWN_REASON:
394
0
    return "PROTO_DOWN_REASON";
395
0
  default:
396
0
    return "UNKNOWN";
397
0
  }
398
0
}
399
400
const char *rtm_type2str(int type)
401
0
{
402
0
  switch (type) {
403
0
  case RTN_UNSPEC:
404
0
    return "UNSPEC";
405
0
  case RTN_UNICAST:
406
0
    return "UNICAST";
407
0
  case RTN_LOCAL:
408
0
    return "LOCAL";
409
0
  case RTN_BROADCAST:
410
0
    return "BROADCAST";
411
0
  case RTN_ANYCAST:
412
0
    return "ANYCAST";
413
0
  case RTN_MULTICAST:
414
0
    return "MULTICAST";
415
0
  case RTN_BLACKHOLE:
416
0
    return "BLACKHOLE";
417
0
  case RTN_UNREACHABLE:
418
0
    return "UNREACHABLE";
419
0
  case RTN_PROHIBIT:
420
0
    return "PROHIBIT";
421
0
  case RTN_THROW:
422
0
    return "THROW";
423
0
  case RTN_NAT:
424
0
    return "NAT";
425
0
  case RTN_XRESOLVE:
426
0
    return "XRESOLVE";
427
0
  default:
428
0
    return "UNKNOWN";
429
0
  }
430
0
}
431
432
const char *rtm_protocol2str(int type)
433
0
{
434
0
  switch (type) {
435
0
  case RTPROT_UNSPEC:
436
0
    return "UNSPEC";
437
0
  case RTPROT_REDIRECT:
438
0
    return "REDIRECT";
439
0
  case RTPROT_KERNEL:
440
0
    return "KERNEL";
441
0
  case RTPROT_BOOT:
442
0
    return "BOOT";
443
0
  case RTPROT_STATIC:
444
0
    return "STATIC";
445
0
  case RTPROT_GATED:
446
0
    return "GATED";
447
0
  case RTPROT_RA:
448
0
    return "RA";
449
0
  case RTPROT_MRT:
450
0
    return "MRT";
451
0
  case RTPROT_ZEBRA:
452
0
    return "ZEBRA";
453
0
  case RTPROT_BGP:
454
0
    return "BGP";
455
0
  case RTPROT_ISIS:
456
0
    return "ISIS";
457
0
  case RTPROT_OSPF:
458
0
    return "OSPF";
459
0
  case RTPROT_BIRD:
460
0
    return "BIRD";
461
0
  case RTPROT_DNROUTED:
462
0
    return "DNROUTED";
463
0
  case RTPROT_XORP:
464
0
    return "XORP";
465
0
  case RTPROT_NTK:
466
0
    return "NTK";
467
0
  case RTPROT_DHCP:
468
0
    return "DHCP";
469
0
  case RTPROT_MROUTED:
470
0
    return "MROUTED";
471
0
  case RTPROT_BABEL:
472
0
    return "BABEL";
473
0
  default:
474
0
    return "UNKNOWN";
475
0
  }
476
0
}
477
478
const char *rtm_scope2str(int type)
479
0
{
480
0
  switch (type) {
481
0
  case RT_SCOPE_UNIVERSE:
482
0
    return "UNIVERSE";
483
0
  case RT_SCOPE_SITE:
484
0
    return "SITE";
485
0
  case RT_SCOPE_LINK:
486
0
    return "LINK";
487
0
  case RT_SCOPE_HOST:
488
0
    return "HOST";
489
0
  case RT_SCOPE_NOWHERE:
490
0
    return "NOWHERE";
491
0
  default:
492
0
    return "UNKNOWN";
493
0
  }
494
0
}
495
496
const char *rtm_rta2str(int type)
497
0
{
498
0
  switch (type) {
499
0
  case RTA_UNSPEC:
500
0
    return "UNSPEC";
501
0
  case RTA_DST:
502
0
    return "DST";
503
0
  case RTA_SRC:
504
0
    return "SRC";
505
0
  case RTA_IIF:
506
0
    return "IIF";
507
0
  case RTA_OIF:
508
0
    return "OIF";
509
0
  case RTA_GATEWAY:
510
0
    return "GATEWAY";
511
0
  case RTA_PRIORITY:
512
0
    return "PRIORITY";
513
0
  case RTA_PREF:
514
0
    return "PREF";
515
0
  case RTA_PREFSRC:
516
0
    return "PREFSRC";
517
0
  case RTA_MARK:
518
0
    return "MARK";
519
0
  case RTA_METRICS:
520
0
    return "METRICS";
521
0
  case RTA_MULTIPATH:
522
0
    return "MULTIPATH";
523
0
  case RTA_PROTOINFO:
524
0
    return "PROTOINFO";
525
0
  case RTA_FLOW:
526
0
    return "FLOW";
527
0
  case RTA_CACHEINFO:
528
0
    return "CACHEINFO";
529
0
  case RTA_TABLE:
530
0
    return "TABLE";
531
0
  case RTA_MFC_STATS:
532
0
    return "MFC_STATS";
533
0
  case RTA_NH_ID:
534
0
    return "NH_ID";
535
0
  case RTA_EXPIRES:
536
0
    return "EXPIRES";
537
0
  default:
538
0
    return "UNKNOWN";
539
0
  }
540
0
}
541
542
const char *neigh_rta2str(int type)
543
0
{
544
0
  switch (type) {
545
0
  case NDA_UNSPEC:
546
0
    return "UNSPEC";
547
0
  case NDA_DST:
548
0
    return "DST";
549
0
  case NDA_LLADDR:
550
0
    return "LLADDR";
551
0
  case NDA_CACHEINFO:
552
0
    return "CACHEINFO";
553
0
  case NDA_PROBES:
554
0
    return "PROBES";
555
0
  case NDA_VLAN:
556
0
    return "VLAN";
557
0
  case NDA_PORT:
558
0
    return "PORT";
559
0
  case NDA_VNI:
560
0
    return "VNI";
561
0
  case NDA_IFINDEX:
562
0
    return "IFINDEX";
563
0
  case NDA_MASTER:
564
0
    return "MASTER";
565
0
  case NDA_LINK_NETNSID:
566
0
    return "LINK_NETNSID";
567
0
  default:
568
0
    return "UNKNOWN";
569
0
  }
570
0
}
571
572
const char *ifa_rta2str(int type)
573
0
{
574
0
  switch (type) {
575
0
  case IFA_UNSPEC:
576
0
    return "UNSPEC";
577
0
  case IFA_ADDRESS:
578
0
    return "ADDRESS";
579
0
  case IFA_LOCAL:
580
0
    return "LOCAL";
581
0
  case IFA_LABEL:
582
0
    return "LABEL";
583
0
  case IFA_BROADCAST:
584
0
    return "BROADCAST";
585
0
  case IFA_ANYCAST:
586
0
    return "ANYCAST";
587
0
  case IFA_CACHEINFO:
588
0
    return "CACHEINFO";
589
0
  case IFA_MULTICAST:
590
0
    return "MULTICAST";
591
0
  case IFA_FLAGS:
592
0
    return "FLAGS";
593
0
  default:
594
0
    return "UNKNOWN";
595
0
  }
596
0
}
597
598
const char *nhm_rta2str(int type)
599
0
{
600
0
  switch (type) {
601
0
  case NHA_UNSPEC:
602
0
    return "UNSPEC";
603
0
  case NHA_ID:
604
0
    return "ID";
605
0
  case NHA_GROUP:
606
0
    return "GROUP";
607
0
  case NHA_GROUP_TYPE:
608
0
    return "GROUP_TYPE";
609
0
  case NHA_BLACKHOLE:
610
0
    return "BLACKHOLE";
611
0
  case NHA_OIF:
612
0
    return "OIF";
613
0
  case NHA_GATEWAY:
614
0
    return "GATEWAY";
615
0
  case NHA_ENCAP_TYPE:
616
0
    return "ENCAP_TYPE";
617
0
  case NHA_ENCAP:
618
0
    return "ENCAP";
619
0
  case NHA_GROUPS:
620
0
    return "GROUPS";
621
0
  case NHA_MASTER:
622
0
    return "MASTER";
623
0
  default:
624
0
    return "UNKNOWN";
625
0
  }
626
0
}
627
628
const char *frh_rta2str(int type)
629
0
{
630
0
  switch (type) {
631
0
  case FRA_DST:
632
0
    return "DST";
633
0
  case FRA_SRC:
634
0
    return "SRC";
635
0
  case FRA_IIFNAME:
636
0
    return "IIFNAME";
637
0
  case FRA_GOTO:
638
0
    return "GOTO";
639
0
  case FRA_UNUSED2:
640
0
    return "UNUSED2";
641
0
  case FRA_PRIORITY:
642
0
    return "PRIORITY";
643
0
  case FRA_UNUSED3:
644
0
    return "UNUSED3";
645
0
  case FRA_UNUSED4:
646
0
    return "UNUSED4";
647
0
  case FRA_UNUSED5:
648
0
    return "UNUSED5";
649
0
  case FRA_FWMARK:
650
0
    return "FWMARK";
651
0
  case FRA_FLOW:
652
0
    return "FLOW";
653
0
  case FRA_TUN_ID:
654
0
    return "TUN_ID";
655
0
  case FRA_SUPPRESS_IFGROUP:
656
0
    return "SUPPRESS_IFGROUP";
657
0
  case FRA_SUPPRESS_PREFIXLEN:
658
0
    return "SUPPRESS_PREFIXLEN";
659
0
  case FRA_TABLE:
660
0
    return "TABLE";
661
0
  case FRA_FWMASK:
662
0
    return "FWMASK";
663
0
  case FRA_OIFNAME:
664
0
    return "OIFNAME";
665
0
  case FRA_PAD:
666
0
    return "PAD";
667
0
  case FRA_L3MDEV:
668
0
    return "L3MDEV";
669
0
  case FRA_UID_RANGE:
670
0
    return "UID_RANGE";
671
0
  case FRA_PROTOCOL:
672
0
    return "PROTOCOL";
673
0
  case FRA_IP_PROTO:
674
0
    return "IP_PROTO";
675
0
  case FRA_SPORT_RANGE:
676
0
    return "SPORT_RANGE";
677
0
  case FRA_DPORT_RANGE:
678
0
    return "DPORT_RANGE";
679
0
  default:
680
0
    return "UNKNOWN";
681
0
  }
682
0
}
683
684
const char *frh_action2str(uint8_t action)
685
0
{
686
0
  switch (action) {
687
0
  case FR_ACT_TO_TBL:
688
0
    return "TO_TBL";
689
0
  case FR_ACT_GOTO:
690
0
    return "GOTO";
691
0
  case FR_ACT_NOP:
692
0
    return "NOP";
693
0
  case FR_ACT_RES3:
694
0
    return "RES3";
695
0
  case FR_ACT_RES4:
696
0
    return "RES4";
697
0
  case FR_ACT_BLACKHOLE:
698
0
    return "BLACKHOLE";
699
0
  case FR_ACT_UNREACHABLE:
700
0
    return "UNREACHABLE";
701
0
  case FR_ACT_PROHIBIT:
702
0
    return "PROHIBIT";
703
0
  default:
704
0
    return "UNKNOWN";
705
0
  }
706
0
}
707
708
static const char *ncm_rta2str(int type)
709
0
{
710
0
  switch (type) {
711
0
  case NETCONFA_UNSPEC:
712
0
    return "UNSPEC";
713
0
  case NETCONFA_IFINDEX:
714
0
    return "IFINDEX";
715
0
  case NETCONFA_FORWARDING:
716
0
    return "FORWARDING";
717
0
  case NETCONFA_RP_FILTER:
718
0
    return "RP_FILTER";
719
0
  case NETCONFA_MC_FORWARDING:
720
0
    return "MCAST";
721
0
  case NETCONFA_PROXY_NEIGH:
722
0
    return "PROXY_NEIGH";
723
0
  case NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN:
724
0
    return "IGNORE_LINKDOWN";
725
0
  case NETCONFA_INPUT:
726
0
    return "MPLS";
727
0
  case NETCONFA_BC_FORWARDING:
728
0
    return "BCAST";
729
0
  default:
730
0
    return "UNKNOWN";
731
0
  }
732
0
}
733
734
static void dump_on_off(uint32_t ival, const char *prefix)
735
0
{
736
0
  zlog_debug("%s%s", prefix, (ival != 0) ? "on" : "off");
737
0
}
738
739
static inline void flag_write(int flags, int flag, const char *flagstr,
740
            char *buf, size_t buflen)
741
0
{
742
0
  if (CHECK_FLAG(flags, flag) == 0)
743
0
    return;
744
745
0
  if (buf[0])
746
0
    strlcat(buf, ",", buflen);
747
748
0
  strlcat(buf, flagstr, buflen);
749
0
}
750
751
const char *nlmsg_flags2str(uint16_t flags, char *buf, size_t buflen)
752
0
{
753
0
  const char *bufp = buf;
754
755
0
  *buf = 0;
756
  /* Specific flags. */
757
0
  flag_write(flags, NLM_F_REQUEST, "REQUEST", buf, buflen);
758
0
  flag_write(flags, NLM_F_MULTI, "MULTI", buf, buflen);
759
0
  flag_write(flags, NLM_F_ACK, "ACK", buf, buflen);
760
0
  flag_write(flags, NLM_F_ECHO, "ECHO", buf, buflen);
761
0
  flag_write(flags, NLM_F_DUMP, "DUMP", buf, buflen);
762
763
  /* Netlink family type dependent. */
764
0
  flag_write(flags, 0x0100, "(ROOT|REPLACE|CAPPED)", buf, buflen);
765
0
  flag_write(flags, 0x0200, "(MATCH|EXCLUDE|ACK_TLVS)", buf, buflen);
766
0
  flag_write(flags, 0x0400, "(ATOMIC|CREATE)", buf, buflen);
767
0
  flag_write(flags, 0x0800, "(DUMP|APPEND)", buf, buflen);
768
769
0
  return (bufp);
770
0
}
771
772
const char *if_flags2str(uint32_t flags, char *buf, size_t buflen)
773
0
{
774
0
  const char *bufp = buf;
775
776
0
  *buf = 0;
777
0
  flag_write(flags, IFF_UP, "UP", buf, buflen);
778
0
  flag_write(flags, IFF_BROADCAST, "BROADCAST", buf, buflen);
779
0
  flag_write(flags, IFF_DEBUG, "DEBUG", buf, buflen);
780
0
  flag_write(flags, IFF_LOOPBACK, "LOOPBACK", buf, buflen);
781
0
  flag_write(flags, IFF_POINTOPOINT, "POINTOPOINT", buf, buflen);
782
0
  flag_write(flags, IFF_NOTRAILERS, "NOTRAILERS", buf, buflen);
783
0
  flag_write(flags, IFF_RUNNING, "RUNNING", buf, buflen);
784
0
  flag_write(flags, IFF_NOARP, "NOARP", buf, buflen);
785
0
  flag_write(flags, IFF_PROMISC, "PROMISC", buf, buflen);
786
0
  flag_write(flags, IFF_ALLMULTI, "ALLMULTI", buf, buflen);
787
0
  flag_write(flags, IFF_MASTER, "MASTER", buf, buflen);
788
0
  flag_write(flags, IFF_SLAVE, "SLAVE", buf, buflen);
789
0
  flag_write(flags, IFF_MULTICAST, "MULTICAST", buf, buflen);
790
0
  flag_write(flags, IFF_PORTSEL, "PORTSEL", buf, buflen);
791
0
  flag_write(flags, IFF_AUTOMEDIA, "AUTOMEDIA", buf, buflen);
792
0
  flag_write(flags, IFF_DYNAMIC, "DYNAMIC", buf, buflen);
793
794
0
  return (bufp);
795
0
}
796
797
const char *rtm_flags2str(uint32_t flags, char *buf, size_t buflen)
798
0
{
799
0
  const char *bufp = buf;
800
801
0
  *buf = 0;
802
0
  flag_write(flags, RTM_F_NOTIFY, "NOTIFY", buf, buflen);
803
0
  flag_write(flags, RTM_F_CLONED, "CLONED", buf, buflen);
804
0
  flag_write(flags, RTM_F_EQUALIZE, "EQUALIZE", buf, buflen);
805
806
0
  return (bufp);
807
0
}
808
809
const char *neigh_state2str(uint32_t flags, char *buf, size_t buflen)
810
0
{
811
0
  const char *bufp = buf;
812
813
0
  *buf = 0;
814
0
  flag_write(flags, NUD_INCOMPLETE, "INCOMPLETE", buf, buflen);
815
0
  flag_write(flags, NUD_REACHABLE, "REACHABLE", buf, buflen);
816
0
  flag_write(flags, NUD_STALE, "STALE", buf, buflen);
817
0
  flag_write(flags, NUD_DELAY, "DELAY", buf, buflen);
818
0
  flag_write(flags, NUD_PROBE, "PROBE", buf, buflen);
819
0
  flag_write(flags, NUD_FAILED, "FAILED", buf, buflen);
820
0
  flag_write(flags, NUD_NOARP, "NOARP", buf, buflen);
821
0
  flag_write(flags, NUD_PERMANENT, "PERMANENT", buf, buflen);
822
823
0
  return (bufp);
824
0
}
825
826
const char *neigh_flags2str(uint32_t flags, char *buf, size_t buflen)
827
0
{
828
0
  const char *bufp = buf;
829
830
0
  *buf = 0;
831
0
  flag_write(flags, NTF_USE, "USE", buf, buflen);
832
0
  flag_write(flags, NTF_SELF, "SELF", buf, buflen);
833
0
  flag_write(flags, NTF_MASTER, "MASTER", buf, buflen);
834
0
  flag_write(flags, NTF_PROXY, "PROXY", buf, buflen);
835
0
  flag_write(flags, NTF_EXT_LEARNED, "EXT_LEARNED", buf, buflen);
836
0
#ifdef NTF_OFFLOADED
837
0
  flag_write(flags, NTF_OFFLOADED, "OFFLOADED", buf, buflen);
838
0
#endif /* NTF_OFFLOADED */
839
0
  flag_write(flags, NTF_ROUTER, "ROUTER", buf, buflen);
840
841
0
  return (bufp);
842
0
}
843
844
const char *ifa_flags2str(uint32_t flags, char *buf, size_t buflen)
845
0
{
846
0
  const char *bufp = buf;
847
848
0
  *buf = 0;
849
0
  flag_write(flags, IFA_F_SECONDARY, "SECONDARY", buf, buflen);
850
0
  flag_write(flags, IFA_F_NODAD, "NODAD", buf, buflen);
851
0
  flag_write(flags, IFA_F_OPTIMISTIC, "OPTIMISTIC", buf, buflen);
852
0
  flag_write(flags, IFA_F_DADFAILED, "DADFAILED", buf, buflen);
853
0
  flag_write(flags, IFA_F_HOMEADDRESS, "HOMEADDRESS", buf, buflen);
854
0
  flag_write(flags, IFA_F_DEPRECATED, "DEPRECATED", buf, buflen);
855
0
  flag_write(flags, IFA_F_TENTATIVE, "TENTATIVE", buf, buflen);
856
0
  flag_write(flags, IFA_F_PERMANENT, "PERMANENT", buf, buflen);
857
0
  flag_write(flags, IFA_F_MANAGETEMPADDR, "MANAGETEMPADDR", buf, buflen);
858
0
  flag_write(flags, IFA_F_NOPREFIXROUTE, "NOPREFIXROUTE", buf, buflen);
859
0
  flag_write(flags, IFA_F_MCAUTOJOIN, "MCAUTOJOIN", buf, buflen);
860
0
  flag_write(flags, IFA_F_STABLE_PRIVACY, "STABLE_PRIVACY", buf, buflen);
861
862
0
  return (bufp);
863
0
}
864
865
const char *nh_flags2str(uint32_t flags, char *buf, size_t buflen)
866
0
{
867
0
  const char *bufp = buf;
868
869
0
  *buf = 0;
870
0
  flag_write(flags, RTNH_F_DEAD, "DEAD", buf, buflen);
871
0
  flag_write(flags, RTNH_F_PERVASIVE, "PERVASIVE", buf, buflen);
872
0
  flag_write(flags, RTNH_F_ONLINK, "ONLINK", buf, buflen);
873
0
  flag_write(flags, RTNH_F_OFFLOAD, "OFFLOAD", buf, buflen);
874
0
  flag_write(flags, RTNH_F_LINKDOWN, "LINKDOWN", buf, buflen);
875
0
  flag_write(flags, RTNH_F_UNRESOLVED, "UNRESOLVED", buf, buflen);
876
877
0
  return (bufp);
878
0
}
879
880
/*
881
 * Netlink abstractions.
882
 */
883
static void nllink_pdr_dump(struct rtattr *rta, size_t msglen)
884
0
{
885
0
  size_t plen;
886
0
  uint32_t u32v;
887
888
0
next_rta:
889
  /* Check the header for valid length and for outbound access. */
890
0
  if (RTA_OK(rta, msglen) == 0)
891
0
    return;
892
893
0
  plen = RTA_PAYLOAD(rta);
894
0
  zlog_debug("      linkinfo [len=%d (payload=%zu) type=(%d) %s]",
895
0
       rta->rta_len, plen, rta->rta_type,
896
0
       ifla_pdr_type2str(rta->rta_type));
897
0
  switch (rta->rta_type) {
898
0
  case IFLA_PROTO_DOWN_REASON_MASK:
899
0
  case IFLA_PROTO_DOWN_REASON_VALUE:
900
0
    if (plen < sizeof(uint32_t)) {
901
0
      zlog_debug("        invalid length");
902
0
      break;
903
0
    }
904
905
0
    u32v = *(uint32_t *)RTA_DATA(rta);
906
0
    zlog_debug("        %u", u32v);
907
0
    break;
908
909
0
  default:
910
    /* NOTHING: unhandled. */
911
0
    break;
912
0
  }
913
914
  /* Get next pointer and start iteration again. */
915
0
  rta = RTA_NEXT(rta, msglen);
916
0
  goto next_rta;
917
0
}
918
919
static void nllink_linkinfo_dump(struct rtattr *rta, size_t msglen)
920
0
{
921
0
  size_t plen;
922
0
  char dbuf[128];
923
924
0
next_rta:
925
  /* Check the header for valid length and for outbound access. */
926
0
  if (RTA_OK(rta, msglen) == 0)
927
0
    return;
928
929
0
  plen = RTA_PAYLOAD(rta);
930
0
  zlog_debug("      linkinfo [len=%d (payload=%zu) type=(%d) %s]",
931
0
       rta->rta_len, plen, rta->rta_type,
932
0
       ifla_info_type2str(rta->rta_type));
933
0
  switch (rta->rta_type) {
934
0
  case IFLA_INFO_KIND:
935
0
    if (plen == 0) {
936
0
      zlog_debug("        invalid length");
937
0
      break;
938
0
    }
939
940
0
    snprintf(dbuf, sizeof(dbuf), "%s", (char *)RTA_DATA(rta));
941
0
    zlog_debug("        %s", dbuf);
942
0
    break;
943
0
  case IFLA_INFO_SLAVE_KIND:
944
0
    if (plen == 0) {
945
0
      zlog_debug("        invalid length");
946
0
      break;
947
0
    }
948
949
0
    snprintf(dbuf, sizeof(dbuf), "%s", (char *)RTA_DATA(rta));
950
0
    zlog_debug("        %s", dbuf);
951
0
    break;
952
953
0
  default:
954
    /* NOTHING: unhandled. */
955
0
    break;
956
0
  }
957
958
  /* Get next pointer and start iteration again. */
959
0
  rta = RTA_NEXT(rta, msglen);
960
0
  goto next_rta;
961
0
}
962
963
static void nllink_dump(struct ifinfomsg *ifi, size_t msglen)
964
0
{
965
0
  uint8_t *datap;
966
0
  struct rtattr *rta;
967
0
  size_t plen, it;
968
0
  uint32_t u32v;
969
0
  uint8_t u8v;
970
0
  char bytestr[16];
971
0
  char dbuf[128];
972
0
  unsigned short rta_type;
973
974
  /* Get the first attribute and go from there. */
975
0
  rta = IFLA_RTA(ifi);
976
0
next_rta:
977
  /* Check the header for valid length and for outbound access. */
978
0
  if (RTA_OK(rta, msglen) == 0)
979
0
    return;
980
981
0
  plen = RTA_PAYLOAD(rta);
982
0
  rta_type = rta->rta_type & ~NLA_F_NESTED;
983
0
  zlog_debug("    rta [len=%d (payload=%zu) type=(%d) %s]", rta->rta_len,
984
0
       plen, rta_type, rta_type2str(rta_type));
985
0
  switch (rta_type) {
986
0
  case IFLA_IFALIAS:
987
0
    if (plen == 0) {
988
0
      zlog_debug("      invalid length");
989
0
      break;
990
0
    }
991
992
0
    snprintf(dbuf, sizeof(dbuf), "%s", (char *)RTA_DATA(rta));
993
0
    zlog_debug("      %s", dbuf);
994
0
    break;
995
996
0
  case IFLA_MTU:
997
0
  case IFLA_TXQLEN:
998
0
  case IFLA_NUM_TX_QUEUES:
999
0
  case IFLA_NUM_RX_QUEUES:
1000
0
  case IFLA_GROUP:
1001
0
  case IFLA_PROMISCUITY:
1002
#ifdef IFLA_GSO_MAX_SEGS
1003
  case IFLA_GSO_MAX_SEGS:
1004
#endif /* IFLA_GSO_MAX_SEGS */
1005
#ifdef IFLA_GSO_MAX_SIZE
1006
  case IFLA_GSO_MAX_SIZE:
1007
#endif /* IFLA_GSO_MAX_SIZE */
1008
0
  case IFLA_CARRIER_CHANGES:
1009
0
  case IFLA_MASTER:
1010
0
  case IFLA_LINK:
1011
0
    if (plen < sizeof(uint32_t)) {
1012
0
      zlog_debug("      invalid length");
1013
0
      break;
1014
0
    }
1015
1016
0
    u32v = *(uint32_t *)RTA_DATA(rta);
1017
0
    zlog_debug("      %u", u32v);
1018
0
    break;
1019
1020
0
  case IFLA_PROTO_DOWN:
1021
0
    if (plen < sizeof(uint8_t)) {
1022
0
      zlog_debug("      invalid length");
1023
0
      break;
1024
0
    }
1025
1026
0
    u8v = *(uint8_t *)RTA_DATA(rta);
1027
0
    zlog_debug("      %u", u8v);
1028
0
    break;
1029
0
  case IFLA_ADDRESS:
1030
0
    datap = RTA_DATA(rta);
1031
0
    dbuf[0] = 0;
1032
0
    for (it = 0; it < plen; it++) {
1033
0
      snprintf(bytestr, sizeof(bytestr), "%02X:", *datap);
1034
0
      strlcat(dbuf, bytestr, sizeof(dbuf));
1035
0
      datap++;
1036
0
    }
1037
    /* Remove trailing ':'. */
1038
0
    if (dbuf[0])
1039
0
      dbuf[strlen(dbuf) - 1] = 0;
1040
1041
0
    zlog_debug("      %s", dbuf[0] ? dbuf : "<empty>");
1042
0
    break;
1043
1044
0
  case IFLA_LINKINFO:
1045
0
    nllink_linkinfo_dump(RTA_DATA(rta), plen);
1046
0
    break;
1047
1048
0
  case IFLA_PROTO_DOWN_REASON:
1049
0
    nllink_pdr_dump(RTA_DATA(rta), plen);
1050
0
    break;
1051
1052
0
  default:
1053
    /* NOTHING: unhandled. */
1054
0
    break;
1055
0
  }
1056
1057
  /* Get next pointer and start iteration again. */
1058
0
  rta = RTA_NEXT(rta, msglen);
1059
0
  goto next_rta;
1060
0
}
1061
1062
static void nlroute_dump(struct rtmsg *rtm, size_t msglen)
1063
0
{
1064
0
  struct rta_mfc_stats *mfc_stats;
1065
0
  struct rtattr *rta;
1066
0
  size_t plen;
1067
0
  uint32_t u32v;
1068
0
  uint64_t u64v;
1069
1070
  /* Get the first attribute and go from there. */
1071
0
  rta = RTM_RTA(rtm);
1072
0
next_rta:
1073
  /* Check the header for valid length and for outbound access. */
1074
0
  if (RTA_OK(rta, msglen) == 0)
1075
0
    return;
1076
1077
0
  plen = RTA_PAYLOAD(rta);
1078
0
  zlog_debug("    rta [len=%d (payload=%zu) type=(%d) %s]", rta->rta_len,
1079
0
       plen, rta->rta_type & NLA_TYPE_MASK,
1080
0
       rtm_rta2str(rta->rta_type & NLA_TYPE_MASK));
1081
0
  switch (rta->rta_type & NLA_TYPE_MASK) {
1082
0
  case RTA_IIF:
1083
0
  case RTA_OIF:
1084
0
  case RTA_PRIORITY:
1085
0
  case RTA_TABLE:
1086
0
  case RTA_NH_ID:
1087
0
    u32v = *(uint32_t *)RTA_DATA(rta);
1088
0
    zlog_debug("      %u", u32v);
1089
0
    break;
1090
1091
0
  case RTA_EXPIRES:
1092
0
    u64v = *(uint64_t *)RTA_DATA(rta);
1093
0
    zlog_debug("      %" PRIu64, u64v);
1094
0
    break;
1095
1096
0
  case RTA_GATEWAY:
1097
0
  case RTA_DST:
1098
0
  case RTA_SRC:
1099
0
  case RTA_PREFSRC:
1100
0
    switch (plen) {
1101
0
    case sizeof(struct in_addr):
1102
0
      zlog_debug("      %pI4",
1103
0
           (struct in_addr *)RTA_DATA(rta));
1104
0
      break;
1105
0
    case sizeof(struct in6_addr):
1106
0
      zlog_debug("      %pI6",
1107
0
           (struct in6_addr *)RTA_DATA(rta));
1108
0
      break;
1109
0
    default:
1110
0
      break;
1111
0
    }
1112
0
    break;
1113
1114
0
  case RTA_MFC_STATS:
1115
0
    mfc_stats = (struct rta_mfc_stats *)RTA_DATA(rta);
1116
0
    zlog_debug("      pkts=%ju bytes=%ju wrong_if=%ju",
1117
0
         (uintmax_t)mfc_stats->mfcs_packets,
1118
0
         (uintmax_t)mfc_stats->mfcs_bytes,
1119
0
         (uintmax_t)mfc_stats->mfcs_wrong_if);
1120
0
    break;
1121
1122
0
  default:
1123
    /* NOTHING: unhandled. */
1124
0
    break;
1125
0
  }
1126
1127
  /* Get next pointer and start iteration again. */
1128
0
  rta = RTA_NEXT(rta, msglen);
1129
0
  goto next_rta;
1130
0
}
1131
1132
static void nlneigh_dump(struct ndmsg *ndm, size_t msglen)
1133
0
{
1134
0
  struct rtattr *rta;
1135
0
  uint8_t *datap;
1136
0
  size_t plen, it;
1137
0
  uint16_t vid;
1138
0
  char bytestr[16];
1139
0
  char dbuf[128];
1140
0
  unsigned short rta_type;
1141
1142
0
#ifndef NDA_RTA
1143
0
#define NDA_RTA(ndm)                                                           \
1144
  /* struct ndmsg *ndm; */                                               \
1145
0
  ((struct rtattr *)(((uint8_t *)(ndm))                                  \
1146
0
         + NLMSG_ALIGN(sizeof(struct ndmsg))))
1147
0
#endif /* NDA_RTA */
1148
1149
  /* Get the first attribute and go from there. */
1150
0
  rta = NDA_RTA(ndm);
1151
0
next_rta:
1152
  /* Check the header for valid length and for outbound access. */
1153
0
  if (RTA_OK(rta, msglen) == 0)
1154
0
    return;
1155
1156
0
  plen = RTA_PAYLOAD(rta);
1157
0
  rta_type = rta->rta_type & ~NLA_F_NESTED;
1158
0
  zlog_debug("    rta [len=%d (payload=%zu) type=(%d) %s]", rta->rta_len,
1159
0
       plen, rta->rta_type, neigh_rta2str(rta_type));
1160
0
  switch (rta_type) {
1161
0
  case NDA_LLADDR:
1162
0
    datap = RTA_DATA(rta);
1163
0
    dbuf[0] = 0;
1164
0
    for (it = 0; it < plen; it++) {
1165
0
      snprintf(bytestr, sizeof(bytestr), "%02X:", *datap);
1166
0
      strlcat(dbuf, bytestr, sizeof(dbuf));
1167
0
      datap++;
1168
0
    }
1169
    /* Remove trailing ':'. */
1170
0
    if (dbuf[0])
1171
0
      dbuf[strlen(dbuf) - 1] = 0;
1172
1173
0
    zlog_debug("      %s", dbuf[0] ? dbuf : "<empty>");
1174
0
    break;
1175
1176
0
  case NDA_DST:
1177
0
    switch (plen) {
1178
0
    case sizeof(struct in_addr):
1179
0
      zlog_debug("      %pI4",
1180
0
           (struct in_addr *)RTA_DATA(rta));
1181
0
      break;
1182
0
    case sizeof(struct in6_addr):
1183
0
      zlog_debug("      %pI6",
1184
0
           (struct in6_addr *)RTA_DATA(rta));
1185
0
      break;
1186
0
    default:
1187
0
      break;
1188
0
    }
1189
0
    break;
1190
1191
0
  case NDA_VLAN:
1192
0
    vid = *(uint16_t *)RTA_DATA(rta);
1193
0
    zlog_debug("      %d", vid);
1194
0
    break;
1195
1196
0
  default:
1197
    /* NOTHING: unhandled. */
1198
0
    break;
1199
0
  }
1200
1201
  /* Get next pointer and start iteration again. */
1202
0
  rta = RTA_NEXT(rta, msglen);
1203
0
  goto next_rta;
1204
0
}
1205
1206
static void nlifa_dump(struct ifaddrmsg *ifa, size_t msglen)
1207
0
{
1208
0
  struct rtattr *rta;
1209
0
  size_t plen;
1210
0
  uint32_t u32v;
1211
1212
  /* Get the first attribute and go from there. */
1213
0
  rta = IFA_RTA(ifa);
1214
0
next_rta:
1215
  /* Check the header for valid length and for outbound access. */
1216
0
  if (RTA_OK(rta, msglen) == 0)
1217
0
    return;
1218
1219
0
  plen = RTA_PAYLOAD(rta);
1220
0
  zlog_debug("    rta [len=%d (payload=%zu) type=(%d) %s]", rta->rta_len,
1221
0
       plen, rta->rta_type, ifa_rta2str(rta->rta_type));
1222
0
  switch (rta->rta_type) {
1223
0
  case IFA_UNSPEC:
1224
0
    u32v = *(uint32_t *)RTA_DATA(rta);
1225
0
    zlog_debug("      %u", u32v);
1226
0
    break;
1227
1228
0
  case IFA_LABEL:
1229
0
    zlog_debug("      %s", (const char *)RTA_DATA(rta));
1230
0
    break;
1231
1232
0
  case IFA_ADDRESS:
1233
0
  case IFA_LOCAL:
1234
0
  case IFA_BROADCAST:
1235
0
    switch (plen) {
1236
0
    case 4:
1237
0
      zlog_debug("      %pI4",
1238
0
           (struct in_addr *)RTA_DATA(rta));
1239
0
      break;
1240
0
    case 16:
1241
0
      zlog_debug("      %pI6",
1242
0
           (struct in6_addr *)RTA_DATA(rta));
1243
0
      break;
1244
0
    default:
1245
0
      break;
1246
0
    }
1247
0
    break;
1248
1249
0
  default:
1250
    /* NOTHING: unhandled. */
1251
0
    break;
1252
0
  }
1253
1254
  /* Get next pointer and start iteration again. */
1255
0
  rta = RTA_NEXT(rta, msglen);
1256
0
  goto next_rta;
1257
0
}
1258
1259
static void nltnl_dump(struct tunnel_msg *tnlm, size_t msglen)
1260
0
{
1261
0
  struct rtattr *attr;
1262
0
  vni_t vni_start = 0, vni_end = 0;
1263
0
  struct rtattr *ttb[VXLAN_VNIFILTER_ENTRY_MAX + 1];
1264
0
  uint8_t rta_type;
1265
1266
0
  attr = TUNNEL_RTA(tnlm);
1267
0
next_attr:
1268
  /* Check the header for valid length and for outbound access. */
1269
0
  if (RTA_OK(attr, msglen) == 0)
1270
0
    return;
1271
1272
0
  rta_type = attr->rta_type & NLA_TYPE_MASK;
1273
1274
0
  if (rta_type != VXLAN_VNIFILTER_ENTRY) {
1275
0
    attr = RTA_NEXT(attr, msglen);
1276
0
    goto next_attr;
1277
0
  }
1278
1279
0
  memset(ttb, 0, sizeof(ttb));
1280
1281
0
  netlink_parse_rtattr_flags(ttb, VXLAN_VNIFILTER_ENTRY_MAX,
1282
0
           RTA_DATA(attr), RTA_PAYLOAD(attr),
1283
0
           NLA_F_NESTED);
1284
1285
0
  if (ttb[VXLAN_VNIFILTER_ENTRY_START])
1286
0
    vni_start =
1287
0
      *(uint32_t *)RTA_DATA(ttb[VXLAN_VNIFILTER_ENTRY_START]);
1288
1289
0
  if (ttb[VXLAN_VNIFILTER_ENTRY_END])
1290
0
    vni_end = *(uint32_t *)RTA_DATA(ttb[VXLAN_VNIFILTER_ENTRY_END]);
1291
0
  zlog_debug("  vni_start %u, vni_end %u", vni_start, vni_end);
1292
1293
0
  attr = RTA_NEXT(attr, msglen);
1294
0
  goto next_attr;
1295
0
}
1296
1297
static const char *lwt_type2str(uint16_t type)
1298
0
{
1299
0
  switch (type) {
1300
0
  case LWTUNNEL_ENCAP_NONE:
1301
0
    return "NONE";
1302
0
  case LWTUNNEL_ENCAP_MPLS:
1303
0
    return "MPLS";
1304
0
  case LWTUNNEL_ENCAP_IP:
1305
0
    return "IPv4";
1306
0
  case LWTUNNEL_ENCAP_ILA:
1307
0
    return "ILA";
1308
0
  case LWTUNNEL_ENCAP_IP6:
1309
0
    return "IPv6";
1310
0
  case LWTUNNEL_ENCAP_SEG6:
1311
0
    return "SEG6";
1312
0
  case LWTUNNEL_ENCAP_BPF:
1313
0
    return "BPF";
1314
0
  case LWTUNNEL_ENCAP_SEG6_LOCAL:
1315
0
    return "SEG6_LOCAL";
1316
0
  default:
1317
0
    return "UNKNOWN";
1318
0
  }
1319
0
}
1320
1321
static const char *nhg_type2str(uint16_t type)
1322
0
{
1323
0
  switch (type) {
1324
0
  case NEXTHOP_GRP_TYPE_MPATH:
1325
0
    return "MULTIPATH";
1326
0
  case NEXTHOP_GRP_TYPE_RES:
1327
0
    return "RESILIENT MULTIPATH";
1328
0
  default:
1329
0
    return "UNKNOWN";
1330
0
  }
1331
0
}
1332
1333
static void nlnh_dump(struct nhmsg *nhm, size_t msglen)
1334
0
{
1335
0
  struct rtattr *rta;
1336
0
  int ifindex;
1337
0
  size_t plen;
1338
0
  uint16_t u16v;
1339
0
  uint32_t u32v;
1340
0
  unsigned long count, i;
1341
0
  struct nexthop_grp *nhgrp;
1342
0
  unsigned short rta_type;
1343
1344
0
  rta = RTM_NHA(nhm);
1345
1346
0
next_rta:
1347
  /* Check the header for valid length and for outbound access. */
1348
0
  if (RTA_OK(rta, msglen) == 0)
1349
0
    return;
1350
1351
0
  plen = RTA_PAYLOAD(rta);
1352
0
  rta_type = rta->rta_type & ~NLA_F_NESTED;
1353
0
  zlog_debug("    rta [len=%d (payload=%zu) type=(%d) %s]", rta->rta_len,
1354
0
       plen, rta->rta_type, nhm_rta2str(rta_type));
1355
0
  switch (rta_type) {
1356
0
  case NHA_ID:
1357
0
    u32v = *(uint32_t *)RTA_DATA(rta);
1358
0
    zlog_debug("      %u", u32v);
1359
0
    break;
1360
0
  case NHA_GROUP:
1361
0
    nhgrp = (struct nexthop_grp *)RTA_DATA(rta);
1362
0
    count = (RTA_PAYLOAD(rta) / sizeof(*nhgrp));
1363
0
    if (count == 0
1364
0
        || (count * sizeof(*nhgrp)) != RTA_PAYLOAD(rta)) {
1365
0
      zlog_debug("      invalid nexthop group received");
1366
0
      return;
1367
0
    }
1368
1369
0
    for (i = 0; i < count; i++)
1370
0
      zlog_debug("      id %d weight %d", nhgrp[i].id,
1371
0
           nhgrp[i].weight);
1372
0
    break;
1373
0
  case NHA_ENCAP_TYPE:
1374
0
    u16v = *(uint16_t *)RTA_DATA(rta);
1375
0
    zlog_debug("      %s", lwt_type2str(u16v));
1376
0
    break;
1377
0
  case NHA_GROUP_TYPE:
1378
0
    u16v = *(uint16_t *)RTA_DATA(rta);
1379
0
    zlog_debug("      %s", nhg_type2str(u16v));
1380
0
    break;
1381
0
  case NHA_BLACKHOLE:
1382
    /* NOTHING */
1383
0
    break;
1384
0
  case NHA_OIF:
1385
0
    ifindex = *(int *)RTA_DATA(rta);
1386
0
    zlog_debug("      %d", ifindex);
1387
0
    break;
1388
0
  case NHA_GATEWAY:
1389
0
    switch (nhm->nh_family) {
1390
0
    case AF_INET:
1391
0
      zlog_debug("      %pI4",
1392
0
           (struct in_addr *)RTA_DATA(rta));
1393
0
      break;
1394
0
    case AF_INET6:
1395
0
      zlog_debug("      %pI6",
1396
0
           (struct in6_addr *)RTA_DATA(rta));
1397
0
      break;
1398
1399
0
    default:
1400
0
      zlog_debug("      invalid family %d", nhm->nh_family);
1401
0
      break;
1402
0
    }
1403
0
    break;
1404
0
  case NHA_ENCAP:
1405
    /* TODO: handle MPLS labels. */
1406
0
    zlog_debug("      unparsed MPLS labels");
1407
0
    break;
1408
0
  case NHA_GROUPS:
1409
    /* TODO: handle this message. */
1410
0
    zlog_debug("      unparsed GROUPS message");
1411
0
    break;
1412
1413
0
  default:
1414
    /* NOTHING: unhandled. */
1415
0
    break;
1416
0
  }
1417
1418
  /* Get next pointer and start iteration again. */
1419
0
  rta = RTA_NEXT(rta, msglen);
1420
0
  goto next_rta;
1421
0
}
1422
1423
static void nlrule_dump(struct fib_rule_hdr *frh, size_t msglen)
1424
0
{
1425
0
  struct rtattr *rta;
1426
0
  size_t plen;
1427
0
  uint8_t u8v;
1428
0
  uint32_t u32v;
1429
0
  int32_t s32v;
1430
0
  uint64_t u64v;
1431
0
  char dbuf[128];
1432
0
  struct fib_rule_uid_range *u_range;
1433
0
  struct fib_rule_port_range *p_range;
1434
1435
  /* Get the first attribute and go from there. */
1436
0
  rta = RTM_RTA(frh);
1437
0
next_rta:
1438
  /* Check the header for valid length and for outbound access. */
1439
0
  if (RTA_OK(rta, msglen) == 0)
1440
0
    return;
1441
1442
0
  plen = RTA_PAYLOAD(rta);
1443
0
  zlog_debug("    rta [len=%d (payload=%zu) type=(%d) %s]", rta->rta_len,
1444
0
       plen, rta->rta_type, frh_rta2str(rta->rta_type));
1445
0
  switch (rta->rta_type) {
1446
0
  case FRA_DST:
1447
0
  case FRA_SRC:
1448
0
    switch (plen) {
1449
0
    case sizeof(struct in_addr):
1450
0
      zlog_debug("      %pI4",
1451
0
           (struct in_addr *)RTA_DATA(rta));
1452
0
      break;
1453
0
    case sizeof(struct in6_addr):
1454
0
      zlog_debug("      %pI6",
1455
0
           (struct in6_addr *)RTA_DATA(rta));
1456
0
      break;
1457
0
    default:
1458
0
      break;
1459
0
    }
1460
0
    break;
1461
1462
0
  case FRA_IIFNAME:
1463
0
  case FRA_OIFNAME:
1464
0
    snprintf(dbuf, sizeof(dbuf), "%s", (char *)RTA_DATA(rta));
1465
0
    zlog_debug("        %s", dbuf);
1466
0
    break;
1467
1468
0
  case FRA_GOTO:
1469
0
  case FRA_UNUSED2:
1470
0
  case FRA_PRIORITY:
1471
0
  case FRA_UNUSED3:
1472
0
  case FRA_UNUSED4:
1473
0
  case FRA_UNUSED5:
1474
0
  case FRA_FWMARK:
1475
0
  case FRA_FLOW:
1476
0
  case FRA_TABLE:
1477
0
  case FRA_FWMASK:
1478
0
    u32v = *(uint32_t *)RTA_DATA(rta);
1479
0
    zlog_debug("      %u", u32v);
1480
0
    break;
1481
1482
0
  case FRA_SUPPRESS_IFGROUP:
1483
0
  case FRA_SUPPRESS_PREFIXLEN:
1484
0
    s32v = *(int32_t *)RTA_DATA(rta);
1485
0
    zlog_debug("      %d", s32v);
1486
0
    break;
1487
1488
0
  case FRA_TUN_ID:
1489
0
    u64v = *(uint64_t *)RTA_DATA(rta);
1490
0
    zlog_debug("      %" PRIu64, u64v);
1491
0
    break;
1492
1493
0
  case FRA_L3MDEV:
1494
0
  case FRA_PROTOCOL:
1495
0
  case FRA_IP_PROTO:
1496
0
    u8v = *(uint8_t *)RTA_DATA(rta);
1497
0
    zlog_debug("      %u", u8v);
1498
0
    break;
1499
1500
0
  case FRA_UID_RANGE:
1501
0
    u_range = (struct fib_rule_uid_range *)RTA_DATA(rta);
1502
0
    if (u_range->start == u_range->end)
1503
0
      zlog_debug("      %u", u_range->start);
1504
0
    else
1505
0
      zlog_debug("      %u-%u", u_range->start, u_range->end);
1506
0
    break;
1507
1508
0
  case FRA_SPORT_RANGE:
1509
0
  case FRA_DPORT_RANGE:
1510
0
    p_range = (struct fib_rule_port_range *)RTA_DATA(rta);
1511
0
    if (p_range->start == p_range->end)
1512
0
      zlog_debug("      %u", p_range->start);
1513
0
    else
1514
0
      zlog_debug("      %u-%u", p_range->start, p_range->end);
1515
0
    break;
1516
1517
0
  case FRA_PAD: /* fallthrough */
1518
0
  default:
1519
    /* NOTHING: unhandled. */
1520
0
    break;
1521
0
  }
1522
1523
  /* Get next pointer and start iteration again. */
1524
0
  rta = RTA_NEXT(rta, msglen);
1525
0
  goto next_rta;
1526
0
}
1527
1528
static const char *tcm_nltype2str(int nltype)
1529
0
{
1530
0
  switch (nltype) {
1531
0
  case RTM_NEWQDISC:
1532
0
  case RTM_DELQDISC:
1533
0
    return "qdisc";
1534
0
  case RTM_NEWTCLASS:
1535
0
  case RTM_DELTCLASS:
1536
0
    return "tclass";
1537
0
  case RTM_NEWTFILTER:
1538
0
  case RTM_DELTFILTER:
1539
0
    return "tfilter";
1540
0
  default:
1541
0
    /* should never hit */
1542
0
    return "unknown";
1543
0
  }
1544
0
}
1545
1546
static void nlncm_dump(const struct netconfmsg *ncm, size_t msglen)
1547
0
{
1548
0
  const struct rtattr *rta;
1549
0
  size_t plen;
1550
0
  uint32_t ival;
1551
1552
0
  rta = (void *)((const char *)ncm +
1553
0
           NLMSG_ALIGN(sizeof(struct netconfmsg)));
1554
1555
0
next_rta:
1556
  /* Check the attr header for valid length. */
1557
0
  if (RTA_OK(rta, msglen) == 0)
1558
0
    return;
1559
1560
0
  plen = RTA_PAYLOAD(rta);
1561
1562
0
  zlog_debug("    rta [len=%d (payload=%zu) type=(%d) %s]", rta->rta_len,
1563
0
       plen, rta->rta_type, ncm_rta2str(rta->rta_type));
1564
1565
0
  switch (rta->rta_type) {
1566
0
  case NETCONFA_IFINDEX:
1567
0
    ival = *(uint32_t *)RTA_DATA(rta);
1568
0
    zlog_debug("      %d", (int32_t)ival);
1569
0
    break;
1570
1571
  /* Most attrs are just on/off. */
1572
0
  case NETCONFA_FORWARDING:
1573
0
  case NETCONFA_RP_FILTER:
1574
0
  case NETCONFA_MC_FORWARDING:
1575
0
  case NETCONFA_PROXY_NEIGH:
1576
0
  case NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN:
1577
0
  case NETCONFA_INPUT:
1578
0
  case NETCONFA_BC_FORWARDING:
1579
0
    ival = *(uint32_t *)RTA_DATA(rta);
1580
0
    dump_on_off(ival, "      ");
1581
0
    break;
1582
0
  default:
1583
    /* NOTHING: unhandled. */
1584
0
    break;
1585
0
  }
1586
1587
  /* Get next pointer and start iteration again. */
1588
0
  rta = RTA_NEXT(rta, msglen);
1589
0
  goto next_rta;
1590
0
}
1591
1592
void nl_dump(void *msg, size_t msglen)
1593
0
{
1594
0
  struct nlmsghdr *nlmsg = msg;
1595
0
  struct nlmsgerr *nlmsgerr;
1596
0
  struct rtgenmsg *rtgen;
1597
0
  struct ifaddrmsg *ifa;
1598
0
  struct ndmsg *ndm;
1599
0
  struct rtmsg *rtm;
1600
0
  struct nhmsg *nhm;
1601
0
  struct netconfmsg *ncm;
1602
0
  struct ifinfomsg *ifi;
1603
0
  struct tunnel_msg *tnlm;
1604
0
  struct fib_rule_hdr *frh;
1605
0
  struct tcmsg *tcm;
1606
1607
0
  char fbuf[128];
1608
0
  char ibuf[128];
1609
1610
0
next_header:
1611
0
  zlog_debug(
1612
0
    "nlmsghdr [len=%u type=(%d) %s flags=(0x%04x) {%s} seq=%u pid=%u]",
1613
0
    nlmsg->nlmsg_len, nlmsg->nlmsg_type,
1614
0
    nlmsg_type2str(nlmsg->nlmsg_type), nlmsg->nlmsg_flags,
1615
0
    nlmsg_flags2str(nlmsg->nlmsg_flags, fbuf, sizeof(fbuf)),
1616
0
    nlmsg->nlmsg_seq, nlmsg->nlmsg_pid);
1617
1618
0
  switch (nlmsg->nlmsg_type) {
1619
  /* Generic. */
1620
0
  case NLMSG_NOOP:
1621
0
    break;
1622
0
  case NLMSG_ERROR:
1623
0
    nlmsgerr = NLMSG_DATA(nlmsg);
1624
0
    zlog_debug("  nlmsgerr [error=(%d) %s]", nlmsgerr->error,
1625
0
         strerror(-nlmsgerr->error));
1626
0
    break;
1627
0
  case NLMSG_DONE:
1628
0
    return;
1629
0
  case NLMSG_OVERRUN:
1630
0
    break;
1631
1632
  /* RTM. */
1633
0
  case RTM_NEWLINK:
1634
0
  case RTM_DELLINK:
1635
0
  case RTM_SETLINK:
1636
0
    ifi = NLMSG_DATA(nlmsg);
1637
0
    zlog_debug(
1638
0
      "  ifinfomsg [family=%d type=(%d) %s index=%d flags=0x%04x {%s}]",
1639
0
      ifi->ifi_family, ifi->ifi_type,
1640
0
      ifi_type2str(ifi->ifi_type), ifi->ifi_index,
1641
0
      ifi->ifi_flags,
1642
0
      if_flags2str(ifi->ifi_flags, ibuf, sizeof(ibuf)));
1643
0
    nllink_dump(ifi, nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
1644
0
    break;
1645
0
  case RTM_GETLINK:
1646
0
    rtgen = NLMSG_DATA(nlmsg);
1647
0
    zlog_debug("  rtgen [family=(%d) %s]", rtgen->rtgen_family,
1648
0
         af_type2str(rtgen->rtgen_family));
1649
0
    break;
1650
1651
0
  case RTM_NEWROUTE:
1652
0
  case RTM_DELROUTE:
1653
0
  case RTM_GETROUTE:
1654
0
    rtm = NLMSG_DATA(nlmsg);
1655
0
    zlog_debug(
1656
0
      "  rtmsg [family=(%d) %s dstlen=%d srclen=%d tos=%d table=%d protocol=(%d) %s scope=(%d) %s type=(%d) %s flags=0x%04x {%s}]",
1657
0
      rtm->rtm_family, af_type2str(rtm->rtm_family),
1658
0
      rtm->rtm_dst_len, rtm->rtm_src_len, rtm->rtm_tos,
1659
0
      rtm->rtm_table, rtm->rtm_protocol,
1660
0
      rtm_protocol2str(rtm->rtm_protocol), rtm->rtm_scope,
1661
0
      rtm_scope2str(rtm->rtm_scope), rtm->rtm_type,
1662
0
      rtm_type2str(rtm->rtm_type), rtm->rtm_flags,
1663
0
      rtm_flags2str(rtm->rtm_flags, fbuf, sizeof(fbuf)));
1664
0
    nlroute_dump(rtm,
1665
0
           nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*rtm)));
1666
0
    break;
1667
1668
0
  case RTM_NEWNEIGH:
1669
0
  case RTM_DELNEIGH:
1670
0
    ndm = NLMSG_DATA(nlmsg);
1671
0
    zlog_debug(
1672
0
      "  ndm [family=%d (%s) ifindex=%d state=0x%04x {%s} flags=0x%04x {%s} type=%d (%s)]",
1673
0
      ndm->ndm_family, af_type2str(ndm->ndm_family),
1674
0
      ndm->ndm_ifindex, ndm->ndm_state,
1675
0
      neigh_state2str(ndm->ndm_state, ibuf, sizeof(ibuf)),
1676
0
      ndm->ndm_flags,
1677
0
      neigh_flags2str(ndm->ndm_flags, fbuf, sizeof(fbuf)),
1678
0
      ndm->ndm_type, rtm_type2str(ndm->ndm_type));
1679
0
    nlneigh_dump(ndm,
1680
0
           nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*ndm)));
1681
0
    break;
1682
1683
0
  case RTM_NEWRULE:
1684
0
  case RTM_DELRULE:
1685
0
    frh = NLMSG_DATA(nlmsg);
1686
0
    zlog_debug(
1687
0
      "  frh [family=%d (%s) dst_len=%d src_len=%d tos=%d table=%d res1=%d res2=%d action=%d (%s) flags=0x%x]",
1688
0
      frh->family, af_type2str(frh->family), frh->dst_len,
1689
0
      frh->src_len, frh->tos, frh->table, frh->res1,
1690
0
      frh->res2, frh->action, frh_action2str(frh->action),
1691
0
      frh->flags);
1692
0
    nlrule_dump(frh, nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*frh)));
1693
0
    break;
1694
1695
1696
0
  case RTM_NEWADDR:
1697
0
  case RTM_DELADDR:
1698
0
    ifa = NLMSG_DATA(nlmsg);
1699
0
    zlog_debug(
1700
0
      "  ifa [family=(%d) %s prefixlen=%d flags=0x%04x {%s} scope=%d index=%u]",
1701
0
      ifa->ifa_family, af_type2str(ifa->ifa_family),
1702
0
      ifa->ifa_prefixlen, ifa->ifa_flags,
1703
0
      if_flags2str(ifa->ifa_flags, fbuf, sizeof(fbuf)),
1704
0
      ifa->ifa_scope, ifa->ifa_index);
1705
0
    nlifa_dump(ifa, nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
1706
0
    break;
1707
1708
0
  case RTM_NEWNEXTHOP:
1709
0
  case RTM_DELNEXTHOP:
1710
0
  case RTM_GETNEXTHOP:
1711
0
    nhm = NLMSG_DATA(nlmsg);
1712
0
    zlog_debug(
1713
0
      "  nhm [family=(%d) %s scope=(%d) %s protocol=(%d) %s flags=0x%08x {%s}]",
1714
0
      nhm->nh_family, af_type2str(nhm->nh_family),
1715
0
      nhm->nh_scope, rtm_scope2str(nhm->nh_scope),
1716
0
      nhm->nh_protocol, rtm_protocol2str(nhm->nh_protocol),
1717
0
      nhm->nh_flags,
1718
0
      nh_flags2str(nhm->nh_flags, fbuf, sizeof(fbuf)));
1719
0
    nlnh_dump(nhm, nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*nhm)));
1720
0
    break;
1721
1722
0
  case RTM_NEWTUNNEL:
1723
0
  case RTM_DELTUNNEL:
1724
0
  case RTM_GETTUNNEL:
1725
0
    tnlm = NLMSG_DATA(nlmsg);
1726
0
    zlog_debug("  tnlm [family=(%d) %s ifindex=%d ", tnlm->family,
1727
0
         af_type2str(tnlm->family), tnlm->ifindex);
1728
0
    nltnl_dump(tnlm,
1729
0
         nlmsg->nlmsg_len -
1730
0
           NLMSG_LENGTH(sizeof(struct tunnel_msg)));
1731
0
    break;
1732
1733
1734
0
  case RTM_NEWNETCONF:
1735
0
  case RTM_DELNETCONF:
1736
0
    ncm = NLMSG_DATA(nlmsg);
1737
0
    zlog_debug(" ncm [family=%s (%d)]",
1738
0
         af_type2str(ncm->ncm_family), ncm->ncm_family);
1739
0
    nlncm_dump(ncm, nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*ncm)));
1740
0
    break;
1741
1742
0
  case RTM_NEWQDISC:
1743
0
  case RTM_DELQDISC:
1744
0
  case RTM_NEWTCLASS:
1745
0
  case RTM_DELTCLASS:
1746
0
  case RTM_NEWTFILTER:
1747
0
  case RTM_DELTFILTER:
1748
0
    tcm = NLMSG_DATA(nlmsg);
1749
0
    zlog_debug(
1750
0
      " tcm [type=%s family=%s (%d) ifindex=%d handle=%04x:%04x]",
1751
0
      tcm_nltype2str(nlmsg->nlmsg_type),
1752
0
      af_type2str(tcm->tcm_family), tcm->tcm_family,
1753
0
      tcm->tcm_ifindex, tcm->tcm_handle >> 16,
1754
0
      tcm->tcm_handle & 0xffff);
1755
0
    break;
1756
1757
0
  default:
1758
0
    break;
1759
0
  }
1760
1761
  /*
1762
   * Try to get the next header. There should only be more
1763
   * messages if this header was flagged as MULTI, otherwise just
1764
   * end it here.
1765
   */
1766
0
  nlmsg = NLMSG_NEXT(nlmsg, msglen);
1767
0
  if (NLMSG_OK(nlmsg, msglen) == 0)
1768
0
    return;
1769
1770
0
  goto next_header;
1771
0
}
1772
1773
#endif /* NETLINK_DEBUG */