mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-08-18 02:10:05 +00:00
tc: actions: add helpers to parse and print control actions
Each tc action is terminated by a control action. Each action parses and prints then intividually. Introduce set of helpers and allow to share this code. Signed-off-by: Jiri Pirko <jiri@mellanox.com>
This commit is contained in:
parent
732f03461b
commit
e67aba5595
@ -75,7 +75,7 @@ static int bpf_parse_opt(struct action_util *a, int *ptr_argc, char ***ptr_argv,
|
|||||||
int tca_id, struct nlmsghdr *n)
|
int tca_id, struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
const char *bpf_obj = NULL, *bpf_uds_name = NULL;
|
const char *bpf_obj = NULL, *bpf_uds_name = NULL;
|
||||||
struct tc_act_bpf parm = { .action = TC_ACT_PIPE };
|
struct tc_act_bpf parm = {};
|
||||||
struct bpf_cfg_in cfg = {};
|
struct bpf_cfg_in cfg = {};
|
||||||
bool seen_run = false;
|
bool seen_run = false;
|
||||||
struct rtattr *tail;
|
struct rtattr *tail;
|
||||||
@ -123,8 +123,8 @@ opt_bpf:
|
|||||||
NEXT_ARG_FWD();
|
NEXT_ARG_FWD();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc && !action_a2n(*argv, &parm.action, false))
|
parse_action_control_dflt(&argc, &argv, &parm.action,
|
||||||
NEXT_ARG_FWD();
|
false, TC_ACT_PIPE);
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -186,7 +186,7 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
b, sizeof(b)));
|
b, sizeof(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "default-action %s\n", action_n2a(parm->action));
|
print_action_control(f, "default-action ", parm->action, "\n");
|
||||||
fprintf(f, "\tindex %u ref %d bind %d", parm->index, parm->refcnt,
|
fprintf(f, "\tindex %u ref %d bind %d", parm->index, parm->refcnt,
|
||||||
parm->bindcnt);
|
parm->bindcnt);
|
||||||
|
|
||||||
|
@ -80,9 +80,7 @@ parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.action = TC_ACT_PIPE;
|
parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE);
|
||||||
if (argc && !action_a2n(*argv, &sel.action, false))
|
|
||||||
NEXT_ARG_FWD();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
|
@ -123,8 +123,7 @@ parse_csum(struct action_util *a, int *argc_p,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc && !action_a2n(*argv, &sel.action, false))
|
parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK);
|
||||||
NEXT_ARG_FWD();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -200,10 +199,10 @@ print_csum(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
uflag_1 = "?empty";
|
uflag_1 = "?empty";
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "csum (%s%s%s%s%s%s%s) action %s\n",
|
fprintf(f, "csum (%s%s%s%s%s%s%s) ",
|
||||||
uflag_1, uflag_2, uflag_3,
|
uflag_1, uflag_2, uflag_3,
|
||||||
uflag_4, uflag_5, uflag_6, uflag_7,
|
uflag_4, uflag_5, uflag_6, uflag_7);
|
||||||
action_n2a(sel->action));
|
print_action_control(f, "action ", sel->action, "\n");
|
||||||
fprintf(f, "\tindex %u ref %d bind %d", sel->index, sel->refcnt,
|
fprintf(f, "\tindex %u ref %d bind %d", sel->index, sel->refcnt,
|
||||||
sel->bindcnt);
|
sel->bindcnt);
|
||||||
|
|
||||||
|
42
tc/m_gact.c
42
tc/m_gact.c
@ -68,18 +68,6 @@ usage(void)
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
get_act(char ***argv_p)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if (action_a2n(**argv_p, &n, false)) {
|
|
||||||
fprintf(stderr, "bad action type %s\n", **argv_p);
|
|
||||||
return -10;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
||||||
int tca_id, struct nlmsghdr *n)
|
int tca_id, struct nlmsghdr *n)
|
||||||
@ -87,8 +75,7 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
int argc = *argc_p;
|
int argc = *argc_p;
|
||||||
char **argv = *argv_p;
|
char **argv = *argv_p;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
int action = TC_POLICE_RECLASSIFY;
|
struct tc_gact p = { 0 };
|
||||||
struct tc_gact p = { .action = TC_POLICE_RECLASSIFY };
|
|
||||||
#ifdef CONFIG_GACT_PROB
|
#ifdef CONFIG_GACT_PROB
|
||||||
int rd = 0;
|
int rd = 0;
|
||||||
struct tc_gact_p pp;
|
struct tc_gact_p pp;
|
||||||
@ -102,14 +89,9 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
if (matches(*argv, "gact") == 0) {
|
if (matches(*argv, "gact") == 0) {
|
||||||
ok++;
|
ok++;
|
||||||
} else {
|
} else {
|
||||||
action = get_act(&argv);
|
if (parse_action_control(&argc, &argv, &p.action, false) == -1)
|
||||||
if (action != -10) {
|
usage();
|
||||||
p.action = action;
|
|
||||||
ok++;
|
ok++;
|
||||||
} else {
|
|
||||||
explain();
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
@ -133,13 +115,9 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
action = get_act(&argv);
|
if (parse_action_control(&argc, &argv,
|
||||||
if (action != -10) { /* FIXME */
|
&pp.paction, false) == -1)
|
||||||
pp.paction = action;
|
usage();
|
||||||
} else {
|
|
||||||
explain();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
if (get_u16(&pp.pval, *argv, 10)) {
|
if (get_u16(&pp.pval, *argv, 10)) {
|
||||||
@ -212,7 +190,8 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
|
|||||||
}
|
}
|
||||||
p = RTA_DATA(tb[TCA_GACT_PARMS]);
|
p = RTA_DATA(tb[TCA_GACT_PARMS]);
|
||||||
|
|
||||||
fprintf(f, "gact action %s", action_n2a(p->action));
|
fprintf(f, "gact ");
|
||||||
|
print_action_control(f, "action ", p->action, "");
|
||||||
#ifdef CONFIG_GACT_PROB
|
#ifdef CONFIG_GACT_PROB
|
||||||
if (tb[TCA_GACT_PROB] != NULL) {
|
if (tb[TCA_GACT_PROB] != NULL) {
|
||||||
pp = RTA_DATA(tb[TCA_GACT_PROB]);
|
pp = RTA_DATA(tb[TCA_GACT_PROB]);
|
||||||
@ -221,8 +200,9 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
|
|||||||
memset(&pp_dummy, 0, sizeof(pp_dummy));
|
memset(&pp_dummy, 0, sizeof(pp_dummy));
|
||||||
pp = &pp_dummy;
|
pp = &pp_dummy;
|
||||||
}
|
}
|
||||||
fprintf(f, "\n\t random type %s %s val %d",
|
fprintf(f, "\n\t random type %s", prob_n2a(pp->ptype));
|
||||||
prob_n2a(pp->ptype), action_n2a(pp->paction), pp->pval);
|
print_action_control(f, " ", pp->paction, " ");
|
||||||
|
fprintf(f, "val %d", pp->pval);
|
||||||
#endif
|
#endif
|
||||||
fprintf(f, "\n\t index %u ref %d bind %d", p->index, p->refcnt,
|
fprintf(f, "\n\t index %u ref %d bind %d", p->index, p->refcnt,
|
||||||
p->bindcnt);
|
p->bindcnt);
|
||||||
|
10
tc/m_ife.c
10
tc/m_ife.c
@ -57,7 +57,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
int argc = *argc_p;
|
int argc = *argc_p;
|
||||||
char **argv = *argv_p;
|
char **argv = *argv_p;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
struct tc_ife p = { .action = TC_ACT_PIPE }; /* good default */
|
struct tc_ife p = { 0 };
|
||||||
struct rtattr *tail;
|
struct rtattr *tail;
|
||||||
struct rtattr *tail2;
|
struct rtattr *tail2;
|
||||||
char dbuf[ETH_ALEN];
|
char dbuf[ETH_ALEN];
|
||||||
@ -156,8 +156,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc && !action_a2n(*argv, &p.action, false))
|
parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);
|
||||||
NEXT_ARG_FWD();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -245,9 +244,8 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
}
|
}
|
||||||
p = RTA_DATA(tb[TCA_IFE_PARMS]);
|
p = RTA_DATA(tb[TCA_IFE_PARMS]);
|
||||||
|
|
||||||
fprintf(f, "ife %s action %s ",
|
fprintf(f, "ife %s ", p->flags & IFE_ENCODE ? "encode" : "decode");
|
||||||
(p->flags & IFE_ENCODE) ? "encode" : "decode",
|
print_action_control(f, "action ", p->action, " ");
|
||||||
action_n2a(p->action));
|
|
||||||
|
|
||||||
if (tb[TCA_IFE_TYPE]) {
|
if (tb[TCA_IFE_TYPE]) {
|
||||||
ife_type = rta_getattr_u16(tb[TCA_IFE_TYPE]);
|
ife_type = rta_getattr_u16(tb[TCA_IFE_TYPE]);
|
||||||
|
@ -170,10 +170,8 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (argc &&
|
if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR)
|
||||||
(p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR)
|
parse_action_control(&argc, &argv, &p.action, false);
|
||||||
&& !action_a2n(*argv, &p.action, false))
|
|
||||||
NEXT_ARG();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (iok && matches(*argv, "index") == 0) {
|
if (iok && matches(*argv, "index") == 0) {
|
||||||
@ -272,8 +270,8 @@ print_mirred(struct action_util *au, FILE * f, struct rtattr *arg)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "mirred (%s to device %s) %s",
|
fprintf(f, "mirred (%s to device %s)", mirred_n2a(p->eaction), dev);
|
||||||
mirred_n2a(p->eaction), dev, action_n2a(p->action));
|
print_action_control(f, " ", p->action, "");
|
||||||
|
|
||||||
fprintf(f, "\n ");
|
fprintf(f, "\n ");
|
||||||
fprintf(f, "\tindex %u ref %d bind %d", p->index, p->refcnt,
|
fprintf(f, "\tindex %u ref %d bind %d", p->index, p->refcnt,
|
||||||
|
@ -115,8 +115,7 @@ parse_nat(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc && !action_a2n(*argv, &sel.action, false))
|
parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK);
|
||||||
NEXT_ARG_FWD();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -164,12 +163,12 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg)
|
|||||||
len = ffs(sel->mask);
|
len = ffs(sel->mask);
|
||||||
len = len ? 33 - len : 0;
|
len = len ? 33 - len : 0;
|
||||||
|
|
||||||
fprintf(f, " nat %s %s/%d %s %s", sel->flags & TCA_NAT_FLAG_EGRESS ?
|
fprintf(f, " nat %s %s/%d %s", sel->flags & TCA_NAT_FLAG_EGRESS ?
|
||||||
"egress" : "ingress",
|
"egress" : "ingress",
|
||||||
format_host_r(AF_INET, 4, &sel->old_addr, buf1, sizeof(buf1)),
|
format_host_r(AF_INET, 4, &sel->old_addr, buf1, sizeof(buf1)),
|
||||||
len,
|
len,
|
||||||
format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2)),
|
format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2)));
|
||||||
action_n2a(sel->action));
|
print_action_control(f, " ", sel->action, "");
|
||||||
|
|
||||||
if (show_stats) {
|
if (show_stats) {
|
||||||
if (tb[TCA_NAT_TM]) {
|
if (tb[TCA_NAT_TM]) {
|
||||||
|
@ -670,8 +670,7 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc && !action_a2n(*argv, &sel.sel.action, false))
|
parse_action_control_dflt(&argc, &argv, &sel.sel.action, false, TC_ACT_OK);
|
||||||
NEXT_ARG();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -776,8 +775,9 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, " pedit action %s keys %d\n ",
|
fprintf(f, " pedit ");
|
||||||
action_n2a(sel->action), sel->nkeys);
|
print_action_control(f, "action ", sel->action, " ");
|
||||||
|
fprintf(f,"keys %d\n ", sel->nkeys);
|
||||||
fprintf(f, "\t index %u ref %d bind %d", sel->index, sel->refcnt,
|
fprintf(f, "\t index %u ref %d bind %d", sel->index, sel->refcnt,
|
||||||
sel->bindcnt);
|
sel->bindcnt);
|
||||||
|
|
||||||
|
@ -50,27 +50,6 @@ static void explain1(char *arg)
|
|||||||
fprintf(stderr, "Illegal \"%s\"\n", arg);
|
fprintf(stderr, "Illegal \"%s\"\n", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_police_result(int *action, int *result, char *arg)
|
|
||||||
{
|
|
||||||
char *p = strchr(arg, '/');
|
|
||||||
|
|
||||||
if (p)
|
|
||||||
*p = 0;
|
|
||||||
|
|
||||||
if (action_a2n(arg, action, true)) {
|
|
||||||
if (p)
|
|
||||||
*p = '/';
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
*p = '/';
|
|
||||||
if (action_a2n(p+1, result, true))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p,
|
int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p,
|
||||||
int tca_id, struct nlmsghdr *n)
|
int tca_id, struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
@ -166,23 +145,19 @@ int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
explain1("peakrate");
|
explain1("peakrate");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (matches(*argv, "reclassify") == 0) {
|
} else if (matches(*argv, "reclassify") == 0 ||
|
||||||
p.action = TC_POLICE_RECLASSIFY;
|
matches(*argv, "drop") == 0 ||
|
||||||
} else if (matches(*argv, "drop") == 0 ||
|
matches(*argv, "shot") == 0 ||
|
||||||
matches(*argv, "shot") == 0) {
|
matches(*argv, "continue") == 0 ||
|
||||||
p.action = TC_POLICE_SHOT;
|
matches(*argv, "pass") == 0 ||
|
||||||
} else if (matches(*argv, "continue") == 0) {
|
matches(*argv, "pipe") == 0) {
|
||||||
p.action = TC_POLICE_UNSPEC;
|
if (parse_action_control(&argc, &argv, &p.action, false))
|
||||||
} else if (matches(*argv, "pass") == 0) {
|
return -1;
|
||||||
p.action = TC_POLICE_OK;
|
|
||||||
} else if (matches(*argv, "pipe") == 0) {
|
|
||||||
p.action = TC_POLICE_PIPE;
|
|
||||||
} else if (strcmp(*argv, "conform-exceed") == 0) {
|
} else if (strcmp(*argv, "conform-exceed") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
if (get_police_result(&p.action, &presult, *argv)) {
|
if (parse_action_control_slash(&argc, &argv, &p.action,
|
||||||
fprintf(stderr, "Illegal \"action\"\n");
|
&presult, true))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
} else if (matches(*argv, "overhead") == 0) {
|
} else if (matches(*argv, "overhead") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
if (get_u16(&overhead, *argv, 10)) {
|
if (get_u16(&overhead, *argv, 10)) {
|
||||||
@ -318,12 +293,13 @@ int print_police(struct action_util *a, FILE *f, struct rtattr *arg)
|
|||||||
fprintf(f, "avrate %s ",
|
fprintf(f, "avrate %s ",
|
||||||
sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]),
|
sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]),
|
||||||
b1));
|
b1));
|
||||||
fprintf(f, "action %s", action_n2a(p->action));
|
|
||||||
|
print_action_control(f, "action ", p->action, "");
|
||||||
|
|
||||||
if (tb[TCA_POLICE_RESULT]) {
|
if (tb[TCA_POLICE_RESULT]) {
|
||||||
__u32 action = rta_getattr_u32(tb[TCA_POLICE_RESULT]);
|
__u32 action = rta_getattr_u32(tb[TCA_POLICE_RESULT]);
|
||||||
|
|
||||||
fprintf(f, "/%s ", action_n2a(action));
|
print_action_control(f, "/", action, " ");
|
||||||
} else
|
} else
|
||||||
fprintf(f, " ");
|
fprintf(f, " ");
|
||||||
|
|
||||||
|
@ -98,9 +98,7 @@ static int parse_sample(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
NEXT_ARG_FWD();
|
NEXT_ARG_FWD();
|
||||||
}
|
}
|
||||||
|
|
||||||
p.action = TC_ACT_PIPE;
|
parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);
|
||||||
if (argc && !action_a2n(*argv, &p.action, false))
|
|
||||||
NEXT_ARG_FWD();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
|
@ -120,9 +120,6 @@ parse_simple(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc && !action_a2n(*argv, &sel.action, false))
|
|
||||||
NEXT_ARG_FWD();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
|
@ -120,9 +120,8 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.action = TC_ACT_PIPE;
|
parse_action_control_dflt(&argc, &argv, &sel.action,
|
||||||
if (argc && !action_a2n(*argv, &sel.action, false))
|
false, TC_ACT_PIPE);
|
||||||
NEXT_ARG();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -214,7 +213,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
fprintf(f, " ptype %d", *ptype);
|
fprintf(f, " ptype %d", *ptype);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, " %s", action_n2a(p->action));
|
print_action_control(f, " ", p->action, "");
|
||||||
|
|
||||||
fprintf(f, "\n\t index %u ref %d bind %d",
|
fprintf(f, "\n\t index %u ref %d bind %d",
|
||||||
p->index, p->refcnt, p->bindcnt);
|
p->index, p->refcnt, p->bindcnt);
|
||||||
|
@ -61,7 +61,6 @@ static int parse_skbmod(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
char *saddr = NULL;
|
char *saddr = NULL;
|
||||||
|
|
||||||
memset(&p, 0, sizeof(p));
|
memset(&p, 0, sizeof(p));
|
||||||
p.action = TC_ACT_PIPE; /* good default */
|
|
||||||
|
|
||||||
if (argc <= 0)
|
if (argc <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -123,31 +122,7 @@ static int parse_skbmod(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc) {
|
parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);
|
||||||
if (matches(*argv, "reclassify") == 0) {
|
|
||||||
p.action = TC_ACT_RECLASSIFY;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
} else if (matches(*argv, "pipe") == 0) {
|
|
||||||
p.action = TC_ACT_PIPE;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
} else if (matches(*argv, "drop") == 0 ||
|
|
||||||
matches(*argv, "shot") == 0) {
|
|
||||||
p.action = TC_ACT_SHOT;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
} else if (matches(*argv, "continue") == 0) {
|
|
||||||
p.action = TC_ACT_UNSPEC;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
} else if (matches(*argv, "pass") == 0 ||
|
|
||||||
matches(*argv, "ok") == 0) {
|
|
||||||
p.action = TC_ACT_OK;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -206,7 +181,8 @@ static int print_skbmod(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
|
|
||||||
p = RTA_DATA(tb[TCA_SKBMOD_PARMS]);
|
p = RTA_DATA(tb[TCA_SKBMOD_PARMS]);
|
||||||
|
|
||||||
fprintf(f, "skbmod action %s ", action_n2a(p->action));
|
fprintf(f, "skbmod ");
|
||||||
|
print_action_control(f, "", p->action, " ");
|
||||||
|
|
||||||
if (tb[TCA_SKBMOD_ETYPE]) {
|
if (tb[TCA_SKBMOD_ETYPE]) {
|
||||||
skbmod_etype = rta_getattr_u16(tb[TCA_SKBMOD_ETYPE]);
|
skbmod_etype = rta_getattr_u16(tb[TCA_SKBMOD_ETYPE]);
|
||||||
|
@ -77,7 +77,7 @@ static int tunnel_key_parse_dst_port(char *str, int type, struct nlmsghdr *n)
|
|||||||
static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
|
static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
|
||||||
int tca_id, struct nlmsghdr *n)
|
int tca_id, struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
struct tc_tunnel_key parm = { .action = TC_ACT_PIPE };
|
struct tc_tunnel_key parm = {};
|
||||||
char **argv = *argv_p;
|
char **argv = *argv_p;
|
||||||
int argc = *argc_p;
|
int argc = *argc_p;
|
||||||
struct rtattr *tail;
|
struct rtattr *tail;
|
||||||
@ -158,8 +158,8 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
NEXT_ARG_FWD();
|
NEXT_ARG_FWD();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc && !action_a2n(*argv, &parm.action, false))
|
parse_action_control_dflt(&argc, &argv, &parm.action,
|
||||||
NEXT_ARG_FWD();
|
false, TC_ACT_PIPE);
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -265,7 +265,7 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
|
tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(f, " %s", action_n2a(parm->action));
|
print_action_control(f, " ", parm->action, "");
|
||||||
|
|
||||||
fprintf(f, "\n\tindex %d ref %d bind %d", parm->index, parm->refcnt,
|
fprintf(f, "\n\tindex %d ref %d bind %d", parm->index, parm->refcnt,
|
||||||
parm->bindcnt);
|
parm->bindcnt);
|
||||||
|
@ -59,7 +59,7 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
int proto_set = 0;
|
int proto_set = 0;
|
||||||
__u8 prio;
|
__u8 prio;
|
||||||
int prio_set = 0;
|
int prio_set = 0;
|
||||||
struct tc_vlan parm = { 0 };
|
struct tc_vlan parm = {};
|
||||||
|
|
||||||
if (matches(*argv, "vlan") != 0)
|
if (matches(*argv, "vlan") != 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -133,9 +133,8 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
parm.action = TC_ACT_PIPE;
|
parse_action_control_dflt(&argc, &argv, &parm.action,
|
||||||
if (argc && !action_a2n(*argv, &parm.action, false))
|
false, TC_ACT_PIPE);
|
||||||
NEXT_ARG_FWD();
|
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (matches(*argv, "index") == 0) {
|
if (matches(*argv, "index") == 0) {
|
||||||
@ -224,7 +223,7 @@ static int print_vlan(struct action_util *au, FILE *f, struct rtattr *arg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(f, " %s", action_n2a(parm->action));
|
print_action_control(f, " ", parm->action, "");
|
||||||
|
|
||||||
fprintf(f, "\n\t index %u ref %d bind %d", parm->index, parm->refcnt,
|
fprintf(f, "\n\t index %u ref %d bind %d", parm->index, parm->refcnt,
|
||||||
parm->bindcnt);
|
parm->bindcnt);
|
||||||
|
137
tc/tc_util.c
137
tc/tc_util.c
@ -411,7 +411,7 @@ char *sprint_qdisc_handle(__u32 h, char *buf)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *action_n2a(int action)
|
static const char *action_n2a(int action)
|
||||||
{
|
{
|
||||||
static char buf[64];
|
static char buf[64];
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ const char *action_n2a(int action)
|
|||||||
*
|
*
|
||||||
* In error case, returns -1 and does not touch @result. Otherwise returns 0.
|
* In error case, returns -1 and does not touch @result. Otherwise returns 0.
|
||||||
*/
|
*/
|
||||||
int action_a2n(char *arg, int *result, bool allow_num)
|
static int action_a2n(char *arg, int *result, bool allow_num)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
char dummy;
|
char dummy;
|
||||||
@ -475,6 +475,139 @@ int action_a2n(char *arg, int *result, bool allow_num)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse action control including possible options.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @argc_p - pointer to argc to parse
|
||||||
|
* @argv_p - pointer to argv to parse
|
||||||
|
* @result_p - pointer to output variable
|
||||||
|
* @allow_num - whether action may be in numeric format already
|
||||||
|
*
|
||||||
|
* In error case, returns -1 and does not touch @result_1p. Otherwise returns 0.
|
||||||
|
*/
|
||||||
|
int parse_action_control(int *argc_p, char ***argv_p,
|
||||||
|
int *result_p, bool allow_num)
|
||||||
|
{
|
||||||
|
int argc = *argc_p;
|
||||||
|
char **argv = *argv_p;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (!argc)
|
||||||
|
return -1;
|
||||||
|
if (action_a2n(*argv, &result, allow_num) == -1) {
|
||||||
|
fprintf(stderr, "Bad action type %s\n", *argv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
NEXT_ARG_FWD();
|
||||||
|
*argc_p = argc;
|
||||||
|
*argv_p = argv;
|
||||||
|
*result_p = result;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse action control including possible options.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @argc_p - pointer to argc to parse
|
||||||
|
* @argv_p - pointer to argv to parse
|
||||||
|
* @result_p - pointer to output variable
|
||||||
|
* @allow_num - whether action may be in numeric format already
|
||||||
|
* @default_result - set as a result in case of parsing error
|
||||||
|
*
|
||||||
|
* In case there is an error during parsing, the default result is used.
|
||||||
|
*/
|
||||||
|
void parse_action_control_dflt(int *argc_p, char ***argv_p,
|
||||||
|
int *result_p, bool allow_num,
|
||||||
|
int default_result)
|
||||||
|
{
|
||||||
|
if (parse_action_control(argc_p, argv_p, result_p, allow_num))
|
||||||
|
*result_p = default_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_action_control_slash_spaces(int *argc_p, char ***argv_p,
|
||||||
|
int *result1_p, int *result2_p,
|
||||||
|
bool allow_num)
|
||||||
|
{
|
||||||
|
int argc = *argc_p;
|
||||||
|
char **argv = *argv_p;
|
||||||
|
int result1, result2;
|
||||||
|
int *result_p = &result1;
|
||||||
|
int ok = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (argc > 0) {
|
||||||
|
switch (ok) {
|
||||||
|
case 1:
|
||||||
|
if (strcmp(*argv, "/") != 0)
|
||||||
|
goto out;
|
||||||
|
result_p = &result2;
|
||||||
|
NEXT_ARG();
|
||||||
|
/* fall-through */
|
||||||
|
case 0: /* fall-through */
|
||||||
|
case 2:
|
||||||
|
ret = parse_action_control(&argc, &argv,
|
||||||
|
result_p, allow_num);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
ok++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
*result1_p = result1;
|
||||||
|
if (ok == 2)
|
||||||
|
*result2_p = result2;
|
||||||
|
*argc_p = argc;
|
||||||
|
*argv_p = argv;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse action control with slash including possible options.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @argc_p - pointer to argc to parse
|
||||||
|
* @argv_p - pointer to argv to parse
|
||||||
|
* @result1_p - pointer to the first (before slash) output variable
|
||||||
|
* @result2_p - pointer to the second (after slash) output variable
|
||||||
|
* @allow_num - whether action may be in numeric format already
|
||||||
|
*
|
||||||
|
* In error case, returns -1 and does not touch @result*. Otherwise returns 0.
|
||||||
|
*/
|
||||||
|
int parse_action_control_slash(int *argc_p, char ***argv_p,
|
||||||
|
int *result1_p, int *result2_p, bool allow_num)
|
||||||
|
{
|
||||||
|
char **argv = *argv_p;
|
||||||
|
int result1, result2;
|
||||||
|
char *p = strchr(*argv, '/');
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
return parse_action_control_slash_spaces(argc_p, argv_p,
|
||||||
|
result1_p, result2_p,
|
||||||
|
allow_num);
|
||||||
|
*p = 0;
|
||||||
|
if (action_a2n(*argv, &result1, allow_num)) {
|
||||||
|
if (p)
|
||||||
|
*p = '/';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = '/';
|
||||||
|
if (action_a2n(p + 1, &result2, allow_num))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*result1_p = result1;
|
||||||
|
*result2_p = result2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_action_control(FILE *f, const char *prefix,
|
||||||
|
int action, const char *suffix)
|
||||||
|
{
|
||||||
|
fprintf(f, "%s%s%s", prefix, action_n2a(action), suffix);
|
||||||
|
}
|
||||||
|
|
||||||
int get_linklayer(unsigned int *val, const char *arg)
|
int get_linklayer(unsigned int *val, const char *arg)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
11
tc/tc_util.h
11
tc/tc_util.h
@ -100,8 +100,15 @@ char *sprint_tc_classid(__u32 h, char *buf);
|
|||||||
int tc_print_police(FILE *f, struct rtattr *tb);
|
int tc_print_police(FILE *f, struct rtattr *tb);
|
||||||
int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n);
|
int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n);
|
||||||
|
|
||||||
const char *action_n2a(int action);
|
int parse_action_control(int *argc_p, char ***argv_p,
|
||||||
int action_a2n(char *arg, int *result, bool allow_num);
|
int *result_p, bool allow_num);
|
||||||
|
void parse_action_control_dflt(int *argc_p, char ***argv_p,
|
||||||
|
int *result_p, bool allow_num,
|
||||||
|
int default_result);
|
||||||
|
int parse_action_control_slash(int *argc_p, char ***argv_p,
|
||||||
|
int *result1_p, int *result2_p, bool allow_num);
|
||||||
|
void print_action_control(FILE *f, const char *prefix,
|
||||||
|
int action, const char *suffix);
|
||||||
int act_parse_police(struct action_util *a, int *argc_p,
|
int act_parse_police(struct action_util *a, int *argc_p,
|
||||||
char ***argv_p, int tca_id, struct nlmsghdr *n);
|
char ***argv_p, int tca_id, struct nlmsghdr *n);
|
||||||
int print_police(struct action_util *a, FILE *f, struct rtattr *tb);
|
int print_police(struct action_util *a, FILE *f, struct rtattr *tb);
|
||||||
|
Loading…
Reference in New Issue
Block a user