summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_flowspec_util.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2019-10-16 08:42:30 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2020-08-21 13:37:08 +0200
commit9cec4121623c18eb5d826420e2078e2a78242362 (patch)
tree345c4ced2b1c8a527dc8dd11e7a2b2e0c2c71599 /bgpd/bgp_flowspec_util.c
parentbgpd: flowspec code support for ipv6 (diff)
downloadfrr-9cec4121623c18eb5d826420e2078e2a78242362.tar.xz
frr-9cec4121623c18eb5d826420e2078e2a78242362.zip
bgpd: ipv6 flowspec address decoding and validation
as per [0], ipv6 adress format introduces an ipv6 offset that needs to be extracted too. The change include the validation, decoding for further usage with policy-routing and decoding for dumping. [0] https://tools.ietf.org/html/draft-ietf-idr-flow-spec-v6-09 Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd/bgp_flowspec_util.c')
-rw-r--r--bgpd/bgp_flowspec_util.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c
index 0e879e816..2dd35696d 100644
--- a/bgpd/bgp_flowspec_util.c
+++ b/bgpd/bgp_flowspec_util.c
@@ -101,7 +101,7 @@ bool bgp_flowspec_contains_prefix(const struct prefix *pfs,
nlri_content+offset,
len - offset,
&compare, &error,
- afi);
+ afi, NULL);
if (ret <= 0)
break;
if (prefix_check &&
@@ -162,13 +162,15 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
uint8_t *nlri_ptr,
uint32_t max_len,
void *result, int *error,
- afi_t afi)
+ afi_t afi,
+ uint8_t *ipv6_offset)
{
char *display = (char *)result; /* for return_string */
struct prefix *prefix = (struct prefix *)result;
uint32_t offset = 0;
struct prefix prefix_local;
int psize;
+ uint8_t prefix_offset = 0;
*error = 0;
memset(&prefix_local, 0, sizeof(struct prefix));
@@ -176,8 +178,13 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
prefix_local.prefixlen = nlri_ptr[offset];
psize = PSIZE(prefix_local.prefixlen);
offset++;
- /* TODO Flowspec IPv6 Support */
- prefix_local.family = AF_INET;
+ prefix_local.family = afi2family(afi);
+ if (prefix_local.family == AF_INET6) {
+ prefix_offset = nlri_ptr[offset];
+ if (ipv6_offset)
+ *ipv6_offset = prefix_offset;
+ offset++;
+ }
/* Prefix length check. */
if (prefix_local.prefixlen > prefix_blen(&prefix_local) * 8)
*error = -1;
@@ -193,11 +200,28 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
offset += psize;
switch (type) {
case BGP_FLOWSPEC_RETURN_STRING:
- prefix2str(&prefix_local, display,
- BGP_FLOWSPEC_STRING_DISPLAY_MAX);
+ if (prefix_local.family == AF_INET6) {
+ char str[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
+ int ret;
+
+ prefix2str(&prefix_local, str,
+ BGP_FLOWSPEC_STRING_DISPLAY_MAX);
+ ret = snprintf(display, BGP_FLOWSPEC_STRING_DISPLAY_MAX,
+ "%s/off %u",
+ str, prefix_offset);
+ if (ret < 0) {
+ *error = -1;
+ break;
+ }
+ } else
+ prefix2str(&prefix_local, display,
+ BGP_FLOWSPEC_STRING_DISPLAY_MAX);
break;
case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
- PREFIX_COPY_IPV4(prefix, &prefix_local)
+ if (prefix_local.family == AF_INET)
+ PREFIX_COPY_IPV4(prefix, &prefix_local)
+ else
+ PREFIX_COPY_IPV6(prefix, &prefix_local)
break;
case BGP_FLOWSPEC_VALIDATE_ONLY:
default:
@@ -430,6 +454,7 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
uint8_t *match_num;
uint8_t bitmask = 0;
int ret = 0, type;
+ uint8_t *prefix_offset;
while (offset < len - 1 && error >= 0) {
type = nlri_content[offset];
@@ -441,16 +466,18 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
if (type == FLOWSPEC_DEST_PREFIX) {
bitmask |= PREFIX_DST_PRESENT;
prefix = &bpem->dst_prefix;
+ prefix_offset = &bpem->dst_prefix_offset;
} else {
bitmask |= PREFIX_SRC_PRESENT;
prefix = &bpem->src_prefix;
+ prefix_offset = &bpem->src_prefix_offset;
}
ret = bgp_flowspec_ip_address(
BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
nlri_content + offset,
len - offset,
prefix, &error,
- afi);
+ afi, prefix_offset);
if (error < 0)
flog_err(EC_BGP_FLOWSPEC_PACKET,
"%s: flowspec_ip_address error %d",
@@ -462,6 +489,11 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
if (prefix->family == AF_INET
&& prefix->u.prefix4.s_addr == INADDR_ANY)
bpem->match_bitmask_iprule |= bitmask;
+ else if (prefix->family == AF_INET6
+ && !memcmp(&prefix->u.prefix6,
+ &in6addr_any,
+ sizeof(struct in6_addr)))
+ bpem->match_bitmask_iprule |= bitmask;
else
bpem->match_bitmask |= bitmask;
}