Receive a (*,G) route and send it upstream to the RP.
The RP at this time does not properly handle the route.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim_oil.c pim_zlookup.c pim_pim.c pim_tlv.c pim_neighbor.c \
pim_hello.c pim_ifchannel.c pim_join.c pim_assert.c \
pim_msg.c pim_upstream.c pim_rpf.c pim_macro.c \
- pim_igmp_join.c pim_ssmpingd.c pim_int.c pim_static.c
+ pim_igmp_join.c pim_ssmpingd.c pim_int.c pim_rp.c pim_static.c
noinst_HEADERS = \
pimd.h pim_version.h pim_cmd.h pim_signals.h pim_iface.h \
pim_oil.h pim_zlookup.h pim_pim.h pim_tlv.h pim_neighbor.h \
pim_hello.h pim_ifchannel.h pim_join.h pim_assert.h \
pim_msg.h pim_upstream.h pim_rpf.h pim_macro.h \
- pim_igmp_join.h pim_ssmpingd.h pim_int.h pim_static.h
+ pim_igmp_join.h pim_ssmpingd.h pim_int.h pim_rp.h pim_static.h
pimd_SOURCES = \
pim_main.c $(libpim_a_SOURCES)
--- /dev/null
+/*
+ * PIM for Quagga
+ * Copyright (C) 2015 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include "network.h"
+
+#include "pimd.h"
+#include "pim_rp.h"
+
+/*
+ * Set the upstream IP address we want to talk to based upon
+ * the rp configured and the source address
+ *
+ * If we have don't have a RP configured and the source address is *
+ * then return failure.
+ *
+ */
+int
+pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source)
+{
+ if ((qpim_rp.s_addr == 0) && (source.s_addr == 0xFFFFFFFF))
+ {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: Received a (*,G) with no RP configured", __PRETTY_FUNCTION__);
+ return 0;
+ }
+
+ *up = (source.s_addr == 0xFFFFFFFF) ? qpim_rp : source;
+
+ return 1;
+}
--- /dev/null
+/*
+ * PIM for Quagga
+ * Copyright (C) 2015 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#ifndef PIM_RP_H
+#define PIM_RP_H
+
+int pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source);
+
+#endif
save_rpf_addr = rpf->rpf_addr; /* detect change in RPF'(S,G) */
if (pim_nexthop_lookup(&rpf->source_nexthop,
- up->source_addr)) {
+ up->upstream_addr)) {
return PIM_RPF_FAILURE;
}
#include "pim_zebra.h"
#include "pim_oil.h"
#include "pim_macro.h"
+#include "pim_rp.h"
static void join_timer_start(struct pim_upstream *up);
static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);
}
+
static struct pim_upstream *pim_upstream_new(struct in_addr source_addr,
struct in_addr group_addr)
{
if (!up) {
zlog_err("%s: PIM XMALLOC(%zu) failure",
__PRETTY_FUNCTION__, sizeof(*up));
- return 0;
+ return NULL;
}
up->source_addr = source_addr;
+ if (!pim_rp_set_upstream_addr (&up->upstream_addr, source_addr))
+ {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: Received a (*,G) with no RP configured", __PRETTY_FUNCTION__);
+
+ XFREE (MTYPE_PIM_UPSTREAM, up);
+ return NULL;
+ }
+
up->group_addr = group_addr;
up->flags = 0;
up->ref_count = 1;
See RFC 4601: 4.5.7. Sending (S,G) Join/Prune Message
*/
struct pim_upstream {
+ struct in_addr upstream_addr;/* Who we are talking to */
struct in_addr source_addr; /* (S,G) source key */
struct in_addr group_addr; /* (S,G) group key */
uint32_t flags;
#include "pim_join.h"
#include "pim_zlookup.h"
#include "pim_ifchannel.h"
+#include "pim_rp.h"
#undef PIM_DEBUG_IFADDR_DUMP
#define PIM_DEBUG_IFADDR_DUMP
group = source->source_group;
if (!source->source_channel_oil) {
+ struct in_addr vif_source;
struct pim_interface *pim_oif;
- int input_iface_vif_index = fib_lookup_if_vif_index(source->source_addr);
+
+ if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr))
+ return;
+
+ int input_iface_vif_index = fib_lookup_if_vif_index(vif_source);
if (input_iface_vif_index < 1) {
char source_str[100];
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
if (PIM_DEBUG_PIM_TRACE) {
char source_str[100];
char group_str[100];
+ char upstream_str[100];
+
pim_inet4_dump("<source?>", ch->source_addr, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", ch->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: (S,G)=(%s,%s) oif=%s",
+ pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str));
+ zlog_debug("%s: (S,G)=(%s,%s) oif=%s(%s)",
__PRETTY_FUNCTION__,
- source_str, group_str, ch->interface->name);
+ source_str, group_str, ch->interface->name, upstream_str);
}
if (!up->channel_oil) {
- int input_iface_vif_index = fib_lookup_if_vif_index(up->source_addr);
+ int input_iface_vif_index = fib_lookup_if_vif_index(up->upstream_addr);
if (input_iface_vif_index < 1) {
char source_str[100];
pim_inet4_dump("<source?>", up->source_addr, source_str, sizeof(source_str));