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 (type == DEFAULT_ROUTE) + return; - 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); - } + 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)