From: Donald Sharp Date: Thu, 18 May 2017 22:51:31 +0000 (-0400) Subject: pimd: Refactor code to be in better spots X-Git-Tag: frr-4.0-dev~468^2~126 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=c2cf4b0230faec3e0c478cb7ab14030a6ffe0593;p=mirror%2Ffrr.git pimd: Refactor code to be in better spots 1) Create pim_instance.[ch] to allow us to handle the instance information there 2) Refactor some pim_rpf_ and some pim_rp commands into appropriate files and appropriate includes. Signed-off-by: Donald Sharp --- diff --git a/pimd/Makefile.am b/pimd/Makefile.am index 0dd6c569dc..f440221d42 100644 --- a/pimd/Makefile.am +++ b/pimd/Makefile.am @@ -53,7 +53,8 @@ libpim_a_SOURCES = \ pim_ssmpingd.c pim_int.c pim_rp.c \ pim_static.c pim_br.c pim_register.c pim_routemap.c \ pim_msdp.c pim_msdp_socket.c pim_msdp_packet.c \ - pim_jp_agg.c pim_nht.c pim_ssm.c pim_bfd.c + pim_jp_agg.c pim_nht.c pim_ssm.c pim_bfd.c \ + pim_instance.c noinst_HEADERS = \ pim_memory.h \ @@ -66,7 +67,7 @@ noinst_HEADERS = \ pim_igmp_join.h pim_ssmpingd.h pim_int.h pim_rp.h \ pim_static.h pim_br.h pim_register.h \ pim_msdp.h pim_msdp_socket.h pim_msdp_packet.h pim_nht.h \ - pim_jp_agg.h pim_ssm.h pim_bfd.h + pim_jp_agg.h pim_ssm.h pim_bfd.h pim_instance.h pimd_SOURCES = \ pim_main.c $(libpim_a_SOURCES) diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 5f9526845f..52dc0e781b 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -29,6 +29,7 @@ #include "hash.h" #include "pimd.h" +#include "pim_instance.h" #include "pim_zebra.h" #include "pim_iface.h" #include "pim_igmp.h" diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c new file mode 100644 index 0000000000..b988c12cea --- /dev/null +++ b/pimd/pim_instance.c @@ -0,0 +1,146 @@ +/* + * PIM for FRR - PIM Instance + * Copyright (C) 2017 Cumulus Networks, Inc. + * Donald Sharp + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +#include + +#include "hash.h" +#include "vrf.h" + +#include "pimd.h" +#include "pim_ssm.h" +#include "pim_rpf.h" +#include "pim_rp.h" +#include "pim_mroute.h" + +static void pim_instance_terminate(struct pim_instance *pim) +{ + /* Traverse and cleanup rpf_hash */ + if (pim->rpf_hash) { + hash_clean(pim->rpf_hash, (void *)pim_rp_list_hash_clean); + hash_free(pim->rpf_hash); + pim->rpf_hash = NULL; + } + + if (pim->ssm_info) { + pim_ssm_terminate(pim->ssm_info); + pim->ssm_info = NULL; + } + + XFREE(MTYPE_PIM_PIM_INSTANCE, pimg); +} + +static struct pim_instance *pim_instance_init(struct vrf *vrf) +{ + struct pim_instance *pim; + + pim = XCALLOC(MTYPE_PIM_PIM_INSTANCE, sizeof(struct pim_instance)); + if (!pim) + return NULL; + + pim->vrf_id = vrf->vrf_id; + pim->vrf = vrf; + + pim->spt.switchover = PIM_SPT_IMMEDIATE; + pim->spt.plist = NULL; + + pim->rpf_hash = + hash_create_size(256, pim_rpf_hash_key, pim_rpf_equal, NULL); + + if (PIM_DEBUG_ZEBRA) + zlog_debug("%s: NHT rpf hash init ", __PRETTY_FUNCTION__); + + pim->ssm_info = pim_ssm_init(); + if (!pim->ssm_info) { + pim_instance_terminate(pim); + return NULL; + } + + pim->send_v6_secondary = 1; + + if (vrf->vrf_id == VRF_DEFAULT) + pimg = pim; + + pim_mroute_socket_enable(pim); + + return pim; +} + +struct pim_instance *pim_get_pim_instance(vrf_id_t vrf_id) +{ + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + + if (vrf) + return vrf->info; + + return NULL; +} + +static int pim_vrf_new(struct vrf *vrf) +{ + zlog_debug("VRF Created: %s(%d)", vrf->name, vrf->vrf_id); + return 0; +} + +static int pim_vrf_delete(struct vrf *vrf) +{ + zlog_debug("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id); + return 0; +} + +static int pim_vrf_enable(struct vrf *vrf) +{ + struct pim_instance *pim; + + zlog_debug("%s: for %s", __PRETTY_FUNCTION__, vrf->name); + pim = pim_instance_init(vrf); + if (pim == NULL) { + zlog_err("%s %s: pim class init failure ", __FILE__, + __PRETTY_FUNCTION__); + /* + * We will crash and burn otherwise + */ + exit(1); + } + + vrf->info = (void *)pim; + + if (vrf->vrf_id == VRF_DEFAULT) + pimg = pim; + + return 0; +} + +static int pim_vrf_disable(struct vrf *vrf) +{ + pim_instance_terminate((struct pim_instance *)vrf->info); + + /* Note: This is a callback, the VRF will be deleted by the caller. */ + return 0; +} + +void pim_vrf_init(void) +{ + vrf_init(pim_vrf_new, pim_vrf_enable, pim_vrf_disable, pim_vrf_delete); +} + +void pim_vrf_terminate(void) +{ + vrf_terminate(); +} diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h new file mode 100644 index 0000000000..33f81497fc --- /dev/null +++ b/pimd/pim_instance.h @@ -0,0 +1,63 @@ +/* + * PIM for FRR - PIM Instance + * Copyright (C) 2017 Cumulus Networks, Inc. + * Donald Sharp + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +#ifndef __PIM_INSTANCE_H__ +#define __PIM_INSTANCE_H__ + +extern struct pim_instance *pimg; // Pim Global Instance + +enum pim_spt_switchover { + PIM_SPT_IMMEDIATE, + PIM_SPT_INFINITY, +}; + +/* Per VRF PIM DB */ +struct pim_instance { + vrf_id_t vrf_id; + struct vrf *vrf; + + struct { + enum pim_spt_switchover switchover; + char *plist; + } spt; + + struct hash *rpf_hash; + + void *ssm_info; /* per-vrf SSM configuration */ + + int send_v6_secondary; + + struct thread *thread; + int mroute_socket; + int64_t mroute_socket_creation; + int64_t mroute_add_events; + int64_t mroute_add_last; + int64_t mroute_del_events; + int64_t mroute_del_last; + + struct interface *regiface; +}; + +void pim_vrf_init(void); +void pim_vrf_terminate(void); + +struct pim_instance *pim_get_pim_instance(vrf_id_t vrf_id); + +#endif diff --git a/pimd/pim_main.c b/pimd/pim_main.c index b8e6d8ad3d..a62406546e 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -40,6 +40,7 @@ #include "libfrr.h" #include "pimd.h" +#include "pim_instance.h" #include "pim_version.h" #include "pim_signals.h" #include "pim_zebra.h" diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 4a88e8f484..8a902ef9be 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -48,6 +48,18 @@ static struct list *qpim_rp_list = NULL; static struct rp_info *tail = NULL; +/* Cleanup pim->rpf_hash each node data */ +void pim_rp_list_hash_clean(void *data) +{ + struct pim_nexthop_cache *pnc; + + pnc = (struct pim_nexthop_cache *)data; + if (pnc->rp_list->count) + list_delete_all_node(pnc->rp_list); + if (pnc->upstream_list->count) + list_delete_all_node(pnc->upstream_list); +} + static void pim_rp_info_free(struct rp_info *rp_info) { XFREE(MTYPE_PIM_RP, rp_info); diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index 7a7c26593e..8d687460e4 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -36,6 +36,7 @@ struct rp_info { void pim_rp_init(void); void pim_rp_free(void); +void pim_rp_list_hash_clean(void *data); int pim_rp_new(const char *rp, const char *group, const char *plist); int pim_rp_del(const char *rp, const char *group, const char *plist); diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 4c77dd4a46..e53c5392c4 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -24,6 +24,7 @@ #include "log.h" #include "prefix.h" #include "memory.h" +#include "jhash.h" #include "pimd.h" #include "pim_rpf.h" @@ -396,3 +397,20 @@ int pim_rpf_is_same(struct pim_rpf *rpf1, struct pim_rpf *rpf2) return 0; } + +unsigned int pim_rpf_hash_key(void *arg) +{ + struct pim_nexthop_cache *r = (struct pim_nexthop_cache *)arg; + + return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0); +} + +int pim_rpf_equal(const void *arg1, const void *arg2) +{ + const struct pim_nexthop_cache *r1 = + (const struct pim_nexthop_cache *)arg1; + const struct pim_nexthop_cache *r2 = + (const struct pim_nexthop_cache *)arg2; + + return prefix_same(&r1->rpf.rpf_addr, &r2->rpf.rpf_addr); +} diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h index 0833143563..3a688a483e 100644 --- a/pimd/pim_rpf.h +++ b/pimd/pim_rpf.h @@ -58,6 +58,9 @@ struct pim_upstream; extern long long nexthop_lookups_avoided; +unsigned int pim_rpf_hash_key(void *arg); +int pim_rpf_equal(const void *arg1, const void *arg2); + int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed); enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old, diff --git a/pimd/pimd.c b/pimd/pimd.c index b687a943a8..164dafe5f7 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -31,19 +31,15 @@ #include "pimd.h" #include "pim_cmd.h" -#include "pim_iface.h" -#include "pim_zebra.h" #include "pim_str.h" #include "pim_oil.h" #include "pim_pim.h" -#include "pim_upstream.h" -#include "pim_rpf.h" #include "pim_ssmpingd.h" #include "pim_static.h" #include "pim_rp.h" #include "pim_ssm.h" #include "pim_zlookup.h" -#include "pim_nht.h" +#include "pim_zebra.h" const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS; const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS; @@ -76,93 +72,6 @@ struct pim_instance *pimg = NULL; int32_t qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT; int32_t qpim_register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT; -static struct pim_instance *pim_instance_init(struct vrf *vrf); -static void pim_instance_terminate(struct pim_instance *pim); - -static int pim_vrf_new(struct vrf *vrf) -{ - zlog_debug("VRF Created: %s(%d)", vrf->name, vrf->vrf_id); - return 0; -} - -static int pim_vrf_delete(struct vrf *vrf) -{ - zlog_debug("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id); - return 0; -} - -static int pim_vrf_enable(struct vrf *vrf) -{ - struct pim_instance *pim; - - zlog_debug("%s: for %s", __PRETTY_FUNCTION__, vrf->name); - pim = pim_instance_init(vrf); - if (pim == NULL) { - zlog_err("%s %s: pim class init failure ", __FILE__, - __PRETTY_FUNCTION__); - /* - * We will crash and burn otherwise - */ - exit(1); - } - - vrf->info = (void *)pim; - - if (vrf->vrf_id == VRF_DEFAULT) - pimg = pim; - - return 0; -} - -static int pim_vrf_disable(struct vrf *vrf) -{ - pim_instance_terminate((struct pim_instance *)vrf->info); - - /* Note: This is a callback, the VRF will be deleted by the caller. */ - return 0; -} - -void pim_vrf_init(void) -{ - vrf_init(pim_vrf_new, pim_vrf_enable, pim_vrf_disable, pim_vrf_delete); -} - -static void pim_vrf_terminate(void) -{ - vrf_terminate(); -} - -/* Key generate for pim->rpf_hash */ -static unsigned int pim_rpf_hash_key(void *arg) -{ - struct pim_nexthop_cache *r = (struct pim_nexthop_cache *)arg; - - return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0); -} - -/* Compare pim->rpf_hash node data */ -static int pim_rpf_equal(const void *arg1, const void *arg2) -{ - const struct pim_nexthop_cache *r1 = - (const struct pim_nexthop_cache *)arg1; - const struct pim_nexthop_cache *r2 = - (const struct pim_nexthop_cache *)arg2; - - return prefix_same(&r1->rpf.rpf_addr, &r2->rpf.rpf_addr); -} - -/* Cleanup pim->rpf_hash each node data */ -static void pim_rp_list_hash_clean(void *data) -{ - struct pim_nexthop_cache *pnc; - - pnc = (struct pim_nexthop_cache *)data; - if (pnc->rp_list->count) - list_delete_all_node(pnc->rp_list); - if (pnc->upstream_list->count) - list_delete_all_node(pnc->upstream_list); -} - void pim_prefix_list_update(struct prefix_list *plist) { pim_rp_prefix_list_update(plist); @@ -170,33 +79,6 @@ void pim_prefix_list_update(struct prefix_list *plist) pim_upstream_spt_prefix_list_update(plist); } -struct pim_instance *pim_get_pim_instance(vrf_id_t vrf_id) -{ - struct vrf *vrf = vrf_lookup_by_id(vrf_id); - - if (vrf) - return vrf->info; - - return NULL; -} - -static void pim_instance_terminate(struct pim_instance *pim) -{ - /* Traverse and cleanup rpf_hash */ - if (pim->rpf_hash) { - hash_clean(pim->rpf_hash, (void *)pim_rp_list_hash_clean); - hash_free(pim->rpf_hash); - pim->rpf_hash = NULL; - } - - if (pim->ssm_info) { - pim_ssm_terminate(pim->ssm_info); - pim->ssm_info = NULL; - } - - XFREE(MTYPE_PIM_PIM_INSTANCE, pimg); -} - static void pim_free() { pim_ssmpingd_destroy(); @@ -218,42 +100,6 @@ static void pim_free() zprivs_terminate(&pimd_privs); } -static struct pim_instance *pim_instance_init(struct vrf *vrf) -{ - struct pim_instance *pim; - - pim = XCALLOC(MTYPE_PIM_PIM_INSTANCE, sizeof(struct pim_instance)); - if (!pim) - return NULL; - - pim->vrf_id = vrf->vrf_id; - pim->vrf = vrf; - - pim->spt.switchover = PIM_SPT_IMMEDIATE; - pim->spt.plist = NULL; - - pim->rpf_hash = - hash_create_size(256, pim_rpf_hash_key, pim_rpf_equal, NULL); - - if (PIM_DEBUG_ZEBRA) - zlog_debug("%s: NHT rpf hash init ", __PRETTY_FUNCTION__); - - pim->ssm_info = pim_ssm_init(); - if (!pim->ssm_info) { - pim_instance_terminate(pim); - return NULL; - } - - pim->send_v6_secondary = 1; - - if (vrf->vrf_id == VRF_DEFAULT) - pimg = pim; - - pim_mroute_socket_enable(pim); - - return pim; -} - void pim_init() { qpim_rp_keep_alive_time = PIM_RP_KEEPALIVE_PERIOD; diff --git a/pimd/pimd.h b/pimd/pimd.h index 57be41154b..7cce15f241 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -27,6 +27,7 @@ #include "vty.h" #include "plist.h" +#include "pim_instance.h" #include "pim_str.h" #include "pim_memory.h" #include "pim_assert.h" @@ -230,48 +231,11 @@ extern int32_t qpim_register_probe_time; #define PIM_DONT_DEBUG_MSDP_PACKETS (qpim_debugs &= ~PIM_MASK_MSDP_PACKETS) #define PIM_DONT_DEBUG_MSDP_INTERNAL (qpim_debugs &= ~PIM_MASK_MSDP_INTERNAL) -enum pim_spt_switchover { - PIM_SPT_IMMEDIATE, - PIM_SPT_INFINITY, -}; - -/* Per VRF PIM DB */ -struct pim_instance { - vrf_id_t vrf_id; - struct vrf *vrf; - - struct { - enum pim_spt_switchover switchover; - char *plist; - } spt; - - struct hash *rpf_hash; - - void *ssm_info; /* per-vrf SSM configuration */ - - int send_v6_secondary; - - struct thread *thread; - int mroute_socket; - int64_t mroute_socket_creation; - int64_t mroute_add_events; - int64_t mroute_add_last; - int64_t mroute_del_events; - int64_t mroute_del_last; - - struct interface *regiface; -}; - -extern struct pim_instance *pimg; // Pim Global Instance - void pim_init(void); void pim_terminate(void); extern void pim_route_map_init(void); extern void pim_route_map_terminate(void); -void pim_vrf_init(void); void pim_prefix_list_update(struct prefix_list *plist); -struct pim_instance *pim_get_pim_instance(vrf_id_t vrf_id); - #endif /* PIMD_H */