From 7c5519562ec585e9f75fd4dfd88710f4c9df5567 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 14 Apr 2016 09:20:47 -0400 Subject: [PATCH] zebra: Refactor zebra_vrf Move zebra_vrf_XXX functionality into it's own file so that we can isolate a bit the api edges Signed-off-by: Donald Sharp Reviewed-by: Don Slice Reviewed-by: Vivek Venkatraman --- zebra/Makefile.am | 8 +- zebra/interface.c | 5 +- zebra/main.c | 77 ---------- zebra/redistribute.c | 43 +----- zebra/redistribute.h | 3 - zebra/redistribute_null.c | 4 - zebra/rib.h | 58 -------- zebra/router-id.c | 1 + zebra/rt_netlink.c | 1 + zebra/rtadv.c | 1 + zebra/test_main.c | 63 +------- zebra/zebra_fpm.c | 3 + zebra/zebra_fpm_netlink.c | 3 + zebra/zebra_ns.c | 1 + zebra/zebra_ptm.c | 2 + zebra/zebra_rib.c | 157 +------------------ zebra/zebra_rnh.c | 1 + zebra/zebra_vrf.c | 306 ++++++++++++++++++++++++++++++++++++++ zebra/zebra_vrf.h | 91 ++++++++++++ zebra/zebra_vty.c | 1 + zebra/zserv.c | 2 + zebra/zserv.h | 1 + zebra/zserv_null.c | 39 +++++ 23 files changed, 465 insertions(+), 406 deletions(-) create mode 100644 zebra/zebra_vrf.c create mode 100644 zebra/zebra_vrf.h create mode 100644 zebra/zserv_null.c diff --git a/zebra/Makefile.am b/zebra/Makefile.am index e4b6b792ca..d0308d8cf9 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -35,19 +35,19 @@ zebra_SOURCES = \ redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \ irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \ $(othersrc) zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c \ - zebra_ns.c + zebra_ns.c zebra_vrf.c testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \ - zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c \ + zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \ kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \ - zebra_ptm_null.c rtadv_null.c if_null.c + zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c noinst_HEADERS = \ connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \ interface.h ipforward.h irdp.h router-id.h kernel_socket.h \ rt_netlink.h zebra_fpm.h zebra_fpm_private.h zebra_rnh.h \ zebra_ptm_redistribute.h zebra_ptm.h zebra_routemap.h \ - zebra_ns.h + zebra_ns.h zebra_vrf.h zebra_LDADD = $(otherobj) ../lib/libzebra.la $(LIBCAP) $(LIB_IPV6) diff --git a/zebra/interface.c b/zebra/interface.c index 1fff39da4c..a6f130da68 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -34,18 +34,17 @@ #include "zclient.h" #include "vrf.h" -#include "zebra/interface.h" #include "zebra/rtadv.h" +#include "zebra_ns.h" +#include "zebra/interface.h" #include "zebra/rib.h" #include "zebra/zserv.h" -#include "zebra/zebra_ns.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/irdp.h" #include "zebra/zebra_ptm.h" #include "zebra/rt_netlink.h" #include "zebra/interface.h" -#include "zebra/zebra_ns.h" #define ZEBRA_PTM_SUPPORT diff --git a/zebra/main.c b/zebra/main.c index c1a2c69021..65a7dbec1a 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -222,83 +222,6 @@ struct quagga_signal_t zebra_signals[] = .handler = &sigint, }, }; - -/* Callback upon creating a new VRF. */ -static int -zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) -{ - struct zebra_vrf *zvrf = *info; - - zlog_info ("ZVRF %s with id %u", name, vrf_id); - - if (! zvrf) - { - zvrf = zebra_vrf_alloc (vrf_id, name); - zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ - *info = (void *)zvrf; - router_id_init (zvrf); - } - - return 0; -} - -/* Callback upon enabling a VRF. */ -static int -zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) -{ - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); - - assert (zvrf); - - zebra_vrf_add_update (zvrf); - - return 0; -} - -/* Callback upon disabling a VRF. */ -static int -zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) -{ - struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info); - - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug ("VRF %s id %u is now disabled.", - zvrf->name, zvrf->vrf_id); - - zebra_vrf_delete_update (zvrf); - - return 0; -} - -static int -zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) -{ - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); - - assert (zvrf); - - rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); - rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); - - list_delete_all_node (zvrf->rid_all_sorted_list); - list_delete_all_node (zvrf->rid_lo_sorted_list); - - XFREE (MTYPE_ZEBRA_VRF, zvrf); - - return 0; -} - -/* Zebra VRF initialization. */ -void -zebra_vrf_init (void) -{ - vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new); - vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable); - vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable); - vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete); - - vrf_init (); -} /* Main startup routine. */ int diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 4de7c56ee5..dcda0b5152 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -34,6 +34,8 @@ #include "zebra/rib.h" #include "zebra/zserv.h" +#include "zebra/zebra_ns.h" +#include "zebra/zebra_vrf.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/router-id.h" @@ -452,47 +454,6 @@ zebra_interface_delete_update (struct interface *ifp) } } -/* VRF information update. */ -void -zebra_vrf_add_update (struct zebra_vrf *zvrf) -{ - struct listnode *node, *nnode; - struct zserv *client; - - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name); - - for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) - zsend_vrf_add (client, zvrf); -} - -void -zebra_vrf_delete_update (struct zebra_vrf *zvrf) -{ - struct listnode *node, *nnode; - struct zserv *client; - - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name); - - for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) - zsend_vrf_delete (client, zvrf); -} - -void -zebra_vrf_update_all (struct zserv *client) -{ - struct vrf *vrf; - vrf_iter_t iter; - - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - { - if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id) - zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id)); - } -} - - /* Interface address addition. */ void zebra_interface_address_add_update (struct interface *ifp, diff --git a/zebra/redistribute.h b/zebra/redistribute.h index cd369c1920..47fa4c2928 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -42,9 +42,6 @@ extern void redistribute_delete (struct prefix *, struct rib *); extern void zebra_interface_up_update (struct interface *); extern void zebra_interface_down_update (struct interface *); -extern void zebra_vrf_add_update (struct zebra_vrf *); -extern void zebra_vrf_update_all (struct zserv *); -extern void zebra_vrf_delete_update (struct zebra_vrf *); extern void zebra_interface_add_update (struct interface *); extern void zebra_interface_delete_update (struct interface *); diff --git a/zebra/redistribute_null.c b/zebra/redistribute_null.c index 63fae3eeb5..27223c609a 100644 --- a/zebra/redistribute_null.c +++ b/zebra/redistribute_null.c @@ -47,10 +47,6 @@ void zebra_interface_delete_update (struct interface *a) { return; } #endif -void zebra_vrf_add_update (struct zebra_vrf *a) -{ return; } -void zebra_vrf_delete_update (struct zebra_vrf *a) -{ return; } void zebra_interface_address_add_update (struct interface *a, struct connected *b) diff --git a/zebra/rib.h b/zebra/rib.h index 662bb697a3..555bb46426 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -273,57 +273,6 @@ struct rtadv }; #endif /* HAVE_RTADV */ -/* Routing table instance. */ -struct zebra_vrf -{ - /* Identifier. */ - vrf_id_t vrf_id; - - /* Routing table name. */ - char name[VRF_NAMSIZ]; - - /* Description. */ - char *desc; - - /* FIB identifier. */ - u_char fib_id; - - /* Flags. */ - u_int16_t flags; -#define ZEBRA_VRF_RIB_SCHEDULED (1 << 0) - - u_int32_t table_id; - - /* Routing table. */ - struct route_table *table[AFI_MAX][SAFI_MAX]; - - /* Static route configuration. */ - struct route_table *stable[AFI_MAX][SAFI_MAX]; - - /* Recursive Nexthop table */ - struct route_table *rnh_table[AFI_MAX]; - - /* Import check table (used mostly by BGP */ - struct route_table *import_check_table[AFI_MAX]; - - /* Routing tables off of main table for redistribute table */ - struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; - - /* 2nd pointer type used primarily to quell a warning on - * ALL_LIST_ELEMENTS_RO - */ - struct list _rid_all_sorted_list; - struct list _rid_lo_sorted_list; - struct list *rid_all_sorted_list; - struct list *rid_lo_sorted_list; - struct prefix rid_user_assigned; - - /* - * Back pointer to the owning namespace. - */ - struct zebra_ns *zns; -}; - /* * rib_table_info_t * @@ -399,13 +348,6 @@ extern struct nexthop *rib_nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6, unsigned int ifindex); -extern void zebra_vrf_init (void); -extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id); -extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); -extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); -extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, vrf_id_t); -extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, - vrf_id_t vrf_id); extern int is_zebra_valid_kernel_table(u_int32_t table_id); extern int is_zebra_main_routing_table(u_int32_t table_id); extern int zebra_check_addr (struct prefix *p); diff --git a/zebra/router-id.c b/zebra/router-id.c index a3195cdc9f..a1d7cb9dab 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -39,6 +39,7 @@ #include "vrf.h" #include "zebra/zserv.h" +#include "zebra/zebra_vrf.h" #include "zebra/router-id.h" #include "zebra/redistribute.h" diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 7756f76358..78364f6f4a 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -41,6 +41,7 @@ #include "zebra/zserv.h" #include "zebra/zebra_ns.h" +#include "zebra/zebra_vrf.h" #include "zebra/rt.h" #include "zebra/redistribute.h" #include "zebra/interface.h" diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 233d600734..4807782d4d 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -39,6 +39,7 @@ #include "zebra/rib.h" #include "zebra/zserv.h" #include "zebra/zebra_ns.h" +#include "zebra/zebra_vrf.h" extern struct zebra_privs_t zserv_privs; diff --git a/zebra/test_main.c b/zebra/test_main.c index 8fbf39951c..902c675aef 100644 --- a/zebra/test_main.c +++ b/zebra/test_main.c @@ -32,7 +32,9 @@ #include "vrf.h" #include "zebra/rib.h" +#include "zebra/zebra_ns.h" #include "zebra/zserv.h" +#include "zebra/zebra_vrf.h" #include "zebra/debug.h" #include "zebra/router-id.h" #include "zebra/interface.h" @@ -201,67 +203,6 @@ struct quagga_signal_t zebra_signals[] = .handler = &sigint, }, }; - -/* Callback upon creating a new VRF. */ -static int -zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) -{ - struct zebra_vrf *zvrf = *info; - - if (! zvrf) - { - zvrf = zebra_vrf_alloc (vrf_id, name); - *info = (void *)zvrf; - } - - return 0; -} - -/* Callback upon enabling a VRF. */ -static int -zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) -{ - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); - - assert (zvrf); - - return 0; -} - -/* Callback upon disabling a VRF. */ -static int -zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) -{ - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); - struct listnode *list_node; - struct interface *ifp; - - assert (zvrf); - - rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); - rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); - - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp)) - { - int operative = if_is_operative (ifp); - UNSET_FLAG (ifp->flags, IFF_UP); - if (operative) - if_down (ifp); - } - - return 0; -} - -/* Zebra VRF initialization. */ -void -zebra_vrf_init (void) -{ - vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new); - vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable); - vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable); - vrf_init (); -} - /* Main startup routine. */ int main (int argc, char **argv) diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index b827b994e3..3771e53e84 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -31,6 +31,9 @@ #include "command.h" #include "zebra/rib.h" +#include "zebra/zserv.h" +#include "zebra/zebra_ns.h" +#include "zebra/zebra_vrf.h" #include "fpm/fpm.h" #include "zebra_fpm.h" diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index dc6c12a23e..f7d0136286 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -28,6 +28,9 @@ #include "log.h" #include "rib.h" +#include "zserv.h" +#include "zebra_ns.h" +#include "zebra_vrf.h" #include "rt_netlink.h" #include "nexthop.h" diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index da03dff37c..6b04aa741a 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -27,6 +27,7 @@ #include "rtadv.h" #include "zebra_ns.h" +#include "zebra_vrf.h" struct zebra_ns *dzns; diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 4ba7d1b4c3..364c1c9fa9 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -35,6 +35,8 @@ #include "zebra/zebra_ptm_redistribute.h" #include "bfd.h" #include "vrf.h" +#include "rib.h" +#include "zebra_vrf.h" #define ZEBRA_PTM_RECONNECT_TIME_INITIAL 1 /* initial reconnect is 1s */ #define ZEBRA_PTM_RECONNECT_TIME_MAX 300 diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 995fe52bf1..0c7dd57911 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -39,7 +39,9 @@ #include "zebra/rib.h" #include "zebra/rt.h" +#include "zebra/zebra_ns.h" #include "zebra/zserv.h" +#include "zebra/zebra_vrf.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/zebra_fpm.h" @@ -1997,32 +1999,6 @@ rib_delnode (struct route_node *rn, struct rib *rib) } } -/* Lookup the routing table in a VRF based on both VRF-Id and table-id. - * NOTE: Table-id is relevant only in the Default VRF. - */ -static struct route_table * -zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, - vrf_id_t vrf_id, u_int32_t table_id) -{ - struct route_table *table = NULL; - - if (afi >= AFI_MAX || safi >= SAFI_MAX) - return NULL; - - if (vrf_id == VRF_DEFAULT) - { - if (table_id == RT_TABLE_MAIN || - table_id == zebrad.rtm_table_default) - table = zebra_vrf_table (afi, safi, vrf_id); - else - table = zebra_vrf_other_route_table (afi, table_id, vrf_id); - } - else - table = zebra_vrf_table (afi, safi, vrf_id); - - return table; -} - int rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p, struct in_addr *gate, struct in_addr *src, @@ -3826,132 +3802,3 @@ rib_tables_iter_next (rib_tables_iter_t *iter) return table; } -/* - * Create a routing table for the specific AFI/SAFI in the given VRF. - */ -static void -zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi) -{ - rib_table_info_t *info; - struct route_table *table; - - assert (!zvrf->table[afi][safi]); - - table = route_table_init (); - zvrf->table[afi][safi] = table; - - info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); - info->zvrf = zvrf; - info->afi = afi; - info->safi = safi; - table->info = info; -} - -/* Allocate new zebra VRF. */ -struct zebra_vrf * -zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) -{ - struct zebra_vrf *zvrf; - - zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf)); - - /* Allocate routing table and static table. */ - zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST); - zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST); - zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init (); - zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init (); - zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST); - zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST); - zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init (); - zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init (); - - zvrf->rnh_table[AFI_IP] = route_table_init(); - zvrf->rnh_table[AFI_IP6] = route_table_init(); - - zvrf->import_check_table[AFI_IP] = route_table_init(); - zvrf->import_check_table[AFI_IP6] = route_table_init(); - - /* Set VRF ID */ - zvrf->vrf_id = vrf_id; - - if (name) - { - strncpy (zvrf->name, name, strlen(name)); - zvrf->name[strlen(name)] = '\0'; - } - - return zvrf; -} - -/* Lookup VRF by identifier. */ -struct zebra_vrf * -zebra_vrf_lookup (vrf_id_t vrf_id) -{ - return vrf_info_lookup (vrf_id); -} - -/* Lookup the routing table in an enabled VRF. */ -struct route_table * -zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id) -{ - struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id); - - if (!zvrf) - return NULL; - - if (afi >= AFI_MAX || safi >= SAFI_MAX) - return NULL; - - return zvrf->table[afi][safi]; -} - -/* Lookup the static routing table in a VRF. */ -struct route_table * -zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id) -{ - struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id); - - if (!zvrf) - return NULL; - - if (afi >= AFI_MAX || safi >= SAFI_MAX) - return NULL; - - return zvrf->stable[afi][safi]; -} - -struct route_table * -zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id) -{ - struct zebra_vrf *zvrf; - rib_table_info_t *info; - struct route_table *table; - - zvrf = vrf_info_lookup (vrf_id); - if (! zvrf) - return NULL; - - if(afi >= AFI_MAX) - return NULL; - - if (table_id >= ZEBRA_KERNEL_TABLE_MAX) - return NULL; - - if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default)) - { - if (zvrf->other_table[afi][table_id] == NULL) - { - table = route_table_init(); - info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); - info->zvrf = zvrf; - info->afi = afi; - info->safi = SAFI_UNICAST; - table->info = info; - zvrf->other_table[afi][table_id] = table; - } - - return (zvrf->other_table[afi][table_id]); - } - - return zvrf->table[afi][SAFI_UNICAST]; -} diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 313dae3f11..abc2daa284 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -42,6 +42,7 @@ #include "zebra/rt.h" #include "zebra/zserv.h" #include "zebra/zebra_ns.h" +#include "zebra/zebra_vrf.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/zebra_rnh.h" diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c new file mode 100644 index 0000000000..c268fcbcb7 --- /dev/null +++ b/zebra/zebra_vrf.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2016 CumulusNetworks + * Donald Sharp + * + * This file is part of Quagga + * + * Quagga is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * Quagga is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include + +#include "log.h" +#include "linklist.h" + +#include "zebra/debug.h" +#include "zebra/zserv.h" +#include "zebra/rib.h" +#include "zebra/zebra_vrf.h" +#include "zebra/router-id.h" + +extern struct zebra_t zebrad; + +/* VRF information update. */ +static void +zebra_vrf_add_update (struct zebra_vrf *zvrf) +{ + struct listnode *node, *nnode; + struct zserv *client; + + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name); + + for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) + zsend_vrf_add (client, zvrf); +} + +static void +zebra_vrf_delete_update (struct zebra_vrf *zvrf) +{ + struct listnode *node, *nnode; + struct zserv *client; + + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name); + + for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) + zsend_vrf_delete (client, zvrf); +} + +void +zebra_vrf_update_all (struct zserv *client) +{ + struct vrf *vrf; + vrf_iter_t iter; + + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id) + zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id)); + } +} + +/* Callback upon creating a new VRF. */ +static int +zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) +{ + struct zebra_vrf *zvrf = *info; + + zlog_info ("ZVRF %s with id %u", name, vrf_id); + + if (! zvrf) + { + zvrf = zebra_vrf_alloc (vrf_id, name); + zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ + *info = (void *)zvrf; + router_id_init (zvrf); + } + + return 0; +} + +/* Callback upon enabling a VRF. */ +static int +zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) +{ + struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); + + assert (zvrf); + + zebra_vrf_add_update (zvrf); + + return 0; +} + +/* Callback upon disabling a VRF. */ +static int +zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) +{ + struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info); + + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug ("VRF %s id %u is now disabled.", + zvrf->name, zvrf->vrf_id); + + return 0; +} + +static int +zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) +{ + struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); + + assert (zvrf); + + zebra_vrf_delete_update (zvrf); + + rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); + rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); + + list_delete_all_node (zvrf->rid_all_sorted_list); + list_delete_all_node (zvrf->rid_lo_sorted_list); + + XFREE (MTYPE_ZEBRA_VRF, zvrf); + + return 0; +} + +/* Lookup the routing table in a VRF based on both VRF-Id and table-id. + * NOTE: Table-id is relevant only in the Default VRF. + */ +struct route_table * +zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, + vrf_id_t vrf_id, u_int32_t table_id) +{ + struct route_table *table = NULL; + + if (afi >= AFI_MAX || safi >= SAFI_MAX) + return NULL; + + if (vrf_id == VRF_DEFAULT) + { + if (table_id == RT_TABLE_MAIN || + table_id == zebrad.rtm_table_default) + table = zebra_vrf_table (afi, safi, vrf_id); + else + table = zebra_vrf_other_route_table (afi, table_id, vrf_id); + } + else + table = zebra_vrf_table (afi, safi, vrf_id); + + return table; +} + +/* + * Create a routing table for the specific AFI/SAFI in the given VRF. + */ +static void +zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi) +{ + rib_table_info_t *info; + struct route_table *table; + + assert (!zvrf->table[afi][safi]); + + table = route_table_init (); + zvrf->table[afi][safi] = table; + + info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); + info->zvrf = zvrf; + info->afi = afi; + info->safi = safi; + table->info = info; +} + +/* Allocate new zebra VRF. */ +struct zebra_vrf * +zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) +{ + struct zebra_vrf *zvrf; + + zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf)); + + /* Allocate routing table and static table. */ + zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST); + zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST); + zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init (); + zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init (); + zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST); + zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST); + zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init (); + zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init (); + + zvrf->rnh_table[AFI_IP] = route_table_init(); + zvrf->rnh_table[AFI_IP6] = route_table_init(); + + zvrf->import_check_table[AFI_IP] = route_table_init(); + zvrf->import_check_table[AFI_IP6] = route_table_init(); + + /* Set VRF ID */ + zvrf->vrf_id = vrf_id; + + if (name) + { + strncpy (zvrf->name, name, strlen(name)); + zvrf->name[strlen(name)] = '\0'; + } + + return zvrf; +} + +/* Lookup VRF by identifier. */ +struct zebra_vrf * +zebra_vrf_lookup (vrf_id_t vrf_id) +{ + return vrf_info_lookup (vrf_id); +} + +/* Lookup the routing table in an enabled VRF. */ +struct route_table * +zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id) +{ + struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id); + + if (!zvrf) + return NULL; + + if (afi >= AFI_MAX || safi >= SAFI_MAX) + return NULL; + + return zvrf->table[afi][safi]; +} + +/* Lookup the static routing table in a VRF. */ +struct route_table * +zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id) +{ + struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id); + + if (!zvrf) + return NULL; + + if (afi >= AFI_MAX || safi >= SAFI_MAX) + return NULL; + + return zvrf->stable[afi][safi]; +} + +struct route_table * +zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id) +{ + struct zebra_vrf *zvrf; + rib_table_info_t *info; + struct route_table *table; + + zvrf = vrf_info_lookup (vrf_id); + if (! zvrf) + return NULL; + + if(afi >= AFI_MAX) + return NULL; + + if (table_id >= ZEBRA_KERNEL_TABLE_MAX) + return NULL; + + if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default)) + { + if (zvrf->other_table[afi][table_id] == NULL) + { + table = route_table_init(); + info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); + info->zvrf = zvrf; + info->afi = afi; + info->safi = SAFI_UNICAST; + table->info = info; + zvrf->other_table[afi][table_id] = table; + } + + return (zvrf->other_table[afi][table_id]); + } + + return zvrf->table[afi][SAFI_UNICAST]; +} + +/* Zebra VRF initialization. */ +void +zebra_vrf_init (void) +{ + vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new); + vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable); + vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable); + vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete); + + vrf_init (); +} diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h new file mode 100644 index 0000000000..e8bc201a63 --- /dev/null +++ b/zebra/zebra_vrf.h @@ -0,0 +1,91 @@ +/* + * Zebra Vrf Header + * Copyright (C) 2016 Cumulus Networks + * Donald Sahrp + * + * This file is part of Quagga. + * + * Quagga is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * Quagga is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#if !defined(__ZEBRA_RIB_H__) +#define __ZEBRA_RIB_H__ + +#include + +/* Routing table instance. */ +struct zebra_vrf +{ + /* Identifier. */ + vrf_id_t vrf_id; + + /* Routing table name. */ + char name[VRF_NAMSIZ]; + + /* Description. */ + char *desc; + + /* FIB identifier. */ + u_char fib_id; + + /* Flags. */ + u_int16_t flags; +#define ZEBRA_VRF_RIB_SCHEDULED (1 << 0) + + u_int32_t table_id; + + /* Routing table. */ + struct route_table *table[AFI_MAX][SAFI_MAX]; + + /* Static route configuration. */ + struct route_table *stable[AFI_MAX][SAFI_MAX]; + + /* Recursive Nexthop table */ + struct route_table *rnh_table[AFI_MAX]; + + /* Import check table (used mostly by BGP */ + struct route_table *import_check_table[AFI_MAX]; + + /* Routing tables off of main table for redistribute table */ + struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; + + /* 2nd pointer type used primarily to quell a warning on + * ALL_LIST_ELEMENTS_RO + */ + struct list _rid_all_sorted_list; + struct list _rid_lo_sorted_list; + struct list *rid_all_sorted_list; + struct list *rid_lo_sorted_list; + struct prefix rid_user_assigned; + + /* + * Back pointer to the owning namespace. + */ + struct zebra_ns *zns; +}; + +struct route_table * +zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, + vrf_id_t vrf_id, u_int32_t table_id); + +extern void zebra_vrf_update_all (struct zserv *client); +extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id); +extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); +extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); +extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, vrf_id_t); +extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, + vrf_id_t vrf_id); +extern void zebra_vrf_init (void); +#endif diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 5edafbdbcc..97a60460c6 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -31,6 +31,7 @@ #include "vrf.h" #include "zebra/zserv.h" +#include "zebra/zebra_vrf.h" #include "zebra/zebra_rnh.h" #include "zebra/redistribute.h" #include "zebra/zebra_routemap.h" diff --git a/zebra/zserv.c b/zebra/zserv.c index e42d146fdf..da66ba4bba 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -40,6 +40,8 @@ #include "vrf.h" #include "zebra/zserv.h" +#include "zebra/zebra_ns.h" +#include "zebra/zebra_vrf.h" #include "zebra/router-id.h" #include "zebra/redistribute.h" #include "zebra/debug.h" diff --git a/zebra/zserv.h b/zebra/zserv.h index 8fcf8e495e..3fa3440519 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -30,6 +30,7 @@ #include "zclient.h" #include "vrf.h" +#include "zebra/zebra_ns.h" /* Default port information. */ #define ZEBRA_VTY_PORT 2601 diff --git a/zebra/zserv_null.c b/zebra/zserv_null.c new file mode 100644 index 0000000000..acab22d96f --- /dev/null +++ b/zebra/zserv_null.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of Quagga. + * + * Quagga is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * Quagga is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Quagga; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include + +#include + +#include +#include +#include +#include + +int zsend_vrf_delete (struct zserv *zserv, struct zebra_vrf *zvrf) +{ return 0; } + +int zsend_vrf_add (struct zserv *zserv, struct zebra_vrf *zvrf) +{ return 0; } + +void router_id_init (struct zebra_vrf *zvrf) +{ return; } -- 2.39.5