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