int rio_interface_parser(const char *ifname, int argc, char **argv) { u_int bandwidth = 100000000; /* 100Mbps */ u_int tbrsize = 0; int weight = 0; /* 0: use default */ int lo_inv_pmax = 0; /* 0: use default */ int lo_th_min = 0; /* 0: use default */ int lo_th_max = 0; /* 0: use default */ int med_inv_pmax = 0; /* 0: use default */ int med_th_min = 0; /* 0: use default */ int med_th_max = 0; /* 0: use default */ int hi_inv_pmax = 0; /* 0: use default */ int hi_th_min = 0; /* 0: use default */ int hi_th_max = 0; /* 0: use default */ int qlimit = 60; int pkttime = 0; int flags = 0; int packet_size = 1000; /* * process options */ while (argc > 0) { if (EQUAL(*argv, "bandwidth")) { argc--; argv++; if (argc > 0) bandwidth = atobps(*argv); } else if (EQUAL(*argv, "tbrsize")) { argc--; argv++; if (argc > 0) tbrsize = atobytes(*argv); } else if (EQUAL(*argv, "packetsize")) { argc--; argv++; if (argc > 0) packet_size = atobytes(*argv); } else if (EQUAL(*argv, "weight")) { argc--; argv++; if (argc > 0) weight = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "qlimit")) { argc--; argv++; if (argc > 0) qlimit = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "lo_thmin")) { argc--; argv++; if (argc > 0) lo_th_min = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "lo_thmax")) { argc--; argv++; if (argc > 0) lo_th_max = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "lo_invpmax")) { argc--; argv++; if (argc > 0) lo_inv_pmax = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "med_thmin")) { argc--; argv++; if (argc > 0) med_th_min = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "med_thmax")) { argc--; argv++; if (argc > 0) med_th_max = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "med_invpmax")) { argc--; argv++; if (argc > 0) med_inv_pmax = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "hi_thmin")) { argc--; argv++; if (argc > 0) hi_th_min = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "hi_thmax")) { argc--; argv++; if (argc > 0) hi_th_max = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "hi_invpmax")) { argc--; argv++; if (argc > 0) hi_inv_pmax = (int)strtol(*argv, NULL, 0); } else if (EQUAL(*argv, "rio")) { /* just skip */ } else if (EQUAL(*argv, "ecn")) { flags |= RIOF_ECN; } else { LOG(LOG_ERR, 0, "Unknown keyword '%s'", *argv); return (0); } argc--; argv++; } if (qcmd_tbr_register(ifname, bandwidth, tbrsize) != 0) return (0); pkttime = packet_size * 8 * 1000 / (bandwidth / 1000); if (weight != 0) { /* check if weight is power of 2 */ int i, w; w = weight; for (i = 0; w > 1; i++) w = w >> 1; w = 1 << i; if (weight != w) { LOG(LOG_ERR, 0, "weight %d: should be power of 2", weight); return (0); } }
/* * recursively parse '<'tc_action'>' * note that array "action" grows during recursive parse. */ static int tc_action_parser(char *ifname, char **cpp, struct tc_action *action) { char *cp, *start, *end; char type[MAX_WORD], w[MAX_WORD]; int depth, i; struct tb_profile profile[2]; /* * find a possibly nested pair of '<' and '>', * make them pointed by 'start' and 'end'. */ start = strchr(*cpp, '<'); if (start == NULL) { LOG(LOG_ERR, 0, "conditioner action missing"); return (0); } depth = 1; cp = start + 1; do { end = strpbrk(cp, "<>"); if (end == NULL) { LOG(LOG_ERR, 0, "conditioner action delimiter mismatch"); return (0); } if (*end == '<') depth++; else if (*end == '>') depth--; cp = end + 1; } while (depth > 0); *end = '\0'; *cpp = end + 1; cp = start + 1; if (IsDebug(DEBUG_ALTQ)) { printf("tc_action_parser: [%s]\n", cp); } if (!next_word(&cp, type)) { LOG(LOG_ERR, 0, "missing conditioner action type"); return (0); } /* * action type specific process */ if (EQUAL(type, "conditioner")) { if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing conditioner name"); return (0); } action->tca_code = TCACODE_HANDLE; action->tca_handle = cdnr_name2handle(ifname, w); if (action->tca_handle == CDNR_NULL_HANDLE) { LOG(LOG_ERR, 0, "wrong conditioner name %s", w); return (0); } } else if (EQUAL(type, "pass")) { action->tca_code = TCACODE_PASS; } else if (EQUAL(type, "drop")) { action->tca_code = TCACODE_DROP; } else if (EQUAL(type, "mark")) { if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing dscp"); return (0); } action->tca_code = TCACODE_MARK; action->tca_dscp = (u_int8_t)strtol(w, NULL, 0); } else if (EQUAL(type, "tbmeter")) { if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[0].rate = atobps(w); if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[0].depth = atobytes(w); if (tc_action_parser(ifname, &cp, &action[1]) == 0) return (0); if (tc_action_parser(ifname, &cp, &action[2]) == 0) return (0); if (qcmd_cdnr_add_tbmeter(action, ifname, NULL, &profile[0], &action[1], &action[2]) != 0) return (0); } else if (EQUAL(type, "trtcm")) { int coloraware = 0; /* default is color-blind */ for (i=0; i<2; i++) { if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[i].rate = atobps(w); if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[i].depth = atobytes(w); } if (tc_action_parser(ifname, &cp, &action[1]) == 0) return (0); if (tc_action_parser(ifname, &cp, &action[2]) == 0) return (0); if (tc_action_parser(ifname, &cp, &action[3]) == 0) return (0); if (next_word(&cp, w)) { if (EQUAL(w, "coloraware")) coloraware = 1; else if (EQUAL(w, "colorblind")) coloraware = 0; } if (qcmd_cdnr_add_trtcm(action, ifname, NULL, &profile[0], &profile[1], &action[1], &action[2], &action[3], coloraware) != 0) return (0); } else if (EQUAL(type, "tswtcm")) { u_int32_t cmtd_rate, peak_rate, avg_interval; if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing cmtd rate"); return (0); } cmtd_rate = atobps(w); if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing peak rate"); return (0); } peak_rate = atobps(w); if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, "missing avg interval"); return (0); } avg_interval = (u_int32_t)strtoul(w, NULL, 0); if (tc_action_parser(ifname, &cp, &action[1]) == 0) return (0); if (tc_action_parser(ifname, &cp, &action[2]) == 0) return (0); if (tc_action_parser(ifname, &cp, &action[3]) == 0) return (0); if (qcmd_cdnr_add_tswtcm(action, ifname, NULL, cmtd_rate, peak_rate, avg_interval, &action[1], &action[2], &action[3]) != 0) return (0); } else { LOG(LOG_ERR, 0, "unkown action type %s"); return (0); } *end = '>'; /* restore the end delimiter */ return (1); }