Ejemplo n.º 1
0
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);
		}
	}
Ejemplo n.º 2
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);
}