From 5c7ef8dc4fee3521a225aec0a3d42912a5bfd247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Fingen?= Date: Wed, 26 Apr 2017 11:50:21 +0200 Subject: [PATCH 01/40] lm: Make relay label manager async MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid blocking zebra when it's acting as a proxy for an external label manager. Besides: Fix get chunk reconnection. Socket was still being destroyed on failure, so next attempt would never work. Filter out unwanted messages in lm sync sock. Until LDE client sends ZEBRA_LABEL_MANAGER_CONNECT message, zserv doesn't know which kind of client it is, so it might enqueue unwanted messages like interface add, interface up, etc. Changes in this commit discard those messages in the client side in case they arrive before the expected response. Change function name for zclient_connect in label manager to avoid confusion with zclient one. Signed-off-by: ßingen --- ldpd/lde.c | 4 +- lib/zclient.c | 100 ++++++++++++++++++------------- zebra/label_manager.c | 133 ++++++++++++++++++++++++++++++------------ zebra/label_manager.h | 2 +- zebra/zserv.c | 5 +- 5 files changed, 159 insertions(+), 85 deletions(-) diff --git a/ldpd/lde.c b/ldpd/lde.c index d8a2924b31..36998e7cf8 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -140,6 +140,8 @@ zclient_sync_init(u_short instance) fprintf(stderr, "Error connecting synchronous zclient!\n"); lde_sleep(); } + /* make socket non-blocking */ + sock_set_nonblock(zclient_sync->sock); /* Connect to label manager */ while (lm_label_manager_connect (zclient_sync) != 0) { @@ -1596,8 +1598,6 @@ lde_get_label_chunk(void) if (ret < 0) { log_warnx("Error getting label chunk!"); - close(zclient_sync->sock); - zclient_sync->sock = -1; return -1; } diff --git a/lib/zclient.c b/lib/zclient.c index d2a5186315..6aea4bd0a3 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1465,6 +1465,47 @@ zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id, *new_vrf_id = new_id; 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 * @@ -1480,11 +1521,6 @@ lm_label_manager_connect (struct zclient *zclient) int ret; struct stream *s; 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) zlog_debug ("Connecting to Label Manager"); @@ -1524,20 +1560,15 @@ lm_label_manager_connect (struct zclient *zclient) zlog_debug ("%s: Label manager connect request (%d bytes) sent", __func__, ret); /* read response */ - s = zclient->ibuf; - stream_reset (s); + if (zclient_read_sync_response (zclient, ZEBRA_LABEL_MANAGER_CONNECT) != 0) + return -1; - 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; - } /* result */ + s = zclient->ibuf; result = stream_getc(s); if (zclient_debug) - zlog_debug ("%s: Label Manager connect response (%d bytes) received, result %u", - __func__, size, result); + zlog_debug ("%s: Label Manager connect response received, result %u", + __func__, result); return (int)result; } @@ -1561,11 +1592,6 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size, { int ret; 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; if (zclient_debug) @@ -1604,18 +1630,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); /* read response */ + if (zclient_read_sync_response (zclient, ZEBRA_GET_LABEL_CHUNK) != 0) + return -1; + s = zclient->ibuf; - 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; - } - if (zclient_debug) - zlog_debug ("%s: Label chunk response (%d bytes) received", __func__, size); - /* keep */ response_keep = stream_getc(s); /* start and end labels */ @@ -1623,18 +1641,20 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size, *end = stream_getl(s); /* not owning this response */ - if (keep != response_keep) { - zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u", - __func__, *start, *end, keep, response_keep); - } + if (keep != response_keep) + { + zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u", + __func__, *start, *end, keep, response_keep); + } /* sanity */ if (*start > *end || *start < MPLS_MIN_UNRESERVED_LABEL - || *end > MPLS_MAX_UNRESERVED_LABEL) { - zlog_err ("%s: Invalid Label chunk: %u - %u", __func__, - *start, *end); - return -1; - } + || *end > MPLS_MAX_UNRESERVED_LABEL) + { + zlog_err ("%s: Invalid Label chunk: %u - %u", __func__, + *start, *end); + return -1; + } if (zclient_debug) zlog_debug ("Label Chunk assign: %u - %u (%u) ", diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 7dbb36edb8..08f3c3cfe9 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -56,6 +56,80 @@ static void delete_label_chunk(void *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 * label manager. @@ -64,19 +138,25 @@ static void delete_label_chunk(void *val) * proxy. * * @param cmd Type of request (connect, get or release) - * @param src Input buffer from zserv + * @param zserv * @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; - int ret; + int ret = 0; if (zclient->sock < 0) { zlog_err("%s: Error relaying label chunk request: no zclient socket", __func__); + reply_error (cmd, zserv, vrf_id); 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 */ src = zserv->ibuf; dst = zclient->obuf; @@ -87,6 +167,7 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv) if (ret <= 0) { zlog_err("%s: Error relaying label chunk request: %s", __func__, strerror(errno)); + reply_error (cmd, zserv, vrf_id); return -1; } zlog_debug("%s: Label chunk request relayed. %d bytes sent", __func__, @@ -96,43 +177,15 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv) if (cmd == ZEBRA_RELEASE_LABEL_CHUNK) return 0; - /* read response */ - src = zclient->ibuf; - dst = zserv->obuf; - - 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); + /* make sure we listen to the response */ + if (!zclient->t_read) + zclient->t_read = + thread_add_read(zclient->master, lm_zclient_read, zserv, zclient->sock); return 0; } -static int zclient_connect(struct thread *t) +static int lm_zclient_connect(struct thread *t) { zclient->t_connect = NULL; @@ -142,11 +195,15 @@ static int zclient_connect(struct thread *t) if (zclient_socket_connect(zclient) < 0) { zlog_err("Error connecting synchronous zclient!"); THREAD_TIMER_ON(zebrad.master, zclient->t_connect, - zclient_connect, + lm_zclient_connect, zclient, CONNECTION_DELAY); return -1; } + /* make socket non-blocking */ + if (set_nonblocking(zclient->sock) < 0) + zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock); + return 0; } @@ -165,7 +222,7 @@ static void lm_zclient_init(char *lm_zserv_path) zclient = zclient_new(zebrad.master); zclient->sock = -1; zclient->t_connect = NULL; - zclient_connect (NULL); + lm_zclient_connect(NULL); } /** diff --git a/zebra/label_manager.h b/zebra/label_manager.h index 0c6a5ebc7d..fd0b3b549b 100644 --- a/zebra/label_manager.h +++ b/zebra/label_manager.h @@ -62,7 +62,7 @@ struct label_manager { 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); struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance, u_char keep, uint32_t size); diff --git a/zebra/zserv.c b/zebra/zserv.c index 3477dc36d2..533678f16d 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1911,10 +1911,7 @@ zread_label_manager_request (int cmd, struct zserv *client, vrf_id_t vrf_id) /* external label manager */ if (lm_is_external) - { - if (zread_relay_label_manager_request (cmd, client) != 0) - zsend_label_manager_connect_response (client, vrf_id, 1); - } + zread_relay_label_manager_request (cmd, client, vrf_id); /* this is a label manager */ else { From eb15f4773acaadce78efeddb425030e14d014116 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Mon, 15 May 2017 17:03:10 +0000 Subject: [PATCH 02/40] bgpd: added bgp_nexthop_afi() Signed-off-by: Daniel Walton Added bgp_nexthop_afi() to have one place that determines what the Nexthop AFI is for bgp_packet_mpattr_start() --- bgpd/bgp_attr.c | 32 ++++++++++++++++++++++++-------- bgpd/bgp_attr.h | 2 ++ bgpd/bgp_updgrp_packet.c | 9 +++++---- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index d80b9f237b..5c444869b4 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2827,10 +2827,6 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi, stream_putw (s, pkt_afi); /* AFI */ stream_putc (s, pkt_safi); /* SAFI */ - if (afi == AFI_L2VPN) - nh_afi = AFI_L2VPN; - else if (nh_afi == AFI_MAX) - nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len); /* Nexthop */ switch (nh_afi) @@ -3099,6 +3095,27 @@ bgp_packet_mpattr_end (struct stream *s, size_t sizep) stream_putw_at (s, sizep, (stream_get_endp (s) - sizep) - 2); } + +/* Return the Nexthop AFI that should be used */ +afi_t +bgp_nexthop_afi (struct peer *peer, afi_t afi, safi_t safi, struct attr *attr) +{ + afi_t nh_afi; + + if (peer_cap_enhe(peer, afi, safi)) { + nh_afi = AFI_IP6; + } else { + if (afi == AFI_L2VPN) + nh_afi = AFI_L2VPN; + else if (safi == SAFI_LABELED_UNICAST) + nh_afi = afi; + else + nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len); + } + + return nh_afi; +} + /* Make attribute packet. */ bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *peer, @@ -3115,6 +3132,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, int send_as4_path = 0; int send_as4_aggregator = 0; int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0; + afi_t nh_afi; if (! bgp) bgp = peer->bgp; @@ -3127,10 +3145,8 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, { size_t mpattrlen_pos = 0; - mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, - (peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : - AFI_MAX), /* get from NH */ - vecarr, attr); + nh_afi = bgp_nexthop_afi(peer, afi, safi, attr); + mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, nh_afi, vecarr, attr); bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag, addpath_encode, addpath_tx_id, attr); bgp_packet_mpattr_end(s, mpattrlen_pos); diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 1df1faf939..2931b2f2b6 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -249,6 +249,8 @@ extern struct attr *bgp_attr_default_set (struct attr *attr, u_char); extern struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char, struct aspath *, struct community *, int as_set, u_char); +extern afi_t bgp_nexthop_afi (struct peer *peer, afi_t afi, safi_t safi, + struct attr *attr); extern bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *, struct stream *, struct attr *, struct bpacket_attr_vec_arr *vecarr, diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index f734763b70..8a4824f859 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -656,6 +656,7 @@ subgroup_update_packet (struct update_subgroup *subgrp) u_int32_t addpath_tx_id = 0; struct prefix_rd *prd = NULL; char label_buf[20]; + afi_t nh_afi; if (!subgrp) return NULL; @@ -767,11 +768,11 @@ subgroup_update_packet (struct update_subgroup *subgrp) if (bgp_labeled_safi(safi)) sprintf (label_buf, "label %u", label_pton(tag)); - if (stream_empty (snlri)) - mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi, - (peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : - AFI_MAX), /* get from NH */ + if (stream_empty (snlri)) { + nh_afi = bgp_nexthop_afi(peer, afi, safi, adv->baa->attr); + mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi, nh_afi, &vecarr, adv->baa->attr); + } bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, tag, addpath_encode, addpath_tx_id, adv->baa->attr); From 604bbacbcf9e3dbee2c72d2454d20c54a3f9803f Mon Sep 17 00:00:00 2001 From: Don Slice Date: Tue, 16 May 2017 09:48:18 -0400 Subject: [PATCH 03/40] bgpd: resolve issue with sending vpn labels Found issue where sending labels using "address-family ipv4 vpn" was broken by the labeled-unicast changes. Signed-off-by: Don Slice --- bgpd/bgp_updgrp_packet.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index f734763b70..87a9cfdcfa 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -763,7 +763,13 @@ subgroup_update_packet (struct update_subgroup *subgrp) if (rn->prn) prd = (struct prefix_rd *) &rn->prn->p; - tag = bgp_adv_label(rn, binfo, peer, afi, safi); + + if (safi == SAFI_LABELED_UNICAST) + tag = bgp_adv_label(rn, binfo, peer, afi, safi); + else + if (binfo && binfo->extra) + tag = binfo->extra->tag; + if (bgp_labeled_safi(safi)) sprintf (label_buf, "label %u", label_pton(tag)); From 5578590086b49586c7967ad75da0e58e28dcf368 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 9 May 2017 11:30:43 -0700 Subject: [PATCH 04/40] pimd: Avoid deleting SGRpt entry from PP->P state -Upon Receving SGRpt Prune message, transitioning from Prune Pending state to NOINFO state, ifchannel entry was getting deleted in prune pending timer expiry. This can result in SGRpt ifhchannel deleted and recreated upon receving triggered or periodic SGRpt received from downstream. The automation test failed as it expected (check) SGRpt entry at RP after it triggers SPT switchover. - While transitioning from Prune-Pending state to NOINFO(Pruned) state, Trigger SGRpt message towards RP. - Add/del some of the debug traces Ticket:CM-16057 Reviewed By:CCR-6198 Testing Done: Rerun test08 multiple times and observed passing it. Pim-smoke with hardnode Ran 95 tests in 11219.420s FAILED (SKIP=10, failures=4) Signed-off-by: Chirag Shah --- pimd/pim_ifchannel.c | 49 +++++++++++++++++------ pimd/pim_nht.c | 6 +-- pimd/pim_upstream.c | 95 +++++++++++++++++++++++++------------------- pimd/pim_upstream.h | 2 +- 4 files changed, 96 insertions(+), 56 deletions(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index f4fe609605..04f8a22c6b 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -148,7 +148,6 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) /* SGRpt entry could have empty 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); /* * Do we have any S,G's that are inheriting? * Nuke from on high too. @@ -179,6 +178,10 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) 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__); ch->upstream = NULL; @@ -200,6 +203,9 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) hash_release(pim_ifp->pim_ifchannel_hash, 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); } @@ -571,14 +577,18 @@ pim_ifchannel_add(struct interface *ifp, 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; } -static void ifjoin_to_noinfo(struct pim_ifchannel *ch) +static void ifjoin_to_noinfo(struct pim_ifchannel *ch, uint8_t ch_del) { pim_forward_stop(ch); pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO); - delete_on_noinfo(ch); + if (ch_del) + delete_on_noinfo(ch); } static int on_ifjoin_expiry_timer(struct thread *t) @@ -589,7 +599,7 @@ static int on_ifjoin_expiry_timer(struct thread *t) ch->t_ifjoin_expiry_timer = NULL; - ifjoin_to_noinfo(ch); + ifjoin_to_noinfo(ch, 1); /* ch may have been deleted */ return 0; @@ -613,10 +623,6 @@ static int on_ifjoin_prune_pending_timer(struct thread *t) pim_ifp = ifp->info; 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) { struct pim_rpf rpf; @@ -625,6 +631,23 @@ static int on_ifjoin_prune_pending_timer(struct thread *t) rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address; 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, 0); + } + else + ifjoin_to_noinfo(ch, 1); + /* from here ch may have been deleted */ } else { @@ -801,7 +824,7 @@ void pim_ifchannel_join_add(struct interface *ifp, (ch->upstream->parent->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) && !(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); } break; @@ -895,8 +918,10 @@ void pim_ifchannel_prune(struct interface *ifp, case PIM_IFJOIN_NOINFO: if (source_flags & PIM_ENCODE_RPT_BIT) { - PIM_IF_FLAG_SET_S_G_RPT(ch->flags); - ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING; + if (!(source_flags & PIM_ENCODE_WC_BIT)) + PIM_IF_FLAG_SET_S_G_RPT(ch->flags); + + ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING; if (listcount(pim_ifp->pim_neighbor_list) > 1) jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp); else @@ -1306,7 +1331,7 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t if (up) { 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); } } diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index c5f8d1d826..9165bef566 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -567,7 +567,7 @@ pim_ecmp_nexthop_search (struct pim_nexthop_cache *pnc, //PIM ECMP flag is enable then choose ECMP path. hash_val = pim_compute_ecmp_hash (src, grp); 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 ", __PRETTY_FUNCTION__, hash_val, mod_val); } @@ -914,7 +914,7 @@ pim_ecmp_nexthop_lookup (struct pim_nexthop *nexthop, struct in_addr addr, { hash_val = pim_compute_ecmp_hash (src, grp); 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", __PRETTY_FUNCTION__, hash_val, mod_val); } @@ -1037,7 +1037,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr, { hash_val = pim_compute_ecmp_hash (src, grp); 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", __PRETTY_FUNCTION__, hash_val, mod_val); } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index dd6eab9cfe..6fadfc2f29 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -78,9 +78,17 @@ pim_upstream_remove_children (struct pim_upstream *up) while (!list_isempty (up->sources)) { child = listnode_head (up->sources); - child->parent = NULL; 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; } /* @@ -149,10 +157,14 @@ void pim_upstream_free(struct pim_upstream *up) static void upstream_channel_oil_detach(struct pim_upstream *up) { - if (up->channel_oil) { - pim_channel_oil_del(up->channel_oil); - up->channel_oil = NULL; - } + 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); + up->channel_oil = NULL; + } } struct pim_upstream * @@ -163,7 +175,7 @@ pim_upstream_del(struct pim_upstream *up, const char *name) if (PIM_DEBUG_TRACE) zlog_debug ("%s(%s): Delete %s ref count: %d , flags: %d c_oil ref count %d (Pre decrement)", - __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags, + __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags, up->channel_oil->oil_ref_count); --up->ref_count; @@ -195,26 +207,12 @@ pim_upstream_del(struct pim_upstream *up, const char *name) } pim_upstream_remove_children (up); + if (up->sources) + list_delete (up->sources); + up->sources = NULL; pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__); 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); up->ifchannels = NULL; @@ -223,11 +221,10 @@ pim_upstream_del(struct pim_upstream *up, const char *name) into pim_upstream_free() because the later is called by list_delete_all_node() */ - if (up->parent) - { - listnode_delete (up->parent->sources, up); - up->parent = NULL; - } + if (up->parent && up->parent->sources) + listnode_delete (up->parent->sources, up); + up->parent = NULL; + listnode_delete (pim_upstream_list, up); hash_release (pim_upstream_hash, up); @@ -538,13 +535,14 @@ pim_upstream_switch(struct pim_upstream *up, { enum pim_upstream_state old_state = up->join_state; - if (PIM_DEBUG_PIM_EVENTS) { - zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s", + if (PIM_DEBUG_PIM_EVENTS) + { + zlog_debug ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s", __PRETTY_FUNCTION__, up->sg_str, pim_upstream_state2str (up->join_state), pim_upstream_state2str (new_state)); - } + } up->join_state = new_state; if (old_state != new_state) @@ -584,7 +582,17 @@ pim_upstream_switch(struct pim_upstream *up, if (old_state == PIM_UPSTREAM_JOINED) pim_msdp_up_join_state_changed(up); - pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */); + /* 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 */); join_timer_stop(up); } } @@ -717,9 +725,9 @@ pim_upstream_new (struct prefix_sg *sg, 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, - inet_ntoa (up->upstream_addr)); + inet_ntoa (up->upstream_addr), up->ref_count); } return up; @@ -750,6 +758,9 @@ pim_upstream_find_or_add(struct prefix_sg *sg, { up->flags |= flags; 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 @@ -759,10 +770,13 @@ pim_upstream_find_or_add(struct prefix_sg *sg, } 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->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, @@ -773,7 +787,7 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg, int found = 0; up = pim_upstream_find(sg); if (up) { - pim_upstream_ref(up, flags); + pim_upstream_ref(up, flags, name); found = 1; } else { @@ -786,10 +800,11 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg, { char buf[PREFIX2STR_BUFFER]; 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, - up->sg_str, buf, found, - up->ref_count); + up->sg_str, buf, up->rpf.source_nexthop.interface ? + up->rpf.source_nexthop.interface->name : "NIL" , + found, up->ref_count); } else zlog_debug("%s(%s): (%s) failure to create", @@ -1660,7 +1675,7 @@ pim_upstream_sg_running (void *arg) if (PIM_DEBUG_TRACE) 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_fhr_kat_start(up); } diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index f1c8df35b1..d728c6c01f 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -145,7 +145,7 @@ struct pim_upstream *pim_upstream_find_or_add (struct prefix_sg *sg, struct pim_upstream *pim_upstream_add (struct prefix_sg *sg, struct interface *ifp, int flags, 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); int pim_upstream_evaluate_join_desired(struct pim_upstream *up); From a91ec03e11c779bb8dcd21882bcecb0a7a8a68e5 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Sat, 6 May 2017 11:18:24 -0700 Subject: [PATCH 05/40] pimd: IGMP Query Tx when Oth. Querier exp Send IGMP General Query and Get Gen. Query timer, once Other Querier timer expired. Ticket:CM-13152 Reviewed By:CCR-6189 Testing Done: tor-4# show ip igmp interface Interface State Address V Querier Query Timer Uptime swp2 up 70.1.1.2 3 other --:--:-- 00:06:45 swp3 up 80.1.1.2 3 local 00:00:35 00:22:52 Upon disabling IGMP on remote igmp interface, after other querier expiry sends a query and elects as Querier tor-4# show ip igmp interface Interface State Address V Querier Query Timer Uptime swp2 up 70.1.1.2 3 local 00:01:29 00:10:16 swp3 up 80.1.1.2 3 local 00:01:14 00:26:23 Signed-off-by: Chirag Shah --- pimd/pim_igmp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index ee88e7d8ea..dd5f7e77e9 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -39,6 +39,7 @@ #include "pim_zebra.h" 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 * in pim_mroute_msg() @@ -172,8 +173,11 @@ static int pim_igmp_other_querier_expire(struct thread *t) /* We are the current querier, then 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; } @@ -497,8 +501,6 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len) return -1; } -static int pim_igmp_general_query(struct thread *t); - void pim_igmp_general_query_on(struct igmp_sock *igmp) { struct pim_interface *pim_ifp; From 2b26882d28fb6c28930c97c4ad53d0bc3e1f29d3 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 16 May 2017 17:28:12 +0000 Subject: [PATCH 06/40] bgpd: fix nh_afi in bgp_packet_mpattr_start() Signed-off-by: Daniel Walton --- bgpd/bgp_attr.c | 39 +++++++++++++++------------------------ bgpd/bgp_attr.h | 4 ++-- bgpd/bgp_updgrp_packet.c | 7 ++----- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 5c444869b4..0eb84bda02 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2807,13 +2807,26 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, } 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 attr *attr) { size_t sizep; iana_afi_t pkt_afi; safi_t pkt_safi; + afi_t nh_afi; + + if (peer_cap_enhe(peer, afi, safi)) { + nh_afi = AFI_IP6; + } else { + if (afi == AFI_L2VPN) + nh_afi = AFI_L2VPN; + else if (safi == SAFI_LABELED_UNICAST) + nh_afi = afi; + else + nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len); + } /* Set extended bit always to encode the attribute length as 2 bytes */ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN); @@ -3096,26 +3109,6 @@ bgp_packet_mpattr_end (struct stream *s, size_t sizep) } -/* Return the Nexthop AFI that should be used */ -afi_t -bgp_nexthop_afi (struct peer *peer, afi_t afi, safi_t safi, struct attr *attr) -{ - afi_t nh_afi; - - if (peer_cap_enhe(peer, afi, safi)) { - nh_afi = AFI_IP6; - } else { - if (afi == AFI_L2VPN) - nh_afi = AFI_L2VPN; - else if (safi == SAFI_LABELED_UNICAST) - nh_afi = afi; - else - nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len); - } - - return nh_afi; -} - /* Make attribute packet. */ bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *peer, @@ -3132,7 +3125,6 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, int send_as4_path = 0; int send_as4_aggregator = 0; int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0; - afi_t nh_afi; if (! bgp) bgp = peer->bgp; @@ -3145,8 +3137,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, { size_t mpattrlen_pos = 0; - nh_afi = bgp_nexthop_afi(peer, afi, safi, attr); - mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, nh_afi, vecarr, attr); + mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, vecarr, attr); bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag, addpath_encode, addpath_tx_id, attr); bgp_packet_mpattr_end(s, mpattrlen_pos); diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 2931b2f2b6..e7f3e25c41 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -299,8 +299,8 @@ bgp_attr_flush_encap(struct attr *attr); * one for each NLRI that needs to be encoded into the UPDATE message, and * finally the _end() function. */ -extern size_t bgp_packet_mpattr_start(struct stream *s, afi_t afi, safi_t safi, - afi_t nh_afi, +extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, + afi_t afi, safi_t safi, struct bpacket_attr_vec_arr *vecarr, struct attr *attr); extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 8a4824f859..2408a8ca30 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -656,7 +656,6 @@ subgroup_update_packet (struct update_subgroup *subgrp) u_int32_t addpath_tx_id = 0; struct prefix_rd *prd = NULL; char label_buf[20]; - afi_t nh_afi; if (!subgrp) return NULL; @@ -768,11 +767,9 @@ subgroup_update_packet (struct update_subgroup *subgrp) if (bgp_labeled_safi(safi)) sprintf (label_buf, "label %u", label_pton(tag)); - if (stream_empty (snlri)) { - nh_afi = bgp_nexthop_afi(peer, afi, safi, adv->baa->attr); - mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi, nh_afi, + if (stream_empty (snlri)) + mpattrlen_pos = bgp_packet_mpattr_start (snlri, peer, afi, safi, &vecarr, adv->baa->attr); - } bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, tag, addpath_encode, addpath_tx_id, adv->baa->attr); From a080e8fbcbbfe05287ad4f7935c81a3816965e00 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 16 May 2017 18:05:45 +0000 Subject: [PATCH 07/40] bgpd: fix nh_afi in bgp_packet_mpattr_start() Signed-off-by: Daniel Walton --- bgpd/bgp_attr.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 0eb84bda02..f21194149f 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2817,17 +2817,6 @@ bgp_packet_mpattr_start (struct stream *s, struct peer *peer, safi_t pkt_safi; afi_t nh_afi; - if (peer_cap_enhe(peer, afi, safi)) { - nh_afi = AFI_IP6; - } else { - if (afi == AFI_L2VPN) - nh_afi = AFI_L2VPN; - else if (safi == SAFI_LABELED_UNICAST) - nh_afi = afi; - else - nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len); - } - /* 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_MP_REACH_NLRI); @@ -2841,6 +2830,18 @@ bgp_packet_mpattr_start (struct stream *s, struct peer *peer, stream_putw (s, pkt_afi); /* AFI */ stream_putc (s, pkt_safi); /* SAFI */ + /* Nexthop AFI */ + if (peer_cap_enhe(peer, afi, safi)) { + nh_afi = AFI_IP6; + } else { + if (afi == AFI_L2VPN) + nh_afi = AFI_L2VPN; + else if (safi == SAFI_LABELED_UNICAST) + nh_afi = afi; + else + nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len); + } + /* Nexthop */ switch (nh_afi) { @@ -3108,7 +3109,6 @@ bgp_packet_mpattr_end (struct stream *s, size_t sizep) stream_putw_at (s, sizep, (stream_get_endp (s) - sizep) - 2); } - /* Make attribute packet. */ bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *peer, From 7780aaaa7230eb077c3cd27a988b44fc102a23d7 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 16 May 2017 18:57:20 +0000 Subject: [PATCH 08/40] lib: Remove the "This command currently does nothing" message Signed-off-by: Daniel Walton This breaks the "vtysh -m" output which causes problems for frr-reload.py --- lib/command.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/command.c b/lib/command.c index cc597952e4..f9566f8154 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1371,11 +1371,6 @@ DEFUN (frr_version_defaults, "set of configuration defaults used\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; } From d32dfc22011c79c87edcdf05b66f4598443ee7b2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 15 Nov 2016 10:16:52 -0500 Subject: [PATCH 09/40] bgpd: Fix ADJCHANGE message to include more info When bgp logs ADJCHANGE messages include the hostname and vrf that this change is being made in. Ticket: CM-10922 Signed-off-by: Donald Sharp --- bgpd/bgp_fsm.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index e669b4f9b7..f20bd3bf26 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1021,8 +1021,14 @@ bgp_stop (struct peer *peer) /* bgp log-neighbor-changes of neighbor Down */ if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) - zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host, - peer_down_str [(int) peer->last_reset]); + { + struct vrf *vrf = vrf_lookup_by_id (peer->bgp->vrf_id); + zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s", + peer->host, + (peer->hostname) ? peer->hostname : "Unknown", + (vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default", + peer_down_str [(int) peer->last_reset]); + } /* graceful restart */ if (peer->t_gr_stale) @@ -1459,8 +1465,13 @@ bgp_establish (struct peer *peer) /* bgp log-neighbor-changes of neighbor Up */ if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) - zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host); - + { + struct vrf *vrf = vrf_lookup_by_id (peer->bgp->vrf_id); + zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up", + peer->host, + (peer->hostname) ? peer->hostname : "Unknown", + (vrf->vrf_id != VRF_DEFAULT ) ? vrf->name : "Default"); + } /* assign update-group/subgroup */ update_group_adjust_peer_afs(peer); From 2e37f307ee663c3955044c6fa97914c37fed9751 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Tue, 22 Nov 2016 09:48:16 -0800 Subject: [PATCH 10/40] bgpd: fix crash in bgp_stop due to missing vrf Problem found to be derefencing a vrf that had already been deleted. Fix verifies that vrf exists before using it. Ticket: CM-13682 Signed-off-by: Don Slice Reviewed By: Vivek Venkatraman Testing Done: manual testing, re-run of failing scripts good --- bgpd/bgp_fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index f20bd3bf26..e3968d21cd 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1026,7 +1026,7 @@ bgp_stop (struct peer *peer) zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s", peer->host, (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]); } From fa14eb2c0b408982a6634459b3afb21e9df6326a Mon Sep 17 00:00:00 2001 From: Don Slice Date: Wed, 5 Apr 2017 07:13:45 -0700 Subject: [PATCH 11/40] bgpd: resolve ipv6 ecmp issue with vrfs and ll nexthop Problem reported that ecmp wasn't working correctly in a vrf with ipv6. Issue was that originator of the routes were sending the updates with a link-local nexthop and nhlen of 16. In this particular case, bgp_zebra_announce was using the wrong call to get the ifindex and was not supplying the vrf. This caused ecmp to work only in the case of the default vrf. Ticket: CM-15545 Signed-off-by: Don Slice Reviewed-by: CCR-6017 --- bgpd/bgp_zebra.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 3d3bd90f5b..d07fc65bdf 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1469,7 +1469,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, if (!ifindex) { if (info->peer->conf_if || info->peer->ifname) - ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname); + ifindex = ifname2ifindex_vrf (info->peer->conf_if ? info->peer->conf_if : + info->peer->ifname, bgp->vrf_id); else if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } From 83f35619359379687f21c839d61121e4ebe72541 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 16 May 2017 23:49:53 +0000 Subject: [PATCH 12/40] zebra: 'no ip route 4.1.1.19 255.255.255.255 99' is ambiguous Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp --- zebra/zebra_mpls_vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 8b967c3af8..343f2975e8 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -472,7 +472,7 @@ DEFUN (no_ip_route_tag_distance_label, DEFUN (no_ip_route_mask_distance_label, no_ip_route_mask_distance_label_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", + "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> label WORD", NO_STR IP_STR "Establish static routes\n" @@ -486,7 +486,7 @@ DEFUN (no_ip_route_mask_distance_label, "One or more labels separated by '/'\n") { return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, - argv[3], NULL, argv[5]); + argv[3], NULL, argv[4]); } DEFUN (no_ip_route_mask_tag_distance_label, From 464598de53722b515c0967eb223aa538bb27ecf6 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 16 May 2017 23:54:46 +0000 Subject: [PATCH 13/40] bgpd: "neighbor swpX interface remote-as XYZ" is ignored Signed-off-by: Daniel Walton Reviewed-by: Don Slice If you did: neighbor swp1 interface neighbor swp1 interface remote-as external we would not set the remote-as. You could however still do neighbor swp1 remote-as external --- bgpd/bgp_vty.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 347d026aff..f163fef712 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2872,7 +2872,12 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi, } peer = peer_lookup_by_conf_if (bgp, conf_if); - if (!peer) + if (peer) + { + if (as_str) + ret = peer_remote_as (bgp, &su, NULL, &as, as_type, afi, safi); + } + else { if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4) && afi == AFI_IP && safi == SAFI_UNICAST) @@ -2896,8 +2901,9 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi, } peer_flag_set (peer, PEER_FLAG_CAPABILITY_ENHE); } - else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) || - (!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))) { if (v6only) SET_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY); From 10a6a98b0af1c5490c8b87ab0ce15d5edabbbc35 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 16 May 2017 23:56:31 +0000 Subject: [PATCH 14/40] bgpd: does not honor configured keepalive timer Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp --- bgpd/bgp_packet.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 796a57f054..5ac982d565 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1118,7 +1118,10 @@ bgp_open_receive (struct peer *peer, bgp_size_t size) else peer->v_holdtime = send_holdtime; - peer->v_keepalive = peer->v_holdtime / 3; + if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)) + peer->v_keepalive = peer->keepalive; + else + peer->v_keepalive = peer->v_holdtime / 3; /* Open option part parse. */ if (optlen != 0) From 501be9875b7e385d4b39e85ea6bddd431e87e8bb Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 16 May 2017 23:58:34 +0000 Subject: [PATCH 15/40] bgpd: 'redistribute' triggers both IPv4 and IPv6 code paths Signed-off-by: Daniel Walton Whenever you did "redistribute" zebra would kick this off for ipv4 and ipv6. No real issue other than this is sub-optimal --- zebra/redistribute.c | 56 ++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 9c7ef5f12c..5d7dbd5b00 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -108,42 +108,38 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id) /* Redistribute routes. */ 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 route_table *table; struct route_node *rn; - int afi; - for (afi = AFI_IP; afi <= AFI_IP6; afi++) - { - table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); - if (! table) - continue; + table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); + if (! table) + return; - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, newrib) - { - 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, - zebra_check_addr (&rn->p)); + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, newrib) + { + 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, + zebra_check_addr (&rn->p)); - if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)) - continue; - if ((type != ZEBRA_ROUTE_ALL && - (newrib->type != type || newrib->instance != instance))) - continue; - if (newrib->distance == DISTANCE_INFINITY) - continue; - if (! zebra_check_addr (&rn->p)) - continue; + if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)) + continue; + if ((type != ZEBRA_ROUTE_ALL && + (newrib->type != type || newrib->instance != instance))) + continue; + if (newrib->distance == DISTANCE_INFINITY) + continue; + if (! zebra_check_addr (&rn->p)) + continue; - zsend_redistribute_route (1, client, &rn->p, newrib); - } - } + zsend_redistribute_route (1, client, &rn->p, newrib); + } } /* Either advertise a route for redistribution to registered clients or */ @@ -262,13 +258,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length, if (! redist_check_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 { if (! vrf_bitmap_check (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); } } } From 3bd07551f803960920db358dd8291b24ca50ec79 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:01:23 +0000 Subject: [PATCH 16/40] bgp: garbage "neighbor (af 54816) remote-as internal" peer in show run Signed-off-by: Daniel Walton --- bgpd/bgp_vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f163fef712..6f330b0d03 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2875,7 +2875,7 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi, if (peer) { if (as_str) - ret = peer_remote_as (bgp, &su, NULL, &as, as_type, afi, safi); + ret = peer_remote_as (bgp, &su, conf_if, &as, as_type, afi, safi); } else { From 46111f2f48e964ac14b617f77fccb574cfb8d693 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:07:02 +0000 Subject: [PATCH 17/40] bgpd: Add epoch uptime to BGP neighbor json outputs Signed-off-by: Daniel Walton --- bgpd/bgp_vty.c | 4 ++++ bgpd/bgpd.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 6f330b0d03..f71d03e46b 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11087,6 +11087,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js u_int16_t i; u_char *msg; json_object *json_neigh = NULL; + time_t epoch_tbuf; bgp = p->bgp; @@ -11277,8 +11278,11 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js uptime = bgp_clock(); uptime -= p->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_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) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 86133cd763..31d54a3e98 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6250,7 +6250,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi, char * 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; /* Check buffer length. */ @@ -6304,8 +6304,10 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object if (use_json) { + epoch_tbuf = time(NULL) - uptime1; json_object_string_add(json, "peerUptime", buf); json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000); + json_object_int_add(json, "peerUptimeEstablishedEpoch", epoch_tbuf); } return buf; From 825be4c27bc165e68ebcb1de8d1beebdbd8c82e9 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:14:37 +0000 Subject: [PATCH 18/40] tools: frr-reload.py should exit non-zero when "set src x.x.x.x" fails Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp --- tools/frr-reload.py | 34 +++++++++++++++++++++++++++++----- vtysh/vtysh.c | 2 +- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 80d2d6a2a3..0e71eaa04c 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -346,6 +346,7 @@ end "debug ", "dump ", "enable ", + "frr ", "hostname ", "ip ", "ipv6 ", @@ -888,11 +889,15 @@ if __name__ == '__main__': # Verify the new config file is valid 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) 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) # Verify that 'service integrated-vtysh-config' is configured @@ -909,7 +914,9 @@ if __name__ == '__main__': break 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) if args.debug: @@ -920,6 +927,7 @@ if __name__ == '__main__': # Create a Config object from the config generated by newconf newconf = Config() newconf.load_from_file(args.filename) + reload_ok = True if args.test: @@ -1029,7 +1037,7 @@ if __name__ == '__main__': # 'no ip ospf authentication message-digest 1.1.1.1' in # our example above # - 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(' ') if len(last_arg) <= 2: @@ -1064,9 +1072,25 @@ if __name__ == '__main__': with open(filename, 'w') as fh: for line in lines_to_configure: 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) # Make these changes persistent if args.overwrite or args.filename != '/etc/frr/frr.conf': subprocess.call(['/usr/bin/vtysh', '-c', 'write']) + + if not reload_ok: + sys.exit(1) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 51f71a46bb..2994c3507a 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -635,7 +635,7 @@ vtysh_mark_file (const char *filename) } } /* This is the end */ - fprintf(stdout, "end\n"); + fprintf(stdout, "\nend\n"); vty_close(vty); XFREE(MTYPE_VTYSH_CMD, vty_buf_copy); From afa2e8e1870eab4578e19c80cfd23bb443d1adbe Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:16:09 +0000 Subject: [PATCH 19/40] tools: reload handle removal of entire address-family section under BGP Signed-off-by: Daniel Walton When an entire address-family section is removed from under BGP, we cannot just issue 'no address-family foo bar' as address-family line doesn't support 'no'. We have to delete the individual lines under the address-family. --- tools/frr-reload.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 0e71eaa04c..1ef6920d06 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -814,6 +814,14 @@ def compare_context_objects(newconf, running): elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd: 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 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)) From 970c956816599fe3d58bc45ca3a18b9542467337 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:18:33 +0000 Subject: [PATCH 20/40] tools: frr-reload removes "ipv6 nd ra-interval" and "no ipv6 nd supp" Signed-off-by: Daniel Walton --- tools/frr-reload.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 1ef6920d06..f6cb6d9910 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -1009,7 +1009,20 @@ if __name__ == '__main__': (lines_to_add, lines_to_del) = compare_context_objects(newconf, running) - if lines_to_del: + # Only do deletes on the first pass. The reason being if we + # configure a bgp neighbor via "neighbor swp1 interface" frr + # will automatically add: + # + # interface swp1 + # ipv6 nd ra-interval 10 + # no ipv6 nd suppress-ra + # ! + # + # but those lines aren't in the config we are reloading against so + # on the 2nd pass they will show up in lines_to_del. This could + # apply to other scenarios as well where configuring FOO adds BAR + # to the config. + if lines_to_del and x == 0: for (ctx_keys, line) in lines_to_del: if line == '!': From 619c4e3acf2077dc16adf6ebd48adaec9365c623 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:22:00 +0000 Subject: [PATCH 21/40] frr-reload.py fails on "no debug ospf6 message unknown" Signed-off-by: Daniel Walton --- tools/frr-reload.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index f6cb6d9910..090937ed27 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -351,6 +351,7 @@ end "ip ", "ipv6 ", "log ", + "no ", "password ", "ptm-enable", "router-id ", From ec3fd9577411a4555a9988f8187e2d1598cd2b00 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:23:38 +0000 Subject: [PATCH 22/40] tools: frr-reload.py VtyshMarkException needs to include "vtysh -m" output Signed-off-by: Daniel Walton --- tools/frr-reload.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 090937ed27..11e0bdc681 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -109,9 +109,12 @@ class Config(object): log.info('Loading Config object from file %s', filename) 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: - raise VtyshMarkException(str(e)) + ve = VtyshMarkException(e) + ve.output = e.output + raise ve for line in file_output.split('\n'): line = line.strip() @@ -134,9 +137,11 @@ class Config(object): try: config_text = subprocess.check_output( "/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: - raise VtyshMarkException(str(e)) + ve = VtyshMarkException(e) + ve.output = e.output + raise ve for line in config_text.split('\n'): line = line.strip() From e80c8c5531635e9df550f11b466f35644668f9f5 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Wed, 17 May 2017 00:25:28 +0000 Subject: [PATCH 23/40] tools: Allow frr-reload.py to know about agentx Signed-off-by: Daniel Walton Signed-off-by: Donald Sharp --- tools/frr-reload.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 11e0bdc681..a9151e3e7d 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -347,6 +347,7 @@ end # the keywords that we know are single line contexts. bgp in this case # is not the main router bgp block, but enabling multi-instance oneline_ctx_keywords = ("access-list ", + "agentx", "bgp ", "debug ", "dump ", From 30cfe9a2910297f1114c3da44d97e0fdcacaecd0 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Mon, 23 Jan 2017 17:39:54 -0800 Subject: [PATCH 24/40] pimd: fix ip pim hello option does not take in effect If frr.conf file has pim hello option setup prior to pim sm under an interface, upon frr start/restart hello option cli replayed prior to sm command from vtysh. Added a code in pim hello option cli handler to create pim vif if it does not exist. Testing Done: configure pim hello options before pim sm in frr.conf file and restart frr Signed-off-by: Chirag Shah --- pimd/pim_cmd.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 1224bc5fc8..0f4e8fdcbf 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -5075,11 +5075,16 @@ DEFUN (interface_ip_pim_hello, pim_ifp = ifp->info; - if (!pim_ifp) { - vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE); - return CMD_WARNING; - } + if (!pim_ifp) + { + if (!pim_cmd_interface_add(ifp)) + { + vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + pim_ifp = ifp->info; pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10); if (argc == idx_hold + 1) From 8dc60b69b582728866ec485c77a3e296123aac5a Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 24 Jan 2017 14:58:59 -0800 Subject: [PATCH 25/40] pimd: fix pim reg processing return 1 upon success pim register_recv api returns 1 instead of 0 upon succesfully processing REG message Testing Done: Verified At RP via receiving PIM (Data/Null) Register messages and checked show ip pim interface < > Received errors under Hello Signed-off-by: Chirag Shah --- pimd/pim_register.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 8dc179c144..e6145a142e 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -346,7 +346,7 @@ pim_register_recv (struct interface *ifp, zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet", __func__, "Sender"); /* Drop Packet Silently */ - return 1; + return 0; } } @@ -408,5 +408,5 @@ pim_register_recv (struct interface *ifp, pim_register_stop_send (ifp, &sg, dest_addr, src_addr); } - return 1; + return 0; } From 95d3f5011b509acbbc3a257c74c23bc5b57148af Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 16 May 2017 21:57:25 -0700 Subject: [PATCH 26/40] pimd: Fix input value to bool Signed-off-by: Chirag Shah --- pimd/pim_ifchannel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 04f8a22c6b..c5953e560c 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -583,7 +583,7 @@ pim_ifchannel_add(struct interface *ifp, return ch; } -static void ifjoin_to_noinfo(struct pim_ifchannel *ch, uint8_t ch_del) +static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del) { pim_forward_stop(ch); pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO); @@ -599,7 +599,7 @@ static int on_ifjoin_expiry_timer(struct thread *t) ch->t_ifjoin_expiry_timer = NULL; - ifjoin_to_noinfo(ch, 1); + ifjoin_to_noinfo(ch, true); /* ch may have been deleted */ return 0; @@ -643,10 +643,10 @@ static int on_ifjoin_prune_pending_timer(struct thread *t) 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, 0); + ifjoin_to_noinfo(ch, false); } else - ifjoin_to_noinfo(ch, 1); + ifjoin_to_noinfo(ch, true); /* from here ch may have been deleted */ } else From 9c5cd62f08f5e0d77a6474e15a49dcf8bd8ce21c Mon Sep 17 00:00:00 2001 From: Don Slice Date: Wed, 23 Nov 2016 11:58:27 -0800 Subject: [PATCH 27/40] zebra: Move interfaces to default before deleting Encountered a crash in zebra due to getting a delete on an SVI with VRR configured. Since we don't actually do a delete but flag the interface as inactive, slag VRR interfaces would remain on the vrf_iflist with a lock count of zero, causing the crash. Since all other interface types are moved to the default table before deleting, doing the same thing for any interfaces that were left in the vrf. Testing includes manual testing, bgp-min, ospf-min, vrf-min, bgp-smoke, and ospf-smoke. All passed (first time or on rerun) or match known failures. Ticket: CM-13288 Signed-off-by: Don Slice Reviewed-by: Donald Sharp --- zebra/interface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/zebra/interface.c b/zebra/interface.c index 39c20e6289..524183a434 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -693,6 +693,10 @@ if_delete_update (struct interface *ifp) for setting ifindex to IFINDEX_INTERNAL after processing the interface deletion message. */ ifp->ifindex = IFINDEX_INTERNAL; + + /* 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 */ From 63d825b0db90ba8a69c3da42a8fc163541495a13 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Tue, 6 Dec 2016 09:29:05 -0800 Subject: [PATCH 28/40] zebrad: Correct problem removing dead routes from rib due to NHT issue Fix for another issue with next-hop tracking for overlapping static routes created a problem removing the dead routes. This fix corrects that error. Ticket: CM-13710 Signed-off-by: Don Slice Reviewed By: Donald Sharp Testing Done: ospf-smoke, bgp-smoke --- zebra/zebra_rnh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index b679803b06..1032d5405f 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -546,7 +546,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family, { RNODE_FOREACH_RIB(static_rn, srib) { - if (srib->type == ZEBRA_ROUTE_STATIC) + if (srib->type != ZEBRA_ROUTE_STATIC) continue; /* Set the filter flag for the correct nexthop - static route may From 1dac3a9619c8436f81c7b37f0252574b0b677dd0 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Tue, 14 Feb 2017 09:15:40 -0800 Subject: [PATCH 29/40] zebra: stop deregistering static nexthops unless removing the static Problem reported was that with some overlapping static route configurations, when the link went down the less specific static was not re-installed after the link came back up. Determined that with the overlapping statics, we would recursively resolve the next-hop temporarily thru the more specific static route, but since the next-hop wasn't actually reachable, we would go through the code that clears the nht information for the static completely. This caused the nht code to no longer process the static route. After reviewing the process, there doesn't seem to be any reason that the static should be deregistered in that section of code. Removed the deregister and the problem is resolved and not addional failures seen in manual testing. zebra_test.py completed successfully and ospf and bgp smokes completed with no new failures. Ticket: CM-14873 Signed-off-by: Don Slice Reviewed-by: CCR-5696 --- zebra/zebra_rib.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index e48da0479b..23c4c9ebea 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -366,7 +366,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (set) { UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops(rib->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; rib->nexthop_mtu = 0; @@ -597,7 +596,6 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, if (set) { UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; } From dbb3cdb601642c1259cffca3b7c85e80e628abd7 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 16 May 2017 18:17:23 +0000 Subject: [PATCH 30/40] lib: correctly handle EOF when using poll() Descriptor owner should handle EOF, not thread.c Signed-off-by: Quentin Young --- lib/thread.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/thread.c b/lib/thread.c index 34802fcedd..dbdd91dd24 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -1052,14 +1052,13 @@ check_pollfds(struct thread_master *m, fd_set *readfd, int num) ready++; /* POLLIN / POLLOUT process event */ - if (m->handler.pfds[i].revents & POLLIN) + 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); /* remove fd from list on POLLNVAL */ - if (m->handler.pfds[i].revents & POLLNVAL || - m->handler.pfds[i].revents & POLLHUP) + if (m->handler.pfds[i].revents & POLLNVAL) { memmove(m->handler.pfds+i, m->handler.pfds+i+1, From f14b7abf4f36f6ebcd6280df41b430e062a696c2 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 17 May 2017 01:53:47 +0000 Subject: [PATCH 31/40] vtysh: fix ldpd vtysh ldpd needs a special case to execute the correct exit command for walkup when using vtysh Signed-off-by: Quentin Young --- vtysh/vtysh.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 5bb969bef7..5c39e1ee90 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -324,7 +324,11 @@ vtysh_execute_func (const char *line, int pager) { 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"); } From a108e6e40d85089fe4e46197c0ae3135a12ab2fb Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 17 May 2017 18:37:24 +0000 Subject: [PATCH 32/40] eigrpd: disambiguate bandwidth command eigrpd defines a bandwidth command that takes kilobits instead of megabits which is problematic when installed in the same node as the megabits command since (1-100000) and (1-10000000) are ambiguous Signed-off-by: Quentin Young --- eigrpd/eigrp_vty.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 5694ca49f9..c6ff7b5a80 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -646,7 +646,8 @@ DEFUN (no_eigrp_if_delay, DEFUN (eigrp_if_bandwidth, eigrp_if_bandwidth_cmd, - "bandwidth (1-10000000)", + "eigrp bandwidth (1-10000000)", + "EIGRP specific commands\n" "Set bandwidth informational parameter\n" "Bandwidth in kilobits\n") { @@ -671,8 +672,9 @@ DEFUN (eigrp_if_bandwidth, DEFUN (no_eigrp_if_bandwidth, no_eigrp_if_bandwidth_cmd, - "no bandwidth [(1-10000000)]", + "no eigrp bandwidth [(1-10000000)]", NO_STR + "EIGRP specific commands\n" "Set bandwidth informational parameter\n" "Bandwidth in kilobits\n") { From 201c3dac294e15ecc6673d88f5ca9c1842a71f88 Mon Sep 17 00:00:00 2001 From: Lou Berger Date: Wed, 17 May 2017 14:54:10 -0400 Subject: [PATCH 33/40] bgpd: fix config of v6 vpn networks tags Signed-off-by: Lou Berger --- bgpd/bgp_encap.c | 4 ++-- bgpd/bgp_evpn_vty.c | 4 ++-- bgpd/bgp_mplsvpn.c | 12 ++++++------ bgpd/bgp_route.c | 16 ++-------------- bgpd/bgp_route.h | 4 ++-- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c index 23be34c63b..01df053952 100644 --- a/bgpd/bgp_encap.c +++ b/bgpd/bgp_encap.c @@ -219,7 +219,7 @@ DEFUN (encap_network, int idx_ipv4 = 1; int idx_rd = 3; 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); } @@ -238,7 +238,7 @@ DEFUN (no_encap_network, int idx_ipv4 = 2; int idx_rd = 4; 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); } diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index c133d7ba39..a51affc4f7 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -705,7 +705,7 @@ DEFUN(evpnrt5_network, int idx_ethtag = 5; int idx_routermac = 13; 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_ext_community]->arg, argv[idx_word]->arg, @@ -739,7 +739,7 @@ DEFUN(no_evpnrt5_network, int idx_ethtag = 6; int idx_esi = 10; 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_ext_community]->arg, argv[idx_label]->arg, EVPN_IP_PREFIX, diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 97b40df28a..60a48f506b 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -471,7 +471,7 @@ DEFUN (vpnv4_network, int idx_ipv4_prefixlen = 1; int idx_ext_community = 3; 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); } @@ -491,7 +491,7 @@ DEFUN (vpnv4_network_route_map, int idx_ext_community = 3; int idx_word = 5; 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); } @@ -510,7 +510,7 @@ DEFUN (no_vpnv4_network, int idx_ipv4_prefixlen = 2; int idx_ext_community = 4; 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, 0, NULL, NULL, NULL); } @@ -532,9 +532,9 @@ DEFUN (vpnv6_network, int idx_word = 5; int idx_word_2 = 7; 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 - 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. */ @@ -552,7 +552,7 @@ DEFUN (no_vpnv6_network, int idx_ipv6_prefix = 2; int idx_ext_community = 4; 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 diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index de51de7a66..cb4d88859e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4453,7 +4453,7 @@ bgp_purge_static_redist_routes (struct bgp *bgp) * I think it can probably be factored with bgp_static_set. */ 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 *rmap_str, int evpn_type, const char *esi, const char *gwip, const char *ethtag, const char *routermac) @@ -4467,14 +4467,8 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str, struct bgp_table *table; struct bgp_static *bgp_static; u_char tag[3]; - afi_t afi; struct prefix gw_ip; - if(safi == SAFI_EVPN) - afi = AFI_L2VPN; - else - afi = AFI_IP; - /* validate ip prefix */ ret = str2prefix (ip_str, &p); if (! ret) @@ -4599,7 +4593,7 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str, /* Configure static BGP network. */ 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, int evpn_type, const char *esi, const char *gwip, const char *ethtag) { @@ -4612,12 +4606,6 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str, struct bgp_table *table; struct bgp_static *bgp_static; 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. */ ret = str2prefix (ip_str, &p); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index e75978d003..dbdcedd005 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -318,11 +318,11 @@ extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static 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 *, 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 *, int, const char *, const char *, const char *); From a27cb3cfe901d4f1378116bc91e6656aaed7c74c Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 17 May 2017 20:31:19 +0000 Subject: [PATCH 34/40] ospf6d: fix decimal area ID cli Not all numbers are dotted quads Signed-off-by: Quentin Young --- ospf6d/ospf6_area.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index bbab8598b8..1691e501f8 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -406,26 +406,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) \ { \ - u_int32_t area_id = 0; \ - if (inet_pton (AF_INET, str, &area_id) != 1) \ + char *ep; \ + 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); \ return CMD_SUCCESS; \ From 32f464d891df378b37bc01e62be6a56ff3b205ba Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 17 May 2017 20:31:19 +0000 Subject: [PATCH 35/40] ospf6d: fix decimal area ID cli Not all numbers are dotted quads Signed-off-by: Quentin Young --- ospf6d/ospf6_area.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 2b25585e6c..fd5e84d88c 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -406,26 +406,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) \ { \ - u_int32_t area_id = 0; \ - if (inet_pton (AF_INET, str, &area_id) != 1) \ + char *ep; \ + 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); \ return CMD_SUCCESS; \ From d79d90b297c5b6fde0d839988e8a07be09baba90 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 18 May 2017 11:29:28 +0200 Subject: [PATCH 36/40] bgpd: remove bgp_nexthop_afi prototype as pointed out by Renato Westphal in #536 Signed-off-by: David Lamparter --- bgpd/bgp_attr.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index e7f3e25c41..b28197cdd2 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -249,8 +249,6 @@ extern struct attr *bgp_attr_default_set (struct attr *attr, u_char); extern struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char, struct aspath *, struct community *, int as_set, u_char); -extern afi_t bgp_nexthop_afi (struct peer *peer, afi_t afi, safi_t safi, - struct attr *attr); extern bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *, struct stream *, struct attr *, struct bpacket_attr_vec_arr *vecarr, From b2b6f8f33c934c87de580a1665acfe79e434b3ec Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 18 May 2017 11:41:01 +0200 Subject: [PATCH 37/40] Pre-revert nonmergeable changes Revert "ospf6d: fix decimal area ID cli" commit a27cb3cfe901d4f1378116bc91e6656aaed7c74c Revert "bgpd: add back unicast option to 'address-family vpnv(4&6)' Issue #459" commit 399598bf6b749daa15d70ad64fc885d00cde1225 Revert "Fix the memory leak" commit d8d58e98397d8442ec68f8d715b64d5e6000b903 Revert "zebra: 'no ip route 4.1.1.19 255.255.255.255 99' is ambiguous" commit 83f35619359379687f21c839d61121e4ebe72541 Revert "ospf6d: Allow unconfig of unknown lsa's" commit 5b0747d71df6006835ead8e6354f70b26f7bca80 Revert "Fix the "Dead assignment" of clang SA." commit 3a6570a1f145c49155d72a815441025085dd45ad Revert "snapcraft: Improve README.usage.md based on feedback received" commit 2a3a819a9c2b2c9700e6228e7352e53b3562776c Revert "zebra: stop deregistering static nexthops unless removing the static" commit 1dac3a9619c8436f81c7b37f0252574b0b677dd0 All of these changes do not apply on stable/3.0 due to either CLI changes or another fix already being present. Signed-off-by: David Lamparter --- bgpd/bgp_vty.c | 16 ----------- lib/csv.c | 7 ----- ospf6d/ospf6_area.c | 21 ++++++++++++-- ospf6d/ospf6_lsa.c | 26 ++--------------- ospfd/ospf_apiserver.c | 2 +- ospfd/ospf_vty.c | 9 ++++++ pimd/pim_register.c | 4 +-- snapcraft/README.usage.md | 59 ++++----------------------------------- zebra/zebra_mpls_vty.c | 4 +-- zebra/zebra_rib.c | 2 ++ 10 files changed, 42 insertions(+), 108 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 9d5a4bd1cf..eef11441d6 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -6147,13 +6147,6 @@ DEFUN (address_family_vpnv4, return CMD_SUCCESS; } -ALIAS (address_family_vpnv4, - address_family_vpnv4_unicast_cmd, - "address-family vpnv4 unicast", - "Enter Address Family command mode\n" - "Address family\n" - "Address Family modifier\n") - DEFUN (address_family_vpnv6, address_family_vpnv6_cmd, "address-family vpnv6", @@ -6164,13 +6157,6 @@ DEFUN (address_family_vpnv6, return CMD_SUCCESS; } -ALIAS (address_family_vpnv6, - address_family_vpnv6_unicast_cmd, - "address-family vpnv6 unicast", - "Enter Address Family command mode\n" - "Address family\n" - "Address Family modifier\n") - DEFUN (address_family_encap, address_family_encap_cmd, "address-family encap", @@ -15173,9 +15159,7 @@ bgp_vty_init (void) install_element (BGP_NODE, &address_family_ipv6_cmd); install_element (BGP_NODE, &address_family_ipv6_safi_cmd); install_element (BGP_NODE, &address_family_vpnv4_cmd); - install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd); install_element (BGP_NODE, &address_family_vpnv6_cmd); - install_element (BGP_NODE, &address_family_vpnv6_unicast_cmd); install_element (BGP_NODE, &address_family_encap_cmd); install_element (BGP_NODE, &address_family_encapv4_cmd); install_element (BGP_NODE, &address_family_encapv6_cmd); diff --git a/lib/csv.c b/lib/csv.c index 95e3e97768..7df9292647 100644 --- a/lib/csv.c +++ b/lib/csv.c @@ -177,9 +177,6 @@ csv_decode_record(csv_record_t *rec) field = strpbrk(curr, ","); } field = strstr(curr, "\n"); - if (!field) { - return; - } fld = malloc(sizeof(csv_field_t)); if (field && fld) { fld->field = curr; @@ -242,10 +239,6 @@ csv_encode (csv_t *csv, rec = malloc(sizeof(csv_record_t)); if (!rec) { log_error("record malloc failed\n"); - if (!buf) { - free(str); - } - va_end(list); return (NULL); } csv_init_record(rec); diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 1691e501f8..bbab8598b8 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -406,11 +406,26 @@ 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) \ { \ - char *ep; \ - u_int32_t area_id = htonl (strtol(str, &ep, 10)); \ - if (*ep && inet_pton (AF_INET, str, &area_id) != 1) \ + 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; \ diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 867dc3d9d8..f3afd487e4 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -872,17 +872,7 @@ ALIAS (debug_ospf6_lsa_type, DEBUG_STR OSPF6_STR "Debug Link State Advertisements (LSAs)\n" - "Router LSA's\n" - "Network LSA's\n" - "Inter-Prefix LSA's\n" - "Inter-Router LSA's\n" - "AS-External LSA's\n" - "Link LSA's\n" - "Intra-Prefix LSA's\n" - "Unknown LSA's\n" - "Originate\n" - "Examine\n" - "Flooding\n" + "Specify LS type as Hexadecimal\n" ) DEFUN (no_debug_ospf6_lsa_type, @@ -938,22 +928,12 @@ DEFUN (no_debug_ospf6_lsa_type, ALIAS (no_debug_ospf6_lsa_type, no_debug_ospf6_lsa_hex_detail_cmd, - "no debug ospf6 lsa (router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown) (originate|examine|flooding)", + "no debug ospf6 lsa (router|network|inter-prefix|inter-router|as-external|link|intra-prefix) (originate|examine|flooding)", NO_STR DEBUG_STR OSPF6_STR "Debug Link State Advertisements (LSAs)\n" - "Router LSA's\n" - "Network LSA's\n" - "Inter-Prefix LSA's\n" - "Inter-Router LSA's\n" - "AS-External LSA's\n" - "Link LSA's\n" - "Intra-Prefix LSA's\n" - "Unknown LSA's\n" - "Originate\n" - "Examine\n" - "Flooding\n" + "Specify LS type as Hexadecimal\n" ) void diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 620dacb157..aac8ef4b8b 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -2459,7 +2459,7 @@ ospf_apiserver_clients_notify_nsm_change (struct ospf_neighbor *nbr) { struct msg *msg; struct in_addr ifaddr = { .s_addr = 0L }; - struct in_addr nbraddr; + struct in_addr nbraddr = { .s_addr = 0L }; assert (nbr); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index b13c28d0c9..c65d148ff0 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -6763,6 +6763,7 @@ DEFUN (no_ip_ospf_cost, int ret; struct ospf_if_params *params; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); if (argc == 1) @@ -6831,6 +6832,7 @@ DEFUN (no_ip_ospf_cost2, int ret; struct ospf_if_params *params; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); /* According to the semantics we are mimicking "no ip ospf cost N" is @@ -7070,6 +7072,7 @@ DEFUN (no_ip_ospf_dead_interval, struct ospf_interface *oi; struct route_node *rn; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); if (argc == 2) @@ -7244,6 +7247,7 @@ DEFUN (no_ip_ospf_hello_interval, int ret; struct ospf_if_params *params; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); if (argc == 2) @@ -7521,6 +7525,7 @@ DEFUN (no_ip_ospf_priority, int ret; struct ospf_if_params *params; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); if (argc == 2) @@ -7667,6 +7672,7 @@ DEFUN (no_ip_ospf_retransmit_interval, struct ospf_if_params *params; int addr_index; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); if (argc >= 1) @@ -7738,6 +7744,7 @@ DEFUN (no_ip_ospf_retransmit_interval_sec, struct interface *ifp = vty->index; struct ospf_if_params *params; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); UNSET_IF_PARAM (params, retransmit_interval); @@ -7822,6 +7829,7 @@ DEFUN (no_ip_ospf_transmit_delay, struct ospf_if_params *params; int addr_index; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); if (argc >= 1) @@ -7894,6 +7902,7 @@ DEFUN (no_ip_ospf_transmit_delay_sec, struct interface *ifp = vty->index; struct ospf_if_params *params; + ifp = vty->index; params = IF_DEF_PARAMS (ifp); UNSET_IF_PARAM (params, transmit_delay); diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 7844bd3399..ce3ac1a433 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -160,8 +160,8 @@ pim_register_recv (struct interface *ifp, int sentRegisterStop = 0; struct ip *ip_hdr; //size_t hlen; - struct in_addr group; - struct in_addr source; + struct in_addr group = { .s_addr = 0 }; + struct in_addr source = { .s_addr = 0 }; //uint8_t *msg; uint32_t *bits; diff --git a/snapcraft/README.usage.md b/snapcraft/README.usage.md index c678c8805c..aaff59438a 100644 --- a/snapcraft/README.usage.md +++ b/snapcraft/README.usage.md @@ -3,7 +3,7 @@ Using the FRRouting Snap After installing the Snap, the priviledged plug need to be connected: - snap connect frr:network-control core:network-control + snap connect frr:network-control ubuntu-core:network-control Enabling/Disabling FRRouting Daemons ------------------------------------------- @@ -53,74 +53,25 @@ depend on them). These are mainly intended to debug the Snap - `frr.ldpd-debug`: Starts ldpd daemon in foreground -MPLS (LDP) ----------- -The MPLS forwarding requires a Linux Kernel version 4.5 or newer and -specific MPLS kernel modules loaded. It will be auto-detected by -FRR. You can check the detected setup with the `show mpls status` -command from within `frr.vtysh` - -The following kernel modules `mpls-router` and `mpls-iptunnel` -need to be loaded. On Ubuntu 16.04, this can be done by editing -'/etc/modules-load.d/modules.conf' and add the following lines: - - # Load MPLS Kernel Modules - mpls-router - mpls-iptunnel - -For other distributions, please check the documentation on loading -modules. You need to either reboot or use `modprobe` to manually load -the modules as well before MPLS will be available. - -In addition to this, the MPLS Label-Processing needs to be enabled -with `sysctl` on the required interfaces. Assuming the interfaces -are named `eth0`, `eth1` and `eth2`, then the additional lines in -`/etc/sysctl.conf` will enable it on a Ubuntu 16.04 system: - - # Enable MPLS Label processing on all interfaces - net.mpls.conf.eth0.input=1 - net.mpls.conf.eth1.input=1 - net.mpls.conf.eth2.input=1 - net.mpls.platform_labels=100000 - -These settings require either a reboot or a manual configuration with -`sysctl` as well. - FAQ --- - frr.vtysh displays `--MORE--` on long output. How to suppress this? - Define `VTYSH_PAGER` to `cat` (default is `more`). (Ie add `export VTYSH_PAGER=cat` to the end of your `.profile`) -- ospfd / ospf6d are not running after installation - - Installing a new snap starts the daemons, but at this time they - may not have the required priviledged access. Make sure you - issue the `snap connect` command as given above (can be verified - with `snap interfaces`) and **THEN** restart the daemons (or - reboot the system). - This is a limitation of any snap package at this time which - requires priviledged interfaces (ie to manipulate routing tables) - Sourcecode available ==================== The source for this SNAP is available as part of the FRRouting -Source Code Distribution under `GPLv2 or later` +Source Code Distribution. - + https://github.com/frrouting/frr.git -Instructions for rebuilding the snap are in `snapcraft/README.snap_build.md` - -*Please checkout the desired branch before following the instructions -as they may have changed between versions of FRR* - -Official Webpage for FRR -======================== - -Official webpage for FRR is at +Instructions for rebuilding the snap are in `README.snap_build.md` Feedback welcome ================ Please send Feedback about this snap to Martin Winter at `mwinter@opensourcerouting.org` + diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 343f2975e8..8b967c3af8 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -472,7 +472,7 @@ DEFUN (no_ip_route_tag_distance_label, DEFUN (no_ip_route_mask_distance_label, no_ip_route_mask_distance_label_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> label WORD", + "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", NO_STR IP_STR "Establish static routes\n" @@ -486,7 +486,7 @@ DEFUN (no_ip_route_mask_distance_label, "One or more labels separated by '/'\n") { return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, - argv[3], NULL, argv[4]); + argv[3], NULL, argv[5]); } DEFUN (no_ip_route_mask_tag_distance_label, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 23c4c9ebea..e48da0479b 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -366,6 +366,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (set) { UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); + zebra_deregister_rnh_static_nexthops(rib->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; rib->nexthop_mtu = 0; @@ -596,6 +597,7 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, if (set) { UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); + zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; } From 05220b6d5d9d3781654e3f36a2dbac076d709059 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 18 May 2017 14:05:53 +0200 Subject: [PATCH 38/40] Revert "bgpd: resolve ipv6 ecmp issue with vrfs and ll nexthop" This reverts commit fa14eb2c0b408982a6634459b3afb21e9df6326a. This was for stable/2.0 and wasn't intended to go on stable/3.0 -- my bad, missed this in the merge. Signed-off-by: David Lamparter --- bgpd/bgp_zebra.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 4e00367aff..72bd081a7e 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1470,8 +1470,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, if (!ifindex) { if (info->peer->conf_if || info->peer->ifname) - ifindex = ifname2ifindex_vrf (info->peer->conf_if ? info->peer->conf_if : - info->peer->ifname, bgp->vrf_id); + ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname); else if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } From 0e20096f60b190f8476a65cc214520fa87e9ccc0 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 18 May 2017 14:51:56 +0200 Subject: [PATCH 39/40] zebra: fix label manager merge snafu Signed-off-by: David Lamparter --- zebra/label_manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 508ba5b923..fbe4cea467 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -178,8 +178,8 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf /* make sure we listen to the response */ if (!zclient->t_read) - zclient->t_read = - thread_add_read(zclient->master, lm_zclient_read, zserv, zclient->sock); + thread_add_read(zclient->master, lm_zclient_read, zserv, + zclient->sock, &zclient->t_read); return 0; } From 69b174d4ec7d347054761d4ddcddba096c9c4ece Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 18 May 2017 08:56:40 -0400 Subject: [PATCH 40/40] pimd: Fix indentation issue that is causing clang unhappiness The indentation of ifjoin_to_noinfo was not consistent with the rest of the function and caused clang to loose it's mind Signed-off-by: Donald Sharp --- pimd/pim_ifchannel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 735df82581..d7df0735a7 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -642,7 +642,7 @@ static int on_ifjoin_prune_pending_timer(struct thread *t) 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); + ifjoin_to_noinfo(ch, false); } else ifjoin_to_noinfo(ch, true);