Merge branch 'frr/pull/133' ("Pim cleanup")

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2017-01-31 15:26:07 +01:00
commit 26df3a33ae
25 changed files with 349 additions and 602 deletions

View File

@ -377,6 +377,7 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
bgp_unlock_node (rn); bgp_unlock_node (rn);
bnc->last_update = bgp_clock(); bnc->last_update = bgp_clock();
bnc->change_flags = 0; bnc->change_flags = 0;
stream_getc (s); // Distance but not currently used
metric = stream_getl (s); metric = stream_getl (s);
nexthop_num = stream_getc (s); nexthop_num = stream_getc (s);

View File

@ -24,6 +24,7 @@
#include <zebra.h> #include <zebra.h>
#include "zclient.h"
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
#include "command.h" #include "command.h"

View File

@ -37,6 +37,62 @@
/* Zebra header size. */ /* Zebra header size. */
#define ZEBRA_HEADER_SIZE 8 #define ZEBRA_HEADER_SIZE 8
/* Zebra message types. */
typedef enum {
ZEBRA_INTERFACE_ADD,
ZEBRA_INTERFACE_DELETE,
ZEBRA_INTERFACE_ADDRESS_ADD,
ZEBRA_INTERFACE_ADDRESS_DELETE,
ZEBRA_INTERFACE_UP,
ZEBRA_INTERFACE_DOWN,
ZEBRA_IPV4_ROUTE_ADD,
ZEBRA_IPV4_ROUTE_DELETE,
ZEBRA_IPV6_ROUTE_ADD,
ZEBRA_IPV6_ROUTE_DELETE,
ZEBRA_REDISTRIBUTE_ADD,
ZEBRA_REDISTRIBUTE_DELETE,
ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
ZEBRA_ROUTER_ID_ADD,
ZEBRA_ROUTER_ID_DELETE,
ZEBRA_ROUTER_ID_UPDATE,
ZEBRA_HELLO,
ZEBRA_NEXTHOP_REGISTER,
ZEBRA_NEXTHOP_UNREGISTER,
ZEBRA_NEXTHOP_UPDATE,
ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
ZEBRA_INTERFACE_BFD_DEST_UPDATE,
ZEBRA_IMPORT_ROUTE_REGISTER,
ZEBRA_IMPORT_ROUTE_UNREGISTER,
ZEBRA_IMPORT_CHECK_UPDATE,
ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
ZEBRA_BFD_DEST_REGISTER,
ZEBRA_BFD_DEST_DEREGISTER,
ZEBRA_BFD_DEST_UPDATE,
ZEBRA_BFD_DEST_REPLAY,
ZEBRA_REDISTRIBUTE_IPV4_ADD,
ZEBRA_REDISTRIBUTE_IPV4_DEL,
ZEBRA_REDISTRIBUTE_IPV6_ADD,
ZEBRA_REDISTRIBUTE_IPV6_DEL,
ZEBRA_VRF_UNREGISTER,
ZEBRA_VRF_ADD,
ZEBRA_VRF_DELETE,
ZEBRA_INTERFACE_VRF_UPDATE,
ZEBRA_BFD_CLIENT_REGISTER,
ZEBRA_INTERFACE_ENABLE_RADV,
ZEBRA_INTERFACE_DISABLE_RADV,
ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB,
ZEBRA_INTERFACE_LINK_PARAMS,
ZEBRA_MPLS_LABELS_ADD,
ZEBRA_MPLS_LABELS_DELETE,
ZEBRA_IPV4_NEXTHOP_ADD,
ZEBRA_IPV4_NEXTHOP_DELETE,
ZEBRA_IPV6_NEXTHOP_ADD,
ZEBRA_IPV6_NEXTHOP_DELETE,
ZEBRA_IPMR_ROUTE_STATS,
} zebra_message_types_t;
struct redist_proto struct redist_proto
{ {
u_char enabled; u_char enabled;

View File

@ -352,62 +352,6 @@ struct in_pktinfo
/* default zebra TCP port for zclient */ /* default zebra TCP port for zclient */
#define ZEBRA_PORT 2600 #define ZEBRA_PORT 2600
/* Zebra message types. */
typedef enum {
ZEBRA_INTERFACE_ADD,
ZEBRA_INTERFACE_DELETE,
ZEBRA_INTERFACE_ADDRESS_ADD,
ZEBRA_INTERFACE_ADDRESS_DELETE,
ZEBRA_INTERFACE_UP,
ZEBRA_INTERFACE_DOWN,
ZEBRA_IPV4_ROUTE_ADD,
ZEBRA_IPV4_ROUTE_DELETE,
ZEBRA_IPV6_ROUTE_ADD,
ZEBRA_IPV6_ROUTE_DELETE,
ZEBRA_REDISTRIBUTE_ADD,
ZEBRA_REDISTRIBUTE_DELETE,
ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
ZEBRA_ROUTER_ID_ADD,
ZEBRA_ROUTER_ID_DELETE,
ZEBRA_ROUTER_ID_UPDATE,
ZEBRA_HELLO,
ZEBRA_NEXTHOP_REGISTER,
ZEBRA_NEXTHOP_UNREGISTER,
ZEBRA_NEXTHOP_UPDATE,
ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
ZEBRA_INTERFACE_BFD_DEST_UPDATE,
ZEBRA_IMPORT_ROUTE_REGISTER,
ZEBRA_IMPORT_ROUTE_UNREGISTER,
ZEBRA_IMPORT_CHECK_UPDATE,
ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
ZEBRA_BFD_DEST_REGISTER,
ZEBRA_BFD_DEST_DEREGISTER,
ZEBRA_BFD_DEST_UPDATE,
ZEBRA_BFD_DEST_REPLAY,
ZEBRA_REDISTRIBUTE_IPV4_ADD,
ZEBRA_REDISTRIBUTE_IPV4_DEL,
ZEBRA_REDISTRIBUTE_IPV6_ADD,
ZEBRA_REDISTRIBUTE_IPV6_DEL,
ZEBRA_VRF_UNREGISTER,
ZEBRA_VRF_ADD,
ZEBRA_VRF_DELETE,
ZEBRA_INTERFACE_VRF_UPDATE,
ZEBRA_BFD_CLIENT_REGISTER,
ZEBRA_INTERFACE_ENABLE_RADV,
ZEBRA_INTERFACE_DISABLE_RADV,
ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB,
ZEBRA_INTERFACE_LINK_PARAMS,
ZEBRA_MPLS_LABELS_ADD,
ZEBRA_MPLS_LABELS_DELETE,
ZEBRA_IPV4_NEXTHOP_ADD,
ZEBRA_IPV4_NEXTHOP_DELETE,
ZEBRA_IPV6_NEXTHOP_ADD,
ZEBRA_IPV6_NEXTHOP_DELETE,
ZEBRA_IPMR_ROUTE_STATS,
} zebra_message_types_t;
/* Marker value used in new Zserv, in the byte location corresponding /* Marker value used in new Zserv, in the byte location corresponding
* the command value in the old zserv header. To allow old and new * the command value in the old zserv header. To allow old and new
* Zserv headers to be distinguished from each other. * Zserv headers to be distinguished from each other.
@ -438,14 +382,6 @@ extern const char *zserv_command_string (unsigned int command);
#define strmatch(a,b) (!strcmp((a), (b))) #define strmatch(a,b) (!strcmp((a), (b)))
/* Error codes of zebra. */
#define ZEBRA_ERR_NOERROR 0
#define ZEBRA_ERR_RTEXIST -1
#define ZEBRA_ERR_RTUNREACH -2
#define ZEBRA_ERR_EPERM -3
#define ZEBRA_ERR_RTNOEXIST -4
#define ZEBRA_ERR_KERNEL -5
/* Zebra message flags */ /* Zebra message flags */
#define ZEBRA_FLAG_INTERNAL 0x01 #define ZEBRA_FLAG_INTERNAL 0x01
#define ZEBRA_FLAG_SELFROUTE 0x02 #define ZEBRA_FLAG_SELFROUTE 0x02

View File

@ -1367,7 +1367,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
if (uj) { if (uj) {
json = json_object_new_object(); json = json_object_new_object();
} else { } else {
vty_out(vty, "%sSource Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE); vty_out(vty, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
vty_out(vty, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE);
} }
for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) { for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
@ -1379,9 +1380,6 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
struct interface *ifp_in; struct interface *ifp_in;
first_oif = 1; first_oif = 1;
if (!c_oil->installed)
continue;
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str)); pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str)); pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent); ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
@ -1426,7 +1424,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
json_object_object_add(json_source, in_ifname, json_ifp_in); json_object_object_add(json_source, in_ifname, json_ifp_in);
} }
} else { } else {
vty_out(vty, "%-15s %-15s %-5s ", vty_out(vty, "%-9d %-15s %-15s %-7s ",
c_oil->installed,
src_str, src_str,
grp_str, grp_str,
ifp_in->name); ifp_in->name);
@ -1455,16 +1454,25 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
json_object_string_add(json_ifp_out, "group", grp_str); json_object_string_add(json_ifp_out, "group", grp_str);
json_object_string_add(json_ifp_out, "inboundInterface", in_ifname); json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
json_object_string_add(json_ifp_out, "outboundInterface", out_ifname); json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
json_object_int_add(json_ifp_out, "installed", c_oil->installed);
json_object_object_add(json_ifp_in, out_ifname, json_ifp_out); json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
} else { } else {
if (first_oif) if (first_oif)
{ {
first_oif = 0; first_oif = 0;
vty_out(vty, "%s", out_ifname); vty_out(vty, "%s(%c%c%c%c)", out_ifname,
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ');
} }
else else
vty_out(vty, ",%s", out_ifname); vty_out(vty, ", %s(%c%c%c%c)", out_ifname,
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
(c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ' );
} }
} }
@ -2825,21 +2833,11 @@ DEFUN (show_ip_multicast,
} }
vty_out(vty, "%s", VTY_NEWLINE); vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, "Zclient update socket: ");
if (qpim_zclient_update) {
vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
qpim_zclient_update->fail, VTY_NEWLINE);
}
else {
vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
}
pim_zebra_zclient_update (vty);
pim_zlookup_show_ip_multicast (vty); pim_zlookup_show_ip_multicast (vty);
vty_out(vty, "%s", VTY_NEWLINE); vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, "Current highest VifIndex: %d%s",
qpim_mroute_oif_highest_vif_index,
VTY_NEWLINE);
vty_out(vty, "Maximum highest VifIndex: %d%s", vty_out(vty, "Maximum highest VifIndex: %d%s",
PIM_MAX_USABLE_VIFS, PIM_MAX_USABLE_VIFS,
VTY_NEWLINE); VTY_NEWLINE);
@ -2970,6 +2968,9 @@ static void show_mroute(struct vty *vty, u_char uj)
if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE)
json_object_boolean_true_add(json_ifp_out, "protocolSource"); json_object_boolean_true_add(json_ifp_out, "protocolSource");
if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR)
json_object_boolean_true_add(json_ifp_out, "protocolInherited");
json_object_string_add(json_ifp_out, "inboundInterface", in_ifname); json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent); json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
json_object_string_add(json_ifp_out, "outboundInterface", out_ifname); json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
@ -2994,6 +2995,10 @@ static void show_mroute(struct vty *vty, u_char uj)
strcpy(proto, "SRC"); strcpy(proto, "SRC");
} }
if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) {
strcpy(proto, "STAR");
}
vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s", vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
src_str, src_str,
grp_str, grp_str,

