From ff2ca10cba9c5a3be690ec1a77a068e23395ef20 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Mon, 9 Dec 2019 04:23:01 +0100 Subject: Filter: Add support for src/dst accessors for Flowspec and SADR --- doc/bird.sgml | 8 +++++-- filter/config.Y | 5 +++-- filter/f-inst.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- filter/f-inst.h | 1 + filter/filter.c | 3 ++- lib/flowspec.c | 28 ++++++++++++++++++++++-- lib/flowspec.h | 3 +++ 7 files changed, 104 insertions(+), 12 deletions(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index aeea613f..2363fb52 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1295,7 +1295,9 @@ in the foot). prefix. The literals are written as , where the first part is the destination prefix and the second art is the source prefix. They support the same - operators as IP prefixes, but just for the destination part. + operators as IP prefixes, but just for the destination part. They also + support ). They support the same special @@ -1309,7 +1311,9 @@ in the foot). and src_prefix, net->src_pxlen); + const byte *part; + + switch(v1.val.net->type) { + case NET_FLOW4: + part = flow4_get_part(&net->flow4, FLOW_TYPE_SRC_PREFIX); + if (part) + net_fill_ip4(src, flow_read_ip4_part(part), flow_read_pxlen(part)); + else + net_fill_ip4(src, IP4_NONE, 0); + break; + + case NET_FLOW6: + part = flow6_get_part(&net->flow6, FLOW_TYPE_SRC_PREFIX); + if (part) + net_fill_ip6(src, flow_read_ip6_part(part), flow_read_pxlen(part)); + else + net_fill_ip6(src, IP6_NONE, 0); + break; + + case NET_IP6_SADR: + net_fill_ip6(src, net->ip6_sadr.src_prefix, net->ip6_sadr.src_pxlen); + break; + + default: + runtime( "Flow or SADR expected" ); + } RESULT(T_NET, net, src); } + INST(FI_NET_DST, 1, 1) { /* Get dst prefix */ + ARG(1, T_NET); + + net_addr_union *net = (void *) v1.val.net; + net_addr *dst = falloc(sizeof(net_addr_ip6)); + const byte *part; + + switch(v1.val.net->type) { + case NET_FLOW4: + part = flow4_get_part(&net->flow4, FLOW_TYPE_DST_PREFIX); + if (part) + net_fill_ip4(dst, flow_read_ip4_part(part), flow_read_pxlen(part)); + else + net_fill_ip4(dst, IP4_NONE, 0); + break; + + case NET_FLOW6: + part = flow6_get_part(&net->flow6, FLOW_TYPE_DST_PREFIX); + if (part) + net_fill_ip6(dst, flow_read_ip6_part(part), flow_read_pxlen(part)); + else + net_fill_ip6(dst, IP6_NONE, 0); + break; + + case NET_IP6_SADR: + net_fill_ip6(dst, net->ip6_sadr.dst_prefix, net->ip6_sadr.dst_pxlen); + break; + + default: + runtime( "Flow or SADR expected" ); + } + + RESULT(T_NET, net, dst); + } + INST(FI_ROA_MAXLEN, 1, 1) { /* Get ROA max prefix length */ ARG(1, T_NET); if (!net_is_roa(v1.val.net)) diff --git a/filter/f-inst.h b/filter/f-inst.h index 8be8443b..bfa163fc 100644 --- a/filter/f-inst.h +++ b/filter/f-inst.h @@ -17,6 +17,7 @@ #include "conf/conf.h" #include "filter/filter.h" #include "filter/data.h" +#include "lib/flowspec.h" /* Flags for instructions */ enum f_instruction_flags { diff --git a/filter/filter.c b/filter/filter.c index ad9588b2..e505d570 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -32,8 +32,9 @@ #include "lib/socket.h" #include "lib/string.h" #include "lib/unaligned.h" -#include "lib/net.h" #include "lib/ip.h" +#include "lib/net.h" +#include "lib/flowspec.h" #include "nest/route.h" #include "nest/protocol.h" #include "nest/iface.h" diff --git a/lib/flowspec.c b/lib/flowspec.c index e9290b88..ef19aa96 100644 --- a/lib/flowspec.c +++ b/lib/flowspec.c @@ -243,12 +243,37 @@ flow6_next_part(const byte *pos, const byte *end) return flow_next_part(pos, end, 1); } +static const byte * +flow_get_part(const byte *data, uint dlen, uint type, int ipv6) +{ + const byte *part; + + for (part = flow_first_part(data); + part && (part[0] <= type); + part = flow_next_part(part, data+dlen, ipv6)) + if (part[0] == type) + return part; + + return NULL; +} + +const byte * +flow4_get_part(const net_addr_flow4 *f, uint type) +{ + return flow_get_part(f->data, f->length - sizeof(net_addr_flow4), type, 0); +} + +const byte * +flow6_get_part(const net_addr_flow6 *f, uint type) +{ + return flow_get_part(f->data, f->length - sizeof(net_addr_flow6), type, 1); +} + /* * Flowspec accessors */ - static inline ip4_addr flow_read_ip4(const byte *px, uint pxlen) { @@ -282,7 +307,6 @@ flow_read_ip6_part(const byte *part) } - /* * Flowspec validation */ diff --git a/lib/flowspec.h b/lib/flowspec.h index d486cda0..9bafc52e 100644 --- a/lib/flowspec.h +++ b/lib/flowspec.h @@ -83,6 +83,8 @@ const byte *flow4_first_part(const net_addr_flow4 *f); const byte *flow6_first_part(const net_addr_flow6 *f); const byte *flow4_next_part(const byte *pos, const byte *end); const byte *flow6_next_part(const byte *pos, const byte *end); +const byte *flow4_get_part(const net_addr_flow4 *f, uint type); +const byte *flow6_get_part(const net_addr_flow6 *f, uint type); /* @@ -91,6 +93,7 @@ const byte *flow6_next_part(const byte *pos, const byte *end); ip4_addr flow_read_ip4_part(const byte *part); ip6_addr flow_read_ip6_part(const byte *part); +static inline int flow_read_pxlen(const byte *part) { return part[1]; } /* -- cgit v1.2.3