Get rid of code duplications and consolidate encapsulation options printing in single function - tnl_print_encap().
Introduce and use tnl_encap_str() to format encapsulation option string according to tempate and given values to avoid code duplication and simplify it. Use print_string() instead of fputs() and fprintf() to print encapsulation for !is_json_context(). Print "unknown" parameter for "encap" type in PRINT_FP context using "%s " format specifier and benefit from complite time string merge. Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com> --- ip/link_gre.c | 75 +++----------------------------------------- ip/link_gre6.c | 64 +++----------------------------------- ip/link_ip6tnl.c | 63 +++---------------------------------- ip/link_iptnl.c | 70 ++++------------------------------------- ip/tunnel.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ip/tunnel.h | 5 +++ 6 files changed, 117 insertions(+), 251 deletions(-) diff --git a/ip/link_gre.c b/ip/link_gre.c index 2462828..d403d24 100644 --- a/ip/link_gre.c +++ b/ip/link_gre.c @@ -468,76 +468,11 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) fprintf(f, "erspan_index %u ", erspan_idx); } - if (tb[IFLA_GRE_ENCAP_TYPE] && - rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) { - __u16 type = rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]); - __u16 flags = rta_getattr_u16(tb[IFLA_GRE_ENCAP_FLAGS]); - __u16 sport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_SPORT]); - __u16 dport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_DPORT]); - - - open_json_object("encap"); - print_string(PRINT_FP, NULL, "encap ", NULL); - - switch (type) { - case TUNNEL_ENCAP_FOU: - print_string(PRINT_ANY, "type", "%s ", "fou"); - break; - case TUNNEL_ENCAP_GUE: - print_string(PRINT_ANY, "type", "%s ", "gue"); - break; - default: - print_null(PRINT_ANY, "type", "%s ", "unknown"); - break; - } - - if (is_json_context()) { - print_uint(PRINT_JSON, - "sport", - NULL, - sport ? ntohs(sport) : 0); - print_uint(PRINT_JSON, "dport", NULL, ntohs(dport)); - - print_bool(PRINT_JSON, - "csum", - NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM); - - print_bool(PRINT_JSON, - "csum6", - NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM6); - - print_bool(PRINT_JSON, - "remcsum", - NULL, - flags & TUNNEL_ENCAP_FLAG_REMCSUM); - - close_json_object(); - } else { - if (sport == 0) - fputs("encap-sport auto ", f); - else - fprintf(f, "encap-sport %u", ntohs(sport)); - - fprintf(f, "encap-dport %u ", ntohs(dport)); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM) - fputs("encap-csum ", f); - else - fputs("noencap-csum ", f); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM6) - fputs("encap-csum6 ", f); - else - fputs("noencap-csum6 ", f); - - if (flags & TUNNEL_ENCAP_FLAG_REMCSUM) - fputs("encap-remcsum ", f); - else - fputs("noencap-remcsum ", f); - } - } + tnl_print_encap(tb, + IFLA_GRE_ENCAP_TYPE, + IFLA_GRE_ENCAP_FLAGS, + IFLA_GRE_ENCAP_SPORT, + IFLA_GRE_ENCAP_DPORT); } static void gre_print_help(struct link_util *lu, int argc, char **argv, diff --git a/ip/link_gre6.c b/ip/link_gre6.c index 7dcd70d..a159b54 100644 --- a/ip/link_gre6.c +++ b/ip/link_gre6.c @@ -516,65 +516,11 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) fprintf(f, "erspan_index %u ", erspan_idx); } - if (tb[IFLA_GRE_ENCAP_TYPE] && - rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) { - __u16 type = rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]); - __u16 flags = rta_getattr_u16(tb[IFLA_GRE_ENCAP_FLAGS]); - __u16 sport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_SPORT]); - __u16 dport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_DPORT]); - - open_json_object("encap"); - - print_string(PRINT_FP, NULL, "encap ", NULL); - switch (type) { - case TUNNEL_ENCAP_FOU: - print_string(PRINT_ANY, "type", "%s ", "fou"); - break; - case TUNNEL_ENCAP_GUE: - print_string(PRINT_ANY, "type", "%s ", "gue"); - break; - default: - print_null(PRINT_ANY, "type", "unknown ", NULL); - break; - } - - if (is_json_context()) { - print_uint(PRINT_JSON, - "sport", - NULL, - sport ? ntohs(sport) : 0); - print_uint(PRINT_JSON, "dport", NULL, ntohs(dport)); - print_bool(PRINT_JSON, "csum", NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM); - print_bool(PRINT_JSON, "csum6", NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM6); - print_bool(PRINT_JSON, "remcsum", NULL, - flags & TUNNEL_ENCAP_FLAG_REMCSUM); - close_json_object(); - } else { - if (sport == 0) - fputs("encap-sport auto ", f); - else - fprintf(f, "encap-sport %u", ntohs(sport)); - - fprintf(f, "encap-dport %u ", ntohs(dport)); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM) - fputs("encap-csum ", f); - else - fputs("noencap-csum ", f); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM6) - fputs("encap-csum6 ", f); - else - fputs("noencap-csum6 ", f); - - if (flags & TUNNEL_ENCAP_FLAG_REMCSUM) - fputs("encap-remcsum ", f); - else - fputs("noencap-remcsum ", f); - } - } + tnl_print_encap(tb, + IFLA_GRE_ENCAP_TYPE, + IFLA_GRE_ENCAP_FLAGS, + IFLA_GRE_ENCAP_SPORT, + IFLA_GRE_ENCAP_DPORT); } static void gre_print_help(struct link_util *lu, int argc, char **argv, diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c index 00bf00a..8f5c9bd 100644 --- a/ip/link_ip6tnl.c +++ b/ip/link_ip6tnl.c @@ -458,64 +458,11 @@ static void ip6tunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb } } - if (tb[IFLA_IPTUN_ENCAP_TYPE] && - rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) { - __u16 type = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_TYPE]); - __u16 flags = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_FLAGS]); - __u16 sport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_SPORT]); - __u16 dport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_DPORT]); - - open_json_object("encap"); - print_string(PRINT_FP, NULL, "encap ", NULL); - switch (type) { - case TUNNEL_ENCAP_FOU: - print_string(PRINT_ANY, "type", "%s ", "fou"); - break; - case TUNNEL_ENCAP_GUE: - print_string(PRINT_ANY, "type", "%s ", "gue"); - break; - default: - print_null(PRINT_ANY, "type", "unknown ", NULL); - break; - } - - if (is_json_context()) { - print_uint(PRINT_JSON, - "sport", - NULL, - sport ? ntohs(sport) : 0); - print_uint(PRINT_JSON, "dport", NULL, ntohs(dport)); - print_bool(PRINT_JSON, "csum", NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM); - print_bool(PRINT_JSON, "csum6", NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM6); - print_bool(PRINT_JSON, "remcsum", NULL, - flags & TUNNEL_ENCAP_FLAG_REMCSUM); - close_json_object(); - } else { - if (sport == 0) - fputs("encap-sport auto ", f); - else - fprintf(f, "encap-sport %u", ntohs(sport)); - - fprintf(f, "encap-dport %u ", ntohs(dport)); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM) - fputs("encap-csum ", f); - else - fputs("noencap-csum ", f); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM6) - fputs("encap-csum6 ", f); - else - fputs("noencap-csum6 ", f); - - if (flags & TUNNEL_ENCAP_FLAG_REMCSUM) - fputs("encap-remcsum ", f); - else - fputs("noencap-remcsum ", f); - } - } + tnl_print_encap(tb, + IFLA_IPTUN_ENCAP_TYPE, + IFLA_IPTUN_ENCAP_FLAGS, + IFLA_IPTUN_ENCAP_SPORT, + IFLA_IPTUN_ENCAP_DPORT); } static void ip6tunnel_print_help(struct link_util *lu, int argc, char **argv, diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c index 00a8366..ce3855c 100644 --- a/ip/link_iptnl.c +++ b/ip/link_iptnl.c @@ -363,7 +363,7 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[ char s2[64]; const char *local = "any"; const char *remote = "any"; - __u16 prefixlen, type; + __u16 prefixlen; __u8 ttl = 0; __u8 tos = 0; @@ -490,69 +490,11 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[ } } - if (tb[IFLA_IPTUN_ENCAP_TYPE] && - (type = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_TYPE])) != TUNNEL_ENCAP_NONE) { - __u16 flags = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_FLAGS]); - __u16 sport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_SPORT]); - __u16 dport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_DPORT]); - - open_json_object("encap"); - print_string(PRINT_FP, NULL, "encap ", NULL); - switch (type) { - case TUNNEL_ENCAP_FOU: - print_string(PRINT_ANY, "type", "%s ", "fou"); - break; - case TUNNEL_ENCAP_GUE: - print_string(PRINT_ANY, "type", "%s ", "gue"); - break; - default: - print_null(PRINT_ANY, "type", "unknown ", NULL); - break; - } - - if (is_json_context()) { - print_uint(PRINT_JSON, - "sport", - NULL, - sport ? ntohs(sport) : 0); - print_uint(PRINT_JSON, "dport", NULL, ntohs(dport)); - print_bool(PRINT_JSON, - "csum", - NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM); - print_bool(PRINT_JSON, - "csum6", - NULL, - flags & TUNNEL_ENCAP_FLAG_CSUM6); - print_bool(PRINT_JSON, - "remcsum", - NULL, - flags & TUNNEL_ENCAP_FLAG_REMCSUM); - close_json_object(); - } else { - if (sport == 0) - fputs("encap-sport auto ", f); - else - fprintf(f, "encap-sport %u", ntohs(sport)); - - fprintf(f, "encap-dport %u ", ntohs(dport)); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM) - fputs("encap-csum ", f); - else - fputs("noencap-csum ", f); - - if (flags & TUNNEL_ENCAP_FLAG_CSUM6) - fputs("encap-csum6 ", f); - else - fputs("noencap-csum6 ", f); - - if (flags & TUNNEL_ENCAP_FLAG_REMCSUM) - fputs("encap-remcsum ", f); - else - fputs("noencap-remcsum ", f); - } - } + tnl_print_encap(tb, + IFLA_IPTUN_ENCAP_TYPE, + IFLA_IPTUN_ENCAP_FLAGS, + IFLA_IPTUN_ENCAP_SPORT, + IFLA_IPTUN_ENCAP_DPORT); } static void iptunnel_print_help(struct link_util *lu, int argc, char **argv, diff --git a/ip/tunnel.c b/ip/tunnel.c index f860103..42ae70e 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -36,6 +36,7 @@ #include "utils.h" #include "tunnel.h" +#include "json_print.h" const char *tnl_strproto(__u8 proto) { @@ -200,6 +201,96 @@ __be32 tnl_parse_key(const char *name, const char *key) return htonl(uval); } +static const char *tnl_encap_str(const char *name, int enabled, int port) +{ + static const char ne[][sizeof("no")] = { + [0] = "no", + [1] = "", + }; + static char buf[32]; + char b1[16]; + const char *val; + + if (!port) { + val = "auto"; + } else if (port < 0) { + val = ""; + } else { + snprintf(b1, sizeof(b1), "%u", port - 1); + val = b1; + } + + snprintf(buf, sizeof(buf), "%sencap-%s %s", ne[!!enabled], name, val); + return buf; +} + +void tnl_print_encap(struct rtattr *tb[], + int encap_type, int encap_flags, + int encap_sport, int encap_dport) +{ + __u16 type, flags, sport, dport; + + if (!tb[encap_type]) + return; + + type = rta_getattr_u16(tb[encap_type]); + if (type == TUNNEL_ENCAP_NONE) + return; + + flags = rta_getattr_u16(tb[encap_flags]); + sport = rta_getattr_u16(tb[encap_sport]); + dport = rta_getattr_u16(tb[encap_dport]); + + open_json_object("encap"); + print_string(PRINT_FP, NULL, "encap ", NULL); + + switch (type) { + case TUNNEL_ENCAP_FOU: + print_string(PRINT_ANY, "type", "%s ", "fou"); + break; + case TUNNEL_ENCAP_GUE: + print_string(PRINT_ANY, "type", "%s ", "gue"); + break; + default: + print_null(PRINT_ANY, "type", "%s ", "unknown"); + break; + } + + if (is_json_context()) { + print_uint(PRINT_JSON, "sport", NULL, ntohs(sport)); + print_uint(PRINT_JSON, "dport", NULL, ntohs(dport)); + print_bool(PRINT_JSON, "csum", NULL, + flags & TUNNEL_ENCAP_FLAG_CSUM); + print_bool(PRINT_JSON, "csum6", NULL, + flags & TUNNEL_ENCAP_FLAG_CSUM6); + print_bool(PRINT_JSON, "remcsum", NULL, + flags & TUNNEL_ENCAP_FLAG_REMCSUM); + close_json_object(); + } else { + int t; + + t = sport ? ntohs(sport) + 1 : 0; + print_string(PRINT_FP, NULL, "%s", + tnl_encap_str("sport", 1, t)); + + t = ntohs(dport) + 1; + print_string(PRINT_FP, NULL, "%s", + tnl_encap_str("dport", 1, t)); + + t = flags & TUNNEL_ENCAP_FLAG_CSUM; + print_string(PRINT_FP, NULL, "%s", + tnl_encap_str("csum", t, -1)); + + t = flags & TUNNEL_ENCAP_FLAG_CSUM6; + print_string(PRINT_FP, NULL, "%s", + tnl_encap_str("csum6", t, -1)); + + t = flags & TUNNEL_ENCAP_FLAG_REMCSUM; + print_string(PRINT_FP, NULL, "%s", + tnl_encap_str("remcsum", t, -1)); + } +} + /* tnl_print_stats - print tunnel statistics * * @buf - tunnel interface's line in /proc/net/dev, diff --git a/ip/tunnel.h b/ip/tunnel.h index 9a03c0d..a5c537c 100644 --- a/ip/tunnel.h +++ b/ip/tunnel.h @@ -23,6 +23,8 @@ #include <linux/types.h> +struct rtattr; + const char *tnl_strproto(__u8 proto); int tnl_get_ioctl(const char *basedev, void *p); @@ -32,6 +34,9 @@ int tnl_prl_ioctl(int cmd, const char *name, void *p); int tnl_6rd_ioctl(int cmd, const char *name, void *p); int tnl_ioctl_get_6rd(const char *name, void *p); __be32 tnl_parse_key(const char *name, const char *key); +void tnl_print_encap(struct rtattr *tb[], + int encap_type, int encap_flags, + int encap_sport, int encap_dport); void tnl_print_stats(const char *buf); #endif -- 1.7.10.4