1
0
mirror of https://github.com/openbsd/src.git synced 2024-12-22 07:27:59 -08:00

Implement bgpctl show flowspec and bgpctl flowspec flush.

This uses the flowspec.c file from bgpd and implements the output
for flowspec only for the text printer for now. That code uses a lot
of code from printconf.c
OK tb@
This commit is contained in:
claudio 2023-04-20 14:01:50 +00:00
parent f7b381036b
commit 5fed6b04b4
6 changed files with 153 additions and 8 deletions

View File

@ -1,10 +1,11 @@
# $OpenBSD: Makefile,v 1.18 2022/10/17 12:01:19 claudio Exp $
# $OpenBSD: Makefile,v 1.19 2023/04/20 14:01:50 claudio Exp $
.PATH: ${.CURDIR}/../bgpd
PROG= bgpctl
SRCS= bgpctl.c output.c output_json.c output_ometric.c parser.c \
mrtparser.c util.c json.c ometric.c
mrtparser.c json.c ometric.c
SRCS+= util.c flowspec.c
CFLAGS+= -Wall
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+= -Wmissing-declarations

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bgpctl.c,v 1.290 2023/03/13 16:59:22 claudio Exp $ */
/* $OpenBSD: bgpctl.c,v 1.291 2023/04/20 14:01:50 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@ -361,6 +361,22 @@ main(int argc, char *argv[])
mrt_parse(res->mrtfd, &net_mrt, 1);
done = 1;
break;
case FLOWSPEC_ADD:
case FLOWSPEC_REMOVE:
done = 1;
break;
case FLOWSPEC_FLUSH:
imsg_compose(ibuf, IMSG_FLOWSPEC_FLUSH, 0, 0, -1, NULL, 0);
printf("request sent.\n");
done = 1;
break;
case FLOWSPEC_SHOW:
memset(&ribreq, 0, sizeof(ribreq));
ribreq.aid = res->aid;
strlcpy(ribreq.rib, res->rib, sizeof(ribreq.rib));
imsg_compose(ibuf, IMSG_CTL_SHOW_FLOWSPEC, 0, 0, -1,
&ribreq, sizeof(ribreq));
break;
case LOG_VERBOSE:
verbose = 1;
/* FALLTHROUGH */
@ -424,6 +440,7 @@ show(struct imsg *imsg, struct parse_result *res)
struct ctl_show_rtr rtr;
struct kroute_full *kf;
struct ktable *kt;
struct flowspec *f;
struct ctl_show_rib rib;
struct rde_memstats stats;
u_char *asdata;
@ -467,6 +484,14 @@ show(struct imsg *imsg, struct parse_result *res)
kf = imsg->data;
output->fib(kf);
break;
case IMSG_CTL_SHOW_FLOWSPEC:
if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(*f))
errx(1, "wrong imsg len");
if (output->flowspec == NULL)
break;
f = imsg->data;
output->flowspec(f);
break;
case IMSG_CTL_SHOW_FIB_TABLES:
if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(*kt))
errx(1, "wrong imsg len");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bgpctl.h,v 1.20 2023/03/28 12:07:09 claudio Exp $ */
/* $OpenBSD: bgpctl.h,v 1.21 2023/04/20 14:01:50 claudio Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@ -24,6 +24,7 @@ struct output {
void (*timer)(struct ctl_timer *);
void (*fib)(struct kroute_full *);
void (*fib_table)(struct ktable *);
void (*flowspec)(struct flowspec *);
void (*nexthop)(struct ctl_show_nexthop *);
void (*interface)(struct ctl_show_interface *);
void (*attr)(u_char *, size_t, int, int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: output.c,v 1.38 2023/03/28 12:07:09 claudio Exp $ */
/* $OpenBSD: output.c,v 1.39 2023/04/20 14:01:50 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@ -85,6 +85,8 @@ show_head(struct parse_result *res)
printf("%-5s %-4s %-32s %-32s\n", "flags", "prio",
"destination", "gateway");
break;
case FLOWSPEC_SHOW:
printf("flags: S = Static\n");
default:
break;
}
@ -492,6 +494,108 @@ show_fib_table(struct ktable *kt)
kt->fib_sync != kt->fib_conf ? "*" : "");
}
static void
print_flowspec_list(struct flowspec *f, int type, int is_v6)
{
const uint8_t *comp;
const char *fmt;
int complen, off = 0;
if (flowspec_get_component(f->data, f->len, type, is_v6,
&comp, &complen) != 1)
return;
printf("%s ", flowspec_fmt_label(type));
fmt = flowspec_fmt_num_op(comp, complen, &off);
if (off == -1) {
printf("%s ", fmt);
} else {
printf("{ %s ", fmt);
do {
fmt = flowspec_fmt_num_op(comp, complen, &off);
printf("%s ", fmt);
} while (off != -1);
printf("} ");
}
}
static void
print_flowspec_flags(struct flowspec *f, int type, int is_v6)
{
const uint8_t *comp;
const char *fmt, *flags;
int complen, off = 0;
if (flowspec_get_component(f->data, f->len, type, is_v6,
&comp, &complen) != 1)
return;
printf("%s ", flowspec_fmt_label(type));
switch (type) {
case FLOWSPEC_TYPE_TCP_FLAGS:
flags = FLOWSPEC_TCP_FLAG_STRING;
break;
case FLOWSPEC_TYPE_FRAG:
if (!is_v6)
flags = FLOWSPEC_FRAG_STRING4;
else
flags = FLOWSPEC_FRAG_STRING6;
break;
}
fmt = flowspec_fmt_bin_op(comp, complen, &off, flags);
if (off == -1) {
printf("%s ", fmt);
} else {
printf("{ %s ", fmt);
do {
fmt = flowspec_fmt_bin_op(comp, complen, &off, flags);
printf("%s ", fmt);
} while (off != -1);
printf("} ");
}
}
static void
print_flowspec_addr(struct flowspec *f, int type, int is_v6)
{
struct bgpd_addr addr;
uint8_t plen;
flowspec_get_addr(f->data, f->len, type, is_v6, &addr, &plen, NULL);
if (plen == 0)
printf("%s any ", flowspec_fmt_label(type));
else
printf("%s %s/%u ", flowspec_fmt_label(type),
log_addr(&addr), plen);
}
static void
show_flowspec(struct flowspec *f)
{
int is_v6 = (f->aid == AID_FLOWSPECv6);
printf("%-5s ", fmt_fib_flags(f->flags));
print_flowspec_list(f, FLOWSPEC_TYPE_PROTO, is_v6);
print_flowspec_addr(f, FLOWSPEC_TYPE_SOURCE, is_v6);
print_flowspec_list(f, FLOWSPEC_TYPE_SRC_PORT, is_v6);
print_flowspec_addr(f, FLOWSPEC_TYPE_DEST, is_v6);
print_flowspec_list(f, FLOWSPEC_TYPE_DST_PORT, is_v6);
print_flowspec_list(f, FLOWSPEC_TYPE_DSCP, is_v6);
print_flowspec_list(f, FLOWSPEC_TYPE_PKT_LEN, is_v6);
print_flowspec_flags(f, FLOWSPEC_TYPE_TCP_FLAGS, is_v6);
print_flowspec_flags(f, FLOWSPEC_TYPE_FRAG, is_v6);
/* TODO: fixup the code handling to be like in the parser */
print_flowspec_list(f, FLOWSPEC_TYPE_ICMP_TYPE, is_v6);
print_flowspec_list(f, FLOWSPEC_TYPE_ICMP_CODE, is_v6);
printf("\n");
}
static void
show_nexthop(struct ctl_show_nexthop *nh)
{
@ -1117,6 +1221,7 @@ const struct output show_output = {
.timer = show_timer,
.fib = show_fib,
.fib_table = show_fib_table,
.flowspec = show_flowspec,
.nexthop = show_nexthop,
.interface = show_interface,
.communities = show_communities,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: parser.c,v 1.129 2023/04/17 13:48:31 claudio Exp $ */
/* $OpenBSD: parser.c,v 1.130 2023/04/20 14:01:50 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -96,6 +96,7 @@ static const struct token t_show_mrt_as[];
static const struct token t_show_prefix[];
static const struct token t_show_ip[];
static const struct token t_network[];
static const struct token t_flowspec[];
static const struct token t_bulk[];
static const struct token t_network_show[];
static const struct token t_prefix[];
@ -107,6 +108,7 @@ static const struct token t_communication[];
static const struct token t_main[] = {
{ KEYWORD, "fib", FIB, t_fib},
{ KEYWORD, "flowspec", NONE, t_flowspec},
{ KEYWORD, "log", NONE, t_log},
{ KEYWORD, "neighbor", NEIGHBOR, t_neighbor},
{ KEYWORD, "network", NONE, t_network},
@ -118,6 +120,7 @@ static const struct token t_main[] = {
static const struct token t_show[] = {
{ NOTOKEN, "", NONE, NULL},
{ KEYWORD, "fib", SHOW_FIB, t_show_fib},
{ KEYWORD, "flowspec", FLOWSPEC_SHOW, t_network_show},
{ KEYWORD, "interfaces", SHOW_INTERFACE, NULL},
{ KEYWORD, "ip", NONE, t_show_ip},
{ KEYWORD, "metrics", SHOW_METRICS, NULL},
@ -329,6 +332,12 @@ static const struct token t_network[] = {
{ ENDTOKEN, "", NONE, NULL}
};
static const struct token t_flowspec[] = {
{ KEYWORD, "flush", FLOWSPEC_FLUSH, NULL},
{ KEYWORD, "show", FLOWSPEC_SHOW, t_network_show},
{ ENDTOKEN, "", NONE, NULL}
};
static const struct token t_bulk[] = {
{ KEYWORD, "add", NETWORK_BULK_ADD, t_set},
{ KEYWORD, "delete", NETWORK_BULK_REMOVE, NULL},

View File

@ -1,4 +1,4 @@
/* $OpenBSD: parser.h,v 1.44 2022/10/17 16:51:36 claudio Exp $ */
/* $OpenBSD: parser.h,v 1.45 2023/04/20 14:01:50 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -56,7 +56,11 @@ enum actions {
NETWORK_SHOW,
NETWORK_MRT,
NETWORK_BULK_ADD,
NETWORK_BULK_REMOVE
NETWORK_BULK_REMOVE,
FLOWSPEC_ADD,
FLOWSPEC_REMOVE,
FLOWSPEC_FLUSH,
FLOWSPEC_SHOW,
};
struct parse_result {