summaryrefslogtreecommitdiffstats
path: root/bgpd/bgpd.c
diff options
context:
space:
mode:
authorChris Hall <chris.hall@highwayman.com>2011-08-12 15:06:06 +0100
committerChris Hall <chris.hall@highwayman.com>2011-08-12 15:06:06 +0100
commitcec1fae79110dffa900c0c5f38c3d3b48f5b0db6 (patch)
tree408055322e19098b98766168624f1b96865ac73b /bgpd/bgpd.c
parent228e06bad624a33090da4a09f32f8fed84a7e15c (diff)
parent7bd8653ef788a6395b07583d6766be8950598342 (diff)
downloadquagga-ex18p.tar.bz2
quagga-ex18p.tar.xz
Merge branch 'euro_ix' of /git/quagga.euro-ix into pipeworkex18p
Merge with euro_ix branch v0.99.18ex17. Update version to: 0.99.18ex18p Of particular note: * includes support for GTSM: neighbor ... ttl-security hops X no neighbor ... ttl-security hops X where X is 1-254. For usual case of immediately connected peer, X == 1. Cannot set ttl-security while ebgp-multihop is set, and vice-versa. If underlying O/S does not support GTSM, then will set ttl as per ebgp-multihop. In passing, have fixed various bugs in the main Quagga branch. * initial support for draft-ietf-idr-optional-transitive Does not yet support "neighbor-complete" flag. * main Quagga now uses TCP_CORK and permanent non-blocking Do not beleive TCP_CORK to be necessary for euro_ix code... which has a different buffering strategy. The euro_ix code already runs sockets permanently non-blocking. * various fixes to attribute intern/unintern Trying to remove memory leaks. Nobody seems convinced that this has been perfected, yet. * fixes for ospfd and ospf6d issues. Up to date with master branch up to: commit 538cb284864c17de66152a5236db4cd80e3e7639 Merge: 036a6e6 8ced4e8 Author: Paul Jakma <paul@quagga.net> Date: Fri Jul 29 18:21:50 2011 +0100
Diffstat (limited to 'bgpd/bgpd.c')
-rw-r--r--bgpd/bgpd.c566
1 files changed, 369 insertions, 197 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 2eee6cae..5a5eab83 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -275,11 +275,12 @@ bgp_confederation_id_set (struct bgp *bgp, as_t as)
were not doing confederation before, reset all EBGP sessions. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
+ bgp_peer_sort_t sort = peer_sort (peer) ;
/* We're looking for peers who's AS is not local or part of our
confederation. */
if (already_confed)
{
- if (peer_sort (peer) == BGP_PEER_EBGP)
+ if (sort == BGP_PEER_EBGP)
{
peer->local_as = as;
bgp_peer_down(peer, PEER_DOWN_CONFED_ID_CHANGE) ;
@@ -289,10 +290,10 @@ bgp_confederation_id_set (struct bgp *bgp, as_t as)
{
/* Not doing confederation before, so reset every non-local
session */
- if (peer_sort (peer) != BGP_PEER_IBGP)
+ if (sort != BGP_PEER_IBGP)
{
/* Reset the local_as to be our EBGP one */
- if (peer_sort (peer) == BGP_PEER_EBGP)
+ if (sort == BGP_PEER_EBGP)
peer->local_as = as;
bgp_peer_down(peer, PEER_DOWN_CONFED_ID_CHANGE) ;
@@ -561,7 +562,19 @@ peer_global_config_reset (struct peer *peer)
{
peer->weight = 0;
peer->change_local_as = 0;
- peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
+
+ if (peer_sort (peer) == BGP_PEER_IBGP)
+ {
+ peer->ttl = MAXTTL ;
+ peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
+ }
+ else /* BGP_PEER_EBGP & BGP_PEER_CONFED */
+ {
+ peer->ttl = 1 ;
+ peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
+ } ;
+ peer->gtsm = false ;
+
if (peer->update_source)
{
sockunion_free (peer->update_source);
@@ -573,11 +586,6 @@ peer_global_config_reset (struct peer *peer)
peer->update_if = NULL;
}
- if (peer_sort (peer) == BGP_PEER_IBGP)
- peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
- else
- peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
-
peer->flags = 0;
peer->config = 0;
peer->holdtime = 0;
@@ -586,7 +594,23 @@ peer_global_config_reset (struct peer *peer)
peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
}
-/* Check peer's AS number and determin is this peer IBGP or EBGP */
+/*------------------------------------------------------------------------------
+ * Check peer's AS number and determine is this peer IBGP or EBGP
+ *
+ * peer->as is the ASN heard from the peer at OPEN time (remote ASN)
+ *
+ * peer->local_as is the ASN sent to the peer at OPEN time
+ *
+ * Generally this will be the bgp->as, but for confederations
+ * the bgp->as is the member ASN, so for peers outside the
+ * confederation the local_as is set to the confed_id.
+ *
+ * Returns: BGP_PEER_EBGP
+ * BGP_PEER_IBGP -- including within a confederation member-AS
+ * BGP_PEER_CONFED -- between different confederation member-ASes
+ * BGP_PEER_INTERNAL -- this is group, and remote ASN is not set
+ * or is not group amd local ASN is not set
+ */
int
peer_sort (struct peer *peer)
{
@@ -594,35 +618,58 @@ peer_sort (struct peer *peer)
bgp = peer->bgp;
- /* Peer-group */
+ /* Peer-group
+ *
+ * If the group's ASN (remote ASN) is set, return iBGP or eBGP depending on
+ * the bgp ASN (local ASN).
+ *
+ * Otherwise: look at first peer in group (if any) and return iBGP or eBGP,
+ * depending on that peer's local and remote ASNs.
+ *
+ * Note that all peers in a group which does not specify an ASN,
+ * must all be of the same sort.
+ *
+ * Does not check for peer1->local_as being unset, because that
+ * is not realy possible... TODO ???
+ *
+ * Otherwise: return BGP_PEER_INTERNAL.
+ *
+ * NB: does not trouble itself about CONFEDERATION TODO ????
+ */
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->as)
- return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP);
+ return (bgp->as == peer->as) ? BGP_PEER_IBGP : BGP_PEER_EBGP ;
else
{
struct peer *peer1;
peer1 = listnode_head (peer->group->peer);
if (peer1)
- return (peer1->local_as == peer1->as
- ? BGP_PEER_IBGP : BGP_PEER_EBGP);
+ return (peer1->local_as == peer1->as) ? BGP_PEER_IBGP
+ : BGP_PEER_EBGP ;
}
return BGP_PEER_INTERNAL;
}
- /* Normal peer */
+ /* Normal peer
+ *
+ * If the peer's local ASN is not set, return BGP_PEER_INTERNAL.
+ *
+ * Otherwise: if peer's remote and local ASN are the same, return iBGP unless
+ * it's the confed_id, in which case return eBGP TODO ????
+ *
+ * Otherwise: if this is a confederation peer, return BGP_PEER_CONFED.
+ *
+ * Otherwise: return eBGP
+ */
+ if (peer->local_as == 0) /* not really possible... TODO ??? */
+ return BGP_PEER_INTERNAL;
+
if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
{
- if (peer->local_as == 0)
- return BGP_PEER_INTERNAL;
-
if (peer->local_as == peer->as)
- {
- if (peer->local_as == bgp->confed_id)
- return BGP_PEER_EBGP;
- else
- return BGP_PEER_IBGP;
- }
+ return (peer->local_as != bgp->confed_id) ? BGP_PEER_IBGP
+ : BGP_PEER_EBGP ;
if (bgp_confederation_peers_check (bgp, peer->as))
return BGP_PEER_CONFED;
@@ -631,9 +678,7 @@ peer_sort (struct peer *peer)
}
else
{
- return (peer->local_as == 0
- ? BGP_PEER_INTERNAL : peer->local_as == peer->as
- ? BGP_PEER_IBGP : BGP_PEER_EBGP);
+ return (peer->local_as == peer->as) ? BGP_PEER_IBGP : BGP_PEER_EBGP ;
}
}
@@ -655,10 +700,11 @@ peer_create_accept (struct bgp *bgp)
static void
peer_as_change (struct peer *peer, as_t as)
{
- int type;
+ bgp_peer_sort_t old_sort, new_sort ;
- type = peer_sort (peer);
+ old_sort = peer_sort (peer);
peer->as = as;
+ new_sort = peer_sort (peer);
if (bgp_config_check (peer->bgp, BGP_CONFIG_CONFEDERATION)
&& ! bgp_confederation_peers_check (peer->bgp, as)
@@ -668,16 +714,33 @@ peer_as_change (struct peer *peer, as_t as)
peer->local_as = peer->bgp->as;
/* Advertisement-interval reset */
- if (peer_sort (peer) == BGP_PEER_IBGP)
+ if (new_sort == BGP_PEER_IBGP)
peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
else
peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
- /* TTL reset */
- if (peer_sort (peer) == BGP_PEER_IBGP)
- peer->ttl = 255;
- else if (type == BGP_PEER_IBGP)
- peer->ttl = 1;
+ /* TTL reset
+ *
+ * -------|----------- new -----------|
+ * old | iBGP | eBGP | Confed |
+ * -------|---------|--------|--------|
+ * iBGP | iBGP | eBGP | eBGP | -- sans GTSM
+ * -------|---------|--------|--------|
+ * eBGP | iBGP | stet | stet |
+ * -------|---------|--------|--------|
+ * Confed | iBGP | stet | stet |
+ * -------|---------|--------|--------|
+* */
+ if (new_sort == BGP_PEER_IBGP)
+ {
+ peer->ttl = MAXTTL ;
+ peer->gtsm = false ;
+ }
+ else if (old_sort == BGP_PEER_IBGP)
+ {
+ peer->ttl = 1;
+ peer->gtsm = false ; /* should already be the case ! */
+ } ;
/* reflector-client reset */
if (peer_sort (peer) != BGP_PEER_IBGP)
@@ -988,6 +1051,7 @@ peer_group_get (struct bgp *bgp, const char *name)
group->conf->group = group;
group->conf->as = 0;
group->conf->ttl = 1;
+ group->conf->gtsm = false ;
group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
@@ -1023,8 +1087,9 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
if (conf->change_local_as)
peer->change_local_as = conf->change_local_as;
- /* TTL */
- peer->ttl = conf->ttl;
+ /* TTL & GTSM */
+ peer->ttl = conf->ttl;
+ peer->gtsm = conf->gtsm;
/* Weight */
peer->weight = conf->weight;
@@ -1446,7 +1511,10 @@ peer_group_bind (struct bgp *bgp, union sockunion *su,
/* ebgp-multihop reset */
if (peer_sort (group->conf) == BGP_PEER_IBGP)
- group->conf->ttl = 255;
+ {
+ group->conf->ttl = MAXTTL;
+ group->conf->gtsm = false ;
+ } ;
/* local-as reset */
if (peer_sort (group->conf) != BGP_PEER_EBGP)
@@ -2283,81 +2351,183 @@ peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
return peer_af_flag_modify (peer, afi, safi, flag, false);
}
-/* EBGP multihop configuration. */
+/*------------------------------------------------------------------------------
+ * eBGP multihop configuration set -- Confed is eBGP for this purpose.
+ *
+ * This is simply ignored if iBGP. For iBGP peer->ttl is set to MAXTTL, and
+ * peer->gtsm is always false.
+ *
+ * For eBGP and for Confed, peer->ttl is set to 1, and peer->gtsm is also
+ * set false -- until either ebgp-multihop or ttl-security is seen.
+ *
+ * NB: cannot set ebgp-multihop if ttl-security (GTSM) is set.
+ *
+ * cannot set ebgp-multihop on a group if ttl-security (GTSM) is set on any
+ * group member.
+ *
+ * NB: setting ebgp-multihop of 1 is the same as unsetting it.
+ *
+ * setting any value < 1 also unsets ebgp-multihop (sets ttl = 1)
+ */
int
peer_ebgp_multihop_set (struct peer *peer, int ttl)
{
struct peer_group *group;
struct listnode *node, *nnode;
- bgp_session session = peer->session;
if (peer_sort (peer) == BGP_PEER_IBGP)
return 0;
- peer->ttl = ttl;
+ if (peer->gtsm)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_GTSM;
+
+ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ struct peer *pgm;
+ group = peer->group;
+
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, pgm))
+ {
+ if (peer_sort (pgm) == BGP_PEER_IBGP)
+ continue;
+
+ if (pgm->gtsm)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_GTSM;
+ }
+ } ;
+
+ if (ttl <= 0)
+ ttl = 1 ;
+
+ peer->ttl = ttl ;
+//qassert(!peer->gtsm) ;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (bgp_session_is_active(session) && peer_sort (peer) != BGP_PEER_IBGP)
- bgp_session_set_ttl (session, peer->ttl);
+ bgp_session_set_ttl (peer->session, peer->ttl, peer->gtsm);
}
else
{
+ struct peer *pgm;
group = peer->group;
- for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, pgm))
{
- if (peer_sort (peer) == BGP_PEER_IBGP)
- continue;
-
- peer->ttl = group->conf->ttl;
- session = peer->session;
+ if (peer_sort (pgm) == BGP_PEER_IBGP)
+ continue;
- if (bgp_session_is_active(session))
- bgp_session_set_ttl (session, peer->ttl);
+ pgm->ttl = ttl;
+// qassert(!pgm->gtsm) ;
+ bgp_session_set_ttl (pgm->session, pgm->ttl, pgm->gtsm);
}
}
return 0;
}
+/*------------------------------------------------------------------------------
+ * eBGP multihop configuration unset -- Confed is eBGP for this purpose.
+ *
+ * Implemented by setting the ttl to 0 !
+ */
int
peer_ebgp_multihop_unset (struct peer *peer)
{
+ return peer_ebgp_multihop_set (peer, 0) ;
+}
+
+/*------------------------------------------------------------------------------
+ * eBGP ttl-security hops configuration set -- Confed is eBGP for this purpose.
+ *
+ * Setting ttl-security hops is equivalent to setting eBGP multi-hop, except
+ * that it also enables the GTSM -- if available.
+ *
+ * This is simply ignored if iBGP. For iBGP peer->ttl is set to MAXTTL, and
+ * peer->gtsm is always false.
+ *
+ * For eBGP and for Confed, peer->ttl is set to 1, and peer->gtsm is also
+ * set false -- until either ebgp-multihop or ttl-security is seen.
+ *
+ * NB: cannot set ttl-security (GTSM) if eBGP multi-hop is set.
+ *
+ * cannot set ttl-security (GTSM) on a group if eBGP multi-hop is set on any
+ * group member.
+ *
+ * NB: setting ebgp-multihop of < 1 is unsets it (sets ttl = 1, and gtsm false)
+ */
+int
+peer_ttl_security_hops_set (struct peer *peer, int ttl)
+{
struct peer_group *group;
struct listnode *node, *nnode;
- bgp_session session = peer->session;
+ bool gtsm ;
+
+ zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
+ ttl, peer->host) ;
if (peer_sort (peer) == BGP_PEER_IBGP)
- return 0;
+ return BGP_ERR_NO_IBGP_WITH_TTLHACK ;
- if (peer_group_active (peer))
- peer->ttl = peer->group->conf->ttl;
+ if (!peer->gtsm && (peer->ttl > 1))
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_GTSM;
+
+ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ struct peer *pgm;
+ group = peer->group;
+
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, pgm))
+ {
+ if (peer_sort (pgm) == BGP_PEER_IBGP)
+ continue;
+
+ if (!pgm->gtsm && (pgm->ttl > 1))
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_GTSM;
+ }
+ } ;
+
+ if (ttl > 0)
+ gtsm = true ;
else
- peer->ttl = 1;
+ {
+ gtsm = false ;
+ ttl = 1 ;
+ } ;
+
+ peer->ttl = ttl ;
+ peer->gtsm = gtsm ;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (bgp_session_is_active(session) && peer_sort (peer) != BGP_PEER_IBGP)
- bgp_session_set_ttl (session, peer->ttl);
+ bgp_session_set_ttl (peer->session, peer->ttl, peer->gtsm);
}
else
{
+ struct peer *pgm;
group = peer->group;
- for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
- {
- if (peer_sort (peer) == BGP_PEER_IBGP)
- continue;
-
- peer->ttl = 1;
- session = peer->session;
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, pgm))
+ {
+ if (peer_sort (pgm) == BGP_PEER_IBGP)
+ continue;
- if (bgp_session_is_active(session))
- bgp_session_set_ttl (session, peer->ttl);
- }
+ pgm->ttl = ttl;
+ pgm->gtsm = gtsm ;
+ bgp_session_set_ttl (pgm->session, pgm->ttl, pgm->gtsm);
+ } ;
}
-
return 0;
}
+/*------------------------------------------------------------------------------
+ * eBGP ttl-security hops configuration unset -- Confed is eBGP for this purpose.
+ *
+ * Implemented by setting the ttl to 0 !
+ */
+int
+peer_ttl_security_hops_unset (struct peer *peer)
+{
+ return peer_ttl_security_hops_set(peer, 0) ;
+}
+
+
/* Neighbor description. */
int
peer_description_set (struct peer *peer, char *desc)
@@ -3835,7 +4005,7 @@ peer_clear (struct peer *peer)
int
peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
- enum bgp_clear_type stype)
+ bgp_clear_type_t stype)
{
if (peer->state != bgp_peer_pEstablished)
return 0;
@@ -4043,160 +4213,168 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
struct peer *peer, afi_t afi, safi_t safi)
{
struct bgp_filter *filter;
- struct peer *g_peer = NULL;
+ struct peer *g_conf ;
+ bool pgm, agm ;
char *addr;
+ bgp_peer_sort_t sort ;
- filter = &peer->filter[afi][safi];
addr = peer->host;
+ sort = peer_sort(peer) ;
if (peer_group_active (peer))
- g_peer = peer->group->conf;
+ g_conf = peer->group->conf ;
+ else
+ g_conf = NULL ;
+ pgm = (g_conf != NULL) ; /* group member for >= 1 address families */
- /************************************
- ****** Global to the neighbor ******
- ************************************/
- if (afi == AFI_IP && safi == SAFI_UNICAST)
+ filter = &peer->filter[afi][safi];
+ agm = (peer->af_group[afi][safi] != 0) ;
+
+ if ((afi == AFI_IP) && (safi == SAFI_UNICAST))
{
- /* remote-as. */
- if (! peer_group_active (peer))
+ /* First: stuff which is global to the neighbor */
+
+ /* peer group and/or remote-as. */
+ if (!pgm)
{
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
- vty_out (vty, " neighbor %s peer-group%s", addr,
- VTY_NEWLINE);
+ vty_out (vty, " neighbor %s peer-group%s", addr, VTY_NEWLINE);
if (peer->as)
vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
- VTY_NEWLINE);
+ VTY_NEWLINE);
}
else
{
- if (! g_peer->as)
+ if (g_conf->as == 0)
vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
- VTY_NEWLINE);
- if (peer->af_group[AFI_IP][SAFI_UNICAST])
+ VTY_NEWLINE);
+ if (agm)
vty_out (vty, " neighbor %s peer-group %s%s", addr,
- peer->group->name, VTY_NEWLINE);
+ peer->group->name, VTY_NEWLINE);
}
- /* local-as. */
+ /* local-as. */
if (peer->change_local_as)
- if (! peer_group_active (peer))
+ if (!pgm)
vty_out (vty, " neighbor %s local-as %u%s%s", addr,
- peer->change_local_as,
- CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
- " no-prepend" : "", VTY_NEWLINE);
+ peer->change_local_as,
+ CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)
+ ? " no-prepend" : "", VTY_NEWLINE);
- /* Description. */
+ /* Description. */
if (peer->desc)
vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
- VTY_NEWLINE);
+ VTY_NEWLINE);
- /* Shutdown. */
+ /* Shutdown. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
- if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
+ if (!pgm || ! CHECK_FLAG (g_conf->flags, PEER_FLAG_SHUTDOWN))
vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
- /* Password. */
+ /* Password. */
if (peer->password)
- if (!peer_group_active (peer)
- || ! g_peer->password
- || strcmp (peer->password, g_peer->password) != 0)
+ if (!pgm || (g_conf->password == NULL)
+ || (strcmp (peer->password, g_conf->password) != 0))
vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
- VTY_NEWLINE);
+ VTY_NEWLINE);
- /* BGP port. */
+ /* BGP port. */
if (peer->port != BGP_PORT_DEFAULT)
- vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
- VTY_NEWLINE);
+ vty_out (vty, " neighbor %s port %d%s", addr, peer->port, VTY_NEWLINE);
- /* Local interface name. */
+ /* Local interface name. */
if (peer->ifname)
vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname,
- VTY_NEWLINE);
+ VTY_NEWLINE);
- /* Passive. */
+ /* Passive. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
- if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE))
+ if (!pgm || ! CHECK_FLAG (g_conf->flags, PEER_FLAG_PASSIVE))
vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
- /* EBGP multihop. */
- if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1)
- if (! peer_group_active (peer) ||
- g_peer->ttl != peer->ttl)
- vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
- VTY_NEWLINE);
+ /* EBGP multihop and ttl-security hops. */
+ if (sort != BGP_PEER_IBGP)
+ {
+ if (peer->gtsm)
+ {
+ /* ttl-security hops */
+ if (!pgm || ! g_conf->gtsm)
+ vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
+ peer->ttl, VTY_NEWLINE) ;
+ }
+ else if (peer->ttl != 1)
+ {
+ /* eBGP multihop */
+ if (!pgm || (g_conf->ttl != peer->ttl))
+ vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr,
+ peer->ttl, VTY_NEWLINE) ;
+ } ;
+ } ;
- /* disable-connected-check. */
+ /* disable-connected-check. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
- if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
- vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
+ if (!pgm ||
+ ! CHECK_FLAG (g_conf->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
+ vty_out (vty, " neighbor %s disable-connected-check%s", addr,
+ VTY_NEWLINE);
- /* Update-source. */
+ /* Update-source. */
if (peer->update_if)
- if (! peer_group_active (peer) || ! g_peer->update_if
- || strcmp (g_peer->update_if, peer->update_if) != 0)
+ if (!pgm || ! g_conf->update_if
+ || (strcmp (g_conf->update_if, peer->update_if) != 0))
vty_out (vty, " neighbor %s update-source %s%s", addr,
- peer->update_if, VTY_NEWLINE);
+ peer->update_if, VTY_NEWLINE);
if (peer->update_source)
- if (! peer_group_active (peer) || ! g_peer->update_source
- || sockunion_cmp (g_peer->update_source,
- peer->update_source) != 0)
+ if (!pgm || ! g_conf->update_source
+ || (sockunion_cmp (g_conf->update_source, peer->update_source) != 0))
vty_out (vty, " neighbor %s update-source %s%s", addr,
sutoa(peer->update_source).str,
VTY_NEWLINE);
- /* advertisement-interval */
+ /* advertisement-interval */
if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV))
vty_out (vty, " neighbor %s advertisement-interval %d%s",
addr, peer->v_routeadv, VTY_NEWLINE);
- /* timers. */
- if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)
- && ! peer_group_active (peer))
- vty_out (vty, " neighbor %s timers %d %d%s", addr,
- peer->keepalive, peer->holdtime, VTY_NEWLINE);
+ /* timers. */
+ if (!pgm && CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
+ vty_out (vty, " neighbor %s timers %d %d%s", addr,
+ peer->keepalive, peer->holdtime, VTY_NEWLINE);
if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT))
- vty_out (vty, " neighbor %s timers connect %d%s", addr,
- peer->connect, VTY_NEWLINE);
+ vty_out (vty, " neighbor %s timers connect %d%s", addr,
+ peer->connect, VTY_NEWLINE);
- /* Default weight. */
+ /* Default weight. */
if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
- if (! peer_group_active (peer) ||
- g_peer->weight != peer->weight)
+ if (!pgm || g_conf->weight != peer->weight)
vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
- VTY_NEWLINE);
+ VTY_NEWLINE);
- /* Dynamic capability. */
+ /* Dynamic capability. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
- if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
+ if (!pgm || ! CHECK_FLAG (g_conf->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
vty_out (vty, " neighbor %s capability dynamic%s", addr,
- VTY_NEWLINE);
+ VTY_NEWLINE);
- /* dont capability negotiation. */
+ /* dont capability negotiation. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
- if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY))
- vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
- VTY_NEWLINE);
+ if (!pgm || ! CHECK_FLAG (g_conf->flags, PEER_FLAG_DONT_CAPABILITY))
+ vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
+ VTY_NEWLINE);
- /* override capability negotiation. */
+ /* override capability negotiation. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
- if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
- vty_out (vty, " neighbor %s override-capability%s", addr,
- VTY_NEWLINE);
+ if (!pgm || ! CHECK_FLAG (g_conf->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
+ vty_out (vty, " neighbor %s override-capability%s", addr,
+ VTY_NEWLINE);
- /* strict capability negotiation. */
+ /* strict capability negotiation. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
- if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
- vty_out (vty, " neighbor %s strict-capability-match%s", addr,
- VTY_NEWLINE);
+ if (!pgm || ! CHECK_FLAG (g_conf->flags, PEER_FLAG_STRICT_CAP_MATCH))
+ vty_out (vty, " neighbor %s strict-capability-match%s", addr,
+ VTY_NEWLINE);
- if (! peer_group_active (peer))
+ if (!pgm)
{
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
{
@@ -4210,25 +4388,25 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
}
}
}
-
-
- /************************************
- ****** Per AF to the neighbor ******
- ************************************/
-
- if (! (afi == AFI_IP && safi == SAFI_UNICAST))
+ else
{
- if (peer->af_group[afi][safi])
+ /* Per AF for the neighbor */
+
+ if (agm)
vty_out (vty, " neighbor %s peer-group %s%s", addr,
- peer->group->name, VTY_NEWLINE);
+ peer->group->name, VTY_NEWLINE);
else
vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
}
+ /*--------------------------------------------------------------------
+ * From now on we are dealing with the particular address family.
+ */
+
/* ORF capability. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
- if (! peer->af_group[afi][safi])
+ if (!agm)
{
vty_out (vty, " neighbor %s capability orf prefix-list", addr);
@@ -4243,24 +4421,20 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
}
/* Route reflector client. */
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT)
- && ! peer->af_group[afi][safi])
+ if (!agm && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT))
vty_out (vty, " neighbor %s route-reflector-client%s", addr,
VTY_NEWLINE);
/* Nexthop self. */
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
- && ! peer->af_group[afi][safi])
+ if (!agm && peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF))
vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);
/* Remove private AS. */
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
- && ! peer->af_group[afi][safi])
- vty_out (vty, " neighbor %s remove-private-AS%s",
- addr, VTY_NEWLINE);
+ if (!agm && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS))
+ vty_out (vty, " neighbor %s remove-private-AS%s", addr, VTY_NEWLINE);
/* send-community print. */
- if (! peer->af_group[afi][safi])
+ if (!agm)
{
if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
{
@@ -4288,9 +4462,8 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
}
}
- /* Default information */
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
- && ! peer->af_group[afi][safi])
+ /* Default information */
+ if (!agm && peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE))
{
vty_out (vty, " neighbor %s default-originate", addr);
if (peer->default_rmap[afi][safi].name)
@@ -4298,19 +4471,19 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
vty_out (vty, "%s", VTY_NEWLINE);
}
- /* Soft reconfiguration inbound. */
+ /* Soft reconfiguration inbound. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
- if (! peer->af_group[afi][safi] ||
- ! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
+ if (!agm ||
+ ! CHECK_FLAG (g_conf->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
- VTY_NEWLINE);
+ VTY_NEWLINE);
- /* maximum-prefix. */
+ /* maximum-prefix. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
- if (! peer->af_group[afi][safi]
- || g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
- || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
- || CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
+ if (!agm
+ || g_conf->pmax[afi][safi] != peer->pmax[afi][safi]
+ || g_conf->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
+ || CHECK_FLAG (g_conf->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
!= CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
{
vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
@@ -4324,15 +4497,14 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
}
/* Route server client. */
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
- && ! peer->af_group[afi][safi])
+ if (!agm && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
/* Allow AS in. */
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
- if (! peer_group_active (peer)
- || ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN)
- || peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
+ if (!pgm
+ || ! peer_af_flag_check (g_conf, afi, safi, PEER_FLAG_ALLOWAS_IN)
+ || peer->allowas_in[afi][safi] != g_conf->allowas_in[afi][safi])
{
if (peer->allowas_in[afi][safi] == 3)
vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
@@ -4345,10 +4517,10 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
bgp_config_write_filter (vty, peer, afi, safi);
/* atribute-unchanged. */
- if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
+ if (!agm &&
+ ( CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
- || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
- && ! peer->af_group[afi][safi])
+ || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED) ))
{
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)