Merge remote-tracking branch 'origin/master' into pim_crash_a_boo

This commit is contained in:
Donald Sharp 2017-05-18 09:45:57 -04:00
commit ac139b5fb6
33 changed files with 426 additions and 267 deletions

View File

@ -2806,13 +2806,15 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
} }
size_t size_t
bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi, bgp_packet_mpattr_start (struct stream *s, struct peer *peer,
afi_t afi, safi_t safi,
struct bpacket_attr_vec_arr *vecarr, struct bpacket_attr_vec_arr *vecarr,
struct attr *attr) struct attr *attr)
{ {
size_t sizep; size_t sizep;
iana_afi_t pkt_afi; iana_afi_t pkt_afi;
safi_t pkt_safi; safi_t pkt_safi;
afi_t nh_afi;
/* Set extended bit always to encode the attribute length as 2 bytes */ /* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN); stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
@ -2826,10 +2828,18 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
stream_putw (s, pkt_afi); /* AFI */ stream_putw (s, pkt_afi); /* AFI */
stream_putc (s, pkt_safi); /* SAFI */ stream_putc (s, pkt_safi); /* SAFI */
/* Nexthop AFI */
if (peer_cap_enhe(peer, afi, safi)) {
nh_afi = AFI_IP6;
} else {
if (afi == AFI_L2VPN) if (afi == AFI_L2VPN)
nh_afi = AFI_L2VPN; nh_afi = AFI_L2VPN;
else if (nh_afi == AFI_MAX) else if (safi == SAFI_LABELED_UNICAST)
nh_afi = afi;
else
nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len); nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
}
/* Nexthop */ /* Nexthop */
switch (nh_afi) switch (nh_afi)
@ -3126,10 +3136,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
{ {
size_t mpattrlen_pos = 0; size_t mpattrlen_pos = 0;
mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, vecarr, attr);
(peer_cap_enhe(peer, afi, safi) ? AFI_IP6 :
AFI_MAX), /* get from NH */
vecarr, attr);
bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag, bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag,
addpath_encode, addpath_tx_id, attr); addpath_encode, addpath_tx_id, attr);
bgp_packet_mpattr_end(s, mpattrlen_pos); bgp_packet_mpattr_end(s, mpattrlen_pos);

View File

@ -297,8 +297,8 @@ bgp_attr_flush_encap(struct attr *attr);
* one for each NLRI that needs to be encoded into the UPDATE message, and * one for each NLRI that needs to be encoded into the UPDATE message, and
* finally the _end() function. * finally the _end() function.
*/ */
extern size_t bgp_packet_mpattr_start(struct stream *s, afi_t afi, safi_t safi, extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer,
afi_t nh_afi, afi_t afi, safi_t safi,
struct bpacket_attr_vec_arr *vecarr, struct bpacket_attr_vec_arr *vecarr,
struct attr *attr); struct attr *attr);
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,

View File

@ -213,7 +213,7 @@ DEFUN (encap_network,
int idx_ipv4 = 1; int idx_ipv4 = 1;
int idx_rd = 3; int idx_rd = 3;
int idx_word = 5; int idx_word = 5;
return bgp_static_set_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg, return bgp_static_set_safi (AFI_IP, SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg,
NULL, 0, NULL, NULL, NULL, NULL); NULL, 0, NULL, NULL, NULL, NULL);
} }
@ -232,7 +232,7 @@ DEFUN (no_encap_network,
int idx_ipv4 = 2; int idx_ipv4 = 2;
int idx_rd = 4; int idx_rd = 4;
int idx_word = 6; int idx_word = 6;
return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg, return bgp_static_unset_safi (AFI_IP, SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg,
0, NULL, NULL, NULL); 0, NULL, NULL, NULL);
} }

View File

@ -705,7 +705,7 @@ DEFUN(evpnrt5_network,
int idx_ethtag = 5; int idx_ethtag = 5;
int idx_routermac = 13; int idx_routermac = 13;
int idx_rmap = 15; int idx_rmap = 15;
return bgp_static_set_safi(SAFI_EVPN, vty, return bgp_static_set_safi(AFI_L2VPN, SAFI_EVPN, vty,
argv[idx_ipv4_prefixlen]->arg, argv[idx_ipv4_prefixlen]->arg,
argv[idx_ext_community]->arg, argv[idx_ext_community]->arg,
argv[idx_word]->arg, argv[idx_word]->arg,
@ -739,7 +739,7 @@ DEFUN(no_evpnrt5_network,
int idx_ethtag = 6; int idx_ethtag = 6;
int idx_esi = 10; int idx_esi = 10;
int idx_gwip = 12; int idx_gwip = 12;
return bgp_static_unset_safi(SAFI_EVPN, vty, return bgp_static_unset_safi(AFI_L2VPN, SAFI_EVPN, vty,
argv[idx_ipv4_prefixlen]->arg, argv[idx_ipv4_prefixlen]->arg,
argv[idx_ext_community]->arg, argv[idx_ext_community]->arg,
argv[idx_label]->arg, EVPN_IP_PREFIX, argv[idx_label]->arg, EVPN_IP_PREFIX,

View File

@ -1025,7 +1025,7 @@ bgp_stop (struct peer *peer)
zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s", zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
peer->host, peer->host,
(peer->hostname) ? peer->hostname : "Unknown", (peer->hostname) ? peer->hostname : "Unknown",
(vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default", vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default") : "",
peer_down_str [(int) peer->last_reset]); peer_down_str [(int) peer->last_reset]);
} }

View File

@ -471,7 +471,7 @@ DEFUN (vpnv4_network,
int idx_ipv4_prefixlen = 1; int idx_ipv4_prefixlen = 1;
int idx_ext_community = 3; int idx_ext_community = 3;
int idx_word = 5; int idx_word = 5;
return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, return bgp_static_set_safi (AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg,
argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL); argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL);
} }
@ -491,7 +491,7 @@ DEFUN (vpnv4_network_route_map,
int idx_ext_community = 3; int idx_ext_community = 3;
int idx_word = 5; int idx_word = 5;
int idx_word_2 = 7; int idx_word_2 = 7;
return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, return bgp_static_set_safi (AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg,
argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL); argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
} }
@ -510,7 +510,7 @@ DEFUN (no_vpnv4_network,
int idx_ipv4_prefixlen = 2; int idx_ipv4_prefixlen = 2;
int idx_ext_community = 4; int idx_ext_community = 4;
int idx_word = 6; int idx_word = 6;
return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, return bgp_static_unset_safi (AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg,
0, NULL, NULL, NULL); 0, NULL, NULL, NULL);
} }
@ -532,9 +532,9 @@ DEFUN (vpnv6_network,
int idx_word = 5; int idx_word = 5;
int idx_word_2 = 7; int idx_word_2 = 7;
if (argc == 8) if (argc == 8)
return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL); return bgp_static_set_safi (AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
else else
return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL); return bgp_static_set_safi (AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL);
} }
/* For testing purpose, static route of MPLS-VPN. */ /* For testing purpose, static route of MPLS-VPN. */
@ -552,7 +552,7 @@ DEFUN (no_vpnv6_network,
int idx_ipv6_prefix = 2; int idx_ipv6_prefix = 2;
int idx_ext_community = 4; int idx_ext_community = 4;
int idx_word = 6; int idx_word = 6;
return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, 0, NULL, NULL, NULL); return bgp_static_unset_safi (AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, 0, NULL, NULL, NULL);
} }
int int

