/* * debug hfsc options */ void debug_tca_options_hfsc(int lev, struct rtattr *tca, const char *name) { struct tc_hfsc_qopt *qopt; struct rtattr *hfsc[__TCA_HFSC_MAX]; rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tca->rta_len)); if(RTA_PAYLOAD(tca) == sizeof(*qopt)) { qopt = (struct tc_hfsc_qopt *)RTA_DATA(tca); rec_dbg(lev, " [ tc_hfsc_qopt(%d) ]", sizeof(*qopt)); rec_dbg(lev, " defcls(%d): 0x%x", sizeof(qopt->defcls), qopt->defcls); return; } parse_nested_rtattr(hfsc, TCA_HFSC_MAX, tca); if(hfsc[TCA_HFSC_RSC]) debug_tca_hfsc_sc(lev+1, hfsc[TCA_HFSC_RSC], "TCA_HFSC_RSC"); if(hfsc[TCA_HFSC_FSC]) debug_tca_hfsc_sc(lev+1, hfsc[TCA_HFSC_FSC], "TCA_HFSC_FSC"); if(hfsc[TCA_HFSC_USC]) debug_tca_hfsc_sc(lev+1, hfsc[TCA_HFSC_USC], "TCA_HFSC_USC"); }
/* * debug attribute TCA_ACT_OPTIONS */ void debug_tca_act_options(int lev, struct rtattr *act, const char *name, char *kind, int len) { rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(act->rta_len)); if(!strncmp(kind, "police", len)) debug_tca_act_options_police(lev, act, NULL); else if(!strncmp(kind, "gact", len)) debug_tca_act_options_gact(lev, act); else if(!strncmp(kind, "pedit", len)) debug_tca_act_options_pedit(lev, act); else if(!strncmp(kind, "mirred", len)) debug_tca_act_options_mirred(lev, act); #ifdef HAVE_LINUX_TC_ACT_TC_NAT_H else if(!strncmp(kind, "nat", len)) debug_tca_act_options_nat(lev, act); #endif #ifdef HAVE_LINUX_TC_ACT_TC_SKBEDIT_H else if(!strncmp(kind, "skbedit", len)) debug_tca_act_options_skbedit(lev, act); #endif #ifdef HAVE_LINUX_TC_ACT_TC_CSUM_H else if(!strncmp(kind, "csum", len)) debug_tca_act_options_csum(lev, act); #endif else rec_dbg(lev, " -- unknown action %s --", kind); }
/* * debug string attribute */ void debug_rta_str(int lev, struct rtattr *rta, const char *name, char *str, unsigned len) { if(RTA_PAYLOAD(rta) > len) { rec_dbg(lev, "%s(%hu): -- payload too long --", name, RTA_ALIGN(rta->rta_len)); return; } char *p = (char *)malloc(len); if(p == NULL) return; memset(p, 0, len); /* always p[len] == NULL */ strncpy(p, (char *)RTA_DATA(rta), len - 1); rec_dbg(lev, "%s(%hu): %s", name, RTA_ALIGN(rta->rta_len), p); if(str) strncpy(str, p, len); free(p); return; }
/* * debug attribute RTA_CACHEINFO */ void debug_rta_cacheinfo(int lev, struct rtattr *rta, const char *name) { struct rta_cacheinfo *rtac; if(debug_rta_len_chk(lev, rta, name, sizeof(*rtac))) return; rtac = (struct rta_cacheinfo *)RTA_DATA(rta); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(rta->rta_len)); rec_dbg(lev, " [ rta_cacheinfo(%d) ]", sizeof(*rtac)); rec_dbg(lev, " rta_clntref(%d): %u", sizeof(rtac->rta_clntref), rtac->rta_clntref); rec_dbg(lev, " rta_lastuse(%d): %u", sizeof(rtac->rta_lastuse), rtac->rta_lastuse); rec_dbg(lev, " rta_expires(%d): %d", sizeof(rtac->rta_expires), rtac->rta_expires); rec_dbg(lev, " rta_error(%d): %u", sizeof(rtac->rta_error), rtac->rta_error); rec_dbg(lev, " rta_used(%d): %u", sizeof(rtac->rta_used), rtac->rta_used); rec_dbg(lev, " rta_id(%d): %u", sizeof(rtac->rta_id), rtac->rta_id); rec_dbg(lev, " rta_ts(%d): %u", sizeof(rtac->rta_ts), rtac->rta_ts); rec_dbg(lev, " rta_tsage(%d): %u", sizeof(rtac->rta_tsage), rtac->rta_tsage); }
/* * debug attribute TCA_EM_META_HDR */ struct tcf_meta_hdr *debug_tca_em_meta_hdr(int lev, struct rtattr *meta, const char *name) { struct tcf_meta_hdr *hdr; struct tcf_meta_val *left, *right; if(debug_rta_len_chk(lev, meta, name, sizeof(*hdr))) return(NULL); hdr = (struct tcf_meta_hdr *)RTA_DATA(meta); left = &(hdr->left); right = &(hdr->right); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(meta->rta_len)); rec_dbg(lev, " [ tcf_meta_hdr(%d) ]", sizeof(*hdr)); rec_dbg(lev, " [ tcf_meta_val left(%d) ]", sizeof(*left)); rec_dbg(lev, " kind(%d): 0x%04x(%s,%s)", sizeof(left->kind), left->kind, conv_tcf_meta_type(TCF_META_TYPE(left->kind), 1), conv_tcf_meta_id(TCF_META_ID(left->kind), 1)); rec_dbg(lev, " shift(%d): %d", sizeof(left->shift), left->shift); rec_dbg(lev, " op(%d): %d(%s)", sizeof(left->op), left->op, conv_tcf_em_opnd(left->op, 1)); rec_dbg(lev, " [ tcf_meta_val right(%d) ]", sizeof(*right)); rec_dbg(lev, " kind(%d): 0x%04x(%s,%s)", sizeof(right->kind), right->kind, conv_tcf_meta_type(TCF_META_TYPE(right->kind), 1), conv_tcf_meta_id(TCF_META_ID(right->kind), 1)); rec_dbg(lev, " shift(%d): %d", sizeof(right->shift), right->shift); rec_dbg(lev, " op(%d): %d(%s)", sizeof(right->op), right->op, conv_tcf_em_opnd(right->op, 1)); return(hdr); }
/* * debug prio options */ void debug_tca_options_prio(int lev, struct rtattr *tca, const char *name) { struct tc_prio_qopt *qopt; char prio[MAX_STR_SIZE] = ""; char *p = prio; int i, len = sizeof(prio); if(debug_rta_len_chk(lev, tca, name, sizeof(*qopt))) return; qopt = (struct tc_prio_qopt *)RTA_DATA(tca); for(i = 0; i < TC_PRIO_MAX + 1; i++) { if(i == TC_PRIO_MAX) APPEND_SNPRINTF(rc, p, len, "%d ", qopt->priomap[i]); else APPEND_SNPRINTF(rc, p, len, "%d-", qopt->priomap[i]); } if (p - prio == sizeof(prio)) { rec_dbg(lev, "%s(%hu): -- priomap too long --", name, RTA_ALIGN(tca->rta_len)); return; } rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tca->rta_len)); rec_dbg(lev, " [ tc_prio_qopt(%d) ]", sizeof(*qopt)); rec_dbg(lev, " bands(%d): %d", sizeof(qopt->bands), qopt->bands); rec_dbg(lev, " priomap(%d): %s", sizeof(qopt->priomap), prio); }
/* * debug tcf_t */ void debug_tcf_t(int lev, struct tcf_t *tm) { rec_dbg(lev, "[ tcf_t(%d) ]", sizeof(*tm)); rec_dbg(lev, " install(%d): 0x%016x", sizeof(tm->install), tm->install); rec_dbg(lev, " lastuse(%d): 0x%016x", sizeof(tm->lastuse), tm->lastuse); rec_dbg(lev, " expires(%d): 0x%016x", sizeof(tm->expires), tm->expires); }
/* * debug traffic control action message */ void debug_tcamsg(int lev, struct tcamsg *tcam, struct rtattr *tcaa[], int tcam_len) { /* debug tcamsg */ rec_dbg(lev, "*********************************************************************"); rec_dbg(lev, "[ tcamsg(%d) ]", NLMSG_ALIGN(sizeof(*tcam))); rec_dbg(lev, " tca_family(%d): 0x%02x(%s)", sizeof(tcam->tca_family), tcam->tca_family, conv_af_type(tcam->tca_family, 1)); rec_dbg(lev, " tca__pad1(%d): 0x%02x", sizeof(tcam->tca__pad1), tcam->tca__pad1); rec_dbg(lev, " tca__pad2(%d): 0x%04x", sizeof(tcam->tca__pad2), tcam->tca__pad2); /* debug traffic control action attributes */ rec_dbg(lev,"*********************************************************************"); rec_dbg(lev, "[ tcamsg attributes(%d) ]", NLMSG_ALIGN(tcam_len - NLMSG_ALIGN(sizeof(*tcam)))); if(tcaa[TCA_ACT_TAB]) debug_tca_acts(lev+1, tcaa[TCA_ACT_TAB], "TCA_ACT_TAB"); rec_dbg(lev, ""); }
/* * debug tc_qfq_xstats */ void debug_tc_qfq_xstats(int lev, struct rtattr *tca, const char *name) { struct tc_qfq_stats *stats; if(debug_rta_len_chk(lev, tca, name, sizeof(*stats))) return; stats = (struct tc_qfq_stats *)RTA_DATA(tca); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tca->rta_len)); rec_dbg(lev, " [ tc_qfq_stats(%d) ]", sizeof(*stats)); rec_dbg(lev, " weight(%d): %u", sizeof(stats->weight), stats->weight); rec_dbg(lev, " lmax(%d): %u", sizeof(stats->lmax), stats->lmax); }
/* * debug attributes of multiple actions */ void debug_tca_acts(int lev, struct rtattr *tcaa, const char *name) { struct rtattr *acts[TCA_ACT_MAX_PRIO+1]; int i; rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tcaa->rta_len)); parse_nested_rtattr(acts, TCA_ACT_MAX_PRIO, tcaa); for(i = 0; i < TCA_ACT_MAX_PRIO; i++) if(acts[i]) { rec_dbg(lev+1, "acts[%hu](%hu):", acts[i]->rta_type, acts[i]->rta_len); debug_tca_act(lev+1, acts[i]); } }
/* * debug attribute TCA_NETEM_CORR */ void debug_tca_netem_corr(int lev, struct rtattr *netem, const char *name) { struct tc_netem_corr *corr; if(debug_rta_len_chk(lev, netem, name, sizeof(*corr))) return; corr = (struct tc_netem_corr *)RTA_DATA(netem); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(netem->rta_len)); rec_dbg(lev, " [ tc_netem_corr(%d) ]", sizeof(*corr)); rec_dbg(lev, " delay_corr(%d): %u", sizeof(corr->delay_corr), corr->delay_corr); rec_dbg(lev, " loss_corr(%d): %u", sizeof(corr->loss_corr), corr->loss_corr); rec_dbg(lev, " dup_corr(%d): %u", sizeof(corr->dup_corr), corr->dup_corr); }
/* * debug attribute TCA_HFSC_*SC */ void debug_tca_hfsc_sc(int lev, struct rtattr *hfsc, const char *name) { struct tc_service_curve *sc; if(debug_rta_len_chk(lev, hfsc, name, sizeof(*sc))) return; sc = (struct tc_service_curve *)RTA_DATA(hfsc); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(hfsc->rta_len)); rec_dbg(lev, " [ tc_service_curve(%d) ]", sizeof(*sc)); rec_dbg(lev, " m1(%d): %u", sizeof(sc->m1), sc->m1); rec_dbg(lev, " d(%d): %u", sizeof(sc->d), sc->d); rec_dbg(lev, " m2(%d): %u", sizeof(sc->m2), sc->m2); }
/* * debug attribute */ void debug_rta_tc_addr(int lev, struct tcmsg *tcm, struct rtattr *rta, const char *name) { char addr[INET6_ADDRSTRLEN+1] = ""; int res; res = inet_ntop_tc_addr(tcm, rta, addr, sizeof(addr)); if(res) { rec_dbg(lev, "%s(%hu): -- %s --", name, RTA_ALIGN(rta->rta_len), (res == 1) ? strerror(errno) : "payload too short"); return; } rec_dbg(lev, "%s(%hu): %s", name, RTA_ALIGN(rta->rta_len), addr); }
/* * debug attribute RTA_METRICS */ void debug_rta_metrics(int lev, struct rtattr *rta, const char *name) { struct rtattr *rtax[RTAX_MAX+1]; rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(rta->rta_len)); parse_rtattr(rtax, RTAX_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)); if(rtax[RTAX_LOCK]) debug_rta_u32(lev+1, rtax[RTAX_LOCK], "RTAX_LOCK", NULL); if(rtax[RTAX_MTU]) debug_rta_u32(lev+1, rtax[RTAX_MTU], "RTAX_MTU", NULL); if(rtax[RTAX_ADVMSS]) debug_rta_u32(lev+1, rtax[RTAX_ADVMSS], "RTAX_ADVMSS", NULL); if(rtax[RTAX_HOPLIMIT]) debug_rta_s32(lev+1, rtax[RTAX_HOPLIMIT], "RTAX_HOPLIMIT", NULL); if(rtax[RTAX_WINDOW]) debug_rta_u32(lev+1, rtax[RTAX_WINDOW], "RTAX_WINDOW", NULL); }
/* * debug attribute TCA_NETEM_REORDER */ void debug_tca_netem_reorder(int lev, struct rtattr *netem, const char *name) { struct tc_netem_reorder *reorder; if(debug_rta_len_chk(lev, netem, name, sizeof(*reorder))) return; reorder = (struct tc_netem_reorder *)RTA_DATA(netem); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(netem->rta_len)); rec_dbg(lev, " [ tc_netem_reorder(%d) ]", sizeof(*reorder)); rec_dbg(lev, " probability(%d): %u", sizeof(reorder->probability), reorder->probability); rec_dbg(lev, " correlation(%d): %u", sizeof(reorder->correlation), reorder->correlation); }
/* * debug int attribute */ void debug_rta_s32x(int lev, struct rtattr *rta, const char *name, const char *(*conv)(int num, unsigned char debug)) { if(debug_rta_len_chk(lev, rta, name, sizeof(int))) return; int data = *(int *)RTA_DATA(rta); if(conv) rec_dbg(lev, "%s(%hu): 0x%08x(%s)", name, RTA_ALIGN(rta->rta_len), data, conv(data, 1)); else rec_dbg(lev, "%s(%hu): 0x%08x", name, RTA_ALIGN(rta->rta_len), data); return; }
/* * debug unsigned short attribute */ void debug_rta_u16(int lev, struct rtattr *rta, const char *name, const char *(*conv)(unsigned short num, unsigned char debug)) { if(debug_rta_len_chk(lev, rta, name, sizeof(unsigned short))) return; unsigned short data = *(unsigned short *)RTA_DATA(rta); if(conv) rec_dbg(lev, "%s(%hu): %hu(%s)", name, RTA_ALIGN(rta->rta_len), data, conv(data, 1)); else rec_dbg(lev, "%s(%hu): %hu", name, RTA_ALIGN(rta->rta_len), data); return; }
/* * debug attribute TCA_NETEM_CORRUPT */ void debug_tca_netem_corrupt(int lev, struct rtattr *netem, const char *name) { struct tc_netem_corrupt *corrupt; if(debug_rta_len_chk(lev, netem, name, sizeof(*corrupt))) return; corrupt = (struct tc_netem_corrupt *)RTA_DATA(netem); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(netem->rta_len)); rec_dbg(lev, " [ tc_netem_corrupt(%d) ]", sizeof(*corrupt)); rec_dbg(lev, " probability(%d): %u", sizeof(corrupt->probability), corrupt->probability); rec_dbg(lev, " correlation(%d): %u", sizeof(corrupt->correlation), corrupt->correlation); }
/* * debug rsvp options */ void debug_tca_options_rsvp(int lev, struct tcmsg *tcm, struct rtattr *tca, const char *name) { struct rtattr *rsvp[__TCA_RSVP_MAX]; rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tca->rta_len)); parse_nested_rtattr(rsvp, TCA_RSVP_MAX, tca); if(rsvp[TCA_RSVP_CLASSID]) debug_tca_classid(lev+1, rsvp[TCA_RSVP_CLASSID], "TCA_RSVP_CLASSID"); if(rsvp[TCA_RSVP_DST]) debug_rta_tc_addr(lev+1, tcm, rsvp[TCA_RSVP_DST], "TCA_RSVP_DST"); if(rsvp[TCA_RSVP_SRC]) debug_rta_tc_addr(lev+1, tcm, rsvp[TCA_RSVP_SRC], "TCA_RSVP_SRC"); if(rsvp[TCA_RSVP_PINFO]) debug_tca_rsvp_pinfo(lev+1, rsvp[TCA_RSVP_PINFO], "TCA_RSVP_PINFO"); if(rsvp[TCA_RSVP_POLICE]) debug_tca_act_options_police(lev+1, rsvp[TCA_RSVP_POLICE], "TCA_RSVP_POLICE"); if(rsvp[TCA_RSVP_ACT]) debug_tca_acts(lev+1, rsvp[TCA_RSVP_ACT], "TCA_RSVP_ACT"); }
/* * debug attribute TCA_EMATCH_TREE_HDR */ int debug_tca_ematch_tree_hdr(int lev, struct rtattr *em_tree, const char *name) { struct tcf_ematch_tree_hdr *hdr; if(debug_rta_len_chk(lev, em_tree, name, sizeof(*hdr))) return(-1); hdr = (struct tcf_ematch_tree_hdr *)RTA_DATA(em_tree); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(em_tree->rta_len)); rec_dbg(lev, " [ tcf_ematch_tree_hdr(%d) ]", sizeof(*hdr)); rec_dbg(lev, " nmatches(%d): %hu", sizeof(hdr->nmatches), hdr->nmatches); rec_dbg(lev, " progid(%d): %hu", sizeof(hdr->progid), hdr->progid); return(hdr->nmatches); }
/* * debug netem options */ void debug_tca_options_netem(int lev, struct rtattr *tca, const char *name) { struct rtattr *netem[__TCA_NETEM_MAX]; struct tc_netem_qopt *qopt; if(debug_rta_len_chk(lev, tca, name, sizeof(*qopt))) return; qopt = (struct tc_netem_qopt *)RTA_DATA(tca); rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tca->rta_len)); rec_dbg(lev, " [ tc_netem_qopt(%d) ]", sizeof(*qopt)); rec_dbg(lev, " latency(%d): %u", sizeof(qopt->latency), qopt->latency); rec_dbg(lev, " limit(%d): %u", sizeof(qopt->limit), qopt->limit); rec_dbg(lev, " loss(%d): %u", sizeof(qopt->loss), qopt->loss); rec_dbg(lev, " gap(%d): %u", sizeof(qopt->gap), qopt->gap); rec_dbg(lev, " duplicate(%d): %u", sizeof(qopt->duplicate), qopt->duplicate); rec_dbg(lev, " jitter(%d): %u", sizeof(qopt->jitter), qopt->jitter); parse_rtattr(netem, TCA_NETEM_MAX, RTA_DATA(tca) + sizeof(struct tc_netem_qopt), RTA_PAYLOAD(tca) - sizeof(struct tc_netem_qopt)); if(netem[TCA_NETEM_CORR]) debug_tca_netem_corr(lev+1, netem[TCA_NETEM_CORR], "TCA_NETEM_CORR"); if(netem[TCA_NETEM_DELAY_DIST]) debug_rta_ignore(lev+1, netem[TCA_NETEM_DELAY_DIST], "TCA_NETEM_DELAY_DIST"); if(netem[TCA_NETEM_REORDER]) debug_tca_netem_reorder(lev+1, netem[TCA_NETEM_REORDER], "TCA_NETEM_REORDER"); if(netem[TCA_NETEM_CORRUPT]) debug_tca_netem_corrupt(lev+1, netem[TCA_NETEM_CORRUPT], "TCA_NETEM_CORRUPT"); #if HAVE_DECL_TCA_NETEM_LOSS if(netem[TCA_NETEM_LOSS]) debug_tca_netem_loss(lev+1, netem[TCA_NETEM_LOSS], "TCA_NETEM_LOSS"); #endif #if HAVE_DECL_TCA_NETEM_RATE if(netem[TCA_NETEM_RATE]) debug_tca_netem_rate(lev+1, netem[TCA_NETEM_RATE], "TCA_NETEM_RATE"); #endif #if HAVE_DECL_TCA_NETEM_ECN if(netem[TCA_NETEM_ECN]) debug_rta_u32(lev+1, netem[TCA_NETEM_ECN], "TCA_NETEM_ECN", NULL); #endif }
/* * debug ARPHRD_* address attribute */ void debug_rta_arphrd(int lev, struct rtattr *rta, const char *name, unsigned short type) { char addr[INET6_ADDRSTRLEN+1] = ""; int res; res = arphrd_ntop(type, rta, addr, sizeof(addr)); if(res) { rec_dbg(lev, "%s(%hu): -- %s --", name, RTA_ALIGN(rta->rta_len), (res == 1) ? strerror(errno) : "payload too short"); return; } rec_dbg(lev, "%s(%hu): %s", name, RTA_ALIGN(rta->rta_len), addr); return; }
/* * debug ematch nbyte */ void debug_ematch_nbyte(int lev, void *p, int len) { struct tcf_em_nbyte *nbyte; int i; char *data; if(len < sizeof(struct tcf_em_nbyte)) { rec_dbg(lev, "[ tcf_em_nbyte(%d) ] -- payload too short --", len); return; } nbyte = (struct tcf_em_nbyte *)p; rec_dbg(lev, "[ tcf_em_nbyte(%d) ]", len); rec_dbg(lev, " off(%d): %hu", sizeof(nbyte->off), nbyte->off); rec_dbg(lev, " len:12(%d): %hu", sizeof(__u16), nbyte->len); rec_dbg(lev, " layer:4(%d): %hu", sizeof(__u8), nbyte->layer); if(len - sizeof(*nbyte) < nbyte->len) { rec_dbg(lev, " data(%d): -- payload too short --", nbyte->len); return; } data = (char *)nbyte + sizeof(*nbyte); for(i = 0; i < nbyte->len; i++) data[i] = isprint(data[i]) ? data[i] : '.'; data[i] = '\0'; rec_dbg(lev, " data(%d): %s", nbyte->len, data); }
/* * check attribute payload length for debug */ int debug_rta_len_chk(int lev, struct rtattr *rta, const char *name, size_t len) { if(RTA_PAYLOAD(rta) < len) { rec_dbg(lev, "%s(%hu): -- payload too short --", name, RTA_ALIGN(rta->rta_len)); return(1); } return(0); }
/* * debug flow options */ void debug_tca_options_flow(int lev, struct rtattr *tca, const char *name) { struct rtattr *flow[__TCA_FLOW_MAX]; rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tca->rta_len)); parse_nested_rtattr(flow, TCA_FLOW_MAX, tca); if(flow[TCA_FLOW_KEYS]) debug_rta_u32(lev+1, flow[TCA_FLOW_KEYS], "TCA_FLOW_KEYS", conv_flow_key); if(flow[TCA_FLOW_MODE]) debug_rta_u32(lev+1, flow[TCA_FLOW_MODE], "TCA_FLOW_MODE", conv_flow_mode); if(flow[TCA_FLOW_BASECLASS]) debug_tca_classid(lev+1, flow[TCA_FLOW_BASECLASS], "TCA_FLOW_BASECLASS"); if(flow[TCA_FLOW_RSHIFT]) debug_rta_u32(lev+1, flow[TCA_FLOW_RSHIFT], "TCA_FLOW_RSHIT", NULL); if(flow[TCA_FLOW_ADDEND]) debug_rta_u32x(lev+1, flow[TCA_FLOW_ADDEND], "TCA_FLOW_ADDEND", NULL); if(flow[TCA_FLOW_MASK]) debug_rta_u32x(lev+1, flow[TCA_FLOW_MASK], "TCA_FLOW_MASK", NULL); if(flow[TCA_FLOW_XOR]) debug_rta_u32x(lev+1, flow[TCA_FLOW_XOR], "TCA_FLOW_XOR", NULL); if(flow[TCA_FLOW_DIVISOR]) debug_rta_u32(lev+1, flow[TCA_FLOW_DIVISOR], "TCA_FLOW_DIVISOR", NULL); if(flow[TCA_FLOW_ACT]) debug_tca_acts(lev+1, flow[TCA_FLOW_ACT], "TCA_FLOW_ACT"); if(flow[TCA_FLOW_POLICE]) debug_tca_act_options_police(lev+1, flow[TCA_FLOW_POLICE], "TCA_FLOW_POLICE"); if(flow[TCA_FLOW_EMATCHES]) debug_tca_ematch(lev+1, flow[TCA_FLOW_EMATCHES], "TCA_FLOW_EMATCHES"); if(flow[TCA_FLOW_PERTURB]) debug_rta_u32(lev+1, flow[TCA_FLOW_PERTURB], "TCA_FLOW_PERTURB", NULL); }
/* * debug attribute TCA_EM_META_LVALUE */ void debug_tca_em_meta_value(int lev, struct rtattr *meta, const char *name, struct tcf_meta_val *p) { int i, type, len = RTA_PAYLOAD(meta) + 1; char *data = (char *)RTA_DATA(meta), *val; type = TCF_META_TYPE(p->kind); switch(type) { case TCF_META_TYPE_VAR: val = malloc(len); if(!val) { rec_dbg(lev, "%s(%hu): -- %s --", name, RTA_ALIGN(meta->rta_len), strerror(errno)); return; } memset(val, 0, len); for(i = 0; i < RTA_PAYLOAD(meta); i++) val[i] = isprint(data[i]) ? data[i] : '.'; data[i] = '\0'; rec_dbg(lev, "%s(%hu): %s", name, RTA_ALIGN(meta->rta_len), data); free(val); break; case TCF_META_TYPE_INT: if(RTA_PAYLOAD(meta) < sizeof(__u32)) { rec_dbg(lev, "%s(%hu): -- payload too short --", name, RTA_ALIGN(meta->rta_len)); return; } rec_dbg(lev, "%s(%hu): %d", name, RTA_ALIGN(meta->rta_len), *(int *)RTA_DATA(meta)); break; default: rec_dbg(lev, "%s(%hu): -- unknown type(%d) --", name, RTA_ALIGN(meta->rta_len), type); return; } }
/* * debug sfb options */ void debug_tca_options_sfb(int lev, struct rtattr *tca, const char *name) { struct rtattr *sfb[__TCA_SFB_MAX]; rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(tca->rta_len)); parse_nested_rtattr(sfb, TCA_SFB_MAX, tca); if(sfb[TCA_SFB_PARMS]) debug_tca_sfb_parms(lev+1, sfb[TCA_SFB_PARMS], "TCA_SFB_PARMS"); }
/* * debug attribute RTA_MULTIPATH */ void debug_rta_multipath(int lev, struct rtmsg *rtm, struct rtattr *rta, const char *name) { struct rtnexthop *rtnh; int rtnh_len = RTA_PAYLOAD(rta); struct rtattr *rtnha[__RTA_MAX]; char ifname[IFNAMSIZ] = ""; char flags_list[MAX_STR_SIZE] = ""; if(debug_rta_len_chk(lev, rta, name, sizeof(*rtnh))) return; rec_dbg(lev, "%s(%hu):", name, RTA_ALIGN(rta->rta_len)); for(rtnh = RTA_DATA(rta); RTNH_OK(rtnh, rtnh_len); rtnh = RTNH_NEXT(rtnh), rtnh_len -= RTNH_ALIGN(rtnh->rtnh_len)) { conv_rtnh_flags(rtnh->rtnh_flags, flags_list, sizeof(flags_list)); if_indextoname_from_lists(rtnh->rtnh_ifindex, ifname); rec_dbg(lev, " [ rtnexthop(%d) ]", sizeof(*rtnh)); rec_dbg(lev, " rtnh_len(%d): %hu", sizeof(rtnh->rtnh_len), rtnh->rtnh_len); rec_dbg(lev, " rtnh_flags(%d): %d(%s)", sizeof(rtnh->rtnh_flags), rtnh->rtnh_flags, flags_list); rec_dbg(lev, " rtnh_hops(%d): %d", sizeof(rtnh->rtnh_hops), rtnh->rtnh_hops); rec_dbg(lev, " rtnh_ifindex(%d): %d(%s)", sizeof(rtnh->rtnh_ifindex), rtnh->rtnh_ifindex, ifname); parse_rtattr(rtnha, RTA_MAX, RTNH_DATA(rtnh), rtnh->rtnh_len - sizeof(*rtnh)); if(rtnha[RTA_GATEWAY]) debug_rta_af(lev+3, rtnha[RTA_GATEWAY], "RTA_GATEWAY", rtm->rtm_family); } }
/* * debug interface index attribute */ void debug_rta_ifindex(int lev, struct rtattr *rta, const char *name) { unsigned ifindex; char ifname[IFNAMSIZ] = ""; if(debug_rta_len_chk(lev, rta, name, sizeof(unsigned))) return; ifindex = *(unsigned *)RTA_DATA(rta); if_indextoname_from_lists(ifindex, ifname); rec_dbg(lev, "%s(%hu): %u(%s)", name, RTA_ALIGN(rta->rta_len), ifindex, ifname); return; }
/* * debug attribute TCA_*_CLASSID */ void debug_tca_classid(int lev, struct rtattr *tca, const char *name) { unsigned n_classid; char s_classid[MAX_STR_SIZE] = ""; if(debug_rta_len_chk(lev, tca, name, sizeof(n_classid))) return; n_classid = *(unsigned *)RTA_DATA(tca); parse_tc_handle(s_classid, sizeof(s_classid), n_classid); rec_dbg(lev, "%s(%hu): 0x%08x(%s)", name, RTA_ALIGN(tca->rta_len), n_classid, s_classid); }