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