View File

@ -1129,6 +1129,9 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
else else
peer->v_holdtime = send_holdtime; peer->v_holdtime = send_holdtime;
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
peer->v_keepalive = peer->keepalive;
else
peer->v_keepalive = peer->v_holdtime / 3; peer->v_keepalive = peer->v_holdtime / 3;
/* Open option part parse. */ /* Open option part parse. */

View File

@ -4540,7 +4540,7 @@ bgp_purge_static_redist_routes (struct bgp *bgp)
* I think it can probably be factored with bgp_static_set. * I think it can probably be factored with bgp_static_set.
*/ */
int int
bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str, bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str,
const char *rd_str, const char *tag_str, const char *rd_str, const char *tag_str,
const char *rmap_str, int evpn_type, const char *esi, const char *gwip, const char *rmap_str, int evpn_type, const char *esi, const char *gwip,
const char *ethtag, const char *routermac) const char *ethtag, const char *routermac)
@ -4554,14 +4554,8 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
struct bgp_table *table; struct bgp_table *table;
struct bgp_static *bgp_static; struct bgp_static *bgp_static;
u_char tag[3]; u_char tag[3];
afi_t afi;
struct prefix gw_ip; struct prefix gw_ip;
if(safi == SAFI_EVPN)
afi = AFI_L2VPN;
else
afi = AFI_IP;
/* validate ip prefix */ /* validate ip prefix */
ret = str2prefix (ip_str, &p); ret = str2prefix (ip_str, &p);
if (! ret) if (! ret)
@ -4686,7 +4680,7 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
/* Configure static BGP network. */ /* Configure static BGP network. */
int int
bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str, bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_str,
const char *rd_str, const char *tag_str, const char *rd_str, const char *tag_str,
int evpn_type, const char *esi, const char *gwip, const char *ethtag) int evpn_type, const char *esi, const char *gwip, const char *ethtag)
{ {
@ -4699,12 +4693,6 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
struct bgp_table *table; struct bgp_table *table;
struct bgp_static *bgp_static; struct bgp_static *bgp_static;
u_char tag[3]; u_char tag[3];
afi_t afi;
if(safi == SAFI_EVPN)
afi = AFI_L2VPN;
else
afi = AFI_IP;
/* Convert IP prefix string to struct prefix. */ /* Convert IP prefix string to struct prefix. */
ret = str2prefix (ip_str, &p); ret = str2prefix (ip_str, &p);

View File

@ -333,11 +333,11 @@ extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static
afi_t, safi_t); afi_t, safi_t);
extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t); extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);
extern int bgp_static_set_safi (safi_t safi, struct vty *vty, const char *, extern int bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *,
const char *, const char *, const char *, const char *, const char *, const char *,
int, const char *, const char *, const char *, const char *); int, const char *, const char *, const char *, const char *);
extern int bgp_static_unset_safi (safi_t safi, struct vty *, const char *, extern int bgp_static_unset_safi (afi_t afi, safi_t safi, struct vty *, const char *,
const char *, const char *, const char *, const char *,
int, const char *, const char *, const char *); int, const char *, const char *, const char *);

View File

@ -762,14 +762,18 @@ subgroup_update_packet (struct update_subgroup *subgrp)
if (rn->prn) if (rn->prn)
prd = (struct prefix_rd *) &rn->prn->p; prd = (struct prefix_rd *) &rn->prn->p;
if (safi == SAFI_LABELED_UNICAST)
tag = bgp_adv_label(rn, binfo, peer, afi, safi); tag = bgp_adv_label(rn, binfo, peer, afi, safi);
else
if (binfo && binfo->extra)
tag = binfo->extra->tag;
if (bgp_labeled_safi(safi)) if (bgp_labeled_safi(safi))
sprintf (label_buf, "label %u", label_pton(tag)); sprintf (label_buf, "label %u", label_pton(tag));
if (stream_empty (snlri)) if (stream_empty (snlri))
mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi, mpattrlen_pos = bgp_packet_mpattr_start (snlri, peer, afi, safi,
(peer_cap_enhe(peer, afi, safi) ? AFI_IP6 :
AFI_MAX), /* get from NH */
&vecarr, adv->baa->attr); &vecarr, adv->baa->attr);
bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd,

View File

@ -2812,7 +2812,12 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
} }
peer = peer_lookup_by_conf_if (bgp, conf_if); peer = peer_lookup_by_conf_if (bgp, conf_if);
if (!peer) if (peer)
{
if (as_str)
ret = peer_remote_as (bgp, &su, conf_if, &as, as_type, afi, safi);
}
else
{ {
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4) if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
&& afi == AFI_IP && safi == SAFI_UNICAST) && afi == AFI_IP && safi == SAFI_UNICAST)
@ -2836,7 +2841,8 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
if (peer->ifp) if (peer->ifp)
bgp_zebra_initiate_radv (bgp, peer); bgp_zebra_initiate_radv (bgp, peer);
} }
else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
(!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))) (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
{ {
if (v6only) if (v6only)
@ -8106,6 +8112,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
u_int16_t i; u_int16_t i;
u_char *msg; u_char *msg;
json_object *json_neigh = NULL; json_object *json_neigh = NULL;
time_t epoch_tbuf;
bgp = p->bgp; bgp = p->bgp;
@ -8295,8 +8302,11 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
uptime = bgp_clock(); uptime = bgp_clock();
uptime -= p->uptime; uptime -= p->uptime;
tm = gmtime(&uptime); tm = gmtime(&uptime);
epoch_tbuf = time(NULL) - uptime;
json_object_int_add(json_neigh, "bgpTimerUp", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000)); json_object_int_add(json_neigh, "bgpTimerUp", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000));
json_object_string_add(json_neigh, "bgpTimerUpString", peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL));
json_object_int_add(json_neigh, "bgpTimerUpEstablishedEpoch", epoch_tbuf);
} }
else if (p->status == Active) else if (p->status == Active)

View File

