]> git.proxmox.com Git - mirror_frr.git/commitdiff
ospf6d: add internal support for multiple vrfs
authorharios_niral <hari@niralnetworks.com>
Wed, 5 May 2021 20:17:01 +0000 (23:17 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Wed, 5 May 2021 20:17:01 +0000 (23:17 +0300)
Co-authored-by: Kaushik Nath <kaushiknath.null@gmail.com>
Signed-off-by: harios_niral <hari@niralnetworks.com>
ospf6d/ospf6_main.c
ospf6d/ospf6_top.c
ospf6d/ospf6_top.h

index cf61ca7a62dd16c20e5052292534505e046813b4..5ffcf8c2faee58dcabe112444e3214b1ec87e1d5 100644 (file)
@@ -225,7 +225,7 @@ int main(int argc, char *argv[], char *envp[])
        /* thread master */
        master = om6->master;
 
-       vrf_init(NULL, NULL, NULL, NULL, NULL);
+       ospf6_vrf_init();
        access_list_init();
        prefix_list_init();
 
index 8c6d4b126d095d9e69d7173db2e327b5ee445e1f..5d26c513f6fa48e34c5474f137ddb3b53d91cf65 100644 (file)
@@ -124,6 +124,104 @@ struct ospf6 *ospf6_lookup_by_vrf_name(const char *name)
        return NULL;
 }
 
+/* This is hook function for vrf create called as part of vrf_init */
+static int ospf6_vrf_new(struct vrf *vrf)
+{
+       return 0;
+}
+
+/* This is hook function for vrf delete call as part of vrf_init */
+static int ospf6_vrf_delete(struct vrf *vrf)
+{
+       return 0;
+}
+
+static void ospf6_set_redist_vrf_bitmaps(struct ospf6 *ospf6, bool set)
+{
+       int type;
+       struct list *red_list;
+
+       for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
+               red_list = ospf6->redist[type];
+               if (!red_list)
+                       continue;
+               if (IS_OSPF6_DEBUG_ZEBRA(RECV))
+                       zlog_debug(
+                               "%s: setting redist vrf %d bitmap for type %d",
+                               __func__, ospf6->vrf_id, type);
+               if (set)
+                       vrf_bitmap_set(zclient->redist[AFI_IP6][type],
+                                      ospf6->vrf_id);
+               else
+                       vrf_bitmap_unset(zclient->redist[AFI_IP6][type],
+                                        ospf6->vrf_id);
+       }
+}
+
+/* Disable OSPF6 VRF instance */
+static int ospf6_vrf_disable(struct vrf *vrf)
+{
+       struct ospf6 *ospf6 = NULL;
+
+       if (vrf->vrf_id == VRF_DEFAULT)
+               return 0;
+
+       ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
+       if (ospf6) {
+               ospf6_zebra_vrf_deregister(ospf6);
+
+               ospf6_set_redist_vrf_bitmaps(ospf6, false);
+
+               /* We have instance configured, unlink
+                * from VRF and make it "down".
+                */
+               ospf6_vrf_unlink(ospf6, vrf);
+               thread_cancel(&ospf6->t_ospf6_receive);
+               close(ospf6->fd);
+               ospf6->fd = -1;
+       }
+
+       /* Note: This is a callback, the VRF will be deleted by the caller. */
+       return 0;
+}
+
+/* Enable OSPF6 VRF instance */
+static int ospf6_vrf_enable(struct vrf *vrf)
+{
+       struct ospf6 *ospf6 = NULL;
+       vrf_id_t old_vrf_id;
+       int ret = 0;
+
+       ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
+       if (ospf6) {
+               old_vrf_id = ospf6->vrf_id;
+               /* We have instance configured, link to VRF and make it "up". */
+               ospf6_vrf_link(ospf6, vrf);
+
+               if (old_vrf_id != ospf6->vrf_id) {
+                       ospf6_set_redist_vrf_bitmaps(ospf6, true);
+
+                       /* start zebra redist to us for new vrf */
+                       ospf6_zebra_vrf_register(ospf6);
+
+                       ret = ospf6_serv_sock(ospf6);
+                       if (ret < 0 || ospf6->fd <= 0)
+                               return 0;
+                       thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
+                                       &ospf6->t_ospf6_receive);
+
+                       ospf6_router_id_update(ospf6);
+               }
+       }
+
+       return 0;
+}
+
+void ospf6_vrf_init(void)
+{
+       vrf_init(ospf6_vrf_new, ospf6_vrf_enable, ospf6_vrf_disable,
+                ospf6_vrf_delete, ospf6_vrf_enable);
+}
 
 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
 {
@@ -292,6 +390,9 @@ struct ospf6 *ospf6_instance_create(const char *name)
        if (ospf6->router_id == 0)
                ospf6_router_id_update(ospf6);
        ospf6_add(ospf6);
+       if (ospf6->fd < 0)
+               return ospf6;
+
        thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
                        &ospf6->t_ospf6_receive);
 
@@ -309,6 +410,8 @@ void ospf6_delete(struct ospf6 *o)
        ospf6_disable(o);
        ospf6_del(o);
 
+       ospf6_zebra_vrf_deregister(o);
+
        ospf6_serv_close(&o->fd);
 
        for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
index 08b884f23a99a7fb9059ab499cdba577280f67bb..9ba5a0f9a4aa6ceb563839aa120efc6a986febf0 100644 (file)
@@ -171,5 +171,5 @@ void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf);
 struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id);
 struct ospf6 *ospf6_lookup_by_vrf_name(const char *name);
 const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id);
-
+void ospf6_vrf_init(void);
 #endif /* OSPF6_TOP_H */