Merge branch 'master' into net-next

This commit is contained in:
Stephen Hemminger 2016-07-25 08:21:00 -07:00
commit 79f5bf17a5
16 changed files with 198 additions and 413 deletions

View File

@ -56,6 +56,8 @@ struct l2tp_parm {
uint16_t pw_type;
uint16_t mtu;
int udp6_csum_tx:1;
int udp6_csum_rx:1;
int udp_csum:1;
int recv_seq:1;
int send_seq:1;
@ -117,6 +119,12 @@ static int create_tunnel(struct l2tp_parm *p)
if (p->encap == L2TP_ENCAPTYPE_UDP) {
addattr16(&req.n, 1024, L2TP_ATTR_UDP_SPORT, p->local_udp_port);
addattr16(&req.n, 1024, L2TP_ATTR_UDP_DPORT, p->peer_udp_port);
if (p->udp_csum)
addattr(&req.n, 1024, L2TP_ATTR_UDP_CSUM);
if (!p->udp6_csum_tx)
addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_TX);
if (!p->udp6_csum_rx)
addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_RX);
}
if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
@ -282,6 +290,12 @@ static int get_response(struct nlmsghdr *n, void *arg)
p->l2spec_len = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_LEN]);
p->udp_csum = !!attrs[L2TP_ATTR_UDP_CSUM];
/*
* Not fetching from L2TP_ATTR_UDP_ZERO_CSUM6_{T,R}X because the
* kernel doesn't send it so just leave it as default value.
*/
p->udp6_csum_tx = 1;
p->udp6_csum_rx = 1;
if (attrs[L2TP_ATTR_COOKIE])
memcpy(p->cookie, RTA_DATA(attrs[L2TP_ATTR_COOKIE]),
p->cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_COOKIE]));
@ -459,6 +473,9 @@ static void usage(void)
fprintf(stderr, " tunnel_id ID peer_tunnel_id ID\n");
fprintf(stderr, " [ encap { ip | udp } ]\n");
fprintf(stderr, " [ udp_sport PORT ] [ udp_dport PORT ]\n");
fprintf(stderr, " [ udp_csum { on | off } ]\n");
fprintf(stderr, " [ udp6_csum_tx { on | off } ]\n");
fprintf(stderr, " [ udp6_csum_rx { on | off } ]\n");
fprintf(stderr, "Usage: ip l2tp add session [ name NAME ]\n");
fprintf(stderr, " tunnel_id ID\n");
fprintf(stderr, " session_id ID peer_session_id ID\n");
@ -489,6 +506,8 @@ static int parse_args(int argc, char **argv, int cmd, struct l2tp_parm *p)
/* Defaults */
p->l2spec_type = L2TP_L2SPECTYPE_DEFAULT;
p->l2spec_len = 4;
p->udp6_csum_rx = 1;
p->udp6_csum_tx = 1;
while (argc > 0) {
if (strcmp(*argv, "encap") == 0) {
@ -558,6 +577,32 @@ static int parse_args(int argc, char **argv, int cmd, struct l2tp_parm *p)
if (get_u16(&uval, *argv, 0))
invarg("invalid port\n", *argv);
p->peer_udp_port = uval;
} else if (strcmp(*argv, "udp_csum") == 0) {
NEXT_ARG();
if (strcmp(*argv, "on") == 0)
p->udp_csum = 1;
else if (strcmp(*argv, "off") == 0)
p->udp_csum = 0;
else
invarg("invalid option for udp_csum\n", *argv);
} else if (strcmp(*argv, "udp6_csum_rx") == 0) {
NEXT_ARG();
if (strcmp(*argv, "on") == 0)
p->udp6_csum_rx = 1;
else if (strcmp(*argv, "off") == 0)
p->udp6_csum_rx = 0;
else
invarg("invalid option for udp6_csum_rx\n"
, *argv);
} else if (strcmp(*argv, "udp6_csum_tx") == 0) {
NEXT_ARG();
if (strcmp(*argv, "on") == 0)
p->udp6_csum_tx = 1;
else if (strcmp(*argv, "off") == 0)
p->udp6_csum_tx = 0;
else
invarg("invalid option for udp6_csum_tx\n"
, *argv);
} else if (strcmp(*argv, "offset") == 0) {
__u8 uval;

View File

@ -73,8 +73,10 @@ An offset for the resulting class ID.
.I ID
may be
.BR root ", " none
or a hexadecimal class ID in the form [\fIX\fB:\fR]\fIY\fR. If \fIX\fR is
omitted, it is assumed to be zero.
or a hexadecimal class ID in the form [\fIX\fB:\fR]\fIY\fR. \fIX\fR must
match qdisc's/class's major handle (if omitted, the correct value is chosen
automatically). If the whole \fBbaseclass\fR is omitted, \fIY\fR defaults
to 1.
.TP
.BI divisor " NUM"
Number of buckets to use for sorting into. Keys are calculated modulo
@ -239,7 +241,7 @@ tc filter add ... flow hash \\
divisor 1024
.EE
.TP
Map destination IPs of 192.168.0.0/24 to classids 1-257:
Map destination IPs of 192.168.0.0/24 to classids 1-256:
.EX
tc filter add ... flow map \\

View File

@ -104,26 +104,8 @@ opt_bpf:
NEXT_ARG_FWD();
}
if (argc) {
if (matches(*argv, "reclassify") == 0) {
parm.action = TC_ACT_RECLASSIFY;
if (argc && !action_a2n(*argv, &parm.action, false))
NEXT_ARG_FWD();
} else if (matches(*argv, "pipe") == 0) {
parm.action = TC_ACT_PIPE;
NEXT_ARG_FWD();
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
parm.action = TC_ACT_SHOT;
NEXT_ARG_FWD();
} else if (matches(*argv, "continue") == 0) {
parm.action = TC_ACT_UNSPEC;
NEXT_ARG_FWD();
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
parm.action = TC_ACT_OK;
NEXT_ARG_FWD();
}
}
if (argc) {
if (matches(*argv, "index") == 0) {
@ -154,8 +136,6 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg)
struct rtattr *tb[TCA_ACT_BPF_MAX + 1];
struct tc_act_bpf *parm;
SPRINT_BUF(action_buf);
if (arg == NULL)
return -1;
@ -180,8 +160,7 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg)
fprintf(f, " ");
}
fprintf(f, "default-action %s\n", action_n2a(parm->action, action_buf,
sizeof(action_buf)));
fprintf(f, "default-action %s\n", action_n2a(parm->action));
fprintf(f, "\tindex %d ref %d bind %d", parm->index, parm->refcnt,
parm->bindcnt);