@ -6350,7 +6350,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
char * char *
peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json) peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json)
{ {
time_t uptime1; time_t uptime1, epoch_tbuf;
struct tm *tm; struct tm *tm;
/* Check buffer length. */ /* Check buffer length. */
@ -6404,8 +6404,10 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
if (use_json) if (use_json)
{ {
epoch_tbuf = time(NULL) - uptime1;
json_object_string_add(json, "peerUptime", buf); json_object_string_add(json, "peerUptime", buf);
json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000); json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000);
json_object_int_add(json, "peerUptimeEstablishedEpoch", epoch_tbuf);
} }
return buf; return buf;

View File

@ -646,7 +646,8 @@ DEFUN (no_eigrp_if_delay,
DEFUN (eigrp_if_bandwidth, DEFUN (eigrp_if_bandwidth,
eigrp_if_bandwidth_cmd, eigrp_if_bandwidth_cmd,
"bandwidth (1-10000000)", "eigrp bandwidth (1-10000000)",
"EIGRP specific commands\n"
"Set bandwidth informational parameter\n" "Set bandwidth informational parameter\n"
"Bandwidth in kilobits\n") "Bandwidth in kilobits\n")
{ {
@ -671,8 +672,9 @@ DEFUN (eigrp_if_bandwidth,
DEFUN (no_eigrp_if_bandwidth, DEFUN (no_eigrp_if_bandwidth,
no_eigrp_if_bandwidth_cmd, no_eigrp_if_bandwidth_cmd,
"no bandwidth [(1-10000000)]", "no eigrp bandwidth [(1-10000000)]",
NO_STR NO_STR
"EIGRP specific commands\n"
"Set bandwidth informational parameter\n" "Set bandwidth informational parameter\n"
"Bandwidth in kilobits\n") "Bandwidth in kilobits\n")
{ {

View File

@ -1623,6 +1623,8 @@ zclient_sync_init(u_short instance)
log_warnx("Error connecting synchronous zclient!"); log_warnx("Error connecting synchronous zclient!");
sleep(1); sleep(1);
} }
/* make socket non-blocking */
sock_set_nonblock(zclient_sync->sock);
/* Connect to label manager */ /* Connect to label manager */
while (lm_label_manager_connect(zclient_sync) != 0) { while (lm_label_manager_connect(zclient_sync) != 0) {
@ -1647,8 +1649,6 @@ lde_get_label_chunk(void)
ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end); ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
if (ret < 0) { if (ret < 0) {
log_warnx("Error getting label chunk!"); log_warnx("Error getting label chunk!");
close(zclient_sync->sock);
zclient_sync->sock = -1;
return -1; return -1;
} }

View File

@ -1372,11 +1372,6 @@ DEFUN (frr_version_defaults,
"set of configuration defaults used\n" "set of configuration defaults used\n"
"version string\n") "version string\n")
{ {
if (vty->type == VTY_TERM || vty->type == VTY_SHELL)
/* only print this when the user tries to do run it */
vty_out (vty, "%% NOTE: This command currently does nothing.%s"
"%% It is written to the configuration for future reference.%s",
VTY_NEWLINE, VTY_NEWLINE);
return CMD_SUCCESS; return CMD_SUCCESS;
} }

View File

@ -1512,6 +1512,47 @@ zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
*new_vrf_id = new_id; *new_vrf_id = new_id;
return ifp; return ifp;
} }
/* filter unwanted messages until the expected one arrives */
static int
zclient_read_sync_response (struct zclient *zclient, u_int16_t expected_cmd)
{
struct stream *s;
u_int16_t size;
u_char marker;
u_char version;
vrf_id_t vrf_id;
u_int16_t cmd;
fd_set readfds;
int ret;
ret = 0;
cmd = expected_cmd + 1;
while (ret == 0 && cmd != expected_cmd)
{
s = zclient->ibuf;
stream_reset (s);
/* wait until response arrives */
FD_ZERO (&readfds);
FD_SET (zclient->sock, &readfds);
select (zclient->sock+1, &readfds, NULL, NULL, NULL);
if (!FD_ISSET(zclient->sock, &readfds))
continue;
/* read response */
ret = zclient_read_header (s, zclient->sock, &size, &marker, &version,
&vrf_id, &cmd);
if (zclient_debug)
zlog_debug ("%s: Response (%d bytes) received", __func__, size);
}
if (ret != 0)
{
zlog_err ("%s: Invalid Sync Message Reply", __func__);
return -1;
}
return 0;
}
/** /**
* Connect to label manager in a syncronous way * Connect to label manager in a syncronous way
* *
@ -1527,11 +1568,6 @@ lm_label_manager_connect (struct zclient *zclient)
int ret; int ret;
struct stream *s; struct stream *s;
u_char result; u_char result;
u_int16_t size;
u_char marker;
u_char version;
vrf_id_t vrf_id;
u_int16_t cmd;
if (zclient_debug) if (zclient_debug)
zlog_debug ("Connecting to Label Manager"); zlog_debug ("Connecting to Label Manager");
@ -1571,20 +1607,15 @@ lm_label_manager_connect (struct zclient *zclient)
zlog_debug ("%s: Label manager connect request (%d bytes) sent", __func__, ret); zlog_debug ("%s: Label manager connect request (%d bytes) sent", __func__, ret);
/* read response */ /* read response */
s = zclient->ibuf; if (zclient_read_sync_response (zclient, ZEBRA_LABEL_MANAGER_CONNECT) != 0)
stream_reset (s);
ret = zclient_read_header (s, zclient->sock, &size, &marker, &version,
&vrf_id, &cmd);
if (ret != 0 || cmd != ZEBRA_LABEL_MANAGER_CONNECT) {
zlog_err ("%s: Invalid Label Manager Connect Message Reply Header", __func__);
return -1; return -1;
}
/* result */ /* result */
s = zclient->ibuf;
result = stream_getc(s); result = stream_getc(s);
if (zclient_debug) if (zclient_debug)
zlog_debug ("%s: Label Manager connect response (%d bytes) received, result %u", zlog_debug ("%s: Label Manager connect response received, result %u",
__func__, size, result); __func__, result);
return (int)result; return (int)result;
} }
@ -1608,11 +1639,6 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
{ {
int ret; int ret;
struct stream *s; struct stream *s;
u_int16_t size;
u_char marker;
u_char version;
vrf_id_t vrf_id;
u_int16_t cmd;
u_char response_keep; u_char response_keep;
if (zclient_debug) if (zclient_debug)
@ -1651,18 +1677,10 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
zlog_debug ("%s: Label chunk request (%d bytes) sent", __func__, ret); zlog_debug ("%s: Label chunk request (%d bytes) sent", __func__, ret);
/* read response */ /* read response */
s = zclient->ibuf; if (zclient_read_sync_response (zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
stream_reset (s);
ret = zclient_read_header (s, zclient->sock, &size, &marker, &version,
&vrf_id, &cmd);
if (ret != 0 || cmd != ZEBRA_GET_LABEL_CHUNK) {
zlog_err ("%s: Invalid Get Label Chunk Message Reply Header", __func__);
return -1; return -1;
}
if (zclient_debug)
zlog_debug ("%s: Label chunk response (%d bytes) received", __func__, size);
s = zclient->ibuf;
/* keep */ /* keep */
response_keep = stream_getc(s); response_keep = stream_getc(s);
/* start and end labels */ /* start and end labels */
@ -1670,14 +1688,16 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
*end = stream_getl(s); *end = stream_getl(s);
/* not owning this response */ /* not owning this response */
if (keep != response_keep) { if (keep != response_keep)
{
zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u", zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
__func__, *start, *end, keep, response_keep); __func__, *start, *end, keep, response_keep);
} }
/* sanity */ /* sanity */
if (*start > *end if (*start > *end
|| *start < MPLS_MIN_UNRESERVED_LABEL || *start < MPLS_MIN_UNRESERVED_LABEL
|| *end > MPLS_MAX_UNRESERVED_LABEL) { || *end > MPLS_MAX_UNRESERVED_LABEL)
{
zlog_err ("%s: Invalid Label chunk: %u - %u", __func__, zlog_err ("%s: Invalid Label chunk: %u - %u", __func__,
*start, *end); *start, *end);
return -1; return -1;

View File

@ -405,26 +405,11 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
} }
#define OSPF6_CMD_AREA_LOOKUP(str, oa) \
{ \
u_int32_t area_id = 0; \
if (inet_pton (AF_INET, str, &area_id) != 1) \
{ \
vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
return CMD_SUCCESS; \
} \
oa = ospf6_area_lookup (area_id, ospf6); \
if (oa == NULL) \
{ \
vty_out (vty, "No such Area: %s%s", str, VNL); \
return CMD_SUCCESS; \
} \
}
#define OSPF6_CMD_AREA_GET(str, oa) \ #define OSPF6_CMD_AREA_GET(str, oa) \
{ \ { \
u_int32_t area_id = 0; \ char *ep; \
if (inet_pton (AF_INET, str, &area_id) != 1) \ u_int32_t area_id = htonl (strtol(str, &ep, 10)); \
if (*ep && inet_pton (AF_INET, str, &area_id) != 1) \
{ \ { \
vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \ vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
return CMD_SUCCESS; \ return CMD_SUCCESS; \

View File

@ -2454,7 +2454,7 @@ ospf_apiserver_clients_notify_nsm_change (struct ospf_neighbor *nbr)
{ {
struct msg *msg; struct msg *msg;
struct in_addr ifaddr = { .s_addr = 0L }; struct in_addr ifaddr = { .s_addr = 0L };
struct in_addr nbraddr; struct in_addr nbraddr = { .s_addr = 0L };
assert (nbr); assert (nbr);

View File

@ -5320,11 +5320,16 @@ DEFUN (interface_ip_pim_hello,
pim_ifp = ifp->info; pim_ifp = ifp->info;
if (!pim_ifp) { if (!pim_ifp)
vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE); {
if (!pim_cmd_interface_add(ifp))
{
vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
}
pim_ifp = ifp->info;
pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10); pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
if (argc == idx_hold + 1) if (argc == idx_hold + 1)

View File

@ -147,7 +147,6 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
/* SGRpt entry could have empty oil */ /* SGRpt entry could have empty oil */
if (ch->upstream->channel_oil) if (ch->upstream->channel_oil)
pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask); pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
/* /*
* Do we have any S,G's that are inheriting? * Do we have any S,G's that are inheriting?
* Nuke from on high too. * Nuke from on high too.
@ -178,6 +177,10 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
pim_upstream_update_join_desired(ch->upstream); pim_upstream_update_join_desired(ch->upstream);
} }
/* upstream is common across ifchannels, check if upstream's
ifchannel list is empty before deleting upstream_del
ref count will take care of it.
*/
pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__); pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
ch->upstream = NULL; ch->upstream = NULL;
@ -199,6 +202,9 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
hash_release(pim_ifp->pim_ifchannel_hash, ch); hash_release(pim_ifp->pim_ifchannel_hash, ch);
listnode_delete(pim_ifchannel_list, ch); listnode_delete(pim_ifchannel_list, ch);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug ("%s: ifchannel entry %s is deleted ", __PRETTY_FUNCTION__, ch->sg_str);
pim_ifchannel_free(ch); pim_ifchannel_free(ch);
} }
@ -570,13 +576,17 @@ pim_ifchannel_add(struct interface *ifp,
listnode_add_sort(up->ifchannels, ch); listnode_add_sort(up->ifchannels, ch);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug ("%s: ifchannel %s is created ", __PRETTY_FUNCTION__, ch->sg_str);
return ch; return ch;
} }
static void ifjoin_to_noinfo(struct pim_ifchannel *ch) static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del)
{ {
pim_forward_stop(ch); pim_forward_stop(ch);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO); pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
if (ch_del)
delete_on_noinfo(ch); delete_on_noinfo(ch);
} }
@ -586,7 +596,7 @@ static int on_ifjoin_expiry_timer(struct thread *t)
ch = THREAD_ARG(t); ch = THREAD_ARG(t);
ifjoin_to_noinfo(ch); ifjoin_to_noinfo(ch, true);
/* ch may have been deleted */ /* ch may have been deleted */
return 0; return 0;
@ -608,10 +618,6 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
pim_ifp = ifp->info; pim_ifp = ifp->info;
send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1); send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
//ch->ifjoin_state transition to NOINFO
ifjoin_to_noinfo(ch);
/* from here ch may have been deleted */
if (send_prune_echo) if (send_prune_echo)
{ {
struct pim_rpf rpf; struct pim_rpf rpf;
@ -620,6 +626,23 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address; rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address;
pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0); pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0);
} }
/* If SGRpt flag is set on ifchannel, Trigger SGRpt
message on RP path upon prune timer expiry.
*/
if (PIM_IF_FLAG_TEST_S_G_RPT (ch->flags))
{
if (ch->upstream)
pim_upstream_update_join_desired(ch->upstream);
/*
ch->ifjoin_state transition to NOINFO state
ch_del is set to 0 for not deleteing from here.
Holdtime expiry (ch_del set to 1) delete the entry.
*/
ifjoin_to_noinfo(ch, false);
}
else
ifjoin_to_noinfo(ch, true);
/* from here ch may have been deleted */
} }
else else
{ {
@ -796,7 +819,7 @@ void pim_ifchannel_join_add(struct interface *ifp,
(ch->upstream->parent->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) && (ch->upstream->parent->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) &&
!(ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)) !(ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR))
{ {
pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR); pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
pim_upstream_keep_alive_timer_start (ch->upstream, qpim_keep_alive_time); pim_upstream_keep_alive_timer_start (ch->upstream, qpim_keep_alive_time);
} }
break; break;
@ -889,7 +912,9 @@ void pim_ifchannel_prune(struct interface *ifp,
case PIM_IFJOIN_NOINFO: case PIM_IFJOIN_NOINFO:
if (source_flags & PIM_ENCODE_RPT_BIT) if (source_flags & PIM_ENCODE_RPT_BIT)
{ {
if (!(source_flags & PIM_ENCODE_WC_BIT))
PIM_IF_FLAG_SET_S_G_RPT(ch->flags); PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING; ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
if (listcount(pim_ifp->pim_neighbor_list) > 1) if (listcount(pim_ifp->pim_neighbor_list) > 1)
jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp); jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
@ -1296,7 +1321,7 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t
if (up) if (up)
{ {
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_TRACE)
zlog_debug ("%s: del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str); 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); pim_channel_del_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
} }
} }

