/* * parse traffic control message */ int parse_tcamsg(struct nlmsghdr *nlh) { struct tcamsg *tcam; int tcam_len; struct rtattr *tcaa[TCAA_MAX+1]; char msg[MAX_MSG_SIZE] = ""; char *mp = msg; int log_opts = get_log_opts(); /* debug nlmsghdr */ if(log_opts & L_DEBUG) debug_nlmsg(0, nlh); /* get tcamsg */ tcam_len = NLMSG_PAYLOAD(nlh, 0); if(tcam_len < sizeof(*tcam)) { rec_log("error: %s: length too short", __func__); return(1); } tcam = (struct tcamsg *)NLMSG_DATA(nlh); /* parse traffic control action message attributes */ parse_tca(tcaa, nlh); /* debug tcamsg */ if(log_opts & L_DEBUG) debug_tcamsg(0, tcam, tcaa, tcam_len); /* kind of message */ switch(nlh->nlmsg_type) { case RTM_NEWACTION: mp = add_log(msg, mp, "tc action added: "); break; case RTM_DELACTION: mp = add_log(msg, mp, "tc action deleted: "); break; default: return(1); } if(tcaa[TCA_ACT_TAB]) if(parse_tca_acts(msg, mp, tcaa[TCA_ACT_TAB])) return(1); return(0); }
/* * parse rsvp options */ int parse_tca_options_rsvp(char *msg, char **mp, struct tcmsg *tcm, struct rtattr *tca) { struct rtattr *rsvp[__TCA_RSVP_MAX]; char *mp_tmp = *mp; parse_nested_rtattr(rsvp, TCA_RSVP_MAX, tca); if(rsvp[TCA_RSVP_CLASSID]) if(parse_tca_classid(msg, mp, rsvp[TCA_RSVP_CLASSID])) return(1); if(rsvp[TCA_RSVP_DST]) if(parse_tca_rsvp_dst(msg, mp, tcm, rsvp[TCA_RSVP_DST])) return(1); if(rsvp[TCA_RSVP_SRC]) if(parse_tca_rsvp_src(msg, mp, tcm, rsvp[TCA_RSVP_SRC])) return(1); if(rsvp[TCA_RSVP_PINFO]) if(parse_tca_rsvp_pinfo(msg, mp, rsvp[TCA_RSVP_PINFO])) return(1); if(*mp != mp_tmp) rec_log("%s", msg); /* rollback pointer */ *mp = mp_tmp; /* logging for each attribute below */ if(rsvp[TCA_RSVP_POLICE]) if(parse_tca_act_options_police(msg, *mp, rsvp[TCA_RSVP_POLICE])) return(1); if(rsvp[TCA_RSVP_ACT]) if(parse_tca_acts(msg, *mp, rsvp[TCA_RSVP_ACT])) return(1); return(0); }
/* * parse flow options */ int parse_tca_options_flow(char *msg, char **mp, struct rtattr *tca) { struct rtattr *flow[__TCA_FLOW_MAX]; char *mp_tmp = *mp; parse_nested_rtattr(flow, TCA_FLOW_MAX, tca); if(flow[TCA_FLOW_BASECLASS]) if(parse_tca_classid(msg, mp, flow[TCA_FLOW_BASECLASS])) return(1); if(flow[TCA_FLOW_KEYS]) if(parse_tca_flow_keys(msg, mp, flow[TCA_FLOW_KEYS])) return(1); if(flow[TCA_FLOW_MODE]) if(parse_tca_flow_mode(msg, mp, flow[TCA_FLOW_MODE])) return(1); if(flow[TCA_FLOW_MASK]) if(parse_tca_mask(msg, mp, flow[TCA_FLOW_MASK])) return(1); if(flow[TCA_FLOW_XOR]) if(parse_tca_flow_xor(msg, mp, flow[TCA_FLOW_XOR])) return(1); if(flow[TCA_FLOW_RSHIFT]) if(parse_tca_flow_rshift(msg, mp, flow[TCA_FLOW_RSHIFT])) return(1); if(flow[TCA_FLOW_ADDEND]) if(parse_tca_flow_addend(msg, mp, flow[TCA_FLOW_ADDEND])) return(1); if(flow[TCA_FLOW_DIVISOR]) if(parse_tca_flow_divisor(msg, mp, flow[TCA_FLOW_DIVISOR])) return(1); if(flow[TCA_FLOW_PERTURB]) if(parse_tca_flow_perturb(msg, mp, flow[TCA_FLOW_PERTURB])) return(1); if(*mp != mp_tmp) rec_log("%s", msg); /* rollback pointer */ *mp = mp_tmp; /* logging for each attribute below */ if(flow[TCA_FLOW_EMATCHES]) if(parse_tca_ematch(msg, *mp, flow[TCA_FLOW_EMATCHES])) return(1); if(flow[TCA_FLOW_POLICE]) if(parse_tca_act_options_police(msg, *mp, flow[TCA_FLOW_POLICE])) return(1); if(flow[TCA_FLOW_ACT]) if(parse_tca_acts(msg, *mp, flow[TCA_FLOW_ACT])) return(1); return(0); }