summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_debug.c3
-rw-r--r--bgpd/bgp_flowspec.c17
-rw-r--r--bgpd/bgp_flowspec.h3
-rw-r--r--bgpd/bgp_flowspec_util.c28
-rw-r--r--bgpd/bgp_flowspec_util.h8
-rw-r--r--bgpd/bgp_flowspec_vty.c15
-rw-r--r--bgpd/bgp_nht.c2
-rw-r--r--bgpd/bgp_pbr.c7
-rw-r--r--bgpd/bgp_pbr.h1
-rw-r--r--bgpd/bgp_route.c4
-rw-r--r--bgpd/bgp_routemap.c6
11 files changed, 62 insertions, 32 deletions
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 255a7f238b..e9d7c9e8aa 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -2692,7 +2692,8 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
bgp_fs_nlri_get_string((unsigned char *)fs->prefix.ptr,
fs->prefix.prefixlen,
return_string,
- NLRI_STRING_FORMAT_DEBUG, NULL);
+ NLRI_STRING_FORMAT_DEBUG, NULL,
+ family2afi(fs->prefix.family));
snprintf(str, size, "FS %s Match{%s}", afi2str(afi),
return_string);
} else
diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c
index 17c41636de..03fc1f52c3 100644
--- a/bgpd/bgp_flowspec.c
+++ b/bgpd/bgp_flowspec.c
@@ -33,7 +33,8 @@
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_errors.h"
-static int bgp_fs_nlri_validate(uint8_t *nlri_content, uint32_t len)
+static int bgp_fs_nlri_validate(uint8_t *nlri_content, uint32_t len,
+ afi_t afi)
{
uint32_t offset = 0;
int type;
@@ -48,7 +49,8 @@ static int bgp_fs_nlri_validate(uint8_t *nlri_content, uint32_t len)
ret = bgp_flowspec_ip_address(
BGP_FLOWSPEC_VALIDATE_ONLY,
nlri_content + offset,
- len - offset, NULL, &error);
+ len - offset, NULL, &error,
+ afi);
break;
case FLOWSPEC_IP_PROTOCOL:
case FLOWSPEC_PORT:
@@ -103,11 +105,6 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
afi = packet->afi;
safi = packet->safi;
- if (afi == AFI_IP6) {
- flog_err(EC_LIB_DEVELOPMENT, "BGP flowspec IPv6 not supported");
- return BGP_NLRI_PARSE_ERROR_FLOWSPEC_IPV6_NOT_SUPPORTED;
- }
-
if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT_EXTENDED) {
flog_err(EC_BGP_FLOWSPEC_PACKET,
"BGP flowspec nlri length maximum reached (%u)",
@@ -137,7 +134,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
psize);
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
}
- if (bgp_fs_nlri_validate(pnt, psize) < 0) {
+ if (bgp_fs_nlri_validate(pnt, psize, afi) < 0) {
flog_err(
EC_BGP_FLOWSPEC_PACKET,
"Bad flowspec format or NLRI options not supported");
@@ -147,6 +144,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
p.prefixlen = 0;
/* Flowspec encoding is in bytes */
p.u.prefix_flowspec.prefixlen = psize;
+ p.u.prefix_flowspec.family = afi2family(afi);
temp = XCALLOC(MTYPE_TMP, psize);
memcpy(temp, pnt, psize);
p.u.prefix_flowspec.ptr = (uintptr_t) temp;
@@ -161,7 +159,8 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
p.u.prefix_flowspec.ptr,
p.u.prefix_flowspec.prefixlen,
return_string,
- NLRI_STRING_FORMAT_MIN, NULL);
+ NLRI_STRING_FORMAT_MIN, NULL,
+ afi);
snprintf(ec_string, sizeof(ec_string),
"EC{none}");
if (attr && attr->ecommunity) {
diff --git a/bgpd/bgp_flowspec.h b/bgpd/bgp_flowspec.h
index 94c571f2fc..d1a59a672d 100644
--- a/bgpd/bgp_flowspec.h
+++ b/bgpd/bgp_flowspec.h
@@ -41,7 +41,8 @@ extern int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
extern void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
char *return_string, int format,
- json_object *json_path);
+ json_object *json_path,
+ afi_t afi);
extern void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,
struct bgp_path_info *path, int display,
diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c
index 764d2f87ae..0e879e8168 100644
--- a/bgpd/bgp_flowspec_util.c
+++ b/bgpd/bgp_flowspec_util.c
@@ -76,6 +76,7 @@ static int bgp_flowspec_call_non_opaque_decode(uint8_t *nlri_content, int len,
return ret;
}
+
bool bgp_flowspec_contains_prefix(const struct prefix *pfs,
struct prefix *input, int prefix_check)
{
@@ -84,6 +85,7 @@ bool bgp_flowspec_contains_prefix(const struct prefix *pfs,
int ret = 0, error = 0;
uint8_t *nlri_content = (uint8_t *)pfs->u.prefix_flowspec.ptr;
size_t len = pfs->u.prefix_flowspec.prefixlen;
+ afi_t afi = family2afi(pfs->u.prefix_flowspec.family);
struct prefix compare;
error = 0;
@@ -98,7 +100,8 @@ bool bgp_flowspec_contains_prefix(const struct prefix *pfs,
BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
nlri_content+offset,
len - offset,
- &compare, &error);
+ &compare, &error,
+ afi);
if (ret <= 0)
break;
if (prefix_check &&
@@ -158,7 +161,8 @@ bool bgp_flowspec_contains_prefix(const struct prefix *pfs,
int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
uint8_t *nlri_ptr,
uint32_t max_len,
- void *result, int *error)
+ void *result, int *error,
+ afi_t afi)
{
char *display = (char *)result; /* for return_string */
struct prefix *prefix = (struct prefix *)result;
@@ -417,7 +421,8 @@ int bgp_flowspec_bitmask_decode(enum bgp_flowspec_util_nlri_t type,
}
int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
- struct bgp_pbr_entry_main *bpem)
+ struct bgp_pbr_entry_main *bpem,
+ afi_t afi)
{
int offset = 0, error = 0;
struct prefix *prefix;
@@ -444,7 +449,8 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
nlri_content + offset,
len - offset,
- prefix, &error);
+ prefix, &error,
+ afi);
if (error < 0)
flog_err(EC_BGP_FLOWSPEC_PACKET,
"%s: flowspec_ip_address error %d",
@@ -599,7 +605,7 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
/* return 1 if FS entry invalid or no NH IP */
bool bgp_flowspec_get_first_nh(struct bgp *bgp, struct bgp_path_info *pi,
- struct prefix *p)
+ struct prefix *p, afi_t afi)
{
struct bgp_pbr_entry_main api;
int i;
@@ -615,9 +621,15 @@ bool bgp_flowspec_get_first_nh(struct bgp *bgp, struct bgp_path_info *pi,
api_action = &api.actions[i];
if (api_action->action != ACTION_REDIRECT_IP)
continue;
- p->family = AF_INET;
- p->prefixlen = IPV4_MAX_BITLEN;
- p->u.prefix4 = api_action->u.zr.redirect_ip_v4;
+ p->family = afi2family(afi);
+ if (afi == AFI_IP) {
+ p->prefixlen = IPV4_MAX_BITLEN;
+ p->u.prefix4 = api_action->u.zr.redirect_ip_v4;
+ } else {
+ p->prefixlen = IPV6_MAX_BITLEN;
+ memcpy(&p->u.prefix6, &api_action->u.zr.redirect_ip_v6,
+ sizeof(struct in6_addr));
+ }
return false;
}
return true;
diff --git a/bgpd/bgp_flowspec_util.h b/bgpd/bgp_flowspec_util.h
index 0e78c7a53c..26d919d7d2 100644
--- a/bgpd/bgp_flowspec_util.h
+++ b/bgpd/bgp_flowspec_util.h
@@ -39,7 +39,8 @@ extern int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
extern int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
uint8_t *nlri_ptr,
uint32_t max_len,
- void *result, int *error);
+ void *result, int *error,
+ afi_t afi);
extern int bgp_flowspec_bitmask_decode(enum bgp_flowspec_util_nlri_t type,
uint8_t *nlri_ptr,
@@ -48,13 +49,14 @@ extern int bgp_flowspec_bitmask_decode(enum bgp_flowspec_util_nlri_t type,
struct bgp_pbr_entry_main;
extern int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
- struct bgp_pbr_entry_main *bpem);
+ struct bgp_pbr_entry_main *bpem,
+ afi_t afi);
extern bool bgp_flowspec_contains_prefix(const struct prefix *pfs,
struct prefix *input,
int prefix_check);
extern bool bgp_flowspec_get_first_nh(struct bgp *bgp, struct bgp_path_info *pi,
- struct prefix *nh);
+ struct prefix *nh, afi_t afi);
#endif /* _FRR_BGP_FLOWSPEC_UTIL_H */
diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c
index e309fa948e..5703d86be3 100644
--- a/bgpd/bgp_flowspec_vty.c
+++ b/bgpd/bgp_flowspec_vty.c
@@ -93,7 +93,8 @@ static const struct message bgp_flowspec_display_min[] = {
*/
void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
char *return_string, int format,
- json_object *json_path)
+ json_object *json_path,
+ afi_t afi)
{
uint32_t offset = 0;
int type;
@@ -127,7 +128,8 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
type_util,
nlri_content+offset,
len - offset,
- local_string, &error);
+ local_string, &error,
+ afi);
if (ret <= 0)
break;
if (json_path) {
@@ -263,7 +265,12 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,
json_object *json_ecom_path = NULL;
json_object *json_time_path = NULL;
char timebuf[BGP_UPTIME_LEN];
+ struct bgp_dest *dest = NULL;
+ if (path)
+ dest = path->net;
+ if (dest)
+ bgp_dest_get_bgp_table_info(dest);
/* Print prefix */
if (p != NULL) {
if (p->family != AF_FLOWSPEC)
@@ -282,7 +289,9 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,
p->u.prefix_flowspec.prefixlen,
return_string,
display,
- json_nlri_path);
+ json_nlri_path,
+ family2afi(p->u.prefix_flowspec
+ .family));
if (display == NLRI_STRING_FORMAT_LARGE)
vty_out(vty, "%s", return_string);
else if (display == NLRI_STRING_FORMAT_DEBUG)
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index a74b5f91ac..a780fb7347 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -544,7 +544,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
if (!pi->peer)
return -1;
return bgp_flowspec_get_first_nh(pi->peer->bgp,
- pi, p);
+ pi, p, afi);
}
memset(p, 0, sizeof(struct prefix));
switch (afi) {
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 7c3e8cd70e..38b1ae4da9 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -668,6 +668,7 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api)
}
/* return -1 if build or validation failed */
+
int bgp_pbr_build_and_validate_entry(const struct prefix *p,
struct bgp_path_info *path,
struct bgp_pbr_entry_main *api)
@@ -679,13 +680,13 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p,
struct bgp_pbr_entry_action *api_action;
struct prefix *src = NULL, *dst = NULL;
int valid_prefix = 0;
- afi_t afi = AFI_IP;
struct bgp_pbr_entry_action *api_action_redirect_ip = NULL;
bool discard_action_found = false;
+ afi_t afi = family2afi(p->u.prefix_flowspec.family);
/* extract match from flowspec entries */
ret = bgp_flowspec_match_rules_fill((uint8_t *)p->u.prefix_flowspec.ptr,
- p->u.prefix_flowspec.prefixlen, api);
+ p->u.prefix_flowspec.prefixlen, api, afi);
if (ret < 0)
return -1;
/* extract actiosn from flowspec ecom list */
@@ -2598,8 +2599,6 @@ void bgp_pbr_update_entry(struct bgp *bgp, const struct prefix *p,
{
struct bgp_pbr_entry_main api;
- if (afi == AFI_IP6)
- return; /* IPv6 not supported */
if (safi != SAFI_FLOWSPEC)
return; /* not supported */
/* Make Zebra API structure. */
diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h
index 043853a157..52bb3b5410 100644
--- a/bgpd/bgp_pbr.h
+++ b/bgpd/bgp_pbr.h
@@ -79,6 +79,7 @@ struct bgp_pbr_entry_action {
vrf_id_t redirect_vrf;
struct _pbr_redirect_ip {
struct in_addr redirect_ip_v4;
+ struct in6_addr redirect_ip_v6;
uint8_t duplicate;
} zr;
uint8_t marking_dscp;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 3a627b4486..eefff4bef8 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -10008,11 +10008,13 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
if (dest_p->family == AF_FLOWSPEC) {
char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
+
bgp_fs_nlri_get_string(
(unsigned char *)
dest_p->u.prefix_flowspec.ptr,
dest_p->u.prefix_flowspec.prefixlen,
- retstr, NLRI_STRING_FORMAT_MIN, NULL);
+ retstr, NLRI_STRING_FORMAT_MIN, NULL,
+ family2afi(dest_p->u.prefix_flowspec.family));
if (first)
vty_out(vty, "\"%s/%d\": ", retstr,
dest_p->u.prefix_flowspec
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 97153cfb72..5644daba62 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -594,10 +594,14 @@ route_match_prefix_list_flowspec(afi_t afi, struct prefix_list *plist,
memset(&api, 0, sizeof(api));
+ if (family2afi(p->u.prefix_flowspec.family) != afi)
+ return RMAP_NOMATCH;
+
/* extract match from flowspec entries */
ret = bgp_flowspec_match_rules_fill(
(uint8_t *)p->u.prefix_flowspec.ptr,
- p->u.prefix_flowspec.prefixlen, &api);
+ p->u.prefix_flowspec.prefixlen, &api,
+ afi);
if (ret < 0)
return RMAP_NOMATCH;
if (api.match_bitmask & PREFIX_DST_PRESENT ||