View File

@ -38,6 +38,7 @@
#include "pim_zebra.h" #include "pim_zebra.h"
static void group_timer_off(struct igmp_group *group); static void group_timer_off(struct igmp_group *group);
static int pim_igmp_general_query(struct thread *t);
/* This socket is used for TXing IGMP packets only, IGMP RX happens /* This socket is used for TXing IGMP packets only, IGMP RX happens
* in pim_mroute_msg() * in pim_mroute_msg()
@ -168,8 +169,11 @@ static int pim_igmp_other_querier_expire(struct thread *t)
/* /*
We are the current querier, then We are the current querier, then
re-start sending general queries. re-start sending general queries.
RFC 2236 - sec 7 Other Querier
present timer expired (Send General
Query, Set Gen. Query. timer)
*/ */
pim_igmp_general_query_on(igmp); pim_igmp_general_query(t);
return 0; return 0;
} }
@ -490,8 +494,6 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
return -1; return -1;
} }
static int pim_igmp_general_query(struct thread *t);
void pim_igmp_general_query_on(struct igmp_sock *igmp) void pim_igmp_general_query_on(struct igmp_sock *igmp)
{ {
struct pim_interface *pim_ifp; struct pim_interface *pim_ifp;

View File

@ -566,7 +566,7 @@ pim_ecmp_nexthop_search (struct pim_nexthop_cache *pnc,
//PIM ECMP flag is enable then choose ECMP path. //PIM ECMP flag is enable then choose ECMP path.
hash_val = pim_compute_ecmp_hash (src, grp); hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % pnc->nexthop_num; mod_val = hash_val % pnc->nexthop_num;
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u ", zlog_debug ("%s: hash_val %u mod_val %u ",
__PRETTY_FUNCTION__, hash_val, mod_val); __PRETTY_FUNCTION__, hash_val, mod_val);
} }
@ -913,7 +913,7 @@ pim_ecmp_nexthop_lookup (struct pim_nexthop *nexthop, struct in_addr addr,
{ {
hash_val = pim_compute_ecmp_hash (src, grp); hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % num_ifindex; mod_val = hash_val % num_ifindex;
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u", zlog_debug ("%s: hash_val %u mod_val %u",
__PRETTY_FUNCTION__, hash_val, mod_val); __PRETTY_FUNCTION__, hash_val, mod_val);
} }
@ -1036,7 +1036,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr,
{ {
hash_val = pim_compute_ecmp_hash (src, grp); hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % num_ifindex; mod_val = hash_val % num_ifindex;
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u", zlog_debug ("%s: hash_val %u mod_val %u",
__PRETTY_FUNCTION__, hash_val, mod_val); __PRETTY_FUNCTION__, hash_val, mod_val);
} }

