]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: Make external routes in ospf VRF aware 1473/head
authorChirag Shah <chirag@cumulusnetworks.com>
Tue, 21 Nov 2017 01:21:03 +0000 (17:21 -0800)
committerChirag Shah <chirag@cumulusnetworks.com>
Tue, 21 Nov 2017 19:23:08 +0000 (11:23 -0800)
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 <chirag@cumulusnetworks.com>
ospfd/ospf_asbr.c
ospfd/ospf_asbr.h
ospfd/ospf_flood.c
ospfd/ospf_lsa.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospf_zebra.h
ospfd/ospfd.c
ospfd/ospfd.h

index 89c462693b6c7babaf74067e4c4835915743147c..33461e6df841cb9f100777a4fdf629040afea109 100644 (file)
@@ -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;
 
index 3d7f14e7f26eb7cfbda2da7ec71db14927f5cdb3..38ed95322b93f32538e5be3f0414914118769f70 100644 (file)
@@ -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 *);
index facce9aafd1d3a54b9bb2896057d6539bf174b08..36b6d5143d813885227cf1f4ad9fbe2dc2923026 100644 (file)
@@ -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;
 
index fc866df965b74a5f5cc7656dc5cd7374c871f43d..c28e500d5b73d1c69535d1b4fdf0ab6cea4b80d4 100644 (file)
@@ -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. */
index a49143873e5120b56af2a19d29672d4aacbdf6d8..fef274bba35b42f2510fe9d422f123987d69d480 100644 (file)
@@ -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);
index d7fe0edcbf354a1dc305e3ca63099bba90ba8ba0..34ad6f65b0878a5f9e2c586b4f895756615e4781 100644 (file)
@@ -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;
index 8340f49ede9d82b1ed13b10dc1b6c2867ee74aaf..d4b00dddff0c90d6da78d3d1dcc552671f667b7f 100644 (file)
@@ -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);
index a37867fe236091fb1d202c791e4527aea0234be6..ceb8440eebd9707d07e0bda90ae598abeca3f2c8 100644 (file)
@@ -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. */
index 6cccccc64901c1418aa4feace23c51c71ebe3dd4..bd3be06646affe439615581f8c4be9cf1e42411e 100644 (file)
@@ -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)