back to topotato report
topotato coverage report
Current view: top level - zebra - debug_nl.c (source / functions) Hit Total Coverage
Test: test_bgp_dont_capability_negotiate.py::BGPDontCapabilityNegotiate Lines: 0 1143 0.0 %
Date: 2023-02-24 18:37:16 Functions: 0 37 0.0 %

          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 */

Generated by: LCOV version v1.16-topotato