View File

@ -353,7 +353,7 @@ pim_register_recv (struct interface *ifp,
zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet", zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet",
__func__, "Sender"); __func__, "Sender");
/* Drop Packet Silently */ /* Drop Packet Silently */
return 1; return 0;
} }
} }
@ -415,5 +415,5 @@ pim_register_recv (struct interface *ifp,
pim_register_stop_send (ifp, &sg, dest_addr, src_addr); pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
} }
return 1; return 0;
} }

View File

@ -77,9 +77,17 @@ pim_upstream_remove_children (struct pim_upstream *up)
while (!list_isempty (up->sources)) while (!list_isempty (up->sources))
{ {
child = listnode_head (up->sources); child = listnode_head (up->sources);
child->parent = NULL;
listnode_delete (up->sources, child); listnode_delete (up->sources, child);
if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
{
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
child = pim_upstream_del(child, __PRETTY_FUNCTION__);
} }
if (child)
child->parent = NULL;
}
list_delete(up->sources);
up->sources = NULL;
} }
/* /*
@ -148,7 +156,11 @@ void pim_upstream_free(struct pim_upstream *up)
static void upstream_channel_oil_detach(struct pim_upstream *up) static void upstream_channel_oil_detach(struct pim_upstream *up)
{ {
if (up->channel_oil) { if (up->channel_oil)
{
/* Detaching from channel_oil, channel_oil may exist post del,
but upstream would not keep reference of it
*/
pim_channel_oil_del(up->channel_oil); pim_channel_oil_del(up->channel_oil);
up->channel_oil = NULL; up->channel_oil = NULL;
} }
@ -194,26 +206,12 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
} }
pim_upstream_remove_children (up); pim_upstream_remove_children (up);
if (up->sources)
list_delete (up->sources);
up->sources = NULL;
pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__); pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
upstream_channel_oil_detach(up); upstream_channel_oil_detach(up);
if (up->sources)
{
struct listnode *node, *nnode;
struct pim_upstream *child;
for (ALL_LIST_ELEMENTS (up->sources, node, nnode, child))
{
if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
{
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
pim_upstream_del(child, __PRETTY_FUNCTION__);
}
}
list_delete (up->sources);
}
up->sources = NULL;
list_delete (up->ifchannels); list_delete (up->ifchannels);
up->ifchannels = NULL; up->ifchannels = NULL;
@ -222,11 +220,10 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
into pim_upstream_free() because the later is into pim_upstream_free() because the later is
called by list_delete_all_node() called by list_delete_all_node()
*/ */
if (up->parent) if (up->parent && up->parent->sources)
{
listnode_delete (up->parent->sources, up); listnode_delete (up->parent->sources, up);
up->parent = NULL; up->parent = NULL;
}
listnode_delete (pim_upstream_list, up); listnode_delete (pim_upstream_list, up);
hash_release (pim_upstream_hash, up); hash_release (pim_upstream_hash, up);
@ -533,7 +530,8 @@ pim_upstream_switch(struct pim_upstream *up,
{ {
enum pim_upstream_state old_state = up->join_state; enum pim_upstream_state old_state = up->join_state;
if (PIM_DEBUG_PIM_EVENTS) { if (PIM_DEBUG_PIM_EVENTS)
{
zlog_debug ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s", zlog_debug ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
up->sg_str, up->sg_str,
@ -579,6 +577,16 @@ pim_upstream_switch(struct pim_upstream *up,
if (old_state == PIM_UPSTREAM_JOINED) if (old_state == PIM_UPSTREAM_JOINED)
pim_msdp_up_join_state_changed(up); pim_msdp_up_join_state_changed(up);
/* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT */
if (pim_upstream_is_sg_rpt(up) && up->parent)
{
if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__,
up->parent->rpf.source_nexthop.interface->name,
up->rpf.source_nexthop.interface->name);
pim_jp_agg_single_upstream_send(&up->parent->rpf, up->parent, 1 /* (W,G) Join */);
}
else
pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */); pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
join_timer_stop(up); join_timer_stop(up);
} }
@ -712,9 +720,9 @@ pim_upstream_new (struct prefix_sg *sg,
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_TRACE)
{ {
zlog_debug ("%s: Created Upstream %s upstream_addr %s", zlog_debug ("%s: Created Upstream %s upstream_addr %s ref count %d increment",
__PRETTY_FUNCTION__, up->sg_str, __PRETTY_FUNCTION__, up->sg_str,
inet_ntoa (up->upstream_addr)); inet_ntoa (up->upstream_addr), up->ref_count);
} }
return up; return up;
@ -745,6 +753,9 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
{ {
up->flags |= flags; up->flags |= flags;
up->ref_count++; up->ref_count++;
if (PIM_DEBUG_TRACE)
zlog_debug ("%s(%s): upstream %s ref count %d increment",
__PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
} }
} }
else else
@ -754,10 +765,13 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
} }
void void
pim_upstream_ref(struct pim_upstream *up, int flags) pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)
{ {
up->flags |= flags; up->flags |= flags;
++up->ref_count; ++up->ref_count;
if (PIM_DEBUG_TRACE)
zlog_debug ("%s(%s): upstream %s ref count %d increment",
__PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
} }
struct pim_upstream *pim_upstream_add(struct prefix_sg *sg, struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
@ -768,7 +782,7 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
int found = 0; int found = 0;
up = pim_upstream_find(sg); up = pim_upstream_find(sg);
if (up) { if (up) {
pim_upstream_ref(up, flags); pim_upstream_ref(up, flags, name);
found = 1; found = 1;
} }
else { else {
@ -781,10 +795,11 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
{ {
char buf[PREFIX2STR_BUFFER]; char buf[PREFIX2STR_BUFFER];
prefix2str (&up->rpf.rpf_addr, buf, sizeof (buf)); prefix2str (&up->rpf.rpf_addr, buf, sizeof (buf));
zlog_debug("%s(%s): %s, iif %s found: %d: ref_count: %d", zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
__PRETTY_FUNCTION__, name, __PRETTY_FUNCTION__, name,
up->sg_str, buf, found, up->sg_str, buf, up->rpf.source_nexthop.interface ?
up->ref_count); up->rpf.source_nexthop.interface->name : "NIL" ,
found, up->ref_count);
} }
else else
zlog_debug("%s(%s): (%s) failure to create", zlog_debug("%s(%s): (%s) failure to create",
@ -1644,7 +1659,7 @@ pim_upstream_sg_running (void *arg)
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_TRACE)
zlog_debug ("source reference created on kat restart %s", up->sg_str); zlog_debug ("source reference created on kat restart %s", up->sg_str);
pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM); pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __PRETTY_FUNCTION__);
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags); PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
pim_upstream_fhr_kat_start(up); pim_upstream_fhr_kat_start(up);
} }

