summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_flowspec_util.c25
-rw-r--r--bgpd/bgp_flowspec_util.h4
-rw-r--r--bgpd/bgp_nht.c11
-rw-r--r--bgpd/bgp_pbr.c2
-rw-r--r--bgpd/bgp_pbr.h3
5 files changed, 43 insertions, 2 deletions
diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c
index c6386dcdb5..cd5bec6267 100644
--- a/bgpd/bgp_flowspec_util.c
+++ b/bgpd/bgp_flowspec_util.c
@@ -23,6 +23,7 @@
#include "prefix.h"
#include "lib_errors.h"
+#include "bgp_route.h"
#include "bgp_table.h"
#include "bgp_flowspec_util.h"
#include "bgp_flowspec_private.h"
@@ -581,3 +582,27 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
}
return error;
}
+
+/* return 1 if FS entry invalid or no NH IP */
+int bgp_flowspec_get_first_nh(struct bgp *bgp, struct bgp_path_info *pi,
+ struct prefix *p)
+{
+ struct bgp_pbr_entry_main api;
+ int i;
+ struct bgp_node *rn = pi->net;
+ struct bgp_pbr_entry_action *api_action;
+
+ memset(&api, 0, sizeof(struct bgp_pbr_entry_main));
+ if (bgp_pbr_build_and_validate_entry(&rn->p, pi, &api) < 0)
+ return 1;
+ for (i = 0; i < api.action_num; i++) {
+ 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;
+ return 0;
+ }
+ return 1;
+}
diff --git a/bgpd/bgp_flowspec_util.h b/bgpd/bgp_flowspec_util.h
index 9bf05847d3..2ce911da4e 100644
--- a/bgpd/bgp_flowspec_util.h
+++ b/bgpd/bgp_flowspec_util.h
@@ -54,4 +54,8 @@ extern bool bgp_flowspec_contains_prefix(struct prefix *pfs,
struct prefix *input,
int prefix_check);
+extern int bgp_flowspec_get_first_nh(struct bgp *bgp,
+ struct bgp_path_info *pi,
+ struct prefix *nh);
+
#endif /* _FRR_BGP_FLOWSPEC_UTIL_H */
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index c5d12a5706..e982e1db6a 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -42,6 +42,7 @@
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_zebra.h"
+#include "bgpd/bgp_flowspec_util.h"
extern struct zclient *zclient;
@@ -533,7 +534,15 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
&& (pi->sub_type == BGP_ROUTE_STATIC))
? 1
: 0;
-
+ struct bgp_node *net = pi->net;
+ struct prefix *p_orig = &net->p;
+
+ if (p_orig->family == AF_FLOWSPEC) {
+ if (!pi->peer)
+ return -1;
+ return bgp_flowspec_get_first_nh(pi->peer->bgp,
+ pi, p);
+ }
memset(p, 0, sizeof(struct prefix));
switch (afi) {
case AFI_IP:
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index f0a0e615e6..f002154701 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -626,7 +626,7 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api)
}
/* return -1 if build or validation failed */
-static int bgp_pbr_build_and_validate_entry(struct prefix *p,
+int bgp_pbr_build_and_validate_entry(struct prefix *p,
struct bgp_path_info *path,
struct bgp_pbr_entry_main *api)
{
diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h
index 84095f9ab9..45c3c9ea13 100644
--- a/bgpd/bgp_pbr.h
+++ b/bgpd/bgp_pbr.h
@@ -290,4 +290,7 @@ extern void bgp_pbr_reset(struct bgp *bgp, afi_t afi);
extern struct bgp_pbr_interface *bgp_pbr_interface_lookup(const char *name,
struct bgp_pbr_interface_head *head);
+extern int bgp_pbr_build_and_validate_entry(struct prefix *p,
+ struct bgp_path_info *path,
+ struct bgp_pbr_entry_main *api);
#endif /* __BGP_PBR_H__ */