View File

@ -44,12 +44,18 @@
struct interface *pim_regiface = NULL; struct interface *pim_regiface = NULL;
struct list *pim_ifchannel_list = NULL; struct list *pim_ifchannel_list = NULL;
static int pim_iface_vif_index[MAXVIFS];
static void pim_if_igmp_join_del_all(struct interface *ifp); static void pim_if_igmp_join_del_all(struct interface *ifp);
void void
pim_if_init (void) pim_if_init (void)
{ {
int i;
for (i = 0; i < MAXVIFS; i++)
pim_iface_vif_index[i] = 0;
vrf_iflist_create(VRF_DEFAULT); vrf_iflist_create(VRF_DEFAULT);
pim_ifchannel_list = list_new(); pim_ifchannel_list = list_new();
pim_ifchannel_list->cmp = (int (*)(void *, void *))pim_ifchannel_compare; pim_ifchannel_list->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
@ -848,11 +854,10 @@ pim_find_primary_addr (struct interface *ifp)
return addr; return addr;
} }
static int pim_iface_vif_index = 0;
static int static int
pim_iface_next_vif_index (struct interface *ifp) pim_iface_next_vif_index (struct interface *ifp)
{ {
int i;
/* /*
* The pimreg vif is always going to be in index 0 * The pimreg vif is always going to be in index 0
* of the table. * of the table.
@ -860,8 +865,12 @@ pim_iface_next_vif_index (struct interface *ifp)
if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF) if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
return 0; return 0;
pim_iface_vif_index++; for (i = 1 ; i < MAXVIFS; i++)
return pim_iface_vif_index; {
if (pim_iface_vif_index[i] == 0)
return i;
}
return MAXVIFS;
} }
/* /*
@ -884,7 +893,7 @@ int pim_if_add_vif(struct interface *ifp)
return -1; return -1;
} }
if (ifp->ifindex < 1) { if (ifp->ifindex < 0) {
zlog_warn("%s: ifindex=%d < 1 on interface %s", zlog_warn("%s: ifindex=%d < 1 on interface %s",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
ifp->ifindex, ifp->name); ifp->ifindex, ifp->name);
@ -921,41 +930,13 @@ int pim_if_add_vif(struct interface *ifp)
return -5; return -5;
} }
/* pim_iface_vif_index[pim_ifp->mroute_vif_index] = 1;
Update highest vif_index
*/
if (pim_ifp->mroute_vif_index != PIM_OIF_PIM_REGISTER_VIF &&
pim_ifp->mroute_vif_index > qpim_mroute_oif_highest_vif_index) {
qpim_mroute_oif_highest_vif_index = pim_ifp->mroute_vif_index;
}
return 0; return 0;
} }
static int iflist_find_highest_vif_index()
{
struct listnode *ifnode;
struct interface *ifp;
struct pim_interface *pim_ifp;
int highest_vif_index = -1;
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
if (pim_ifp->mroute_vif_index > highest_vif_index) {
highest_vif_index = pim_ifp->mroute_vif_index;
}
}
return highest_vif_index;
}
int pim_if_del_vif(struct interface *ifp) int pim_if_del_vif(struct interface *ifp)
{ {
struct pim_interface *pim_ifp = ifp->info; struct pim_interface *pim_ifp = ifp->info;
int old_vif_index;
if (pim_ifp->mroute_vif_index < 1) { if (pim_ifp->mroute_vif_index < 1) {
zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d", zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d",
@ -970,18 +951,12 @@ int pim_if_del_vif(struct interface *ifp)
} }
/* /*
Update highest vif_index Update vif_index
*/ */
pim_iface_vif_index[pim_ifp->mroute_vif_index] = 0;
/* save old vif_index in order to compare with highest below */
old_vif_index = pim_ifp->mroute_vif_index;
pim_ifp->mroute_vif_index = -1; pim_ifp->mroute_vif_index = -1;
if (old_vif_index == qpim_mroute_oif_highest_vif_index) {
qpim_mroute_oif_highest_vif_index = iflist_find_highest_vif_index();
}
return 0; return 0;
} }

