diff --git a/cumulus/etc/sudoers.d/quagga_sudoers b/cumulus/etc/sudoers.d/quagga_sudoers index 972966c6a8..4375d7e5fa 100644 --- a/cumulus/etc/sudoers.d/quagga_sudoers +++ b/cumulus/etc/sudoers.d/quagga_sudoers @@ -1 +1,15 @@ Defaults env_keep += VTYSH_PAGER + +# Allow user in group quagga to run vtysh show commands +# without a password by uncommenting the "%quagga" line below. + +# Subshell commands need to be disallowed, including +# preventing the user passing command line args like 'start-shell' +# Since vtysh allows minimum non-conflicting prefix'es, that means +# anything beginning with the string "st" in any arg. That's a bit +# restrictive. +# Instead, use NOEXEC, to prevent any exec'ed commands. + +Cmnd_Alias VTY_SHOW = /usr/bin/vtysh -c show * +# %quagga ALL = (root) NOPASSWD:NOEXEC: VTY_SHOW + diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index f85f422298..624264b3b5 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -524,6 +524,7 @@ int pim_mroute_del_vif(int vif_index) int pim_mroute_add(struct mfcctl *mc) { int err; + int orig = 0; qpim_mroute_add_last = pim_time_monotonic_sec(); ++qpim_mroute_add_events; @@ -534,8 +535,22 @@ int pim_mroute_add(struct mfcctl *mc) return -1; } + /* The linux kernel *expects* the incoming + * vif to be part of the outgoing list + * in the case of a (*,G). + */ + if (mc->mfcc_origin.s_addr == INADDR_ANY) + { + orig = mc->mfcc_ttls[mc->mfcc_parent]; + mc->mfcc_ttls[mc->mfcc_parent] = 1; + } + err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC, mc, sizeof(*mc)); + + if (mc->mfcc_origin.s_addr == INADDR_ANY) + mc->mfcc_ttls[mc->mfcc_parent] = orig; + if (err) { int e = errno; zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_MFC): errno=%d: %s", diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 07f9652fe8..ce3ac1a433 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -35,6 +35,10 @@ #include "pim_register.h" #include "pim_upstream.h" #include "pim_br.h" +#include "pim_rpf.h" +#include "pim_oil.h" +#include "pim_zebra.h" +#include "pim_join.h" struct thread *send_test_packet_timer = NULL; @@ -250,10 +254,25 @@ pim_register_recv (struct interface *ifp, } if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) && - !(*bits & PIM_REGISTER_NR_BIT)) { - //decapsulate and forward the iner packet to - //inherited_olist(S,G,rpt) - } + !(*bits & PIM_REGISTER_NR_BIT)) + { + pim_rp_set_upstream_addr (&upstream->upstream_addr, source); + pim_nexthop_lookup (&upstream->rpf.source_nexthop, + upstream->upstream_addr, NULL); + upstream->rpf.source_nexthop.interface = ifp; + upstream->source_addr.s_addr = source.s_addr; + upstream->rpf.rpf_addr.s_addr = source.s_addr; + upstream->channel_oil->oil.mfcc_origin = source; + pim_scan_individual_oil (upstream->channel_oil); + pim_joinprune_send(upstream->rpf.source_nexthop.interface, + upstream->rpf.source_nexthop.mrib_nexthop_addr, + upstream->source_addr, + upstream->group_addr, + 1); + + //decapsulate and forward the iner packet to + //inherited_olist(S,G,rpt) + } } else { pim_register_stop_send(src_addr); } diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index e947ff87c5..5918a5192d 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -383,19 +383,14 @@ static void scan_upstream_rpf_cache() } -void pim_scan_oil() +void +pim_scan_individual_oil (struct channel_oil *c_oil) { - struct listnode *node; - struct listnode *nextnode; - struct channel_oil *c_oil; + int old_vif_index; + int input_iface_vif_index = fib_lookup_if_vif_index(c_oil->oil.mfcc_origin); - qpim_scan_oil_last = pim_time_monotonic_sec(); - ++qpim_scan_oil_events; - - for (ALL_LIST_ELEMENTS(qpim_channel_oil_list, node, nextnode, c_oil)) { - int old_vif_index; - int input_iface_vif_index = fib_lookup_if_vif_index(c_oil->oil.mfcc_origin); - if (input_iface_vif_index < 1) { + if (input_iface_vif_index < 1) + { char source_str[100]; char group_str[100]; pim_inet4_dump("", c_oil->oil.mfcc_origin, source_str, sizeof(source_str)); @@ -403,15 +398,17 @@ void pim_scan_oil() zlog_warn("%s %s: could not find input interface for (S,G)=(%s,%s)", __FILE__, __PRETTY_FUNCTION__, source_str, group_str); - continue; + return; } - if (input_iface_vif_index == c_oil->oil.mfcc_parent) { + if (input_iface_vif_index == c_oil->oil.mfcc_parent) + { /* RPF unchanged */ - continue; + return; } - if (PIM_DEBUG_ZEBRA) { + if (PIM_DEBUG_ZEBRA) + { struct interface *old_iif = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent); struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index); char source_str[100]; @@ -425,8 +422,9 @@ void pim_scan_oil() new_iif ? new_iif->name : "", input_iface_vif_index); } - /* new iif loops to existing oif ? */ - if (c_oil->oil.mfcc_ttls[input_iface_vif_index]) { + /* new iif loops to existing oif ? */ + if (c_oil->oil.mfcc_ttls[input_iface_vif_index]) + { struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index); if (PIM_DEBUG_ZEBRA) { @@ -447,8 +445,10 @@ void pim_scan_oil() old_vif_index = c_oil->oil.mfcc_parent; c_oil->oil.mfcc_parent = input_iface_vif_index; + zlog_debug ("FF"); /* update kernel multicast forwarding cache (MFC) */ - if (pim_mroute_add(&c_oil->oil)) { + if (pim_mroute_add(&c_oil->oil)) + { /* just log warning */ struct interface *old_iif = pim_if_find_by_vif_index(old_vif_index); struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index); @@ -457,14 +457,24 @@ void pim_scan_oil() pim_inet4_dump("", c_oil->oil.mfcc_origin, source_str, sizeof(source_str)); pim_inet4_dump("", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); zlog_warn("%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d", - __FILE__, __PRETTY_FUNCTION__, - source_str, group_str, - old_iif ? old_iif->name : "", c_oil->oil.mfcc_parent, - new_iif ? new_iif->name : "", input_iface_vif_index); - continue; + __FILE__, __PRETTY_FUNCTION__, + source_str, group_str, + old_iif ? old_iif->name : "", c_oil->oil.mfcc_parent, + new_iif ? new_iif->name : "", input_iface_vif_index); } +} - } /* for (qpim_channel_oil_list) */ +void pim_scan_oil() +{ + struct listnode *node; + struct listnode *nextnode; + struct channel_oil *c_oil; + + qpim_scan_oil_last = pim_time_monotonic_sec(); + ++qpim_scan_oil_events; + + for (ALL_LIST_ELEMENTS(qpim_channel_oil_list, node, nextnode, c_oil)) + pim_scan_individual_oil (c_oil); } static int on_rpf_cache_refresh(struct thread *t) diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h index d624c86661..8e8f09551a 100644 --- a/pimd/pim_zebra.h +++ b/pimd/pim_zebra.h @@ -28,6 +28,7 @@ void pim_zebra_init(char *zebra_sock_path); +void pim_scan_individual_oil (struct channel_oil *c_oil); void pim_scan_oil(void); void igmp_anysource_forward_start(struct igmp_group *group); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 185f866916..e9090cbed2 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2227,13 +2227,16 @@ do_show_ip_route(struct vty *vty, const char *vrf_name, safi_t safi) return CMD_SUCCESS; } -ALIAS (show_ip_route, +DEFUN (show_ip_route_vrf, show_ip_route_vrf_cmd, "show ip route " VRF_CMD_STR, SHOW_STR IP_STR "IP routing table\n" VRF_CMD_HELP_STR) +{ + return do_show_ip_route (vty, argv[0], SAFI_UNICAST); +} DEFUN (show_ip_nht, show_ip_nht_cmd,