View File

@ -144,7 +144,7 @@ struct pim_upstream *pim_upstream_find_or_add (struct prefix_sg *sg,
struct pim_upstream *pim_upstream_add (struct prefix_sg *sg, struct pim_upstream *pim_upstream_add (struct prefix_sg *sg,
struct interface *ifp, int flags, struct interface *ifp, int flags,
const char *name); const char *name);
void pim_upstream_ref (struct pim_upstream *up, int flags); void pim_upstream_ref (struct pim_upstream *up, int flags, const char *name);
struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name); struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name);
int pim_upstream_evaluate_join_desired(struct pim_upstream *up); int pim_upstream_evaluate_join_desired(struct pim_upstream *up);

View File

@ -109,9 +109,12 @@ class Config(object):
log.info('Loading Config object from file %s', filename) log.info('Loading Config object from file %s', filename)
try: try:
file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename]) file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename],
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise VtyshMarkException(str(e)) ve = VtyshMarkException(e)
ve.output = e.output
raise ve
for line in file_output.split('\n'): for line in file_output.split('\n'):
line = line.strip() line = line.strip()
@ -134,9 +137,11 @@ class Config(object):
try: try:
config_text = subprocess.check_output( config_text = subprocess.check_output(
"/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -", "/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -",
shell=True) shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise VtyshMarkException(str(e)) ve = VtyshMarkException(e)
ve.output = e.output
raise ve
for line in config_text.split('\n'): for line in config_text.split('\n'):
line = line.strip() line = line.strip()
@ -342,10 +347,12 @@ end
# the keywords that we know are single line contexts. bgp in this case # the keywords that we know are single line contexts. bgp in this case
# is not the main router bgp block, but enabling multi-instance # is not the main router bgp block, but enabling multi-instance
oneline_ctx_keywords = ("access-list ", oneline_ctx_keywords = ("access-list ",
"agentx",
"bgp ", "bgp ",
"debug ", "debug ",
"dump ", "dump ",
"enable ", "enable ",
"frr ",
"hostname ", "hostname ",
"ip ", "ip ",
"ipv6 ", "ipv6 ",
@ -815,6 +822,14 @@ def compare_context_objects(newconf, running):
elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd: elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd:
continue continue
elif ("router bgp" in running_ctx_keys[0] and
len(running_ctx_keys) > 1 and
running_ctx_keys[1].startswith('address-family')):
# There's no 'no address-family' support and so we have to
# delete each line individually again
for line in running_ctx.lines:
lines_to_del.append((running_ctx_keys, line))
# Non-global context # Non-global context
elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys): elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys):
lines_to_del.append((running_ctx_keys, None)) lines_to_del.append((running_ctx_keys, None))
@ -890,11 +905,15 @@ if __name__ == '__main__':
# Verify the new config file is valid # Verify the new config file is valid
if not os.path.isfile(args.filename): if not os.path.isfile(args.filename):
print "Filename %s does not exist" % args.filename msg = "Filename %s does not exist" % args.filename
print msg
log.error(msg)
sys.exit(1) sys.exit(1)
if not os.path.getsize(args.filename): if not os.path.getsize(args.filename):
print "Filename %s is an empty file" % args.filename msg = "Filename %s is an empty file" % args.filename
print msg
log.error(msg)
sys.exit(1) sys.exit(1)
# Verify that 'service integrated-vtysh-config' is configured # Verify that 'service integrated-vtysh-config' is configured
@ -911,7 +930,9 @@ if __name__ == '__main__':
break break
if not service_integrated_vtysh_config: if not service_integrated_vtysh_config:
print "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'" msg = "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
print msg
log.error(msg)
sys.exit(1) sys.exit(1)
if args.debug: if args.debug:
@ -922,6 +943,7 @@ if __name__ == '__main__':
# Create a Config object from the config generated by newconf # Create a Config object from the config generated by newconf
newconf = Config() newconf = Config()
newconf.load_from_file(args.filename) newconf.load_from_file(args.filename)
reload_ok = True
if args.test: if args.test:
@ -1064,7 +1086,7 @@ if __name__ == '__main__':
# 'no ip ospf authentication message-digest 1.1.1.1' in # 'no ip ospf authentication message-digest 1.1.1.1' in
# our example above # our example above
# - Split that last entry by whitespace and drop the last word # - Split that last entry by whitespace and drop the last word
log.warning('Failed to execute %s', ' '.join(cmd)) log.info('Failed to execute %s', ' '.join(cmd))
last_arg = cmd[-1].split(' ') last_arg = cmd[-1].split(' ')
if len(last_arg) <= 2: if len(last_arg) <= 2:
@ -1099,9 +1121,25 @@ if __name__ == '__main__':
with open(filename, 'w') as fh: with open(filename, 'w') as fh:
for line in lines_to_configure: for line in lines_to_configure:
fh.write(line + '\n') fh.write(line + '\n')
subprocess.call(['/usr/bin/vtysh', '-f', filename])
output = subprocess.check_output(['/usr/bin/vtysh', '-f', filename])
# exit non-zero if we see these errors
for x in ('BGP instance name and AS number mismatch',
'BGP instance is already running',
'% not a local address'):
for line in output.splitlines():
if x in line:
msg = "ERROR: %s" % x
log.error(msg)
print msg
reload_ok = False
os.unlink(filename) os.unlink(filename)
# Make these changes persistent # Make these changes persistent
if args.overwrite or args.filename != '/etc/frr/frr.conf': if args.overwrite or args.filename != '/etc/frr/frr.conf':
subprocess.call(['/usr/bin/vtysh', '-c', 'write']) subprocess.call(['/usr/bin/vtysh', '-c', 'write'])
if not reload_ok:
sys.exit(1)

View File

@ -323,7 +323,11 @@ vtysh_execute_func (const char *line, int pager)
{ {
vtysh_execute("exit-vnc"); vtysh_execute("exit-vnc");
} }
else if ((saved_node == KEYCHAIN_KEY_NODE) && (tried == 1)) else if ((saved_node == KEYCHAIN_KEY_NODE
|| saved_node == LDP_PSEUDOWIRE_NODE
|| saved_node == LDP_IPV4_IFACE_NODE
|| saved_node == LDP_IPV6_IFACE_NODE)
&& (tried == 1))
{ {
vtysh_execute("exit"); vtysh_execute("exit");
} }
@ -641,7 +645,7 @@ vtysh_mark_file (const char *filename)
} }
} }
/* This is the end */ /* This is the end */
fprintf(stdout, "end\n"); fprintf(stdout, "\nend\n");
vty_close(vty); vty_close(vty);
XFREE(MTYPE_VTYSH_CMD, vty_buf_copy); XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);

