]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Store ifchannel information in a global list too.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 7 Nov 2016 17:34:44 +0000 (12:34 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:14 +0000 (20:26 -0500)
This fix handles two issues:

1) Searching entire vrf_iflist to get per interface pim_ifchannel_list
2) Display of ifchannel information in pim not being ordered correctly.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_cmd.c
pimd/pim_iface.c
pimd/pim_iface.h
pimd/pim_ifchannel.c
pimd/pim_upstream.c
pimd/pimd.c

index 6eb14a140d26cca85157e27d1b58b75b61b5f75d..52d1157f26aebe31ea7793c77c14fb990dc7622c 100644 (file)
@@ -161,9 +161,11 @@ static void pim_if_membership_refresh(struct interface *ifp)
 
 static void pim_show_assert(struct vty *vty)
 {
-  struct listnode  *ifnode;
-  struct interface *ifp;
-  time_t            now;
+  struct pim_interface *pim_ifp;
+  struct pim_ifchannel *ch;
+  struct listnode *ch_node;
+  struct in_addr ifaddr;
+  time_t now;
   
   now = pim_time_monotonic_sec();
 
@@ -171,55 +173,50 @@ static void pim_show_assert(struct vty *vty)
          "Interface Address         Source          Group           State  Winner          Uptime   Timer%s",
          VTY_NEWLINE);
 
-  for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
-    struct pim_interface *pim_ifp;
-    struct in_addr ifaddr;
-    struct listnode *ch_node;
-    struct pim_ifchannel *ch;
+  for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+    char ch_src_str[INET_ADDRSTRLEN];
+    char ch_grp_str[INET_ADDRSTRLEN];
+    char winner_str[INET_ADDRSTRLEN];
+    char uptime[10];
+    char timer[10];
 
-    pim_ifp = ifp->info;
+    pim_ifp = ch->interface->info;
     
     if (!pim_ifp)
       continue;
 
     ifaddr = pim_ifp->primary_address;
 
-    for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
-      char ch_src_str[INET_ADDRSTRLEN];
-      char ch_grp_str[INET_ADDRSTRLEN];
-      char winner_str[INET_ADDRSTRLEN];
-      char uptime[10];
-      char timer[10];
-
-      pim_inet4_dump("<ch_src?>", ch->sg.src,
-                    ch_src_str, sizeof(ch_src_str));
-      pim_inet4_dump("<ch_grp?>", ch->sg.grp,
-                    ch_grp_str, sizeof(ch_grp_str));
-      pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
-                    winner_str, sizeof(winner_str));
+    pim_inet4_dump("<ch_src?>", ch->sg.src,
+                  ch_src_str, sizeof(ch_src_str));
+    pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+                  ch_grp_str, sizeof(ch_grp_str));
+    pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
+                  winner_str, sizeof(winner_str));
 
-      pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
-      pim_time_timer_to_mmss(timer, sizeof(timer),
-                            ch->t_ifassert_timer);
+    pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
+    pim_time_timer_to_mmss(timer, sizeof(timer),
+                          ch->t_ifassert_timer);
 
