mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 18:44:54 +00:00
Merge remote-tracking branch 'frr/master' into pull-624
This commit is contained in:
commit
97bd5c48de
1
.gitignore
vendored
1
.gitignore
vendored
@ -74,3 +74,4 @@ GRTAGS
|
||||
GPATH
|
||||
*.la
|
||||
*.lo
|
||||
compile_commands.json
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include "bgpd/bgp_updgrp.h"
|
||||
#include "bgpd/bgp_mplsvpn.h"
|
||||
|
||||
#define BGP_ADDPATH_STR 20
|
||||
|
||||
unsigned long conf_bgp_debug_as4;
|
||||
unsigned long conf_bgp_debug_neighbor_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 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)
|
||||
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. */
|
||||
pathid_buf[0] = '\0';
|
||||
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)
|
||||
snprintf (str, size, "RD %s %s%s",
|
||||
|
@ -1455,7 +1455,7 @@ subgroup_announce_check (struct bgp_node *rn, struct bgp_info *ri,
|
||||
|
||||
#define NEXTHOP_IS_V6 (\
|
||||
(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) &&\
|
||||
attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
|
||||
|
||||
@ -5017,7 +5017,7 @@ DEFUN (bgp_network_mask_natural_backdoor,
|
||||
|
||||
DEFUN (bgp_network_label_index,
|
||||
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"
|
||||
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\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,
|
||||
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"
|
||||
"IP prefix\n"
|
||||
"Label index to associate with the prefix\n"
|
||||
@ -5117,7 +5117,7 @@ DEFUN (no_bgp_network_mask_natural,
|
||||
|
||||
ALIAS (no_bgp_network,
|
||||
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
|
||||
"Specify a network to announce via BGP\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,
|
||||
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
|
||||
"Specify a network to announce via BGP\n"
|
||||
"IP prefix\n"
|
||||
@ -5164,7 +5164,7 @@ DEFUN (ipv6_bgp_network_route_map,
|
||||
|
||||
DEFUN (ipv6_bgp_network_label_index,
|
||||
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"
|
||||
"IPv6 prefix <network>/<length>\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,
|
||||
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"
|
||||
"IPv6 prefix\n"
|
||||
"Label index to associate with the prefix\n"
|
||||
@ -5209,7 +5209,7 @@ DEFUN (no_ipv6_bgp_network,
|
||||
|
||||
ALIAS (no_ipv6_bgp_network,
|
||||
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
|
||||
"Specify a network to announce via BGP\n"
|
||||
"IPv6 prefix <network>/<length>\n"
|
||||
@ -5218,7 +5218,7 @@ ALIAS (no_ipv6_bgp_network,
|
||||
|
||||
ALIAS (no_ipv6_bgp_network,
|
||||
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
|
||||
"Specify a network to announce via BGP\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, &no_bgp_table_map_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_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd);
|
||||
install_element (BGP_IPV6_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, &ipv6_bgp_network_label_index_cmd);
|
||||
install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_label_index_cmd);
|
||||
install_element (BGP_IPV6L_NODE, &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, &no_ipv6_aggregate_address_cmd);
|
||||
|
@ -2207,6 +2207,41 @@ static struct route_map_rule_cmd route_set_tag_cmd =
|
||||
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' */
|
||||
|
||||
@ -3654,6 +3689,33 @@ DEFUN (no_set_weight,
|
||||
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,
|
||||
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_local_pref_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_aspath_prepend_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_soo_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_local_cmd);
|
||||
@ -4594,7 +4658,9 @@ bgp_route_map_init (void)
|
||||
install_element (RMAP_NODE, &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_label_index_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_lastas_cmd);
|
||||
install_element (RMAP_NODE, &set_aspath_exclude_cmd);
|
||||
|
@ -1169,8 +1169,8 @@ update_subgroup_trigger_merge_check (struct update_subgroup *subgrp,
|
||||
return 0;
|
||||
|
||||
subgrp->t_merge_check = NULL;
|
||||
thread_add_background(bm->master, update_subgroup_merge_check_thread_cb, subgrp, 0,
|
||||
&subgrp->t_merge_check);
|
||||
thread_add_timer_msec (bm->master, update_subgroup_merge_check_thread_cb, subgrp,
|
||||
0, &subgrp->t_merge_check);
|
||||
|
||||
SUBGRP_INCR_STAT (subgrp, merge_checks_triggered);
|
||||
|
||||
|
@ -651,17 +651,6 @@ subgroup_packets_to_build (struct update_subgroup *subgrp)
|
||||
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. */
|
||||
struct bpacket *
|
||||
subgroup_update_packet (struct update_subgroup *subgrp)
|
||||
@ -1079,11 +1068,21 @@ subgroup_default_update_packet (struct update_subgroup *subgrp,
|
||||
{
|
||||
char attrstr[BUFSIZ];
|
||||
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];
|
||||
|
||||
attrstr[0] = '\0';
|
||||
|
||||
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",
|
||||
(SUBGRP_UPDGRP (subgrp))->id, subgrp->id,
|
||||
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))
|
||||
{
|
||||
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",
|
||||
(SUBGRP_UPDGRP (subgrp))->id, subgrp->id,
|
||||
prefix2str (&p, buf, sizeof (buf)), tx_id_buf);
|
||||
|
@ -12244,6 +12244,7 @@ lcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
argv_find (argv, argc, "AA:BB:CC", &idx);
|
||||
argv_find (argv, argc, "LINE", &idx);
|
||||
/* Concat community string argument. */
|
||||
|
@ -3385,7 +3385,7 @@ DEFUN (vnc_vrf_policy_nexthop,
|
||||
"Specify next hop to use for VRF advertised prefixes\n"
|
||||
"IPv4 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);
|
||||
struct prefix p;
|
||||
|
@ -3051,7 +3051,7 @@ rfapiBiStartWithdrawTimer (
|
||||
lifetime_msec = (lifetime * 1000) + jitter;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
11
configure.ac
11
configure.ac
@ -314,8 +314,6 @@ AC_ARG_ENABLE(fpm,
|
||||
AS_HELP_STRING([--enable-fpm], [enable Forwarding Plane Manager support]))
|
||||
AC_ARG_ENABLE(systemd,
|
||||
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,
|
||||
AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)]))
|
||||
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)
|
||||
fi
|
||||
|
||||
if test "${enable_poll}" = "yes" ; then
|
||||
AC_DEFINE(HAVE_POLL_CALL,,Compile systemd support in)
|
||||
fi
|
||||
|
||||
dnl ----------
|
||||
dnl MPLS check
|
||||
dnl ----------
|
||||
@ -1427,8 +1421,9 @@ dnl ---------------------------
|
||||
dnl check system has PCRE regexp
|
||||
dnl ---------------------------
|
||||
if test "x$enable_pcreposix" = "xyes"; then
|
||||
AC_CHECK_LIB(pcreposix, pcreposix_regexec, ,[enable_pcreposix=no
|
||||
AC_MSG_WARN([*** falling back to other regex library ***]) ])
|
||||
AC_CHECK_LIB(pcreposix, regexec, [], [
|
||||
AC_MSG_ERROR([--enable-pcreposix given but unable to find libpcreposix])
|
||||
])
|
||||
fi
|
||||
AC_SUBST(HAVE_LIBPCREPOSIX)
|
||||
|
||||
|
@ -13,7 +13,7 @@ Add packages:
|
||||
|
||||
apt-get install git autoconf automake libtool make gawk libreadline-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
|
||||
is too old)
|
||||
@ -51,6 +51,11 @@ Install newer version of autoconf and automake:
|
||||
sudo make install
|
||||
cd ..
|
||||
|
||||
Install XML::LibXML
|
||||
|
||||
sudo cpan
|
||||
install XML::LibXML
|
||||
|
||||
Install pytest:
|
||||
|
||||
pip install pytest
|
||||
|
@ -252,7 +252,7 @@ rnh table:
|
||||
struct rnh
|
||||
{
|
||||
u_char flags;
|
||||
struct rib *state;
|
||||
struct route_entry *state;
|
||||
struct list *client_list;
|
||||
struct route_node *node;
|
||||
};
|
||||
|
@ -437,7 +437,6 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
|
||||
struct lde_req *lre;
|
||||
struct lde_map *me;
|
||||
struct l2vpn_pw *pw;
|
||||
int msgsource = 0;
|
||||
|
||||
lde_map2fec(map, ln->id, &fec);
|
||||
|
||||
@ -538,18 +537,12 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
msgsource = 1;
|
||||
}
|
||||
/* LMp.13 & LMp.16: Record the mapping from this peer */
|
||||
if (me == NULL)
|
||||
me = lde_map_add(ln, fn, 0);
|
||||
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
|
||||
* loop detection. LMp.28 - LMp.30 are unnecessary because we are
|
||||
|
@ -431,7 +431,7 @@ ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[])
|
||||
vty_conf->flags |= F_LDPD_ENABLED;
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -458,7 +458,7 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
|
||||
|
||||
if (disable) {
|
||||
af_conf->flags &= ~F_LDPD_AF_ENABLED;
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
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;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -530,7 +530,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
break;
|
||||
case LDP_IPV4_NODE:
|
||||
case LDP_IPV6_NODE:
|
||||
@ -556,7 +556,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
break;
|
||||
case LDP_IPV4_IFACE_NODE:
|
||||
case LDP_IPV6_IFACE_NODE:
|
||||
@ -570,7 +570,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
ia->hello_holdtime = secs;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
break;
|
||||
default:
|
||||
fatalx("ldp_vty_disc_holdtime: unexpected node");
|
||||
@ -631,7 +631,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
break;
|
||||
case LDP_IPV4_NODE:
|
||||
case LDP_IPV6_NODE:
|
||||
@ -657,7 +657,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
break;
|
||||
case LDP_IPV4_IFACE_NODE:
|
||||
case LDP_IPV6_IFACE_NODE:
|
||||
@ -671,7 +671,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
ia->hello_interval = secs;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
break;
|
||||
default:
|
||||
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';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -758,7 +758,7 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
|
||||
nbrp->flags |= F_NBRP_KEEPALIVE;
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -790,7 +790,7 @@ ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
af_conf->keepalive = secs;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -836,7 +836,7 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
|
||||
ia->hello_holdtime = 0;
|
||||
ia->hello_interval = 0;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
QOBJ_REG(iface, iface);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
} else {
|
||||
ia = iface_af_get(iface, af);
|
||||
if (!ia->enabled) {
|
||||
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);
|
||||
}
|
||||
@ -940,7 +940,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
|
||||
RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
|
||||
free(tnbr);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
QOBJ_REG(tnbr, tnbr);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1111,7 +1111,7 @@ ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
af_conf->flags |= F_LDPD_AF_NO_GTSM;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1152,7 +1152,7 @@ ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1169,7 +1169,7 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
vty_conf->trans_pref = DUAL_STACK_LDPOV4;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1220,7 +1220,7 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
|
||||
nbrp->auth.method = AUTH_MD5SIG;
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1280,7 +1280,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
|
||||
nbrp->gtsm_enabled = 0;
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
l2vpn_del(l2vpn);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1330,7 +1330,7 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
|
||||
|
||||
VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1350,7 +1350,7 @@ ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname));
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1378,7 +1378,7 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
l2vpn->mtu = mtu;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1404,7 +1404,7 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
l2vpn->pw_type = pw_type;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
free(lif);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
QOBJ_REG(lif, l2vpn_if);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
free(pw);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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);
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1582,7 +1582,7 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
pw->lsr_id = lsr_id;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1610,7 +1610,7 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
pw->pwid = pwid;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
@ -1628,7 +1628,7 @@ ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
|
||||
else
|
||||
pw->flags &= ~F_PW_STATUSTLV_CONF;
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
ldp_config_apply(vty, vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
|
63
ldpd/ldpd.c
63
ldpd/ldpd.c
@ -53,6 +53,7 @@ static void main_imsg_send_net_sockets(int);
|
||||
static void main_imsg_send_net_socket(int, enum socket_type);
|
||||
static int main_imsg_send_config(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_af(struct ldpd_conf *, int);
|
||||
static void ldp_config_reset_l2vpns(struct ldpd_conf *);
|
||||
@ -131,20 +132,13 @@ sighup(void)
|
||||
{
|
||||
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()
|
||||
* will be the least disruptive as possible.
|
||||
* Do a full configuration reload. In other words, reset vty_conf
|
||||
* 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. */
|
||||
@ -324,22 +318,22 @@ main(int argc, char *argv[])
|
||||
ldp_vty_init();
|
||||
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
|
||||
* configuration requests (e.g. CLI) act on vty_conf and then call
|
||||
* ldp_reload() to merge the changes into ldpd_conf.
|
||||
* Create base configuration with sane defaults. All configuration
|
||||
* requests (e.g. CLI) act on vty_conf and then call ldp_config_apply()
|
||||
* to merge the changes into ldpd_conf, which contains the actual
|
||||
* running configuration.
|
||||
*/
|
||||
ldpd_conf = config_new_empty();
|
||||
vty_conf = config_new_empty();
|
||||
ldp_config_reset_main(vty_conf);
|
||||
QOBJ_REG(vty_conf, ldpd_conf);
|
||||
|
||||
/* read configuration file and daemonize */
|
||||
frr_config_fork();
|
||||
|
||||
/* apply configuration */
|
||||
ldp_config_apply(NULL, vty_conf);
|
||||
|
||||
/* setup pipes to children */
|
||||
if ((iev_ldpe = 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);
|
||||
|
||||
ldp_config_reset_main(vty_conf);
|
||||
ldp_config_reset_l2vpns(vty_conf);
|
||||
ldp_config_reset(vty_conf);
|
||||
QOBJ_UNREG(vty_conf);
|
||||
free(vty_conf);
|
||||
|
||||
@ -952,9 +945,15 @@ main_imsg_send_config(struct ldpd_conf *xconf)
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (ldpd_process == PROC_LDE_ENGINE &&
|
||||
!reset_nbr && reinstall_pwfec)
|
||||
if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec)
|
||||
l2vpn_pw_exit(pw);
|
||||
pw->lsr_id = xp->lsr_id;
|
||||
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;
|
||||
if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr)
|
||||
ldpe_l2vpn_pw_init(pw);
|
||||
if (ldpd_process == PROC_LDE_ENGINE &&
|
||||
!reset_nbr && reinstall_pwfec) {
|
||||
if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec) {
|
||||
l2vpn->pw_type = xl->pw_type;
|
||||
l2vpn->mtu = xl->mtu;
|
||||
l2vpn_pw_init(pw);
|
||||
@ -1762,6 +1766,9 @@ config_new_empty(void)
|
||||
RB_INIT(&xconf->nbrp_tree);
|
||||
RB_INIT(&xconf->l2vpn_tree);
|
||||
|
||||
/* set default values */
|
||||
ldp_config_reset(xconf);
|
||||
|
||||
return (xconf);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "qobj.h"
|
||||
#include "prefix.h"
|
||||
#include "filter.h"
|
||||
#include "vty.h"
|
||||
|
||||
#include "ldp.h"
|
||||
|
||||
@ -516,7 +517,6 @@ struct ldpd_af_global {
|
||||
|
||||
struct ldpd_global {
|
||||
int cmd_opts;
|
||||
int sighup;
|
||||
struct in_addr rtr_id;
|
||||
struct ldpd_af_global ipv4;
|
||||
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);
|
||||
int ldp_is_dual_stack(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 merge_config(struct ldpd_conf *, struct ldpd_conf *);
|
||||
struct ldpd_conf *config_new_empty(void);
|
||||
|
@ -2613,5 +2613,6 @@ cmd_terminate ()
|
||||
if (host.config)
|
||||
XFREE (MTYPE_HOST, host.config);
|
||||
|
||||
list_delete (varhandlers);
|
||||
qobj_finish ();
|
||||
}
|
||||
|
@ -39,7 +39,10 @@
|
||||
#
|
||||
# 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
|
||||
ZEBRA_ROUTE_SYSTEM, system, NULL, 'X', 0, 0, "Reserved"
|
||||
ZEBRA_ROUTE_KERNEL, kernel, zebra, 'K', 1, 1, "kernel route"
|
||||
|
418
lib/thread.c
418
lib/thread.c
@ -30,6 +30,7 @@
|
||||
#include "pqueue.h"
|
||||
#include "command.h"
|
||||
#include "sigevent.h"
|
||||
#include "network.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread")
|
||||
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>
|
||||
#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 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->cpu.total/a->total_calls, a->cpu.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_WRITE) ? 'W':' ',
|
||||
a->types & (1 << THREAD_TIMER) ? 'T':' ',
|
||||
a->types & (1 << THREAD_EVENT) ? 'E':' ',
|
||||
a->types & (1 << THREAD_EXECUTE) ? 'X':' ',
|
||||
a->types & (1 << THREAD_BACKGROUND) ? 'B' : ' ',
|
||||
a->funcname, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
@ -188,10 +194,6 @@ DEFUN (show_thread_cpu,
|
||||
case 'X':
|
||||
filter |= (1 << THREAD_EXECUTE);
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
filter |= (1 << THREAD_BACKGROUND);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -280,10 +282,6 @@ DEFUN (clear_thread_cpu,
|
||||
case 'X':
|
||||
filter |= (1 << THREAD_EXECUTE);
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
filter |= (1 << THREAD_BACKGROUND);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -372,19 +370,22 @@ thread_master_create (void)
|
||||
|
||||
/* Initialize the timer queues */
|
||||
rv->timer = pqueue_create();
|
||||
rv->background = pqueue_create();
|
||||
rv->timer->cmp = rv->background->cmp = thread_timer_cmp;
|
||||
rv->timer->update = rv->background->update = thread_timer_update;
|
||||
rv->timer->cmp = thread_timer_cmp;
|
||||
rv->timer->update = thread_timer_update;
|
||||
rv->spin = true;
|
||||
rv->handle_signals = true;
|
||||
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.pfdcount = 0;
|
||||
rv->handler.pfds = XCALLOC (MTYPE_THREAD_MASTER,
|
||||
sizeof (struct pollfd) * rv->handler.pfdsize);
|
||||
#endif
|
||||
rv->handler.copy = XCALLOC (MTYPE_THREAD_MASTER,
|
||||
sizeof (struct pollfd) * rv->handler.pfdsize);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -419,18 +420,6 @@ thread_list_delete (struct thread_list *list, struct thread *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. */
|
||||
static int
|
||||
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->ready);
|
||||
thread_list_free (m, &m->unuse);
|
||||
thread_queue_free (m, m->background);
|
||||
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);
|
||||
#endif
|
||||
XFREE (MTYPE_THREAD_MASTER, m->handler.copy);
|
||||
XFREE (MTYPE_THREAD_MASTER, m);
|
||||
|
||||
pthread_mutex_lock (&cpu_record_mtx);
|
||||
@ -646,77 +635,21 @@ thread_get (struct thread_master *m, u_char type,
|
||||
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
|
||||
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 either select() or poll() should
|
||||
* block indefinitely, unless the thread_master has overriden it. select()
|
||||
* and poll() differ in the timeout values they interpret as an indefinite
|
||||
* block; select() requires a null pointer, while poll takes a millisecond
|
||||
* 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)
|
||||
/* If timer_wait is null here, that means poll() should block indefinitely,
|
||||
* unless the thread_master has overriden it 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. */
|
||||
int timeout = -1;
|
||||
|
||||
/* number of file descriptors with events */
|
||||
int num;
|
||||
|
||||
if (timer_wait != NULL && m->selectpoll_timeout == 0) // use the default value
|
||||
timeout = (timer_wait->tv_sec*1000) + (timer_wait->tv_usec/1000);
|
||||
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)
|
||||
timeout = 0;
|
||||
|
||||
num = poll (m->handler.pfds, m->handler.pfdcount + m->handler.pfdcountsnmp, timeout);
|
||||
#else
|
||||
struct timeval timeout;
|
||||
/* add poll pipe poker */
|
||||
assert (count + 1 < pfdsize);
|
||||
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
|
||||
{
|
||||
timeout.tv_sec = m->selectpoll_timeout / 1000;
|
||||
timeout.tv_usec = (m->selectpoll_timeout % 1000) * 1000;
|
||||
timer_wait = &timeout;
|
||||
}
|
||||
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
|
||||
num = poll (pfds, count + 1, timeout);
|
||||
|
||||
static unsigned char trash[64];
|
||||
if (num > 0 && pfds[count].revents != 0 && num--)
|
||||
while (read (m->io_pipe[0], &trash, sizeof (trash)) > 0);
|
||||
|
||||
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. */
|
||||
struct thread *
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined (HAVE_POLL_CALL)
|
||||
thread = generic_thread_add(m, func, arg, fd, dir, debugargpass);
|
||||
#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;
|
||||
/* default to a new pollfd */
|
||||
nfds_t queuepos = m->handler.pfdcount;
|
||||
|
||||
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++)
|
||||
if (m->handler.pfds[i].fd == fd)
|
||||
{
|
||||
zlog_warn ("There is already %s fd [%d]",
|
||||
(dir == THREAD_READ) ? "read" : "write", fd);
|
||||
queuepos = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
FD_SET (fd, fdset);
|
||||
|
||||
/* make sure we have room for this fd + pipe poker fd */
|
||||
assert (queuepos + 1 < m->handler.pfdsize);
|
||||
|
||||
thread = thread_get (m, dir, func, arg, debugargpass);
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
@ -825,9 +716,9 @@ funcname_thread_add_read_write (int dir, struct thread_master *m,
|
||||
{
|
||||
thread->u.fd = fd;
|
||||
if (dir == THREAD_READ)
|
||||
thread_add_fd (m->read, thread);
|
||||
m->read[thread->u.fd] = thread;
|
||||
else
|
||||
thread_add_fd (m->write, thread);
|
||||
m->write[thread->u.fd] = thread;
|
||||
}
|
||||
pthread_mutex_unlock (&thread->mtx);
|
||||
|
||||
@ -837,6 +728,8 @@ funcname_thread_add_read_write (int dir, struct thread_master *m,
|
||||
thread->ref = t_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
AWAKEN (m);
|
||||
}
|
||||
pthread_mutex_unlock (&m->mtx);
|
||||
|
||||
@ -853,7 +746,7 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
|
||||
|
||||
assert (m != NULL);
|
||||
|
||||
assert (type == THREAD_TIMER || type == THREAD_BACKGROUND);
|
||||
assert (type == THREAD_TIMER);
|
||||
assert (time_relative);
|
||||
|
||||
pthread_mutex_lock (&m->mtx);
|
||||
@ -864,7 +757,7 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
queue = ((type == THREAD_TIMER) ? m->timer : m->background);
|
||||
queue = m->timer;
|
||||
thread = thread_get (m, type, func, arg, debugargpass);
|
||||
|
||||
pthread_mutex_lock (&thread->mtx);
|
||||
@ -879,6 +772,8 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock (&thread->mtx);
|
||||
|
||||
AWAKEN (m);
|
||||
}
|
||||
pthread_mutex_unlock (&m->mtx);
|
||||
|
||||
@ -930,31 +825,6 @@ funcname_thread_add_timer_tv (struct thread_master *m,
|
||||
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. */
|
||||
struct thread *
|
||||
funcname_thread_add_event (struct thread_master *m,
|
||||
@ -986,6 +856,8 @@ funcname_thread_add_event (struct thread_master *m,
|
||||
*t_ptr = thread;
|
||||
thread->ref = t_ptr;
|
||||
}
|
||||
|
||||
AWAKEN (m);
|
||||
}
|
||||
pthread_mutex_unlock (&m->mtx);
|
||||
|
||||
@ -995,10 +867,7 @@ funcname_thread_add_event (struct thread_master *m,
|
||||
static void
|
||||
thread_cancel_read_or_write (struct thread *thread, short int state)
|
||||
{
|
||||
#if defined(HAVE_POLL_CALL)
|
||||
nfds_t i;
|
||||
|
||||
for (i=0;i<thread->master->handler.pfdcount;++i)
|
||||
for (nfds_t i = 0; i < thread->master->handler.pfdcount; ++i)
|
||||
if (thread->master->handler.pfds[i].fd == thread->u.fd)
|
||||
{
|
||||
thread->master->handler.pfds[i].events &= ~(state);
|
||||
@ -1013,9 +882,6 @@ thread_cancel_read_or_write (struct thread *thread, short int state)
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fd_clear_read_write (thread);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1039,19 +905,11 @@ thread_cancel (struct thread *thread)
|
||||
switch (thread->type)
|
||||
{
|
||||
case THREAD_READ:
|
||||
#if defined (HAVE_POLL_CALL)
|
||||
thread_cancel_read_or_write (thread, POLLIN | POLLHUP);
|
||||
#else
|
||||
thread_cancel_read_or_write (thread, 0);
|
||||
#endif
|
||||
thread_array = thread->master->read;
|
||||
break;
|
||||
case THREAD_WRITE:
|
||||
#if defined (HAVE_POLL_CALL)
|
||||
thread_cancel_read_or_write (thread, POLLOUT | POLLHUP);
|
||||
#else
|
||||
thread_cancel_read_or_write (thread, 0);
|
||||
#endif
|
||||
thread_array = thread->master->write;
|
||||
break;
|
||||
case THREAD_TIMER:
|
||||
@ -1063,9 +921,6 @@ thread_cancel (struct thread *thread)
|
||||
case THREAD_READY:
|
||||
list = &thread->master->ready;
|
||||
break;
|
||||
case THREAD_BACKGROUND:
|
||||
queue = thread->master->background;
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
break;
|
||||
@ -1082,7 +937,7 @@ thread_cancel (struct thread *thread)
|
||||
}
|
||||
else if (thread_array)
|
||||
{
|
||||
thread_delete_fd (thread_array, thread);
|
||||
thread_array[thread->u.fd] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1176,7 +1031,8 @@ thread_run (struct thread_master *m, struct thread *thread,
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -1188,76 +1044,60 @@ thread_process_fds_helper (struct thread_master *m, struct thread *thread, threa
|
||||
else
|
||||
thread_array = m->write;
|
||||
|
||||
if (fd_is_set (thread, fdset, pos))
|
||||
{
|
||||
fd_clear_read_write (thread);
|
||||
thread_delete_fd (thread_array, thread);
|
||||
thread_array[thread->u.fd] = NULL;
|
||||
thread_list_add (&m->ready, thread);
|
||||
thread->type = THREAD_READY;
|
||||
#if defined(HAVE_POLL_CALL)
|
||||
/* if another pthread scheduled this file descriptor for the event we're
|
||||
* responding to, no problem; we're getting to it now */
|
||||
thread->master->handler.pfds[pos].events &= ~(state);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(HAVE_POLL_CALL)
|
||||
|
||||
/* check poll events */
|
||||
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;
|
||||
int ready = 0;
|
||||
for (i = 0; i < m->handler.pfdcount && ready < num ; ++i)
|
||||
unsigned int ready = 0;
|
||||
|
||||
for (nfds_t i = 0; i < count && ready < num ; ++i)
|
||||
{
|
||||
/* no event for current fd? immideatly continue */
|
||||
if(m->handler.pfds[i].revents == 0)
|
||||
/* no event for current fd? immediately continue */
|
||||
if (pfds[i].revents == 0)
|
||||
continue;
|
||||
|
||||
ready++;
|
||||
|
||||
/* POLLIN / POLLOUT process event */
|
||||
if (m->handler.pfds[i].revents & (POLLIN | POLLHUP))
|
||||
thread_process_fds_helper(m, m->read[m->handler.pfds[i].fd], NULL, POLLIN, i);
|
||||
if (m->handler.pfds[i].revents & POLLOUT)
|
||||
thread_process_fds_helper(m, m->write[m->handler.pfds[i].fd], NULL, POLLOUT, i);
|
||||
/* Unless someone has called thread_cancel from another pthread, the only
|
||||
* thing that could have changed in m->handler.pfds while we were
|
||||
* asleep is the .events field in a given pollfd. Barring thread_cancel()
|
||||
* that value should be a superset of the values we have in our copy, so
|
||||
* 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 (m->handler.pfds[i].revents & POLLNVAL)
|
||||
/* if one of our file descriptors is garbage, remove the same from
|
||||
* both pfds + update sizes and index */
|
||||
if (pfds[i].revents & POLLNVAL)
|
||||
{
|
||||
memmove(m->handler.pfds+i,
|
||||
m->handler.pfds+i+1,
|
||||
(m->handler.pfdsize-i-1) * sizeof(struct pollfd));
|
||||
memmove (m->handler.pfds + i,
|
||||
m->handler.pfds + i + 1,
|
||||
(m->handler.pfdcount - i - 1) * sizeof(struct pollfd));
|
||||
m->handler.pfdcount--;
|
||||
|
||||
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. */
|
||||
static unsigned int
|
||||
thread_timer_process (struct pqueue *queue, struct timeval *timenow)
|
||||
thread_process_timers (struct pqueue *queue, struct timeval *timenow)
|
||||
{
|
||||
struct thread *thread;
|
||||
unsigned int ready = 0;
|
||||
@ -1300,14 +1140,9 @@ struct thread *
|
||||
thread_fetch (struct thread_master *m, struct thread *fetch)
|
||||
{
|
||||
struct thread *thread;
|
||||
thread_fd_set readfd;
|
||||
thread_fd_set writefd;
|
||||
thread_fd_set exceptfd;
|
||||
struct timeval now;
|
||||
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_bg;
|
||||
|
||||
do
|
||||
{
|
||||
@ -1338,22 +1173,10 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
|
||||
/* Normal event are the next highest priority. */
|
||||
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 */
|
||||
if (m->ready.count == 0)
|
||||
{
|
||||
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)
|
||||
@ -1362,7 +1185,14 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
|
||||
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 */
|
||||
if (num < 0)
|
||||
@ -1372,38 +1202,20 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
|
||||
pthread_mutex_unlock (&m->mtx);
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check foreground timers. Historically, they have had higher
|
||||
priority than I/O threads, so let's push them onto the ready
|
||||
list in front of the I/O threads. */
|
||||
* priority than I/O threads, so let's push them onto the ready
|
||||
* list in front of the I/O threads. */
|
||||
monotime(&now);
|
||||
thread_timer_process (m->timer, &now);
|
||||
thread_process_timers (m->timer, &now);
|
||||
|
||||
/* Got IO, process it */
|
||||
if (num > 0)
|
||||
thread_process_fds (m, &readfd, &writefd, num);
|
||||
|
||||
#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);
|
||||
thread_process_io (m, m->handler.copy, num, count);
|
||||
|
||||
if ((thread = thread_trim_head (&m->ready)) != NULL)
|
||||
{
|
||||
|
35
lib/thread.h
35
lib/thread.h
@ -22,8 +22,9 @@
|
||||
#define _ZEBRA_THREAD_H
|
||||
|
||||
#include <zebra.h>
|
||||
#include "monotime.h"
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
#include "monotime.h"
|
||||
|
||||
struct rusage_t
|
||||
{
|
||||
@ -44,14 +45,6 @@ struct thread_list
|
||||
|
||||
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
|
||||
{
|
||||
/* number of pfd stored in pfds */
|
||||
@ -60,16 +53,11 @@ struct fd_handler
|
||||
nfds_t pfdcountsnmp;
|
||||
/* number of pfd that fit in the allocated space of pfds */
|
||||
nfds_t pfdsize;
|
||||
/* file descriptors to monitor for i/o */
|
||||
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. */
|
||||
struct thread_master
|
||||
@ -80,7 +68,7 @@ struct thread_master
|
||||
struct thread_list event;
|
||||
struct thread_list ready;
|
||||
struct thread_list unuse;
|
||||
struct pqueue *background;
|
||||
int io_pipe[2];
|
||||
int fd_limit;
|
||||
struct fd_handler handler;
|
||||
unsigned long alloc;
|
||||
@ -142,9 +130,8 @@ struct cpu_thread_history
|
||||
#define THREAD_TIMER 2
|
||||
#define THREAD_EVENT 3
|
||||
#define THREAD_READY 4
|
||||
#define THREAD_BACKGROUND 5
|
||||
#define THREAD_UNUSED 6
|
||||
#define THREAD_EXECUTE 7
|
||||
#define THREAD_UNUSED 5
|
||||
#define THREAD_EXECUTE 6
|
||||
|
||||
/* Thread yield time. */
|
||||
#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_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. */
|
||||
extern struct thread_master *thread_master_create (void);
|
||||
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 *,
|
||||
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 *,
|
||||
int (*)(struct thread *), void *, int, debugargdef);
|
||||
#undef debugargdef
|
||||
|
17
lib/vrf.h
17
lib/vrf.h
@ -56,6 +56,20 @@ enum {
|
||||
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF name\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
|
||||
{
|
||||
RB_ENTRY(vrf) id_entry, name_entry;
|
||||
@ -76,6 +90,9 @@ struct vrf
|
||||
/* User data */
|
||||
void *info;
|
||||
|
||||
/* The table_id from the kernel */
|
||||
struct vrf_data data;
|
||||
|
||||
QOBJ_FIELDS
|
||||
};
|
||||
RB_HEAD (vrf_id_head, vrf);
|
||||
|
@ -126,7 +126,7 @@ work_queue_schedule (struct work_queue *wq, unsigned int delay)
|
||||
&& (listcount (wq->items) > 0) )
|
||||
{
|
||||
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);
|
||||
/* set thread yield time, if needed */
|
||||
if (wq->thread && wq->spec.yield != THREAD_YIELD_TIME_SLOT)
|
||||
|
@ -1169,12 +1169,15 @@ zclient_vrf_add (struct zclient *zclient, vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
char vrfname_tmp[VRF_NAMSIZ];
|
||||
struct vrf_data data;
|
||||
|
||||
stream_get (&data, zclient->ibuf, sizeof (struct vrf_data));
|
||||
/* Read interface name. */
|
||||
stream_get (vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
|
||||
|
||||
/* Lookup/create vrf by vrf_id. */
|
||||
vrf = vrf_get (vrf_id, vrfname_tmp);
|
||||
vrf->data = data;
|
||||
|
||||
vrf_enable (vrf);
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ static int vici_reconnect(struct thread *t)
|
||||
|
||||
fd = sock_open_unix("/var/run/charon.vici");
|
||||
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));
|
||||
thread_add_timer(master, vici_reconnect, vici, 2,
|
||||
&vici->t_reconnect);
|
||||
|
@ -619,21 +619,23 @@ DEFUN (area_filter_list,
|
||||
"Filter networks sent to this area\n"
|
||||
"Filter networks sent from this area\n")
|
||||
{
|
||||
int idx_ipv4 = 1;
|
||||
int idx_word = 4;
|
||||
char *inout = argv[argc - 1]->text;
|
||||
char *areaid = argv[1]->arg;
|
||||
char *plistname = argv[4]->arg;
|
||||
|
||||
struct ospf6_area *area;
|
||||
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);
|
||||
if (strncmp (argv[idx_word]->arg, "in", 2) == 0)
|
||||
plist = prefix_list_lookup (AFI_IP6, plistname);
|
||||
if (strmatch (inout, "in"))
|
||||
{
|
||||
PREFIX_LIST_IN (area) = plist;
|
||||
if (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);
|
||||
}
|
||||
else
|
||||
@ -642,7 +644,7 @@ DEFUN (area_filter_list,
|
||||
if (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);
|
||||
}
|
||||
|
||||
@ -661,16 +663,18 @@ DEFUN (no_area_filter_list,
|
||||
"Filter networks sent to this area\n"
|
||||
"Filter networks sent from this area\n")
|
||||
{
|
||||
int idx_ipv4 = 2;
|
||||
int idx_word = 5;
|
||||
char *inout = argv[argc - 1]->text;
|
||||
char *areaid = argv[2]->arg;
|
||||
char *plistname = argv[5]->arg;
|
||||
|
||||
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 (strcmp (PREFIX_NAME_IN (area), argv[idx_ipv4]->arg) != 0)
|
||||
if (!strmatch (PREFIX_NAME_IN (area), plistname))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
PREFIX_LIST_IN (area) = NULL;
|
||||
@ -683,7 +687,7 @@ DEFUN (no_area_filter_list,
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
PREFIX_LIST_OUT (area) = NULL;
|
||||
|
@ -838,6 +838,7 @@ initialize_linkparams (struct mpls_te_link *lp)
|
||||
|
||||
if ((oi = lookup_oi_by_ifp (ifp, NULL, OI_ANY)) == NULL)
|
||||
{
|
||||
if (IS_DEBUG_OSPF_TE)
|
||||
zlog_warn("MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s",
|
||||
ifp->name);
|
||||
return;
|
||||
@ -991,6 +992,7 @@ ospf_mpls_te_update_if (struct interface *ifp)
|
||||
/* Get Link context from interface */
|
||||
if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL)
|
||||
{
|
||||
if (IS_DEBUG_OSPF_TE)
|
||||
zlog_warn ("OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s", ifp->name);
|
||||
return;
|
||||
}
|
||||
|
154
ospfd/ospf_vty.c
154
ospfd/ospf_vty.c
@ -988,15 +988,15 @@ ospf_vl_set (struct ospf *ospf, struct ospf_vl_config_data *vl_config)
|
||||
"Use null 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 \
|
||||
VLINK_HELPSTR_TIME_PARAM_NOSECS \
|
||||
"Seconds\n"
|
||||
"Time between HELLO packets\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 \
|
||||
"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,
|
||||
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>]",
|
||||
@ -1292,19 +1239,56 @@ DEFUN (no_ospf_area_vlink,
|
||||
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,
|
||||
no_ospf_area_vlink_intervals_cmd,
|
||||
"no 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)"
|
||||
"]]]",
|
||||
"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)}",
|
||||
NO_STR
|
||||
VLINK_HELPSTR_IPADDR
|
||||
VLINK_HELPSTR_TIME_PARAM
|
||||
VLINK_HELPSTR_TIME_PARAM
|
||||
VLINK_HELPSTR_TIME_PARAM
|
||||
VLINK_HELPSTR_TIME_PARAM)
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(ospf, ospf);
|
||||
@ -1330,16 +1314,15 @@ DEFUN (no_ospf_area_vlink_intervals,
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
for (int idx = 5; idx < argc; idx++)
|
||||
{
|
||||
int idx = 0;
|
||||
if (argv_find (argv, argc, "hello-interval", &idx))
|
||||
if (strmatch (argv[idx]->text, "hello-interval"))
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2222,7 +2205,7 @@ DEFUN (ospf_timers_min_ls_interval,
|
||||
int idx_number = 4;
|
||||
unsigned int interval;
|
||||
|
||||
if (argc != 1)
|
||||
if (argc < 5)
|
||||
{
|
||||
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
@ -2264,7 +2247,7 @@ DEFUN (ospf_timers_min_ls_arrival,
|
||||
int idx_number = 3;
|
||||
unsigned int arrival;
|
||||
|
||||
if (argc != 1)
|
||||
if (argc < 4)
|
||||
{
|
||||
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
@ -2309,7 +2292,7 @@ DEFUN (ospf_timers_throttle_spf,
|
||||
int idx_number_3 = 5;
|
||||
unsigned int delay, hold, max;
|
||||
|
||||
if (argc != 3)
|
||||
if (argc < 6)
|
||||
{
|
||||
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
@ -2352,7 +2335,7 @@ DEFUN (ospf_timers_lsa,
|
||||
int idx_number = 3;
|
||||
unsigned int minarrival;
|
||||
|
||||
if (argc != 1)
|
||||
if (argc < 4)
|
||||
{
|
||||
vty_out (vty, "Insufficient number of arguments%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
@ -3552,7 +3535,6 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
|
||||
if (use_json)
|
||||
{
|
||||
json = json_object_new_object();
|
||||
json_interface_sub = json_object_new_object();
|
||||
}
|
||||
|
||||
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 (use_json)
|
||||
json_interface_sub = json_object_new_object();
|
||||
|
||||
show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json);
|
||||
|
||||
if (use_json)
|
||||
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
|
||||
{
|
||||
if (use_json)
|
||||
json_interface_sub = json_object_new_object();
|
||||
|
||||
show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json);
|
||||
|
||||
if (use_json)
|
||||
json_object_object_add(json, ifp->name, json_interface_sub);
|
||||
}
|
||||
@ -9099,7 +9089,7 @@ DEFUN (clear_ip_ospf_interface,
|
||||
}
|
||||
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);
|
||||
else
|
||||
ospf_interface_clear(ifp);
|
||||
|
@ -46,13 +46,11 @@ pim_bfd_write_config (struct vty *vty, struct interface *ifp)
|
||||
|
||||
if (!pim_ifp)
|
||||
return;
|
||||
|
||||
bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
|
||||
if (!bfd_info)
|
||||
{
|
||||
zlog_debug ("%s: interface %s bfd_info is NULL ", __PRETTY_FUNCTION__,
|
||||
ifp->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
|
||||
vty_out (vty, " ip pim bfd %d %d %d%s",
|
||||
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)
|
||||
return;
|
||||
zlog_debug ("%s: bfd_info ", __PRETTY_FUNCTION__);
|
||||
|
||||
nbr_bfd_info = (struct bfd_info *) neigh->bfd_info;
|
||||
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;
|
||||
int command = 0;
|
||||
|
||||
if (!pim_ifp)
|
||||
return;
|
||||
bfd_set_param ((struct bfd_info **) &(pim_ifp->bfd_info), min_rx, min_tx,
|
||||
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,
|
||||
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;
|
||||
if (bfd_info->status == status)
|
||||
{
|
||||
|
@ -297,7 +297,7 @@ static int detect_primary_address_change(struct interface *ifp,
|
||||
int changed;
|
||||
|
||||
if (force_prim_as_any)
|
||||
new_prim_addr = qpim_inaddr_any;
|
||||
new_prim_addr.s_addr = INADDR_ANY;
|
||||
else
|
||||
new_prim_addr = pim_find_primary_addr(ifp);
|
||||
|
||||
|
@ -387,11 +387,13 @@ const char *pim_ifchannel_ifassert_name(enum pim_ifassert_state ifassert_state)
|
||||
*/
|
||||
void reset_ifassert_state(struct pim_ifchannel *ch)
|
||||
{
|
||||
struct in_addr any = { .s_addr = INADDR_ANY };
|
||||
|
||||
THREAD_OFF(ch->t_ifassert_timer);
|
||||
|
||||
pim_ifassert_winner_set(ch,
|
||||
PIM_IFASSERT_NOINFO,
|
||||
qpim_inaddr_any,
|
||||
any,
|
||||
qpim_infinite_assert_metric);
|
||||
}
|
||||
|
||||
@ -1277,7 +1279,7 @@ pim_ifchannel_scan_forward_start (struct interface *new_ifp)
|
||||
* we get End of Message
|
||||
*/
|
||||
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 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))
|
||||
{
|
||||
/* 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
|
||||
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))
|
||||
{
|
||||
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 (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_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))
|
||||
continue;
|
||||
|
@ -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_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);
|
||||
|
||||
|
@ -228,7 +228,8 @@ int pim_joinprune_recv(struct interface *ifp,
|
||||
uint16_t msg_num_joined_sources;
|
||||
uint16_t msg_num_pruned_sources;
|
||||
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));
|
||||
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)
|
||||
{
|
||||
ch = pim_ifchannel_find (ifp, &sg);
|
||||
if (ch)
|
||||
pim_ifchannel_set_star_g_join_state (ch, 0, msg_source_flags, 1);
|
||||
starg_alone = 1;
|
||||
starg_ch = pim_ifchannel_find (ifp, &sg);
|
||||
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;
|
||||
}
|
||||
|
||||
buf += addr_offset;
|
||||
sg_ch = pim_ifchannel_find (ifp, &sg);
|
||||
|
||||
buf += addr_offset;
|
||||
starg_alone = 0;
|
||||
recv_prune(ifp, neigh, msg_holdtime,
|
||||
msg_upstream_addr.u.prefix4,
|
||||
&sg,
|
||||
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)
|
||||
pim_ifchannel_set_star_g_join_state (ch, 1, msg_source_flags, 0);
|
||||
ch = NULL;
|
||||
}
|
||||
}
|
||||
if (starg_ch)
|
||||
pim_ifchannel_set_star_g_join_state (starg_ch, 1, msg_source_flags, 0, starg_alone);
|
||||
starg_ch = NULL;
|
||||
} /* scan groups */
|
||||
|
||||
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_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;
|
||||
if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255)
|
||||
{
|
||||
|
@ -247,7 +247,8 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
|
||||
|
||||
rpf->rpf_addr.family = AF_INET;
|
||||
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",
|
||||
__FILE__, __PRETTY_FUNCTION__,
|
||||
|
@ -577,8 +577,9 @@ pim_upstream_switch(struct pim_upstream *up,
|
||||
if (old_state == PIM_UPSTREAM_JOINED)
|
||||
pim_msdp_up_join_state_changed(up);
|
||||
|
||||
/* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT */
|
||||
if (pim_upstream_is_sg_rpt(up) && up->parent)
|
||||
/* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT towards RP.
|
||||
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)
|
||||
zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__,
|
||||
|
@ -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_events = 0;
|
||||
int64_t qpim_rpf_cache_refresh_last = 0;
|
||||
struct in_addr qpim_inaddr_any;
|
||||
struct list *qpim_ssmpingd_list = NULL;
|
||||
struct in_addr qpim_ssmpingd_group_addr;
|
||||
int64_t qpim_scan_oil_events = 0;
|
||||
@ -293,7 +292,6 @@ void pim_init()
|
||||
|
||||
pim_mroute_socket_enable();
|
||||
|
||||
qpim_inaddr_any.s_addr = PIM_NET_INADDR_ANY;
|
||||
|
||||
/*
|
||||
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.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_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_cmd_init();
|
||||
|
@ -140,7 +140,6 @@ struct thread *qpim_rpf_cache_refresher;
|
||||
int64_t qpim_rpf_cache_refresh_requests;
|
||||
int64_t qpim_rpf_cache_refresh_events;
|
||||
int64_t qpim_rpf_cache_refresh_last;
|
||||
struct in_addr qpim_inaddr_any;
|
||||
struct list *qpim_ssmpingd_list; /* list of struct ssmpingd_sock */
|
||||
struct in_addr qpim_ssmpingd_group_addr;
|
||||
int64_t qpim_scan_oil_events;
|
||||
|
@ -1,8 +1,5 @@
|
||||
|
||||
EXTRA_DIST = bgpd.init isisd.init \
|
||||
ospf6d.init ospfd.init ldpd.init \
|
||||
EXTRA_DIST = frr.init frr.service daemons \
|
||||
frr.logrotate frr.pam frr.spec \
|
||||
frr.sysconfig ripd.init ripngd.init \
|
||||
watchfrr.init pimd.init zebra.init \
|
||||
README.rpm_build.md
|
||||
|
||||
|
@ -1,31 +1,45 @@
|
||||
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.
|
||||
|
||||
Newer automake/autoconf/bison is only needed to build the rpm and is
|
||||
**not** needed to install the binary rpm package
|
||||
|
||||
2. Install the following packages to build the RPMs:
|
||||
|
||||
yum install git autoconf automake libtool make gawk readline-devel \
|
||||
texinfo dejagnu net-snmp-devel groff rpm-build net-snmp-devel \
|
||||
libcap-devel texi2html
|
||||
texinfo net-snmp-devel groff pkgconfig rpm-build json-c-devel \
|
||||
pam-devel texi2html bison libcap-devel flex
|
||||
|
||||
(use `dnf install` on new Fedora instead of `yum install `)
|
||||
Additionally, on systems with systemd (CentOS 7, Fedora)
|
||||
|
||||
2. Checkout FRR under a **unpriviledged** user account
|
||||
yum install systemd-devel
|
||||
|
||||
(use `dnf install` on new Fedora instead of `yum install`)
|
||||
|
||||
**CentOS 6:** Please check doc/Building_FRR_on_CentOS6.md for details on
|
||||
how to install required version of autoconf, automake and bison. The
|
||||
versions in the common Repo are too old.
|
||||
|
||||
3. Checkout FRR under a **unpriviledged** user account
|
||||
|
||||
git clone https://github.com/frrouting/frr.git frr
|
||||
|
||||
3. Run Bootstrap and make distribution tar.gz
|
||||
4. Run Bootstrap and make distribution tar.gz
|
||||
|
||||
cd frr
|
||||
./bootstrap.sh
|
||||
./configure --with-pkg-extra-version=-MyRPMVersion
|
||||
make dist
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
4. Create RPM directory structure and populate with sources
|
||||
5. Create RPM directory structure and populate with sources
|
||||
|
||||
mkdir rpmbuild
|
||||
mkdir rpmbuild/SOURCES
|
||||
@ -33,42 +47,37 @@ Building your own FRRouting RPM
|
||||
cp redhat/*.spec rpmbuild/SPECS/
|
||||
cp frr*.tar.gz rpmbuild/SOURCES/
|
||||
|
||||
5. 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:
|
||||
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:
|
||||
|
||||
################# frr configure options ####################
|
||||
############### FRRouting (FRR) configure options #################
|
||||
# with-feature options
|
||||
%{!?with_snmp: %global with_snmp 1 }
|
||||
%{!?with_vtysh: %global with_vtysh 1 }
|
||||
%{!?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_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_isisd: %global with_isisd 1 }
|
||||
%{!?with_pimd: %global with_pimd 1 }
|
||||
%{!?with_mpls: %global with_mpls 0 }
|
||||
%{!?with_ldpd: %global with_ldpd 0 }
|
||||
%{!?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 64 }
|
||||
%{!?with_multipath: %global with_multipath 256 }
|
||||
%{!?frr_user: %global frr_user frr }
|
||||
%{!?vty_group: %global vty_group frrvt }
|
||||
%{!?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 }
|
||||
|
||||
6. Build the RPM
|
||||
7. Build the RPM
|
||||
|
||||
rpmbuild --define "_topdir `pwd`/rpmbuild" -ba rpmbuild/SPECS/frr.spec
|
||||
|
||||
DONE.
|
||||
|
||||
If all works correctly, then you should end up with the RPMs under `rpmbuild/RPMS`
|
||||
and the Source RPM under `rpmbuild/SRPMS`
|
||||
If all works correctly, then you should end up with the RPMs under
|
||||
`rpmbuild/RPMS` and the Source RPM under `rpmbuild/SRPMS`
|
||||
|
||||
|
||||
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):
|
||||
|
||||
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
|
||||
chkconfig ospfd on
|
||||
chkconfig ospf6d on
|
||||
chkconfig bgpd on
|
||||
... etc
|
||||
2. Enable the daemons as needed to run after boot (Zebra is mandatory)
|
||||
|
||||
2. If you want to run `watchfrr`, then configure `/etc/sysconfig/frr`
|
||||
and uncomment the line with the daemons for `watchfrr` to monitor,
|
||||
then enable watchfrr
|
||||
|
||||
chkconfig watchfrr on
|
||||
chkconfig frr on
|
||||
|
||||
3. Check your firewall / IPtables to make sure the routing protocols are
|
||||
allowed.
|
||||
|
||||
4. Start the daemons (or reboot)
|
||||
5. Start the FRR daemons (or reboot)
|
||||
|
||||
service zebra start
|
||||
service bgpd start
|
||||
service ospfd start
|
||||
... etc
|
||||
service frr start
|
||||
|
||||
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
|
||||
systemctl enable ospfd
|
||||
systemctl enable ospf6d
|
||||
systemctl enable bgpd
|
||||
... etc
|
||||
2. Enable the frr daemons to run after boot.
|
||||
|
||||
Note: There is no watchfrr on systemd based systems. Systemd contains
|
||||
the functionality of monitoring and restarting daemons.
|
||||
systemctl enable frr
|
||||
|
||||
2. Check your firewall / IPtables to make sure the routing protocols are
|
||||
allowed.
|
||||
|
||||
3. Start the daemons (or reboot)
|
||||
|
||||
systemctl start zebra
|
||||
systemctl start bgpd
|
||||
systemctl start ospfd
|
||||
... etc
|
||||
systemctl start frr
|
||||
|
||||
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`.
|
||||
|
||||
|
@ -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
63
redhat/daemons
Normal 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
561
redhat/frr.init
Executable 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
|
@ -61,3 +61,20 @@
|
||||
/bin/kill -USR1 `cat /var/run/frr/ldpd.pid 2> /dev/null` 2> /dev/null || true
|
||||
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
23
redhat/frr.service
Normal 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
|
||||
|
@ -8,7 +8,7 @@
|
||||
# rpms again and again on the same day, so the newer rpms can be installed.
|
||||
# bumping the number each time.
|
||||
|
||||
####################### FRRouting (FRR) configure options #########################
|
||||
#################### FRRouting (FRR) configure options #####################
|
||||
# with-feature options
|
||||
%{!?with_tcp_zebra: %global with_tcp_zebra 0 }
|
||||
%{!?with_pam: %global with_pam 0 }
|
||||
@ -16,9 +16,9 @@
|
||||
%{!?with_ospfapi: %global with_ospfapi 1 }
|
||||
%{!?with_irdp: %global with_irdp 1 }
|
||||
%{!?with_rtadv: %global with_rtadv 1 }
|
||||
%{!?with_mpls: %global with_mpls 0 }
|
||||
%{!?with_ldpd: %global with_ldpd 0 }
|
||||
%{!?with_ldpd: %global with_ldpd 1 }
|
||||
%{!?with_nhrpd: %global with_nhrpd 1 }
|
||||
%{!?with_eigrpd: %global with_eigrpd 1 }
|
||||
%{!?with_shared: %global with_shared 1 }
|
||||
%{!?with_multipath: %global with_multipath 256 }
|
||||
%{!?frr_user: %global frr_user frr }
|
||||
@ -26,6 +26,7 @@
|
||||
%{!?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 }
|
||||
|
||||
# path defines
|
||||
%define _sysconfdir /etc/frr
|
||||
@ -34,7 +35,6 @@
|
||||
%define zeb_rh_src %{zeb_src}/redhat
|
||||
%define zeb_docs %{zeb_src}/doc
|
||||
%define frr_tools %{zeb_src}/tools
|
||||
%define frr_tools_etc %{frr_tools}/etc
|
||||
|
||||
# defines for configure
|
||||
%define _localstatedir /var/run/frr
|
||||
@ -47,11 +47,11 @@
|
||||
|
||||
#### Check version of texi2html
|
||||
# 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 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
|
||||
#
|
||||
@ -62,6 +62,15 @@
|
||||
%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
|
||||
|
||||
# if FPM is enabled, then enable tcp_zebra as well
|
||||
#
|
||||
%if %{with_fpm}
|
||||
@ -73,7 +82,7 @@
|
||||
%{!?frr_gid: %global frr_gid 92 }
|
||||
%{!?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}
|
||||
%define daemon_ldpd ldpd
|
||||
@ -81,19 +90,31 @@
|
||||
%define daemon_ldpd ""
|
||||
%endif
|
||||
|
||||
%if %{with_pimd}
|
||||
%define daemon_pimd pimd
|
||||
%else
|
||||
%define daemon_pimd ""
|
||||
%endif
|
||||
|
||||
%if %{with_nhrpd}
|
||||
%define daemon_nhrpd nhrpd
|
||||
%else
|
||||
%define daemon_nhrpd ""
|
||||
%endif
|
||||
|
||||
%if %{with_eigrpd}
|
||||
%define daemon_eigrpd eigrpd
|
||||
%else
|
||||
%define daemon_eigrpd ""
|
||||
%endif
|
||||
|
||||
%if %{with_watchfrr}
|
||||
%define daemon_watchfrr watchfrr
|
||||
%else
|
||||
%define daemon_watchfrr ""
|
||||
%endif
|
||||
|
||||
%define all_daemons %{daemon_list} %{daemon_ldpd} %{daemon_nhrpd} %{daemon_watchfrr}
|
||||
%define all_daemons %{daemon_list} %{daemon_ldpd} %{daemon_pimd} %{daemon_nhrpd} %{daemon_eigrpd} %{daemon_watchfrr}
|
||||
|
||||
# allow build dir to be kept
|
||||
%{!?keep_build: %global keep_build 0 }
|
||||
@ -109,20 +130,19 @@ License: GPLv2+
|
||||
Group: System Environment/Daemons
|
||||
Source0: http://www.frrouting.org/releases/frr/%{name}-%{frrversion}.tar.gz
|
||||
URL: http://www.frrouting.org
|
||||
Requires: ncurses json-c
|
||||
Requires(pre): /sbin/install-info
|
||||
Requires(preun): /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: json-c-devel bison flex
|
||||
Requires: ncurses initscripts
|
||||
BuildRequires: json-c-devel bison >= 2.7 flex make
|
||||
Requires: ncurses json-c initscripts
|
||||
%if %{with_pam}
|
||||
BuildRequires: pam-devel
|
||||
Requires: pam
|
||||
%endif
|
||||
%if "%{initsystem}" == "systemd"
|
||||
BuildRequires: systemd
|
||||
BuildRequires: systemd systemd-devel
|
||||
Requires(post): systemd
|
||||
Requires(preun): systemd
|
||||
Requires(postun): systemd
|
||||
@ -140,7 +160,7 @@ protocol. It takes multi-server and multi-thread approach to resolve
|
||||
the current complexity of the Internet.
|
||||
|
||||
FRRouting supports BGP4, OSPFv2, OSPFv3, ISIS, RIP, RIPng, PIM, LDP
|
||||
and NHRP.
|
||||
NHRP and EIGRP.
|
||||
|
||||
FRRouting is a fork of Quagga.
|
||||
|
||||
@ -151,6 +171,15 @@ Group: System Environment/Daemons
|
||||
%description contrib
|
||||
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
|
||||
Summary: Header and object files for frr development
|
||||
Group: System Environment/Daemons
|
||||
@ -193,9 +222,9 @@ developing OSPF-API and frr applications.
|
||||
%endif
|
||||
--enable-vtysh \
|
||||
%if %{with_ospfclient}
|
||||
--enable-ospfclient=yes \
|
||||
--enable-ospfclient \
|
||||
%else
|
||||
--enable-ospfclient=no\
|
||||
--disable-ospfclient\
|
||||
%endif
|
||||
%if %{with_ospfapi}
|
||||
--enable-ospfapi=yes \
|
||||
@ -212,21 +241,26 @@ developing OSPF-API and frr applications.
|
||||
%else
|
||||
--enable-rtadv=no \
|
||||
%endif
|
||||
%if %{with_mpls}
|
||||
--enable-mpls=yes \
|
||||
%else
|
||||
--disable-mpls \
|
||||
%endif
|
||||
%if %{with_ldpd}
|
||||
--enable-ldpd \
|
||||
%else
|
||||
--disable-ldpd \
|
||||
%endif
|
||||
%if %{with_pimd}
|
||||
--enable-pimd \
|
||||
%else
|
||||
--disable-pimd \
|
||||
%endif
|
||||
%if %{with_nhrpd}
|
||||
--enable-nhrpd \
|
||||
%else
|
||||
--disable-nhrpd \
|
||||
%endif
|
||||
%if %{with_eigrpd}
|
||||
--enable-eigrpd \
|
||||
%else
|
||||
--disable-eigrpd \
|
||||
%endif
|
||||
%if %{with_pam}
|
||||
--with-libpam \
|
||||
%endif
|
||||
@ -254,7 +288,9 @@ developing OSPF-API and frr applications.
|
||||
%endif
|
||||
--enable-gcc-rdynamic \
|
||||
--enable-isisd=yes \
|
||||
%if "%{initsystem}" == "systemd"
|
||||
--enable-systemd=yes \
|
||||
%endif
|
||||
--enable-poll=yes
|
||||
|
||||
make %{?_smp_mflags} MAKEINFO="makeinfo --no-split"
|
||||
@ -275,25 +311,23 @@ make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install
|
||||
# Remove this file, as it is uninstalled and causes errors when building on RH9
|
||||
rm -rf %{buildroot}/usr/share/info/dir
|
||||
|
||||
# Remove debian init script if it was installed
|
||||
rm -f %{buildroot}%{_sbindir}/frr
|
||||
|
||||
# install /etc sources
|
||||
%if "%{initsystem}" == "systemd"
|
||||
mkdir -p %{buildroot}%{_unitdir}
|
||||
install %{frr_tools}/frr.service \
|
||||
install %{zeb_rh_src}/frr.service \
|
||||
%{buildroot}%{_unitdir}/frr.service
|
||||
install %{zeb_rh_src}/frr.init \
|
||||
%{buildroot}%{_sbindir}/frr
|
||||
%else
|
||||
mkdir -p %{buildroot}/etc/rc.d/init.d
|
||||
for daemon in %{all_daemons} ; do
|
||||
if [ x"${daemon}" != x"" ] ; then
|
||||
install %{zeb_rh_src}/${daemon}.init \
|
||||
%{buildroot}/etc/rc.d/init.d/${daemon}
|
||||
fi
|
||||
done
|
||||
install %{zeb_rh_src}/frr.init \
|
||||
%{buildroot}/etc/rc.d/init.d/frr
|
||||
%endif
|
||||
|
||||
install %{frr_tools_dir}/frr/daemons.conf %{buildroot}/etc/frr
|
||||
install %{frr_tools_dir}/frr/daemons %{buildroot}/etc/frr
|
||||
install -m644 %{frr_tools_dir}/default/frr %{buildroot}/etc/default
|
||||
install %{zeb_rh_src}/daemons %{buildroot}/etc/frr
|
||||
install -m644 %{zeb_rh_src}/frr.pam \
|
||||
%{buildroot}/etc/pam.d/frr
|
||||
install -m644 %{zeb_rh_src}/frr.logrotate \
|
||||
@ -348,10 +382,15 @@ zebra_spec_add_service ospf6d 2606/tcp "OSPF6d vty"
|
||||
zebra_spec_add_service ospfapi 2607/tcp "OSPF-API"
|
||||
%endif
|
||||
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}
|
||||
zebra_spec_add_service nhrpd 2610/tcp "NHRPd vty"
|
||||
%endif
|
||||
%if %{with_pimd}
|
||||
zebra_spec_add_service pimd 2611/tcp "PIMd vty"
|
||||
%endif
|
||||
%if %{with_ldpd}
|
||||
zebra_spec_add_service ldpd 2612/tcp "LDPd vty"
|
||||
%endif
|
||||
@ -361,9 +400,7 @@ for daemon in %all_daemons ; do
|
||||
%systemd_post frr.service
|
||||
done
|
||||
%else
|
||||
for daemon in %all_daemons ; do
|
||||
/sbin/chkconfig --add ${daemon}
|
||||
done
|
||||
/sbin/chkconfig --add frr
|
||||
%endif
|
||||
|
||||
/sbin/install-info %{_infodir}/frr.info.gz %{_infodir}/dir
|
||||
@ -374,16 +411,22 @@ if [ ! -e %{_sysconfdir}/zebra.conf ]; then
|
||||
%if 0%{?frr_user:1}
|
||||
chown %frr_user:%frr_user %{_sysconfdir}/zebra.conf*
|
||||
%endif
|
||||
chmod 640 %{_sysconfdir}/zebra.conf
|
||||
chmod 640 %{_sysconfdir}/zebra.conf*
|
||||
fi
|
||||
for daemon in %{all_daemons} ; do
|
||||
if [ x"${daemon}" != x"" ] ; then
|
||||
if [ ! -e %{_sysconfdir}/${daemon}.conf ]; then
|
||||
touch %{_sysconfdir}/${daemon}.conf
|
||||
%if 0%{?frr_user:1}
|
||||
chown %frr_user:%frr_user %{_sysconfdir}/${daemon}.conf*
|
||||
%endif
|
||||
fi
|
||||
fi
|
||||
done
|
||||
%if 0%{?frr_user:1}
|
||||
chown %frr_user:%frr_user %{_sysconfdir}/daemons
|
||||
%endif
|
||||
|
||||
%if %{with_watchfrr}
|
||||
# No config for watchfrr - this is part of /etc/sysconfig/frr
|
||||
rm -f %{_sysconfdir}/watchfrr.*
|
||||
@ -392,81 +435,30 @@ done
|
||||
if [ ! -e %{_sysconfdir}/vtysh.conf ]; then
|
||||
touch %{_sysconfdir}/vtysh.conf
|
||||
chmod 640 %{_sysconfdir}/vtysh.conf
|
||||
%if 0%{?frr_user:1}
|
||||
%if 0%{?vty_group:1}
|
||||
chown frr:%{vty_group} %{_sysconfdir}/vtysh.conf*
|
||||
chown %{frr_user}:%{vty_group} %{_sysconfdir}/vtysh.conf*
|
||||
%endif
|
||||
%endif
|
||||
fi
|
||||
|
||||
%postun
|
||||
if [ "$1" -ge 1 ]; then
|
||||
# Find out which daemons need to be restarted.
|
||||
for daemon in %all_daemons ; do
|
||||
if [ -f /var/lock/subsys/${daemon} ]; then
|
||||
eval restart_${daemon}=yes
|
||||
else
|
||||
eval restart_${daemon}=no
|
||||
fi
|
||||
done
|
||||
# Rename restart flags for daemons handled specially.
|
||||
running_zebra="$restart_zebra"
|
||||
restart_zebra=no
|
||||
%if %{with_watchfrr}
|
||||
running_watchfrr="$restart_watchfrr"
|
||||
restart_watchfrr=no
|
||||
%endif
|
||||
|
||||
#
|
||||
# Upgrade from older version
|
||||
#
|
||||
%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
|
||||
%systemd_postun frr.service
|
||||
%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
|
||||
/etc/rc.d/init.d/frr restart >/dev/null 2>&1
|
||||
%endif
|
||||
:
|
||||
fi
|
||||
|
||||
%preun
|
||||
@ -476,7 +468,9 @@ fi
|
||||
##
|
||||
if [ "$1" = "0" ]; then
|
||||
for daemon in %all_daemons ; do
|
||||
%systemd_preun ${daemon}.service
|
||||
if [ x"${daemon}" != x"" ] ; then
|
||||
%systemd_preun frr.service
|
||||
fi
|
||||
done
|
||||
fi
|
||||
%else
|
||||
@ -484,10 +478,8 @@ fi
|
||||
## init.d Version
|
||||
##
|
||||
if [ "$1" = "0" ]; then
|
||||
for daemon in %all_daemons ; do
|
||||
/etc/rc.d/init.d/${daemon} stop >/dev/null 2>&1
|
||||
/sbin/chkconfig --del ${daemon}
|
||||
done
|
||||
/etc/rc.d/init.d/frr stop >/dev/null 2>&1
|
||||
/sbin/chkconfig --del frr
|
||||
fi
|
||||
%endif
|
||||
/sbin/install-info --delete %{_infodir}/frr.info.gz %{_infodir}/dir
|
||||
@ -521,52 +513,39 @@ rm -rf %{buildroot}
|
||||
%{_sbindir}/ospfd
|
||||
%{_sbindir}/ripd
|
||||
%{_sbindir}/bgpd
|
||||
%{_sbindir}/ssd
|
||||
%{_sbindir}/frr
|
||||
%{_sbindir}/frr-reload.py
|
||||
%{_sbindir}/frr-reload.pyc
|
||||
%{_sbindir}/frr-reload.pyo
|
||||
%exclude %{_sbindir}/ssd
|
||||
%if %{with_watchfrr}
|
||||
%{_sbindir}/watchfrr
|
||||
%endif
|
||||
%{_sbindir}/ripngd
|
||||
%{_sbindir}/ospf6d
|
||||
%{_sbindir}/pimd
|
||||
%if %{with_pimd}
|
||||
%{_sbindir}/pimd
|
||||
%endif
|
||||
%{_sbindir}/isisd
|
||||
%if %{with_ldpd}
|
||||
%{_sbindir}/ldpd
|
||||
%{_sbindir}/ldpd
|
||||
%endif
|
||||
%if %{with_eigrpd}
|
||||
%{_sbindir}/eigrpd
|
||||
%endif
|
||||
%if %{with_nhrpd}
|
||||
%{_sbindir}/nhrpd
|
||||
%{_sbindir}/nhrpd
|
||||
%endif
|
||||
%if %{with_shared}
|
||||
%attr(755,root,root) %{_libdir}/lib*.so
|
||||
%attr(755,root,root) %{_libdir}/lib*.so.*
|
||||
%{_libdir}/lib*.so
|
||||
%{_libdir}/lib*.so.0
|
||||
%attr(755,root,root) %{_libdir}/lib*.so.0.*
|
||||
%endif
|
||||
%{_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"
|
||||
%config %{_unitdir}/frr.service
|
||||
%{_sbindir}/frr
|
||||
%else
|
||||
%config /etc/rc.d/init.d/zebra
|
||||
%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
|
||||
%config /etc/rc.d/init.d/frr
|
||||
%endif
|
||||
%config(noreplace) /etc/default/frr
|
||||
%config(noreplace) /etc/pam.d/frr
|
||||
%config(noreplace) %attr(640,root,root) /etc/logrotate.d/*
|
||||
|
||||
@ -574,6 +553,12 @@ rm -rf %{buildroot}
|
||||
%defattr(-,root,root)
|
||||
%doc tools
|
||||
|
||||
%files pythontools
|
||||
%defattr(-,root,root)
|
||||
%{_sbindir}/frr-reload.py
|
||||
%{_sbindir}/frr-reload.pyc
|
||||
%{_sbindir}/frr-reload.pyo
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
%if %{with_ospfclient}
|
||||
@ -589,12 +574,23 @@ rm -rf %{buildroot}
|
||||
%dir %attr(755,root,root) %{_includedir}/%{name}/ospfapi
|
||||
%{_includedir}/%name/ospfapi/*.h
|
||||
%endif
|
||||
%if %{with_eigrpd}
|
||||
%dir %attr(755,root,root) %{_includedir}/%{name}/eigrpd
|
||||
%{_includedir}/%name/eigrpd/*.h
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Feb 14 2017 Timo Teräs <timo.teras@iki.fi> - %{version}
|
||||
- add nhrpd
|
||||
* Mon Jun 5 2017 Martin Winter <mwinter@opensourcerouting.org> - %{version}
|
||||
- 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
|
||||
|
||||
* Thu Feb 11 2016 Paul Jakma <paul@jakma.org>
|
||||
|
@ -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"
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -90,7 +90,7 @@ clear_something (struct thread *thread)
|
||||
ws->i++;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -134,7 +134,7 @@ DEFUN (clear_foo,
|
||||
ws->vty = vty;
|
||||
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;
|
||||
}
|
||||
|
@ -5,5 +5,7 @@
|
||||
188 ospf
|
||||
189 rip
|
||||
190 ripng
|
||||
191 static
|
||||
191 nhrp
|
||||
192 eigrp
|
||||
193 ldp
|
||||
194 babel
|
@ -2623,6 +2623,7 @@ vtysh_write_config_integrated(void)
|
||||
err++;
|
||||
}
|
||||
|
||||
#ifdef FRR_USER
|
||||
pwentry = getpwnam (FRR_USER);
|
||||
if (pwentry)
|
||||
uid = pwentry->pw_uid;
|
||||
@ -2631,7 +2632,8 @@ vtysh_write_config_integrated(void)
|
||||
printf ("%% Warning: could not look up user \"%s\"\n", FRR_USER);
|
||||
err++;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef FRR_GROUP
|
||||
grentry = getgrnam (FRR_GROUP);
|
||||
if (grentry)
|
||||
gid = grentry->gr_gid;
|
||||
@ -2640,6 +2642,7 @@ vtysh_write_config_integrated(void)
|
||||
printf ("%% Warning: could not look up group \"%s\"\n", FRR_GROUP);
|
||||
err++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fstat (fd, &st))
|
||||
{
|
||||
|
@ -185,7 +185,8 @@ vtysh_config_parse_line (void *arg, const char *line)
|
||||
else if (config->index == RMAP_NODE ||
|
||||
config->index == INTERFACE_NODE ||
|
||||
config->index == NS_NODE ||
|
||||
config->index == VTY_NODE)
|
||||
config->index == VTY_NODE ||
|
||||
config->index == VRF_NODE)
|
||||
config_add_line_uniq (config->line, line);
|
||||
else
|
||||
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, "frr", strlen ("frr")) == 0
|
||||
|| strncmp (line, "agentx", strlen ("agentx")) == 0
|
||||
|| strncmp (line, "no log", strlen ("no log")) == 0
|
||||
)
|
||||
config_add_line_uniq (config_top, line);
|
||||
else
|
||||
@ -326,7 +328,7 @@ vtysh_config_dump (FILE *fp)
|
||||
/* Don't print empty sections for interface/vrf. Route maps on the
|
||||
* 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))
|
||||
continue;
|
||||
|
||||
|
@ -666,12 +666,10 @@ static void daemon_send_ready(void)
|
||||
{
|
||||
static int sent = 0;
|
||||
if (!sent && gs.numdown == 0) {
|
||||
#if defined (HAVE_CUMULUS)
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w");
|
||||
fclose(fp);
|
||||
#endif
|
||||
zlog_notice
|
||||
("Watchfrr: Notifying Systemd we are up and running");
|
||||
systemd_send_started(master, 0);
|
||||
|
@ -849,6 +849,7 @@ if_up (struct interface *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 */
|
||||
if (zif->rtadv.AdvSendAdvertisements &&
|
||||
(zif->rtadv.MaxRtrAdvInterval >= 1000))
|
||||
@ -856,6 +857,7 @@ if_up (struct interface *ifp)
|
||||
zif->rtadv.inFastRexmit = 1;
|
||||
zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Install connected routes to the kernel. */
|
||||
if_install_connected (ifp);
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "zebra/rib.h"
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -25,7 +25,9 @@
|
||||
#include "zebra/irdp.h"
|
||||
#include "zebra/interface.h"
|
||||
|
||||
#if defined (HAVE_RTADV)
|
||||
void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; }
|
||||
#endif
|
||||
void irdp_config_write (struct vty *vty, struct interface *ifp) { return; }
|
||||
#ifdef HAVE_PROC_NET_DEV
|
||||
void ifstat_update_proc (void) { return; }
|
||||
|
@ -79,7 +79,7 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
|
||||
struct prefix p;
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *newrib;
|
||||
struct route_entry *newre;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
RNODE_FOREACH_RIB (rn, newrib)
|
||||
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
|
||||
&& newrib->distance != DISTANCE_INFINITY)
|
||||
zsend_redistribute_route (1, client, &rn->p, NULL, newrib);
|
||||
RNODE_FOREACH_RE (rn, newre)
|
||||
if (CHECK_FLAG (newre->flags, ZEBRA_FLAG_SELECTED)
|
||||
&& newre->distance != DISTANCE_INFINITY)
|
||||
zsend_redistribute_route (1, client, &rn->p, NULL, newre);
|
||||
|
||||
route_unlock_node (rn);
|
||||
}
|
||||
@ -108,7 +108,7 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
|
||||
static void
|
||||
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_node *rn;
|
||||
|
||||
@ -117,7 +117,7 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
|
||||
return;
|
||||
|
||||
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;
|
||||
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)
|
||||
zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, "
|
||||
"zebra_check_addr=%d", __func__,
|
||||
CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED),
|
||||
newrib->type, newrib->distance,
|
||||
CHECK_FLAG (newre->flags, ZEBRA_FLAG_SELECTED),
|
||||
newre->type, newre->distance,
|
||||
zebra_check_addr (dst_p));
|
||||
|
||||
if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED))
|
||||
if (! CHECK_FLAG (newre->flags, ZEBRA_FLAG_SELECTED))
|
||||
continue;
|
||||
if ((type != ZEBRA_ROUTE_ALL &&
|
||||
(newrib->type != type || newrib->instance != instance)))
|
||||
(newre->type != type || newre->instance != instance)))
|
||||
continue;
|
||||
if (newrib->distance == DISTANCE_INFINITY)
|
||||
if (newre->distance == DISTANCE_INFINITY)
|
||||
continue;
|
||||
if (! zebra_check_addr (dst_p))
|
||||
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 */
|
||||
void
|
||||
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 zserv *client;
|
||||
@ -158,9 +158,9 @@ redistribute_update (struct prefix *p, struct prefix *src_p,
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
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)",
|
||||
rib->vrf_id, buf, p->prefixlen, rib, rib->type,
|
||||
prev_rib, prev_rib ? prev_rib->type : -1);
|
||||
zlog_debug ("%u:%s/%d: Redist update re %p (type %d), old %p (type %d)",
|
||||
re->vrf_id, buf, p->prefixlen, re, re->type,
|
||||
prev_re, prev_re ? prev_re->type : -1);
|
||||
}
|
||||
|
||||
afi = family2afi(p->family);
|
||||
@ -174,33 +174,33 @@ redistribute_update (struct prefix *p, struct prefix *src_p,
|
||||
{
|
||||
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;
|
||||
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;
|
||||
else if (rib->instance && redist_check_instance (&client->mi_redist[afi][rib->type],
|
||||
rib->instance))
|
||||
else if (re->instance && redist_check_instance (&client->mi_redist[afi][re->type],
|
||||
re->instance))
|
||||
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;
|
||||
|
||||
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 &&
|
||||
((rib->instance &&
|
||||
redist_check_instance(&client->mi_redist[afi][prev_rib->type],
|
||||
rib->instance)) ||
|
||||
vrf_bitmap_check (client->redist[afi][prev_rib->type], rib->vrf_id)))
|
||||
else if (prev_re &&
|
||||
((re->instance &&
|
||||
redist_check_instance(&client->mi_redist[afi][prev_re->type],
|
||||
re->instance)) ||
|
||||
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
|
||||
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 zserv *client;
|
||||
@ -210,12 +210,12 @@ redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib)
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Redist delete rib %p (type %d)",
|
||||
rib->vrf_id, buf, p->prefixlen, rib, rib->type);
|
||||
zlog_debug ("%u:%s/%d: Redist delete re %p (type %d)",
|
||||
re->vrf_id, buf, p->prefixlen, re, re->type);
|
||||
}
|
||||
|
||||
/* Add DISTANCE_INFINITY check. */
|
||||
if (rib->distance == DISTANCE_INFINITY)
|
||||
if (re->distance == DISTANCE_INFINITY)
|
||||
return;
|
||||
|
||||
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))
|
||||
{
|
||||
if ((is_default (p) &&
|
||||
vrf_bitmap_check (client->redist_default, rib->vrf_id)) ||
|
||||
vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], rib->vrf_id) ||
|
||||
(rib->instance &&
|
||||
redist_check_instance(&client->mi_redist[afi][rib->type],
|
||||
rib->instance)) ||
|
||||
vrf_bitmap_check (client->redist[afi][rib->type], rib->vrf_id))
|
||||
vrf_bitmap_check (client->redist_default, re->vrf_id)) ||
|
||||
vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], re->vrf_id) ||
|
||||
(re->instance &&
|
||||
redist_check_instance(&client->mi_redist[afi][re->type],
|
||||
re->instance)) ||
|
||||
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
|
||||
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 rib *same;
|
||||
struct route_entry *newre;
|
||||
struct route_entry *same;
|
||||
struct prefix p;
|
||||
struct nexthop *nhop;
|
||||
union g_addr *gate;
|
||||
route_map_result_t ret = RMAP_MATCH;
|
||||
|
||||
if (rmap_name)
|
||||
ret = zebra_import_table_route_map_check (AFI_IP, rib->type, &rn->p, rib->nexthop, rib->vrf_id,
|
||||
rib->tag, rmap_name);
|
||||
ret = zebra_import_table_route_map_check (AFI_IP, re->type, &rn->p, re->nexthop, re->vrf_id,
|
||||
re->tag, rmap_name);
|
||||
|
||||
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.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;
|
||||
|
||||
if (same->type == rib->type && same->instance == rib->instance
|
||||
&& same->table == rib->table
|
||||
if (same->type == re->type && same->instance == re->instance
|
||||
&& same->table == re->table
|
||||
&& same->type != ZEBRA_ROUTE_CONNECT)
|
||||
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);
|
||||
|
||||
|
||||
if (rib->nexthop_num == 1)
|
||||
if (re->nexthop_num == 1)
|
||||
{
|
||||
nhop = rib->nexthop;
|
||||
nhop = re->nexthop;
|
||||
if (nhop->type == NEXTHOP_TYPE_IFINDEX)
|
||||
gate = NULL;
|
||||
else
|
||||
gate = (union g_addr *)&nhop->gate.ipv4;
|
||||
|
||||
rib_add (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
|
||||
rib->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4,
|
||||
rib_add (AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
|
||||
re->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4,
|
||||
nhop->ifindex, zebrad.rtm_table_default,
|
||||
rib->metric, rib->mtu,
|
||||
zebra_import_table_distance[AFI_IP][rib->table]);
|
||||
re->metric, re->mtu,
|
||||
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));
|
||||
newrib->type = ZEBRA_ROUTE_TABLE;
|
||||
newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
|
||||
newrib->flags = rib->flags;
|
||||
newrib->metric = rib->metric;
|
||||
newrib->mtu = rib->mtu;
|
||||
newrib->table = zebrad.rtm_table_default;
|
||||
newrib->nexthop_num = 0;
|
||||
newrib->uptime = time(NULL);
|
||||
newrib->instance = rib->table;
|
||||
newre = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
||||
newre->type = ZEBRA_ROUTE_TABLE;
|
||||
newre->distance = zebra_import_table_distance[AFI_IP][re->table];
|
||||
newre->flags = re->flags;
|
||||
newre->metric = re->metric;
|
||||
newre->mtu = re->mtu;
|
||||
newre->table = zebrad.rtm_table_default;
|
||||
newre->nexthop_num = 0;
|
||||
newre->uptime = time(NULL);
|
||||
newre->instance = re->table;
|
||||
|
||||
/* Assuming these routes are never recursive */
|
||||
for (nhop = rib->nexthop; nhop; nhop = nhop->next)
|
||||
rib_copy_nexthops(newrib, nhop);
|
||||
for (nhop = re->nexthop; nhop; nhop = nhop->next)
|
||||
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
|
||||
{
|
||||
zebra_del_import_table_entry (rn, rib);
|
||||
zebra_del_import_table_entry (rn, re);
|
||||
}
|
||||
/* DD: Add IPv6 code */
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -580,8 +580,8 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
|
||||
p.prefixlen = rn->p.prefixlen;
|
||||
p.u.prefix4 = rn->p.u.prefix4;
|
||||
|
||||
rib_delete (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
|
||||
rib->table, rib->flags, &p, NULL, NULL,
|
||||
rib_delete (AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
|
||||
re->table, re->flags, &p, NULL, NULL,
|
||||
0, zebrad.rtm_table_default);
|
||||
}
|
||||
/* 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)
|
||||
{
|
||||
struct route_table *table;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct route_node *rn;
|
||||
|
||||
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)
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rib)
|
||||
if (!re)
|
||||
continue;
|
||||
|
||||
if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
|
||||
((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
|
||||
{
|
||||
if (add)
|
||||
zebra_add_import_table_entry (rn, rib, rmap_name);
|
||||
zebra_add_import_table_entry (rn, re, rmap_name);
|
||||
else
|
||||
zebra_del_import_table_entry (rn, rib);
|
||||
zebra_del_import_table_entry (rn, re);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -713,7 +713,7 @@ zebra_import_table_rm_update ()
|
||||
afi_t afi;
|
||||
int i;
|
||||
struct route_table *table;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct route_node *rn;
|
||||
const char *rmap_name;
|
||||
|
||||
@ -736,19 +736,19 @@ zebra_import_table_rm_update ()
|
||||
if (!rn->info)
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rib)
|
||||
if (!re)
|
||||
continue;
|
||||
|
||||
if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
|
||||
((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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ extern void zebra_redistribute_default_delete (int, struct zserv *, int,
|
||||
struct zebra_vrf *zvrf);
|
||||
|
||||
extern void redistribute_update (struct prefix *, struct prefix *,
|
||||
struct rib *, struct rib *);
|
||||
extern void redistribute_delete (struct prefix *, struct prefix *, struct rib *);
|
||||
struct route_entry *, struct route_entry *);
|
||||
extern void redistribute_delete (struct prefix *, struct prefix *, struct route_entry *);
|
||||
|
||||
extern void zebra_interface_up_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);
|
||||
|
||||
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,
|
||||
struct rib *rib);
|
||||
struct route_entry *re);
|
||||
extern int is_zebra_import_table_enabled(afi_t, u_int32_t table_id);
|
||||
|
||||
extern int zebra_import_table_config(struct vty *);
|
||||
|
@ -39,9 +39,9 @@ void zebra_redistribute_default_delete (int a, struct zserv *b, int c,
|
||||
{ return; }
|
||||
|
||||
void redistribute_update (struct prefix *a, struct prefix *b,
|
||||
struct rib *c, struct rib *d)
|
||||
struct route_entry *c, struct route_entry *d)
|
||||
{ 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; }
|
||||
|
||||
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)
|
||||
{ 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; }
|
||||
|
||||
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; }
|
||||
|
||||
int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
|
||||
|
95
zebra/rib.h
95
zebra/rib.h
@ -37,11 +37,11 @@
|
||||
#define DISTANCE_INFINITY 255
|
||||
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
|
||||
|
||||
struct rib
|
||||
struct route_entry
|
||||
{
|
||||
/* Link list. */
|
||||
struct rib *next;
|
||||
struct rib *prev;
|
||||
struct route_entry *next;
|
||||
struct route_entry *prev;
|
||||
|
||||
/* Nexthop structure */
|
||||
struct nexthop *nexthop;
|
||||
@ -85,11 +85,11 @@ struct rib
|
||||
|
||||
/* RIB internal 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 */
|
||||
#define RIB_ENTRY_NEXTHOPS_CHANGED 0x2
|
||||
#define RIB_ENTRY_CHANGED 0x4
|
||||
#define RIB_ENTRY_SELECTED_FIB 0x8
|
||||
#define ROUTE_ENTRY_NEXTHOPS_CHANGED 0x2
|
||||
#define ROUTE_ENTRY_CHANGED 0x4
|
||||
#define ROUTE_ENTRY_SELECTED_FIB 0x8
|
||||
|
||||
/* Nexthop information. */
|
||||
u_char nexthop_num;
|
||||
@ -99,7 +99,7 @@ struct rib
|
||||
/* meta-queue structure:
|
||||
* sub-queue 0: connected, kernel
|
||||
* 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 4: any other origin (if any)
|
||||
*/
|
||||
@ -125,7 +125,7 @@ typedef struct rib_dest_t_
|
||||
/*
|
||||
* Doubly-linked list of routes for this prefix.
|
||||
*/
|
||||
struct rib *routes;
|
||||
struct route_entry *routes;
|
||||
|
||||
/*
|
||||
* Flags, see below.
|
||||
@ -161,22 +161,22 @@ typedef struct rib_dest_t_
|
||||
/*
|
||||
* Macro to iterate over each route for a destination (prefix).
|
||||
*/
|
||||
#define RIB_DEST_FOREACH_ROUTE(dest, rib) \
|
||||
for ((rib) = (dest) ? (dest)->routes : NULL; (rib); (rib) = (rib)->next)
|
||||
#define RE_DEST_FOREACH_ROUTE(dest, re) \
|
||||
for ((re) = (dest) ? (dest)->routes : NULL; (re); (re) = (re)->next)
|
||||
|
||||
/*
|
||||
* Same as above, but allows the current node to be unlinked.
|
||||
*/
|
||||
#define RIB_DEST_FOREACH_ROUTE_SAFE(dest, rib, next) \
|
||||
for ((rib) = (dest) ? (dest)->routes : NULL; \
|
||||
(rib) && ((next) = (rib)->next, 1); \
|
||||
(rib) = (next))
|
||||
#define RE_DEST_FOREACH_ROUTE_SAFE(dest, re, next) \
|
||||
for ((re) = (dest) ? (dest)->routes : NULL; \
|
||||
(re) && ((next) = (re)->next, 1); \
|
||||
(re) = (next))
|
||||
|
||||
#define RNODE_FOREACH_RIB(rn, rib) \
|
||||
RIB_DEST_FOREACH_ROUTE (rib_dest_from_rnode (rn), rib)
|
||||
#define RNODE_FOREACH_RE(rn, re) \
|
||||
RE_DEST_FOREACH_ROUTE (rib_dest_from_rnode (rn), re)
|
||||
|
||||
#define RNODE_FOREACH_RIB_SAFE(rn, rib, next) \
|
||||
RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next)
|
||||
#define RNODE_FOREACH_RE_SAFE(rn, re, next) \
|
||||
RE_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), re, next)
|
||||
|
||||
/* The following for loop allows to iterate over the nexthop
|
||||
* structure of routes.
|
||||
@ -283,17 +283,28 @@ typedef enum
|
||||
RIB_UPDATE_OTHER
|
||||
} rib_update_event_t;
|
||||
|
||||
extern struct nexthop *rib_nexthop_ifindex_add (struct rib *, ifindex_t);
|
||||
extern struct nexthop *rib_nexthop_blackhole_add (struct rib *);
|
||||
extern struct nexthop *rib_nexthop_ipv4_add (struct rib *, struct in_addr *,
|
||||
extern struct nexthop *route_entry_nexthop_ifindex_add (struct route_entry *, ifindex_t);
|
||||
extern struct nexthop *route_entry_nexthop_blackhole_add (struct route_entry *);
|
||||
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 *,
|
||||
extern struct nexthop *route_entry_nexthop_ipv4_ifindex_add (struct route_entry *,
|
||||
struct in_addr *,
|
||||
struct in_addr *,
|
||||
ifindex_t);
|
||||
extern void rib_nexthop_add (struct rib *rib, struct nexthop *nexthop);
|
||||
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 */
|
||||
enum multicast_mode
|
||||
{
|
||||
@ -309,13 +320,9 @@ enum multicast_mode
|
||||
extern void multicast_mode_ipv4_set (enum multicast_mode mode);
|
||||
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_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 *,
|
||||
vrf_id_t);
|
||||
#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_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_main_routing_table(u_int32_t table_id);
|
||||
extern int zebra_check_addr (struct prefix *p);
|
||||
|
||||
extern void rib_addnode (struct route_node *rn, struct rib *rib, int process);
|
||||
extern void rib_delnode (struct route_node *rn, struct rib *rib);
|
||||
extern int rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old);
|
||||
extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
|
||||
extern void rib_addnode (struct route_node *rn, struct route_entry *re, int process);
|
||||
extern void rib_delnode (struct route_node *rn, struct route_entry *re);
|
||||
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 route_entry *re);
|
||||
|
||||
/* NOTE:
|
||||
* 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);
|
||||
|
||||
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,
|
||||
u_short instance, int flags, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p, union g_addr *gate,
|
||||
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);
|
||||
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);
|
||||
|
||||
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_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 void rib_queue_add (struct route_node *rn);
|
||||
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 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 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
|
||||
* route_node.
|
||||
*/
|
||||
static inline struct rib *
|
||||
static inline struct route_entry *
|
||||
rnode_to_ribs (struct route_node *rn)
|
||||
{
|
||||
rib_dest_t *dest;
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "zebra/zebra_mpls.h"
|
||||
|
||||
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_delete_ipv4 (struct interface *, struct connected *);
|
||||
|
@ -122,7 +122,8 @@ static inline int is_selfroute(int proto)
|
||||
if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) ||
|
||||
(proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA) ||
|
||||
(proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG) ||
|
||||
(proto == RTPROT_BABEL)) {
|
||||
(proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP) ||
|
||||
(proto == RTPROT_LDP) || (proto == RTPROT_BABEL)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -154,6 +155,15 @@ static inline int get_rt_proto(int proto)
|
||||
case ZEBRA_ROUTE_RIPNG:
|
||||
proto = RTPROT_RIPNG;
|
||||
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:
|
||||
proto = RTPROT_ZEBRA;
|
||||
break;
|
||||
@ -346,22 +356,22 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
{
|
||||
/* This is a multipath route */
|
||||
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct rtnexthop *rtnh =
|
||||
(struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
|
||||
|
||||
len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
|
||||
|
||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||
rib->type = ZEBRA_ROUTE_KERNEL;
|
||||
rib->distance = 0;
|
||||
rib->flags = flags;
|
||||
rib->metric = metric;
|
||||
rib->mtu = mtu;
|
||||
rib->vrf_id = vrf_id;
|
||||
rib->table = table;
|
||||
rib->nexthop_num = 0;
|
||||
rib->uptime = time (NULL);
|
||||
re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
||||
re->type = ZEBRA_ROUTE_KERNEL;
|
||||
re->distance = 0;
|
||||
re->flags = flags;
|
||||
re->metric = metric;
|
||||
re->mtu = mtu;
|
||||
re->vrf_id = vrf_id;
|
||||
re->table = table;
|
||||
re->nexthop_num = 0;
|
||||
re->uptime = time (NULL);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -384,31 +394,31 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (rtm->rtm_family == AF_INET)
|
||||
{
|
||||
if (index)
|
||||
rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index);
|
||||
route_entry_nexthop_ipv4_ifindex_add (re, gate, prefsrc, index);
|
||||
else
|
||||
rib_nexthop_ipv4_add (rib, gate, prefsrc);
|
||||
route_entry_nexthop_ipv4_add (re, gate, prefsrc);
|
||||
}
|
||||
else if (rtm->rtm_family == AF_INET6)
|
||||
{
|
||||
if (index)
|
||||
rib_nexthop_ipv6_ifindex_add (rib, gate, index);
|
||||
route_entry_nexthop_ipv6_ifindex_add (re, gate, index);
|
||||
else
|
||||
rib_nexthop_ipv6_add (rib,gate);
|
||||
route_entry_nexthop_ipv6_add (re,gate);
|
||||
}
|
||||
}
|
||||
else
|
||||
rib_nexthop_ifindex_add (rib, index);
|
||||
route_entry_nexthop_ifindex_add (re, index);
|
||||
|
||||
len -= NLMSG_ALIGN(rtnh->rtnh_len);
|
||||
rtnh = RTNH_NEXT(rtnh);
|
||||
}
|
||||
|
||||
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
|
||||
rib->nexthop_num);
|
||||
if (rib->nexthop_num == 0)
|
||||
XFREE (MTYPE_RIB, rib);
|
||||
re->nexthop_num);
|
||||
if (re->nexthop_num == 0)
|
||||
XFREE (MTYPE_RE, re);
|
||||
else
|
||||
rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
|
||||
rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, re);
|
||||
}
|
||||
}
|
||||
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. */
|
||||
static int
|
||||
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;
|
||||
struct sockaddr_nl snl;
|
||||
@ -1193,7 +1203,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
} req;
|
||||
|
||||
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);
|
||||
|
||||
@ -1207,10 +1217,10 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
req.r.rtm_family = family;
|
||||
req.r.rtm_dst_len = p->prefixlen;
|
||||
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;
|
||||
|
||||
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
|
||||
if ((re->flags & ZEBRA_FLAG_BLACKHOLE) || (re->flags & ZEBRA_FLAG_REJECT))
|
||||
discard = 1;
|
||||
else
|
||||
discard = 0;
|
||||
@ -1219,9 +1229,9 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
{
|
||||
if (discard)
|
||||
{
|
||||
if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
|
||||
if (re->flags & ZEBRA_FLAG_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;
|
||||
else
|
||||
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);
|
||||
|
||||
/* Table corresponding to this route. */
|
||||
if (rib->table < 256)
|
||||
req.r.rtm_table = rib->table;
|
||||
if (re->table < 256)
|
||||
req.r.rtm_table = re->table;
|
||||
else
|
||||
{
|
||||
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];
|
||||
struct rtattr *rta = (void *) buf;
|
||||
u_int32_t mtu = rib->mtu;
|
||||
if (!mtu || (rib->nexthop_mtu && rib->nexthop_mtu < mtu))
|
||||
mtu = rib->nexthop_mtu;
|
||||
u_int32_t mtu = re->mtu;
|
||||
if (!mtu || (re->nexthop_mtu && re->nexthop_mtu < mtu))
|
||||
mtu = re->nexthop_mtu;
|
||||
rta->rta_type = RTA_METRICS;
|
||||
rta->rta_len = RTA_LENGTH(0);
|
||||
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 (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,
|
||||
* 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
|
||||
* or multipath case. */
|
||||
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))
|
||||
continue;
|
||||
@ -1297,7 +1307,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
if (nexthop_num == 1 || multipath_num == 1)
|
||||
{
|
||||
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))
|
||||
{
|
||||
@ -1368,7 +1378,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
rtnh = RTA_DATA (rta);
|
||||
|
||||
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)
|
||||
break;
|
||||
@ -1501,7 +1511,7 @@ kernel_get_ipmr_sg_stats (void *in)
|
||||
|
||||
int
|
||||
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)
|
||||
return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 0);
|
||||
|
@ -36,6 +36,9 @@
|
||||
#if !defined(RTPROT_BABEL)
|
||||
#define RTPROT_BABEL 42
|
||||
#endif
|
||||
#define RTPROT_NHRP 191
|
||||
#define RTPROT_EIGRP 192
|
||||
#define RTPROT_LDP 193
|
||||
|
||||
void rt_netlink_init (void);
|
||||
|
||||
|
@ -71,7 +71,7 @@ sin_masklen (struct in_addr mask)
|
||||
|
||||
/* Interface between zebra message and rtm message. */
|
||||
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;
|
||||
@ -106,7 +106,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
|
||||
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||
|
||||
/* 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))
|
||||
continue;
|
||||
@ -172,16 +172,16 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
|
||||
gate ? (union sockunion *)&sin_gate : NULL,
|
||||
smplsp,
|
||||
ifindex,
|
||||
rib->flags,
|
||||
rib->metric);
|
||||
re->flags,
|
||||
re->metric);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
if (!gate)
|
||||
{
|
||||
zlog_debug ("%s: %s: attention! gate not found for rib %p",
|
||||
__func__, prefix_buf, rib);
|
||||
rib_dump (p, NULL, rib);
|
||||
zlog_debug ("%s: %s: attention! gate not found for re %p",
|
||||
__func__, prefix_buf, re);
|
||||
route_entry_dump (p, NULL, re);
|
||||
}
|
||||
else
|
||||
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 (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*/
|
||||
}
|
||||
@ -262,7 +262,7 @@ sin6_masklen (struct in6_addr mask)
|
||||
|
||||
/* Interface between zebra message and rtm message. */
|
||||
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 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 */
|
||||
|
||||
/* 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))
|
||||
continue;
|
||||
@ -349,8 +349,8 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib)
|
||||
gate ? (union sockunion *)&sin_gate : NULL,
|
||||
NULL,
|
||||
ifindex,
|
||||
rib->flags,
|
||||
rib->metric);
|
||||
re->flags,
|
||||
re->metric);
|
||||
|
||||
#if 0
|
||||
if (error)
|
||||
@ -377,21 +377,21 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib)
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
case AF_INET:
|
||||
return kernel_rtm_ipv4 (cmd, p, rib);
|
||||
return kernel_rtm_ipv4 (cmd, p, re);
|
||||
case AF_INET6:
|
||||
return kernel_rtm_ipv6 (cmd, p, rib);
|
||||
return kernel_rtm_ipv6 (cmd, p, re);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
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;
|
||||
|
||||
|
@ -1403,8 +1403,8 @@ DEFUN (ipv6_nd_router_preference,
|
||||
"Neighbor discovery\n"
|
||||
"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;
|
||||
VTY_DECLVAR_CONTEXT (interface, ifp);
|
||||
|
@ -564,7 +564,7 @@ zfpm_conn_up_thread_cb (struct thread *thread)
|
||||
zfpm_g->stats.t_conn_up_yields++;
|
||||
zfpm_rnodes_iter_pause (iter);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
@ -598,7 +598,7 @@ zfpm_connection_up (const char *detail)
|
||||
|
||||
zfpm_debug ("Starting conn_up thread");
|
||||
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->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_rnodes_iter_pause (iter);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
@ -736,7 +736,7 @@ zfpm_connection_down (const char *detail)
|
||||
zfpm_debug ("Starting conn_down thread");
|
||||
zfpm_rnodes_iter_init (&zfpm_g->t_conn_down_state.iter);
|
||||
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->stats.t_conn_down_starts++;
|
||||
|
||||
@ -866,7 +866,7 @@ zfpm_writes_pending (void)
|
||||
* value indicates an error.
|
||||
*/
|
||||
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 len;
|
||||
@ -881,7 +881,7 @@ zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf,
|
||||
|
||||
case ZFPM_MSG_FORMAT_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);
|
||||
*msg_type = FPM_MSG_TYPE_PROTOBUF;
|
||||
#endif
|
||||
@ -890,8 +890,8 @@ zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf,
|
||||
case ZFPM_MSG_FORMAT_NETLINK:
|
||||
#ifdef HAVE_NETLINK
|
||||
*msg_type = FPM_MSG_TYPE_NETLINK;
|
||||
cmd = rib ? RTM_NEWROUTE : RTM_DELROUTE;
|
||||
len = zfpm_netlink_encode_route (cmd, dest, rib, in_buf, in_buf_len);
|
||||
cmd = re ? RTM_NEWROUTE : RTM_DELROUTE;
|
||||
len = zfpm_netlink_encode_route (cmd, dest, re, in_buf, in_buf_len);
|
||||
assert(fpm_msg_align(len) == len);
|
||||
*msg_type = FPM_MSG_TYPE_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
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
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;
|
||||
|
||||
return rib;
|
||||
return re;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -944,7 +944,7 @@ zfpm_build_updates (void)
|
||||
size_t msg_len;
|
||||
size_t data_len;
|
||||
fpm_msg_hdr_t *hdr;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
int is_add, write_msg;
|
||||
fpm_msg_type_e msg_type;
|
||||
|
||||
@ -974,8 +974,8 @@ zfpm_build_updates (void)
|
||||
|
||||
data = fpm_msg_data (hdr);
|
||||
|
||||
rib = zfpm_route_for_update (dest);
|
||||
is_add = rib ? 1 : 0;
|
||||
re = zfpm_route_for_update (dest);
|
||||
is_add = re ? 1 : 0;
|
||||
|
||||
write_msg = 1;
|
||||
|
||||
@ -990,7 +990,7 @@ zfpm_build_updates (void)
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
assert (data_len);
|
||||
|
@ -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.
|
||||
*/
|
||||
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;
|
||||
route_table_iter_t iter;
|
||||
struct route_table *table;
|
||||
rib_dest_t *dest;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
int ret;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
rib = zfpm_route_for_update(dest);
|
||||
if (!rib)
|
||||
re = zfpm_route_for_update(dest);
|
||||
if (!re)
|
||||
continue;
|
||||
|
||||
if (rib->nexthop_active_num <= 0)
|
||||
if (re->nexthop_active_num <= 0)
|
||||
continue;
|
||||
|
||||
*dest_p = dest;
|
||||
*rib_p = rib;
|
||||
*re_p = re;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
@ -117,7 +117,7 @@ zfpm_dt_benchmark_netlink_encode (int argc, const char **argv)
|
||||
{
|
||||
int times, i, len;
|
||||
rib_dest_t *dest;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
char buf[4096];
|
||||
|
||||
times = 100000;
|
||||
@ -125,12 +125,12 @@ zfpm_dt_benchmark_netlink_encode (int argc, const char **argv)
|
||||
times = atoi(argv[0]);
|
||||
}
|
||||
|
||||
if (!zfpm_dt_find_route(&dest, &rib)) {
|
||||
if (!zfpm_dt_find_route(&dest, &re)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
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) {
|
||||
return 2;
|
||||
}
|
||||
@ -150,7 +150,7 @@ zfpm_dt_benchmark_protobuf_encode (int argc, const char **argv)
|
||||
{
|
||||
int times, i, len;
|
||||
rib_dest_t *dest;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
uint8_t buf[4096];
|
||||
|
||||
times = 100000;
|
||||
@ -158,12 +158,12 @@ zfpm_dt_benchmark_protobuf_encode (int argc, const char **argv)
|
||||
times = atoi(argv[0]);
|
||||
}
|
||||
|
||||
if (!zfpm_dt_find_route(&dest, &rib)) {
|
||||
if (!zfpm_dt_find_route(&dest, &re)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
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) {
|
||||
return 2;
|
||||
}
|
||||
@ -229,7 +229,7 @@ zfpm_dt_benchmark_protobuf_decode (int argc, const char **argv)
|
||||
{
|
||||
int times, i, len;
|
||||
rib_dest_t *dest;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
uint8_t msg_buf[4096];
|
||||
QPB_DECLARE_STACK_ALLOCATOR (allocator, 8192);
|
||||
Fpm__Message *fpm_msg;
|
||||
@ -240,13 +240,13 @@ zfpm_dt_benchmark_protobuf_decode (int argc, const char **argv)
|
||||
if (argc > 0)
|
||||
times = atoi(argv[0]);
|
||||
|
||||
if (!zfpm_dt_find_route (&dest, &rib))
|
||||
if (!zfpm_dt_find_route (&dest, &re))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
return 2;
|
||||
|
||||
|
@ -231,7 +231,7 @@ netlink_proto_from_route_type (int type)
|
||||
*/
|
||||
static int
|
||||
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;
|
||||
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,
|
||||
* particularly in our communication with the FPM.
|
||||
*/
|
||||
if (cmd == RTM_DELROUTE && !rib)
|
||||
if (cmd == RTM_DELROUTE && !re)
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
else
|
||||
discard = 0;
|
||||
@ -270,9 +270,9 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
||||
{
|
||||
if (discard)
|
||||
{
|
||||
if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
|
||||
if (re->flags & ZEBRA_FLAG_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;
|
||||
else
|
||||
assert (0);
|
||||
@ -281,12 +281,12 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
||||
ri->rtm_type = RTN_UNICAST;
|
||||
}
|
||||
|
||||
ri->metric = &rib->metric;
|
||||
ri->metric = &re->metric;
|
||||
|
||||
if (discard)
|
||||
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)
|
||||
break;
|
||||
@ -474,14 +474,14 @@ zfpm_log_route_info (netlink_route_info_t *ri, const char *label)
|
||||
* value indicates an error.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
netlink_route_info_t ri_space, *ri;
|
||||
|
||||
ri = &ri_space;
|
||||
|
||||
if (!netlink_route_info_fill (ri, cmd, dest, rib))
|
||||
if (!netlink_route_info_fill (ri, cmd, dest, re))
|
||||
return 0;
|
||||
|
||||
zfpm_log_route_info (ri, __FUNCTION__);
|
||||
|
@ -49,12 +49,12 @@ static inline void zfpm_debug(const char *format, ...) { return; }
|
||||
* Externs
|
||||
*/
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
static Fpm__DeleteRoute *
|
||||
create_delete_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
struct rib *rib)
|
||||
struct route_entry *re)
|
||||
{
|
||||
Fpm__DeleteRoute *msg;
|
||||
|
||||
@ -141,7 +141,7 @@ add_nexthop (qpb_allocator_t *allocator, Fpm__AddRoute *msg, rib_dest_t *dest,
|
||||
*/
|
||||
static Fpm__AddRoute *
|
||||
create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
struct rib *rib)
|
||||
struct route_entry *re)
|
||||
{
|
||||
Fpm__AddRoute *msg;
|
||||
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->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;
|
||||
else
|
||||
discard = 0;
|
||||
|
||||
if (discard)
|
||||
{
|
||||
if (rib->flags & ZEBRA_FLAG_BLACKHOLE) {
|
||||
if (re->flags & ZEBRA_FLAG_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;
|
||||
} else {
|
||||
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->metric = rib->metric;
|
||||
msg->metric = re->metric;
|
||||
|
||||
/*
|
||||
* Figure out the set of nexthops to be added to the message.
|
||||
*/
|
||||
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)
|
||||
break;
|
||||
@ -245,7 +245,7 @@ create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
*/
|
||||
static Fpm__Message *
|
||||
create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
struct rib *rib)
|
||||
struct route_entry *re)
|
||||
{
|
||||
Fpm__Message *msg;
|
||||
|
||||
@ -257,9 +257,9 @@ create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
|
||||
fpm__message__init(msg);
|
||||
|
||||
if (!rib) {
|
||||
if (!re) {
|
||||
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) {
|
||||
assert(0);
|
||||
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->add_route = create_add_route_message(allocator, dest, rib);
|
||||
msg->add_route = create_add_route_message(allocator, dest, re);
|
||||
if (!msg->add_route) {
|
||||
assert(0);
|
||||
return NULL;
|
||||
@ -287,7 +287,7 @@ create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
* value indicates an error.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
Fpm__Message *msg;
|
||||
@ -296,7 +296,7 @@ zfpm_protobuf_encode_route (rib_dest_t *dest, struct rib *rib,
|
||||
|
||||
QPB_INIT_STACK_ALLOCATOR (allocator);
|
||||
|
||||
msg = create_route_message(&allocator, dest, rib);
|
||||
msg = create_route_message(&allocator, dest, re);
|
||||
if (!msg) {
|
||||
assert(0);
|
||||
return 0;
|
||||
|
@ -28,7 +28,7 @@
|
||||
DEFINE_MGROUP(ZEBRA, "zebra")
|
||||
DEFINE_MTYPE(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix")
|
||||
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, STATIC_ROUTE, "Static route")
|
||||
DEFINE_MTYPE(ZEBRA, RIB_DEST, "RIB destination")
|
||||
|
@ -28,7 +28,7 @@ DECLARE_MGROUP(ZEBRA)
|
||||
DECLARE_MTYPE(RTADV_PREFIX)
|
||||
DECLARE_MTYPE(ZEBRA_NS)
|
||||
DECLARE_MTYPE(ZEBRA_VRF)
|
||||
DECLARE_MTYPE(RIB)
|
||||
DECLARE_MTYPE(RE)
|
||||
DECLARE_MTYPE(RIB_QUEUE)
|
||||
DECLARE_MTYPE(STATIC_ROUTE)
|
||||
DECLARE_MTYPE(RIB_DEST)
|
||||
|
@ -65,7 +65,7 @@ static u_int32_t
|
||||
fec_derive_label_from_index (struct zebra_vrf *vrf, zebra_fec_t *fec);
|
||||
static int
|
||||
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
|
||||
lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label);
|
||||
static int
|
||||
@ -168,7 +168,7 @@ mpls_processq_init (struct zebra_t *zebra);
|
||||
*/
|
||||
static int
|
||||
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;
|
||||
zebra_ile_t tmp_ile;
|
||||
@ -184,7 +184,7 @@ lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
|
||||
if (!lsp_table)
|
||||
return -1;
|
||||
|
||||
lsp_type = lsp_type_from_rib_type (rib->type);
|
||||
lsp_type = lsp_type_from_re_type (re->type);
|
||||
added = changed = 0;
|
||||
|
||||
/* 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
|
||||
* 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. */
|
||||
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_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
afi_t afi;
|
||||
|
||||
/* 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)
|
||||
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;
|
||||
}
|
||||
|
||||
if (!rib || !zebra_rib_labeled_unicast (rib))
|
||||
if (!re || !zebra_rib_labeled_unicast (re))
|
||||
return 0;
|
||||
|
||||
if (lsp_install (zvrf, fec->label, rn, rib))
|
||||
if (lsp_install (zvrf, fec->label, rn, re))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@ -656,7 +656,7 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
|
||||
struct route_table *table;
|
||||
struct prefix_ipv4 p;
|
||||
struct route_node *rn;
|
||||
struct rib *match;
|
||||
struct route_entry *match;
|
||||
struct nexthop *match_nh;
|
||||
|
||||
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);
|
||||
|
||||
/* 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))
|
||||
continue;
|
||||
|
||||
@ -708,7 +708,7 @@ nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
|
||||
struct route_table *table;
|
||||
struct prefix_ipv6 p;
|
||||
struct route_node *rn;
|
||||
struct rib *match;
|
||||
struct route_entry *match;
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
|
||||
if (!table)
|
||||
@ -727,10 +727,10 @@ nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
|
||||
route_unlock_node (rn);
|
||||
|
||||
/* Locate a valid connected route. */
|
||||
RNODE_FOREACH_RIB (rn, match)
|
||||
RNODE_FOREACH_RE (rn, match)
|
||||
{
|
||||
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))
|
||||
break;
|
||||
}
|
||||
@ -1734,44 +1734,59 @@ mpls_processq_init (struct zebra_t *zebra)
|
||||
|
||||
/*
|
||||
* 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
|
||||
mpls_str2label (const char *label_str, u_int8_t *num_labels,
|
||||
mpls_label_t *labels)
|
||||
{
|
||||
char *endp;
|
||||
int i;
|
||||
char *ostr; // copy of label string (start)
|
||||
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;
|
||||
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')
|
||||
rc = -1;
|
||||
/* validity check */
|
||||
else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
|
||||
rc = -2;
|
||||
}
|
||||
|
||||
/* validity checks */
|
||||
if (endp == label_str)
|
||||
return -1;
|
||||
/* excess labels */
|
||||
if (!rc && i == MPLS_MAX_LABELS && lstr)
|
||||
rc = -3;
|
||||
|
||||
if (!IS_MPLS_UNRESERVED_LABEL(label))
|
||||
return -1;
|
||||
|
||||
labels[i] = label;
|
||||
if (*endp == '\0')
|
||||
if (!rc)
|
||||
{
|
||||
*num_labels = i + 1;
|
||||
return 0;
|
||||
memcpy (labels, pl, *num_labels * sizeof (mpls_label_t));
|
||||
}
|
||||
|
||||
/* Check separator. */
|
||||
if (*endp != '/')
|
||||
return -1;
|
||||
XFREE (MTYPE_TMP, ostr);
|
||||
|
||||
label_str = endp + 1;
|
||||
}
|
||||
|
||||
/* Too many labels. */
|
||||
return -1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1809,7 +1824,7 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
|
||||
* Install dynamic LSP entry.
|
||||
*/
|
||||
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;
|
||||
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)
|
||||
return 0;
|
||||
|
||||
if (lsp_install (zvrf, fec->label, rn, rib))
|
||||
if (lsp_install (zvrf, fec->label, rn, re))
|
||||
return -1;
|
||||
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
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_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct nexthop *nexthop;
|
||||
|
||||
/* Lookup table. */
|
||||
@ -2306,18 +2321,18 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
|
||||
|
||||
/* Lookup existing route */
|
||||
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;
|
||||
if (rib->distance == distance)
|
||||
if (re->distance == distance)
|
||||
break;
|
||||
}
|
||||
|
||||
if (rib == NULL)
|
||||
if (re == NULL)
|
||||
return -1;
|
||||
|
||||
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
|
||||
for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
|
||||
{
|
||||
switch (nexthop->type)
|
||||
{
|
||||
@ -2356,8 +2371,8 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
|
||||
else
|
||||
return 0;
|
||||
|
||||
SET_FLAG (rib->status, RIB_ENTRY_CHANGED);
|
||||
SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
|
||||
SET_FLAG (re->status, ROUTE_ENTRY_CHANGED);
|
||||
SET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
|
||||
rib_queue_add (rn);
|
||||
|
||||
return 0;
|
||||
@ -2534,7 +2549,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
|
||||
{
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct nexthop *nexthop;
|
||||
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))
|
||||
{
|
||||
update = 0;
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
|
||||
RNODE_FOREACH_RE (rn, re)
|
||||
for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
|
||||
if (nexthop->nh_label_type == ZEBRA_LSP_LDP)
|
||||
{
|
||||
nexthop_del_labels (nexthop);
|
||||
SET_FLAG (rib->status, RIB_ENTRY_CHANGED);
|
||||
SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
|
||||
SET_FLAG (re->status, ROUTE_ENTRY_CHANGED);
|
||||
SET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
|
||||
update = 1;
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,8 @@
|
||||
(((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 || \
|
||||
(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 */
|
||||
|
||||
@ -208,13 +210,13 @@ zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *vrf);
|
||||
* Install dynamic LSP entry.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
@ -449,9 +451,9 @@ lsp_distance (enum lsp_types_t type)
|
||||
* are converted into LSPs.
|
||||
*/
|
||||
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:
|
||||
return ZEBRA_LSP_STATIC;
|
||||
|
@ -321,8 +321,7 @@ DEFUN (ip_route_label,
|
||||
"IP gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
|
||||
NULL, NULL, argv[5]->arg);
|
||||
@ -339,8 +338,7 @@ DEFUN (ip_route_tag_label,
|
||||
"Null interface\n"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg,
|
||||
NULL, NULL, argv[7]->arg);
|
||||
@ -357,8 +355,7 @@ DEFUN (ip_route_mask_label,
|
||||
"IP gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL,
|
||||
NULL, NULL, argv[6]->arg);
|
||||
@ -376,8 +373,7 @@ DEFUN (ip_route_mask_tag_label,
|
||||
"Null interface\n"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
|
||||
{
|
||||
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"
|
||||
"Null interface\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
|
||||
argv[4]->arg, NULL, argv[6]->arg);
|
||||
@ -414,8 +409,7 @@ DEFUN (ip_route_tag_distance_label,
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
|
||||
{
|
||||
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"
|
||||
"Null interface\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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);
|
||||
@ -453,8 +446,7 @@ DEFUN (ip_route_mask_tag_distance_label,
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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);
|
||||
@ -470,8 +462,7 @@ DEFUN (no_ip_route_label,
|
||||
"IP gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
|
||||
NULL, NULL, argv[6]->arg);
|
||||
@ -489,8 +480,7 @@ DEFUN (no_ip_route_tag_label,
|
||||
"Null interface\n"
|
||||
"Tag of this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg,
|
||||
NULL, NULL, argv[8]->arg);
|
||||
@ -507,8 +497,7 @@ DEFUN (no_ip_route_mask_label,
|
||||
"IP gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL,
|
||||
NULL, NULL, argv[7]->arg);
|
||||
@ -527,8 +516,7 @@ DEFUN (no_ip_route_mask_tag_label,
|
||||
"Null interface\n"
|
||||
"Tag of this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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);
|
||||
@ -545,8 +533,7 @@ DEFUN (no_ip_route_distance_label,
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
|
||||
argv[5]->arg, NULL, argv[7]->arg);
|
||||
@ -565,8 +552,7 @@ DEFUN (no_ip_route_tag_distance_label,
|
||||
"Tag of this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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);
|
||||
@ -584,8 +570,7 @@ DEFUN (no_ip_route_mask_distance_label,
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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);
|
||||
@ -605,8 +590,7 @@ DEFUN (no_ip_route_mask_tag_distance_label,
|
||||
"Tag of this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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);
|
||||
@ -620,8 +604,7 @@ DEFUN (ipv6_route_label,
|
||||
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
||||
"IPv6 gateway address\n"
|
||||
"IPv6 gateway interface name\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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 gateway address\n"
|
||||
"IPv6 gateway interface name\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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 interface name\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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 interface name\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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 gateway address\n"
|
||||
"IPv6 gateway interface name\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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 gateway address\n"
|
||||
"IPv6 gateway interface name\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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 interface name\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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 interface name\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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"
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
"Specify label(s) for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
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
@ -48,8 +48,8 @@
|
||||
#include "zebra/interface.h"
|
||||
#include "zebra/zebra_memory.h"
|
||||
|
||||
static void free_state(vrf_id_t vrf_id, struct rib *rib, struct route_node *rn);
|
||||
static void copy_state(struct rnh *rnh, struct rib *rib,
|
||||
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 route_entry *re,
|
||||
struct route_node *rn);
|
||||
#define lookup_rnh_table(v, f) \
|
||||
({ \
|
||||
@ -61,7 +61,7 @@ static void copy_state(struct rnh *rnh, struct rib *rib,
|
||||
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,
|
||||
vrf_id_t vrf_id);
|
||||
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
|
||||
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 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;
|
||||
|
||||
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);
|
||||
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).
|
||||
*/
|
||||
static struct rib *
|
||||
static struct route_entry *
|
||||
zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type,
|
||||
struct route_node *nrn, struct rnh *rnh,
|
||||
struct route_node **prn)
|
||||
{
|
||||
struct route_table *route_table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
|
||||
*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) &&
|
||||
(is_default_prefix (&rn->p) &&
|
||||
!nh_resolve_via_default(rn->p.family)))
|
||||
rib = NULL;
|
||||
re = NULL;
|
||||
else if ((type == RNH_IMPORT_CHECK_TYPE) &&
|
||||
CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH) &&
|
||||
!prefix_same(&nrn->p, &rn->p))
|
||||
rib = NULL;
|
||||
re = NULL;
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
if (! CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
|
||||
if (! CHECK_FLAG (re->status, ROUTE_ENTRY_SELECTED_FIB))
|
||||
continue;
|
||||
|
||||
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
|
||||
{
|
||||
if (rib->type == ZEBRA_ROUTE_CONNECT)
|
||||
if (re->type == ZEBRA_ROUTE_CONNECT)
|
||||
break;
|
||||
if (rib->type == ZEBRA_ROUTE_NHRP)
|
||||
if (re->type == ZEBRA_ROUTE_NHRP)
|
||||
{
|
||||
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)
|
||||
break;
|
||||
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) &&
|
||||
(rib->type == ZEBRA_ROUTE_BGP))
|
||||
(re->type == ZEBRA_ROUTE_BGP))
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
@ -402,9 +402,9 @@ zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type,
|
||||
|
||||
/* Need to unlock route node */
|
||||
route_unlock_node(rn);
|
||||
if (rib)
|
||||
if (re)
|
||||
*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
|
||||
zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force,
|
||||
struct route_node *nrn, struct rnh *rnh,
|
||||
struct rib *rib)
|
||||
struct route_entry *re)
|
||||
{
|
||||
int state_changed = 0;
|
||||
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;
|
||||
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))
|
||||
{
|
||||
state_changed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!rib && (rnh->state != NULL))
|
||||
else if (!re && (rnh->state != NULL))
|
||||
state_changed = 1;
|
||||
|
||||
if (compare_state(rib, rnh->state))
|
||||
copy_state(rnh, rib, nrn);
|
||||
if (compare_state(re, rnh->state))
|
||||
copy_state(rnh, re, nrn);
|
||||
|
||||
if (state_changed || force)
|
||||
{
|
||||
@ -461,7 +461,7 @@ zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force,
|
||||
static void
|
||||
zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family,
|
||||
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 zserv *client;
|
||||
@ -472,7 +472,7 @@ zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family,
|
||||
if (IS_ZEBRA_DEBUG_NHT)
|
||||
{
|
||||
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
|
||||
if (prn && rib)
|
||||
if (prn && re)
|
||||
{
|
||||
prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
|
||||
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))
|
||||
{
|
||||
if (prn && rib)
|
||||
if (prn && re)
|
||||
{
|
||||
/* Apply route-map for this client to route resolving this
|
||||
* 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);
|
||||
if (num_resolving_nh)
|
||||
rnh->filtered[client->proto] = 0;
|
||||
@ -515,12 +515,12 @@ zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family,
|
||||
static void
|
||||
zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
|
||||
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;
|
||||
int num_resolving_nh = 0;
|
||||
struct route_node *static_rn;
|
||||
struct rib *srib;
|
||||
struct route_entry *sre;
|
||||
struct nexthop *nexthop;
|
||||
char bufn[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);
|
||||
}
|
||||
|
||||
if (prn && rib)
|
||||
if (prn && re)
|
||||
{
|
||||
/* Apply route-map for "static" to route resolving this
|
||||
* 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);
|
||||
if (num_resolving_nh)
|
||||
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,
|
||||
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;
|
||||
|
||||
/* Set the filter flag for the correct nexthop - static route may
|
||||
* 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)
|
||||
{
|
||||
@ -593,7 +593,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
|
||||
if (IS_ZEBRA_DEBUG_NHT)
|
||||
{
|
||||
prefix2str(&static_rn->p, bufs, INET6_ADDRSTRLEN);
|
||||
if (prn && rib)
|
||||
if (prn && re)
|
||||
zlog_debug("%u:%s: NH change %s, scheduling static route %s",
|
||||
vrfid, bufn, num_resolving_nh ?
|
||||
"" : "(filtered by route-map)", bufs);
|
||||
@ -602,8 +602,8 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
|
||||
vrfid, bufn, bufs);
|
||||
}
|
||||
|
||||
SET_FLAG(srib->status, RIB_ENTRY_CHANGED);
|
||||
SET_FLAG(srib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
|
||||
SET_FLAG(sre->status, ROUTE_ENTRY_CHANGED);
|
||||
SET_FLAG(sre->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
|
||||
}
|
||||
|
||||
rib_queue_add(static_rn);
|
||||
@ -618,7 +618,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
|
||||
static void
|
||||
zebra_rnh_eval_nexthop_entry (vrf_id_t vrfid, int family, int force,
|
||||
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;
|
||||
|
||||
@ -633,12 +633,12 @@ zebra_rnh_eval_nexthop_entry (vrf_id_t vrfid, int family, int force,
|
||||
else
|
||||
memset(&rnh->resolved_route, 0, sizeof(struct prefix));
|
||||
|
||||
copy_state(rnh, rib, nrn);
|
||||
copy_state(rnh, re, nrn);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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 rnh *rnh;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct route_node *prn;
|
||||
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;
|
||||
|
||||
/* Identify route entry (RIB) resolving this tracked entry. */
|
||||
rib = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn);
|
||||
/* Identify route entry (RE) resolving this tracked entry. */
|
||||
re = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn);
|
||||
|
||||
/* If the entry cannot be resolved and that is also the existing state,
|
||||
* there is nothing further to do.
|
||||
*/
|
||||
if (!rib && rnh->state == NULL && !force)
|
||||
if (!re && rnh->state == NULL && !force)
|
||||
return;
|
||||
|
||||
/* Process based on type of entry. */
|
||||
if (type == RNH_IMPORT_CHECK_TYPE)
|
||||
zebra_rnh_eval_import_check_entry (vrfid, family, force,
|
||||
nrn, rnh, rib);
|
||||
nrn, rnh, re);
|
||||
else
|
||||
zebra_rnh_eval_nexthop_entry (vrfid, family, force,
|
||||
nrn, rnh, prn, rib);
|
||||
nrn, rnh, prn, re);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the RIB_ENTRY_NEXTHOPS_CHANGED flag
|
||||
* from the rib entries.
|
||||
* Clear the ROUTE_ENTRY_NEXTHOPS_CHANGED flag
|
||||
* from the re entries.
|
||||
*
|
||||
* Please note we are doing this *after* we have
|
||||
* 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.
|
||||
*/
|
||||
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 rnh *rnh;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct route_node *prn;
|
||||
|
||||
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)
|
||||
UNSET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
|
||||
if (re)
|
||||
UNSET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
|
||||
}
|
||||
|
||||
/* 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
|
||||
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;
|
||||
|
||||
/* free RIB and nexthops */
|
||||
zebra_deregister_rnh_static_nexthops (vrf_id, rib->nexthop, rn);
|
||||
nexthops_free(rib->nexthop);
|
||||
XFREE (MTYPE_RIB, rib);
|
||||
/* free RE and nexthops */
|
||||
zebra_deregister_rnh_static_nexthops (vrf_id, re->nexthop, rn);
|
||||
nexthops_free(re->nexthop);
|
||||
XFREE (MTYPE_RE, re);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (rnh->state)
|
||||
@ -839,20 +839,20 @@ copy_state (struct rnh *rnh, struct rib *rib, struct route_node *rn)
|
||||
rnh->state = NULL;
|
||||
}
|
||||
|
||||
if (!rib)
|
||||
if (!re)
|
||||
return;
|
||||
|
||||
state = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||
state->type = rib->type;
|
||||
state->metric = rib->metric;
|
||||
state = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
||||
state->type = re->type;
|
||||
state->metric = re->metric;
|
||||
|
||||
for (nh = rib->nexthop; nh; nh = nh->next)
|
||||
rib_copy_nexthops(state, nh);
|
||||
for (nh = re->nexthop; nh; nh = nh->next)
|
||||
route_entry_copy_nexthops(state, nh);
|
||||
rnh->state = state;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_state (struct rib *r1, struct rib *r2)
|
||||
compare_state (struct route_entry *r1, struct route_entry *r2)
|
||||
{
|
||||
|
||||
if (!r1 && !r2)
|
||||
@ -867,7 +867,7 @@ compare_state (struct rib *r1, struct rib *r2)
|
||||
if (r1->nexthop_num != r2->nexthop_num)
|
||||
return 1;
|
||||
|
||||
if (CHECK_FLAG(r1->status, RIB_ENTRY_NEXTHOPS_CHANGED))
|
||||
if (CHECK_FLAG(r1->status, ROUTE_ENTRY_NEXTHOPS_CHANGED))
|
||||
return 1;
|
||||
|
||||
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)
|
||||
{
|
||||
struct stream *s;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
unsigned long nump;
|
||||
u_char num;
|
||||
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;
|
||||
|
||||
rn = rnh->node;
|
||||
rib = rnh->state;
|
||||
re = rnh->state;
|
||||
|
||||
/* Get output stream. */
|
||||
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);
|
||||
break;
|
||||
}
|
||||
if (rib)
|
||||
if (re)
|
||||
{
|
||||
stream_putc (s, rib->distance);
|
||||
stream_putl (s, rib->metric);
|
||||
stream_putc (s, re->distance);
|
||||
stream_putl (s, re->metric);
|
||||
num = 0;
|
||||
nump = stream_get_endp(s);
|
||||
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) ||
|
||||
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) &&
|
||||
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
||||
|
@ -37,7 +37,7 @@ struct rnh
|
||||
/* VRF identifier. */
|
||||
vrf_id_t vrf_id;
|
||||
|
||||
struct rib *state;
|
||||
struct route_entry *state;
|
||||
struct prefix resolved_route;
|
||||
struct list *client_list;
|
||||
struct list *zebra_static_route_list; /* static routes dependent on this NH */
|
||||
|
@ -1351,7 +1351,7 @@ zebra_del_import_table_route_map (afi_t afi, uint32_t table)
|
||||
}
|
||||
|
||||
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 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.vrf_id = vrf_id;
|
||||
nh_obj.source_protocol = rib_type;
|
||||
nh_obj.source_protocol = re_type;
|
||||
nh_obj.metric = 0;
|
||||
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);
|
||||
if (rmap) {
|
||||
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
|
||||
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;
|
||||
route_map_result_t ret = RMAP_MATCH;
|
||||
struct nh_rmap_obj nh_obj;
|
||||
|
||||
nh_obj.nexthop = nexthop;
|
||||
nh_obj.vrf_id = rib->vrf_id;
|
||||
nh_obj.source_protocol = rib->type;
|
||||
nh_obj.metric = rib->metric;
|
||||
nh_obj.tag = rib->tag;
|
||||
nh_obj.vrf_id = re->vrf_id;
|
||||
nh_obj.source_protocol = re->type;
|
||||
nh_obj.metric = re->metric;
|
||||
nh_obj.tag = re->tag;
|
||||
|
||||
if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
|
||||
rmap = route_map_lookup_by_name (nht_rm[family][client_proto]);
|
||||
|
@ -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,
|
||||
int client_proto,
|
||||
struct prefix *p,
|
||||
struct rib *,
|
||||
struct route_entry *,
|
||||
struct nexthop *nexthop);
|
||||
|
||||
|
||||
|
@ -143,7 +143,7 @@ ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
|
||||
static int result;
|
||||
struct route_table *table;
|
||||
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)
|
||||
return NULL;
|
||||
@ -155,7 +155,7 @@ ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
|
||||
/* Return number of routing entries. */
|
||||
result = 0;
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
RNODE_FOREACH_RE (rn, re)
|
||||
result++;
|
||||
|
||||
return (u_char *)&result;
|
||||
@ -168,7 +168,7 @@ ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
|
||||
static int result;
|
||||
struct route_table *table;
|
||||
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)
|
||||
return NULL;
|
||||
@ -180,7 +180,7 @@ ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
|
||||
/* Return number of routing entries. */
|
||||
result = 0;
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
RNODE_FOREACH_RE (rn, re)
|
||||
result++;
|
||||
|
||||
return (u_char *)&result;
|
||||
@ -256,15 +256,15 @@ proto_trans(int type)
|
||||
}
|
||||
|
||||
static void
|
||||
check_replace(struct route_node *np2, struct rib *rib2,
|
||||
struct route_node **np, struct rib **rib)
|
||||
check_replace(struct route_node *np2, struct route_entry *re2,
|
||||
struct route_node **np, struct route_entry **re)
|
||||
{
|
||||
int proto, proto2;
|
||||
|
||||
if (!*np)
|
||||
{
|
||||
*np = np2;
|
||||
*rib = rib2;
|
||||
*re = re2;
|
||||
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)
|
||||
{
|
||||
*np = np2;
|
||||
*rib = rib2;
|
||||
*re = re2;
|
||||
return;
|
||||
}
|
||||
|
||||
proto = proto_trans((*rib)->type);
|
||||
proto2 = proto_trans(rib2->type);
|
||||
proto = proto_trans((*re)->type);
|
||||
proto2 = proto_trans(re2->type);
|
||||
|
||||
if (proto2 > proto)
|
||||
return;
|
||||
if (proto2 < proto)
|
||||
{
|
||||
*np = np2;
|
||||
*rib = rib2;
|
||||
*re = re2;
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,
|
||||
(u_char *)&rib2->nexthop->gate.ipv4) <= 0)
|
||||
if (in_addr_cmp((u_char *)&(*re)->nexthop->gate.ipv4,
|
||||
(u_char *)&re2->nexthop->gate.ipv4) <= 0)
|
||||
return;
|
||||
|
||||
*np = np2;
|
||||
*rib = rib2;
|
||||
*re = re2;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
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 route_table *table;
|
||||
struct route_node *np2;
|
||||
struct rib *rib2;
|
||||
struct route_entry *re2;
|
||||
int proto;
|
||||
int policy;
|
||||
struct in_addr nexthop;
|
||||
@ -328,7 +328,7 @@ get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
|
||||
/* Init return variables */
|
||||
|
||||
*np = NULL;
|
||||
*rib = NULL;
|
||||
*re = NULL;
|
||||
|
||||
/* 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))
|
||||
{
|
||||
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))
|
||||
if (proto == proto_trans((*rib)->type))
|
||||
if (proto == proto_trans((*re)->type))
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -393,34 +393,34 @@ get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
|
||||
|
||||
/* Check destination first */
|
||||
if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0)
|
||||
RNODE_FOREACH_RIB (np2, rib2)
|
||||
check_replace(np2, rib2, np, rib);
|
||||
RNODE_FOREACH_RE (np2, re2)
|
||||
check_replace(np2, re2, np, re);
|
||||
|
||||
if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0)
|
||||
{ /* have to look at each rib individually */
|
||||
RNODE_FOREACH_RIB (np2, rib2)
|
||||
{ /* have to look at each re individually */
|
||||
RNODE_FOREACH_RE (np2, re2)
|
||||
{
|
||||
int proto2, policy2;
|
||||
|
||||
proto2 = proto_trans(rib2->type);
|
||||
proto2 = proto_trans(re2->type);
|
||||
policy2 = 0;
|
||||
|
||||
if ((policy < policy2)
|
||||
|| ((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)
|
||||
))
|
||||
check_replace(np2, rib2, np, rib);
|
||||
check_replace(np2, re2, np, re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!*rib)
|
||||
if (!*re)
|
||||
return;
|
||||
|
||||
policy = 0;
|
||||
proto = proto_trans((*rib)->type);
|
||||
proto = proto_trans((*re)->type);
|
||||
|
||||
*objid_len = v->namelen + 10;
|
||||
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;
|
||||
|
||||
nexthop = (*rib)->nexthop;
|
||||
nexthop = (*re)->nexthop;
|
||||
if (nexthop)
|
||||
{
|
||||
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)
|
||||
{
|
||||
struct route_node *np;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
static int result;
|
||||
static int resarr[2];
|
||||
static struct in_addr netmask;
|
||||
@ -460,11 +460,11 @@ ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
|
||||
== MATCH_FAILED)
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
nexthop = rib->nexthop;
|
||||
nexthop = re->nexthop;
|
||||
if (! nexthop)
|
||||
return NULL;
|
||||
|
||||
@ -501,7 +501,7 @@ ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
|
||||
return (u_char *)&result;
|
||||
break;
|
||||
case IPFORWARDPROTO:
|
||||
result = proto_trans(rib->type);
|
||||
result = proto_trans(re->type);
|
||||
*val_len = sizeof(int);
|
||||
return (u_char *)&result;
|
||||
break;
|
||||
|
@ -40,7 +40,7 @@ void
|
||||
static_install_route (afi_t afi, safi_t safi, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p, struct static_route *si)
|
||||
{
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct route_node *rn;
|
||||
struct route_table *table;
|
||||
struct prefix nh_p;
|
||||
@ -55,20 +55,20 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
|
||||
|
||||
/* Lookup existing route */
|
||||
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;
|
||||
|
||||
if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
|
||||
if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance)
|
||||
break;
|
||||
}
|
||||
|
||||
if (rib)
|
||||
if (re)
|
||||
{
|
||||
/* if tag value changed , update old value in RIB */
|
||||
if (rib->tag != si->tag)
|
||||
rib->tag = si->tag;
|
||||
if (re->tag != si->tag)
|
||||
re->tag = si->tag;
|
||||
|
||||
/* Same distance static route is there. Update it with new
|
||||
nexthop. */
|
||||
@ -76,27 +76,27 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
|
||||
switch (si->type)
|
||||
{
|
||||
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.prefixlen = IPV4_MAX_BITLEN;
|
||||
nh_p.u.prefix4 = si->addr.ipv4;
|
||||
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
|
||||
break;
|
||||
case STATIC_IFINDEX:
|
||||
nexthop = rib_nexthop_ifindex_add (rib, si->ifindex);
|
||||
nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex);
|
||||
break;
|
||||
case STATIC_BLACKHOLE:
|
||||
nexthop = rib_nexthop_blackhole_add (rib);
|
||||
nexthop = route_entry_nexthop_blackhole_add (re);
|
||||
break;
|
||||
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.prefixlen = IPV6_MAX_BITLEN;
|
||||
nh_p.u.prefix6 = si->addr.ipv6;
|
||||
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@ -111,8 +111,8 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)",
|
||||
si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
|
||||
zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)",
|
||||
si->vrf_id, buf, p->prefixlen, rn, re, re->type);
|
||||
}
|
||||
}
|
||||
/* 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
|
||||
{
|
||||
/* 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;
|
||||
rib->instance = 0;
|
||||
rib->distance = si->distance;
|
||||
rib->metric = 0;
|
||||
rib->mtu = 0;
|
||||
rib->vrf_id = si->vrf_id;
|
||||
rib->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default;
|
||||
rib->nexthop_num = 0;
|
||||
rib->tag = si->tag;
|
||||
re->type = ZEBRA_ROUTE_STATIC;
|
||||
re->instance = 0;
|
||||
re->distance = si->distance;
|
||||
re->metric = 0;
|
||||
re->mtu = 0;
|
||||
re->vrf_id = si->vrf_id;
|
||||
re->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default;
|
||||
re->nexthop_num = 0;
|
||||
re->tag = si->tag;
|
||||
|
||||
switch (si->type)
|
||||
{
|
||||
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.prefixlen = IPV4_MAX_BITLEN;
|
||||
nh_p.u.prefix4 = si->addr.ipv4;
|
||||
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
|
||||
break;
|
||||
case STATIC_IFINDEX:
|
||||
nexthop = rib_nexthop_ifindex_add (rib, si->ifindex);
|
||||
nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex);
|
||||
break;
|
||||
case STATIC_BLACKHOLE:
|
||||
nexthop = rib_nexthop_blackhole_add (rib);
|
||||
nexthop = route_entry_nexthop_blackhole_add (re);
|
||||
break;
|
||||
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.prefixlen = IPV6_MAX_BITLEN;
|
||||
nh_p.u.prefix6 = si->addr.ipv6;
|
||||
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@ -170,7 +170,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p,
|
||||
&si->snh_label.label[0]);
|
||||
|
||||
/* Save the flags of this static routes (reject, blackhole) */
|
||||
rib->flags = si->flags;
|
||||
re->flags = si->flags;
|
||||
|
||||
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)
|
||||
{
|
||||
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d)",
|
||||
si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
|
||||
zlog_debug ("%u:%s/%d: Inserting route rn %p, re %p (type %d)",
|
||||
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.
|
||||
*/
|
||||
if (si->type == STATIC_IPV4_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);
|
||||
}
|
||||
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 route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct nexthop *nexthop;
|
||||
struct route_table *table;
|
||||
struct prefix nh_p;
|
||||
@ -245,24 +245,24 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
|
||||
if (! rn)
|
||||
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;
|
||||
|
||||
if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
|
||||
rib->tag == si->tag)
|
||||
if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance &&
|
||||
re->tag == si->tag)
|
||||
break;
|
||||
}
|
||||
|
||||
if (! rib)
|
||||
if (! re)
|
||||
{
|
||||
route_unlock_node (rn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lookup nexthop. */
|
||||
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
|
||||
for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
|
||||
if (static_nexthop_same (nexthop, si))
|
||||
break;
|
||||
|
||||
@ -274,8 +274,8 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
|
||||
}
|
||||
|
||||
/* Check nexthop. */
|
||||
if (rib->nexthop_num == 1)
|
||||
rib_delnode (rn, rib);
|
||||
if (re->nexthop_num == 1)
|
||||
rib_delnode (rn, re);
|
||||
else
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)",
|
||||
si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
|
||||
zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)",
|
||||
si->vrf_id, buf, p->prefixlen, rn, re, re->type);
|
||||
}
|
||||
}
|
||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||
{
|
||||
/* 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 */
|
||||
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
|
||||
rib_install_kernel (rn, rib, rib);
|
||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
|
||||
rib_install_kernel (rn, re, re);
|
||||
/* Update redistribution if it's selected */
|
||||
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
redistribute_update (p, (struct prefix*)src_p, rib, NULL);
|
||||
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
|
||||
redistribute_update (p, (struct prefix*)src_p, re, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove from redistribute if selected route becomes inactive */
|
||||
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
redistribute_delete (p, (struct prefix*)src_p, rib);
|
||||
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
|
||||
redistribute_delete (p, (struct prefix*)src_p, re);
|
||||
/* Remove from kernel if fib route becomes inactive */
|
||||
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
|
||||
rib_uninstall_kernel (rn, rib);
|
||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
|
||||
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.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);
|
||||
nexthop_free (nexthop);
|
||||
}
|
||||
|
@ -334,10 +334,10 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
|
||||
static void
|
||||
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)
|
||||
rib_unlink (node, rib);
|
||||
RNODE_FOREACH_RE_SAFE (node, re, next)
|
||||
rib_unlink (node, re);
|
||||
|
||||
if (node->info)
|
||||
XFREE (MTYPE_RIB_DEST, node->info);
|
||||
|
@ -126,10 +126,24 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (mpls_str2label (label_str, &snh_label.num_labels,
|
||||
snh_label.label))
|
||||
int rc = mpls_str2label (label_str, &snh_label.num_labels,
|
||||
snh_label.label);
|
||||
if (rc < 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -321,7 +335,7 @@ DEFUN (show_ip_rpf_addr,
|
||||
int idx_ipv4 = 3;
|
||||
struct in_addr addr;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
int ret;
|
||||
|
||||
ret = inet_aton (argv[idx_ipv4]->arg, &addr);
|
||||
@ -331,9 +345,9 @@ DEFUN (show_ip_rpf_addr,
|
||||
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);
|
||||
else
|
||||
vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE);
|
||||
@ -421,8 +435,7 @@ DEFUN (ip_route_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4_prefixlen = 2;
|
||||
int idx_reject_blackhole = 3;
|
||||
@ -455,8 +468,7 @@ DEFUN (ip_route_mask,
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4 = 2;
|
||||
int idx_ipv4_2 = 3;
|
||||
@ -487,8 +499,7 @@ DEFUN (ip_route_mask_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4 = 2;
|
||||
int idx_ipv4_2 = 3;
|
||||
@ -521,8 +532,7 @@ DEFUN (no_ip_route,
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4_prefixlen = 3;
|
||||
int idx_ipv4_ifname_null = 4;
|
||||
@ -553,8 +563,7 @@ DEFUN (no_ip_route_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4_prefixlen = 3;
|
||||
int idx_curr = 5;
|
||||
@ -584,8 +593,7 @@ DEFUN (no_ip_route_mask,
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4 = 3;
|
||||
int idx_ipv4_2 = 4;
|
||||
@ -618,8 +626,7 @@ DEFUN (no_ip_route_mask_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4 = 3;
|
||||
int idx_ipv4_2 = 4;
|
||||
@ -640,13 +647,13 @@ DEFUN (no_ip_route_mask_flags,
|
||||
static void
|
||||
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;
|
||||
int recursing;
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
RNODE_FOREACH_RE (rn, re)
|
||||
{
|
||||
const char *mcast_info = "";
|
||||
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",
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info,
|
||||
VTY_NEWLINE);
|
||||
vty_out (vty, " Known via \"%s", zebra_route_string (rib->type));
|
||||
if (rib->instance)
|
||||
vty_out (vty, "[%d]", rib->instance);
|
||||
vty_out (vty, " Known via \"%s", zebra_route_string (re->type));
|
||||
if (re->instance)
|
||||
vty_out (vty, "[%d]", re->instance);
|
||||
vty_out (vty, "\"");
|
||||
vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
|
||||
if (rib->tag)
|
||||
vty_out (vty, ", tag %d", rib->tag);
|
||||
if (rib->mtu)
|
||||
vty_out (vty, ", mtu %u", rib->mtu);
|
||||
if (rib->vrf_id != VRF_DEFAULT)
|
||||
vty_out (vty, ", distance %u, metric %u", re->distance, re->metric);
|
||||
if (re->tag)
|
||||
vty_out (vty, ", tag %d", re->tag);
|
||||
if (re->mtu)
|
||||
vty_out (vty, ", mtu %u", re->mtu);
|
||||
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));
|
||||
}
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
|
||||
vty_out (vty, ", best");
|
||||
if (rib->refcnt)
|
||||
vty_out (vty, ", refcnt %ld", rib->refcnt);
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
|
||||
if (re->refcnt)
|
||||
vty_out (vty, ", refcnt %ld", re->refcnt);
|
||||
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_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, "%s", VTY_NEWLINE);
|
||||
|
||||
if (rib->type == ZEBRA_ROUTE_RIP
|
||||
|| rib->type == ZEBRA_ROUTE_OSPF
|
||||
|| rib->type == ZEBRA_ROUTE_ISIS
|
||||
|| rib->type == ZEBRA_ROUTE_NHRP
|
||||
|| rib->type == ZEBRA_ROUTE_TABLE
|
||||
|| rib->type == ZEBRA_ROUTE_BGP)
|
||||
if (re->type == ZEBRA_ROUTE_RIP
|
||||
|| re->type == ZEBRA_ROUTE_OSPF
|
||||
|| re->type == ZEBRA_ROUTE_ISIS
|
||||
|| re->type == ZEBRA_ROUTE_NHRP
|
||||
|| re->type == ZEBRA_ROUTE_TABLE
|
||||
|| re->type == ZEBRA_ROUTE_BGP)
|
||||
{
|
||||
time_t uptime;
|
||||
struct tm *tm;
|
||||
|
||||
uptime = time (NULL);
|
||||
uptime -= rib->uptime;
|
||||
uptime -= re->uptime;
|
||||
tm = gmtime (&uptime);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
|
||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
||||
{
|
||||
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));
|
||||
if (nexthop->ifindex)
|
||||
vty_out (vty, ", via %s",
|
||||
ifindex2ifname (nexthop->ifindex, rib->vrf_id));
|
||||
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
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));
|
||||
if (nexthop->ifindex)
|
||||
vty_out (vty, ", via %s",
|
||||
ifindex2ifname (nexthop->ifindex, rib->vrf_id));
|
||||
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
||||
break;
|
||||
case NEXTHOP_TYPE_IFINDEX:
|
||||
vty_out (vty, " directly connected, %s",
|
||||
ifindex2ifname (nexthop->ifindex, rib->vrf_id));
|
||||
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
||||
break;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
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
|
||||
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)
|
||||
{
|
||||
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_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)
|
||||
json_object_int_add(json_route, "instance", rib->instance);
|
||||
if (re->instance)
|
||||
json_object_int_add(json_route, "instance", re->instance);
|
||||
|
||||
if (rib->vrf_id)
|
||||
json_object_int_add(json_route, "vrfId", rib->vrf_id);
|
||||
if (re->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");
|
||||
|
||||
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, "metric", rib->metric);
|
||||
json_object_int_add(json_route, "distance", re->distance);
|
||||
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");
|
||||
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
|
||||
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
|
||||
json_object_boolean_true_add(json_route, "reject");
|
||||
|
||||
if (rib->type == ZEBRA_ROUTE_RIP
|
||||
|| rib->type == ZEBRA_ROUTE_OSPF
|
||||
|| rib->type == ZEBRA_ROUTE_ISIS
|
||||
|| rib->type == ZEBRA_ROUTE_NHRP
|
||||
|| rib->type == ZEBRA_ROUTE_TABLE
|
||||
|| rib->type == ZEBRA_ROUTE_BGP)
|
||||
if (re->type == ZEBRA_ROUTE_RIP
|
||||
|| re->type == ZEBRA_ROUTE_OSPF
|
||||
|| re->type == ZEBRA_ROUTE_ISIS
|
||||
|| re->type == ZEBRA_ROUTE_NHRP
|
||||
|| re->type == ZEBRA_ROUTE_TABLE
|
||||
|| re->type == ZEBRA_ROUTE_BGP)
|
||||
{
|
||||
time_t uptime;
|
||||
struct tm *tm;
|
||||
|
||||
uptime = time (NULL);
|
||||
uptime -= rib->uptime;
|
||||
uptime -= re->uptime;
|
||||
tm = gmtime (&uptime);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
|
||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
case NEXTHOP_TYPE_IFINDEX:
|
||||
json_object_boolean_true_add(json_nexthop, "directlyConnected");
|
||||
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;
|
||||
case NEXTHOP_TYPE_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. */
|
||||
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. */
|
||||
len = vty_out (vty, "%c", zebra_route_char (rib->type));
|
||||
if (rib->instance)
|
||||
len += vty_out (vty, "[%d]", rib->instance);
|
||||
len = vty_out (vty, "%c", zebra_route_char (re->type));
|
||||
if (re->instance)
|
||||
len += vty_out (vty, "[%d]", re->instance);
|
||||
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)
|
||||
? '*' : ' ',
|
||||
srcdest_rnode2str (rn, buf, sizeof buf));
|
||||
|
||||
/* Distance and metric display. */
|
||||
if (rib->type != ZEBRA_ROUTE_CONNECT
|
||||
&& rib->type != ZEBRA_ROUTE_KERNEL)
|
||||
len += vty_out (vty, " [%d/%d]", rib->distance,
|
||||
rib->metric);
|
||||
if (re->type != ZEBRA_ROUTE_CONNECT
|
||||
&& re->type != ZEBRA_ROUTE_KERNEL)
|
||||
len += vty_out (vty, " [%d/%d]", re->distance,
|
||||
re->metric);
|
||||
}
|
||||
else
|
||||
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));
|
||||
if (nexthop->ifindex)
|
||||
vty_out (vty, ", %s",
|
||||
ifindex2ifname (nexthop->ifindex, rib->vrf_id));
|
||||
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
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));
|
||||
if (nexthop->ifindex)
|
||||
vty_out (vty, ", %s",
|
||||
ifindex2ifname (nexthop->ifindex, rib->vrf_id));
|
||||
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
||||
break;
|
||||
|
||||
case NEXTHOP_TYPE_IFINDEX:
|
||||
vty_out (vty, " is directly connected, %s",
|
||||
ifindex2ifname (nexthop->ifindex, rib->vrf_id));
|
||||
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
||||
break;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
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));
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
|
||||
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
|
||||
vty_out (vty, ", bh");
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
|
||||
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
|
||||
vty_out (vty, ", rej");
|
||||
|
||||
if (rib->type == ZEBRA_ROUTE_RIP
|
||||
|| rib->type == ZEBRA_ROUTE_OSPF
|
||||
|| rib->type == ZEBRA_ROUTE_ISIS
|
||||
|| rib->type == ZEBRA_ROUTE_NHRP
|
||||
|| rib->type == ZEBRA_ROUTE_TABLE
|
||||
|| rib->type == ZEBRA_ROUTE_BGP)
|
||||
if (re->type == ZEBRA_ROUTE_RIP
|
||||
|| re->type == ZEBRA_ROUTE_OSPF
|
||||
|| re->type == ZEBRA_ROUTE_ISIS
|
||||
|| re->type == ZEBRA_ROUTE_NHRP
|
||||
|| re->type == ZEBRA_ROUTE_TABLE
|
||||
|| re->type == ZEBRA_ROUTE_BGP)
|
||||
{
|
||||
time_t uptime;
|
||||
struct tm *tm;
|
||||
|
||||
uptime = time (NULL);
|
||||
uptime -= rib->uptime;
|
||||
uptime -= re->uptime;
|
||||
tm = gmtime (&uptime);
|
||||
|
||||
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_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
int first = 1;
|
||||
struct zebra_vrf *zvrf = NULL;
|
||||
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. */
|
||||
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;
|
||||
|
||||
if (tag && rib->tag != tag)
|
||||
if (tag && re->tag != tag)
|
||||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (type && rib->type != type)
|
||||
if (type && re->type != type)
|
||||
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;
|
||||
|
||||
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)
|
||||
@ -1569,7 +1576,7 @@ static void
|
||||
vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
|
||||
#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 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 (&fib_cnt, 0, sizeof(fib_cnt));
|
||||
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 &&
|
||||
CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP));
|
||||
is_ibgp = (re->type == ZEBRA_ROUTE_BGP &&
|
||||
CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP));
|
||||
|
||||
rib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
||||
if (is_ibgp)
|
||||
rib_cnt[ZEBRA_ROUTE_IBGP]++;
|
||||
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]++;
|
||||
|
||||
if (is_ibgp)
|
||||
fib_cnt[ZEBRA_ROUTE_IBGP]++;
|
||||
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)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct nexthop *nexthop;
|
||||
#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
|
||||
#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 (&fib_cnt, 0, sizeof(fib_cnt));
|
||||
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.
|
||||
*/
|
||||
cnt = 0;
|
||||
for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
|
||||
for (nexthop = re->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
|
||||
{
|
||||
cnt++;
|
||||
rib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
||||
rib_cnt[rib->type]++;
|
||||
rib_cnt[re->type]++;
|
||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||
{
|
||||
fib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
||||
fib_cnt[rib->type]++;
|
||||
fib_cnt[re->type]++;
|
||||
}
|
||||
if (rib->type == ZEBRA_ROUTE_BGP &&
|
||||
CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
|
||||
if (re->type == ZEBRA_ROUTE_BGP &&
|
||||
CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP))
|
||||
{
|
||||
rib_cnt[ZEBRA_ROUTE_IBGP]++;
|
||||
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);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (mpls_str2label (label_str, &snh_label.num_labels,
|
||||
snh_label.label))
|
||||
int rc = mpls_str2label (label_str, &snh_label.num_labels,
|
||||
snh_label.label);
|
||||
if (rc < 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -2153,13 +2174,11 @@ DEFUN (ipv6_route,
|
||||
"IPv6 gateway address\n"
|
||||
"IPv6 gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Null interface\n"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 2;
|
||||
int idx_ipv6_ifname;
|
||||
@ -2207,8 +2226,7 @@ DEFUN (ipv6_route_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 2;
|
||||
int idx_ipv6_ifname;
|
||||
@ -2257,8 +2275,7 @@ DEFUN (ipv6_route_ifname,
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 2;
|
||||
int idx_ipv6 = 3;
|
||||
@ -2309,8 +2326,7 @@ DEFUN (ipv6_route_ifname_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 2;
|
||||
int idx_ipv6;
|
||||
@ -2364,8 +2380,7 @@ DEFUN (no_ipv6_route,
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 3;
|
||||
int idx_ipv6_ifname;
|
||||
@ -2413,8 +2428,7 @@ DEFUN (no_ipv6_route_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 3;
|
||||
int idx_ipv6_ifname;
|
||||
@ -2464,8 +2478,7 @@ DEFUN (no_ipv6_route_ifname,
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 3;
|
||||
int idx_ipv6;
|
||||
@ -2517,8 +2530,7 @@ DEFUN (no_ipv6_route_ifname_flags,
|
||||
"Tag value\n"
|
||||
"Distance value for this prefix\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Specify labels for this route\n"
|
||||
"One or more labels separated by '/'\n")
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv6_prefixlen = 3;
|
||||
int idx_ipv6;
|
||||
@ -2820,7 +2832,7 @@ DEFUN (show_ipv6_mroute,
|
||||
{
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
int first = 1;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
@ -2833,14 +2845,14 @@ DEFUN (show_ipv6_mroute,
|
||||
|
||||
/* Show all IPv6 route. */
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
RNODE_FOREACH_RE (rn, re)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
||||
first = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
vty_show_ip_route (vty, rn, re, NULL);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -2963,7 +2975,7 @@ DEFUN (show_ipv6_mroute_vrf_all,
|
||||
{
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
int first = 1;
|
||||
@ -2976,14 +2988,14 @@ DEFUN (show_ipv6_mroute_vrf_all,
|
||||
|
||||
/* Show all IPv6 route. */
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
RNODE_FOREACH_RE (rn, re)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
||||
first = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
vty_show_ip_route (vty, rn, re, NULL);
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
|
175
zebra/zserv.c
175
zebra/zserv.c
@ -192,6 +192,11 @@ zserv_encode_interface (struct stream *s, struct interface *ifp)
|
||||
static void
|
||||
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. */
|
||||
stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ);
|
||||
|
||||
@ -608,7 +613,7 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
|
||||
*/
|
||||
int
|
||||
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;
|
||||
int cmd;
|
||||
@ -658,12 +663,12 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
|
||||
stream_reset (s);
|
||||
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. */
|
||||
stream_putc (s, rib->type);
|
||||
stream_putw (s, rib->instance);
|
||||
stream_putl (s, rib->flags);
|
||||
stream_putc (s, re->type);
|
||||
stream_putw (s, re->instance);
|
||||
stream_putl (s, re->flags);
|
||||
|
||||
/* marker for message flags field */
|
||||
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);
|
||||
}
|
||||
|
||||
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 */
|
||||
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_IFINDEX);
|
||||
@ -764,22 +769,22 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
|
||||
|
||||
/* Distance */
|
||||
SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
|
||||
stream_putc (s, rib->distance);
|
||||
stream_putc (s, re->distance);
|
||||
|
||||
/* Metric */
|
||||
SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
|
||||
stream_putl (s, rib->metric);
|
||||
stream_putl (s, re->metric);
|
||||
|
||||
/* Tag */
|
||||
if (rib->tag)
|
||||
if (re->tag)
|
||||
{
|
||||
SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
|
||||
stream_putl(s, rib->tag);
|
||||
stream_putl(s, re->tag);
|
||||
}
|
||||
|
||||
/* MTU */
|
||||
SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
|
||||
stream_putl (s, rib->mtu);
|
||||
stream_putl (s, re->mtu);
|
||||
|
||||
/* write real message flags value */
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
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));
|
||||
stream_put_in_addr (s, &addr);
|
||||
|
||||
if (rib)
|
||||
if (re)
|
||||
{
|
||||
stream_putc (s, rib->distance);
|
||||
stream_putl (s, rib->metric);
|
||||
stream_putc (s, re->distance);
|
||||
stream_putl (s, re->metric);
|
||||
num = 0;
|
||||
nump = stream_get_endp(s); /* remember position for nexthop_num */
|
||||
stream_putc (s, 0); /* reserve room for nexthop_num */
|
||||
/* Only non-recursive routes are elegible to resolve the nexthop we
|
||||
* are looking up. Therefore, we will just iterate over the top
|
||||
* 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))
|
||||
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. */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
static int
|
||||
zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
int i;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
struct prefix p;
|
||||
u_char message;
|
||||
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. */
|
||||
s = client->ibuf;
|
||||
|
||||
/* Allocate new rib. */
|
||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||
/* Allocate new re. */
|
||||
re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
||||
|
||||
/* Type, flags, message. */
|
||||
rib->type = stream_getc (s);
|
||||
rib->instance = stream_getw (s);
|
||||
rib->flags = stream_getl (s);
|
||||
re->type = stream_getc (s);
|
||||
re->instance = stream_getw (s);
|
||||
re->flags = stream_getl (s);
|
||||
message = stream_getc (s);
|
||||
safi = stream_getw (s);
|
||||
rib->uptime = time (NULL);
|
||||
re->uptime = time (NULL);
|
||||
|
||||
/* IPv4 prefix. */
|
||||
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));
|
||||
|
||||
/* VRF ID */
|
||||
rib->vrf_id = zvrf_id (zvrf);
|
||||
re->vrf_id = zvrf_id (zvrf);
|
||||
|
||||
/* Nexthop parse. */
|
||||
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:
|
||||
ifindex = stream_getl (s);
|
||||
rib_nexthop_ifindex_add (rib, ifindex);
|
||||
route_entry_nexthop_ifindex_add (re, ifindex);
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV4:
|
||||
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. */
|
||||
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:
|
||||
nhop_addr.s_addr = stream_get_ipv4 (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;
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
stream_forward_getp (s, IPV6_MAX_BYTELEN);
|
||||
break;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
rib_nexthop_blackhole_add (rib);
|
||||
route_entry_nexthop_blackhole_add (re);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1255,27 +1260,27 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
|
||||
/* Distance. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
|
||||
rib->distance = stream_getc (s);
|
||||
re->distance = stream_getc (s);
|
||||
|
||||
/* Metric. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
||||
rib->metric = stream_getl (s);
|
||||
re->metric = stream_getl (s);
|
||||
|
||||
/* Tag */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
|
||||
rib->tag = stream_getl (s);
|
||||
re->tag = stream_getl (s);
|
||||
else
|
||||
rib->tag = 0;
|
||||
re->tag = 0;
|
||||
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
|
||||
rib->mtu = stream_getl (s);
|
||||
re->mtu = stream_getl (s);
|
||||
else
|
||||
rib->mtu = 0;
|
||||
re->mtu = 0;
|
||||
|
||||
/* 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 */
|
||||
if (ret > 0)
|
||||
@ -1384,11 +1389,11 @@ static int
|
||||
zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
struct in_addr addr;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
|
||||
addr.s_addr = stream_get_ipv4 (client->ibuf);
|
||||
rib = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL);
|
||||
return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf);
|
||||
re = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL);
|
||||
return zsend_ipv4_nexthop_lookup_mrib (client, addr, re, zvrf);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
struct stream *s;
|
||||
struct in6_addr nhop_addr;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
u_char message;
|
||||
u_char nexthop_num;
|
||||
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));
|
||||
|
||||
/* Allocate new rib. */
|
||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||
/* Allocate new re. */
|
||||
re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
||||
|
||||
/* Type, flags, message. */
|
||||
rib->type = stream_getc (s);
|
||||
rib->instance = stream_getw (s);
|
||||
rib->flags = stream_getl (s);
|
||||
re->type = stream_getc (s);
|
||||
re->instance = stream_getw (s);
|
||||
re->flags = stream_getl (s);
|
||||
message = stream_getc (s);
|
||||
safi = stream_getw (s);
|
||||
rib->uptime = time (NULL);
|
||||
re->uptime = time (NULL);
|
||||
|
||||
/* IPv4 prefix. */
|
||||
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));
|
||||
|
||||
/* 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
|
||||
* 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
|
||||
* next-hop-addr/next-hop-ifindices. */
|
||||
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;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
rib_nexthop_blackhole_add (rib);
|
||||
route_entry_nexthop_blackhole_add (re);
|
||||
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 < 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
|
||||
nexthop = rib_nexthop_ipv6_add (rib, &nexthops[i]);
|
||||
nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]);
|
||||
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
|
||||
nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]);
|
||||
}
|
||||
else {
|
||||
if ((i < if_count) && ifindices[i])
|
||||
rib_nexthop_ifindex_add (rib, ifindices[i]);
|
||||
route_entry_nexthop_ifindex_add (re, ifindices[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Distance. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
|
||||
rib->distance = stream_getc (s);
|
||||
re->distance = stream_getc (s);
|
||||
|
||||
/* Metric. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
||||
rib->metric = stream_getl (s);
|
||||
re->metric = stream_getl (s);
|
||||
|
||||
/* Tag */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
|
||||
rib->tag = stream_getl (s);
|
||||
re->tag = stream_getl (s);
|
||||
else
|
||||
rib->tag = 0;
|
||||
re->tag = 0;
|
||||
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
|
||||
rib->mtu = stream_getl (s);
|
||||
re->mtu = stream_getl (s);
|
||||
else
|
||||
rib->mtu = 0;
|
||||
re->mtu = 0;
|
||||
|
||||
/* 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 */
|
||||
if (ret > 0)
|
||||
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;
|
||||
struct stream *s;
|
||||
struct in6_addr nhop_addr;
|
||||
struct rib *rib;
|
||||
struct route_entry *re;
|
||||
u_char message;
|
||||
u_char nexthop_num;
|
||||
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));
|
||||
|
||||
/* Allocate new rib. */
|
||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||
/* Allocate new re. */
|
||||
re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
||||
|
||||
/* Type, flags, message. */
|
||||
rib->type = stream_getc (s);
|
||||
rib->instance = stream_getw (s);
|
||||
rib->flags = stream_getl (s);
|
||||
re->type = stream_getc (s);
|
||||
re->instance = stream_getw (s);
|
||||
re->flags = stream_getl (s);
|
||||
message = stream_getc (s);
|
||||
safi = stream_getw (s);
|
||||
rib->uptime = time (NULL);
|
||||
re->uptime = time (NULL);
|
||||
|
||||
/* IPv6 prefix. */
|
||||
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;
|
||||
|
||||
/* 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
|
||||
* next-hop-addr/next-hop-ifindices. */
|
||||
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;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
rib_nexthop_blackhole_add (rib);
|
||||
route_entry_nexthop_blackhole_add (re);
|
||||
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 < 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
|
||||
nexthop = rib_nexthop_ipv6_add (rib, &nexthops[i]);
|
||||
nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]);
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
|
||||
nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]);
|
||||
}
|
||||
else {
|
||||
if ((i < if_count) && ifindices[i])
|
||||
rib_nexthop_ifindex_add (rib, ifindices[i]);
|
||||
route_entry_nexthop_ifindex_add (re, ifindices[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Distance. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
|
||||
rib->distance = stream_getc (s);
|
||||
re->distance = stream_getc (s);
|
||||
|
||||
/* Metric. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
||||
rib->metric = stream_getl (s);
|
||||
re->metric = stream_getl (s);
|
||||
|
||||
/* Tag */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
|
||||
rib->tag = stream_getl (s);
|
||||
re->tag = stream_getl (s);
|
||||
else
|
||||
rib->tag = 0;
|
||||
re->tag = 0;
|
||||
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
|
||||
rib->mtu = stream_getl (s);
|
||||
re->mtu = stream_getl (s);
|
||||
else
|
||||
rib->mtu = 0;
|
||||
re->mtu = 0;
|
||||
|
||||
/* VRF ID */
|
||||
rib->vrf_id = zvrf_id (zvrf);
|
||||
rib->table = zvrf->table_id;
|
||||
re->vrf_id = zvrf_id (zvrf);
|
||||
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 */
|
||||
if (ret > 0)
|
||||
client->v6_route_add_cnt++;
|
||||
@ -2391,10 +2396,14 @@ zebra_client_read (struct thread *thread)
|
||||
zebra_ptm_bfd_client_register(client, sock, length);
|
||||
break;
|
||||
case ZEBRA_INTERFACE_ENABLE_RADV:
|
||||
#if defined (HAVE_RTADV)
|
||||
zebra_interface_radv_set (client, sock, length, zvrf, 1);
|
||||
#endif
|
||||
break;
|
||||
case ZEBRA_INTERFACE_DISABLE_RADV:
|
||||
#if defined (HAVE_RTADV)
|
||||
zebra_interface_radv_set (client, sock, length, zvrf, 0);
|
||||
#endif
|
||||
break;
|
||||
case ZEBRA_MPLS_LABELS_ADD:
|
||||
case ZEBRA_MPLS_LABELS_DELETE:
|
||||
|
@ -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 int zsend_interface_update (int, struct zserv *, struct interface *);
|
||||
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 *,
|
||||
vrf_id_t);
|
||||
extern int zsend_interface_vrf_update (struct zserv *, struct interface *,
|
||||
|
Loading…
Reference in New Issue
Block a user