mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 06:31:27 +00:00
lib: add some printfrr specifiers
More to come - these are just the most obvious and easy. Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
parent
807f5b9842
commit
d52ec5720f
@ -32,6 +32,7 @@
|
|||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
#include "mpls.h"
|
#include "mpls.h"
|
||||||
#include "jhash.h"
|
#include "jhash.h"
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
|
DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
|
||||||
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
|
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
|
||||||
@ -423,3 +424,87 @@ uint32_t nexthop_hash(const struct nexthop *nexthop)
|
|||||||
}
|
}
|
||||||
return key;
|
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;
|
||||||
|
}
|
||||||
|
46
lib/prefix.c
46
lib/prefix.c
@ -28,6 +28,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "jhash.h"
|
#include "jhash.h"
|
||||||
#include "lib_errors.h"
|
#include "lib_errors.h"
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix")
|
DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix")
|
||||||
DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec")
|
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]);
|
esi->val[9]);
|
||||||
return ptr;
|
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;
|
||||||
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(LIB, ROUTE_SRC_NODE, "Route source node")
|
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;
|
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)
|
const struct prefix **src_p)
|
||||||
{
|
{
|
||||||
if (rnode_is_srcnode(rn)) {
|
if (rnode_is_srcnode(rn)) {
|
||||||
@ -296,10 +298,22 @@ const char *srcdest2str(const struct prefix *dst_p,
|
|||||||
return str;
|
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;
|
const struct prefix *dst_p, *src_p;
|
||||||
|
|
||||||
srcdest_rnode_prefixes(rn, &dst_p, &src_p);
|
srcdest_rnode_prefixes(rn, &dst_p, &src_p);
|
||||||
return srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, str, size);
|
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;
|
||||||
|
}
|
||||||
|
@ -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,
|
extern struct route_node *srcdest_rnode_lookup(struct route_table *table,
|
||||||
union prefixconstptr dst_pu,
|
union prefixconstptr dst_pu,
|
||||||
const struct prefix_ipv6 *src_p);
|
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 **p,
|
||||||
const struct prefix **src_p);
|
const struct prefix **src_p);
|
||||||
extern const char *srcdest2str(const struct prefix *dst_p,
|
extern const char *srcdest2str(const struct prefix *dst_p,
|
||||||
const struct prefix_ipv6 *src_p,
|
const struct prefix_ipv6 *src_p,
|
||||||
char *str, int size);
|
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);
|
int size);
|
||||||
extern struct route_node *srcdest_route_next(struct route_node *rn);
|
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;
|
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;
|
return rn->table->delegate == &_srcdest_srcnode_delegate;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user