From d52ec5720f6076283c561111503387781e3f3f07 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 14 May 2019 16:28:31 +0200 Subject: [PATCH] lib: add some printfrr specifiers More to come - these are just the most obvious and easy. Signed-off-by: David Lamparter --- lib/nexthop.c | 85 +++++++++++++++++++++++++++++++++++++++++++++ lib/prefix.c | 46 ++++++++++++++++++++++++ lib/srcdest_table.c | 18 ++++++++-- lib/srcdest_table.h | 8 ++--- 4 files changed, 151 insertions(+), 6 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 57a2f1daaa..4cea14955a 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -32,6 +32,7 @@ #include "nexthop.h" #include "mpls.h" #include "jhash.h" +#include "printfrr.h" DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop") DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label") @@ -423,3 +424,87 @@ uint32_t nexthop_hash(const struct nexthop *nexthop) } return key; } + +/* + * nexthop printing variants: + * %pNHvv + * via 1.2.3.4 + * via 1.2.3.4, eth0 + * is directly connected, eth0 + * unreachable (blackhole) + * %pNHv + * 1.2.3.4 + * 1.2.3.4, via eth0 + * directly connected, eth0 + * unreachable (blackhole) + * %pNHs + * nexthop2str() + */ +printfrr_ext_autoreg_p("NH", printfrr_nh) +static ssize_t printfrr_nh(char *buf, size_t bsz, const char *fmt, + int prec, const void *ptr) +{ + const struct nexthop *nexthop = ptr; + struct fbuf fb = { .buf = buf, .pos = buf, .len = bsz - 1 }; + bool do_ifi = false; + const char *s, *v_is = "", *v_via = "", *v_viaif = "via "; + ssize_t ret = 3; + + switch (fmt[2]) { + case 'v': + if (fmt[3] == 'v') { + v_is = "is "; + v_via = "via "; + v_viaif = ""; + ret++; + } + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + bprintfrr(&fb, "%s%pI4", v_via, &nexthop->gate.ipv4); + do_ifi = true; + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + bprintfrr(&fb, "%s%pI6", v_via, &nexthop->gate.ipv6); + do_ifi = true; + break; + case NEXTHOP_TYPE_IFINDEX: + bprintfrr(&fb, "%sdirectly connected, %s", v_is, + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + switch (nexthop->bh_type) { + case BLACKHOLE_REJECT: + s = " (ICMP unreachable)"; + break; + case BLACKHOLE_ADMINPROHIB: + s = " (ICMP admin-prohibited)"; + break; + case BLACKHOLE_NULL: + s = " (blackhole)"; + break; + default: + s = ""; + break; + } + bprintfrr(&fb, "unreachable%s", s); + break; + default: + break; + } + if (do_ifi && nexthop->ifindex) + bprintfrr(&fb, ", %s%s", v_viaif, ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); + + *fb.pos = '\0'; + return ret; + case 's': + nexthop2str(nexthop, buf, bsz); + return 3; + } + return 0; +} diff --git a/lib/prefix.c b/lib/prefix.c index 42d202ddbc..134d9cf908 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -28,6 +28,7 @@ #include "log.h" #include "jhash.h" #include "lib_errors.h" +#include "printfrr.h" DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix") DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec") @@ -1626,3 +1627,48 @@ char *esi_to_str(const esi_t *esi, char *buf, int size) esi->val[9]); return ptr; } + +printfrr_ext_autoreg_p("I4", printfrr_i4) +static ssize_t printfrr_i4(char *buf, size_t bsz, const char *fmt, + int prec, const void *ptr) +{ + inet_ntop(AF_INET, ptr, buf, bsz); + return 2; +} + +printfrr_ext_autoreg_p("I6", printfrr_i6) +static ssize_t printfrr_i6(char *buf, size_t bsz, const char *fmt, + int prec, const void *ptr) +{ + inet_ntop(AF_INET6, ptr, buf, bsz); + return 2; +} + +printfrr_ext_autoreg_p("FX", printfrr_pfx) +static ssize_t printfrr_pfx(char *buf, size_t bsz, const char *fmt, + int prec, const void *ptr) +{ + prefix2str(ptr, buf, bsz); + return 2; +} + +printfrr_ext_autoreg_p("SG4", printfrr_psg) +static ssize_t printfrr_psg(char *buf, size_t bsz, const char *fmt, + int prec, const void *ptr) +{ + const struct prefix_sg *sg = ptr; + struct fbuf fb = { .buf = buf, .pos = buf, .len = bsz - 1 }; + + if (sg->src.s_addr == INADDR_ANY) + bprintfrr(&fb, "(*,"); + else + bprintfrr(&fb, "(%pI4,", &sg->src); + + if (sg->grp.s_addr == INADDR_ANY) + bprintfrr(&fb, "*)"); + else + bprintfrr(&fb, "%pI4)", &sg->grp); + + fb.pos[0] = '\0'; + return 3; +} diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c index 80004b41ac..ee87d73077 100644 --- a/lib/srcdest_table.c +++ b/lib/srcdest_table.c @@ -28,6 +28,7 @@ #include "memory.h" #include "prefix.h" #include "table.h" +#include "printfrr.h" DEFINE_MTYPE_STATIC(LIB, ROUTE_SRC_NODE, "Route source node") @@ -264,7 +265,8 @@ struct route_node *srcdest_rnode_lookup(struct route_table *table, return srn; } -void srcdest_rnode_prefixes(struct route_node *rn, const struct prefix **p, +void srcdest_rnode_prefixes(const struct route_node *rn, + const struct prefix **p, const struct prefix **src_p) { if (rnode_is_srcnode(rn)) { @@ -296,10 +298,22 @@ const char *srcdest2str(const struct prefix *dst_p, return str; } -const char *srcdest_rnode2str(struct route_node *rn, char *str, int size) +const char *srcdest_rnode2str(const struct route_node *rn, char *str, int size) { const struct prefix *dst_p, *src_p; srcdest_rnode_prefixes(rn, &dst_p, &src_p); return srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, str, size); } + +printfrr_ext_autoreg_p("RN", printfrr_rn) +static ssize_t printfrr_rn(char *buf, size_t bsz, const char *fmt, + int prec, const void *ptr) +{ + const struct route_node *rn = ptr; + const struct prefix *dst_p, *src_p; + + srcdest_rnode_prefixes(rn, &dst_p, &src_p); + srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, buf, bsz); + return 2; +} diff --git a/lib/srcdest_table.h b/lib/srcdest_table.h index 8845931de7..90418944c7 100644 --- a/lib/srcdest_table.h +++ b/lib/srcdest_table.h @@ -65,22 +65,22 @@ extern struct route_node *srcdest_rnode_get(struct route_table *table, extern struct route_node *srcdest_rnode_lookup(struct route_table *table, union prefixconstptr dst_pu, const struct prefix_ipv6 *src_p); -extern void srcdest_rnode_prefixes(struct route_node *rn, +extern void srcdest_rnode_prefixes(const struct route_node *rn, const struct prefix **p, const struct prefix **src_p); extern const char *srcdest2str(const struct prefix *dst_p, const struct prefix_ipv6 *src_p, char *str, int size); -extern const char *srcdest_rnode2str(struct route_node *rn, char *str, +extern const char *srcdest_rnode2str(const struct route_node *rn, char *str, int size); extern struct route_node *srcdest_route_next(struct route_node *rn); -static inline int rnode_is_dstnode(struct route_node *rn) +static inline int rnode_is_dstnode(const struct route_node *rn) { return rn->table->delegate == &_srcdest_dstnode_delegate; } -static inline int rnode_is_srcnode(struct route_node *rn) +static inline int rnode_is_srcnode(const struct route_node *rn) { return rn->table->delegate == &_srcdest_srcnode_delegate; }