View File

@ -142,7 +142,11 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
if (ch->upstream->channel_oil) if (ch->upstream->channel_oil)
{ {
pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
mask = PIM_OIF_FLAG_PROTO_IGMP;
pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
/* /*
* Do we have any S,G's that are inheriting? * Do we have any S,G's that are inheriting?
* Nuke from on high too. * Nuke from on high too.
@ -153,7 +157,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
struct listnode *up_node; struct listnode *up_node;
for (ALL_LIST_ELEMENTS_RO (ch->upstream->sources, up_node, child)) for (ALL_LIST_ELEMENTS_RO (ch->upstream->sources, up_node, child))
pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
} }
} }
@ -270,15 +274,19 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
continue; continue;
if (!pim_upstream_evaluate_join_desired (child)) if (!pim_upstream_evaluate_join_desired (child))
pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); {
pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
pim_upstream_update_join_desired (child);
}
/* /*
* If the S,G has no if channel and the c_oil still * If the S,G has no if channel and the c_oil still
* has output here then the *,G was supplying the implied * has output here then the *,G was supplying the implied
* if channel. So remove it. * if channel. So remove it.
* I think this is dead code now. is it?
*/ */
if (!ch && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index]) if (!ch && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
} }
} }
if (ch->ifjoin_state == PIM_IFJOIN_JOIN) if (ch->ifjoin_state == PIM_IFJOIN_JOIN)
@ -292,8 +300,8 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
if (pim_upstream_evaluate_join_desired (child)) if (pim_upstream_evaluate_join_desired (child))
{ {
pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
pim_upstream_switch (child, PIM_UPSTREAM_JOINED); pim_upstream_update_join_desired (child);
} }
} }
} }
@ -492,7 +500,7 @@ pim_ifchannel_add(struct interface *ifp,
return NULL; return NULL;
} }
ch = XMALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch)); ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));
if (!ch) { if (!ch) {
zlog_warn("%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s", zlog_warn("%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
@ -531,6 +539,7 @@ pim_ifchannel_add(struct interface *ifp,
/* Assert state */ /* Assert state */
ch->t_ifassert_timer = NULL; ch->t_ifassert_timer = NULL;
ch->ifassert_state = PIM_IFASSERT_NOINFO;
reset_ifassert_state(ch); reset_ifassert_state(ch);
if (pim_macro_ch_could_assert_eval(ch)) if (pim_macro_ch_could_assert_eval(ch))
PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags); PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags);
@ -929,8 +938,9 @@ void pim_ifchannel_prune(struct interface *ifp,
} }
} }
void pim_ifchannel_local_membership_add(struct interface *ifp, int
struct prefix_sg *sg) pim_ifchannel_local_membership_add(struct interface *ifp,
struct prefix_sg *sg)
{ {
struct pim_ifchannel *ch; struct pim_ifchannel *ch;
struct pim_interface *pim_ifp; struct pim_interface *pim_ifp;
@ -938,13 +948,13 @@ void pim_ifchannel_local_membership_add(struct interface *ifp,
/* PIM enabled on interface? */ /* PIM enabled on interface? */
pim_ifp = ifp->info; pim_ifp = ifp->info;
if (!pim_ifp) if (!pim_ifp)
return; return 0;
if (!PIM_IF_TEST_PIM(pim_ifp->options)) if (!PIM_IF_TEST_PIM(pim_ifp->options))
return; return 0;
ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP); ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);
if (!ch) { if (!ch) {
return; return 0;
} }
ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE); ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE);
@ -964,11 +974,13 @@ void pim_ifchannel_local_membership_add(struct interface *ifp,
if (pim_upstream_evaluate_join_desired (child)) if (pim_upstream_evaluate_join_desired (child))
{ {
pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
pim_upstream_switch (child, PIM_UPSTREAM_JOINED); pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
} }
} }
} }
return 1;
} }
void pim_ifchannel_local_membership_del(struct interface *ifp, void pim_ifchannel_local_membership_del(struct interface *ifp,
@ -1008,7 +1020,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
up->sg_str, ifp->name, child->sg_str); up->sg_str, ifp->name, child->sg_str);
if (c_oil && !pim_upstream_evaluate_join_desired (child)) if (c_oil && !pim_upstream_evaluate_join_desired (child))
pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
/* /*
* If the S,G has no if channel and the c_oil still * If the S,G has no if channel and the c_oil still
@ -1016,7 +1028,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
* if channel. So remove it. * if channel. So remove it.
*/ */
if (!chchannel && c_oil && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index]) if (!chchannel && c_oil && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
} }
} }
delete_on_noinfo(ch); delete_on_noinfo(ch);

View File

@ -130,8 +130,8 @@ void pim_ifchannel_prune(struct interface *ifp,
struct prefix_sg *sg, struct prefix_sg *sg,
uint8_t source_flags, uint8_t source_flags,
uint16_t holdtime); uint16_t holdtime);
void pim_ifchannel_local_membership_add(struct interface *ifp, int pim_ifchannel_local_membership_add(struct interface *ifp,
struct prefix_sg *sg); struct prefix_sg *sg);
void pim_ifchannel_local_membership_del(struct interface *ifp, void pim_ifchannel_local_membership_del(struct interface *ifp,
struct prefix_sg *sg); struct prefix_sg *sg);

View File

