mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 09:22:03 +00:00
zebra: vrf aware routmap is missing in Zebra #2802(Part 1 of 4)
Work to handle the route-maps, namely the header changes in zebra_vrf.h and the mapping of using that everywhere Signed-off-by: vishaldhingra vdhingra@vmware.com
This commit is contained in:
parent
b3c8d34291
commit
ac6eebce50
@ -886,6 +886,8 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
int family;
|
int family;
|
||||||
char buf[SRCDEST2STR_BUFFER];
|
char buf[SRCDEST2STR_BUFFER];
|
||||||
const struct prefix *p, *src_p;
|
const struct prefix *p, *src_p;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
srcdest_rnode_prefixes(rn, &p, &src_p);
|
srcdest_rnode_prefixes(rn, &p, &src_p);
|
||||||
|
|
||||||
if (rn->p.family == AF_INET)
|
if (rn->p.family == AF_INET)
|
||||||
@ -949,7 +951,8 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: What exactly do those checks do? Do we support
|
/* XXX: What exactly do those checks do? Do we support
|
||||||
* e.g. IPv4 routes with IPv6 nexthops or vice versa? */
|
* e.g. IPv4 routes with IPv6 nexthops or vice versa?
|
||||||
|
*/
|
||||||
if (RIB_SYSTEM_ROUTE(re) || (family == AFI_IP && p->family != AF_INET)
|
if (RIB_SYSTEM_ROUTE(re) || (family == AFI_IP && p->family != AF_INET)
|
||||||
|| (family == AFI_IP6 && p->family != AF_INET6))
|
|| (family == AFI_IP6 && p->family != AF_INET6))
|
||||||
return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
@ -969,9 +972,16 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
|
|
||||||
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
|
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
|
||||||
|
|
||||||
|
zvrf = zebra_vrf_lookup_by_id(nexthop->vrf_id);
|
||||||
|
if (!zvrf) {
|
||||||
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
|
zlog_debug("\t%s: zvrf is NULL", __PRETTY_FUNCTION__);
|
||||||
|
return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
/* It'll get set if required inside */
|
/* It'll get set if required inside */
|
||||||
ret = zebra_route_map_check(family, re->type, re->instance, p, nexthop,
|
ret = zebra_route_map_check(family, re->type, re->instance, p,
|
||||||
nexthop->vrf_id, re->tag);
|
nexthop, zvrf, re->tag);
|
||||||
if (ret == RMAP_DENYMATCH) {
|
if (ret == RMAP_DENYMATCH) {
|
||||||
if (IS_ZEBRA_DEBUG_RIB) {
|
if (IS_ZEBRA_DEBUG_RIB) {
|
||||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||||
@ -1002,6 +1012,7 @@ static int nexthop_active_update(struct route_node *rn, struct route_entry *re,
|
|||||||
union g_addr prev_src;
|
union g_addr prev_src;
|
||||||
unsigned int prev_active, new_active, old_num_nh;
|
unsigned int prev_active, new_active, old_num_nh;
|
||||||
ifindex_t prev_index;
|
ifindex_t prev_index;
|
||||||
|
|
||||||
old_num_nh = re->nexthop_active_num;
|
old_num_nh = re->nexthop_active_num;
|
||||||
|
|
||||||
re->nexthop_active_num = 0;
|
re->nexthop_active_num = 0;
|
||||||
|
@ -302,8 +302,10 @@ static int zebra_rnh_apply_nht_rmap(int family, struct route_node *prn,
|
|||||||
if (prn && re) {
|
if (prn && re) {
|
||||||
for (nexthop = re->ng.nexthop; nexthop;
|
for (nexthop = re->ng.nexthop; nexthop;
|
||||||
nexthop = nexthop->next) {
|
nexthop = nexthop->next) {
|
||||||
ret = zebra_nht_route_map_check(rmap_family, proto,
|
struct zebra_vrf *zvrf =
|
||||||
&prn->p, re, nexthop);
|
zebra_vrf_lookup_by_id(nexthop->vrf_id);
|
||||||
|
ret = zebra_nht_route_map_check(
|
||||||
|
rmap_family, proto, &prn->p, zvrf, re, nexthop);
|
||||||
if (ret != RMAP_DENYMATCH) {
|
if (ret != RMAP_DENYMATCH) {
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
at_least_one++; /* at least one valid NH */
|
at_least_one++; /* at least one valid NH */
|
||||||
|
@ -1309,42 +1309,63 @@ static void zebra_rib_table_rm_update(const char *rmap)
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
|
struct vrf *vrf = NULL;
|
||||||
|
struct zebra_vrf *zvrf = NULL;
|
||||||
char *rmap_name;
|
char *rmap_name;
|
||||||
char afi_ip = 0;
|
char afi_ip = 0;
|
||||||
char afi_ipv6 = 0;
|
char afi_ipv6 = 0;
|
||||||
|
|
||||||
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||||
/* Check for ip routemap table */
|
zvrf = vrf->info;
|
||||||
rmap_name = proto_rm[AFI_IP][i];
|
if (!zvrf)
|
||||||
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
continue;
|
||||||
if (IS_ZEBRA_DEBUG_EVENT)
|
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
|
||||||
zlog_debug("%s : AFI_IP rmap %s, route type %s",
|
rmap_name = PROTO_RM_NAME(zvrf, AFI_IP, i);
|
||||||
__func__, rmap, zebra_route_string(i));
|
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
||||||
/* There is single rib table for all protocols */
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
if (afi_ip == 0) {
|
zlog_debug(
|
||||||
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST,
|
"%s : AFI_IP rmap %s, route type %s",
|
||||||
VRF_DEFAULT);
|
__func__, rmap,
|
||||||
if (table) {
|
zebra_route_string(i));
|
||||||
afi_ip = 1;
|
|
||||||
rib_update_table(table,
|
PROTO_RM_MAP(zvrf, AFI_IP, i) =
|
||||||
RIB_UPDATE_RMAP_CHANGE);
|
route_map_lookup_by_name(rmap_name);
|
||||||
|
/* There is single rib table for all protocols
|
||||||
|
*/
|
||||||
|
if (afi_ip == 0) {
|
||||||
|
table = zvrf->table[AFI_IP]
|
||||||
|
[SAFI_UNICAST];
|
||||||
|
if (table) {
|
||||||
|
|
||||||
|
afi_ip = 1;
|
||||||
|
rib_update_table(
|
||||||
|
table,
|
||||||
|
RIB_UPDATE_RMAP_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
rmap_name = PROTO_RM_NAME(zvrf, AFI_IP6, i);
|
||||||
|
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
||||||
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
|
zlog_debug(
|
||||||
|
"%s : AFI_IP6 rmap %s, route type %s",
|
||||||
|
__func__, rmap,
|
||||||
|
zebra_route_string(i));
|
||||||
|
|
||||||
/* Check for ipv6 routemap table */
|
PROTO_RM_MAP(zvrf, AFI_IP6, i) =
|
||||||
rmap_name = proto_rm[AFI_IP6][i];
|
route_map_lookup_by_name(rmap_name);
|
||||||
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
/* There is single rib table for all protocols
|
||||||
if (IS_ZEBRA_DEBUG_EVENT)
|
*/
|
||||||
zlog_debug("%s : AFI_IP6 rmap %s,route type %s",
|
if (afi_ipv6 == 0) {
|
||||||
__func__, rmap, zebra_route_string(i));
|
table = zvrf->table[AFI_IP6]
|
||||||
if (afi_ipv6 == 0) {
|
[SAFI_UNICAST];
|
||||||
table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST,
|
if (table) {
|
||||||
VRF_DEFAULT);
|
|
||||||
if (table) {
|
afi_ipv6 = 1;
|
||||||
afi_ipv6 = 1;
|
rib_update_table(
|
||||||
rib_update_table(table,
|
table,
|
||||||
RIB_UPDATE_RMAP_CHANGE);
|
RIB_UPDATE_RMAP_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1358,31 +1379,70 @@ static void zebra_rib_table_rm_update(const char *rmap)
|
|||||||
static void zebra_nht_rm_update(const char *rmap)
|
static void zebra_nht_rm_update(const char *rmap)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
struct route_table *table;
|
||||||
|
struct vrf *vrf = NULL;
|
||||||
|
struct zebra_vrf *zvrf = NULL;
|
||||||
char *rmap_name;
|
char *rmap_name;
|
||||||
char afi_ip = 0;
|
char afi_ip = 0;
|
||||||
char afi_ipv6 = 0;
|
char afi_ipv6 = 0;
|
||||||
|
|
||||||
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||||
rmap_name = nht_rm[AFI_IP][i];
|
zvrf = vrf->info;
|
||||||
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
if (!zvrf)
|
||||||
if (IS_ZEBRA_DEBUG_EVENT)
|
continue;
|
||||||
zlog_debug("%s : AFI_IP rmap %s route type %s",
|
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
|
||||||
__func__, rmap, zebra_route_string(i));
|
rmap_name = NHT_RM_NAME(zvrf, AFI_IP, i);
|
||||||
if (afi_ip == 0) {
|
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
||||||
afi_ip = 1;
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
zebra_evaluate_rnh(0, AF_INET, 1,
|
zlog_debug(
|
||||||
RNH_NEXTHOP_TYPE, NULL);
|
"%s : AFI_IP rmap %s, route type %s",
|
||||||
|
__func__, rmap,
|
||||||
|
zebra_route_string(i));
|
||||||
|
|
||||||
|
NHT_RM_MAP(zvrf, AFI_IP, i) =
|
||||||
|
route_map_lookup_by_name(rmap_name);
|
||||||
|
/* There is single rib table for all protocols
|
||||||
|
*/
|
||||||
|
if (afi_ip == 0) {
|
||||||
|
table = zvrf->table[AFI_IP]
|
||||||
|
[SAFI_UNICAST];
|
||||||
|
if (table) {
|
||||||
|
|
||||||
|
afi_ip = 1;
|
||||||
|
|
||||||
|
zebra_evaluate_rnh(
|
||||||
|
zvrf->vrf->vrf_id,
|
||||||
|
AF_INET, 1,
|
||||||
|
RNH_NEXTHOP_TYPE, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
rmap_name = nht_rm[AFI_IP6][i];
|
rmap_name = NHT_RM_NAME(zvrf, AFI_IP6, i);
|
||||||
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
|
||||||
if (IS_ZEBRA_DEBUG_EVENT)
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
zlog_debug("%s : AFI_IP6 rmap %s route type %s",
|
zlog_debug(
|
||||||
__func__, rmap, zebra_route_string(i));
|
"%s : AFI_IP6 rmap %s, route type %s",
|
||||||
if (afi_ipv6 == 0) {
|
__func__, rmap,
|
||||||
afi_ipv6 = 1;
|
zebra_route_string(i));
|
||||||
zebra_evaluate_rnh(0, AF_INET6, 1,
|
|
||||||
RNH_NEXTHOP_TYPE, NULL);
|
NHT_RM_MAP(zvrf, AFI_IP6, i) =
|
||||||
|
route_map_lookup_by_name(rmap_name);
|
||||||
|
/* There is single rib table for all protocols
|
||||||
|
*/
|
||||||
|
if (afi_ipv6 == 0) {
|
||||||
|
table = zvrf->table[AFI_IP6]
|
||||||
|
[SAFI_UNICAST];
|
||||||
|
if (table) {
|
||||||
|
|
||||||
|
afi_ipv6 = 1;
|
||||||
|
|
||||||
|
zebra_evaluate_rnh(
|
||||||
|
zvrf->vrf->vrf_id,
|
||||||
|
AF_INET, 1,
|
||||||
|
RNH_NEXTHOP_TYPE, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1439,28 +1499,26 @@ void zebra_route_map_write_delay_timer(struct vty *vty)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
route_map_result_t zebra_route_map_check(int family, int rib_type,
|
route_map_result_t
|
||||||
uint8_t instance,
|
zebra_route_map_check(int family, int rib_type, uint8_t instance,
|
||||||
const struct prefix *p,
|
const struct prefix *p, struct nexthop *nexthop,
|
||||||
struct nexthop *nexthop,
|
struct zebra_vrf *zvrf, route_tag_t tag)
|
||||||
vrf_id_t vrf_id, route_tag_t tag)
|
|
||||||
{
|
{
|
||||||
struct route_map *rmap = NULL;
|
struct route_map *rmap = NULL;
|
||||||
route_map_result_t ret = RMAP_MATCH;
|
route_map_result_t ret = RMAP_MATCH;
|
||||||
struct nh_rmap_obj nh_obj;
|
struct nh_rmap_obj nh_obj;
|
||||||
|
|
||||||
nh_obj.nexthop = nexthop;
|
nh_obj.nexthop = nexthop;
|
||||||
nh_obj.vrf_id = vrf_id;
|
nh_obj.vrf_id = nexthop->vrf_id;
|
||||||
nh_obj.source_protocol = rib_type;
|
nh_obj.source_protocol = rib_type;
|
||||||
nh_obj.instance = instance;
|
nh_obj.instance = instance;
|
||||||
nh_obj.metric = 0;
|
nh_obj.metric = 0;
|
||||||
nh_obj.tag = tag;
|
nh_obj.tag = tag;
|
||||||
|
|
||||||
if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX)
|
if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX)
|
||||||
rmap = route_map_lookup_by_name(proto_rm[family][rib_type]);
|
rmap = PROTO_RM_MAP(zvrf, family, rib_type);
|
||||||
if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
|
if (!rmap && PROTO_RM_NAME(zvrf, family, ZEBRA_ROUTE_MAX))
|
||||||
rmap = route_map_lookup_by_name(
|
rmap = PROTO_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX);
|
||||||
proto_rm[family][ZEBRA_ROUTE_MAX]);
|
|
||||||
if (rmap) {
|
if (rmap) {
|
||||||
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
|
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
|
||||||
}
|
}
|
||||||
@ -1514,6 +1572,7 @@ zebra_import_table_route_map_check(int family, int re_type, uint8_t instance,
|
|||||||
|
|
||||||
route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
|
route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
|
||||||
const struct prefix *p,
|
const struct prefix *p,
|
||||||
|
struct zebra_vrf *zvrf,
|
||||||
struct route_entry *re,
|
struct route_entry *re,
|
||||||
struct nexthop *nexthop)
|
struct nexthop *nexthop)
|
||||||
{
|
{
|
||||||
@ -1529,10 +1588,9 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
|
|||||||
nh_obj.tag = re->tag;
|
nh_obj.tag = re->tag;
|
||||||
|
|
||||||
if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
|
if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
|
||||||
rmap = route_map_lookup_by_name(nht_rm[family][client_proto]);
|
rmap = NHT_RM_MAP(zvrf, family, client_proto);
|
||||||
if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX])
|
if (!rmap && NHT_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX))
|
||||||
rmap = route_map_lookup_by_name(
|
rmap = NHT_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX);
|
||||||
nht_rm[family][ZEBRA_ROUTE_MAX]);
|
|
||||||
if (rmap)
|
if (rmap)
|
||||||
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
|
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
|
||||||
|
|
||||||
|
@ -42,10 +42,10 @@ zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance,
|
|||||||
extern route_map_result_t
|
extern route_map_result_t
|
||||||
zebra_route_map_check(int family, int rib_type, uint8_t instance,
|
zebra_route_map_check(int family, int rib_type, uint8_t instance,
|
||||||
const struct prefix *p, struct nexthop *nexthop,
|
const struct prefix *p, struct nexthop *nexthop,
|
||||||
vrf_id_t vrf_id, route_tag_t tag);
|
struct zebra_vrf *zvrf, route_tag_t tag);
|
||||||
extern route_map_result_t
|
extern route_map_result_t
|
||||||
zebra_nht_route_map_check(int family, int client_proto, const struct prefix *p,
|
zebra_nht_route_map_check(int family, int client_proto, const struct prefix *p,
|
||||||
struct route_entry *, struct nexthop *nexthop);
|
struct zebra_vrf *zvrf, struct route_entry *,
|
||||||
|
struct nexthop *nexthop);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +32,11 @@ typedef struct mpls_srgb_t_ {
|
|||||||
uint32_t end_label;
|
uint32_t end_label;
|
||||||
} mpls_srgb_t;
|
} mpls_srgb_t;
|
||||||
|
|
||||||
|
struct zebra_rmap {
|
||||||
|
char *name;
|
||||||
|
struct route_map *map;
|
||||||
|
};
|
||||||
|
|
||||||
/* Routing table instance. */
|
/* Routing table instance. */
|
||||||
struct zebra_vrf {
|
struct zebra_vrf {
|
||||||
/* Back pointer */
|
/* Back pointer */
|
||||||
@ -92,6 +97,9 @@ struct zebra_vrf {
|
|||||||
struct zebra_pw_head pseudowires;
|
struct zebra_pw_head pseudowires;
|
||||||
struct zebra_static_pw_head static_pseudowires;
|
struct zebra_static_pw_head static_pseudowires;
|
||||||
|
|
||||||
|
struct zebra_rmap proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1];
|
||||||
|
struct zebra_rmap nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1];
|
||||||
|
|
||||||
/* MPLS processing flags */
|
/* MPLS processing flags */
|
||||||
uint16_t mpls_flags;
|
uint16_t mpls_flags;
|
||||||
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)
|
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)
|
||||||
@ -122,6 +130,10 @@ struct zebra_vrf {
|
|||||||
uint64_t lsp_installs;
|
uint64_t lsp_installs;
|
||||||
uint64_t lsp_removals;
|
uint64_t lsp_removals;
|
||||||
};
|
};
|
||||||
|
#define PROTO_RM_NAME(zvrf, afi, rtype) zvrf->proto_rm[afi][rtype].name
|
||||||
|
#define NHT_RM_NAME(zvrf, afi, rtype) zvrf->nht_rm[afi][rtype].name
|
||||||
|
#define PROTO_RM_MAP(zvrf, afi, rtype) zvrf->proto_rm[afi][rtype].map
|
||||||
|
#define NHT_RM_MAP(zvrf, afi, rtype) zvrf->nht_rm[afi][rtype].map
|
||||||
|
|
||||||
static inline vrf_id_t zvrf_id(struct zebra_vrf *zvrf)
|
static inline vrf_id_t zvrf_id(struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user