-      vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
-             ifp->name,
-             inet_ntoa(ifaddr),
-             ch_src_str,
-             ch_grp_str,
-             pim_ifchannel_ifassert_name(ch->ifassert_state),
-             winner_str,
-             uptime,
-             timer,
-             VTY_NEWLINE);
-    } /* scan interface channels */
-  } /* scan interfaces */
+    vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
+           ch->interface->name,
+           inet_ntoa(ifaddr),
+           ch_src_str,
+           ch_grp_str,
+           pim_ifchannel_ifassert_name(ch->ifassert_state),
+           winner_str,
+           uptime,
+           timer,
+           VTY_NEWLINE);
+  } /* scan interface channels */
 }
 
 static void pim_show_assert_internal(struct vty *vty)
 {
-  struct listnode  *ifnode;
-  struct interface *ifp;
+  struct pim_interface *pim_ifp;
+  struct listnode *ch_node;
+  struct pim_ifchannel *ch;
+  struct in_addr ifaddr;
 
   vty_out(vty,
          "CA:   CouldAssert%s"
@@ -232,153 +229,136 @@ static void pim_show_assert_internal(struct vty *vty)
          "Interface Address         Source          Group           CA  eCA ATD eATD%s",
          VTY_NEWLINE);
 
-  for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
-    struct pim_interface *pim_ifp;
-    struct in_addr ifaddr;
-    struct listnode *ch_node;
-    struct pim_ifchannel *ch;
-
-    pim_ifp = ifp->info;
+  for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+    pim_ifp = ch->interface->info;
     
     if (!pim_ifp)
       continue;
 
     ifaddr = pim_ifp->primary_address;
 
-    for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
-      char ch_src_str[INET_ADDRSTRLEN];
-      char ch_grp_str[INET_ADDRSTRLEN];
+    char ch_src_str[INET_ADDRSTRLEN];
+    char ch_grp_str[INET_ADDRSTRLEN];
 
-      pim_inet4_dump("<ch_src?>", ch->sg.src,
-                    ch_src_str, sizeof(ch_src_str));
-      pim_inet4_dump("<ch_grp?>", ch->sg.grp,
-                    ch_grp_str, sizeof(ch_grp_str));
-      vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
-             ifp->name,
-             inet_ntoa(ifaddr),
-             ch_src_str,
-             ch_grp_str,
-             PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
-             pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
-             PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
-             pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
-             VTY_NEWLINE);
-    } /* scan interface channels */
-  } /* scan interfaces */
+    pim_inet4_dump("<ch_src?>", ch->sg.src,
+                  ch_src_str, sizeof(ch_src_str));
+    pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+                  ch_grp_str, sizeof(ch_grp_str));
+    vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
+           ch->interface->name,
+           inet_ntoa(ifaddr),
+           ch_src_str,
+           ch_grp_str,
+           PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
+           pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
+           PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
+           pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
+           VTY_NEWLINE);
+  } /* scan interface channels */
 }
 
 static void pim_show_assert_metric(struct vty *vty)
 {
-  struct listnode  *ifnode;
-  struct interface *ifp;
-  
+  struct pim_interface *pim_ifp;
+  struct listnode *ch_node;
+  struct pim_ifchannel *ch;
+  struct in_addr ifaddr;
+
   vty_out(vty,
          "Interface Address         Source          Group           RPT Pref Metric Address        %s",
          VTY_NEWLINE);
 
-  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
-    struct pim_interface *pim_ifp;
-    struct in_addr ifaddr;
-    struct listnode *ch_node;
-    struct pim_ifchannel *ch;
+  for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+    pim_ifp = ch->interface->info;
 
-    pim_ifp = ifp->info;
-    
     if (!pim_ifp)
       continue;
 
     ifaddr = pim_ifp->primary_address;
 
-    for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
-      char ch_src_str[INET_ADDRSTRLEN];
-      char ch_grp_str[INET_ADDRSTRLEN];
-      char addr_str[INET_ADDRSTRLEN];
-      struct pim_assert_metric am;
+    char ch_src_str[INET_ADDRSTRLEN];
+    char ch_grp_str[INET_ADDRSTRLEN];
+    char addr_str[INET_ADDRSTRLEN];
+    struct pim_assert_metric am;
 
-      am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
+    am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
 
-      pim_inet4_dump("<ch_src?>", ch->sg.src,
-                    ch_src_str, sizeof(ch_src_str));
-      pim_inet4_dump("<ch_grp?>", ch->sg.grp,
-                    ch_grp_str, sizeof(ch_grp_str));
-      pim_inet4_dump("<addr?>", am.ip_address,
-                    addr_str, sizeof(addr_str));
+    pim_inet4_dump("<ch_src?>", ch->sg.src,
+                  ch_src_str, sizeof(ch_src_str));
+    pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+                  ch_grp_str, sizeof(ch_grp_str));
+    pim_inet4_dump("<addr?>", am.ip_address,
+                  addr_str, sizeof(addr_str));
 
-      vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
-             ifp->name,
-             inet_ntoa(ifaddr),
-             ch_src_str,
-             ch_grp_str,
-             am.rpt_bit_flag ? "yes" : "no",
-             am.metric_preference,
-             am.route_metric,
-             addr_str,
-             VTY_NEWLINE);
+    vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
+           ch->interface->name,
+           inet_ntoa(ifaddr),
+           ch_src_str,
+           ch_grp_str,
+           am.rpt_bit_flag ? "yes" : "no",
+           am.metric_preference,
+           am.route_metric,
+           addr_str,
+           VTY_NEWLINE);
     } /* scan interface channels */
