summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y5
-rw-r--r--filter/f-inst.c68
-rw-r--r--filter/f-inst.h1
-rw-r--r--filter/filter.c3
4 files changed, 69 insertions, 8 deletions
diff --git a/filter/config.Y b/filter/config.Y
index 340053ba..c8b868af 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -433,7 +433,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX,
PREFERENCE,
- ROA_CHECK, ASN, SRC,
+ ROA_CHECK, ASN, SRC, DST,
IS_V4, IS_V6,
LEN, MAXLEN,
DEFINED,
@@ -940,7 +940,8 @@ term:
| term '.' LEN { $$ = f_new_inst(FI_LENGTH, $1); }
| term '.' MAXLEN { $$ = f_new_inst(FI_ROA_MAXLEN, $1); }
| term '.' ASN { $$ = f_new_inst(FI_ROA_ASN, $1); }
- | term '.' SRC { $$ = f_new_inst(FI_SADR_SRC, $1); }
+ | term '.' SRC { $$ = f_new_inst(FI_NET_SRC, $1); }
+ | term '.' DST { $$ = f_new_inst(FI_NET_DST, $1); }
| term '.' MASK '(' term ')' { $$ = f_new_inst(FI_IP_MASK, $1, $5); }
| term '.' FIRST { $$ = f_new_inst(FI_AS_PATH_FIRST, $1); }
| term '.' LAST { $$ = f_new_inst(FI_AS_PATH_LAST, $1); }
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 3bd0249c..e3e0d76d 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -771,18 +771,76 @@
}
}
- INST(FI_SADR_SRC, 1, 1) { /* Get SADR src prefix */
+ INST(FI_NET_SRC, 1, 1) { /* Get src prefix */
ARG(1, T_NET);
- if (!net_is_sadr(v1.val.net))
- runtime( "SADR expected" );
- net_addr_ip6_sadr *net = (void *) v1.val.net;
+ net_addr_union *net = (void *) v1.val.net;
net_addr *src = falloc(sizeof(net_addr_ip6));
- net_fill_ip6(src, net->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"