@ -41,8 +41,6 @@
#include "pim_zlookup.h" #include "pim_zlookup.h"
/* GLOBAL VARS */ /* GLOBAL VARS */
extern struct zebra_privs_t pimd_privs;
static struct thread *qpim_mroute_socket_reader = NULL; static struct thread *qpim_mroute_socket_reader = NULL;
static void mroute_read_on(void); static void mroute_read_on(void);
@ -812,13 +810,10 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name)
if (PIM_DEBUG_MROUTE) if (PIM_DEBUG_MROUTE)
{ {
struct prefix_sg sg; char buf[1000];
zlog_debug("%s(%s), Added Route: %s",
sg.src = c_oil->oil.mfcc_origin; __PRETTY_FUNCTION__, name,
sg.grp = c_oil->oil.mfcc_mcastgrp; pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
zlog_debug("%s(%s), Added Route: %s to mroute table",
__PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg));
} }
c_oil->installed = 1; c_oil->installed = 1;
@ -850,14 +845,12 @@ int pim_mroute_del (struct channel_oil *c_oil, const char *name)
if (PIM_DEBUG_MROUTE) if (PIM_DEBUG_MROUTE)
{ {
struct prefix_sg sg; char buf[1000];
zlog_debug("%s(%s), Deleted Route: %s",
sg.src = c_oil->oil.mfcc_origin; __PRETTY_FUNCTION__, name,
sg.grp = c_oil->oil.mfcc_mcastgrp; pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
zlog_debug("%s(%s), Deleted Route: %s from mroute table",
__PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg));
} }
c_oil->installed = 0; c_oil->installed = 0;
return 0; return 0;

View File

@ -31,8 +31,6 @@
#include "pim_msdp.h" #include "pim_msdp.h"
#include "pim_msdp_socket.h" #include "pim_msdp_socket.h"
extern struct zebra_privs_t pimd_privs;
/* increase socket send buffer size */ /* increase socket send buffer size */
static void static void
pim_msdp_update_sock_send_buffer_size (int fd) pim_msdp_update_sock_send_buffer_size (int fd)

View File

@ -36,6 +36,31 @@
struct list *pim_channel_oil_list = NULL; struct list *pim_channel_oil_list = NULL;
struct hash *pim_channel_oil_hash = NULL; struct hash *pim_channel_oil_hash = NULL;
char *
pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size)
{
struct prefix_sg sg;
int i;
memset (buf, 0, size);
sg.src = c_oil->oil.mfcc_origin;
sg.grp = c_oil->oil.mfcc_mcastgrp;
sprintf(buf, "%s IIF: %d, OIFS: ",
pim_str_sg_dump (&sg), c_oil->oil.mfcc_parent);
for (i = 0 ; i < MAXVIFS ; i++)
{
if (c_oil->oil.mfcc_ttls[i] != 0)
{
char buf1[10];
sprintf(buf1, "%d ", i);
strcat(buf, buf1);
}
}
return buf;
}
static int static int
pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2) pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2)
{ {
@ -353,25 +378,26 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
} }
/* Allow other protocol to request subscription of same interface to /* Allow other protocol to request subscription of same interface to
channel (S,G) multiple times, by silently ignoring further * channel (S,G), we need to note this information
requests */ */
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) { if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) {
channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec();
channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
/* Check the OIF really exists before returning, and only log /* Check the OIF really exists before returning, and only log
warning otherwise */ warning otherwise */
if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) { if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
if (PIM_DEBUG_MROUTE) {
{ char group_str[INET_ADDRSTRLEN];
char group_str[INET_ADDRSTRLEN]; char source_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN]; pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); zlog_warn("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
zlog_debug("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)", __FILE__, __PRETTY_FUNCTION__,
__FILE__, __PRETTY_FUNCTION__, proto_mask, oif->name, pim_ifp->mroute_vif_index,
proto_mask, oif->name, pim_ifp->mroute_vif_index, channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index], source_str, group_str);
source_str, group_str); }
}
} }
return 0; return 0;

View File

@ -29,13 +29,16 @@
* IGMP - Learned from IGMP * IGMP - Learned from IGMP
* PIM - Learned from PIM * PIM - Learned from PIM
* SOURCE - Learned from Source multicast packet received * SOURCE - Learned from Source multicast packet received
* STAR - Inherited
*/ */
#define PIM_OIF_FLAG_PROTO_IGMP (1 << 0) #define PIM_OIF_FLAG_PROTO_IGMP (1 << 0)
#define PIM_OIF_FLAG_PROTO_PIM (1 << 1) #define PIM_OIF_FLAG_PROTO_PIM (1 << 1)
#define PIM_OIF_FLAG_PROTO_SOURCE (2 << 1) #define PIM_OIF_FLAG_PROTO_SOURCE (1 << 2)
#define PIM_OIF_FLAG_PROTO_STAR (1 << 3)
#define PIM_OIF_FLAG_PROTO_ANY (PIM_OIF_FLAG_PROTO_IGMP | \ #define PIM_OIF_FLAG_PROTO_ANY (PIM_OIF_FLAG_PROTO_IGMP | \
PIM_OIF_FLAG_PROTO_PIM | \ PIM_OIF_FLAG_PROTO_PIM | \
PIM_OIF_FLAG_PROTO_SOURCE) PIM_OIF_FLAG_PROTO_SOURCE | \
PIM_OIF_FLAG_PROTO_STAR)
/* /*
* We need a pimreg vif id from the kernel. * We need a pimreg vif id from the kernel.
@ -45,8 +48,8 @@
* Don't come running to me if this assumption is bad, * Don't come running to me if this assumption is bad,
* fix it. * fix it.
*/ */
#define PIM_OIF_PIM_REGISTER_VIF (MAXVIFS - 1) #define PIM_OIF_PIM_REGISTER_VIF 0
#define PIM_MAX_USABLE_VIFS (MAXVIFS - 2) #define PIM_MAX_USABLE_VIFS (MAXVIFS - 1)
struct channel_counts struct channel_counts
@ -96,4 +99,6 @@ int pim_channel_del_oif (struct channel_oil *c_oil,
uint32_t proto_mask); uint32_t proto_mask);
int pim_channel_oil_empty (struct channel_oil *c_oil); int pim_channel_oil_empty (struct channel_oil *c_oil);
char *pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size);
#endif /* PIM_OIL_H */ #endif /* PIM_OIL_H */

View File

@ -126,7 +126,8 @@ void
pim_rp_free (void) pim_rp_free (void)
{ {
if (qpim_rp_list) if (qpim_rp_list)
list_free (qpim_rp_list); list_delete (qpim_rp_list);
qpim_rp_list = NULL;
} }
/* /*

View File

@ -42,7 +42,6 @@
#include "pim_igmp_join.h" #include "pim_igmp_join.h"
/* GLOBAL VARS */ /* GLOBAL VARS */
extern struct zebra_privs_t pimd_privs;
int int
pim_socket_raw (int protocol) pim_socket_raw (int protocol)

View File

