Merge remote-tracking branch 'frr/master' into pull-624

This commit is contained in:
David Lamparter 2017-06-13 09:18:14 +02:00
commit 97bd5c48de
92 changed files with 2809 additions and 2972 deletions

1
.gitignore vendored
View File

@ -74,3 +74,4 @@ GRTAGS
GPATH GPATH
*.la *.la
*.lo *.lo
compile_commands.json

View File

@ -40,8 +40,6 @@
#include "bgpd/bgp_updgrp.h" #include "bgpd/bgp_updgrp.h"
#include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_mplsvpn.h"
#define BGP_ADDPATH_STR 20
unsigned long conf_bgp_debug_as4; unsigned long conf_bgp_debug_as4;
unsigned long conf_bgp_debug_neighbor_events; unsigned long conf_bgp_debug_neighbor_events;
unsigned long conf_bgp_debug_events; unsigned long conf_bgp_debug_events;
@ -2139,7 +2137,12 @@ bgp_debug_rdpfxpath2str (struct prefix_rd *prd, union prefixconstptr pu,
{ {
char rd_buf[RD_ADDRSTRLEN]; char rd_buf[RD_ADDRSTRLEN];
char pfx_buf[PREFIX_STRLEN]; char pfx_buf[PREFIX_STRLEN];
char pathid_buf[BGP_ADDPATH_STR]; /* ' with addpath ID ' 17
* max strlen of uint32 + 10
* +/- (just in case) + 1
* null terminator + 1
* ============================ 29 */
char pathid_buf[30];
if (size < BGP_PRD_PATH_STRLEN) if (size < BGP_PRD_PATH_STRLEN)
return NULL; return NULL;
@ -2147,7 +2150,7 @@ bgp_debug_rdpfxpath2str (struct prefix_rd *prd, union prefixconstptr pu,
/* Note: Path-id is created by default, but only included in update sometimes. */ /* Note: Path-id is created by default, but only included in update sometimes. */
pathid_buf[0] = '\0'; pathid_buf[0] = '\0';
if (addpath_valid) if (addpath_valid)
sprintf(pathid_buf, " with addpath ID %d", addpath_id); snprintf(pathid_buf, sizeof(pathid_buf), " with addpath ID %u", addpath_id);
if (prd) if (prd)
snprintf (str, size, "RD %s %s%s", snprintf (str, size, "RD %s %s%s",

View File

@ -1455,7 +1455,7 @@ subgroup_announce_check (struct bgp_node *rn, struct bgp_info *ri,
#define NEXTHOP_IS_V6 (\ #define NEXTHOP_IS_V6 (\
(safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\ (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
(p->family == AF_INET6 || peer_cap_enhe(peer, AFI_IP6, safi))) || \ (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) || \
((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\ ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN)) attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
@ -5017,7 +5017,7 @@ DEFUN (bgp_network_mask_natural_backdoor,
DEFUN (bgp_network_label_index, DEFUN (bgp_network_label_index,
bgp_network_label_index_cmd, bgp_network_label_index_cmd,
"network A.B.C.D/M label-index (0-4294967294)", "network A.B.C.D/M label-index (0-1048560)",
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Label index to associate with the prefix\n" "Label index to associate with the prefix\n"
@ -5032,7 +5032,7 @@ DEFUN (bgp_network_label_index,
DEFUN (bgp_network_label_index_route_map, DEFUN (bgp_network_label_index_route_map,
bgp_network_label_index_route_map_cmd, bgp_network_label_index_route_map_cmd,
"network A.B.C.D/M label-index (0-4294967294) route-map WORD", "network A.B.C.D/M label-index (0-1048560) route-map WORD",
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IP prefix\n" "IP prefix\n"
"Label index to associate with the prefix\n" "Label index to associate with the prefix\n"
@ -5117,7 +5117,7 @@ DEFUN (no_bgp_network_mask_natural,
ALIAS (no_bgp_network, ALIAS (no_bgp_network,
no_bgp_network_label_index_cmd, no_bgp_network_label_index_cmd,
"no network A.B.C.D/M label-index (0-4294967294)", "no network A.B.C.D/M label-index (0-1048560)",
NO_STR NO_STR
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
@ -5126,7 +5126,7 @@ ALIAS (no_bgp_network,
ALIAS (no_bgp_network, ALIAS (no_bgp_network,
no_bgp_network_label_index_route_map_cmd, no_bgp_network_label_index_route_map_cmd,
"no network A.B.C.D/M label-index (0-4294967294) route-map WORD", "no network A.B.C.D/M label-index (0-1048560) route-map WORD",
NO_STR NO_STR
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IP prefix\n" "IP prefix\n"
@ -5164,7 +5164,7 @@ DEFUN (ipv6_bgp_network_route_map,
DEFUN (ipv6_bgp_network_label_index, DEFUN (ipv6_bgp_network_label_index,
ipv6_bgp_network_label_index_cmd, ipv6_bgp_network_label_index_cmd,
"network X:X::X:X/M label-index (0-4294967294)", "network X:X::X:X/M label-index (0-1048560)",
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IPv6 prefix <network>/<length>\n" "IPv6 prefix <network>/<length>\n"
"Label index to associate with the prefix\n" "Label index to associate with the prefix\n"
@ -5179,7 +5179,7 @@ DEFUN (ipv6_bgp_network_label_index,
DEFUN (ipv6_bgp_network_label_index_route_map, DEFUN (ipv6_bgp_network_label_index_route_map,
ipv6_bgp_network_label_index_route_map_cmd, ipv6_bgp_network_label_index_route_map_cmd,
"network X:X::X:X/M label-index (0-4294967294) route-map WORD", "network X:X::X:X/M label-index (0-1048560) route-map WORD",
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IPv6 prefix\n" "IPv6 prefix\n"
"Label index to associate with the prefix\n" "Label index to associate with the prefix\n"
@ -5209,7 +5209,7 @@ DEFUN (no_ipv6_bgp_network,
ALIAS (no_ipv6_bgp_network, ALIAS (no_ipv6_bgp_network,
no_ipv6_bgp_network_label_index_cmd, no_ipv6_bgp_network_label_index_cmd,
"no network X:X::X:X/M label-index (0-4294967294)", "no network X:X::X:X/M label-index (0-1048560)",
NO_STR NO_STR
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IPv6 prefix <network>/<length>\n" "IPv6 prefix <network>/<length>\n"
@ -5218,7 +5218,7 @@ ALIAS (no_ipv6_bgp_network,
ALIAS (no_ipv6_bgp_network, ALIAS (no_ipv6_bgp_network,
no_ipv6_bgp_network_label_index_route_map_cmd, no_ipv6_bgp_network_label_index_route_map_cmd,
"no network X:X::X:X/M label-index (0-4294967294) route-map WORD", "no network X:X::X:X/M label-index (0-1048560) route-map WORD",
NO_STR NO_STR
"Specify a network to announce via BGP\n" "Specify a network to announce via BGP\n"
"IPv6 prefix\n" "IPv6 prefix\n"
@ -10988,10 +10988,10 @@ bgp_route_init (void)
install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd); install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd); install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_cmd); install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_label_index_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd); install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_label_index_cmd);
install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_route_map_cmd); install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_label_index_route_map_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd); install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd);
install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd); install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);

View File

@ -2207,6 +2207,41 @@ static struct route_map_rule_cmd route_set_tag_cmd =
route_map_rule_tag_free, route_map_rule_tag_free,
}; };
/* Set label-index to object. object must be pointer to struct bgp_info */
static route_map_result_t
route_set_label_index (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
struct bgp_info *bgp_info;
u_int32_t label_index;
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
rv = rule;
bgp_info = object;
/* Set label-index value. */
label_index = rv->value;
if (label_index)
{
(bgp_attr_extra_get (bgp_info->attr))->label_index = label_index;
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
}
}
return RMAP_OKAY;
}
/* Route map commands for label-index set. */
static struct route_map_rule_cmd route_set_label_index_cmd =
{
"label-index",
route_set_label_index,
route_value_compile,
route_value_free,
};
/* `match ipv6 address IP_ACCESS_LIST' */ /* `match ipv6 address IP_ACCESS_LIST' */
@ -3654,6 +3689,33 @@ DEFUN (no_set_weight,
argv[idx_weight]->arg); argv[idx_weight]->arg);
} }
DEFUN (set_label_index,
set_label_index_cmd,
"set label-index (0-1048560)",
SET_STR
"Label index to associate with the prefix\n"
"Label index value\n")
{
int idx_number = 2;
return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "label-index",
argv[idx_number]->arg);
}
DEFUN (no_set_label_index,
no_set_label_index_cmd,
"no set label-index [(0-1048560)]",
NO_STR
SET_STR
"Label index to associate with the prefix\n"
"Label index value\n")
{
int idx_label_index = 3;
if (argc <= idx_label_index)
return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
"label-index", NULL);
return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), "label-index",
argv[idx_label_index]->arg);
}
DEFUN (set_aspath_prepend_asn, DEFUN (set_aspath_prepend_asn,
set_aspath_prepend_asn_cmd, set_aspath_prepend_asn_cmd,
@ -4549,6 +4611,7 @@ bgp_route_map_init (void)
route_map_install_set (&route_set_ip_nexthop_cmd); route_map_install_set (&route_set_ip_nexthop_cmd);
route_map_install_set (&route_set_local_pref_cmd); route_map_install_set (&route_set_local_pref_cmd);
route_map_install_set (&route_set_weight_cmd); route_map_install_set (&route_set_weight_cmd);
route_map_install_set (&route_set_label_index_cmd);
route_map_install_set (&route_set_metric_cmd); route_map_install_set (&route_set_metric_cmd);
route_map_install_set (&route_set_aspath_prepend_cmd); route_map_install_set (&route_set_aspath_prepend_cmd);
route_map_install_set (&route_set_aspath_exclude_cmd); route_map_install_set (&route_set_aspath_exclude_cmd);
@ -4565,6 +4628,7 @@ bgp_route_map_init (void)
route_map_install_set (&route_set_ecommunity_rt_cmd); route_map_install_set (&route_set_ecommunity_rt_cmd);
route_map_install_set (&route_set_ecommunity_soo_cmd); route_map_install_set (&route_set_ecommunity_soo_cmd);
route_map_install_set (&route_set_tag_cmd); route_map_install_set (&route_set_tag_cmd);
route_map_install_set (&route_set_label_index_cmd);
install_element (RMAP_NODE, &match_peer_cmd); install_element (RMAP_NODE, &match_peer_cmd);
install_element (RMAP_NODE, &match_peer_local_cmd); install_element (RMAP_NODE, &match_peer_local_cmd);
@ -4594,7 +4658,9 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &set_local_pref_cmd); install_element (RMAP_NODE, &set_local_pref_cmd);
install_element (RMAP_NODE, &no_set_local_pref_cmd); install_element (RMAP_NODE, &no_set_local_pref_cmd);
install_element (RMAP_NODE, &set_weight_cmd); install_element (RMAP_NODE, &set_weight_cmd);
install_element (RMAP_NODE, &set_label_index_cmd);
install_element (RMAP_NODE, &no_set_weight_cmd); install_element (RMAP_NODE, &no_set_weight_cmd);
install_element (RMAP_NODE, &no_set_label_index_cmd);
install_element (RMAP_NODE, &set_aspath_prepend_asn_cmd); install_element (RMAP_NODE, &set_aspath_prepend_asn_cmd);
install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd); install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
install_element (RMAP_NODE, &set_aspath_exclude_cmd); install_element (RMAP_NODE, &set_aspath_exclude_cmd);

View File

@ -1169,8 +1169,8 @@ update_subgroup_trigger_merge_check (struct update_subgroup *subgrp,
return 0; return 0;
subgrp->t_merge_check = NULL; subgrp->t_merge_check = NULL;
thread_add_background(bm->master, update_subgroup_merge_check_thread_cb, subgrp, 0, thread_add_timer_msec (bm->master, update_subgroup_merge_check_thread_cb, subgrp,
&subgrp->t_merge_check); 0, &subgrp->t_merge_check);
SUBGRP_INCR_STAT (subgrp, merge_checks_triggered); SUBGRP_INCR_STAT (subgrp, merge_checks_triggered);

View File

@ -651,17 +651,6 @@ subgroup_packets_to_build (struct update_subgroup *subgrp)
return 0; return 0;
} }
static void
bgp_info_addpath_tx_str (int addpath_encode, u_int32_t addpath_tx_id,
char *buf)
{
buf[0] = '\0';
if (addpath_encode)
sprintf(buf, " with addpath ID %d", addpath_tx_id);
else
buf[0] = '\0';
}
/* Make BGP update packet. */ /* Make BGP update packet. */
struct bpacket * struct bpacket *
subgroup_update_packet (struct update_subgroup *subgrp) subgroup_update_packet (struct update_subgroup *subgrp)
@ -1079,11 +1068,21 @@ subgroup_default_update_packet (struct update_subgroup *subgrp,
{ {
char attrstr[BUFSIZ]; char attrstr[BUFSIZ];
char buf[PREFIX_STRLEN]; char buf[PREFIX_STRLEN];
/* ' with addpath ID ' 17
* max strlen of uint32 + 10
* +/- (just in case) + 1
* null terminator + 1
* ============================ 29 */
char tx_id_buf[30]; char tx_id_buf[30];
attrstr[0] = '\0'; attrstr[0] = '\0';
bgp_dump_attr (attr, attrstr, BUFSIZ); bgp_dump_attr (attr, attrstr, BUFSIZ);
bgp_info_addpath_tx_str (addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, tx_id_buf);
if (addpath_encode)
snprintf(tx_id_buf, sizeof (tx_id_buf), " with addpath ID %u",
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s", zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s",
(SUBGRP_UPDGRP (subgrp))->id, subgrp->id, (SUBGRP_UPDGRP (subgrp))->id, subgrp->id,
prefix2str (&p, buf, sizeof (buf)), prefix2str (&p, buf, sizeof (buf)),
@ -1153,9 +1152,17 @@ subgroup_default_withdraw_packet (struct update_subgroup *subgrp)
if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) if (bgp_debug_update(NULL, &p, subgrp->update_group, 0))
{ {
char buf[PREFIX_STRLEN]; char buf[PREFIX_STRLEN];
char tx_id_buf[INET6_BUFSIZ]; /* ' with addpath ID ' 17
* max strlen of uint32 + 10
* +/- (just in case) + 1
* null terminator + 1
* ============================ 29 */
char tx_id_buf[30];
if (addpath_encode)
snprintf(tx_id_buf, sizeof (tx_id_buf), " with addpath ID %u",
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
bgp_info_addpath_tx_str (addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, tx_id_buf);
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s -- unreachable", zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s -- unreachable",
(SUBGRP_UPDGRP (subgrp))->id, subgrp->id, (SUBGRP_UPDGRP (subgrp))->id, subgrp->id,
prefix2str (&p, buf, sizeof (buf)), tx_id_buf); prefix2str (&p, buf, sizeof (buf)), tx_id_buf);

View File

@ -12244,6 +12244,7 @@ lcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
return CMD_WARNING; return CMD_WARNING;
} }
idx = 0;
argv_find (argv, argc, "AA:BB:CC", &idx); argv_find (argv, argc, "AA:BB:CC", &idx);
argv_find (argv, argc, "LINE", &idx); argv_find (argv, argc, "LINE", &idx);
/* Concat community string argument. */ /* Concat community string argument. */

View File

@ -3385,7 +3385,7 @@ DEFUN (vnc_vrf_policy_nexthop,
"Specify next hop to use for VRF advertised prefixes\n" "Specify next hop to use for VRF advertised prefixes\n"
"IPv4 prefix\n" "IPv4 prefix\n"
"IPv6 prefix\n" "IPv6 prefix\n"
"Use configured router-id (default)") "Use configured router-id (default)\n")
{ {
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
struct prefix p; struct prefix p;

View File

@ -3051,7 +3051,7 @@ rfapiBiStartWithdrawTimer (
lifetime_msec = (lifetime * 1000) + jitter; lifetime_msec = (lifetime * 1000) + jitter;
bi->extra->vnc.import.timer = NULL; bi->extra->vnc.import.timer = NULL;
thread_add_background(bm->master, timer_service_func, wcb, lifetime_msec, thread_add_timer_msec(bm->master, timer_service_func, wcb, lifetime_msec,
&bi->extra->vnc.import.timer); &bi->extra->vnc.import.timer);
} }

View File

@ -314,8 +314,6 @@ AC_ARG_ENABLE(fpm,
AS_HELP_STRING([--enable-fpm], [enable Forwarding Plane Manager support])) AS_HELP_STRING([--enable-fpm], [enable Forwarding Plane Manager support]))
AC_ARG_ENABLE(systemd, AC_ARG_ENABLE(systemd,
AS_HELP_STRING([--enable-systemd], [enable Systemd support])) AS_HELP_STRING([--enable-systemd], [enable Systemd support]))
AC_ARG_ENABLE(poll,
AS_HELP_STRING([--enable-poll], [enable usage of Poll instead of select]))
AC_ARG_ENABLE(werror, AC_ARG_ENABLE(werror,
AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)])) AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)]))
AC_ARG_ENABLE(cumulus, AC_ARG_ENABLE(cumulus,
@ -366,10 +364,6 @@ if test "${enable_rr_semantics}" != "no" ; then
AC_DEFINE(HAVE_V6_RR_SEMANTICS,, Compile in v6 Route Replacement Semantics) AC_DEFINE(HAVE_V6_RR_SEMANTICS,, Compile in v6 Route Replacement Semantics)
fi fi
if test "${enable_poll}" = "yes" ; then
AC_DEFINE(HAVE_POLL_CALL,,Compile systemd support in)
fi
dnl ---------- dnl ----------
dnl MPLS check dnl MPLS check
dnl ---------- dnl ----------
@ -1427,8 +1421,9 @@ dnl ---------------------------
dnl check system has PCRE regexp dnl check system has PCRE regexp
dnl --------------------------- dnl ---------------------------
if test "x$enable_pcreposix" = "xyes"; then if test "x$enable_pcreposix" = "xyes"; then
AC_CHECK_LIB(pcreposix, pcreposix_regexec, ,[enable_pcreposix=no AC_CHECK_LIB(pcreposix, regexec, [], [
AC_MSG_WARN([*** falling back to other regex library ***]) ]) AC_MSG_ERROR([--enable-pcreposix given but unable to find libpcreposix])
])
fi fi
AC_SUBST(HAVE_LIBPCREPOSIX) AC_SUBST(HAVE_LIBPCREPOSIX)

View File

@ -13,7 +13,7 @@ Add packages:
apt-get install git autoconf automake libtool make gawk libreadline-dev \ apt-get install git autoconf automake libtool make gawk libreadline-dev \
texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \ texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \
libjson0-dev flex python-pip libc-ares-dev python3-dev libjson0-dev flex python-pip libc-ares-dev python3-dev libxml2 libxml2-dev
Install newer bison from 14.04 package source (Ubuntu 12.04 package source Install newer bison from 14.04 package source (Ubuntu 12.04 package source
is too old) is too old)
@ -51,6 +51,11 @@ Install newer version of autoconf and automake:
sudo make install sudo make install
cd .. cd ..
Install XML::LibXML
sudo cpan
install XML::LibXML
Install pytest: Install pytest:
pip install pytest pip install pytest

View File

@ -252,7 +252,7 @@ rnh table:
struct rnh struct rnh
{ {
u_char flags; u_char flags;
struct rib *state; struct route_entry *state;
struct list *client_list; struct list *client_list;
struct route_node *node; struct route_node *node;
}; };

View File

@ -437,7 +437,6 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
struct lde_req *lre; struct lde_req *lre;
struct lde_map *me; struct lde_map *me;
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
int msgsource = 0;
lde_map2fec(map, ln->id, &fec); lde_map2fec(map, ln->id, &fec);
@ -538,18 +537,12 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
default: default:
break; break;
} }
msgsource = 1;
} }
/* LMp.13 & LMp.16: Record the mapping from this peer */ /* LMp.13 & LMp.16: Record the mapping from this peer */
if (me == NULL) if (me == NULL)
me = lde_map_add(ln, fn, 0); me = lde_map_add(ln, fn, 0);
me->map = *map; me->map = *map;
if (msgsource == 0)
/* LMp.13: just return since we use liberal lbl retention */
return;
/* /*
* LMp.17 - LMp.27 are unnecessary since we don't need to implement * LMp.17 - LMp.27 are unnecessary since we don't need to implement
* loop detection. LMp.28 - LMp.30 are unnecessary because we are * loop detection. LMp.28 - LMp.30 are unnecessary because we are

View File

@ -431,7 +431,7 @@ ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[])
vty_conf->flags |= F_LDPD_ENABLED; vty_conf->flags |= F_LDPD_ENABLED;
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -458,7 +458,7 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
if (disable) { if (disable) {
af_conf->flags &= ~F_LDPD_AF_ENABLED; af_conf->flags &= ~F_LDPD_AF_ENABLED;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -474,7 +474,7 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
} }
af_conf->flags |= F_LDPD_AF_ENABLED; af_conf->flags |= F_LDPD_AF_ENABLED;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -530,7 +530,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
break; break;
} }
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
break; break;
case LDP_IPV4_NODE: case LDP_IPV4_NODE:
case LDP_IPV6_NODE: case LDP_IPV6_NODE:
@ -556,7 +556,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
break; break;
} }
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
break; break;
case LDP_IPV4_IFACE_NODE: case LDP_IPV4_IFACE_NODE:
case LDP_IPV6_IFACE_NODE: case LDP_IPV6_IFACE_NODE:
@ -570,7 +570,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
else else
ia->hello_holdtime = secs; ia->hello_holdtime = secs;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
break; break;
default: default:
fatalx("ldp_vty_disc_holdtime: unexpected node"); fatalx("ldp_vty_disc_holdtime: unexpected node");
@ -631,7 +631,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
break; break;
} }
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
break; break;
case LDP_IPV4_NODE: case LDP_IPV4_NODE:
case LDP_IPV6_NODE: case LDP_IPV6_NODE:
@ -657,7 +657,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
break; break;
} }
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
break; break;
case LDP_IPV4_IFACE_NODE: case LDP_IPV4_IFACE_NODE:
case LDP_IPV6_IFACE_NODE: case LDP_IPV6_IFACE_NODE:
@ -671,7 +671,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
else else
ia->hello_interval = secs; ia->hello_interval = secs;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
break; break;
default: default:
fatalx("ldp_vty_disc_interval: unexpected node"); fatalx("ldp_vty_disc_interval: unexpected node");
@ -706,7 +706,7 @@ ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[])
af_conf->acl_thello_accept_from[0] = '\0'; af_conf->acl_thello_accept_from[0] = '\0';
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -758,7 +758,7 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
nbrp->flags |= F_NBRP_KEEPALIVE; nbrp->flags |= F_NBRP_KEEPALIVE;
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -790,7 +790,7 @@ ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[])
else else
af_conf->keepalive = secs; af_conf->keepalive = secs;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -836,7 +836,7 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
ia->hello_holdtime = 0; ia->hello_holdtime = 0;
ia->hello_interval = 0; ia->hello_interval = 0;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -854,12 +854,12 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
RB_INSERT(iface_head, &vty_conf->iface_tree, iface); RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
QOBJ_REG(iface, iface); QOBJ_REG(iface, iface);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
} else { } else {
ia = iface_af_get(iface, af); ia = iface_af_get(iface, af);
if (!ia->enabled) { if (!ia->enabled) {
ia->enabled = 1; ia->enabled = 1;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
} }
} }
@ -901,7 +901,7 @@ ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[])
} }
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -940,7 +940,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr); RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
free(tnbr); free(tnbr);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -953,7 +953,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr); RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr);
QOBJ_REG(tnbr, tnbr); QOBJ_REG(tnbr, tnbr);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -990,7 +990,7 @@ ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[])
af_conf->acl_label_advertise_for[0] = '\0'; af_conf->acl_label_advertise_for[0] = '\0';
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1021,7 +1021,7 @@ ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[])
sizeof(af_conf->acl_label_allocate_for)); sizeof(af_conf->acl_label_allocate_for));
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1052,7 +1052,7 @@ ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[])
af_conf->acl_label_expnull_for[0] = '\0'; af_conf->acl_label_expnull_for[0] = '\0';
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1089,7 +1089,7 @@ ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[])
af_conf->acl_label_accept_for[0] = '\0'; af_conf->acl_label_accept_for[0] = '\0';
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1111,7 +1111,7 @@ ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[])
else else
af_conf->flags |= F_LDPD_AF_NO_GTSM; af_conf->flags |= F_LDPD_AF_NO_GTSM;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1135,7 +1135,7 @@ ldp_vty_router_id(struct vty *vty, struct vty_arg *args[])
} }
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1152,7 +1152,7 @@ ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[])
else else
vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP; vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1169,7 +1169,7 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[])
else else
vty_conf->trans_pref = DUAL_STACK_LDPOV4; vty_conf->trans_pref = DUAL_STACK_LDPOV4;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1220,7 +1220,7 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
nbrp->auth.method = AUTH_MD5SIG; nbrp->auth.method = AUTH_MD5SIG;
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1280,7 +1280,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
nbrp->gtsm_enabled = 0; nbrp->gtsm_enabled = 0;
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1313,7 +1313,7 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn); RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
l2vpn_del(l2vpn); l2vpn_del(l2vpn);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1330,7 +1330,7 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn); VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1350,7 +1350,7 @@ ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
else else
strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname)); strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname));
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1378,7 +1378,7 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
else else
l2vpn->mtu = mtu; l2vpn->mtu = mtu;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1404,7 +1404,7 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
else else
l2vpn->pw_type = pw_type; l2vpn->pw_type = pw_type;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1430,7 +1430,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif); free(lif);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1447,7 +1447,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif); RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
QOBJ_REG(lif, l2vpn_if); QOBJ_REG(lif, l2vpn_if);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1476,7 +1476,7 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw); free(pw);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1498,7 +1498,7 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw); VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1522,7 +1522,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
pw->flags |= F_PW_CWORD_CONF; pw->flags |= F_PW_CWORD_CONF;
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1555,7 +1555,7 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
pw->flags |= F_PW_STATIC_NBR_ADDR; pw->flags |= F_PW_STATIC_NBR_ADDR;
} }
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1582,7 +1582,7 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
else else
pw->lsr_id = lsr_id; pw->lsr_id = lsr_id;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1610,7 +1610,7 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
else else
pw->pwid = pwid; pw->pwid = pwid;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
@ -1628,7 +1628,7 @@ ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
else else
pw->flags &= ~F_PW_STATUSTLV_CONF; pw->flags &= ~F_PW_STATUSTLV_CONF;
ldp_reload(vty_conf); ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }

View File

@ -53,6 +53,7 @@ static void main_imsg_send_net_sockets(int);
static void main_imsg_send_net_socket(int, enum socket_type); static void main_imsg_send_net_socket(int, enum socket_type);
static int main_imsg_send_config(struct ldpd_conf *); static int main_imsg_send_config(struct ldpd_conf *);
static void ldp_config_normalize(struct ldpd_conf *); static void ldp_config_normalize(struct ldpd_conf *);
static void ldp_config_reset(struct ldpd_conf *);
static void ldp_config_reset_main(struct ldpd_conf *); static void ldp_config_reset_main(struct ldpd_conf *);
static void ldp_config_reset_af(struct ldpd_conf *, int); static void ldp_config_reset_af(struct ldpd_conf *, int);
static void ldp_config_reset_l2vpns(struct ldpd_conf *); static void ldp_config_reset_l2vpns(struct ldpd_conf *);
@ -131,20 +132,13 @@ sighup(void)
{ {
log_info("SIGHUP received"); log_info("SIGHUP received");
/* reset vty_conf */
ldp_config_reset_main(vty_conf);
ldp_config_reset_l2vpns(vty_conf);
/* read configuration file without applying any changes */
global.sighup = 1;
vty_read_config(ldpd_di.config_file, config_default);
global.sighup = 0;
/* /*
* Apply the new configuration all at once, this way merge_config() * Do a full configuration reload. In other words, reset vty_conf
* will be the least disruptive as possible. * and build a new configuartion from scratch.
*/ */
ldp_reload(vty_conf); ldp_config_reset(vty_conf);
vty_read_config(ldpd_di.config_file, config_default);
ldp_config_apply(NULL, vty_conf);
} }
/* SIGINT / SIGTERM handler. */ /* SIGINT / SIGTERM handler. */
@ -324,22 +318,22 @@ main(int argc, char *argv[])
ldp_vty_init(); ldp_vty_init();
ldp_zebra_init(master); ldp_zebra_init(master);
/* create base configuration with sane defaults */
ldpd_conf = config_new_empty();
ldp_config_reset_main(ldpd_conf);
/* /*
* Create vty_conf as a duplicate of the main configuration. All * Create base configuration with sane defaults. All configuration
* configuration requests (e.g. CLI) act on vty_conf and then call * requests (e.g. CLI) act on vty_conf and then call ldp_config_apply()
* ldp_reload() to merge the changes into ldpd_conf. * to merge the changes into ldpd_conf, which contains the actual
* running configuration.
*/ */
ldpd_conf = config_new_empty();
vty_conf = config_new_empty(); vty_conf = config_new_empty();
ldp_config_reset_main(vty_conf);
QOBJ_REG(vty_conf, ldpd_conf); QOBJ_REG(vty_conf, ldpd_conf);
/* read configuration file and daemonize */ /* read configuration file and daemonize */
frr_config_fork(); frr_config_fork();
/* apply configuration */
ldp_config_apply(NULL, vty_conf);
/* setup pipes to children */ /* setup pipes to children */
if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL || if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
(iev_ldpe_sync = calloc(1, sizeof(struct imsgev))) == NULL || (iev_ldpe_sync = calloc(1, sizeof(struct imsgev))) == NULL ||
@ -406,8 +400,7 @@ ldpd_shutdown(void)
config_clear(ldpd_conf); config_clear(ldpd_conf);
ldp_config_reset_main(vty_conf); ldp_config_reset(vty_conf);
ldp_config_reset_l2vpns(vty_conf);
QOBJ_UNREG(vty_conf); QOBJ_UNREG(vty_conf);
free(vty_conf); free(vty_conf);
@ -952,9 +945,15 @@ main_imsg_send_config(struct ldpd_conf *xconf)
} }
int int
ldp_reload(struct ldpd_conf *xconf) ldp_config_apply(struct vty *vty, struct ldpd_conf *xconf)
{ {
if (global.sighup) /*
* When reading from a configuration file (startup and sighup), we
* call merge_config() only once after the whole config has been read.
* This is the optimal and least disruptive way to update the running
* configuration.
*/
if (vty && vty->type == VTY_FILE)
return (0); return (0);
ldp_config_normalize(xconf); ldp_config_normalize(xconf);
@ -1031,6 +1030,13 @@ ldp_config_normalize(struct ldpd_conf *xconf)
} }
} }
static void
ldp_config_reset(struct ldpd_conf *conf)
{
ldp_config_reset_main(conf);
ldp_config_reset_l2vpns(conf);
}
static void static void
ldp_config_reset_main(struct ldpd_conf *conf) ldp_config_reset_main(struct ldpd_conf *conf)
{ {
@ -1673,8 +1679,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
session_shutdown(nbr, S_SHUTDOWN, 0, 0); session_shutdown(nbr, S_SHUTDOWN, 0, 0);
} }
} }
if (ldpd_process == PROC_LDE_ENGINE && if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec)
!reset_nbr && reinstall_pwfec)
l2vpn_pw_exit(pw); l2vpn_pw_exit(pw);
pw->lsr_id = xp->lsr_id; pw->lsr_id = xp->lsr_id;
pw->af = xp->af; pw->af = xp->af;
@ -1696,8 +1701,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
pw->flags &= ~F_PW_STATIC_NBR_ADDR; pw->flags &= ~F_PW_STATIC_NBR_ADDR;
if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr) if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr)
ldpe_l2vpn_pw_init(pw); ldpe_l2vpn_pw_init(pw);
if (ldpd_process == PROC_LDE_ENGINE && if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec) {
!reset_nbr && reinstall_pwfec) {
l2vpn->pw_type = xl->pw_type; l2vpn->pw_type = xl->pw_type;
l2vpn->mtu = xl->mtu; l2vpn->mtu = xl->mtu;
l2vpn_pw_init(pw); l2vpn_pw_init(pw);
@ -1762,6 +1766,9 @@ config_new_empty(void)
RB_INIT(&xconf->nbrp_tree); RB_INIT(&xconf->nbrp_tree);
RB_INIT(&xconf->l2vpn_tree); RB_INIT(&xconf->l2vpn_tree);
/* set default values */
ldp_config_reset(xconf);
return (xconf); return (xconf);
} }

View File

@ -29,6 +29,7 @@
#include "qobj.h" #include "qobj.h"
#include "prefix.h" #include "prefix.h"
#include "filter.h" #include "filter.h"
#include "vty.h"
#include "ldp.h" #include "ldp.h"
@ -516,7 +517,6 @@ struct ldpd_af_global {
struct ldpd_global { struct ldpd_global {
int cmd_opts; int cmd_opts;
int sighup;
struct in_addr rtr_id; struct in_addr rtr_id;
struct ldpd_af_global ipv4; struct ldpd_af_global ipv4;
struct ldpd_af_global ipv6; struct ldpd_af_global ipv6;
@ -719,7 +719,7 @@ struct ldpd_af_conf *ldp_af_conf_get(struct ldpd_conf *, int);
struct ldpd_af_global *ldp_af_global_get(struct ldpd_global *, int); struct ldpd_af_global *ldp_af_global_get(struct ldpd_global *, int);
int ldp_is_dual_stack(struct ldpd_conf *); int ldp_is_dual_stack(struct ldpd_conf *);
in_addr_t ldp_rtr_id_get(struct ldpd_conf *); in_addr_t ldp_rtr_id_get(struct ldpd_conf *);
int ldp_reload(struct ldpd_conf *); int ldp_config_apply(struct vty *, struct ldpd_conf *);
void ldp_clear_config(struct ldpd_conf *); void ldp_clear_config(struct ldpd_conf *);
void merge_config(struct ldpd_conf *, struct ldpd_conf *); void merge_config(struct ldpd_conf *, struct ldpd_conf *);
struct ldpd_conf *config_new_empty(void); struct ldpd_conf *config_new_empty(void);

View File

@ -2613,5 +2613,6 @@ cmd_terminate ()
if (host.config) if (host.config)
XFREE (MTYPE_HOST, host.config); XFREE (MTYPE_HOST, host.config);
list_delete (varhandlers);
qobj_finish (); qobj_finish ();
} }

View File

@ -39,7 +39,10 @@
# #
# Long description: Full description, but should try fit on a line. # Long description: Full description, but should try fit on a line.
#### ####
#
# If you add a new routing protocol here, make sure you go update
# meta_queue_map in zebra_rib.c
#
## type cname daemon C 4 6 short help ## type cname daemon C 4 6 short help
ZEBRA_ROUTE_SYSTEM, system, NULL, 'X', 0, 0, "Reserved" ZEBRA_ROUTE_SYSTEM, system, NULL, 'X', 0, 0, "Reserved"
ZEBRA_ROUTE_KERNEL, kernel, zebra, 'K', 1, 1, "kernel route" ZEBRA_ROUTE_KERNEL, kernel, zebra, 'K', 1, 1, "kernel route"

View File

@ -30,6 +30,7 @@
#include "pqueue.h" #include "pqueue.h"
#include "command.h" #include "command.h"
#include "sigevent.h" #include "sigevent.h"
#include "network.h"
DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread") DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread")
DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master") DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master")
@ -40,6 +41,12 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats")
#include <mach/mach_time.h> #include <mach/mach_time.h>
#endif #endif
#define AWAKEN(m) \
do { \
static unsigned char wakebyte = 0x01; \
write (m->io_pipe[1], &wakebyte, 1); \
} while (0);
static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER;
static struct hash *cpu_record = NULL; static struct hash *cpu_record = NULL;
@ -89,13 +96,12 @@ vty_out_cpu_thread_history(struct vty* vty,
a->total_active, a->cpu.total/1000, a->cpu.total%1000, a->total_calls, a->total_active, a->cpu.total/1000, a->cpu.total%1000, a->total_calls,
a->cpu.total/a->total_calls, a->cpu.max, a->cpu.total/a->total_calls, a->cpu.max,
a->real.total/a->total_calls, a->real.max); a->real.total/a->total_calls, a->real.max);
vty_out(vty, " %c%c%c%c%c%c %s%s", vty_out(vty, " %c%c%c%c%c %s%s",
a->types & (1 << THREAD_READ) ? 'R':' ', a->types & (1 << THREAD_READ) ? 'R':' ',
a->types & (1 << THREAD_WRITE) ? 'W':' ', a->types & (1 << THREAD_WRITE) ? 'W':' ',
a->types & (1 << THREAD_TIMER) ? 'T':' ', a->types & (1 << THREAD_TIMER) ? 'T':' ',
a->types & (1 << THREAD_EVENT) ? 'E':' ', a->types & (1 << THREAD_EVENT) ? 'E':' ',
a->types & (1 << THREAD_EXECUTE) ? 'X':' ', a->types & (1 << THREAD_EXECUTE) ? 'X':' ',
a->types & (1 << THREAD_BACKGROUND) ? 'B' : ' ',
a->funcname, VTY_NEWLINE); a->funcname, VTY_NEWLINE);
} }
@ -188,10 +194,6 @@ DEFUN (show_thread_cpu,
case 'X': case 'X':
filter |= (1 << THREAD_EXECUTE); filter |= (1 << THREAD_EXECUTE);
break; break;
case 'b':
case 'B':
filter |= (1 << THREAD_BACKGROUND);
break;
default: default:
break; break;
} }
@ -280,10 +282,6 @@ DEFUN (clear_thread_cpu,
case 'X': case 'X':
filter |= (1 << THREAD_EXECUTE); filter |= (1 << THREAD_EXECUTE);
break; break;
case 'b':
case 'B':
filter |= (1 << THREAD_BACKGROUND);
break;
default: default:
break; break;
} }
@ -372,19 +370,22 @@ thread_master_create (void)
/* Initialize the timer queues */ /* Initialize the timer queues */
rv->timer = pqueue_create(); rv->timer = pqueue_create();
rv->background = pqueue_create(); rv->timer->cmp = thread_timer_cmp;
rv->timer->cmp = rv->background->cmp = thread_timer_cmp; rv->timer->update = thread_timer_update;
rv->timer->update = rv->background->update = thread_timer_update;
rv->spin = true; rv->spin = true;
rv->handle_signals = true; rv->handle_signals = true;
rv->owner = pthread_self(); rv->owner = pthread_self();
pipe (rv->io_pipe);
set_nonblocking (rv->io_pipe[0]);
set_nonblocking (rv->io_pipe[1]);
#if defined(HAVE_POLL_CALL)
rv->handler.pfdsize = rv->fd_limit; rv->handler.pfdsize = rv->fd_limit;
rv->handler.pfdcount = 0; rv->handler.pfdcount = 0;
rv->handler.pfds = XCALLOC (MTYPE_THREAD_MASTER, rv->handler.pfds = XCALLOC (MTYPE_THREAD_MASTER,
sizeof (struct pollfd) * rv->handler.pfdsize); sizeof (struct pollfd) * rv->handler.pfdsize);
#endif rv->handler.copy = XCALLOC (MTYPE_THREAD_MASTER,
sizeof (struct pollfd) * rv->handler.pfdsize);
return rv; return rv;
} }
@ -419,18 +420,6 @@ thread_list_delete (struct thread_list *list, struct thread *thread)
return thread; return thread;
} }
static void
thread_delete_fd (struct thread **thread_array, struct thread *thread)
{
thread_array[thread->u.fd] = NULL;
}
static void
thread_add_fd (struct thread **thread_array, struct thread *thread)
{
thread_array[thread->u.fd] = thread;
}
/* Thread list is empty or not. */ /* Thread list is empty or not. */
static int static int
thread_empty (struct thread_list *list) thread_empty (struct thread_list *list)
@ -541,12 +530,12 @@ thread_master_free (struct thread_master *m)
thread_list_free (m, &m->event); thread_list_free (m, &m->event);
thread_list_free (m, &m->ready); thread_list_free (m, &m->ready);
thread_list_free (m, &m->unuse); thread_list_free (m, &m->unuse);
thread_queue_free (m, m->background);
pthread_mutex_destroy (&m->mtx); pthread_mutex_destroy (&m->mtx);
close (m->io_pipe[0]);
close (m->io_pipe[1]);
#if defined(HAVE_POLL_CALL)
XFREE (MTYPE_THREAD_MASTER, m->handler.pfds); XFREE (MTYPE_THREAD_MASTER, m->handler.pfds);
#endif XFREE (MTYPE_THREAD_MASTER, m->handler.copy);
XFREE (MTYPE_THREAD_MASTER, m); XFREE (MTYPE_THREAD_MASTER, m);
pthread_mutex_lock (&cpu_record_mtx); pthread_mutex_lock (&cpu_record_mtx);
@ -646,77 +635,21 @@ thread_get (struct thread_master *m, u_char type,
return thread; return thread;
} }
#if defined (HAVE_POLL_CALL)
#define fd_copy_fd_set(X) (X)
/* generic add thread function */
static struct thread *
generic_thread_add(struct thread_master *m, int (*func) (struct thread *),
void *arg, int fd, int dir, debugargdef)
{
struct thread *thread;
u_char type;
short int event;
if (dir == THREAD_READ)
{
event = (POLLIN | POLLHUP);
type = THREAD_READ;
}
else
{
event = (POLLOUT | POLLHUP);
type = THREAD_WRITE;
}
nfds_t queuepos = m->handler.pfdcount;
nfds_t i=0;
for (i=0; i<m->handler.pfdcount; i++)
if (m->handler.pfds[i].fd == fd)
{
queuepos = i;
break;
}
/* is there enough space for a new fd? */
assert (queuepos < m->handler.pfdsize);
thread = thread_get (m, type, func, arg, debugargpass);
m->handler.pfds[queuepos].fd = fd;
m->handler.pfds[queuepos].events |= event;
if (queuepos == m->handler.pfdcount)
m->handler.pfdcount++;
return thread;
}
#else
#define fd_copy_fd_set(X) (X)
#endif
static int static int
fd_select (struct thread_master *m, int size, thread_fd_set *read, thread_fd_set *write, thread_fd_set *except, struct timeval *timer_wait) fd_poll (struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize,
nfds_t count, struct timeval *timer_wait)
{ {
int num; /* If timer_wait is null here, that means poll() should block indefinitely,
* unless the thread_master has overriden it by setting ->selectpoll_timeout.
/* If timer_wait is null here, that means either select() or poll() should * If the value is positive, it specifies the maximum number of milliseconds
* block indefinitely, unless the thread_master has overriden it. select() * to wait. If the timeout is -1, it specifies that we should never wait and
* and poll() differ in the timeout values they interpret as an indefinite * always return immediately even if no event is detected. If the value is
* block; select() requires a null pointer, while poll takes a millisecond * zero, the behavior is default. */
* value of -1.
*
* The thread_master owner has the option of overriding the default behavior
* by setting ->selectpoll_timeout. If the value is positive, it specifies
* the maximum number of milliseconds to wait. If the timeout is -1, it
* specifies that we should never wait and always return immediately even if
* no event is detected. If the value is zero, the behavior is default.
*/
#if defined(HAVE_POLL_CALL)
int timeout = -1; int timeout = -1;
/* number of file descriptors with events */
int num;
if (timer_wait != NULL && m->selectpoll_timeout == 0) // use the default value if (timer_wait != NULL && m->selectpoll_timeout == 0) // use the default value
timeout = (timer_wait->tv_sec*1000) + (timer_wait->tv_usec/1000); timeout = (timer_wait->tv_sec*1000) + (timer_wait->tv_usec/1000);
else if (m->selectpoll_timeout > 0) // use the user's timeout else if (m->selectpoll_timeout > 0) // use the user's timeout
@ -724,58 +657,21 @@ fd_select (struct thread_master *m, int size, thread_fd_set *read, thread_fd_set
else if (m->selectpoll_timeout < 0) // effect a poll (return immediately) else if (m->selectpoll_timeout < 0) // effect a poll (return immediately)
timeout = 0; timeout = 0;
num = poll (m->handler.pfds, m->handler.pfdcount + m->handler.pfdcountsnmp, timeout); /* add poll pipe poker */
#else assert (count + 1 < pfdsize);
struct timeval timeout; pfds[count].fd = m->io_pipe[0];
pfds[count].events = POLLIN;
pfds[count].revents = 0x00;
if (m->selectpoll_timeout > 0) // use the user's timeout num = poll (pfds, count + 1, timeout);
{
timeout.tv_sec = m->selectpoll_timeout / 1000; static unsigned char trash[64];
timeout.tv_usec = (m->selectpoll_timeout % 1000) * 1000; if (num > 0 && pfds[count].revents != 0 && num--)
timer_wait = &timeout; while (read (m->io_pipe[0], &trash, sizeof (trash)) > 0);
}
else if (m->selectpoll_timeout < 0) // effect a poll (return immediately)
{
timeout.tv_sec = 0;
timeout.tv_usec = 0;
timer_wait = &timeout;
}
num = select (size, read, write, except, timer_wait);
#endif
return num; return num;
} }
static int
fd_is_set (struct thread *thread, thread_fd_set *fdset, int pos)
{
#if defined(HAVE_POLL_CALL)
return 1;
#else
return FD_ISSET (THREAD_FD (thread), fdset);
#endif
}
static int
fd_clear_read_write (struct thread *thread)
{
#if !defined(HAVE_POLL_CALL)
thread_fd_set *fdset = NULL;
int fd = THREAD_FD (thread);
if (thread->type == THREAD_READ)
fdset = &thread->master->handler.readfd;
else
fdset = &thread->master->handler.writefd;
if (!FD_ISSET (fd, fdset))
return 0;
FD_CLR (fd, fdset);
#endif
return 1;
}
/* Add new read thread. */ /* Add new read thread. */
struct thread * struct thread *
funcname_thread_add_read_write (int dir, struct thread_master *m, funcname_thread_add_read_write (int dir, struct thread_master *m,
@ -792,32 +688,27 @@ funcname_thread_add_read_write (int dir, struct thread_master *m,
return NULL; return NULL;
} }
#if defined (HAVE_POLL_CALL) /* default to a new pollfd */
thread = generic_thread_add(m, func, arg, fd, dir, debugargpass); nfds_t queuepos = m->handler.pfdcount;
#else
if (fd >= FD_SETSIZE)
{
zlog_err ("File descriptor %d is >= FD_SETSIZE (%d). Please recompile"
"with --enable-poll=yes", fd, FD_SETSIZE);
assert (fd < FD_SETSIZE && !"fd >= FD_SETSIZE");
}
thread_fd_set *fdset = NULL;
if (dir == THREAD_READ)
fdset = &m->handler.readfd;
else
fdset = &m->handler.writefd;
if (FD_ISSET (fd, fdset)) /* if we already have a pollfd for our file descriptor, find and use it */
{ for (nfds_t i = 0; i < m->handler.pfdcount; i++)
zlog_warn ("There is already %s fd [%d]", if (m->handler.pfds[i].fd == fd)
(dir == THREAD_READ) ? "read" : "write", fd); {
} queuepos = i;
else break;
{ }
FD_SET (fd, fdset);
thread = thread_get (m, dir, func, arg, debugargpass); /* make sure we have room for this fd + pipe poker fd */
} assert (queuepos + 1 < m->handler.pfdsize);
#endif
thread = thread_get (m, dir, func, arg, debugargpass);
m->handler.pfds[queuepos].fd = fd;
m->handler.pfds[queuepos].events |= (dir == THREAD_READ ? POLLIN : POLLOUT);
if (queuepos == m->handler.pfdcount)
m->handler.pfdcount++;
if (thread) if (thread)
{ {
@ -825,9 +716,9 @@ funcname_thread_add_read_write (int dir, struct thread_master *m,
{ {
thread->u.fd = fd; thread->u.fd = fd;
if (dir == THREAD_READ) if (dir == THREAD_READ)
thread_add_fd (m->read, thread); m->read[thread->u.fd] = thread;
else else
thread_add_fd (m->write, thread); m->write[thread->u.fd] = thread;
} }
pthread_mutex_unlock (&thread->mtx); pthread_mutex_unlock (&thread->mtx);
@ -837,6 +728,8 @@ funcname_thread_add_read_write (int dir, struct thread_master *m,
thread->ref = t_ptr; thread->ref = t_ptr;
} }
} }
AWAKEN (m);
} }
pthread_mutex_unlock (&m->mtx); pthread_mutex_unlock (&m->mtx);
@ -853,7 +746,7 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
assert (m != NULL); assert (m != NULL);
assert (type == THREAD_TIMER || type == THREAD_BACKGROUND); assert (type == THREAD_TIMER);
assert (time_relative); assert (time_relative);
pthread_mutex_lock (&m->mtx); pthread_mutex_lock (&m->mtx);
@ -864,7 +757,7 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
return NULL; return NULL;
} }
queue = ((type == THREAD_TIMER) ? m->timer : m->background); queue = m->timer;
thread = thread_get (m, type, func, arg, debugargpass); thread = thread_get (m, type, func, arg, debugargpass);
pthread_mutex_lock (&thread->mtx); pthread_mutex_lock (&thread->mtx);
@ -879,6 +772,8 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
} }
} }
pthread_mutex_unlock (&thread->mtx); pthread_mutex_unlock (&thread->mtx);
AWAKEN (m);
} }
pthread_mutex_unlock (&m->mtx); pthread_mutex_unlock (&m->mtx);
@ -930,31 +825,6 @@ funcname_thread_add_timer_tv (struct thread_master *m,
t_ptr, debugargpass); t_ptr, debugargpass);
} }
/* Add a background thread, with an optional millisec delay */
struct thread *
funcname_thread_add_background (struct thread_master *m,
int (*func) (struct thread *), void *arg, long delay,
struct thread **t_ptr, debugargdef)
{
struct timeval trel;
assert (m != NULL);
if (delay)
{
trel.tv_sec = delay / 1000;
trel.tv_usec = 1000*(delay % 1000);
}
else
{
trel.tv_sec = 0;
trel.tv_usec = 0;
}
return funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND, arg, &trel,
t_ptr, debugargpass);
}
/* Add simple event thread. */ /* Add simple event thread. */
struct thread * struct thread *
funcname_thread_add_event (struct thread_master *m, funcname_thread_add_event (struct thread_master *m,
@ -986,6 +856,8 @@ funcname_thread_add_event (struct thread_master *m,
*t_ptr = thread; *t_ptr = thread;
thread->ref = t_ptr; thread->ref = t_ptr;
} }
AWAKEN (m);
} }
pthread_mutex_unlock (&m->mtx); pthread_mutex_unlock (&m->mtx);
@ -995,10 +867,7 @@ funcname_thread_add_event (struct thread_master *m,
static void static void
thread_cancel_read_or_write (struct thread *thread, short int state) thread_cancel_read_or_write (struct thread *thread, short int state)
{ {
#if defined(HAVE_POLL_CALL) for (nfds_t i = 0; i < thread->master->handler.pfdcount; ++i)
nfds_t i;
for (i=0;i<thread->master->handler.pfdcount;++i)
if (thread->master->handler.pfds[i].fd == thread->u.fd) if (thread->master->handler.pfds[i].fd == thread->u.fd)
{ {
thread->master->handler.pfds[i].events &= ~(state); thread->master->handler.pfds[i].events &= ~(state);
@ -1013,9 +882,6 @@ thread_cancel_read_or_write (struct thread *thread, short int state)
return; return;
} }
} }
#endif
fd_clear_read_write (thread);
} }
/** /**
@ -1039,19 +905,11 @@ thread_cancel (struct thread *thread)
switch (thread->type) switch (thread->type)
{ {
case THREAD_READ: case THREAD_READ:
#if defined (HAVE_POLL_CALL)
thread_cancel_read_or_write (thread, POLLIN | POLLHUP); thread_cancel_read_or_write (thread, POLLIN | POLLHUP);
#else
thread_cancel_read_or_write (thread, 0);
#endif
thread_array = thread->master->read; thread_array = thread->master->read;
break; break;
case THREAD_WRITE: case THREAD_WRITE:
#if defined (HAVE_POLL_CALL)
thread_cancel_read_or_write (thread, POLLOUT | POLLHUP); thread_cancel_read_or_write (thread, POLLOUT | POLLHUP);
#else
thread_cancel_read_or_write (thread, 0);
#endif
thread_array = thread->master->write; thread_array = thread->master->write;
break; break;
case THREAD_TIMER: case THREAD_TIMER:
@ -1063,9 +921,6 @@ thread_cancel (struct thread *thread)
case THREAD_READY: case THREAD_READY:
list = &thread->master->ready; list = &thread->master->ready;
break; break;
case THREAD_BACKGROUND:
queue = thread->master->background;
break;
default: default:
goto done; goto done;
break; break;
@ -1082,7 +937,7 @@ thread_cancel (struct thread *thread)
} }
else if (thread_array) else if (thread_array)
{ {
thread_delete_fd (thread_array, thread); thread_array[thread->u.fd] = NULL;
} }
else else
{ {
@ -1168,7 +1023,7 @@ thread_timer_wait (struct pqueue *queue, struct timeval *timer_val)
static struct thread * static struct thread *
thread_run (struct thread_master *m, struct thread *thread, thread_run (struct thread_master *m, struct thread *thread,
struct thread *fetch) struct thread *fetch)
{ {
*fetch = *thread; *fetch = *thread;
thread_add_unuse (m, thread); thread_add_unuse (m, thread);
@ -1176,7 +1031,8 @@ thread_run (struct thread_master *m, struct thread *thread,
} }
static int static int
thread_process_fds_helper (struct thread_master *m, struct thread *thread, thread_fd_set *fdset, short int state, int pos) thread_process_io_helper (struct thread_master *m, struct thread *thread,
short state, int pos)
{ {
struct thread **thread_array; struct thread **thread_array;
@ -1188,76 +1044,60 @@ thread_process_fds_helper (struct thread_master *m, struct thread *thread, threa
else else
thread_array = m->write; thread_array = m->write;
if (fd_is_set (thread, fdset, pos)) thread_array[thread->u.fd] = NULL;
{ thread_list_add (&m->ready, thread);
fd_clear_read_write (thread); thread->type = THREAD_READY;
thread_delete_fd (thread_array, thread); /* if another pthread scheduled this file descriptor for the event we're
thread_list_add (&m->ready, thread); * responding to, no problem; we're getting to it now */
thread->type = THREAD_READY; thread->master->handler.pfds[pos].events &= ~(state);
#if defined(HAVE_POLL_CALL) return 1;
thread->master->handler.pfds[pos].events &= ~(state);
#endif
return 1;
}
return 0;
} }
#if defined(HAVE_POLL_CALL)
/* check poll events */
static void static void
check_pollfds(struct thread_master *m, fd_set *readfd, int num) thread_process_io (struct thread_master *m, struct pollfd *pfds,
unsigned int num, unsigned int count)
{ {
nfds_t i = 0; unsigned int ready = 0;
int ready = 0;
for (i = 0; i < m->handler.pfdcount && ready < num ; ++i) for (nfds_t i = 0; i < count && ready < num ; ++i)
{ {
/* no event for current fd? immideatly continue */ /* no event for current fd? immediately continue */
if(m->handler.pfds[i].revents == 0) if (pfds[i].revents == 0)
continue; continue;
ready++; ready++;
/* POLLIN / POLLOUT process event */ /* Unless someone has called thread_cancel from another pthread, the only
if (m->handler.pfds[i].revents & (POLLIN | POLLHUP)) * thing that could have changed in m->handler.pfds while we were
thread_process_fds_helper(m, m->read[m->handler.pfds[i].fd], NULL, POLLIN, i); * asleep is the .events field in a given pollfd. Barring thread_cancel()
if (m->handler.pfds[i].revents & POLLOUT) * that value should be a superset of the values we have in our copy, so
thread_process_fds_helper(m, m->write[m->handler.pfds[i].fd], NULL, POLLOUT, i); * there's no need to update it. Similarily, barring deletion, the fd
* should still be a valid index into the master's pfds. */
if (pfds[i].revents & (POLLIN | POLLHUP))
thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN, i);
if (pfds[i].revents & POLLOUT)
thread_process_io_helper(m, m->write[pfds[i].fd], POLLOUT, i);
/* remove fd from list on POLLNVAL */ /* if one of our file descriptors is garbage, remove the same from
if (m->handler.pfds[i].revents & POLLNVAL) * both pfds + update sizes and index */
if (pfds[i].revents & POLLNVAL)
{ {
memmove(m->handler.pfds+i, memmove (m->handler.pfds + i,
m->handler.pfds+i+1, m->handler.pfds + i + 1,
(m->handler.pfdsize-i-1) * sizeof(struct pollfd)); (m->handler.pfdcount - i - 1) * sizeof(struct pollfd));
m->handler.pfdcount--; m->handler.pfdcount--;
i--;
memmove (pfds + i, pfds + i + 1,
(count - i - 1) * sizeof(struct pollfd));
count--;
i--;
} }
else
m->handler.pfds[i].revents = 0;
} }
} }
#endif
static void
thread_process_fds (struct thread_master *m, thread_fd_set *rset, thread_fd_set *wset, int num)
{
#if defined (HAVE_POLL_CALL)
check_pollfds (m, rset, num);
#else
int ready = 0, index;
for (index = 0; index < m->fd_limit && ready < num; ++index)
{
ready += thread_process_fds_helper (m, m->read[index], rset, 0, 0);
ready += thread_process_fds_helper (m, m->write[index], wset, 0, 0);
}
#endif
}
/* Add all timers that have popped to the ready list. */ /* Add all timers that have popped to the ready list. */
static unsigned int static unsigned int
thread_timer_process (struct pqueue *queue, struct timeval *timenow) thread_process_timers (struct pqueue *queue, struct timeval *timenow)
{ {
struct thread *thread; struct thread *thread;
unsigned int ready = 0; unsigned int ready = 0;
@ -1300,14 +1140,9 @@ struct thread *
thread_fetch (struct thread_master *m, struct thread *fetch) thread_fetch (struct thread_master *m, struct thread *fetch)
{ {
struct thread *thread; struct thread *thread;
thread_fd_set readfd;
thread_fd_set writefd;
thread_fd_set exceptfd;
struct timeval now; struct timeval now;
struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 }; struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 };
struct timeval timer_val_bg;
struct timeval *timer_wait = &timer_val; struct timeval *timer_wait = &timer_val;
struct timeval *timer_wait_bg;
do do
{ {
@ -1338,22 +1173,10 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
/* Normal event are the next highest priority. */ /* Normal event are the next highest priority. */
thread_process (&m->event); thread_process (&m->event);
/* Structure copy. */
#if !defined(HAVE_POLL_CALL)
readfd = fd_copy_fd_set(m->handler.readfd);
writefd = fd_copy_fd_set(m->handler.writefd);
exceptfd = fd_copy_fd_set(m->handler.exceptfd);
#endif
/* Calculate select wait timer if nothing else to do */ /* Calculate select wait timer if nothing else to do */
if (m->ready.count == 0) if (m->ready.count == 0)
{ {
timer_wait = thread_timer_wait (m->timer, &timer_val); timer_wait = thread_timer_wait (m->timer, &timer_val);
timer_wait_bg = thread_timer_wait (m->background, &timer_val_bg);
if (timer_wait_bg &&
(!timer_wait || (timercmp (timer_wait, timer_wait_bg, >))))
timer_wait = timer_wait_bg;
} }
if (timer_wait && timer_wait->tv_sec < 0) if (timer_wait && timer_wait->tv_sec < 0)
@ -1362,7 +1185,14 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
timer_wait = &timer_val; timer_wait = &timer_val;
} }
num = fd_select (m, FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait); unsigned int count = m->handler.pfdcount + m->handler.pfdcountsnmp;
memcpy (m->handler.copy, m->handler.pfds, count * sizeof (struct pollfd));
pthread_mutex_unlock (&m->mtx);
{
num = fd_poll (m, m->handler.copy, m->handler.pfdsize, count, timer_wait);
}
pthread_mutex_lock (&m->mtx);
/* Signals should get quick treatment */ /* Signals should get quick treatment */
if (num < 0) if (num < 0)
@ -1372,38 +1202,20 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
pthread_mutex_unlock (&m->mtx); pthread_mutex_unlock (&m->mtx);
continue; /* signal received - process it */ continue; /* signal received - process it */
} }
zlog_warn ("select() error: %s", safe_strerror (errno)); zlog_warn ("poll() error: %s", safe_strerror (errno));
pthread_mutex_unlock (&m->mtx); pthread_mutex_unlock (&m->mtx);
return NULL; return NULL;
} }
/* Check foreground timers. Historically, they have had higher /* Check foreground timers. Historically, they have had higher
priority than I/O threads, so let's push them onto the ready * priority than I/O threads, so let's push them onto the ready
list in front of the I/O threads. */ * list in front of the I/O threads. */
monotime(&now); monotime(&now);
thread_timer_process (m->timer, &now); thread_process_timers (m->timer, &now);
/* Got IO, process it */ /* Got IO, process it */
if (num > 0) if (num > 0)
thread_process_fds (m, &readfd, &writefd, num); thread_process_io (m, m->handler.copy, num, count);
#if 0
/* If any threads were made ready above (I/O or foreground timer),
perhaps we should avoid adding background timers to the ready
list at this time. If this is code is uncommented, then background
timer threads will not run unless there is nothing else to do. */
if ((thread = thread_trim_head (&m->ready)) != NULL)
{
fetch = thread_run (m, thread, fetch);
if (fetch->ref)
*fetch->ref = NULL;
pthread_mutex_unlock (&m->mtx);
return fetch;
}
#endif
/* Background timer/events, lowest priority */
thread_timer_process (m->background, &now);
if ((thread = thread_trim_head (&m->ready)) != NULL) if ((thread = thread_trim_head (&m->ready)) != NULL)
{ {

View File

@ -22,8 +22,9 @@
#define _ZEBRA_THREAD_H #define _ZEBRA_THREAD_H
#include <zebra.h> #include <zebra.h>
#include "monotime.h"
#include <pthread.h> #include <pthread.h>
#include <poll.h>
#include "monotime.h"
struct rusage_t struct rusage_t
{ {
@ -44,14 +45,6 @@ struct thread_list
struct pqueue; struct pqueue;
/*
* Abstract it so we can use different methodologies to
* select on data.
*/
typedef fd_set thread_fd_set;
#if defined(HAVE_POLL_CALL)
#include <poll.h>
struct fd_handler struct fd_handler
{ {
/* number of pfd stored in pfds */ /* number of pfd stored in pfds */
@ -60,16 +53,11 @@ struct fd_handler
nfds_t pfdcountsnmp; nfds_t pfdcountsnmp;
/* number of pfd that fit in the allocated space of pfds */ /* number of pfd that fit in the allocated space of pfds */
nfds_t pfdsize; nfds_t pfdsize;
/* file descriptors to monitor for i/o */
struct pollfd *pfds; struct pollfd *pfds;
/* chunk used for temp copy of pollfds */
struct pollfd *copy;
}; };
#else
struct fd_handler
{
fd_set readfd;
fd_set writefd;
fd_set exceptfd;
};
#endif
/* Master of the theads. */ /* Master of the theads. */
struct thread_master struct thread_master
@ -80,7 +68,7 @@ struct thread_master
struct thread_list event; struct thread_list event;
struct thread_list ready; struct thread_list ready;
struct thread_list unuse; struct thread_list unuse;
struct pqueue *background; int io_pipe[2];
int fd_limit; int fd_limit;
struct fd_handler handler; struct fd_handler handler;
unsigned long alloc; unsigned long alloc;
@ -142,9 +130,8 @@ struct cpu_thread_history
#define THREAD_TIMER 2 #define THREAD_TIMER 2
#define THREAD_EVENT 3 #define THREAD_EVENT 3
#define THREAD_READY 4 #define THREAD_READY 4
#define THREAD_BACKGROUND 5 #define THREAD_UNUSED 5
#define THREAD_UNUSED 6 #define THREAD_EXECUTE 6
#define THREAD_EXECUTE 7
/* Thread yield time. */ /* Thread yield time. */
#define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */ #define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
@ -177,9 +164,6 @@ struct cpu_thread_history
#define thread_add_event(m,f,a,v,t) funcname_thread_add_event(m,f,a,v,t,#f,__FILE__,__LINE__) #define thread_add_event(m,f,a,v,t) funcname_thread_add_event(m,f,a,v,t,#f,__FILE__,__LINE__)
#define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__) #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
/* The 4th arg to thread_add_background is the # of milliseconds to delay. */
#define thread_add_background(m,f,a,v,t) funcname_thread_add_background(m,f,a,v,t,#f,__FILE__,__LINE__)
/* Prototypes. */ /* Prototypes. */
extern struct thread_master *thread_master_create (void); extern struct thread_master *thread_master_create (void);
extern void thread_master_free (struct thread_master *); extern void thread_master_free (struct thread_master *);
@ -200,9 +184,6 @@ extern struct thread * funcname_thread_add_timer_tv (struct thread_master *,
extern struct thread * funcname_thread_add_event (struct thread_master *, extern struct thread * funcname_thread_add_event (struct thread_master *,
int (*)(struct thread *), void *, int, struct thread **, debugargdef); int (*)(struct thread *), void *, int, struct thread **, debugargdef);
extern struct thread * funcname_thread_add_background (struct thread_master *,
int (*)(struct thread *), void *, long, struct thread **, debugargdef);
extern void funcname_thread_execute (struct thread_master *, extern void funcname_thread_execute (struct thread_master *,
int (*)(struct thread *), void *, int, debugargdef); int (*)(struct thread *), void *, int, debugargdef);
#undef debugargdef #undef debugargdef

View File

@ -56,6 +56,20 @@ enum {
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF name\n" #define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF name\n"
#define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n" #define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n"
/*
* Pass some OS specific data up through
* to the daemons
*/
struct vrf_data
{
union
{
struct {
uint32_t table_id;
} l;
};
};
struct vrf struct vrf
{ {
RB_ENTRY(vrf) id_entry, name_entry; RB_ENTRY(vrf) id_entry, name_entry;
@ -76,6 +90,9 @@ struct vrf
/* User data */ /* User data */
void *info; void *info;
/* The table_id from the kernel */
struct vrf_data data;
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD (vrf_id_head, vrf); RB_HEAD (vrf_id_head, vrf);

View File

@ -126,8 +126,8 @@ work_queue_schedule (struct work_queue *wq, unsigned int delay)
&& (listcount (wq->items) > 0) ) && (listcount (wq->items) > 0) )
{ {
wq->thread = NULL; wq->thread = NULL;
thread_add_background(wq->master, work_queue_run, wq, delay, thread_add_timer_msec (wq->master, work_queue_run, wq, delay,
&wq->thread); &wq->thread);
/* set thread yield time, if needed */ /* set thread yield time, if needed */
if (wq->thread && wq->spec.yield != THREAD_YIELD_TIME_SLOT) if (wq->thread && wq->spec.yield != THREAD_YIELD_TIME_SLOT)
thread_set_yield_time (wq->thread, wq->spec.yield); thread_set_yield_time (wq->thread, wq->spec.yield);

View File

@ -1169,12 +1169,15 @@ zclient_vrf_add (struct zclient *zclient, vrf_id_t vrf_id)
{ {
struct vrf *vrf; struct vrf *vrf;
char vrfname_tmp[VRF_NAMSIZ]; char vrfname_tmp[VRF_NAMSIZ];
struct vrf_data data;
stream_get (&data, zclient->ibuf, sizeof (struct vrf_data));
/* Read interface name. */ /* Read interface name. */
stream_get (vrfname_tmp, zclient->ibuf, VRF_NAMSIZ); stream_get (vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
/* Lookup/create vrf by vrf_id. */ /* Lookup/create vrf by vrf_id. */
vrf = vrf_get (vrf_id, vrfname_tmp); vrf = vrf_get (vrf_id, vrfname_tmp);
vrf->data = data;
vrf_enable (vrf); vrf_enable (vrf);
} }

View File

@ -421,7 +421,7 @@ static int vici_reconnect(struct thread *t)
fd = sock_open_unix("/var/run/charon.vici"); fd = sock_open_unix("/var/run/charon.vici");
if (fd < 0) { if (fd < 0) {
zlog_warn("%s: failure connecting VICI socket: %s", debugf(NHRP_DEBUG_VICI, "%s: failure connecting VICI socket: %s",
__PRETTY_FUNCTION__, strerror(errno)); __PRETTY_FUNCTION__, strerror(errno));
thread_add_timer(master, vici_reconnect, vici, 2, thread_add_timer(master, vici_reconnect, vici, 2,
&vici->t_reconnect); &vici->t_reconnect);

View File

@ -619,21 +619,23 @@ DEFUN (area_filter_list,
"Filter networks sent to this area\n" "Filter networks sent to this area\n"
"Filter networks sent from this area\n") "Filter networks sent from this area\n")
{ {
int idx_ipv4 = 1; char *inout = argv[argc - 1]->text;
int idx_word = 4; char *areaid = argv[1]->arg;
char *plistname = argv[4]->arg;
struct ospf6_area *area; struct ospf6_area *area;
struct prefix_list *plist; struct prefix_list *plist;
OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area); OSPF6_CMD_AREA_GET (areaid, area);
plist = prefix_list_lookup (AFI_IP6, argv[idx_ipv4]->arg); plist = prefix_list_lookup (AFI_IP6, plistname);
if (strncmp (argv[idx_word]->arg, "in", 2) == 0) if (strmatch (inout, "in"))
{ {
PREFIX_LIST_IN (area) = plist; PREFIX_LIST_IN (area) = plist;
if (PREFIX_NAME_IN (area)) if (PREFIX_NAME_IN (area))
free (PREFIX_NAME_IN (area)); free (PREFIX_NAME_IN (area));
PREFIX_NAME_IN (area) = strdup (argv[idx_ipv4]->arg); PREFIX_NAME_IN (area) = strdup (plistname);
ospf6_abr_reimport (area); ospf6_abr_reimport (area);
} }
else else
@ -642,7 +644,7 @@ DEFUN (area_filter_list,
if (PREFIX_NAME_OUT (area)) if (PREFIX_NAME_OUT (area))
free (PREFIX_NAME_OUT (area)); free (PREFIX_NAME_OUT (area));
PREFIX_NAME_OUT (area) = strdup (argv[idx_ipv4]->arg); PREFIX_NAME_OUT (area) = strdup (plistname);
ospf6_abr_enable_area (area); ospf6_abr_enable_area (area);
} }
@ -661,16 +663,18 @@ DEFUN (no_area_filter_list,
"Filter networks sent to this area\n" "Filter networks sent to this area\n"
"Filter networks sent from this area\n") "Filter networks sent from this area\n")
{ {
int idx_ipv4 = 2; char *inout = argv[argc - 1]->text;
int idx_word = 5; char *areaid = argv[2]->arg;
char *plistname = argv[5]->arg;
struct ospf6_area *area; struct ospf6_area *area;
OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area); OSPF6_CMD_AREA_GET (areaid, area);
if (strncmp (argv[idx_word]->arg, "in", 2) == 0) if (strmatch (inout, "in"))
{ {
if (PREFIX_NAME_IN (area)) if (PREFIX_NAME_IN (area))
if (strcmp (PREFIX_NAME_IN (area), argv[idx_ipv4]->arg) != 0) if (!strmatch (PREFIX_NAME_IN (area), plistname))
return CMD_SUCCESS; return CMD_SUCCESS;
PREFIX_LIST_IN (area) = NULL; PREFIX_LIST_IN (area) = NULL;
@ -683,7 +687,7 @@ DEFUN (no_area_filter_list,
else else
{ {
if (PREFIX_NAME_OUT (area)) if (PREFIX_NAME_OUT (area))
if (strcmp (PREFIX_NAME_OUT (area), argv[idx_ipv4]->arg) != 0) if (!strmatch (PREFIX_NAME_OUT (area), plistname))
return CMD_SUCCESS; return CMD_SUCCESS;
PREFIX_LIST_OUT (area) = NULL; PREFIX_LIST_OUT (area) = NULL;

View File

@ -838,8 +838,9 @@ initialize_linkparams (struct mpls_te_link *lp)
if ((oi = lookup_oi_by_ifp (ifp, NULL, OI_ANY)) == NULL) if ((oi = lookup_oi_by_ifp (ifp, NULL, OI_ANY)) == NULL)
{ {
zlog_warn("MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s", if (IS_DEBUG_OSPF_TE)
ifp->name); zlog_warn("MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s",
ifp->name);
return; return;
} }
@ -991,7 +992,8 @@ ospf_mpls_te_update_if (struct interface *ifp)
/* Get Link context from interface */ /* Get Link context from interface */
if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL) if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL)
{ {
zlog_warn ("OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s", ifp->name); if (IS_DEBUG_OSPF_TE)
zlog_warn ("OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s", ifp->name);
return; return;
} }

View File

@ -988,15 +988,15 @@ ospf_vl_set (struct ospf *ospf, struct ospf_vl_config_data *vl_config)
"Use null authentication\n" \ "Use null authentication\n" \
"Use message-digest authentication\n" "Use message-digest authentication\n"
#define VLINK_HELPSTR_TIME_PARAM_NOSECS \
"Time between HELLO packets\n" \
"Time between retransmitting lost link state advertisements\n" \
"Link state transmit delay\n" \
"Interval time after which a neighbor is declared down\n"
#define VLINK_HELPSTR_TIME_PARAM \ #define VLINK_HELPSTR_TIME_PARAM \
VLINK_HELPSTR_TIME_PARAM_NOSECS \ "Time between HELLO packets\n" \
"Seconds\n" "Seconds\n" \
"Time between retransmitting lost link state advertisements\n" \
"Seconds\n" \
"Link state transmit delay\n" \
"Seconds\n" \
"Interval time after which a neighbor is declared down\n" \
"Seconds\n" \
#define VLINK_HELPSTR_AUTH_SIMPLE \ #define VLINK_HELPSTR_AUTH_SIMPLE \
"Authentication password (key)\n" \ "Authentication password (key)\n" \
@ -1129,59 +1129,6 @@ DEFUN (ospf_area_vlink,
} }
DEFUN (ospf_area_vlink_intervals,
ospf_area_vlink_intervals_cmd,
"area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D"
"<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"]]]",
VLINK_HELPSTR_IPADDR
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM)
{
VTY_DECLVAR_CONTEXT(ospf, ospf);
struct ospf_vl_config_data vl_config;
int ret = 0;
ospf_vl_config_data_init(&vl_config, vty);
char *area_id = argv[1]->arg;
char *router_id = argv[3]->arg;
ret = str2area_id (area_id, &vl_config.area_id, &vl_config.area_id_fmt);
if (ret < 0)
{
vty_out (vty, "OSPF area ID is invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
ret = inet_aton (router_id, &vl_config.vl_peer);
if (! ret)
{
vty_out (vty, "Please specify valid Router ID as a.b.c.d%s", VTY_NEWLINE);
return CMD_WARNING;
}
for (unsigned int i = 0; i < 4; i++)
{
int idx = 0;
if (argv_find (argv, argc, "hello-interval", &idx))
vl_config.hello_interval = strtol(argv[idx+1]->arg, NULL, 10);
else if (argv_find (argv, argc, "retransmit-interval", &idx))
vl_config.retransmit_interval = strtol(argv[idx+1]->arg, NULL, 10);
else if (argv_find (argv, argc, "transmit-delay", &idx))
vl_config.transmit_delay = strtol(argv[idx+1]->arg, NULL, 10);
else if (argv_find (argv, argc, "dead-interval", &idx))
vl_config.dead_interval = strtol(argv[idx+1]->arg, NULL, 10);
}
/* Action configuration */
return ospf_vl_set (ospf, &vl_config);
}
DEFUN (no_ospf_area_vlink, DEFUN (no_ospf_area_vlink,
no_ospf_area_vlink_cmd, no_ospf_area_vlink_cmd,
"no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]", "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
@ -1292,19 +1239,56 @@ DEFUN (no_ospf_area_vlink,
return ospf_vl_set (ospf, &vl_config); return ospf_vl_set (ospf, &vl_config);
} }
DEFUN (ospf_area_vlink_intervals,
ospf_area_vlink_intervals_cmd,
"area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|transmit-delay (1-65535)|dead-interval (1-65535)}",
VLINK_HELPSTR_IPADDR
VLINK_HELPSTR_TIME_PARAM)
{
VTY_DECLVAR_CONTEXT(ospf, ospf);
struct ospf_vl_config_data vl_config;
int ret = 0;
ospf_vl_config_data_init(&vl_config, vty);
char *area_id = argv[1]->arg;
char *router_id = argv[3]->arg;
ret = str2area_id (area_id, &vl_config.area_id, &vl_config.area_id_fmt);
if (ret < 0)
{
vty_out (vty, "OSPF area ID is invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
ret = inet_aton (router_id, &vl_config.vl_peer);
if (! ret)
{
vty_out (vty, "Please specify valid Router ID as a.b.c.d%s", VTY_NEWLINE);
return CMD_WARNING;
}
for (int idx = 4; idx < argc; idx++)
{
if (strmatch (argv[idx]->text, "hello-interval"))
vl_config.hello_interval = strtol(argv[++idx]->arg, NULL, 10);
else if (strmatch (argv[idx]->text, "retransmit-interval"))
vl_config.retransmit_interval = strtol(argv[++idx]->arg, NULL, 10);
else if (strmatch (argv[idx]->text, "transmit-delay"))
vl_config.transmit_delay = strtol(argv[++idx]->arg, NULL, 10);
else if (strmatch (argv[idx]->text, "dead-interval"))
vl_config.dead_interval = strtol(argv[++idx]->arg, NULL, 10);
}
/* Action configuration */
return ospf_vl_set (ospf, &vl_config);
}
DEFUN (no_ospf_area_vlink_intervals, DEFUN (no_ospf_area_vlink_intervals,
no_ospf_area_vlink_intervals_cmd, no_ospf_area_vlink_intervals_cmd,
"no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D" "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|transmit-delay (1-65535)|dead-interval (1-65535)}",
"<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
"]]]",
NO_STR NO_STR
VLINK_HELPSTR_IPADDR VLINK_HELPSTR_IPADDR
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM) VLINK_HELPSTR_TIME_PARAM)
{ {
VTY_DECLVAR_CONTEXT(ospf, ospf); VTY_DECLVAR_CONTEXT(ospf, ospf);
@ -1330,16 +1314,15 @@ DEFUN (no_ospf_area_vlink_intervals,
return CMD_WARNING; return CMD_WARNING;
} }
for (unsigned int i = 0; i < 4; i++) for (int idx = 5; idx < argc; idx++)
{ {
int idx = 0; if (strmatch (argv[idx]->text, "hello-interval"))
if (argv_find (argv, argc, "hello-interval", &idx))
vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT; vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
else if (argv_find (argv, argc, "retransmit-interval", &idx)) else if (strmatch (argv[idx]->text, "retransmit-interval"))
vl_config.retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; vl_config.retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
else if (argv_find (argv, argc, "transmit-delay", &idx)) else if (strmatch (argv[idx]->text, "transmit-delay"))
vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
else if (argv_find (argv, argc, "dead-interval", &idx)) else if (strmatch (argv[idx]->text, "dead-interval"))
vl_config.dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; vl_config.dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
} }
@ -2222,7 +2205,7 @@ DEFUN (ospf_timers_min_ls_interval,
int idx_number = 4; int idx_number = 4;
unsigned int interval; unsigned int interval;
if (argc != 1) if (argc < 5)
{ {
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE); vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
@ -2264,7 +2247,7 @@ DEFUN (ospf_timers_min_ls_arrival,
int idx_number = 3; int idx_number = 3;
unsigned int arrival; unsigned int arrival;
if (argc != 1) if (argc < 4)
{ {
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE); vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
@ -2309,7 +2292,7 @@ DEFUN (ospf_timers_throttle_spf,
int idx_number_3 = 5; int idx_number_3 = 5;
unsigned int delay, hold, max; unsigned int delay, hold, max;
if (argc != 3) if (argc < 6)
{ {
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE); vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
@ -2352,7 +2335,7 @@ DEFUN (ospf_timers_lsa,
int idx_number = 3; int idx_number = 3;
unsigned int minarrival; unsigned int minarrival;
if (argc != 1) if (argc < 4)
{ {
vty_out (vty, "Insufficient number of arguments%s", VTY_NEWLINE); vty_out (vty, "Insufficient number of arguments%s", VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
@ -3552,7 +3535,6 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
if (use_json) if (use_json)
{ {
json = json_object_new_object(); json = json_object_new_object();
json_interface_sub = json_object_new_object();
} }
if (ospf->instance) if (ospf->instance)
@ -3571,7 +3553,11 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
{ {
if (ospf_oi_count(ifp)) if (ospf_oi_count(ifp))
{ {
if (use_json)
json_interface_sub = json_object_new_object();
show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json);
if (use_json) if (use_json)
json_object_object_add (json, ifp->name, json_interface_sub); json_object_object_add (json, ifp->name, json_interface_sub);
} }
@ -3589,7 +3575,11 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
} }
else else
{ {
if (use_json)
json_interface_sub = json_object_new_object();
show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json);
if (use_json) if (use_json)
json_object_object_add(json, ifp->name, json_interface_sub); json_object_object_add(json, ifp->name, json_interface_sub);
} }
@ -9099,7 +9089,7 @@ DEFUN (clear_ip_ospf_interface,
} }
else /* Interface name is specified. */ else /* Interface name is specified. */
{ {
if ((ifp = if_lookup_by_name (argv[idx_ifname]->text, VRF_DEFAULT)) == NULL) if ((ifp = if_lookup_by_name (argv[idx_ifname]->arg, VRF_DEFAULT)) == NULL)
vty_out (vty, "No such interface name%s", VTY_NEWLINE); vty_out (vty, "No such interface name%s", VTY_NEWLINE);
else else
ospf_interface_clear(ifp); ospf_interface_clear(ifp);

View File

@ -46,13 +46,11 @@ pim_bfd_write_config (struct vty *vty, struct interface *ifp)
if (!pim_ifp) if (!pim_ifp)
return; return;
bfd_info = (struct bfd_info *) pim_ifp->bfd_info; bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
if (!bfd_info) if (!bfd_info)
{ return;
zlog_debug ("%s: interface %s bfd_info is NULL ", __PRETTY_FUNCTION__,
ifp->name);
return;
}
if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG)) if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_out (vty, " ip pim bfd %d %d %d%s", vty_out (vty, " ip pim bfd %d %d %d%s",
bfd_info->detect_mult, bfd_info->required_min_rx, bfd_info->detect_mult, bfd_info->required_min_rx,
@ -94,7 +92,6 @@ pim_bfd_info_nbr_create (struct pim_interface *pim_ifp,
if (!neigh->bfd_info) if (!neigh->bfd_info)
return; return;
zlog_debug ("%s: bfd_info ", __PRETTY_FUNCTION__);
nbr_bfd_info = (struct bfd_info *) neigh->bfd_info; nbr_bfd_info = (struct bfd_info *) neigh->bfd_info;
nbr_bfd_info->detect_mult = pim_ifp->bfd_info->detect_mult; nbr_bfd_info->detect_mult = pim_ifp->bfd_info->detect_mult;
@ -200,6 +197,8 @@ pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
struct pim_interface *pim_ifp = ifp->info; struct pim_interface *pim_ifp = ifp->info;
int command = 0; int command = 0;
if (!pim_ifp)
return;
bfd_set_param ((struct bfd_info **) &(pim_ifp->bfd_info), min_rx, min_tx, bfd_set_param ((struct bfd_info **) &(pim_ifp->bfd_info), min_rx, min_tx,
detect_mult, defaults, &command); detect_mult, defaults, &command);
@ -265,6 +264,10 @@ pim_bfd_interface_dest_update (int command, struct zclient *zclient,
for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node, for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node,
neigh_nextnode, neigh)) neigh_nextnode, neigh))
{ {
/* Check neigh address matches with BFD address */
if (neigh->source_addr.s_addr != p.u.prefix4.s_addr)
continue;
bfd_info = (struct bfd_info *) neigh->bfd_info; bfd_info = (struct bfd_info *) neigh->bfd_info;
if (bfd_info->status == status) if (bfd_info->status == status)
{ {

View File

@ -297,7 +297,7 @@ static int detect_primary_address_change(struct interface *ifp,
int changed; int changed;
if (force_prim_as_any) if (force_prim_as_any)
new_prim_addr = qpim_inaddr_any; new_prim_addr.s_addr = INADDR_ANY;
else else
new_prim_addr = pim_find_primary_addr(ifp); new_prim_addr = pim_find_primary_addr(ifp);

View File

@ -387,12 +387,14 @@ const char *pim_ifchannel_ifassert_name(enum pim_ifassert_state ifassert_state)
*/ */
void reset_ifassert_state(struct pim_ifchannel *ch) void reset_ifassert_state(struct pim_ifchannel *ch)
{ {
struct in_addr any = { .s_addr = INADDR_ANY };
THREAD_OFF(ch->t_ifassert_timer); THREAD_OFF(ch->t_ifassert_timer);
pim_ifassert_winner_set(ch, pim_ifassert_winner_set(ch,
PIM_IFASSERT_NOINFO, PIM_IFASSERT_NOINFO,
qpim_inaddr_any, any,
qpim_infinite_assert_metric); qpim_infinite_assert_metric);
} }
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp, struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
@ -1277,7 +1279,7 @@ pim_ifchannel_scan_forward_start (struct interface *new_ifp)
* we get End of Message * we get End of Message
*/ */
void void
pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join) pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join, uint8_t starg_alone)
{ {
struct pim_ifchannel *child; struct pim_ifchannel *child;
struct listnode *ch_node; struct listnode *ch_node;
@ -1292,10 +1294,11 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t
for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child)) for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child))
{ {
/* Only *,G Join received and no (SG-RPT) prune. /* Only *,G Join received and no (SG-RPT) prune.
eom = 1, only (W,G) join_alone is true, WC and RPT are set.
Scan all S,G associated to G and if any SG-RPT Scan all S,G associated to G and if any SG-RPT
remove the SG-RPT flag. remove the SG-RPT flag.
*/ */
if (join && (source_flags & PIM_RPT_BIT_MASK) && if (eom && starg_alone && (source_flags & PIM_RPT_BIT_MASK) &&
(source_flags & PIM_WILDCARD_BIT_MASK)) (source_flags & PIM_WILDCARD_BIT_MASK))
{ {
if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
@ -1306,25 +1309,13 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t
if (up) if (up)
{ {
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_TRACE)
zlog_debug ("%s: clearing SGRpt flag, add inherit oif to up %s ", __PRETTY_FUNCTION__, up->sg_str); zlog_debug ("%s: SGRpt flag is cleared, add inherit oif to up %s",
__PRETTY_FUNCTION__, up->sg_str);
pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR); pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, child, PIM_IFJOIN_JOIN);
} }
} }
} }
/* Received SG-RPT Prune delete oif from S,G */
else if (join == 0 && (source_flags & PIM_RPT_BIT_MASK) &&
!(source_flags & PIM_WILDCARD_BIT_MASK))
{
struct pim_upstream *up = child->upstream;
PIM_IF_FLAG_SET_S_G_RPT(child->flags);
if (up)
{
if (PIM_DEBUG_TRACE)
zlog_debug ("%s: SGRpt Set, del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
pim_channel_del_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
}
}
if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
continue; continue;

View File

@ -150,7 +150,7 @@ void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch);
void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch); void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch);
void pim_ifchannel_scan_forward_start (struct interface *new_ifp); void pim_ifchannel_scan_forward_start (struct interface *new_ifp);
void pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join); void pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join, uint8_t starg_alone);
int pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2); int pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);

View File

@ -228,7 +228,8 @@ int pim_joinprune_recv(struct interface *ifp,
uint16_t msg_num_joined_sources; uint16_t msg_num_joined_sources;
uint16_t msg_num_pruned_sources; uint16_t msg_num_pruned_sources;
int source; int source;
struct pim_ifchannel *ch = NULL; struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL;
uint8_t starg_alone = 0;
memset (&sg, 0, sizeof (struct prefix_sg)); memset (&sg, 0, sizeof (struct prefix_sg));
addr_offset = pim_parse_addr_group (&sg, addr_offset = pim_parse_addr_group (&sg,
@ -287,9 +288,10 @@ int pim_joinprune_recv(struct interface *ifp,
if (sg.src.s_addr == INADDR_ANY) if (sg.src.s_addr == INADDR_ANY)
{ {
ch = pim_ifchannel_find (ifp, &sg); starg_alone = 1;
if (ch) starg_ch = pim_ifchannel_find (ifp, &sg);
pim_ifchannel_set_star_g_join_state (ch, 0, msg_source_flags, 1); if (starg_ch)
pim_ifchannel_set_star_g_join_state (starg_ch, 0, msg_source_flags, 1, starg_alone);
} }
} }
@ -302,16 +304,33 @@ int pim_joinprune_recv(struct interface *ifp,
return -8; return -8;
} }
buf += addr_offset; sg_ch = pim_ifchannel_find (ifp, &sg);
buf += addr_offset;
starg_alone = 0;
recv_prune(ifp, neigh, msg_holdtime, recv_prune(ifp, neigh, msg_holdtime,
msg_upstream_addr.u.prefix4, msg_upstream_addr.u.prefix4,
&sg, &sg,
msg_source_flags); msg_source_flags);
/* Received SG-RPT Prune delete oif from specific S,G */
if (starg_ch && sg_ch && (msg_source_flags & PIM_RPT_BIT_MASK)
&& !(msg_source_flags & PIM_WILDCARD_BIT_MASK))
{
struct pim_upstream *up = sg_ch->upstream;
PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags);
if (up)
{
if (PIM_DEBUG_TRACE)
zlog_debug ("%s: SGRpt flag is set, del inherit oif from up %s",
__PRETTY_FUNCTION__, up->sg_str);
pim_channel_del_oif (up->channel_oil, starg_ch->interface, PIM_OIF_FLAG_PROTO_STAR);
}
}
} }
if (ch) if (starg_ch)
pim_ifchannel_set_star_g_join_state (ch, 1, msg_source_flags, 0); pim_ifchannel_set_star_g_join_state (starg_ch, 1, msg_source_flags, 0, starg_alone);
ch = NULL; starg_ch = NULL;
} /* scan groups */ } /* scan groups */
return 0; return 0;
@ -518,6 +537,10 @@ int pim_joinprune_send(struct pim_rpf *rpf,
pim_ifp->pim_ifstat_join_send += ntohs(grp->joins); pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes); pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug ("%s: interface %s num_joins %u num_prunes %u", __PRETTY_FUNCTION__,
rpf->source_nexthop.interface->name, ntohs(grp->joins), ntohs (grp->prunes));
grp = (struct pim_jp_groups *)curr_ptr; grp = (struct pim_jp_groups *)curr_ptr;
if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255) if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255)
{ {

View File

@ -243,17 +243,18 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
{ {
return PIM_RPF_FAILURE; return PIM_RPF_FAILURE;
} }
} }
rpf->rpf_addr.family = AF_INET; rpf->rpf_addr.family = AF_INET;
rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up); rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up);
if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA) { if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA)
/* RPF'(S,G) not found */ {
zlog_debug("%s %s: RPF'%s not found: won't send join upstream", /* RPF'(S,G) not found */
zlog_debug("%s %s: RPF'%s not found: won't send join upstream",
__FILE__, __PRETTY_FUNCTION__, __FILE__, __PRETTY_FUNCTION__,
up->sg_str); up->sg_str);
/* warning only */ /* warning only */
} }
/* detect change in pim_nexthop */ /* detect change in pim_nexthop */
if (nexthop_mismatch(&rpf->source_nexthop, &saved.source_nexthop)) { if (nexthop_mismatch(&rpf->source_nexthop, &saved.source_nexthop)) {

View File

@ -577,8 +577,9 @@ pim_upstream_switch(struct pim_upstream *up,
if (old_state == PIM_UPSTREAM_JOINED) if (old_state == PIM_UPSTREAM_JOINED)
pim_msdp_up_join_state_changed(up); pim_msdp_up_join_state_changed(up);
/* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT */ /* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT towards RP.
if (pim_upstream_is_sg_rpt(up) && up->parent) If I am RP for G then send S,G prune to its IIF. */
if (pim_upstream_is_sg_rpt(up) && up->parent && !I_am_RP(up->sg.grp))
{ {
if (PIM_DEBUG_PIM_TRACE_DETAIL) if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__, zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__,

View File

@ -61,7 +61,6 @@ struct thread *qpim_rpf_cache_refresher = NULL;
int64_t qpim_rpf_cache_refresh_requests = 0; int64_t qpim_rpf_cache_refresh_requests = 0;
int64_t qpim_rpf_cache_refresh_events = 0; int64_t qpim_rpf_cache_refresh_events = 0;
int64_t qpim_rpf_cache_refresh_last = 0; int64_t qpim_rpf_cache_refresh_last = 0;
struct in_addr qpim_inaddr_any;
struct list *qpim_ssmpingd_list = NULL; struct list *qpim_ssmpingd_list = NULL;
struct in_addr qpim_ssmpingd_group_addr; struct in_addr qpim_ssmpingd_group_addr;
int64_t qpim_scan_oil_events = 0; int64_t qpim_scan_oil_events = 0;
@ -293,7 +292,6 @@ void pim_init()
pim_mroute_socket_enable(); pim_mroute_socket_enable();
qpim_inaddr_any.s_addr = PIM_NET_INADDR_ANY;
/* /*
RFC 4601: 4.6.3. Assert Metrics RFC 4601: 4.6.3. Assert Metrics
@ -306,7 +304,7 @@ void pim_init()
qpim_infinite_assert_metric.rpt_bit_flag = 1; qpim_infinite_assert_metric.rpt_bit_flag = 1;
qpim_infinite_assert_metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX; qpim_infinite_assert_metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX;
qpim_infinite_assert_metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX; qpim_infinite_assert_metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX;
qpim_infinite_assert_metric.ip_address = qpim_inaddr_any; qpim_infinite_assert_metric.ip_address.s_addr = INADDR_ANY;
pim_if_init(); pim_if_init();
pim_cmd_init(); pim_cmd_init();

View File

@ -140,7 +140,6 @@ struct thread *qpim_rpf_cache_refresher;
int64_t qpim_rpf_cache_refresh_requests; int64_t qpim_rpf_cache_refresh_requests;
int64_t qpim_rpf_cache_refresh_events; int64_t qpim_rpf_cache_refresh_events;
int64_t qpim_rpf_cache_refresh_last; int64_t qpim_rpf_cache_refresh_last;
struct in_addr qpim_inaddr_any;
struct list *qpim_ssmpingd_list; /* list of struct ssmpingd_sock */ struct list *qpim_ssmpingd_list; /* list of struct ssmpingd_sock */
struct in_addr qpim_ssmpingd_group_addr; struct in_addr qpim_ssmpingd_group_addr;
int64_t qpim_scan_oil_events; int64_t qpim_scan_oil_events;

View File

@ -1,8 +1,5 @@
EXTRA_DIST = bgpd.init isisd.init \ EXTRA_DIST = frr.init frr.service daemons \
ospf6d.init ospfd.init ldpd.init \
frr.logrotate frr.pam frr.spec \ frr.logrotate frr.pam frr.spec \
frr.sysconfig ripd.init ripngd.init \
watchfrr.init pimd.init zebra.init \
README.rpm_build.md README.rpm_build.md

View File

@ -1,74 +1,83 @@
Building your own FRRouting RPM Building your own FRRouting RPM
====================================== ======================================
(Tested on CentOS 6, CentOS 7 and Fedora 22.) (Tested on CentOS 6, CentOS 7 and Fedora 24.)
1. Install the following packages to build the RPMs: 1. On CentOS 6 (which doesn't provide a bison/automake/autoconf of a recent enough version):
- Check out ../doc/Building_FRR_on_CentOS6.md for details on installing
a bison/automake/autoconf to support frr building.
yum install git autoconf automake libtool make gawk readline-devel \ Newer automake/autoconf/bison is only needed to build the rpm and is
texinfo dejagnu net-snmp-devel groff rpm-build net-snmp-devel \ **not** needed to install the binary rpm package
libcap-devel texi2html
(use `dnf install` on new Fedora instead of `yum install `) 2. Install the following packages to build the RPMs:
2. Checkout FRR under a **unpriviledged** user account yum install git autoconf automake libtool make gawk readline-devel \
texinfo net-snmp-devel groff pkgconfig rpm-build json-c-devel \
pam-devel texi2html bison libcap-devel flex
git clone https://github.com/frrouting/frr.git frr Additionally, on systems with systemd (CentOS 7, Fedora)
3. Run Bootstrap and make distribution tar.gz yum install systemd-devel
cd frr (use `dnf install` on new Fedora instead of `yum install`)
./bootstrap.sh
./configure --with-pkg-extra-version=-MyRPMVersion
make dist
Note: configure parameters are not important for the RPM building - except the **CentOS 6:** Please check doc/Building_FRR_on_CentOS6.md for details on
`with-pkg-extra-version` if you want to give the RPM a specific name to how to install required version of autoconf, automake and bison. The
mark your own unoffical build versions in the common Repo are too old.
4. Create RPM directory structure and populate with sources 3. Checkout FRR under a **unpriviledged** user account
mkdir rpmbuild git clone https://github.com/frrouting/frr.git frr
mkdir rpmbuild/SOURCES
mkdir rpmbuild/SPECS
cp redhat/*.spec rpmbuild/SPECS/
cp frr*.tar.gz rpmbuild/SOURCES/
5. Edit rpm/SPECS/frr.spec with configuration as needed 4. Run Bootstrap and make distribution tar.gz
Look at the beginning of the file and adjust the following parameters to enable
or disable features as required:
################# frr configure options #################### cd frr
# with-feature options ./bootstrap.sh
%{!?with_snmp: %global with_snmp 1 } ./configure --with-pkg-extra-version=-MyRPMVersion
%{!?with_vtysh: %global with_vtysh 1 } make dist
%{!?with_ospf_te: %global with_ospf_te 1 }
%{!?with_opaque_lsa: %global with_opaque_lsa 1 }
%{!?with_tcp_zebra: %global with_tcp_zebra 0 }
%{!?with_vtysh: %global with_vtysh 1 }
%{!?with_pam: %global with_pam 1 }
%{!?with_ospfclient: %global with_ospfclient 1 }
%{!?with_ospfapi: %global with_ospfapi 1 }
%{!?with_irdp: %global with_irdp 1 }
%{!?with_rtadv: %global with_rtadv 1 }
%{!?with_isisd: %global with_isisd 1 }
%{!?with_pimd: %global with_pimd 1 }
%{!?with_mpls: %global with_mpls 0 }
%{!?with_ldpd: %global with_ldpd 0 }
%{!?with_shared: %global with_shared 1 }
%{!?with_multipath: %global with_multipath 64 }
%{!?frr_user: %global frr_user frr }
%{!?vty_group: %global vty_group frrvt }
%{!?with_fpm: %global with_fpm 0 }
%{!?with_watchfrr: %global with_watchfrr 1 }
6. Build the RPM Note: configure parameters are not important for the RPM building - except the `with-pkg-extra-version` if you want to give the RPM a specific name to
mark your own unoffical build
rpmbuild --define "_topdir `pwd`/rpmbuild" -ba rpmbuild/SPECS/frr.spec 5. Create RPM directory structure and populate with sources
mkdir rpmbuild
mkdir rpmbuild/SOURCES
mkdir rpmbuild/SPECS
cp redhat/*.spec rpmbuild/SPECS/
cp frr*.tar.gz rpmbuild/SOURCES/
6. Edit rpm/SPECS/frr.spec with configuration as needed
Look at the beginning of the file and adjust the following parameters to enable or disable features as required:
############### FRRouting (FRR) configure options #################
# with-feature options
%{!?with_tcp_zebra: %global with_tcp_zebra 0 }
%{!?with_pam: %global with_pam 0 }
%{!?with_ospfclient: %global with_ospfclient 1 }
%{!?with_ospfapi: %global with_ospfapi 1 }
%{!?with_irdp: %global with_irdp 1 }
%{!?with_rtadv: %global with_rtadv 1 }
%{!?with_ldpd: %global with_ldpd 1 }
%{!?with_nhrpd: %global with_nhrpd 1 }
%{!?with_eigrp: %global with_eigrpd 1 }
%{!?with_shared: %global with_shared 1 }
%{!?with_multipath: %global with_multipath 256 }
%{!?frr_user: %global frr_user frr }
%{!?vty_group: %global vty_group frrvty }
%{!?with_fpm: %global with_fpm 0 }
%{!?with_watchfrr: %global with_watchfrr 1 }
%{!?with_bgp_vnc: %global with_bgp_vnc 0 }
%{!?with_pimd: %global with_pimd 1 }
7. Build the RPM
rpmbuild --define "_topdir `pwd`/rpmbuild" -ba rpmbuild/SPECS/frr.spec
DONE. DONE.
If all works correctly, then you should end up with the RPMs under `rpmbuild/RPMS` If all works correctly, then you should end up with the RPMs under
and the Source RPM under `rpmbuild/SRPMS` `rpmbuild/RPMS` and the Source RPM under `rpmbuild/SRPMS`
Enabling daemons after installation of the package: Enabling daemons after installation of the package:
@ -76,55 +85,36 @@ Enabling daemons after installation of the package:
### init.d based systems (ie CentOS 6): ### init.d based systems (ie CentOS 6):
1. Enable the daemons as needed to run after boot (Zebra is mandatory) 1. Edit /etc/frr/daemons and enable required routing daemons (Zebra is probably needed for most deployments, so make sure to enable it.)
chkconfig zebra on 2. Enable the daemons as needed to run after boot (Zebra is mandatory)
chkconfig ospfd on
chkconfig ospf6d on
chkconfig bgpd on
... etc
2. If you want to run `watchfrr`, then configure `/etc/sysconfig/frr` chkconfig frr on
and uncomment the line with the daemons for `watchfrr` to monitor,
then enable watchfrr
chkconfig watchfrr on
3. Check your firewall / IPtables to make sure the routing protocols are 3. Check your firewall / IPtables to make sure the routing protocols are
allowed. allowed.
4. Start the daemons (or reboot) 5. Start the FRR daemons (or reboot)
service zebra start service frr start
service bgpd start
service ospfd start
... etc
Configuration is stored in `/etc/frr/*.conf` files. Configuration is stored in `/etc/frr/*.conf` files and daemon selection is stored in `/etc/frr/daemons`.
### systemd based systems (ie CentOS 7, Fedora 22) ### systemd based systems (ie CentOS 7, Fedora 24)
1. Enable the daemons as needed to run after boot (Zebra is mandatory) 1. Edit /etc/frr/daemons and enable required routing daemons (Zebra is probably needed for most deployments, so make sure to enable it.)
systemctl enable zebra 2. Enable the frr daemons to run after boot.
systemctl enable ospfd
systemctl enable ospf6d
systemctl enable bgpd
... etc
Note: There is no watchfrr on systemd based systems. Systemd contains systemctl enable frr
the functionality of monitoring and restarting daemons.
2. Check your firewall / IPtables to make sure the routing protocols are 2. Check your firewall / IPtables to make sure the routing protocols are
allowed. allowed.
3. Start the daemons (or reboot) 3. Start the daemons (or reboot)
systemctl start zebra systemctl start frr
systemctl start bgpd
systemctl start ospfd
... etc
Configuration is stored in `/etc/frr/*.conf` files. Configuration is stored in `/etc/frr/*.conf` files and daemon selection is stored in `/etc/frr/daemons`.

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/bgpd.conf
### BEGIN INIT INFO
# Provides: bgpd
# Short-Description: BGP routing engine
# Description: BGP routing engine for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="bgpd"
cmd=bgpd
LOCK_FILE=/var/lock/subsys/bgpd
CONF_FILE=/etc/frr/bgpd.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $BGPD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

63
redhat/daemons Normal file
View File

@ -0,0 +1,63 @@
# This file tells the frr package which daemons to start.
#
# Entries are in the format: <daemon>=(yes|no|priority)
# 0, "no" = disabled
# 1, "yes" = highest priority
# 2 .. 10 = lower priorities
#
# For daemons which support multiple instances, a 2nd line listing
# the instances can be added. Eg for ospfd:
# ospfd=yes
# ospfd_instances="1,2"
#
# Priorities were suggested by Dancer <dancer@zeor.simegen.com>.
# They're used to start the FRR daemons in more than one step
# (for example start one or two at network initialization and the
# rest later). The number of FRR daemons being small, priorities
# must be between 1 and 9, inclusive (or the initscript has to be
# changed). /etc/init.d/frr then can be started as
#
# /etc/init.d/frr <start|stop|restart|<priority>>
#
# where priority 0 is the same as 'stop', priority 10 or 'start'
# means 'start all'
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/frr/examples/.
#
# ATTENTION:
#
# When activation a daemon at the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "frr", else
# the daemon will not be started by /etc/init.d/frr. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
#
watchfrr_enable=no
watchfrr_options=("-Az" "-b_" "-r/etc/init.d/frr_restart_%s" "-s/etc/init.d/frr_start_%s" "-k/etc/init.d/frr_stop_%s")
#
zebra=no
bgpd=no
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
ldpd=no
nhrpd=no
eigrpd=no
#
# Command line options for the daemons
#
zebra_options=("-A 127.0.0.1")
bgpd_options=("-A 127.0.0.1")
ospfd_options=("-A 127.0.0.1")
ospf6d_options=("-A ::1")
ripd_options=("-A 127.0.0.1")
ripngd_options=("-A ::1")
isisd_options=("-A 127.0.0.1")
ldpd_options=("-A 127.0.0.1")
nhrpd_options=("-A 127.0.0.1")
eigrpd_options=("-A 127.0.0.1")

561
redhat/frr.init Executable file
View File

@ -0,0 +1,561 @@
#!/bin/bash
#
# /etc/rc.d/init.d/frr
#
# Start/Stop the FRR Routing daemons
# <any general comments about this init script>
#
# chkconfig: 2345 15 85
#
# description: FRRouting (FRR) is a routing suite for IP routing protocols
# like BGP, OSPF, RIP and others. This script contols the main
# daemon "frr" as well as the individual protocol daemons.
#
### BEGIN INIT INFO
# Provides: frr
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $syslog
# Should-Start: $syslog
# Should-Stop: $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/Stop the FRR Routing daemons
# Description: FRRouting (FRR) is a routing suite for IP routing protocols
# like BGP, OSPF, RIP and others. This script contols the main
# daemon "frr" as well as the individual protocol daemons.
### END INIT INFO
PATH=/bin:/usr/bin:/sbin:/usr/sbin
D_PATH=/usr/lib/frr
C_PATH=/etc/frr
V_PATH=/var/run/frr
# Local Daemon selection may be done by using /etc/frr/daemons.
# See /usr/share/doc/frr/README.Debian.gz for further information.
# Keep zebra first and do not list watchfrr!
DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd ldpd nhrpd eigrpd"
MAX_INSTANCES=5
RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py
. /etc/init.d/functions
# Print the name of the pidfile.
pidfile()
{
echo "$V_PATH/$1.pid"
}
# Print the name of the vtysh.
vtyfile()
{
echo "$V_PATH/$1.vty"
}
# Check if daemon is started by using the pidfile.
started()
{
[ ! -e `pidfile $1` ] && return 3
if [ -n "$2" ] && [ "$2" == "log" ]; then
status -p `pidfile $1` $1 && return 0 || return $?
else
kill -0 `cat \`pidfile $1\`` 2> /dev/null || return 1
return 0
fi
}
# Loads the config via vtysh -b if configured to do so.
vtysh_b ()
{
# Rember, that all variables have been incremented by 1 in convert_daemon_prios()
if [ "$vtysh_enable" = 2 -a -f $C_PATH/frr.conf ]; then
/usr/bin/vtysh -b -n
fi
}
# Check if the daemon is activated and if its executable and config files
# are in place.
# params: daemon name
# returns: 0=ok, 1=error
check_daemon()
{
# If the integrated config file is used the others are not checked.
if [ -r "$C_PATH/frr.conf" ]; then
return 0
fi
# vtysh_enable has no config file nor binary so skip check.
# (Not sure why vtysh_enable is in this list but does not hurt)
if [ $1 != "watchfrr" -a $1 != "vtysh_enable" ]; then
# check for daemon binary
if [ ! -x "$D_PATH/$1" ]; then return 1; fi
# check for config file
if [ -n "$2" ]; then
if [ ! -r "$C_PATH/$1-$2.conf" ]; then
touch "$C_PATH/$1-$2.conf"
chown frr:frr "$C_PATH/$1-$2.conf"
fi
elif [ ! -r "$C_PATH/$1.conf" ]; then
touch "$C_PATH/$1.conf"
chown frr:frr "$C_PATH/$1.conf"
fi
fi
return 0
}
# Starts the server if it's not already running according to the pid file.
# The Frr daemons creates the pidfile when starting.
start()
{
ulimit -n $MAX_FDS > /dev/null 2> /dev/null
if [ "$1" = "watchfrr" ]; then
# We may need to restart watchfrr if new daemons are added and/or
# removed
if started "$1" ; then
stop watchfrr
else
# Echo only once. watchfrr is printed in the stop above
echo -n " $1"
fi
if [ -e /var/run/frr/watchfrr.started ] ; then
rm /var/run/frr/watchfrr.started
fi
daemon --pidfile=`pidfile $1` "$D_PATH/$1" -d "${watchfrr_options[@]}"
RETVAL=$?
[ $RETVAL -ne 0 ] && break
for i in `seq 1 10`;
do
if [ -e /var/run/frr/watchfrr.started ] ; then
RETVAL=0
break
else
sleep 1
fi
done
RETVAL=1
elif [ -n "$2" ]; then
echo -n " $1-$2"
if ! check_daemon $1 $2 ; then
echo -n " (binary does not exist)"
return;
fi
daemon --pidfile=`pidfile $1-$2` "$D_PATH/$1" -d `eval echo "$""$1""_options"` -n "$2"
RETVAL=$?
else
echo -n " $1 "
if ! check_daemon $1; then
echo " (binary does not exist)"
return;
fi
daemon --pidfile=`pidfile $1` "$D_PATH/$1" -d `eval echo "$""$1""_options"`
RETVAL=$?
fi
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$1
return $RETVAL
}
# Stop the daemon given in the parameter, printing its name to the terminal.
stop()
{
local inst
if [ -n "$2" ]; then
inst="$1-$2"
else
inst="$1"
fi
if ! started "$inst" ; then
# echo -n " ($inst)"
return 0
else
echo -n " $inst"
PIDFILE=`pidfile $inst`
PID=`cat $PIDFILE 2>/dev/null`
killproc -p "$PIDFILE" "$D_PATH/$1"
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $lockfile
rm -f `pidfile $inst`
rm -f `vtyfile $inst`
echo
return $RETVAL
fi
}
# Converts values from /etc/frr/daemons to all-numeric values.
convert_daemon_prios()
{
for name in $DAEMONS zebra vtysh_enable watchfrr_enable; do
# First, assign the value set by the user to $value
eval value=\${${name}:0:3}
# Daemon not activated or entry missing?
if [ "$value" = "no" -o "$value" = "" ]; then value=0; fi
# These strings parsed for backwards compatibility.
if [ "$value" = "yes" -o "$value" = "true" ]; then
value=1;
fi
# Zebra is threatened special. It must be between 0=off and the first
# user assigned value "1" so we increase all other enabled daemons' values.
if [ "$name" != "zebra" -a "$value" -gt 0 ]; then value=`expr "$value" + 1`; fi
# If e.g. name is zebra then we set "zebra=yes".
eval $name=$value
done
}
# Starts watchfrr for all wanted daemons.
start_watchfrr()
{
local daemon_name
local daemon_prio
local found_one
local daemon_inst
# Start the monitor daemon only if desired.
if [ 0 -eq "$watchfrr_enable" ]; then
return
fi
# Check variable type
if ! declare -p watchfrr_options | grep -q '^declare \-a'; then
echo
echo "ERROR: The variable watchfrr_options from /etc/frr/daemons must be a BASH array!"
echo "ERROR: Please convert config file and restart!"
exit 1
fi
# Which daemons have been started?
found_one=0
for daemon_name in $DAEMONS; do
eval daemon_prio=\$$daemon_name
if [ "$daemon_prio" -gt 0 ]; then
eval "daemon_inst=\${${daemon_name}_instances//,/ }"
if [ -n "$daemon_inst" ]; then
for inst in ${daemon_inst}; do
eval "inst_disable=\${${daemon_name}_${inst}}"
if [ -z ${inst_disable} ] || [ ${inst_disable} != 0 ]; then
if check_daemon $daemon_name $inst; then
watchfrr_options+=("${daemon_name}-${inst}")
fi
fi
done
else
if check_daemon $daemon_name; then
watchfrr_options+=($daemon_name)
fi
fi
found_one=1
fi
done
# Start if at least one daemon is activated.
if [ $found_one -eq 1 ]; then
echo "Starting FRRouting monitor daemon:"
start watchfrr
fi
}
# Stopps watchfrr.
stop_watchfrr()
{
echo "Stopping FRRouting monitor daemon:"
stop watchfrr
}
# Stops all daemons that have a lower level of priority than the given.
# (technically if daemon_prio >= wanted_prio)
stop_prio()
{
local wanted_prio
local daemon_prio
local daemon_list
local daemon_inst
local inst
if [ -n "$2" ] && [[ "$2" =~ (.*)-(.*) ]]; then
daemon=${BASH_REMATCH[1]}
inst=${BASH_REMATCH[2]}
else
daemon="$2"
fi
wanted_prio=$1
daemon_list=${daemon:-$DAEMONS}
echo "Stopping FRRouting daemons (prio:$wanted_prio):"
for prio_i in `seq 10 -1 $wanted_prio`; do
for daemon_name in $daemon_list; do
eval daemon_prio=\${${daemon_name}:0:3}
daemon_inst=""
if [ $daemon_prio -eq $prio_i ]; then
eval "daemon_inst=\${${daemon_name}_instances//,/ }"
if [ -n "$daemon_inst" ]; then
for i in ${daemon_inst}; do
if [ -n "$inst" ] && [ "$i" == "$inst" ]; then
stop "$daemon_name" "$inst"
elif [ x"$inst" == x ]; then
stop "$daemon_name" "$i"
fi
done
else
stop "$daemon_name"
fi
fi
done
done
if [ -z "$inst" ]; then
# Now stop other daemons that're prowling, coz the daemons file changed
echo "Stopping other FRRouting daemons"
if [ -n "$daemon" ]; then
eval "file_list_suffix="$V_PATH"/"$daemon*""
else
eval "file_list_suffix="$V_PATH/*""
fi
for pidfile in $file_list_suffix.pid; do
if [ -f "$pidfile" ]; then
filename=${pidfile##*/}
daemon=${filename%.*}
echo -n " $daemon"
killproc -p "$pidfile" "$daemon"
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $lockfile
rm -f "$pidfile"
echo
fi
done
echo -n "Removing remaining .vty files"
for vtyfile in $file_list_suffix.vty; do
rm -rf "$vtyfile"
done
echo
fi
}
# Starts all daemons that have a higher level of priority than the given.
# (technically if daemon_prio <= wanted_prio)
start_prio()
{
local wanted_prio
local daemon_prio
local daemon_list
local daemon_name
local daemon_inst
local inst
if [ -n "$2" ] && [[ "$2" =~ (.*)-(.*) ]]; then
daemon=${BASH_REMATCH[1]}
inst=${BASH_REMATCH[2]}
else
daemon="$2"
fi
wanted_prio=$1
daemon_list=${daemon:-$DAEMONS}
echo "Starting FRRouting daemons (prio:$wanted_prio):"
for prio_i in `seq 1 $wanted_prio`; do
for daemon_name in $daemon_list; do
eval daemon_prio=\$${daemon_name}
daemon_inst=""
if [ $daemon_prio -eq $prio_i ]; then
eval "daemon_inst=\${${daemon_name}_instances//,/ }"
if [ -n "$daemon_inst" ]; then
if [ `echo "$daemon_inst" | wc -w` -gt ${MAX_INSTANCES} ]; then
echo "Max instances supported is ${MAX_INSTANCES}. Aborting"
exit 1
fi
# Check if we're starting again by switching from single instance
# to MI version
if started "$daemon_name"; then
PIDFILE=`pidfile $daemon_name`
killproc -p "$PIDFILE" "$daemon_name"
rm -f `pidfile $1`
rm -f `vtyfile $1`
fi
for i in ${daemon_inst}; do
if [ -n "$inst" ] && [ "$i" == "$inst" ]; then
start "$daemon_name" "$inst"
elif [ x"$inst" == x ]; then
start "$daemon_name" "$i"
fi
done
else
# Check if we're starting again by switching from
# single instance to MI version
eval "file_list_suffix="$V_PATH"/"$daemon_name-*""
for pidfile in $file_list_suffix.pid; do
if [ -f "$pidfile" ]; then
killproc -p "$pidfile" "$daemon_name"
rm -rf "$pidfile"
fi
done
for vtyfile in $file_list_suffix.vty; do
rm -rf "$vtyfile"
done
start "$daemon_name"
fi
fi
done
done
}
check_status()
{
local daemon_name
local daemon_prio
local daemon_inst
local failed_status=0
if [ -n "$1" ] && [[ "$1" =~ (.*)-(.*) ]]; then
daemon=${BASH_REMATCH[1]}
inst=${BASH_REMATCH[2]}
else
daemon="$1"
fi
daemon_list=${daemon:-$DAEMONS}
# Which daemons have been started?
for daemon_name in $daemon_list; do
eval daemon_prio=\$$daemon_name
if [ "$daemon_prio" -gt 0 ]; then
eval "daemon_inst=\${${daemon_name}_instances//,/ }"
if [ -n "$daemon_inst" ]; then
for i in ${daemon_inst}; do
if [ -n "$inst" -a "$inst" = "$i" ]; then
started "$1" "log" || failed_status=$?
elif [ -z "$inst" ]; then
started "$daemon_name-$i" "log" || failed_status=$?
fi
done
else
started "$daemon_name" "log" || failed_status=$?
fi
fi
done
# All daemons that need to have been started are up and running
return $failed_status
}
#########################################################
# Main program #
#########################################################
# Config broken but script must exit silently.
[ ! -r "$C_PATH/daemons" ] && exit 0
# Load configuration
. "$C_PATH/daemons"
# Read configuration variable file if it is present
[ -r /etc/sysconfig/frr ] && . /etc/sysconfig/frr
MAX_INSTANCES=${MAX_INSTANCES:=5}
# Set priority of un-startable daemons to 'no' and substitute 'yes' to '0'
convert_daemon_prios
if [ ! -d $V_PATH ]; then
echo "Creating $V_PATH"
mkdir -p $V_PATH
chown frr:frr $V_PATH
chmod 755 /$V_PATH
fi
if [ -n "$3" ] && [ "$3" != "all" ]; then
dmn="$2"-"$3"
elif [ -n "$2" ] && [ "$2" != "all" ]; then
dmn="$2"
fi
case "$1" in
start)
# Try to load this necessary (at least for 2.6) module.
if [ -d /lib/modules/`uname -r` ] ; then
echo "Loading capability module if not yet done."
LC_ALL=C modprobe -a capability 2>&1 | egrep -v "(not found|Can't locate)"
fi
# Start all daemons
cd $C_PATH/
if [ "$2" != "watchfrr" ]; then
start_prio 10 $dmn
fi
start_watchfrr
vtysh_b
;;
1|2|3|4|5|6|7|8|9|10)
# Stop/start daemons for the appropriate priority level
stop_prio $1
start_prio $1
vtysh_b
;;
stop|0)
# Stop all daemons at level '0' or 'stop'
stop_watchfrr
if [ "$dmn" != "watchfrr" ]; then
[ -n "${dmn}" ] && eval "${dmn/-/_}=0"
stop_prio 0 $dmn
fi
if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
echo "Removing all routes made by zebra."
ip route flush proto zebra
else
[ -n "$dmn" ] && eval "${dmn/-/_}=0"
start_watchfrr
fi
;;
reload)
# Just apply the commands that have changed, no restart necessary
if [ ! -x "$RELOAD_SCRIPT" ]; then
echo "frr-reload - reload not supported. Use restart or install frr-pythontools package"
exit 1
fi
NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}"
if [ ! -r $NEW_CONFIG_FILE ]; then
echo "Unable to read configuration file $NEW_CONFIG_FILE. Only supporting integrated config"
exit 1
fi
echo "Applying only incremental changes to running configuration from frr.conf"
"$RELOAD_SCRIPT" --reload /etc/frr/frr.conf
exit $?
;;
status)
check_status $dmn
exit $?
;;
restart|force-reload)
$0 stop $dmn
sleep 1
$0 start $dmn
;;
*)
echo "Usage: /etc/init.d/frr {start|stop|status|reload|restart|force-reload|<priority>} [daemon]"
echo " E.g. '/etc/init.d/frr 5' would start all daemons with a prio 1-5."
echo " reload applies only modifications from the running config to all daemons."
echo " reload neither restarts starts any daemon nor starts any new ones."
echo " Read /usr/share/doc/frr/README.Debian for details."
exit 1
;;
esac
exit 0

View File

@ -61,3 +61,20 @@
/bin/kill -USR1 `cat /var/run/frr/ldpd.pid 2> /dev/null` 2> /dev/null || true /bin/kill -USR1 `cat /var/run/frr/ldpd.pid 2> /dev/null` 2> /dev/null || true
endscript endscript
} }
/var/log/frr/nhrpd.log {
notifempty
missingok
postrotate
/bin/kill -USR1 `cat /var/run/frr/nhrpd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
/var/log/frr/eigrpd.log {
notifempty
missingok
postrotate
/bin/kill -USR1 `cat /var/run/frr/eigrpd.pid 2> /dev/null` 2> /dev/null || true
endscript
}

23
redhat/frr.service Normal file
View File

@ -0,0 +1,23 @@
[Unit]
Description=FRRouting (FRR)
After=syslog.target networking.service
OnFailure=heartbeat-failed@%n.service
[Service]
Nice=-5
Type=forking
NotifyAccess=all
StartLimitInterval=3m
StartLimitBurst=3
TimeoutSec=1m
WatchdogSec=60s
RestartSec=5
Restart=on-abnormal
LimitNOFILE=1024
ExecStart=/usr/lib/frr/frr start
ExecStop=/usr/lib/frr/frr stop
ExecReload=/usr/lib/frr/frr reload
[Install]
WantedBy=network-online.target

View File

@ -8,36 +8,36 @@
# rpms again and again on the same day, so the newer rpms can be installed. # rpms again and again on the same day, so the newer rpms can be installed.
# bumping the number each time. # bumping the number each time.
####################### FRRouting (FRR) configure options ######################### #################### FRRouting (FRR) configure options #####################
# with-feature options # with-feature options
%{!?with_tcp_zebra: %global with_tcp_zebra 0 } %{!?with_tcp_zebra: %global with_tcp_zebra 0 }
%{!?with_pam: %global with_pam 0 } %{!?with_pam: %global with_pam 0 }
%{!?with_ospfclient: %global with_ospfclient 1 } %{!?with_ospfclient: %global with_ospfclient 1 }
%{!?with_ospfapi: %global with_ospfapi 1 } %{!?with_ospfapi: %global with_ospfapi 1 }
%{!?with_irdp: %global with_irdp 1 } %{!?with_irdp: %global with_irdp 1 }
%{!?with_rtadv: %global with_rtadv 1 } %{!?with_rtadv: %global with_rtadv 1 }
%{!?with_mpls: %global with_mpls 0 } %{!?with_ldpd: %global with_ldpd 1 }
%{!?with_ldpd: %global with_ldpd 0 } %{!?with_nhrpd: %global with_nhrpd 1 }
%{!?with_nhrpd: %global with_nhrpd 1 } %{!?with_eigrpd: %global with_eigrpd 1 }
%{!?with_shared: %global with_shared 1 } %{!?with_shared: %global with_shared 1 }
%{!?with_multipath: %global with_multipath 256 } %{!?with_multipath: %global with_multipath 256 }
%{!?frr_user: %global frr_user frr } %{!?frr_user: %global frr_user frr }
%{!?vty_group: %global vty_group frrvty } %{!?vty_group: %global vty_group frrvty }
%{!?with_fpm: %global with_fpm 0 } %{!?with_fpm: %global with_fpm 0 }
%{!?with_watchfrr: %global with_watchfrr 1 } %{!?with_watchfrr: %global with_watchfrr 1 }
%{!?with_bgp_vnc: %global with_bgp_vnc 0 } %{!?with_bgp_vnc: %global with_bgp_vnc 0 }
%{!?with_pimd: %global with_pimd 1 }
# path defines # path defines
%define _sysconfdir /etc/frr %define _sysconfdir /etc/frr
%define _sbindir /usr/lib/frr %define _sbindir /usr/lib/frr
%define zeb_src %{_builddir}/%{name}-%{frrversion} %define zeb_src %{_builddir}/%{name}-%{frrversion}
%define zeb_rh_src %{zeb_src}/redhat %define zeb_rh_src %{zeb_src}/redhat
%define zeb_docs %{zeb_src}/doc %define zeb_docs %{zeb_src}/doc
%define frr_tools %{zeb_src}/tools %define frr_tools %{zeb_src}/tools
%define frr_tools_etc %{frr_tools}/etc
# defines for configure # defines for configure
%define _localstatedir /var/run/frr %define _localstatedir /var/run/frr
############################################################################ ############################################################################
#### Version String tweak #### Version String tweak
@ -47,38 +47,53 @@
#### Check version of texi2html #### Check version of texi2html
# Old versions don't support "--number-footnotes" option. # Old versions don't support "--number-footnotes" option.
%{expand: %%global texi2htmlversion %(/usr/bin/texi2html --version | cut -d. -f1)} %{expand: %%global texi2htmlversion %(if [[ -f /usr/bin/texi2html ]]; then /usr/bin/texi2html --version | cut -d. -f1; else echo 0; fi)}
#### Check for systemd or init.d (upstart) #### Check for systemd or init.d (upstart)
# Check for init.d (upstart) as used in CentOS 6 or systemd (ie CentOS 7) # Check for init.d (upstart) as used in CentOS 6 or systemd (ie CentOS 7)
%{expand: %%global initsystem %(if [[ `/sbin/init --version 2> /dev/null` =~ upstart ]]; then echo upstart; elif [[ `systemctl` =~ -\.mount ]]; then echo systemd; fi)} %{expand: %%global initsystem %(if [[ `/sbin/init --version 2> /dev/null` =~ upstart ]]; then echo upstart; elif [[ `file /sbin/init` =~ "symbolic link to \`../lib/systemd/systemd'" ]]; then echo systemd; elif [[ `systemctl` =~ -\.mount ]]; then echo systemd; fi)}
# #
# If init system is systemd, then always disable watchfrr # If init system is systemd, then always disable watchfrr
# #
%if "%{initsystem}" == "systemd" %if "%{initsystem}" == "systemd"
# Note: For systems with systemd, watchfrr will NOT be built. Systemd # Note: For systems with systemd, watchfrr will NOT be built. Systemd
# takes over the role of restarting crashed processes. Value will # takes over the role of restarting crashed processes. Value will
# be overwritten with 0 below for systemd independent on the setting here # be overwritten with 0 below for systemd independent on the setting here
%global with_watchfrr 1 %global with_watchfrr 1
%endif
#### Check for RedHat 6.x or CentOS 6.x - they are too old to support PIM.
#### Always disable it on these old systems unconditionally
%{expand: %%global redhat6 %(if [[ `cat /etc/redhat-release 2> /dev/null` =~ release\ 6\. ]]; then echo 6; else echo 0; fi)}
#
# if CentOS 6 / RedHat 6, then disable PIMd
%if "%{redhat6}" == "6"
%global with_pimd 0
%endif %endif
# if FPM is enabled, then enable tcp_zebra as well # if FPM is enabled, then enable tcp_zebra as well
# #
%if %{with_fpm} %if %{with_fpm}
%global with_tcp_zebra 1 %global with_tcp_zebra 1
%endif %endif
# misc internal defines # misc internal defines
%{!?frr_uid: %global frr_uid 92 } %{!?frr_uid: %global frr_uid 92 }
%{!?frr_gid: %global frr_gid 92 } %{!?frr_gid: %global frr_gid 92 }
%{!?vty_gid: %global vty_gid 85 } %{!?vty_gid: %global vty_gid 85 }
%define daemon_list zebra ripd ospfd bgpd isisd pimd ripngd ospf6d %define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d
%if %{with_ldpd} %if %{with_ldpd}
%define daemon_ldpd ldpd %define daemon_ldpd ldpd
%else %else
%define daemon_ldpd "" %define daemon_ldpd ""
%endif
%if %{with_pimd}
%define daemon_pimd pimd
%else
%define daemon_pimd ""
%endif %endif
%if %{with_nhrpd} %if %{with_nhrpd}
@ -87,52 +102,57 @@
%define daemon_nhrpd "" %define daemon_nhrpd ""
%endif %endif
%if %{with_watchfrr} %if %{with_eigrpd}
%define daemon_watchfrr watchfrr %define daemon_eigrpd eigrpd
%else %else
%define daemon_watchfrr "" %define daemon_eigrpd ""
%endif %endif
%define all_daemons %{daemon_list} %{daemon_ldpd} %{daemon_nhrpd} %{daemon_watchfrr} %if %{with_watchfrr}
%define daemon_watchfrr watchfrr
%else
%define daemon_watchfrr ""
%endif
%define all_daemons %{daemon_list} %{daemon_ldpd} %{daemon_pimd} %{daemon_nhrpd} %{daemon_eigrpd} %{daemon_watchfrr}
# allow build dir to be kept # allow build dir to be kept
%{!?keep_build: %global keep_build 0 } %{!?keep_build: %global keep_build 0 }
#release sub-revision (the two digits after the CONFDATE) #release sub-revision (the two digits after the CONFDATE)
%{!?release_rev: %global release_rev 01 } %{!?release_rev: %global release_rev 01 }
Summary: Routing daemon Summary: Routing daemon
Name: frr Name: frr
Version: %{rpmversion} Version: %{rpmversion}
Release: @CONFDATE@%{release_rev}%{?dist} Release: @CONFDATE@%{release_rev}%{?dist}
License: GPLv2+ License: GPLv2+
Group: System Environment/Daemons Group: System Environment/Daemons
Source0: http://www.frrouting.org/releases/frr/%{name}-%{frrversion}.tar.gz Source0: http://www.frrouting.org/releases/frr/%{name}-%{frrversion}.tar.gz
URL: http://www.frrouting.org URL: http://www.frrouting.org
Requires: ncurses json-c Requires(pre): /sbin/install-info
Requires(pre): /sbin/install-info
Requires(preun): /sbin/install-info Requires(preun): /sbin/install-info
Requires(post): /sbin/install-info Requires(post): /sbin/install-info
BuildRequires: texi2html texinfo autoconf patch libcap-devel groff BuildRequires: gcc texi2html texinfo patch libcap-devel groff
BuildRequires: readline readline-devel ncurses ncurses-devel BuildRequires: readline readline-devel ncurses ncurses-devel
BuildRequires: json-c-devel bison flex BuildRequires: json-c-devel bison >= 2.7 flex make
Requires: ncurses initscripts Requires: ncurses json-c initscripts
%if %{with_pam} %if %{with_pam}
BuildRequires: pam-devel BuildRequires: pam-devel
Requires: pam Requires: pam
%endif %endif
%if "%{initsystem}" == "systemd" %if "%{initsystem}" == "systemd"
BuildRequires: systemd BuildRequires: systemd systemd-devel
Requires(post): systemd Requires(post): systemd
Requires(preun): systemd Requires(preun): systemd
Requires(postun): systemd Requires(postun): systemd
%else %else
# Initscripts > 5.60 is required for IPv6 support # Initscripts > 5.60 is required for IPv6 support
Requires(pre): initscripts >= 5.60 Requires(pre): initscripts >= 5.60
%endif %endif
Provides: routingdaemon = %{version}-%{release} Provides: routingdaemon = %{version}-%{release}
BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRoot: %{_tmppath}/%{name}-%{version}-root
Obsoletes: bird gated mrt zebra frr-sysvinit Obsoletes: bird gated mrt zebra frr-sysvinit
%description %description
FRRouting is a free software that manages TCP/IP based routing FRRouting is a free software that manages TCP/IP based routing
@ -140,7 +160,7 @@ protocol. It takes multi-server and multi-thread approach to resolve
the current complexity of the Internet. the current complexity of the Internet.
FRRouting supports BGP4, OSPFv2, OSPFv3, ISIS, RIP, RIPng, PIM, LDP FRRouting supports BGP4, OSPFv2, OSPFv3, ISIS, RIP, RIPng, PIM, LDP
and NHRP. NHRP and EIGRP.
FRRouting is a fork of Quagga. FRRouting is a fork of Quagga.
@ -151,6 +171,15 @@ Group: System Environment/Daemons
%description contrib %description contrib
Contributed/3rd party tools which may be of use with frr. Contributed/3rd party tools which may be of use with frr.
%package pythontools
Summary: python tools for frr
BuildRequires: python
Requires: python python-ipaddr
Group: System Environment/Daemons
%description pythontools
Contributed python 2.7 tools which may be of use with frr.
%package devel %package devel
Summary: Header and object files for frr development Summary: Header and object files for frr development
Group: System Environment/Daemons Group: System Environment/Daemons
@ -181,81 +210,88 @@ developing OSPF-API and frr applications.
--libdir=%{_libdir} \ --libdir=%{_libdir} \
--libexecdir=%{_libexecdir} \ --libexecdir=%{_libexecdir} \
--localstatedir=%{_localstatedir} \ --localstatedir=%{_localstatedir} \
--disable-werror \ --disable-werror \
%if !%{with_shared} %if !%{with_shared}
--disable-shared \ --disable-shared \
%endif %endif
%if %{with_multipath} %if %{with_multipath}
--enable-multipath=%{with_multipath} \ --enable-multipath=%{with_multipath} \
%endif %endif
%if %{with_tcp_zebra} %if %{with_tcp_zebra}
--enable-tcp-zebra \ --enable-tcp-zebra \
%endif %endif
--enable-vtysh \ --enable-vtysh \
%if %{with_ospfclient} %if %{with_ospfclient}
--enable-ospfclient=yes \ --enable-ospfclient \
%else %else
--enable-ospfclient=no\ --disable-ospfclient\
%endif %endif
%if %{with_ospfapi} %if %{with_ospfapi}
--enable-ospfapi=yes \ --enable-ospfapi=yes \
%else %else
--enable-ospfapi=no \ --enable-ospfapi=no \
%endif %endif
%if %{with_irdp} %if %{with_irdp}
--enable-irdp=yes \ --enable-irdp=yes \
%else %else
--enable-irdp=no \ --enable-irdp=no \
%endif %endif
%if %{with_rtadv} %if %{with_rtadv}
--enable-rtadv=yes \ --enable-rtadv=yes \
%else %else
--enable-rtadv=no \ --enable-rtadv=no \
%endif
%if %{with_mpls}
--enable-mpls=yes \
%else
--disable-mpls \
%endif %endif
%if %{with_ldpd} %if %{with_ldpd}
--enable-ldpd \ --enable-ldpd \
%else %else
--disable-ldpd \ --disable-ldpd \
%endif
%if %{with_pimd}
--enable-pimd \
%else
--disable-pimd \
%endif %endif
%if %{with_nhrpd} %if %{with_nhrpd}
--enable-nhrpd \ --enable-nhrpd \
%else %else
--disable-nhrpd \ --disable-nhrpd \
%endif %endif
%if %{with_eigrpd}
--enable-eigrpd \
%else
--disable-eigrpd \
%endif
%if %{with_pam} %if %{with_pam}
--with-libpam \ --with-libpam \
%endif %endif
%if 0%{?frr_user:1} %if 0%{?frr_user:1}
--enable-user=%frr_user \ --enable-user=%frr_user \
--enable-group=%frr_user \ --enable-group=%frr_user \
%endif %endif
%if 0%{?vty_group:1} %if 0%{?vty_group:1}
--enable-vty-group=%vty_group \ --enable-vty-group=%vty_group \
%endif %endif
%if %{with_fpm} %if %{with_fpm}
--enable-fpm \ --enable-fpm \
%else %else
--disable-fpm \ --disable-fpm \
%endif %endif
%if %{with_watchfrr} %if %{with_watchfrr}
--enable-watchfrr \ --enable-watchfrr \
%else %else
--disable-watchfrr \ --disable-watchfrr \
%endif %endif
%if %{with_bgp_vnc} %if %{with_bgp_vnc}
--enable-bgp-vnc \ --enable-bgp-vnc \
%else %else
--disable-bgp-vnc \ --disable-bgp-vnc \
%endif %endif
--enable-gcc-rdynamic \ --enable-gcc-rdynamic \
--enable-isisd=yes \ --enable-isisd=yes \
--enable-systemd=yes \ %if "%{initsystem}" == "systemd"
--enable-poll=yes --enable-systemd=yes \
%endif
--enable-poll=yes
make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" make %{?_smp_mflags} MAKEINFO="makeinfo --no-split"
@ -275,29 +311,27 @@ make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install
# Remove this file, as it is uninstalled and causes errors when building on RH9 # Remove this file, as it is uninstalled and causes errors when building on RH9
rm -rf %{buildroot}/usr/share/info/dir rm -rf %{buildroot}/usr/share/info/dir
# Remove debian init script if it was installed
rm -f %{buildroot}%{_sbindir}/frr
# install /etc sources # install /etc sources
%if "%{initsystem}" == "systemd" %if "%{initsystem}" == "systemd"
mkdir -p %{buildroot}%{_unitdir} mkdir -p %{buildroot}%{_unitdir}
install %{frr_tools}/frr.service \ install %{zeb_rh_src}/frr.service \
%{buildroot}%{_unitdir}/frr.service %{buildroot}%{_unitdir}/frr.service
install %{zeb_rh_src}/frr.init \
%{buildroot}%{_sbindir}/frr
%else %else
mkdir -p %{buildroot}/etc/rc.d/init.d mkdir -p %{buildroot}/etc/rc.d/init.d
for daemon in %{all_daemons} ; do install %{zeb_rh_src}/frr.init \
if [ x"${daemon}" != x"" ] ; then %{buildroot}/etc/rc.d/init.d/frr
install %{zeb_rh_src}/${daemon}.init \
%{buildroot}/etc/rc.d/init.d/${daemon}
fi
done
%endif %endif
install %{frr_tools_dir}/frr/daemons.conf %{buildroot}/etc/frr install %{zeb_rh_src}/daemons %{buildroot}/etc/frr
install %{frr_tools_dir}/frr/daemons %{buildroot}/etc/frr
install -m644 %{frr_tools_dir}/default/frr %{buildroot}/etc/default
install -m644 %{zeb_rh_src}/frr.pam \ install -m644 %{zeb_rh_src}/frr.pam \
%{buildroot}/etc/pam.d/frr %{buildroot}/etc/pam.d/frr
install -m644 %{zeb_rh_src}/frr.logrotate \ install -m644 %{zeb_rh_src}/frr.logrotate \
%{buildroot}/etc/logrotate.d/frr %{buildroot}/etc/logrotate.d/frr
install -d -m750 %{buildroot}/var/run/frr install -d -m750 %{buildroot}/var/run/frr
%pre %pre
@ -330,11 +364,11 @@ fi
zebra_spec_add_service () zebra_spec_add_service ()
{ {
# Add port /etc/services entry if it isn't already there # Add port /etc/services entry if it isn't already there
if [ -f /etc/services ] && \ if [ -f /etc/services ] && \
! %__sed -e 's/#.*$//' /etc/services | %__grep -wq $1 ; then ! %__sed -e 's/#.*$//' /etc/services | %__grep -wq $1 ; then
echo "$1 $2 # $3" >> /etc/services echo "$1 $2 # $3" >> /etc/services
fi fi
} }
zebra_spec_add_service zebrasrv 2600/tcp "zebra service" zebra_spec_add_service zebrasrv 2600/tcp "zebra service"
@ -348,147 +382,105 @@ zebra_spec_add_service ospf6d 2606/tcp "OSPF6d vty"
zebra_spec_add_service ospfapi 2607/tcp "OSPF-API" zebra_spec_add_service ospfapi 2607/tcp "OSPF-API"
%endif %endif
zebra_spec_add_service isisd 2608/tcp "ISISd vty" zebra_spec_add_service isisd 2608/tcp "ISISd vty"
%if %{with_eigrpd}
zebra_spec_add_service eigrpd 2609/tcp "EIGRPd vty"
%endif
%if %{with_nhrpd} %if %{with_nhrpd}
zebra_spec_add_service nhrpd 2610/tcp "NHRPd vty" zebra_spec_add_service nhrpd 2610/tcp "NHRPd vty"
%endif %endif
%if %{with_pimd}
zebra_spec_add_service pimd 2611/tcp "PIMd vty" zebra_spec_add_service pimd 2611/tcp "PIMd vty"
%endif
%if %{with_ldpd} %if %{with_ldpd}
zebra_spec_add_service ldpd 2612/tcp "LDPd vty" zebra_spec_add_service ldpd 2612/tcp "LDPd vty"
%endif %endif
%if "%{initsystem}" == "systemd" %if "%{initsystem}" == "systemd"
for daemon in %all_daemons ; do for daemon in %all_daemons ; do
%systemd_post frr.service %systemd_post frr.service
done done
%else %else
for daemon in %all_daemons ; do /sbin/chkconfig --add frr
/sbin/chkconfig --add ${daemon}
done
%endif %endif
/sbin/install-info %{_infodir}/frr.info.gz %{_infodir}/dir /sbin/install-info %{_infodir}/frr.info.gz %{_infodir}/dir
# Create dummy files if they don't exist so basic functions can be used. # Create dummy files if they don't exist so basic functions can be used.
if [ ! -e %{_sysconfdir}/zebra.conf ]; then if [ ! -e %{_sysconfdir}/zebra.conf ]; then
echo "hostname `hostname`" > %{_sysconfdir}/zebra.conf echo "hostname `hostname`" > %{_sysconfdir}/zebra.conf
%if 0%{?frr_user:1} %if 0%{?frr_user:1}
chown %frr_user:%frr_user %{_sysconfdir}/zebra.conf* chown %frr_user:%frr_user %{_sysconfdir}/zebra.conf*
%endif %endif
chmod 640 %{_sysconfdir}/zebra.conf chmod 640 %{_sysconfdir}/zebra.conf*
fi fi
for daemon in %{all_daemons} ; do for daemon in %{all_daemons} ; do
if [ ! -e %{_sysconfdir}/${daemon}.conf ]; then if [ x"${daemon}" != x"" ] ; then
touch %{_sysconfdir}/${daemon}.conf if [ ! -e %{_sysconfdir}/${daemon}.conf ]; then
%if 0%{?frr_user:1} touch %{_sysconfdir}/${daemon}.conf
chown %frr_user:%frr_user %{_sysconfdir}/${daemon}.conf* %if 0%{?frr_user:1}
%endif chown %frr_user:%frr_user %{_sysconfdir}/${daemon}.conf*
fi %endif
fi
fi
done done
%if 0%{?frr_user:1}
chown %frr_user:%frr_user %{_sysconfdir}/daemons
%endif
%if %{with_watchfrr} %if %{with_watchfrr}
# No config for watchfrr - this is part of /etc/sysconfig/frr # No config for watchfrr - this is part of /etc/sysconfig/frr
rm -f %{_sysconfdir}/watchfrr.* rm -f %{_sysconfdir}/watchfrr.*
%endif %endif
if [ ! -e %{_sysconfdir}/vtysh.conf ]; then if [ ! -e %{_sysconfdir}/vtysh.conf ]; then
touch %{_sysconfdir}/vtysh.conf touch %{_sysconfdir}/vtysh.conf
chmod 640 %{_sysconfdir}/vtysh.conf chmod 640 %{_sysconfdir}/vtysh.conf
%if 0%{?frr_user:1}
%if 0%{?vty_group:1} %if 0%{?vty_group:1}
chown frr:%{vty_group} %{_sysconfdir}/vtysh.conf* chown %{frr_user}:%{vty_group} %{_sysconfdir}/vtysh.conf*
%endif
%endif %endif
fi fi
%postun %postun
if [ "$1" -ge 1 ]; then if [ "$1" -ge 1 ]; then
# Find out which daemons need to be restarted. #
for daemon in %all_daemons ; do # Upgrade from older version
if [ -f /var/lock/subsys/${daemon} ]; then #
eval restart_${daemon}=yes %if "%{initsystem}" == "systemd"
else ##
eval restart_${daemon}=no ## Systemd Version
fi ##
done %systemd_postun frr.service
# Rename restart flags for daemons handled specially. %else
running_zebra="$restart_zebra" ##
restart_zebra=no ## init.d Version
%if %{with_watchfrr} ##
running_watchfrr="$restart_watchfrr" /etc/rc.d/init.d/frr restart >/dev/null 2>&1
restart_watchfrr=no %endif
%endif :
%if "%{initsystem}" == "systemd"
##
## Systemd Version
##
# No watchfrr for systemd version
#
# Stop all daemons other than zebra.
for daemon in %all_daemons ; do
eval restart=\$restart_${daemon}
[ "$restart" = yes ] && \
%systemd_postun ${daemon}.service
done
# Restart zebra.
[ "$running_zebra" = yes ] && \
%systemd_postun_with_restart $daemon.service
# Start all daemons other than zebra.
for daemon in %all_daemons ; do
eval restart=\$restart_${daemon}
[ "$restart" = yes ] && \
%systemd_post ${daemon}.service
done
%else
##
## init.d Version
##
%if %{with_watchfrr}
# Stop watchfrr first.
[ "$running_watchfrr" = yes ] && \
/etc/rc.d/init.d/watchfrr stop >/dev/null 2>&1
%endif
# Stop all daemons other than zebra and watchfrr.
for daemon in %all_daemons ; do
eval restart=\$restart_${daemon}
[ "$restart" = yes ] && \
/etc/rc.d/init.d/${daemon} stop >/dev/null 2>&1
done
# Restart zebra.
[ "$running_zebra" = yes ] && \
/etc/rc.d/init.d/zebra restart >/dev/null 2>&1
# Start all daemons other than zebra and watchfrr.
for daemon in %all_daemons ; do
eval restart=\$restart_${daemon}
[ "$restart" = yes ] && \
/etc/rc.d/init.d/${daemon} start >/dev/null 2>&1
done
%if %{with_watchfrr}
# Start watchfrr last.
# Avoid postun scriptlet error if watchfrr is not running.
[ "$running_watchfrr" = yes ] && \
/etc/rc.d/init.d/watchfrr start >/dev/null 2>&1 || :
%endif
%endif
fi fi
%preun %preun
%if "%{initsystem}" == "systemd" %if "%{initsystem}" == "systemd"
## ##
## Systemd Version ## Systemd Version
## ##
if [ "$1" = "0" ]; then if [ "$1" = "0" ]; then
for daemon in %all_daemons ; do for daemon in %all_daemons ; do
%systemd_preun ${daemon}.service if [ x"${daemon}" != x"" ] ; then
done %systemd_preun frr.service
fi fi
done
fi
%else %else
## ##
## init.d Version ## init.d Version
## ##
if [ "$1" = "0" ]; then if [ "$1" = "0" ]; then
for daemon in %all_daemons ; do /etc/rc.d/init.d/frr stop >/dev/null 2>&1
/etc/rc.d/init.d/${daemon} stop >/dev/null 2>&1 /sbin/chkconfig --del frr
/sbin/chkconfig --del ${daemon} fi
done
fi
%endif %endif
/sbin/install-info --delete %{_infodir}/frr.info.gz %{_infodir}/dir /sbin/install-info --delete %{_infodir}/frr.info.gz %{_infodir}/dir
@ -521,52 +513,39 @@ rm -rf %{buildroot}
%{_sbindir}/ospfd %{_sbindir}/ospfd
%{_sbindir}/ripd %{_sbindir}/ripd
%{_sbindir}/bgpd %{_sbindir}/bgpd
%{_sbindir}/ssd %exclude %{_sbindir}/ssd
%{_sbindir}/frr
%{_sbindir}/frr-reload.py
%{_sbindir}/frr-reload.pyc
%{_sbindir}/frr-reload.pyo
%if %{with_watchfrr} %if %{with_watchfrr}
%{_sbindir}/watchfrr %{_sbindir}/watchfrr
%endif %endif
%{_sbindir}/ripngd %{_sbindir}/ripngd
%{_sbindir}/ospf6d %{_sbindir}/ospf6d
%{_sbindir}/pimd %if %{with_pimd}
%{_sbindir}/pimd
%endif
%{_sbindir}/isisd %{_sbindir}/isisd
%if %{with_ldpd} %if %{with_ldpd}
%{_sbindir}/ldpd %{_sbindir}/ldpd
%endif
%if %{with_eigrpd}
%{_sbindir}/eigrpd
%endif %endif
%if %{with_nhrpd} %if %{with_nhrpd}
%{_sbindir}/nhrpd %{_sbindir}/nhrpd
%endif %endif
%if %{with_shared} %if %{with_shared}
%attr(755,root,root) %{_libdir}/lib*.so %{_libdir}/lib*.so
%attr(755,root,root) %{_libdir}/lib*.so.* %{_libdir}/lib*.so.0
%attr(755,root,root) %{_libdir}/lib*.so.0.*
%endif %endif
%{_bindir}/* %{_bindir}/*
%config /etc/frr/[!v]* %config(noreplace) /etc/frr/[!v]*.conf*
%config(noreplace) %attr(750,%frr_user,%frr_user) /etc/frr/daemons
%if "%{initsystem}" == "systemd" %if "%{initsystem}" == "systemd"
%config %{_unitdir}/frr.service %config %{_unitdir}/frr.service
%{_sbindir}/frr
%else %else
%config /etc/rc.d/init.d/zebra %config /etc/rc.d/init.d/frr
%if %{with_watchfrr}
%config /etc/rc.d/init.d/watchfrr
%endif
%config /etc/rc.d/init.d/ripd
%config /etc/rc.d/init.d/ospfd
%config /etc/rc.d/init.d/bgpd
%config /etc/rc.d/init.d/ripngd
%config /etc/rc.d/init.d/ospf6d
%config /etc/rc.d/init.d/isisd
%config /etc/rc.d/init.d/pimd
%if %{with_ldpd}
%config /etc/rc.d/init.d/ldpd
%endif
%if %{with_nhrpd}
%config /etc/rc.d/init.d/nhrpd
%endif
%endif %endif
%config(noreplace) /etc/default/frr
%config(noreplace) /etc/pam.d/frr %config(noreplace) /etc/pam.d/frr
%config(noreplace) %attr(640,root,root) /etc/logrotate.d/* %config(noreplace) %attr(640,root,root) /etc/logrotate.d/*
@ -574,6 +553,12 @@ rm -rf %{buildroot}
%defattr(-,root,root) %defattr(-,root,root)
%doc tools %doc tools
%files pythontools
%defattr(-,root,root)
%{_sbindir}/frr-reload.py
%{_sbindir}/frr-reload.pyc
%{_sbindir}/frr-reload.pyo
%files devel %files devel
%defattr(-,root,root) %defattr(-,root,root)
%if %{with_ospfclient} %if %{with_ospfclient}
@ -589,12 +574,23 @@ rm -rf %{buildroot}
%dir %attr(755,root,root) %{_includedir}/%{name}/ospfapi %dir %attr(755,root,root) %{_includedir}/%{name}/ospfapi
%{_includedir}/%name/ospfapi/*.h %{_includedir}/%name/ospfapi/*.h
%endif %endif
%if %{with_eigrpd}
%dir %attr(755,root,root) %{_includedir}/%{name}/eigrpd
%{_includedir}/%name/eigrpd/*.h
%endif
%changelog %changelog
* Tue Feb 14 2017 Timo Teräs <timo.teras@iki.fi> - %{version} * Mon Jun 5 2017 Martin Winter <mwinter@opensourcerouting.org> - %{version}
- add nhrpd - added NHRP and EIGRP daemon
* Fri Jan 6 2017 Martin Winter <mwinter@opensourcerouting.org> - %{version} * Mon Apr 17 2017 Martin Winter <mwinter@opensourcerouting.org>
- new subpackage frr-pythontools with python 2.7 restart script
- remove PIMd from CentOS/RedHat 6 RPM packages (won't work - too old)
- converted to single frr init script (not per daemon) based on debian init script
- created systemd service file for systemd based systems (which uses init script)
- Various other RPM package fixes for FRR 2.0
* Fri Jan 6 2017 Martin Winter <mwinter@opensourcerouting.org>
- Renamed to frr for FRRouting fork of Quagga - Renamed to frr for FRRouting fork of Quagga
* Thu Feb 11 2016 Paul Jakma <paul@jakma.org> * Thu Feb 11 2016 Paul Jakma <paul@jakma.org>

View File

@ -1,25 +0,0 @@
#
# Default: Bind all daemon vtys to the loopback(s) only
#
BGPD_OPTS="-A 127.0.0.1"
ISISD_OPTS="-A ::1"
OSPF6D_OPTS="-A ::1"
OSPFD_OPTS="-A 127.0.0.1"
RIPD_OPTS="-A 127.0.0.1"
RIPNGD_OPTS="-A ::1"
ZEBRA_OPTS="-A 127.0.0.1"
PIMD_OPTS="-A 127.0.0.1"
LDPD_OPTS="-A 127.0.0.1"
# Watchfrr configuration for LSB initscripts
#
# (Not needed with systemd: the service files are configured to automatically
# restart any daemon on failure. If zebra fails, all running daemons will be
# stopped; zebra will be started again; and then the previously running daemons
# will be started again.)
#
# Uncomment and edit this line to reflect the daemons you are actually using:
#WATCH_DAEMONS="zebra bgpd ospfd ospf6d ripd ripngd"
#
# Timer values can be adjusting by editing this line:
WATCH_OPTS="-Az -b_ -r/sbin/service_%s_restart -s/sbin/service_%s_start -k/sbin/service_%s_stop"

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/isisd.conf
### BEGIN INIT INFO
# Provides: isisd
# Short-Description: IS-IS routing engine
# Description: IS-IS routing engine for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="isisd"
cmd=isisd
LOCK_FILE=/var/lock/subsys/isisd
CONF_FILE=/etc/frr/isisd.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $ISISD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/ldpd.conf
### BEGIN INIT INFO
# Provides: ldpd
# Short-Description: LDP engine
# Description: LDP engine for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="ldpd"
cmd=ldpd
LOCK_FILE=/var/lock/subsys/ldpd
CONF_FILE=/etc/frr/ldpd.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $LDPD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/ospf6d.conf
### BEGIN INIT INFO
# Provides: ospf6d
# Short-Description: OSPF routing engine for IPv6
# Description: OSPF routing engine for use with Zebra and IPv6
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="ospf6d"
cmd=ospf6d
LOCK_FILE=/var/lock/subsys/ospf6d
CONF_FILE=/etc/frr/ospf6d.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $OSPF6D_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/ospfd.conf
### BEGIN INIT INFO
# Provides: ospfd
# Short-Description: OSPF routing engine
# Description: OSPF routing engine for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="ospfd"
cmd=ospfd
LOCK_FILE=/var/lock/subsys/ospfd
CONF_FILE=/etc/frr/ospfd.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $OSPFD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/pimd.conf
### BEGIN INIT INFO
# Provides: pimd
# Short-Description: PIM multicast routing engine
# Description: PIM routing engine for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="pimd"
cmd=pimd
LOCK_FILE=/var/lock/subsys/pimd
CONF_FILE=/etc/frr/pimd.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $PIMD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/ripd.conf
### BEGIN INIT INFO
# Provides: ripd
# Short-Description: RIP routing engine
# Description: RIP routing engine for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="ripd"
cmd=ripd
LOCK_FILE=/var/lock/subsys/ripd
CONF_FILE=/etc/frr/ripd.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $RIPD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/frr/ripngd.conf
### BEGIN INIT INFO
# Provides: ripngd
# Short-Description: RIP routing engine for IPv6
# Description: RIP routing engine for use with Zebra and IPv6
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="ripngd"
cmd=ripngd
LOCK_FILE=/var/lock/subsys/ripngd
CONF_FILE=/etc/frr/ripngd.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $RIPNGD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,66 +0,0 @@
#!/bin/bash
# chkconfig: 2345 17 83
### BEGIN INIT INFO
# Provides: watchfrr
# Short-Description: Frr watchdog
# Description: Frr watchdog for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="watchfrr"
cmd=watchfrr
LOCK_FILE=/var/lock/subsys/watchfrr
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# Check that there are daemons to be monitored.
[ -z "$WATCH_DAEMONS" ] && exit 1
echo -n $"Starting $PROG: "
daemon $cmd -d $WATCH_OPTS $WATCH_DAEMONS
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -1,73 +0,0 @@
#!/bin/bash
# chkconfig: - 15 85
# config: /etc/frr/zebra.conf
### BEGIN INIT INFO
# Provides: zebra
# Short-Description: GNU Zebra routing manager
# Description: GNU Zebra routing manager
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# frr command line options
. /etc/sysconfig/frr
RETVAL=0
PROG="zebra"
cmd=zebra
LOCK_FILE=/var/lock/subsys/zebra
CONF_FILE=/etc/frr/zebra.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
/sbin/ip route flush proto zebra
daemon $cmd -d $ZEBRA_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View File

@ -90,7 +90,7 @@ clear_something (struct thread *thread)
ws->i++; ws->i++;
if (thread_should_yield(thread)) if (thread_should_yield(thread))
{ {
thread_add_background(master, clear_something, ws, 0, NULL); thread_add_timer_msec (master, clear_something, ws, 0, NULL);
return 0; return 0;
} }
} }
@ -134,7 +134,7 @@ DEFUN (clear_foo,
ws->vty = vty; ws->vty = vty;
ws->i = ITERS_FIRST; ws->i = ITERS_FIRST;
thread_add_background(master, clear_something, ws, 0, NULL); thread_add_timer_msec (master, clear_something, ws, 0, NULL);
return CMD_SUCCESS; return CMD_SUCCESS;
} }

View File

@ -5,5 +5,7 @@
188 ospf 188 ospf
189 rip 189 rip
190 ripng 190 ripng
191 static 191 nhrp
192 eigrp
193 ldp
194 babel 194 babel

View File

@ -2623,6 +2623,7 @@ vtysh_write_config_integrated(void)
err++; err++;
} }
#ifdef FRR_USER
pwentry = getpwnam (FRR_USER); pwentry = getpwnam (FRR_USER);
if (pwentry) if (pwentry)
uid = pwentry->pw_uid; uid = pwentry->pw_uid;
@ -2631,7 +2632,8 @@ vtysh_write_config_integrated(void)
printf ("%% Warning: could not look up user \"%s\"\n", FRR_USER); printf ("%% Warning: could not look up user \"%s\"\n", FRR_USER);
err++; err++;
} }
#endif
#ifdef FRR_GROUP
grentry = getgrnam (FRR_GROUP); grentry = getgrnam (FRR_GROUP);
if (grentry) if (grentry)
gid = grentry->gr_gid; gid = grentry->gr_gid;
@ -2640,6 +2642,7 @@ vtysh_write_config_integrated(void)
printf ("%% Warning: could not look up group \"%s\"\n", FRR_GROUP); printf ("%% Warning: could not look up group \"%s\"\n", FRR_GROUP);
err++; err++;
} }
#endif
if (!fstat (fd, &st)) if (!fstat (fd, &st))
{ {

View File

@ -183,9 +183,10 @@ vtysh_config_parse_line (void *arg, const char *line)
config->index = INTERFACE_NODE; config->index = INTERFACE_NODE;
} }
else if (config->index == RMAP_NODE || else if (config->index == RMAP_NODE ||
config->index == INTERFACE_NODE || config->index == INTERFACE_NODE ||
config->index == NS_NODE || config->index == NS_NODE ||
config->index == VTY_NODE) config->index == VTY_NODE ||
config->index == VRF_NODE)
config_add_line_uniq (config->line, line); config_add_line_uniq (config->line, line);
else else
config_add_line (config->line, line); config_add_line (config->line, line);
@ -280,6 +281,7 @@ vtysh_config_parse_line (void *arg, const char *line)
|| strncmp (line, "hostname", strlen ("hostname")) == 0 || strncmp (line, "hostname", strlen ("hostname")) == 0
|| strncmp (line, "frr", strlen ("frr")) == 0 || strncmp (line, "frr", strlen ("frr")) == 0
|| strncmp (line, "agentx", strlen ("agentx")) == 0 || strncmp (line, "agentx", strlen ("agentx")) == 0
|| strncmp (line, "no log", strlen ("no log")) == 0
) )
config_add_line_uniq (config_top, line); config_add_line_uniq (config_top, line);
else else
@ -321,41 +323,41 @@ vtysh_config_dump (FILE *fp)
for (i = 0; i < vector_active (configvec); i++) for (i = 0; i < vector_active (configvec); i++)
if ((master = vector_slot (configvec, i)) != NULL) if ((master = vector_slot (configvec, i)) != NULL)
{ {
for (ALL_LIST_ELEMENTS (master, node, nnode, config)) for (ALL_LIST_ELEMENTS (master, node, nnode, config))
{ {
/* Don't print empty sections for interface/vrf. Route maps on the /* Don't print empty sections for interface/vrf. Route maps on the
* other hand could have a legitimate empty section at the end. * other hand could have a legitimate empty section at the end.
*/ */
if ((config->index == INTERFACE_NODE || (config->index == VRF_NODE)) if ((config->index == INTERFACE_NODE || config->index == VRF_NODE)
&& list_isempty (config->line)) && list_isempty (config->line))
continue; continue;
fprintf (fp, "%s\n", config->name); fprintf (fp, "%s\n", config->name);
fflush (fp); fflush (fp);
for (ALL_LIST_ELEMENTS (config->line, mnode, mnnode, line)) for (ALL_LIST_ELEMENTS (config->line, mnode, mnnode, line))
{ {
fprintf (fp, "%s\n", line); fprintf (fp, "%s\n", line);
fflush (fp); fflush (fp);
} }
if (! NO_DELIMITER (i)) if (! NO_DELIMITER (i))
{ {
fprintf (fp, "!\n"); fprintf (fp, "!\n");
fflush (fp); fflush (fp);
} }
} }
if (NO_DELIMITER (i)) if (NO_DELIMITER (i))
{ {
fprintf (fp, "!\n"); fprintf (fp, "!\n");
fflush (fp); fflush (fp);
} }
} }
for (i = 0; i < vector_active (configvec); i++) for (i = 0; i < vector_active (configvec); i++)
if ((master = vector_slot (configvec, i)) != NULL) if ((master = vector_slot (configvec, i)) != NULL)
{ {
list_delete (master); list_delete (master);
vector_slot (configvec, i) = NULL; vector_slot (configvec, i) = NULL;
} }
list_delete_all_node (config_top); list_delete_all_node (config_top);
} }

View File

@ -666,12 +666,10 @@ static void daemon_send_ready(void)
{ {
static int sent = 0; static int sent = 0;
if (!sent && gs.numdown == 0) { if (!sent && gs.numdown == 0) {
#if defined (HAVE_CUMULUS)
FILE *fp; FILE *fp;
fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w"); fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w");
fclose(fp); fclose(fp);
#endif
zlog_notice zlog_notice
("Watchfrr: Notifying Systemd we are up and running"); ("Watchfrr: Notifying Systemd we are up and running");
systemd_send_started(master, 0); systemd_send_started(master, 0);

View File

@ -849,6 +849,7 @@ if_up (struct interface *ifp)
if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp); if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);
#if defined (HAVE_RTADV)
/* Enable fast tx of RA if enabled && RA interval is not in msecs */ /* Enable fast tx of RA if enabled && RA interval is not in msecs */
if (zif->rtadv.AdvSendAdvertisements && if (zif->rtadv.AdvSendAdvertisements &&
(zif->rtadv.MaxRtrAdvInterval >= 1000)) (zif->rtadv.MaxRtrAdvInterval >= 1000))
@ -856,6 +857,7 @@ if_up (struct interface *ifp)
zif->rtadv.inFastRexmit = 1; zif->rtadv.inFastRexmit = 1;
zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS; zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
} }
#endif
/* Install connected routes to the kernel. */ /* Install connected routes to the kernel. */
if_install_connected (ifp); if_install_connected (ifp);

View File

@ -31,7 +31,7 @@
#include "zebra/rib.h" #include "zebra/rib.h"
int kernel_route_rib (struct prefix *a, struct prefix *b, int kernel_route_rib (struct prefix *a, struct prefix *b,
struct rib *old, struct rib *new) { return 0; } struct route_entry *old, struct route_entry *new) { return 0; }
int kernel_address_add_ipv4 (struct interface *a, struct connected *b) int kernel_address_add_ipv4 (struct interface *a, struct connected *b)
{ {

View File

@ -25,7 +25,9 @@
#include "zebra/irdp.h" #include "zebra/irdp.h"
#include "zebra/interface.h" #include "zebra/interface.h"
#if defined (HAVE_RTADV)
void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; } void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; }
#endif
void irdp_config_write (struct vty *vty, struct interface *ifp) { return; } void irdp_config_write (struct vty *vty, struct interface *ifp) { return; }
#ifdef HAVE_PROC_NET_DEV #ifdef HAVE_PROC_NET_DEV
void ifstat_update_proc (void) { return; } void ifstat_update_proc (void) { return; }

View File

@ -79,7 +79,7 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
struct prefix p; struct prefix p;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *newrib; struct route_entry *newre;
for (afi = AFI_IP; afi <= AFI_IP6; afi++) for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{ {
@ -95,10 +95,10 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
if (! rn) if (! rn)
continue; continue;
RNODE_FOREACH_RIB (rn, newrib) RNODE_FOREACH_RE (rn, newre)
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED) if (CHECK_FLAG (newre->flags, ZEBRA_FLAG_SELECTED)
&& newrib->distance != DISTANCE_INFINITY) && newre->distance != DISTANCE_INFINITY)
zsend_redistribute_route (1, client, &rn->p, NULL, newrib); zsend_redistribute_route (1, client, &rn->p, NULL, newre);
route_unlock_node (rn); route_unlock_node (rn);
} }
@ -108,7 +108,7 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
static void static void
zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id, int afi) zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id, int afi)
{ {
struct rib *newrib; struct route_entry *newre;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
@ -117,7 +117,7 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
return; return;
for (rn = route_top (table); rn; rn = route_next (rn)) for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, newrib) RNODE_FOREACH_RE (rn, newre)
{ {
struct prefix *dst_p, *src_p; struct prefix *dst_p, *src_p;
srcdest_rnode_prefixes(rn, &dst_p, &src_p); srcdest_rnode_prefixes(rn, &dst_p, &src_p);
@ -125,21 +125,21 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
if (IS_ZEBRA_DEBUG_EVENT) if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, " zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, "
"zebra_check_addr=%d", __func__, "zebra_check_addr=%d", __func__,
CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED), CHECK_FLAG (newre->flags, ZEBRA_FLAG_SELECTED),
newrib->type, newrib->distance, newre->type, newre->distance,
zebra_check_addr (dst_p)); zebra_check_addr (dst_p));
if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)) if (! CHECK_FLAG (newre->flags, ZEBRA_FLAG_SELECTED))
continue; continue;
if ((type != ZEBRA_ROUTE_ALL && if ((type != ZEBRA_ROUTE_ALL &&
(newrib->type != type || newrib->instance != instance))) (newre->type != type || newre->instance != instance)))
continue; continue;
if (newrib->distance == DISTANCE_INFINITY) if (newre->distance == DISTANCE_INFINITY)
continue; continue;
if (! zebra_check_addr (dst_p)) if (! zebra_check_addr (dst_p))
continue; continue;
zsend_redistribute_route (1, client, dst_p, src_p, newrib); zsend_redistribute_route (1, client, dst_p, src_p, newre);
} }
} }
@ -147,7 +147,7 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
/* withdraw redistribution if add cannot be done for client */ /* withdraw redistribution if add cannot be done for client */
void void
redistribute_update (struct prefix *p, struct prefix *src_p, redistribute_update (struct prefix *p, struct prefix *src_p,
struct rib *rib, struct rib *prev_rib) struct route_entry *re, struct route_entry *prev_re)
{ {
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct zserv *client; struct zserv *client;
@ -158,9 +158,9 @@ redistribute_update (struct prefix *p, struct prefix *src_p,
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
{ {
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: Redist update rib %p (type %d), old %p (type %d)", zlog_debug ("%u:%s/%d: Redist update re %p (type %d), old %p (type %d)",
rib->vrf_id, buf, p->prefixlen, rib, rib->type, re->vrf_id, buf, p->prefixlen, re, re->type,
prev_rib, prev_rib ? prev_rib->type : -1); prev_re, prev_re ? prev_re->type : -1);
} }
afi = family2afi(p->family); afi = family2afi(p->family);
@ -174,33 +174,33 @@ redistribute_update (struct prefix *p, struct prefix *src_p,
{ {
send_redistribute = 0; send_redistribute = 0;
if (is_default (p) && vrf_bitmap_check (client->redist_default, rib->vrf_id)) if (is_default (p) && vrf_bitmap_check (client->redist_default, re->vrf_id))
send_redistribute = 1; send_redistribute = 1;
else if (vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], rib->vrf_id)) else if (vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], re->vrf_id))
send_redistribute = 1; send_redistribute = 1;
else if (rib->instance && redist_check_instance (&client->mi_redist[afi][rib->type], else if (re->instance && redist_check_instance (&client->mi_redist[afi][re->type],
rib->instance)) re->instance))
send_redistribute = 1; send_redistribute = 1;
else if (vrf_bitmap_check (client->redist[afi][rib->type], rib->vrf_id)) else if (vrf_bitmap_check (client->redist[afi][re->type], re->vrf_id))
send_redistribute = 1; send_redistribute = 1;
if (send_redistribute) if (send_redistribute)
{ {
zsend_redistribute_route (1, client, p, src_p, rib); zsend_redistribute_route (1, client, p, src_p, re);
} }
else if (prev_rib && else if (prev_re &&
((rib->instance && ((re->instance &&
redist_check_instance(&client->mi_redist[afi][prev_rib->type], redist_check_instance(&client->mi_redist[afi][prev_re->type],
rib->instance)) || re->instance)) ||
vrf_bitmap_check (client->redist[afi][prev_rib->type], rib->vrf_id))) vrf_bitmap_check (client->redist[afi][prev_re->type], re->vrf_id)))
{ {
zsend_redistribute_route (0, client, p, src_p, prev_rib); zsend_redistribute_route (0, client, p, src_p, prev_re);
} }
} }
} }
void void
redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib) redistribute_delete (struct prefix *p, struct prefix *src_p, struct route_entry *re)
{ {
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct zserv *client; struct zserv *client;
@ -210,12 +210,12 @@ redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib)
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
{ {
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: Redist delete rib %p (type %d)", zlog_debug ("%u:%s/%d: Redist delete re %p (type %d)",
rib->vrf_id, buf, p->prefixlen, rib, rib->type); re->vrf_id, buf, p->prefixlen, re, re->type);
} }
/* Add DISTANCE_INFINITY check. */ /* Add DISTANCE_INFINITY check. */
if (rib->distance == DISTANCE_INFINITY) if (re->distance == DISTANCE_INFINITY)
return; return;
afi = family2afi(p->family); afi = family2afi(p->family);
@ -228,14 +228,14 @@ redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib)
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
{ {
if ((is_default (p) && if ((is_default (p) &&
vrf_bitmap_check (client->redist_default, rib->vrf_id)) || vrf_bitmap_check (client->redist_default, re->vrf_id)) ||
vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], rib->vrf_id) || vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], re->vrf_id) ||
(rib->instance && (re->instance &&
redist_check_instance(&client->mi_redist[afi][rib->type], redist_check_instance(&client->mi_redist[afi][re->type],
rib->instance)) || re->instance)) ||
vrf_bitmap_check (client->redist[afi][rib->type], rib->vrf_id)) vrf_bitmap_check (client->redist[afi][re->type], re->vrf_id))
{ {
zsend_redistribute_route (0, client, p, src_p, rib); zsend_redistribute_route (0, client, p, src_p, re);
} }
} }
} }
@ -490,18 +490,18 @@ zebra_interface_vrf_update_add (struct interface *ifp, vrf_id_t old_vrf_id)
} }
int int
zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name) zebra_add_import_table_entry (struct route_node *rn, struct route_entry *re, const char *rmap_name)
{ {
struct rib *newrib; struct route_entry *newre;
struct rib *same; struct route_entry *same;
struct prefix p; struct prefix p;
struct nexthop *nhop; struct nexthop *nhop;
union g_addr *gate; union g_addr *gate;
route_map_result_t ret = RMAP_MATCH; route_map_result_t ret = RMAP_MATCH;
if (rmap_name) if (rmap_name)
ret = zebra_import_table_route_map_check (AFI_IP, rib->type, &rn->p, rib->nexthop, rib->vrf_id, ret = zebra_import_table_route_map_check (AFI_IP, re->type, &rn->p, re->nexthop, re->vrf_id,
rib->tag, rmap_name); re->tag, rmap_name);
if (ret == RMAP_MATCH) if (ret == RMAP_MATCH)
{ {
@ -511,13 +511,13 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
p.prefixlen = rn->p.prefixlen; p.prefixlen = rn->p.prefixlen;
p.u.prefix4 = rn->p.u.prefix4; p.u.prefix4 = rn->p.u.prefix4;
RNODE_FOREACH_RIB (rn, same) RNODE_FOREACH_RE (rn, same)
{ {
if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (same->status, ROUTE_ENTRY_REMOVED))
continue; continue;
if (same->type == rib->type && same->instance == rib->instance if (same->type == re->type && same->instance == re->instance
&& same->table == rib->table && same->table == re->table
&& same->type != ZEBRA_ROUTE_CONNECT) && same->type != ZEBRA_ROUTE_CONNECT)
break; break;
} }
@ -526,51 +526,51 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
zebra_del_import_table_entry (rn, same); zebra_del_import_table_entry (rn, same);
if (rib->nexthop_num == 1) if (re->nexthop_num == 1)
{ {
nhop = rib->nexthop; nhop = re->nexthop;
if (nhop->type == NEXTHOP_TYPE_IFINDEX) if (nhop->type == NEXTHOP_TYPE_IFINDEX)
gate = NULL; gate = NULL;
else else
gate = (union g_addr *)&nhop->gate.ipv4; gate = (union g_addr *)&nhop->gate.ipv4;
rib_add (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE, rib_add (AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
rib->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4, re->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4,
nhop->ifindex, zebrad.rtm_table_default, nhop->ifindex, zebrad.rtm_table_default,
rib->metric, rib->mtu, re->metric, re->mtu,
zebra_import_table_distance[AFI_IP][rib->table]); zebra_import_table_distance[AFI_IP][re->table]);
} }
else if (rib->nexthop_num > 1) else if (re->nexthop_num > 1)
{ {
newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); newre = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
newrib->type = ZEBRA_ROUTE_TABLE; newre->type = ZEBRA_ROUTE_TABLE;
newrib->distance = zebra_import_table_distance[AFI_IP][rib->table]; newre->distance = zebra_import_table_distance[AFI_IP][re->table];
newrib->flags = rib->flags; newre->flags = re->flags;
newrib->metric = rib->metric; newre->metric = re->metric;
newrib->mtu = rib->mtu; newre->mtu = re->mtu;
newrib->table = zebrad.rtm_table_default; newre->table = zebrad.rtm_table_default;
newrib->nexthop_num = 0; newre->nexthop_num = 0;
newrib->uptime = time(NULL); newre->uptime = time(NULL);
newrib->instance = rib->table; newre->instance = re->table;
/* Assuming these routes are never recursive */ /* Assuming these routes are never recursive */
for (nhop = rib->nexthop; nhop; nhop = nhop->next) for (nhop = re->nexthop; nhop; nhop = nhop->next)
rib_copy_nexthops(newrib, nhop); route_entry_copy_nexthops(newre, nhop);
rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, NULL, newrib); rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, NULL, newre);
} }
} }
} }
else else
{ {
zebra_del_import_table_entry (rn, rib); zebra_del_import_table_entry (rn, re);
} }
/* DD: Add IPv6 code */ /* DD: Add IPv6 code */
return 0; return 0;
} }
int int
zebra_del_import_table_entry (struct route_node *rn, struct rib *rib) zebra_del_import_table_entry (struct route_node *rn, struct route_entry *re)
{ {
struct prefix p; struct prefix p;
@ -580,8 +580,8 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
p.prefixlen = rn->p.prefixlen; p.prefixlen = rn->p.prefixlen;
p.u.prefix4 = rn->p.u.prefix4; p.u.prefix4 = rn->p.u.prefix4;
rib_delete (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE, rib_delete (AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
rib->table, rib->flags, &p, NULL, NULL, re->table, re->flags, &p, NULL, NULL,
0, zebrad.rtm_table_default); 0, zebrad.rtm_table_default);
} }
/* DD: Add IPv6 code */ /* DD: Add IPv6 code */
@ -594,7 +594,7 @@ int
zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, const char *rmap_name, int add) zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, const char *rmap_name, int add)
{ {
struct route_table *table; struct route_table *table;
struct rib *rib; struct route_entry *re;
struct route_node *rn; struct route_node *rn;
if (!is_zebra_valid_kernel_table(table_id) || if (!is_zebra_valid_kernel_table(table_id) ||
@ -647,23 +647,23 @@ zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, const cha
if (!rn->info) if (!rn->info)
continue; continue;
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue; continue;
break; break;
} }
if (!rib) if (!re)
continue; continue;
if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
((afi == AFI_IP6) && (rn->p.family == AF_INET6))) ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
{ {
if (add) if (add)
zebra_add_import_table_entry (rn, rib, rmap_name); zebra_add_import_table_entry (rn, re, rmap_name);
else else
zebra_del_import_table_entry (rn, rib); zebra_del_import_table_entry (rn, re);
} }
} }
return 0; return 0;
@ -713,7 +713,7 @@ zebra_import_table_rm_update ()
afi_t afi; afi_t afi;
int i; int i;
struct route_table *table; struct route_table *table;
struct rib *rib; struct route_entry *re;
struct route_node *rn; struct route_node *rn;
const char *rmap_name; const char *rmap_name;
@ -736,19 +736,19 @@ zebra_import_table_rm_update ()
if (!rn->info) if (!rn->info)
continue; continue;
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue; continue;
break; break;
} }
if (!rib) if (!re)
continue; continue;
if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
((afi == AFI_IP6) && (rn->p.family == AF_INET6))) ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
zebra_add_import_table_entry (rn, rib, rmap_name); zebra_add_import_table_entry (rn, re, rmap_name);
} }
} }
} }

View File

@ -36,8 +36,8 @@ extern void zebra_redistribute_default_delete (int, struct zserv *, int,
struct zebra_vrf *zvrf); struct zebra_vrf *zvrf);
extern void redistribute_update (struct prefix *, struct prefix *, extern void redistribute_update (struct prefix *, struct prefix *,
struct rib *, struct rib *); struct route_entry *, struct route_entry *);
extern void redistribute_delete (struct prefix *, struct prefix *, struct rib *); extern void redistribute_delete (struct prefix *, struct prefix *, struct route_entry *);
extern void zebra_interface_up_update (struct interface *); extern void zebra_interface_up_update (struct interface *);
extern void zebra_interface_down_update (struct interface *); extern void zebra_interface_down_update (struct interface *);
@ -57,9 +57,9 @@ extern int zebra_import_table (afi_t afi, u_int32_t table_id,
u_int32_t distance, const char *rmap_name, int add); u_int32_t distance, const char *rmap_name, int add);
extern int zebra_add_import_table_entry (struct route_node *rn, extern int zebra_add_import_table_entry (struct route_node *rn,
struct rib *rib, const char *rmap_name); struct route_entry *re, const char *rmap_name);
extern int zebra_del_import_table_entry (struct route_node *rn, extern int zebra_del_import_table_entry (struct route_node *rn,
struct rib *rib); struct route_entry *re);
extern int is_zebra_import_table_enabled(afi_t, u_int32_t table_id); extern int is_zebra_import_table_enabled(afi_t, u_int32_t table_id);
extern int zebra_import_table_config(struct vty *); extern int zebra_import_table_config(struct vty *);

View File

@ -39,9 +39,9 @@ void zebra_redistribute_default_delete (int a, struct zserv *b, int c,
{ return; } { return; }
void redistribute_update (struct prefix *a, struct prefix *b, void redistribute_update (struct prefix *a, struct prefix *b,
struct rib *c, struct rib *d) struct route_entry *c, struct route_entry *d)
{ return; } { return; }
void redistribute_delete (struct prefix *a, struct prefix *b, struct rib *c) void redistribute_delete (struct prefix *a, struct prefix *b, struct route_entry *c)
{ return; } { return; }
void zebra_interface_up_update (struct interface *a) void zebra_interface_up_update (struct interface *a)
@ -75,10 +75,10 @@ int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance,
const char *rmap_name, int add) const char *rmap_name, int add)
{ return 0; } { return 0; }
int zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name) int zebra_add_import_table_entry (struct route_node *rn, struct route_entry *re, const char *rmap_name)
{ return 0; } { return 0; }
int zebra_del_import_table_entry (struct route_node *rn, struct rib *rib) int zebra_del_import_table_entry (struct route_node *rn, struct route_entry *re)
{ return 0; } { return 0; }
int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id) int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)

View File

@ -37,11 +37,11 @@
#define DISTANCE_INFINITY 255 #define DISTANCE_INFINITY 255
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */ #define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
struct rib struct route_entry
{ {
/* Link list. */ /* Link list. */
struct rib *next; struct route_entry *next;
struct rib *prev; struct route_entry *prev;
/* Nexthop structure */ /* Nexthop structure */
struct nexthop *nexthop; struct nexthop *nexthop;
@ -85,11 +85,11 @@ struct rib
/* RIB internal status */ /* RIB internal status */
u_char status; u_char status;
#define RIB_ENTRY_REMOVED 0x1 #define ROUTE_ENTRY_REMOVED 0x1
/* to simplify NHT logic when NHs change, instead of doing a NH by NH cmp */ /* to simplify NHT logic when NHs change, instead of doing a NH by NH cmp */
#define RIB_ENTRY_NEXTHOPS_CHANGED 0x2 #define ROUTE_ENTRY_NEXTHOPS_CHANGED 0x2
#define RIB_ENTRY_CHANGED 0x4 #define ROUTE_ENTRY_CHANGED 0x4
#define RIB_ENTRY_SELECTED_FIB 0x8 #define ROUTE_ENTRY_SELECTED_FIB 0x8
/* Nexthop information. */ /* Nexthop information. */
u_char nexthop_num; u_char nexthop_num;
@ -99,7 +99,7 @@ struct rib
/* meta-queue structure: /* meta-queue structure:
* sub-queue 0: connected, kernel * sub-queue 0: connected, kernel
* sub-queue 1: static * sub-queue 1: static
* sub-queue 2: RIP, RIPng, OSPF, OSPF6, IS-IS * sub-queue 2: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP
* sub-queue 3: iBGP, eBGP * sub-queue 3: iBGP, eBGP
* sub-queue 4: any other origin (if any) * sub-queue 4: any other origin (if any)
*/ */
@ -125,7 +125,7 @@ typedef struct rib_dest_t_
/* /*
* Doubly-linked list of routes for this prefix. * Doubly-linked list of routes for this prefix.
*/ */
struct rib *routes; struct route_entry *routes;
/* /*
* Flags, see below. * Flags, see below.
@ -161,22 +161,22 @@ typedef struct rib_dest_t_
/* /*
* Macro to iterate over each route for a destination (prefix). * Macro to iterate over each route for a destination (prefix).
*/ */
#define RIB_DEST_FOREACH_ROUTE(dest, rib) \ #define RE_DEST_FOREACH_ROUTE(dest, re) \
for ((rib) = (dest) ? (dest)->routes : NULL; (rib); (rib) = (rib)->next) for ((re) = (dest) ? (dest)->routes : NULL; (re); (re) = (re)->next)
/* /*
* Same as above, but allows the current node to be unlinked. * Same as above, but allows the current node to be unlinked.
*/ */
#define RIB_DEST_FOREACH_ROUTE_SAFE(dest, rib, next) \ #define RE_DEST_FOREACH_ROUTE_SAFE(dest, re, next) \
for ((rib) = (dest) ? (dest)->routes : NULL; \ for ((re) = (dest) ? (dest)->routes : NULL; \
(rib) && ((next) = (rib)->next, 1); \ (re) && ((next) = (re)->next, 1); \
(rib) = (next)) (re) = (next))
#define RNODE_FOREACH_RIB(rn, rib) \ #define RNODE_FOREACH_RE(rn, re) \
RIB_DEST_FOREACH_ROUTE (rib_dest_from_rnode (rn), rib) RE_DEST_FOREACH_ROUTE (rib_dest_from_rnode (rn), re)
#define RNODE_FOREACH_RIB_SAFE(rn, rib, next) \ #define RNODE_FOREACH_RE_SAFE(rn, re, next) \
RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next) RE_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), re, next)
/* The following for loop allows to iterate over the nexthop /* The following for loop allows to iterate over the nexthop
* structure of routes. * structure of routes.
@ -283,17 +283,28 @@ typedef enum
RIB_UPDATE_OTHER RIB_UPDATE_OTHER
} rib_update_event_t; } rib_update_event_t;
extern struct nexthop *rib_nexthop_ifindex_add (struct rib *, ifindex_t); extern struct nexthop *route_entry_nexthop_ifindex_add (struct route_entry *, ifindex_t);
extern struct nexthop *rib_nexthop_blackhole_add (struct rib *); extern struct nexthop *route_entry_nexthop_blackhole_add (struct route_entry *);
extern struct nexthop *rib_nexthop_ipv4_add (struct rib *, struct in_addr *, extern struct nexthop *route_entry_nexthop_ipv4_add (struct route_entry *,
struct in_addr *); struct in_addr *,
extern struct nexthop *rib_nexthop_ipv4_ifindex_add (struct rib *, struct in_addr *);
struct in_addr *, extern struct nexthop *route_entry_nexthop_ipv4_ifindex_add (struct route_entry *,
struct in_addr *, struct in_addr *,
ifindex_t); struct in_addr *,
extern void rib_nexthop_add (struct rib *rib, struct nexthop *nexthop); ifindex_t);
extern void rib_copy_nexthops (struct rib *rib, struct nexthop *nh); extern void route_entry_nexthop_delete (struct route_entry *re, struct nexthop *nexthop);
extern struct nexthop *route_entry_nexthop_ipv6_add (struct route_entry *,
struct in6_addr *);
extern struct nexthop *route_entry_nexthop_ipv6_ifindex_add (struct route_entry *re,
struct in6_addr *ipv6,
ifindex_t ifindex);
extern void route_entry_nexthop_add (struct route_entry *re, struct nexthop *nexthop);
extern void route_entry_copy_nexthops (struct route_entry *re, struct nexthop *nh);
#define route_entry_dump(prefix, src, re) _route_entry_dump(__func__, prefix, src, re)
extern void _route_entry_dump (const char *,
union prefixconstptr,
union prefixconstptr, const struct route_entry *);
/* RPF lookup behaviour */ /* RPF lookup behaviour */
enum multicast_mode enum multicast_mode
{ {
@ -309,13 +320,9 @@ enum multicast_mode
extern void multicast_mode_ipv4_set (enum multicast_mode mode); extern void multicast_mode_ipv4_set (enum multicast_mode mode);
extern enum multicast_mode multicast_mode_ipv4_get (void); extern enum multicast_mode multicast_mode_ipv4_get (void);
extern int nexthop_has_fib_child(struct nexthop *);
extern void rib_lookup_and_dump (struct prefix_ipv4 *, vrf_id_t); extern void rib_lookup_and_dump (struct prefix_ipv4 *, vrf_id_t);
extern void rib_lookup_and_pushup (struct prefix_ipv4 *, vrf_id_t); extern void rib_lookup_and_pushup (struct prefix_ipv4 *, vrf_id_t);
#define rib_dump(prefix, src, rib) _rib_dump(__func__, prefix, src, rib)
extern void _rib_dump (const char *,
union prefixconstptr,
union prefixconstptr, const struct rib *);
extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *, extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *,
vrf_id_t); vrf_id_t);
#define ZEBRA_RIB_LOOKUP_ERROR -1 #define ZEBRA_RIB_LOOKUP_ERROR -1
@ -324,20 +331,16 @@ extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *,
#define ZEBRA_RIB_FOUND_CONNECTED 2 #define ZEBRA_RIB_FOUND_CONNECTED 2
#define ZEBRA_RIB_NOTFOUND 3 #define ZEBRA_RIB_NOTFOUND 3
extern void rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop);
extern struct nexthop *rib_nexthop_ipv6_add (struct rib *, struct in6_addr *);
extern struct nexthop *rib_nexthop_ipv6_ifindex_add (struct rib *rib,
struct in6_addr *ipv6,
ifindex_t ifindex);
extern int is_zebra_valid_kernel_table(u_int32_t table_id); extern int is_zebra_valid_kernel_table(u_int32_t table_id);
extern int is_zebra_main_routing_table(u_int32_t table_id); extern int is_zebra_main_routing_table(u_int32_t table_id);
extern int zebra_check_addr (struct prefix *p); extern int zebra_check_addr (struct prefix *p);
extern void rib_addnode (struct route_node *rn, struct rib *rib, int process); extern void rib_addnode (struct route_node *rn, struct route_entry *re, int process);
extern void rib_delnode (struct route_node *rn, struct rib *rib); extern void rib_delnode (struct route_node *rn, struct route_entry *re);
extern int rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old); extern int rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_entry *old);
extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib); extern int rib_uninstall_kernel (struct route_node *rn, struct route_entry *re);
/* NOTE: /* NOTE:
* All rib_add function will not just add prefix into RIB, but * All rib_add function will not just add prefix into RIB, but
@ -349,19 +352,19 @@ extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_int32_t, u_int32_t, u_char); u_int32_t, u_int32_t, u_char);
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 prefix_ipv6 *src_p, struct rib *); struct prefix_ipv6 *src_p, struct route_entry *);
extern void 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,
struct prefix_ipv6 *src_p, union g_addr *gate, struct prefix_ipv6 *src_p, union g_addr *gate,
ifindex_t ifindex, u_int32_t table_id); ifindex_t ifindex, u_int32_t table_id);
extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *, extern struct route_entry *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *,
struct route_node **rn_out); struct route_node **rn_out);
extern struct rib *rib_match_ipv4_multicast (vrf_id_t vrf_id, struct in_addr addr, extern struct route_entry *rib_match_ipv4_multicast (vrf_id_t vrf_id, struct in_addr addr,
struct route_node **rn_out); struct route_node **rn_out);
extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *, vrf_id_t); extern struct route_entry *rib_lookup_ipv4 (struct prefix_ipv4 *, vrf_id_t);
extern void rib_update (vrf_id_t, rib_update_event_t); extern void rib_update (vrf_id_t, rib_update_event_t);
extern void rib_weed_tables (void); extern void rib_weed_tables (void);
@ -371,10 +374,10 @@ extern void rib_init (void);
extern unsigned long rib_score_proto (u_char proto, u_short instance); extern unsigned long rib_score_proto (u_char proto, u_short instance);
extern void rib_queue_add (struct route_node *rn); extern void rib_queue_add (struct route_node *rn);
extern void meta_queue_free (struct meta_queue *mq); extern void meta_queue_free (struct meta_queue *mq);
extern int zebra_rib_labeled_unicast (struct rib *rib); extern int zebra_rib_labeled_unicast (struct route_entry *re);
extern struct route_table *rib_table_ipv6; extern struct route_table *rib_table_ipv6;
extern void rib_unlink (struct route_node *, struct rib *); extern void rib_unlink (struct route_node *, struct route_entry *);
extern int rib_gc_dest (struct route_node *rn); extern int rib_gc_dest (struct route_node *rn);
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
@ -408,7 +411,7 @@ rib_dest_from_rnode (struct route_node *rn)
* Returns a pointer to the list of routes corresponding to the given * Returns a pointer to the list of routes corresponding to the given
* route_node. * route_node.
*/ */
static inline struct rib * static inline struct route_entry *
rnode_to_ribs (struct route_node *rn) rnode_to_ribs (struct route_node *rn)
{ {
rib_dest_t *dest; rib_dest_t *dest;

View File

@ -29,7 +29,7 @@
#include "zebra/zebra_mpls.h" #include "zebra/zebra_mpls.h"
extern int kernel_route_rib (struct prefix *, struct prefix *, extern int kernel_route_rib (struct prefix *, struct prefix *,
struct rib *, struct rib *); struct route_entry *, struct route_entry *);
extern int kernel_address_add_ipv4 (struct interface *, struct connected *); extern int kernel_address_add_ipv4 (struct interface *, struct connected *);
extern int kernel_address_delete_ipv4 (struct interface *, struct connected *); extern int kernel_address_delete_ipv4 (struct interface *, struct connected *);

View File

@ -122,7 +122,8 @@ static inline int is_selfroute(int proto)
if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) || if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) ||
(proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA) || (proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA) ||
(proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG) || (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG) ||
(proto == RTPROT_BABEL)) { (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP) ||
(proto == RTPROT_LDP) || (proto == RTPROT_BABEL)) {
return 1; return 1;
} }
@ -154,6 +155,15 @@ static inline int get_rt_proto(int proto)
case ZEBRA_ROUTE_RIPNG: case ZEBRA_ROUTE_RIPNG:
proto = RTPROT_RIPNG; proto = RTPROT_RIPNG;
break; break;
case ZEBRA_ROUTE_NHRP:
proto = RTPROT_NHRP;
break;
case ZEBRA_ROUTE_EIGRP:
proto = RTPROT_EIGRP;
break;
case ZEBRA_ROUTE_LDP:
proto = RTPROT_LDP;
break;
default: default:
proto = RTPROT_ZEBRA; proto = RTPROT_ZEBRA;
break; break;
@ -346,22 +356,22 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
{ {
/* This is a multipath route */ /* This is a multipath route */
struct rib *rib; struct route_entry *re;
struct rtnexthop *rtnh = struct rtnexthop *rtnh =
(struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]); (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
len = RTA_PAYLOAD (tb[RTA_MULTIPATH]); len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
rib->type = ZEBRA_ROUTE_KERNEL; re->type = ZEBRA_ROUTE_KERNEL;
rib->distance = 0; re->distance = 0;
rib->flags = flags; re->flags = flags;
rib->metric = metric; re->metric = metric;
rib->mtu = mtu; re->mtu = mtu;
rib->vrf_id = vrf_id; re->vrf_id = vrf_id;
rib->table = table; re->table = table;
rib->nexthop_num = 0; re->nexthop_num = 0;
rib->uptime = time (NULL); re->uptime = time (NULL);
for (;;) for (;;)
{ {
@ -384,31 +394,31 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (rtm->rtm_family == AF_INET) if (rtm->rtm_family == AF_INET)
{ {
if (index) if (index)
rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index); route_entry_nexthop_ipv4_ifindex_add (re, gate, prefsrc, index);
else else
rib_nexthop_ipv4_add (rib, gate, prefsrc); route_entry_nexthop_ipv4_add (re, gate, prefsrc);
} }
else if (rtm->rtm_family == AF_INET6) else if (rtm->rtm_family == AF_INET6)
{ {
if (index) if (index)
rib_nexthop_ipv6_ifindex_add (rib, gate, index); route_entry_nexthop_ipv6_ifindex_add (re, gate, index);
else else
rib_nexthop_ipv6_add (rib,gate); route_entry_nexthop_ipv6_add (re,gate);
} }
} }
else else
rib_nexthop_ifindex_add (rib, index); route_entry_nexthop_ifindex_add (re, index);
len -= NLMSG_ALIGN(rtnh->rtnh_len); len -= NLMSG_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh); rtnh = RTNH_NEXT(rtnh);
} }
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
rib->nexthop_num); re->nexthop_num);
if (rib->nexthop_num == 0) if (re->nexthop_num == 0)
XFREE (MTYPE_RIB, rib); XFREE (MTYPE_RE, re);
else else
rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib); rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, re);
} }
} }
else else
@ -1172,7 +1182,7 @@ netlink_neigh_update (int cmd, int ifindex, uint32_t addr, char *lla, int llalen
/* Update flag indicates whether this is a "replace" or not. */ /* Update flag indicates whether this is a "replace" or not. */
static int static int
netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p, netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
struct rib *rib, int update) struct route_entry *re, int update)
{ {
int bytelen; int bytelen;
struct sockaddr_nl snl; struct sockaddr_nl snl;
@ -1193,7 +1203,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
} req; } req;
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT); struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
struct zebra_vrf *zvrf = vrf_info_lookup (rib->vrf_id); struct zebra_vrf *zvrf = vrf_info_lookup (re->vrf_id);
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE); memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
@ -1207,10 +1217,10 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
req.r.rtm_family = family; req.r.rtm_family = family;
req.r.rtm_dst_len = p->prefixlen; req.r.rtm_dst_len = p->prefixlen;
req.r.rtm_src_len = src_p ? src_p->prefixlen : 0; req.r.rtm_src_len = src_p ? src_p->prefixlen : 0;
req.r.rtm_protocol = get_rt_proto(rib->type); req.r.rtm_protocol = get_rt_proto(re->type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE; req.r.rtm_scope = RT_SCOPE_UNIVERSE;
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) if ((re->flags & ZEBRA_FLAG_BLACKHOLE) || (re->flags & ZEBRA_FLAG_REJECT))
discard = 1; discard = 1;
else else
discard = 0; discard = 0;
@ -1219,9 +1229,9 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
{ {
if (discard) if (discard)
{ {
if (rib->flags & ZEBRA_FLAG_BLACKHOLE) if (re->flags & ZEBRA_FLAG_BLACKHOLE)
req.r.rtm_type = RTN_BLACKHOLE; req.r.rtm_type = RTN_BLACKHOLE;
else if (rib->flags & ZEBRA_FLAG_REJECT) else if (re->flags & ZEBRA_FLAG_REJECT)
req.r.rtm_type = RTN_UNREACHABLE; req.r.rtm_type = RTN_UNREACHABLE;
else else
assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */ assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
@ -1242,21 +1252,21 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
addattr32 (&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC); addattr32 (&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC);
/* Table corresponding to this route. */ /* Table corresponding to this route. */
if (rib->table < 256) if (re->table < 256)
req.r.rtm_table = rib->table; req.r.rtm_table = re->table;
else else
{ {
req.r.rtm_table = RT_TABLE_UNSPEC; req.r.rtm_table = RT_TABLE_UNSPEC;
addattr32(&req.n, sizeof req, RTA_TABLE, rib->table); addattr32(&req.n, sizeof req, RTA_TABLE, re->table);
} }
if (rib->mtu || rib->nexthop_mtu) if (re->mtu || re->nexthop_mtu)
{ {
char buf[NL_PKT_BUF_SIZE]; char buf[NL_PKT_BUF_SIZE];
struct rtattr *rta = (void *) buf; struct rtattr *rta = (void *) buf;
u_int32_t mtu = rib->mtu; u_int32_t mtu = re->mtu;
if (!mtu || (rib->nexthop_mtu && rib->nexthop_mtu < mtu)) if (!mtu || (re->nexthop_mtu && re->nexthop_mtu < mtu))
mtu = rib->nexthop_mtu; mtu = re->nexthop_mtu;
rta->rta_type = RTA_METRICS; rta->rta_type = RTA_METRICS;
rta->rta_len = RTA_LENGTH(0); rta->rta_len = RTA_LENGTH(0);
rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTAX_MTU, &mtu, sizeof mtu); rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTAX_MTU, &mtu, sizeof mtu);
@ -1267,7 +1277,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
if (discard) if (discard)
{ {
if (cmd == RTM_NEWROUTE) if (cmd == RTM_NEWROUTE)
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
/* We shouldn't encounter recursive nexthops on discard routes, /* We shouldn't encounter recursive nexthops on discard routes,
* but it is probably better to handle that case correctly anyway. * but it is probably better to handle that case correctly anyway.
@ -1281,7 +1291,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
/* Count overall nexthops so we can decide whether to use singlepath /* Count overall nexthops so we can decide whether to use singlepath
* or multipath case. */ * or multipath case. */
nexthop_num = 0; nexthop_num = 0;
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue; continue;
@ -1297,7 +1307,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
if (nexthop_num == 1 || multipath_num == 1) if (nexthop_num == 1 || multipath_num == 1)
{ {
nexthop_num = 0; nexthop_num = 0;
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
{ {
@ -1368,7 +1378,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
rtnh = RTA_DATA (rta); rtnh = RTA_DATA (rta);
nexthop_num = 0; nexthop_num = 0;
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
if (nexthop_num >= multipath_num) if (nexthop_num >= multipath_num)
break; break;
@ -1501,7 +1511,7 @@ kernel_get_ipmr_sg_stats (void *in)
int int
kernel_route_rib (struct prefix *p, struct prefix *src_p, kernel_route_rib (struct prefix *p, struct prefix *src_p,
struct rib *old, struct rib *new) struct route_entry *old, struct route_entry *new)
{ {
if (!old && new) if (!old && new)
return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 0); return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 0);

View File

@ -36,6 +36,9 @@
#if !defined(RTPROT_BABEL) #if !defined(RTPROT_BABEL)
#define RTPROT_BABEL 42 #define RTPROT_BABEL 42
#endif #endif
#define RTPROT_NHRP 191
#define RTPROT_EIGRP 192
#define RTPROT_LDP 193
void rt_netlink_init (void); void rt_netlink_init (void);

View File

@ -71,7 +71,7 @@ sin_masklen (struct in_addr mask)
/* Interface between zebra message and rtm message. */ /* Interface between zebra message and rtm message. */
static int static int
kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib) kernel_rtm_ipv4 (int cmd, struct prefix *p, struct route_entry *re)
{ {
struct sockaddr_in *mask = NULL; struct sockaddr_in *mask = NULL;
@ -106,7 +106,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
/* Make gateway. */ /* Make gateway. */
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue; continue;
@ -172,16 +172,16 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
gate ? (union sockunion *)&sin_gate : NULL, gate ? (union sockunion *)&sin_gate : NULL,
smplsp, smplsp,
ifindex, ifindex,
rib->flags, re->flags,
rib->metric); re->metric);
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
{ {
if (!gate) if (!gate)
{ {
zlog_debug ("%s: %s: attention! gate not found for rib %p", zlog_debug ("%s: %s: attention! gate not found for re %p",
__func__, prefix_buf, rib); __func__, prefix_buf, re);
rib_dump (p, NULL, rib); route_entry_dump (p, NULL, re);
} }
else else
inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN); inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);
@ -230,7 +230,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
/* If there was no useful nexthop, then complain. */ /* If there was no useful nexthop, then complain. */
if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL) if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: No useful nexthops were found in RIB entry %p", __func__, rib); zlog_debug ("%s: No useful nexthops were found in RIB entry %p", __func__, re);
return 0; /*XXX*/ return 0; /*XXX*/
} }
@ -262,7 +262,7 @@ sin6_masklen (struct in6_addr mask)
/* Interface between zebra message and rtm message. */ /* Interface between zebra message and rtm message. */
static int static int
kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib) kernel_rtm_ipv6 (int cmd, struct prefix *p, struct route_entry *re)
{ {
struct sockaddr_in6 *mask; struct sockaddr_in6 *mask;
struct sockaddr_in6 sin_dest, sin_mask, sin_gate; struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
@ -289,7 +289,7 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib)
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
/* Make gateway. */ /* Make gateway. */
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue; continue;
@ -349,8 +349,8 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib)
gate ? (union sockunion *)&sin_gate : NULL, gate ? (union sockunion *)&sin_gate : NULL,
NULL, NULL,
ifindex, ifindex,
rib->flags, re->flags,
rib->metric); re->metric);
#if 0 #if 0
if (error) if (error)
@ -377,21 +377,21 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib)
} }
static int static int
kernel_rtm (int cmd, struct prefix *p, struct rib *rib) kernel_rtm (int cmd, struct prefix *p, struct route_entry *re)
{ {
switch (PREFIX_FAMILY(p)) switch (PREFIX_FAMILY(p))
{ {
case AF_INET: case AF_INET:
return kernel_rtm_ipv4 (cmd, p, rib); return kernel_rtm_ipv4 (cmd, p, re);
case AF_INET6: case AF_INET6:
return kernel_rtm_ipv6 (cmd, p, rib); return kernel_rtm_ipv6 (cmd, p, re);
} }
return 0; return 0;
} }
int int
kernel_route_rib (struct prefix *p, struct prefix *src_p, kernel_route_rib (struct prefix *p, struct prefix *src_p,
struct rib *old, struct rib *new) struct route_entry *old, struct route_entry *new)
{ {
int route = 0; int route = 0;

View File

@ -1403,8 +1403,8 @@ DEFUN (ipv6_nd_router_preference,
"Neighbor discovery\n" "Neighbor discovery\n"
"Default router preference\n" "Default router preference\n"
"High default router preference\n" "High default router preference\n"
"Low default router preference\n" "Medium default router preference (default)\n"
"Medium default router preference (default)\n") "Low default router preference\n")
{ {
int idx_high_medium_low = 3; int idx_high_medium_low = 3;
VTY_DECLVAR_CONTEXT (interface, ifp); VTY_DECLVAR_CONTEXT (interface, ifp);

View File

@ -564,8 +564,8 @@ zfpm_conn_up_thread_cb (struct thread *thread)
zfpm_g->stats.t_conn_up_yields++; zfpm_g->stats.t_conn_up_yields++;
zfpm_rnodes_iter_pause (iter); zfpm_rnodes_iter_pause (iter);
zfpm_g->t_conn_up = NULL; zfpm_g->t_conn_up = NULL;
thread_add_background(zfpm_g->master, zfpm_conn_up_thread_cb, 0, 0, thread_add_timer_msec (zfpm_g->master, zfpm_conn_up_thread_cb, NULL, 0,
&zfpm_g->t_conn_up); &zfpm_g->t_conn_up);
return 0; return 0;
} }
@ -598,7 +598,7 @@ zfpm_connection_up (const char *detail)
zfpm_debug ("Starting conn_up thread"); zfpm_debug ("Starting conn_up thread");
zfpm_g->t_conn_up = NULL; zfpm_g->t_conn_up = NULL;
thread_add_background(zfpm_g->master, zfpm_conn_up_thread_cb, 0, 0, thread_add_timer_msec(zfpm_g->master, zfpm_conn_up_thread_cb, NULL, 0,
&zfpm_g->t_conn_up); &zfpm_g->t_conn_up);
zfpm_g->stats.t_conn_up_starts++; zfpm_g->stats.t_conn_up_starts++;
} }
@ -688,7 +688,7 @@ zfpm_conn_down_thread_cb (struct thread *thread)
zfpm_g->stats.t_conn_down_yields++; zfpm_g->stats.t_conn_down_yields++;
zfpm_rnodes_iter_pause (iter); zfpm_rnodes_iter_pause (iter);
zfpm_g->t_conn_down = NULL; zfpm_g->t_conn_down = NULL;
thread_add_background(zfpm_g->master, zfpm_conn_down_thread_cb, 0, 0, thread_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb, NULL, 0,
&zfpm_g->t_conn_down); &zfpm_g->t_conn_down);
return 0; return 0;
} }
@ -736,7 +736,7 @@ zfpm_connection_down (const char *detail)
zfpm_debug ("Starting conn_down thread"); zfpm_debug ("Starting conn_down thread");
zfpm_rnodes_iter_init (&zfpm_g->t_conn_down_state.iter); zfpm_rnodes_iter_init (&zfpm_g->t_conn_down_state.iter);
zfpm_g->t_conn_down = NULL; zfpm_g->t_conn_down = NULL;
thread_add_background(zfpm_g->master, zfpm_conn_down_thread_cb, 0, 0, thread_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb, NULL, 0,
&zfpm_g->t_conn_down); &zfpm_g->t_conn_down);
zfpm_g->stats.t_conn_down_starts++; zfpm_g->stats.t_conn_down_starts++;
@ -866,7 +866,7 @@ zfpm_writes_pending (void)
* value indicates an error. * value indicates an error.
*/ */
static inline int static inline int
zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf, zfpm_encode_route (rib_dest_t *dest, struct route_entry *re, char *in_buf,
size_t in_buf_len, fpm_msg_type_e *msg_type) size_t in_buf_len, fpm_msg_type_e *msg_type)
{ {
size_t len; size_t len;
@ -881,7 +881,7 @@ zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf,
case ZFPM_MSG_FORMAT_PROTOBUF: case ZFPM_MSG_FORMAT_PROTOBUF:
#ifdef HAVE_PROTOBUF #ifdef HAVE_PROTOBUF
len = zfpm_protobuf_encode_route (dest, rib, (uint8_t *) in_buf, len = zfpm_protobuf_encode_route (dest, re, (uint8_t *) in_buf,
in_buf_len); in_buf_len);
*msg_type = FPM_MSG_TYPE_PROTOBUF; *msg_type = FPM_MSG_TYPE_PROTOBUF;
#endif #endif
@ -890,8 +890,8 @@ zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf,
case ZFPM_MSG_FORMAT_NETLINK: case ZFPM_MSG_FORMAT_NETLINK:
#ifdef HAVE_NETLINK #ifdef HAVE_NETLINK
*msg_type = FPM_MSG_TYPE_NETLINK; *msg_type = FPM_MSG_TYPE_NETLINK;
cmd = rib ? RTM_NEWROUTE : RTM_DELROUTE; cmd = re ? RTM_NEWROUTE : RTM_DELROUTE;
len = zfpm_netlink_encode_route (cmd, dest, rib, in_buf, in_buf_len); len = zfpm_netlink_encode_route (cmd, dest, re, in_buf, in_buf_len);
assert(fpm_msg_align(len) == len); assert(fpm_msg_align(len) == len);
*msg_type = FPM_MSG_TYPE_NETLINK; *msg_type = FPM_MSG_TYPE_NETLINK;
#endif /* HAVE_NETLINK */ #endif /* HAVE_NETLINK */
@ -908,19 +908,19 @@ zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf,
/* /*
* zfpm_route_for_update * zfpm_route_for_update
* *
* Returns the rib that is to be sent to the FPM for a given dest. * Returns the re that is to be sent to the FPM for a given dest.
*/ */
struct rib * struct route_entry *
zfpm_route_for_update (rib_dest_t *dest) zfpm_route_for_update (rib_dest_t *dest)
{ {
struct rib *rib; struct route_entry *re;
RIB_DEST_FOREACH_ROUTE (dest, rib) RE_DEST_FOREACH_ROUTE (dest, re)
{ {
if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) if (!CHECK_FLAG (re->status, ROUTE_ENTRY_SELECTED_FIB))
continue; continue;
return rib; return re;
} }
/* /*
@ -944,7 +944,7 @@ zfpm_build_updates (void)
size_t msg_len; size_t msg_len;
size_t data_len; size_t data_len;
fpm_msg_hdr_t *hdr; fpm_msg_hdr_t *hdr;
struct rib *rib; struct route_entry *re;
int is_add, write_msg; int is_add, write_msg;
fpm_msg_type_e msg_type; fpm_msg_type_e msg_type;
@ -974,8 +974,8 @@ zfpm_build_updates (void)
data = fpm_msg_data (hdr); data = fpm_msg_data (hdr);
rib = zfpm_route_for_update (dest); re = zfpm_route_for_update (dest);
is_add = rib ? 1 : 0; is_add = re ? 1 : 0;
write_msg = 1; write_msg = 1;
@ -990,7 +990,7 @@ zfpm_build_updates (void)
} }
if (write_msg) { if (write_msg) {
data_len = zfpm_encode_route (dest, rib, (char *) data, buf_end - data, data_len = zfpm_encode_route (dest, re, (char *) data, buf_end - data,
&msg_type); &msg_type);
assert (data_len); assert (data_len);

View File

@ -67,13 +67,13 @@ extern int zfpm_dt_benchmark_protobuf_decode (int argc, const char **argv);
* Selects a suitable rib destination for fpm interface tests. * Selects a suitable rib destination for fpm interface tests.
*/ */
static int static int
zfpm_dt_find_route (rib_dest_t **dest_p, struct rib **rib_p) zfpm_dt_find_route (rib_dest_t **dest_p, struct route_entry **re_p)
{ {
struct route_node *rnode; struct route_node *rnode;
route_table_iter_t iter; route_table_iter_t iter;
struct route_table *table; struct route_table *table;
rib_dest_t *dest; rib_dest_t *dest;
struct rib *rib; struct route_entry *re;
int ret; int ret;
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
@ -88,15 +88,15 @@ zfpm_dt_find_route (rib_dest_t **dest_p, struct rib **rib_p)
if (!dest) if (!dest)
continue; continue;
rib = zfpm_route_for_update(dest); re = zfpm_route_for_update(dest);
if (!rib) if (!re)
continue; continue;
if (rib->nexthop_active_num <= 0) if (re->nexthop_active_num <= 0)
continue; continue;
*dest_p = dest; *dest_p = dest;
*rib_p = rib; *re_p = re;
ret = 1; ret = 1;
goto done; goto done;
} }
@ -117,7 +117,7 @@ zfpm_dt_benchmark_netlink_encode (int argc, const char **argv)
{ {
int times, i, len; int times, i, len;
rib_dest_t *dest; rib_dest_t *dest;
struct rib *rib; struct route_entry *re;
char buf[4096]; char buf[4096];
times = 100000; times = 100000;
@ -125,12 +125,12 @@ zfpm_dt_benchmark_netlink_encode (int argc, const char **argv)
times = atoi(argv[0]); times = atoi(argv[0]);
} }
if (!zfpm_dt_find_route(&dest, &rib)) { if (!zfpm_dt_find_route(&dest, &re)) {
return 1; return 1;
} }
for (i = 0; i < times; i++) { for (i = 0; i < times; i++) {
len = zfpm_netlink_encode_route(RTM_NEWROUTE, dest, rib, buf, sizeof(buf)); len = zfpm_netlink_encode_route(RTM_NEWROUTE, dest, re, buf, sizeof(buf));
if (len <= 0) { if (len <= 0) {
return 2; return 2;
} }
@ -150,7 +150,7 @@ zfpm_dt_benchmark_protobuf_encode (int argc, const char **argv)
{ {
int times, i, len; int times, i, len;
rib_dest_t *dest; rib_dest_t *dest;
struct rib *rib; struct route_entry *re;
uint8_t buf[4096]; uint8_t buf[4096];
times = 100000; times = 100000;
@ -158,12 +158,12 @@ zfpm_dt_benchmark_protobuf_encode (int argc, const char **argv)
times = atoi(argv[0]); times = atoi(argv[0]);
} }
if (!zfpm_dt_find_route(&dest, &rib)) { if (!zfpm_dt_find_route(&dest, &re)) {
return 1; return 1;
} }
for (i = 0; i < times; i++) { for (i = 0; i < times; i++) {
len = zfpm_protobuf_encode_route(dest, rib, buf, sizeof(buf)); len = zfpm_protobuf_encode_route(dest, re, buf, sizeof(buf));
if (len <= 0) { if (len <= 0) {
return 2; return 2;
} }
@ -229,7 +229,7 @@ zfpm_dt_benchmark_protobuf_decode (int argc, const char **argv)
{ {
int times, i, len; int times, i, len;
rib_dest_t *dest; rib_dest_t *dest;
struct rib *rib; struct route_entry *re;
uint8_t msg_buf[4096]; uint8_t msg_buf[4096];
QPB_DECLARE_STACK_ALLOCATOR (allocator, 8192); QPB_DECLARE_STACK_ALLOCATOR (allocator, 8192);
Fpm__Message *fpm_msg; Fpm__Message *fpm_msg;
@ -240,13 +240,13 @@ zfpm_dt_benchmark_protobuf_decode (int argc, const char **argv)
if (argc > 0) if (argc > 0)
times = atoi(argv[0]); times = atoi(argv[0]);
if (!zfpm_dt_find_route (&dest, &rib)) if (!zfpm_dt_find_route (&dest, &re))
return 1; return 1;
/* /*
* Encode the route into the message buffer once only. * Encode the route into the message buffer once only.
*/ */
len = zfpm_protobuf_encode_route (dest, rib, msg_buf, sizeof (msg_buf)); len = zfpm_protobuf_encode_route (dest, re, msg_buf, sizeof (msg_buf));
if (len <= 0) if (len <= 0)
return 2; return 2;

View File

@ -231,7 +231,7 @@ netlink_proto_from_route_type (int type)
*/ */
static int static int
netlink_route_info_fill (netlink_route_info_t *ri, int cmd, netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
rib_dest_t *dest, struct rib *rib) rib_dest_t *dest, struct route_entry *re)
{ {
struct nexthop *nexthop, *tnexthop; struct nexthop *nexthop, *tnexthop;
int recursing; int recursing;
@ -250,18 +250,18 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
* An RTM_DELROUTE need not be accompanied by any nexthops, * An RTM_DELROUTE need not be accompanied by any nexthops,
* particularly in our communication with the FPM. * particularly in our communication with the FPM.
*/ */
if (cmd == RTM_DELROUTE && !rib) if (cmd == RTM_DELROUTE && !re)
return 1; return 1;
if (!rib) if (!re)
{ {
zfpm_debug ("%s: Expected non-NULL rib pointer", __PRETTY_FUNCTION__); zfpm_debug ("%s: Expected non-NULL re pointer", __PRETTY_FUNCTION__);
return 0; return 0;
} }
ri->rtm_protocol = netlink_proto_from_route_type (rib->type); ri->rtm_protocol = netlink_proto_from_route_type (re->type);
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) if ((re->flags & ZEBRA_FLAG_BLACKHOLE) || (re->flags & ZEBRA_FLAG_REJECT))
discard = 1; discard = 1;
else else
discard = 0; discard = 0;
@ -270,9 +270,9 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
{ {
if (discard) if (discard)
{ {
if (rib->flags & ZEBRA_FLAG_BLACKHOLE) if (re->flags & ZEBRA_FLAG_BLACKHOLE)
ri->rtm_type = RTN_BLACKHOLE; ri->rtm_type = RTN_BLACKHOLE;
else if (rib->flags & ZEBRA_FLAG_REJECT) else if (re->flags & ZEBRA_FLAG_REJECT)
ri->rtm_type = RTN_UNREACHABLE; ri->rtm_type = RTN_UNREACHABLE;
else else
assert (0); assert (0);
@ -281,12 +281,12 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
ri->rtm_type = RTN_UNICAST; ri->rtm_type = RTN_UNICAST;
} }
ri->metric = &rib->metric; ri->metric = &re->metric;
if (discard) if (discard)
return 1; return 1;
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
if (ri->num_nhs >= multipath_num) if (ri->num_nhs >= multipath_num)
break; break;
@ -474,14 +474,14 @@ zfpm_log_route_info (netlink_route_info_t *ri, const char *label)
* value indicates an error. * value indicates an error.
*/ */
int int
zfpm_netlink_encode_route (int cmd, rib_dest_t *dest, struct rib *rib, zfpm_netlink_encode_route (int cmd, rib_dest_t *dest, struct route_entry *re,
char *in_buf, size_t in_buf_len) char *in_buf, size_t in_buf_len)
{ {
netlink_route_info_t ri_space, *ri; netlink_route_info_t ri_space, *ri;
ri = &ri_space; ri = &ri_space;
if (!netlink_route_info_fill (ri, cmd, dest, rib)) if (!netlink_route_info_fill (ri, cmd, dest, re))
return 0; return 0;
zfpm_log_route_info (ri, __FUNCTION__); zfpm_log_route_info (ri, __FUNCTION__);

View File

@ -49,12 +49,12 @@ static inline void zfpm_debug(const char *format, ...) { return; }
* Externs * Externs
*/ */
extern int extern int
zfpm_netlink_encode_route (int cmd, rib_dest_t *dest, struct rib *rib, zfpm_netlink_encode_route (int cmd, rib_dest_t *dest, struct route_entry *re,
char *in_buf, size_t in_buf_len); char *in_buf, size_t in_buf_len);
extern int extern int
zfpm_protobuf_encode_route (rib_dest_t *dest, struct rib *rib, zfpm_protobuf_encode_route (rib_dest_t *dest, struct route_entry *re,
uint8_t *in_buf, size_t in_buf_len); uint8_t *in_buf, size_t in_buf_len);
extern struct rib *zfpm_route_for_update (rib_dest_t *dest); extern struct route_entry *zfpm_route_for_update (rib_dest_t *dest);
#endif /* _ZEBRA_FPM_PRIVATE_H */ #endif /* _ZEBRA_FPM_PRIVATE_H */

View File

@ -41,7 +41,7 @@
*/ */
static Fpm__DeleteRoute * static Fpm__DeleteRoute *
create_delete_route_message (qpb_allocator_t *allocator, rib_dest_t *dest, create_delete_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
struct rib *rib) struct route_entry *re)
{ {
Fpm__DeleteRoute *msg; Fpm__DeleteRoute *msg;
@ -141,7 +141,7 @@ add_nexthop (qpb_allocator_t *allocator, Fpm__AddRoute *msg, rib_dest_t *dest,
*/ */
static Fpm__AddRoute * static Fpm__AddRoute *
create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest, create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
struct rib *rib) struct route_entry *re)
{ {
Fpm__AddRoute *msg; Fpm__AddRoute *msg;
int discard; int discard;
@ -167,18 +167,18 @@ create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
*/ */
msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST; msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST;
msg->key = fpm_route_key_create (allocator, rib_dest_prefix(dest)); msg->key = fpm_route_key_create (allocator, rib_dest_prefix(dest));
qpb_protocol_set (&msg->protocol, rib->type); qpb_protocol_set (&msg->protocol, re->type);
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) if ((re->flags & ZEBRA_FLAG_BLACKHOLE) || (re->flags & ZEBRA_FLAG_REJECT))
discard = 1; discard = 1;
else else
discard = 0; discard = 0;
if (discard) if (discard)
{ {
if (rib->flags & ZEBRA_FLAG_BLACKHOLE) { if (re->flags & ZEBRA_FLAG_BLACKHOLE) {
msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE; msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE;
} else if (rib->flags & ZEBRA_FLAG_REJECT) { } else if (re->flags & ZEBRA_FLAG_REJECT) {
msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE; msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE;
} else { } else {
assert (0); assert (0);
@ -189,13 +189,13 @@ create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
msg->route_type = FPM__ROUTE_TYPE__NORMAL; msg->route_type = FPM__ROUTE_TYPE__NORMAL;
} }
msg->metric = rib->metric; msg->metric = re->metric;
/* /*
* Figure out the set of nexthops to be added to the message. * Figure out the set of nexthops to be added to the message.
*/ */
num_nhs = 0; num_nhs = 0;
for (ALL_NEXTHOPS_RO (rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO (re->nexthop, nexthop, tnexthop, recursing))
{ {
if (num_nhs >= multipath_num) if (num_nhs >= multipath_num)
break; break;
@ -245,7 +245,7 @@ create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
*/ */
static Fpm__Message * static Fpm__Message *
create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest, create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
struct rib *rib) struct route_entry *re)
{ {
Fpm__Message *msg; Fpm__Message *msg;
@ -257,9 +257,9 @@ create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
fpm__message__init(msg); fpm__message__init(msg);
if (!rib) { if (!re) {
msg->type = FPM__MESSAGE__TYPE__DELETE_ROUTE; msg->type = FPM__MESSAGE__TYPE__DELETE_ROUTE;
msg->delete_route = create_delete_route_message(allocator, dest, rib); msg->delete_route = create_delete_route_message(allocator, dest, re);
if (!msg->delete_route) { if (!msg->delete_route) {
assert(0); assert(0);
return NULL; return NULL;
@ -268,7 +268,7 @@ create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
} }
msg->type = FPM__MESSAGE__TYPE__ADD_ROUTE; msg->type = FPM__MESSAGE__TYPE__ADD_ROUTE;
msg->add_route = create_add_route_message(allocator, dest, rib); msg->add_route = create_add_route_message(allocator, dest, re);
if (!msg->add_route) { if (!msg->add_route) {
assert(0); assert(0);
return NULL; return NULL;
@ -287,7 +287,7 @@ create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
* value indicates an error. * value indicates an error.
*/ */
int int
zfpm_protobuf_encode_route (rib_dest_t *dest, struct rib *rib, zfpm_protobuf_encode_route (rib_dest_t *dest, struct route_entry *re,
uint8_t *in_buf, size_t in_buf_len) uint8_t *in_buf, size_t in_buf_len)
{ {
Fpm__Message *msg; Fpm__Message *msg;
@ -296,7 +296,7 @@ zfpm_protobuf_encode_route (rib_dest_t *dest, struct rib *rib,
QPB_INIT_STACK_ALLOCATOR (allocator); QPB_INIT_STACK_ALLOCATOR (allocator);
msg = create_route_message(&allocator, dest, rib); msg = create_route_message(&allocator, dest, re);
if (!msg) { if (!msg) {
assert(0); assert(0);
return 0; return 0;

View File

@ -28,7 +28,7 @@
DEFINE_MGROUP(ZEBRA, "zebra") DEFINE_MGROUP(ZEBRA, "zebra")
DEFINE_MTYPE(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix") DEFINE_MTYPE(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix")
DEFINE_MTYPE(ZEBRA, ZEBRA_VRF, "ZEBRA VRF") DEFINE_MTYPE(ZEBRA, ZEBRA_VRF, "ZEBRA VRF")
DEFINE_MTYPE(ZEBRA, RIB, "RIB") DEFINE_MTYPE(ZEBRA, RE, "Route Entry")
DEFINE_MTYPE(ZEBRA, RIB_QUEUE, "RIB process work queue") DEFINE_MTYPE(ZEBRA, RIB_QUEUE, "RIB process work queue")
DEFINE_MTYPE(ZEBRA, STATIC_ROUTE, "Static route") DEFINE_MTYPE(ZEBRA, STATIC_ROUTE, "Static route")
DEFINE_MTYPE(ZEBRA, RIB_DEST, "RIB destination") DEFINE_MTYPE(ZEBRA, RIB_DEST, "RIB destination")

View File

@ -28,7 +28,7 @@ DECLARE_MGROUP(ZEBRA)
DECLARE_MTYPE(RTADV_PREFIX) DECLARE_MTYPE(RTADV_PREFIX)
DECLARE_MTYPE(ZEBRA_NS) DECLARE_MTYPE(ZEBRA_NS)
DECLARE_MTYPE(ZEBRA_VRF) DECLARE_MTYPE(ZEBRA_VRF)
DECLARE_MTYPE(RIB) DECLARE_MTYPE(RE)
DECLARE_MTYPE(RIB_QUEUE) DECLARE_MTYPE(RIB_QUEUE)
DECLARE_MTYPE(STATIC_ROUTE) DECLARE_MTYPE(STATIC_ROUTE)
DECLARE_MTYPE(RIB_DEST) DECLARE_MTYPE(RIB_DEST)

View File

@ -65,7 +65,7 @@ static u_int32_t
fec_derive_label_from_index (struct zebra_vrf *vrf, zebra_fec_t *fec); fec_derive_label_from_index (struct zebra_vrf *vrf, zebra_fec_t *fec);
static int static int
lsp_install (struct zebra_vrf *zvrf, mpls_label_t label, lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
struct route_node *rn, struct rib *rib); struct route_node *rn, struct route_entry *re);
static int static int
lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label); lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label);
static int static int
@ -168,7 +168,7 @@ mpls_processq_init (struct zebra_t *zebra);
*/ */
static int static int
lsp_install (struct zebra_vrf *zvrf, mpls_label_t label, lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
struct route_node *rn, struct rib *rib) struct route_node *rn, struct route_entry *re)
{ {
struct hash *lsp_table; struct hash *lsp_table;
zebra_ile_t tmp_ile; zebra_ile_t tmp_ile;
@ -184,7 +184,7 @@ lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
if (!lsp_table) if (!lsp_table)
return -1; return -1;
lsp_type = lsp_type_from_rib_type (rib->type); lsp_type = lsp_type_from_re_type (re->type);
added = changed = 0; added = changed = 0;
/* Locate or allocate LSP entry. */ /* Locate or allocate LSP entry. */
@ -198,7 +198,7 @@ lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
* the label advertised by the recursive nexthop (plus we don't have the * the label advertised by the recursive nexthop (plus we don't have the
* logic yet to push multiple labels). * logic yet to push multiple labels).
*/ */
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
{ {
/* Skip inactive and recursive entries. */ /* Skip inactive and recursive entries. */
if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
@ -441,7 +441,7 @@ fec_change_update_lsp (struct zebra_vrf *zvrf, zebra_fec_t *fec, mpls_label_t ol
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
afi_t afi; afi_t afi;
/* Uninstall label forwarding entry, if previously installed. */ /* Uninstall label forwarding entry, if previously installed. */
@ -464,16 +464,16 @@ fec_change_update_lsp (struct zebra_vrf *zvrf, zebra_fec_t *fec, mpls_label_t ol
if (!rn) if (!rn)
return 0; return 0;
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
break; break;
} }
if (!rib || !zebra_rib_labeled_unicast (rib)) if (!re || !zebra_rib_labeled_unicast (re))
return 0; return 0;
if (lsp_install (zvrf, fec->label, rn, rib)) if (lsp_install (zvrf, fec->label, rn, re))
return -1; return -1;
return 0; return 0;
@ -656,7 +656,7 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
struct route_table *table; struct route_table *table;
struct prefix_ipv4 p; struct prefix_ipv4 p;
struct route_node *rn; struct route_node *rn;
struct rib *match; struct route_entry *match;
struct nexthop *match_nh; struct nexthop *match_nh;
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
@ -676,9 +676,9 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
route_unlock_node (rn); route_unlock_node (rn);
/* Locate a valid connected route. */ /* Locate a valid connected route. */
RNODE_FOREACH_RIB (rn, match) RNODE_FOREACH_RE (rn, match)
{ {
if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) || if (CHECK_FLAG (match->status, ROUTE_ENTRY_REMOVED) ||
!CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) !CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
continue; continue;
@ -708,7 +708,7 @@ nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
struct route_table *table; struct route_table *table;
struct prefix_ipv6 p; struct prefix_ipv6 p;
struct route_node *rn; struct route_node *rn;
struct rib *match; struct route_entry *match;
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT); table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
if (!table) if (!table)
@ -727,10 +727,10 @@ nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
route_unlock_node (rn); route_unlock_node (rn);
/* Locate a valid connected route. */ /* Locate a valid connected route. */
RNODE_FOREACH_RIB (rn, match) RNODE_FOREACH_RE (rn, match)
{ {
if ((match->type == ZEBRA_ROUTE_CONNECT) && if ((match->type == ZEBRA_ROUTE_CONNECT) &&
!CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) && !CHECK_FLAG (match->status, ROUTE_ENTRY_REMOVED) &&
CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
break; break;
} }
@ -1734,44 +1734,59 @@ mpls_processq_init (struct zebra_t *zebra)
/* /*
* String to label conversion, labels separated by '/'. * String to label conversion, labels separated by '/'.
*
* @param label_str labels separated by /
* @param num_labels number of labels; zero if conversion was unsuccessful
* @param labels preallocated mpls_label_t array of size MPLS_MAX_LABELS; only
* modified if the conversion succeeded
* @return 0 on success
* -1 if the string could not be parsed as integers
* -2 if a label was inside the reserved range (0-15)
* -3 if the number of labels given exceeds MPLS_MAX_LABELS
*/ */
int int
mpls_str2label (const char *label_str, u_int8_t *num_labels, mpls_str2label (const char *label_str, u_int8_t *num_labels,
mpls_label_t *labels) mpls_label_t *labels)
{ {
char *endp; char *ostr; // copy of label string (start)
int i; char *lstr; // copy of label string
char *nump; // pointer to next segment
char *endp; // end pointer
int i; // for iterating label_str
int rc; // return code
mpls_label_t pl[MPLS_MAX_LABELS]; // parsed labels
/* labels to zero until we have a successful parse */
ostr = lstr = XSTRDUP (MTYPE_TMP, label_str);
*num_labels = 0; *num_labels = 0;
for (i = 0; i < MPLS_MAX_LABELS; i++) rc = 0;
for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++)
{ {
mpls_label_t label; nump = strsep (&lstr, "/");
pl[i] = strtoul(nump, &endp, 10);
label = strtoul(label_str, &endp, 0); /* format check */
if (*endp != '\0')
/* validity checks */ rc = -1;
if (endp == label_str) /* validity check */
return -1; else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
rc = -2;
if (!IS_MPLS_UNRESERVED_LABEL(label))
return -1;
labels[i] = label;
if (*endp == '\0')
{
*num_labels = i + 1;
return 0;
}
/* Check separator. */
if (*endp != '/')
return -1;
label_str = endp + 1;
} }
/* Too many labels. */ /* excess labels */
return -1; if (!rc && i == MPLS_MAX_LABELS && lstr)
rc = -3;
if (!rc)
{
*num_labels = i + 1;
memcpy (labels, pl, *num_labels * sizeof (mpls_label_t));
}
XFREE (MTYPE_TMP, ostr);
return rc;
} }
/* /*
@ -1809,7 +1824,7 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
* Install dynamic LSP entry. * Install dynamic LSP entry.
*/ */
int int
zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib) zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *re)
{ {
struct route_table *table; struct route_table *table;
zebra_fec_t *fec; zebra_fec_t *fec;
@ -1829,7 +1844,7 @@ zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct ri
if (fec->label == MPLS_IMP_NULL_LABEL) if (fec->label == MPLS_IMP_NULL_LABEL)
return 0; return 0;
if (lsp_install (zvrf, fec->label, rn, rib)) if (lsp_install (zvrf, fec->label, rn, re))
return -1; return -1;
return 0; return 0;
@ -1839,7 +1854,7 @@ zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct ri
* Uninstall dynamic LSP entry, if any. * Uninstall dynamic LSP entry, if any.
*/ */
int int
zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib) zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *re)
{ {
struct route_table *table; struct route_table *table;
zebra_fec_t *fec; zebra_fec_t *fec;
@ -2296,7 +2311,7 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
struct nexthop *nexthop; struct nexthop *nexthop;
/* Lookup table. */ /* Lookup table. */
@ -2306,18 +2321,18 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
/* Lookup existing route */ /* Lookup existing route */
rn = route_node_get (table, prefix); rn = route_node_get (table, prefix);
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue; continue;
if (rib->distance == distance) if (re->distance == distance)
break; break;
} }
if (rib == NULL) if (re == NULL)
return -1; return -1;
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
{ {
switch (nexthop->type) switch (nexthop->type)
{ {
@ -2356,8 +2371,8 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
else else
return 0; return 0;
SET_FLAG (rib->status, RIB_ENTRY_CHANGED); SET_FLAG (re->status, ROUTE_ENTRY_CHANGED);
SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); SET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
rib_queue_add (rn); rib_queue_add (rn);
return 0; return 0;
@ -2534,7 +2549,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
struct nexthop *nexthop; struct nexthop *nexthop;
int update; int update;
@ -2546,13 +2561,13 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
for (rn = route_top (table); rn; rn = route_next (rn)) for (rn = route_top (table); rn; rn = route_next (rn))
{ {
update = 0; update = 0;
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
if (nexthop->nh_label_type == ZEBRA_LSP_LDP) if (nexthop->nh_label_type == ZEBRA_LSP_LDP)
{ {
nexthop_del_labels (nexthop); nexthop_del_labels (nexthop);
SET_FLAG (rib->status, RIB_ENTRY_CHANGED); SET_FLAG (re->status, ROUTE_ENTRY_CHANGED);
SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); SET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
update = 1; update = 1;
} }

View File

@ -43,6 +43,8 @@
(((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 || \ (((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 || \
(nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) ? AF_INET6 : AF_INET) (nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) ? AF_INET6 : AF_INET)
#define MPLS_LABEL_HELPSTR "Specify label(s) for this route\nOne or more " \
"labels in the range (16-1048575) separated by '/'\n"
/* Typedefs */ /* Typedefs */
@ -208,13 +210,13 @@ zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *vrf);
* Install dynamic LSP entry. * Install dynamic LSP entry.
*/ */
int int
zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib); zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *re);
/* /*
* Uninstall dynamic LSP entry, if any. * Uninstall dynamic LSP entry, if any.
*/ */
int int
zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib); zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *re);
/* /*
* Registration from a client for the label binding for a FEC. If a binding * Registration from a client for the label binding for a FEC. If a binding
@ -449,9 +451,9 @@ lsp_distance (enum lsp_types_t type)
* are converted into LSPs. * are converted into LSPs.
*/ */
static inline enum lsp_types_t static inline enum lsp_types_t
lsp_type_from_rib_type (int rib_type) lsp_type_from_re_type (int re_type)
{ {
switch (rib_type) switch (re_type)
{ {
case ZEBRA_ROUTE_STATIC: case ZEBRA_ROUTE_STATIC:
return ZEBRA_LSP_STATIC; return ZEBRA_LSP_STATIC;

View File

@ -321,8 +321,7 @@ DEFUN (ip_route_label,
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
NULL, NULL, argv[5]->arg); NULL, NULL, argv[5]->arg);
@ -339,8 +338,7 @@ DEFUN (ip_route_tag_label,
"Null interface\n" "Null interface\n"
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg,
NULL, NULL, argv[7]->arg); NULL, NULL, argv[7]->arg);
@ -357,8 +355,7 @@ DEFUN (ip_route_mask_label,
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL,
NULL, NULL, argv[6]->arg); NULL, NULL, argv[6]->arg);
@ -376,8 +373,7 @@ DEFUN (ip_route_mask_tag_label,
"Null interface\n" "Null interface\n"
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg,
@ -395,8 +391,7 @@ DEFUN (ip_route_distance_label,
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
argv[4]->arg, NULL, argv[6]->arg); argv[4]->arg, NULL, argv[6]->arg);
@ -414,8 +409,7 @@ DEFUN (ip_route_tag_distance_label,
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg,
@ -433,8 +427,7 @@ DEFUN (ip_route_mask_distance_label,
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL,
argv[5]->arg, NULL, argv[7]->arg); argv[5]->arg, NULL, argv[7]->arg);
@ -453,8 +446,7 @@ DEFUN (ip_route_mask_tag_distance_label,
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg,
argv[7]->arg, NULL, argv[9]->arg); argv[7]->arg, NULL, argv[9]->arg);
@ -470,8 +462,7 @@ DEFUN (no_ip_route_label,
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
NULL, NULL, argv[6]->arg); NULL, NULL, argv[6]->arg);
@ -489,8 +480,7 @@ DEFUN (no_ip_route_tag_label,
"Null interface\n" "Null interface\n"
"Tag of this route\n" "Tag of this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg,
NULL, NULL, argv[8]->arg); NULL, NULL, argv[8]->arg);
@ -507,8 +497,7 @@ DEFUN (no_ip_route_mask_label,
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL,
NULL, NULL, argv[7]->arg); NULL, NULL, argv[7]->arg);
@ -527,8 +516,7 @@ DEFUN (no_ip_route_mask_tag_label,
"Null interface\n" "Null interface\n"
"Tag of this route\n" "Tag of this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg,
NULL, NULL, argv[9]->arg); NULL, NULL, argv[9]->arg);
@ -545,8 +533,7 @@ DEFUN (no_ip_route_distance_label,
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
argv[5]->arg, NULL, argv[7]->arg); argv[5]->arg, NULL, argv[7]->arg);
@ -565,8 +552,7 @@ DEFUN (no_ip_route_tag_distance_label,
"Tag of this route\n" "Tag of this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg,
argv[7]->arg, NULL, argv[9]->arg); argv[7]->arg, NULL, argv[9]->arg);
@ -584,8 +570,7 @@ DEFUN (no_ip_route_mask_distance_label,
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n" "Null interface\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL,
argv[6]->arg, NULL, argv[8]->arg); argv[6]->arg, NULL, argv[8]->arg);
@ -605,8 +590,7 @@ DEFUN (no_ip_route_mask_tag_distance_label,
"Tag of this route\n" "Tag of this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg,
argv[8]->arg, NULL, argv[10]->arg); argv[8]->arg, NULL, argv[10]->arg);
@ -620,8 +604,7 @@ DEFUN (ipv6_route_label,
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg);
} }
@ -636,8 +619,7 @@ DEFUN (ipv6_route_tag_label,
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg);
} }
@ -650,8 +632,7 @@ DEFUN (ipv6_route_ifname_label,
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg);
} }
@ -665,8 +646,7 @@ DEFUN (ipv6_route_ifname_tag_label,
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
} }
@ -680,8 +660,7 @@ DEFUN (ipv6_route_pref_label,
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg);
} }
@ -697,8 +676,7 @@ DEFUN (ipv6_route_pref_tag_label,
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg);
} }
@ -712,8 +690,7 @@ DEFUN (ipv6_route_ifname_pref_label,
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
} }
@ -729,8 +706,7 @@ DEFUN (ipv6_route_ifname_pref_tag_label,
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
} }
@ -744,8 +720,7 @@ DEFUN (no_ipv6_route_label,
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg);
} }
@ -761,8 +736,7 @@ DEFUN (no_ipv6_route_tag_label,
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
} }
@ -776,8 +750,7 @@ DEFUN (no_ipv6_route_ifname_label,
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg);
} }
@ -793,8 +766,7 @@ DEFUN (no_ipv6_route_ifname_tag_label,
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg);
} }
@ -809,8 +781,7 @@ DEFUN (no_ipv6_route_pref_label,
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
} }
@ -827,8 +798,7 @@ DEFUN (no_ipv6_route_pref_tag_label,
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
} }
@ -843,8 +813,7 @@ DEFUN (no_ipv6_route_ifname_pref_label,
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg);
} }
@ -861,8 +830,7 @@ DEFUN (no_ipv6_route_ifname_pref_tag_label,
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
"Specify label(s) for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg);
} }

File diff suppressed because it is too large Load Diff

View File

@ -48,8 +48,8 @@
#include "zebra/interface.h" #include "zebra/interface.h"
#include "zebra/zebra_memory.h" #include "zebra/zebra_memory.h"
static void free_state(vrf_id_t vrf_id, struct rib *rib, struct route_node *rn); static void free_state(vrf_id_t vrf_id, struct route_entry *re, struct route_node *rn);
static void copy_state(struct rnh *rnh, struct rib *rib, static void copy_state(struct rnh *rnh, struct route_entry *re,
struct route_node *rn); struct route_node *rn);
#define lookup_rnh_table(v, f) \ #define lookup_rnh_table(v, f) \
({ \ ({ \
@ -61,7 +61,7 @@ static void copy_state(struct rnh *rnh, struct rib *rib,
t; \ t; \
}) })
static int compare_state(struct rib *r1, struct rib *r2); static int compare_state(struct route_entry *r1, struct route_entry *r2);
static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
vrf_id_t vrf_id); vrf_id_t vrf_id);
static void print_rnh(struct route_node *rn, struct vty *vty); static void print_rnh(struct route_node *rn, struct vty *vty);
@ -305,7 +305,7 @@ zebra_deregister_rnh_static_nexthops (vrf_id_t vrf_id, struct nexthop *nexthop,
*/ */
static int static int
zebra_rnh_apply_nht_rmap(int family, struct route_node *prn, zebra_rnh_apply_nht_rmap(int family, struct route_node *prn,
struct rib *rib, int proto) struct route_entry *re, int proto)
{ {
int at_least_one = 0; int at_least_one = 0;
int rmap_family; /* Route map has diff AF family enum */ int rmap_family; /* Route map has diff AF family enum */
@ -314,11 +314,11 @@ zebra_rnh_apply_nht_rmap(int family, struct route_node *prn,
rmap_family = (family == AF_INET) ? AFI_IP : AFI_IP6; rmap_family = (family == AF_INET) ? AFI_IP : AFI_IP6;
if (prn && rib) if (prn && re)
{ {
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
{ {
ret = zebra_nht_route_map_check(rmap_family, proto, &prn->p, rib, ret = zebra_nht_route_map_check(rmap_family, proto, &prn->p, re,
nexthop); nexthop);
if (ret != RMAP_DENYMATCH) if (ret != RMAP_DENYMATCH)
{ {
@ -335,17 +335,17 @@ zebra_rnh_apply_nht_rmap(int family, struct route_node *prn,
} }
/* /*
* Determine appropriate route (RIB entry) resolving a tracked entry * Determine appropriate route (RE entry) resolving a tracked entry
* (nexthop or BGP route for import). * (nexthop or BGP route for import).
*/ */
static struct rib * static struct route_entry *
zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type, zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type,
struct route_node *nrn, struct rnh *rnh, struct route_node *nrn, struct rnh *rnh,
struct route_node **prn) struct route_node **prn)
{ {
struct route_table *route_table; struct route_table *route_table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
*prn = NULL; *prn = NULL;
@ -363,29 +363,29 @@ zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type,
if ((type == RNH_NEXTHOP_TYPE) && if ((type == RNH_NEXTHOP_TYPE) &&
(is_default_prefix (&rn->p) && (is_default_prefix (&rn->p) &&
!nh_resolve_via_default(rn->p.family))) !nh_resolve_via_default(rn->p.family)))
rib = NULL; re = NULL;
else if ((type == RNH_IMPORT_CHECK_TYPE) && else if ((type == RNH_IMPORT_CHECK_TYPE) &&
CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH) && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH) &&
!prefix_same(&nrn->p, &rn->p)) !prefix_same(&nrn->p, &rn->p))
rib = NULL; re = NULL;
else else
{ {
/* Identify appropriate route entry. */ /* Identify appropriate route entry. */
RNODE_FOREACH_RIB(rn, rib) RNODE_FOREACH_RE(rn, re)
{ {
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue; continue;
if (! CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) if (! CHECK_FLAG (re->status, ROUTE_ENTRY_SELECTED_FIB))
continue; continue;
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
{ {
if (rib->type == ZEBRA_ROUTE_CONNECT) if (re->type == ZEBRA_ROUTE_CONNECT)
break; break;
if (rib->type == ZEBRA_ROUTE_NHRP) if (re->type == ZEBRA_ROUTE_NHRP)
{ {
struct nexthop *nexthop; struct nexthop *nexthop;
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
if (nexthop->type == NEXTHOP_TYPE_IFINDEX) if (nexthop->type == NEXTHOP_TYPE_IFINDEX)
break; break;
if (nexthop) if (nexthop)
@ -393,7 +393,7 @@ zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type,
} }
} }
else if ((type == RNH_IMPORT_CHECK_TYPE) && else if ((type == RNH_IMPORT_CHECK_TYPE) &&
(rib->type == ZEBRA_ROUTE_BGP)) (re->type == ZEBRA_ROUTE_BGP))
continue; continue;
else else
break; break;
@ -402,9 +402,9 @@ zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type,
/* Need to unlock route node */ /* Need to unlock route node */
route_unlock_node(rn); route_unlock_node(rn);
if (rib) if (re)
*prn = rn; *prn = rn;
return rib; return re;
} }
/* /*
@ -414,7 +414,7 @@ zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type,
static void static void
zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force, zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force,
struct route_node *nrn, struct rnh *rnh, struct route_node *nrn, struct rnh *rnh,
struct rib *rib) struct route_entry *re)
{ {
int state_changed = 0; int state_changed = 0;
struct zserv *client; struct zserv *client;
@ -423,20 +423,20 @@ zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force,
struct nexthop *nexthop, *tnexthop; struct nexthop *nexthop, *tnexthop;
int recursing; int recursing;
if (rib && (rnh->state == NULL)) if (re && (rnh->state == NULL))
{ {
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{ {
state_changed = 1; state_changed = 1;
break; break;
} }
} }
else if (!rib && (rnh->state != NULL)) else if (!re && (rnh->state != NULL))
state_changed = 1; state_changed = 1;
if (compare_state(rib, rnh->state)) if (compare_state(re, rnh->state))
copy_state(rnh, rib, nrn); copy_state(rnh, re, nrn);
if (state_changed || force) if (state_changed || force)
{ {
@ -461,7 +461,7 @@ zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force,
static void static void
zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family, zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family,
struct route_node *nrn, struct rnh *rnh, struct route_node *nrn, struct rnh *rnh,
struct route_node *prn, struct rib *rib) struct route_node *prn, struct route_entry *re)
{ {
struct listnode *node; struct listnode *node;
struct zserv *client; struct zserv *client;
@ -472,7 +472,7 @@ zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family,
if (IS_ZEBRA_DEBUG_NHT) if (IS_ZEBRA_DEBUG_NHT)
{ {
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
if (prn && rib) if (prn && re)
{ {
prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN); prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
zlog_debug("%u:%s: NH resolved over route %s", vrfid, bufn, bufp); zlog_debug("%u:%s: NH resolved over route %s", vrfid, bufn, bufp);
@ -483,12 +483,12 @@ zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family,
for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client))
{ {
if (prn && rib) if (prn && re)
{ {
/* Apply route-map for this client to route resolving this /* Apply route-map for this client to route resolving this
* nexthop to see if it is filtered or not. * nexthop to see if it is filtered or not.
*/ */
num_resolving_nh = zebra_rnh_apply_nht_rmap(family, prn, rib, num_resolving_nh = zebra_rnh_apply_nht_rmap(family, prn, re,
client->proto); client->proto);
if (num_resolving_nh) if (num_resolving_nh)
rnh->filtered[client->proto] = 0; rnh->filtered[client->proto] = 0;
@ -515,12 +515,12 @@ zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family,
static void static void
zebra_rnh_process_static_routes (vrf_id_t vrfid, int family, zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
struct route_node *nrn, struct rnh *rnh, struct route_node *nrn, struct rnh *rnh,
struct route_node *prn, struct rib *rib) struct route_node *prn, struct route_entry *re)
{ {
struct listnode *node; struct listnode *node;
int num_resolving_nh = 0; int num_resolving_nh = 0;
struct route_node *static_rn; struct route_node *static_rn;
struct rib *srib; struct route_entry *sre;
struct nexthop *nexthop; struct nexthop *nexthop;
char bufn[INET6_ADDRSTRLEN]; char bufn[INET6_ADDRSTRLEN];
char bufp[INET6_ADDRSTRLEN]; char bufp[INET6_ADDRSTRLEN];
@ -533,12 +533,12 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN); prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
} }
if (prn && rib) if (prn && re)
{ {
/* Apply route-map for "static" to route resolving this /* Apply route-map for "static" to route resolving this
* nexthop to see if it is filtered or not. * nexthop to see if it is filtered or not.
*/ */
num_resolving_nh = zebra_rnh_apply_nht_rmap(family, prn, rib, num_resolving_nh = zebra_rnh_apply_nht_rmap(family, prn, re,
ZEBRA_ROUTE_STATIC); ZEBRA_ROUTE_STATIC);
if (num_resolving_nh) if (num_resolving_nh)
rnh->filtered[ZEBRA_ROUTE_STATIC] = 0; rnh->filtered[ZEBRA_ROUTE_STATIC] = 0;
@ -552,15 +552,15 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
for (ALL_LIST_ELEMENTS_RO(rnh->zebra_static_route_list, node, for (ALL_LIST_ELEMENTS_RO(rnh->zebra_static_route_list, node,
static_rn)) static_rn))
{ {
RNODE_FOREACH_RIB(static_rn, srib) RNODE_FOREACH_RE(static_rn, sre)
{ {
if (srib->type != ZEBRA_ROUTE_STATIC) if (sre->type != ZEBRA_ROUTE_STATIC)
continue; continue;
/* Set the filter flag for the correct nexthop - static route may /* Set the filter flag for the correct nexthop - static route may
* be having multiple. We care here only about registered nexthops. * be having multiple. We care here only about registered nexthops.
*/ */
for (nexthop = srib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = sre->nexthop; nexthop; nexthop = nexthop->next)
{ {
switch (nexthop->type) switch (nexthop->type)
{ {
@ -593,7 +593,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
if (IS_ZEBRA_DEBUG_NHT) if (IS_ZEBRA_DEBUG_NHT)
{ {
prefix2str(&static_rn->p, bufs, INET6_ADDRSTRLEN); prefix2str(&static_rn->p, bufs, INET6_ADDRSTRLEN);
if (prn && rib) if (prn && re)
zlog_debug("%u:%s: NH change %s, scheduling static route %s", zlog_debug("%u:%s: NH change %s, scheduling static route %s",
vrfid, bufn, num_resolving_nh ? vrfid, bufn, num_resolving_nh ?
"" : "(filtered by route-map)", bufs); "" : "(filtered by route-map)", bufs);
@ -602,8 +602,8 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
vrfid, bufn, bufs); vrfid, bufn, bufs);
} }
SET_FLAG(srib->status, RIB_ENTRY_CHANGED); SET_FLAG(sre->status, ROUTE_ENTRY_CHANGED);
SET_FLAG(srib->status, RIB_ENTRY_NEXTHOPS_CHANGED); SET_FLAG(sre->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
} }
rib_queue_add(static_rn); rib_queue_add(static_rn);
@ -618,7 +618,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
static void static void
zebra_rnh_eval_nexthop_entry (vrf_id_t vrfid, int family, int force, zebra_rnh_eval_nexthop_entry (vrf_id_t vrfid, int family, int force,
struct route_node *nrn, struct rnh *rnh, struct route_node *nrn, struct rnh *rnh,
struct route_node *prn, struct rib *rib) struct route_node *prn, struct route_entry *re)
{ {
int state_changed = 0; int state_changed = 0;
@ -633,12 +633,12 @@ zebra_rnh_eval_nexthop_entry (vrf_id_t vrfid, int family, int force,
else else
memset(&rnh->resolved_route, 0, sizeof(struct prefix)); memset(&rnh->resolved_route, 0, sizeof(struct prefix));
copy_state(rnh, rib, nrn); copy_state(rnh, re, nrn);
state_changed = 1; state_changed = 1;
} }
else if (compare_state(rib, rnh->state)) else if (compare_state(re, rnh->state))
{ {
copy_state(rnh, rib, nrn); copy_state(rnh, re, nrn);
state_changed = 1; state_changed = 1;
} }
@ -663,7 +663,7 @@ zebra_rnh_evaluate_entry (vrf_id_t vrfid, int family, int force, rnh_type_t type
struct route_node *nrn) struct route_node *nrn)
{ {
struct rnh *rnh; struct rnh *rnh;
struct rib *rib; struct route_entry *re;
struct route_node *prn; struct route_node *prn;
char bufn[INET6_ADDRSTRLEN]; char bufn[INET6_ADDRSTRLEN];
@ -676,31 +676,31 @@ zebra_rnh_evaluate_entry (vrf_id_t vrfid, int family, int force, rnh_type_t type
rnh = nrn->info; rnh = nrn->info;
/* Identify route entry (RIB) resolving this tracked entry. */ /* Identify route entry (RE) resolving this tracked entry. */
rib = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn); re = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn);
/* If the entry cannot be resolved and that is also the existing state, /* If the entry cannot be resolved and that is also the existing state,
* there is nothing further to do. * there is nothing further to do.
*/ */
if (!rib && rnh->state == NULL && !force) if (!re && rnh->state == NULL && !force)
return; return;
/* Process based on type of entry. */ /* Process based on type of entry. */
if (type == RNH_IMPORT_CHECK_TYPE) if (type == RNH_IMPORT_CHECK_TYPE)
zebra_rnh_eval_import_check_entry (vrfid, family, force, zebra_rnh_eval_import_check_entry (vrfid, family, force,
nrn, rnh, rib); nrn, rnh, re);
else else
zebra_rnh_eval_nexthop_entry (vrfid, family, force, zebra_rnh_eval_nexthop_entry (vrfid, family, force,
nrn, rnh, prn, rib); nrn, rnh, prn, re);
} }
/* /*
* Clear the RIB_ENTRY_NEXTHOPS_CHANGED flag * Clear the ROUTE_ENTRY_NEXTHOPS_CHANGED flag
* from the rib entries. * from the re entries.
* *
* Please note we are doing this *after* we have * Please note we are doing this *after* we have
* notified the world about each nexthop as that * notified the world about each nexthop as that
* we can have a situation where one rib entry * we can have a situation where one re entry
* covers multiple nexthops we are interested in. * covers multiple nexthops we are interested in.
*/ */
static void static void
@ -708,15 +708,15 @@ zebra_rnh_clear_nhc_flag (vrf_id_t vrfid, int family, rnh_type_t type,
struct route_node *nrn) struct route_node *nrn)
{ {
struct rnh *rnh; struct rnh *rnh;
struct rib *rib; struct route_entry *re;
struct route_node *prn; struct route_node *prn;
rnh = nrn->info; rnh = nrn->info;
rib = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn); re = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn);
if (rib) if (re)
UNSET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); UNSET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
} }
/* Evaluate all tracked entries (nexthops or routes for import into BGP) /* Evaluate all tracked entries (nexthops or routes for import into BGP)
@ -812,25 +812,25 @@ zebra_cleanup_rnh_client (vrf_id_t vrf_id, int family, struct zserv *client,
} }
/** /**
* free_state - free up the rib structure associated with the rnh. * free_state - free up the re structure associated with the rnh.
*/ */
static void static void
free_state (vrf_id_t vrf_id, struct rib *rib, struct route_node *rn) free_state (vrf_id_t vrf_id, struct route_entry *re, struct route_node *rn)
{ {
if (!rib) if (!re)
return; return;
/* free RIB and nexthops */ /* free RE and nexthops */
zebra_deregister_rnh_static_nexthops (vrf_id, rib->nexthop, rn); zebra_deregister_rnh_static_nexthops (vrf_id, re->nexthop, rn);
nexthops_free(rib->nexthop); nexthops_free(re->nexthop);
XFREE (MTYPE_RIB, rib); XFREE (MTYPE_RE, re);
} }
static void static void
copy_state (struct rnh *rnh, struct rib *rib, struct route_node *rn) copy_state (struct rnh *rnh, struct route_entry *re, struct route_node *rn)
{ {
struct rib *state; struct route_entry *state;
struct nexthop *nh; struct nexthop *nh;
if (rnh->state) if (rnh->state)
@ -839,20 +839,20 @@ copy_state (struct rnh *rnh, struct rib *rib, struct route_node *rn)
rnh->state = NULL; rnh->state = NULL;
} }
if (!rib) if (!re)
return; return;
state = XCALLOC (MTYPE_RIB, sizeof (struct rib)); state = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
state->type = rib->type; state->type = re->type;
state->metric = rib->metric; state->metric = re->metric;
for (nh = rib->nexthop; nh; nh = nh->next) for (nh = re->nexthop; nh; nh = nh->next)
rib_copy_nexthops(state, nh); route_entry_copy_nexthops(state, nh);
rnh->state = state; rnh->state = state;
} }
static int static int
compare_state (struct rib *r1, struct rib *r2) compare_state (struct route_entry *r1, struct route_entry *r2)
{ {
if (!r1 && !r2) if (!r1 && !r2)
@ -867,7 +867,7 @@ compare_state (struct rib *r1, struct rib *r2)
if (r1->nexthop_num != r2->nexthop_num) if (r1->nexthop_num != r2->nexthop_num)
return 1; return 1;
if (CHECK_FLAG(r1->status, RIB_ENTRY_NEXTHOPS_CHANGED)) if (CHECK_FLAG(r1->status, ROUTE_ENTRY_NEXTHOPS_CHANGED))
return 1; return 1;
return 0; return 0;
@ -877,7 +877,7 @@ static int
send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vrf_id) send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vrf_id)
{ {
struct stream *s; struct stream *s;
struct rib *rib; struct route_entry *re;
unsigned long nump; unsigned long nump;
u_char num; u_char num;
struct nexthop *nexthop; struct nexthop *nexthop;
@ -886,7 +886,7 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
? ZEBRA_IMPORT_CHECK_UPDATE : ZEBRA_NEXTHOP_UPDATE; ? ZEBRA_IMPORT_CHECK_UPDATE : ZEBRA_NEXTHOP_UPDATE;
rn = rnh->node; rn = rnh->node;
rib = rnh->state; re = rnh->state;
/* Get output stream. */ /* Get output stream. */
s = client->obuf; s = client->obuf;
@ -910,14 +910,14 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
__FUNCTION__, rn->p.family); __FUNCTION__, rn->p.family);
break; break;
} }
if (rib) if (re)
{ {
stream_putc (s, rib->distance); stream_putc (s, re->distance);
stream_putl (s, rib->metric); stream_putl (s, re->metric);
num = 0; num = 0;
nump = stream_get_endp(s); nump = stream_get_endp(s);
stream_putc (s, 0); stream_putc (s, 0);
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
if ((CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) || if ((CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ||
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) &&
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))

View File

@ -37,7 +37,7 @@ struct rnh
/* VRF identifier. */ /* VRF identifier. */
vrf_id_t vrf_id; vrf_id_t vrf_id;
struct rib *state; struct route_entry *state;
struct prefix resolved_route; struct prefix resolved_route;
struct list *client_list; struct list *client_list;
struct list *zebra_static_route_list; /* static routes dependent on this NH */ struct list *zebra_static_route_list; /* static routes dependent on this NH */

View File

@ -1351,7 +1351,7 @@ zebra_del_import_table_route_map (afi_t afi, uint32_t table)
} }
route_map_result_t route_map_result_t
zebra_import_table_route_map_check (int family, int rib_type, struct prefix *p, zebra_import_table_route_map_check (int family, int re_type, struct prefix *p,
struct nexthop *nexthop, vrf_id_t vrf_id, route_tag_t tag, const char *rmap_name) struct nexthop *nexthop, vrf_id_t vrf_id, route_tag_t tag, const char *rmap_name)
{ {
struct route_map *rmap = NULL; struct route_map *rmap = NULL;
@ -1360,11 +1360,11 @@ zebra_import_table_route_map_check (int family, int rib_type, struct prefix *p,
nh_obj.nexthop = nexthop; nh_obj.nexthop = nexthop;
nh_obj.vrf_id = vrf_id; nh_obj.vrf_id = vrf_id;
nh_obj.source_protocol = rib_type; nh_obj.source_protocol = re_type;
nh_obj.metric = 0; nh_obj.metric = 0;
nh_obj.tag = tag; nh_obj.tag = tag;
if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) if (re_type >= 0 && re_type < ZEBRA_ROUTE_MAX)
rmap = route_map_lookup_by_name (rmap_name); rmap = route_map_lookup_by_name (rmap_name);
if (rmap) { if (rmap) {
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
@ -1375,17 +1375,17 @@ zebra_import_table_route_map_check (int family, int rib_type, struct prefix *p,
route_map_result_t route_map_result_t
zebra_nht_route_map_check (int family, int client_proto, struct prefix *p, zebra_nht_route_map_check (int family, int client_proto, struct prefix *p,
struct rib * rib, struct nexthop *nexthop) struct route_entry * re, struct nexthop *nexthop)
{ {
struct route_map *rmap = NULL; struct route_map *rmap = NULL;
route_map_result_t ret = RMAP_MATCH; route_map_result_t ret = RMAP_MATCH;
struct nh_rmap_obj nh_obj; struct nh_rmap_obj nh_obj;
nh_obj.nexthop = nexthop; nh_obj.nexthop = nexthop;
nh_obj.vrf_id = rib->vrf_id; nh_obj.vrf_id = re->vrf_id;
nh_obj.source_protocol = rib->type; nh_obj.source_protocol = re->type;
nh_obj.metric = rib->metric; nh_obj.metric = re->metric;
nh_obj.tag = rib->tag; nh_obj.tag = re->tag;
if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
rmap = route_map_lookup_by_name (nht_rm[family][client_proto]); rmap = route_map_lookup_by_name (nht_rm[family][client_proto]);

View File

@ -43,7 +43,7 @@ extern route_map_result_t zebra_route_map_check (int family, int rib_type,
extern route_map_result_t zebra_nht_route_map_check (int family, extern route_map_result_t zebra_nht_route_map_check (int family,
int client_proto, int client_proto,
struct prefix *p, struct prefix *p,
struct rib *, struct route_entry *,
struct nexthop *nexthop); struct nexthop *nexthop);

View File

@ -143,7 +143,7 @@ ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
static int result; static int result;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED) if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
return NULL; return NULL;
@ -155,7 +155,7 @@ ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
/* Return number of routing entries. */ /* Return number of routing entries. */
result = 0; result = 0;
for (rn = route_top (table); rn; rn = route_next (rn)) for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
result++; result++;
return (u_char *)&result; return (u_char *)&result;
@ -168,7 +168,7 @@ ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
static int result; static int result;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED) if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
return NULL; return NULL;
@ -180,7 +180,7 @@ ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
/* Return number of routing entries. */ /* Return number of routing entries. */
result = 0; result = 0;
for (rn = route_top (table); rn; rn = route_next (rn)) for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
result++; result++;
return (u_char *)&result; return (u_char *)&result;
@ -256,15 +256,15 @@ proto_trans(int type)
} }
static void static void
check_replace(struct route_node *np2, struct rib *rib2, check_replace(struct route_node *np2, struct route_entry *re2,
struct route_node **np, struct rib **rib) struct route_node **np, struct route_entry **re)
{ {
int proto, proto2; int proto, proto2;
if (!*np) if (!*np)
{ {
*np = np2; *np = np2;
*rib = rib2; *re = re2;
return; return;
} }
@ -273,39 +273,39 @@ check_replace(struct route_node *np2, struct rib *rib2,
if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0) if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0)
{ {
*np = np2; *np = np2;
*rib = rib2; *re = re2;
return; return;
} }
proto = proto_trans((*rib)->type); proto = proto_trans((*re)->type);
proto2 = proto_trans(rib2->type); proto2 = proto_trans(re2->type);
if (proto2 > proto) if (proto2 > proto)
return; return;
if (proto2 < proto) if (proto2 < proto)
{ {
*np = np2; *np = np2;
*rib = rib2; *re = re2;
return; return;
} }
if (in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4, if (in_addr_cmp((u_char *)&(*re)->nexthop->gate.ipv4,
(u_char *)&rib2->nexthop->gate.ipv4) <= 0) (u_char *)&re2->nexthop->gate.ipv4) <= 0)
return; return;
*np = np2; *np = np2;
*rib = rib2; *re = re2;
return; return;
} }
static void static void
get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len, get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
int exact, struct route_node **np, struct rib **rib) int exact, struct route_node **np, struct route_entry **re)
{ {
struct in_addr dest; struct in_addr dest;
struct route_table *table; struct route_table *table;
struct route_node *np2; struct route_node *np2;
struct rib *rib2; struct route_entry *re2;
int proto; int proto;
int policy; int policy;
struct in_addr nexthop; struct in_addr nexthop;
@ -328,7 +328,7 @@ get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
/* Init return variables */ /* Init return variables */
*np = NULL; *np = NULL;
*rib = NULL; *re = NULL;
/* Short circuit exact matches of wrong length */ /* Short circuit exact matches of wrong length */
@ -374,11 +374,11 @@ get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
{ {
if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest)) if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest))
{ {
RNODE_FOREACH_RIB (*np, *rib) RNODE_FOREACH_RE (*np, *re)
{ {
if (!in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4, if (!in_addr_cmp((u_char *)&(*re)->nexthop->gate.ipv4,
(u_char *)&nexthop)) (u_char *)&nexthop))
if (proto == proto_trans((*rib)->type)) if (proto == proto_trans((*re)->type))
return; return;
} }
} }
@ -393,34 +393,34 @@ get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
/* Check destination first */ /* Check destination first */
if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0) if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0)
RNODE_FOREACH_RIB (np2, rib2) RNODE_FOREACH_RE (np2, re2)
check_replace(np2, rib2, np, rib); check_replace(np2, re2, np, re);
if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0) if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0)
{ /* have to look at each rib individually */ { /* have to look at each re individually */
RNODE_FOREACH_RIB (np2, rib2) RNODE_FOREACH_RE (np2, re2)
{ {
int proto2, policy2; int proto2, policy2;
proto2 = proto_trans(rib2->type); proto2 = proto_trans(re2->type);
policy2 = 0; policy2 = 0;
if ((policy < policy2) if ((policy < policy2)
|| ((policy == policy2) && (proto < proto2)) || ((policy == policy2) && (proto < proto2))
|| ((policy == policy2) && (proto == proto2) || ((policy == policy2) && (proto == proto2)
&& (in_addr_cmp((u_char *)&rib2->nexthop->gate.ipv4, && (in_addr_cmp((u_char *)&re2->nexthop->gate.ipv4,
(u_char *) &nexthop) >= 0) (u_char *) &nexthop) >= 0)
)) ))
check_replace(np2, rib2, np, rib); check_replace(np2, re2, np, re);
} }
} }
} }
if (!*rib) if (!*re)
return; return;
policy = 0; policy = 0;
proto = proto_trans((*rib)->type); proto = proto_trans((*re)->type);
*objid_len = v->namelen + 10; *objid_len = v->namelen + 10;
pnt = (u_char *) &(*np)->p.u.prefix; pnt = (u_char *) &(*np)->p.u.prefix;
@ -433,7 +433,7 @@ get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
{ {
struct nexthop *nexthop; struct nexthop *nexthop;
nexthop = (*rib)->nexthop; nexthop = (*re)->nexthop;
if (nexthop) if (nexthop)
{ {
pnt = (u_char *) &nexthop->gate.ipv4; pnt = (u_char *) &nexthop->gate.ipv4;
@ -450,7 +450,7 @@ ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
int exact, size_t *val_len, WriteMethod **write_method) int exact, size_t *val_len, WriteMethod **write_method)
{ {
struct route_node *np; struct route_node *np;
struct rib *rib; struct route_entry *re;
static int result; static int result;
static int resarr[2]; static int resarr[2];
static struct in_addr netmask; static struct in_addr netmask;
@ -460,11 +460,11 @@ ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
== MATCH_FAILED) == MATCH_FAILED)
return NULL; return NULL;
get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib); get_fwtable_route_node(v, objid, objid_len, exact, &np, &re);
if (!np) if (!np)
return NULL; return NULL;
nexthop = rib->nexthop; nexthop = re->nexthop;
if (! nexthop) if (! nexthop)
return NULL; return NULL;
@ -501,7 +501,7 @@ ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
return (u_char *)&result; return (u_char *)&result;
break; break;
case IPFORWARDPROTO: case IPFORWARDPROTO:
result = proto_trans(rib->type); result = proto_trans(re->type);
*val_len = sizeof(int); *val_len = sizeof(int);
return (u_char *)&result; return (u_char *)&result;
break; break;

View File

@ -40,7 +40,7 @@ void
static_install_route (afi_t afi, safi_t safi, struct prefix *p, static_install_route (afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p, struct static_route *si) struct prefix_ipv6 *src_p, struct static_route *si)
{ {
struct rib *rib; struct route_entry *re;
struct route_node *rn; struct route_node *rn;
struct route_table *table; struct route_table *table;
struct prefix nh_p; struct prefix nh_p;
@ -55,20 +55,20 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
/* Lookup existing route */ /* Lookup existing route */
rn = srcdest_rnode_get (table, p, src_p); rn = srcdest_rnode_get (table, p, src_p);
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue; continue;
if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance) if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance)
break; break;
} }
if (rib) if (re)
{ {
/* if tag value changed , update old value in RIB */ /* if tag value changed , update old value in RIB */
if (rib->tag != si->tag) if (re->tag != si->tag)
rib->tag = si->tag; re->tag = si->tag;
/* Same distance static route is there. Update it with new /* Same distance static route is there. Update it with new
nexthop. */ nexthop. */
@ -76,27 +76,27 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
switch (si->type) switch (si->type)
{ {
case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY:
nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); nexthop = route_entry_nexthop_ipv4_add (re, &si->addr.ipv4, NULL);
nh_p.family = AF_INET; nh_p.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4; nh_p.u.prefix4 = si->addr.ipv4;
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
break; break;
case STATIC_IFINDEX: case STATIC_IFINDEX:
nexthop = rib_nexthop_ifindex_add (rib, si->ifindex); nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex);
break; break;
case STATIC_BLACKHOLE: case STATIC_BLACKHOLE:
nexthop = rib_nexthop_blackhole_add (rib); nexthop = route_entry_nexthop_blackhole_add (re);
break; break;
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6); nexthop = route_entry_nexthop_ipv6_add (re, &si->addr.ipv6);
nh_p.family = AF_INET6; nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6; nh_p.u.prefix6 = si->addr.ipv6;
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
break; break;
case STATIC_IPV6_GATEWAY_IFINDEX: case STATIC_IPV6_GATEWAY_IFINDEX:
nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &si->addr.ipv6,
si->ifindex); si->ifindex);
break; break;
} }
@ -111,8 +111,8 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
{ {
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)", zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)",
si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); si->vrf_id, buf, p->prefixlen, rn, re, re->type);
} }
} }
/* Schedule route for processing or invoke NHT, as appropriate. */ /* Schedule route for processing or invoke NHT, as appropriate. */
@ -125,42 +125,42 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
else else
{ {
/* This is new static route. */ /* This is new static route. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
rib->type = ZEBRA_ROUTE_STATIC; re->type = ZEBRA_ROUTE_STATIC;
rib->instance = 0; re->instance = 0;
rib->distance = si->distance; re->distance = si->distance;
rib->metric = 0; re->metric = 0;
rib->mtu = 0; re->mtu = 0;
rib->vrf_id = si->vrf_id; re->vrf_id = si->vrf_id;
rib->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default; re->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default;
rib->nexthop_num = 0; re->nexthop_num = 0;
rib->tag = si->tag; re->tag = si->tag;
switch (si->type) switch (si->type)
{ {
case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY:
nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); nexthop = route_entry_nexthop_ipv4_add (re, &si->addr.ipv4, NULL);
nh_p.family = AF_INET; nh_p.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4; nh_p.u.prefix4 = si->addr.ipv4;
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
break; break;
case STATIC_IFINDEX: case STATIC_IFINDEX:
nexthop = rib_nexthop_ifindex_add (rib, si->ifindex); nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex);
break; break;
case STATIC_BLACKHOLE: case STATIC_BLACKHOLE:
nexthop = rib_nexthop_blackhole_add (rib); nexthop = route_entry_nexthop_blackhole_add (re);
break; break;
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6); nexthop = route_entry_nexthop_ipv6_add (re, &si->addr.ipv6);
nh_p.family = AF_INET6; nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6; nh_p.u.prefix6 = si->addr.ipv6;
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
break; break;
case STATIC_IPV6_GATEWAY_IFINDEX: case STATIC_IPV6_GATEWAY_IFINDEX:
nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &si->addr.ipv6,
si->ifindex); si->ifindex);
break; break;
} }
@ -170,7 +170,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
&si->snh_label.label[0]); &si->snh_label.label[0]);
/* Save the flags of this static routes (reject, blackhole) */ /* Save the flags of this static routes (reject, blackhole) */
rib->flags = si->flags; re->flags = si->flags;
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
{ {
@ -178,21 +178,21 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
{ {
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d)", zlog_debug ("%u:%s/%d: Inserting route rn %p, re %p (type %d)",
si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); si->vrf_id, buf, p->prefixlen, rn, re, re->type);
} }
} }
/* Link this rib to the tree. Schedule for processing or invoke NHT, /* Link this re to the tree. Schedule for processing or invoke NHT,
* as appropriate. * as appropriate.
*/ */
if (si->type == STATIC_IPV4_GATEWAY || if (si->type == STATIC_IPV4_GATEWAY ||
si->type == STATIC_IPV6_GATEWAY) si->type == STATIC_IPV6_GATEWAY)
{ {
rib_addnode (rn, rib, 0); rib_addnode (rn, re, 0);
zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p);
} }
else else
rib_addnode (rn, rib, 1); rib_addnode (rn, re, 1);
} }
} }
@ -230,7 +230,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p, struct static_route *si) struct prefix_ipv6 *src_p, struct static_route *si)
{ {
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
struct nexthop *nexthop; struct nexthop *nexthop;
struct route_table *table; struct route_table *table;
struct prefix nh_p; struct prefix nh_p;
@ -245,24 +245,24 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
if (! rn) if (! rn)
return; return;
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue; continue;
if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance && if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance &&
rib->tag == si->tag) re->tag == si->tag)
break; break;
} }
if (! rib) if (! re)
{ {
route_unlock_node (rn); route_unlock_node (rn);
return; return;
} }
/* Lookup nexthop. */ /* Lookup nexthop. */
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
if (static_nexthop_same (nexthop, si)) if (static_nexthop_same (nexthop, si))
break; break;
@ -274,8 +274,8 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
} }
/* Check nexthop. */ /* Check nexthop. */
if (rib->nexthop_num == 1) if (re->nexthop_num == 1)
rib_delnode (rn, rib); rib_delnode (rn, re);
else else
{ {
/* Mark this nexthop as inactive and reinstall the route. Then, delete /* Mark this nexthop as inactive and reinstall the route. Then, delete
@ -288,31 +288,31 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)
{ {
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)", zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)",
si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); si->vrf_id, buf, p->prefixlen, rn, re, re->type);
} }
} }
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{ {
/* If there are other active nexthops, do an update. */ /* If there are other active nexthops, do an update. */
if (rib->nexthop_active_num > 1) if (re->nexthop_active_num > 1)
{ {
/* Update route in kernel if it's in fib */ /* Update route in kernel if it's in fib */
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
rib_install_kernel (rn, rib, rib); rib_install_kernel (rn, re, re);
/* Update redistribution if it's selected */ /* Update redistribution if it's selected */
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
redistribute_update (p, (struct prefix*)src_p, rib, NULL); redistribute_update (p, (struct prefix*)src_p, re, NULL);
} }
else else
{ {
/* Remove from redistribute if selected route becomes inactive */ /* Remove from redistribute if selected route becomes inactive */
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
redistribute_delete (p, (struct prefix*)src_p, rib); redistribute_delete (p, (struct prefix*)src_p, re);
/* Remove from kernel if fib route becomes inactive */ /* Remove from kernel if fib route becomes inactive */
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
rib_uninstall_kernel (rn, rib); rib_uninstall_kernel (rn, re);
} }
} }
@ -329,7 +329,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = nexthop->gate.ipv6; nh_p.u.prefix6 = nexthop->gate.ipv6;
} }
rib_nexthop_delete (rib, nexthop); route_entry_nexthop_delete (re, nexthop);
zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn); zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn);
nexthop_free (nexthop); nexthop_free (nexthop);
} }

View File

@ -334,10 +334,10 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
static void static void
zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node) zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node)
{ {
struct rib *rib, *next; struct route_entry *re, *next;
RNODE_FOREACH_RIB_SAFE (node, rib, next) RNODE_FOREACH_RE_SAFE (node, re, next)
rib_unlink (node, rib); rib_unlink (node, re);
if (node->info) if (node->info)
XFREE (MTYPE_RIB_DEST, node->info); XFREE (MTYPE_RIB_DEST, node->info);

View File

@ -126,10 +126,24 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
VTY_NEWLINE); VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
if (mpls_str2label (label_str, &snh_label.num_labels, int rc = mpls_str2label (label_str, &snh_label.num_labels,
snh_label.label)) snh_label.label);
if (rc < 0)
{ {
vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE); switch (rc) {
case -1:
vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
break;
case -2:
vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)%s",
MPLS_MIN_RESERVED_LABEL, MPLS_MAX_RESERVED_LABEL,
VTY_NEWLINE);
break;
case -3:
vty_out (vty, "%% Too many labels. Enter %d or fewer%s",
MPLS_MAX_LABELS, VTY_NEWLINE);
break;
}
return CMD_WARNING; return CMD_WARNING;
} }
} }
@ -321,7 +335,7 @@ DEFUN (show_ip_rpf_addr,
int idx_ipv4 = 3; int idx_ipv4 = 3;
struct in_addr addr; struct in_addr addr;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
int ret; int ret;
ret = inet_aton (argv[idx_ipv4]->arg, &addr); ret = inet_aton (argv[idx_ipv4]->arg, &addr);
@ -331,9 +345,9 @@ DEFUN (show_ip_rpf_addr,
return CMD_WARNING; return CMD_WARNING;
} }
rib = rib_match_ipv4_multicast (VRF_DEFAULT, addr, &rn); re = rib_match_ipv4_multicast (VRF_DEFAULT, addr, &rn);
if (rib) if (re)
vty_show_ip_route_detail (vty, rn, 1); vty_show_ip_route_detail (vty, rn, 1);
else else
vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE); vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE);
@ -421,8 +435,7 @@ DEFUN (ip_route_flags,
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv4_prefixlen = 2; int idx_ipv4_prefixlen = 2;
int idx_reject_blackhole = 3; int idx_reject_blackhole = 3;
@ -455,8 +468,7 @@ DEFUN (ip_route_mask,
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv4 = 2; int idx_ipv4 = 2;
int idx_ipv4_2 = 3; int idx_ipv4_2 = 3;
@ -487,8 +499,7 @@ DEFUN (ip_route_mask_flags,
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv4 = 2; int idx_ipv4 = 2;
int idx_ipv4_2 = 3; int idx_ipv4_2 = 3;
@ -521,8 +532,7 @@ DEFUN (no_ip_route,
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv4_prefixlen = 3; int idx_ipv4_prefixlen = 3;
int idx_ipv4_ifname_null = 4; int idx_ipv4_ifname_null = 4;
@ -553,8 +563,7 @@ DEFUN (no_ip_route_flags,
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv4_prefixlen = 3; int idx_ipv4_prefixlen = 3;
int idx_curr = 5; int idx_curr = 5;
@ -584,8 +593,7 @@ DEFUN (no_ip_route_mask,
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv4 = 3; int idx_ipv4 = 3;
int idx_ipv4_2 = 4; int idx_ipv4_2 = 4;
@ -618,8 +626,7 @@ DEFUN (no_ip_route_mask_flags,
"Tag value\n" "Tag value\n"
"Distance value for this route\n" "Distance value for this route\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv4 = 3; int idx_ipv4 = 3;
int idx_ipv4_2 = 4; int idx_ipv4_2 = 4;
@ -640,13 +647,13 @@ DEFUN (no_ip_route_mask_flags,
static void static void
vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast) vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
{ {
struct rib *rib; struct route_entry *re;
struct nexthop *nexthop, *tnexthop; struct nexthop *nexthop, *tnexthop;
int recursing; int recursing;
char buf[SRCDEST2STR_BUFFER]; char buf[SRCDEST2STR_BUFFER];
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
const char *mcast_info = ""; const char *mcast_info = "";
if (mcast) if (mcast)
@ -660,42 +667,42 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
vty_out (vty, "Routing entry for %s%s%s", vty_out (vty, "Routing entry for %s%s%s",
srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info, srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info,
VTY_NEWLINE); VTY_NEWLINE);
vty_out (vty, " Known via \"%s", zebra_route_string (rib->type)); vty_out (vty, " Known via \"%s", zebra_route_string (re->type));
if (rib->instance) if (re->instance)
vty_out (vty, "[%d]", rib->instance); vty_out (vty, "[%d]", re->instance);
vty_out (vty, "\""); vty_out (vty, "\"");
vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric); vty_out (vty, ", distance %u, metric %u", re->distance, re->metric);
if (rib->tag) if (re->tag)
vty_out (vty, ", tag %d", rib->tag); vty_out (vty, ", tag %d", re->tag);
if (rib->mtu) if (re->mtu)
vty_out (vty, ", mtu %u", rib->mtu); vty_out (vty, ", mtu %u", re->mtu);
if (rib->vrf_id != VRF_DEFAULT) if (re->vrf_id != VRF_DEFAULT)
{ {
zvrf = vrf_info_lookup(rib->vrf_id); zvrf = vrf_info_lookup(re->vrf_id);
vty_out (vty, ", vrf %s", zvrf_name (zvrf)); vty_out (vty, ", vrf %s", zvrf_name (zvrf));
} }
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
vty_out (vty, ", best"); vty_out (vty, ", best");
if (rib->refcnt) if (re->refcnt)
vty_out (vty, ", refcnt %ld", rib->refcnt); vty_out (vty, ", refcnt %ld", re->refcnt);
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
vty_out (vty, ", blackhole"); vty_out (vty, ", blackhole");
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
vty_out (vty, ", reject"); vty_out (vty, ", reject");
vty_out (vty, "%s", VTY_NEWLINE); vty_out (vty, "%s", VTY_NEWLINE);
if (rib->type == ZEBRA_ROUTE_RIP if (re->type == ZEBRA_ROUTE_RIP
|| rib->type == ZEBRA_ROUTE_OSPF || re->type == ZEBRA_ROUTE_OSPF
|| rib->type == ZEBRA_ROUTE_ISIS || re->type == ZEBRA_ROUTE_ISIS
|| rib->type == ZEBRA_ROUTE_NHRP || re->type == ZEBRA_ROUTE_NHRP
|| rib->type == ZEBRA_ROUTE_TABLE || re->type == ZEBRA_ROUTE_TABLE
|| rib->type == ZEBRA_ROUTE_BGP) || re->type == ZEBRA_ROUTE_BGP)
{ {
time_t uptime; time_t uptime;
struct tm *tm; struct tm *tm;
uptime = time (NULL); uptime = time (NULL);
uptime -= rib->uptime; uptime -= re->uptime;
tm = gmtime (&uptime); tm = gmtime (&uptime);
vty_out (vty, " Last update "); vty_out (vty, " Last update ");
@ -713,7 +720,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
vty_out (vty, " ago%s", VTY_NEWLINE); vty_out (vty, " ago%s", VTY_NEWLINE);
} }
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
char addrstr[32]; char addrstr[32];
@ -728,7 +735,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4)); vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out (vty, ", via %s", vty_out (vty, ", via %s",
ifindex2ifname (nexthop->ifindex, rib->vrf_id)); ifindex2ifname (nexthop->ifindex, re->vrf_id));
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
@ -736,11 +743,11 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out (vty, ", via %s", vty_out (vty, ", via %s",
ifindex2ifname (nexthop->ifindex, rib->vrf_id)); ifindex2ifname (nexthop->ifindex, re->vrf_id));
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
vty_out (vty, " directly connected, %s", vty_out (vty, " directly connected, %s",
ifindex2ifname (nexthop->ifindex, rib->vrf_id)); ifindex2ifname (nexthop->ifindex, re->vrf_id));
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
vty_out (vty, " directly connected, Null0"); vty_out (vty, " directly connected, Null0");
@ -796,7 +803,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
} }
static void static void
vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib, vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *re,
json_object *json) json_object *json)
{ {
struct nexthop *nexthop, *tnexthop; struct nexthop *nexthop, *tnexthop;
@ -814,41 +821,41 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
json_nexthops = json_object_new_array(); json_nexthops = json_object_new_array();
json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf)); json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf));
json_object_string_add(json_route, "protocol", zebra_route_string(rib->type)); json_object_string_add(json_route, "protocol", zebra_route_string(re->type));
if (rib->instance) if (re->instance)
json_object_int_add(json_route, "instance", rib->instance); json_object_int_add(json_route, "instance", re->instance);
if (rib->vrf_id) if (re->vrf_id)
json_object_int_add(json_route, "vrfId", rib->vrf_id); json_object_int_add(json_route, "vrfId", re->vrf_id);
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
json_object_boolean_true_add(json_route, "selected"); json_object_boolean_true_add(json_route, "selected");
if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL) if (re->type != ZEBRA_ROUTE_CONNECT && re->type != ZEBRA_ROUTE_KERNEL)
{ {
json_object_int_add(json_route, "distance", rib->distance); json_object_int_add(json_route, "distance", re->distance);
json_object_int_add(json_route, "metric", rib->metric); json_object_int_add(json_route, "metric", re->metric);
} }
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
json_object_boolean_true_add(json_route, "blackhole"); json_object_boolean_true_add(json_route, "blackhole");
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
json_object_boolean_true_add(json_route, "reject"); json_object_boolean_true_add(json_route, "reject");
if (rib->type == ZEBRA_ROUTE_RIP if (re->type == ZEBRA_ROUTE_RIP
|| rib->type == ZEBRA_ROUTE_OSPF || re->type == ZEBRA_ROUTE_OSPF
|| rib->type == ZEBRA_ROUTE_ISIS || re->type == ZEBRA_ROUTE_ISIS
|| rib->type == ZEBRA_ROUTE_NHRP || re->type == ZEBRA_ROUTE_NHRP
|| rib->type == ZEBRA_ROUTE_TABLE || re->type == ZEBRA_ROUTE_TABLE
|| rib->type == ZEBRA_ROUTE_BGP) || re->type == ZEBRA_ROUTE_BGP)
{ {
time_t uptime; time_t uptime;
struct tm *tm; struct tm *tm;
uptime = time (NULL); uptime = time (NULL);
uptime -= rib->uptime; uptime -= re->uptime;
tm = gmtime (&uptime); tm = gmtime (&uptime);
if (uptime < ONE_DAY_SECOND) if (uptime < ONE_DAY_SECOND)
@ -861,7 +868,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
json_object_string_add(json_route, "uptime", buf); json_object_string_add(json_route, "uptime", buf);
} }
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
json_nexthop = json_object_new_object(); json_nexthop = json_object_new_object();
@ -878,7 +885,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
if (nexthop->ifindex) if (nexthop->ifindex)
{ {
json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id)); json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
} }
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
@ -889,14 +896,14 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
if (nexthop->ifindex) if (nexthop->ifindex)
{ {
json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id)); json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
} }
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
json_object_boolean_true_add(json_nexthop, "directlyConnected"); json_object_boolean_true_add(json_nexthop, "directlyConnected");
json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id)); json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
json_object_boolean_true_add(json_nexthop, "blackhole"); json_object_boolean_true_add(json_nexthop, "blackhole");
@ -955,26 +962,26 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
} }
/* Nexthop information. */ /* Nexthop information. */
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
{ {
if (nexthop == rib->nexthop) if (nexthop == re->nexthop)
{ {
/* Prefix information. */ /* Prefix information. */
len = vty_out (vty, "%c", zebra_route_char (rib->type)); len = vty_out (vty, "%c", zebra_route_char (re->type));
if (rib->instance) if (re->instance)
len += vty_out (vty, "[%d]", rib->instance); len += vty_out (vty, "[%d]", re->instance);
len += vty_out (vty, "%c%c %s", len += vty_out (vty, "%c%c %s",
CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED)
? '>' : ' ', ? '>' : ' ',
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
? '*' : ' ', ? '*' : ' ',
srcdest_rnode2str (rn, buf, sizeof buf)); srcdest_rnode2str (rn, buf, sizeof buf));
/* Distance and metric display. */ /* Distance and metric display. */
if (rib->type != ZEBRA_ROUTE_CONNECT if (re->type != ZEBRA_ROUTE_CONNECT
&& rib->type != ZEBRA_ROUTE_KERNEL) && re->type != ZEBRA_ROUTE_KERNEL)
len += vty_out (vty, " [%d/%d]", rib->distance, len += vty_out (vty, " [%d/%d]", re->distance,
rib->metric); re->metric);
} }
else else
vty_out (vty, " %c%*c", vty_out (vty, " %c%*c",
@ -989,7 +996,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4)); vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out (vty, ", %s", vty_out (vty, ", %s",
ifindex2ifname (nexthop->ifindex, rib->vrf_id)); ifindex2ifname (nexthop->ifindex, re->vrf_id));
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
@ -997,12 +1004,12 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out (vty, ", %s", vty_out (vty, ", %s",
ifindex2ifname (nexthop->ifindex, rib->vrf_id)); ifindex2ifname (nexthop->ifindex, re->vrf_id));
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
vty_out (vty, " is directly connected, %s", vty_out (vty, " is directly connected, %s",
ifindex2ifname (nexthop->ifindex, rib->vrf_id)); ifindex2ifname (nexthop->ifindex, re->vrf_id));
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
vty_out (vty, " is directly connected, Null0"); vty_out (vty, " is directly connected, Null0");
@ -1049,23 +1056,23 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
nexthop->nh_label->label, buf, BUFSIZ, 1)); nexthop->nh_label->label, buf, BUFSIZ, 1));
} }
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
vty_out (vty, ", bh"); vty_out (vty, ", bh");
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
vty_out (vty, ", rej"); vty_out (vty, ", rej");
if (rib->type == ZEBRA_ROUTE_RIP if (re->type == ZEBRA_ROUTE_RIP
|| rib->type == ZEBRA_ROUTE_OSPF || re->type == ZEBRA_ROUTE_OSPF
|| rib->type == ZEBRA_ROUTE_ISIS || re->type == ZEBRA_ROUTE_ISIS
|| rib->type == ZEBRA_ROUTE_NHRP || re->type == ZEBRA_ROUTE_NHRP
|| rib->type == ZEBRA_ROUTE_TABLE || re->type == ZEBRA_ROUTE_TABLE
|| rib->type == ZEBRA_ROUTE_BGP) || re->type == ZEBRA_ROUTE_BGP)
{ {
time_t uptime; time_t uptime;
struct tm *tm; struct tm *tm;
uptime = time (NULL); uptime = time (NULL);
uptime -= rib->uptime; uptime -= re->uptime;
tm = gmtime (&uptime); tm = gmtime (&uptime);
if (uptime < ONE_DAY_SECOND) if (uptime < ONE_DAY_SECOND)
@ -1097,7 +1104,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, afi_t afi, safi_t safi,
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
int first = 1; int first = 1;
struct zebra_vrf *zvrf = NULL; struct zebra_vrf *zvrf = NULL;
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -1137,12 +1144,12 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, afi_t afi, safi_t safi,
/* Show all routes. */ /* Show all routes. */
for (rn = route_top (table); rn; rn = route_next (rn)) for (rn = route_top (table); rn; rn = route_next (rn))
{ {
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (use_fib && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) if (use_fib && !CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
continue; continue;
if (tag && rib->tag != tag) if (tag && re->tag != tag)
continue; continue;
if (longer_prefix_p && ! prefix_match (longer_prefix_p, &rn->p)) if (longer_prefix_p && ! prefix_match (longer_prefix_p, &rn->p))
@ -1163,10 +1170,10 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, afi_t afi, safi_t safi,
continue; continue;
} }
if (type && rib->type != type) if (type && re->type != type)
continue; continue;
if (ospf_instance_id && (rib->type != ZEBRA_ROUTE_OSPF || rib->instance != ospf_instance_id)) if (ospf_instance_id && (re->type != ZEBRA_ROUTE_OSPF || re->instance != ospf_instance_id))
continue; continue;
if (use_json) if (use_json)
@ -1190,7 +1197,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, afi_t afi, safi_t safi,
} }
} }
vty_show_ip_route (vty, rn, rib, json_prefix); vty_show_ip_route (vty, rn, re, json_prefix);
} }
if (json_prefix) if (json_prefix)
@ -1569,7 +1576,7 @@ static void
vty_show_ip_route_summary (struct vty *vty, struct route_table *table) vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
{ {
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1) #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
@ -1580,25 +1587,25 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
memset (&rib_cnt, 0, sizeof(rib_cnt)); memset (&rib_cnt, 0, sizeof(rib_cnt));
memset (&fib_cnt, 0, sizeof(fib_cnt)); memset (&fib_cnt, 0, sizeof(fib_cnt));
for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
is_ibgp = (rib->type == ZEBRA_ROUTE_BGP && is_ibgp = (re->type == ZEBRA_ROUTE_BGP &&
CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)); CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP));
rib_cnt[ZEBRA_ROUTE_TOTAL]++; rib_cnt[ZEBRA_ROUTE_TOTAL]++;
if (is_ibgp) if (is_ibgp)
rib_cnt[ZEBRA_ROUTE_IBGP]++; rib_cnt[ZEBRA_ROUTE_IBGP]++;
else else
rib_cnt[rib->type]++; rib_cnt[re->type]++;
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
{ {
fib_cnt[ZEBRA_ROUTE_TOTAL]++; fib_cnt[ZEBRA_ROUTE_TOTAL]++;
if (is_ibgp) if (is_ibgp)
fib_cnt[ZEBRA_ROUTE_IBGP]++; fib_cnt[ZEBRA_ROUTE_IBGP]++;
else else
fib_cnt[rib->type]++; fib_cnt[re->type]++;
} }
} }
@ -1644,7 +1651,7 @@ static void
vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table) vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
{ {
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
struct nexthop *nexthop; struct nexthop *nexthop;
#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1) #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
@ -1656,25 +1663,25 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
memset (&rib_cnt, 0, sizeof(rib_cnt)); memset (&rib_cnt, 0, sizeof(rib_cnt));
memset (&fib_cnt, 0, sizeof(fib_cnt)); memset (&fib_cnt, 0, sizeof(fib_cnt));
for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
/* /*
* In case of ECMP, count only once. * In case of ECMP, count only once.
*/ */
cnt = 0; cnt = 0;
for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next) for (nexthop = re->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
{ {
cnt++; cnt++;
rib_cnt[ZEBRA_ROUTE_TOTAL]++; rib_cnt[ZEBRA_ROUTE_TOTAL]++;
rib_cnt[rib->type]++; rib_cnt[re->type]++;
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{ {
fib_cnt[ZEBRA_ROUTE_TOTAL]++; fib_cnt[ZEBRA_ROUTE_TOTAL]++;
fib_cnt[rib->type]++; fib_cnt[re->type]++;
} }
if (rib->type == ZEBRA_ROUTE_BGP && if (re->type == ZEBRA_ROUTE_BGP &&
CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)) CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP))
{ {
rib_cnt[ZEBRA_ROUTE_IBGP]++; rib_cnt[ZEBRA_ROUTE_IBGP]++;
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
@ -2049,10 +2056,24 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
VTY_NEWLINE); VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
if (mpls_str2label (label_str, &snh_label.num_labels, int rc = mpls_str2label (label_str, &snh_label.num_labels,
snh_label.label)) snh_label.label);
if (rc < 0)
{ {
vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE); switch (rc) {
case -1:
vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
break;
case -2:
vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)%s",
MPLS_MIN_RESERVED_LABEL, MPLS_MAX_RESERVED_LABEL,
VTY_NEWLINE);
break;
case -3:
vty_out (vty, "%% Too many labels. Enter %d or fewer%s",
MPLS_MAX_LABELS, VTY_NEWLINE);
break;
}
return CMD_WARNING; return CMD_WARNING;
} }
} }
@ -2153,13 +2174,11 @@ DEFUN (ipv6_route,
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Null interface\n" "Null interface\n"
"Null interface\n"
"Set tag for this route\n" "Set tag for this route\n"
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 2; int idx_ipv6_prefixlen = 2;
int idx_ipv6_ifname; int idx_ipv6_ifname;
@ -2207,8 +2226,7 @@ DEFUN (ipv6_route_flags,
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 2; int idx_ipv6_prefixlen = 2;
int idx_ipv6_ifname; int idx_ipv6_ifname;
@ -2257,8 +2275,7 @@ DEFUN (ipv6_route_ifname,
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 2; int idx_ipv6_prefixlen = 2;
int idx_ipv6 = 3; int idx_ipv6 = 3;
@ -2309,8 +2326,7 @@ DEFUN (ipv6_route_ifname_flags,
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 2; int idx_ipv6_prefixlen = 2;
int idx_ipv6; int idx_ipv6;
@ -2364,8 +2380,7 @@ DEFUN (no_ipv6_route,
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6_ifname; int idx_ipv6_ifname;
@ -2413,8 +2428,7 @@ DEFUN (no_ipv6_route_flags,
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6_ifname; int idx_ipv6_ifname;
@ -2464,8 +2478,7 @@ DEFUN (no_ipv6_route_ifname,
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6; int idx_ipv6;
@ -2517,8 +2530,7 @@ DEFUN (no_ipv6_route_ifname_flags,
"Tag value\n" "Tag value\n"
"Distance value for this prefix\n" "Distance value for this prefix\n"
VRF_CMD_HELP_STR VRF_CMD_HELP_STR
"Specify labels for this route\n" MPLS_LABEL_HELPSTR)
"One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6; int idx_ipv6;
@ -2820,7 +2832,7 @@ DEFUN (show_ipv6_mroute,
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
int first = 1; int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT; vrf_id_t vrf_id = VRF_DEFAULT;
@ -2833,14 +2845,14 @@ DEFUN (show_ipv6_mroute,
/* Show all IPv6 route. */ /* Show all IPv6 route. */
for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (first) if (first)
{ {
vty_out (vty, SHOW_ROUTE_V6_HEADER); vty_out (vty, SHOW_ROUTE_V6_HEADER);
first = 0; first = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, re, NULL);
} }
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -2963,7 +2975,7 @@ DEFUN (show_ipv6_mroute_vrf_all,
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct route_entry *re;
struct vrf *vrf; struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
int first = 1; int first = 1;
@ -2976,14 +2988,14 @@ DEFUN (show_ipv6_mroute_vrf_all,
/* Show all IPv6 route. */ /* Show all IPv6 route. */
for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RE (rn, re)
{ {
if (first) if (first)
{ {
vty_out (vty, SHOW_ROUTE_V6_HEADER); vty_out (vty, SHOW_ROUTE_V6_HEADER);
first = 0; first = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, re, NULL);
} }
} }
return CMD_SUCCESS; return CMD_SUCCESS;

View File

@ -192,6 +192,11 @@ zserv_encode_interface (struct stream *s, struct interface *ifp)
static void static void
zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf) zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf)
{ {
struct vrf_data data;
data.l.table_id = zvrf->table_id;
/* Pass the tableid */
stream_put (s, &data, sizeof (struct vrf_data));
/* Interface information. */ /* Interface information. */
stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ); stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ);
@ -608,7 +613,7 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
*/ */
int int
zsend_redistribute_route (int add, struct zserv *client, struct prefix *p, zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
struct prefix *src_p, struct rib *rib) struct prefix *src_p, struct route_entry *re)
{ {
afi_t afi; afi_t afi;
int cmd; int cmd;
@ -658,12 +663,12 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
stream_reset (s); stream_reset (s);
memset(&dummy_nh, 0, sizeof(struct nexthop)); memset(&dummy_nh, 0, sizeof(struct nexthop));
zserv_create_header (s, cmd, rib->vrf_id); zserv_create_header (s, cmd, re->vrf_id);
/* Put type and nexthop. */ /* Put type and nexthop. */
stream_putc (s, rib->type); stream_putc (s, re->type);
stream_putw (s, rib->instance); stream_putw (s, re->instance);
stream_putl (s, rib->flags); stream_putl (s, re->flags);
/* marker for message flags field */ /* marker for message flags field */
messmark = stream_get_endp (s); messmark = stream_get_endp (s);
@ -682,10 +687,10 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
stream_write (s, (u_char *) & src_p->u.prefix, psize); stream_write (s, (u_char *) & src_p->u.prefix, psize);
} }
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
{ {
/* We don't send any nexthops when there's a multipath */ /* We don't send any nexthops when there's a multipath */
if (rib->nexthop_active_num > 1 && client->proto != ZEBRA_ROUTE_LDP) if (re->nexthop_active_num > 1 && client->proto != ZEBRA_ROUTE_LDP)
{ {
SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
@ -764,22 +769,22 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
/* Distance */ /* Distance */
SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE); SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
stream_putc (s, rib->distance); stream_putc (s, re->distance);
/* Metric */ /* Metric */
SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
stream_putl (s, rib->metric); stream_putl (s, re->metric);
/* Tag */ /* Tag */
if (rib->tag) if (re->tag)
{ {
SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
stream_putl(s, rib->tag); stream_putl(s, re->tag);
} }
/* MTU */ /* MTU */
SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU); SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
stream_putl (s, rib->mtu); stream_putl (s, re->mtu);
/* write real message flags value */ /* write real message flags value */
stream_putc_at (s, messmark, zapi_flags); stream_putc_at (s, messmark, zapi_flags);
@ -1044,7 +1049,7 @@ zserv_fec_unregister (struct zserv *client, int sock, u_short length)
Returns both route metric and protocol distance. Returns both route metric and protocol distance.
*/ */
static int static int
zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struct rib *rib, struct zebra_vrf *zvrf) zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struct route_entry *re, struct zebra_vrf *zvrf)
{ {
struct stream *s; struct stream *s;
unsigned long nump; unsigned long nump;
@ -1059,17 +1064,17 @@ zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struc
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf)); zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf));
stream_put_in_addr (s, &addr); stream_put_in_addr (s, &addr);
if (rib) if (re)
{ {
stream_putc (s, rib->distance); stream_putc (s, re->distance);
stream_putl (s, rib->metric); stream_putl (s, re->metric);
num = 0; num = 0;
nump = stream_get_endp(s); /* remember position for nexthop_num */ nump = stream_get_endp(s); /* remember position for nexthop_num */
stream_putc (s, 0); /* reserve room for nexthop_num */ stream_putc (s, 0); /* reserve room for nexthop_num */
/* Only non-recursive routes are elegible to resolve the nexthop we /* Only non-recursive routes are elegible to resolve the nexthop we
* are looking up. Therefore, we will just iterate over the top * are looking up. Therefore, we will just iterate over the top
* chain of nexthops. */ * chain of nexthops. */
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
num += zsend_write_nexthop (s, nexthop); num += zsend_write_nexthop (s, nexthop);
@ -1169,14 +1174,14 @@ zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const unsign
/* This function support multiple nexthop. */ /* This function support multiple nexthop. */
/* /*
* Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update re and
* add kernel route. * add kernel route.
*/ */
static int static int
zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{ {
int i; int i;
struct rib *rib; struct route_entry *re;
struct prefix p; struct prefix p;
u_char message; u_char message;
struct in_addr nhop_addr; struct in_addr nhop_addr;
@ -1192,16 +1197,16 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
/* Get input stream. */ /* Get input stream. */
s = client->ibuf; s = client->ibuf;
/* Allocate new rib. */ /* Allocate new re. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
/* Type, flags, message. */ /* Type, flags, message. */
rib->type = stream_getc (s); re->type = stream_getc (s);
rib->instance = stream_getw (s); re->instance = stream_getw (s);
rib->flags = stream_getl (s); re->flags = stream_getl (s);
message = stream_getc (s); message = stream_getc (s);
safi = stream_getw (s); safi = stream_getw (s);
rib->uptime = time (NULL); re->uptime = time (NULL);
/* IPv4 prefix. */ /* IPv4 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4)); memset (&p, 0, sizeof (struct prefix_ipv4));
@ -1210,7 +1215,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */ /* VRF ID */
rib->vrf_id = zvrf_id (zvrf); re->vrf_id = zvrf_id (zvrf);
/* Nexthop parse. */ /* Nexthop parse. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
@ -1226,11 +1231,11 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{ {
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
ifindex = stream_getl (s); ifindex = stream_getl (s);
rib_nexthop_ifindex_add (rib, ifindex); route_entry_nexthop_ifindex_add (re, ifindex);
break; break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
nhop_addr.s_addr = stream_get_ipv4 (s); nhop_addr.s_addr = stream_get_ipv4 (s);
nexthop = rib_nexthop_ipv4_add (rib, &nhop_addr, NULL); nexthop = route_entry_nexthop_ipv4_add (re, &nhop_addr, NULL);
/* For labeled-unicast, each nexthop is followed by label. */ /* For labeled-unicast, each nexthop is followed by label. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
{ {
@ -1241,13 +1246,13 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
nhop_addr.s_addr = stream_get_ipv4 (s); nhop_addr.s_addr = stream_get_ipv4 (s);
ifindex = stream_getl (s); ifindex = stream_getl (s);
rib_nexthop_ipv4_ifindex_add (rib, &nhop_addr, NULL, ifindex); route_entry_nexthop_ipv4_ifindex_add (re, &nhop_addr, NULL, ifindex);
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
stream_forward_getp (s, IPV6_MAX_BYTELEN); stream_forward_getp (s, IPV6_MAX_BYTELEN);
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
rib_nexthop_blackhole_add (rib); route_entry_nexthop_blackhole_add (re);
break; break;
} }
} }
@ -1255,27 +1260,27 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
/* Distance. */ /* Distance. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
rib->distance = stream_getc (s); re->distance = stream_getc (s);
/* Metric. */ /* Metric. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
rib->metric = stream_getl (s); re->metric = stream_getl (s);
/* Tag */ /* Tag */
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
rib->tag = stream_getl (s); re->tag = stream_getl (s);
else else
rib->tag = 0; re->tag = 0;
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
rib->mtu = stream_getl (s); re->mtu = stream_getl (s);
else else
rib->mtu = 0; re->mtu = 0;
/* Table */ /* Table */
rib->table = zvrf->table_id; re->table = zvrf->table_id;
ret = rib_add_multipath (AFI_IP, safi, &p, NULL, rib); ret = rib_add_multipath (AFI_IP, safi, &p, NULL, re);
/* Stats */ /* Stats */
if (ret > 0) if (ret > 0)
@ -1384,11 +1389,11 @@ static int
zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zebra_vrf *zvrf) zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{ {
struct in_addr addr; struct in_addr addr;
struct rib *rib; struct route_entry *re;
addr.s_addr = stream_get_ipv4 (client->ibuf); addr.s_addr = stream_get_ipv4 (client->ibuf);
rib = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL); re = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL);
return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf); return zsend_ipv4_nexthop_lookup_mrib (client, addr, re, zvrf);
} }
/* Zebra server IPv6 prefix add function. */ /* Zebra server IPv6 prefix add function. */
@ -1398,7 +1403,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
unsigned int i; unsigned int i;
struct stream *s; struct stream *s;
struct in6_addr nhop_addr; struct in6_addr nhop_addr;
struct rib *rib; struct route_entry *re;
u_char message; u_char message;
u_char nexthop_num; u_char nexthop_num;
u_char nexthop_type; u_char nexthop_type;
@ -1416,16 +1421,16 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
memset (&nhop_addr, 0, sizeof (struct in6_addr)); memset (&nhop_addr, 0, sizeof (struct in6_addr));
/* Allocate new rib. */ /* Allocate new re. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
/* Type, flags, message. */ /* Type, flags, message. */
rib->type = stream_getc (s); re->type = stream_getc (s);
rib->instance = stream_getw (s); re->instance = stream_getw (s);
rib->flags = stream_getl (s); re->flags = stream_getl (s);
message = stream_getc (s); message = stream_getc (s);
safi = stream_getw (s); safi = stream_getw (s);
rib->uptime = time (NULL); re->uptime = time (NULL);
/* IPv4 prefix. */ /* IPv4 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4)); memset (&p, 0, sizeof (struct prefix_ipv4));
@ -1434,10 +1439,10 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */ /* VRF ID */
rib->vrf_id = zvrf_id (zvrf); re->vrf_id = zvrf_id (zvrf);
/* We need to give nh-addr, nh-ifindex with the same next-hop object /* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce * to the re to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of * these. Clients should send the same number of paired set of
* next-hop-addr/next-hop-ifindices. */ * next-hop-addr/next-hop-ifindices. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
@ -1474,7 +1479,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
} }
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
rib_nexthop_blackhole_add (rib); route_entry_nexthop_blackhole_add (re);
break; break;
} }
} }
@ -1484,43 +1489,43 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
{ {
if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) { if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
if ((i < if_count) && ifindices[i]) if ((i < if_count) && ifindices[i])
nexthop = rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]); nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &nexthops[i], ifindices[i]);
else else
nexthop = rib_nexthop_ipv6_add (rib, &nexthops[i]); nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]);
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]); nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]);
} }
else { else {
if ((i < if_count) && ifindices[i]) if ((i < if_count) && ifindices[i])
rib_nexthop_ifindex_add (rib, ifindices[i]); route_entry_nexthop_ifindex_add (re, ifindices[i]);
} }
} }
} }
/* Distance. */ /* Distance. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
rib->distance = stream_getc (s); re->distance = stream_getc (s);
/* Metric. */ /* Metric. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
rib->metric = stream_getl (s); re->metric = stream_getl (s);
/* Tag */ /* Tag */
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
rib->tag = stream_getl (s); re->tag = stream_getl (s);
else else
rib->tag = 0; re->tag = 0;
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
rib->mtu = stream_getl (s); re->mtu = stream_getl (s);
else else
rib->mtu = 0; re->mtu = 0;
/* Table */ /* Table */
rib->table = zvrf->table_id; re->table = zvrf->table_id;
ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, rib); ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, re);
/* Stats */ /* Stats */
if (ret > 0) if (ret > 0)
client->v4_route_add_cnt++; client->v4_route_add_cnt++;
@ -1536,7 +1541,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
unsigned int i; unsigned int i;
struct stream *s; struct stream *s;
struct in6_addr nhop_addr; struct in6_addr nhop_addr;
struct rib *rib; struct route_entry *re;
u_char message; u_char message;
u_char nexthop_num; u_char nexthop_num;
u_char nexthop_type; u_char nexthop_type;
@ -1555,16 +1560,16 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
memset (&nhop_addr, 0, sizeof (struct in6_addr)); memset (&nhop_addr, 0, sizeof (struct in6_addr));
/* Allocate new rib. */ /* Allocate new re. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
/* Type, flags, message. */ /* Type, flags, message. */
rib->type = stream_getc (s); re->type = stream_getc (s);
rib->instance = stream_getw (s); re->instance = stream_getw (s);
rib->flags = stream_getl (s); re->flags = stream_getl (s);
message = stream_getc (s); message = stream_getc (s);
safi = stream_getw (s); safi = stream_getw (s);
rib->uptime = time (NULL); re->uptime = time (NULL);
/* IPv6 prefix. */ /* IPv6 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv6)); memset (&p, 0, sizeof (struct prefix_ipv6));
@ -1584,7 +1589,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
src_pp = NULL; src_pp = NULL;
/* We need to give nh-addr, nh-ifindex with the same next-hop object /* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce * to the re to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of * these. Clients should send the same number of paired set of
* next-hop-addr/next-hop-ifindices. */ * next-hop-addr/next-hop-ifindices. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
@ -1620,7 +1625,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
} }
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
rib_nexthop_blackhole_add (rib); route_entry_nexthop_blackhole_add (re);
break; break;
} }
} }
@ -1630,43 +1635,43 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{ {
if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) { if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
if ((i < if_count) && ifindices[i]) if ((i < if_count) && ifindices[i])
nexthop = rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]); nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &nexthops[i], ifindices[i]);
else else
nexthop = rib_nexthop_ipv6_add (rib, &nexthops[i]); nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]);
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]); nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]);
} }
else { else {
if ((i < if_count) && ifindices[i]) if ((i < if_count) && ifindices[i])
rib_nexthop_ifindex_add (rib, ifindices[i]); route_entry_nexthop_ifindex_add (re, ifindices[i]);
} }
} }
} }
/* Distance. */ /* Distance. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
rib->distance = stream_getc (s); re->distance = stream_getc (s);
/* Metric. */ /* Metric. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
rib->metric = stream_getl (s); re->metric = stream_getl (s);
/* Tag */ /* Tag */
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
rib->tag = stream_getl (s); re->tag = stream_getl (s);
else else
rib->tag = 0; re->tag = 0;
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
rib->mtu = stream_getl (s); re->mtu = stream_getl (s);
else else
rib->mtu = 0; re->mtu = 0;
/* VRF ID */ /* VRF ID */
rib->vrf_id = zvrf_id (zvrf); re->vrf_id = zvrf_id (zvrf);
rib->table = zvrf->table_id; re->table = zvrf->table_id;
ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, rib); ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, re);
/* Stats */ /* Stats */
if (ret > 0) if (ret > 0)
client->v6_route_add_cnt++; client->v6_route_add_cnt++;
@ -2391,10 +2396,14 @@ zebra_client_read (struct thread *thread)
zebra_ptm_bfd_client_register(client, sock, length); zebra_ptm_bfd_client_register(client, sock, length);
break; break;
case ZEBRA_INTERFACE_ENABLE_RADV: case ZEBRA_INTERFACE_ENABLE_RADV:
#if defined (HAVE_RTADV)
zebra_interface_radv_set (client, sock, length, zvrf, 1); zebra_interface_radv_set (client, sock, length, zvrf, 1);
#endif
break; break;
case ZEBRA_INTERFACE_DISABLE_RADV: case ZEBRA_INTERFACE_DISABLE_RADV:
#if defined (HAVE_RTADV)
zebra_interface_radv_set (client, sock, length, zvrf, 0); zebra_interface_radv_set (client, sock, length, zvrf, 0);
#endif
break; break;
case ZEBRA_MPLS_LABELS_ADD: case ZEBRA_MPLS_LABELS_ADD:
case ZEBRA_MPLS_LABELS_DELETE: case ZEBRA_MPLS_LABELS_DELETE:

View File

@ -162,7 +162,7 @@ extern void nbr_connected_add_ipv6 (struct interface *, struct in6_addr *);
extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *); extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *);
extern int zsend_interface_update (int, struct zserv *, struct interface *); extern int zsend_interface_update (int, struct zserv *, struct interface *);
extern int zsend_redistribute_route (int, struct zserv *, struct prefix *, extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
struct prefix *, struct rib *); struct prefix *, struct route_entry *);
extern int zsend_router_id_update (struct zserv *, struct prefix *, extern int zsend_router_id_update (struct zserv *, struct prefix *,
vrf_id_t); vrf_id_t);
extern int zsend_interface_vrf_update (struct zserv *, struct interface *, extern int zsend_interface_vrf_update (struct zserv *, struct interface *,