Ejemplo n.º 1
0
static int
parse_direction(struct action_util *a, int *argc_p, char ***argv_p,
		int tca_id, struct nlmsghdr *n)
{

	int argc = *argc_p;
	char **argv = *argv_p;
	int ok = 0, iok = 0, mirror = 0, redir = 0, ingress = 0, egress = 0;
	struct tc_mirred p = {};
	struct rtattr *tail;
	char d[IFNAMSIZ] = {};

	while (argc > 0) {

		if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			break;
		} else if (!egress && matches(*argv, "egress") == 0) {
			egress = 1;
			if (ingress) {
				fprintf(stderr,
					"Can't have both egress and ingress\n");
				return -1;
			}
			NEXT_ARG();
			ok++;
			continue;
		} else if (!ingress && matches(*argv, "ingress") == 0) {
			ingress = 1;
			if (egress) {
				fprintf(stderr,
					"Can't have both ingress and egress\n");
				return -1;
			}
			NEXT_ARG();
			ok++;
			continue;
		} else {

			if (matches(*argv, "index") == 0) {
				NEXT_ARG();
				if (get_u32(&p.index, *argv, 10)) {
					fprintf(stderr, "Illegal \"index\"\n");
					return -1;
				}
				iok++;
				if (!ok) {
					argc--;
					argv++;
					break;
				}
			} else if (!ok) {
				fprintf(stderr,
					"was expecting egress or ingress (%s)\n",
					*argv);
				break;

			} else if (!mirror && matches(*argv, "mirror") == 0) {
				mirror = 1;
				if (redir) {
					fprintf(stderr,
						"Can't have both mirror and redir\n");
					return -1;
				}
				p.eaction = egress ? TCA_EGRESS_MIRROR :
					TCA_INGRESS_MIRROR;
				p.action = TC_ACT_PIPE;
				ok++;
			} else if (!redir && matches(*argv, "redirect") == 0) {
				redir = 1;
				if (mirror) {
					fprintf(stderr,
						"Can't have both mirror and redir\n");
					return -1;
				}
				p.eaction = egress ? TCA_EGRESS_REDIR :
					TCA_INGRESS_REDIR;
				p.action = TC_ACT_STOLEN;
				ok++;
			} else if ((redir || mirror) &&
				   matches(*argv, "dev") == 0) {
				NEXT_ARG();
				if (strlen(d))
					duparg("dev", *argv);

				strncpy(d, *argv, sizeof(d)-1);
				argc--;
				argv++;

				break;

			}
		}

		NEXT_ARG();
	}

	if (!ok && !iok)
		return -1;

	if (d[0])  {
		int idx;

		ll_init_map(&rth);

		idx = ll_name_to_index(d);
		if (!idx)
			return nodev(d);

		p.ifindex = idx;
	}


	if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR)
		parse_action_control(&argc, &argv, &p.action, false);

	if (argc) {
		if (iok && matches(*argv, "index") == 0) {
			fprintf(stderr, "mirred: Illegal double index\n");
			return -1;
		}

		if (matches(*argv, "index") == 0) {
			NEXT_ARG();
			if (get_u32(&p.index, *argv, 10)) {
				fprintf(stderr,
					"mirred: Illegal \"index\"\n");
				return -1;
			}
			argc--;
			argv++;
		}
	}

	tail = addattr_nest(n, MAX_MSG, tca_id);
	addattr_l(n, MAX_MSG, TCA_MIRRED_PARMS, &p, sizeof(p));
	addattr_nest_end(n, tail);

	*argc_p = argc;
	*argv_p = argv;
	return 0;
}
Ejemplo n.º 2
0
static int
parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
	   int tca_id, struct nlmsghdr *n)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int ok = 0;
	struct tc_gact p = { 0 };
#ifdef CONFIG_GACT_PROB
	int rd = 0;
	struct tc_gact_p pp;
#endif
	struct rtattr *tail;

	if (argc < 0)
		return -1;


	if (matches(*argv, "gact") == 0) {
		ok++;
		argc--;
		argv++;
	} else {
		if (parse_action_control(&argc, &argv, &p.action, false) == -1)
			usage();
		ok++;
	}

#ifdef CONFIG_GACT_PROB
	if (ok && argc > 0) {
		if (matches(*argv, "random") == 0) {
			rd = 1;
			NEXT_ARG();
			if (matches(*argv, "netrand") == 0) {
				NEXT_ARG();
				pp.ptype = PGACT_NETRAND;
			} else if  (matches(*argv, "determ") == 0) {
				NEXT_ARG();
				pp.ptype = PGACT_DETERM;
			} else {
				fprintf(stderr, "Illegal \"random type\"\n");
				return -1;
			}

			if (parse_action_control(&argc, &argv,
						 &pp.paction, false) == -1)
				usage();
			if (get_u16(&pp.pval, *argv, 10)) {
				fprintf(stderr, "Illegal probability val 0x%x\n", pp.pval);
				return -1;
			}
			if (pp.pval > 10000) {
				fprintf(stderr, "Illegal probability val  0x%x\n", pp.pval);
				return -1;
			}
			argc--;
			argv++;
		} else if (matches(*argv, "help") == 0) {
				usage();
		}
	}
#endif

	if (argc > 0) {
		if (matches(*argv, "index") == 0) {
			NEXT_ARG();
			if (get_u32(&p.index, *argv, 10)) {
				fprintf(stderr, "Illegal \"index\"\n");
				return -1;
			}
			argc--;
			argv++;
			ok++;
		} else if (matches(*argv, "help") == 0) {
				usage();
		}
	}

	if (!ok)
		return -1;

	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
	addattr_l(n, MAX_MSG, TCA_GACT_PARMS, &p, sizeof(p));
#ifdef CONFIG_GACT_PROB
	if (rd) {
		addattr_l(n, MAX_MSG, TCA_GACT_PROB, &pp, sizeof(pp));
	}
#endif
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;

	*argc_p = argc;
	*argv_p = argv;
	return 0;
}