]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Create channel_oil hash for quicker lookup
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 13 Oct 2016 12:34:48 +0000 (08:34 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:11 +0000 (20:26 -0500)
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>
pimd/pim_cmd.c
pimd/pim_oil.c
pimd/pim_oil.h
pimd/pim_upstream.c
pimd/pim_zebra.c
pimd/pimd.c
pimd/pimd.h

index a12a7a230ef735be8d9cb74a3dc5632bba0def13..5ea8887faf0c1114df8ebd44f6c4cf16c4814c49 100644 (file)
@@ -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);
   }
 
-  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 src_str[100];
     char in_ifname[16];
@@ -2232,7 +2232,7 @@ static void mroute_add_all()
   struct listnode    *node;
   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)) {
       /* just log warning */
       char source_str[100];
@@ -2251,7 +2251,7 @@ static void mroute_del_all()
   struct listnode    *node;
   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)) {
       /* just log warning */
       char source_str[100];
@@ -2829,7 +2829,7 @@ static void show_mroute(struct vty *vty, u_char uj)
   now = pim_time_monotonic_sec();
 
   /* 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 src_str[100];
     char in_ifname[16];
@@ -3110,7 +3110,7 @@ static void show_mroute_count(struct vty *vty)
          VTY_NEWLINE);
 
   /* 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 source_str[100];
 
index 9728d6304f9ae6316e1dd67c53658034e9042e1f..7fe4d8af323feb2b268c22063fd1943e5c8a7b1d 100644 (file)
@@ -25,6 +25,8 @@
 #include "memory.h"
 #include "linklist.h"
 #include "if.h"
+#include "hash.h"
+#include "jhash.h"
 
 #include "pimd.h"
 #include "pim_oil.h"
 #include "pim_iface.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)
 {
   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
     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);
 }
@@ -73,27 +145,28 @@ pim_add_channel_oil (struct prefix_sg *sg,
 
   c_oil->oil.mfcc_mcastgrp = sg->grp;
   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_ref_count     = 1;
   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;
 }
 
 static struct channel_oil *pim_find_channel_oil(struct prefix_sg *sg)
 {
-  struct listnode    *node;
-  struct channel_oil *c_oil;
+  struct channel_oil *c_oil = NULL;
+  struct channel_oil 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 0;
+  lookup.oil.mfcc_mcastgrp = sg->grp;
+  lookup.oil.mfcc_origin   = sg->src;
+
+  c_oil = hash_lookup (pim_channel_oil_hash, &lookup);
+
+  return c_oil;
 }
 
 struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
index 4b23b211a9c4a6097fd9013a5a351542bbdf5569..0c99afb62533a8359b43cf876118dbf855ec4cdf 100644 (file)
@@ -78,6 +78,11 @@ struct channel_oil {
   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);
 struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
                                        int input_vif_index);
index 88755ec9fd1f5156882a061c2394cd58abd755fc..a7e40da9482c834b76a00e23d8d41f4d01a0c68f 100644 (file)
@@ -1184,7 +1184,8 @@ pim_upstream_equal (const void *arg1, const void *arg2)
   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_equal);
index 6115bcbf6e8d3e92fd887e917cdc09562f4781a0..cd0dd5c4520e0cd21edd8b440409b2723fb03b16 100644 (file)
@@ -519,7 +519,7 @@ void pim_scan_oil()
   qpim_scan_oil_last = pim_time_monotonic_sec();
   ++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);
 }
 
index 82ecdc9fc5750f6fef16de60e0bdd80de1d1cf94..1608f2d07e448f51df81390d65dccfcc1b4c271f 100644 (file)
@@ -52,7 +52,6 @@ int                       qpim_mroute_socket_fd = -1;
 int64_t                   qpim_mroute_socket_creation = 0; /* timestamp of creation */
 struct thread            *qpim_mroute_socket_reader = NULL;
 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 */
 struct zclient           *qpim_zclient_update = NULL;
 struct pim_assert_metric  qpim_infinite_assert_metric;
@@ -82,8 +81,7 @@ static void pim_free()
 {
   pim_ssmpingd_destroy();
 
-  if (qpim_channel_oil_list)
-    list_free(qpim_channel_oil_list);
+  pim_oil_terminate ();
 
   pim_upstream_terminate ();
 
@@ -96,24 +94,6 @@ static void pim_free()
   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()
 {
   srandom(time(NULL));
@@ -130,14 +110,7 @@ void pim_init()
     return;
   }
 
-  qpim_channel_oil_list = list_new();
-  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_oil_init ();
 
   pim_upstream_init ();
 
index f435072325821a359ff9147f9787c7e4fe094315..fb9cb14ca1bdb24d35b6366aaac6101724ecc978 100644 (file)
@@ -94,7 +94,6 @@ int                       qpim_mroute_socket_fd;
 int64_t                   qpim_mroute_socket_creation; /* timestamp of creation */
 struct thread            *qpim_mroute_socket_reader;
 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;
 int                       qpim_t_periodic; /* Period between Join/Prune Messages */
 struct zclient           *qpim_zclient_update;