From 9bf9d05b235936d03e41abe4ab15cd7cd59053b8 Mon Sep 17 00:00:00 2001 From: Shanker Wang Date: Thu, 21 Jul 2016 18:59:10 +0800 Subject: [PATCH 1/6] l2tp: add udp checksum control flags Three options are added for the user to control whether the checksum is enabled Signed-off-by: Miao Wang --- ip/ipl2tp.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c index 1f84c614..9ebda135 100644 --- a/ip/ipl2tp.c +++ b/ip/ipl2tp.c @@ -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; From 9ffc80b1e49c4264fb20851e179aaa8ec0bc0766 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 23 Jul 2016 13:28:07 +0200 Subject: [PATCH 2/6] tc: Reformat tc_util.h * Drop 'extern' keyword before function declarations. * Add parameter names where they were missing for matters of consistency. * Drop fancy indenting (e.g. tab between type and name). * Break long lines to not exceed 80 columns. Signed-off-by: Phil Sutter --- tc/tc_util.h | 129 +++++++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 61 deletions(-) diff --git a/tc/tc_util.h b/tc/tc_util.h index 61e60b1c..744f18fd 100644 --- a/tc/tc_util.h +++ b/tc/tc_util.h @@ -22,89 +22,96 @@ 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 (*print_copt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt); + 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); }; 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); + 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); }; 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 (*print_aopt)(struct action_util *au, FILE *f, struct rtattr *opt); - int (*print_xstats)(struct action_util *au, FILE *f, struct rtattr *xstats); + struct action_util *next; + char id[16]; + 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); }; struct exec_util { - struct exec_util *next; - char id[16]; - int (*parse_eopt)(struct exec_util *eu, int argc, char **argv); + struct exec_util *next; + char id[16]; + 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); +char *action_n2a(int action, char *buf, int len); +int action_a2n(char *arg, int *result); +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 From 53aadc5286261fecb6e994918db8371515f9dd99 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 23 Jul 2016 13:28:08 +0200 Subject: [PATCH 3/6] tc: util: bore up action_a2n() It's a pitty this function is used nowhere, so let's polish it for use: * Loop over branch names, makes it clear that every former conditional was exactly identical. * Support 'pipe' branch name, too. * Make number parsing optional. Signed-off-by: Phil Sutter --- tc/tc_util.c | 54 +++++++++++++++++++++++++++++++++------------------- tc/tc_util.h | 2 +- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/tc/tc_util.c b/tc/tc_util.c index fd6669f2..cd7b40b0 100644 --- a/tc/tc_util.c +++ b/tc/tc_util.c @@ -435,29 +435,43 @@ char *action_n2a(int action, char *buf, int len) } } -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; + 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 (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 { - char dummy; - - 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; } diff --git a/tc/tc_util.h b/tc/tc_util.h index 744f18fd..e7613ab1 100644 --- a/tc/tc_util.h +++ b/tc/tc_util.h @@ -100,7 +100,7 @@ int tc_print_police(FILE *f, struct rtattr *tb); int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n); char *action_n2a(int action, char *buf, int len); -int action_a2n(char *arg, int *result); +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); From 69f5aff63c770bd95607b33d5ee8ee183dc13a64 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 23 Jul 2016 13:28:09 +0200 Subject: [PATCH 4/6] tc: use action_a2n() everywhere Signed-off-by: Phil Sutter --- tc/m_bpf.c | 22 ++-------------------- tc/m_connmark.c | 27 ++------------------------- tc/m_csum.c | 27 ++------------------------- tc/m_gact.c | 17 ++++------------- tc/m_ife.c | 27 ++------------------------- tc/m_mirred.c | 25 +++---------------------- tc/m_nat.c | 27 ++------------------------- tc/m_pedit.c | 22 ++-------------------- tc/m_police.c | 32 ++------------------------------ tc/m_simple.c | 27 ++------------------------- tc/m_skbedit.c | 22 ++-------------------- tc/m_vlan.c | 27 ++------------------------- 12 files changed, 27 insertions(+), 275 deletions(-) diff --git a/tc/m_bpf.c b/tc/m_bpf.c index 20da11d0..275634e7 100644 --- a/tc/m_bpf.c +++ b/tc/m_bpf.c @@ -104,26 +104,8 @@ opt_bpf: NEXT_ARG_FWD(); } - if (argc) { - if (matches(*argv, "reclassify") == 0) { - parm.action = TC_ACT_RECLASSIFY; - 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 && !action_a2n(*argv, &parm.action, false)) + NEXT_ARG_FWD(); if (argc) { if (matches(*argv, "index") == 0) { diff --git a/tc/m_connmark.c b/tc/m_connmark.c index 143d75de..20f98e4f 100644 --- a/tc/m_connmark.c +++ b/tc/m_connmark.c @@ -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) { diff --git a/tc/m_csum.c b/tc/m_csum.c index 047986ef..db7eed3a 100644 --- a/tc/m_csum.c +++ b/tc/m_csum.c @@ -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) { diff --git a/tc/m_gact.c b/tc/m_gact.c index ea2c9ec8..9f31fdd3 100644 --- a/tc/m_gact.c +++ b/tc/m_gact.c @@ -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 diff --git a/tc/m_ife.c b/tc/m_ife.c index eaab1cc8..5eee544b 100644 --- a/tc/m_ife.c +++ b/tc/m_ife.c @@ -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) { diff --git a/tc/m_mirred.c b/tc/m_mirred.c index 0066905a..61a84f57 100644 --- a/tc/m_mirred.c +++ b/tc/m_mirred.c @@ -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; - 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 && p.eaction == TCA_EGRESS_MIRROR + && !action_a2n(*argv, &p.action, false)) + NEXT_ARG(); if (argc) { if (iok && matches(*argv, "index") == 0) { diff --git a/tc/m_nat.c b/tc/m_nat.c index 839fb8a0..52bafa79 100644 --- a/tc/m_nat.c +++ b/tc/m_nat.c @@ -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) { diff --git a/tc/m_pedit.c b/tc/m_pedit.c index 35879b7f..c28f2610 100644 --- a/tc/m_pedit.c +++ b/tc/m_pedit.c @@ -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; - 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 && !action_a2n(*argv, &sel.sel.action, false)) + NEXT_ARG(); if (argc) { if (matches(*argv, "index") == 0) { diff --git a/tc/m_police.c b/tc/m_police.c index 9ae25f28..3ba580e4 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -71,34 +71,6 @@ static const char *police_action_n2a(int action, char *buf, int len) } } -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 +78,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 +86,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; diff --git a/tc/m_simple.c b/tc/m_simple.c index 27b3e5e4..732eaf1e 100644 --- a/tc/m_simple.c +++ b/tc/m_simple.c @@ -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) { diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c index 9ba288c0..eca6a8ac 100644 --- a/tc/m_skbedit.c +++ b/tc/m_skbedit.c @@ -100,26 +100,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; - 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 && !action_a2n(*argv, &sel.action, false)) + NEXT_ARG(); if (argc) { if (matches(*argv, "index") == 0) { diff --git a/tc/m_vlan.c b/tc/m_vlan.c index c2684461..82311dd6 100644 --- a/tc/m_vlan.c +++ b/tc/m_vlan.c @@ -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) { From 709320061154c2d381aa91fc6a135eea96b32672 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 23 Jul 2016 13:28:10 +0200 Subject: [PATCH 5/6] tc: util: No need for action_n2a() to be reentrant This allows to remove some buffers here and there. While at it, make it return a const value. Signed-off-by: Phil Sutter --- tc/m_bpf.c | 5 +---- tc/m_csum.c | 4 +--- tc/m_gact.c | 7 +++---- tc/m_ife.c | 3 +-- tc/m_mirred.c | 5 ++--- tc/m_nat.c | 3 +-- tc/m_pedit.c | 4 +--- tc/m_police.c | 28 ++-------------------------- tc/m_vlan.c | 2 +- tc/tc_util.c | 12 ++++++------ tc/tc_util.h | 2 +- 11 files changed, 20 insertions(+), 55 deletions(-) diff --git a/tc/m_bpf.c b/tc/m_bpf.c index 275634e7..9bf2a85e 100644 --- a/tc/m_bpf.c +++ b/tc/m_bpf.c @@ -136,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; @@ -162,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); diff --git a/tc/m_csum.c b/tc/m_csum.c index db7eed3a..a6e4c1eb 100644 --- a/tc/m_csum.c +++ b/tc/m_csum.c @@ -161,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) @@ -200,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) { diff --git a/tc/m_gact.c b/tc/m_gact.c index 9f31fdd3..c0a938c7 100644 --- a/tc/m_gact.c +++ b/tc/m_gact.c @@ -194,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 @@ -214,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]); @@ -223,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) { diff --git a/tc/m_ife.c b/tc/m_ife.c index 5eee544b..0219760a 100644 --- a/tc/m_ife.c +++ b/tc/m_ife.c @@ -215,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) @@ -231,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]); diff --git a/tc/m_mirred.c b/tc/m_mirred.c index 61a84f57..11f4c9b4 100644 --- a/tc/m_mirred.c +++ b/tc/m_mirred.c @@ -235,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; @@ -258,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); diff --git a/tc/m_nat.c b/tc/m_nat.c index 52bafa79..525f185e 100644 --- a/tc/m_nat.c +++ b/tc/m_nat.c @@ -148,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) @@ -170,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]) { diff --git a/tc/m_pedit.c b/tc/m_pedit.c index c28f2610..891c2ec7 100644 --- a/tc/m_pedit.c +++ b/tc/m_pedit.c @@ -514,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; @@ -528,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); diff --git a/tc/m_police.c b/tc/m_police.c index 3ba580e4..f0b179fc 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -49,28 +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 get_police_result(int *action, int *result, char *arg) { char *p = strchr(arg, '/'); @@ -339,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, " "); diff --git a/tc/m_vlan.c b/tc/m_vlan.c index 82311dd6..ac63d9ed 100644 --- a/tc/m_vlan.c +++ b/tc/m_vlan.c @@ -182,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); diff --git a/tc/tc_util.c b/tc/tc_util.c index cd7b40b0..15e49b7b 100644 --- a/tc/tc_util.c +++ b/tc/tc_util.c @@ -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,7 +429,8 @@ 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; } } diff --git a/tc/tc_util.h b/tc/tc_util.h index e7613ab1..f198a4ad 100644 --- a/tc/tc_util.h +++ b/tc/tc_util.h @@ -99,7 +99,7 @@ char *sprint_tc_classid(__u32 h, char *buf); int tc_print_police(FILE *f, struct rtattr *tb); int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n); -char *action_n2a(int action, char *buf, int len); +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); From bdd6104f52ad10c67d37bf4c6c36efa137d5d0ec Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Sun, 24 Jul 2016 02:00:29 +0200 Subject: [PATCH 6/6] man/man8/tc-flow.8: minor corrections - baseclass: major handle must match that of class's, Y defaults to 1 - flow map example: maps to 1-256, not 1-257 Signed-off-by: Michal Soltys --- man/man8/tc-flow.8 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/man/man8/tc-flow.8 b/man/man8/tc-flow.8 index f1b7e2a4..54f6bf7d 100644 --- a/man/man8/tc-flow.8 +++ b/man/man8/tc-flow.8 @@ -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 \\