int print_netconf(const struct sockaddr_nl *who, struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; struct netconfmsg *ncm = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NETCONFA_MAX+1]; int ifindex = 0; if (n->nlmsg_type == NLMSG_ERROR) return -1; if (n->nlmsg_type != RTM_NEWNETCONF) { fprintf(stderr, "Not RTM_NEWNETCONF: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return -1; } len -= NLMSG_SPACE(sizeof(*ncm)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (filter.family && filter.family != ncm->ncm_family) return 0; parse_rtattr(tb, NETCONFA_MAX, netconf_rta(ncm), NLMSG_PAYLOAD(n, sizeof(*ncm))); if (tb[NETCONFA_IFINDEX]) ifindex = rta_getattr_u32(tb[NETCONFA_IFINDEX]); if (filter.ifindex && filter.ifindex != ifindex) return 0; switch (ncm->ncm_family) { case AF_INET: fprintf(fp, "ipv4 "); break; case AF_INET6: fprintf(fp, "ipv6 "); break; case AF_MPLS: fprintf(fp, "mpls "); break; default: fprintf(fp, "unknown "); break; } if (tb[NETCONFA_IFINDEX]) { switch (ifindex) { case NETCONFA_IFINDEX_ALL: fprintf(fp, "all "); break; case NETCONFA_IFINDEX_DEFAULT: fprintf(fp, "default "); break; default: fprintf(fp, "dev %s ", ll_index_to_name(ifindex)); break; } } if (tb[NETCONFA_FORWARDING]) print_onoff(fp, "forwarding", rta_getattr_u32(tb[NETCONFA_FORWARDING])); if (tb[NETCONFA_RP_FILTER]) { __u32 rp_filter = rta_getattr_u32(tb[NETCONFA_RP_FILTER]); if (rp_filter == 0) fprintf(fp, "rp_filter off "); else if (rp_filter == 1) fprintf(fp, "rp_filter strict "); else if (rp_filter == 2) fprintf(fp, "rp_filter loose "); else fprintf(fp, "rp_filter unknown mode "); } if (tb[NETCONFA_MC_FORWARDING]) print_onoff(fp, "mc_forwarding", rta_getattr_u32(tb[NETCONFA_MC_FORWARDING])); if (tb[NETCONFA_PROXY_NEIGH]) print_onoff(fp, "proxy_neigh", rta_getattr_u32(tb[NETCONFA_PROXY_NEIGH])); if (tb[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN]) print_onoff(fp, "ignore_routes_with_linkdown", rta_getattr_u32(tb[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN])); if (tb[NETCONFA_INPUT]) print_onoff(fp, "input", rta_getattr_u32(tb[NETCONFA_INPUT])); fprintf(fp, "\n"); fflush(fp); return 0; }
int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = arg; int len = n->nlmsg_len; struct ifinfomsg *ifi = NLMSG_DATA(n); struct rtattr * tb[IFLA_MAX+1]; char b1[IFNAMSIZ]; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) { fprintf(stderr, "Message too short!\n"); return -1; } if (!(ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_UNSPEC)) return 0; if (filter_index && filter_index != ifi->ifi_index) return 0; parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED); if (tb[IFLA_IFNAME] == NULL) { fprintf(stderr, "BUG: nil ifname\n"); return -1; } if (n->nlmsg_type == RTM_DELLINK) fprintf(fp, "Deleted "); fprintf(fp, "%d: %s ", ifi->ifi_index, tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>"); if (tb[IFLA_OPERSTATE]) print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); if (tb[IFLA_LINK]) { SPRINT_BUF(b1); int iflink = rta_getattr_u32(tb[IFLA_LINK]); if (iflink == 0) fprintf(fp, "@NONE: "); else fprintf(fp, "@%s: ", if_indextoname(iflink, b1)); } else fprintf(fp, ": "); print_link_flags(fp, ifi->ifi_flags); if (tb[IFLA_MTU]) fprintf(fp, "mtu %u ", rta_getattr_u32(tb[IFLA_MTU])); if (tb[IFLA_MASTER]) fprintf(fp, "master %s ", if_indextoname(rta_getattr_u32(tb[IFLA_MASTER]), b1)); if (tb[IFLA_PROTINFO]) { if (tb[IFLA_PROTINFO]->rta_type & NLA_F_NESTED) { struct rtattr *prtb[IFLA_BRPORT_MAX+1]; parse_rtattr_nested(prtb, IFLA_BRPORT_MAX, tb[IFLA_PROTINFO]); if (prtb[IFLA_BRPORT_STATE]) print_portstate(fp, rta_getattr_u8(prtb[IFLA_BRPORT_STATE])); if (prtb[IFLA_BRPORT_PRIORITY]) fprintf(fp, "priority %hu ", rta_getattr_u16(prtb[IFLA_BRPORT_PRIORITY])); if (prtb[IFLA_BRPORT_COST]) fprintf(fp, "cost %u ", rta_getattr_u32(prtb[IFLA_BRPORT_COST])); if (show_details) { fprintf(fp, "%s ", _SL_); if (prtb[IFLA_BRPORT_MODE]) print_onoff(fp, "hairpin", rta_getattr_u8(prtb[IFLA_BRPORT_MODE])); if (prtb[IFLA_BRPORT_GUARD]) print_onoff(fp, "guard", rta_getattr_u8(prtb[IFLA_BRPORT_GUARD])); if (prtb[IFLA_BRPORT_PROTECT]) print_onoff(fp, "root_block", rta_getattr_u8(prtb[IFLA_BRPORT_PROTECT])); if (prtb[IFLA_BRPORT_FAST_LEAVE]) print_onoff(fp, "fastleave", rta_getattr_u8(prtb[IFLA_BRPORT_FAST_LEAVE])); if (prtb[IFLA_BRPORT_LEARNING]) print_onoff(fp, "learning", rta_getattr_u8(prtb[IFLA_BRPORT_LEARNING])); if (prtb[IFLA_BRPORT_LEARNING_SYNC]) print_onoff(fp, "learning_sync", rta_getattr_u8(prtb[IFLA_BRPORT_LEARNING_SYNC])); if (prtb[IFLA_BRPORT_UNICAST_FLOOD]) print_onoff(fp, "flood", rta_getattr_u8(prtb[IFLA_BRPORT_UNICAST_FLOOD])); } } else print_portstate(fp, rta_getattr_u8(tb[IFLA_PROTINFO])); } if (tb[IFLA_AF_SPEC]) { /* This is reported by HW devices that have some bridging * capabilities. */ struct rtattr *aftb[IFLA_BRIDGE_MAX+1]; parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]); if (aftb[IFLA_BRIDGE_MODE]) print_hwmode(fp, rta_getattr_u16(aftb[IFLA_BRIDGE_MODE])); } fprintf(fp, "\n"); fflush(fp); return 0; }