summaryrefslogtreecommitdiffstats
path: root/pimd/pim_jp_agg.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_jp_agg.c')
-rw-r--r--pimd/pim_jp_agg.c495
1 files changed, 235 insertions, 260 deletions
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index 25530f40b..16d55d7bf 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -30,65 +30,63 @@
#include "pim_join.h"
#include "pim_iface.h"
-void
-pim_jp_agg_group_list_free (struct pim_jp_agg_group *jag)
+void pim_jp_agg_group_list_free(struct pim_jp_agg_group *jag)
{
- list_delete(jag->sources);
+ list_delete(jag->sources);
- XFREE (MTYPE_PIM_JP_AGG_GROUP, jag);
+ XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
-static void
-pim_jp_agg_src_free (struct pim_jp_sources *js)
+static void pim_jp_agg_src_free(struct pim_jp_sources *js)
{
- struct pim_upstream *up = js->up;
-
- /*
- * When we are being called here, we know
- * that the neighbor is going away start
- * the normal j/p timer so that it can
- * pick this shit back up when the
- * nbr comes back alive
- */
- if (up)
- join_timer_start(js->up);
- XFREE (MTYPE_PIM_JP_AGG_SOURCE, js);
+ struct pim_upstream *up = js->up;
+
+ /*
+ * When we are being called here, we know
+ * that the neighbor is going away start
+ * the normal j/p timer so that it can
+ * pick this shit back up when the
+ * nbr comes back alive
+ */
+ if (up)
+ join_timer_start(js->up);
+ XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
}
-int
-pim_jp_agg_group_list_cmp (void *arg1, void *arg2)
+int pim_jp_agg_group_list_cmp(void *arg1, void *arg2)
{
- const struct pim_jp_agg_group *jag1 = (const struct pim_jp_agg_group *)arg1;
- const struct pim_jp_agg_group *jag2 = (const struct pim_jp_agg_group *)arg2;
+ const struct pim_jp_agg_group *jag1 =
+ (const struct pim_jp_agg_group *)arg1;
+ const struct pim_jp_agg_group *jag2 =
+ (const struct pim_jp_agg_group *)arg2;
- if (jag1->group.s_addr < jag2->group.s_addr)
- return -1;
+ if (jag1->group.s_addr < jag2->group.s_addr)
+ return -1;
- if (jag1->group.s_addr > jag2->group.s_addr)
- return 1;
+ if (jag1->group.s_addr > jag2->group.s_addr)
+ return 1;
- return 0;
+ return 0;
}
-static int
-pim_jp_agg_src_cmp (void *arg1, void *arg2)
+static int pim_jp_agg_src_cmp(void *arg1, void *arg2)
{
- const struct pim_jp_sources *js1 = (const struct pim_jp_sources *)arg1;
- const struct pim_jp_sources *js2 = (const struct pim_jp_sources *)arg2;
+ const struct pim_jp_sources *js1 = (const struct pim_jp_sources *)arg1;
+ const struct pim_jp_sources *js2 = (const struct pim_jp_sources *)arg2;
- if (js1->is_join && !js2->is_join)
- return -1;
+ if (js1->is_join && !js2->is_join)
+ return -1;
- if (!js1->is_join && js2->is_join)
- return 1;
+ if (!js1->is_join && js2->is_join)
+ return 1;
- if ((uint32_t)js1->up->sg.src.s_addr < (uint32_t)js2->up->sg.src.s_addr)
- return -1;
+ if ((uint32_t)js1->up->sg.src.s_addr < (uint32_t)js2->up->sg.src.s_addr)
+ return -1;
- if ((uint32_t)js1->up->sg.src.s_addr > (uint32_t)js2->up->sg.src.s_addr)
- return 1;
+ if ((uint32_t)js1->up->sg.src.s_addr > (uint32_t)js2->up->sg.src.s_addr)
+ return 1;
- return 0;
+ return 0;
}
/*
@@ -97,119 +95,107 @@ pim_jp_agg_src_cmp (void *arg1, void *arg2)
* figuring out where to send prunes
* and joins.
*/
-void
-pim_jp_agg_clear_group (struct list *group)
+void pim_jp_agg_clear_group(struct list *group)
{
- struct listnode *gnode, *gnnode;
- struct listnode *snode, *snnode;
- struct pim_jp_agg_group *jag;
- struct pim_jp_sources *js;
-
- for (ALL_LIST_ELEMENTS(group, gnode, gnnode, jag))
- {
- for (ALL_LIST_ELEMENTS(jag->sources, snode, snnode, js))
- {
- listnode_delete(jag->sources, js);
- js->up = NULL;
- XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
- }
- jag->sources = NULL;
- listnode_delete(group, jag);
- XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
- }
+ struct listnode *gnode, *gnnode;
+ struct listnode *snode, *snnode;
+ struct pim_jp_agg_group *jag;
+ struct pim_jp_sources *js;
+
+ for (ALL_LIST_ELEMENTS(group, gnode, gnnode, jag)) {
+ for (ALL_LIST_ELEMENTS(jag->sources, snode, snnode, js)) {
+ listnode_delete(jag->sources, js);
+ js->up = NULL;
+ XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
+ }
+ jag->sources = NULL;
+ listnode_delete(group, jag);
+ XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
+ }
}
static struct pim_iface_upstream_switch *
-pim_jp_agg_get_interface_upstream_switch_list (struct pim_rpf *rpf)
+pim_jp_agg_get_interface_upstream_switch_list(struct pim_rpf *rpf)
{
- struct pim_interface *pim_ifp = rpf->source_nexthop.interface->info;
- struct pim_iface_upstream_switch *pius;
- struct listnode *node, *nnode;
-
- /* Old interface is pim disabled */
- if (!pim_ifp)
- return NULL;
-
- for (ALL_LIST_ELEMENTS(pim_ifp->upstream_switch_list, node, nnode, pius))
- {
- if (pius->address.s_addr == rpf->rpf_addr.u.prefix4.s_addr)
- break;
- }
-
- if (!pius)
- {
- pius = XCALLOC(MTYPE_PIM_JP_AGG_GROUP, sizeof (struct pim_iface_upstream_switch));
- pius->address.s_addr = rpf->rpf_addr.u.prefix4.s_addr;
- pius->us = list_new();
- listnode_add_sort (pim_ifp->upstream_switch_list, pius);
- }
-
- return pius;
+ struct pim_interface *pim_ifp = rpf->source_nexthop.interface->info;
+ struct pim_iface_upstream_switch *pius;
+ struct listnode *node, *nnode;
+
+ /* Old interface is pim disabled */
+ if (!pim_ifp)
+ return NULL;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->upstream_switch_list, node, nnode,
+ pius)) {
+ if (pius->address.s_addr == rpf->rpf_addr.u.prefix4.s_addr)
+ break;
+ }
+
+ if (!pius) {
+ pius = XCALLOC(MTYPE_PIM_JP_AGG_GROUP,
+ sizeof(struct pim_iface_upstream_switch));
+ pius->address.s_addr = rpf->rpf_addr.u.prefix4.s_addr;
+ pius->us = list_new();
+ listnode_add_sort(pim_ifp->upstream_switch_list, pius);
+ }
+
+ return pius;
}
-void
-pim_jp_agg_remove_group (struct list *group, struct pim_upstream *up)
+void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up)
{
- struct listnode *node, *nnode;
- struct pim_jp_agg_group *jag = NULL;
- struct pim_jp_sources *js = NULL;
-
- for (ALL_LIST_ELEMENTS(group, node, nnode, jag))
- {
- if (jag->group.s_addr == up->sg.grp.s_addr)
- break;
- }
-
- if (!jag)
- return;
-
- for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
- {
- if (js->up == up)
- break;
- }
-
- if (js)
- {
- js->up = NULL;
- listnode_delete(jag->sources, js);
- XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
- }
-
- if (jag->sources->count == 0)
- {
- list_delete(jag->sources);
- jag->sources = NULL;
- listnode_delete(group, jag);
- XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
- }
-
+ struct listnode *node, *nnode;
+ struct pim_jp_agg_group *jag = NULL;
+ struct pim_jp_sources *js = NULL;
+
+ for (ALL_LIST_ELEMENTS(group, node, nnode, jag)) {
+ if (jag->group.s_addr == up->sg.grp.s_addr)
+ break;
+ }
+
+ if (!jag)
+ return;
+
+ for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js)) {
+ if (js->up == up)
+ break;
+ }
+
+ if (js) {
+ js->up = NULL;
+ listnode_delete(jag->sources, js);
+ XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
+ }
+
+ if (jag->sources->count == 0) {
+ list_delete(jag->sources);
+ jag->sources = NULL;
+ listnode_delete(group, jag);
+ XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
+ }
}
-int
-pim_jp_agg_is_in_list (struct list *group, struct pim_upstream *up)
+int pim_jp_agg_is_in_list(struct list *group, struct pim_upstream *up)
{
- struct listnode *node, *nnode;
- struct pim_jp_agg_group *jag = NULL;
- struct pim_jp_sources *js = NULL;
+ struct listnode *node, *nnode;
+ struct pim_jp_agg_group *jag = NULL;
+ struct pim_jp_sources *js = NULL;
- for (ALL_LIST_ELEMENTS (group, node, nnode, jag))
- {
- if (jag->group.s_addr == up->sg.grp.s_addr)
- break;
- }
+ for (ALL_LIST_ELEMENTS(group, node, nnode, jag)) {
+ if (jag->group.s_addr == up->sg.grp.s_addr)
+ break;
+ }
- if (!jag)
- return 0;
+ if (!jag)
+ return 0;
- for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
- {
- if (js->up == up)
- return 1;
- }
+ for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js)) {
+ if (js->up == up)
+ return 1;
+ }
- return 0;
- }
+ return 0;
+}
//#define PIM_JP_AGG_DEBUG 1
/*
@@ -224,148 +210,137 @@ pim_jp_agg_is_in_list (struct list *group, struct pim_upstream *up)
* can be safely compiled out in real
* builds
*/
-void
-pim_jp_agg_upstream_verification (struct pim_upstream *up, bool ignore)
+void pim_jp_agg_upstream_verification(struct pim_upstream *up, bool ignore)
{
#ifdef PIM_JP_AGG_DEBUG
- struct listnode *node;
- struct interface *ifp;
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *nnode;
-
- if (ignore && ifp == up->rpf.source_nexthop.interface)
- continue;
-
- if (pim_ifp)
- {
- struct pim_neighbor *neigh;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, nnode, neigh))
- {
- assert (!pim_jp_agg_is_in_list(neigh->upstream_jp_agg, up));
- }
- }
- }
+ struct listnode *node;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *nnode;
+
+ if (ignore && ifp == up->rpf.source_nexthop.interface)
+ continue;
+
+ if (pim_ifp) {
+ struct pim_neighbor *neigh;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
+ nnode, neigh)) {
+ assert(!pim_jp_agg_is_in_list(
+ neigh->upstream_jp_agg, up));
+ }
+ }
+ }
#else
- return;
+ return;
#endif
}
-void
-pim_jp_agg_add_group (struct list *group, struct pim_upstream *up, bool is_join)
+void pim_jp_agg_add_group(struct list *group, struct pim_upstream *up,
+ bool is_join)
{
- struct listnode *node, *nnode;
- struct pim_jp_agg_group *jag = NULL;
- struct pim_jp_sources *js = NULL;
-
- for (ALL_LIST_ELEMENTS(group, node, nnode, jag))
- {
- if (jag->group.s_addr == up->sg.grp.s_addr)
- break;
- }
-
- if (!jag)
- {
- jag = XCALLOC(MTYPE_PIM_JP_AGG_GROUP, sizeof (struct pim_jp_agg_group));
- jag->group.s_addr = up->sg.grp.s_addr;
- jag->sources = list_new();
- jag->sources->cmp = pim_jp_agg_src_cmp;
- jag->sources->del = (void (*)(void *))pim_jp_agg_src_free;
- listnode_add_sort (group, jag);
- }
-
- for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
- {
- if (js->up == up)
- break;
- }
-
- if (!js)
- {
- js = XCALLOC(MTYPE_PIM_JP_AGG_SOURCE, sizeof (struct pim_jp_sources));
- js->up = up;
- js->is_join = is_join;
- listnode_add_sort (jag->sources, js);
- }
- else
- {
- if (js->is_join != is_join)
- {
- listnode_delete(jag->sources, js);
- js->is_join = is_join;
- listnode_add_sort (jag->sources, js);
- }
- }
+ struct listnode *node, *nnode;
+ struct pim_jp_agg_group *jag = NULL;
+ struct pim_jp_sources *js = NULL;
+
+ for (ALL_LIST_ELEMENTS(group, node, nnode, jag)) {
+ if (jag->group.s_addr == up->sg.grp.s_addr)
+ break;
+ }
+
+ if (!jag) {
+ jag = XCALLOC(MTYPE_PIM_JP_AGG_GROUP,
+ sizeof(struct pim_jp_agg_group));
+ jag->group.s_addr = up->sg.grp.s_addr;
+ jag->sources = list_new();
+ jag->sources->cmp = pim_jp_agg_src_cmp;
+ jag->sources->del = (void (*)(void *))pim_jp_agg_src_free;
+ listnode_add_sort(group, jag);
+ }
+
+ for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js)) {
+ if (js->up == up)
+ break;
+ }
+
+ if (!js) {
+ js = XCALLOC(MTYPE_PIM_JP_AGG_SOURCE,
+ sizeof(struct pim_jp_sources));
+ js->up = up;
+ js->is_join = is_join;
+ listnode_add_sort(jag->sources, js);
+ } else {
+ if (js->is_join != is_join) {
+ listnode_delete(jag->sources, js);
+ js->is_join = is_join;
+ listnode_add_sort(jag->sources, js);
+ }
+ }
}
-void
-pim_jp_agg_switch_interface (struct pim_rpf *orpf,
- struct pim_rpf *nrpf,
- struct pim_upstream *up)
+void pim_jp_agg_switch_interface(struct pim_rpf *orpf, struct pim_rpf *nrpf,
+ struct pim_upstream *up)
{
- struct pim_iface_upstream_switch *opius;
- struct pim_iface_upstream_switch *npius;
-
- opius = pim_jp_agg_get_interface_upstream_switch_list(orpf);
- npius = pim_jp_agg_get_interface_upstream_switch_list(nrpf);
-
- /*
- * RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
- *
- * Transitions from Joined State
- *
- * RPF'(S,G) changes not due to an Assert
- *
- * The upstream (S,G) state machine remains in Joined
- * state. Send Join(S,G) to the new upstream neighbor, which is
- * the new value of RPF'(S,G). Send Prune(S,G) to the old
- * upstream neighbor, which is the old value of RPF'(S,G). Set
- * the Join Timer (JT) to expire after t_periodic seconds.
- */
-
- /* send Prune(S,G) to the old upstream neighbor */
- if (opius)
- pim_jp_agg_add_group (opius->us, up, false);
-
- /* send Join(S,G) to the current upstream neighbor */
- pim_jp_agg_add_group (npius->us, up, true);
-
+ struct pim_iface_upstream_switch *opius;
+ struct pim_iface_upstream_switch *npius;
+
+ opius = pim_jp_agg_get_interface_upstream_switch_list(orpf);
+ npius = pim_jp_agg_get_interface_upstream_switch_list(nrpf);
+
+ /*
+ * RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
+ *
+ * Transitions from Joined State
+ *
+ * RPF'(S,G) changes not due to an Assert
+ *
+ * The upstream (S,G) state machine remains in Joined
+ * state. Send Join(S,G) to the new upstream neighbor, which is
+ * the new value of RPF'(S,G). Send Prune(S,G) to the old
+ * upstream neighbor, which is the old value of RPF'(S,G). Set
+ * the Join Timer (JT) to expire after t_periodic seconds.
+ */
+
+ /* send Prune(S,G) to the old upstream neighbor */
+ if (opius)
+ pim_jp_agg_add_group(opius->us, up, false);
+
+ /* send Join(S,G) to the current upstream neighbor */
+ pim_jp_agg_add_group(npius->us, up, true);
}
-void
-pim_jp_agg_single_upstream_send (struct pim_rpf *rpf,
- struct pim_upstream *up,
- bool is_join)
+void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf,
+ struct pim_upstream *up, bool is_join)
{
- static struct list *groups = NULL;
- static struct pim_jp_agg_group jag;
- static struct pim_jp_sources js;
+ static struct list *groups = NULL;
+ static struct pim_jp_agg_group jag;
+ static struct pim_jp_sources js;
- static bool first = true;
+ static bool first = true;
- /* skip JP upstream messages if source is directly connected */
- if (!up || !rpf->source_nexthop.interface ||
- pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src))
- return;
+ /* skip JP upstream messages if source is directly connected */
+ if (!up || !rpf->source_nexthop.interface || pim_if_connected_to_source(
+ rpf->source_nexthop
+ .interface,
+ up->sg.src))
+ return;
- if (first)
- {
- groups = list_new();
+ if (first) {
+ groups = list_new();
- jag.sources = list_new();
+ jag.sources = list_new();
- listnode_add(groups, &jag);
- listnode_add(jag.sources, &js);
+ listnode_add(groups, &jag);
+ listnode_add(jag.sources, &js);
- first = false;
- }
+ first = false;
+ }
- jag.group.s_addr = up->sg.grp.s_addr;
- js.up = up;
- js.is_join = is_join;
+ jag.group.s_addr = up->sg.grp.s_addr;
+ js.up = up;
+ js.is_join = is_join;
- pim_joinprune_send(rpf, groups);
+ pim_joinprune_send(rpf, groups);
}