mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 16:52:25 +00:00
pimd: Create channel_oil hash for quicker lookup
When looking up the channel_oil use a hash to find it. Keep the list around for quick walks of the channel oils. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
0f58898971
commit
040d86ade7
@ -1311,7 +1311,7 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
|
|||||||
vty_out(vty, "%sSource Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE);
|
vty_out(vty, "%sSource Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
|
for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
|
||||||
char grp_str[100];
|
char grp_str[100];
|
||||||
char src_str[100];
|
char src_str[100];
|
||||||
char in_ifname[16];
|
char in_ifname[16];
|
||||||
@ -2232,7 +2232,7 @@ static void mroute_add_all()
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct channel_oil *c_oil;
|
struct channel_oil *c_oil;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
|
for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
|
||||||
if (pim_mroute_add(c_oil)) {
|
if (pim_mroute_add(c_oil)) {
|
||||||
/* just log warning */
|
/* just log warning */
|
||||||
char source_str[100];
|
char source_str[100];
|
||||||
@ -2251,7 +2251,7 @@ static void mroute_del_all()
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct channel_oil *c_oil;
|
struct channel_oil *c_oil;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
|
for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
|
||||||
if (pim_mroute_del(c_oil)) {
|
if (pim_mroute_del(c_oil)) {
|
||||||
/* just log warning */
|
/* just log warning */
|
||||||
char source_str[100];
|
char source_str[100];
|
||||||
@ -2829,7 +2829,7 @@ static void show_mroute(struct vty *vty, u_char uj)
|
|||||||
now = pim_time_monotonic_sec();
|
now = pim_time_monotonic_sec();
|
||||||
|
|
||||||
/* print list of PIM and IGMP routes */
|
/* print list of PIM and IGMP routes */
|
||||||
for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
|
for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
|
||||||
char grp_str[100];
|
char grp_str[100];
|
||||||
char src_str[100];
|
char src_str[100];
|
||||||
char in_ifname[16];
|
char in_ifname[16];
|
||||||
@ -3110,7 +3110,7 @@ static void show_mroute_count(struct vty *vty)
|
|||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
|
|
||||||
/* Print PIM and IGMP route counts */
|
/* Print PIM and IGMP route counts */
|
||||||
for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
|
for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
|
||||||
char group_str[100];
|
char group_str[100];
|
||||||
char source_str[100];
|
char source_str[100];
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "if.h"
|
#include "if.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "jhash.h"
|
||||||
|
|
||||||
#include "pimd.h"
|
#include "pimd.h"
|
||||||
#include "pim_oil.h"
|
#include "pim_oil.h"
|
||||||
@ -32,6 +34,75 @@
|
|||||||
#include "pim_iface.h"
|
#include "pim_iface.h"
|
||||||
#include "pim_time.h"
|
#include "pim_time.h"
|
||||||
|
|
||||||
|
struct list *pim_channel_oil_list = NULL;
|
||||||
|
struct hash *pim_channel_oil_hash = NULL;
|
||||||
|
|
||||||
|
static int
|
||||||
|
pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2)
|
||||||
|
{
|
||||||
|
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) < ntohl(c2->oil.mfcc_mcastgrp.s_addr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) > ntohl(c2->oil.mfcc_mcastgrp.s_addr))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (ntohl(c1->oil.mfcc_origin.s_addr) < ntohl(c2->oil.mfcc_origin.s_addr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ntohl(c1->oil.mfcc_origin.s_addr) > ntohl(c2->oil.mfcc_origin.s_addr))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pim_oil_equal (const void *arg1, const void *arg2)
|
||||||
|
{
|
||||||
|
const struct channel_oil *c1 = (const struct channel_oil *)arg1;
|
||||||
|
const struct channel_oil *c2 = (const struct channel_oil *)arg2;
|
||||||
|
|
||||||
|
if ((c1->oil.mfcc_mcastgrp.s_addr == c2->oil.mfcc_mcastgrp.s_addr) &&
|
||||||
|
(c2->oil.mfcc_origin.s_addr == c2->oil.mfcc_origin.s_addr))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
pim_oil_hash_key (void *arg)
|
||||||
|
{
|
||||||
|
struct channel_oil *oil = (struct channel_oil *)arg;
|
||||||
|
|
||||||
|
return jhash_2words (oil->oil.mfcc_mcastgrp.s_addr, oil->oil.mfcc_origin.s_addr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pim_oil_init (void)
|
||||||
|
{
|
||||||
|
pim_channel_oil_hash = hash_create_size (8192, pim_oil_hash_key,
|
||||||
|
pim_oil_equal);
|
||||||
|
|
||||||
|
pim_channel_oil_list = list_new();
|
||||||
|
if (!pim_channel_oil_list) {
|
||||||
|
zlog_err("%s %s: failure: channel_oil_list=list_new()",
|
||||||
|
__FILE__, __PRETTY_FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pim_channel_oil_list->del = (void (*)(void *)) pim_channel_oil_free;
|
||||||
|
pim_channel_oil_list->cmp = (int (*)(void *, void *)) pim_channel_oil_compare;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pim_oil_terminate (void)
|
||||||
|
{
|
||||||
|
if (pim_channel_oil_list)
|
||||||
|
list_free(pim_channel_oil_list);
|
||||||
|
pim_channel_oil_list = NULL;
|
||||||
|
|
||||||
|
if (pim_channel_oil_hash)
|
||||||
|
hash_free (pim_upstream_hash);
|
||||||
|
}
|
||||||
|
|
||||||
void pim_channel_oil_free(struct channel_oil *c_oil)
|
void pim_channel_oil_free(struct channel_oil *c_oil)
|
||||||
{
|
{
|
||||||
XFREE(MTYPE_PIM_CHANNEL_OIL, c_oil);
|
XFREE(MTYPE_PIM_CHANNEL_OIL, c_oil);
|
||||||
@ -45,7 +116,8 @@ pim_del_channel_oil (struct channel_oil *c_oil)
|
|||||||
into pim_channel_oil_free() because the later is
|
into pim_channel_oil_free() because the later is
|
||||||
called by list_delete_all_node()
|
called by list_delete_all_node()
|
||||||
*/
|
*/
|
||||||
listnode_delete(qpim_channel_oil_list, c_oil);
|
listnode_delete(pim_channel_oil_list, c_oil);
|
||||||
|
hash_release (pim_channel_oil_hash, c_oil);
|
||||||
|
|
||||||
pim_channel_oil_free(c_oil);
|
pim_channel_oil_free(c_oil);
|
||||||
}
|
}
|
||||||
@ -73,29 +145,30 @@ pim_add_channel_oil (struct prefix_sg *sg,
|
|||||||
|
|
||||||
c_oil->oil.mfcc_mcastgrp = sg->grp;
|
c_oil->oil.mfcc_mcastgrp = sg->grp;
|
||||||
c_oil->oil.mfcc_origin = sg->src;
|
c_oil->oil.mfcc_origin = sg->src;
|
||||||
|
c_oil = hash_get (pim_channel_oil_hash, c_oil, hash_alloc_intern);
|
||||||
|
|
||||||
c_oil->oil.mfcc_parent = input_vif_index;
|
c_oil->oil.mfcc_parent = input_vif_index;
|
||||||
c_oil->oil_ref_count = 1;
|
c_oil->oil_ref_count = 1;
|
||||||
c_oil->installed = 0;
|
c_oil->installed = 0;
|
||||||
|
|
||||||
listnode_add_sort(qpim_channel_oil_list, c_oil);
|
listnode_add_sort(pim_channel_oil_list, c_oil);
|
||||||
|
|
||||||
return c_oil;
|
return c_oil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct channel_oil *pim_find_channel_oil(struct prefix_sg *sg)
|
static struct channel_oil *pim_find_channel_oil(struct prefix_sg *sg)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct channel_oil *c_oil = NULL;
|
||||||
struct channel_oil *c_oil;
|
struct channel_oil lookup;
|
||||||
|
|
||||||
|
lookup.oil.mfcc_mcastgrp = sg->grp;
|
||||||
|
lookup.oil.mfcc_origin = sg->src;
|
||||||
|
|
||||||
|
c_oil = hash_lookup (pim_channel_oil_hash, &lookup);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
|
|
||||||
if ((sg->grp.s_addr == c_oil->oil.mfcc_mcastgrp.s_addr) &&
|
|
||||||
(sg->src.s_addr == c_oil->oil.mfcc_origin.s_addr))
|
|
||||||
return c_oil;
|
return c_oil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
|
struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
|
||||||
int input_vif_index)
|
int input_vif_index)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,11 @@ struct channel_oil {
|
|||||||
struct channel_counts cc;
|
struct channel_counts cc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct list *pim_channel_oil_list;
|
||||||
|
|
||||||
|
void pim_oil_init (void);
|
||||||
|
void pim_oil_terminate (void);
|
||||||
|
|
||||||
void pim_channel_oil_free(struct channel_oil *c_oil);
|
void pim_channel_oil_free(struct channel_oil *c_oil);
|
||||||
struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
|
struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
|
||||||
int input_vif_index);
|
int input_vif_index);
|
||||||
|
@ -1184,7 +1184,8 @@ pim_upstream_equal (const void *arg1, const void *arg2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pim_upstream_init (void)
|
void
|
||||||
|
pim_upstream_init (void)
|
||||||
{
|
{
|
||||||
pim_upstream_hash = hash_create_size (8192, pim_upstream_hash_key,
|
pim_upstream_hash = hash_create_size (8192, pim_upstream_hash_key,
|
||||||
pim_upstream_equal);
|
pim_upstream_equal);
|
||||||
|
@ -519,7 +519,7 @@ void pim_scan_oil()
|
|||||||
qpim_scan_oil_last = pim_time_monotonic_sec();
|
qpim_scan_oil_last = pim_time_monotonic_sec();
|
||||||
++qpim_scan_oil_events;
|
++qpim_scan_oil_events;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(qpim_channel_oil_list, node, nextnode, c_oil))
|
for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil))
|
||||||
pim_scan_individual_oil (c_oil);
|
pim_scan_individual_oil (c_oil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
pimd/pimd.c
31
pimd/pimd.c
@ -52,7 +52,6 @@ int qpim_mroute_socket_fd = -1;
|
|||||||
int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */
|
int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */
|
||||||
struct thread *qpim_mroute_socket_reader = NULL;
|
struct thread *qpim_mroute_socket_reader = NULL;
|
||||||
int qpim_mroute_oif_highest_vif_index = -1;
|
int qpim_mroute_oif_highest_vif_index = -1;
|
||||||
struct list *qpim_channel_oil_list = NULL;
|
|
||||||
int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
|
int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
|
||||||
struct zclient *qpim_zclient_update = NULL;
|
struct zclient *qpim_zclient_update = NULL;
|
||||||
struct pim_assert_metric qpim_infinite_assert_metric;
|
struct pim_assert_metric qpim_infinite_assert_metric;
|
||||||
@ -82,8 +81,7 @@ static void pim_free()
|
|||||||
{
|
{
|
||||||
pim_ssmpingd_destroy();
|
pim_ssmpingd_destroy();
|
||||||
|
|
||||||
if (qpim_channel_oil_list)
|
pim_oil_terminate ();
|
||||||
list_free(qpim_channel_oil_list);
|
|
||||||
|
|
||||||
pim_upstream_terminate ();
|
pim_upstream_terminate ();
|
||||||
|
|
||||||
@ -96,24 +94,6 @@ static void pim_free()
|
|||||||
pim_route_map_terminate();
|
pim_route_map_terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2)
|
|
||||||
{
|
|
||||||
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) < ntohl(c2->oil.mfcc_mcastgrp.s_addr))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) > ntohl(c2->oil.mfcc_mcastgrp.s_addr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (ntohl(c1->oil.mfcc_origin.s_addr) < ntohl(c2->oil.mfcc_origin.s_addr))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ntohl(c1->oil.mfcc_origin.s_addr) > ntohl(c2->oil.mfcc_origin.s_addr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pim_init()
|
void pim_init()
|
||||||
{
|
{
|
||||||
srandom(time(NULL));
|
srandom(time(NULL));
|
||||||
@ -130,14 +110,7 @@ void pim_init()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpim_channel_oil_list = list_new();
|
pim_oil_init ();
|
||||||
if (!qpim_channel_oil_list) {
|
|
||||||
zlog_err("%s %s: failure: channel_oil_list=list_new()",
|
|
||||||
__FILE__, __PRETTY_FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qpim_channel_oil_list->del = (void (*)(void *)) pim_channel_oil_free;
|
|
||||||
qpim_channel_oil_list->cmp = (int (*)(void *, void *)) pim_channel_oil_compare;
|
|
||||||
|
|
||||||
pim_upstream_init ();
|
pim_upstream_init ();
|
||||||
|
|
||||||
|
@ -94,7 +94,6 @@ int qpim_mroute_socket_fd;
|
|||||||
int64_t qpim_mroute_socket_creation; /* timestamp of creation */
|
int64_t qpim_mroute_socket_creation; /* timestamp of creation */
|
||||||
struct thread *qpim_mroute_socket_reader;
|
struct thread *qpim_mroute_socket_reader;
|
||||||
int qpim_mroute_oif_highest_vif_index;
|
int qpim_mroute_oif_highest_vif_index;
|
||||||
struct list *qpim_channel_oil_list; /* list of struct channel_oil */
|
|
||||||
struct in_addr qpim_all_pim_routers_addr;
|
struct in_addr qpim_all_pim_routers_addr;
|
||||||
int qpim_t_periodic; /* Period between Join/Prune Messages */
|
int qpim_t_periodic; /* Period between Join/Prune Messages */
|
||||||
struct zclient *qpim_zclient_update;
|
struct zclient *qpim_zclient_update;
|
||||||
|
Loading…
Reference in New Issue
Block a user