From: Donald Sharp Date: Wed, 30 Sep 2015 12:41:18 +0000 (-0700) Subject: pimd: Receive and transmit (*,G) to the RP X-Git-Tag: frr-2.0-rc1~835 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=8f5f5e91b6d2eedf13611567d3a1035c910d6894;p=mirror%2Ffrr.git pimd: Receive and transmit (*,G) to the RP 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 --- diff --git a/pimd/Makefile.am b/pimd/Makefile.am index e839f9e213..8e0f5e91dd 100644 --- a/pimd/Makefile.am +++ b/pimd/Makefile.am @@ -53,7 +53,7 @@ libpim_a_SOURCES = \ 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 \ @@ -62,7 +62,7 @@ noinst_HEADERS = \ 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) diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c new file mode 100644 index 0000000000..757c770c1d --- /dev/null +++ b/pimd/pim_rp.c @@ -0,0 +1,49 @@ +/* + * 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 + +#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; +} diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h new file mode 100644 index 0000000000..114cc2cfd8 --- /dev/null +++ b/pimd/pim_rp.h @@ -0,0 +1,26 @@ +/* + * 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 diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 38339da1bd..fb3636b2dc 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -131,7 +131,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, 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; } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 7957f5da46..e6cbbc61a1 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -44,6 +44,7 @@ #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); @@ -345,6 +346,7 @@ static void pim_upstream_switch(struct pim_upstream *up, } + static struct pim_upstream *pim_upstream_new(struct in_addr source_addr, struct in_addr group_addr) { @@ -355,10 +357,19 @@ static struct pim_upstream *pim_upstream_new(struct in_addr source_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; diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 5b5182dd43..c7cdbc28d5 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -80,6 +80,7 @@ enum pim_upstream_state { 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; diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index b2bdb0d7f3..c8b362c140 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -42,6 +42,7 @@ #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 @@ -1091,8 +1092,13 @@ void igmp_source_forward_start(struct igmp_source *source) 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_addr, source_str, sizeof(source_str)); @@ -1239,15 +1245,18 @@ void pim_forward_start(struct pim_ifchannel *ch) if (PIM_DEBUG_PIM_TRACE) { char source_str[100]; char group_str[100]; + char upstream_str[100]; + pim_inet4_dump("", ch->source_addr, source_str, sizeof(source_str)); pim_inet4_dump("", ch->group_addr, group_str, sizeof(group_str)); - zlog_debug("%s: (S,G)=(%s,%s) oif=%s", + pim_inet4_dump("", 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("", up->source_addr, source_str, sizeof(source_str));