More to come - these are just the most obvious and easy.
Signed-off-by: David Lamparter <equinox@diac24.net>
#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")
}
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;
+}
#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")
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;
+}
#include "memory.h"
#include "prefix.h"
#include "table.h"
+#include "printfrr.h"
DEFINE_MTYPE_STATIC(LIB, ROUTE_SRC_NODE, "Route source node")
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)) {
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;
+}
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;
}