@ -1288,7 +1288,11 @@ pim_upstream_inherited_olist_decide (struct pim_upstream *up)
if (pim_upstream_evaluate_join_desired_interface (up, ch)) if (pim_upstream_evaluate_join_desired_interface (up, ch))
{ {
pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); int flag = PIM_OIF_FLAG_PROTO_PIM;
if (ch->sg.src.s_addr == INADDR_ANY && ch->upstream != up)
flag = PIM_OIF_FLAG_PROTO_STAR;
pim_channel_add_oif (up->channel_oil, ch->interface, flag);
output_intf++; output_intf++;
} }
} }

View File

@ -48,6 +48,8 @@
#undef PIM_DEBUG_IFADDR_DUMP #undef PIM_DEBUG_IFADDR_DUMP
#define PIM_DEBUG_IFADDR_DUMP #define PIM_DEBUG_IFADDR_DUMP
static struct zclient *zclient = NULL;
static int fib_lookup_if_vif_index(struct in_addr addr); static int fib_lookup_if_vif_index(struct in_addr addr);
static int del_oif(struct channel_oil *channel_oil, static int del_oif(struct channel_oil *channel_oil,
struct interface *oif, struct interface *oif,
@ -724,31 +726,31 @@ void pim_zebra_init(char *zebra_sock_path)
#endif #endif
/* Socket for receiving updates from Zebra daemon */ /* Socket for receiving updates from Zebra daemon */
qpim_zclient_update = zclient_new (master); zclient = zclient_new (master);
qpim_zclient_update->zebra_connected = pim_zebra_connected; zclient->zebra_connected = pim_zebra_connected;
qpim_zclient_update->router_id_update = pim_router_id_update_zebra; zclient->router_id_update = pim_router_id_update_zebra;
qpim_zclient_update->interface_add = pim_zebra_if_add; zclient->interface_add = pim_zebra_if_add;
qpim_zclient_update->interface_delete = pim_zebra_if_del; zclient->interface_delete = pim_zebra_if_del;
qpim_zclient_update->interface_up = pim_zebra_if_state_up; zclient->interface_up = pim_zebra_if_state_up;
qpim_zclient_update->interface_down = pim_zebra_if_state_down; zclient->interface_down = pim_zebra_if_state_down;
qpim_zclient_update->interface_address_add = pim_zebra_if_address_add; zclient->interface_address_add = pim_zebra_if_address_add;
qpim_zclient_update->interface_address_delete = pim_zebra_if_address_del; zclient->interface_address_delete = pim_zebra_if_address_del;
qpim_zclient_update->redistribute_route_ipv4_add = redist_read_ipv4_route; zclient->redistribute_route_ipv4_add = redist_read_ipv4_route;
qpim_zclient_update->redistribute_route_ipv4_del = redist_read_ipv4_route; zclient->redistribute_route_ipv4_del = redist_read_ipv4_route;
zclient_init(qpim_zclient_update, ZEBRA_ROUTE_PIM, 0); zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
if (PIM_DEBUG_PIM_TRACE) { if (PIM_DEBUG_PIM_TRACE) {
zlog_info("zclient_init cleared redistribution request"); zlog_info("zclient_init cleared redistribution request");
} }
zassert(qpim_zclient_update->redist_default == ZEBRA_ROUTE_PIM); zassert(zclient->redist_default == ZEBRA_ROUTE_PIM);
/* Request all redistribution */ /* Request all redistribution */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
if (i == qpim_zclient_update->redist_default) if (i == zclient->redist_default)
continue; continue;
vrf_bitmap_set (qpim_zclient_update->redist[AFI_IP][i], VRF_DEFAULT);; vrf_bitmap_set (zclient->redist[AFI_IP][i], VRF_DEFAULT);;
if (PIM_DEBUG_PIM_TRACE) { if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: requesting redistribution for %s (%i)", zlog_debug("%s: requesting redistribution for %s (%i)",
__PRETTY_FUNCTION__, zebra_route_string(i), i); __PRETTY_FUNCTION__, zebra_route_string(i), i);
@ -757,7 +759,7 @@ void pim_zebra_init(char *zebra_sock_path)
/* Request default information */ /* Request default information */
zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
qpim_zclient_update, VRF_DEFAULT); zclient, VRF_DEFAULT);
if (PIM_DEBUG_PIM_TRACE) { if (PIM_DEBUG_PIM_TRACE) {
zlog_info("%s: requesting default information redistribution", zlog_info("%s: requesting default information redistribution",
@ -1095,7 +1097,13 @@ void igmp_source_forward_start(struct igmp_source *source)
Feed IGMPv3-gathered local membership information into PIM Feed IGMPv3-gathered local membership information into PIM
per-interface (S,G) state. per-interface (S,G) state.
*/ */
pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg); if (!pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg))
{
if (PIM_DEBUG_MROUTE)
zlog_warn ("%s: Failure to add local membership for %s",
__PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
return;
}
IGMP_SOURCE_DO_FORWARDING(source->source_flags); IGMP_SOURCE_DO_FORWARDING(source->source_flags);
} }
@ -1165,6 +1173,7 @@ void igmp_source_forward_stop(struct igmp_source *source)
void pim_forward_start(struct pim_ifchannel *ch) void pim_forward_start(struct pim_ifchannel *ch)
{ {
struct pim_upstream *up = ch->upstream; struct pim_upstream *up = ch->upstream;
uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
if (PIM_DEBUG_PIM_TRACE) { if (PIM_DEBUG_PIM_TRACE) {
char source_str[INET_ADDRSTRLEN]; char source_str[INET_ADDRSTRLEN];
@ -1204,9 +1213,10 @@ void pim_forward_start(struct pim_ifchannel *ch)
} }
} }
pim_channel_add_oif(up->channel_oil, if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
ch->interface, mask = PIM_OIF_FLAG_PROTO_IGMP;
PIM_OIF_FLAG_PROTO_PIM);
pim_channel_add_oif(up->channel_oil, ch->interface, mask);
} }
void pim_forward_stop(struct pim_ifchannel *ch) void pim_forward_stop(struct pim_ifchannel *ch)
@ -1232,3 +1242,17 @@ void pim_forward_stop(struct pim_ifchannel *ch)
ch->interface, ch->interface,
PIM_OIF_FLAG_PROTO_PIM); PIM_OIF_FLAG_PROTO_PIM);
} }
void
pim_zebra_zclient_update (struct vty *vty)
{
vty_out(vty, "Zclient update socket: ");
if (zclient) {
vty_out(vty, "%d failures=%d%s", zclient->sock,
zclient->fail, VTY_NEWLINE);
}
else {
vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
}
}

View File

@ -25,6 +25,7 @@
#include "pim_ifchannel.h" #include "pim_ifchannel.h"
void pim_zebra_init(char *zebra_sock_path); void pim_zebra_init(char *zebra_sock_path);
void pim_zebra_zclient_update (struct vty *vty);
void pim_scan_individual_oil (struct channel_oil *c_oil); void pim_scan_individual_oil (struct channel_oil *c_oil);
void pim_scan_oil(void); void pim_scan_oil(void);

View File