View File

@ -81,31 +81,8 @@ parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
}
sel.action = TC_ACT_PIPE;
if (argc) {
if (matches(*argv, "reclassify") == 0) {
sel.action = TC_ACT_RECLASSIFY;
argc--;
argv++;
} else if (matches(*argv, "pipe") == 0) {
sel.action = TC_ACT_PIPE;
argc--;
argv++;
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
sel.action = TC_ACT_SHOT;
argc--;
argv++;
} else if (matches(*argv, "continue") == 0) {
sel.action = TC_ACT_UNSPEC;
argc--;
argv++;
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
sel.action = TC_ACT_OK;
argc--;
argv++;
}
}
if (argc && !action_a2n(*argv, &sel.action, false))
NEXT_ARG_FWD();
if (argc) {
if (matches(*argv, "index") == 0) {

View File

@ -120,31 +120,8 @@ parse_csum(struct action_util *a, int *argc_p,
return -1;
}
if (argc) {
if (matches(*argv, "reclassify") == 0) {
sel.action = TC_ACT_RECLASSIFY;
argc--;
argv++;
} else if (matches(*argv, "pipe") == 0) {
sel.action = TC_ACT_PIPE;
argc--;
argv++;
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
sel.action = TC_ACT_SHOT;
argc--;
argv++;
} else if (matches(*argv, "continue") == 0) {
sel.action = TC_ACT_UNSPEC;
argc--;
argv++;
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
sel.action = TC_ACT_OK;
argc--;
argv++;
}
}
if (argc && !action_a2n(*argv, &sel.action, false))
NEXT_ARG_FWD();
if (argc) {
if (matches(*argv, "index") == 0) {
@ -184,8 +161,6 @@ print_csum(struct action_util *au, FILE *f, struct rtattr *arg)
char *uflag_5 = "";
char *uflag_6 = "";
SPRINT_BUF(action_buf);
int uflag_count = 0;
if (arg == NULL)
@ -223,7 +198,7 @@ print_csum(struct action_util *au, FILE *f, struct rtattr *arg)
fprintf(f, "csum (%s%s%s%s%s%s) action %s\n",
uflag_1, uflag_2, uflag_3,
uflag_4, uflag_5, uflag_6,
action_n2a(sel->action, action_buf, sizeof(action_buf)));
action_n2a(sel->action));
fprintf(f, "\tindex %d ref %d bind %d", sel->index, sel->refcnt, sel->bindcnt);
if (show_stats) {

View File

@ -71,22 +71,13 @@ usage(void)
static int
get_act(char ***argv_p)
{
char **argv = *argv_p;
int n;
if (matches(*argv, "reclassify") == 0) {
return TC_ACT_RECLASSIFY;
} else if (matches(*argv, "drop") == 0 || matches(*argv, "shot") == 0) {
return TC_ACT_SHOT;
} else if (matches(*argv, "continue") == 0) {
return TC_ACT_UNSPEC;
} else if (matches(*argv, "pipe") == 0) {
return TC_ACT_PIPE;
} else if (matches(*argv, "pass") == 0 || matches(*argv, "ok") == 0) {
return TC_ACT_OK;
} else {
fprintf(stderr, "bad action type %s\n", *argv);
if (!action_a2n(**argv_p, &n, false)) {
fprintf(stderr, "bad action type %s\n", **argv_p);
return -10;
}
return n;
}
static int
@ -203,9 +194,7 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
static int
print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
{
SPRINT_BUF(b1);
#ifdef CONFIG_GACT_PROB
SPRINT_BUF(b2);
struct tc_gact_p *pp = NULL;
struct tc_gact_p pp_dummy;
#endif
@ -223,7 +212,7 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
}
p = RTA_DATA(tb[TCA_GACT_PARMS]);
fprintf(f, "gact action %s", action_n2a(p->action, b1, sizeof(b1)));
fprintf(f, "gact action %s", action_n2a(p->action));
#ifdef CONFIG_GACT_PROB
if (tb[TCA_GACT_PROB] != NULL) {
pp = RTA_DATA(tb[TCA_GACT_PROB]);
@ -232,7 +221,8 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
memset(&pp_dummy, 0, sizeof(pp_dummy));
pp = &pp_dummy;
}
fprintf(f, "\n\t random type %s %s val %d", prob_n2a(pp->ptype), action_n2a(pp->paction, b2, sizeof (b2)), pp->pval);
fprintf(f, "\n\t random type %s %s val %d",
prob_n2a(pp->ptype), action_n2a(pp->paction), pp->pval);
#endif
fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);
if (show_stats) {

View File

@ -146,31 +146,8 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
argv++;
}
if (argc) {
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 && !action_a2n(*argv, &p.action, false))
NEXT_ARG_FWD();
if (argc) {
if (matches(*argv, "index") == 0) {
@ -238,7 +215,6 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
__u32 mhash = 0;
__u32 mprio = 0;
int has_optional = 0;
SPRINT_BUF(b1);
SPRINT_BUF(b2);
if (arg == NULL)
@ -254,7 +230,7 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
fprintf(f, "ife %s action %s ",
(p->flags & IFE_ENCODE) ? "encode" : "decode",
action_n2a(p->action, b1, sizeof(b1)));
action_n2a(p->action));
if (tb[TCA_IFE_TYPE]) {
ife_type = rta_getattr_u16(tb[TCA_IFE_TYPE]);

View File

@ -154,28 +154,9 @@ parse_egress(struct action_util *a, int *argc_p, char ***argv_p,
}
if (argc && p.eaction == TCA_EGRESS_MIRROR) {
if (matches(*argv, "reclassify") == 0) {
p.action = TC_POLICE_RECLASSIFY;
if (argc && p.eaction == TCA_EGRESS_MIRROR
&& !action_a2n(*argv, &p.action, false))
NEXT_ARG();
} else if (matches(*argv, "pipe") == 0) {
p.action = TC_POLICE_PIPE;
NEXT_ARG();
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
p.action = TC_POLICE_SHOT;
NEXT_ARG();
} else if (matches(*argv, "continue") == 0) {
p.action = TC_POLICE_UNSPEC;
NEXT_ARG();
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
p.action = TC_POLICE_OK;
NEXT_ARG();
}
}
if (argc) {
if (iok && matches(*argv, "index") == 0) {
@ -254,8 +235,6 @@ print_mirred(struct action_util *au, FILE * f, struct rtattr *arg)
struct rtattr *tb[TCA_MIRRED_MAX + 1];
const char *dev;
SPRINT_BUF(b1);
if (arg == NULL)
return -1;
@ -277,7 +256,8 @@ print_mirred(struct action_util *au, FILE * f, struct rtattr *arg)
return -1;
}
fprintf(f, "mirred (%s to device %s) %s", mirred_n2a(p->eaction), dev, action_n2a(p->action, b1, sizeof (b1)));
fprintf(f, "mirred (%s to device %s) %s",
mirred_n2a(p->eaction), dev, action_n2a(p->action));
fprintf(f, "\n ");
fprintf(f, "\tindex %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);

View File

@ -115,31 +115,8 @@ parse_nat(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct
return -1;
}
if (argc) {
if (matches(*argv, "reclassify") == 0) {
sel.action = TC_ACT_RECLASSIFY;
argc--;
argv++;
} else if (matches(*argv, "pipe") == 0) {
sel.action = TC_ACT_PIPE;
argc--;
argv++;
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
sel.action = TC_ACT_SHOT;
argc--;
argv++;
} else if (matches(*argv, "continue") == 0) {
sel.action = TC_ACT_UNSPEC;
argc--;
argv++;
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
sel.action = TC_ACT_OK;
argc--;
argv++;
}
}
if (argc && !action_a2n(*argv, &sel.action, false))
NEXT_ARG_FWD();
if (argc) {
if (matches(*argv, "index") == 0) {
@ -171,7 +148,6 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg)
char buf1[256];
char buf2[256];
SPRINT_BUF(buf3);
int len;
if (arg == NULL)
@ -193,7 +169,7 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg)
format_host_r(AF_INET, 4, &sel->old_addr, buf1, sizeof(buf1)),
len,
format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2)),
action_n2a(sel->action, buf3, sizeof(buf3)));
action_n2a(sel->action));
if (show_stats) {
if (tb[TCA_NAT_TM]) {

View File

@ -481,26 +481,8 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
return -1;
}
if (argc) {
if (matches(*argv, "reclassify") == 0) {
sel.sel.action = TC_ACT_RECLASSIFY;
if (argc && !action_a2n(*argv, &sel.sel.action, false))
NEXT_ARG();
} else if (matches(*argv, "pipe") == 0) {
sel.sel.action = TC_ACT_PIPE;
NEXT_ARG();
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
sel.sel.action = TC_ACT_SHOT;
NEXT_ARG();
} else if (matches(*argv, "continue") == 0) {
sel.sel.action = TC_ACT_UNSPEC;
NEXT_ARG();
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
sel.sel.action = TC_ACT_OK;
NEXT_ARG();
}
}
if (argc) {
if (matches(*argv, "index") == 0) {
@ -532,8 +514,6 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
struct tc_pedit_sel *sel;
struct rtattr *tb[TCA_PEDIT_MAX + 1];
SPRINT_BUF(b1);
if (arg == NULL)
return -1;
@ -546,7 +526,7 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
sel = RTA_DATA(tb[TCA_PEDIT_PARMS]);
fprintf(f, " pedit action %s keys %d\n ",
action_n2a(sel->action, b1, sizeof(b1)), sel->nkeys);
action_n2a(sel->action), sel->nkeys);
fprintf(f, "\t index %d ref %d bind %d", sel->index, sel->refcnt,
sel->bindcnt);

View File

@ -49,56 +49,6 @@ static void explain1(char *arg)
fprintf(stderr, "Illegal \"%s\"\n", arg);
}
static const char *police_action_n2a(int action, char *buf, int len)
{
switch (action) {
case -1:
return "continue";
break;
case TC_POLICE_OK:
return "pass";
break;
case TC_POLICE_SHOT:
return "drop";
break;
case TC_POLICE_RECLASSIFY:
return "reclassify";
case TC_POLICE_PIPE:
return "pipe";
default:
snprintf(buf, len, "%d", action);
return buf;
}
}
static int police_action_a2n(const char *arg, int *result)
{
int res;
if (matches(arg, "continue") == 0)
res = -1;
else if (matches(arg, "drop") == 0)
res = TC_POLICE_SHOT;
else if (matches(arg, "shot") == 0)
res = TC_POLICE_SHOT;
else if (matches(arg, "pass") == 0)
res = TC_POLICE_OK;
else if (strcmp(arg, "ok") == 0)
res = TC_POLICE_OK;
else if (matches(arg, "reclassify") == 0)
res = TC_POLICE_RECLASSIFY;
else if (matches(arg, "pipe") == 0)
res = TC_POLICE_PIPE;
else {
char dummy;
if (sscanf(arg, "%d%c", &res, &dummy) != 1)
return -1;
}
*result = res;
return 0;
}
static int get_police_result(int *action, int *result, char *arg)
{
char *p = strchr(arg, '/');
@ -106,7 +56,7 @@ static int get_police_result(int *action, int *result, char *arg)
if (p)
*p = 0;
if (police_action_a2n(arg, action)) {
if (action_a2n(arg, action, true)) {
if (p)
*p = '/';
return -1;
@ -114,7 +64,7 @@ static int get_police_result(int *action, int *result, char *arg)
if (p) {
*p = '/';
if (police_action_a2n(p+1, result))
if (action_a2n(p+1, result, true))
return -1;
}
return 0;
@ -367,14 +317,12 @@ int print_police(struct action_util *a, FILE *f, struct rtattr *arg)
fprintf(f, "avrate %s ",
sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]),
b1));
fprintf(f, "action %s",
police_action_n2a(p->action, b1, sizeof(b1)));
fprintf(f, "action %s", action_n2a(p->action));
if (tb[TCA_POLICE_RESULT]) {
__u32 action = rta_getattr_u32(tb[TCA_POLICE_RESULT]);
fprintf(f, "/%s",
police_action_n2a(action, b1, sizeof(b1)));
fprintf(f, "/%s", action_n2a(action));
} else
fprintf(f, " ");

View File

@ -120,31 +120,8 @@ parse_simple(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
}
}
if (argc) {
if (matches(*argv, "reclassify") == 0) {
sel.action = TC_ACT_RECLASSIFY;
argc--;
argv++;
} else if (matches(*argv, "pipe") == 0) {
sel.action = TC_ACT_PIPE;
argc--;
argv++;
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
sel.action = TC_ACT_SHOT;
argc--;
argv++;
} else if (matches(*argv, "continue") == 0) {
sel.action = TC_ACT_UNSPEC;
argc--;
argv++;
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
sel.action = TC_ACT_OK;
argc--;
argv++;
}
}
if (argc && !action_a2n(*argv, &sel.action, false))
NEXT_ARG_FWD();
if (argc) {
if (matches(*argv, "index") == 0) {

View File

@ -121,26 +121,8 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
}
sel.action = TC_ACT_PIPE;
if (argc) {
if (matches(*argv, "reclassify") == 0) {
sel.action = TC_ACT_RECLASSIFY;
if (argc && !action_a2n(*argv, &sel.action, false))
NEXT_ARG();
} else if (matches(*argv, "pipe") == 0) {
sel.action = TC_ACT_PIPE;
NEXT_ARG();
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
sel.action = TC_ACT_SHOT;
NEXT_ARG();
} else if (matches(*argv, "continue") == 0) {
sel.action = TC_ACT_UNSPEC;
NEXT_ARG();
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
sel.action = TC_ACT_OK;
NEXT_ARG();
}
}
if (argc) {
if (matches(*argv, "index") == 0) {

View File

@ -101,31 +101,8 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
}
parm.action = TC_ACT_PIPE;
if (argc) {
if (matches(*argv, "reclassify") == 0) {
parm.action = TC_ACT_RECLASSIFY;
argc--;
argv++;
} else if (matches(*argv, "pipe") == 0) {
parm.action = TC_ACT_PIPE;
argc--;
argv++;
} else if (matches(*argv, "drop") == 0 ||
matches(*argv, "shot") == 0) {
parm.action = TC_ACT_SHOT;
argc--;
argv++;
} else if (matches(*argv, "continue") == 0) {
parm.action = TC_ACT_UNSPEC;
argc--;
argv++;
} else if (matches(*argv, "pass") == 0 ||
matches(*argv, "ok") == 0) {
parm.action = TC_ACT_OK;
argc--;
argv++;
}
}
if (argc && !action_a2n(*argv, &parm.action, false))
NEXT_ARG_FWD();
if (argc) {
if (matches(*argv, "index") == 0) {
@ -205,7 +182,7 @@ static int print_vlan(struct action_util *au, FILE *f, struct rtattr *arg)
}
break;
}
fprintf(f, " %s", action_n2a(parm->action, b1, sizeof(b1)));
fprintf(f, " %s", action_n2a(parm->action));
fprintf(f, "\n\t index %d ref %d bind %d", parm->index, parm->refcnt,
parm->bindcnt);

View File

@ -411,18 +411,17 @@ char *sprint_qdisc_handle(__u32 h, char *buf)
return buf;
}
char *action_n2a(int action, char *buf, int len)
const char *action_n2a(int action)
{
static char buf[64];
switch (action) {
case -1:
case TC_ACT_UNSPEC:
return "continue";
break;
case TC_ACT_OK:
return "pass";
break;
case TC_ACT_SHOT:
return "drop";
break;
case TC_ACT_RECLASSIFY:
return "reclassify";
case TC_ACT_PIPE:
@ -430,34 +429,49 @@ char *action_n2a(int action, char *buf, int len)
case TC_ACT_STOLEN:
return "stolen";
default:
snprintf(buf, len, "%d", action);
snprintf(buf, 64, "%d", action);
buf[63] = '\0';
return buf;
}
}
int action_a2n(char *arg, int *result)
/* Convert action branch name into numeric format.
*
* Parameters:
* @arg - string to parse
* @result - pointer to output variable
* @allow_num - whether @arg may be in numeric format already
*
* In error case, returns -1 and does not touch @result. Otherwise returns 0.
*/
int action_a2n(char *arg, int *result, bool allow_num)
{
int res;
if (matches(arg, "continue") == 0)
res = -1;
else if (matches(arg, "drop") == 0)
res = TC_ACT_SHOT;
else if (matches(arg, "shot") == 0)
res = TC_ACT_SHOT;
else if (matches(arg, "pass") == 0)
res = TC_ACT_OK;
else if (strcmp(arg, "ok") == 0)
res = TC_ACT_OK;
else if (matches(arg, "reclassify") == 0)
res = TC_ACT_RECLASSIFY;
else {
int n;
char dummy;
struct {
const char *a;
int n;
} a2n[] = {
{"continue", TC_ACT_UNSPEC},
{"drop", TC_ACT_SHOT},
{"shot", TC_ACT_SHOT},
{"pass", TC_ACT_OK},
{"ok", TC_ACT_OK},
{"reclassify", TC_ACT_RECLASSIFY},
{"pipe", TC_ACT_PIPE},
{ NULL },
}, *iter;
if (sscanf(arg, "%d%c", &res, &dummy) != 1)
return -1;
for (iter = a2n; iter->a; iter++) {
if (matches(arg, iter->a) != 0)
continue;
*result = iter->n;
return 0;
}
*result = res;
if (!allow_num || sscanf(arg, "%d%c", &n, &dummy) != 1)
return -1;
*result = n;
return 0;
}

View File

@ -22,11 +22,15 @@ enum
struct qdisc_util {
struct qdisc_util *next;
const char *id;
int (*parse_qopt)(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n);
int (*print_qopt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
int (*print_xstats)(struct qdisc_util *qu, FILE *f, struct rtattr *xstats);
int (*parse_qopt)(struct qdisc_util *qu, int argc,
char **argv, struct nlmsghdr *n);
int (*print_qopt)(struct qdisc_util *qu,
FILE *f, struct rtattr *opt);
int (*print_xstats)(struct qdisc_util *qu,
FILE *f, struct rtattr *xstats);
int (*parse_copt)(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n);
int (*parse_copt)(struct qdisc_util *qu, int argc,
char **argv, struct nlmsghdr *n);
int (*print_copt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
};
@ -34,18 +38,20 @@ extern __u16 f_proto;
struct filter_util {
struct filter_util *next;
char id[16];
int (*parse_fopt)(struct filter_util *qu, char *fhandle, int argc,
char **argv, struct nlmsghdr *n);
int (*print_fopt)(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 fhandle);
int (*parse_fopt)(struct filter_util *qu, char *fhandle,
int argc, char **argv, struct nlmsghdr *n);
int (*print_fopt)(struct filter_util *qu,
FILE *f, struct rtattr *opt, __u32 fhandle);
};
struct action_util {
struct action_util *next;
char id[16];
int (*parse_aopt)(struct action_util *a, int *argc, char ***argv,
int code, struct nlmsghdr *n);
int (*parse_aopt)(struct action_util *a, int *argc,
char ***argv, int code, struct nlmsghdr *n);
int (*print_aopt)(struct action_util *au, FILE *f, struct rtattr *opt);
int (*print_xstats)(struct action_util *au, FILE *f, struct rtattr *xstats);
int (*print_xstats)(struct action_util *au,
FILE *f, struct rtattr *xstats);
};
struct exec_util {
@ -54,57 +60,58 @@ struct exec_util {
int (*parse_eopt)(struct exec_util *eu, int argc, char **argv);
};
extern const char *get_tc_lib(void);
const char *get_tc_lib(void);
extern struct qdisc_util *get_qdisc_kind(const char *str);
extern struct filter_util *get_filter_kind(const char *str);
struct qdisc_util *get_qdisc_kind(const char *str);
struct filter_util *get_filter_kind(const char *str);
extern int get_qdisc_handle(__u32 *h, const char *str);
extern int get_rate(unsigned *rate, const char *str);
extern int get_rate64(__u64 *rate, const char *str);
extern int get_size(unsigned *size, const char *str);
extern int get_size_and_cell(unsigned *size, int *cell_log, char *str);
extern int get_time(unsigned *time, const char *str);
extern int get_linklayer(unsigned *val, const char *arg);
int get_qdisc_handle(__u32 *h, const char *str);
int get_rate(unsigned int *rate, const char *str);
int get_rate64(__u64 *rate, const char *str);
int get_size(unsigned int *size, const char *str);
int get_size_and_cell(unsigned int *size, int *cell_log, char *str);
int get_time(unsigned int *time, const char *str);
int get_linklayer(unsigned int *val, const char *arg);
extern void print_rate(char *buf, int len, __u64 rate);
extern void print_size(char *buf, int len, __u32 size);
extern void print_qdisc_handle(char *buf, int len, __u32 h);
extern void print_time(char *buf, int len, __u32 time);
extern void print_linklayer(char *buf, int len, unsigned linklayer);
void print_rate(char *buf, int len, __u64 rate);
void print_size(char *buf, int len, __u32 size);
void print_qdisc_handle(char *buf, int len, __u32 h);
void print_time(char *buf, int len, __u32 time);
void print_linklayer(char *buf, int len, unsigned int linklayer);
extern char * sprint_rate(__u64 rate, char *buf);
extern char * sprint_size(__u32 size, char *buf);
extern char * sprint_qdisc_handle(__u32 h, char *buf);
extern char * sprint_tc_classid(__u32 h, char *buf);
extern char * sprint_time(__u32 time, char *buf);
extern char * sprint_ticks(__u32 ticks, char *buf);
extern char * sprint_linklayer(unsigned linklayer, char *buf);
char *sprint_rate(__u64 rate, char *buf);
char *sprint_size(__u32 size, char *buf);
char *sprint_qdisc_handle(__u32 h, char *buf);
char *sprint_tc_classid(__u32 h, char *buf);
char *sprint_time(__u32 time, char *buf);
char *sprint_ticks(__u32 ticks, char *buf);
char *sprint_linklayer(unsigned int linklayer, char *buf);
extern void print_tcstats_attr(FILE *fp, struct rtattr *tb[], char *prefix, struct rtattr **xstats);
extern void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats);
void print_tcstats_attr(FILE *fp, struct rtattr *tb[],
char *prefix, struct rtattr **xstats);
void print_tcstats2_attr(FILE *fp, struct rtattr *rta,
char *prefix, struct rtattr **xstats);
extern int get_tc_classid(__u32 *h, const char *str);
extern int print_tc_classid(char *buf, int len, __u32 h);
extern char * sprint_tc_classid(__u32 h, char *buf);
int get_tc_classid(__u32 *h, const char *str);
int print_tc_classid(char *buf, int len, __u32 h);
char *sprint_tc_classid(__u32 h, char *buf);
extern int tc_print_police(FILE *f, struct rtattr *tb);
extern int parse_police(int *, char ***, int, struct nlmsghdr *);
int tc_print_police(FILE *f, struct rtattr *tb);
int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n);
extern char *action_n2a(int action, char *buf, int len);
extern int action_a2n(char *arg, int *result);
extern int act_parse_police(struct action_util *a,int *, char ***, int, struct nlmsghdr *);
extern int print_police(struct action_util *a, FILE *f,
struct rtattr *tb);
extern int police_print_xstats(struct action_util *a,FILE *f,
struct rtattr *tb);
extern int tc_print_action(FILE *f, const struct rtattr *tb);
extern int tc_print_ipt(FILE *f, const struct rtattr *tb);
extern int parse_action(int *, char ***, int, struct nlmsghdr *);
extern void print_tm(FILE *f, const struct tcf_t *tm);
extern int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
const char *action_n2a(int action);
int action_a2n(char *arg, int *result, bool allow_num);
int act_parse_police(struct action_util *a, int *argc_p,
char ***argv_p, int tca_id, struct nlmsghdr *n);
int print_police(struct action_util *a, FILE *f, struct rtattr *tb);
int police_print_xstats(struct action_util *a, FILE *f, struct rtattr *tb);
int tc_print_action(FILE *f, const struct rtattr *tb);
int tc_print_ipt(FILE *f, const struct rtattr *tb);
int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n);
void print_tm(FILE *f, const struct tcf_t *tm);
int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
extern int cls_names_init(char *path);
extern void cls_names_uninit(void);
int cls_names_init(char *path);
void cls_names_uninit(void);
#endif