Filter: Add support for src/dst accessors for Flowspec and SADR
This commit is contained in:
parent
21d09632a5
commit
ff2ca10cba
7 changed files with 104 additions and 12 deletions
|
@ -1295,7 +1295,9 @@ in the foot).
|
|||
prefix. The literals are written as <cf><m/ipaddress//<m/pxlen/ from
|
||||
<m/ipaddress//<m/pxlen/</cf>, 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 <cf/.src/ and <cf/.dst/ operators to get respective parts of the
|
||||
address as separate <cf/NET_IP6/ values.
|
||||
|
||||
<cf/NET_VPN4/ and <cf/NET_VPN6/ prefixes hold an IP prefix with VPN
|
||||
Route Distinguisher (<rfc id="4364">). They support the same special
|
||||
|
@ -1309,7 +1311,9 @@ in the foot).
|
|||
and <cf/.asn/ which extracts the ASN.
|
||||
|
||||
<cf/NET_FLOW4/ and <cf/NET_FLOW6/ hold an IP prefix together with a
|
||||
flowspec rule. Filters currently don't support flowspec parsing.
|
||||
flowspec rule. Filters currently do not support much flowspec parsing,
|
||||
only <cf/.src/ and <cf/.dst/ operators to get source and destination
|
||||
parts of the flowspec as separate <cf/NET_IP4/ / <cf/NET_IP6/ values.
|
||||
|
||||
<cf/NET_MPLS/ holds a single MPLS label and its handling is currently
|
||||
not implemented.
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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]; }
|
||||
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue