On Thu, Apr 20, 2023 at 06:23:45PM +0200, Claudio Jeker wrote:
> This currently only supports prefixes and numeric options.
> It does not handle TCP and fragment flags right now.
> Appart from that lists of options work.
ok, some small suggestions inline. Do it the way you like it better.
>
> --
> :wq Claudio
>
> Index: bgpctl.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
> retrieving revision 1.291
> diff -u -p -r1.291 bgpctl.c
> --- bgpctl.c 20 Apr 2023 14:01:50 -0000 1.291
> +++ bgpctl.c 20 Apr 2023 14:09:27 -0000
> @@ -57,6 +57,7 @@ void show_mrt_msg(struct mrt_bgp_msg *
> const char *msg_type(uint8_t);
> void network_bulk(struct parse_result *);
> int match_aspath(void *, uint16_t, struct filter_as *);
> +struct flowspec *res_to_flowspec(struct parse_result *);
>
> struct imsgbuf *ibuf;
> struct mrt_parser show_mrt = { show_mrt_dump, show_mrt_state, show_mrt_msg };
> @@ -85,6 +86,7 @@ main(int argc, char *argv[])
> struct parse_result *res;
> struct ctl_neighbor neighbor;
> struct ctl_show_rib_request ribreq;
> + struct flowspec *f;
> char *sockname;
> enum imsg_type type;
>
> @@ -363,6 +365,18 @@ main(int argc, char *argv[])
> break;
> case FLOWSPEC_ADD:
> case FLOWSPEC_REMOVE:
> + f = res_to_flowspec(res);
> + /* attribute sets are not supported */
> + if (res->action == FLOWSPEC_ADD) {
> + imsg_compose(ibuf, IMSG_FLOWSPEC_ADD, 0, 0, -1,
> + f, FLOWSPEC_SIZE + f->len);
> + send_filterset(ibuf, &res->set);
> + imsg_compose(ibuf, IMSG_FLOWSPEC_DONE, 0, 0, -1,
> + NULL, 0);
> + } else
> + imsg_compose(ibuf, IMSG_FLOWSPEC_REMOVE, 0, 0, -1,
> + f, FLOWSPEC_SIZE + f->len);
> + printf("request sent.\n");
> done = 1;
> break;
> case FLOWSPEC_FLUSH:
> @@ -1953,4 +1967,112 @@ match_aspath(void *data, uint16_t len, s
> }
> }
> return (0);
> +}
> +
> +static void
> +component_finish(int type, uint8_t *data, int len)
> +{
> + uint8_t *last;
> + int i = 0;
> +
> + switch (type) {
> + case FLOWSPEC_TYPE_DEST:
> + case FLOWSPEC_TYPE_SOURCE:
> + /* nothing todo */
> + return;
> + default:
> + break;
> + }
> +
I'd prefer initializing i = 0 here.
> + do {
> + last = data + i;
> + i += FLOWSPEC_OP_LEN(*last) + 1;
> + } while (i < len);
> + *last |= FLOWSPEC_OP_EOL;
> +}
> +
> +static void
> +push_prefix(struct parse_result *r, int type, struct bgpd_addr *addr,
> + uint8_t len)
> +{
> + void *data;
> + uint8_t *comp;
> + int complen, l = 0;
> +
> + switch (addr->aid) {
> + case AID_UNSPEC:
> + return;
> + case AID_INET:
> + complen = PREFIX_SIZE(len);
> + data = &addr->v4;
> + break;
> + case AID_INET6:
> + /* IPv6 includes an offset byte */
> + complen = PREFIX_SIZE(len) + 1;
> + data = &addr->v6;
> + break;
> + }
> + comp = malloc(complen);
> + if (comp == NULL)
> + err(1, NULL);
> +
Same here: I'd probably initialize l = 0 here
> + comp[l++] = len;
> + if (addr->aid == AID_INET6)
> + comp[l++] = 0;
> + memcpy(comp + l, data, PREFIX_SIZE(len) - 1);
and then do
> + memcpy(comp + l, data, complen - l);
> +
> + r->flow.complen[type] = complen;
> + r->flow.components[type] = comp;
> +}