-  } /* scan interfaces */
 }
 
 static void pim_show_assert_winner_metric(struct vty *vty)
 {
-  struct listnode  *ifnode;
-  struct interface *ifp;
+  struct pim_interface *pim_ifp;
+  struct listnode *ch_node;
+  struct pim_ifchannel *ch;
+  struct in_addr ifaddr;
   
   vty_out(vty,
          "Interface Address         Source          Group           RPT Pref Metric Address        %s",
          VTY_NEWLINE);
 
-  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
-    struct pim_interface *pim_ifp;
-    struct in_addr ifaddr;
-    struct listnode *ch_node;
-    struct pim_ifchannel *ch;
-
-    pim_ifp = ifp->info;
+  for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+    pim_ifp = ch->interface->info;
     
     if (!pim_ifp)
       continue;
 
     ifaddr = pim_ifp->primary_address;
 
-    for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
-      char ch_src_str[INET_ADDRSTRLEN];
-      char ch_grp_str[INET_ADDRSTRLEN];
-      char addr_str[INET_ADDRSTRLEN];
-      struct pim_assert_metric *am;
-      char pref_str[5];
-      char metr_str[7];
-
-      am = &ch->ifassert_winner_metric;
-
-      pim_inet4_dump("<ch_src?>", ch->sg.src,
-                    ch_src_str, sizeof(ch_src_str));
-      pim_inet4_dump("<ch_grp?>", ch->sg.grp,
-                    ch_grp_str, sizeof(ch_grp_str));
-      pim_inet4_dump("<addr?>", am->ip_address,
-                    addr_str, sizeof(addr_str));
-
-      if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
-       snprintf(pref_str, sizeof(pref_str), "INFI");
-      else
-       snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
+    char ch_src_str[INET_ADDRSTRLEN];
+    char ch_grp_str[INET_ADDRSTRLEN];
+    char addr_str[INET_ADDRSTRLEN];
+    struct pim_assert_metric *am;
+    char pref_str[5];
+    char metr_str[7];
 
-      if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
-       snprintf(metr_str, sizeof(metr_str), "INFI");
-      else
-       snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
+    am = &ch->ifassert_winner_metric;
 
-      vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
-             ifp->name,
-             inet_ntoa(ifaddr),
-             ch_src_str,
-             ch_grp_str,
-             am->rpt_bit_flag ? "yes" : "no",
-             pref_str,
-             metr_str,
-             addr_str,
-             VTY_NEWLINE);
-    } /* scan interface channels */
-  } /* scan interfaces */
+    pim_inet4_dump("<ch_src?>", ch->sg.src,
+                  ch_src_str, sizeof(ch_src_str));
+    pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+                  ch_grp_str, sizeof(ch_grp_str));
+    pim_inet4_dump("<addr?>", am->ip_address,
+                  addr_str, sizeof(addr_str));
+
+    if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
+      snprintf(pref_str, sizeof(pref_str), "INFI");
+    else
+      snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
+
+    if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
+      snprintf(metr_str, sizeof(metr_str), "INFI");
+    else
+      snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
+
+    vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
+           ch->interface->name,
+           inet_ntoa(ifaddr),
+           ch_src_str,
+           ch_grp_str,
+           am->rpt_bit_flag ? "yes" : "no",
+           pref_str,
+           metr_str,
+           addr_str,
+           VTY_NEWLINE);
+  } /* scan interface channels */
 }
 
 static void json_object_pim_ifp_add(struct json_object *json, struct interface *ifp)
