From: Chirag Shah Date: Tue, 21 Nov 2017 01:21:03 +0000 (-0800) Subject: ospfd: Make external routes in ospf VRF aware X-Git-Tag: frr-4.0-dev~134^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=de1ac5fd63a52de2d6a2133edd770ec9979a7102;p=mirror%2Ffrr.git ospfd: Make external routes in ospf VRF aware Currently, ospf external routers are part of struct ospf_master which is not vrf aware ospf instance. All ospf external routes are injected/leaked into all vrfs. Moved ospf external routes db to struct ospf to make vrf aware, such one external routes learnt in one vrf is not leaked into another vrf. Ticket:CM-18855 Testing Done: Inject external route in non-default vrf x, validated ospf database across the vrf x, validated ospf routes for vrf x. Signed-off-by: Chirag Shah --- diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 89c462693b..33461e6df8 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -127,7 +127,8 @@ int ospf_route_map_set_compare(struct route_map_set_values *values1, } /* Add an External info for AS-external-LSA. */ -struct external_info *ospf_external_info_add(u_char type, u_short instance, +struct external_info *ospf_external_info_add(struct ospf *ospf, u_char type, + u_short instance, struct prefix_ipv4 p, ifindex_t ifindex, struct in_addr nexthop, @@ -138,9 +139,9 @@ struct external_info *ospf_external_info_add(u_char type, u_short instance, struct ospf_external *ext; char inetbuf[INET6_BUFSIZ]; - ext = ospf_external_lookup(type, instance); + ext = ospf_external_lookup(ospf, type, instance); if (!ext) - ext = ospf_external_add(type, instance); + ext = ospf_external_add(ospf, type, instance); rn = route_node_get(EXTERNAL_INFO(ext), (struct prefix *)&p); /* If old info exists, -- discard new one or overwrite with new one? */ @@ -157,9 +158,10 @@ struct external_info *ospf_external_info_add(u_char type, u_short instance, inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ); zlog_warn( - "Redistribute[%s][%d]: %s/%d discarding old info with NH %s.", + "Redistribute[%s][%d][%u]: %s/%d discarding old info with NH %s.", ospf_redist_string(type), instance, - inet_ntoa(p.prefix), p.prefixlen, inetbuf); + ospf->vrf_id, inet_ntoa(p.prefix), + p.prefixlen, inetbuf); XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info); rn->info = NULL; } @@ -179,20 +181,20 @@ struct external_info *ospf_external_info_add(u_char type, u_short instance, inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ); zlog_debug( - "Redistribute[%s]: %s/%d external info created, with NH %s", - ospf_redist_string(type), inet_ntoa(p.prefix), - p.prefixlen, inetbuf); + "Redistribute[%s][%u]: %s/%d external info created, with NH %s", + ospf_redist_string(type), ospf->vrf_id, + inet_ntoa(p.prefix), p.prefixlen, inetbuf); } return new; } -void ospf_external_info_delete(u_char type, u_short instance, +void ospf_external_info_delete(struct ospf *ospf, u_char type, u_short instance, struct prefix_ipv4 p) { struct route_node *rn; struct ospf_external *ext; - ext = ospf_external_lookup(type, instance); + ext = ospf_external_lookup(ospf, type, instance); if (!ext) return; @@ -205,13 +207,14 @@ void ospf_external_info_delete(u_char type, u_short instance, } } -struct external_info *ospf_external_info_lookup(u_char type, u_short instance, +struct external_info *ospf_external_info_lookup(struct ospf *ospf, u_char type, + u_short instance, struct prefix_ipv4 *p) { struct route_node *rn; struct ospf_external *ext; - ext = ospf_external_lookup(type, instance); + ext = ospf_external_lookup(ospf, type, instance); if (!ext) return NULL; @@ -288,7 +291,7 @@ void ospf_redistribute_withdraw(struct ospf *ospf, u_char type, struct external_info *ei; struct ospf_external *ext; - ext = ospf_external_lookup(type, instance); + ext = ospf_external_lookup(ospf, type, instance); if (!ext) return; diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h index 3d7f14e7f2..38ed95322b 100644 --- a/ospfd/ospf_asbr.h +++ b/ospfd/ospf_asbr.h @@ -58,12 +58,15 @@ extern struct external_info *ospf_external_info_new(u_char, u_short); extern void ospf_reset_route_map_set_values(struct route_map_set_values *); extern int ospf_route_map_set_compare(struct route_map_set_values *, struct route_map_set_values *); -extern struct external_info *ospf_external_info_add(u_char, u_short, +extern struct external_info *ospf_external_info_add(struct ospf *, + u_char, u_short, struct prefix_ipv4, ifindex_t, struct in_addr, route_tag_t); -extern void ospf_external_info_delete(u_char, u_short, struct prefix_ipv4); -extern struct external_info *ospf_external_info_lookup(u_char, u_short, +extern void ospf_external_info_delete(struct ospf*, u_char, u_short, + struct prefix_ipv4); +extern struct external_info *ospf_external_info_lookup(struct ospf*, u_char, + u_short, struct prefix_ipv4 *); extern struct ospf_route *ospf_external_route_lookup(struct ospf *, struct prefix_ipv4 *); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index facce9aafd..36b6d5143d 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -108,7 +108,7 @@ struct external_info *ospf_external_info_check(struct ospf *ospf, struct listnode *node; struct ospf_external *ext; - ext_list = om->external[type]; + ext_list = ospf->external[type]; if (!ext_list) continue; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index fc866df965..c28e500d5b 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2037,7 +2037,7 @@ int ospf_external_lsa_originate_timer(struct thread *thread) ospf->t_external_lsa = NULL; - ext_list = om->external[type]; + ext_list = ospf->external[type]; if (!ext_list) return 0; @@ -2077,7 +2077,7 @@ static struct external_info *ospf_default_external_info(struct ospf *ospf) if (type == ZEBRA_ROUTE_OSPF) continue; - ext_list = om->external[type]; + ext_list = ospf->external[type]; if (!ext_list) continue; @@ -2114,7 +2114,8 @@ int ospf_default_originate_timer(struct thread *thread) /* If there is no default route via redistribute, then originate AS-external-LSA with nexthop 0 (self). */ nexthop.s_addr = 0; - ospf_external_info_add(DEFAULT_ROUTE, 0, p, 0, nexthop, 0); + ospf_external_info_add(ospf, DEFAULT_ROUTE, 0, p, 0, + nexthop, 0); } if ((ei = ospf_default_external_info(ospf))) @@ -2245,25 +2246,32 @@ void ospf_external_lsa_refresh_type(struct ospf *ospf, u_char type, struct external_info *ei; struct ospf_external *ext; - if (type != DEFAULT_ROUTE) - if ((ext = ospf_external_lookup(type, instance)) - && EXTERNAL_INFO(ext)) - /* Refresh each redistributed AS-external-LSAs. */ - for (rn = route_top(EXTERNAL_INFO(ext)); rn; - rn = route_next(rn)) - if ((ei = rn->info)) - if (!is_prefix_default(&ei->p)) { - struct ospf_lsa *lsa; - - if ((lsa = ospf_external_info_find_lsa( - ospf, &ei->p))) - ospf_external_lsa_refresh( - ospf, lsa, ei, - force); - else - ospf_external_lsa_originate( - ospf, ei); - } + if (type == DEFAULT_ROUTE) + return; + + ext = ospf_external_lookup(ospf, type, instance); + + if (ext && EXTERNAL_INFO(ext)) { + /* Refresh each redistributed AS-external-LSAs. */ + for (rn = route_top(EXTERNAL_INFO(ext)); rn; + rn = route_next(rn)) { + ei = rn->info; + if (ei) { + if (!is_prefix_default(&ei->p)) { + struct ospf_lsa *lsa; + + lsa = ospf_external_info_find_lsa(ospf, + &ei->p); + if (lsa) + ospf_external_lsa_refresh(ospf, + lsa, ei, force); + else + ospf_external_lsa_originate(ospf + , ei); + } + } + } + } } /* Refresh AS-external-LSA. */ diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index a49143873e..fef274bba3 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -8361,10 +8361,10 @@ DEFUN (no_ospf_default_information_originate, ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0); - if ((ext = ospf_external_lookup(DEFAULT_ROUTE, 0)) - && EXTERNAL_INFO(ext)) { - ospf_external_info_delete(DEFAULT_ROUTE, 0, p); - ospf_external_del(DEFAULT_ROUTE, 0); + ext = ospf_external_lookup(ospf, DEFAULT_ROUTE, 0); + if (ext && EXTERNAL_INFO(ext)) { + ospf_external_info_delete(ospf, DEFAULT_ROUTE, 0, p); + ospf_external_del(ospf, DEFAULT_ROUTE, 0); } red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index d7fe0edcbf..34ad6f65b0 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -519,13 +519,14 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) inet_ntoa(p->prefix), p->prefixlen); } -struct ospf_external *ospf_external_lookup(u_char type, u_short instance) +struct ospf_external *ospf_external_lookup(struct ospf *ospf, u_char type, + u_short instance) { struct list *ext_list; struct listnode *node; struct ospf_external *ext; - ext_list = om->external[type]; + ext_list = ospf->external[type]; if (!ext_list) return (NULL); @@ -536,19 +537,20 @@ struct ospf_external *ospf_external_lookup(u_char type, u_short instance) return NULL; } -struct ospf_external *ospf_external_add(u_char type, u_short instance) +struct ospf_external *ospf_external_add(struct ospf *ospf, u_char type, + u_short instance) { struct list *ext_list; struct ospf_external *ext; - ext = ospf_external_lookup(type, instance); + ext = ospf_external_lookup(ospf, type, instance); if (ext) return ext; - if (!om->external[type]) - om->external[type] = list_new(); + if (!ospf->external[type]) + ospf->external[type] = list_new(); - ext_list = om->external[type]; + ext_list = ospf->external[type]; ext = (struct ospf_external *)XCALLOC(MTYPE_OSPF_EXTERNAL, sizeof(struct ospf_external)); ext->instance = instance; @@ -559,20 +561,21 @@ struct ospf_external *ospf_external_add(u_char type, u_short instance) return ext; } -void ospf_external_del(u_char type, u_short instance) +void ospf_external_del(struct ospf *ospf, u_char type, u_short instance) { struct ospf_external *ext; - ext = ospf_external_lookup(type, instance); + ext = ospf_external_lookup(ospf, type, instance); if (ext) { if (EXTERNAL_INFO(ext)) route_table_finish(EXTERNAL_INFO(ext)); - listnode_delete(om->external[type], ext); - if (!om->external[type]->count) { - list_delete_and_null(&om->external[type]); - } + listnode_delete(ospf->external[type], ext); + + if (!ospf->external[type]->count) + list_delete_and_null(&ospf->external[type]); + XFREE(MTYPE_OSPF_EXTERNAL, ext); } } @@ -684,7 +687,7 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance, red->dmetric.type = mtype; red->dmetric.value = mvalue; - ospf_external_add(type, instance); + ospf_external_add(ospf, type, instance); zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, instance, ospf->vrf_id); @@ -720,7 +723,7 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance) /* Remove the routes from OSPF table. */ ospf_redistribute_withdraw(ospf, type, instance); - ospf_external_del(type, instance); + ospf_external_del(ospf, type, instance); ospf_asbr_status_update(ospf, --ospf->redistribute); @@ -738,7 +741,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, red->dmetric.type = mtype; red->dmetric.value = mvalue; - ospf_external_add(DEFAULT_ROUTE, 0); + ospf_external_add(ospf, DEFAULT_ROUTE, 0); if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) { /* if ospf->default_originate changes value, is calling @@ -963,10 +966,11 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient, */ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) if (i != api.type) - ospf_external_info_delete(i, api.instance, p); + ospf_external_info_delete(ospf, i, + api.instance, p); - ei = ospf_external_info_add(api.type, api.instance, p, ifindex, - nexthop, api.tag); + ei = ospf_external_info_add(ospf, api.type, api.instance, p, + ifindex, nexthop, api.tag); if (ei == NULL) { /* Nothing has changed, so nothing to do; return */ return 0; @@ -1004,7 +1008,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient, } } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */ { - ospf_external_info_delete(api.type, api.instance, p); + ospf_external_info_delete(ospf, api.type, api.instance, p); if (is_prefix_default(&p)) ospf_external_lsa_refresh_default(ospf); else @@ -1087,7 +1091,7 @@ static int ospf_distribute_list_update_timer(struct thread *thread) struct listnode *node; struct ospf_external *ext; - ext_list = om->external[type]; + ext_list = ospf->external[type]; if (!ext_list) continue; @@ -1130,7 +1134,7 @@ void ospf_distribute_list_update(struct ospf *ospf, int type, args[1] = (void *)((ptrdiff_t) type); /* External info does not exist. */ - ext = ospf_external_lookup(type, instance); + ext = ospf_external_lookup(ospf, type, instance); if (!ext || !(rt = EXTERNAL_INFO(ext))) { XFREE(MTYPE_OSPF_DIST_ARGS, args); return; diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index 8340f49ede..d4b00dddff 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -59,9 +59,10 @@ extern int ospf_is_type_redistributed(struct ospf *, int, u_short); extern void ospf_distance_reset(struct ospf *); extern u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *, struct ospf_route *); -extern struct ospf_external *ospf_external_lookup(u_char, u_short); -extern struct ospf_external *ospf_external_add(u_char, u_short); -extern void ospf_external_del(u_char, u_short); +extern struct ospf_external *ospf_external_lookup(struct ospf*, u_char, + u_short); +extern struct ospf_external *ospf_external_add(struct ospf*, u_char, u_short); +extern void ospf_external_del(struct ospf *, u_char, u_short); extern struct ospf_redist *ospf_redist_lookup(struct ospf *, u_char, u_short); extern struct ospf_redist *ospf_redist_add(struct ospf *, u_char, u_short); extern void ospf_redist_del(struct ospf *, u_char, u_short); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index a37867fe23..ceb8440eeb 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -741,7 +741,7 @@ static void ospf_finish_final(struct ospf *ospf) struct listnode *node; struct ospf_external *ext; - ext_list = om->external[i]; + ext_list = ospf->external[i]; if (!ext_list) continue; @@ -970,34 +970,37 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf) struct external_info *ei; struct ospf_external *ext; - if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) - if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) - && EXTERNAL_INFO(ext)) { + if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) { + ext = ospf_external_lookup(ospf, ZEBRA_ROUTE_CONNECT, 0); + if ((ext) && EXTERNAL_INFO(ext)) { for (rn = route_top(EXTERNAL_INFO(ext)); rn; rn = route_next(rn)) { - if ((ei = rn->info) != NULL) { - if (add_to_ospf) { - if (ospf_external_info_find_lsa( - ospf, &ei->p)) - if (!ospf_distribute_check_connected( - ospf, ei)) - ospf_external_lsa_flush( - ospf, - ei->type, - &ei->p, - ei->ifindex /*, ei->nexthop */); - } else { - if (!ospf_external_info_find_lsa( - ospf, &ei->p)) - if (ospf_distribute_check_connected( - ospf, ei)) - ospf_external_lsa_originate( - ospf, - ei); - } + ei = rn->info; + if (ei == NULL) + continue; + + if (add_to_ospf) { + if (ospf_external_info_find_lsa( + ospf, &ei->p)) + if (!ospf_distribute_check_connected( + ospf, ei)) + ospf_external_lsa_flush( + ospf, + ei->type, + &ei->p, + ei->ifindex /*, ei->nexthop */); + } else { + if (!ospf_external_info_find_lsa( + ospf, &ei->p)) + if (ospf_distribute_check_connected( + ospf, ei)) + ospf_external_lsa_originate( + ospf, + ei); } } } + } } /* Config network statement related functions. */ diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 6cccccc649..bd3be06646 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -93,11 +93,6 @@ struct ospf_master { /* OSPF thread master. */ struct thread_master *master; - - /* Redistributed external information. */ - struct list *external[ZEBRA_ROUTE_MAX + 1]; -#define EXTERNAL_INFO(E) (E->external_info) - /* Various OSPF global configuration. */ u_char options; #define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */ @@ -314,6 +309,10 @@ struct ospf { * update to neighbors immediatly */ uint8_t inst_shutdown; + /* Redistributed external information. */ + struct list *external[ZEBRA_ROUTE_MAX + 1]; +#define EXTERNAL_INFO(E) (E->external_info) + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(ospf)