@ -120,6 +120,13 @@ static void zclient_lookup_failed(struct zclient *zlookup)
zclient_lookup_reconnect(zlookup); zclient_lookup_reconnect(zlookup);
} }
void
zclient_lookup_free (void)
{
zclient_free (zlookup);
zlookup = NULL;
}
void void
zclient_lookup_new (void) zclient_lookup_new (void)
{ {
@ -131,9 +138,7 @@ zclient_lookup_new (void)
} }
zlookup->sock = -1; zlookup->sock = -1;
zlookup->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ); zlookup->t_connect = NULL;
zlookup->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
zlookup->t_connect = 0;
zclient_lookup_sched_now(zlookup); zclient_lookup_sched_now(zlookup);

View File

@ -35,6 +35,7 @@ struct pim_zlookup_nexthop {
}; };
void zclient_lookup_new (void); void zclient_lookup_new (void);
void zclient_lookup_free (void);
int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[], int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
const int tab_size, const int tab_size,

View File

@ -39,6 +39,7 @@
#include "pim_ssmpingd.h" #include "pim_ssmpingd.h"
#include "pim_static.h" #include "pim_static.h"
#include "pim_rp.h" #include "pim_rp.h"
#include "pim_zlookup.h"
const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS; const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS;
const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS; const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS;
@ -49,9 +50,7 @@ struct thread_master *master = NULL;
uint32_t qpim_debugs = 0; uint32_t qpim_debugs = 0;
int qpim_mroute_socket_fd = -1; int qpim_mroute_socket_fd = -1;
int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */ int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */
int qpim_mroute_oif_highest_vif_index = -1;
int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */ int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
struct zclient *qpim_zclient_update = NULL;
struct pim_assert_metric qpim_infinite_assert_metric; struct pim_assert_metric qpim_infinite_assert_metric;
long qpim_rpf_cache_refresh_delay_msec = 50; long qpim_rpf_cache_refresh_delay_msec = 50;
struct thread *qpim_rpf_cache_refresher = NULL; struct thread *qpim_rpf_cache_refresher = NULL;
@ -91,6 +90,10 @@ static void pim_free()
pim_rp_free (); pim_rp_free ();
pim_route_map_terminate(); pim_route_map_terminate();
zclient_lookup_free ();
zprivs_terminate(&pimd_privs);
} }
void pim_init() void pim_init()
@ -122,7 +125,6 @@ void pim_init()
qpim_static_route_list->del = (void (*)(void *)) pim_static_route_free; qpim_static_route_list->del = (void (*)(void *)) pim_static_route_free;
qpim_mroute_socket_fd = -1; /* mark mroute as disabled */ qpim_mroute_socket_fd = -1; /* mark mroute as disabled */
qpim_mroute_oif_highest_vif_index = -1;
qpim_inaddr_any.s_addr = PIM_NET_INADDR_ANY; qpim_inaddr_any.s_addr = PIM_NET_INADDR_ANY;

View File

@ -96,13 +96,12 @@ const char *const PIM_ALL_PIM_ROUTERS;
const char *const PIM_ALL_IGMP_ROUTERS; const char *const PIM_ALL_IGMP_ROUTERS;
extern struct thread_master *master; extern struct thread_master *master;
extern struct zebra_privs_t pimd_privs;
uint32_t qpim_debugs; uint32_t qpim_debugs;
int qpim_mroute_socket_fd; int qpim_mroute_socket_fd;
int64_t qpim_mroute_socket_creation; /* timestamp of creation */ int64_t qpim_mroute_socket_creation; /* timestamp of creation */
int qpim_mroute_oif_highest_vif_index;
struct in_addr qpim_all_pim_routers_addr; struct in_addr qpim_all_pim_routers_addr;
int qpim_t_periodic; /* Period between Join/Prune Messages */ int qpim_t_periodic; /* Period between Join/Prune Messages */
struct zclient *qpim_zclient_update;
struct pim_assert_metric qpim_infinite_assert_metric; struct pim_assert_metric qpim_infinite_assert_metric;
long qpim_rpf_cache_refresh_delay_msec; long qpim_rpf_cache_refresh_delay_msec;
struct thread *qpim_rpf_cache_refresher; struct thread *qpim_rpf_cache_refresher;

View File

@ -23,6 +23,14 @@
#ifndef __ZEBRA_KERNEL_SOCKET_H #ifndef __ZEBRA_KERNEL_SOCKET_H
#define __ZEBRA_KERNEL_SOCKET_H #define __ZEBRA_KERNEL_SOCKET_H
/* Error codes of zebra. */
#define ZEBRA_ERR_NOERROR 0
#define ZEBRA_ERR_RTEXIST -1
#define ZEBRA_ERR_RTUNREACH -2
#define ZEBRA_ERR_EPERM -3
#define ZEBRA_ERR_RTNOEXIST -4
#define ZEBRA_ERR_KERNEL -5
extern void rtm_read (struct rt_msghdr *); extern void rtm_read (struct rt_msghdr *);
extern int ifam_read (struct ifa_msghdr *); extern int ifam_read (struct ifa_msghdr *);
extern int ifm_read (struct if_msghdr *); extern int ifm_read (struct if_msghdr *);

View File

@ -349,10 +349,10 @@ extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *, extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *,
struct rib *); struct rib *);
extern int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, extern void rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p, u_short instance, int flags, struct prefix *p,
union g_addr *gate, ifindex_t ifindex, union g_addr *gate, ifindex_t ifindex,
u_int32_t table_id); u_int32_t table_id);
extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *, extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *,
struct route_node **rn_out); struct route_node **rn_out);

View File