@@ -412,8 +392,9 @@ static void json_object_pim_ifp_add(struct json_object *json, struct interface *
 
 static void pim_show_membership(struct vty *vty, u_char uj)
 {
-  struct listnode  *ifnode;
-  struct interface *ifp;
+  struct pim_interface *pim_ifp;
+  struct listnode *ch_node;
+  struct pim_ifchannel *ch;
   enum json_type type;
   json_object *json = NULL;
   json_object *json_iface = NULL;
@@ -422,41 +403,36 @@ static void pim_show_membership(struct vty *vty, u_char uj)
 
   json = json_object_new_object();
 
-  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
-    struct pim_interface *pim_ifp;
-    struct listnode *ch_node;
-    struct pim_ifchannel *ch;
+  for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
 
-    pim_ifp = ifp->info;
+    pim_ifp = ch->interface->info;
 
     if (!pim_ifp)
       continue;
 
-    for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
-      char ch_src_str[INET_ADDRSTRLEN];
-      char ch_grp_str[INET_ADDRSTRLEN];
+    char ch_src_str[INET_ADDRSTRLEN];
+    char ch_grp_str[INET_ADDRSTRLEN];
 
-      pim_inet4_dump("<ch_src?>", ch->sg.src,
-                    ch_src_str, sizeof(ch_src_str));
-      pim_inet4_dump("<ch_grp?>", ch->sg.grp,
-                    ch_grp_str, sizeof(ch_grp_str));
+    pim_inet4_dump("<ch_src?>", ch->sg.src,
+                  ch_src_str, sizeof(ch_src_str));
+    pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+                  ch_grp_str, sizeof(ch_grp_str));
 
-      json_object_object_get_ex(json, ifp->name, &json_iface);
+    json_object_object_get_ex(json, ch->interface->name, &json_iface);
 
-      if (!json_iface) {
-        json_iface = json_object_new_object();
-        json_object_pim_ifp_add(json_iface, ifp);
-        json_object_object_add(json, ifp->name, json_iface);
-      }
+    if (!json_iface) {
+      json_iface = json_object_new_object();
+      json_object_pim_ifp_add(json_iface, ch->interface);
+      json_object_object_add(json, ch->interface->name, json_iface);
+    }
 
-      json_row = json_object_new_object();
-      json_object_string_add(json_row, "source", ch_src_str);
-      json_object_string_add(json_row, "group", ch_grp_str);
-      json_object_string_add(json_row, "localMembership",
-                             ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?  "NOINFO" : "INCLUDE");
-      json_object_object_add(json_iface, ch_grp_str, json_row);
-    } /* scan interface channels */
-  } /* scan interfaces */
+    json_row = json_object_new_object();
+    json_object_string_add(json_row, "source", ch_src_str);
+    json_object_string_add(json_row, "group", ch_grp_str);
+    json_object_string_add(json_row, "localMembership",
+                          ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?  "NOINFO" : "INCLUDE");
+    json_object_object_add(json_iface, ch_grp_str, json_row);
+  } /* scan interface channels */
 
   if (uj) {
     vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
@@ -1106,8 +1082,10 @@ static void pim_show_interfaces(struct vty *vty, u_char uj)
 
 static void pim_show_join(struct vty *vty, u_char uj)
 {
-  struct listnode  *ifnode;
-  struct interface *ifp;
+  struct pim_interface *pim_ifp;
+  struct in_addr ifaddr;
+  struct listnode *ch_node;
+  struct pim_ifchannel *ch;
   time_t            now;
   json_object *json = NULL;
   json_object *json_iface = NULL;
@@ -1122,69 +1100,63 @@ static void pim_show_join(struct vty *vty, u_char uj)
             "Interface Address         Source          Group           State  Uptime   Expire Prune%s",
             VTY_NEWLINE);
 
-  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
-    struct pim_interface *pim_ifp;
-    struct in_addr ifaddr;
-    struct listnode *ch_node;
-    struct pim_ifchannel *ch;
+  for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
 
-    pim_ifp = ifp->info;
+    pim_ifp = ch->interface->info;
     
     if (!pim_ifp)
       continue;
 
     ifaddr = pim_ifp->primary_address;
 
-    for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
-      char ch_src_str[INET_ADDRSTRLEN];
-      char ch_grp_str[INET_ADDRSTRLEN];
-      char uptime[10];
-      char expire[10];
-      char prune[10];
+    char ch_src_str[INET_ADDRSTRLEN];
+    char ch_grp_str[INET_ADDRSTRLEN];
+    char uptime[10];
+    char expire[10];
+    char prune[10];
 
-      pim_inet4_dump("<ch_src?>", ch->sg.src,
-                    ch_src_str, sizeof(ch_src_str));
-      pim_inet4_dump("<ch_grp?>", ch->sg.grp,
-                    ch_grp_str, sizeof(ch_grp_str));
+    pim_inet4_dump("<ch_src?>", ch->sg.src,
+                  ch_src_str, sizeof(ch_src_str));
+    pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+                  ch_grp_str, sizeof(ch_grp_str));
 
-      pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
-      pim_time_timer_to_mmss(expire, sizeof(expire),
-                            ch->t_ifjoin_expiry_timer);
-      pim_time_timer_to_mmss(prune, sizeof(prune),
-                            ch->t_ifjoin_prune_pending_timer);
+    pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
+    pim_time_timer_to_mmss(expire, sizeof(expire),
+                          ch->t_ifjoin_expiry_timer);
+    pim_time_timer_to_mmss(prune, sizeof(prune),
+                          ch->t_ifjoin_prune_pending_timer);
 
