]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Create register stop timer for DR
authorDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 18 Jul 2016 13:47:19 +0000 (09:47 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:02 +0000 (20:26 -0500)
When a register stop is received, create the register stop
timer and associated state machine.

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

index 8f1b019808ce4eadf4b5cff5c5b71bcc3f2e2be4..066fbc47219887786452670d32cdff55e1cfc864 100644 (file)
@@ -46,6 +46,7 @@
 #include "pim_macro.h"
 #include "pim_rp.h"
 #include "pim_br.h"
+#include "pim_register.h"
 
 static void join_timer_start(struct pim_upstream *up);
 static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);
@@ -805,3 +806,88 @@ pim_upstream_state2str (struct pim_upstream *up)
     }
   return "Unkwn";
 }
+
+static int
+pim_upstream_register_stop_timer (struct thread *t)
+{
+  struct pim_upstream *up;
+  struct pim_rpf *rpg;
+  struct ip ip_hdr;
+
+  up = THREAD_ARG (t);
+
+  up->t_rs_timer = NULL;
+
+  if (PIM_DEBUG_TRACE)
+    {
+      char src_str[100];
+      char grp_str[100];
+
+      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
+      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
+      zlog_debug ("%s: (S,G)=(%s,%s) upstream register stop timer %d",
+                 __PRETTY_FUNCTION__, src_str, grp_str, up->join_state);
+    }
+
+  switch (up->join_state)
+    {
+    case PIM_UPSTREAM_JOIN_PENDING:
+      up->join_state = PIM_UPSTREAM_JOINED;
+      break;
+    case PIM_UPSTREAM_PRUNE:
+      up->join_state = PIM_UPSTREAM_JOIN_PENDING;
+      pim_upstream_start_register_stop_timer (up, 1);
+
+      rpg = RP (up->group_addr);
+      memset (&ip_hdr, 0, sizeof (struct ip));
+      ip_hdr.ip_p = PIM_IP_PROTO_PIM;
+      ip_hdr.ip_hl = 5;
+      ip_hdr.ip_v = 4;
+      ip_hdr.ip_src = up->source_addr;
+      ip_hdr.ip_dst = up->group_addr;
+      ip_hdr.ip_len = 20;
+      // checksum is broken
+      pim_register_send ((uint8_t *)&ip_hdr, sizeof (struct ip), rpg, 1);
+      pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+      break;
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+void
+pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register)
+{
+  uint32_t time;
+
+  if (up->t_rs_timer)
+    {
+      THREAD_TIMER_OFF (up->t_rs_timer);
+      up->t_rs_timer = NULL;
+    }
+
+  if (!null_register)
+    {
+      uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
+      uint32_t upper = (1.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
+      time = lower + (random () % (upper - lower + 1)) - PIM_REGISTER_PROBE_PERIOD;
+    }
+  else
+    time = PIM_REGISTER_PROBE_PERIOD;
+
+  if (PIM_DEBUG_TRACE)
+    {
+      char src_str[100];
+      char grp_str[100];
+
+      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
+      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
+      zlog_debug ("%s: (S,G)=(%s,%s) Starting upstream register stop timer %d",
+                 __PRETTY_FUNCTION__, src_str, grp_str, time);
+    }
+  THREAD_TIMER_ON (master, up->t_rs_timer,
+                  pim_upstream_register_stop_timer,
+                  up, time);
+}
index 1ae3893d47b64bed8d0f2ed30af58cbfb5bc6e74..222e30b4baf157b57cadd3eff346bc288be49eb4 100644 (file)
@@ -150,5 +150,7 @@ void pim_upstream_keep_alive_timer_start (struct pim_upstream *up, uint32_t time
 int pim_upstream_switch_to_spt_desired (struct in_addr source, struct in_addr group);
 #define SwitchToSptDesired(S,G) pim_upstream_switch_to_spt_desired ((S), (G))
 
+void pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register);
+
 const char *pim_upstream_state2str (struct pim_upstream *up);
 #endif /* PIM_UPSTREAM_H */