2 * Copyright (c) 2018 Rafael Zalamena
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.
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.
19 #if defined(HAVE_NETLINK) && defined(NETLINK_DEBUG)
21 #include <sys/socket.h>
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>
34 #include "zebra/rt_netlink.h"
35 #include "zebra/kernel_netlink.h"
37 const char *nlmsg_type2str(uint16_t type
)
96 return "RTM_NEWNETCONF";
98 return "RTM_DELNETCONF";
105 const char *af_type2str(int type
)
125 return "AF_BLUETOOTH";
137 const char *ifi_type2str(int type
)
156 case ARPHRD_APPLETLK
:
162 case ARPHRD_METRICOM
:
164 case ARPHRD_IEEE1394
:
168 case ARPHRD_INFINIBAND
:
204 case ARPHRD_LOOPBACK
:
206 case ARPHRD_LOCALTLK
:
234 case ARPHRD_FCFABRIC
:
236 case ARPHRD_IEEE802_TR
:
238 case ARPHRD_IEEE80211
:
240 case ARPHRD_IEEE80211_PRISM
:
241 return "IEEE80211_PRISM";
242 case ARPHRD_IEEE80211_RADIOTAP
:
243 return "IEEE80211_RADIOTAP";
244 case ARPHRD_IEEE802154
:
246 #ifdef ARPHRD_VSOCKMON
247 case ARPHRD_VSOCKMON
:
249 #endif /* ARPHRD_VSOCKMON */
259 const char *ifla_pdr_type2str(int type
)
262 case IFLA_PROTO_DOWN_REASON_UNSPEC
:
264 case IFLA_PROTO_DOWN_REASON_MASK
:
266 case IFLA_PROTO_DOWN_REASON_VALUE
:
273 const char *ifla_info_type2str(int type
)
276 case IFLA_INFO_UNSPEC
:
282 case IFLA_INFO_XSTATS
:
284 case IFLA_INFO_SLAVE_KIND
:
286 case IFLA_INFO_SLAVE_DATA
:
293 const char *rta_type2str(int type
)
334 case IFLA_NET_NS_PID
:
340 case IFLA_VFINFO_LIST
:
341 return "VFINFO_LIST";
356 case IFLA_PROMISCUITY
:
357 return "PROMISCUITY";
358 case IFLA_NUM_TX_QUEUES
:
359 return "NUM_TX_QUEUES";
360 case IFLA_NUM_RX_QUEUES
:
361 return "NUM_RX_QUEUES";
364 case IFLA_PHYS_PORT_ID
:
365 return "PHYS_PORT_ID";
366 case IFLA_CARRIER_CHANGES
:
367 return "CARRIER_CHANGES";
368 case IFLA_PHYS_SWITCH_ID
:
369 return "PHYS_SWITCH_ID";
370 case IFLA_LINK_NETNSID
:
371 return "LINK_NETNSID";
372 case IFLA_PHYS_PORT_NAME
:
373 return "PHYS_PORT_NAME";
374 case IFLA_PROTO_DOWN
:
376 #ifdef IFLA_GSO_MAX_SEGS
377 case IFLA_GSO_MAX_SEGS
:
378 return "GSO_MAX_SEGS";
379 #endif /* IFLA_GSO_MAX_SEGS */
380 #ifdef IFLA_GSO_MAX_SIZE
381 case IFLA_GSO_MAX_SIZE
:
382 return "GSO_MAX_SIZE";
383 #endif /* IFLA_GSO_MAX_SIZE */
387 #endif /* IFLA_PAD */
391 #endif /* IFLA_XDP */
395 #endif /* IFLA_EVENT */
396 case IFLA_PROTO_DOWN_REASON
:
397 return "PROTO_DOWN_REASON";
403 const char *rtm_type2str(int type
)
420 case RTN_UNREACHABLE
:
421 return "UNREACHABLE";
435 const char *rtm_protocol2str(int type
)
440 case RTPROT_REDIRECT
:
464 case RTPROT_DNROUTED
:
481 const char *rtm_scope2str(int type
)
484 case RT_SCOPE_UNIVERSE
:
492 case RT_SCOPE_NOWHERE
:
499 const char *rtm_rta2str(int type
)
543 const char *neigh_rta2str(int type
)
566 case NDA_LINK_NETNSID
:
567 return "LINK_NETNSID";
573 const char *ifa_rta2str(int type
)
599 const char *nhm_rta2str(int type
)
629 const char *frh_rta2str(int type
)
656 case FRA_SUPPRESS_IFGROUP
:
657 return "SUPPRESS_IFGROUP";
658 case FRA_SUPPRESS_PREFIXLEN
:
659 return "SUPPRESS_PREFIXLEN";
676 case FRA_SPORT_RANGE
:
677 return "SPORT_RANGE";
678 case FRA_DPORT_RANGE
:
679 return "DPORT_RANGE";
685 const char *frh_action2str(uint8_t action
)
698 case FR_ACT_BLACKHOLE
:
700 case FR_ACT_UNREACHABLE
:
701 return "UNREACHABLE";
702 case FR_ACT_PROHIBIT
:
709 static const char *ncm_rta2str(int type
)
712 case NETCONFA_UNSPEC
:
714 case NETCONFA_IFINDEX
:
716 case NETCONFA_FORWARDING
:
718 case NETCONFA_RP_FILTER
:
720 case NETCONFA_MC_FORWARDING
:
722 case NETCONFA_PROXY_NEIGH
:
723 return "PROXY_NEIGH";
724 case NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN
:
725 return "IGNORE_LINKDOWN";
728 case NETCONFA_BC_FORWARDING
:
735 static void dump_on_off(uint32_t ival
, const char *prefix
)
737 zlog_debug("%s%s", prefix
, (ival
!= 0) ? "on" : "off");
740 static inline void flag_write(int flags
, int flag
, const char *flagstr
,
741 char *buf
, size_t buflen
)
743 if (CHECK_FLAG(flags
, flag
) == 0)
747 strlcat(buf
, ",", buflen
);
749 strlcat(buf
, flagstr
, buflen
);
752 const char *nlmsg_flags2str(uint16_t flags
, char *buf
, size_t buflen
)
754 const char *bufp
= buf
;
757 /* Specific flags. */
758 flag_write(flags
, NLM_F_REQUEST
, "REQUEST", buf
, buflen
);
759 flag_write(flags
, NLM_F_MULTI
, "MULTI", buf
, buflen
);
760 flag_write(flags
, NLM_F_ACK
, "ACK", buf
, buflen
);
761 flag_write(flags
, NLM_F_ECHO
, "ECHO", buf
, buflen
);
762 flag_write(flags
, NLM_F_DUMP
, "DUMP", buf
, buflen
);
764 /* Netlink family type dependent. */
765 flag_write(flags
, 0x0100, "(ROOT|REPLACE|CAPPED)", buf
, buflen
);
766 flag_write(flags
, 0x0200, "(MATCH|EXCLUDE|ACK_TLVS)", buf
, buflen
);
767 flag_write(flags
, 0x0400, "(ATOMIC|CREATE)", buf
, buflen
);
768 flag_write(flags
, 0x0800, "(DUMP|APPEND)", buf
, buflen
);
773 const char *if_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
775 const char *bufp
= buf
;
778 flag_write(flags
, IFF_UP
, "UP", buf
, buflen
);
779 flag_write(flags
, IFF_BROADCAST
, "BROADCAST", buf
, buflen
);
780 flag_write(flags
, IFF_DEBUG
, "DEBUG", buf
, buflen
);
781 flag_write(flags
, IFF_LOOPBACK
, "LOOPBACK", buf
, buflen
);
782 flag_write(flags
, IFF_POINTOPOINT
, "POINTOPOINT", buf
, buflen
);
783 flag_write(flags
, IFF_NOTRAILERS
, "NOTRAILERS", buf
, buflen
);
784 flag_write(flags
, IFF_RUNNING
, "RUNNING", buf
, buflen
);
785 flag_write(flags
, IFF_NOARP
, "NOARP", buf
, buflen
);
786 flag_write(flags
, IFF_PROMISC
, "PROMISC", buf
, buflen
);
787 flag_write(flags
, IFF_ALLMULTI
, "ALLMULTI", buf
, buflen
);
788 flag_write(flags
, IFF_MASTER
, "MASTER", buf
, buflen
);
789 flag_write(flags
, IFF_SLAVE
, "SLAVE", buf
, buflen
);
790 flag_write(flags
, IFF_MULTICAST
, "MULTICAST", buf
, buflen
);
791 flag_write(flags
, IFF_PORTSEL
, "PORTSEL", buf
, buflen
);
792 flag_write(flags
, IFF_AUTOMEDIA
, "AUTOMEDIA", buf
, buflen
);
793 flag_write(flags
, IFF_DYNAMIC
, "DYNAMIC", buf
, buflen
);
798 const char *rtm_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
800 const char *bufp
= buf
;
803 flag_write(flags
, RTM_F_NOTIFY
, "NOTIFY", buf
, buflen
);
804 flag_write(flags
, RTM_F_CLONED
, "CLONED", buf
, buflen
);
805 flag_write(flags
, RTM_F_EQUALIZE
, "EQUALIZE", buf
, buflen
);
810 const char *neigh_state2str(uint32_t flags
, char *buf
, size_t buflen
)
812 const char *bufp
= buf
;
815 flag_write(flags
, NUD_INCOMPLETE
, "INCOMPLETE", buf
, buflen
);
816 flag_write(flags
, NUD_REACHABLE
, "REACHABLE", buf
, buflen
);
817 flag_write(flags
, NUD_STALE
, "STALE", buf
, buflen
);
818 flag_write(flags
, NUD_DELAY
, "DELAY", buf
, buflen
);
819 flag_write(flags
, NUD_PROBE
, "PROBE", buf
, buflen
);
820 flag_write(flags
, NUD_FAILED
, "FAILED", buf
, buflen
);
821 flag_write(flags
, NUD_NOARP
, "NOARP", buf
, buflen
);
822 flag_write(flags
, NUD_PERMANENT
, "PERMANENT", buf
, buflen
);
827 const char *neigh_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
829 const char *bufp
= buf
;
832 flag_write(flags
, NTF_USE
, "USE", buf
, buflen
);
833 flag_write(flags
, NTF_SELF
, "SELF", buf
, buflen
);
834 flag_write(flags
, NTF_MASTER
, "MASTER", buf
, buflen
);
835 flag_write(flags
, NTF_PROXY
, "PROXY", buf
, buflen
);
836 flag_write(flags
, NTF_EXT_LEARNED
, "EXT_LEARNED", buf
, buflen
);
838 flag_write(flags
, NTF_OFFLOADED
, "OFFLOADED", buf
, buflen
);
839 #endif /* NTF_OFFLOADED */
840 flag_write(flags
, NTF_ROUTER
, "ROUTER", buf
, buflen
);
845 const char *ifa_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
847 const char *bufp
= buf
;
850 flag_write(flags
, IFA_F_SECONDARY
, "SECONDARY", buf
, buflen
);
851 flag_write(flags
, IFA_F_NODAD
, "NODAD", buf
, buflen
);
852 flag_write(flags
, IFA_F_OPTIMISTIC
, "OPTIMISTIC", buf
, buflen
);
853 flag_write(flags
, IFA_F_DADFAILED
, "DADFAILED", buf
, buflen
);
854 flag_write(flags
, IFA_F_HOMEADDRESS
, "HOMEADDRESS", buf
, buflen
);
855 flag_write(flags
, IFA_F_DEPRECATED
, "DEPRECATED", buf
, buflen
);
856 flag_write(flags
, IFA_F_TENTATIVE
, "TENTATIVE", buf
, buflen
);
857 flag_write(flags
, IFA_F_PERMANENT
, "PERMANENT", buf
, buflen
);
858 flag_write(flags
, IFA_F_MANAGETEMPADDR
, "MANAGETEMPADDR", buf
, buflen
);
859 flag_write(flags
, IFA_F_NOPREFIXROUTE
, "NOPREFIXROUTE", buf
, buflen
);
860 flag_write(flags
, IFA_F_MCAUTOJOIN
, "MCAUTOJOIN", buf
, buflen
);
861 flag_write(flags
, IFA_F_STABLE_PRIVACY
, "STABLE_PRIVACY", buf
, buflen
);
866 const char *nh_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
868 const char *bufp
= buf
;
871 flag_write(flags
, RTNH_F_DEAD
, "DEAD", buf
, buflen
);
872 flag_write(flags
, RTNH_F_PERVASIVE
, "PERVASIVE", buf
, buflen
);
873 flag_write(flags
, RTNH_F_ONLINK
, "ONLINK", buf
, buflen
);
874 flag_write(flags
, RTNH_F_OFFLOAD
, "OFFLOAD", buf
, buflen
);
875 flag_write(flags
, RTNH_F_LINKDOWN
, "LINKDOWN", buf
, buflen
);
876 flag_write(flags
, RTNH_F_UNRESOLVED
, "UNRESOLVED", buf
, buflen
);
882 * Netlink abstractions.
884 static void nllink_pdr_dump(struct rtattr
*rta
, size_t msglen
)
890 /* Check the header for valid length and for outbound access. */
891 if (RTA_OK(rta
, msglen
) == 0)
894 plen
= RTA_PAYLOAD(rta
);
895 zlog_debug(" linkinfo [len=%d (payload=%zu) type=(%d) %s]",
896 rta
->rta_len
, plen
, rta
->rta_type
,
897 ifla_pdr_type2str(rta
->rta_type
));
898 switch (rta
->rta_type
) {
899 case IFLA_PROTO_DOWN_REASON_MASK
:
900 case IFLA_PROTO_DOWN_REASON_VALUE
:
901 if (plen
< sizeof(uint32_t)) {
902 zlog_debug(" invalid length");
906 u32v
= *(uint32_t *)RTA_DATA(rta
);
907 zlog_debug(" %u", u32v
);
911 /* NOTHING: unhandled. */
915 /* Get next pointer and start iteration again. */
916 rta
= RTA_NEXT(rta
, msglen
);
920 static void nllink_linkinfo_dump(struct rtattr
*rta
, size_t msglen
)
926 /* Check the header for valid length and for outbound access. */
927 if (RTA_OK(rta
, msglen
) == 0)
930 plen
= RTA_PAYLOAD(rta
);
931 zlog_debug(" linkinfo [len=%d (payload=%zu) type=(%d) %s]",
932 rta
->rta_len
, plen
, rta
->rta_type
,
933 ifla_info_type2str(rta
->rta_type
));
934 switch (rta
->rta_type
) {
937 zlog_debug(" invalid length");
941 snprintf(dbuf
, sizeof(dbuf
), "%s", (char *)RTA_DATA(rta
));
942 zlog_debug(" %s", dbuf
);
944 case IFLA_INFO_SLAVE_KIND
:
946 zlog_debug(" invalid length");
950 snprintf(dbuf
, sizeof(dbuf
), "%s", (char *)RTA_DATA(rta
));
951 zlog_debug(" %s", dbuf
);
955 /* NOTHING: unhandled. */
959 /* Get next pointer and start iteration again. */
960 rta
= RTA_NEXT(rta
, msglen
);
964 static void nllink_dump(struct ifinfomsg
*ifi
, size_t msglen
)
973 unsigned short rta_type
;
975 /* Get the first attribute and go from there. */
978 /* Check the header for valid length and for outbound access. */
979 if (RTA_OK(rta
, msglen
) == 0)
982 plen
= RTA_PAYLOAD(rta
);
983 rta_type
= rta
->rta_type
& ~NLA_F_NESTED
;
984 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
985 plen
, rta_type
, rta_type2str(rta_type
));
989 zlog_debug(" invalid length");
993 snprintf(dbuf
, sizeof(dbuf
), "%s", (char *)RTA_DATA(rta
));
994 zlog_debug(" %s", dbuf
);
999 case IFLA_NUM_TX_QUEUES
:
1000 case IFLA_NUM_RX_QUEUES
:
1002 case IFLA_PROMISCUITY
:
1003 #ifdef IFLA_GSO_MAX_SEGS
1004 case IFLA_GSO_MAX_SEGS
:
1005 #endif /* IFLA_GSO_MAX_SEGS */
1006 #ifdef IFLA_GSO_MAX_SIZE
1007 case IFLA_GSO_MAX_SIZE
:
1008 #endif /* IFLA_GSO_MAX_SIZE */
1009 case IFLA_CARRIER_CHANGES
:
1012 if (plen
< sizeof(uint32_t)) {
1013 zlog_debug(" invalid length");
1017 u32v
= *(uint32_t *)RTA_DATA(rta
);
1018 zlog_debug(" %u", u32v
);
1021 case IFLA_PROTO_DOWN
:
1022 if (plen
< sizeof(uint8_t)) {
1023 zlog_debug(" invalid length");
1027 u8v
= *(uint8_t *)RTA_DATA(rta
);
1028 zlog_debug(" %u", u8v
);
1031 datap
= RTA_DATA(rta
);
1033 for (it
= 0; it
< plen
; it
++) {
1034 snprintf(bytestr
, sizeof(bytestr
), "%02X:", *datap
);
1035 strlcat(dbuf
, bytestr
, sizeof(dbuf
));
1038 /* Remove trailing ':'. */
1040 dbuf
[strlen(dbuf
) - 1] = 0;
1042 zlog_debug(" %s", dbuf
[0] ? dbuf
: "<empty>");
1046 nllink_linkinfo_dump(RTA_DATA(rta
), plen
);
1049 case IFLA_PROTO_DOWN_REASON
:
1050 nllink_pdr_dump(RTA_DATA(rta
), plen
);
1054 /* NOTHING: unhandled. */
1058 /* Get next pointer and start iteration again. */
1059 rta
= RTA_NEXT(rta
, msglen
);
1063 static void nlroute_dump(struct rtmsg
*rtm
, size_t msglen
)
1069 /* Get the first attribute and go from there. */
1072 /* Check the header for valid length and for outbound access. */
1073 if (RTA_OK(rta
, msglen
) == 0)
1076 plen
= RTA_PAYLOAD(rta
);
1077 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
1078 plen
, rta
->rta_type
, rtm_rta2str(rta
->rta_type
));
1079 switch (rta
->rta_type
) {
1085 u32v
= *(uint32_t *)RTA_DATA(rta
);
1086 zlog_debug(" %u", u32v
);
1094 case sizeof(struct in_addr
):
1096 (struct in_addr
*)RTA_DATA(rta
));
1098 case sizeof(struct in6_addr
):
1100 (struct in6_addr
*)RTA_DATA(rta
));
1108 /* NOTHING: unhandled. */
1112 /* Get next pointer and start iteration again. */
1113 rta
= RTA_NEXT(rta
, msglen
);
1117 static void nlneigh_dump(struct ndmsg
*ndm
, size_t msglen
)
1125 unsigned short rta_type
;
1128 #define NDA_RTA(ndm) \
1129 /* struct ndmsg *ndm; */ \
1130 ((struct rtattr *)(((uint8_t *)(ndm)) \
1131 + NLMSG_ALIGN(sizeof(struct ndmsg))))
1132 #endif /* NDA_RTA */
1134 /* Get the first attribute and go from there. */
1137 /* Check the header for valid length and for outbound access. */
1138 if (RTA_OK(rta
, msglen
) == 0)
1141 plen
= RTA_PAYLOAD(rta
);
1142 rta_type
= rta
->rta_type
& ~NLA_F_NESTED
;
1143 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
1144 plen
, rta
->rta_type
, neigh_rta2str(rta_type
));
1147 datap
= RTA_DATA(rta
);
1149 for (it
= 0; it
< plen
; it
++) {
1150 snprintf(bytestr
, sizeof(bytestr
), "%02X:", *datap
);
1151 strlcat(dbuf
, bytestr
, sizeof(dbuf
));
1154 /* Remove trailing ':'. */
1156 dbuf
[strlen(dbuf
) - 1] = 0;
1158 zlog_debug(" %s", dbuf
[0] ? dbuf
: "<empty>");
1163 case sizeof(struct in_addr
):
1165 (struct in_addr
*)RTA_DATA(rta
));
1167 case sizeof(struct in6_addr
):
1169 (struct in6_addr
*)RTA_DATA(rta
));
1177 vid
= *(uint16_t *)RTA_DATA(rta
);
1178 zlog_debug(" %d", vid
);
1182 /* NOTHING: unhandled. */
1186 /* Get next pointer and start iteration again. */
1187 rta
= RTA_NEXT(rta
, msglen
);
1191 static void nlifa_dump(struct ifaddrmsg
*ifa
, size_t msglen
)
1197 /* Get the first attribute and go from there. */
1200 /* Check the header for valid length and for outbound access. */
1201 if (RTA_OK(rta
, msglen
) == 0)
1204 plen
= RTA_PAYLOAD(rta
);
1205 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
1206 plen
, rta
->rta_type
, ifa_rta2str(rta
->rta_type
));
1207 switch (rta
->rta_type
) {
1209 u32v
= *(uint32_t *)RTA_DATA(rta
);
1210 zlog_debug(" %u", u32v
);
1214 zlog_debug(" %s", (const char *)RTA_DATA(rta
));
1223 (struct in_addr
*)RTA_DATA(rta
));
1227 (struct in6_addr
*)RTA_DATA(rta
));
1235 /* NOTHING: unhandled. */
1239 /* Get next pointer and start iteration again. */
1240 rta
= RTA_NEXT(rta
, msglen
);
1244 static const char *lwt_type2str(uint16_t type
)
1247 case LWTUNNEL_ENCAP_NONE
:
1249 case LWTUNNEL_ENCAP_MPLS
:
1251 case LWTUNNEL_ENCAP_IP
:
1253 case LWTUNNEL_ENCAP_ILA
:
1255 case LWTUNNEL_ENCAP_IP6
:
1257 case LWTUNNEL_ENCAP_SEG6
:
1259 case LWTUNNEL_ENCAP_BPF
:
1261 case LWTUNNEL_ENCAP_SEG6_LOCAL
:
1262 return "SEG6_LOCAL";
1268 static const char *nhg_type2str(uint16_t type
)
1271 case NEXTHOP_GRP_TYPE_MPATH
:
1273 case NEXTHOP_GRP_TYPE_RES
:
1274 return "RESILIENT MULTIPATH";
1280 static void nlnh_dump(struct nhmsg
*nhm
, size_t msglen
)
1287 unsigned long count
, i
;
1288 struct nexthop_grp
*nhgrp
;
1289 unsigned short rta_type
;
1294 /* Check the header for valid length and for outbound access. */
1295 if (RTA_OK(rta
, msglen
) == 0)
1298 plen
= RTA_PAYLOAD(rta
);
1299 rta_type
= rta
->rta_type
& ~NLA_F_NESTED
;
1300 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
1301 plen
, rta
->rta_type
, nhm_rta2str(rta_type
));
1304 u32v
= *(uint32_t *)RTA_DATA(rta
);
1305 zlog_debug(" %u", u32v
);
1308 nhgrp
= (struct nexthop_grp
*)RTA_DATA(rta
);
1309 count
= (RTA_PAYLOAD(rta
) / sizeof(*nhgrp
));
1311 || (count
* sizeof(*nhgrp
)) != RTA_PAYLOAD(rta
)) {
1312 zlog_debug(" invalid nexthop group received");
1316 for (i
= 0; i
< count
; i
++)
1317 zlog_debug(" id %d weight %d", nhgrp
[i
].id
,
1320 case NHA_ENCAP_TYPE
:
1321 u16v
= *(uint16_t *)RTA_DATA(rta
);
1322 zlog_debug(" %s", lwt_type2str(u16v
));
1324 case NHA_GROUP_TYPE
:
1325 u16v
= *(uint16_t *)RTA_DATA(rta
);
1326 zlog_debug(" %s", nhg_type2str(u16v
));
1332 ifindex
= *(int *)RTA_DATA(rta
);
1333 zlog_debug(" %d", ifindex
);
1336 switch (nhm
->nh_family
) {
1339 (struct in_addr
*)RTA_DATA(rta
));
1343 (struct in6_addr
*)RTA_DATA(rta
));
1347 zlog_debug(" invalid family %d", nhm
->nh_family
);
1352 /* TODO: handle MPLS labels. */
1353 zlog_debug(" unparsed MPLS labels");
1356 /* TODO: handle this message. */
1357 zlog_debug(" unparsed GROUPS message");
1361 /* NOTHING: unhandled. */
1365 /* Get next pointer and start iteration again. */
1366 rta
= RTA_NEXT(rta
, msglen
);
1370 static void nlrule_dump(struct fib_rule_hdr
*frh
, size_t msglen
)
1379 struct fib_rule_uid_range
*u_range
;
1380 struct fib_rule_port_range
*p_range
;
1382 /* Get the first attribute and go from there. */
1385 /* Check the header for valid length and for outbound access. */
1386 if (RTA_OK(rta
, msglen
) == 0)
1389 plen
= RTA_PAYLOAD(rta
);
1390 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
1391 plen
, rta
->rta_type
, frh_rta2str(rta
->rta_type
));
1392 switch (rta
->rta_type
) {
1396 case sizeof(struct in_addr
):
1398 (struct in_addr
*)RTA_DATA(rta
));
1400 case sizeof(struct in6_addr
):
1402 (struct in6_addr
*)RTA_DATA(rta
));
1411 snprintf(dbuf
, sizeof(dbuf
), "%s", (char *)RTA_DATA(rta
));
1412 zlog_debug(" %s", dbuf
);
1425 u32v
= *(uint32_t *)RTA_DATA(rta
);
1426 zlog_debug(" %u", u32v
);
1429 case FRA_SUPPRESS_IFGROUP
:
1430 case FRA_SUPPRESS_PREFIXLEN
:
1431 s32v
= *(int32_t *)RTA_DATA(rta
);
1432 zlog_debug(" %d", s32v
);
1436 u64v
= *(uint64_t *)RTA_DATA(rta
);
1437 zlog_debug(" %" PRIu64
, u64v
);
1443 u8v
= *(uint8_t *)RTA_DATA(rta
);
1444 zlog_debug(" %u", u8v
);
1448 u_range
= (struct fib_rule_uid_range
*)RTA_DATA(rta
);
1449 if (u_range
->start
== u_range
->end
)
1450 zlog_debug(" %u", u_range
->start
);
1452 zlog_debug(" %u-%u", u_range
->start
, u_range
->end
);
1455 case FRA_SPORT_RANGE
:
1456 case FRA_DPORT_RANGE
:
1457 p_range
= (struct fib_rule_port_range
*)RTA_DATA(rta
);
1458 if (p_range
->start
== p_range
->end
)
1459 zlog_debug(" %u", p_range
->start
);
1461 zlog_debug(" %u-%u", p_range
->start
, p_range
->end
);
1464 case FRA_PAD
: /* fallthrough */
1466 /* NOTHING: unhandled. */
1470 /* Get next pointer and start iteration again. */
1471 rta
= RTA_NEXT(rta
, msglen
);
1475 static void nlncm_dump(const struct netconfmsg
*ncm
, size_t msglen
)
1477 const struct rtattr
*rta
;
1481 rta
= (void *)((const char *)ncm
+
1482 NLMSG_ALIGN(sizeof(struct netconfmsg
)));
1485 /* Check the attr header for valid length. */
1486 if (RTA_OK(rta
, msglen
) == 0)
1489 plen
= RTA_PAYLOAD(rta
);
1491 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
1492 plen
, rta
->rta_type
, ncm_rta2str(rta
->rta_type
));
1494 switch (rta
->rta_type
) {
1495 case NETCONFA_IFINDEX
:
1496 ival
= *(uint32_t *)RTA_DATA(rta
);
1497 zlog_debug(" %d", (int32_t)ival
);
1500 /* Most attrs are just on/off. */
1501 case NETCONFA_FORWARDING
:
1502 case NETCONFA_RP_FILTER
:
1503 case NETCONFA_MC_FORWARDING
:
1504 case NETCONFA_PROXY_NEIGH
:
1505 case NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN
:
1506 case NETCONFA_INPUT
:
1507 case NETCONFA_BC_FORWARDING
:
1508 ival
= *(uint32_t *)RTA_DATA(rta
);
1509 dump_on_off(ival
, " ");
1512 /* NOTHING: unhandled. */
1516 /* Get next pointer and start iteration again. */
1517 rta
= RTA_NEXT(rta
, msglen
);
1521 void nl_dump(void *msg
, size_t msglen
)
1523 struct nlmsghdr
*nlmsg
= msg
;
1524 struct nlmsgerr
*nlmsgerr
;
1525 struct rtgenmsg
*rtgen
;
1526 struct ifaddrmsg
*ifa
;
1530 struct netconfmsg
*ncm
;
1531 struct ifinfomsg
*ifi
;
1532 struct fib_rule_hdr
*frh
;
1538 "nlmsghdr [len=%u type=(%d) %s flags=(0x%04x) {%s} seq=%u pid=%u]",
1539 nlmsg
->nlmsg_len
, nlmsg
->nlmsg_type
,
1540 nlmsg_type2str(nlmsg
->nlmsg_type
), nlmsg
->nlmsg_flags
,
1541 nlmsg_flags2str(nlmsg
->nlmsg_flags
, fbuf
, sizeof(fbuf
)),
1542 nlmsg
->nlmsg_seq
, nlmsg
->nlmsg_pid
);
1544 switch (nlmsg
->nlmsg_type
) {
1549 nlmsgerr
= NLMSG_DATA(nlmsg
);
1550 zlog_debug(" nlmsgerr [error=(%d) %s]", nlmsgerr
->error
,
1551 strerror(-nlmsgerr
->error
));
1562 ifi
= NLMSG_DATA(nlmsg
);
1564 " ifinfomsg [family=%d type=(%d) %s index=%d flags=0x%04x {%s}]",
1565 ifi
->ifi_family
, ifi
->ifi_type
,
1566 ifi_type2str(ifi
->ifi_type
), ifi
->ifi_index
,
1568 if_flags2str(ifi
->ifi_flags
, ibuf
, sizeof(ibuf
)));
1569 nllink_dump(ifi
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
1572 rtgen
= NLMSG_DATA(nlmsg
);
1573 zlog_debug(" rtgen [family=(%d) %s]", rtgen
->rtgen_family
,
1574 af_type2str(rtgen
->rtgen_family
));
1580 rtm
= NLMSG_DATA(nlmsg
);
1582 " 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}]",
1583 rtm
->rtm_family
, af_type2str(rtm
->rtm_family
),
1584 rtm
->rtm_dst_len
, rtm
->rtm_src_len
, rtm
->rtm_tos
,
1585 rtm
->rtm_table
, rtm
->rtm_protocol
,
1586 rtm_protocol2str(rtm
->rtm_protocol
), rtm
->rtm_scope
,
1587 rtm_scope2str(rtm
->rtm_scope
), rtm
->rtm_type
,
1588 rtm_type2str(rtm
->rtm_type
), rtm
->rtm_flags
,
1589 rtm_flags2str(rtm
->rtm_flags
, fbuf
, sizeof(fbuf
)));
1591 nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*rtm
)));
1596 ndm
= NLMSG_DATA(nlmsg
);
1598 " ndm [family=%d (%s) ifindex=%d state=0x%04x {%s} flags=0x%04x {%s} type=%d (%s)]",
1599 ndm
->ndm_family
, af_type2str(ndm
->ndm_family
),
1600 ndm
->ndm_ifindex
, ndm
->ndm_state
,
1601 neigh_state2str(ndm
->ndm_state
, ibuf
, sizeof(ibuf
)),
1603 neigh_flags2str(ndm
->ndm_flags
, fbuf
, sizeof(fbuf
)),
1604 ndm
->ndm_type
, rtm_type2str(ndm
->ndm_type
));
1606 nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ndm
)));
1611 frh
= NLMSG_DATA(nlmsg
);
1613 " frh [family=%d (%s) dst_len=%d src_len=%d tos=%d table=%d res1=%d res2=%d action=%d (%s) flags=0x%x]",
1614 frh
->family
, af_type2str(frh
->family
), frh
->dst_len
,
1615 frh
->src_len
, frh
->tos
, frh
->table
, frh
->res1
,
1616 frh
->res2
, frh
->action
, frh_action2str(frh
->action
),
1618 nlrule_dump(frh
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*frh
)));
1624 ifa
= NLMSG_DATA(nlmsg
);
1626 " ifa [family=(%d) %s prefixlen=%d flags=0x%04x {%s} scope=%d index=%u]",
1627 ifa
->ifa_family
, af_type2str(ifa
->ifa_family
),
1628 ifa
->ifa_prefixlen
, ifa
->ifa_flags
,
1629 if_flags2str(ifa
->ifa_flags
, fbuf
, sizeof(fbuf
)),
1630 ifa
->ifa_scope
, ifa
->ifa_index
);
1631 nlifa_dump(ifa
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
1634 case RTM_NEWNEXTHOP
:
1635 case RTM_DELNEXTHOP
:
1636 case RTM_GETNEXTHOP
:
1637 nhm
= NLMSG_DATA(nlmsg
);
1639 " nhm [family=(%d) %s scope=(%d) %s protocol=(%d) %s flags=0x%08x {%s}]",
1640 nhm
->nh_family
, af_type2str(nhm
->nh_family
),
1641 nhm
->nh_scope
, rtm_scope2str(nhm
->nh_scope
),
1642 nhm
->nh_protocol
, rtm_protocol2str(nhm
->nh_protocol
),
1644 nh_flags2str(nhm
->nh_flags
, fbuf
, sizeof(fbuf
)));
1645 nlnh_dump(nhm
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*nhm
)));
1648 case RTM_NEWNETCONF
:
1649 case RTM_DELNETCONF
:
1650 ncm
= NLMSG_DATA(nlmsg
);
1651 zlog_debug(" ncm [family=%s (%d)]",
1652 af_type2str(ncm
->ncm_family
), ncm
->ncm_family
);
1653 nlncm_dump(ncm
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ncm
)));
1661 * Try to get the next header. There should only be more
1662 * messages if this header was flagged as MULTI, otherwise just
1665 nlmsg
= NLMSG_NEXT(nlmsg
, msglen
);
1666 if (NLMSG_OK(nlmsg
, msglen
) == 0)
1672 #endif /* NETLINK_DEBUG */