@ -347,10 +347,10 @@ nexthop_has_fib_child(struct nexthop *nexthop)
/* If force flag is not set, do not modify falgs at all for uninstall /* If force flag is not set, do not modify falgs at all for uninstall
the route from FIB. */ the route from FIB. */
static int static int
nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, nexthop_active (afi_t afi, struct rib *rib, struct nexthop *nexthop, int set,
struct route_node *top) struct route_node *top)
{ {
struct prefix_ipv4 p; struct prefix p;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *match; struct rib *match;
@ -360,7 +360,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
int recursing = 0; int recursing = 0;
struct interface *ifp; struct interface *ifp;
if (nexthop->type == NEXTHOP_TYPE_IPV4) if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6)
nexthop->ifindex = 0; nexthop->ifindex = 0;
if (set) if (set)
@ -398,13 +398,25 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
} }
/* Make lookup prefix. */ /* Make lookup prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4)); memset (&p, 0, sizeof (struct prefix));
p.family = AF_INET; switch (afi)
p.prefixlen = IPV4_MAX_PREFIXLEN; {
p.prefix = nexthop->gate.ipv4; case AFI_IP:
p.family = AF_INET;
p.prefixlen = IPV4_MAX_PREFIXLEN;
p.u.prefix4 = nexthop->gate.ipv4;
break;
case AFI_IP6:
p.family = AF_INET6;
p.prefixlen = IPV6_MAX_PREFIXLEN;
p.u.prefix6 = nexthop->gate.ipv6;
break;
default:
assert (afi != AFI_IP && afi != AFI_IP6);
break;
}
/* Lookup table. */ /* Lookup table. */
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id); table = zebra_vrf_table (afi, SAFI_UNICAST, rib->vrf_id);
if (! table) if (! table)
return 0; return 0;
@ -457,9 +469,12 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
{ {
/* Directly point connected route. */ /* Directly point connected route. */
newhop = match->nexthop; newhop = match->nexthop;
if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4) if (newhop)
nexthop->ifindex = newhop->ifindex; {
if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
nexthop->type == NEXTHOP_TYPE_IPV6)
nexthop->ifindex = newhop->ifindex;
}
return 1; return 1;
} }
else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL)) else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
@ -491,6 +506,18 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
} }
} }
if (newhop->type == NEXTHOP_TYPE_IPV6
|| newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
{
resolved_hop->type = newhop->type;
resolved_hop->gate.ipv6 = newhop->gate.ipv6;
if (newhop->ifindex)
{
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->ifindex = newhop->ifindex;
}
}
/* If the resolving route is an interface route, /* If the resolving route is an interface route,
* it means the gateway we are looking up is connected * it means the gateway we are looking up is connected
@ -503,8 +530,16 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
if (newhop->type == NEXTHOP_TYPE_IFINDEX) if (newhop->type == NEXTHOP_TYPE_IFINDEX)
{ {
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; if (afi == AFI_IP)
resolved_hop->gate.ipv4 = nexthop->gate.ipv4; {
resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
}
else if (afi == AFI_IP6)
{
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
}
resolved_hop->ifindex = newhop->ifindex; resolved_hop->ifindex = newhop->ifindex;
} }
@ -541,6 +576,18 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
} }
} }
if (newhop->type == NEXTHOP_TYPE_IPV6
|| newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
{
resolved_hop->type = newhop->type;
resolved_hop->gate.ipv6 = newhop->gate.ipv6;
if (newhop->ifindex)
{
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->ifindex = newhop->ifindex;
}
}
/* If the resolving route is an interface route, /* If the resolving route is an interface route,
* it means the gateway we are looking up is connected * it means the gateway we are looking up is connected
@ -554,8 +601,16 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
if (newhop->type == NEXTHOP_TYPE_IFINDEX) if (newhop->type == NEXTHOP_TYPE_IFINDEX)
{ {
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; if (afi == AFI_IP)
resolved_hop->gate.ipv4 = nexthop->gate.ipv4; {
resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
}
else if (afi == AFI_IP6)
{
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
}
resolved_hop->ifindex = newhop->ifindex; resolved_hop->ifindex = newhop->ifindex;
} }
@ -576,193 +631,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
return 0; return 0;
} }
/* If force flag is not set, do not modify falgs at all for uninstall
the route from FIB. */
static int
nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
struct route_node *top)
{
struct prefix_ipv6 p;
struct route_table *table;
struct route_node *rn;
struct rib *match;
int resolved;
struct nexthop *newhop, *tnewhop;
int recursing = 0;
struct nexthop *resolved_hop;
if (nexthop->type == NEXTHOP_TYPE_IPV6)
nexthop->ifindex = 0;
if (set)
{
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top);
nexthops_free(nexthop->resolved);
nexthop->resolved = NULL;
}
/* Skip nexthops that have been filtered out due to route-map */
/* The nexthops are specific to this route and so the same */
/* nexthop for a different route may not have this flag set */
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED))
return 0;
/* Make lookup prefix. */
memset (&p, 0, sizeof (struct prefix_ipv6));
p.family = AF_INET6;
p.prefixlen = IPV6_MAX_PREFIXLEN;
p.prefix = nexthop->gate.ipv6;
/* Lookup table. */
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
if (! table)
return 0;
rn = route_node_match (table, (struct prefix *) &p);
while (rn)
{
route_unlock_node (rn);
/* If lookup self prefix return immediately. */
if (rn == top)
return 0;
/* Pick up selected route. */
/* However, do not resolve over default route unless explicitly allowed. */
if (is_default_prefix (&rn->p) &&
!nh_resolve_via_default (p.family))
return 0;
RNODE_FOREACH_RIB (rn, match)
{
if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
continue;
if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
break;
}
/* If there is no selected route or matched route is EGP, go up
tree. */
if (! match)
{
do {
rn = rn->parent;
} while (rn && rn->info == NULL);
if (rn)
route_lock_node (rn);
}
else
{
/* If the longest prefix match for the nexthop yields
* a blackhole, mark it as inactive. */
if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
|| CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
return 0;
if (match->type == ZEBRA_ROUTE_CONNECT)
{
/* Directly point connected route. */
newhop = match->nexthop;
if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
nexthop->ifindex = newhop->ifindex;
return 1;
}
else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
{
resolved = 0;
for (newhop = match->nexthop; newhop; newhop = newhop->next)
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
&& ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
{
if (set)
{
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
resolved_hop = nexthop_new();
SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
/* See nexthop_active_ipv4 for a description how the
* resolved nexthop is constructed. */
if (newhop->type == NEXTHOP_TYPE_IPV6
|| newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
{
resolved_hop->type = newhop->type;
resolved_hop->gate.ipv6 = newhop->gate.ipv6;
if (newhop->ifindex)
{
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->ifindex = newhop->ifindex;
}
}
if (newhop->type == NEXTHOP_TYPE_IFINDEX)
{
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
resolved_hop->ifindex = newhop->ifindex;
}
nexthop_add(&nexthop->resolved, resolved_hop);
}
resolved = 1;
}
return resolved;
}
else if (rib->type == ZEBRA_ROUTE_STATIC)
{
resolved = 0;
for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
{
if (set)
{
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
resolved_hop = nexthop_new();
SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
/* See nexthop_active_ipv4 for a description how the
* resolved nexthop is constructed. */
if (newhop->type == NEXTHOP_TYPE_IPV6
|| newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
{
resolved_hop->type = newhop->type;
resolved_hop->gate.ipv6 = newhop->gate.ipv6;
if (newhop->ifindex)
{
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->ifindex = newhop->ifindex;
}
}
if (newhop->type == NEXTHOP_TYPE_IFINDEX)
{
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
resolved_hop->ifindex = newhop->ifindex;
}
nexthop_add(&nexthop->resolved, resolved_hop);
}
resolved = 1;
}
return resolved;
}
else
{
return 0;
}
}
}
return 0;
}
struct rib * struct rib *
rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id, rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id,
union g_addr *addr, struct route_node **rn_out) union g_addr *addr, struct route_node **rn_out)
@ -1075,14 +943,14 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
family = AFI_IP; family = AFI_IP;
if (nexthop_active_ipv4 (rib, nexthop, set, rn)) if (nexthop_active (AFI_IP, rib, nexthop, set, rn))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
family = AFI_IP6; family = AFI_IP6;
if (nexthop_active_ipv6 (rib, nexthop, set, rn)) if (nexthop_active (AFI_IP6, rib, nexthop, set, rn))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@ -1101,7 +969,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
} }
else else
{ {
if (nexthop_active_ipv6 (rib, nexthop, set, rn)) if (nexthop_active (AFI_IP6, rib, nexthop, set, rn))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@ -1802,181 +1670,6 @@ rib_process (struct route_node *rn)
} }
} }
#if 0
if (select && select == fib)
{
if (IS_ZEBRA_DEBUG_RIB)
rnode_debug (rn, vrf_id, "Updating existing route, select %p, fib %p",
(void *)select, (void *)fib);
if (CHECK_FLAG (select->status, RIB_ENTRY_CHANGED))
{
if (info->safi == SAFI_UNICAST)
zfpm_trigger_update (rn, "updating existing route");
/* Set real nexthop. */
/* Need to check if any NHs are active to clear the
* the selected flag
*/
if (nexthop_active_update (rn, select, 1))
{
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
if (! RIB_SYSTEM_ROUTE (select))
{
/* Clear FIB flag if performing a replace, will get set again
* as part of install.
*/
for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
rib_install_kernel (rn, select, 1);
}
/* assuming that the receiver knows how to dedup */
redistribute_update (&rn->p, select, NULL);
}
else
{
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
"- nexthop inactive",
vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
/* Withdraw unreachable redistribute route */
redistribute_delete(&rn->p, select);
/* Do the uninstall here, if not done earlier. */
if (! RIB_SYSTEM_ROUTE (select))
rib_uninstall_kernel (rn, select);
UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
}
UNSET_FLAG (select->status, RIB_ENTRY_CHANGED);
}
else if (! RIB_SYSTEM_ROUTE (select))
{
/* Housekeeping code to deal with
race conditions in kernel with linux
netlink reporting interface up before IPv4 or IPv6 protocol
is ready to add routes.
This makes sure the routes are IN the kernel.
*/
for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{
installed = 1;
break;
}
if (! installed)
rib_install_kernel (rn, select, 0);
}
goto end;
}
/* At this point we either haven't found the best RIB entry or it is
* different from what we currently intend to flag with SELECTED. In both
* cases, if a RIB block is present in FIB, it should be withdrawn.
*/
if (fib)
{
if (IS_ZEBRA_DEBUG_RIB)
rnode_debug (rn, vrf_id, "Removing existing route, fib %p", (void *)fib);
if (info->safi == SAFI_UNICAST)
zfpm_trigger_update (rn, "removing existing route");
/* If there's no route to replace this with, withdraw redistribute and
* uninstall from kernel.
*/
if (!select)
{
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type);
redistribute_delete(&rn->p, fib);
if (! RIB_SYSTEM_ROUTE (fib))
rib_uninstall_kernel (rn, fib);
}
UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
/* Set real nexthop. */
nexthop_active_update (rn, fib, 1);
UNSET_FLAG(fib->status, RIB_ENTRY_CHANGED);
}
/* Regardless of some RIB entry being SELECTED or not before, now we can
* tell, that if a new winner exists, FIB is still not updated with this
* data, but ready to be.
*/
if (select)
{
if (IS_ZEBRA_DEBUG_RIB)
rnode_debug (rn, "Adding route, select %p", (void *)select);
if (info->safi == SAFI_UNICAST)
zfpm_trigger_update (rn, "new route selected");
/* Set real nexthop. */
if (nexthop_active_update (rn, select, 1))
{
if (IS_ZEBRA_DEBUG_RIB)
{
if (fib)
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
"old %p (type %d)", vrf_id, buf, rn->p.prefixlen, rn,
select, select->type, fib, fib->type);
else
zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
}
if (! RIB_SYSTEM_ROUTE (select))
{
/* Clear FIB flag if performing a replace, will get set again
* as part of install.
*/
if (fib)
{
for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
}
rib_install_kernel (rn, select, fib? 1 : 0);
}
else
{
/* Uninstall prior route here, if needed. */
if (fib && !RIB_SYSTEM_ROUTE (fib))
rib_uninstall_kernel (rn, fib);
}
SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
/* Unconditionally announce, this part is exercised by new routes */
/* If we cannot add, for example route added is learnt by the */
/* protocol we're trying to redistribute to, delete the redist */
/* This is notified by setting the is_update to 1 */
redistribute_update (&rn->p, select, fib);
}
else
{
/* Uninstall prior route here and do redist delete, if needed. */
if (fib)
{
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
"- nexthop inactive",
vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type);
if (!RIB_SYSTEM_ROUTE (fib))
rib_uninstall_kernel (rn, fib);
redistribute_delete(&rn->p, fib);
}
}
UNSET_FLAG(select->status, RIB_ENTRY_CHANGED);
}
#endif
/* Remove all RIB entries queued for removal */ /* Remove all RIB entries queued for removal */
RNODE_FOREACH_RIB_SAFE (rn, rib, next) RNODE_FOREACH_RIB_SAFE (rn, rib, next)
{ {
@ -2672,7 +2365,7 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
return ret; return ret;
} }
int void
rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex, int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex,
u_int32_t table_id) u_int32_t table_id)
@ -2690,7 +2383,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
/* Lookup table. */ /* Lookup table. */
table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id); table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id);
if (! table) if (! table)
return 0; return;
/* Apply mask. */ /* Apply mask. */
apply_mask (p); apply_mask (p);
@ -2702,7 +2395,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
zlog_debug ("%u:%s: doesn't exist in rib", zlog_debug ("%u:%s: doesn't exist in rib",
vrf_id, prefix2str (p, buf1, sizeof(buf1))); vrf_id, prefix2str (p, buf1, sizeof(buf1)));
return ZEBRA_ERR_RTNOEXIST; return;
} }
/* Lookup same type route. */ /* Lookup same type route. */
@ -2728,7 +2421,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
rib->refcnt--; rib->refcnt--;
route_unlock_node (rn); route_unlock_node (rn);
route_unlock_node (rn); route_unlock_node (rn);
return 0; return;
} }
same = rib; same = rib;
break; break;
@ -2799,7 +2492,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
type); type);
} }
route_unlock_node (rn); route_unlock_node (rn);
return ZEBRA_ERR_RTNOEXIST; return;
} }
} }
@ -2807,7 +2500,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
rib_delnode (rn, same); rib_delnode (rn, same);
route_unlock_node (rn); route_unlock_node (rn);
return 0; return;
} }

View File

@ -878,6 +878,7 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
} }
if (rib) if (rib)
{ {
stream_putc (s, rib->distance);
stream_putl (s, rib->metric); stream_putl (s, rib->metric);
num = 0; num = 0;
nump = stream_get_endp(s); nump = stream_get_endp(s);
@ -917,8 +918,9 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
} }
else else
{ {
stream_putl (s, 0); stream_putc (s, 0); // distance
stream_putc (s, 0); stream_putl (s, 0); // metric
stream_putc (s, 0); // nexthops
} }
stream_putw_at (s, 0, stream_get_endp (s)); stream_putw_at (s, 0, stream_get_endp (s));