-      if (uj) {
-        json_object_object_get_ex(json, ifp->name, &json_iface);
+    if (uj) {
+      json_object_object_get_ex(json, ch->interface->name, &json_iface);
 
-        if (!json_iface) {
-          json_iface = json_object_new_object();
-          json_object_pim_ifp_add(json_iface, ifp);
-          json_object_object_add(json, ifp->name, json_iface);
-        }
+      if (!json_iface) {
+       json_iface = json_object_new_object();
+       json_object_pim_ifp_add(json_iface, ch->interface);
+       json_object_object_add(json, ch->interface->name, json_iface);
+      }
 
-        json_row = json_object_new_object();
-        json_object_string_add(json_row, "source", ch_src_str);
-        json_object_string_add(json_row, "group", ch_grp_str);
-        json_object_string_add(json_row, "upTime", uptime);
-        json_object_string_add(json_row, "expire", expire);
-        json_object_string_add(json_row, "prune", prune);
-        json_object_string_add(json_row, "channelJoinName", pim_ifchannel_ifjoin_name(ch->ifjoin_state));
-        json_object_object_add(json_iface, ch_grp_str, json_row);
+      json_row = json_object_new_object();
+      json_object_string_add(json_row, "source", ch_src_str);
+      json_object_string_add(json_row, "group", ch_grp_str);
+      json_object_string_add(json_row, "upTime", uptime);
+      json_object_string_add(json_row, "expire", expire);
+      json_object_string_add(json_row, "prune", prune);
+      json_object_string_add(json_row, "channelJoinName", pim_ifchannel_ifjoin_name(ch->ifjoin_state));
+      json_object_object_add(json_iface, ch_grp_str, json_row);
 
-      } else {
-        vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
-                ifp->name,
-                inet_ntoa(ifaddr),
-                ch_src_str,
-                ch_grp_str,
-                pim_ifchannel_ifjoin_name(ch->ifjoin_state),
-                uptime,
-                expire,
-                prune,
-                VTY_NEWLINE);
-      }
-    } /* scan interface channels */
-  } /* scan interfaces */
+    } else {
+      vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
+             ch->interface->name,
+             inet_ntoa(ifaddr),
+             ch_src_str,
+             ch_grp_str,
+             pim_ifchannel_ifjoin_name(ch->ifjoin_state),
+             uptime,
+             expire,
+             prune,
+             VTY_NEWLINE);
+    }
+  } /* scan interface channels */
 
   if (uj) {
     vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
@@ -1697,9 +1669,7 @@ static void pim_show_upstream(struct vty *vty, u_char uj)
 
 static void pim_show_join_desired(struct vty *vty, u_char uj)
 {
-  struct listnode      *ifnode;
   struct listnode      *chnode;
-  struct interface     *ifp;
   struct pim_interface *pim_ifp;
   struct pim_ifchannel *ch;
   char src_str[INET_ADDRSTRLEN];
@@ -1715,59 +1685,57 @@ static void pim_show_join_desired(struct vty *vty, u_char uj)
             "Interface Source          Group           LostAssert Joins PimInclude JoinDesired EvalJD%s",
             VTY_NEWLINE);
 
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
-    pim_ifp = ifp->info;
+  /* scan per-interface (S,G) state */
+  for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, chnode, ch)) {
+    /* scan all interfaces */
+    pim_ifp = ch->interface->info;
     if (!pim_ifp)
       continue;
 
-    /* scan per-interface (S,G) state */
-    for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
-      struct pim_upstream *up = ch->upstream;
+    struct pim_upstream *up = ch->upstream;
 
-      pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
-      pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+    pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+    pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
 
-      if (uj) {
-        json_object_object_get_ex(json, grp_str, &json_group);
+    if (uj) {
+      json_object_object_get_ex(json, grp_str, &json_group);
 
-        if (!json_group) {
-          json_group = json_object_new_object();
-          json_object_object_add(json, grp_str, json_group);
-        }
+      if (!json_group) {
+       json_group = json_object_new_object();
+       json_object_object_add(json, grp_str, json_group);
+      }
 
-        json_row = json_object_new_object();
-        json_object_pim_upstream_add(json_row, up);
-        json_object_string_add(json_row, "interface", ifp->name);
-        json_object_string_add(json_row, "source", src_str);
-        json_object_string_add(json_row, "group", grp_str);
+      json_row = json_object_new_object();
+      json_object_pim_upstream_add(json_row, up);
+      json_object_string_add(json_row, "interface", ch->interface->name);
+      json_object_string_add(json_row, "source", src_str);
+      json_object_string_add(json_row, "group", grp_str);
 
-        if (pim_macro_ch_lost_assert(ch))
-          json_object_boolean_true_add(json_row, "lostAssert");
+      if (pim_macro_ch_lost_assert(ch))
+       json_object_boolean_true_add(json_row, "lostAssert");
 
-        if (pim_macro_chisin_joins(ch))
-          json_object_boolean_true_add(json_row, "joins");
+      if (pim_macro_chisin_joins(ch))
+       json_object_boolean_true_add(json_row, "joins");
 
-        if (pim_macro_chisin_pim_include(ch))
-          json_object_boolean_true_add(json_row, "pimInclude");
+      if (pim_macro_chisin_pim_include(ch))
+       json_object_boolean_true_add(json_row, "pimInclude");
 
-        if (pim_upstream_evaluate_join_desired(up))
-          json_object_boolean_true_add(json_row, "evaluateJoinDesired");
+      if (pim_upstream_evaluate_join_desired(up))
+       json_object_boolean_true_add(json_row, "evaluateJoinDesired");
 
-        json_object_object_add(json_group, src_str, json_row);
+      json_object_object_add(json_group, src_str, json_row);
 
-      } else {
-        vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
-                ifp->name,
-                src_str,
-                grp_str,
-                pim_macro_ch_lost_assert(ch) ? "yes" : "no",
-                pim_macro_chisin_joins(ch) ? "yes" : "no",
-                pim_macro_chisin_pim_include(ch) ? "yes" : "no",
-                PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
-                pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
-                VTY_NEWLINE);
-      }
+    } else {
+      vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
+             ch->interface->name,
+             src_str,
+             grp_str,
+             pim_macro_ch_lost_assert(ch) ? "yes" : "no",
+             pim_macro_chisin_joins(ch) ? "yes" : "no",
+             pim_macro_chisin_pim_include(ch) ? "yes" : "no",
+             PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
+             pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
+             VTY_NEWLINE);
     }
   }
 
