-# $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
-/* $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>
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 */
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;
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");
-/* $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>
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);
-/* $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>
printf("%-5s %-4s %-32s %-32s\n", "flags", "prio",
"destination", "gateway");
break;
+ case FLOWSPEC_SHOW:
+ printf("flags: S = Static\n");
default:
break;
}
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)
{
.timer = show_timer,
.fib = show_fib,
.fib_table = show_fib_table,
+ .flowspec = show_flowspec,
.nexthop = show_nexthop,
.interface = show_interface,
.communities = show_communities,
-/* $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>
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[];
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},
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},
{ 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},
-/* $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>
NETWORK_SHOW,
NETWORK_MRT,
NETWORK_BULK_ADD,
- NETWORK_BULK_REMOVE
+ NETWORK_BULK_REMOVE,
+ FLOWSPEC_ADD,
+ FLOWSPEC_REMOVE,
+ FLOWSPEC_FLUSH,
+ FLOWSPEC_SHOW,
};
struct parse_result {