View File

@ -709,6 +709,10 @@ if_delete_update (struct interface *ifp)
interface deletion message. */ interface deletion message. */
ifp->ifindex = IFINDEX_INTERNAL; ifp->ifindex = IFINDEX_INTERNAL;
ifp->node = NULL; ifp->node = NULL;
/* if the ifp is in a vrf, move it to default so vrf can be deleted if desired */
if (ifp->vrf_id)
if_handle_vrf_change (ifp, VRF_DEFAULT);
} }
/* VRF change for an interface */ /* VRF change for an interface */

View File

@ -55,6 +55,80 @@ static void delete_label_chunk(void *val)
XFREE(MTYPE_LM_CHUNK, val); XFREE(MTYPE_LM_CHUNK, val);
} }
static int relay_response_back(struct zserv *zserv)
{
int ret = 0;
struct stream *src, *dst;
u_int16_t size = 0;
u_char marker;
u_char version;
vrf_id_t vrf_id;
u_int16_t resp_cmd;
src = zclient->ibuf;
dst = zserv->obuf;
stream_reset(src);
ret = zclient_read_header(src, zclient->sock, &size, &marker, &version,
&vrf_id, &resp_cmd);
if (ret < 0 && errno != EAGAIN) {
zlog_err("%s: Error reading Label Manager response: %s", __func__,
strerror(errno));
return -1;
}
zlog_debug("%s: Label Manager response received, %d bytes", __func__,
size);
if (size == 0)
return -1;
/* send response back */
stream_copy(dst, src);
ret = writen(zserv->sock, dst->data, stream_get_endp(dst));
if (ret <= 0) {
zlog_err("%s: Error sending Label Manager response back: %s",
__func__, strerror(errno));
return -1;
}
zlog_debug("%s: Label Manager response (%d bytes) sent back", __func__,
ret);
return 0;
}
static int lm_zclient_read(struct thread *t)
{
struct zserv *zserv;
int ret;
/* Get socket to zebra. */
zserv = THREAD_ARG(t);
zclient->t_read = NULL;
/* read response and send it back */
ret = relay_response_back(zserv);
return ret;
}
static int reply_error (int cmd, struct zserv *zserv, vrf_id_t vrf_id)
{
struct stream *s;
s = zserv->obuf;
stream_reset (s);
zserv_create_header (s, cmd, vrf_id);
/* result */
stream_putc (s, 1);
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
return writen (zserv->sock, s->data, stream_get_endp (s));
}
/** /**
* Receive a request to get or release a label chunk and forward it to external * Receive a request to get or release a label chunk and forward it to external
* label manager. * label manager.
@ -63,19 +137,25 @@ static void delete_label_chunk(void *val)
* proxy. * proxy.
* *
* @param cmd Type of request (connect, get or release) * @param cmd Type of request (connect, get or release)
* @param src Input buffer from zserv * @param zserv
* @return 0 on success, -1 otherwise * @return 0 on success, -1 otherwise
*/ */
int zread_relay_label_manager_request(int cmd, struct zserv *zserv) int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf_id)
{ {
struct stream *src, *dst; struct stream *src, *dst;
int ret; int ret = 0;
if (zclient->sock < 0) { if (zclient->sock < 0) {
zlog_err("%s: Error relaying label chunk request: no zclient socket", zlog_err("%s: Error relaying label chunk request: no zclient socket",
__func__); __func__);
reply_error (cmd, zserv, vrf_id);
return -1; return -1;
} }
/* in case there's any incoming message enqueued, read and forward it */
while (ret == 0)
ret = relay_response_back(zserv);
/* Send request to external label manager */ /* Send request to external label manager */
src = zserv->ibuf; src = zserv->ibuf;
dst = zclient->obuf; dst = zclient->obuf;
@ -86,6 +166,7 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv)
if (ret <= 0) { if (ret <= 0) {
zlog_err("%s: Error relaying label chunk request: %s", __func__, zlog_err("%s: Error relaying label chunk request: %s", __func__,
strerror(errno)); strerror(errno));
reply_error (cmd, zserv, vrf_id);
return -1; return -1;
} }
zlog_debug("%s: Label chunk request relayed. %d bytes sent", __func__, zlog_debug("%s: Label chunk request relayed. %d bytes sent", __func__,
@ -95,43 +176,15 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv)
if (cmd == ZEBRA_RELEASE_LABEL_CHUNK) if (cmd == ZEBRA_RELEASE_LABEL_CHUNK)
return 0; return 0;
/* read response */ /* make sure we listen to the response */
src = zclient->ibuf; if (!zclient->t_read)
dst = zserv->obuf; thread_add_read(zclient->master, lm_zclient_read, zserv,
zclient->sock, &zclient->t_read);
stream_reset(src);
u_int16_t size;
u_char marker;
u_char version;
vrf_id_t vrf_id;
u_int16_t resp_cmd;
ret = zclient_read_header(src, zclient->sock, &size, &marker, &version,
&vrf_id, &resp_cmd);
if (ret < 0) {
zlog_err("%s: Error reading label chunk response: %s", __func__,
strerror(errno));
return -1;
}
zlog_debug("%s: Label chunk response received, %d bytes", __func__,
size);
/* send response back */
stream_copy(dst, src);
stream_copy(zserv->obuf, zclient->ibuf);
ret = writen(zserv->sock, dst->data, stream_get_endp(dst));
if (ret <= 0) {
zlog_err("%s: Error sending label chunk response back: %s",
__func__, strerror(errno));
return -1;
}
zlog_debug("%s: Label chunk response (%d bytes) sent back", __func__,
ret);
return 0; return 0;
} }
static int zclient_connect(struct thread *t) static int lm_zclient_connect(struct thread *t)
{ {
zclient->t_connect = NULL; zclient->t_connect = NULL;
@ -140,11 +193,15 @@ static int zclient_connect(struct thread *t)
if (zclient_socket_connect(zclient) < 0) { if (zclient_socket_connect(zclient) < 0) {
zlog_err("Error connecting synchronous zclient!"); zlog_err("Error connecting synchronous zclient!");
thread_add_timer(zebrad.master, zclient_connect, zclient, thread_add_timer(zebrad.master, lm_zclient_connect, zclient,
CONNECTION_DELAY, &zclient->t_connect); CONNECTION_DELAY, &zclient->t_connect);
return -1; return -1;
} }
/* make socket non-blocking */
if (set_nonblocking(zclient->sock) < 0)
zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
return 0; return 0;
} }
@ -163,7 +220,7 @@ static void lm_zclient_init(char *lm_zserv_path)
zclient = zclient_new(zebrad.master); zclient = zclient_new(zebrad.master);
zclient->sock = -1; zclient->sock = -1;
zclient->t_connect = NULL; zclient->t_connect = NULL;
zclient_connect (NULL); lm_zclient_connect(NULL);
} }
/** /**

View File

@ -61,7 +61,7 @@ struct label_manager {
bool lm_is_external; bool lm_is_external;
int zread_relay_label_manager_request(int cmd, struct zserv *zserv); int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf_id);
void label_manager_init(char *lm_zserv_path); void label_manager_init(char *lm_zserv_path);
struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance, struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,
u_char keep, uint32_t size); u_char keep, uint32_t size);

View File

@ -106,18 +106,15 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
/* Redistribute routes. */ /* Redistribute routes. */
static void static void
zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id) zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id, int afi)
{ {
struct rib *newrib; struct rib *newrib;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
int afi;
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{
table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id);
if (! table) if (! table)
continue; return;
for (rn = route_top (table); rn; rn = route_next (rn)) for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, newrib) RNODE_FOREACH_RIB (rn, newrib)
@ -145,7 +142,6 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
zsend_redistribute_route (1, client, dst_p, src_p, newrib); zsend_redistribute_route (1, client, dst_p, src_p, newrib);
} }
} }
}
/* Either advertise a route for redistribution to registered clients or */ /* Either advertise a route for redistribution to registered clients or */
/* withdraw redistribution if add cannot be done for client */ /* withdraw redistribution if add cannot be done for client */
@ -264,13 +260,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
if (! redist_check_instance (&client->mi_redist[afi][type], instance)) if (! redist_check_instance (&client->mi_redist[afi][type], instance))
{ {
redist_add_instance (&client->mi_redist[afi][type], instance); redist_add_instance (&client->mi_redist[afi][type], instance);
zebra_redistribute (client, type, instance, zvrf_id (zvrf)); zebra_redistribute (client, type, instance, zvrf_id (zvrf), afi);
} }
} else { } else {
if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf))) if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf)))
{ {
vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf)); vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf));
zebra_redistribute (client, type, 0, zvrf_id (zvrf)); zebra_redistribute (client, type, 0, zvrf_id (zvrf), afi);
} }
} }
} }

View File

@ -554,7 +554,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
{ {
RNODE_FOREACH_RIB(static_rn, srib) RNODE_FOREACH_RIB(static_rn, srib)
{ {
if (srib->type == ZEBRA_ROUTE_STATIC) if (srib->type != ZEBRA_ROUTE_STATIC)
continue; continue;
/* Set the filter flag for the correct nexthop - static route may /* Set the filter flag for the correct nexthop - static route may

View File

@ -2045,10 +2045,7 @@ zread_label_manager_request (int cmd, struct zserv *client, vrf_id_t vrf_id)
/* external label manager */ /* external label manager */
if (lm_is_external) if (lm_is_external)
{ zread_relay_label_manager_request (cmd, client, vrf_id);
if (zread_relay_label_manager_request (cmd, client) != 0)
zsend_label_manager_connect_response (client, vrf_id, 1);
}
/* this is a label manager */ /* this is a label manager */
else else
{ {