index 599b18ddce61dab9e2a8a83f9faa4c9e151e5c78..ecba4dd1b215b4a1a1ca121ff6ed4c5eb9b1022b 100644 (file)
 #include "pim_ssmpingd.h"
 
 struct interface *pim_regiface = NULL;
+struct list *pim_ifchannel_list = NULL;
 
 static void pim_if_igmp_join_del_all(struct interface *ifp);
 
-void pim_if_init()
-{
-  vrf_iflist_create(VRF_DEFAULT);
-}
-
-static void *if_list_clean(struct pim_interface *pim_ifp)
-{
-  if (pim_ifp->igmp_join_list) {
-    list_delete(pim_ifp->igmp_join_list);
-  }
-
-  if (pim_ifp->igmp_socket_list) {
-    list_delete(pim_ifp->igmp_socket_list);
-  }
-
-  if (pim_ifp->pim_neighbor_list) {
-    list_delete(pim_ifp->pim_neighbor_list);
-  }
-
-  if (pim_ifp->pim_ifchannel_list) {
-    list_delete(pim_ifp->pim_ifchannel_list);
-  }
-
-  XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
-
-  return 0;
-}
-
 static int
 pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
 {
@@ -108,6 +81,44 @@ pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
   return 0;
 }
 
+void
+pim_if_init (void)
+{
+  vrf_iflist_create(VRF_DEFAULT);
+  pim_ifchannel_list = list_new();
+  pim_ifchannel_list->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
+}
+
+void
+pim_if_terminate (void)
+{
+  if (pim_ifchannel_list)
+    list_free (pim_ifchannel_list);
+}
+
+static void *if_list_clean(struct pim_interface *pim_ifp)
+{
+  if (pim_ifp->igmp_join_list) {
+    list_delete(pim_ifp->igmp_join_list);
+  }
+
+  if (pim_ifp->igmp_socket_list) {
+    list_delete(pim_ifp->igmp_socket_list);
+  }
+
+  if (pim_ifp->pim_neighbor_list) {
+    list_delete(pim_ifp->pim_neighbor_list);
+  }
+
+  if (pim_ifp->pim_ifchannel_list) {
+    list_delete(pim_ifp->pim_ifchannel_list);
+  }
+
+  XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
+
+  return 0;
+}
+
 struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
 {
   struct pim_interface *pim_ifp;
index f671a7d54bdd90c08153e2cb4701a4a14d11c0f1..9e8b177947c17aca572b34200d5ee33033e2a031 100644 (file)
@@ -108,6 +108,7 @@ struct pim_interface {
 };
 
 extern struct interface *pim_regiface;
+extern struct list *pim_ifchannel_list;
 /*
   if default_holdtime is set (>= 0), use it;
   otherwise default_holdtime is 3.5 * hello_period
@@ -118,6 +119,7 @@ extern struct interface *pim_regiface;
   ((pim_ifp)->pim_default_holdtime))
 
 void pim_if_init(void);
+void pim_if_terminate (void);
 
 struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim);
 void                  pim_if_delete(struct interface *ifp);
index b786ad09ae4c8022ca305ed62169d5a7101a90cd..32e079831080c74bc09989f3d06aaaea2dbd0f4a 100644 (file)
@@ -140,6 +140,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
     called by list_delete_all_node()
   */
   listnode_delete(pim_ifp->pim_ifchannel_list, ch);
+  listnode_delete(pim_ifchannel_list, ch);
 
   pim_ifchannel_free(ch);
 }
@@ -435,6 +436,7 @@ pim_ifchannel_add(struct interface *ifp,
 
   /* Attach to list */
   listnode_add_sort(pim_ifp->pim_ifchannel_list, ch);
+  listnode_add_sort(pim_ifchannel_list, ch);
 
   return ch;
 }
index 3d592460dc1052f1ec46b131bc66e9e19e98bde1..84503eb3e952a7d4d6a696ea9990aed77895efee 100644 (file)
@@ -354,59 +354,45 @@ void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
 
 static void forward_on(struct pim_upstream *up)
 {
-  struct listnode      *ifnode;
-  struct listnode      *ifnextnode;
   struct listnode      *chnode;
   struct listnode      *chnextnode;
-  struct interface     *ifp;
   struct pim_interface *pim_ifp;
   struct pim_ifchannel *ch;
 
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
-    pim_ifp = ifp->info;
+  /* scan (S,G) state */
+  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+    pim_ifp = ch->interface->info;
     if (!pim_ifp)
       continue;
 
-    /* scan per-interface (S,G) state */
-    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
-      if (ch->upstream != up)
-       continue;
+    if (ch->upstream != up)
+      continue;
 
-      if (pim_macro_chisin_oiflist(ch))
-       pim_forward_start(ch);
+    if (pim_macro_chisin_oiflist(ch))
+      pim_forward_start(ch);
 
-    } /* scan iface channel list */
-  } /* scan iflist */
+  } /* scan iface channel list */
 }
 
 static void forward_off(struct pim_upstream *up)
 {
-  struct listnode      *ifnode;
-  struct listnode      *ifnextnode;
   struct listnode      *chnode;
   struct listnode      *chnextnode;
-  struct interface     *ifp;
   struct pim_interface *pim_ifp;
   struct pim_ifchannel *ch;
 
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
-    pim_ifp = ifp->info;
+  /* scan per-interface (S,G) state */
+  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+    pim_ifp = ch->interface->info;
     if (!pim_ifp)
       continue;
 
-    /* scan per-interface (S,G) state */
-    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
-      if (ch->upstream != up)
-       continue;
+    if (ch->upstream != up)
+      continue;
 
-      pim_forward_stop(ch);
+    pim_forward_stop(ch);
 
-    } /* scan iface channel list */
-  } /* scan iflist */
+  } /* scan iface channel list */
 }
 
 static int
@@ -696,27 +682,21 @@ pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
  */
 int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
 {
-  struct listnode      *ifnode;
-  struct listnode      *ifnextnode;
   struct listnode      *chnode;
   struct listnode      *chnextnode;
-  struct interface     *ifp;
   struct pim_interface *pim_ifp;
   struct pim_ifchannel *ch;
   int                  ret = 0;
 
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
-    pim_ifp = ifp->info;
-    if (!pim_ifp)
-      continue;
+  /* scan per-interface (S,G) state */
+  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch))
+    {
+      pim_ifp = ch->interface->info;
+      if (!pim_ifp)
+       continue;
 
-    /* scan per-interface (S,G) state */
-    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch))
-      {
-       ret += pim_upstream_evaluate_join_desired_interface (up, ch);
-      } /* scan iface channel list */
-  } /* scan iflist */
+      ret += pim_upstream_evaluate_join_desired_interface (up, ch);
+    } /* scan iface channel list */
 
   return ret; /* false */
 }
@@ -799,125 +779,97 @@ void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr)
 void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
                                        struct interface *old_rpf_ifp)
 {
-  struct listnode  *ifnode;
-  struct listnode  *ifnextnode;
-  struct interface *ifp;
-
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
-    struct listnode      *chnode;
-    struct listnode      *chnextnode;
-    struct pim_ifchannel *ch;
-    struct pim_interface *pim_ifp;
-
-    pim_ifp = ifp->info;
+  struct listnode      *chnode;
+  struct listnode      *chnextnode;
+  struct pim_ifchannel *ch;
+  struct pim_interface *pim_ifp;
+
+  /* search all ifchannels */
+  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+
+    pim_ifp = ch->interface->info;
     if (!pim_ifp)
       continue;
 
-    /* search all ifchannels */
-    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-      if (ch->upstream != up)
-       continue;
+    if (ch->upstream != up)
+      continue;
 
-      if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
-       if (
-           /* RPF_interface(S) was NOT I */
-           (old_rpf_ifp == ch->interface)
-           &&
-           /* RPF_interface(S) stopped being I */
-           (ch->upstream->rpf.source_nexthop.interface != ch->interface)
-           ) {
-         assert_action_a5(ch);
-       }
-      } /* PIM_IFASSERT_I_AM_LOSER */
+    if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
+      if (
+         /* RPF_interface(S) was NOT I */
+         (old_rpf_ifp == ch->interface)
+         &&
+         /* RPF_interface(S) stopped being I */
+         (ch->upstream->rpf.source_nexthop.interface != ch->interface)
+         ) {
+       assert_action_a5(ch);
+      }
+    } /* PIM_IFASSERT_I_AM_LOSER */
 
-      pim_ifchannel_update_assert_tracking_desired(ch);
-    }
+    pim_ifchannel_update_assert_tracking_desired(ch);
   }
 }
 
 void pim_upstream_update_could_assert(struct pim_upstream *up)
 {
-  struct listnode      *ifnode;
-  struct listnode      *ifnextnode;
   struct listnode      *chnode;
   struct listnode      *chnextnode;
-  struct interface     *ifp;
   struct pim_interface *pim_ifp;
   struct pim_ifchannel *ch;
 
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
-    pim_ifp = ifp->info;
+  /* scan per-interface (S,G) state */
+  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+    pim_ifp = ch->interface->info;
     if (!pim_ifp)
       continue;
 
-    /* scan per-interface (S,G) state */
-    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
-      if (ch->upstream != up)
-       continue;
-
-      pim_ifchannel_update_could_assert(ch);
+    if (ch->upstream != up)
+      continue;
 
-    } /* scan iface channel list */
-  } /* scan iflist */
+    pim_ifchannel_update_could_assert(ch);
+  } /* scan iface channel list */
 }
 
 void pim_upstream_update_my_assert_metric(struct pim_upstream *up)
 {
-  struct listnode      *ifnode;
-  struct listnode      *ifnextnode;
   struct listnode      *chnode;
   struct listnode      *chnextnode;
-  struct interface     *ifp;
   struct pim_interface *pim_ifp;
   struct pim_ifchannel *ch;
 
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
-    pim_ifp = ifp->info;
+  /* scan per-interface (S,G) state */
+  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+    pim_ifp = ch->interface->info;
     if (!pim_ifp)
       continue;
 
-    /* scan per-interface (S,G) state */
-    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
-      if (ch->upstream != up)
-       continue;
+    if (ch->upstream != up)
+      continue;
 
-      pim_ifchannel_update_my_assert_metric(ch);
+    pim_ifchannel_update_my_assert_metric(ch);
 
-    } /* scan iface channel list */
-  } /* scan iflist */
+  } /* scan iface channel list */
 }
 
 static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up)
 {
-  struct listnode      *ifnode;
-  struct listnode      *ifnextnode;
   struct listnode      *chnode;
   struct listnode      *chnextnode;
-  struct interface     *ifp;
   struct pim_interface *pim_ifp;
   struct pim_ifchannel *ch;
 
-  /* scan all interfaces */
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
-    pim_ifp = ifp->info;
+  /* scan per-interface (S,G) state */
+  for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+    pim_ifp = ch->interface->info;
     if (!pim_ifp)
       continue;
 
-    /* scan per-interface (S,G) state */
-    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
-      if (ch->upstream != up)
-       continue;
+    if (ch->upstream != up)
+      continue;
 
-      pim_ifchannel_update_assert_tracking_desired(ch);
+    pim_ifchannel_update_assert_tracking_desired(ch);
 
-    } /* scan iface channel list */
-  } /* scan iflist */
+  } /* scan iface channel list */
 }
 
 /*
@@ -1237,31 +1189,25 @@ int
 pim_upstream_inherited_olist (struct pim_upstream *up)
 {
   struct pim_interface *pim_ifp;
-  struct listnode *ifnextnode;
   struct listnode *chnextnode;
   struct pim_ifchannel *ch;
   struct listnode *chnode;
-  struct listnode *ifnode;
-  struct interface *ifp;
   int output_intf = 0;
 
   pim_ifp = up->rpf.source_nexthop.interface->info;
   if (pim_ifp && !up->channel_oil)
     up->channel_oil = pim_channel_oil_add (&up->sg, pim_ifp->mroute_vif_index);
 
-  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp))
+  for (ALL_LIST_ELEMENTS (pim_ifchannel_list, chnode, chnextnode, ch))
     {
-      pim_ifp = ifp->info;
+      pim_ifp = ch->interface->info;
       if (!pim_ifp)
        continue;
 
-      for (ALL_LIST_ELEMENTS (pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch))
+      if (pim_upstream_evaluate_join_desired_interface (up, ch))
        {
-         if (pim_upstream_evaluate_join_desired_interface (up, ch))
-           {
-             pim_channel_add_oif (up->channel_oil, ifp, PIM_OIF_FLAG_PROTO_PIM);
-             output_intf++;
-           }
+         pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+         output_intf++;
        }
     }
 
index 1608f2d07e448f51df81390d65dccfcc1b4c271f..bd8ee755c3f0de53015d6c98a5dc5b9b8ed4301a 100644 (file)
@@ -90,6 +90,7 @@ static void pim_free()
 
   pim_route_map_terminate();
 
+  pim_if_terminate ();
   pim_rp_free ();
   pim_route_map_terminate();
 }